Skip to content

Commit

Permalink
KVM: arm64: vgic: Wrap vgic_its_create() with config_lock
Browse files Browse the repository at this point in the history
[ Upstream commit 9cf2f84 ]

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: f003277 ("KVM: arm64: Use config_lock to protect vgic state")
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
Reviewed-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230518100914.2837292-3-jean-philippe@linaro.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
  • Loading branch information
jpbrucker authored and gregkh committed Jun 9, 2023
1 parent 4129d71 commit 150a5f7
Showing 1 changed file with 10 additions and 4 deletions.
14 changes: 10 additions & 4 deletions arch/arm64/kvm/vgic/vgic-its.c
Original file line number Diff line number Diff line change
Expand Up @@ -1936,6 +1936,7 @@ void vgic_lpi_translation_cache_destroy(struct kvm *kvm)

static int vgic_its_create(struct kvm_device *dev, u32 type)
{
int ret;
struct vgic_its *its;

if (type != KVM_DEV_TYPE_ARM_VGIC_ITS)
Expand All @@ -1945,9 +1946,12 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
if (!its)
return -ENOMEM;

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

if (vgic_initialized(dev->kvm)) {
int ret = vgic_v4_init(dev->kvm);
ret = vgic_v4_init(dev->kvm);
if (ret < 0) {
mutex_unlock(&dev->kvm->arch.config_lock);
kfree(its);
return ret;
}
Expand All @@ -1960,12 +1964,10 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)

/* Yep, even more trickery for lock ordering... */
#ifdef CONFIG_LOCKDEP
mutex_lock(&dev->kvm->arch.config_lock);
mutex_lock(&its->cmd_lock);
mutex_lock(&its->its_lock);
mutex_unlock(&its->its_lock);
mutex_unlock(&its->cmd_lock);
mutex_unlock(&dev->kvm->arch.config_lock);
#endif

its->vgic_its_base = VGIC_ADDR_UNDEF;
Expand All @@ -1986,7 +1988,11 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)

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)
Expand Down

0 comments on commit 150a5f7

Please sign in to comment.