mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-12 16:58:53 +00:00
KVM/ARM Fixes for v4.12-rc5 - Take 2
Changes include: - Fix an issue with migrating GICv2 VMs on GICv3 systems. - Squashed a bug for gicv3 when figuring out preemption levels. - Fix a potential null pointer derefence in KVM happening under memory pressure. - Maintain RES1 bits in the SCTLR_EL2 to make sure KVM works on new architecture revisions. - Allow unaligned accesses at EL2/HYP -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJZODC6AAoJEEtpOizt6ddy7qsH/RakZzHHlPcIFk+VPhK4AvIV ke6y1IznIVVv024geILb2NyF2pZoSUROxk1NF0wBIWM4ryjPm7oYgK7TTLyxkiX0 00gNxWpRRerCSxfh11a28tQywc7ATlw0yFpogGvbbHG9qEMX1NaGP/CNFK5us0LT dw3y7jIZounlHlHu0W85AE27Osn5anFPHQnEtvJlUsM7WkIQf765EIfttXGUKRDZ szmwuFAhdsSeIfo23LNXj87WAn6uP/37qRUmNXnxSya4u5urXa4qlOM5Hvg6agw2 K6LdpDXF/FnHhiT+b/xMTRPPivy4rXJZTpP51shl5GqKE2gI0tbhsHwJJ5Di/Aw= =3xSf -----END PGP SIGNATURE----- Merge tag 'kvm-arm-for-v4.12-rc5-take2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD KVM/ARM Fixes for v4.12-rc5 - Take 2 Changes include: - Fix an issue with migrating GICv2 VMs on GICv3 systems. - Squashed a bug for gicv3 when figuring out preemption levels. - Fix a potential null pointer derefence in KVM happening under memory pressure. - Maintain RES1 bits in the SCTLR_EL2 to make sure KVM works on new architecture revisions. - Allow unaligned accesses at EL2/HYP
This commit is contained in:
commit
38a4f43d56
@ -104,7 +104,6 @@ __do_hyp_init:
|
|||||||
@ - Write permission implies XN: disabled
|
@ - Write permission implies XN: disabled
|
||||||
@ - Instruction cache: enabled
|
@ - Instruction cache: enabled
|
||||||
@ - Data/Unified cache: enabled
|
@ - Data/Unified cache: enabled
|
||||||
@ - Memory alignment checks: enabled
|
|
||||||
@ - MMU: enabled (this code must be run from an identity mapping)
|
@ - MMU: enabled (this code must be run from an identity mapping)
|
||||||
mrc p15, 4, r0, c1, c0, 0 @ HSCR
|
mrc p15, 4, r0, c1, c0, 0 @ HSCR
|
||||||
ldr r2, =HSCTLR_MASK
|
ldr r2, =HSCTLR_MASK
|
||||||
@ -112,8 +111,8 @@ __do_hyp_init:
|
|||||||
mrc p15, 0, r1, c1, c0, 0 @ SCTLR
|
mrc p15, 0, r1, c1, c0, 0 @ SCTLR
|
||||||
ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C)
|
ldr r2, =(HSCTLR_EE | HSCTLR_FI | HSCTLR_I | HSCTLR_C)
|
||||||
and r1, r1, r2
|
and r1, r1, r2
|
||||||
ARM( ldr r2, =(HSCTLR_M | HSCTLR_A) )
|
ARM( ldr r2, =(HSCTLR_M) )
|
||||||
THUMB( ldr r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_TE) )
|
THUMB( ldr r2, =(HSCTLR_M | HSCTLR_TE) )
|
||||||
orr r1, r1, r2
|
orr r1, r1, r2
|
||||||
orr r0, r0, r1
|
orr r0, r0, r1
|
||||||
mcr p15, 4, r0, c1, c0, 0 @ HSCR
|
mcr p15, 4, r0, c1, c0, 0 @ HSCR
|
||||||
|
@ -286,6 +286,10 @@
|
|||||||
#define SCTLR_ELx_A (1 << 1)
|
#define SCTLR_ELx_A (1 << 1)
|
||||||
#define SCTLR_ELx_M 1
|
#define SCTLR_ELx_M 1
|
||||||
|
|
||||||
|
#define SCTLR_EL2_RES1 ((1 << 4) | (1 << 5) | (1 << 11) | (1 << 16) | \
|
||||||
|
(1 << 16) | (1 << 18) | (1 << 22) | (1 << 23) | \
|
||||||
|
(1 << 28) | (1 << 29))
|
||||||
|
|
||||||
#define SCTLR_ELx_FLAGS (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
|
#define SCTLR_ELx_FLAGS (SCTLR_ELx_M | SCTLR_ELx_A | SCTLR_ELx_C | \
|
||||||
SCTLR_ELx_SA | SCTLR_ELx_I)
|
SCTLR_ELx_SA | SCTLR_ELx_I)
|
||||||
|
|
||||||
|
@ -106,10 +106,13 @@ __do_hyp_init:
|
|||||||
tlbi alle2
|
tlbi alle2
|
||||||
dsb sy
|
dsb sy
|
||||||
|
|
||||||
mrs x4, sctlr_el2
|
/*
|
||||||
and x4, x4, #SCTLR_ELx_EE // preserve endianness of EL2
|
* Preserve all the RES1 bits while setting the default flags,
|
||||||
ldr x5, =SCTLR_ELx_FLAGS
|
* as well as the EE bit on BE. Drop the A flag since the compiler
|
||||||
orr x4, x4, x5
|
* is allowed to generate unaligned accesses.
|
||||||
|
*/
|
||||||
|
ldr x4, =(SCTLR_EL2_RES1 | (SCTLR_ELx_FLAGS & ~SCTLR_ELx_A))
|
||||||
|
CPU_BE( orr x4, x4, #SCTLR_ELx_EE)
|
||||||
msr sctlr_el2, x4
|
msr sctlr_el2, x4
|
||||||
isb
|
isb
|
||||||
|
|
||||||
|
@ -65,8 +65,8 @@ static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
|
|||||||
* Here set VMCR.CTLR in ICC_CTLR_EL1 layout.
|
* Here set VMCR.CTLR in ICC_CTLR_EL1 layout.
|
||||||
* The vgic_set_vmcr() will convert to ICH_VMCR layout.
|
* The vgic_set_vmcr() will convert to ICH_VMCR layout.
|
||||||
*/
|
*/
|
||||||
vmcr.ctlr = val & ICC_CTLR_EL1_CBPR_MASK;
|
vmcr.cbpr = (val & ICC_CTLR_EL1_CBPR_MASK) >> ICC_CTLR_EL1_CBPR_SHIFT;
|
||||||
vmcr.ctlr |= val & ICC_CTLR_EL1_EOImode_MASK;
|
vmcr.eoim = (val & ICC_CTLR_EL1_EOImode_MASK) >> ICC_CTLR_EL1_EOImode_SHIFT;
|
||||||
vgic_set_vmcr(vcpu, &vmcr);
|
vgic_set_vmcr(vcpu, &vmcr);
|
||||||
} else {
|
} else {
|
||||||
val = 0;
|
val = 0;
|
||||||
@ -83,8 +83,8 @@ static bool access_gic_ctlr(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
|
|||||||
* The VMCR.CTLR value is in ICC_CTLR_EL1 layout.
|
* The VMCR.CTLR value is in ICC_CTLR_EL1 layout.
|
||||||
* Extract it directly using ICC_CTLR_EL1 reg definitions.
|
* Extract it directly using ICC_CTLR_EL1 reg definitions.
|
||||||
*/
|
*/
|
||||||
val |= vmcr.ctlr & ICC_CTLR_EL1_CBPR_MASK;
|
val |= (vmcr.cbpr << ICC_CTLR_EL1_CBPR_SHIFT) & ICC_CTLR_EL1_CBPR_MASK;
|
||||||
val |= vmcr.ctlr & ICC_CTLR_EL1_EOImode_MASK;
|
val |= (vmcr.eoim << ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK;
|
||||||
|
|
||||||
p->regval = val;
|
p->regval = val;
|
||||||
}
|
}
|
||||||
@ -135,7 +135,7 @@ static bool access_gic_bpr1(struct kvm_vcpu *vcpu, struct sys_reg_params *p,
|
|||||||
p->regval = 0;
|
p->regval = 0;
|
||||||
|
|
||||||
vgic_get_vmcr(vcpu, &vmcr);
|
vgic_get_vmcr(vcpu, &vmcr);
|
||||||
if (!((vmcr.ctlr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT)) {
|
if (!vmcr.cbpr) {
|
||||||
if (p->is_write) {
|
if (p->is_write) {
|
||||||
vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >>
|
vmcr.abpr = (p->regval & ICC_BPR1_EL1_MASK) >>
|
||||||
ICC_BPR1_EL1_SHIFT;
|
ICC_BPR1_EL1_SHIFT;
|
||||||
|
@ -417,6 +417,10 @@
|
|||||||
#define ICH_HCR_EN (1 << 0)
|
#define ICH_HCR_EN (1 << 0)
|
||||||
#define ICH_HCR_UIE (1 << 1)
|
#define ICH_HCR_UIE (1 << 1)
|
||||||
|
|
||||||
|
#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_SHIFT 4
|
||||||
#define ICH_VMCR_CBPR_MASK (1 << ICH_VMCR_CBPR_SHIFT)
|
#define ICH_VMCR_CBPR_MASK (1 << ICH_VMCR_CBPR_SHIFT)
|
||||||
#define ICH_VMCR_EOIM_SHIFT 9
|
#define ICH_VMCR_EOIM_SHIFT 9
|
||||||
|
@ -25,7 +25,18 @@
|
|||||||
#define GICC_ENABLE 0x1
|
#define GICC_ENABLE 0x1
|
||||||
#define GICC_INT_PRI_THRESHOLD 0xf0
|
#define GICC_INT_PRI_THRESHOLD 0xf0
|
||||||
|
|
||||||
#define GIC_CPU_CTRL_EOImodeNS (1 << 9)
|
#define GIC_CPU_CTRL_EnableGrp0_SHIFT 0
|
||||||
|
#define GIC_CPU_CTRL_EnableGrp0 (1 << GIC_CPU_CTRL_EnableGrp0_SHIFT)
|
||||||
|
#define GIC_CPU_CTRL_EnableGrp1_SHIFT 1
|
||||||
|
#define GIC_CPU_CTRL_EnableGrp1 (1 << GIC_CPU_CTRL_EnableGrp1_SHIFT)
|
||||||
|
#define GIC_CPU_CTRL_AckCtl_SHIFT 2
|
||||||
|
#define GIC_CPU_CTRL_AckCtl (1 << GIC_CPU_CTRL_AckCtl_SHIFT)
|
||||||
|
#define GIC_CPU_CTRL_FIQEn_SHIFT 3
|
||||||
|
#define GIC_CPU_CTRL_FIQEn (1 << GIC_CPU_CTRL_FIQEn_SHIFT)
|
||||||
|
#define GIC_CPU_CTRL_CBPR_SHIFT 4
|
||||||
|
#define GIC_CPU_CTRL_CBPR (1 << GIC_CPU_CTRL_CBPR_SHIFT)
|
||||||
|
#define GIC_CPU_CTRL_EOImodeNS_SHIFT 9
|
||||||
|
#define GIC_CPU_CTRL_EOImodeNS (1 << GIC_CPU_CTRL_EOImodeNS_SHIFT)
|
||||||
|
|
||||||
#define GICC_IAR_INT_ID_MASK 0x3ff
|
#define GICC_IAR_INT_ID_MASK 0x3ff
|
||||||
#define GICC_INT_SPURIOUS 1023
|
#define GICC_INT_SPURIOUS 1023
|
||||||
@ -84,8 +95,19 @@
|
|||||||
#define GICH_LR_EOI (1 << 19)
|
#define GICH_LR_EOI (1 << 19)
|
||||||
#define GICH_LR_HW (1 << 31)
|
#define GICH_LR_HW (1 << 31)
|
||||||
|
|
||||||
#define GICH_VMCR_CTRL_SHIFT 0
|
#define GICH_VMCR_ENABLE_GRP0_SHIFT 0
|
||||||
#define GICH_VMCR_CTRL_MASK (0x21f << GICH_VMCR_CTRL_SHIFT)
|
#define GICH_VMCR_ENABLE_GRP0_MASK (1 << GICH_VMCR_ENABLE_GRP0_SHIFT)
|
||||||
|
#define GICH_VMCR_ENABLE_GRP1_SHIFT 1
|
||||||
|
#define GICH_VMCR_ENABLE_GRP1_MASK (1 << GICH_VMCR_ENABLE_GRP1_SHIFT)
|
||||||
|
#define GICH_VMCR_ACK_CTL_SHIFT 2
|
||||||
|
#define GICH_VMCR_ACK_CTL_MASK (1 << GICH_VMCR_ACK_CTL_SHIFT)
|
||||||
|
#define GICH_VMCR_FIQ_EN_SHIFT 3
|
||||||
|
#define GICH_VMCR_FIQ_EN_MASK (1 << GICH_VMCR_FIQ_EN_SHIFT)
|
||||||
|
#define GICH_VMCR_CBPR_SHIFT 4
|
||||||
|
#define GICH_VMCR_CBPR_MASK (1 << GICH_VMCR_CBPR_SHIFT)
|
||||||
|
#define GICH_VMCR_EOI_MODE_SHIFT 9
|
||||||
|
#define GICH_VMCR_EOI_MODE_MASK (1 << GICH_VMCR_EOI_MODE_SHIFT)
|
||||||
|
|
||||||
#define GICH_VMCR_PRIMASK_SHIFT 27
|
#define GICH_VMCR_PRIMASK_SHIFT 27
|
||||||
#define GICH_VMCR_PRIMASK_MASK (0x1f << GICH_VMCR_PRIMASK_SHIFT)
|
#define GICH_VMCR_PRIMASK_MASK (0x1f << GICH_VMCR_PRIMASK_SHIFT)
|
||||||
#define GICH_VMCR_BINPOINT_SHIFT 21
|
#define GICH_VMCR_BINPOINT_SHIFT 21
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
#include <asm/kvm_hyp.h>
|
#include <asm/kvm_hyp.h>
|
||||||
|
|
||||||
#define vtr_to_max_lr_idx(v) ((v) & 0xf)
|
#define vtr_to_max_lr_idx(v) ((v) & 0xf)
|
||||||
#define vtr_to_nr_pre_bits(v) (((u32)(v) >> 26) + 1)
|
#define vtr_to_nr_pre_bits(v) ((((u32)(v) >> 26) & 7) + 1)
|
||||||
|
|
||||||
static u64 __hyp_text __gic_v3_get_lr(unsigned int lr)
|
static u64 __hyp_text __gic_v3_get_lr(unsigned int lr)
|
||||||
{
|
{
|
||||||
|
@ -879,6 +879,9 @@ static pmd_t *stage2_get_pmd(struct kvm *kvm, struct kvm_mmu_memory_cache *cache
|
|||||||
pmd_t *pmd;
|
pmd_t *pmd;
|
||||||
|
|
||||||
pud = stage2_get_pud(kvm, cache, addr);
|
pud = stage2_get_pud(kvm, cache, addr);
|
||||||
|
if (!pud)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
if (stage2_pud_none(*pud)) {
|
if (stage2_pud_none(*pud)) {
|
||||||
if (!cache)
|
if (!cache)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -226,7 +226,13 @@ static unsigned long vgic_mmio_read_vcpuif(struct kvm_vcpu *vcpu,
|
|||||||
|
|
||||||
switch (addr & 0xff) {
|
switch (addr & 0xff) {
|
||||||
case GIC_CPU_CTRL:
|
case GIC_CPU_CTRL:
|
||||||
val = vmcr.ctlr;
|
val = vmcr.grpen0 << GIC_CPU_CTRL_EnableGrp0_SHIFT;
|
||||||
|
val |= vmcr.grpen1 << GIC_CPU_CTRL_EnableGrp1_SHIFT;
|
||||||
|
val |= vmcr.ackctl << GIC_CPU_CTRL_AckCtl_SHIFT;
|
||||||
|
val |= vmcr.fiqen << GIC_CPU_CTRL_FIQEn_SHIFT;
|
||||||
|
val |= vmcr.cbpr << GIC_CPU_CTRL_CBPR_SHIFT;
|
||||||
|
val |= vmcr.eoim << GIC_CPU_CTRL_EOImodeNS_SHIFT;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case GIC_CPU_PRIMASK:
|
case GIC_CPU_PRIMASK:
|
||||||
/*
|
/*
|
||||||
@ -267,7 +273,13 @@ static void vgic_mmio_write_vcpuif(struct kvm_vcpu *vcpu,
|
|||||||
|
|
||||||
switch (addr & 0xff) {
|
switch (addr & 0xff) {
|
||||||
case GIC_CPU_CTRL:
|
case GIC_CPU_CTRL:
|
||||||
vmcr.ctlr = val;
|
vmcr.grpen0 = !!(val & GIC_CPU_CTRL_EnableGrp0);
|
||||||
|
vmcr.grpen1 = !!(val & GIC_CPU_CTRL_EnableGrp1);
|
||||||
|
vmcr.ackctl = !!(val & GIC_CPU_CTRL_AckCtl);
|
||||||
|
vmcr.fiqen = !!(val & GIC_CPU_CTRL_FIQEn);
|
||||||
|
vmcr.cbpr = !!(val & GIC_CPU_CTRL_CBPR);
|
||||||
|
vmcr.eoim = !!(val & GIC_CPU_CTRL_EOImodeNS);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case GIC_CPU_PRIMASK:
|
case GIC_CPU_PRIMASK:
|
||||||
/*
|
/*
|
||||||
|
@ -177,7 +177,18 @@ void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
|||||||
struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
|
struct vgic_v2_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v2;
|
||||||
u32 vmcr;
|
u32 vmcr;
|
||||||
|
|
||||||
vmcr = (vmcrp->ctlr << GICH_VMCR_CTRL_SHIFT) & GICH_VMCR_CTRL_MASK;
|
vmcr = (vmcrp->grpen0 << GICH_VMCR_ENABLE_GRP0_SHIFT) &
|
||||||
|
GICH_VMCR_ENABLE_GRP0_MASK;
|
||||||
|
vmcr |= (vmcrp->grpen1 << GICH_VMCR_ENABLE_GRP1_SHIFT) &
|
||||||
|
GICH_VMCR_ENABLE_GRP1_MASK;
|
||||||
|
vmcr |= (vmcrp->ackctl << GICH_VMCR_ACK_CTL_SHIFT) &
|
||||||
|
GICH_VMCR_ACK_CTL_MASK;
|
||||||
|
vmcr |= (vmcrp->fiqen << GICH_VMCR_FIQ_EN_SHIFT) &
|
||||||
|
GICH_VMCR_FIQ_EN_MASK;
|
||||||
|
vmcr |= (vmcrp->cbpr << GICH_VMCR_CBPR_SHIFT) &
|
||||||
|
GICH_VMCR_CBPR_MASK;
|
||||||
|
vmcr |= (vmcrp->eoim << GICH_VMCR_EOI_MODE_SHIFT) &
|
||||||
|
GICH_VMCR_EOI_MODE_MASK;
|
||||||
vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) &
|
vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) &
|
||||||
GICH_VMCR_ALIAS_BINPOINT_MASK;
|
GICH_VMCR_ALIAS_BINPOINT_MASK;
|
||||||
vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) &
|
vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) &
|
||||||
@ -195,8 +206,19 @@ void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
|||||||
|
|
||||||
vmcr = cpu_if->vgic_vmcr;
|
vmcr = cpu_if->vgic_vmcr;
|
||||||
|
|
||||||
vmcrp->ctlr = (vmcr & GICH_VMCR_CTRL_MASK) >>
|
vmcrp->grpen0 = (vmcr & GICH_VMCR_ENABLE_GRP0_MASK) >>
|
||||||
GICH_VMCR_CTRL_SHIFT;
|
GICH_VMCR_ENABLE_GRP0_SHIFT;
|
||||||
|
vmcrp->grpen1 = (vmcr & GICH_VMCR_ENABLE_GRP1_MASK) >>
|
||||||
|
GICH_VMCR_ENABLE_GRP1_SHIFT;
|
||||||
|
vmcrp->ackctl = (vmcr & GICH_VMCR_ACK_CTL_MASK) >>
|
||||||
|
GICH_VMCR_ACK_CTL_SHIFT;
|
||||||
|
vmcrp->fiqen = (vmcr & GICH_VMCR_FIQ_EN_MASK) >>
|
||||||
|
GICH_VMCR_FIQ_EN_SHIFT;
|
||||||
|
vmcrp->cbpr = (vmcr & GICH_VMCR_CBPR_MASK) >>
|
||||||
|
GICH_VMCR_CBPR_SHIFT;
|
||||||
|
vmcrp->eoim = (vmcr & GICH_VMCR_EOI_MODE_MASK) >>
|
||||||
|
GICH_VMCR_EOI_MODE_SHIFT;
|
||||||
|
|
||||||
vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >>
|
vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >>
|
||||||
GICH_VMCR_ALIAS_BINPOINT_SHIFT;
|
GICH_VMCR_ALIAS_BINPOINT_SHIFT;
|
||||||
vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >>
|
vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >>
|
||||||
|
@ -159,15 +159,24 @@ void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr)
|
|||||||
void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
||||||
{
|
{
|
||||||
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
|
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
|
||||||
|
u32 model = vcpu->kvm->arch.vgic.vgic_model;
|
||||||
u32 vmcr;
|
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;
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* Ignore the FIQen bit, because GIC emulation always implies
|
* When emulating GICv3 on GICv3 with SRE=1 on the
|
||||||
* SRE=1 which means the vFIQEn bit is also RES1.
|
* VFIQEn bit is RES1 and the VAckCtl bit is RES0.
|
||||||
*/
|
*/
|
||||||
vmcr = ((vmcrp->ctlr >> ICC_CTLR_EL1_EOImode_SHIFT) <<
|
vmcr = ICH_VMCR_FIQ_EN_MASK;
|
||||||
ICH_VMCR_EOIM_SHIFT) & ICH_VMCR_EOIM_MASK;
|
}
|
||||||
vmcr |= (vmcrp->ctlr << ICH_VMCR_CBPR_SHIFT) & ICH_VMCR_CBPR_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->abpr << ICH_VMCR_BPR1_SHIFT) & ICH_VMCR_BPR1_MASK;
|
||||||
vmcr |= (vmcrp->bpr << ICH_VMCR_BPR0_SHIFT) & ICH_VMCR_BPR0_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->pmr << ICH_VMCR_PMR_SHIFT) & ICH_VMCR_PMR_MASK;
|
||||||
@ -180,17 +189,27 @@ void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
|||||||
void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp)
|
||||||
{
|
{
|
||||||
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
|
struct vgic_v3_cpu_if *cpu_if = &vcpu->arch.vgic_cpu.vgic_v3;
|
||||||
|
u32 model = vcpu->kvm->arch.vgic.vgic_model;
|
||||||
u32 vmcr;
|
u32 vmcr;
|
||||||
|
|
||||||
vmcr = cpu_if->vgic_vmcr;
|
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;
|
||||||
|
} else {
|
||||||
/*
|
/*
|
||||||
* Ignore the FIQen bit, because GIC emulation always implies
|
* When emulating GICv3 on GICv3 with SRE=1 on the
|
||||||
* SRE=1 which means the vFIQEn bit is also RES1.
|
* VFIQEn bit is RES1 and the VAckCtl bit is RES0.
|
||||||
*/
|
*/
|
||||||
vmcrp->ctlr = ((vmcr >> ICH_VMCR_EOIM_SHIFT) <<
|
vmcrp->fiqen = 1;
|
||||||
ICC_CTLR_EL1_EOImode_SHIFT) & ICC_CTLR_EL1_EOImode_MASK;
|
vmcrp->ackctl = 0;
|
||||||
vmcrp->ctlr |= (vmcr & ICH_VMCR_CBPR_MASK) >> ICH_VMCR_CBPR_SHIFT;
|
}
|
||||||
|
|
||||||
|
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->abpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT;
|
||||||
vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT;
|
vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT;
|
||||||
vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT;
|
vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT;
|
||||||
|
@ -111,14 +111,18 @@ static inline bool irq_is_pending(struct vgic_irq *irq)
|
|||||||
* registers regardless of the hardware backed GIC used.
|
* registers regardless of the hardware backed GIC used.
|
||||||
*/
|
*/
|
||||||
struct vgic_vmcr {
|
struct vgic_vmcr {
|
||||||
u32 ctlr;
|
u32 grpen0;
|
||||||
|
u32 grpen1;
|
||||||
|
|
||||||
|
u32 ackctl;
|
||||||
|
u32 fiqen;
|
||||||
|
u32 cbpr;
|
||||||
|
u32 eoim;
|
||||||
|
|
||||||
u32 abpr;
|
u32 abpr;
|
||||||
u32 bpr;
|
u32 bpr;
|
||||||
u32 pmr; /* Priority mask field in the GICC_PMR and
|
u32 pmr; /* Priority mask field in the GICC_PMR and
|
||||||
* ICC_PMR_EL1 priority field format */
|
* ICC_PMR_EL1 priority field format */
|
||||||
/* Below member variable are valid only for GICv3 */
|
|
||||||
u32 grpen0;
|
|
||||||
u32 grpen1;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct vgic_reg_attr {
|
struct vgic_reg_attr {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user