Skip to content

Commit 2e0f239

Browse files
author
Marc Zyngier
committed
Merge branch kvm-arm64/nv-at-pan into kvmarm-master/next
* kvm-arm64/nv-at-pan: : . : Add NV support for the AT family of instructions, which mostly results : in adding a page table walker that deals with most of the complexity : of the architecture. : : From the cover letter: : : "Another task that a hypervisor supporting NV on arm64 has to deal with : is to emulate the AT instruction, because we multiplex all the S1 : translations on a single set of registers, and the guest S2 is never : truly resident on the CPU. : : So given that we lie about page tables, we also have to lie about : translation instructions, hence the emulation. Things are made : complicated by the fact that guest S1 page tables can be swapped out, : and that our shadow S2 is likely to be incomplete. So while using AT : to emulate AT is tempting (and useful), it is not going to always : work, and we thus need a fallback in the shape of a SW S1 walker." : . KVM: arm64: nv: Add support for FEAT_ATS1A KVM: arm64: nv: Plumb handling of AT S1* traps from EL2 KVM: arm64: nv: Make AT+PAN instructions aware of FEAT_PAN3 KVM: arm64: nv: Sanitise SCTLR_EL1.EPAN according to VM configuration KVM: arm64: nv: Add SW walker for AT S1 emulation KVM: arm64: nv: Make ps_to_output_size() generally available KVM: arm64: nv: Add emulation of AT S12E{0,1}{R,W} KVM: arm64: nv: Add basic emulation of AT S1E2{R,W} KVM: arm64: nv: Add basic emulation of AT S1E1{R,W}P KVM: arm64: nv: Add basic emulation of AT S1E{0,1}{R,W} KVM: arm64: nv: Honor absence of FEAT_PAN2 KVM: arm64: nv: Turn upper_attr for S2 walk into the full descriptor KVM: arm64: nv: Enforce S2 alignment when contiguous bit is set arm64: Add ESR_ELx_FSC_ADDRSZ_L() helper arm64: Add system register encoding for PSTATE.PAN arm64: Add PAR_EL1 field description arm64: Add missing APTable and TCR_ELx.HPD masks KVM: arm64: Make kvm_at() take an OP_AT_* Signed-off-by: Marc Zyngier <[email protected]> # Conflicts: # arch/arm64/kvm/nested.c
2 parents f77e63e + ff987ff commit 2e0f239

File tree

12 files changed

+1258
-32
lines changed

12 files changed

+1258
-32
lines changed

arch/arm64/include/asm/esr.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@
122122
#define ESR_ELx_FSC_SECC_TTW(n) (0x1c + (n))
123123

124124
/* Status codes for individual page table levels */
125-
#define ESR_ELx_FSC_ACCESS_L(n) (ESR_ELx_FSC_ACCESS + n)
126-
#define ESR_ELx_FSC_PERM_L(n) (ESR_ELx_FSC_PERM + n)
125+
#define ESR_ELx_FSC_ACCESS_L(n) (ESR_ELx_FSC_ACCESS + (n))
126+
#define ESR_ELx_FSC_PERM_L(n) (ESR_ELx_FSC_PERM + (n))
127127

128128
#define ESR_ELx_FSC_FAULT_nL (0x2C)
129129
#define ESR_ELx_FSC_FAULT_L(n) (((n) < 0 ? ESR_ELx_FSC_FAULT_nL : \
@@ -161,6 +161,7 @@
161161

162162
/* ISS field definitions for exceptions taken in to Hyp */
163163
#define ESR_ELx_FSC_ADDRSZ (0x00)
164+
#define ESR_ELx_FSC_ADDRSZ_L(n) (ESR_ELx_FSC_ADDRSZ + (n))
164165
#define ESR_ELx_CV (UL(1) << 24)
165166
#define ESR_ELx_COND_SHIFT (20)
166167
#define ESR_ELx_COND_MASK (UL(0xF) << ESR_ELx_COND_SHIFT)

arch/arm64/include/asm/kvm_arm.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@
107107
/* TCR_EL2 Registers bits */
108108
#define TCR_EL2_DS (1UL << 32)
109109
#define TCR_EL2_RES1 ((1U << 31) | (1 << 23))
110+
#define TCR_EL2_HPD (1 << 24)
110111
#define TCR_EL2_TBI (1 << 20)
111112
#define TCR_EL2_PS_SHIFT 16
112113
#define TCR_EL2_PS_MASK (7 << TCR_EL2_PS_SHIFT)

arch/arm64/include/asm/kvm_asm.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <asm/hyp_image.h>
1111
#include <asm/insn.h>
1212
#include <asm/virt.h>
13+
#include <asm/sysreg.h>
1314

1415
#define ARM_EXIT_WITH_SERROR_BIT 31
1516
#define ARM_EXCEPTION_CODE(x) ((x) & ~(1U << ARM_EXIT_WITH_SERROR_BIT))
@@ -235,6 +236,9 @@ extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
235236
extern int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding);
236237

237238
extern void __kvm_timer_set_cntvoff(u64 cntvoff);
239+
extern void __kvm_at_s1e01(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
240+
extern void __kvm_at_s1e2(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
241+
extern void __kvm_at_s12(struct kvm_vcpu *vcpu, u32 op, u64 vaddr);
238242

239243
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
240244

@@ -259,7 +263,7 @@ extern u64 __kvm_get_mdcr_el2(void);
259263
asm volatile( \
260264
" mrs %1, spsr_el2\n" \
261265
" mrs %2, elr_el2\n" \
262-
"1: at "at_op", %3\n" \
266+
"1: " __msr_s(at_op, "%3") "\n" \
263267
" isb\n" \
264268
" b 9f\n" \
265269
"2: msr spsr_el2, %1\n" \

arch/arm64/include/asm/kvm_nested.h

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ struct kvm_s2_trans {
8585
bool readable;
8686
int level;
8787
u32 esr;
88-
u64 upper_attr;
88+
u64 desc;
8989
};
9090

9191
static inline phys_addr_t kvm_s2_trans_output(struct kvm_s2_trans *trans)
@@ -115,7 +115,7 @@ static inline bool kvm_s2_trans_writable(struct kvm_s2_trans *trans)
115115

116116
static inline bool kvm_s2_trans_executable(struct kvm_s2_trans *trans)
117117
{
118-
return !(trans->upper_attr & BIT(54));
118+
return !(trans->desc & BIT(54));
119119
}
120120

121121
extern int kvm_walk_nested_s2(struct kvm_vcpu *vcpu, phys_addr_t gipa,
@@ -205,4 +205,40 @@ static inline u64 kvm_encode_nested_level(struct kvm_s2_trans *trans)
205205
return FIELD_PREP(KVM_NV_GUEST_MAP_SZ, trans->level);
206206
}
207207

208+
/* Adjust alignment for the contiguous bit as per StageOA() */
209+
#define contiguous_bit_shift(d, wi, l) \
210+
({ \
211+
u8 shift = 0; \
212+
\
213+
if ((d) & PTE_CONT) { \
214+
switch (BIT((wi)->pgshift)) { \
215+
case SZ_4K: \
216+
shift = 4; \
217+
break; \
218+
case SZ_16K: \
219+
shift = (l) == 2 ? 5 : 7; \
220+
break; \
221+
case SZ_64K: \
222+
shift = 5; \
223+
break; \
224+
} \
225+
} \
226+
\
227+
shift; \
228+
})
229+
230+
static inline unsigned int ps_to_output_size(unsigned int ps)
231+
{
232+
switch (ps) {
233+
case 0: return 32;
234+
case 1: return 36;
235+
case 2: return 40;
236+
case 3: return 42;
237+
case 4: return 44;
238+
case 5:
239+
default:
240+
return 48;
241+
}
242+
}
243+
208244
#endif /* __ARM64_KVM_NESTED_H */

arch/arm64/include/asm/pgtable-hwdef.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,11 @@
204204
*/
205205
#define PTE_S2_MEMATTR(t) (_AT(pteval_t, (t)) << 2)
206206

207+
/*
208+
* Hierarchical permission for Stage-1 tables
209+
*/
210+
#define S1_TABLE_AP (_AT(pmdval_t, 3) << 61)
211+
207212
/*
208213
* Highest possible physical address supported.
209214
*/
@@ -298,6 +303,10 @@
298303
#define TCR_TBI1 (UL(1) << 38)
299304
#define TCR_HA (UL(1) << 39)
300305
#define TCR_HD (UL(1) << 40)
306+
#define TCR_HPD0_SHIFT 41
307+
#define TCR_HPD0 (UL(1) << TCR_HPD0_SHIFT)
308+
#define TCR_HPD1_SHIFT 42
309+
#define TCR_HPD1 (UL(1) << TCR_HPD1_SHIFT)
301310
#define TCR_TBID0 (UL(1) << 51)
302311
#define TCR_TBID1 (UL(1) << 52)
303312
#define TCR_NFD0 (UL(1) << 53)

arch/arm64/include/asm/sysreg.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@
109109
#define set_pstate_ssbs(x) asm volatile(SET_PSTATE_SSBS(x))
110110
#define set_pstate_dit(x) asm volatile(SET_PSTATE_DIT(x))
111111

112+
/* Register-based PAN access, for save/restore purposes */
113+
#define SYS_PSTATE_PAN sys_reg(3, 0, 4, 2, 3)
114+
112115
#define __SYS_BARRIER_INSN(CRm, op2, Rt) \
113116
__emit_inst(0xd5000000 | sys_insn(0, 3, 3, (CRm), (op2)) | ((Rt) & 0x1f))
114117

@@ -325,7 +328,25 @@
325328
#define SYS_PAR_EL1 sys_reg(3, 0, 7, 4, 0)
326329

327330
#define SYS_PAR_EL1_F BIT(0)
331+
/* When PAR_EL1.F == 1 */
328332
#define SYS_PAR_EL1_FST GENMASK(6, 1)
333+
#define SYS_PAR_EL1_PTW BIT(8)
334+
#define SYS_PAR_EL1_S BIT(9)
335+
#define SYS_PAR_EL1_AssuredOnly BIT(12)
336+
#define SYS_PAR_EL1_TopLevel BIT(13)
337+
#define SYS_PAR_EL1_Overlay BIT(14)
338+
#define SYS_PAR_EL1_DirtyBit BIT(15)
339+
#define SYS_PAR_EL1_F1_IMPDEF GENMASK_ULL(63, 48)
340+
#define SYS_PAR_EL1_F1_RES0 (BIT(7) | BIT(10) | GENMASK_ULL(47, 16))
341+
#define SYS_PAR_EL1_RES1 BIT(11)
342+
/* When PAR_EL1.F == 0 */
343+
#define SYS_PAR_EL1_SH GENMASK_ULL(8, 7)
344+
#define SYS_PAR_EL1_NS BIT(9)
345+
#define SYS_PAR_EL1_F0_IMPDEF BIT(10)
346+
#define SYS_PAR_EL1_NSE BIT(11)
347+
#define SYS_PAR_EL1_PA GENMASK_ULL(51, 12)
348+
#define SYS_PAR_EL1_ATTR GENMASK_ULL(63, 56)
349+
#define SYS_PAR_EL1_F0_RES0 (GENMASK_ULL(6, 1) | GENMASK_ULL(55, 52))
329350

330351
/*** Statistical Profiling Extension ***/
331352
#define PMSEVFR_EL1_RES0_IMP \
@@ -652,6 +673,7 @@
652673
#define OP_AT_S12E1W sys_insn(AT_Op0, 4, AT_CRn, 8, 5)
653674
#define OP_AT_S12E0R sys_insn(AT_Op0, 4, AT_CRn, 8, 6)
654675
#define OP_AT_S12E0W sys_insn(AT_Op0, 4, AT_CRn, 8, 7)
676+
#define OP_AT_S1E2A sys_insn(AT_Op0, 4, AT_CRn, 9, 2)
655677

656678
/* TLBI instructions */
657679
#define TLBI_Op0 1

arch/arm64/kvm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ kvm-y += arm.o mmu.o mmio.o psci.o hypercalls.o pvtime.o \
1717
inject_fault.o va_layout.o handle_exit.o \
1818
guest.o debug.o reset.o sys_regs.o stacktrace.o \
1919
vgic-sys-reg-v3.o fpsimd.o pkvm.o \
20-
arch_timer.o trng.o vmid.o emulate-nested.o nested.o \
20+
arch_timer.o trng.o vmid.o emulate-nested.o nested.o at.o \
2121
vgic/vgic.o vgic/vgic-init.o \
2222
vgic/vgic-irqfd.o vgic/vgic-v2.o \
2323
vgic/vgic-v3.o vgic/vgic-v4.o \

0 commit comments

Comments
 (0)