Skip to content

Commit 9cf2f84

Browse files
jpbruckerMarc Zyngier
authored andcommitted
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: 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
1 parent 59112e9 commit 9cf2f84

File tree

1 file changed

+10
-4
lines changed

1 file changed

+10
-4
lines changed

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

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,7 @@ void vgic_lpi_translation_cache_destroy(struct kvm *kvm)
19361936

19371937
static int vgic_its_create(struct kvm_device *dev, u32 type)
19381938
{
1939+
int ret;
19391940
struct vgic_its *its;
19401941

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

1949+
mutex_lock(&dev->kvm->arch.config_lock);
1950+
19481951
if (vgic_initialized(dev->kvm)) {
1949-
int ret = vgic_v4_init(dev->kvm);
1952+
ret = vgic_v4_init(dev->kvm);
19501953
if (ret < 0) {
1954+
mutex_unlock(&dev->kvm->arch.config_lock);
19511955
kfree(its);
19521956
return ret;
19531957
}
@@ -1960,12 +1964,10 @@ static int vgic_its_create(struct kvm_device *dev, u32 type)
19601964

19611965
/* Yep, even more trickery for lock ordering... */
19621966
#ifdef CONFIG_LOCKDEP
1963-
mutex_lock(&dev->kvm->arch.config_lock);
19641967
mutex_lock(&its->cmd_lock);
19651968
mutex_lock(&its->its_lock);
19661969
mutex_unlock(&its->its_lock);
19671970
mutex_unlock(&its->cmd_lock);
1968-
mutex_unlock(&dev->kvm->arch.config_lock);
19691971
#endif
19701972

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

19871989
dev->private = its;
19881990

1989-
return vgic_its_set_abi(its, NR_ITS_ABIS - 1);
1991+
ret = vgic_its_set_abi(its, NR_ITS_ABIS - 1);
1992+
1993+
mutex_unlock(&dev->kvm->arch.config_lock);
1994+
1995+
return ret;
19901996
}
19911997

19921998
static void vgic_its_destroy(struct kvm_device *kvm_dev)

0 commit comments

Comments
 (0)