Generic and VT-d specific Xen header changes for PCI passthru.

Signed-off-by: default avatarAllen Kay <allen.m.kay@intel.com>
Signed-off-by: default avatarGuy Zana <guy@neocleus.com>
parent 62916af3
......@@ -196,4 +196,6 @@ struct acpi_sleep_info {
extern u8 x86_acpiid_to_apicid[];
#define MAX_LOCAL_APIC 256
extern int acpi_dmar_init(void);
#endif /*_ASM_ACPI_H*/
......@@ -17,6 +17,7 @@
#include <asm/acpi.h>
#include <asm/page.h>
#include <xen/kexec.h>
#include <asm/iommu.h>
/*
* Here we define all the compile-time 'special' virtual
......@@ -40,6 +41,8 @@ enum fixed_addresses {
FIX_KEXEC_BASE_0,
FIX_KEXEC_BASE_END = FIX_KEXEC_BASE_0 \
+ ((KEXEC_XEN_NO_PAGES >> 1) * KEXEC_IMAGE_NR) - 1,
FIX_IOMMU_REGS_BASE_0,
FIX_IOMMU_REGS_END = FIX_IOMMU_REGS_BASE_0 + MAX_IOMMUS-1,
__end_of_fixed_addresses
};
......
......@@ -21,10 +21,12 @@
#ifndef __ASM_X86_HVM_DOMAIN_H__
#define __ASM_X86_HVM_DOMAIN_H__
#include <asm/iommu.h>
#include <asm/hvm/irq.h>
#include <asm/hvm/vpt.h>
#include <asm/hvm/vlapic.h>
#include <asm/hvm/io.h>
#include <asm/hvm/iommu.h>
#include <public/hvm/params.h>
#include <public/hvm/save.h>
......@@ -57,6 +59,9 @@ struct hvm_domain {
uint64_t params[HVM_NR_PARAMS];
unsigned long vmx_apic_access_mfn;
/* Pass-through */
struct hvm_iommu hvm_iommu;
};
#endif /* __ASM_X86_HVM_DOMAIN_H__ */
......
......@@ -151,6 +151,7 @@ void send_invalidate_req(void);
extern void handle_mmio(unsigned long gpa);
extern void hvm_interrupt_post(struct vcpu *v, int vector, int type);
extern void hvm_io_assist(void);
extern void hvm_dpci_eoi(unsigned int guest_irq, union vioapic_redir_entry *ent);
#endif /* __ASM_X86_HVM_IO_H__ */
/*
* 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 __ASM_X86_HVM_IOMMU_H__
#define __ASM_X86_HVM_IOMMU_H__
#include <asm/iommu.h>
#include <asm/hvm/irq.h>
#include <asm/hvm/vpt.h>
#include <asm/hvm/vlapic.h>
#include <asm/hvm/io.h>
#include <public/hvm/params.h>
#include <public/hvm/save.h>
struct hvm_iommu {
spinlock_t iommu_list_lock; /* protect iommu specific lists */
struct list_head pdev_list; /* direct accessed pci devices */
struct dma_pte *pgd; /* io page directory root */
spinlock_t mapping_lock; /* io page table lock */
int agaw; /* adjusted guest address width, 0 is level 2 30-bit */
struct list_head g2m_ioport_list; /* guest to machine ioport mapping */
};
#endif // __ASM_X86_HVM_IOMMU_H__
......@@ -29,6 +29,16 @@
#include <asm/hvm/vioapic.h>
#include <public/hvm/save.h>
struct hvm_irq_mapping {
uint8_t valid;
uint8_t device;
uint8_t intx;
union {
uint8_t guest_gsi;
uint8_t machine_gsi;
};
};
struct hvm_irq {
/*
* Virtual interrupt wires for a single PCI bus.
......@@ -88,6 +98,12 @@ struct hvm_irq {
/* Last VCPU that was delivered a LowestPrio interrupt. */
u8 round_robin_prev_vcpu;
/* machine irq to guest device/intx mapping */
struct hvm_irq_mapping mirq[NR_IRQS];
/* guest irq to guest device/intx mapping */
struct hvm_irq_mapping girq[NR_IRQS];
DECLARE_BITMAP(dirq_mask, NR_IRQS);
};
#define hvm_pci_intx_gsi(dev, intx) \
......
This diff is collapsed.
/*
* 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 _IOMMU_H_
#define _IOMMU_H_
#include <xen/init.h>
#include <xen/bitmap.h>
#include <xen/irq.h>
#include <xen/spinlock.h>
#include <xen/mm.h>
#include <xen/xmalloc.h>
#include <asm/hvm/vmx/intel-iommu.h>
#include <public/hvm/ioreq.h>
extern int vtd_enabled;
#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu)
#define domain_vmx_iommu(d) (&d->arch.hvm_domain.hvm_iommu.vmx_iommu)
/*
* The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded
* in a single byte as follows:
*
* 15:8 = bus
* 7:3 = slot
* 2:0 = function
*/
#define PCI_DEVFN(slot,func) (((slot & 0x1f) << 3) | (func & 0x07))
#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f)
#define PCI_FUNC(devfn) ((devfn) & 0x07)
struct pci_dev {
struct list_head list;
u8 bus;
u8 devfn;
};
struct iommu {
struct list_head list;
void __iomem *reg; /* Pointer to hardware regs, virtual addr */
u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
u64 cap;
u64 ecap;
spinlock_t lock; /* protect context, domain ids */
spinlock_t register_lock; /* protect iommu register handling */
struct root_entry *root_entry; /* virtual address */
unsigned int vector;
};
int iommu_setup(void);
int iommu_domain_init(struct domain *d);
int assign_device(struct domain *d, u8 bus, u8 devfn);
int release_devices(struct domain *d);
int iommu_map_page(struct domain *d, dma_addr_t gfn, dma_addr_t mfn);
int iommu_unmap_page(struct domain *d, dma_addr_t gfn);
void iommu_flush(struct domain *d, dma_addr_t gfn, u64 *p2m_entry);
void iommu_set_pgd(struct domain *d);
void iommu_domain_teardown(struct domain *d);
int hvm_do_IRQ_dpci(struct domain *d, unsigned int irq);
#endif // _IOMMU_H_
......@@ -14,6 +14,9 @@
#define wbinvd() \
__asm__ __volatile__ ("wbinvd": : :"memory");
#define clflush(a) \
__asm__ __volatile__ ("clflush (%0)": :"r"(a));
#define nop() __asm__ __volatile__ ("nop")
#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
......
......@@ -432,7 +432,69 @@ struct xen_domctl_sendtrigger {
typedef struct xen_domctl_sendtrigger xen_domctl_sendtrigger_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_sendtrigger_t);
/* Assign PCI device to HVM guest. Sets up IOMMU structures. */
#define XEN_DOMCTL_assign_device 37
#define DPCI_ADD_MAPPING 1
#define DPCI_REMOVE_MAPPING 0
struct xen_domctl_assign_device {
uint32_t machine_bdf; /* machine PCI ID of assigned device */
};
typedef struct xen_domctl_assign_device xen_domctl_assign_device_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t);
/* Pass-through interrupts: bind real irq -> hvm devfn. */
#define XEN_DOMCTL_bind_pt_irq 38
typedef enum pt_irq_type_e {
PT_IRQ_TYPE_PCI,
PT_IRQ_TYPE_ISA
} pt_irq_type_t;
struct xen_domctl_bind_pt_irq {
uint32_t machine_irq;
pt_irq_type_t irq_type;
uint32_t hvm_domid;
union {
struct {
uint8_t isa_irq;
} isa;
struct {
uint8_t bus;
uint8_t device;
uint8_t intx;
} pci;
} u;
};
typedef struct xen_domctl_bind_pt_irq xen_domctl_bind_pt_irq_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_bind_pt_irq_t);
/* Bind machine I/O address range -> HVM address range. */
#define XEN_DOMCTL_memory_mapping 39
struct xen_domctl_memory_mapping {
uint64_t first_gfn; /* first page (hvm guest phys page) in range */
uint64_t first_mfn; /* first page (machine page) in range */
uint64_t nr_mfns; /* number of pages in range (>0) */
uint32_t add_mapping; /* add or remove mapping */
uint32_t padding; /* padding for 64-bit aligned structure */
};
typedef struct xen_domctl_memory_mapping xen_domctl_memory_mapping_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_memory_mapping_t);
/* Bind machine I/O port range -> HVM I/O port range. */
#define XEN_DOMCTL_ioport_mapping 40
struct xen_domctl_ioport_mapping {
uint32_t first_gport; /* first guest IO port*/
uint32_t first_mport; /* first machine IO port */
uint32_t nr_ports; /* size of port range */
uint32_t add_mapping; /* add or remove mapping */
};
typedef struct xen_domctl_ioport_mapping xen_domctl_ioport_mapping_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_ioport_mapping_t);
struct xen_domctl {
uint32_t cmd;
uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
......@@ -462,6 +524,10 @@ struct xen_domctl {
struct xen_domctl_hvmcontext hvmcontext;
struct xen_domctl_address_size address_size;
struct xen_domctl_sendtrigger sendtrigger;
struct xen_domctl_assign_device assign_device;
struct xen_domctl_bind_pt_irq bind_pt_irq;
struct xen_domctl_memory_mapping memory_mapping;
struct xen_domctl_ioport_mapping ioport_mapping;
uint8_t pad[128];
} u;
};
......
......@@ -367,9 +367,79 @@ enum acpi_table_id {
ACPI_SPMI,
ACPI_HPET,
ACPI_MCFG,
ACPI_DMAR,
ACPI_TABLE_COUNT
};
/* DMA Remapping Reporting Table (DMAR) */
#define DMAR_FLAGS_INTR_REMAP 0x1 /* intr remap supported */
struct acpi_table_dmar {
struct acpi_table_header header;
u8 haw; /* Host address Width */
u8 flags;
u8 reserved[10];
} __attribute__ ((packed));
struct acpi_dmar_entry_header {
u16 type;
u16 length;
} __attribute__((packed));
enum acpi_dmar_entry_type {
ACPI_DMAR_DRHD = 0,
ACPI_DMAR_RMRR,
ACPI_DMAR_ATSR,
ACPI_DMAR_ENTRY_COUNT
};
#define DRHD_FLAGS_INCLUDE_ALL 0x1 /* drhd remaps remaining devices */
struct acpi_table_drhd {
struct acpi_dmar_entry_header header;
u8 flags;
u8 reserved;
u16 segment;
u64 address; /* register base address for this drhd */
} __attribute__ ((packed));
struct acpi_table_rmrr {
struct acpi_dmar_entry_header header;
u16 reserved;
u16 segment;
u64 base_address;
u64 end_address;
} __attribute__ ((packed));
struct acpi_table_atsr {
struct acpi_dmar_entry_header header;
u8 flags;
u8 reserved;
u16 segment;
} __attribute__ ((packed));
enum acpi_dev_scope_type {
ACPI_DEV_ENDPOINT=0x01, /* PCI Endpoing device */
ACPI_DEV_P2PBRIDGE, /* PCI-PCI Bridge */
ACPI_DEV_IOAPIC, /* IOAPIC device*/
ACPI_DEV_MSI_HPET, /* MSI capable HPET*/
ACPI_DEV_ENTRY_COUNT
};
struct acpi_dev_scope {
u8 dev_type;
u8 length;
u8 reserved[2];
u8 enum_id;
u8 start_bus;
} __attribute__((packed));
struct acpi_pci_path {
u8 dev;
u8 fn;
} __attribute__((packed));
typedef int (*acpi_dmar_entry_handler) (struct acpi_dmar_entry_header *header, const unsigned long end);
typedef int (*acpi_table_handler) (unsigned long phys_addr, unsigned long size);
extern acpi_table_handler acpi_table_ops[ACPI_TABLE_COUNT];
......
......@@ -64,6 +64,9 @@ extern irq_desc_t irq_desc[NR_IRQS];
extern int setup_irq(unsigned int, struct irqaction *);
extern void free_irq(unsigned int);
extern int request_irq(unsigned int irq,
void (*handler)(int, void *, struct cpu_user_regs *),
unsigned long irqflags, const char * devname, void *dev_id);
extern hw_irq_controller no_irq_type;
extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment