Commit 56e3e5c8 authored by Oliver Upton's avatar Oliver Upton
Browse files

Merge branch 'kvm-arm64/nv-vgic' into kvmarm/next



* kvm-arm64/nv-vgic:
  : NV VGICv3 support, courtesy of Marc Zyngier
  :
  : Support for emulating the GIC hypervisor controls and managing shadow
  : VGICv3 state for the L1 hypervisor. As part of it, bring in support for
  : taking IRQs to the L1 and UAPI to manage the VGIC maintenance interrupt.
  KVM: arm64: nv: Fail KVM init if asking for NV without GICv3
  KVM: arm64: nv: Allow userland to set VGIC maintenance IRQ
  KVM: arm64: nv: Fold GICv3 host trapping requirements into guest setup
  KVM: arm64: nv: Propagate used_lrs between L1 and L0 contexts
  KVM: arm64: nv: Request vPE doorbell upon nested ERET to L2
  KVM: arm64: nv: Respect virtual HCR_EL2.TWx setting
  KVM: arm64: nv: Add Maintenance Interrupt emulation
  KVM: arm64: nv: Handle L2->L1 transition on interrupt injection
  KVM: arm64: nv: Nested GICv3 emulation
  KVM: arm64: nv: Sanitise ICH_HCR_EL2 accesses
  KVM: arm64: nv: Plumb handling of GICv3 EL2 accesses
  KVM: arm64: nv: Add ICH_*_EL2 registers to vpcu_sysreg
  KVM: arm64: nv: Load timer before the GIC
  arm64: sysreg: Add layout for ICH_MISR_EL2
  arm64: sysreg: Add layout for ICH_VTR_EL2
  arm64: sysreg: Add layout for ICH_HCR_EL2

Signed-off-by: default avatarOliver Upton <oliver.upton@linux.dev>
parents 3ed0dc03 83c6cb20
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -291,8 +291,18 @@ Groups:
      |    Aff3    |    Aff2    |    Aff1    |    Aff0    |

  Errors:

    =======  =============================================
    -EINVAL  vINTID is not multiple of 32 or info field is
	     not VGIC_LEVEL_INFO_LINE_LEVEL
    =======  =============================================

  KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ
   Attributes:

    The attr field of kvm_device_attr encodes the following values:

      bits:     | 31   ....    5 | 4  ....  0 |
      values:   |      RES0      |   vINTID   |

    The vINTID specifies which interrupt is generated when the vGIC
    must generate a maintenance interrupt. This must be a PPI.
+13 −0
Original line number Diff line number Diff line
@@ -275,6 +275,19 @@ static __always_inline u64 kvm_vcpu_get_esr(const struct kvm_vcpu *vcpu)
	return vcpu->arch.fault.esr_el2;
}

static inline bool guest_hyp_wfx_traps_enabled(const struct kvm_vcpu *vcpu)
{
	u64 esr = kvm_vcpu_get_esr(vcpu);
	bool is_wfe = !!(esr & ESR_ELx_WFx_ISS_WFE);
	u64 hcr_el2 = __vcpu_sys_reg(vcpu, HCR_EL2);

	if (!vcpu_has_nv(vcpu) || vcpu_is_el2(vcpu))
		return false;

	return ((is_wfe && (hcr_el2 & HCR_TWE)) ||
		(!is_wfe && (hcr_el2 & HCR_TWI)));
}

static __always_inline int kvm_vcpu_get_condition(const struct kvm_vcpu *vcpu)
{
	u64 esr = kvm_vcpu_get_esr(vcpu);
+37 −8
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@
#define KVM_REQ_SUSPEND			KVM_ARCH_REQ(6)
#define KVM_REQ_RESYNC_PMU_EL0		KVM_ARCH_REQ(7)
#define KVM_REQ_NESTED_S2_UNMAP		KVM_ARCH_REQ(8)
#define KVM_REQ_GUEST_HYP_IRQ_PENDING	KVM_ARCH_REQ(9)

#define KVM_DIRTY_LOG_MANUAL_CAPS   (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \
				     KVM_DIRTY_LOG_INITIALLY_SET)
@@ -557,7 +558,33 @@ enum vcpu_sysreg {
	VNCR(CNTP_CVAL_EL0),
	VNCR(CNTP_CTL_EL0),

	VNCR(ICH_LR0_EL2),
	VNCR(ICH_LR1_EL2),
	VNCR(ICH_LR2_EL2),
	VNCR(ICH_LR3_EL2),
	VNCR(ICH_LR4_EL2),
	VNCR(ICH_LR5_EL2),
	VNCR(ICH_LR6_EL2),
	VNCR(ICH_LR7_EL2),
	VNCR(ICH_LR8_EL2),
	VNCR(ICH_LR9_EL2),
	VNCR(ICH_LR10_EL2),
	VNCR(ICH_LR11_EL2),
	VNCR(ICH_LR12_EL2),
	VNCR(ICH_LR13_EL2),
	VNCR(ICH_LR14_EL2),
	VNCR(ICH_LR15_EL2),

	VNCR(ICH_AP0R0_EL2),
	VNCR(ICH_AP0R1_EL2),
	VNCR(ICH_AP0R2_EL2),
	VNCR(ICH_AP0R3_EL2),
	VNCR(ICH_AP1R0_EL2),
	VNCR(ICH_AP1R1_EL2),
	VNCR(ICH_AP1R2_EL2),
	VNCR(ICH_AP1R3_EL2),
	VNCR(ICH_HCR_EL2),
	VNCR(ICH_VMCR_EL2),

	NR_SYS_REGS	/* Nothing after this line! */
};
@@ -919,6 +946,8 @@ struct kvm_vcpu_arch {
#define PMUSERENR_ON_CPU	__vcpu_single_flag(sflags, BIT(5))
/* WFI instruction trapped */
#define IN_WFI			__vcpu_single_flag(sflags, BIT(6))
/* KVM is currently emulating a nested ERET */
#define IN_NESTED_ERET		__vcpu_single_flag(sflags, BIT(7))


/* Pointer to the vcpu's SVE FFR for sve_{save,load}_state() */
+2 −0
Original line number Diff line number Diff line
@@ -76,6 +76,8 @@ DECLARE_PER_CPU(struct kvm_nvhe_init_params, kvm_init_params);

int __vgic_v2_perform_cpuif_access(struct kvm_vcpu *vcpu);

u64 __gic_v3_get_lr(unsigned int lr);

void __vgic_v3_save_state(struct vgic_v3_cpu_if *cpu_if);
void __vgic_v3_restore_state(struct vgic_v3_cpu_if *cpu_if);
void __vgic_v3_activate_traps(struct vgic_v3_cpu_if *cpu_if);
+0 −30
Original line number Diff line number Diff line
@@ -562,9 +562,6 @@

#define SYS_ICH_VSEIR_EL2		sys_reg(3, 4, 12, 9, 4)
#define SYS_ICC_SRE_EL2			sys_reg(3, 4, 12, 9, 5)
#define SYS_ICH_HCR_EL2			sys_reg(3, 4, 12, 11, 0)
#define SYS_ICH_VTR_EL2			sys_reg(3, 4, 12, 11, 1)
#define SYS_ICH_MISR_EL2		sys_reg(3, 4, 12, 11, 2)
#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)
@@ -985,10 +982,6 @@
#define SYS_MPIDR_SAFE_VAL	(BIT(31))

/* GIC Hypervisor interface registers */
/* ICH_MISR_EL2 bit definitions */
#define ICH_MISR_EOI		(1 << 0)
#define ICH_MISR_U		(1 << 1)

/* ICH_LR*_EL2 bit definitions */
#define ICH_LR_VIRTUAL_ID_MASK	((1ULL << 32) - 1)

@@ -1003,17 +996,6 @@
#define ICH_LR_PRIORITY_SHIFT	48
#define ICH_LR_PRIORITY_MASK	(0xffULL << ICH_LR_PRIORITY_SHIFT)

/* ICH_HCR_EL2 bit definitions */
#define ICH_HCR_EN		(1 << 0)
#define ICH_HCR_UIE		(1 << 1)
#define ICH_HCR_NPIE		(1 << 3)
#define ICH_HCR_TC		(1 << 10)
#define ICH_HCR_TALL0		(1 << 11)
#define ICH_HCR_TALL1		(1 << 12)
#define ICH_HCR_TDIR		(1 << 14)
#define ICH_HCR_EOIcount_SHIFT	27
#define ICH_HCR_EOIcount_MASK	(0x1f << ICH_HCR_EOIcount_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)
@@ -1034,18 +1016,6 @@
#define ICH_VMCR_ENG1_SHIFT	1
#define ICH_VMCR_ENG1_MASK	(1 << ICH_VMCR_ENG1_SHIFT)

/* ICH_VTR_EL2 bit definitions */
#define ICH_VTR_PRI_BITS_SHIFT	29
#define ICH_VTR_PRI_BITS_MASK	(7 << ICH_VTR_PRI_BITS_SHIFT)
#define ICH_VTR_ID_BITS_SHIFT	23
#define ICH_VTR_ID_BITS_MASK	(7 << ICH_VTR_ID_BITS_SHIFT)
#define ICH_VTR_SEIS_SHIFT	22
#define ICH_VTR_SEIS_MASK	(1 << ICH_VTR_SEIS_SHIFT)
#define ICH_VTR_A3V_SHIFT	21
#define ICH_VTR_A3V_MASK	(1 << ICH_VTR_A3V_SHIFT)
#define ICH_VTR_TDS_SHIFT	19
#define ICH_VTR_TDS_MASK	(1 << ICH_VTR_TDS_SHIFT)

/*
 * Permission Indirection Extension (PIE) permission encodings.
 * Encodings with the _O suffix, have overlays applied (Permission Overlay Extension).
Loading