diff options
author | Jan Beulich <jbeulich@novell.com> | 2011-06-23 11:32:43 +0100 |
---|---|---|
committer | Jan Beulich <jbeulich@novell.com> | 2011-06-23 11:32:43 +0100 |
commit | c24536b636f23e4d3202968fcad129d979881e2c (patch) | |
tree | e3e188d484b371f8770714bc0453f6395d6da241 /xen/include/xen | |
parent | eebfd58f212c5fb75e602ac1aa126863452375da (diff) | |
download | xen-c24536b636f23e4d3202968fcad129d979881e2c.tar.gz xen-c24536b636f23e4d3202968fcad129d979881e2c.tar.bz2 xen-c24536b636f23e4d3202968fcad129d979881e2c.zip |
replace d->nr_pirqs sized arrays with radix tree
With this it is questionable whether retaining struct domain's
nr_pirqs is actually necessary - the value now only serves for bounds
checking, and this boundary could easily be nr_irqs.
Note that ia64, the build of which is broken currently anyway, is only
being partially fixed up.
v2: adjustments for split setup/teardown of translation data
v3: re-sync with radix tree implementation changes
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Diffstat (limited to 'xen/include/xen')
-rw-r--r-- | xen/include/xen/domain.h | 6 | ||||
-rw-r--r-- | xen/include/xen/event.h | 2 | ||||
-rw-r--r-- | xen/include/xen/hvm/irq.h | 37 | ||||
-rw-r--r-- | xen/include/xen/iommu.h | 4 | ||||
-rw-r--r-- | xen/include/xen/irq.h | 36 | ||||
-rw-r--r-- | xen/include/xen/pci.h | 5 | ||||
-rw-r--r-- | xen/include/xen/sched.h | 9 |
7 files changed, 73 insertions, 26 deletions
diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index ddebbe14a9..765e1328fa 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -38,6 +38,12 @@ struct vcpu_guest_context *alloc_vcpu_guest_context(void); void free_vcpu_guest_context(struct vcpu_guest_context *); #endif +/* Allocate/free a PIRQ structure. */ +#ifndef alloc_pirq_struct +struct pirq *alloc_pirq_struct(struct domain *); +#endif +void free_pirq_struct(void *); + /* * Initialise/destroy arch-specific details of a VCPU. * - vcpu_initialise() is called after the basic generic fields of the diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index f39207c8d0..257cb3a5f0 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -36,7 +36,7 @@ void send_guest_global_virq(struct domain *d, int virq); * @pirq: Physical IRQ number * Returns TRUE if the delivery port was already pending. */ -int send_guest_pirq(struct domain *d, int pirq); +int send_guest_pirq(struct domain *, const struct pirq *); /* Send a notification from a given domain's event-channel port. */ int evtchn_send(struct domain *d, unsigned int lport); diff --git a/xen/include/xen/hvm/irq.h b/xen/include/xen/hvm/irq.h index e20cdcf1a8..b91c48de9b 100644 --- a/xen/include/xen/hvm/irq.h +++ b/xen/include/xen/hvm/irq.h @@ -25,7 +25,7 @@ #include <xen/types.h> #include <xen/spinlock.h> #include <xen/tasklet.h> -#include <asm/irq.h> +#include <xen/timer.h> #include <public/hvm/save.h> struct dev_intx_gsi_link { @@ -38,11 +38,15 @@ struct dev_intx_gsi_link { #define _HVM_IRQ_DPCI_MACH_PCI_SHIFT 0 #define _HVM_IRQ_DPCI_MACH_MSI_SHIFT 1 +#define _HVM_IRQ_DPCI_MAPPED_SHIFT 2 +#define _HVM_IRQ_DPCI_EOI_LATCH_SHIFT 3 #define _HVM_IRQ_DPCI_GUEST_PCI_SHIFT 4 #define _HVM_IRQ_DPCI_GUEST_MSI_SHIFT 5 #define _HVM_IRQ_DPCI_TRANSLATE_SHIFT 15 #define HVM_IRQ_DPCI_MACH_PCI (1 << _HVM_IRQ_DPCI_MACH_PCI_SHIFT) #define HVM_IRQ_DPCI_MACH_MSI (1 << _HVM_IRQ_DPCI_MACH_MSI_SHIFT) +#define HVM_IRQ_DPCI_MAPPED (1 << _HVM_IRQ_DPCI_MAPPED_SHIFT) +#define HVM_IRQ_DPCI_EOI_LATCH (1 << _HVM_IRQ_DPCI_EOI_LATCH_SHIFT) #define HVM_IRQ_DPCI_GUEST_PCI (1 << _HVM_IRQ_DPCI_GUEST_PCI_SHIFT) #define HVM_IRQ_DPCI_GUEST_MSI (1 << _HVM_IRQ_DPCI_GUEST_MSI_SHIFT) #define HVM_IRQ_DPCI_TRANSLATE (1 << _HVM_IRQ_DPCI_TRANSLATE_SHIFT) @@ -63,14 +67,6 @@ struct hvm_gmsi_info { int dest_vcpu_id; /* -1 :multi-dest, non-negative: dest_vcpu_id */ }; -struct hvm_mirq_dpci_mapping { - uint32_t flags; - int pending; - struct list_head digl_list; - struct domain *dom; - struct hvm_gmsi_info gmsi; -}; - struct hvm_girq_dpci_mapping { struct list_head list; uint8_t device; @@ -88,20 +84,33 @@ struct hvm_girq_dpci_mapping { /* Protected by domain's event_lock */ struct hvm_irq_dpci { - /* Machine IRQ to guest device/intx mapping. */ - unsigned long *mapping; - struct hvm_mirq_dpci_mapping *mirq; - unsigned long *dirq_mask; /* Guest IRQ to guest device/intx mapping. */ struct list_head girq[NR_HVM_IRQS]; /* Record of mapped ISA IRQs */ DECLARE_BITMAP(isairq_map, NR_ISAIRQS); /* Record of mapped Links */ uint8_t link_cnt[NR_LINK]; - struct timer *hvm_timer; struct tasklet dirq_tasklet; }; +/* Machine IRQ to guest device/intx mapping. */ +struct hvm_pirq_dpci { + uint32_t flags; + bool_t masked; + uint16_t pending; + struct list_head digl_list; + struct domain *dom; + struct hvm_gmsi_info gmsi; + struct timer timer; +}; + +void pt_pirq_init(struct domain *, struct hvm_pirq_dpci *); +bool_t pt_pirq_cleanup_check(struct hvm_pirq_dpci *); +int pt_pirq_iterate(struct domain *d, + int (*cb)(struct domain *, + struct hvm_pirq_dpci *, void *arg), + void *arg); + /* Modify state of a PCI INTx wire. */ void hvm_pci_intx_assert( struct domain *d, unsigned int device, unsigned int intx); diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index d4c94d0c16..a8a60f9ae3 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -88,7 +88,9 @@ int iommu_unmap_page(struct domain *d, unsigned long gfn); void iommu_pte_flush(struct domain *d, u64 gfn, u64 *pte, int order, int present); 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); + +struct pirq; +int hvm_do_IRQ_dpci(struct domain *, struct pirq *); int dpci_ioport_intercept(ioreq_t *p); int pt_irq_create_bind_vtd(struct domain *d, xen_domctl_bind_pt_irq_t *pt_irq_bind); diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h index 02456e4a80..b771fa2d75 100644 --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -3,6 +3,7 @@ #include <xen/config.h> #include <xen/cpumask.h> +#include <xen/rcupdate.h> #include <xen/spinlock.h> #include <xen/time.h> #include <xen/list.h> @@ -135,13 +136,42 @@ extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs); struct domain; struct vcpu; -extern int pirq_guest_eoi(struct domain *d, int irq); + +struct pirq { + int pirq; + u16 evtchn; + bool_t masked; + struct rcu_head rcu_head; + struct arch_pirq arch; +}; + +#define pirq_info(d, p) ((struct pirq *)radix_tree_lookup(&(d)->pirq_tree, p)) + +/* Use this instead of pirq_info() if the structure may need allocating. */ +extern struct pirq *pirq_get_info(struct domain *, int pirq); + +#define pirq_field(d, p, f) ({ \ + const struct pirq *__pi = pirq_info(d, p); \ + __pi ? __pi->f : 0; \ +}) +#define pirq_to_evtchn(d, pirq) pirq_field(d, pirq, evtchn) +#define pirq_masked(d, pirq) pirq_field(d, pirq, masked) + +void pirq_cleanup_check(struct pirq *, struct domain *); + +#define pirq_cleanup_check(pirq, d) \ + ((pirq)->evtchn ? pirq_cleanup_check(pirq, d) : (void)0) + +extern void pirq_guest_eoi(struct domain *, struct pirq *); +extern void desc_guest_eoi(struct domain *, struct irq_desc *, struct pirq *); extern int pirq_guest_unmask(struct domain *d); -extern int pirq_guest_bind(struct vcpu *v, int irq, int will_share); -extern void pirq_guest_unbind(struct domain *d, int irq); +extern int pirq_guest_bind(struct vcpu *, struct pirq *, int will_share); +extern void pirq_guest_unbind(struct domain *d, struct pirq *); extern void pirq_set_affinity(struct domain *d, int irq, const cpumask_t *); extern irq_desc_t *domain_spin_lock_irq_desc( struct domain *d, int irq, unsigned long *pflags); +extern irq_desc_t *pirq_spin_lock_irq_desc( + struct domain *, const struct pirq *, unsigned long *pflags); static inline void set_native_irq_info(unsigned int irq, const cpumask_t *mask) { diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index 79082d1721..49eabbcd49 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -117,8 +117,9 @@ int pci_find_cap_offset(u8 bus, u8 dev, u8 func, u8 cap); int pci_find_next_cap(u8 bus, unsigned int devfn, u8 pos, int cap); int pci_find_ext_capability(int seg, int bus, int devfn, int cap); -int msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable); -void msixtbl_pt_unregister(struct domain *d, int pirq); +struct pirq; +int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable); +void msixtbl_pt_unregister(struct domain *, struct pirq *); void msixtbl_pt_cleanup(struct domain *d); void pci_enable_acs(struct pci_dev *pdev); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index e3eab706a3..902cd07418 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -12,6 +12,7 @@ #include <xen/rcupdate.h> #include <xen/cpumask.h> #include <xen/nodemask.h> +#include <xen/radix-tree.h> #include <xen/multicall.h> #include <public/xen.h> #include <public/domctl.h> @@ -227,13 +228,11 @@ struct domain struct grant_table *grant_table; /* - * Interrupt to event-channel mappings. Updates should be protected by the - * domain's event-channel spinlock. Read accesses can also synchronise on - * the lock, but races don't usually matter. + * Interrupt to event-channel mappings and other per-guest-pirq data. + * Protected by the domain's event-channel spinlock. */ unsigned int nr_pirqs; - u16 *pirq_to_evtchn; - unsigned long *pirq_mask; + struct radix_tree_root pirq_tree; /* I/O capabilities (access to IRQs and memory-mapped I/O). */ struct rangeset *iomem_caps; |