Skip to content

Commit 300dca6

Browse files
author
Marc Zyngier
committed
Merge branch 'kvm-arm64/pre-nv-5.9' into kvmarm-master/next-WIP
Signed-off-by: Marc Zyngier <[email protected]>
2 parents c199a00 + 41ce82f commit 300dca6

30 files changed

+696
-425
lines changed

arch/arm64/include/asm/cpucaps.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@
6262
#define ARM64_HAS_GENERIC_AUTH 52
6363
#define ARM64_HAS_32BIT_EL1 53
6464
#define ARM64_BTI 54
65+
#define ARM64_HAS_ARMv8_4_TTL 55
6566

66-
#define ARM64_NCAPS 55
67+
#define ARM64_NCAPS 56
6768

6869
#endif /* __ASM_CPUCAPS_H */

arch/arm64/include/asm/kvm_asm.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ extern void *__nvhe_undefined_symbol;
9595

9696
struct kvm;
9797
struct kvm_vcpu;
98+
struct kvm_s2_mmu;
9899

99100
DECLARE_KVM_NVHE_SYM(__kvm_hyp_init);
100101
DECLARE_KVM_HYP_SYM(__kvm_hyp_vector);
@@ -108,9 +109,10 @@ DECLARE_KVM_HYP_SYM(__bp_harden_hyp_vecs);
108109
#endif
109110

110111
extern void __kvm_flush_vm_context(void);
111-
extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
112-
extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
113-
extern void __kvm_tlb_flush_local_vmid(struct kvm_vcpu *vcpu);
112+
extern void __kvm_tlb_flush_vmid_ipa(struct kvm_s2_mmu *mmu, phys_addr_t ipa,
113+
int level);
114+
extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
115+
extern void __kvm_tlb_flush_local_vmid(struct kvm_s2_mmu *mmu);
114116

115117
extern void __kvm_timer_set_cntvoff(u64 cntvoff);
116118

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -124,33 +124,12 @@ static inline void vcpu_set_vsesr(struct kvm_vcpu *vcpu, u64 vsesr)
124124

125125
static __always_inline unsigned long *vcpu_pc(const struct kvm_vcpu *vcpu)
126126
{
127-
return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pc;
128-
}
129-
130-
static inline unsigned long *__vcpu_elr_el1(const struct kvm_vcpu *vcpu)
131-
{
132-
return (unsigned long *)&vcpu_gp_regs(vcpu)->elr_el1;
133-
}
134-
135-
static inline unsigned long vcpu_read_elr_el1(const struct kvm_vcpu *vcpu)
136-
{
137-
if (vcpu->arch.sysregs_loaded_on_cpu)
138-
return read_sysreg_el1(SYS_ELR);
139-
else
140-
return *__vcpu_elr_el1(vcpu);
141-
}
142-
143-
static inline void vcpu_write_elr_el1(const struct kvm_vcpu *vcpu, unsigned long v)
144-
{
145-
if (vcpu->arch.sysregs_loaded_on_cpu)
146-
write_sysreg_el1(v, SYS_ELR);
147-
else
148-
*__vcpu_elr_el1(vcpu) = v;
127+
return (unsigned long *)&vcpu_gp_regs(vcpu)->pc;
149128
}
150129

151130
static __always_inline unsigned long *vcpu_cpsr(const struct kvm_vcpu *vcpu)
152131
{
153-
return (unsigned long *)&vcpu_gp_regs(vcpu)->regs.pstate;
132+
return (unsigned long *)&vcpu_gp_regs(vcpu)->pstate;
154133
}
155134

156135
static __always_inline bool vcpu_mode_is_32bit(const struct kvm_vcpu *vcpu)
@@ -179,14 +158,14 @@ static inline void vcpu_set_thumb(struct kvm_vcpu *vcpu)
179158
static __always_inline unsigned long vcpu_get_reg(const struct kvm_vcpu *vcpu,
180159
u8 reg_num)
181160
{
182-
return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs.regs[reg_num];
161+
return (reg_num == 31) ? 0 : vcpu_gp_regs(vcpu)->regs[reg_num];
183162
}
184163

185164
static __always_inline void vcpu_set_reg(struct kvm_vcpu *vcpu, u8 reg_num,
186165
unsigned long val)
187166
{
188167
if (reg_num != 31)
189-
vcpu_gp_regs(vcpu)->regs.regs[reg_num] = val;
168+
vcpu_gp_regs(vcpu)->regs[reg_num] = val;
190169
}
191170

192171
static inline unsigned long vcpu_read_spsr(const struct kvm_vcpu *vcpu)
@@ -197,7 +176,7 @@ static inline unsigned long vcpu_read_spsr(const struct kvm_vcpu *vcpu)
197176
if (vcpu->arch.sysregs_loaded_on_cpu)
198177
return read_sysreg_el1(SYS_SPSR);
199178
else
200-
return vcpu_gp_regs(vcpu)->spsr[KVM_SPSR_EL1];
179+
return __vcpu_sys_reg(vcpu, SPSR_EL1);
201180
}
202181

203182
static inline void vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long v)
@@ -210,7 +189,7 @@ static inline void vcpu_write_spsr(struct kvm_vcpu *vcpu, unsigned long v)
210189
if (vcpu->arch.sysregs_loaded_on_cpu)
211190
write_sysreg_el1(v, SYS_SPSR);
212191
else
213-
vcpu_gp_regs(vcpu)->spsr[KVM_SPSR_EL1] = v;
192+
__vcpu_sys_reg(vcpu, SPSR_EL1) = v;
214193
}
215194

216195
/*
@@ -519,11 +498,11 @@ static __always_inline void kvm_skip_instr(struct kvm_vcpu *vcpu, bool is_wide_i
519498
static __always_inline void __kvm_skip_instr(struct kvm_vcpu *vcpu)
520499
{
521500
*vcpu_pc(vcpu) = read_sysreg_el2(SYS_ELR);
522-
vcpu->arch.ctxt.gp_regs.regs.pstate = read_sysreg_el2(SYS_SPSR);
501+
vcpu_gp_regs(vcpu)->pstate = read_sysreg_el2(SYS_SPSR);
523502

524503
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
525504

526-
write_sysreg_el2(vcpu->arch.ctxt.gp_regs.regs.pstate, SYS_SPSR);
505+
write_sysreg_el2(vcpu_gp_regs(vcpu)->pstate, SYS_SPSR);
527506
write_sysreg_el2(*vcpu_pc(vcpu), SYS_ELR);
528507
}
529508

arch/arm64/include/asm/kvm_host.h

Lines changed: 56 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,34 @@ struct kvm_vmid {
6666
u32 vmid;
6767
};
6868

69-
struct kvm_arch {
69+
struct kvm_s2_mmu {
7070
struct kvm_vmid vmid;
7171

72-
/* stage2 entry level table */
73-
pgd_t *pgd;
74-
phys_addr_t pgd_phys;
75-
76-
/* VTCR_EL2 value for this VM */
77-
u64 vtcr;
72+
/*
73+
* stage2 entry level table
74+
*
75+
* Two kvm_s2_mmu structures in the same VM can point to the same
76+
* pgd here. This happens when running a guest using a
77+
* translation regime that isn't affected by its own stage-2
78+
* translation, such as a non-VHE hypervisor running at vEL2, or
79+
* for vEL1/EL0 with vHCR_EL2.VM == 0. In that case, we use the
80+
* canonical stage-2 page tables.
81+
*/
82+
pgd_t *pgd;
83+
phys_addr_t pgd_phys;
7884

7985
/* The last vcpu id that ran on each physical CPU */
8086
int __percpu *last_vcpu_ran;
8187

88+
struct kvm *kvm;
89+
};
90+
91+
struct kvm_arch {
92+
struct kvm_s2_mmu mmu;
93+
94+
/* VTCR_EL2 value for this VM */
95+
u64 vtcr;
96+
8297
/* The maximum number of vCPUs depends on the used GIC model */
8398
int max_vcpus;
8499

@@ -170,6 +185,16 @@ enum vcpu_sysreg {
170185
APGAKEYLO_EL1,
171186
APGAKEYHI_EL1,
172187

188+
ELR_EL1,
189+
SP_EL1,
190+
SPSR_EL1,
191+
192+
CNTVOFF_EL2,
193+
CNTV_CVAL_EL0,
194+
CNTV_CTL_EL0,
195+
CNTP_CVAL_EL0,
196+
CNTP_CTL_EL0,
197+
173198
/* 32bit specific registers. Keep them at the end of the range */
174199
DACR32_EL2, /* Domain Access Control Register */
175200
IFSR32_EL2, /* Instruction Fault Status Register */
@@ -221,7 +246,15 @@ enum vcpu_sysreg {
221246
#define NR_COPRO_REGS (NR_SYS_REGS * 2)
222247

223248
struct kvm_cpu_context {
224-
struct kvm_regs gp_regs;
249+
struct user_pt_regs regs; /* sp = sp_el0 */
250+
251+
u64 spsr_abt;
252+
u64 spsr_und;
253+
u64 spsr_irq;
254+
u64 spsr_fiq;
255+
256+
struct user_fpsimd_state fp_regs;
257+
225258
union {
226259
u64 sys_regs[NR_SYS_REGS];
227260
u32 copro[NR_COPRO_REGS];
@@ -254,6 +287,9 @@ struct kvm_vcpu_arch {
254287
void *sve_state;
255288
unsigned int sve_max_vl;
256289

290+
/* Stage 2 paging state used by the hardware on next switch */
291+
struct kvm_s2_mmu *hw_mmu;
292+
257293
/* HYP configuration */
258294
u64 hcr_el2;
259295
u32 mdcr_el2;
@@ -384,15 +420,20 @@ struct kvm_vcpu_arch {
384420
system_supports_generic_auth()) && \
385421
((vcpu)->arch.flags & KVM_ARM64_GUEST_HAS_PTRAUTH))
386422

387-
#define vcpu_gp_regs(v) (&(v)->arch.ctxt.gp_regs)
423+
#define vcpu_gp_regs(v) (&(v)->arch.ctxt.regs)
388424

389425
/*
390-
* Only use __vcpu_sys_reg if you know you want the memory backed version of a
391-
* register, and not the one most recently accessed by a running VCPU. For
392-
* example, for userspace access or for system registers that are never context
393-
* switched, but only emulated.
426+
* Only use __vcpu_sys_reg/ctxt_sys_reg if you know you want the
427+
* memory backed version of a register, and not the one most recently
428+
* accessed by a running VCPU. For example, for userspace access or
429+
* for system registers that are never context switched, but only
430+
* emulated.
394431
*/
395-
#define __vcpu_sys_reg(v,r) ((v)->arch.ctxt.sys_regs[(r)])
432+
#define __ctxt_sys_reg(c,r) (&(c)->sys_regs[(r)])
433+
434+
#define ctxt_sys_reg(c,r) (*__ctxt_sys_reg(c,r))
435+
436+
#define __vcpu_sys_reg(v,r) (ctxt_sys_reg(&(v)->arch.ctxt, (r)))
396437

397438
u64 vcpu_read_sys_reg(const struct kvm_vcpu *vcpu, int reg);
398439
void vcpu_write_sys_reg(struct kvm_vcpu *vcpu, u64 val, int reg);
@@ -538,7 +579,7 @@ DECLARE_PER_CPU(kvm_host_data_t, kvm_host_data);
538579
static inline void kvm_init_host_cpu_context(struct kvm_cpu_context *cpu_ctxt)
539580
{
540581
/* The host's MPIDR is immutable, so let's set it up at boot time */
541-
cpu_ctxt->sys_regs[MPIDR_EL1] = read_cpuid_mpidr();
582+
ctxt_sys_reg(cpu_ctxt, MPIDR_EL1) = read_cpuid_mpidr();
542583
}
543584

544585
static inline bool kvm_arch_requires_vhe(void)

arch/arm64/include/asm/kvm_mmu.h

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size,
134134
void free_hyp_pgds(void);
135135

136136
void stage2_unmap_vm(struct kvm *kvm);
137-
int kvm_alloc_stage2_pgd(struct kvm *kvm);
138-
void kvm_free_stage2_pgd(struct kvm *kvm);
137+
int kvm_init_stage2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu);
138+
void kvm_free_stage2_pgd(struct kvm_s2_mmu *mmu);
139139
int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
140140
phys_addr_t pa, unsigned long size, bool writable);
141141

@@ -577,13 +577,13 @@ static inline u64 kvm_vttbr_baddr_mask(struct kvm *kvm)
577577
return vttbr_baddr_mask(kvm_phys_shift(kvm), kvm_stage2_levels(kvm));
578578
}
579579

580-
static __always_inline u64 kvm_get_vttbr(struct kvm *kvm)
580+
static __always_inline u64 kvm_get_vttbr(struct kvm_s2_mmu *mmu)
581581
{
582-
struct kvm_vmid *vmid = &kvm->arch.vmid;
582+
struct kvm_vmid *vmid = &mmu->vmid;
583583
u64 vmid_field, baddr;
584584
u64 cnp = system_supports_cnp() ? VTTBR_CNP_BIT : 0;
585585

586-
baddr = kvm->arch.pgd_phys;
586+
baddr = mmu->pgd_phys;
587587
vmid_field = (u64)vmid->vmid << VTTBR_VMID_SHIFT;
588588
return kvm_phys_to_vttbr(baddr) | vmid_field | cnp;
589589
}
@@ -592,10 +592,10 @@ static __always_inline u64 kvm_get_vttbr(struct kvm *kvm)
592592
* Must be called from hyp code running at EL2 with an updated VTTBR
593593
* and interrupts disabled.
594594
*/
595-
static __always_inline void __load_guest_stage2(struct kvm *kvm)
595+
static __always_inline void __load_guest_stage2(struct kvm_s2_mmu *mmu)
596596
{
597-
write_sysreg(kvm->arch.vtcr, vtcr_el2);
598-
write_sysreg(kvm_get_vttbr(kvm), vttbr_el2);
597+
write_sysreg(kern_hyp_va(mmu->kvm)->arch.vtcr, vtcr_el2);
598+
write_sysreg(kvm_get_vttbr(mmu), vttbr_el2);
599599

600600
/*
601601
* ARM errata 1165522 and 1530923 require the actual execution of the

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,10 +178,12 @@
178178
#define PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[2:1] */
179179
#define PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
180180
#define PTE_S2_XN (_AT(pteval_t, 2) << 53) /* XN[1:0] */
181+
#define PTE_S2_SW_RESVD (_AT(pteval_t, 15) << 55) /* Reserved for SW */
181182

182183
#define PMD_S2_RDONLY (_AT(pmdval_t, 1) << 6) /* HAP[2:1] */
183184
#define PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
184185
#define PMD_S2_XN (_AT(pmdval_t, 2) << 53) /* XN[1:0] */
186+
#define PMD_S2_SW_RESVD (_AT(pmdval_t, 15) << 55) /* Reserved for SW */
185187

186188
#define PUD_S2_RDONLY (_AT(pudval_t, 1) << 6) /* HAP[2:1] */
187189
#define PUD_S2_RDWR (_AT(pudval_t, 3) << 6) /* HAP[2:1] */

arch/arm64/include/asm/stage2_pgtable.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,4 +256,13 @@ stage2_pgd_addr_end(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
256256
return (boundary - 1 < end - 1) ? boundary : end;
257257
}
258258

259+
/*
260+
* Level values for the ARMv8.4-TTL extension, mapping PUD/PMD/PTE and
261+
* the architectural page-table level.
262+
*/
263+
#define S2_NO_LEVEL_HINT 0
264+
#define S2_PUD_LEVEL 1
265+
#define S2_PMD_LEVEL 2
266+
#define S2_PTE_LEVEL 3
267+
259268
#endif /* __ARM64_S2_PGTABLE_H_ */

arch/arm64/include/asm/sysreg.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@
746746

747747
/* id_aa64mmfr2 */
748748
#define ID_AA64MMFR2_E0PD_SHIFT 60
749+
#define ID_AA64MMFR2_TTL_SHIFT 48
749750
#define ID_AA64MMFR2_FWB_SHIFT 40
750751
#define ID_AA64MMFR2_AT_SHIFT 32
751752
#define ID_AA64MMFR2_LVA_SHIFT 16

arch/arm64/include/asm/tlbflush.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#ifndef __ASSEMBLY__
1212

13+
#include <linux/bitfield.h>
1314
#include <linux/mm_types.h>
1415
#include <linux/sched.h>
1516
#include <asm/cputype.h>
@@ -59,6 +60,50 @@
5960
__ta; \
6061
})
6162

63+
/*
64+
* Level-based TLBI operations.
65+
*
66+
* When ARMv8.4-TTL exists, TLBI operations take an additional hint for
67+
* the level at which the invalidation must take place. If the level is
68+
* wrong, no invalidation may take place. In the case where the level
69+
* cannot be easily determined, a 0 value for the level parameter will
70+
* perform a non-hinted invalidation.
71+
*
72+
* For Stage-2 invalidation, use the level values provided to that effect
73+
* in asm/stage2_pgtable.h.
74+
*/
75+
#define TLBI_TTL_MASK GENMASK_ULL(47, 44)
76+
#define TLBI_TTL_TG_4K 1
77+
#define TLBI_TTL_TG_16K 2
78+
#define TLBI_TTL_TG_64K 3
79+
80+
#define __tlbi_level(op, addr, level) \
81+
do { \
82+
u64 arg = addr; \
83+
\
84+
if (cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL) && \
85+
level) { \
86+
u64 ttl = level & 3; \
87+
\
88+
switch (PAGE_SIZE) { \
89+
case SZ_4K: \
90+
ttl |= TLBI_TTL_TG_4K << 2; \
91+
break; \
92+
case SZ_16K: \
93+
ttl |= TLBI_TTL_TG_16K << 2; \
94+
break; \
95+
case SZ_64K: \
96+
ttl |= TLBI_TTL_TG_64K << 2; \
97+
break; \
98+
} \
99+
\
100+
arg &= ~TLBI_TTL_MASK; \
101+
arg |= FIELD_PREP(TLBI_TTL_MASK, ttl); \
102+
} \
103+
\
104+
__tlbi(op, arg); \
105+
} while(0)
106+
62107
/*
63108
* TLB Invalidation
64109
* ================

arch/arm64/kernel/asm-offsets.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,13 +102,12 @@ int main(void)
102102
DEFINE(VCPU_FAULT_DISR, offsetof(struct kvm_vcpu, arch.fault.disr_el1));
103103
DEFINE(VCPU_WORKAROUND_FLAGS, offsetof(struct kvm_vcpu, arch.workaround_flags));
104104
DEFINE(VCPU_HCR_EL2, offsetof(struct kvm_vcpu, arch.hcr_el2));
105-
DEFINE(CPU_GP_REGS, offsetof(struct kvm_cpu_context, gp_regs));
105+
DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_cpu_context, regs));
106106
DEFINE(CPU_APIAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APIAKEYLO_EL1]));
107107
DEFINE(CPU_APIBKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APIBKEYLO_EL1]));
108108
DEFINE(CPU_APDAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APDAKEYLO_EL1]));
109109
DEFINE(CPU_APDBKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APDBKEYLO_EL1]));
110110
DEFINE(CPU_APGAKEYLO_EL1, offsetof(struct kvm_cpu_context, sys_regs[APGAKEYLO_EL1]));
111-
DEFINE(CPU_USER_PT_REGS, offsetof(struct kvm_regs, regs));
112111
DEFINE(HOST_CONTEXT_VCPU, offsetof(struct kvm_cpu_context, __hyp_running_vcpu));
113112
DEFINE(HOST_DATA_CONTEXT, offsetof(struct kvm_host_data, host_ctxt));
114113
#endif

0 commit comments

Comments
 (0)