mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
intel-iommu: correctly check passthrough during translation
When scalable mode is enabled, the passthrough more is not determined by the context entry but PASID entry, so switch to use the logic of vtd_dev_pt_enabled() to determine the passthrough mode in vtd_do_iommu_translate(). Signed-off-by: Jason Wang <jasowang@redhat.com> Message-Id: <20220105041945.13459-2-jasowang@redhat.com> Reviewed-by: Peter Xu <peterx@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
60f1f77cab
commit
5178d78f4b
@ -1516,11 +1516,29 @@ static int vtd_sync_shadow_page_table(VTDAddressSpace *vtd_as)
|
||||
* 1st-level translation or 2nd-level translation, it depends
|
||||
* on PGTT setting.
|
||||
*/
|
||||
static bool vtd_dev_pt_enabled(VTDAddressSpace *as)
|
||||
static bool vtd_dev_pt_enabled(IntelIOMMUState *s, VTDContextEntry *ce)
|
||||
{
|
||||
VTDPASIDEntry pe;
|
||||
int ret;
|
||||
|
||||
if (s->root_scalable) {
|
||||
ret = vtd_ce_get_rid2pasid_entry(s, ce, &pe);
|
||||
if (ret) {
|
||||
error_report_once("%s: vtd_ce_get_rid2pasid_entry error: %"PRId32,
|
||||
__func__, ret);
|
||||
return false;
|
||||
}
|
||||
return (VTD_PE_GET_TYPE(&pe) == VTD_SM_PASID_ENTRY_PT);
|
||||
}
|
||||
|
||||
return (vtd_ce_get_type(ce) == VTD_CONTEXT_TT_PASS_THROUGH);
|
||||
|
||||
}
|
||||
|
||||
static bool vtd_as_pt_enabled(VTDAddressSpace *as)
|
||||
{
|
||||
IntelIOMMUState *s;
|
||||
VTDContextEntry ce;
|
||||
VTDPASIDEntry pe;
|
||||
int ret;
|
||||
|
||||
assert(as);
|
||||
@ -1538,17 +1556,7 @@ static bool vtd_dev_pt_enabled(VTDAddressSpace *as)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s->root_scalable) {
|
||||
ret = vtd_ce_get_rid2pasid_entry(s, &ce, &pe);
|
||||
if (ret) {
|
||||
error_report_once("%s: vtd_ce_get_rid2pasid_entry error: %"PRId32,
|
||||
__func__, ret);
|
||||
return false;
|
||||
}
|
||||
return (VTD_PE_GET_TYPE(&pe) == VTD_SM_PASID_ENTRY_PT);
|
||||
}
|
||||
|
||||
return (vtd_ce_get_type(&ce) == VTD_CONTEXT_TT_PASS_THROUGH);
|
||||
return vtd_dev_pt_enabled(s, &ce);
|
||||
}
|
||||
|
||||
/* Return whether the device is using IOMMU translation. */
|
||||
@ -1560,7 +1568,7 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
|
||||
|
||||
assert(as);
|
||||
|
||||
use_iommu = as->iommu_state->dmar_enabled && !vtd_dev_pt_enabled(as);
|
||||
use_iommu = as->iommu_state->dmar_enabled && !vtd_as_pt_enabled(as);
|
||||
|
||||
trace_vtd_switch_address_space(pci_bus_num(as->bus),
|
||||
VTD_PCI_SLOT(as->devfn),
|
||||
@ -1753,7 +1761,7 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus,
|
||||
* We don't need to translate for pass-through context entries.
|
||||
* Also, let's ignore IOTLB caching as well for PT devices.
|
||||
*/
|
||||
if (vtd_ce_get_type(&ce) == VTD_CONTEXT_TT_PASS_THROUGH) {
|
||||
if (vtd_dev_pt_enabled(s, &ce)) {
|
||||
entry->iova = addr & VTD_PAGE_MASK_4K;
|
||||
entry->translated_addr = entry->iova;
|
||||
entry->addr_mask = ~VTD_PAGE_MASK_4K;
|
||||
|
Loading…
Reference in New Issue
Block a user