Skip to content

Commit e9001a3

Browse files
committed
Merge tag 'kvmarm-fixes-6.12-3' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 fixes for 6.12, take #3 - Stop wasting space in the HYP idmap, as we are dangerously close to the 4kB limit, and this has already exploded in -next - Fix another race in vgic_init() - Fix a UBSAN error when faking the cache topology with MTE enabled
2 parents ddd5c58 + 78a0055 commit e9001a3

File tree

6 files changed

+49
-27
lines changed

6 files changed

+49
-27
lines changed

arch/arm64/include/asm/kvm_asm.h

+1
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ struct kvm_nvhe_init_params {
178178
unsigned long hcr_el2;
179179
unsigned long vttbr;
180180
unsigned long vtcr;
181+
unsigned long tmp;
181182
};
182183

183184
/*

arch/arm64/kernel/asm-offsets.c

+1
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,7 @@ int main(void)
146146
DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2));
147147
DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr));
148148
DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr));
149+
DEFINE(NVHE_INIT_TMP, offsetof(struct kvm_nvhe_init_params, tmp));
149150
#endif
150151
#ifdef CONFIG_CPU_PM
151152
DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp));

arch/arm64/kvm/hyp/nvhe/hyp-init.S

+29-23
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,25 @@
2424
.align 11
2525

2626
SYM_CODE_START(__kvm_hyp_init)
27-
ventry __invalid // Synchronous EL2t
28-
ventry __invalid // IRQ EL2t
29-
ventry __invalid // FIQ EL2t
30-
ventry __invalid // Error EL2t
27+
ventry . // Synchronous EL2t
28+
ventry . // IRQ EL2t
29+
ventry . // FIQ EL2t
30+
ventry . // Error EL2t
3131

32-
ventry __invalid // Synchronous EL2h
33-
ventry __invalid // IRQ EL2h
34-
ventry __invalid // FIQ EL2h
35-
ventry __invalid // Error EL2h
32+
ventry . // Synchronous EL2h
33+
ventry . // IRQ EL2h
34+
ventry . // FIQ EL2h
35+
ventry . // Error EL2h
3636

3737
ventry __do_hyp_init // Synchronous 64-bit EL1
38-
ventry __invalid // IRQ 64-bit EL1
39-
ventry __invalid // FIQ 64-bit EL1
40-
ventry __invalid // Error 64-bit EL1
38+
ventry . // IRQ 64-bit EL1
39+
ventry . // FIQ 64-bit EL1
40+
ventry . // Error 64-bit EL1
4141

42-
ventry __invalid // Synchronous 32-bit EL1
43-
ventry __invalid // IRQ 32-bit EL1
44-
ventry __invalid // FIQ 32-bit EL1
45-
ventry __invalid // Error 32-bit EL1
46-
47-
__invalid:
48-
b .
42+
ventry . // Synchronous 32-bit EL1
43+
ventry . // IRQ 32-bit EL1
44+
ventry . // FIQ 32-bit EL1
45+
ventry . // Error 32-bit EL1
4946

5047
/*
5148
* Only uses x0..x3 so as to not clobber callee-saved SMCCC registers.
@@ -76,6 +73,13 @@ __do_hyp_init:
7673
eret
7774
SYM_CODE_END(__kvm_hyp_init)
7875

76+
SYM_CODE_START_LOCAL(__kvm_init_el2_state)
77+
/* Initialize EL2 CPU state to sane values. */
78+
init_el2_state // Clobbers x0..x2
79+
finalise_el2_state
80+
ret
81+
SYM_CODE_END(__kvm_init_el2_state)
82+
7983
/*
8084
* Initialize the hypervisor in EL2.
8185
*
@@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init)
102106
// TPIDR_EL2 is used to preserve x0 across the macro maze...
103107
isb
104108
msr tpidr_el2, x0
105-
init_el2_state
106-
finalise_el2_state
109+
str lr, [x0, #NVHE_INIT_TMP]
110+
111+
bl __kvm_init_el2_state
112+
107113
mrs x0, tpidr_el2
114+
ldr lr, [x0, #NVHE_INIT_TMP]
108115

109116
1:
110117
ldr x1, [x0, #NVHE_INIT_TPIDR_EL2]
@@ -199,9 +206,8 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)
199206

200207
2: msr SPsel, #1 // We want to use SP_EL{1,2}
201208

202-
/* Initialize EL2 CPU state to sane values. */
203-
init_el2_state // Clobbers x0..x2
204-
finalise_el2_state
209+
bl __kvm_init_el2_state
210+
205211
__init_el2_nvhe_prepare_eret
206212

207213
/* Enable MMU, set vectors and stack. */

arch/arm64/kvm/sys_regs.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -1994,7 +1994,7 @@ static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
19941994
* one cache line.
19951995
*/
19961996
if (kvm_has_mte(vcpu->kvm))
1997-
clidr |= 2 << CLIDR_TTYPE_SHIFT(loc);
1997+
clidr |= 2ULL << CLIDR_TTYPE_SHIFT(loc);
19981998

19991999
__vcpu_sys_reg(vcpu, r->reg) = clidr;
20002000

arch/arm64/kvm/vgic/vgic-init.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -544,14 +544,23 @@ int kvm_vgic_map_resources(struct kvm *kvm)
544544
if (ret)
545545
goto out;
546546

547-
dist->ready = true;
548547
dist_base = dist->vgic_dist_base;
549548
mutex_unlock(&kvm->arch.config_lock);
550549

551550
ret = vgic_register_dist_iodev(kvm, dist_base, type);
552-
if (ret)
551+
if (ret) {
553552
kvm_err("Unable to register VGIC dist MMIO regions\n");
553+
goto out_slots;
554+
}
554555

556+
/*
557+
* kvm_io_bus_register_dev() guarantees all readers see the new MMIO
558+
* registration before returning through synchronize_srcu(), which also
559+
* implies a full memory barrier. As such, marking the distributor as
560+
* 'ready' here is guaranteed to be ordered after all vCPUs having seen
561+
* a completely configured distributor.
562+
*/
563+
dist->ready = true;
555564
goto out_slots;
556565
out:
557566
mutex_unlock(&kvm->arch.config_lock);

arch/arm64/kvm/vgic/vgic-kvm-device.c

+6-1
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,12 @@ static int vgic_set_common_attr(struct kvm_device *dev,
236236

237237
mutex_lock(&dev->kvm->arch.config_lock);
238238

239-
if (vgic_ready(dev->kvm) || dev->kvm->arch.vgic.nr_spis)
239+
/*
240+
* Either userspace has already configured NR_IRQS or
241+
* the vgic has already been initialized and vgic_init()
242+
* supplied a default amount of SPIs.
243+
*/
244+
if (dev->kvm->arch.vgic.nr_spis)
240245
ret = -EBUSY;
241246
else
242247
dev->kvm->arch.vgic.nr_spis =

0 commit comments

Comments
 (0)