Skip to content

Commit 0afd104

Browse files
committed
KVM/arm64 updates for 6.15 - Nested virtualization support for VGICv3, giving the nested hypervisor control of the VGIC hardware when running an L2 VM - Removal of 'late' nested virtualization feature register masking, making the supported feature set directly visible to userspace - Support for emulating FEAT_PMUv3 on Apple silicon, taking advantage of an IMPLEMENTATION DEFINED trap that covers all PMUv3 registers - Paravirtual interface for discovering the set of CPU implementations where a VM may run, addressing a longstanding issue of guest CPU errata awareness in big-little systems and cross-implementation VM migration - Userspace control of the registers responsible for identifying a particular CPU implementation (MIDR_EL1, REVIDR_EL1, AIDR_EL1), allowing VMs to be migrated cross-implementation - pKVM updates, including support for tracking stage-2 page table allocations in the protected hypervisor in the 'SecPageTable' stat - Fixes to vPMU, ensuring that userspace updates to the vPMU after KVM_RUN are reflected into the backing perf events
2 parents c0f99fb + 369c012 commit 0afd104

Some content is hidden

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

72 files changed

+2173
-752
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8262,6 +8262,24 @@ KVM exits with the register state of either the L1 or L2 guest
82628262
depending on which executed at the time of an exit. Userspace must
82638263
take care to differentiate between these cases.
82648264

8265+
7.37 KVM_CAP_ARM_WRITABLE_IMP_ID_REGS
8266+
-------------------------------------
8267+
8268+
:Architectures: arm64
8269+
:Target: VM
8270+
:Parameters: None
8271+
:Returns: 0 on success, -EINVAL if vCPUs have been created before enabling this
8272+
capability.
8273+
8274+
This capability changes the behavior of the registers that identify a PE
8275+
implementation of the Arm architecture: MIDR_EL1, REVIDR_EL1, and AIDR_EL1.
8276+
By default, these registers are visible to userspace but treated as invariant.
8277+
8278+
When this capability is enabled, KVM allows userspace to change the
8279+
aforementioned registers before the first KVM_RUN. These registers are VM
8280+
scoped, meaning that the same set of values are presented on all vCPUs in a
8281+
given VM.
8282+
82658283
8. Other capabilities.
82668284
======================
82678285

Documentation/virt/kvm/arm/fw-pseudo-registers.rst

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ The pseudo-firmware bitmap register are as follows:
116116
ARM DEN0057A.
117117

118118
* KVM_REG_ARM_VENDOR_HYP_BMAP:
119-
Controls the bitmap of the Vendor specific Hypervisor Service Calls.
119+
Controls the bitmap of the Vendor specific Hypervisor Service Calls[0-63].
120120

121121
The following bits are accepted:
122122

@@ -127,6 +127,19 @@ The pseudo-firmware bitmap register are as follows:
127127
Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_PTP:
128128
The bit represents the Precision Time Protocol KVM service.
129129

130+
* KVM_REG_ARM_VENDOR_HYP_BMAP_2:
131+
Controls the bitmap of the Vendor specific Hypervisor Service Calls[64-127].
132+
133+
The following bits are accepted:
134+
135+
Bit-0: KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_VER
136+
This represents the ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID
137+
function-id. This is reset to 0.
138+
139+
Bit-1: KVM_REG_ARM_VENDOR_HYP_BIT_DISCOVER_IMPL_CPUS
140+
This represents the ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID
141+
function-id. This is reset to 0.
142+
130143
Errors:
131144

132145
======= =============================================================

Documentation/virt/kvm/arm/hypercalls.rst

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,62 @@ region is equal to the memory protection granule advertised by
142142
| | | +---------------------------------------------+
143143
| | | | ``INVALID_PARAMETER (-3)`` |
144144
+---------------------+----------+----+---------------------------------------------+
145+
146+
``ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_VER_FUNC_ID``
147+
-------------------------------------------------------
148+
Request the target CPU implementation version information and the number of target
149+
implementations for the Guest VM.
150+
151+
+---------------------+-------------------------------------------------------------+
152+
| Presence: | Optional; KVM/ARM64 Guests only |
153+
+---------------------+-------------------------------------------------------------+
154+
| Calling convention: | HVC64 |
155+
+---------------------+----------+--------------------------------------------------+
156+
| Function ID: | (uint32) | 0xC6000040 |
157+
+---------------------+----------+--------------------------------------------------+
158+
| Arguments: | None |
159+
+---------------------+----------+----+---------------------------------------------+
160+
| Return Values: | (int64) | R0 | ``SUCCESS (0)`` |
161+
| | | +---------------------------------------------+
162+
| | | | ``NOT_SUPPORTED (-1)`` |
163+
| +----------+----+---------------------------------------------+
164+
| | (uint64) | R1 | Bits [63:32] Reserved/Must be zero |
165+
| | | +---------------------------------------------+
166+
| | | | Bits [31:16] Major version |
167+
| | | +---------------------------------------------+
168+
| | | | Bits [15:0] Minor version |
169+
| +----------+----+---------------------------------------------+
170+
| | (uint64) | R2 | Number of target implementations |
171+
| +----------+----+---------------------------------------------+
172+
| | (uint64) | R3 | Reserved / Must be zero |
173+
+---------------------+----------+----+---------------------------------------------+
174+
175+
``ARM_SMCCC_VENDOR_HYP_KVM_DISCOVER_IMPL_CPUS_FUNC_ID``
176+
-------------------------------------------------------
177+
178+
Request the target CPU implementation information for the Guest VM. The Guest kernel
179+
will use this information to enable the associated errata.
180+
181+
+---------------------+-------------------------------------------------------------+
182+
| Presence: | Optional; KVM/ARM64 Guests only |
183+
+---------------------+-------------------------------------------------------------+
184+
| Calling convention: | HVC64 |
185+
+---------------------+----------+--------------------------------------------------+
186+
| Function ID: | (uint32) | 0xC6000041 |
187+
+---------------------+----------+----+---------------------------------------------+
188+
| Arguments: | (uint64) | R1 | selected implementation index |
189+
| +----------+----+---------------------------------------------+
190+
| | (uint64) | R2 | Reserved / Must be zero |
191+
| +----------+----+---------------------------------------------+
192+
| | (uint64) | R3 | Reserved / Must be zero |
193+
+---------------------+----------+----+---------------------------------------------+
194+
| Return Values: | (int64) | R0 | ``SUCCESS (0)`` |
195+
| | | +---------------------------------------------+
196+
| | | | ``INVALID_PARAMETER (-3)`` |
197+
| +----------+----+---------------------------------------------+
198+
| | (uint64) | R1 | MIDR_EL1 of the selected implementation |
199+
| +----------+----+---------------------------------------------+
200+
| | (uint64) | R2 | REVIDR_EL1 of the selected implementation |
201+
| +----------+----+---------------------------------------------+
202+
| | (uint64) | R3 | AIDR_EL1 of the selected implementation |
203+
+---------------------+----------+----+---------------------------------------------+

Documentation/virt/kvm/devices/arm-vgic-its.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,8 @@ KVM_DEV_ARM_VGIC_GRP_ITS_REGS
126126
ITS Restore Sequence:
127127
---------------------
128128

129-
The following ordering must be followed when restoring the GIC and the ITS:
129+
The following ordering must be followed when restoring the GIC, ITS, and
130+
KVM_IRQFD assignments:
130131

131132
a) restore all guest memory and create vcpus
132133
b) restore all redistributors
@@ -139,6 +140,8 @@ d) restore the ITS in the following order:
139140
3. Load the ITS table data (KVM_DEV_ARM_ITS_RESTORE_TABLES)
140141
4. Restore GITS_CTLR
141142

143+
e) restore KVM_IRQFD assignments for MSIs
144+
142145
Then vcpus can be started.
143146

144147
ITS Table ABI REV0:

Documentation/virt/kvm/devices/arm-vgic-v3.rst

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,8 +291,18 @@ Groups:
291291
| Aff3 | Aff2 | Aff1 | Aff0 |
292292

293293
Errors:
294-
295294
======= =============================================
296295
-EINVAL vINTID is not multiple of 32 or info field is
297296
not VGIC_LEVEL_INFO_LINE_LEVEL
298297
======= =============================================
298+
299+
KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ
300+
Attributes:
301+
302+
The attr field of kvm_device_attr encodes the following values:
303+
304+
bits: | 31 .... 5 | 4 .... 0 |
305+
values: | RES0 | vINTID |
306+
307+
The vINTID specifies which interrupt is generated when the vGIC
308+
must generate a maintenance interrupt. This must be a PPI.

arch/arm64/include/asm/apple_m1_pmu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
#define PMCR0_PMI_ENABLE_8_9 GENMASK(45, 44)
3838

3939
#define SYS_IMP_APL_PMCR1_EL1 sys_reg(3, 1, 15, 1, 0)
40+
#define SYS_IMP_APL_PMCR1_EL12 sys_reg(3, 1, 15, 7, 2)
4041
#define PMCR1_COUNT_A64_EL0_0_7 GENMASK(15, 8)
4142
#define PMCR1_COUNT_A64_EL1_0_7 GENMASK(23, 16)
4243
#define PMCR1_COUNT_A64_EL0_8_9 GENMASK(41, 40)

arch/arm64/include/asm/cpucaps.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ cpucap_is_possible(const unsigned int cap)
7171
* KVM MPAM support doesn't rely on the host kernel supporting MPAM.
7272
*/
7373
return true;
74+
case ARM64_HAS_PMUV3:
75+
return IS_ENABLED(CONFIG_HW_PERF_EVENTS);
7476
}
7577

7678
return true;

arch/arm64/include/asm/cpufeature.h

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -525,29 +525,6 @@ cpuid_feature_extract_unsigned_field(u64 features, int field)
525525
return cpuid_feature_extract_unsigned_field_width(features, field, 4);
526526
}
527527

528-
/*
529-
* Fields that identify the version of the Performance Monitors Extension do
530-
* not follow the standard ID scheme. See ARM DDI 0487E.a page D13-2825,
531-
* "Alternative ID scheme used for the Performance Monitors Extension version".
532-
*/
533-
static inline u64 __attribute_const__
534-
cpuid_feature_cap_perfmon_field(u64 features, int field, u64 cap)
535-
{
536-
u64 val = cpuid_feature_extract_unsigned_field(features, field);
537-
u64 mask = GENMASK_ULL(field + 3, field);
538-
539-
/* Treat IMPLEMENTATION DEFINED functionality as unimplemented */
540-
if (val == ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
541-
val = 0;
542-
543-
if (val > cap) {
544-
features &= ~mask;
545-
features |= (cap << field) & mask;
546-
}
547-
548-
return features;
549-
}
550-
551528
static inline u64 arm64_ftr_mask(const struct arm64_ftr_bits *ftrp)
552529
{
553530
return (u64)GENMASK(ftrp->shift + ftrp->width - 1, ftrp->shift);
@@ -866,6 +843,11 @@ static __always_inline bool system_supports_mpam_hcr(void)
866843
return alternative_has_cap_unlikely(ARM64_MPAM_HCR);
867844
}
868845

846+
static inline bool system_supports_pmuv3(void)
847+
{
848+
return cpus_have_final_cap(ARM64_HAS_PMUV3);
849+
}
850+
869851
int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt);
870852
bool try_emulate_mrs(struct pt_regs *regs, u32 isn);
871853

arch/arm64/include/asm/cputype.h

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,16 @@
231231

232232
#define read_cpuid(reg) read_sysreg_s(SYS_ ## reg)
233233

234+
/*
235+
* The CPU ID never changes at run time, so we might as well tell the
236+
* compiler that it's constant. Use this function to read the CPU ID
237+
* rather than directly reading processor_id or read_cpuid() directly.
238+
*/
239+
static inline u32 __attribute_const__ read_cpuid_id(void)
240+
{
241+
return read_cpuid(MIDR_EL1);
242+
}
243+
234244
/*
235245
* Represent a range of MIDR values for a given CPU model and a
236246
* range of variant/revision values.
@@ -266,30 +276,14 @@ static inline bool midr_is_cpu_model_range(u32 midr, u32 model, u32 rv_min,
266276
return _model == model && rv >= rv_min && rv <= rv_max;
267277
}
268278

269-
static inline bool is_midr_in_range(u32 midr, struct midr_range const *range)
270-
{
271-
return midr_is_cpu_model_range(midr, range->model,
272-
range->rv_min, range->rv_max);
273-
}
274-
275-
static inline bool
276-
is_midr_in_range_list(u32 midr, struct midr_range const *ranges)
277-
{
278-
while (ranges->model)
279-
if (is_midr_in_range(midr, ranges++))
280-
return true;
281-
return false;
282-
}
279+
struct target_impl_cpu {
280+
u64 midr;
281+
u64 revidr;
282+
u64 aidr;
283+
};
283284

284-
/*
285-
* The CPU ID never changes at run time, so we might as well tell the
286-
* compiler that it's constant. Use this function to read the CPU ID
287-
* rather than directly reading processor_id or read_cpuid() directly.
288-
*/
289-
static inline u32 __attribute_const__ read_cpuid_id(void)
290-
{
291-
return read_cpuid(MIDR_EL1);
292-
}
285+
bool cpu_errata_set_target_impl(u64 num, void *impl_cpus);
286+
bool is_midr_in_range_list(struct midr_range const *ranges);
293287

294288
static inline u64 __attribute_const__ read_cpuid_mpidr(void)
295289
{

arch/arm64/include/asm/hypervisor.h

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

77
void kvm_init_hyp_services(void);
88
bool kvm_arm_hyp_service_available(u32 func_id);
9+
void kvm_arm_target_impl_cpu_init(void);
910

1011
#ifdef CONFIG_ARM_PKVM_GUEST
1112
void pkvm_init_hyp_services(void);

0 commit comments

Comments
 (0)