mirror of https://github.com/xemu-project/xemu.git
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
|
* 1st-level translation or 2nd-level translation, it depends
|
||||||
* on PGTT setting.
|
* 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;
|
IntelIOMMUState *s;
|
||||||
VTDContextEntry ce;
|
VTDContextEntry ce;
|
||||||
VTDPASIDEntry pe;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
assert(as);
|
assert(as);
|
||||||
|
@ -1538,17 +1556,7 @@ static bool vtd_dev_pt_enabled(VTDAddressSpace *as)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->root_scalable) {
|
return vtd_dev_pt_enabled(s, &ce);
|
||||||
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 whether the device is using IOMMU translation. */
|
/* Return whether the device is using IOMMU translation. */
|
||||||
|
@ -1560,7 +1568,7 @@ static bool vtd_switch_address_space(VTDAddressSpace *as)
|
||||||
|
|
||||||
assert(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),
|
trace_vtd_switch_address_space(pci_bus_num(as->bus),
|
||||||
VTD_PCI_SLOT(as->devfn),
|
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.
|
* We don't need to translate for pass-through context entries.
|
||||||
* Also, let's ignore IOTLB caching as well for PT devices.
|
* 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->iova = addr & VTD_PAGE_MASK_4K;
|
||||||
entry->translated_addr = entry->iova;
|
entry->translated_addr = entry->iova;
|
||||||
entry->addr_mask = ~VTD_PAGE_MASK_4K;
|
entry->addr_mask = ~VTD_PAGE_MASK_4K;
|
||||||
|
|
Loading…
Reference in New Issue