Message ID | 20221028061436.30093-4-jasowang@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | PASID support for Intel IOMMU | expand |
On 2022/10/28 14:14, Jason Wang wrote: > We used to have a macro for VTD_PE_GET_FPD_ERR() but it has an > internal goto which prevents it from being reused. This patch convert > that macro to a dedicated function and let the caller to decide what > to do (e.g using goto or not). This makes sure it can be re-used for > other function that requires fault reporting. > > Reviewed-by: Peter Xu <peterx@redhat.com> > Signed-off-by: Jason Wang <jasowang@redhat.com> > --- > Changes since V4: > - rename vtd_report_qualify_fault() to vtd_report_fault() > Changes since V2: > - rename vtd_qualify_report_fault() to vtd_report_qualify_fault() > --- > hw/i386/intel_iommu.c | 42 ++++++++++++++++++++++++++++-------------- > 1 file changed, 28 insertions(+), 14 deletions(-) Reviewed-by: Yi Liu <yi.l.liu@intel.com> > diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c > index 9fe5a222eb..9029ee98f4 100644 > --- a/hw/i386/intel_iommu.c > +++ b/hw/i386/intel_iommu.c > @@ -49,17 +49,6 @@ > /* pe operations */ > #define VTD_PE_GET_TYPE(pe) ((pe)->val[0] & VTD_SM_PASID_ENTRY_PGTT) > #define VTD_PE_GET_LEVEL(pe) (2 + (((pe)->val[0] >> 2) & VTD_SM_PASID_ENTRY_AW)) > -#define VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write) {\ > - if (ret_fr) { \ > - ret_fr = -ret_fr; \ > - if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) { \ > - trace_vtd_fault_disabled(); \ > - } else { \ > - vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write); \ > - } \ > - goto error; \ > - } \ > -} > > /* > * PCI bus number (or SID) is not reliable since the device is usaully > @@ -1716,6 +1705,19 @@ out: > trace_vtd_pt_enable_fast_path(source_id, success); > } > > +static void vtd_report_fault(IntelIOMMUState *s, > + int err, bool is_fpd_set, > + uint16_t source_id, > + hwaddr addr, > + bool is_write) > +{ > + if (is_fpd_set && vtd_is_qualified_fault(err)) { > + trace_vtd_fault_disabled(); > + } else { > + vtd_report_dmar_fault(s, source_id, addr, err, is_write); > + } > +} > + > /* Map dev to context-entry then do a paging-structures walk to do a iommu > * translation. > * > @@ -1776,7 +1778,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, > is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; > if (!is_fpd_set && s->root_scalable) { > ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set); > - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); > + if (ret_fr) { > + vtd_report_fault(s, -ret_fr, is_fpd_set, > + source_id, addr, is_write); > + goto error; > + } > } > } else { > ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce); > @@ -1784,7 +1790,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, > if (!ret_fr && !is_fpd_set && s->root_scalable) { > ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set); > } > - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); > + if (ret_fr) { > + vtd_report_fault(s, -ret_fr, is_fpd_set, > + source_id, addr, is_write); > + goto error; > + } > /* Update context-cache */ > trace_vtd_iotlb_cc_update(bus_num, devfn, ce.hi, ce.lo, > cc_entry->context_cache_gen, > @@ -1820,7 +1830,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, > > ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &slpte, &level, > &reads, &writes, s->aw_bits); > - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); > + if (ret_fr) { > + vtd_report_fault(s, -ret_fr, is_fpd_set, source_id, > + addr, is_write); > + goto error; > + } > > page_mask = vtd_slpt_level_page_mask(level); > access_flags = IOMMU_ACCESS_FLAG(reads, writes);
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 9fe5a222eb..9029ee98f4 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -49,17 +49,6 @@ /* pe operations */ #define VTD_PE_GET_TYPE(pe) ((pe)->val[0] & VTD_SM_PASID_ENTRY_PGTT) #define VTD_PE_GET_LEVEL(pe) (2 + (((pe)->val[0] >> 2) & VTD_SM_PASID_ENTRY_AW)) -#define VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write) {\ - if (ret_fr) { \ - ret_fr = -ret_fr; \ - if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) { \ - trace_vtd_fault_disabled(); \ - } else { \ - vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write); \ - } \ - goto error; \ - } \ -} /* * PCI bus number (or SID) is not reliable since the device is usaully @@ -1716,6 +1705,19 @@ out: trace_vtd_pt_enable_fast_path(source_id, success); } +static void vtd_report_fault(IntelIOMMUState *s, + int err, bool is_fpd_set, + uint16_t source_id, + hwaddr addr, + bool is_write) +{ + if (is_fpd_set && vtd_is_qualified_fault(err)) { + trace_vtd_fault_disabled(); + } else { + vtd_report_dmar_fault(s, source_id, addr, err, is_write); + } +} + /* Map dev to context-entry then do a paging-structures walk to do a iommu * translation. * @@ -1776,7 +1778,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD; if (!is_fpd_set && s->root_scalable) { ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set); - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); + if (ret_fr) { + vtd_report_fault(s, -ret_fr, is_fpd_set, + source_id, addr, is_write); + goto error; + } } } else { ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce); @@ -1784,7 +1790,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, if (!ret_fr && !is_fpd_set && s->root_scalable) { ret_fr = vtd_ce_get_pasid_fpd(s, &ce, &is_fpd_set); } - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); + if (ret_fr) { + vtd_report_fault(s, -ret_fr, is_fpd_set, + source_id, addr, is_write); + goto error; + } /* Update context-cache */ trace_vtd_iotlb_cc_update(bus_num, devfn, ce.hi, ce.lo, cc_entry->context_cache_gen, @@ -1820,7 +1830,11 @@ static bool vtd_do_iommu_translate(VTDAddressSpace *vtd_as, PCIBus *bus, ret_fr = vtd_iova_to_slpte(s, &ce, addr, is_write, &slpte, &level, &reads, &writes, s->aw_bits); - VTD_PE_GET_FPD_ERR(ret_fr, is_fpd_set, s, source_id, addr, is_write); + if (ret_fr) { + vtd_report_fault(s, -ret_fr, is_fpd_set, source_id, + addr, is_write); + goto error; + } page_mask = vtd_slpt_level_page_mask(level); access_flags = IOMMU_ACCESS_FLAG(reads, writes);