Skip to content

Commit 3eef0c8

Browse files
author
Oliver Upton
committed
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: Oliver Upton <oupton@kernel.org>
2 parents 938309b + d52aca1 commit 3eef0c8

16 files changed

Lines changed: 608 additions & 96 deletions

File tree

arch/arm64/include/asm/kvm_arm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@
111111
#define TCR_EL2_DS (1UL << 32)
112112
#define TCR_EL2_RES1 ((1U << 31) | (1 << 23))
113113
#define TCR_EL2_HPD (1 << 24)
114+
#define TCR_EL2_HA (1 << 21)
114115
#define TCR_EL2_TBI (1 << 20)
115116
#define TCR_EL2_PS_SHIFT 16
116117
#define TCR_EL2_PS_MASK (7 << TCR_EL2_PS_SHIFT)

arch/arm64/include/asm/kvm_asm.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,9 +246,9 @@ extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
246246
extern int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding);
247247

248248
extern void __kvm_timer_set_cntvoff(u64 cntvoff);
249-
extern void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
250-
extern void __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
251-
extern void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
249+
extern int __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
250+
extern int __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
251+
extern int __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
252252

253253
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
254254

arch/arm64/include/asm/kvm_nested.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,42 @@ static inline bool kvm_s2_trans_writable(struct kvm_s2_trans *trans)
120120
return trans->writable;
121121
}
122122

123-
static inline bool kvm_s2_trans_executable(struct kvm_s2_trans *trans)
123+
static inline bool kvm_has_xnx(struct kvm *kvm)
124124
{
125-
return !(trans->desc & BIT(54));
125+
return cpus_have_final_cap(ARM64_HAS_XNX) &&
126+
kvm_has_feat(kvm, ID_AA64MMFR1_EL1, XNX, IMP);
127+
}
128+
129+
static inline bool kvm_s2_trans_exec_el0(struct kvm *kvm, struct kvm_s2_trans *trans)
130+
{
131+
u8 xn = FIELD_GET(KVM_PTE_LEAF_ATTR_HI_S2_XN, trans->desc);
132+
133+
if (!kvm_has_xnx(kvm))
134+
xn &= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_S2_XN, 0b10);
135+
136+
switch (xn) {
137+
case 0b00:
138+
case 0b01:
139+
return true;
140+
default:
141+
return false;
142+
}
143+
}
144+
145+
static inline bool kvm_s2_trans_exec_el1(struct kvm *kvm, struct kvm_s2_trans *trans)
146+
{
147+
u8 xn = FIELD_GET(KVM_PTE_LEAF_ATTR_HI_S2_XN, trans->desc);
148+
149+
if (!kvm_has_xnx(kvm))
150+
xn &= FIELD_PREP(KVM_PTE_LEAF_ATTR_HI_S2_XN, 0b10);
151+
152+
switch (xn) {
153+
case 0b00:
154+
case 0b11:
155+
return true;
156+
default:
157+
return false;
158+
}
126159
}
127160

128161
extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
@@ -320,6 +353,7 @@ struct s1_walk_info {
320353
bool be;
321354
bool s2;
322355
bool pa52bit;
356+
bool ha;
323357
};
324358

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

407+
int __kvm_at_swap_desc(struct kvm *kvm, gpa_t ipa, u64 old, u64 new);
408+
373409
#endif /* __ARM64_KVM_NESTED_H */

arch/arm64/include/asm/kvm_pgtable.h

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ typedef u64 kvm_pte_t;
8989

9090
#define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54)
9191

92-
#define KVM_PTE_LEAF_ATTR_HI_S2_XN BIT(54)
92+
#define KVM_PTE_LEAF_ATTR_HI_S2_XN GENMASK(54, 53)
9393

9494
#define KVM_PTE_LEAF_ATTR_HI_S1_GP BIT(50)
9595

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

241241
/**
242242
* enum kvm_pgtable_prot - Page-table permissions and attributes.
243-
* @KVM_PGTABLE_PROT_X: Execute permission.
243+
* @KVM_PGTABLE_PROT_UX: Unprivileged execute permission.
244+
* @KVM_PGTABLE_PROT_PX: Privileged execute permission.
245+
* @KVM_PGTABLE_PROT_X: Privileged and unprivileged execute permission.
244246
* @KVM_PGTABLE_PROT_W: Write permission.
245247
* @KVM_PGTABLE_PROT_R: Read permission.
246248
* @KVM_PGTABLE_PROT_DEVICE: Device attributes.
@@ -251,12 +253,15 @@ enum kvm_pgtable_stage2_flags {
251253
* @KVM_PGTABLE_PROT_SW3: Software bit 3.
252254
*/
253255
enum kvm_pgtable_prot {
254-
KVM_PGTABLE_PROT_X = BIT(0),
255-
KVM_PGTABLE_PROT_W = BIT(1),
256-
KVM_PGTABLE_PROT_R = BIT(2),
257-
258-
KVM_PGTABLE_PROT_DEVICE = BIT(3),
259-
KVM_PGTABLE_PROT_NORMAL_NC = BIT(4),
256+
KVM_PGTABLE_PROT_PX = BIT(0),
257+
KVM_PGTABLE_PROT_UX = BIT(1),
258+
KVM_PGTABLE_PROT_X = KVM_PGTABLE_PROT_PX |
259+
KVM_PGTABLE_PROT_UX,
260+
KVM_PGTABLE_PROT_W = BIT(2),
261+
KVM_PGTABLE_PROT_R = BIT(3),
262+
263+
KVM_PGTABLE_PROT_DEVICE = BIT(4),
264+
KVM_PGTABLE_PROT_NORMAL_NC = BIT(5),
260265

261266
KVM_PGTABLE_PROT_SW0 = BIT(55),
262267
KVM_PGTABLE_PROT_SW1 = BIT(56),

arch/arm64/kernel/cpufeature.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3140,6 +3140,13 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
31403140
.capability = ARM64_HAS_GICV5_LEGACY,
31413141
.matches = test_has_gicv5_legacy,
31423142
},
3143+
{
3144+
.desc = "XNX",
3145+
.capability = ARM64_HAS_XNX,
3146+
.type = ARM64_CPUCAP_SYSTEM_FEATURE,
3147+
.matches = has_cpuid_feature,
3148+
ARM64_CPUID_FIELDS(ID_AA64MMFR1_EL1, XNX, IMP)
3149+
},
31433150
{},
31443151
};
31453152

0 commit comments

Comments
 (0)