Skip to content

Commit 5d26eaa

Browse files
committed
Merge tag 'kvmarm-fixes-6.18-1' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 fixes for 6.18, take #1 Improvements and bug fixes: - Fix the handling of ZCR_EL2 in NV VMs (20250926194108.84093-1-oliver.upton@linux.dev) - Pick the correct translation regime when doing a PTW on the back of a SEA (20250926224246.731748-1-oliver.upton@linux.dev) - Prevent userspace from injecting an event into a vcpu that isn't initialised yet (20250930085237.108326-1-oliver.upton@linux.dev) - Move timer save/restore to the sysreg handling code, fixing EL2 timer access in the process (20250929160458.3351788-1-maz@kernel.org) - Add FGT-based trapping of MDSCR_EL1 to reduce the overhead of debug (20250924235150.617451-1-oliver.upton@linux.dev) - Fix trapping configuration when the host isn't GICv3 (20251007160704.1673584-1-sascha.bischoff@arm.com) - Improve the detection of HCR_EL2.E2H being RES1 (20251009121239.29370-1-maz@kernel.org) - Drop a spurious 'break' statement in the S1 PTW (20250930135621.162050-1-osama.abdelkader@gmail.com) - Don't try to access SPE when owned by EL3 (20251010174707.1684200-1-mukesh.ojha@oss.qualcomm.com) Documentation updates: - Document the failure modes of event injection (20250930233620.124607-1-oliver.upton@linux.dev) - Document that a GICv3 guest can be created on a GICv5 host with FEAT_GCIE_LEGACY (20251007154848.1640444-1-sascha.bischoff@arm.com) Selftest improvements: - Add a selftest for the effective value of HCR_EL2.AMO (20250926224454.734066-1-oliver.upton@linux.dev) - Address build warning in the timer selftest when building with clang (20250926155838.2612205-1-seanjc@google.com) - Teach irq_fd selftests about non-x86 architectures (20250930193301.119859-1-oliver.upton@linux.dev) - Add missing sysregs to the set_id_regs selftest (20251012154352.61133-1-zenghui.yu@linux.dev) - Fix vcpu allocation in the vgic_lpi_stress selftest (20251008154520.54801-1-zenghui.yu@linux.dev) - Correctly enable interrupts in the vgic_lpi_stress selftest (20251007195254.260539-1-oliver.upton@linux.dev)
2 parents 3a86608 + ca88ecd commit 5d26eaa

File tree

30 files changed

+565
-354
lines changed

30 files changed

+565
-354
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1229,6 +1229,9 @@ It is not possible to read back a pending external abort (injected via
12291229
KVM_SET_VCPU_EVENTS or otherwise) because such an exception is always delivered
12301230
directly to the virtual CPU).
12311231

1232+
Calling this ioctl on a vCPU that hasn't been initialized will return
1233+
-ENOEXEC.
1234+
12321235
::
12331236

12341237
struct kvm_vcpu_events {
@@ -1309,6 +1312,8 @@ exceptions by manipulating individual registers using the KVM_SET_ONE_REG API.
13091312

13101313
See KVM_GET_VCPU_EVENTS for the data structure.
13111314

1315+
Calling this ioctl on a vCPU that hasn't been initialized will return
1316+
-ENOEXEC.
13121317

13131318
4.33 KVM_GET_DEBUGREGS
13141319
----------------------

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ will act as the VM interrupt controller, requiring emulated user-space devices
1313
to inject interrupts to the VGIC instead of directly to CPUs. It is not
1414
possible to create both a GICv3 and GICv2 on the same VM.
1515

16-
Creating a guest GICv3 device requires a host GICv3 as well.
16+
Creating a guest GICv3 device requires a host GICv3 host, or a GICv5 host with
17+
support for FEAT_GCIE_LEGACY.
1718

1819

1920
Groups:

arch/arm64/include/asm/el2_setup.h

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,48 @@
2424
* ID_AA64MMFR4_EL1.E2H0 < 0. On such CPUs HCR_EL2.E2H is RES1, but it
2525
* can reset into an UNKNOWN state and might not read as 1 until it has
2626
* been initialized explicitly.
27-
*
28-
* Fruity CPUs seem to have HCR_EL2.E2H set to RAO/WI, but
29-
* don't advertise it (they predate this relaxation).
30-
*
3127
* Initalize HCR_EL2.E2H so that later code can rely upon HCR_EL2.E2H
3228
* indicating whether the CPU is running in E2H mode.
3329
*/
3430
mrs_s x1, SYS_ID_AA64MMFR4_EL1
3531
sbfx x1, x1, #ID_AA64MMFR4_EL1_E2H0_SHIFT, #ID_AA64MMFR4_EL1_E2H0_WIDTH
3632
cmp x1, #0
37-
b.ge .LnVHE_\@
33+
b.lt .LnE2H0_\@
3834

35+
/*
36+
* Unfortunately, HCR_EL2.E2H can be RES1 even if not advertised
37+
* as such via ID_AA64MMFR4_EL1.E2H0:
38+
*
39+
* - Fruity CPUs predate the !FEAT_E2H0 relaxation, and seem to
40+
* have HCR_EL2.E2H implemented as RAO/WI.
41+
*
42+
* - On CPUs that lack FEAT_FGT, a hypervisor can't trap guest
43+
* reads of ID_AA64MMFR4_EL1 to advertise !FEAT_E2H0. NV
44+
* guests on these hosts can write to HCR_EL2.E2H without
45+
* trapping to the hypervisor, but these writes have no
46+
* functional effect.
47+
*
48+
* Handle both cases by checking for an essential VHE property
49+
* (system register remapping) to decide whether we're
50+
* effectively VHE-only or not.
51+
*/
52+
msr_hcr_el2 x0 // Setup HCR_EL2 as nVHE
53+
isb
54+
mov x1, #1 // Write something to FAR_EL1
55+
msr far_el1, x1
56+
isb
57+
mov x1, #2 // Try to overwrite it via FAR_EL2
58+
msr far_el2, x1
59+
isb
60+
mrs x1, far_el1 // If we see the latest write in FAR_EL1,
61+
cmp x1, #2 // we can safely assume we are VHE only.
62+
b.ne .LnVHE_\@ // Otherwise, we know that nVHE works.
63+
64+
.LnE2H0_\@:
3965
orr x0, x0, #HCR_E2H
40-
.LnVHE_\@:
4166
msr_hcr_el2 x0
4267
isb
68+
.LnVHE_\@:
4369
.endm
4470

4571
.macro __init_el2_sctlr

arch/arm64/include/asm/kvm_host.h

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -816,6 +816,11 @@ struct kvm_vcpu_arch {
816816
u64 hcrx_el2;
817817
u64 mdcr_el2;
818818

819+
struct {
820+
u64 r;
821+
u64 w;
822+
} fgt[__NR_FGT_GROUP_IDS__];
823+
819824
/* Exception Information */
820825
struct kvm_vcpu_fault_info fault;
821826

@@ -1600,6 +1605,51 @@ static inline bool kvm_arch_has_irq_bypass(void)
16001605
void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt);
16011606
void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *res1);
16021607
void check_feature_map(void);
1608+
void kvm_vcpu_load_fgt(struct kvm_vcpu *vcpu);
1609+
1610+
static __always_inline enum fgt_group_id __fgt_reg_to_group_id(enum vcpu_sysreg reg)
1611+
{
1612+
switch (reg) {
1613+
case HFGRTR_EL2:
1614+
case HFGWTR_EL2:
1615+
return HFGRTR_GROUP;
1616+
case HFGITR_EL2:
1617+
return HFGITR_GROUP;
1618+
case HDFGRTR_EL2:
1619+
case HDFGWTR_EL2:
1620+
return HDFGRTR_GROUP;
1621+
case HAFGRTR_EL2:
1622+
return HAFGRTR_GROUP;
1623+
case HFGRTR2_EL2:
1624+
case HFGWTR2_EL2:
1625+
return HFGRTR2_GROUP;
1626+
case HFGITR2_EL2:
1627+
return HFGITR2_GROUP;
1628+
case HDFGRTR2_EL2:
1629+
case HDFGWTR2_EL2:
1630+
return HDFGRTR2_GROUP;
1631+
default:
1632+
BUILD_BUG_ON(1);
1633+
}
1634+
}
16031635

1636+
#define vcpu_fgt(vcpu, reg) \
1637+
({ \
1638+
enum fgt_group_id id = __fgt_reg_to_group_id(reg); \
1639+
u64 *p; \
1640+
switch (reg) { \
1641+
case HFGWTR_EL2: \
1642+
case HDFGWTR_EL2: \
1643+
case HFGWTR2_EL2: \
1644+
case HDFGWTR2_EL2: \
1645+
p = &(vcpu)->arch.fgt[id].w; \
1646+
break; \
1647+
default: \
1648+
p = &(vcpu)->arch.fgt[id].r; \
1649+
break; \
1650+
} \
1651+
\
1652+
p; \
1653+
})
16041654

16051655
#endif /* __ARM64_KVM_HOST_H__ */

arch/arm64/kvm/arch_timer.c

Lines changed: 14 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ static int nr_timers(struct kvm_vcpu *vcpu)
6666

6767
u32 timer_get_ctl(struct arch_timer_context *ctxt)
6868
{
69-
struct kvm_vcpu *vcpu = ctxt->vcpu;
69+
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctxt);
7070

7171
switch(arch_timer_ctx_index(ctxt)) {
7272
case TIMER_VTIMER:
@@ -85,7 +85,7 @@ u32 timer_get_ctl(struct arch_timer_context *ctxt)
8585

8686
u64 timer_get_cval(struct arch_timer_context *ctxt)
8787
{
88-
struct kvm_vcpu *vcpu = ctxt->vcpu;
88+
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctxt);
8989

9090
switch(arch_timer_ctx_index(ctxt)) {
9191
case TIMER_VTIMER:
@@ -104,7 +104,7 @@ u64 timer_get_cval(struct arch_timer_context *ctxt)
104104

105105
static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
106106
{
107-
struct kvm_vcpu *vcpu = ctxt->vcpu;
107+
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctxt);
108108

109109
switch(arch_timer_ctx_index(ctxt)) {
110110
case TIMER_VTIMER:
@@ -126,7 +126,7 @@ static void timer_set_ctl(struct arch_timer_context *ctxt, u32 ctl)
126126

127127
static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
128128
{
129-
struct kvm_vcpu *vcpu = ctxt->vcpu;
129+
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctxt);
130130

131131
switch(arch_timer_ctx_index(ctxt)) {
132132
case TIMER_VTIMER:
@@ -146,16 +146,6 @@ static void timer_set_cval(struct arch_timer_context *ctxt, u64 cval)
146146
}
147147
}
148148

149-
static void timer_set_offset(struct arch_timer_context *ctxt, u64 offset)
150-
{
151-
if (!ctxt->offset.vm_offset) {
152-
WARN(offset, "timer %ld\n", arch_timer_ctx_index(ctxt));
153-
return;
154-
}
155-
156-
WRITE_ONCE(*ctxt->offset.vm_offset, offset);
157-
}
158-
159149
u64 kvm_phys_timer_read(void)
160150
{
161151
return timecounter->cc->read(timecounter->cc);
@@ -343,7 +333,7 @@ static enum hrtimer_restart kvm_hrtimer_expire(struct hrtimer *hrt)
343333
u64 ns;
344334

345335
ctx = container_of(hrt, struct arch_timer_context, hrtimer);
346-
vcpu = ctx->vcpu;
336+
vcpu = timer_context_to_vcpu(ctx);
347337

348338
trace_kvm_timer_hrtimer_expire(ctx);
349339

@@ -436,8 +426,9 @@ static void kvm_timer_update_status(struct arch_timer_context *ctx, bool level)
436426
*
437427
* But hey, it's fast, right?
438428
*/
439-
if (is_hyp_ctxt(ctx->vcpu) &&
440-
(ctx == vcpu_vtimer(ctx->vcpu) || ctx == vcpu_ptimer(ctx->vcpu))) {
429+
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctx);
430+
if (is_hyp_ctxt(vcpu) &&
431+
(ctx == vcpu_vtimer(vcpu) || ctx == vcpu_ptimer(vcpu))) {
441432
unsigned long val = timer_get_ctl(ctx);
442433
__assign_bit(__ffs(ARCH_TIMER_CTRL_IT_STAT), &val, level);
443434
timer_set_ctl(ctx, val);
@@ -470,7 +461,7 @@ static void timer_emulate(struct arch_timer_context *ctx)
470461
trace_kvm_timer_emulate(ctx, should_fire);
471462

472463
if (should_fire != ctx->irq.level)
473-
kvm_timer_update_irq(ctx->vcpu, should_fire, ctx);
464+
kvm_timer_update_irq(timer_context_to_vcpu(ctx), should_fire, ctx);
474465

475466
kvm_timer_update_status(ctx, should_fire);
476467

@@ -498,7 +489,7 @@ static void set_cntpoff(u64 cntpoff)
498489

499490
static void timer_save_state(struct arch_timer_context *ctx)
500491
{
501-
struct arch_timer_cpu *timer = vcpu_timer(ctx->vcpu);
492+
struct arch_timer_cpu *timer = vcpu_timer(timer_context_to_vcpu(ctx));
502493
enum kvm_arch_timers index = arch_timer_ctx_index(ctx);
503494
unsigned long flags;
504495

@@ -609,7 +600,7 @@ static void kvm_timer_unblocking(struct kvm_vcpu *vcpu)
609600

610601
static void timer_restore_state(struct arch_timer_context *ctx)
611602
{
612-
struct arch_timer_cpu *timer = vcpu_timer(ctx->vcpu);
603+
struct arch_timer_cpu *timer = vcpu_timer(timer_context_to_vcpu(ctx));
613604
enum kvm_arch_timers index = arch_timer_ctx_index(ctx);
614605
unsigned long flags;
615606

@@ -668,7 +659,7 @@ static inline void set_timer_irq_phys_active(struct arch_timer_context *ctx, boo
668659

669660
static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx)
670661
{
671-
struct kvm_vcpu *vcpu = ctx->vcpu;
662+
struct kvm_vcpu *vcpu = timer_context_to_vcpu(ctx);
672663
bool phys_active = false;
673664

674665
/*
@@ -677,7 +668,7 @@ static void kvm_timer_vcpu_load_gic(struct arch_timer_context *ctx)
677668
* this point and the register restoration, we'll take the
678669
* interrupt anyway.
679670
*/
680-
kvm_timer_update_irq(ctx->vcpu, kvm_timer_should_fire(ctx), ctx);
671+
kvm_timer_update_irq(vcpu, kvm_timer_should_fire(ctx), ctx);
681672

682673
if (irqchip_in_kernel(vcpu->kvm))
683674
phys_active = kvm_vgic_map_is_active(vcpu, timer_irq(ctx));
@@ -1063,7 +1054,7 @@ static void timer_context_init(struct kvm_vcpu *vcpu, int timerid)
10631054
struct arch_timer_context *ctxt = vcpu_get_timer(vcpu, timerid);
10641055
struct kvm *kvm = vcpu->kvm;
10651056

1066-
ctxt->vcpu = vcpu;
1057+
ctxt->timer_id = timerid;
10671058

10681059
if (timerid == TIMER_VTIMER)
10691060
ctxt->offset.vm_offset = &kvm->arch.timer_data.voffset;
@@ -1121,49 +1112,6 @@ void kvm_timer_cpu_down(void)
11211112
disable_percpu_irq(host_ptimer_irq);
11221113
}
11231114

1124-
int kvm_arm_timer_set_reg(struct kvm_vcpu *vcpu, u64 regid, u64 value)
1125-
{
1126-
struct arch_timer_context *timer;
1127-
1128-
switch (regid) {
1129-
case KVM_REG_ARM_TIMER_CTL:
1130-
timer = vcpu_vtimer(vcpu);
1131-
kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
1132-
break;
1133-
case KVM_REG_ARM_TIMER_CNT:
1134-
if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET,
1135-
&vcpu->kvm->arch.flags)) {
1136-
timer = vcpu_vtimer(vcpu);
1137-
timer_set_offset(timer, kvm_phys_timer_read() - value);
1138-
}
1139-
break;
1140-
case KVM_REG_ARM_TIMER_CVAL:
1141-
timer = vcpu_vtimer(vcpu);
1142-
kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value);
1143-
break;
1144-
case KVM_REG_ARM_PTIMER_CTL:
1145-
timer = vcpu_ptimer(vcpu);
1146-
kvm_arm_timer_write(vcpu, timer, TIMER_REG_CTL, value);
1147-
break;
1148-
case KVM_REG_ARM_PTIMER_CNT:
1149-
if (!test_bit(KVM_ARCH_FLAG_VM_COUNTER_OFFSET,
1150-
&vcpu->kvm->arch.flags)) {
1151-
timer = vcpu_ptimer(vcpu);
1152-
timer_set_offset(timer, kvm_phys_timer_read() - value);
1153-
}
1154-
break;
1155-
case KVM_REG_ARM_PTIMER_CVAL:
1156-
timer = vcpu_ptimer(vcpu);
1157-
kvm_arm_timer_write(vcpu, timer, TIMER_REG_CVAL, value);
1158-
break;
1159-
1160-
default:
1161-
return -1;
1162-
}
1163-
1164-
return 0;
1165-
}
1166-
11671115
static u64 read_timer_ctl(struct arch_timer_context *timer)
11681116
{
11691117
/*
@@ -1180,31 +1128,6 @@ static u64 read_timer_ctl(struct arch_timer_context *timer)
11801128
return ctl;
11811129
}
11821130

1183-
u64 kvm_arm_timer_get_reg(struct kvm_vcpu *vcpu, u64 regid)
1184-
{
1185-
switch (regid) {
1186-
case KVM_REG_ARM_TIMER_CTL:
1187-
return kvm_arm_timer_read(vcpu,
1188-
vcpu_vtimer(vcpu), TIMER_REG_CTL);
1189-
case KVM_REG_ARM_TIMER_CNT:
1190-
return kvm_arm_timer_read(vcpu,
1191-
vcpu_vtimer(vcpu), TIMER_REG_CNT);
1192-
case KVM_REG_ARM_TIMER_CVAL:
1193-
return kvm_arm_timer_read(vcpu,
1194-
vcpu_vtimer(vcpu), TIMER_REG_CVAL);
1195-
case KVM_REG_ARM_PTIMER_CTL:
1196-
return kvm_arm_timer_read(vcpu,
1197-
vcpu_ptimer(vcpu), TIMER_REG_CTL);
1198-
case KVM_REG_ARM_PTIMER_CNT:
1199-
return kvm_arm_timer_read(vcpu,
1200-
vcpu_ptimer(vcpu), TIMER_REG_CNT);
1201-
case KVM_REG_ARM_PTIMER_CVAL:
1202-
return kvm_arm_timer_read(vcpu,
1203-
vcpu_ptimer(vcpu), TIMER_REG_CVAL);
1204-
}
1205-
return (u64)-1;
1206-
}
1207-
12081131
static u64 kvm_arm_timer_read(struct kvm_vcpu *vcpu,
12091132
struct arch_timer_context *timer,
12101133
enum kvm_arch_timer_regs treg)

arch/arm64/kvm/arm.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,6 +642,7 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
642642
vcpu->arch.hcr_el2 |= HCR_TWI;
643643

644644
vcpu_set_pauth_traps(vcpu);
645+
kvm_vcpu_load_fgt(vcpu);
645646

646647
if (is_protected_kvm_enabled()) {
647648
kvm_call_hyp_nvhe(__pkvm_vcpu_load,
@@ -1794,6 +1795,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
17941795
case KVM_GET_VCPU_EVENTS: {
17951796
struct kvm_vcpu_events events;
17961797

1798+
if (!kvm_vcpu_initialized(vcpu))
1799+
return -ENOEXEC;
1800+
17971801
if (kvm_arm_vcpu_get_events(vcpu, &events))
17981802
return -EINVAL;
17991803

@@ -1805,6 +1809,9 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
18051809
case KVM_SET_VCPU_EVENTS: {
18061810
struct kvm_vcpu_events events;
18071811

1812+
if (!kvm_vcpu_initialized(vcpu))
1813+
return -ENOEXEC;
1814+
18081815
if (copy_from_user(&events, argp, sizeof(events)))
18091816
return -EFAULT;
18101817

0 commit comments

Comments
 (0)