mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-09-22 04:31:58 +08:00
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: f003277311
("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
This commit is contained in:
parent
59112e9c39
commit
9cf2f840c4
@ -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)
|
|||||||
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)
|
|||||||
|
|
||||||
/* 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)
|
|||||||
|
|
||||||
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user