Skip to content

Commit 7b541d5

Browse files
committed
KVM/arm64 changes for 6.13, part #1 - Support for stage-1 permission indirection (FEAT_S1PIE) and permission overlays (FEAT_S1POE), including nested virt + the emulated page table walker - Introduce PSCI SYSTEM_OFF2 support to KVM + client driver. This call was introduced in PSCIv1.3 as a mechanism to request hibernation, similar to the S4 state in ACPI - Explicitly trap + hide FEAT_MPAM (QoS controls) from KVM guests. As part of it, introduce trivial initialization of the host's MPAM context so KVM can use the corresponding traps - PMU support under nested virtualization, honoring the guest hypervisor's trap configuration and event filtering when running a nested guest - Fixes to vgic ITS serialization where stale device/interrupt table entries are not zeroed when the mapping is invalidated by the VM - Avoid emulated MMIO completion if userspace has requested synchronous external abort injection - Various fixes and cleanups affecting pKVM, vCPU initialization, and selftests
2 parents b467ab8 + 60ad25e commit 7b541d5

Some content is hidden

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

59 files changed

+2859
-461
lines changed

Documentation/arch/arm64/cpu-feature-registers.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,8 @@ infrastructure:
152152
+------------------------------+---------+---------+
153153
| DIT | [51-48] | y |
154154
+------------------------------+---------+---------+
155+
| MPAM | [43-40] | n |
156+
+------------------------------+---------+---------+
155157
| SVE | [35-32] | y |
156158
+------------------------------+---------+---------+
157159
| GIC | [27-24] | n |

Documentation/virt/kvm/api.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6857,6 +6857,10 @@ the first `ndata` items (possibly zero) of the data array are valid.
68576857
the guest issued a SYSTEM_RESET2 call according to v1.1 of the PSCI
68586858
specification.
68596859

6860+
- for arm64, data[0] is set to KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2
6861+
if the guest issued a SYSTEM_OFF2 call according to v1.3 of the PSCI
6862+
specification.
6863+
68606864
- for RISC-V, data[0] is set to the value of the second argument of the
68616865
``sbi_system_reset`` call.
68626866

@@ -6890,6 +6894,12 @@ either:
68906894
- Deny the guest request to suspend the VM. See ARM DEN0022D.b 5.19.2
68916895
"Caller responsibilities" for possible return values.
68926896

6897+
Hibernation using the PSCI SYSTEM_OFF2 call is enabled when PSCI v1.3
6898+
is enabled. If a guest invokes the PSCI SYSTEM_OFF2 function, KVM will
6899+
exit to userspace with the KVM_SYSTEM_EVENT_SHUTDOWN event type and with
6900+
data[0] set to KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2. The only
6901+
supported hibernate type for the SYSTEM_OFF2 function is HIBERNATE_OFF.
6902+
68936903
::
68946904

68956905
/* KVM_EXIT_IOAPIC_EOI */

arch/arm64/include/asm/cpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ struct cpuinfo_arm64 {
4646
u64 reg_revidr;
4747
u64 reg_gmid;
4848
u64 reg_smidr;
49+
u64 reg_mpamidr;
4950

5051
u64 reg_id_aa64dfr0;
5152
u64 reg_id_aa64dfr1;

arch/arm64/include/asm/cpucaps.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ cpucap_is_possible(const unsigned int cap)
6060
return IS_ENABLED(CONFIG_ARM64_WORKAROUND_REPEAT_TLBI);
6161
case ARM64_WORKAROUND_SPECULATIVE_SSBS:
6262
return IS_ENABLED(CONFIG_ARM64_ERRATUM_3194386);
63+
case ARM64_MPAM:
64+
/*
65+
* KVM MPAM support doesn't rely on the host kernel supporting MPAM.
66+
*/
67+
return true;
6368
}
6469

6570
return true;

arch/arm64/include/asm/cpufeature.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,13 @@ static inline bool id_aa64pfr1_sme(u64 pfr1)
612612
return val > 0;
613613
}
614614

615+
static inline bool id_aa64pfr0_mpam(u64 pfr0)
616+
{
617+
u32 val = cpuid_feature_extract_unsigned_field(pfr0, ID_AA64PFR0_EL1_MPAM_SHIFT);
618+
619+
return val > 0;
620+
}
621+
615622
static inline bool id_aa64pfr1_mte(u64 pfr1)
616623
{
617624
u32 val = cpuid_feature_extract_unsigned_field(pfr1, ID_AA64PFR1_EL1_MTE_SHIFT);
@@ -838,6 +845,16 @@ static inline bool system_supports_poe(void)
838845
alternative_has_cap_unlikely(ARM64_HAS_S1POE);
839846
}
840847

848+
static __always_inline bool system_supports_mpam(void)
849+
{
850+
return alternative_has_cap_unlikely(ARM64_MPAM);
851+
}
852+
853+
static __always_inline bool system_supports_mpam_hcr(void)
854+
{
855+
return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
856+
}
857+
841858
int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
842859
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);
843860

arch/arm64/include/asm/el2_setup.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,19 @@
220220
msr spsr_el2, x0
221221
.endm
222222

223+
.macro __init_el2_mpam
224+
/* Memory Partitioning And Monitoring: disable EL2 traps */
225+
mrs x1, id_aa64pfr0_el1
226+
ubfx x0, x1, #ID_AA64PFR0_EL1_MPAM_SHIFT, #4
227+
cbz x0, .Lskip_mpam_\@ // skip if no MPAM
228+
msr_s SYS_MPAM2_EL2, xzr // use the default partition
229+
// and disable lower traps
230+
mrs_s x0, SYS_MPAMIDR_EL1
231+
tbz x0, #MPAMIDR_EL1_HAS_HCR_SHIFT, .Lskip_mpam_\@ // skip if no MPAMHCR reg
232+
msr_s SYS_MPAMHCR_EL2, xzr // clear TRAP_MPAMIDR_EL1 -> EL2
233+
.Lskip_mpam_\@:
234+
.endm
235+
223236
/**
224237
* Initialize EL2 registers to sane values. This should be called early on all
225238
* cores that were booted in EL2. Note that everything gets initialised as
@@ -237,6 +250,7 @@
237250
__init_el2_stage2
238251
__init_el2_gicv3
239252
__init_el2_hstr
253+
__init_el2_mpam
240254
__init_el2_nvhe_idregs
241255
__init_el2_cptr
242256
__init_el2_fgt

arch/arm64/include/asm/kvm_arm.h

Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
#define HCR_HOST_VHE_FLAGS (HCR_RW | HCR_TGE | HCR_E2H)
104104

105105
#define HCRX_HOST_FLAGS (HCRX_EL2_MSCEn | HCRX_EL2_TCR2En | HCRX_EL2_EnFPM)
106+
#define MPAMHCR_HOST_FLAGS 0
106107

107108
/* TCR_EL2 Registers bits */
108109
#define TCR_EL2_DS (1UL << 32)
@@ -311,35 +312,6 @@
311312
GENMASK(19, 18) | \
312313
GENMASK(15, 0))
313314

314-
/* Hyp Debug Configuration Register bits */
315-
#define MDCR_EL2_E2TB_MASK (UL(0x3))
316-
#define MDCR_EL2_E2TB_SHIFT (UL(24))
317-
#define MDCR_EL2_HPMFZS (UL(1) << 36)
318-
#define MDCR_EL2_HPMFZO (UL(1) << 29)
319-
#define MDCR_EL2_MTPME (UL(1) << 28)
320-
#define MDCR_EL2_TDCC (UL(1) << 27)
321-
#define MDCR_EL2_HLP (UL(1) << 26)
322-
#define MDCR_EL2_HCCD (UL(1) << 23)
323-
#define MDCR_EL2_TTRF (UL(1) << 19)
324-
#define MDCR_EL2_HPMD (UL(1) << 17)
325-
#define MDCR_EL2_TPMS (UL(1) << 14)
326-
#define MDCR_EL2_E2PB_MASK (UL(0x3))
327-
#define MDCR_EL2_E2PB_SHIFT (UL(12))
328-
#define MDCR_EL2_TDRA (UL(1) << 11)
329-
#define MDCR_EL2_TDOSA (UL(1) << 10)
330-
#define MDCR_EL2_TDA (UL(1) << 9)
331-
#define MDCR_EL2_TDE (UL(1) << 8)
332-
#define MDCR_EL2_HPME (UL(1) << 7)
333-
#define MDCR_EL2_TPM (UL(1) << 6)
334-
#define MDCR_EL2_TPMCR (UL(1) << 5)
335-
#define MDCR_EL2_HPMN_MASK (UL(0x1F))
336-
#define MDCR_EL2_RES0 (GENMASK(63, 37) | \
337-
GENMASK(35, 30) | \
338-
GENMASK(25, 24) | \
339-
GENMASK(22, 20) | \
340-
BIT(18) | \
341-
GENMASK(16, 15))
342-
343315
/*
344316
* FGT register definitions
345317
*

arch/arm64/include/asm/kvm_asm.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ enum __kvm_host_smccc_func {
7676
__KVM_HOST_SMCCC_FUNC___kvm_timer_set_cntvoff,
7777
__KVM_HOST_SMCCC_FUNC___vgic_v3_save_vmcr_aprs,
7878
__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
79-
__KVM_HOST_SMCCC_FUNC___pkvm_vcpu_init_traps,
8079
__KVM_HOST_SMCCC_FUNC___pkvm_init_vm,
8180
__KVM_HOST_SMCCC_FUNC___pkvm_init_vcpu,
8281
__KVM_HOST_SMCCC_FUNC___pkvm_teardown_vm,

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,11 @@ static inline bool is_hyp_ctxt(const struct kvm_vcpu *vcpu)
225225
return vcpu_has_nv(vcpu) && __is_hyp_ctxt(&vcpu->arch.ctxt);
226226
}
227227

228+
static inline bool vcpu_is_host_el0(const struct kvm_vcpu *vcpu)
229+
{
230+
return is_hyp_ctxt(vcpu) && !vcpu_is_el2(vcpu);
231+
}
232+
228233
/*
229234
* The layout of SPSR for an AArch32 state is different when observed from an
230235
* AArch64 SPSR_ELx or an AArch32 SPSR_*. This function generates the AArch32
@@ -693,4 +698,8 @@ static inline bool guest_hyp_sve_traps_enabled(const struct kvm_vcpu *vcpu)
693698
return __guest_hyp_cptr_xen_trap_enabled(vcpu, ZEN);
694699
}
695700

701+
static inline void kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
702+
{
703+
vcpu_set_flag(vcpu, GUEST_HAS_PTRAUTH);
704+
}
696705
#endif /* __ARM64_KVM_EMULATE_H__ */

arch/arm64/include/asm/kvm_host.h

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ enum kvm_mode kvm_get_mode(void);
7474
static inline enum kvm_mode kvm_get_mode(void) { return KVM_MODE_NONE; };
7575
#endif
7676

77-
DECLARE_STATIC_KEY_FALSE(userspace_irqchip_in_use);
78-
7977
extern unsigned int __ro_after_init kvm_sve_max_vl;
8078
extern unsigned int __ro_after_init kvm_host_sve_max_vl;
8179
int __init kvm_arm_init_sve(void);
@@ -374,7 +372,7 @@ struct kvm_arch {
374372

375373
u64 ctr_el0;
376374

377-
/* Masks for VNCR-baked sysregs */
375+
/* Masks for VNCR-backed and general EL2 sysregs */
378376
struct kvm_sysreg_masks *sysreg_masks;
379377

380378
/*
@@ -408,6 +406,9 @@ struct kvm_vcpu_fault_info {
408406
r = __VNCR_START__ + ((VNCR_ ## r) / 8), \
409407
__after_##r = __MAX__(__before_##r - 1, r)
410408

409+
#define MARKER(m) \
410+
m, __after_##m = m - 1
411+
411412
enum vcpu_sysreg {
412413
__INVALID_SYSREG__, /* 0 is reserved as an invalid value */
413414
MPIDR_EL1, /* MultiProcessor Affinity Register */
@@ -468,13 +469,15 @@ enum vcpu_sysreg {
468469
/* EL2 registers */
469470
SCTLR_EL2, /* System Control Register (EL2) */
470471
ACTLR_EL2, /* Auxiliary Control Register (EL2) */
471-
MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */
472472
CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
473473
HACR_EL2, /* Hypervisor Auxiliary Control Register */
474474
ZCR_EL2, /* SVE Control Register (EL2) */
475475
TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
476476
TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
477477
TCR_EL2, /* Translation Control Register (EL2) */
478+
PIRE0_EL2, /* Permission Indirection Register 0 (EL2) */
479+
PIR_EL2, /* Permission Indirection Register 1 (EL2) */
480+
POR_EL2, /* Permission Overlay Register 2 (EL2) */
478481
SPSR_EL2, /* EL2 saved program status register */
479482
ELR_EL2, /* EL2 exception link register */
480483
AFSR0_EL2, /* Auxiliary Fault Status Register 0 (EL2) */
@@ -494,7 +497,13 @@ enum vcpu_sysreg {
494497
CNTHV_CTL_EL2,
495498
CNTHV_CVAL_EL2,
496499

497-
__VNCR_START__, /* Any VNCR-capable reg goes after this point */
500+
/* Anything from this can be RES0/RES1 sanitised */
501+
MARKER(__SANITISED_REG_START__),
502+
TCR2_EL2, /* Extended Translation Control Register (EL2) */
503+
MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */
504+
505+
/* Any VNCR-capable reg goes after this point */
506+
MARKER(__VNCR_START__),
498507

499508
VNCR(SCTLR_EL1),/* System Control Register */
500509
VNCR(ACTLR_EL1),/* Auxiliary Control Register */
@@ -554,7 +563,7 @@ struct kvm_sysreg_masks {
554563
struct {
555564
u64 res0;
556565
u64 res1;
557-
} mask[NR_SYS_REGS - __VNCR_START__];
566+
} mask[NR_SYS_REGS - __SANITISED_REG_START__];
558567
};
559568

560569
struct kvm_cpu_context {
@@ -1002,13 +1011,13 @@ static inline u64 *___ctxt_sys_reg(const struct kvm_cpu_context *ctxt, int r)
10021011

10031012
#define ctxt_sys_reg(c,r) (*__ctxt_sys_reg(c,r))
10041013

1005-
u64 kvm_vcpu_sanitise_vncr_reg(const struct kvm_vcpu *, enum vcpu_sysreg);
1014+
u64 kvm_vcpu_apply_reg_masks(const struct kvm_vcpu *, enum vcpu_sysreg, u64);
10061015
#define __vcpu_sys_reg(v,r) \
10071016
(*({ \
10081017
const struct kvm_cpu_context *ctxt = &(v)->arch.ctxt; \
10091018
u64 *__r = __ctxt_sys_reg(ctxt, (r)); \
1010-
if (vcpu_has_nv((v)) && (r) >= __VNCR_START__) \
1011-
*__r = kvm_vcpu_sanitise_vncr_reg((v), (r)); \
1019+
if (vcpu_has_nv((v)) && (r) >= __SANITISED_REG_START__) \
1020+
*__r = kvm_vcpu_apply_reg_masks((v), (r), *__r);\
10121021
__r; \
10131022
}))
10141023

@@ -1037,6 +1046,10 @@ static inline bool __vcpu_read_sys_reg_from_cpu(int reg, u64 *val)
10371046
case TTBR0_EL1: *val = read_sysreg_s(SYS_TTBR0_EL12); break;
10381047
case TTBR1_EL1: *val = read_sysreg_s(SYS_TTBR1_EL12); break;
10391048
case TCR_EL1: *val = read_sysreg_s(SYS_TCR_EL12); break;
1049+
case TCR2_EL1: *val = read_sysreg_s(SYS_TCR2_EL12); break;
1050+
case PIR_EL1: *val = read_sysreg_s(SYS_PIR_EL12); break;
1051+
case PIRE0_EL1: *val = read_sysreg_s(SYS_PIRE0_EL12); break;
1052+
case POR_EL1: *val = read_sysreg_s(SYS_POR_EL12); break;
10401053
case ESR_EL1: *val = read_sysreg_s(SYS_ESR_EL12); break;
10411054
case AFSR0_EL1: *val = read_sysreg_s(SYS_AFSR0_EL12); break;
10421055
case AFSR1_EL1: *val = read_sysreg_s(SYS_AFSR1_EL12); break;
@@ -1083,6 +1096,10 @@ static inline bool __vcpu_write_sys_reg_to_cpu(u64 val, int reg)
10831096
case TTBR0_EL1: write_sysreg_s(val, SYS_TTBR0_EL12); break;
10841097
case TTBR1_EL1: write_sysreg_s(val, SYS_TTBR1_EL12); break;
10851098
case TCR_EL1: write_sysreg_s(val, SYS_TCR_EL12); break;
1099+
case TCR2_EL1: write_sysreg_s(val, SYS_TCR2_EL12); break;
1100+
case PIR_EL1: write_sysreg_s(val, SYS_PIR_EL12); break;
1101+
case PIRE0_EL1: write_sysreg_s(val, SYS_PIRE0_EL12); break;
1102+
case POR_EL1: write_sysreg_s(val, SYS_POR_EL12); break;
10861103
case ESR_EL1: write_sysreg_s(val, SYS_ESR_EL12); break;
10871104
case AFSR0_EL1: write_sysreg_s(val, SYS_AFSR0_EL12); break;
10881105
case AFSR1_EL1: write_sysreg_s(val, SYS_AFSR1_EL12); break;
@@ -1503,4 +1520,13 @@ void kvm_set_vm_id_reg(struct kvm *kvm, u32 reg, u64 val);
15031520
(system_supports_fpmr() && \
15041521
kvm_has_feat((k), ID_AA64PFR2_EL1, FPMR, IMP))
15051522

1523+
#define kvm_has_tcr2(k) \
1524+
(kvm_has_feat((k), ID_AA64MMFR3_EL1, TCRX, IMP))
1525+
1526+
#define kvm_has_s1pie(k) \
1527+
(kvm_has_feat((k), ID_AA64MMFR3_EL1, S1PIE, IMP))
1528+
1529+
#define kvm_has_s1poe(k) \
1530+
(kvm_has_feat((k), ID_AA64MMFR3_EL1, S1POE, IMP))
1531+
15061532
#endif /* __ARM64_KVM_HOST_H__ */

arch/arm64/include/asm/sysreg.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -542,18 +542,6 @@
542542

543543
#define SYS_MAIR_EL2 sys_reg(3, 4, 10, 2, 0)
544544
#define SYS_AMAIR_EL2 sys_reg(3, 4, 10, 3, 0)
545-
#define SYS_MPAMHCR_EL2 sys_reg(3, 4, 10, 4, 0)
546-
#define SYS_MPAMVPMV_EL2 sys_reg(3, 4, 10, 4, 1)
547-
#define SYS_MPAM2_EL2 sys_reg(3, 4, 10, 5, 0)
548-
#define __SYS__MPAMVPMx_EL2(x) sys_reg(3, 4, 10, 6, x)
549-
#define SYS_MPAMVPM0_EL2 __SYS__MPAMVPMx_EL2(0)
550-
#define SYS_MPAMVPM1_EL2 __SYS__MPAMVPMx_EL2(1)
551-
#define SYS_MPAMVPM2_EL2 __SYS__MPAMVPMx_EL2(2)
552-
#define SYS_MPAMVPM3_EL2 __SYS__MPAMVPMx_EL2(3)
553-
#define SYS_MPAMVPM4_EL2 __SYS__MPAMVPMx_EL2(4)
554-
#define SYS_MPAMVPM5_EL2 __SYS__MPAMVPMx_EL2(5)
555-
#define SYS_MPAMVPM6_EL2 __SYS__MPAMVPMx_EL2(6)
556-
#define SYS_MPAMVPM7_EL2 __SYS__MPAMVPMx_EL2(7)
557545

558546
#define SYS_VBAR_EL2 sys_reg(3, 4, 12, 0, 0)
559547
#define SYS_RVBAR_EL2 sys_reg(3, 4, 12, 0, 1)

arch/arm64/include/asm/vncr_mapping.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
#define VNCR_VBAR_EL1 0x250
5151
#define VNCR_TCR2_EL1 0x270
5252
#define VNCR_PIRE0_EL1 0x290
53-
#define VNCR_PIRE0_EL2 0x298
5453
#define VNCR_PIR_EL1 0x2A0
5554
#define VNCR_POR_EL1 0x2A8
5655
#define VNCR_ICH_LR0_EL2 0x400

arch/arm64/include/uapi/asm/kvm.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,12 @@ enum {
484484
*/
485485
#define KVM_SYSTEM_EVENT_RESET_FLAG_PSCI_RESET2 (1ULL << 0)
486486

487+
/*
488+
* Shutdown caused by a PSCI v1.3 SYSTEM_OFF2 call.
489+
* Valid only when the system event has a type of KVM_SYSTEM_EVENT_SHUTDOWN.
490+
*/
491+
#define KVM_SYSTEM_EVENT_SHUTDOWN_FLAG_PSCI_OFF2 (1ULL << 0)
492+
487493
/* run->fail_entry.hardware_entry_failure_reason codes. */
488494
#define KVM_EXIT_FAIL_ENTRY_CPU_UNSUPPORTED (1ULL << 0)
489495

0 commit comments

Comments
 (0)