Commit 9cf2f840 authored by Jean-Philippe Brucker's avatar Jean-Philippe Brucker Committed by Marc Zyngier

KVM: arm64: vgic: Wrap vgic_its_create() with config_lock

vgic_its_create() changes the vgic state without holding the
config_lock, which triggers a lockdep warning in vgic_v4_init():

[  358.667941] WARNING: CPU: 3 PID: 178 at arch/arm64/kvm/vgic/vgic-v4.c:245 vgic_v4_init+0x15c/0x7a8
...
[  358.707410]  vgic_v4_init+0x15c/0x7a8
[  358.708550]  vgic_its_create+0x37c/0x4a4
[  358.709640]  kvm_vm_ioctl+0x1518/0x2d80
[  358.710688]  __arm64_sys_ioctl+0x7ac/0x1ba8
[  358.711960]  invoke_syscall.constprop.0+0x70/0x1e0
[  358.713245]  do_el0_svc+0xe4/0x2d4
[  358.714289]  el0_svc+0x44/0x8c
[  358.715329]  el0t_64_sync_handler+0xf4/0x120
[  358.716615]  el0t_64_sync+0x190/0x194

Wrap the whole of vgic_its_create() with config_lock since, in addition
to calling vgic_v4_init(), it also modifies the global kvm->arch.vgic
state.

Fixes: f0032773 ("KVM: arm64: Use config_lock to protect vgic state")
Signed-off-by: default avatarJean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: default avatarOliver Upton <oliver.upton@linux.dev>
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230518100914.2837292-3-jean-philippe@linaro.org
parent 59112e9c
...@@ -1936,6 +1936,7 @@ void vgic_lpi_translation_cache_destroy(struct kvm *kvm) ...@@ -1936,6 +1936,7 @@ void vgic_lpi_translation_cache_destroy(struct kvm *kvm)
static int vgic_its_create(struct kvm_device *dev, u32 type) static int vgic_its_create(struct kvm_device *dev, u32 type)
{ {
int ret;
struct vgic_its *its; struct vgic_its *its;
if (type != KVM_DEV_TYPE_ARM_VGIC_ITS) if (type != KVM_DEV_TYPE_ARM_VGIC_ITS)
...@@ -1945,9 +1946,12 @@ static int vgic_its_create(struct kvm_device *dev, u32 type) ...@@ -1945,9 +1946,12 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
if (!its) if (!its)
return -ENOMEM; return -ENOMEM;
mutex_lock(&dev->kvm->arch.config_lock);
if (vgic_initialized(dev->kvm)) { if (vgic_initialized(dev->kvm)) {
int ret = vgic_v4_init(dev->kvm); ret = vgic_v4_init(dev->kvm);
if (ret < 0) { if (ret < 0) {
mutex_unlock(&dev->kvm->arch.config_lock);
kfree(its); kfree(its);
return ret; return ret;
} }
...@@ -1960,12 +1964,10 @@ static int vgic_its_create(struct kvm_device *dev, u32 type) ...@@ -1960,12 +1964,10 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
/* Yep, even more trickery for lock ordering... */ /* Yep, even more trickery for lock ordering... */
#ifdef CONFIG_LOCKDEP #ifdef CONFIG_LOCKDEP
mutex_lock(&dev->kvm->arch.config_lock);
mutex_lock(&its->cmd_lock); mutex_lock(&its->cmd_lock);
mutex_lock(&its->its_lock); mutex_lock(&its->its_lock);
mutex_unlock(&its->its_lock); mutex_unlock(&its->its_lock);
mutex_unlock(&its->cmd_lock); mutex_unlock(&its->cmd_lock);
mutex_unlock(&dev->kvm->arch.config_lock);
#endif #endif
its->vgic_its_base = VGIC_ADDR_UNDEF; its->vgic_its_base = VGIC_ADDR_UNDEF;
...@@ -1986,7 +1988,11 @@ static int vgic_its_create(struct kvm_device *dev, u32 type) ...@@ -1986,7 +1988,11 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
dev->private = its; dev->private = its;
return vgic_its_set_abi(its, NR_ITS_ABIS - 1); ret = vgic_its_set_abi(its, NR_ITS_ABIS - 1);
mutex_unlock(&dev->kvm->arch.config_lock);
return ret;
} }
static void vgic_its_destroy(struct kvm_device *kvm_dev) static void vgic_its_destroy(struct kvm_device *kvm_dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment