...rather than testing the global iommu_enabled flag and ops pointer.
Now that there is a per-domain flag indicating whether the domain is
permitted to use the IOMMU (which determines whether the ops pointer will
be set), many tests of the global iommu_enabled flag and ops pointer can
be translated into tests of the per-domain flag. Some of the other tests of
purely the global iommu_enabled flag can also be translated into tests of
the per-domain flag.
NOTE: The comment in iommu_share_p2m_table() is also fixed; need_iommu()
disappeared some time ago. Also, whilst the style of the 'if' in
flask_iommu_resource_use_perm() is fixed, I have not translated any
instances of u32 into uint32_t to keep consistency. IMO such a
translation would be better done globally for the source module in
a separate patch.
The change to the definition of iommu_call() is to keep the PV shim
build happy. Without this change it will fail to compile with errors
of the form:
iommu.c:361:32: error: unused variable ‘hd’ [-Werror=unused-variable]
const struct domain_iommu *hd = dom_iommu(d);
^~
Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Reviewed-by: "Roger Pau Monné" <roger.pau@citrix.com>
Reviewed-by: Kevin Tian <kevin.tian@intel.com>
Acked-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Acked-by: Julien Grall <julien.grall@arm.com>
* shared with the CPU, Xen has to make sure that the PT changes have
* reached the memory
*/
- p2m->clean_pte = iommu_enabled &&
+ p2m->clean_pte = is_iommu_enabled(d) &&
!iommu_has_feature(d, IOMMU_FEAT_COHERENT_WALK);
rc = p2m_alloc_table(d);
avail -= d->max_vcpus - 1;
/* Reserve memory for iommu_dom0_init() (rough estimate). */
- if ( iommu_enabled )
+ if ( is_iommu_enabled(d) )
{
unsigned int s;
break;
ret = -ESRCH;
- if ( iommu_enabled )
+ if ( is_iommu_enabled(d) )
{
pcidevs_lock();
ret = pt_irq_create_bind(d, bind);
if ( ret )
break;
- if ( iommu_enabled )
+ if ( is_iommu_enabled(d) )
{
pcidevs_lock();
ret = pt_irq_destroy_bind(d, bind);
void hvm_migrate_pirq(struct hvm_pirq_dpci *pirq_dpci, const struct vcpu *v)
{
- ASSERT(iommu_enabled &&
+ ASSERT(is_iommu_enabled(v->domain) &&
(is_hardware_domain(v->domain) || hvm_domain_irq(v->domain)->dpci));
if ( (pirq_dpci->flags & HVM_IRQ_DPCI_MACH_MSI) &&
{
struct domain *d = v->domain;
- if ( !iommu_enabled || !hvm_domain_irq(d)->dpci )
+ if ( !is_iommu_enabled(d) || !hvm_domain_irq(d)->dpci )
return;
spin_lock(&d->event_lock);
}
if ( ((value ^ old_value) & X86_CR0_CD) &&
- iommu_enabled && hvm_funcs.handle_cd &&
+ is_iommu_enabled(d) && hvm_funcs.handle_cd &&
(!rangeset_is_empty(d->iomem_caps) ||
!rangeset_is_empty(d->arch.ioport_caps) ||
has_arch_pdevs(d)) )
ent->fields.remote_irr = 0;
- if ( iommu_enabled )
+ if ( is_iommu_enabled(d) )
{
spin_unlock(&d->arch.hvm.irq_lock);
hvm_dpci_eoi(d, vioapic->base_gsi + pin, ent);
vmx_clear_msr_intercept(v, MSR_IA32_SYSENTER_CS, VMX_MSR_RW);
vmx_clear_msr_intercept(v, MSR_IA32_SYSENTER_ESP, VMX_MSR_RW);
vmx_clear_msr_intercept(v, MSR_IA32_SYSENTER_EIP, VMX_MSR_RW);
- if ( paging_mode_hap(d) && (!iommu_enabled || iommu_snoop) )
+ if ( paging_mode_hap(d) && (!is_iommu_enabled(d) || iommu_snoop) )
vmx_clear_msr_intercept(v, MSR_IA32_CR_PAT, VMX_MSR_RW);
if ( (vmexit_ctl & VM_EXIT_CLEAR_BNDCFGS) &&
(vmentry_ctl & VM_ENTRY_LOAD_BNDCFGS) )
{
v->arch.hvm.cache_mode = NORMAL_CACHE_MODE;
vmx_set_guest_pat(v, *pat);
- if ( !iommu_enabled || iommu_snoop )
+ if ( !is_iommu_enabled(v->domain) || iommu_snoop )
vmx_clear_msr_intercept(v, MSR_IA32_CR_PAT, VMX_MSR_RW);
hvm_asid_flush_vcpu(v); /* no need to flush cache */
}
*epte = *ept_entry;
epte->sp = (level > 1);
epte->mfn += i * trunk;
- epte->snp = (iommu_enabled && iommu_snoop);
+ epte->snp = is_iommu_enabled(p2m->domain) && iommu_snoop;
epte->suppress_ve = 1;
ept_p2m_type_to_flags(p2m, epte, epte->sa_p2mt, epte->access);
new_entry.sp = !!i;
new_entry.sa_p2mt = p2mt;
new_entry.access = p2ma;
- new_entry.snp = (iommu_enabled && iommu_snoop);
+ new_entry.snp = is_iommu_enabled(d) && iommu_snoop;
/* the caller should take care of the previous page */
new_entry.mfn = mfn_x(mfn);
struct guest_iommu *iommu;
struct domain_iommu *hd = dom_iommu(d);
- if ( !is_hvm_domain(d) || !iommu_enabled || !iommuv2_enabled ||
+ if ( !is_hvm_domain(d) || !is_iommu_enabled(d) || !iommuv2_enabled ||
!has_viommu(d) )
return 0;
int rc = -EBUSY;
struct domain_iommu *hd = dom_iommu(d);
- if ( !iommu_enabled || !hd->platform_ops )
+ if ( !is_iommu_enabled(d) )
return -EINVAL;
if ( !dt_device_is_protected(dev) )
const struct domain_iommu *hd = dom_iommu(d);
int rc;
- if ( !iommu_enabled || !hd->platform_ops )
+ if ( !is_iommu_enabled(d) )
return -EINVAL;
if ( !dt_device_is_protected(dev) )
if ( vcpu )
pirq_dpci->gmsi.posted = true;
}
- if ( vcpu && iommu_enabled )
+ if ( vcpu && is_iommu_enabled(d) )
hvm_migrate_pirq(pirq_dpci, vcpu);
/* Use interrupt posting if it is supported. */
ASSERT(is_hvm_domain(d));
- if ( !iommu_enabled || (!is_hardware_domain(d) && !dpci) ||
+ if ( !is_iommu_enabled(d) || (!is_hardware_domain(d) && !dpci) ||
!pirq_dpci || !(pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) )
return 0;
void hvm_dpci_msi_eoi(struct domain *d, int vector)
{
- if ( !iommu_enabled ||
+ if ( !is_iommu_enabled(d) ||
(!hvm_domain_irq(d)->dpci && !is_hardware_domain(d)) )
return;
const struct hvm_irq_dpci *hvm_irq_dpci;
const struct hvm_girq_dpci_mapping *girq;
- if ( !iommu_enabled )
+ if ( !is_iommu_enabled(d) )
return;
if ( is_hardware_domain(d) )
check_hwdom_reqs(d);
- if ( !iommu_enabled )
+ if ( !is_iommu_enabled(d) )
return;
register_keyhandler('o', &iommu_dump_p2m_table, "dump iommu p2m table", 0);
void iommu_domain_destroy(struct domain *d)
{
- if ( !iommu_enabled || !dom_iommu(d)->platform_ops )
+ if ( !is_iommu_enabled(d) )
return;
iommu_teardown(d);
unsigned long i;
int rc = 0;
- if ( !iommu_enabled || !hd->platform_ops )
+ if ( !is_iommu_enabled(d) )
return 0;
ASSERT(IS_ALIGNED(dfn_x(dfn), (1ul << page_order)));
unsigned long i;
int rc = 0;
- if ( !iommu_enabled || !hd->platform_ops )
+ if ( !is_iommu_enabled(d) )
return 0;
ASSERT(IS_ALIGNED(dfn_x(dfn), (1ul << page_order)));
{
const struct domain_iommu *hd = dom_iommu(d);
- if ( !iommu_enabled || !hd->platform_ops || !hd->platform_ops->lookup_page )
+ if ( !is_iommu_enabled(d) || !hd->platform_ops->lookup_page )
return -EOPNOTSUPP;
return iommu_call(hd->platform_ops, lookup_page, d, dfn, mfn, flags);
const struct domain_iommu *hd = dom_iommu(d);
int rc;
- if ( !iommu_enabled || !hd->platform_ops ||
- !hd->platform_ops->iotlb_flush || !page_count || !flush_flags )
+ if ( !is_iommu_enabled(d) || !hd->platform_ops->iotlb_flush ||
+ !page_count || !flush_flags )
return 0;
if ( dfn_eq(dfn, INVALID_DFN) )
const struct domain_iommu *hd = dom_iommu(d);
int rc;
- if ( !iommu_enabled || !hd->platform_ops ||
- !hd->platform_ops->iotlb_flush_all || !flush_flags )
+ if ( !is_iommu_enabled(d) || !hd->platform_ops->iotlb_flush_all ||
+ !flush_flags )
return 0;
/*
{
int ret = -ENODEV;
- if ( !iommu_enabled )
- return -ENOSYS;
+ if ( !is_iommu_enabled(d) )
+ return -EOPNOTSUPP;
#ifdef CONFIG_HAS_PCI
ret = iommu_do_pci_domctl(domctl, d, u_domctl);
ASSERT(hap_enabled(d));
/*
* iommu_use_hap_pt(d) cannot be used here because during domain
- * construction need_iommu(d) will always return false here.
+ * construction has_iommu_pt(d) will always return false here.
*/
- if ( iommu_enabled && iommu_hap_pt_share )
+ if ( is_iommu_enabled(d) && iommu_hap_pt_share )
iommu_get_ops()->share_p2m(d);
}
bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature)
{
- if ( !iommu_enabled )
- return 0;
-
- return test_bit(feature, dom_iommu(d)->features);
+ return is_iommu_enabled(d) && test_bit(feature, dom_iommu(d)->features);
}
static void iommu_dump_p2m_table(unsigned char key)
u16 cap, ctrl, seg = pdev->seg;
u8 bus = pdev->bus;
- if ( !iommu_enabled )
+ if ( !is_iommu_enabled(pdev->domain) )
return;
pos = pci_find_ext_capability(seg, bus, pdev->devfn, PCI_EXT_CAP_ID_ACS);
{
struct hvm_irq_dpci *hvm_irq_dpci = NULL;
- if ( !iommu_enabled )
+ if ( !is_iommu_enabled(d) )
return 0;
if ( !is_hvm_domain(d) )
struct pci_dev *pdev;
int ret = 0;
- if ( !iommu_enabled || !hd->platform_ops )
+ if ( !is_iommu_enabled(d) )
return -EINVAL;
ASSERT(pcidevs_locked());
ASSERT(pcidevs_locked());
hd = dom_iommu(pdev->domain);
- if ( !iommu_enabled || !hd->platform_ops )
+ if ( !is_iommu_enabled(pdev->domain) )
return 0;
rc = hd->platform_ops->add_device(pdev->devfn, pci_to_dev(pdev));
ASSERT(pcidevs_locked());
hd = dom_iommu(pdev->domain);
- if ( !iommu_enabled || !hd->platform_ops ||
+ if ( !is_iommu_enabled(pdev->domain) ||
!hd->platform_ops->enable_device )
return 0;
return -EINVAL;
hd = dom_iommu(pdev->domain);
- if ( !iommu_enabled || !hd->platform_ops )
+ if ( !is_iommu_enabled(pdev->domain) )
return 0;
for ( devfn = pdev->devfn ; pdev->phantom_stride; )
struct pci_dev *pdev;
int rc = 0;
- if ( !iommu_enabled || !hd->platform_ops )
+ if ( !is_iommu_enabled(d) )
return 0;
/* Prevent device assign if mem paging or mem sharing have been
int i = 0;
const struct iommu_ops *ops = hd->platform_ops;
- if ( !iommu_enabled || !ops || !ops->get_device_group_id )
+ if ( !is_iommu_enabled(d) || !ops->get_device_group_id )
return 0;
group_id = ops->get_device_group_id(seg, bus, devfn);
xfree(mrmrr);
}
- ASSERT(iommu_enabled);
+ ASSERT(is_iommu_enabled(d));
/*
* We can't use iommu_use_hap_pt here because either IOMMU state
struct hvm_irq_dpci *dpci = NULL;
ASSERT(isairq < NR_ISAIRQS);
- if ( !iommu_enabled )
+ if ( !is_iommu_enabled(d) )
return;
spin_lock(&d->event_lock);
void __hwdom_init arch_iommu_check_autotranslated_hwdom(struct domain *d)
{
- if ( !iommu_enabled )
+ if ( !is_iommu_enabled(d) )
panic("Presently, iommu must be enabled for PVH hardware domain\n");
}
#ifdef NDEBUG
# include <asm/alternative.h>
-# define iommu_call(ops, fn, args...) alternative_call(iommu_ops.fn, ## args)
-# define iommu_vcall(ops, fn, args...) alternative_vcall(iommu_ops.fn, ## args)
+# define iommu_call(ops, fn, args...) ({ \
+ (void)(ops); \
+ alternative_call(iommu_ops.fn, ## args); \
+})
+
+# define iommu_vcall(ops, fn, args...) ({ \
+ (void)(ops); \
+ alternative_vcall(iommu_ops.fn, ## args); \
+})
#endif
static inline const struct iommu_ops *iommu_get_ops(void)
#endif
}
-static u32 flask_iommu_resource_use_perm(void)
+static u32 flask_iommu_resource_use_perm(const struct domain *d)
{
/* Obtain the permission level required for allowing a domain
* to use an assigned device.
*/
u32 perm = RESOURCE__USE_NOIOMMU;
- if (iommu_enabled)
+ if ( is_iommu_enabled(d) )
perm = ( iommu_intremap ? RESOURCE__USE_IOMMU :
RESOURCE__USE_IOMMU_NOINTREMAP );
return perm;
u32 sid, dsid;
int rc = -EPERM;
struct avc_audit_data ad;
- u32 dperm = flask_iommu_resource_use_perm();
+ u32 dperm = flask_iommu_resource_use_perm(d);
if ( irq >= nr_static_irqs && data ) {
rc = flask_map_domain_msi(d, irq, data, &sid, &ad);
int rc = -EPERM;
int irq;
struct avc_audit_data ad;
- u32 dperm = flask_iommu_resource_use_perm();
+ u32 dperm = flask_iommu_resource_use_perm(d);
rc = current_has_perm(d, SECCLASS_RESOURCE, RESOURCE__ADD);
if ( rc )
data.ssid = domain_sid(current->domain);
data.dsid = domain_sid(d);
- data.use_perm = flask_iommu_resource_use_perm();
+ data.use_perm = flask_iommu_resource_use_perm(d);
return security_iterate_iomem_sids(start, end, _iomem_has_perm, &data);
}
if ( access && (end >= 0x10 && start < 0x28) )
perm = RESOURCE__SETUP;
else
- perm = flask_iommu_resource_use_perm();
+ perm = flask_iommu_resource_use_perm(d);
AVC_AUDIT_DATA_INIT(&ad, DEV);
ad.device = (unsigned long) machine_bdf;
u32 dsid, rsid;
int rc = -EPERM;
struct avc_audit_data ad;
- u32 dperm = flask_iommu_resource_use_perm();
+ u32 dperm = flask_iommu_resource_use_perm(d);
if ( !d )
return flask_test_assign_device(machine_bdf);
u32 dsid, rsid;
int rc = -EPERM;
struct avc_audit_data ad;
- u32 dperm = flask_iommu_resource_use_perm();
+ u32 dperm = flask_iommu_resource_use_perm(d);
if ( !d )
return flask_test_assign_dtdevice(dtpath);
data.ssid = domain_sid(current->domain);
data.dsid = domain_sid(d);
- data.use_perm = flask_iommu_resource_use_perm();
+ data.use_perm = flask_iommu_resource_use_perm(d);
return security_iterate_ioport_sids(start, end, _ioport_has_perm, &data);
}