Commit 3eef0c83 authored by Oliver Upton's avatar Oliver Upton
Browse files

Merge branch 'kvm-arm64/nv-xnx-haf' into kvmarm/next



* kvm-arm64/nv-xnx-haf: (22 commits)
  : Support for FEAT_XNX and FEAT_HAF in nested
  :
  : Add support for a couple of MMU-related features that weren't
  : implemented by KVM's software page table walk:
  :
  :  - FEAT_XNX: Allows the hypervisor to describe execute permissions
  :    separately for EL0 and EL1
  :
  :  - FEAT_HAF: Hardware update of the Access Flag, which in the context of
  :    nested means software walkers must also set the Access Flag.
  :
  : The series also adds some basic support for testing KVM's emulation of
  : the AT instruction, including the implementation detail that AT sets the
  : Access Flag in KVM.
  KVM: arm64: at: Update AF on software walk only if VM has FEAT_HAFDBS
  KVM: arm64: at: Use correct HA bit in TCR_EL2 when regime is EL2
  KVM: arm64: Document KVM_PGTABLE_PROT_{UX,PX}
  KVM: arm64: Fix spelling mistake "Unexpeced" -> "Unexpected"
  KVM: arm64: Add break to default case in kvm_pgtable_stage2_pte_prot()
  KVM: arm64: Add endian casting to kvm_swap_s[12]_desc()
  KVM: arm64: Fix compilation when CONFIG_ARM64_USE_LSE_ATOMICS=n
  KVM: arm64: selftests: Add test for AT emulation
  KVM: arm64: nv: Expose hardware access flag management to NV guests
  KVM: arm64: nv: Implement HW access flag management in stage-2 SW PTW
  KVM: arm64: Implement HW access flag management in stage-1 SW PTW
  KVM: arm64: Propagate PTW errors up to AT emulation
  KVM: arm64: Add helper for swapping guest descriptor
  KVM: arm64: nv: Use pgtable definitions in stage-2 walk
  KVM: arm64: Handle endianness in read helper for emulated PTW
  KVM: arm64: nv: Stop passing vCPU through void ptr in S2 PTW
  KVM: arm64: Call helper for reading descriptors directly
  KVM: arm64: nv: Advertise support for FEAT_XNX
  KVM: arm64: Teach ptdump about FEAT_XNX permissions
  KVM: arm64: nv: Forward FEAT_XNX permissions to the shadow stage-2
  ...

Signed-off-by: default avatarOliver Upton <oupton@kernel.org>
parents 938309b0 d52aca16
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -111,6 +111,7 @@
#define TCR_EL2_DS		(1UL << 32)
#define TCR_EL2_RES1		((1U << 31) | (1 << 23))
#define TCR_EL2_HPD		(1 << 24)
#define TCR_EL2_HA		(1 << 21)
#define TCR_EL2_TBI		(1 << 20)
#define TCR_EL2_PS_SHIFT	16
#define TCR_EL2_PS_MASK		(7 << TCR_EL2_PS_SHIFT)
+3 −3
Original line number Diff line number Diff line
@@ -246,9 +246,9 @@ extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
extern int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding);

extern void __kvm_timer_set_cntvoff(u64 cntvoff);
extern void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
extern void __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
extern void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
extern int __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
extern int __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
extern int __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);

extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);

+38 −2
Original line number Diff line number Diff line
@@ -120,9 +120,42 @@ static inline bool kvm_s2_trans_writable(struct kvm_s2_trans *trans)
	return trans->writable;
}

static inline bool kvm_s2_trans_executable(struct kvm_s2_trans *trans)
static inline bool kvm_has_xnx(struct kvm *kvm)
{
	return !(trans->desc & BIT(54));
	return cpus_have_final_cap(ARM64_HAS_XNX) &&
		kvm_has_feat(kvm, ID_AA64MMFR1_EL1, XNX, IMP);
}

static inline bool kvm_s2_trans_exec_el0(struct kvm *kvm, struct kvm_s2_trans *trans)
{
	u8 xn = FIELD_GET(KVM_PTE_LEAF_ATTR_HI_S2_XN, trans->desc);

	if (!kvm_has_xnx(kvm))
		xn &= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_S2_XN, 0b10);

	switch (xn) {
	case 0b00:
	case 0b01:
		return true;
	default:
		return false;
	}
}

static inline bool kvm_s2_trans_exec_el1(struct kvm *kvm, struct kvm_s2_trans *trans)
{
	u8 xn = FIELD_GET(KVM_PTE_LEAF_ATTR_HI_S2_XN, trans->desc);

	if (!kvm_has_xnx(kvm))
		xn &= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_S2_XN, 0b10);

	switch (xn) {
	case 0b00:
	case 0b11:
		return true;
	default:
		return false;
	}
}

extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
@@ -320,6 +353,7 @@ struct s1_walk_info {
	bool	     		be;
	bool	     		s2;
	bool			pa52bit;
	bool			ha;
};

struct s1_walk_result {
@@ -370,4 +404,6 @@ void kvm_handle_s1e2_tlbi(struct kvm_vcpu *vcpu, u32 inst, u64 val);
		(FIX_VNCR - __c);				\
	})

int __kvm_at_swap_desc(struct kvm *kvm, gpa_t ipa, u64 old, u64 new);

#endif /* __ARM64_KVM_NESTED_H */
+13 −8
Original line number Diff line number Diff line
@@ -89,7 +89,7 @@ typedef u64 kvm_pte_t;

#define KVM_PTE_LEAF_ATTR_HI_S1_XN	BIT(54)

#define KVM_PTE_LEAF_ATTR_HI_S2_XN	BIT(54)
#define KVM_PTE_LEAF_ATTR_HI_S2_XN	GENMASK(54, 53)

#define KVM_PTE_LEAF_ATTR_HI_S1_GP	BIT(50)

@@ -240,7 +240,9 @@ enum kvm_pgtable_stage2_flags {

/**
 * enum kvm_pgtable_prot - Page-table permissions and attributes.
 * @KVM_PGTABLE_PROT_X:		Execute permission.
 * @KVM_PGTABLE_PROT_UX:	Unprivileged execute permission.
 * @KVM_PGTABLE_PROT_PX:	Privileged execute permission.
 * @KVM_PGTABLE_PROT_X:		Privileged and unprivileged execute permission.
 * @KVM_PGTABLE_PROT_W:		Write permission.
 * @KVM_PGTABLE_PROT_R:		Read permission.
 * @KVM_PGTABLE_PROT_DEVICE:	Device attributes.
@@ -251,12 +253,15 @@ enum kvm_pgtable_stage2_flags {
 * @KVM_PGTABLE_PROT_SW3:	Software bit 3.
 */
enum kvm_pgtable_prot {
	KVM_PGTABLE_PROT_X			= BIT(0),
	KVM_PGTABLE_PROT_W			= BIT(1),
	KVM_PGTABLE_PROT_R			= BIT(2),

	KVM_PGTABLE_PROT_DEVICE			= BIT(3),
	KVM_PGTABLE_PROT_NORMAL_NC		= BIT(4),
	KVM_PGTABLE_PROT_PX			= BIT(0),
	KVM_PGTABLE_PROT_UX			= BIT(1),
	KVM_PGTABLE_PROT_X			= KVM_PGTABLE_PROT_PX	|
						  KVM_PGTABLE_PROT_UX,
	KVM_PGTABLE_PROT_W			= BIT(2),
	KVM_PGTABLE_PROT_R			= BIT(3),

	KVM_PGTABLE_PROT_DEVICE			= BIT(4),
	KVM_PGTABLE_PROT_NORMAL_NC		= BIT(5),

	KVM_PGTABLE_PROT_SW0			= BIT(55),
	KVM_PGTABLE_PROT_SW1			= BIT(56),
+7 −0
Original line number Diff line number Diff line
@@ -3140,6 +3140,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
		.capability = ARM64_HAS_GICV5_LEGACY,
		.matches = test_has_gicv5_legacy,
	},
	{
		.desc = "XNX",
		.capability = ARM64_HAS_XNX,
		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
		.matches = has_cpuid_feature,
		ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, XNX, IMP)
	},
	{},
};

Loading