Skip to content

Commit 64dd3b6

Browse files
committed
Merge tag 'for-linus-non-x86' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull kvm updates from Paolo Bonzini: "These are the non-x86 changes (mostly ARM, as is usually the case). The generic and x86 changes will come later" ARM: - New Stage-2 page table dumper, reusing the main ptdump infrastructure - FP8 support - Nested virtualization now supports the address translation (FEAT_ATS1A) family of instructions - Add selftest checks for a bunch of timer emulation corner cases - Fix multiple cases where KVM/arm64 doesn't correctly handle the guest trying to use a GICv3 that wasn't advertised - Remove REG_HIDDEN_USER from the sysreg infrastructure, making things little simpler - Prevent MTE tags being restored by userspace if we are actively logging writes, as that's a recipe for disaster - Correct the refcount on a page that is not considered for MTE tag copying (such as a device) - When walking a page table to split block mappings, synchronize only at the end the walk rather than on every store - Fix boundary check when transfering memory using FFA - Fix pKVM TLB invalidation, only affecting currently out of tree code but worth addressing for peace of mind LoongArch: - Revert qspinlock to test-and-set simple lock on VM. - Add Loongson Binary Translation extension support. - Add PMU support for guest. - Enable paravirt feature control from VMM. - Implement function kvm_para_has_feature(). RISC-V: - Fix sbiret init before forwarding to userspace - Don't zero-out PMU snapshot area before freeing data - Allow legacy PMU access from guest - Fix to allow hpmcounter31 from the guest" * tag 'for-linus-non-x86' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (64 commits) LoongArch: KVM: Implement function kvm_para_has_feature() LoongArch: KVM: Enable paravirt feature control from VMM LoongArch: KVM: Add PMU support for guest KVM: arm64: Get rid of REG_HIDDEN_USER visibility qualifier KVM: arm64: Simplify visibility handling of AArch32 SPSR_* KVM: arm64: Simplify handling of CNTKCTL_EL12 LoongArch: KVM: Add vm migration support for LBT registers LoongArch: KVM: Add Binary Translation extension support LoongArch: KVM: Add VM feature detection function LoongArch: Revert qspinlock to test-and-set simple lock on VM KVM: arm64: Register ptdump with debugfs on guest creation arm64: ptdump: Don't override the level when operating on the stage-2 tables arm64: ptdump: Use the ptdump description from a local context arm64: ptdump: Expose the attribute parsing functionality KVM: arm64: Add memory length checks and remove inline in do_ffa_mem_xfer KVM: arm64: Move pagetable definitions to common header 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 ...
2 parents 980bcd3 + 0cdcc99 commit 64dd3b6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+4039
-408
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: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,9 @@ extern void __kvm_tlb_flush_vmid(struct kvm_s2_mmu *mmu);
236236
extern int __kvm_tlbi_s1e2(struct kvm_s2_mmu *mmu, u64 va, u64 sys_encoding);
237237

238238
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);
239242

240243
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
241244

arch/arm64/include/asm/kvm_host.h

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,10 @@ enum vcpu_sysreg {
448448

449449
POR_EL0, /* Permission Overlay Register 0 (EL0) */
450450

451+
/* FP/SIMD/SVE */
452+
SVCR,
453+
FPMR,
454+
451455
/* 32bit specific registers. */
452456
DACR32_EL2, /* Domain Access Control Register */
453457
IFSR32_EL2, /* Instruction Fault Status Register */
@@ -534,6 +538,8 @@ enum vcpu_sysreg {
534538
VNCR(CNTP_CVAL_EL0),
535539
VNCR(CNTP_CTL_EL0),
536540

541+
VNCR(ICH_HCR_EL2),
542+
537543
NR_SYS_REGS /* Nothing after this line! */
538544
};
539545

@@ -599,6 +605,16 @@ struct kvm_host_data {
599605
struct cpu_sve_state *sve_state;
600606
};
601607

608+
union {
609+
/* HYP VA pointer to the host storage for FPMR */
610+
u64 *fpmr_ptr;
611+
/*
612+
* Used by pKVM only, as it needs to provide storage
613+
* for the host
614+
*/
615+
u64 fpmr;
616+
};
617+
602618
/* Ownership of the FP regs */
603619
enum {
604620
FP_STATE_FREE,
@@ -668,8 +684,6 @@ struct kvm_vcpu_arch {
668684
void *sve_state;
669685
enum fp_type fp_type;
670686
unsigned int sve_max_vl;
671-
u64 svcr;
672-
u64 fpmr;
673687

674688
/* Stage 2 paging state used by the hardware on next switch */
675689
struct kvm_s2_mmu *hw_mmu;
@@ -1477,4 +1491,8 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
14771491
(pa + pi + pa3) == 1; \
14781492
})
14791493

1494+
#define kvm_has_fpmr(k) \
1495+
(system_supports_fpmr() && \
1496+
kvm_has_feat((k), ID_AA64PFR2_EL1, FPMR, IMP))
1497+
14801498
#endif /* __ARM64_KVM_HOST_H__ */

arch/arm64/include/asm/kvm_mmu.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,5 +352,11 @@ static inline bool kvm_is_nested_s2_mmu(struct kvm *kvm, struct kvm_s2_mmu *mmu)
352352
return &kvm->arch.mmu != mmu;
353353
}
354354

355+
#ifdef CONFIG_PTDUMP_STAGE2_DEBUGFS
356+
void kvm_s2_ptdump_create_debugfs(struct kvm *kvm);
357+
#else
358+
static inline void kvm_s2_ptdump_create_debugfs(struct kvm *kvm) {}
359+
#endif /* CONFIG_PTDUMP_STAGE2_DEBUGFS */
360+
355361
#endif /* __ASSEMBLY__ */
356362
#endif /* __ARM64_KVM_MMU_H__ */

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/kvm_pgtable.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,48 @@ typedef u64 kvm_pte_t;
5959

6060
#define KVM_PHYS_INVALID (-1ULL)
6161

62+
#define KVM_PTE_LEAF_ATTR_LO GENMASK(11, 2)
63+
64+
#define KVM_PTE_LEAF_ATTR_LO_S1_ATTRIDX GENMASK(4, 2)
65+
#define KVM_PTE_LEAF_ATTR_LO_S1_AP GENMASK(7, 6)
66+
#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RO \
67+
({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 2 : 3; })
68+
#define KVM_PTE_LEAF_ATTR_LO_S1_AP_RW \
69+
({ cpus_have_final_cap(ARM64_KVM_HVHE) ? 0 : 1; })
70+
#define KVM_PTE_LEAF_ATTR_LO_S1_SH GENMASK(9, 8)
71+
#define KVM_PTE_LEAF_ATTR_LO_S1_SH_IS 3
72+
#define KVM_PTE_LEAF_ATTR_LO_S1_AF BIT(10)
73+
74+
#define KVM_PTE_LEAF_ATTR_LO_S2_MEMATTR GENMASK(5, 2)
75+
#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R BIT(6)
76+
#define KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W BIT(7)
77+
#define KVM_PTE_LEAF_ATTR_LO_S2_SH GENMASK(9, 8)
78+
#define KVM_PTE_LEAF_ATTR_LO_S2_SH_IS 3
79+
#define KVM_PTE_LEAF_ATTR_LO_S2_AF BIT(10)
80+
81+
#define KVM_PTE_LEAF_ATTR_HI GENMASK(63, 50)
82+
83+
#define KVM_PTE_LEAF_ATTR_HI_SW GENMASK(58, 55)
84+
85+
#define KVM_PTE_LEAF_ATTR_HI_S1_XN BIT(54)
86+
87+
#define KVM_PTE_LEAF_ATTR_HI_S2_XN BIT(54)
88+
89+
#define KVM_PTE_LEAF_ATTR_HI_S1_GP BIT(50)
90+
91+
#define KVM_PTE_LEAF_ATTR_S2_PERMS (KVM_PTE_LEAF_ATTR_LO_S2_S2AP_R | \
92+
KVM_PTE_LEAF_ATTR_LO_S2_S2AP_W | \
93+
KVM_PTE_LEAF_ATTR_HI_S2_XN)
94+
95+
#define KVM_INVALID_PTE_OWNER_MASK GENMASK(9, 2)
96+
#define KVM_MAX_OWNER_ID 1
97+
98+
/*
99+
* Used to indicate a pte for which a 'break-before-make' sequence is in
100+
* progress.
101+
*/
102+
#define KVM_INVALID_PTE_LOCKED BIT(10)
103+
62104
static inline bool kvm_pte_valid(kvm_pte_t pte)
63105
{
64106
return pte & KVM_PTE_VALID;

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,11 @@
213213
*/
214214
#define PTE_S2_MEMATTR(t) (_AT(pteval_t, (t)) << 2)
215215

216+
/*
217+
* Hierarchical permission for Stage-1 tables
218+
*/
219+
#define S1_TABLE_AP (_AT(pmdval_t, 3) << 61)
220+
216221
/*
217222
* Highest possible physical address supported.
218223
*/
@@ -307,6 +312,10 @@
307312
#define TCR_TBI1 (UL(1) << 38)
308313
#define TCR_HA (UL(1) << 39)
309314
#define TCR_HD (UL(1) << 40)
315+
#define TCR_HPD0_SHIFT 41
316+
#define TCR_HPD0 (UL(1) << TCR_HPD0_SHIFT)
317+
#define TCR_HPD1_SHIFT 42
318+
#define TCR_HPD1 (UL(1) << TCR_HPD1_SHIFT)
310319
#define TCR_TBID0 (UL(1) << 51)
311320
#define TCR_TBID1 (UL(1) << 52)
312321
#define TCR_NFD0 (UL(1) << 53)

arch/arm64/include/asm/ptdump.h

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#ifndef __ASM_PTDUMP_H
66
#define __ASM_PTDUMP_H
77

8+
#include <linux/ptdump.h>
9+
810
#ifdef CONFIG_PTDUMP_CORE
911

1012
#include <linux/mm_types.h>
@@ -21,14 +23,53 @@ struct ptdump_info {
2123
unsigned long base_addr;
2224
};
2325

26+
struct ptdump_prot_bits {
27+
u64 mask;
28+
u64 val;
29+
const char *set;
30+
const char *clear;
31+
};
32+
33+
struct ptdump_pg_level {
34+
const struct ptdump_prot_bits *bits;
35+
char name[4];
36+
int num;
37+
u64 mask;
38+
};
39+
40+
/*
41+
* The page dumper groups page table entries of the same type into a single
42+
* description. It uses pg_state to track the range information while
43+
* iterating over the pte entries. When the continuity is broken it then
44+
* dumps out a description of the range.
45+
*/
46+
struct ptdump_pg_state {
47+
struct ptdump_state ptdump;
48+
struct ptdump_pg_level *pg_level;
49+
struct seq_file *seq;
50+
const struct addr_marker *marker;
51+
const struct mm_struct *mm;
52+
unsigned long start_address;
53+
int level;
54+
u64 current_prot;
55+
bool check_wx;
56+
unsigned long wx_pages;
57+
unsigned long uxn_pages;
58+
};
59+
2460
void ptdump_walk(struct seq_file *s, struct ptdump_info *info);
61+
void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
62+
u64 val);
2563
#ifdef CONFIG_PTDUMP_DEBUGFS
2664
#define EFI_RUNTIME_MAP_END DEFAULT_MAP_WINDOW_64
2765
void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
2866
#else
2967
static inline void ptdump_debugfs_register(struct ptdump_info *info,
3068
const char *name) { }
31-
#endif
69+
#endif /* CONFIG_PTDUMP_DEBUGFS */
70+
#else
71+
static inline void note_page(struct ptdump_state *pt_st, unsigned long addr,
72+
int level, u64 val) { }
3273
#endif /* CONFIG_PTDUMP_CORE */
3374

3475
#endif /* __ASM_PTDUMP_H */

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 \
@@ -651,6 +672,7 @@
651672
#define OP_AT_S12E1W sys_insn(AT_Op0, 4, AT_CRn, 8, 5)
652673
#define OP_AT_S12E0R sys_insn(AT_Op0, 4, AT_CRn, 8, 6)
653674
#define OP_AT_S12E0W sys_insn(AT_Op0, 4, AT_CRn, 8, 7)
675+
#define OP_AT_S1E2A sys_insn(AT_Op0, 4, AT_CRn, 9, 2)
654676

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

0 commit comments

Comments
 (0)