mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 18:13:41 +02:00
Merge branch kvm-arm64/gicv5-prologue into kvmarm-master/next
* kvm-arm64/gicv5-prologue: : . : Prologue to GICv5 support, courtesy of Sascha Bischoff. : : This is preliminary work that sets the scene for the full-blow : support. : . irqchip/gic-v5: Check if impl is virt capable KVM: arm64: gic: Set vgic_model before initing private IRQs arm64/sysreg: Drop ICH_HFGRTR_EL2.ICC_HAPR_EL1 and make RES1 KVM: arm64: gic-v3: Switch vGIC-v3 to use generated ICH_VMCR_EL2 Signed-off-by: Marc Zyngier <maz@kernel.org>
This commit is contained in:
commit
47e89febd3
|
|
@ -235,7 +235,6 @@
|
|||
ICH_HFGRTR_EL2_ICC_ICSR_EL1 | \
|
||||
ICH_HFGRTR_EL2_ICC_PCR_EL1 | \
|
||||
ICH_HFGRTR_EL2_ICC_HPPIR_EL1 | \
|
||||
ICH_HFGRTR_EL2_ICC_HAPR_EL1 | \
|
||||
ICH_HFGRTR_EL2_ICC_CR0_EL1 | \
|
||||
ICH_HFGRTR_EL2_ICC_IDRn_EL1 | \
|
||||
ICH_HFGRTR_EL2_ICC_APR_EL1)
|
||||
|
|
|
|||
|
|
@ -560,7 +560,6 @@
|
|||
#define SYS_ICC_SRE_EL2 sys_reg(3, 4, 12, 9, 5)
|
||||
#define SYS_ICH_EISR_EL2 sys_reg(3, 4, 12, 11, 3)
|
||||
#define SYS_ICH_ELRSR_EL2 sys_reg(3, 4, 12, 11, 5)
|
||||
#define SYS_ICH_VMCR_EL2 sys_reg(3, 4, 12, 11, 7)
|
||||
|
||||
#define __SYS__LR0_EL2(x) sys_reg(3, 4, 12, 12, x)
|
||||
#define SYS_ICH_LR0_EL2 __SYS__LR0_EL2(0)
|
||||
|
|
@ -988,26 +987,6 @@
|
|||
#define ICH_LR_PRIORITY_SHIFT 48
|
||||
#define ICH_LR_PRIORITY_MASK (0xffULL << ICH_LR_PRIORITY_SHIFT)
|
||||
|
||||
/* ICH_VMCR_EL2 bit definitions */
|
||||
#define ICH_VMCR_ACK_CTL_SHIFT 2
|
||||
#define ICH_VMCR_ACK_CTL_MASK (1 << ICH_VMCR_ACK_CTL_SHIFT)
|
||||
#define ICH_VMCR_FIQ_EN_SHIFT 3
|
||||
#define ICH_VMCR_FIQ_EN_MASK (1 << ICH_VMCR_FIQ_EN_SHIFT)
|
||||
#define ICH_VMCR_CBPR_SHIFT 4
|
||||
#define ICH_VMCR_CBPR_MASK (1 << ICH_VMCR_CBPR_SHIFT)
|
||||
#define ICH_VMCR_EOIM_SHIFT 9
|
||||
#define ICH_VMCR_EOIM_MASK (1 << ICH_VMCR_EOIM_SHIFT)
|
||||
#define ICH_VMCR_BPR1_SHIFT 18
|
||||
#define ICH_VMCR_BPR1_MASK (7 << ICH_VMCR_BPR1_SHIFT)
|
||||
#define ICH_VMCR_BPR0_SHIFT 21
|
||||
#define ICH_VMCR_BPR0_MASK (7 << ICH_VMCR_BPR0_SHIFT)
|
||||
#define ICH_VMCR_PMR_SHIFT 24
|
||||
#define ICH_VMCR_PMR_MASK (0xffUL << ICH_VMCR_PMR_SHIFT)
|
||||
#define ICH_VMCR_ENG0_SHIFT 0
|
||||
#define ICH_VMCR_ENG0_MASK (1 << ICH_VMCR_ENG0_SHIFT)
|
||||
#define ICH_VMCR_ENG1_SHIFT 1
|
||||
#define ICH_VMCR_ENG1_MASK (1 << ICH_VMCR_ENG1_SHIFT)
|
||||
|
||||
/*
|
||||
* Permission Indirection Extension (PIE) permission encodings.
|
||||
* Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
|
||||
|
|
|
|||
|
|
@ -569,11 +569,11 @@ static int __vgic_v3_highest_priority_lr(struct kvm_vcpu *vcpu, u32 vmcr,
|
|||
continue;
|
||||
|
||||
/* Group-0 interrupt, but Group-0 disabled? */
|
||||
if (!(val & ICH_LR_GROUP) && !(vmcr & ICH_VMCR_ENG0_MASK))
|
||||
if (!(val & ICH_LR_GROUP) && !(vmcr & ICH_VMCR_EL2_VENG0_MASK))
|
||||
continue;
|
||||
|
||||
/* Group-1 interrupt, but Group-1 disabled? */
|
||||
if ((val & ICH_LR_GROUP) && !(vmcr & ICH_VMCR_ENG1_MASK))
|
||||
if ((val & ICH_LR_GROUP) && !(vmcr & ICH_VMCR_EL2_VENG1_MASK))
|
||||
continue;
|
||||
|
||||
/* Not the highest priority? */
|
||||
|
|
@ -646,19 +646,19 @@ static int __vgic_v3_get_highest_active_priority(void)
|
|||
|
||||
static unsigned int __vgic_v3_get_bpr0(u32 vmcr)
|
||||
{
|
||||
return (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT;
|
||||
return FIELD_GET(ICH_VMCR_EL2_VBPR0, vmcr);
|
||||
}
|
||||
|
||||
static unsigned int __vgic_v3_get_bpr1(u32 vmcr)
|
||||
{
|
||||
unsigned int bpr;
|
||||
|
||||
if (vmcr & ICH_VMCR_CBPR_MASK) {
|
||||
if (vmcr & ICH_VMCR_EL2_VCBPR_MASK) {
|
||||
bpr = __vgic_v3_get_bpr0(vmcr);
|
||||
if (bpr < 7)
|
||||
bpr++;
|
||||
} else {
|
||||
bpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT;
|
||||
bpr = FIELD_GET(ICH_VMCR_EL2_VBPR1, vmcr);
|
||||
}
|
||||
|
||||
return bpr;
|
||||
|
|
@ -758,7 +758,7 @@ static void __vgic_v3_read_iar(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
if (grp != !!(lr_val & ICH_LR_GROUP))
|
||||
goto spurious;
|
||||
|
||||
pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT;
|
||||
pmr = FIELD_GET(ICH_VMCR_EL2_VPMR, vmcr);
|
||||
lr_prio = (lr_val & ICH_LR_PRIORITY_MASK) >> ICH_LR_PRIORITY_SHIFT;
|
||||
if (pmr <= lr_prio)
|
||||
goto spurious;
|
||||
|
|
@ -806,7 +806,7 @@ static int ___vgic_v3_write_dir(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
int lr;
|
||||
|
||||
/* EOImode == 0, nothing to be done here */
|
||||
if (!(vmcr & ICH_VMCR_EOIM_MASK))
|
||||
if (!(vmcr & ICH_VMCR_EL2_VEOIM_MASK))
|
||||
return 1;
|
||||
|
||||
/* No deactivate to be performed on an LPI */
|
||||
|
|
@ -849,7 +849,7 @@ static void __vgic_v3_write_eoir(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
}
|
||||
|
||||
/* EOImode == 1 and not an LPI, nothing to be done here */
|
||||
if ((vmcr & ICH_VMCR_EOIM_MASK) && !(vid >= VGIC_MIN_LPI))
|
||||
if ((vmcr & ICH_VMCR_EL2_VEOIM_MASK) && !(vid >= VGIC_MIN_LPI))
|
||||
return;
|
||||
|
||||
lr_prio = (lr_val & ICH_LR_PRIORITY_MASK) >> ICH_LR_PRIORITY_SHIFT;
|
||||
|
|
@ -865,22 +865,19 @@ static void __vgic_v3_write_eoir(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
|
||||
static void __vgic_v3_read_igrpen0(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
||||
{
|
||||
vcpu_set_reg(vcpu, rt, !!(vmcr & ICH_VMCR_ENG0_MASK));
|
||||
vcpu_set_reg(vcpu, rt, FIELD_GET(ICH_VMCR_EL2_VENG0, vmcr));
|
||||
}
|
||||
|
||||
static void __vgic_v3_read_igrpen1(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
||||
{
|
||||
vcpu_set_reg(vcpu, rt, !!(vmcr & ICH_VMCR_ENG1_MASK));
|
||||
vcpu_set_reg(vcpu, rt, FIELD_GET(ICH_VMCR_EL2_VENG1, vmcr));
|
||||
}
|
||||
|
||||
static void __vgic_v3_write_igrpen0(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
||||
{
|
||||
u64 val = vcpu_get_reg(vcpu, rt);
|
||||
|
||||
if (val & 1)
|
||||
vmcr |= ICH_VMCR_ENG0_MASK;
|
||||
else
|
||||
vmcr &= ~ICH_VMCR_ENG0_MASK;
|
||||
FIELD_MODIFY(ICH_VMCR_EL2_VENG0, &vmcr, val & 1);
|
||||
|
||||
__vgic_v3_write_vmcr(vmcr);
|
||||
}
|
||||
|
|
@ -889,10 +886,7 @@ static void __vgic_v3_write_igrpen1(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
{
|
||||
u64 val = vcpu_get_reg(vcpu, rt);
|
||||
|
||||
if (val & 1)
|
||||
vmcr |= ICH_VMCR_ENG1_MASK;
|
||||
else
|
||||
vmcr &= ~ICH_VMCR_ENG1_MASK;
|
||||
FIELD_MODIFY(ICH_VMCR_EL2_VENG1, &vmcr, val & 1);
|
||||
|
||||
__vgic_v3_write_vmcr(vmcr);
|
||||
}
|
||||
|
|
@ -916,10 +910,7 @@ static void __vgic_v3_write_bpr0(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
if (val < bpr_min)
|
||||
val = bpr_min;
|
||||
|
||||
val <<= ICH_VMCR_BPR0_SHIFT;
|
||||
val &= ICH_VMCR_BPR0_MASK;
|
||||
vmcr &= ~ICH_VMCR_BPR0_MASK;
|
||||
vmcr |= val;
|
||||
FIELD_MODIFY(ICH_VMCR_EL2_VBPR0, &vmcr, val);
|
||||
|
||||
__vgic_v3_write_vmcr(vmcr);
|
||||
}
|
||||
|
|
@ -929,17 +920,14 @@ static void __vgic_v3_write_bpr1(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
u64 val = vcpu_get_reg(vcpu, rt);
|
||||
u8 bpr_min = __vgic_v3_bpr_min();
|
||||
|
||||
if (vmcr & ICH_VMCR_CBPR_MASK)
|
||||
if (FIELD_GET(ICH_VMCR_EL2_VCBPR, val))
|
||||
return;
|
||||
|
||||
/* Enforce BPR limiting */
|
||||
if (val < bpr_min)
|
||||
val = bpr_min;
|
||||
|
||||
val <<= ICH_VMCR_BPR1_SHIFT;
|
||||
val &= ICH_VMCR_BPR1_MASK;
|
||||
vmcr &= ~ICH_VMCR_BPR1_MASK;
|
||||
vmcr |= val;
|
||||
FIELD_MODIFY(ICH_VMCR_EL2_VBPR1, &vmcr, val);
|
||||
|
||||
__vgic_v3_write_vmcr(vmcr);
|
||||
}
|
||||
|
|
@ -1029,19 +1017,14 @@ static void __vgic_v3_read_hppir(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
|
||||
static void __vgic_v3_read_pmr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
||||
{
|
||||
vmcr &= ICH_VMCR_PMR_MASK;
|
||||
vmcr >>= ICH_VMCR_PMR_SHIFT;
|
||||
vcpu_set_reg(vcpu, rt, vmcr);
|
||||
vcpu_set_reg(vcpu, rt, FIELD_GET(ICH_VMCR_EL2_VPMR, vmcr));
|
||||
}
|
||||
|
||||
static void __vgic_v3_write_pmr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
||||
{
|
||||
u32 val = vcpu_get_reg(vcpu, rt);
|
||||
|
||||
val <<= ICH_VMCR_PMR_SHIFT;
|
||||
val &= ICH_VMCR_PMR_MASK;
|
||||
vmcr &= ~ICH_VMCR_PMR_MASK;
|
||||
vmcr |= val;
|
||||
FIELD_MODIFY(ICH_VMCR_EL2_VPMR, &vmcr, val);
|
||||
|
||||
write_gicreg(vmcr, ICH_VMCR_EL2);
|
||||
}
|
||||
|
|
@ -1064,9 +1047,11 @@ static void __vgic_v3_read_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
/* A3V */
|
||||
val |= ((vtr >> 21) & 1) << ICC_CTLR_EL1_A3V_SHIFT;
|
||||
/* EOImode */
|
||||
val |= ((vmcr & ICH_VMCR_EOIM_MASK) >> ICH_VMCR_EOIM_SHIFT) << ICC_CTLR_EL1_EOImode_SHIFT;
|
||||
val |= FIELD_PREP(ICC_CTLR_EL1_EOImode_MASK,
|
||||
FIELD_GET(ICH_VMCR_EL2_VEOIM, vmcr));
|
||||
/* CBPR */
|
||||
val |= (vmcr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT;
|
||||
val |= FIELD_PREP(ICC_CTLR_EL1_CBPR_MASK,
|
||||
FIELD_GET(ICH_VMCR_EL2_VCBPR, vmcr));
|
||||
|
||||
vcpu_set_reg(vcpu, rt, val);
|
||||
}
|
||||
|
|
@ -1075,15 +1060,11 @@ static void __vgic_v3_write_ctlr(struct kvm_vcpu *vcpu, u32 vmcr, int rt)
|
|||
{
|
||||
u32 val = vcpu_get_reg(vcpu, rt);
|
||||
|
||||
if (val & ICC_CTLR_EL1_CBPR_MASK)
|
||||
vmcr |= ICH_VMCR_CBPR_MASK;
|
||||
else
|
||||
vmcr &= ~ICH_VMCR_CBPR_MASK;
|
||||
FIELD_MODIFY(ICH_VMCR_EL2_VCBPR, &vmcr,
|
||||
FIELD_GET(ICC_CTLR_EL1_CBPR_MASK, val));
|
||||
|
||||
if (val & ICC_CTLR_EL1_EOImode_MASK)
|
||||
vmcr |= ICH_VMCR_EOIM_MASK;
|
||||
else
|
||||
vmcr &= ~ICH_VMCR_EOIM_MASK;
|
||||
FIELD_MODIFY(ICH_VMCR_EL2_VEOIM, &vmcr,
|
||||
FIELD_GET(ICC_CTLR_EL1_EOImode_MASK, val));
|
||||
|
||||
write_gicreg(vmcr, ICH_VMCR_EL2);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -140,6 +140,10 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
kvm->arch.vgic.in_kernel = true;
|
||||
kvm->arch.vgic.vgic_model = type;
|
||||
kvm->arch.vgic.implementation_rev = KVM_VGIC_IMP_REV_LATEST;
|
||||
|
||||
kvm_for_each_vcpu(i, vcpu, kvm) {
|
||||
ret = vgic_allocate_private_irqs_locked(vcpu, type);
|
||||
if (ret)
|
||||
|
|
@ -156,10 +160,6 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
kvm->arch.vgic.in_kernel = true;
|
||||
kvm->arch.vgic.vgic_model = type;
|
||||
kvm->arch.vgic.implementation_rev = KVM_VGIC_IMP_REV_LATEST;
|
||||
|
||||
kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF;
|
||||
|
||||
aa64pfr0 = kvm_read_vm_id_reg(kvm, SYS_ID_AA64PFR0_EL1) & ~ID_AA64PFR0_EL1_GIC;
|
||||
|
|
|
|||
|
|
@ -202,16 +202,16 @@ u64 vgic_v3_get_misr(struct kvm_vcpu *vcpu)
|
|||
if ((hcr & ICH_HCR_EL2_NPIE) && !mi_state.pend)
|
||||
reg |= ICH_MISR_EL2_NP;
|
||||
|
||||
if ((hcr & ICH_HCR_EL2_VGrp0EIE) && (vmcr & ICH_VMCR_ENG0_MASK))
|
||||
if ((hcr & ICH_HCR_EL2_VGrp0EIE) && (vmcr & ICH_VMCR_EL2_VENG0_MASK))
|
||||
reg |= ICH_MISR_EL2_VGrp0E;
|
||||
|
||||
if ((hcr & ICH_HCR_EL2_VGrp0DIE) && !(vmcr & ICH_VMCR_ENG0_MASK))
|
||||
if ((hcr & ICH_HCR_EL2_VGrp0DIE) && !(vmcr & ICH_VMCR_EL2_VENG0_MASK))
|
||||
reg |= ICH_MISR_EL2_VGrp0D;
|
||||
|
||||
if ((hcr & ICH_HCR_EL2_VGrp1EIE) && (vmcr & ICH_VMCR_ENG1_MASK))
|
||||
if ((hcr & ICH_HCR_EL2_VGrp1EIE) && (vmcr & ICH_VMCR_EL2_VENG1_MASK))
|
||||
reg |= ICH_MISR_EL2_VGrp1E;
|
||||
|
||||
if ((hcr & ICH_HCR_EL2_VGrp1DIE) && !(vmcr & ICH_VMCR_ENG1_MASK))
|
||||
if ((hcr & ICH_HCR_EL2_VGrp1DIE) && !(vmcr & ICH_VMCR_EL2_VENG1_MASK))
|
||||
reg |= ICH_MISR_EL2_VGrp1D;
|
||||
|
||||
return reg;
|
||||
|
|
|
|||
|
|
@ -41,9 +41,9 @@ void vgic_v3_configure_hcr(struct kvm_vcpu *vcpu,
|
|||
if (!als->nr_sgi)
|
||||
cpuif->vgic_hcr |= ICH_HCR_EL2_vSGIEOICount;
|
||||
|
||||
cpuif->vgic_hcr |= (cpuif->vgic_vmcr & ICH_VMCR_ENG0_MASK) ?
|
||||
cpuif->vgic_hcr |= (cpuif->vgic_vmcr & ICH_VMCR_EL2_VENG0_MASK) ?
|
||||
ICH_HCR_EL2_VGrp0DIE : ICH_HCR_EL2_VGrp0EIE;
|
||||
cpuif->vgic_hcr |= (cpuif->vgic_vmcr & ICH_VMCR_ENG1_MASK) ?
|
||||
cpuif->vgic_hcr |= (cpuif->vgic_vmcr & ICH_VMCR_EL2_VENG1_MASK) ?
|
||||
ICH_HCR_EL2_VGrp1DIE : ICH_HCR_EL2_VGrp1EIE;
|
||||
|
||||
/*
|
||||
|
|
@ -215,7 +215,7 @@ void vgic_v3_deactivate(struct kvm_vcpu *vcpu, u64 val)
|
|||
* We only deal with DIR when EOIMode==1, and only for SGI,
|
||||
* PPI or SPI.
|
||||
*/
|
||||
if (!(cpuif->vgic_vmcr & ICH_VMCR_EOIM_MASK) ||
|
||||
if (!(cpuif->vgic_vmcr & ICH_VMCR_EL2_VEOIM_MASK) ||
|
||||
val >= vcpu->kvm->arch.vgic.nr_spis + VGIC_NR_PRIVATE_IRQS)
|
||||
return;
|
||||
|
||||
|
|
@ -408,25 +408,23 @@ void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
|||
u32 vmcr;
|
||||
|
||||
if (model == KVM_DEV_TYPE_ARM_VGIC_V2) {
|
||||
vmcr = (vmcrp->ackctl << ICH_VMCR_ACK_CTL_SHIFT) &
|
||||
ICH_VMCR_ACK_CTL_MASK;
|
||||
vmcr |= (vmcrp->fiqen << ICH_VMCR_FIQ_EN_SHIFT) &
|
||||
ICH_VMCR_FIQ_EN_MASK;
|
||||
vmcr = FIELD_PREP(ICH_VMCR_EL2_VAckCtl, vmcrp->ackctl);
|
||||
vmcr |= FIELD_PREP(ICH_VMCR_EL2_VFIQEn, vmcrp->fiqen);
|
||||
} else {
|
||||
/*
|
||||
* When emulating GICv3 on GICv3 with SRE=1 on the
|
||||
* VFIQEn bit is RES1 and the VAckCtl bit is RES0.
|
||||
*/
|
||||
vmcr = ICH_VMCR_FIQ_EN_MASK;
|
||||
vmcr = ICH_VMCR_EL2_VFIQEn_MASK;
|
||||
}
|
||||
|
||||
vmcr |= (vmcrp->cbpr << ICH_VMCR_CBPR_SHIFT) & ICH_VMCR_CBPR_MASK;
|
||||
vmcr |= (vmcrp->eoim << ICH_VMCR_EOIM_SHIFT) & ICH_VMCR_EOIM_MASK;
|
||||
vmcr |= (vmcrp->abpr << ICH_VMCR_BPR1_SHIFT) & ICH_VMCR_BPR1_MASK;
|
||||
vmcr |= (vmcrp->bpr << ICH_VMCR_BPR0_SHIFT) & ICH_VMCR_BPR0_MASK;
|
||||
vmcr |= (vmcrp->pmr << ICH_VMCR_PMR_SHIFT) & ICH_VMCR_PMR_MASK;
|
||||
vmcr |= (vmcrp->grpen0 << ICH_VMCR_ENG0_SHIFT) & ICH_VMCR_ENG0_MASK;
|
||||
vmcr |= (vmcrp->grpen1 << ICH_VMCR_ENG1_SHIFT) & ICH_VMCR_ENG1_MASK;
|
||||
vmcr |= FIELD_PREP(ICH_VMCR_EL2_VCBPR, vmcrp->cbpr);
|
||||
vmcr |= FIELD_PREP(ICH_VMCR_EL2_VEOIM, vmcrp->eoim);
|
||||
vmcr |= FIELD_PREP(ICH_VMCR_EL2_VBPR1, vmcrp->abpr);
|
||||
vmcr |= FIELD_PREP(ICH_VMCR_EL2_VBPR0, vmcrp->bpr);
|
||||
vmcr |= FIELD_PREP(ICH_VMCR_EL2_VPMR, vmcrp->pmr);
|
||||
vmcr |= FIELD_PREP(ICH_VMCR_EL2_VENG0, vmcrp->grpen0);
|
||||
vmcr |= FIELD_PREP(ICH_VMCR_EL2_VENG1, vmcrp->grpen1);
|
||||
|
||||
cpu_if->vgic_vmcr = vmcr;
|
||||
}
|
||||
|
|
@ -440,10 +438,8 @@ void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
|||
vmcr = cpu_if->vgic_vmcr;
|
||||
|
||||
if (model == KVM_DEV_TYPE_ARM_VGIC_V2) {
|
||||
vmcrp->ackctl = (vmcr & ICH_VMCR_ACK_CTL_MASK) >>
|
||||
ICH_VMCR_ACK_CTL_SHIFT;
|
||||
vmcrp->fiqen = (vmcr & ICH_VMCR_FIQ_EN_MASK) >>
|
||||
ICH_VMCR_FIQ_EN_SHIFT;
|
||||
vmcrp->ackctl = FIELD_GET(ICH_VMCR_EL2_VAckCtl, vmcr);
|
||||
vmcrp->fiqen = FIELD_GET(ICH_VMCR_EL2_VFIQEn, vmcr);
|
||||
} else {
|
||||
/*
|
||||
* When emulating GICv3 on GICv3 with SRE=1 on the
|
||||
|
|
@ -453,13 +449,13 @@ void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
|||
vmcrp->ackctl = 0;
|
||||
}
|
||||
|
||||
vmcrp->cbpr = (vmcr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT;
|
||||
vmcrp->eoim = (vmcr & ICH_VMCR_EOIM_MASK) >> ICH_VMCR_EOIM_SHIFT;
|
||||
vmcrp->abpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT;
|
||||
vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT;
|
||||
vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT;
|
||||
vmcrp->grpen0 = (vmcr & ICH_VMCR_ENG0_MASK) >> ICH_VMCR_ENG0_SHIFT;
|
||||
vmcrp->grpen1 = (vmcr & ICH_VMCR_ENG1_MASK) >> ICH_VMCR_ENG1_SHIFT;
|
||||
vmcrp->cbpr = FIELD_GET(ICH_VMCR_EL2_VCBPR, vmcr);
|
||||
vmcrp->eoim = FIELD_GET(ICH_VMCR_EL2_VEOIM, vmcr);
|
||||
vmcrp->abpr = FIELD_GET(ICH_VMCR_EL2_VBPR1, vmcr);
|
||||
vmcrp->bpr = FIELD_GET(ICH_VMCR_EL2_VBPR0, vmcr);
|
||||
vmcrp->pmr = FIELD_GET(ICH_VMCR_EL2_VPMR, vmcr);
|
||||
vmcrp->grpen0 = FIELD_GET(ICH_VMCR_EL2_VENG0, vmcr);
|
||||
vmcrp->grpen1 = FIELD_GET(ICH_VMCR_EL2_VENG1, vmcr);
|
||||
}
|
||||
|
||||
#define INITIAL_PENDBASER_VALUE \
|
||||
|
|
|
|||
|
|
@ -4637,7 +4637,7 @@ Field 7 ICC_IAFFIDR_EL1
|
|||
Field 6 ICC_ICSR_EL1
|
||||
Field 5 ICC_PCR_EL1
|
||||
Field 4 ICC_HPPIR_EL1
|
||||
Field 3 ICC_HAPR_EL1
|
||||
Res1 3
|
||||
Field 2 ICC_CR0_EL1
|
||||
Field 1 ICC_IDRn_EL1
|
||||
Field 0 ICC_APR_EL1
|
||||
|
|
|
|||
|
|
@ -743,6 +743,8 @@ static int __init gicv5_irs_init(struct device_node *node)
|
|||
* be consistent across IRSes by the architecture.
|
||||
*/
|
||||
if (list_empty(&irs_nodes)) {
|
||||
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR0);
|
||||
gicv5_global_data.virt_capable = !FIELD_GET(GICV5_IRS_IDR0_VIRT, idr);
|
||||
|
||||
idr = irs_readl_relaxed(irs_data, GICV5_IRS_IDR1);
|
||||
irs_setup_pri_bits(idr);
|
||||
|
|
|
|||
|
|
@ -1064,6 +1064,16 @@ static struct gic_kvm_info gic_v5_kvm_info __initdata;
|
|||
|
||||
static void __init gic_of_setup_kvm_info(struct device_node *node)
|
||||
{
|
||||
/*
|
||||
* If we don't have native GICv5 virtualisation support, then
|
||||
* we also don't have FEAT_GCIE_LEGACY - the architecture
|
||||
* forbids this combination.
|
||||
*/
|
||||
if (!gicv5_global_data.virt_capable) {
|
||||
pr_info("GIC implementation is not virtualization capable\n");
|
||||
return;
|
||||
}
|
||||
|
||||
gic_v5_kvm_info.type = GIC_V5;
|
||||
|
||||
/* GIC Virtual CPU interface maintenance interrupt */
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@
|
|||
/*
|
||||
* IRS registers and tables structures
|
||||
*/
|
||||
#define GICV5_IRS_IDR0 0x0000
|
||||
#define GICV5_IRS_IDR1 0x0004
|
||||
#define GICV5_IRS_IDR2 0x0008
|
||||
#define GICV5_IRS_IDR5 0x0014
|
||||
|
|
@ -63,6 +64,8 @@
|
|||
#define GICV5_IRS_IST_STATUSR 0x0194
|
||||
#define GICV5_IRS_MAP_L2_ISTR 0x01c0
|
||||
|
||||
#define GICV5_IRS_IDR0_VIRT BIT(6)
|
||||
|
||||
#define GICV5_IRS_IDR1_PRIORITY_BITS GENMASK(22, 20)
|
||||
#define GICV5_IRS_IDR1_IAFFID_BITS GENMASK(19, 16)
|
||||
|
||||
|
|
@ -278,6 +281,7 @@ struct gicv5_chip_data {
|
|||
u8 cpuif_pri_bits;
|
||||
u8 cpuif_id_bits;
|
||||
u8 irs_pri_bits;
|
||||
bool virt_capable;
|
||||
struct {
|
||||
__le64 *l1ist_addr;
|
||||
u32 l2_size;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user