mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
IOMMU/x86: per-domain control structure is not HVM-specific
... and hence should not live in the HVM part of the PV/HVM union. In
fact it's not even architecture specific (there already is a per-arch
extension type to it), so it gets moved out right to common struct
domain.
Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Julien Grall <julien.grall@arm.com>
Reviewed-by: Wei Liu <wei.liu2@citrix.com>
master commit: af07377007
master date: 2016-05-04 09:44:32 +0200
This commit is contained in:
1 parent
8d1e55944b
commit
e5fa482e0d
26 files changed
+103
-157
No files matched your search
@@ -646,7 +646,7 @@ long arch_do_domctl(
|
||||
|
||||
case XEN_DOMCTL_ioport_mapping:
|
||||
{
|
||||
struct hvm_iommu *hd;
|
||||
struct domain_iommu *hd;
|
||||
unsigned int fgp = domctl->u.ioport_mapping.first_gport;
|
||||
unsigned int fmp = domctl->u.ioport_mapping.first_mport;
|
||||
unsigned int np = domctl->u.ioport_mapping.nr_ports;
|
||||
@@ -672,7 +672,7 @@ long arch_do_domctl(
|
||||
if ( ret )
|
||||
break;
|
||||
|
||||
hd = domain_hvm_iommu(d);
|
||||
hd = dom_iommu(d);
|
||||
if ( add )
|
||||
{
|
||||
printk(XENLOG_G_INFO
|
||||
|
||||
@@ -347,13 +347,13 @@ static int dpci_ioport_write(uint32_t mport, ioreq_t *p)
|
||||
int dpci_ioport_intercept(ioreq_t *p)
|
||||
{
|
||||
struct domain *d = current->domain;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *dio = dom_iommu(d);
|
||||
struct g2m_ioport *g2m_ioport;
|
||||
unsigned int mport, gport = p->addr;
|
||||
unsigned int s = 0, e = 0;
|
||||
int rc;
|
||||
|
||||
list_for_each_entry( g2m_ioport, &hd->arch.g2m_ioport_list, list )
|
||||
list_for_each_entry( g2m_ioport, &dio->arch.g2m_ioport_list, list )
|
||||
{
|
||||
s = g2m_ioport->gport;
|
||||
e = s + g2m_ioport->np;
|
||||
|
||||
@@ -228,9 +228,10 @@ static void tboot_gen_domain_integrity(const uint8_t key[TB_KEY_SIZE],
|
||||
|
||||
if ( !is_idle_domain(d) )
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
update_iommu_mac(&ctx, hd->arch.pgd_maddr,
|
||||
agaw_to_level(hd->arch.agaw));
|
||||
const struct domain_iommu *dio = dom_iommu(d);
|
||||
|
||||
update_iommu_mac(&ctx, dio->arch.pgd_maddr,
|
||||
agaw_to_level(dio->arch.agaw));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
*/
|
||||
|
||||
#include <xen/sched.h>
|
||||
#include <xen/hvm/iommu.h>
|
||||
#include <asm/amd-iommu.h>
|
||||
#include <asm/hvm/svm/amd-iommu-proto.h>
|
||||
#include "../ats.h"
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <xen/sched.h>
|
||||
#include <asm/p2m.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
#include <asm/amd-iommu.h>
|
||||
#include <asm/hvm/svm/amd-iommu-proto.h>
|
||||
|
||||
@@ -60,12 +59,12 @@ static uint16_t guest_bdf(struct domain *d, uint16_t machine_bdf)
|
||||
|
||||
static inline struct guest_iommu *domain_iommu(struct domain *d)
|
||||
{
|
||||
return domain_hvm_iommu(d)->arch.g_iommu;
|
||||
return dom_iommu(d)->arch.g_iommu;
|
||||
}
|
||||
|
||||
static inline struct guest_iommu *vcpu_iommu(struct vcpu *v)
|
||||
{
|
||||
return domain_hvm_iommu(v->domain)->arch.g_iommu;
|
||||
return dom_iommu(v->domain)->arch.g_iommu;
|
||||
}
|
||||
|
||||
static void guest_iommu_enable(struct guest_iommu *iommu)
|
||||
@@ -872,7 +871,7 @@ static void guest_iommu_reg_init(struct guest_iommu *iommu)
|
||||
int guest_iommu_init(struct domain* d)
|
||||
{
|
||||
struct guest_iommu *iommu;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
if ( !is_hvm_domain(d) || !iommu_enabled || !iommuv2_enabled )
|
||||
return 0;
|
||||
@@ -908,7 +907,7 @@ void guest_iommu_destroy(struct domain *d)
|
||||
tasklet_kill(&iommu->cmd_buffer_tasklet);
|
||||
xfree(iommu);
|
||||
|
||||
domain_hvm_iommu(d)->arch.g_iommu = NULL;
|
||||
dom_iommu(d)->arch.g_iommu = NULL;
|
||||
}
|
||||
|
||||
static int guest_iommu_mmio_range(struct vcpu *v, unsigned long addr)
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
|
||||
#include <xen/err.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/hvm/iommu.h>
|
||||
#include <asm/amd-iommu.h>
|
||||
#include <asm/hvm/svm/amd-iommu-proto.h>
|
||||
#include <asm/io_apic.h>
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <xen/acpi.h>
|
||||
#include <xen/sched.h>
|
||||
#include <asm/p2m.h>
|
||||
#include <xen/hvm/iommu.h>
|
||||
#include <asm/amd-iommu.h>
|
||||
#include <asm/hvm/svm/amd-iommu-proto.h>
|
||||
#include "../ats.h"
|
||||
@@ -341,7 +340,7 @@ static int iommu_update_pde_count(struct domain *d, unsigned long pt_mfn,
|
||||
unsigned long first_mfn;
|
||||
u64 *table, *pde, *ntable;
|
||||
u64 ntable_maddr, mask;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
bool_t ok = 0;
|
||||
|
||||
ASSERT( spin_is_locked(&hd->arch.mapping_lock) && pt_mfn );
|
||||
@@ -396,7 +395,7 @@ static int iommu_merge_pages(struct domain *d, unsigned long pt_mfn,
|
||||
u64 *table, *pde, *ntable;
|
||||
u64 ntable_mfn;
|
||||
unsigned long first_mfn;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
ASSERT( spin_is_locked(&hd->arch.mapping_lock) && pt_mfn );
|
||||
|
||||
@@ -446,7 +445,7 @@ static int iommu_pde_from_gfn(struct domain *d, unsigned long pfn,
|
||||
unsigned long next_table_mfn;
|
||||
unsigned int level;
|
||||
struct page_info *table;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
table = hd->arch.root_table;
|
||||
level = hd->arch.paging_mode;
|
||||
@@ -555,7 +554,7 @@ static int update_paging_mode(struct domain *d, unsigned long gfn)
|
||||
struct page_info *old_root = NULL;
|
||||
void *new_root_vaddr;
|
||||
unsigned long old_root_mfn;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
level = hd->arch.paging_mode;
|
||||
old_root = hd->arch.root_table;
|
||||
@@ -634,7 +633,7 @@ int amd_iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn,
|
||||
unsigned int flags)
|
||||
{
|
||||
bool_t need_flush = 0;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
unsigned long pt_mfn[7];
|
||||
unsigned int merge_level;
|
||||
|
||||
@@ -714,7 +713,7 @@ out:
|
||||
int amd_iommu_unmap_page(struct domain *d, unsigned long gfn)
|
||||
{
|
||||
unsigned long pt_mfn[7];
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
BUG_ON( !hd->arch.root_table );
|
||||
|
||||
@@ -781,7 +780,7 @@ int amd_iommu_reserve_domain_unity_map(struct domain *domain,
|
||||
/* Share p2m table with iommu. */
|
||||
void amd_iommu_share_p2m(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
struct page_info *p2m_table;
|
||||
mfn_t pgd_mfn;
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
#include <xen/pci_regs.h>
|
||||
#include <xen/paging.h>
|
||||
#include <xen/softirq.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
#include <asm/amd-iommu.h>
|
||||
#include <asm/hvm/svm/amd-iommu-proto.h>
|
||||
#include "../ats.h"
|
||||
@@ -118,8 +117,7 @@ static void amd_iommu_setup_domain_device(
|
||||
int req_id, valid = 1;
|
||||
int dte_i = 0;
|
||||
u8 bus = pdev->bus;
|
||||
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(domain);
|
||||
const struct domain_iommu *hd = dom_iommu(domain);
|
||||
|
||||
BUG_ON( !hd->arch.root_table || !hd->arch.paging_mode ||
|
||||
!iommu->dev_table.buffer );
|
||||
@@ -225,7 +223,7 @@ int __init amd_iov_detect(void)
|
||||
return scan_pci_devices();
|
||||
}
|
||||
|
||||
static int allocate_domain_resources(struct hvm_iommu *hd)
|
||||
static int allocate_domain_resources(struct domain_iommu *hd)
|
||||
{
|
||||
/* allocate root table */
|
||||
spin_lock(&hd->arch.mapping_lock);
|
||||
@@ -260,7 +258,7 @@ static int get_paging_mode(unsigned long entries)
|
||||
|
||||
static int amd_iommu_domain_init(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
/* allocate page directroy */
|
||||
if ( allocate_domain_resources(hd) != 0 )
|
||||
@@ -342,7 +340,7 @@ void amd_iommu_disable_domain_device(struct domain *domain,
|
||||
AMD_IOMMU_DEBUG("Disable: device id = %#x, "
|
||||
"domain = %d, paging mode = %d\n",
|
||||
req_id, domain->domain_id,
|
||||
domain_hvm_iommu(domain)->arch.paging_mode);
|
||||
dom_iommu(domain)->arch.paging_mode);
|
||||
}
|
||||
spin_unlock_irqrestore(&iommu->lock, flags);
|
||||
|
||||
@@ -359,7 +357,7 @@ static int reassign_device(struct domain *source, struct domain *target,
|
||||
{
|
||||
struct amd_iommu *iommu;
|
||||
int bdf;
|
||||
struct hvm_iommu *t = domain_hvm_iommu(target);
|
||||
struct domain_iommu *t = dom_iommu(target);
|
||||
|
||||
bdf = PCI_BDF2(pdev->bus, pdev->devfn);
|
||||
iommu = find_iommu_for_device(pdev->seg, bdf);
|
||||
@@ -459,7 +457,7 @@ static void deallocate_page_table(struct page_info *pg)
|
||||
|
||||
static void deallocate_iommu_page_tables(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
if ( iommu_use_hap_pt(d) )
|
||||
return;
|
||||
@@ -599,7 +597,7 @@ static void amd_dump_p2m_table_level(struct page_info* pg, int level,
|
||||
|
||||
static void amd_dump_p2m_table(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
if ( !hd->arch.root_table )
|
||||
return;
|
||||
|
||||
@@ -673,7 +673,7 @@ static void arm_smmu_tlb_inv_context(struct arm_smmu_domain_cfg *cfg)
|
||||
|
||||
static void arm_smmu_iotlb_flush_all(struct domain *d)
|
||||
{
|
||||
struct arm_smmu_domain *smmu_domain = domain_hvm_iommu(d)->arch.priv;
|
||||
struct arm_smmu_domain *smmu_domain = dom_iommu(d)->arch.priv;
|
||||
struct arm_smmu_domain_cfg *cfg;
|
||||
|
||||
spin_lock(&smmu_domain->lock);
|
||||
@@ -1030,7 +1030,7 @@ arm_smmu_alloc_domain_context(struct domain *d,
|
||||
unsigned int irq;
|
||||
int ret, start;
|
||||
struct arm_smmu_domain_cfg *cfg;
|
||||
struct arm_smmu_domain *smmu_domain = domain_hvm_iommu(d)->arch.priv;
|
||||
struct arm_smmu_domain *smmu_domain = dom_iommu(d)->arch.priv;
|
||||
|
||||
ASSERT(spin_is_locked(&smmu_domain->lock));
|
||||
|
||||
@@ -1092,7 +1092,7 @@ out_free_mem:
|
||||
static void arm_smmu_destroy_domain_context(struct arm_smmu_domain_cfg *cfg)
|
||||
{
|
||||
struct domain *d = cfg->domain;
|
||||
struct arm_smmu_domain *smmu_domain = domain_hvm_iommu(d)->arch.priv;
|
||||
struct arm_smmu_domain *smmu_domain = dom_iommu(d)->arch.priv;
|
||||
struct arm_smmu_device *smmu = cfg->smmu;
|
||||
void __iomem *cb_base;
|
||||
unsigned int irq;
|
||||
@@ -1140,7 +1140,7 @@ static int arm_smmu_attach_dev(struct domain *d,
|
||||
{
|
||||
struct arm_smmu_device *smmu = arm_smmu_find_smmu_by_dev(dev);
|
||||
struct arm_smmu_master *master;
|
||||
struct arm_smmu_domain *smmu_domain = domain_hvm_iommu(d)->arch.priv;
|
||||
struct arm_smmu_domain *smmu_domain = dom_iommu(d)->arch.priv;
|
||||
struct arm_smmu_domain_cfg *cfg = NULL;
|
||||
struct arm_smmu_domain_cfg *curr;
|
||||
int ret;
|
||||
@@ -1200,7 +1200,7 @@ static int arm_smmu_attach_dev(struct domain *d,
|
||||
static int arm_smmu_detach_dev(struct domain *d,
|
||||
const struct dt_device_node *dev)
|
||||
{
|
||||
struct arm_smmu_domain *smmu_domain = domain_hvm_iommu(d)->arch.priv;
|
||||
struct arm_smmu_domain *smmu_domain = dom_iommu(d)->arch.priv;
|
||||
struct arm_smmu_master *master;
|
||||
struct arm_smmu_device *smmu = arm_smmu_find_smmu_by_dev(dev);
|
||||
struct arm_smmu_domain_cfg *cfg;
|
||||
@@ -1519,7 +1519,7 @@ static int arm_smmu_iommu_domain_init(struct domain *d)
|
||||
spin_lock_init(&smmu_domain->lock);
|
||||
INIT_LIST_HEAD(&smmu_domain->contexts);
|
||||
|
||||
domain_hvm_iommu(d)->arch.priv = smmu_domain;
|
||||
dom_iommu(d)->arch.priv = smmu_domain;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1530,7 +1530,7 @@ static void __hwdom_init arm_smmu_iommu_hwdom_init(struct domain *d)
|
||||
|
||||
static void arm_smmu_iommu_domain_teardown(struct domain *d)
|
||||
{
|
||||
struct arm_smmu_domain *smmu_domain = domain_hvm_iommu(d)->arch.priv;
|
||||
struct arm_smmu_domain *smmu_domain = dom_iommu(d)->arch.priv;
|
||||
|
||||
ASSERT(list_empty(&smmu_domain->contexts));
|
||||
xfree(smmu_domain);
|
||||
|
||||
@@ -28,7 +28,7 @@ static spinlock_t dtdevs_lock = SPIN_LOCK_UNLOCKED;
|
||||
int iommu_assign_dt_device(struct domain *d, struct dt_device_node *dev)
|
||||
{
|
||||
int rc = -EBUSY;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
if ( !iommu_enabled || !hd->platform_ops )
|
||||
return -EINVAL;
|
||||
@@ -57,7 +57,7 @@ fail:
|
||||
|
||||
int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
int rc;
|
||||
|
||||
if ( !iommu_enabled || !hd->platform_ops )
|
||||
@@ -75,7 +75,7 @@ int iommu_deassign_dt_device(struct domain *d, struct dt_device_node *dev)
|
||||
list_del(&dev->domain_list);
|
||||
|
||||
dt_device_set_used_by(dev, hardware_domain->domain_id);
|
||||
list_add(&dev->domain_list, &domain_hvm_iommu(hardware_domain)->dt_devices);
|
||||
list_add(&dev->domain_list, &dom_iommu(hardware_domain)->dt_devices);
|
||||
|
||||
fail:
|
||||
spin_unlock(&dtdevs_lock);
|
||||
@@ -85,16 +85,14 @@ fail:
|
||||
|
||||
int iommu_dt_domain_init(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
|
||||
INIT_LIST_HEAD(&hd->dt_devices);
|
||||
INIT_LIST_HEAD(&dom_iommu(d)->dt_devices);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iommu_dt_domain_destroy(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
struct dt_device_node *dev, *_dev;
|
||||
int rc;
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <xen/iommu.h>
|
||||
#include <xen/irq.h>
|
||||
#include <asm/hvm/irq.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
#include <asm/hvm/support.h>
|
||||
#include <xen/hvm/irq.h>
|
||||
#include <xen/tasklet.h>
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
#include <xen/sched.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
#include <xen/paging.h>
|
||||
#include <xen/guest_access.h>
|
||||
#include <xen/event.h>
|
||||
@@ -116,7 +115,7 @@ static void __init parse_iommu_param(char *s)
|
||||
|
||||
int iommu_domain_init(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
int ret = 0;
|
||||
|
||||
ret = arch_iommu_domain_init(d);
|
||||
@@ -146,7 +145,7 @@ static void __hwdom_init check_hwdom_reqs(struct domain *d)
|
||||
|
||||
void __hwdom_init iommu_hwdom_init(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
check_hwdom_reqs(d);
|
||||
|
||||
@@ -180,7 +179,7 @@ void __hwdom_init iommu_hwdom_init(struct domain *d)
|
||||
|
||||
void iommu_teardown(struct domain *d)
|
||||
{
|
||||
const struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
d->need_iommu = 0;
|
||||
hd->platform_ops->teardown(d);
|
||||
@@ -189,9 +188,7 @@ void iommu_teardown(struct domain *d)
|
||||
|
||||
void iommu_domain_destroy(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
|
||||
if ( !iommu_enabled || !hd->platform_ops )
|
||||
if ( !iommu_enabled || !dom_iommu(d)->platform_ops )
|
||||
return;
|
||||
|
||||
if ( need_iommu(d) )
|
||||
@@ -203,7 +200,7 @@ void iommu_domain_destroy(struct domain *d)
|
||||
int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
if ( !iommu_enabled || !hd->platform_ops )
|
||||
return 0;
|
||||
@@ -213,7 +210,7 @@ int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn,
|
||||
|
||||
int iommu_unmap_page(struct domain *d, unsigned long gfn)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
if ( !iommu_enabled || !hd->platform_ops )
|
||||
return 0;
|
||||
@@ -240,7 +237,7 @@ static void iommu_free_pagetables(unsigned long unused)
|
||||
|
||||
void iommu_iotlb_flush(struct domain *d, unsigned long gfn, unsigned int page_count)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
if ( !iommu_enabled || !hd->platform_ops || !hd->platform_ops->iotlb_flush )
|
||||
return;
|
||||
@@ -250,7 +247,7 @@ void iommu_iotlb_flush(struct domain *d, unsigned long gfn, unsigned int page_co
|
||||
|
||||
void iommu_iotlb_flush_all(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
if ( !iommu_enabled || !hd->platform_ops || !hd->platform_ops->iotlb_flush_all )
|
||||
return;
|
||||
@@ -346,12 +343,10 @@ void iommu_crash_shutdown(void)
|
||||
|
||||
bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature)
|
||||
{
|
||||
const struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
|
||||
if ( !iommu_enabled )
|
||||
return 0;
|
||||
|
||||
return test_bit(feature, hd->features);
|
||||
return test_bit(feature, dom_iommu(d)->features);
|
||||
}
|
||||
|
||||
static void iommu_dump_p2m_table(unsigned char key)
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <xen/prefetch.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <xen/irq.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
#include <asm/hvm/irq.h>
|
||||
#include <xen/delay.h>
|
||||
#include <xen/keyhandler.h>
|
||||
@@ -1228,7 +1227,7 @@ void iommu_read_msi_from_ire(
|
||||
|
||||
int iommu_add_device(struct pci_dev *pdev)
|
||||
{
|
||||
struct hvm_iommu *hd;
|
||||
const struct domain_iommu *hd;
|
||||
int rc;
|
||||
u8 devfn;
|
||||
|
||||
@@ -1237,7 +1236,7 @@ int iommu_add_device(struct pci_dev *pdev)
|
||||
|
||||
ASSERT(spin_is_locked(&pcidevs_lock));
|
||||
|
||||
hd = domain_hvm_iommu(pdev->domain);
|
||||
hd = dom_iommu(pdev->domain);
|
||||
if ( !iommu_enabled || !hd->platform_ops )
|
||||
return 0;
|
||||
|
||||
@@ -1259,14 +1258,14 @@ int iommu_add_device(struct pci_dev *pdev)
|
||||
|
||||
int iommu_enable_device(struct pci_dev *pdev)
|
||||
{
|
||||
struct hvm_iommu *hd;
|
||||
const struct domain_iommu *hd;
|
||||
|
||||
if ( !pdev->domain )
|
||||
return -EINVAL;
|
||||
|
||||
ASSERT(spin_is_locked(&pcidevs_lock));
|
||||
|
||||
hd = domain_hvm_iommu(pdev->domain);
|
||||
hd = dom_iommu(pdev->domain);
|
||||
if ( !iommu_enabled || !hd->platform_ops ||
|
||||
!hd->platform_ops->enable_device )
|
||||
return 0;
|
||||
@@ -1276,13 +1275,13 @@ int iommu_enable_device(struct pci_dev *pdev)
|
||||
|
||||
int iommu_remove_device(struct pci_dev *pdev)
|
||||
{
|
||||
struct hvm_iommu *hd;
|
||||
const struct domain_iommu *hd;
|
||||
u8 devfn;
|
||||
|
||||
if ( !pdev->domain )
|
||||
return -EINVAL;
|
||||
|
||||
hd = domain_hvm_iommu(pdev->domain);
|
||||
hd = dom_iommu(pdev->domain);
|
||||
if ( !iommu_enabled || !hd->platform_ops )
|
||||
return 0;
|
||||
|
||||
@@ -1322,7 +1321,7 @@ static int device_assigned(u16 seg, u8 bus, u8 devfn)
|
||||
|
||||
static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
struct pci_dev *pdev;
|
||||
int rc = 0;
|
||||
|
||||
@@ -1389,7 +1388,7 @@ static int assign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
|
||||
/* caller should hold the pcidevs_lock */
|
||||
int deassign_device(struct domain *d, u16 seg, u8 bus, u8 devfn)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
struct pci_dev *pdev = NULL;
|
||||
int ret = 0;
|
||||
|
||||
@@ -1437,7 +1436,7 @@ static int iommu_get_device_group(
|
||||
struct domain *d, u16 seg, u8 bus, u8 devfn,
|
||||
XEN_GUEST_HANDLE_64(uint32) buf, int max_sdevs)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
struct pci_dev *pdev;
|
||||
int group_id, sdev_id;
|
||||
u32 bdf;
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <xen/irq.h>
|
||||
#include <xen/sched.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
#include <xen/time.h>
|
||||
#include <xen/list.h>
|
||||
#include <xen/pci.h>
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <xen/domain_page.h>
|
||||
#include <xen/iocap.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
#include <xen/numa.h>
|
||||
#include <xen/softirq.h>
|
||||
#include <xen/time.h>
|
||||
@@ -253,7 +252,7 @@ static u64 addr_to_dma_page_maddr(struct domain *domain, u64 addr, int alloc)
|
||||
{
|
||||
struct acpi_drhd_unit *drhd;
|
||||
struct pci_dev *pdev;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(domain);
|
||||
struct domain_iommu *hd = dom_iommu(domain);
|
||||
int addr_width = agaw_to_width(hd->arch.agaw);
|
||||
struct dma_pte *parent, *pte = NULL;
|
||||
int level = agaw_to_level(hd->arch.agaw);
|
||||
@@ -561,7 +560,7 @@ static void iommu_flush_all(void)
|
||||
static void __intel_iommu_iotlb_flush(struct domain *d, unsigned long gfn,
|
||||
int dma_old_pte_present, unsigned int page_count)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
struct acpi_drhd_unit *drhd;
|
||||
struct iommu *iommu;
|
||||
int flush_dev_iotlb;
|
||||
@@ -612,7 +611,7 @@ static void intel_iommu_iotlb_flush_all(struct domain *d)
|
||||
/* clear one page's page table */
|
||||
static void dma_pte_clear_one(struct domain *domain, u64 addr)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(domain);
|
||||
struct domain_iommu *hd = dom_iommu(domain);
|
||||
struct dma_pte *page = NULL, *pte = NULL;
|
||||
u64 pg_maddr;
|
||||
|
||||
@@ -1245,9 +1244,7 @@ void __init iommu_free(struct acpi_drhd_unit *drhd)
|
||||
|
||||
static int intel_iommu_domain_init(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
|
||||
hd->arch.agaw = width_to_agaw(DEFAULT_DOMAIN_ADDRESS_WIDTH);
|
||||
dom_iommu(d)->arch.agaw = width_to_agaw(DEFAULT_DOMAIN_ADDRESS_WIDTH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1281,7 +1278,7 @@ int domain_context_mapping_one(
|
||||
struct iommu *iommu,
|
||||
u8 bus, u8 devfn, const struct pci_dev *pdev)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(domain);
|
||||
struct domain_iommu *hd = dom_iommu(domain);
|
||||
struct context_entry *context, *context_entries;
|
||||
u64 maddr, pgd_maddr;
|
||||
u16 seg = iommu->intel->drhd->segment;
|
||||
@@ -1651,10 +1648,9 @@ static int domain_context_unmap(
|
||||
|
||||
if ( found == 0 )
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(domain);
|
||||
int iommu_domid;
|
||||
|
||||
clear_bit(iommu->index, &hd->arch.iommu_bitmap);
|
||||
clear_bit(iommu->index, &dom_iommu(domain)->arch.iommu_bitmap);
|
||||
|
||||
iommu_domid = domain_iommu_domid(domain, iommu);
|
||||
if ( iommu_domid == -1 )
|
||||
@@ -1673,7 +1669,7 @@ out:
|
||||
|
||||
static void iommu_domain_teardown(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
struct mapped_rmrr *mrmrr, *tmp;
|
||||
|
||||
if ( list_empty(&acpi_drhd_units) )
|
||||
@@ -1698,7 +1694,7 @@ static int intel_iommu_map_page(
|
||||
struct domain *d, unsigned long gfn, unsigned long mfn,
|
||||
unsigned int flags)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
struct dma_pte *page = NULL, *pte = NULL, old, new = { 0 };
|
||||
u64 pg_maddr;
|
||||
|
||||
@@ -1764,7 +1760,7 @@ void iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte,
|
||||
{
|
||||
struct acpi_drhd_unit *drhd;
|
||||
struct iommu *iommu = NULL;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
int flush_dev_iotlb;
|
||||
int iommu_domid;
|
||||
|
||||
@@ -1805,7 +1801,6 @@ static int __init vtd_ept_page_compatible(struct iommu *iommu)
|
||||
*/
|
||||
static void iommu_set_pgd(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
mfn_t pgd_mfn;
|
||||
|
||||
ASSERT( is_hvm_domain(d) && d->arch.hvm_domain.hap_enabled );
|
||||
@@ -1814,7 +1809,8 @@ static void iommu_set_pgd(struct domain *d)
|
||||
return;
|
||||
|
||||
pgd_mfn = pagetable_get_mfn(p2m_get_pagetable(p2m_get_hostp2m(d)));
|
||||
hd->arch.pgd_maddr = pagetable_get_paddr(pagetable_from_mfn(pgd_mfn));
|
||||
dom_iommu(d)->arch.pgd_maddr =
|
||||
pagetable_get_paddr(pagetable_from_mfn(pgd_mfn));
|
||||
}
|
||||
|
||||
static int rmrr_identity_mapping(struct domain *d, bool_t map,
|
||||
@@ -1823,7 +1819,7 @@ static int rmrr_identity_mapping(struct domain *d, bool_t map,
|
||||
unsigned long base_pfn = rmrr->base_address >> PAGE_SHIFT_4K;
|
||||
unsigned long end_pfn = PAGE_ALIGN_4K(rmrr->end_address) >> PAGE_SHIFT_4K;
|
||||
struct mapped_rmrr *mrmrr;
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
ASSERT(spin_is_locked(&pcidevs_lock));
|
||||
ASSERT(rmrr->base_address < rmrr->end_address);
|
||||
@@ -2470,12 +2466,12 @@ static void vtd_dump_p2m_table_level(paddr_t pt_maddr, int level, paddr_t gpa,
|
||||
|
||||
static void vtd_dump_p2m_table(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd;
|
||||
const struct domain_iommu *hd;
|
||||
|
||||
if ( list_empty(&acpi_drhd_units) )
|
||||
return;
|
||||
|
||||
hd = domain_hvm_iommu(d);
|
||||
hd = dom_iommu(d);
|
||||
printk("p2m table has %d levels\n", agaw_to_level(hd->arch.agaw));
|
||||
vtd_dump_p2m_table_level(hd->arch.pgd_maddr, agaw_to_level(hd->arch.agaw), 0, 0);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <xen/xmalloc.h>
|
||||
#include <xen/domain_page.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
#include <xen/numa.h>
|
||||
#include <xen/softirq.h>
|
||||
#include <xen/time.h>
|
||||
|
||||
@@ -42,7 +42,7 @@ int __init iommu_setup_hpet_msi(struct msi_desc *msi)
|
||||
|
||||
int arch_iommu_populate_page_table(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
struct page_info *page;
|
||||
int rc = 0, n = 0;
|
||||
|
||||
@@ -112,7 +112,7 @@ void __hwdom_init arch_iommu_check_autotranslated_hwdom(struct domain *d)
|
||||
|
||||
int arch_iommu_domain_init(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
struct domain_iommu *hd = dom_iommu(d);
|
||||
|
||||
spin_lock_init(&hd->arch.mapping_lock);
|
||||
INIT_LIST_HEAD(&hd->arch.g2m_ioport_list);
|
||||
@@ -123,7 +123,7 @@ int arch_iommu_domain_init(struct domain *d)
|
||||
|
||||
void arch_iommu_domain_destroy(struct domain *d)
|
||||
{
|
||||
struct hvm_iommu *hd = domain_hvm_iommu(d);
|
||||
const struct domain_iommu *hd = dom_iommu(d);
|
||||
struct list_head *ioport_list, *tmp;
|
||||
struct g2m_ioport *ioport;
|
||||
|
||||
|
||||
@@ -11,12 +11,10 @@
|
||||
#include <asm/gic.h>
|
||||
#include <public/hvm/params.h>
|
||||
#include <xen/serial.h>
|
||||
#include <xen/hvm/iommu.h>
|
||||
|
||||
struct hvm_domain
|
||||
{
|
||||
uint64_t params[HVM_NR_PARAMS];
|
||||
struct hvm_iommu iommu;
|
||||
} __cacheline_aligned;
|
||||
|
||||
#ifdef CONFIG_ARM_64
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef __ASM_ARM_HVM_IOMMU_H_
|
||||
#define __ASM_ARM_HVM_IOMMU_H_
|
||||
|
||||
struct arch_hvm_iommu
|
||||
{
|
||||
/* Private information for the IOMMU drivers */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
#endif /* __ASM_ARM_HVM_IOMMU_H_ */
|
||||
@@ -15,9 +15,14 @@
|
||||
#ifndef __ARCH_ARM_IOMMU_H__
|
||||
#define __ARCH_ARM_IOMMU_H__
|
||||
|
||||
struct arch_iommu
|
||||
{
|
||||
/* Private information for the IOMMU drivers */
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/* Always share P2M Table between the CPU and the IOMMU */
|
||||
#define iommu_use_hap_pt(d) (1)
|
||||
#define domain_hvm_iommu(d) (&d->arch.hvm_domain.iommu)
|
||||
|
||||
const struct iommu_ops *iommu_get_ops(void);
|
||||
void __init iommu_set_ops(const struct iommu_ops *ops);
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include <asm/hvm/vlapic.h>
|
||||
#include <asm/hvm/vioapic.h>
|
||||
#include <asm/hvm/io.h>
|
||||
#include <xen/hvm/iommu.h>
|
||||
#include <asm/hvm/viridian.h>
|
||||
#include <asm/hvm/vmx/vmcs.h>
|
||||
#include <asm/hvm/svm/vmcb.h>
|
||||
@@ -122,9 +121,6 @@ struct hvm_domain {
|
||||
spinlock_t uc_lock;
|
||||
bool_t is_in_uc_mode;
|
||||
|
||||
/* Pass-through */
|
||||
struct hvm_iommu hvm_iommu;
|
||||
|
||||
/* hypervisor intercepted msix table */
|
||||
struct list_head msixtbl_list;
|
||||
spinlock_t msixtbl_list_lock;
|
||||
|
||||
@@ -46,7 +46,7 @@ struct g2m_ioport {
|
||||
unsigned int np;
|
||||
};
|
||||
|
||||
struct arch_hvm_iommu
|
||||
struct arch_iommu
|
||||
{
|
||||
u64 pgd_maddr; /* io page directory machine address */
|
||||
spinlock_t mapping_lock; /* io page table lock */
|
||||
|
||||
@@ -15,11 +15,12 @@
|
||||
#ifndef __ARCH_X86_IOMMU_H__
|
||||
#define __ARCH_X86_IOMMU_H__
|
||||
|
||||
#include <asm/hvm/iommu.h> /* For now - should really be merged here. */
|
||||
|
||||
#define MAX_IOMMUS 32
|
||||
|
||||
/* Does this domain have a P2M table we can use as its IOMMU pagetable? */
|
||||
#define iommu_use_hap_pt(d) (hap_enabled(d) && iommu_hap_pt_share)
|
||||
#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu)
|
||||
|
||||
void iommu_update_ire_from_apic(unsigned int apic, unsigned int reg, unsigned int value);
|
||||
unsigned int iommu_read_apic_from_ire(unsigned int apic, unsigned int reg);
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2006, Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
* Place - Suite 330, Boston, MA 02111-1307 USA.
|
||||
*
|
||||
* Copyright (C) Allen Kay <allen.m.kay@intel.com>
|
||||
*/
|
||||
|
||||
#ifndef __XEN_HVM_IOMMU_H__
|
||||
#define __XEN_HVM_IOMMU_H__
|
||||
|
||||
#include <xen/iommu.h>
|
||||
#include <xen/list.h>
|
||||
#include <asm/hvm/iommu.h>
|
||||
|
||||
struct hvm_iommu {
|
||||
struct arch_hvm_iommu arch;
|
||||
|
||||
/* iommu_ops */
|
||||
const struct iommu_ops *platform_ops;
|
||||
|
||||
#ifdef HAS_DEVICE_TREE
|
||||
/* List of DT devices assigned to this domain */
|
||||
struct list_head dt_devices;
|
||||
#endif
|
||||
|
||||
/* Features supported by the IOMMU */
|
||||
DECLARE_BITMAP(features, IOMMU_FEAT_count);
|
||||
};
|
||||
|
||||
#define iommu_set_feature(d, f) set_bit((f), domain_hvm_iommu(d)->features)
|
||||
#define iommu_clear_feature(d, f) clear_bit((f), domain_hvm_iommu(d)->features)
|
||||
|
||||
#endif /* __XEN_HVM_IOMMU_H__ */
|
||||
@@ -84,6 +84,24 @@ enum iommu_feature
|
||||
|
||||
bool_t iommu_has_feature(struct domain *d, enum iommu_feature feature);
|
||||
|
||||
struct domain_iommu {
|
||||
struct arch_iommu arch;
|
||||
|
||||
/* iommu_ops */
|
||||
const struct iommu_ops *platform_ops;
|
||||
|
||||
#ifdef HAS_DEVICE_TREE
|
||||
/* List of DT devices assigned to this domain */
|
||||
struct list_head dt_devices;
|
||||
#endif
|
||||
|
||||
/* Features supported by the IOMMU */
|
||||
DECLARE_BITMAP(features, IOMMU_FEAT_count);
|
||||
};
|
||||
|
||||
#define dom_iommu(d) (&(d)->iommu)
|
||||
#define iommu_set_feature(d, f) set_bit(f, dom_iommu(d)->features)
|
||||
#define iommu_clear_feature(d, f) clear_bit(f, dom_iommu(d)->features)
|
||||
|
||||
#ifdef HAS_PCI
|
||||
void pt_pci_init(void);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <xen/timer.h>
|
||||
#include <xen/rangeset.h>
|
||||
#include <xen/domain.h>
|
||||
#include <xen/iommu.h>
|
||||
#include <xen/rcupdate.h>
|
||||
#include <xen/cpumask.h>
|
||||
#include <xen/nodemask.h>
|
||||
@@ -357,6 +358,8 @@ struct domain
|
||||
enum guest_type guest_type;
|
||||
|
||||
#ifdef HAS_PASSTHROUGH
|
||||
struct domain_iommu iommu;
|
||||
|
||||
/* Does this guest need iommu mappings (-1 meaning "being set up")? */
|
||||
s8 need_iommu;
|
||||
#endif
|
||||
|
||||