Commit e9001a38 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

Merge tag 'kvmarm-fixes-6.12-3' of...

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
parents ddd5c582 78a00555
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -178,6 +178,7 @@ struct kvm_nvhe_init_params {
	unsigned long hcr_el2;
	unsigned long vttbr;
	unsigned long vtcr;
	unsigned long tmp;
};

/*
+1 −0
Original line number Diff line number Diff line
@@ -146,6 +146,7 @@ int main(void)
  DEFINE(NVHE_INIT_HCR_EL2,	offsetof(struct kvm_nvhe_init_params, hcr_el2));
  DEFINE(NVHE_INIT_VTTBR,	offsetof(struct kvm_nvhe_init_params, vttbr));
  DEFINE(NVHE_INIT_VTCR,	offsetof(struct kvm_nvhe_init_params, vtcr));
  DEFINE(NVHE_INIT_TMP,		offsetof(struct kvm_nvhe_init_params, tmp));
#endif
#ifdef CONFIG_CPU_PM
  DEFINE(CPU_CTX_SP,		offsetof(struct cpu_suspend_ctx, sp));
+29 −23
Original line number Diff line number Diff line
@@ -24,28 +24,25 @@
	.align	11

SYM_CODE_START(__kvm_hyp_init)
	ventry	__invalid		// Synchronous EL2t
	ventry	__invalid		// IRQ EL2t
	ventry	__invalid		// FIQ EL2t
	ventry	__invalid		// Error EL2t
	ventry	.			// Synchronous EL2t
	ventry	.			// IRQ EL2t
	ventry	.			// FIQ EL2t
	ventry	.			// Error EL2t

	ventry	__invalid		// Synchronous EL2h
	ventry	__invalid		// IRQ EL2h
	ventry	__invalid		// FIQ EL2h
	ventry	__invalid		// Error EL2h
	ventry	.			// Synchronous EL2h
	ventry	.			// IRQ EL2h
	ventry	.			// FIQ EL2h
	ventry	.			// Error EL2h

	ventry	__do_hyp_init		// Synchronous 64-bit EL1
	ventry	__invalid		// IRQ 64-bit EL1
	ventry	__invalid		// FIQ 64-bit EL1
	ventry	__invalid		// Error 64-bit EL1
	ventry	.			// IRQ 64-bit EL1
	ventry	.			// FIQ 64-bit EL1
	ventry	.			// Error 64-bit EL1

	ventry	__invalid		// Synchronous 32-bit EL1
	ventry	__invalid		// IRQ 32-bit EL1
	ventry	__invalid		// FIQ 32-bit EL1
	ventry	__invalid		// Error 32-bit EL1

__invalid:
	b	.
	ventry	.			// Synchronous 32-bit EL1
	ventry	.			// IRQ 32-bit EL1
	ventry	.			// FIQ 32-bit EL1
	ventry	.			// Error 32-bit EL1

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

SYM_CODE_START_LOCAL(__kvm_init_el2_state)
	/* Initialize EL2 CPU state to sane values. */
	init_el2_state				// Clobbers x0..x2
	finalise_el2_state
	ret
SYM_CODE_END(__kvm_init_el2_state)

/*
 * Initialize the hypervisor in EL2.
 *
@@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init)
	// TPIDR_EL2 is used to preserve x0 across the macro maze...
	isb
	msr	tpidr_el2, x0
	init_el2_state
	finalise_el2_state
	str	lr, [x0, #NVHE_INIT_TMP]

	bl	__kvm_init_el2_state

	mrs	x0, tpidr_el2
	ldr	lr, [x0, #NVHE_INIT_TMP]

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

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

	/* Initialize EL2 CPU state to sane values. */
	init_el2_state				// Clobbers x0..x2
	finalise_el2_state
	bl	__kvm_init_el2_state

	__init_el2_nvhe_prepare_eret

	/* Enable MMU, set vectors and stack. */
+1 −1
Original line number Diff line number Diff line
@@ -1994,7 +1994,7 @@ static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r)
	 * one cache line.
	 */
	if (kvm_has_mte(vcpu->kvm))
		clidr |= 2 << CLIDR_TTYPE_SHIFT(loc);
		clidr |= 2ULL << CLIDR_TTYPE_SHIFT(loc);

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

+11 −2
Original line number Diff line number Diff line
@@ -544,14 +544,23 @@ int kvm_vgic_map_resources(struct kvm *kvm)
	if (ret)
		goto out;

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

	ret = vgic_register_dist_iodev(kvm, dist_base, type);
	if (ret)
	if (ret) {
		kvm_err("Unable to register VGIC dist MMIO regions\n");
		goto out_slots;
	}

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