diff options
author | Peter Xu <peterx@redhat.com> | 2017-08-17 13:56:14 +0800 |
---|---|---|
committer | Michael S. Tsirkin <mst@redhat.com> | 2017-09-08 16:15:17 +0300 |
commit | 66a4a0318e6b9539505491e4576fb93a708095d8 (patch) | |
tree | fcb988023d2427fa216f90dca88a3ab9e56167ef /hw/i386/intel_iommu.c | |
parent | c1800a16276582f65807f464a6ab0b7c88a1c16e (diff) | |
download | qemu-66a4a0318e6b9539505491e4576fb93a708095d8.zip |
intel_iommu: fix missing BQL in pt fast path
In vtd_switch_address_space() we did the memory region switch, however
it's possible that the caller of it has not taken the BQL at all. Make
sure we have it.
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Jason Wang <jasowang@redhat.com>
CC: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Peter Xu <peterx@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386/intel_iommu.c')
-rw-r--r-- | hw/i386/intel_iommu.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index a7bf87a19e..3a5bb0bc2e 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -957,6 +957,8 @@ static bool vtd_dev_pt_enabled(VTDAddressSpace *as) static bool vtd_switch_address_space(VTDAddressSpace *as) { bool use_iommu; + /* Whether we need to take the BQL on our own */ + bool take_bql = !qemu_mutex_iothread_locked(); assert(as); @@ -967,6 +969,15 @@ static bool vtd_switch_address_space(VTDAddressSpace *as) VTD_PCI_FUNC(as->devfn), use_iommu); + /* + * It's possible that we reach here without BQL, e.g., when called + * from vtd_pt_enable_fast_path(). However the memory APIs need + * it. We'd better make sure we have had it already, or, take it. + */ + if (take_bql) { + qemu_mutex_lock_iothread(); + } + /* Turn off first then on the other */ if (use_iommu) { memory_region_set_enabled(&as->sys_alias, false); @@ -976,6 +987,10 @@ static bool vtd_switch_address_space(VTDAddressSpace *as) memory_region_set_enabled(&as->sys_alias, true); } + if (take_bql) { + qemu_mutex_unlock_iothread(); + } + return use_iommu; } |