All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs
@ 2017-03-29 14:39 Roger Pau Monne
  2017-03-29 14:39 ` [PATCH v3 1/8] x86/vioapic: expand hvm_vioapic to contain vIO APIC internal state Roger Pau Monne
                   ` (8 more replies)
  0 siblings, 9 replies; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:39 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky

Hello,

This patch series introduce support for having a variable number of entries in
vIO APICs, and also having a variable number of vIO APICs per domain. This
functionality is not used by unprivileged guests, that are still limited to a
single IO APIC with 48 entries.

The functionality introduced is only used by PVHv2 Dom0, in order to copy the
IO APIC topology found on bare metal.

A private osstest flight is currently running against this series.

They can also be found in my personal git tree:

git://xenbits.xen.org/people/royger/xen.git vioapics_v3

Thanks, Roger.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH v3 1/8] x86/vioapic: expand hvm_vioapic to contain vIO APIC internal state
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
@ 2017-03-29 14:39 ` Roger Pau Monne
  2017-03-31 14:52   ` Jan Beulich
  2017-03-29 14:47 ` [PATCH v3 2/8] x86/hvm: introduce hvm_domain_irq macro Roger Pau Monne
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:39 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

This is required in order to have a variable number of vIO APIC pins, instead
of the current fixed value (48). Note that this patch only expands the fields
of the hvm_vioapic struct, without actually introducing any new fields or
functionality.

The reason to expand the hvm_vioapic structure instead of the hvm_hw_vioapic
one is that the variable number of pins functionality is only going to be used
by the hardware domain, so no modifications are needed to the save format.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v2:
 - Change patch title.
 - Use an unnamed struct to store the vioapic state inside of hvm_vioapic.
 - Use a define to declare the hvm_hw_vioapic struct (and the equivalent
   unnamed struct inside of hvm_vioapic).
 - Remove the BUILD_BUG_ON.

Changes since v1:
 - New in this version.
---
 xen/arch/x86/hvm/vioapic.c             | 39 +++++++++++++------------
 xen/include/asm-x86/hvm/vioapic.h      | 10 ++++---
 xen/include/public/arch-x86/hvm/save.h | 53 ++++++++++++++++++++--------------
 3 files changed, 57 insertions(+), 45 deletions(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index fdbb21f097..23abdfc4c6 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -42,9 +42,9 @@
 /* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */
 #define IRQ0_SPECIAL_ROUTING 1
 
-static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq);
+static void vioapic_deliver(struct hvm_vioapic *vioapic, int irq);
 
-static uint32_t vioapic_read_indirect(const struct hvm_hw_vioapic *vioapic)
+static uint32_t vioapic_read_indirect(const struct hvm_vioapic *vioapic)
 {
     uint32_t result = 0;
 
@@ -94,7 +94,7 @@ static int vioapic_read(
     struct vcpu *v, unsigned long addr,
     unsigned int length, unsigned long *pval)
 {
-    const struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
+    const struct hvm_vioapic *vioapic = domain_vioapic(v->domain);
     uint32_t result;
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "addr %lx", addr);
@@ -119,7 +119,7 @@ static int vioapic_read(
 }
 
 static void vioapic_write_redirent(
-    struct hvm_hw_vioapic *vioapic, unsigned int idx,
+    struct hvm_vioapic *vioapic, unsigned int idx,
     int top_word, uint32_t val)
 {
     struct domain *d = vioapic_domain(vioapic);
@@ -170,7 +170,7 @@ static void vioapic_write_redirent(
 }
 
 static void vioapic_write_indirect(
-    struct hvm_hw_vioapic *vioapic, uint32_t val)
+    struct hvm_vioapic *vioapic, uint32_t val)
 {
     switch ( vioapic->ioregsel )
     {
@@ -215,7 +215,7 @@ static int vioapic_write(
     struct vcpu *v, unsigned long addr,
     unsigned int length, unsigned long val)
 {
-    struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
+    struct hvm_vioapic *vioapic = domain_vioapic(v->domain);
 
     switch ( addr & 0xff )
     {
@@ -242,7 +242,7 @@ static int vioapic_write(
 
 static int vioapic_range(struct vcpu *v, unsigned long addr)
 {
-    struct hvm_hw_vioapic *vioapic = domain_vioapic(v->domain);
+    struct hvm_vioapic *vioapic = domain_vioapic(v->domain);
 
     return ((addr >= vioapic->base_address &&
              (addr < vioapic->base_address + VIOAPIC_MEM_LENGTH)));
@@ -255,7 +255,7 @@ static const struct hvm_mmio_ops vioapic_mmio_ops = {
 };
 
 static void ioapic_inj_irq(
-    struct hvm_hw_vioapic *vioapic,
+    struct hvm_vioapic *vioapic,
     struct vlapic *target,
     uint8_t vector,
     uint8_t trig_mode,
@@ -275,7 +275,7 @@ static inline int pit_channel0_enabled(void)
     return pt_active(&current->domain->arch.vpit.pt0);
 }
 
-static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq)
+static void vioapic_deliver(struct hvm_vioapic *vioapic, int irq)
 {
     uint16_t dest = vioapic->redirtbl[irq].fields.dest_id;
     uint8_t dest_mode = vioapic->redirtbl[irq].fields.dest_mode;
@@ -361,7 +361,7 @@ static void vioapic_deliver(struct hvm_hw_vioapic *vioapic, int irq)
 
 void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
 {
-    struct hvm_hw_vioapic *vioapic = domain_vioapic(d);
+    struct hvm_vioapic *vioapic = domain_vioapic(d);
     union vioapic_redir_entry *ent;
 
     ASSERT(has_vioapic(d));
@@ -388,7 +388,7 @@ void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
 
 void vioapic_update_EOI(struct domain *d, u8 vector)
 {
-    struct hvm_hw_vioapic *vioapic = domain_vioapic(d);
+    struct hvm_vioapic *vioapic = domain_vioapic(d);
     struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
     union vioapic_redir_entry *ent;
     int gsi;
@@ -426,38 +426,39 @@ void vioapic_update_EOI(struct domain *d, u8 vector)
 
 static int ioapic_save(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_hw_vioapic *s = domain_vioapic(d);
+    struct hvm_vioapic *s = domain_vioapic(d);
 
     if ( !has_vioapic(d) )
         return 0;
 
-    return hvm_save_entry(IOAPIC, 0, h, s);
+    return hvm_save_entry(IOAPIC, 0, h, &s->domU);
 }
 
 static int ioapic_load(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_hw_vioapic *s = domain_vioapic(d);
+    struct hvm_vioapic *s = domain_vioapic(d);
 
     if ( !has_vioapic(d) )
         return -ENODEV;
 
-    return hvm_load_entry(IOAPIC, h, s);
+    return hvm_load_entry(IOAPIC, h, &s->domU);
 }
 
 HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load, 1, HVMSR_PER_DOM);
 
 void vioapic_reset(struct domain *d)
 {
-    struct hvm_vioapic *vioapic = d->arch.hvm_domain.vioapic;
+    struct hvm_vioapic *vioapic = domain_vioapic(d);
     int i;
 
     if ( !has_vioapic(d) )
         return;
 
-    memset(&vioapic->hvm_hw_vioapic, 0, sizeof(vioapic->hvm_hw_vioapic));
+    memset(vioapic, 0, sizeof(*vioapic));
+    vioapic->domain = d;
     for ( i = 0; i < VIOAPIC_NUM_PINS; i++ )
-        vioapic->hvm_hw_vioapic.redirtbl[i].fields.mask = 1;
-    vioapic->hvm_hw_vioapic.base_address = VIOAPIC_DEFAULT_BASE_ADDRESS;
+        vioapic->redirtbl[i].fields.mask = 1;
+    vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS;
 }
 
 int vioapic_init(struct domain *d)
diff --git a/xen/include/asm-x86/hvm/vioapic.h b/xen/include/asm-x86/hvm/vioapic.h
index 745c09ab5c..ab7be9e741 100644
--- a/xen/include/asm-x86/hvm/vioapic.h
+++ b/xen/include/asm-x86/hvm/vioapic.h
@@ -48,13 +48,15 @@
 #define VIOAPIC_REG_RTE0    0x10
 
 struct hvm_vioapic {
-    struct hvm_hw_vioapic hvm_hw_vioapic;
     struct domain *domain;
+    union {
+        XEN_HVM_VIOAPIC(, VIOAPIC_NUM_PINS);
+        struct hvm_hw_vioapic domU;
+    };
 };
 
-#define domain_vioapic(d) (&(d)->arch.hvm_domain.vioapic->hvm_hw_vioapic)
-#define vioapic_domain(v) (container_of((v), struct hvm_vioapic, \
-                                        hvm_hw_vioapic)->domain)
+#define domain_vioapic(d) ((d)->arch.hvm_domain.vioapic)
+#define vioapic_domain(v) ((v)->domain)
 
 int vioapic_init(struct domain *d);
 void vioapic_deinit(struct domain *d);
diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/arch-x86/hvm/save.h
index 66ae1a2b80..ab848f6467 100644
--- a/xen/include/public/arch-x86/hvm/save.h
+++ b/xen/include/public/arch-x86/hvm/save.h
@@ -361,30 +361,39 @@ DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
  * IO-APIC
  */
 
+union vioapic_redir_entry
+{
+    uint64_t bits;
+    struct {
+        uint8_t vector;
+        uint8_t delivery_mode:3;
+        uint8_t dest_mode:1;
+        uint8_t delivery_status:1;
+        uint8_t polarity:1;
+        uint8_t remote_irr:1;
+        uint8_t trig_mode:1;
+        uint8_t mask:1;
+        uint8_t reserve:7;
+        uint8_t reserved[4];
+        uint8_t dest_id;
+    } fields;
+};
+
 #define VIOAPIC_NUM_PINS  48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
 
-struct hvm_hw_vioapic {
-    uint64_t base_address;
-    uint32_t ioregsel;
-    uint32_t id;
-    union vioapic_redir_entry
-    {
-        uint64_t bits;
-        struct {
-            uint8_t vector;
-            uint8_t delivery_mode:3;
-            uint8_t dest_mode:1;
-            uint8_t delivery_status:1;
-            uint8_t polarity:1;
-            uint8_t remote_irr:1;
-            uint8_t trig_mode:1;
-            uint8_t mask:1;
-            uint8_t reserve:7;
-            uint8_t reserved[4];
-            uint8_t dest_id;
-        } fields;
-    } redirtbl[VIOAPIC_NUM_PINS];
-};
+#define XEN_HVM_VIOAPIC(name, cnt)                      \
+    struct name {                                       \
+        uint64_t base_address;                          \
+        uint32_t ioregsel;                              \
+        uint32_t id;                                    \
+        union vioapic_redir_entry redirtbl[cnt];        \
+    }
+
+XEN_HVM_VIOAPIC(hvm_hw_vioapic, VIOAPIC_NUM_PINS);
+
+#ifndef __XEN__
+#undef XEN_HVM_VIOAPIC
+#endif
 
 DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
 
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 2/8] x86/hvm: introduce hvm_domain_irq macro
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
  2017-03-29 14:39 ` [PATCH v3 1/8] x86/vioapic: expand hvm_vioapic to contain vIO APIC internal state Roger Pau Monne
@ 2017-03-29 14:47 ` Roger Pau Monne
  2017-03-31  5:10   ` Tian, Kevin
  2017-03-31 14:53   ` Jan Beulich
  2017-03-29 14:47 ` [PATCH v3 3/8] x86/irq: rename NR_HVM_IRQS and break it's dependency on VIOAPIC_NUM_PINS Roger Pau Monne
                   ` (6 subsequent siblings)
  8 siblings, 2 replies; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:47 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Kevin Tian, Jan Beulich, Roger Pau Monne

Introduce a macro to get a pointer to the hvm_irq for a HVM domain. No
functional change.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Kevin Tian <kevin.tian@intel.com>
---
Changes since v2:
 - Switch d->arch.hvm_domain.irq.dpci accesses to use the macro also.
---
NB: this is a pre-patch in order to make patch #3 smaller.
---
 xen/arch/x86/hvm/hvm.c                |  2 +-
 xen/arch/x86/hvm/irq.c                | 30 +++++++++++++++---------------
 xen/arch/x86/hvm/vioapic.c            |  4 ++--
 xen/arch/x86/hvm/vlapic.c             |  6 +++---
 xen/arch/x86/physdev.c                |  2 +-
 xen/drivers/passthrough/io.c          |  8 ++++----
 xen/drivers/passthrough/pci.c         |  2 +-
 xen/drivers/passthrough/vtd/x86/vtd.c |  2 +-
 xen/include/asm-x86/hvm/irq.h         |  1 +
 9 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index b6c5c9bf8d..98dede20db 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -457,7 +457,7 @@ void hvm_migrate_pirqs(struct vcpu *v)
 {
     struct domain *d = v->domain;
 
-    if ( !iommu_enabled || !d->arch.hvm_domain.irq.dpci )
+    if ( !iommu_enabled || !hvm_domain_irq(d)->dpci )
        return;
 
     spin_lock(&d->event_lock);
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index a774ed7450..c2951ccf8a 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -60,7 +60,7 @@ static void deassert_irq(struct domain *d, unsigned isa_irq)
 static void __hvm_pci_intx_assert(
     struct domain *d, unsigned int device, unsigned int intx)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     unsigned int gsi, link, isa_irq;
 
     ASSERT((device <= 31) && (intx <= 3));
@@ -90,7 +90,7 @@ void hvm_pci_intx_assert(
 static void __hvm_pci_intx_deassert(
     struct domain *d, unsigned int device, unsigned int intx)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     unsigned int gsi, link, isa_irq;
 
     ASSERT((device <= 31) && (intx <= 3));
@@ -119,7 +119,7 @@ void hvm_pci_intx_deassert(
 void hvm_isa_irq_assert(
     struct domain *d, unsigned int isa_irq)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
 
     ASSERT(isa_irq <= 15);
@@ -136,7 +136,7 @@ void hvm_isa_irq_assert(
 void hvm_isa_irq_deassert(
     struct domain *d, unsigned int isa_irq)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq);
 
     ASSERT(isa_irq <= 15);
@@ -153,7 +153,7 @@ void hvm_isa_irq_deassert(
 static void hvm_set_callback_irq_level(struct vcpu *v)
 {
     struct domain *d = v->domain;
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     unsigned int gsi, pdev, pintx, asserted;
 
     ASSERT(v->vcpu_id == 0);
@@ -201,7 +201,7 @@ static void hvm_set_callback_irq_level(struct vcpu *v)
 void hvm_maybe_deassert_evtchn_irq(void)
 {
     struct domain *d = current->domain;
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
 
     if ( hvm_irq->callback_via_asserted &&
          !vcpu_info(d->vcpu[0], evtchn_upcall_pending) )
@@ -230,7 +230,7 @@ void hvm_assert_evtchn_irq(struct vcpu *v)
 
 int hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     u8 old_isa_irq;
     int i;
 
@@ -323,7 +323,7 @@ int hvm_inject_msi(struct domain *d, uint64_t addr, uint32_t data)
 
 void hvm_set_callback_via(struct domain *d, uint64_t via)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     unsigned int gsi=0, pdev=0, pintx=0;
     uint8_t via_type;
 
@@ -486,7 +486,7 @@ void arch_evtchn_inject(struct vcpu *v)
 
 static void irq_dump(struct domain *d)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     int i; 
     printk("Domain %d:\n", d->domain_id);
     printk("PCI 0x%16.16"PRIx64"%16.16"PRIx64
@@ -541,7 +541,7 @@ __initcall(dump_irq_info_key_init);
 
 static int irq_save_pci(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     unsigned int asserted, pdev, pintx;
     int rc;
 
@@ -573,7 +573,7 @@ static int irq_save_pci(struct domain *d, hvm_domain_context_t *h)
 
 static int irq_save_isa(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
 
     /* Save ISA IRQ lines */
     return ( hvm_save_entry(ISA_IRQ, 0, h, &hvm_irq->isa_irq) );
@@ -581,7 +581,7 @@ static int irq_save_isa(struct domain *d, hvm_domain_context_t *h)
 
 static int irq_save_link(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
 
     /* Save PCI-ISA link state */
     return ( hvm_save_entry(PCI_LINK, 0, h, &hvm_irq->pci_link) );
@@ -589,7 +589,7 @@ static int irq_save_link(struct domain *d, hvm_domain_context_t *h)
 
 static int irq_load_pci(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     int link, dev, intx, gsi;
 
     /* Load the PCI IRQ lines */
@@ -622,7 +622,7 @@ static int irq_load_pci(struct domain *d, hvm_domain_context_t *h)
 
 static int irq_load_isa(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     int irq;
 
     /* Load the ISA IRQ lines */
@@ -641,7 +641,7 @@ static int irq_load_isa(struct domain *d, hvm_domain_context_t *h)
 
 static int irq_load_link(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     int link, gsi;
 
     /* Load the PCI-ISA IRQ link routing table */
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 23abdfc4c6..3e92947abf 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -123,7 +123,7 @@ static void vioapic_write_redirent(
     int top_word, uint32_t val)
 {
     struct domain *d = vioapic_domain(vioapic);
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     union vioapic_redir_entry *pent, ent;
     int unmasked = 0;
 
@@ -389,7 +389,7 @@ void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
 void vioapic_update_EOI(struct domain *d, u8 vector)
 {
     struct hvm_vioapic *vioapic = domain_vioapic(d);
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     union vioapic_redir_entry *ent;
     int gsi;
 
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index 14356a78fe..0590d6c69d 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -373,7 +373,7 @@ struct vlapic *vlapic_lowest_prio(
     struct domain *d, const struct vlapic *source,
     int short_hand, uint32_t dest, bool_t dest_mode)
 {
-    int old = d->arch.hvm_domain.irq.round_robin_prev_vcpu;
+    int old = hvm_domain_irq(d)->round_robin_prev_vcpu;
     uint32_t ppr, target_ppr = UINT_MAX;
     struct vlapic *vlapic, *target = NULL;
     struct vcpu *v;
@@ -394,8 +394,8 @@ struct vlapic *vlapic_lowest_prio(
     } while ( v->vcpu_id != old );
 
     if ( target != NULL )
-        d->arch.hvm_domain.irq.round_robin_prev_vcpu =
-            vlapic_vcpu(target)->vcpu_id;
+        hvm_domain_irq(d)->round_robin_prev_vcpu =
+           vlapic_vcpu(target)->vcpu_id;
 
     return target;
 }
diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index 81cd6c94e7..6c15f9bf49 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -317,7 +317,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         if ( is_hvm_domain(currd) &&
              domain_pirq_to_emuirq(currd, eoi.irq) > 0 )
         {
-            struct hvm_irq *hvm_irq = &currd->arch.hvm_domain.irq;
+            struct hvm_irq *hvm_irq = hvm_domain_irq(currd);
             int gsi = domain_pirq_to_emuirq(currd, eoi.irq);
 
             /* if this is a level irq and count > 0, send another
diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c
index 080183ea31..f48eb31420 100644
--- a/xen/drivers/passthrough/io.c
+++ b/xen/drivers/passthrough/io.c
@@ -195,7 +195,7 @@ struct hvm_irq_dpci *domain_get_irq_dpci(const struct domain *d)
     if ( !d || !is_hvm_domain(d) )
         return NULL;
 
-    return d->arch.hvm_domain.irq.dpci;
+    return hvm_domain_irq(d)->dpci;
 }
 
 void free_hvm_irq_dpci(struct hvm_irq_dpci *dpci)
@@ -333,7 +333,7 @@ int pt_irq_create_bind(
         for ( i = 0; i < NR_HVM_IRQS; i++ )
             INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]);
 
-        d->arch.hvm_domain.irq.dpci = hvm_irq_dpci;
+        hvm_domain_irq(d)->dpci = hvm_irq_dpci;
     }
 
     info = pirq_get_info(d, pirq);
@@ -788,7 +788,7 @@ static int _hvm_dpci_msi_eoi(struct domain *d,
 
 void hvm_dpci_msi_eoi(struct domain *d, int vector)
 {
-    if ( !iommu_enabled || !d->arch.hvm_domain.irq.dpci )
+    if ( !iommu_enabled || !hvm_domain_irq(d)->dpci )
        return;
 
     spin_lock(&d->event_lock);
@@ -798,7 +798,7 @@ void hvm_dpci_msi_eoi(struct domain *d, int vector)
 
 static void hvm_dirq_assist(struct domain *d, struct hvm_pirq_dpci *pirq_dpci)
 {
-    if ( unlikely(!d->arch.hvm_domain.irq.dpci) )
+    if ( unlikely(!hvm_domain_irq(d)->dpci) )
     {
         ASSERT_UNREACHABLE();
         return;
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index beddd42701..c8e2d2d9a9 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -815,7 +815,7 @@ static int pci_clean_dpci_irqs(struct domain *d)
             return ret;
         }
 
-        d->arch.hvm_domain.irq.dpci = NULL;
+        hvm_domain_irq(d)->dpci = NULL;
         free_hvm_irq_dpci(hvm_irq_dpci);
     }
     spin_unlock(&d->event_lock);
diff --git a/xen/drivers/passthrough/vtd/x86/vtd.c b/xen/drivers/passthrough/vtd/x86/vtd.c
index 8a89f3471f..88a60b3307 100644
--- a/xen/drivers/passthrough/vtd/x86/vtd.c
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c
@@ -66,7 +66,7 @@ void flush_all_cache()
 static int _hvm_dpci_isairq_eoi(struct domain *d,
                                 struct hvm_pirq_dpci *pirq_dpci, void *arg)
 {
-    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
+    struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     unsigned int isairq = (long)arg;
     const struct dev_intx_gsi_link *digl;
 
diff --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h
index 73b8fb0457..17a957d4b5 100644
--- a/xen/include/asm-x86/hvm/irq.h
+++ b/xen/include/asm-x86/hvm/irq.h
@@ -95,6 +95,7 @@ struct hvm_irq {
     (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16)
 #define hvm_pci_intx_link(dev, intx) \
     (((dev) + (intx)) & 3)
+#define hvm_domain_irq(d) (&(d)->arch.hvm_domain.irq)
 
 #define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
 
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 3/8] x86/irq: rename NR_HVM_IRQS and break it's dependency on VIOAPIC_NUM_PINS
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
  2017-03-29 14:39 ` [PATCH v3 1/8] x86/vioapic: expand hvm_vioapic to contain vIO APIC internal state Roger Pau Monne
  2017-03-29 14:47 ` [PATCH v3 2/8] x86/hvm: introduce hvm_domain_irq macro Roger Pau Monne
@ 2017-03-29 14:47 ` Roger Pau Monne
  2017-03-31 15:01   ` Jan Beulich
  2017-03-29 14:47 ` [PATCH v3 4/8] x86/hvm: convert gsi_assert_count into a variable size array Roger Pau Monne
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:47 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Rename it to NR_HVM_DOMU_IRQS, and get it's value from the size of the DomU vIO
APIC redirection table.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v2:
 - New in this version.

NB: this patch makes it easier to get rid of VIOAPIC_NUM_PINS in later patches.
---
 xen/arch/x86/physdev.c       | 6 ++++--
 xen/drivers/passthrough/io.c | 2 +-
 xen/include/xen/hvm/irq.h    | 4 ++--
 3 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c
index 6c15f9bf49..eec4a41231 100644
--- a/xen/arch/x86/physdev.c
+++ b/xen/arch/x86/physdev.c
@@ -32,6 +32,8 @@ static int physdev_hvm_map_pirq(
 {
     int ret = 0;
 
+    ASSERT(!is_hardware_domain(d));
+
     spin_lock(&d->event_lock);
     switch ( type )
     {
@@ -39,7 +41,7 @@ static int physdev_hvm_map_pirq(
         const struct hvm_irq_dpci *hvm_irq_dpci;
         unsigned int machine_gsi = 0;
 
-        if ( *index < 0 || *index >= NR_HVM_IRQS )
+        if ( *index < 0 || *index >= NR_HVM_DOMU_IRQS )
         {
             ret = -EINVAL;
             break;
@@ -52,7 +54,7 @@ static int physdev_hvm_map_pirq(
         {
             const struct hvm_girq_dpci_mapping *girq;
 
-            BUILD_BUG_ON(ARRAY_SIZE(hvm_irq_dpci->girq) < NR_HVM_IRQS);
+            BUILD_BUG_ON(ARRAY_SIZE(hvm_irq_dpci->girq) < NR_HVM_DOMU_IRQS);
             list_for_each_entry ( girq,
                                   &hvm_irq_dpci->girq[*index],
                                   list )
diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c
index f48eb31420..83e096131e 100644
--- a/xen/drivers/passthrough/io.c
+++ b/xen/drivers/passthrough/io.c
@@ -330,7 +330,7 @@ int pt_irq_create_bind(
             spin_unlock(&d->event_lock);
             return -ENOMEM;
         }
-        for ( i = 0; i < NR_HVM_IRQS; i++ )
+        for ( i = 0; i < NR_HVM_DOMU_IRQS; i++ )
             INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]);
 
         hvm_domain_irq(d)->dpci = hvm_irq_dpci;
diff --git a/xen/include/xen/hvm/irq.h b/xen/include/xen/hvm/irq.h
index d3f8623c0c..f04125248e 100644
--- a/xen/include/xen/hvm/irq.h
+++ b/xen/include/xen/hvm/irq.h
@@ -76,13 +76,13 @@ struct hvm_girq_dpci_mapping {
 #define NR_ISAIRQS  16
 #define NR_LINK     4
 #if defined(CONFIG_X86)
-# define NR_HVM_IRQS VIOAPIC_NUM_PINS
+# define NR_HVM_DOMU_IRQS ARRAY_SIZE(((struct hvm_hw_vioapic *)0)->redirtbl)
 #endif
 
 /* Protected by domain's event_lock */
 struct hvm_irq_dpci {
     /* Guest IRQ to guest device/intx mapping. */
-    struct list_head girq[NR_HVM_IRQS];
+    struct list_head girq[NR_HVM_DOMU_IRQS];
     /* Record of mapped ISA IRQs */
     DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
     /* Record of mapped Links */
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 4/8] x86/hvm: convert gsi_assert_count into a variable size array
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
                   ` (2 preceding siblings ...)
  2017-03-29 14:47 ` [PATCH v3 3/8] x86/irq: rename NR_HVM_IRQS and break it's dependency on VIOAPIC_NUM_PINS Roger Pau Monne
@ 2017-03-29 14:47 ` Roger Pau Monne
  2017-03-31 15:16   ` Jan Beulich
  2017-03-29 14:47 ` [PATCH v3 5/8] x86/vioapic: allow the vIO APIC to have a variable number of pins Roger Pau Monne
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:47 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Rearrange the fields of hvm_irq so that gsi_assert_count can be converted into
a variable size array and add a new field to account the number of GSIs.

Due to this changes the irq member in the hvm_domain struct also needs to
become a pointer set at runtime.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v2:
 - Parenthesize is_hvm_pv_evtchn_domain argument.
 - Add a build BUG_ON to make sure DomU number of IRQs covers the ISA range at
   least.
 - Add an ASSERT to make sure nr_gsis covers the ISA range (those two are
   identical now, but that's going to change when Dom0 introduces a variable
   number of GSIs, hence the ASSERT and the BUILD_BUG_ON).
 - Don't expand the ASSERTs in the irq assert/deassert routines (the above
   additions already cover those).
 - Use %2 as format specifier to print the GSIs assert count (the existing code
   has been left as-is, using %2.2 instead).
---
 xen/arch/x86/hvm/hvm.c           | 14 +++++++++++++-
 xen/arch/x86/hvm/irq.c           | 19 ++++++++++++++-----
 xen/include/asm-x86/domain.h     |  2 +-
 xen/include/asm-x86/hvm/domain.h |  2 +-
 xen/include/asm-x86/hvm/irq.h    | 28 +++++++++++++++-------------
 5 files changed, 44 insertions(+), 21 deletions(-)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 98dede20db..6c3c944abd 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -620,11 +620,19 @@ int hvm_domain_initialise(struct domain *d)
     d->arch.hvm_domain.params = xzalloc_array(uint64_t, HVM_NR_PARAMS);
     d->arch.hvm_domain.io_handler = xzalloc_array(struct hvm_io_handler,
                                                   NR_IO_HANDLERS);
+    d->arch.hvm_domain.irq = xzalloc_bytes(hvm_irq_size(NR_HVM_DOMU_IRQS));
+
     rc = -ENOMEM;
-    if ( !d->arch.hvm_domain.pl_time ||
+    if ( !d->arch.hvm_domain.pl_time || !d->arch.hvm_domain.irq ||
          !d->arch.hvm_domain.params  || !d->arch.hvm_domain.io_handler )
         goto fail1;
 
+    /* Set the default number of GSIs */
+    hvm_domain_irq(d)->nr_gsis = NR_HVM_DOMU_IRQS;
+
+    BUILD_BUG_ON(NR_HVM_DOMU_IRQS < NR_ISAIRQS);
+    ASSERT(hvm_domain_irq(d)->nr_gsis >= NR_ISAIRQS);
+
     /* need link to containing domain */
     d->arch.hvm_domain.pl_time->domain = d;
 
@@ -681,6 +689,7 @@ int hvm_domain_initialise(struct domain *d)
     xfree(d->arch.hvm_domain.io_handler);
     xfree(d->arch.hvm_domain.params);
     xfree(d->arch.hvm_domain.pl_time);
+    xfree(d->arch.hvm_domain.irq);
  fail0:
     hvm_destroy_cacheattr_region_list(d);
     return rc;
@@ -727,6 +736,9 @@ void hvm_domain_destroy(struct domain *d)
     xfree(d->arch.hvm_domain.pl_time);
     d->arch.hvm_domain.pl_time = NULL;
 
+    xfree(d->arch.hvm_domain.irq);
+    d->arch.hvm_domain.irq = NULL;
+
     list_for_each_safe ( ioport_list, tmp,
                          &d->arch.hvm_domain.g2m_ioport_list )
     {
diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c
index c2951ccf8a..00713257c9 100644
--- a/xen/arch/x86/hvm/irq.c
+++ b/xen/arch/x86/hvm/irq.c
@@ -69,6 +69,7 @@ static void __hvm_pci_intx_assert(
         return;
 
     gsi = hvm_pci_intx_gsi(device, intx);
+    ASSERT(gsi < hvm_irq->nr_gsis);
     if ( hvm_irq->gsi_assert_count[gsi]++ == 0 )
         assert_gsi(d, gsi);
 
@@ -99,6 +100,7 @@ static void __hvm_pci_intx_deassert(
         return;
 
     gsi = hvm_pci_intx_gsi(device, intx);
+    ASSERT(gsi < hvm_irq->nr_gsis);
     --hvm_irq->gsi_assert_count[gsi];
 
     link    = hvm_pci_intx_link(device, intx);
@@ -363,7 +365,7 @@ void hvm_set_callback_via(struct domain *d, uint64_t via)
     {
     case HVMIRQ_callback_gsi:
         gsi = hvm_irq->callback_via.gsi = (uint8_t)via;
-        if ( (gsi == 0) || (gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count)) )
+        if ( (gsi == 0) || (gsi >= hvm_irq->nr_gsis) )
             hvm_irq->callback_via_type = HVMIRQ_callback_none;
         else if ( hvm_irq->callback_via_asserted &&
                   (hvm_irq->gsi_assert_count[gsi]++ == 0) )
@@ -419,9 +421,9 @@ struct hvm_intack hvm_vcpu_has_pending_irq(struct vcpu *v)
     if ( unlikely(v->mce_pending) )
         return hvm_intack_mce;
 
-    if ( (plat->irq.callback_via_type == HVMIRQ_callback_vector)
+    if ( (plat->irq->callback_via_type == HVMIRQ_callback_vector)
          && vcpu_info(v, evtchn_upcall_pending) )
-        return hvm_intack_vector(plat->irq.callback_via.vector);
+        return hvm_intack_vector(plat->irq->callback_via.vector);
 
     if ( vlapic_accept_pic_intr(v) && plat->vpic[0].int_output )
         return hvm_intack_pic(0);
@@ -495,7 +497,7 @@ static void irq_dump(struct domain *d)
            (uint32_t) hvm_irq->isa_irq.pad[0], 
            hvm_irq->pci_link.route[0], hvm_irq->pci_link.route[1],
            hvm_irq->pci_link.route[2], hvm_irq->pci_link.route[3]);
-    for ( i = 0 ; i < VIOAPIC_NUM_PINS; i += 8 )
+    for ( i = 0; i < hvm_irq->nr_gsis && i + 8 <= hvm_irq->nr_gsis; i += 8 )
         printk("GSI [%x - %x] %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8
                " %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8"\n",
                i, i+7,
@@ -507,6 +509,13 @@ static void irq_dump(struct domain *d)
                hvm_irq->gsi_assert_count[i+5],
                hvm_irq->gsi_assert_count[i+6],
                hvm_irq->gsi_assert_count[i+7]);
+    if ( i != hvm_irq->nr_gsis )
+    {
+        printk("GSI [%x - %x]", i, hvm_irq->nr_gsis - 1);
+        for ( ; i < hvm_irq->nr_gsis; i++)
+            printk(" %2"PRIu8, hvm_irq->gsi_assert_count[i]);
+        printk("\n");
+    }
     printk("Link %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8"\n",
            hvm_irq->pci_link_assert_count[0],
            hvm_irq->pci_link_assert_count[1],
@@ -601,7 +610,7 @@ static int irq_load_pci(struct domain *d, hvm_domain_context_t *h)
         hvm_irq->pci_link_assert_count[link] = 0;
     
     /* Clear the GSI link assert counts */
-    for ( gsi = 0; gsi < VIOAPIC_NUM_PINS; gsi++ )
+    for ( gsi = 0; gsi < hvm_irq->nr_gsis; gsi++ )
         hvm_irq->gsi_assert_count[gsi] = 0;
 
     /* Recalculate the counts from the IRQ line state */
diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h
index ec14cce81f..6420ca24b9 100644
--- a/xen/include/asm-x86/domain.h
+++ b/xen/include/asm-x86/domain.h
@@ -17,7 +17,7 @@
 #define is_pv_32bit_vcpu(v)    (is_pv_32bit_domain((v)->domain))
 
 #define is_hvm_pv_evtchn_domain(d) (is_hvm_domain(d) && \
-        d->arch.hvm_domain.irq.callback_via_type == HVMIRQ_callback_vector)
+        (d)->arch.hvm_domain.irq->callback_via_type == HVMIRQ_callback_vector)
 #define is_hvm_pv_evtchn_vcpu(v) (is_hvm_pv_evtchn_domain(v->domain))
 #define is_domain_direct_mapped(d) ((void)(d), 0)
 
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index bdfc082641..622e1ca12d 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -125,7 +125,7 @@ struct hvm_domain {
 
     /* Lock protects access to irq, vpic and vioapic. */
     spinlock_t             irq_lock;
-    struct hvm_irq         irq;
+    struct hvm_irq        *irq;
     struct hvm_hw_vpic     vpic[2]; /* 0=master; 1=slave */
     struct hvm_vioapic    *vioapic;
     struct hvm_hw_stdvga   stdvga;
diff --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h
index 17a957d4b5..7d45293aed 100644
--- a/xen/include/asm-x86/hvm/irq.h
+++ b/xen/include/asm-x86/hvm/irq.h
@@ -67,18 +67,6 @@ struct hvm_irq {
     u8 pci_link_assert_count[4];
 
     /*
-     * Number of wires asserting each GSI.
-     * 
-     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
-     * except ISA IRQ 0, which is connected to GSI 2.
-     * PCI links map into this space via the PCI-ISA bridge.
-     * 
-     * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
-     * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
-     */
-    u8 gsi_assert_count[VIOAPIC_NUM_PINS];
-
-    /*
      * GSIs map onto PIC/IO-APIC in the usual way:
      *  0-7:  Master 8259 PIC, IO-APIC pins 0-7
      *  8-15: Slave  8259 PIC, IO-APIC pins 8-15
@@ -89,13 +77,27 @@ struct hvm_irq {
     u8 round_robin_prev_vcpu;
 
     struct hvm_irq_dpci *dpci;
+
+    /*
+     * Number of wires asserting each GSI.
+     *
+     * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space
+     * except ISA IRQ 0, which is connected to GSI 2.
+     * PCI links map into this space via the PCI-ISA bridge.
+     *
+     * GSIs 16+ are used only be PCI devices. The mapping from PCI device to
+     * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16
+     */
+    unsigned int nr_gsis;
+    u8 gsi_assert_count[];
 };
 
 #define hvm_pci_intx_gsi(dev, intx)  \
     (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16)
 #define hvm_pci_intx_link(dev, intx) \
     (((dev) + (intx)) & 3)
-#define hvm_domain_irq(d) (&(d)->arch.hvm_domain.irq)
+#define hvm_domain_irq(d) ((d)->arch.hvm_domain.irq)
+#define hvm_irq_size(cnt) offsetof(struct hvm_irq, gsi_assert_count[cnt])
 
 #define hvm_isa_irq_to_gsi(isa_irq) ((isa_irq) ? : 2)
 
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 5/8] x86/vioapic: allow the vIO APIC to have a variable number of pins
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
                   ` (3 preceding siblings ...)
  2017-03-29 14:47 ` [PATCH v3 4/8] x86/hvm: convert gsi_assert_count into a variable size array Roger Pau Monne
@ 2017-03-29 14:47 ` Roger Pau Monne
  2017-03-31 15:20   ` Jan Beulich
  2017-03-29 14:47 ` [PATCH v3 6/8] x86/vioapic: introduce support for multiple vIO APICS Roger Pau Monne
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:47 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Although it's still always set to VIOAPIC_NUM_PINS (48).

Add a new field to the hvm_ioapic struct to contain the number of pins (number
of IO redirection table entries) and turn the redirection table into a variable
sized array.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v2:
 - Undefine VIOAPIC_NUM_PINS for hypervisor code.

Changes since v1:
 - Almost completely reworked due to previous changes.
---
 xen/arch/x86/hvm/vioapic.c             | 23 ++++++++++++++++-------
 xen/include/asm-x86/hvm/vioapic.h      |  4 +++-
 xen/include/public/arch-x86/hvm/save.h |  2 ++
 3 files changed, 21 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 3e92947abf..6bc8dbdd42 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -53,7 +53,7 @@ static uint32_t vioapic_read_indirect(const struct hvm_vioapic *vioapic)
     case VIOAPIC_REG_VERSION:
         result = ((union IO_APIC_reg_01){
                   .bits = { .version = VIOAPIC_VERSION_ID,
-                            .entries = VIOAPIC_NUM_PINS - 1 }
+                            .entries = vioapic->nr_pins - 1 }
                   }).raw;
         break;
 
@@ -73,7 +73,7 @@ static uint32_t vioapic_read_indirect(const struct hvm_vioapic *vioapic)
         uint32_t redir_index = (vioapic->ioregsel - VIOAPIC_REG_RTE0) >> 1;
         uint64_t redir_content;
 
-        if ( redir_index >= VIOAPIC_NUM_PINS )
+        if ( redir_index >= vioapic->nr_pins )
         {
             gdprintk(XENLOG_WARNING, "apic_mem_readl:undefined ioregsel %x\n",
                      vioapic->ioregsel);
@@ -197,7 +197,7 @@ static void vioapic_write_indirect(
         HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "rte[%02x].%s = %08x",
                     redir_index, vioapic->ioregsel & 1 ? "hi" : "lo", val);
 
-        if ( redir_index >= VIOAPIC_NUM_PINS )
+        if ( redir_index >= vioapic->nr_pins )
         {
             gdprintk(XENLOG_WARNING, "vioapic_write_indirect "
                      "error register %x\n", vioapic->ioregsel);
@@ -368,7 +368,7 @@ void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "irq %x", irq);
 
-    ASSERT(irq < VIOAPIC_NUM_PINS);
+    ASSERT(irq < vioapic->nr_pins);
     ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
 
     ent = &vioapic->redirtbl[irq];
@@ -397,7 +397,7 @@ void vioapic_update_EOI(struct domain *d, u8 vector)
 
     spin_lock(&d->arch.hvm_domain.irq_lock);
 
-    for ( gsi = 0; gsi < VIOAPIC_NUM_PINS; gsi++ )
+    for ( gsi = 0; gsi < vioapic->nr_pins; gsi++ )
     {
         ent = &vioapic->redirtbl[gsi];
         if ( ent->fields.vector != vector )
@@ -431,6 +431,9 @@ static int ioapic_save(struct domain *d, hvm_domain_context_t *h)
     if ( !has_vioapic(d) )
         return 0;
 
+    if ( s->nr_pins != ARRAY_SIZE(s->domU.redirtbl) )
+        return -EOPNOTSUPP;
+
     return hvm_save_entry(IOAPIC, 0, h, &s->domU);
 }
 
@@ -441,6 +444,9 @@ static int ioapic_load(struct domain *d, hvm_domain_context_t *h)
     if ( !has_vioapic(d) )
         return -ENODEV;
 
+    if ( s->nr_pins != ARRAY_SIZE(s->domU.redirtbl) )
+        return -EOPNOTSUPP;
+
     return hvm_load_entry(IOAPIC, h, &s->domU);
 }
 
@@ -449,14 +455,16 @@ HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load, 1, HVMSR_PER_DOM);
 void vioapic_reset(struct domain *d)
 {
     struct hvm_vioapic *vioapic = domain_vioapic(d);
+    uint32_t nr_pins = vioapic->nr_pins;
     int i;
 
     if ( !has_vioapic(d) )
         return;
 
-    memset(vioapic, 0, sizeof(*vioapic));
+    memset(vioapic, 0, hvm_vioapic_size(nr_pins));
     vioapic->domain = d;
-    for ( i = 0; i < VIOAPIC_NUM_PINS; i++ )
+    vioapic->nr_pins = nr_pins;
+    for ( i = 0; i < nr_pins; i++ )
         vioapic->redirtbl[i].fields.mask = 1;
     vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS;
 }
@@ -471,6 +479,7 @@ int vioapic_init(struct domain *d)
         return -ENOMEM;
 
     d->arch.hvm_domain.vioapic->domain = d;
+    domain_vioapic(d)->nr_pins = ARRAY_SIZE(domain_vioapic(d)->domU.redirtbl);
     vioapic_reset(d);
 
     register_mmio_handler(d, &vioapic_mmio_ops);
diff --git a/xen/include/asm-x86/hvm/vioapic.h b/xen/include/asm-x86/hvm/vioapic.h
index ab7be9e741..711f294fbe 100644
--- a/xen/include/asm-x86/hvm/vioapic.h
+++ b/xen/include/asm-x86/hvm/vioapic.h
@@ -49,12 +49,14 @@
 
 struct hvm_vioapic {
     struct domain *domain;
+    uint32_t nr_pins;
     union {
-        XEN_HVM_VIOAPIC(, VIOAPIC_NUM_PINS);
+        XEN_HVM_VIOAPIC(, 0);
         struct hvm_hw_vioapic domU;
     };
 };
 
+#define hvm_vioapic_size(cnt) offsetof(struct hvm_vioapic, redirtbl[cnt])
 #define domain_vioapic(d) ((d)->arch.hvm_domain.vioapic)
 #define vioapic_domain(v) ((v)->domain)
 
diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/arch-x86/hvm/save.h
index ab848f6467..816973b9c2 100644
--- a/xen/include/public/arch-x86/hvm/save.h
+++ b/xen/include/public/arch-x86/hvm/save.h
@@ -393,6 +393,8 @@ XEN_HVM_VIOAPIC(hvm_hw_vioapic, VIOAPIC_NUM_PINS);
 
 #ifndef __XEN__
 #undef XEN_HVM_VIOAPIC
+#else
+#undef VIOAPIC_NUM_PINS
 #endif
 
 DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 6/8] x86/vioapic: introduce support for multiple vIO APICS
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
                   ` (4 preceding siblings ...)
  2017-03-29 14:47 ` [PATCH v3 5/8] x86/vioapic: allow the vIO APIC to have a variable number of pins Roger Pau Monne
@ 2017-03-29 14:47 ` Roger Pau Monne
  2017-03-31 15:48   ` Jan Beulich
  2017-03-29 14:47 ` [PATCH v3 7/8] x86/ioapic: add prototype for io_apic_gsi_base to io_apic.h Roger Pau Monne
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:47 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

Add support for multiple vIO APICs on the same domain, thus turning
d->arch.hvm_domain.vioapic into an array of vIO APIC control structures.

Note that this functionality is not exposed to unprivileged guests, and will
only be used by PVHv2 Dom0.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v2:
 - More constify.
 - gsi_vioapic should return the pin and not the base GSI.
 - Change pin_gsi to base_gsi, and make it return the base vIO APIC GSI.
 - Make sure base_gsi doesn't overrun the array.
 - Add ASSERTs to make sure DomU don't use more than one vIO APIC.

Changes since v1:
 - Constify some parameters.
 - Make gsi_vioapic return the base GSI of the IO APIC.
 - Add checks to pt_irq_vector in order to prevent dereferencing NULL.
---
 xen/arch/x86/hvm/dom0_build.c     |   2 +-
 xen/arch/x86/hvm/vioapic.c        | 218 ++++++++++++++++++++++++++++----------
 xen/arch/x86/hvm/vlapic.c         |   2 +-
 xen/arch/x86/hvm/vpt.c            |  25 ++++-
 xen/include/asm-x86/hvm/domain.h  |   3 +-
 xen/include/asm-x86/hvm/vioapic.h |   4 +-
 6 files changed, 188 insertions(+), 66 deletions(-)

diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c
index 5576db4ee8..daa791d3f4 100644
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -729,7 +729,7 @@ static int __init pvh_setup_acpi_madt(struct domain *d, paddr_t *addr)
     io_apic = (void *)(madt + 1);
     io_apic->header.type = ACPI_MADT_TYPE_IO_APIC;
     io_apic->header.length = sizeof(*io_apic);
-    io_apic->id = domain_vioapic(d)->id;
+    io_apic->id = domain_vioapic(d, 0)->id;
     io_apic->address = VIOAPIC_DEFAULT_BASE_ADDRESS;
 
     x2apic = (void *)(io_apic + 1);
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 6bc8dbdd42..990ad707ec 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -42,7 +42,57 @@
 /* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */
 #define IRQ0_SPECIAL_ROUTING 1
 
-static void vioapic_deliver(struct hvm_vioapic *vioapic, int irq);
+static void vioapic_deliver(struct hvm_vioapic *vioapic, unsigned int irq);
+
+static struct hvm_vioapic *addr_vioapic(const struct domain *d,
+                                        unsigned long addr)
+{
+    unsigned int i;
+
+    for ( i = 0; i < d->arch.hvm_domain.nr_vioapics; i++ )
+    {
+        struct hvm_vioapic *vioapic = domain_vioapic(d, i);
+
+        if ( addr >= vioapic->base_address &&
+             addr < vioapic->base_address + VIOAPIC_MEM_LENGTH )
+            return vioapic;
+    }
+
+    return NULL;
+}
+
+struct hvm_vioapic *gsi_vioapic(const struct domain *d, unsigned int gsi,
+                                unsigned int *pin)
+{
+    unsigned int i, base_gsi = 0;
+
+    for ( i = 0; i < d->arch.hvm_domain.nr_vioapics; i++ )
+    {
+        struct hvm_vioapic *vioapic = domain_vioapic(d, i);
+
+        if ( gsi >= base_gsi && gsi < base_gsi + vioapic->nr_pins )
+        {
+            *pin = gsi - base_gsi;
+            return vioapic;
+        }
+
+        base_gsi += vioapic->nr_pins;
+    }
+
+    return NULL;
+}
+
+static unsigned int base_gsi(const struct domain *d,
+                             const struct hvm_vioapic *vioapic)
+{
+    const struct hvm_vioapic *tmp;
+    unsigned int base_gsi = 0, nr_vioapics = d->arch.hvm_domain.nr_vioapics;
+
+    for ( tmp = domain_vioapic(d, 0); --nr_vioapics && tmp != vioapic; tmp++ )
+        base_gsi += tmp->nr_pins;
+
+    return base_gsi;
+}
 
 static uint32_t vioapic_read_indirect(const struct hvm_vioapic *vioapic)
 {
@@ -94,11 +144,14 @@ static int vioapic_read(
     struct vcpu *v, unsigned long addr,
     unsigned int length, unsigned long *pval)
 {
-    const struct hvm_vioapic *vioapic = domain_vioapic(v->domain);
+    const struct hvm_vioapic *vioapic;
     uint32_t result;
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "addr %lx", addr);
 
+    vioapic = addr_vioapic(v->domain, addr);
+    ASSERT(vioapic);
+
     switch ( addr & 0xff )
     {
     case VIOAPIC_REG_SELECT:
@@ -126,6 +179,7 @@ static void vioapic_write_redirent(
     struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     union vioapic_redir_entry *pent, ent;
     int unmasked = 0;
+    unsigned int gsi = base_gsi(d, vioapic) + idx;
 
     spin_lock(&d->arch.hvm_domain.irq_lock);
 
@@ -149,7 +203,7 @@ static void vioapic_write_redirent(
 
     *pent = ent;
 
-    if ( idx == 0 )
+    if ( gsi == 0 )
     {
         vlapic_adjust_i8259_target(d);
     }
@@ -165,7 +219,7 @@ static void vioapic_write_redirent(
 
     spin_unlock(&d->arch.hvm_domain.irq_lock);
 
-    if ( idx == 0 || unmasked )
+    if ( gsi == 0 || unmasked )
         pt_may_unmask_irq(d, NULL);
 }
 
@@ -215,7 +269,10 @@ static int vioapic_write(
     struct vcpu *v, unsigned long addr,
     unsigned int length, unsigned long val)
 {
-    struct hvm_vioapic *vioapic = domain_vioapic(v->domain);
+    struct hvm_vioapic *vioapic;
+
+    vioapic = addr_vioapic(v->domain, addr);
+    ASSERT(vioapic);
 
     switch ( addr & 0xff )
     {
@@ -242,10 +299,7 @@ static int vioapic_write(
 
 static int vioapic_range(struct vcpu *v, unsigned long addr)
 {
-    struct hvm_vioapic *vioapic = domain_vioapic(v->domain);
-
-    return ((addr >= vioapic->base_address &&
-             (addr < vioapic->base_address + VIOAPIC_MEM_LENGTH)));
+    return !!addr_vioapic(v->domain, addr);
 }
 
 static const struct hvm_mmio_ops vioapic_mmio_ops = {
@@ -275,16 +329,17 @@ static inline int pit_channel0_enabled(void)
     return pt_active(&current->domain->arch.vpit.pt0);
 }
 
-static void vioapic_deliver(struct hvm_vioapic *vioapic, int irq)
+static void vioapic_deliver(struct hvm_vioapic *vioapic, unsigned int pin)
 {
-    uint16_t dest = vioapic->redirtbl[irq].fields.dest_id;
-    uint8_t dest_mode = vioapic->redirtbl[irq].fields.dest_mode;
-    uint8_t delivery_mode = vioapic->redirtbl[irq].fields.delivery_mode;
-    uint8_t vector = vioapic->redirtbl[irq].fields.vector;
-    uint8_t trig_mode = vioapic->redirtbl[irq].fields.trig_mode;
+    uint16_t dest = vioapic->redirtbl[pin].fields.dest_id;
+    uint8_t dest_mode = vioapic->redirtbl[pin].fields.dest_mode;
+    uint8_t delivery_mode = vioapic->redirtbl[pin].fields.delivery_mode;
+    uint8_t vector = vioapic->redirtbl[pin].fields.vector;
+    uint8_t trig_mode = vioapic->redirtbl[pin].fields.trig_mode;
     struct domain *d = vioapic_domain(vioapic);
     struct vlapic *target;
     struct vcpu *v;
+    unsigned int irq = base_gsi(d, vioapic) + pin;
 
     ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
 
@@ -361,64 +416,71 @@ static void vioapic_deliver(struct hvm_vioapic *vioapic, int irq)
 
 void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
 {
-    struct hvm_vioapic *vioapic = domain_vioapic(d);
+    unsigned int pin;
+    struct hvm_vioapic *vioapic = gsi_vioapic(d, irq, &pin);
     union vioapic_redir_entry *ent;
 
     ASSERT(has_vioapic(d));
 
     HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "irq %x", irq);
 
-    ASSERT(irq < vioapic->nr_pins);
+    ASSERT(pin < vioapic->nr_pins);
     ASSERT(spin_is_locked(&d->arch.hvm_domain.irq_lock));
 
-    ent = &vioapic->redirtbl[irq];
+    ent = &vioapic->redirtbl[pin];
     if ( ent->fields.mask )
         return;
 
     if ( ent->fields.trig_mode == VIOAPIC_EDGE_TRIG )
     {
-        vioapic_deliver(vioapic, irq);
+        vioapic_deliver(vioapic, pin);
     }
     else if ( !ent->fields.remote_irr )
     {
         ent->fields.remote_irr = 1;
-        vioapic_deliver(vioapic, irq);
+        vioapic_deliver(vioapic, pin);
     }
 }
 
 void vioapic_update_EOI(struct domain *d, u8 vector)
 {
-    struct hvm_vioapic *vioapic = domain_vioapic(d);
     struct hvm_irq *hvm_irq = hvm_domain_irq(d);
     union vioapic_redir_entry *ent;
-    int gsi;
+    unsigned int i, base_gsi = 0;
 
     ASSERT(has_vioapic(d));
 
     spin_lock(&d->arch.hvm_domain.irq_lock);
 
-    for ( gsi = 0; gsi < vioapic->nr_pins; gsi++ )
+    for ( i = 0; i < d->arch.hvm_domain.nr_vioapics; i++ )
     {
-        ent = &vioapic->redirtbl[gsi];
-        if ( ent->fields.vector != vector )
-            continue;
-
-        ent->fields.remote_irr = 0;
+        struct hvm_vioapic *vioapic = domain_vioapic(d, i);
+        unsigned int j;
 
-        if ( iommu_enabled )
+        for ( j = 0; j < vioapic->nr_pins; j++ )
         {
-            spin_unlock(&d->arch.hvm_domain.irq_lock);
-            hvm_dpci_eoi(d, gsi, ent);
-            spin_lock(&d->arch.hvm_domain.irq_lock);
-        }
-
-        if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
-             !ent->fields.mask &&
-             hvm_irq->gsi_assert_count[gsi] )
-        {
-            ent->fields.remote_irr = 1;
-            vioapic_deliver(vioapic, gsi);
+            ent = &vioapic->redirtbl[j];
+            if ( ent->fields.vector != vector )
+                continue;
+
+            ent->fields.remote_irr = 0;
+
+            if ( iommu_enabled )
+            {
+                spin_unlock(&d->arch.hvm_domain.irq_lock);
+                hvm_dpci_eoi(d, base_gsi + j, ent);
+                spin_lock(&d->arch.hvm_domain.irq_lock);
+            }
+
+            if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
+                 !ent->fields.mask &&
+                 hvm_irq->gsi_assert_count[base_gsi + j] )
+            {
+                ent->fields.remote_irr = 1;
+                vioapic_deliver(vioapic, j);
+            }
         }
+        base_gsi += vioapic->nr_pins;
     }
 
     spin_unlock(&d->arch.hvm_domain.irq_lock);
@@ -426,12 +488,13 @@ void vioapic_update_EOI(struct domain *d, u8 vector)
 
 static int ioapic_save(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_vioapic *s = domain_vioapic(d);
+    struct hvm_vioapic *s = domain_vioapic(d, 0);
 
     if ( !has_vioapic(d) )
         return 0;
 
-    if ( s->nr_pins != ARRAY_SIZE(s->domU.redirtbl) )
+    if ( s->nr_pins != ARRAY_SIZE(s->domU.redirtbl) ||
+         d->arch.hvm_domain.nr_vioapics != 1 )
         return -EOPNOTSUPP;
 
     return hvm_save_entry(IOAPIC, 0, h, &s->domU);
@@ -439,12 +502,13 @@ static int ioapic_save(struct domain *d, hvm_domain_context_t *h)
 
 static int ioapic_load(struct domain *d, hvm_domain_context_t *h)
 {
-    struct hvm_vioapic *s = domain_vioapic(d);
+    struct hvm_vioapic *s = domain_vioapic(d, 0);
 
     if ( !has_vioapic(d) )
         return -ENODEV;
 
-    if ( s->nr_pins != ARRAY_SIZE(s->domU.redirtbl) )
+    if ( s->nr_pins != ARRAY_SIZE(s->domU.redirtbl) ||
+         d->arch.hvm_domain.nr_vioapics != 1 )
         return -EOPNOTSUPP;
 
     return hvm_load_entry(IOAPIC, h, &s->domU);
@@ -454,32 +518,68 @@ HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load, 1, HVMSR_PER_DOM);
 
 void vioapic_reset(struct domain *d)
 {
-    struct hvm_vioapic *vioapic = domain_vioapic(d);
-    uint32_t nr_pins = vioapic->nr_pins;
-    int i;
+    unsigned int i;
 
     if ( !has_vioapic(d) )
+    {
+        ASSERT(!d->arch.hvm_domain.nr_vioapics);
         return;
+    }
 
-    memset(vioapic, 0, hvm_vioapic_size(nr_pins));
-    vioapic->domain = d;
-    vioapic->nr_pins = nr_pins;
-    for ( i = 0; i < nr_pins; i++ )
-        vioapic->redirtbl[i].fields.mask = 1;
-    vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS;
+    for ( i = 0; i < d->arch.hvm_domain.nr_vioapics; i++ )
+    {
+        struct hvm_vioapic *vioapic = domain_vioapic(d, i);
+        unsigned int j, nr_pins = vioapic->nr_pins;
+
+        memset(vioapic, 0, hvm_vioapic_size(nr_pins));
+        for ( j = 0; j < nr_pins; j++ )
+            vioapic->redirtbl[j].fields.mask = 1;
+        ASSERT(!i);
+        vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS +
+                                VIOAPIC_MEM_LENGTH * i;
+        vioapic->id = i;
+        vioapic->nr_pins = nr_pins;
+        vioapic->domain = d;
+    }
+}
+
+static void vioapic_free(const struct domain *d, unsigned int nr_vioapics)
+{
+    unsigned int i;
+
+    for ( i = 0; i < nr_vioapics; i++)
+        xfree(domain_vioapic(d, i));
+    xfree(d->arch.hvm_domain.vioapic);
 }
 
 int vioapic_init(struct domain *d)
 {
+    unsigned int i, nr_vioapics = 1;
+    unsigned int nr_pins = ARRAY_SIZE(domain_vioapic(d, 0)->domU.redirtbl);
+
     if ( !has_vioapic(d) )
+    {
+        ASSERT(!d->arch.hvm_domain.nr_vioapics);
         return 0;
+    }
 
     if ( (d->arch.hvm_domain.vioapic == NULL) &&
-         ((d->arch.hvm_domain.vioapic = xmalloc(struct hvm_vioapic)) == NULL) )
+         ((d->arch.hvm_domain.vioapic =
+           xzalloc_array(struct hvm_vioapic *, nr_vioapics)) == NULL) )
         return -ENOMEM;
 
-    d->arch.hvm_domain.vioapic->domain = d;
-    domain_vioapic(d)->nr_pins = ARRAY_SIZE(domain_vioapic(d)->domU.redirtbl);
+    for ( i = 0; i < nr_vioapics; i++ )
+    {
+        if ( (domain_vioapic(d, i) =
+              xmalloc_bytes(hvm_vioapic_size(nr_pins))) == NULL )
+        {
+            vioapic_free(d, nr_vioapics);
+            return -ENOMEM;
+        }
+        domain_vioapic(d, i)->nr_pins = nr_pins;
+    }
+
+    d->arch.hvm_domain.nr_vioapics = nr_vioapics;
     vioapic_reset(d);
 
     register_mmio_handler(d, &vioapic_mmio_ops);
@@ -490,8 +590,10 @@ int vioapic_init(struct domain *d)
 void vioapic_deinit(struct domain *d)
 {
     if ( !has_vioapic(d) )
+    {
+        ASSERT(!d->arch.hvm_domain.nr_vioapics);
         return;
+    }
 
-    xfree(d->arch.hvm_domain.vioapic);
-    d->arch.hvm_domain.vioapic = NULL;
+    vioapic_free(d, d->arch.hvm_domain.nr_vioapics);
 }
diff --git a/xen/arch/x86/hvm/vlapic.c b/xen/arch/x86/hvm/vlapic.c
index 0590d6c69d..2653ba80fd 100644
--- a/xen/arch/x86/hvm/vlapic.c
+++ b/xen/arch/x86/hvm/vlapic.c
@@ -1107,7 +1107,7 @@ static int __vlapic_accept_pic_intr(struct vcpu *v)
     if ( !has_vioapic(d) )
         return 0;
 
-    redir0 = domain_vioapic(d)->redirtbl[0];
+    redir0 = domain_vioapic(d, 0)->redirtbl[0];
 
     /* We deliver 8259 interrupts to the appropriate CPU as follows. */
     return ((/* IOAPIC pin0 is unmasked and routing to this LAPIC? */
diff --git a/xen/arch/x86/hvm/vpt.c b/xen/arch/x86/hvm/vpt.c
index 5c48fdb4b5..aa738b24fd 100644
--- a/xen/arch/x86/hvm/vpt.c
+++ b/xen/arch/x86/hvm/vpt.c
@@ -78,7 +78,8 @@ void hvm_set_guest_time(struct vcpu *v, u64 guest_time)
 static int pt_irq_vector(struct periodic_time *pt, enum hvm_intsrc src)
 {
     struct vcpu *v = pt->vcpu;
-    unsigned int gsi, isa_irq;
+    struct hvm_vioapic *vioapic;
+    unsigned int gsi, isa_irq, pin;
 
     if ( pt->source == PTSRC_lapic )
         return pt->irq;
@@ -91,13 +92,22 @@ static int pt_irq_vector(struct periodic_time *pt, enum hvm_intsrc src)
                 + (isa_irq & 7));
 
     ASSERT(src == hvm_intsrc_lapic);
-    return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
+    vioapic = gsi_vioapic(v->domain, gsi, &pin);
+    if ( !vioapic )
+    {
+        gdprintk(XENLOG_WARNING, "Invalid GSI (%u) for platform timer\n", gsi);
+        domain_crash(v->domain);
+        return -1;
+    }
+
+    return vioapic->redirtbl[pin].fields.vector;
 }
 
 static int pt_irq_masked(struct periodic_time *pt)
 {
     struct vcpu *v = pt->vcpu;
-    unsigned int gsi, isa_irq;
+    unsigned int gsi, isa_irq, pin;
+    struct hvm_vioapic *vioapic;
     uint8_t pic_imr;
 
     if ( pt->source == PTSRC_lapic )
@@ -110,9 +120,16 @@ static int pt_irq_masked(struct periodic_time *pt)
     isa_irq = pt->irq;
     gsi = hvm_isa_irq_to_gsi(isa_irq);
     pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr;
+    vioapic = gsi_vioapic(v->domain, gsi, &pin);
+    if ( !vioapic )
+    {
+        gdprintk(XENLOG_WARNING, "Invalid GSI (%u) for platform timer\n", gsi);
+        domain_crash(v->domain);
+        return -1;
+    }
 
     return (((pic_imr & (1 << (isa_irq & 7))) || !vlapic_accept_pic_intr(v)) &&
-            domain_vioapic(v->domain)->redirtbl[gsi].fields.mask);
+            vioapic->redirtbl[pin].fields.mask);
 }
 
 static void pt_lock(struct periodic_time *pt)
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 622e1ca12d..d2899c9bb2 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -127,7 +127,8 @@ struct hvm_domain {
     spinlock_t             irq_lock;
     struct hvm_irq        *irq;
     struct hvm_hw_vpic     vpic[2]; /* 0=master; 1=slave */
-    struct hvm_vioapic    *vioapic;
+    struct hvm_vioapic    **vioapic;
+    unsigned int           nr_vioapics;
     struct hvm_hw_stdvga   stdvga;
 
     /*
diff --git a/xen/include/asm-x86/hvm/vioapic.h b/xen/include/asm-x86/hvm/vioapic.h
index 711f294fbe..ac01c2a3e6 100644
--- a/xen/include/asm-x86/hvm/vioapic.h
+++ b/xen/include/asm-x86/hvm/vioapic.h
@@ -57,8 +57,10 @@ struct hvm_vioapic {
 };
 
 #define hvm_vioapic_size(cnt) offsetof(struct hvm_vioapic, redirtbl[cnt])
-#define domain_vioapic(d) ((d)->arch.hvm_domain.vioapic)
+#define domain_vioapic(d, i) ((d)->arch.hvm_domain.vioapic[i])
 #define vioapic_domain(v) ((v)->domain)
+struct hvm_vioapic *gsi_vioapic(const struct domain *d, unsigned int gsi,
+                                unsigned int *pin);
 
 int vioapic_init(struct domain *d);
 void vioapic_deinit(struct domain *d);
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 7/8] x86/ioapic: add prototype for io_apic_gsi_base to io_apic.h
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
                   ` (5 preceding siblings ...)
  2017-03-29 14:47 ` [PATCH v3 6/8] x86/vioapic: introduce support for multiple vIO APICS Roger Pau Monne
@ 2017-03-29 14:47 ` Roger Pau Monne
  2017-03-29 14:47 ` [PATCH v3 8/8] x86/vioapic: allow PVHv2 Dom0 to have more than one IO APIC Roger Pau Monne
  2017-03-30  8:16 ` [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
  8 siblings, 0 replies; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:47 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

So that the function can be called from other files without adding prototypes
to each of them.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
Changes since v1:
 - Add io_ prefix to avoid confusion.
 - Make the parameter unsigned.
---
 xen/arch/x86/io_apic.c        | 4 +---
 xen/arch/x86/mpparse.c        | 2 +-
 xen/include/asm-x86/io_apic.h | 3 +++
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index 24ee431b00..d18046067c 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -2274,8 +2274,6 @@ static int ioapic_physbase_to_id(unsigned long physbase)
     return -EINVAL;
 }
 
-unsigned apic_gsi_base(int apic);
-
 static int apic_pin_2_gsi_irq(int apic, int pin)
 {
     int idx;
@@ -2286,7 +2284,7 @@ static int apic_pin_2_gsi_irq(int apic, int pin)
     idx = find_irq_entry(apic, pin, mp_INT);
 
     return idx >= 0 ? pin_2_irq(idx, apic, pin)
-                    : apic_gsi_base(apic) + pin;
+                    : io_apic_gsi_base(apic) + pin;
 }
 
 int ioapic_guest_read(unsigned long physbase, unsigned int reg, u32 *pval)
diff --git a/xen/arch/x86/mpparse.c b/xen/arch/x86/mpparse.c
index 1eb7c99ea7..efcbc6115d 100644
--- a/xen/arch/x86/mpparse.c
+++ b/xen/arch/x86/mpparse.c
@@ -913,7 +913,7 @@ unsigned __init highest_gsi(void)
 	return res;
 }
 
-unsigned apic_gsi_base(int apic)
+unsigned int io_apic_gsi_base(unsigned int apic)
 {
 	return mp_ioapic_routing[apic].gsi_base;
 }
diff --git a/xen/include/asm-x86/io_apic.h b/xen/include/asm-x86/io_apic.h
index 225edd63b2..8029c8f400 100644
--- a/xen/include/asm-x86/io_apic.h
+++ b/xen/include/asm-x86/io_apic.h
@@ -127,6 +127,9 @@ struct __packed IO_APIC_route_entry {
 /* I/O APIC entries */
 extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS];
 
+/* Base GSI for this IO APIC */
+unsigned int io_apic_gsi_base(unsigned int apic);
+
 /* Only need to remap ioapic RTE (reg: 10~3Fh) */
 #define ioapic_reg_remapped(reg) (iommu_intremap && ((reg) >= 0x10))
 
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH v3 8/8] x86/vioapic: allow PVHv2 Dom0 to have more than one IO APIC
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
                   ` (6 preceding siblings ...)
  2017-03-29 14:47 ` [PATCH v3 7/8] x86/ioapic: add prototype for io_apic_gsi_base to io_apic.h Roger Pau Monne
@ 2017-03-29 14:47 ` Roger Pau Monne
  2017-03-30  8:16 ` [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
  8 siblings, 0 replies; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-29 14:47 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Jan Beulich, Roger Pau Monne

The base address, id and number of pins of the vIO APICs exposed to PVHv2 Dom0
is the same as the values found on bare metal.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/dom0_build.c | 33 ++++++++++++---------------------
 xen/arch/x86/hvm/hvm.c        |  8 +++++---
 xen/arch/x86/hvm/vioapic.c    | 29 +++++++++++++++++++++++------
 3 files changed, 40 insertions(+), 30 deletions(-)

diff --git a/xen/arch/x86/hvm/dom0_build.c b/xen/arch/x86/hvm/dom0_build.c
index daa791d3f4..db9be87612 100644
--- a/xen/arch/x86/hvm/dom0_build.c
+++ b/xen/arch/x86/hvm/dom0_build.c
@@ -681,12 +681,7 @@ static int __init pvh_setup_acpi_madt(struct domain *d, paddr_t *addr)
     max_vcpus = dom0_max_vcpus();
     /* Calculate the size of the crafted MADT. */
     size = sizeof(*madt);
-    /*
-     * FIXME: the current vIO-APIC code just supports one IO-APIC instance
-     * per domain. This must be fixed in order to provide the same amount of
-     * IO APICs as available on bare metal.
-     */
-    size += sizeof(*io_apic);
+    size += sizeof(*io_apic) * nr_ioapics;
     size += sizeof(*intsrcovr) * acpi_intr_overrides;
     size += sizeof(*nmisrc) * acpi_nmi_sources;
     size += sizeof(*x2apic) * max_vcpus;
@@ -716,23 +711,19 @@ static int __init pvh_setup_acpi_madt(struct domain *d, paddr_t *addr)
      */
     madt->header.revision = min_t(unsigned char, table->revision, 4);
 
-    /*
-     * Setup the IO APIC entry.
-     * FIXME: the current vIO-APIC code just supports one IO-APIC instance
-     * per domain. This must be fixed in order to provide the same amount of
-     * IO APICs as available on bare metal, and with the same IDs as found in
-     * the native IO APIC MADT entries.
-     */
-    if ( nr_ioapics > 1 )
-        printk("WARNING: found %d IO APICs, Dom0 will only have access to 1 emulated IO APIC\n",
-               nr_ioapics);
+    /* Setup the IO APIC entries. */
     io_apic = (void *)(madt + 1);
-    io_apic->header.type = ACPI_MADT_TYPE_IO_APIC;
-    io_apic->header.length = sizeof(*io_apic);
-    io_apic->id = domain_vioapic(d, 0)->id;
-    io_apic->address = VIOAPIC_DEFAULT_BASE_ADDRESS;
+    for ( i = 0; i < nr_ioapics; i++ )
+    {
+        io_apic->header.type = ACPI_MADT_TYPE_IO_APIC;
+        io_apic->header.length = sizeof(*io_apic);
+        io_apic->id = domain_vioapic(d, i)->id;
+        io_apic->address = domain_vioapic(d, i)->base_address;
+        io_apic->global_irq_base = io_apic_gsi_base(i);
+        io_apic++;
+    }
 
-    x2apic = (void *)(io_apic + 1);
+    x2apic = (void *)io_apic;
     for ( i = 0; i < max_vcpus; i++ )
     {
         x2apic->header.type = ACPI_MADT_TYPE_LOCAL_X2APIC;
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 6c3c944abd..9a9732b308 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -595,6 +595,7 @@ static int hvm_print_line(
 
 int hvm_domain_initialise(struct domain *d)
 {
+    unsigned int nr_gsis;
     int rc;
 
     if ( !hvm_enabled )
@@ -616,19 +617,20 @@ int hvm_domain_initialise(struct domain *d)
     if ( rc != 0 )
         goto fail0;
 
+    nr_gsis = is_hardware_domain(d) ? nr_irqs_gsi : NR_HVM_DOMU_IRQS;
     d->arch.hvm_domain.pl_time = xzalloc(struct pl_time);
     d->arch.hvm_domain.params = xzalloc_array(uint64_t, HVM_NR_PARAMS);
     d->arch.hvm_domain.io_handler = xzalloc_array(struct hvm_io_handler,
                                                   NR_IO_HANDLERS);
-    d->arch.hvm_domain.irq = xzalloc_bytes(hvm_irq_size(NR_HVM_DOMU_IRQS));
+    d->arch.hvm_domain.irq = xzalloc_bytes(hvm_irq_size(nr_gsis));
 
     rc = -ENOMEM;
     if ( !d->arch.hvm_domain.pl_time || !d->arch.hvm_domain.irq ||
          !d->arch.hvm_domain.params  || !d->arch.hvm_domain.io_handler )
         goto fail1;
 
-    /* Set the default number of GSIs */
-    hvm_domain_irq(d)->nr_gsis = NR_HVM_DOMU_IRQS;
+    /* Set the number of GSIs */
+    hvm_domain_irq(d)->nr_gsis = nr_gsis;
 
     BUILD_BUG_ON(NR_HVM_DOMU_IRQS < NR_ISAIRQS);
     ASSERT(hvm_domain_irq(d)->nr_gsis >= NR_ISAIRQS);
diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c
index 990ad707ec..02ae58ba5f 100644
--- a/xen/arch/x86/hvm/vioapic.c
+++ b/xen/arch/x86/hvm/vioapic.c
@@ -534,10 +534,20 @@ void vioapic_reset(struct domain *d)
         memset(vioapic, 0, hvm_vioapic_size(nr_pins));
         for ( j = 0; j < nr_pins; j++ )
             vioapic->redirtbl[j].fields.mask = 1;
-        ASSERT(!i);
-        vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS +
-                                VIOAPIC_MEM_LENGTH * i;
-        vioapic->id = i;
+
+        if ( !is_hardware_domain(d) )
+        {
+            ASSERT(!i);
+            vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS +
+                                    VIOAPIC_MEM_LENGTH * i;
+            vioapic->id = i;
+        }
+        else
+        {
+            vioapic->base_address = mp_ioapics[i].mpc_apicaddr;
+            vioapic->id = mp_ioapics[i].mpc_apicid;
+        }
+
         vioapic->nr_pins = nr_pins;
         vioapic->domain = d;
     }
@@ -554,8 +564,7 @@ static void vioapic_free(const struct domain *d, unsigned int nr_vioapics)
 
 int vioapic_init(struct domain *d)
 {
-    unsigned int i, nr_vioapics = 1;
-    unsigned int nr_pins = ARRAY_SIZE(domain_vioapic(d, 0)->domU.redirtbl);
+    unsigned int i, nr_vioapics, nr_gsis = 0;
 
     if ( !has_vioapic(d) )
     {
@@ -563,6 +572,8 @@ int vioapic_init(struct domain *d)
         return 0;
     }
 
+    nr_vioapics = is_hardware_domain(d) ? nr_ioapics : 1;
+
     if ( (d->arch.hvm_domain.vioapic == NULL) &&
          ((d->arch.hvm_domain.vioapic =
            xzalloc_array(struct hvm_vioapic *, nr_vioapics)) == NULL) )
@@ -570,6 +581,9 @@ int vioapic_init(struct domain *d)
 
     for ( i = 0; i < nr_vioapics; i++ )
     {
+        unsigned int nr_pins = is_hardware_domain(d) ? nr_ioapic_entries[i] :
+            ARRAY_SIZE(domain_vioapic(d, 0)->domU.redirtbl);
+
         if ( (domain_vioapic(d, i) =
               xmalloc_bytes(hvm_vioapic_size(nr_pins))) == NULL )
         {
@@ -577,8 +591,11 @@ int vioapic_init(struct domain *d)
             return -ENOMEM;
         }
         domain_vioapic(d, i)->nr_pins = nr_pins;
+        nr_gsis += nr_pins;
     }
 
+    ASSERT(hvm_domain_irq(d)->nr_gsis == nr_gsis);
+
     d->arch.hvm_domain.nr_vioapics = nr_vioapics;
     vioapic_reset(d);
 
-- 
2.11.0 (Apple Git-81)


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs
  2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
                   ` (7 preceding siblings ...)
  2017-03-29 14:47 ` [PATCH v3 8/8] x86/vioapic: allow PVHv2 Dom0 to have more than one IO APIC Roger Pau Monne
@ 2017-03-30  8:16 ` Roger Pau Monne
  8 siblings, 0 replies; 20+ messages in thread
From: Roger Pau Monne @ 2017-03-30  8:16 UTC (permalink / raw)
  To: xen-devel, konrad.wilk, boris.ostrovsky

On Wed, Mar 29, 2017 at 03:39:10PM +0100, Roger Pau Monne wrote:
> Hello,
> 
> This patch series introduce support for having a variable number of entries in
> vIO APICs, and also having a variable number of vIO APICs per domain. This
> functionality is not used by unprivileged guests, that are still limited to a
> single IO APIC with 48 entries.
> 
> The functionality introduced is only used by PVHv2 Dom0, in order to copy the
> IO APIC topology found on bare metal.
> 
> A private osstest flight is currently running against this series.

The osstest adhoc flight hasn't found any regressions with this series.

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 2/8] x86/hvm: introduce hvm_domain_irq macro
  2017-03-29 14:47 ` [PATCH v3 2/8] x86/hvm: introduce hvm_domain_irq macro Roger Pau Monne
@ 2017-03-31  5:10   ` Tian, Kevin
  2017-03-31 14:53   ` Jan Beulich
  1 sibling, 0 replies; 20+ messages in thread
From: Tian, Kevin @ 2017-03-31  5:10 UTC (permalink / raw)
  To: Roger Pau Monne, xen-devel, konrad.wilk, boris.ostrovsky
  Cc: Andrew Cooper, Jan Beulich

> From: Roger Pau Monne [mailto:roger.pau@citrix.com]
> Sent: Wednesday, March 29, 2017 10:47 PM
> 
> Introduce a macro to get a pointer to the hvm_irq for a HVM domain. No
> functional change.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

Reviewed-by: Kevin Tian <kevin.tian@intel.com> for VTd part.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 1/8] x86/vioapic: expand hvm_vioapic to contain vIO APIC internal state
  2017-03-29 14:39 ` [PATCH v3 1/8] x86/vioapic: expand hvm_vioapic to contain vIO APIC internal state Roger Pau Monne
@ 2017-03-31 14:52   ` Jan Beulich
  0 siblings, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2017-03-31 14:52 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, boris.ostrovsky, xen-devel

>>> On 29.03.17 at 16:39, <roger.pau@citrix.com> wrote:
> This is required in order to have a variable number of vIO APIC pins, instead
> of the current fixed value (48). Note that this patch only expands the fields
> of the hvm_vioapic struct, without actually introducing any new fields or
> functionality.
> 
> The reason to expand the hvm_vioapic structure instead of the hvm_hw_vioapic
> one is that the variable number of pins functionality is only going to be used
> by the hardware domain, so no modifications are needed to the save format.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 2/8] x86/hvm: introduce hvm_domain_irq macro
  2017-03-29 14:47 ` [PATCH v3 2/8] x86/hvm: introduce hvm_domain_irq macro Roger Pau Monne
  2017-03-31  5:10   ` Tian, Kevin
@ 2017-03-31 14:53   ` Jan Beulich
  1 sibling, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2017-03-31 14:53 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, Kevin Tian, boris.ostrovsky, xen-devel

>>> On 29.03.17 at 16:47, <roger.pau@citrix.com> wrote:
> Introduce a macro to get a pointer to the hvm_irq for a HVM domain. No
> functional change.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

Acked-by: Jan Beulich <jbeulich@suse.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 3/8] x86/irq: rename NR_HVM_IRQS and break it's dependency on VIOAPIC_NUM_PINS
  2017-03-29 14:47 ` [PATCH v3 3/8] x86/irq: rename NR_HVM_IRQS and break it's dependency on VIOAPIC_NUM_PINS Roger Pau Monne
@ 2017-03-31 15:01   ` Jan Beulich
  2017-04-04 10:15     ` Roger Pau Monne
  0 siblings, 1 reply; 20+ messages in thread
From: Jan Beulich @ 2017-03-31 15:01 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, boris.ostrovsky, xen-devel

>>> On 29.03.17 at 16:47, <roger.pau@citrix.com> wrote:
> Rename it to NR_HVM_DOMU_IRQS, and get it's value from the size of the DomU vIO
> APIC redirection table.

The line wrapping here is slightly puzzling...

> --- a/xen/include/xen/hvm/irq.h
> +++ b/xen/include/xen/hvm/irq.h
> @@ -76,13 +76,13 @@ struct hvm_girq_dpci_mapping {
>  #define NR_ISAIRQS  16
>  #define NR_LINK     4
>  #if defined(CONFIG_X86)
> -# define NR_HVM_IRQS VIOAPIC_NUM_PINS
> +# define NR_HVM_DOMU_IRQS ARRAY_SIZE(((struct hvm_hw_vioapic *)0)->redirtbl)

An abuse of NULL pointers like this is not the end of the world, but
did you consider avoiding this by expressing things starting from
current (which ought to be always in scope)? Or did you event try
doing so, and it didn't work out for some reason (possibly header
dependencies getting in the way)?

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 4/8] x86/hvm: convert gsi_assert_count into a variable size array
  2017-03-29 14:47 ` [PATCH v3 4/8] x86/hvm: convert gsi_assert_count into a variable size array Roger Pau Monne
@ 2017-03-31 15:16   ` Jan Beulich
  2017-04-03 16:18     ` Roger Pau Monne
  0 siblings, 1 reply; 20+ messages in thread
From: Jan Beulich @ 2017-03-31 15:16 UTC (permalink / raw)
  To: Andrew Cooper, Roger Pau Monne; +Cc: xen-devel, boris.ostrovsky

>>> On 29.03.17 at 16:47, <roger.pau@citrix.com> wrote:
> Rearrange the fields of hvm_irq so that gsi_assert_count can be converted into
> a variable size array and add a new field to account the number of GSIs.
> 
> Due to this changes the irq member in the hvm_domain struct also needs to
> become a pointer set at runtime.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
with one possible adjustment:

> --- a/xen/arch/x86/hvm/irq.c
> +++ b/xen/arch/x86/hvm/irq.c
> @@ -69,6 +69,7 @@ static void __hvm_pci_intx_assert(
>          return;
>  
>      gsi = hvm_pci_intx_gsi(device, intx);
> +    ASSERT(gsi < hvm_irq->nr_gsis);
>      if ( hvm_irq->gsi_assert_count[gsi]++ == 0 )
>          assert_gsi(d, gsi);
>  
> @@ -99,6 +100,7 @@ static void __hvm_pci_intx_deassert(
>          return;
>  
>      gsi = hvm_pci_intx_gsi(device, intx);
> +    ASSERT(gsi < hvm_irq->nr_gsis);
>      --hvm_irq->gsi_assert_count[gsi];

These ASSERT()s certainly don't make the situation worse after
just this patch alone, but once the higher Dom0 count comes
into play them turning into nothing on release builds is sub-
optimal. In a few cases we've used (or at least have been
considering using) something like

    if ( gsi >= hvm_irq->nr_gsis)
    {
        ASSERT_UNREACHABLE();
        return;
    }

to avoid the array overrun even in the release build case.
Otoh it's only Dom0 which could actually cause this, so it
wouldn't be a security issue as per our current classification.
Andrew - do you have a specific opinion either way here?

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 5/8] x86/vioapic: allow the vIO APIC to have a variable number of pins
  2017-03-29 14:47 ` [PATCH v3 5/8] x86/vioapic: allow the vIO APIC to have a variable number of pins Roger Pau Monne
@ 2017-03-31 15:20   ` Jan Beulich
  0 siblings, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2017-03-31 15:20 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, boris.ostrovsky, xen-devel

>>> On 29.03.17 at 16:47, <roger.pau@citrix.com> wrote:
> Although it's still always set to VIOAPIC_NUM_PINS (48).
> 
> Add a new field to the hvm_ioapic struct to contain the number of pins (number
> of IO redirection table entries) and turn the redirection table into a variable
> sized array.
> 
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>

Reviewed-by: Jan Beulich <jbeulich@suse.com>
with one remark:

> --- a/xen/include/asm-x86/hvm/vioapic.h
> +++ b/xen/include/asm-x86/hvm/vioapic.h
> @@ -49,12 +49,14 @@
>  
>  struct hvm_vioapic {
>      struct domain *domain;
> +    uint32_t nr_pins;
>      union {
> -        XEN_HVM_VIOAPIC(, VIOAPIC_NUM_PINS);
> +        XEN_HVM_VIOAPIC(, 0);

I think the 0 here isn't needed either, and having two blank macro
arguments doesn't seem any worse than having one. That way we
would have one less place where we depend on gcc's zero-length
array extension.

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 6/8] x86/vioapic: introduce support for multiple vIO APICS
  2017-03-29 14:47 ` [PATCH v3 6/8] x86/vioapic: introduce support for multiple vIO APICS Roger Pau Monne
@ 2017-03-31 15:48   ` Jan Beulich
  0 siblings, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2017-03-31 15:48 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, boris.ostrovsky, xen-devel

>>> On 29.03.17 at 16:47, <roger.pau@citrix.com> wrote:
> +static unsigned int base_gsi(const struct domain *d,
> +                             const struct hvm_vioapic *vioapic)
> +{
> +    const struct hvm_vioapic *tmp;
> +    unsigned int base_gsi = 0, nr_vioapics = d->arch.hvm_domain.nr_vioapics;
> +
> +    for ( tmp = domain_vioapic(d, 0); --nr_vioapics && tmp != vioapic; tmp++ )

I don't think tmp++ is correct here - you need to use
domain_vioapic(d, i) on every iteration.

> @@ -361,64 +416,71 @@ static void vioapic_deliver(struct hvm_vioapic *vioapic, int irq)
>  
>  void vioapic_irq_positive_edge(struct domain *d, unsigned int irq)
>  {
> -    struct hvm_vioapic *vioapic = domain_vioapic(d);
> +    unsigned int pin;
> +    struct hvm_vioapic *vioapic = gsi_vioapic(d, irq, &pin);
>      union vioapic_redir_entry *ent;
>  
>      ASSERT(has_vioapic(d));

Perhaps better make this ASSERT(vioapic) now? Or even bail if this
ends up being NULL? The ASSERT() above comes too late now in
any event.

>  void vioapic_update_EOI(struct domain *d, u8 vector)
>  {
> -    struct hvm_vioapic *vioapic = domain_vioapic(d);
>      struct hvm_irq *hvm_irq = hvm_domain_irq(d);
>      union vioapic_redir_entry *ent;
> -    int gsi;
> +    unsigned int i, base_gsi = 0;
>  
>      ASSERT(has_vioapic(d));
> 
>      spin_lock(&d->arch.hvm_domain.irq_lock);
>  
> -    for ( gsi = 0; gsi < vioapic->nr_pins; gsi++ )
> +    for ( i = 0; i < d->arch.hvm_domain.nr_vioapics; i++ )
>      {
> -        ent = &vioapic->redirtbl[gsi];
> -        if ( ent->fields.vector != vector )
> -            continue;
> -
> -        ent->fields.remote_irr = 0;
> +        struct hvm_vioapic *vioapic = domain_vioapic(d, i);
> +        unsigned int j;
>  
> -        if ( iommu_enabled )
> +        for ( j = 0; j < vioapic->nr_pins; j++ )

Please use pin instead of j.

> @@ -426,12 +488,13 @@ void vioapic_update_EOI(struct domain *d, u8 vector)
>  
>  static int ioapic_save(struct domain *d, hvm_domain_context_t *h)
>  {
> -    struct hvm_vioapic *s = domain_vioapic(d);
> +    struct hvm_vioapic *s = domain_vioapic(d, 0);
>  
>      if ( !has_vioapic(d) )
>          return 0;

This check needs to be ahead of domain_vioapic() use - I'd expect
d->vioapic to be NULL in such a case, and the macro dereferences
it. Please double check other uses.

> @@ -454,32 +518,68 @@ HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load, 1, HVMSR_PER_DOM);
>  
>  void vioapic_reset(struct domain *d)
>  {
> -    struct hvm_vioapic *vioapic = domain_vioapic(d);
> -    uint32_t nr_pins = vioapic->nr_pins;
> -    int i;
> +    unsigned int i;
>  
>      if ( !has_vioapic(d) )
> +    {
> +        ASSERT(!d->arch.hvm_domain.nr_vioapics);
>          return;
> +    }
>  
> -    memset(vioapic, 0, hvm_vioapic_size(nr_pins));
> -    vioapic->domain = d;
> -    vioapic->nr_pins = nr_pins;
> -    for ( i = 0; i < nr_pins; i++ )
> -        vioapic->redirtbl[i].fields.mask = 1;
> -    vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS;
> +    for ( i = 0; i < d->arch.hvm_domain.nr_vioapics; i++ )
> +    {
> +        struct hvm_vioapic *vioapic = domain_vioapic(d, i);
> +        unsigned int j, nr_pins = vioapic->nr_pins;
> +
> +        memset(vioapic, 0, hvm_vioapic_size(nr_pins));
> +        for ( j = 0; j < nr_pins; j++ )
> +            vioapic->redirtbl[j].fields.mask = 1;

It's not as relevant here, but s/j/pin/ would again be better imo.

> +        ASSERT(!i);
> +        vioapic->base_address = VIOAPIC_DEFAULT_BASE_ADDRESS +
> +                                VIOAPIC_MEM_LENGTH * i;

With the ASSERT() above, please drop the (wrong, as pointed out
before) dependency on i of this expression.

> @@ -91,13 +92,22 @@ static int pt_irq_vector(struct periodic_time *pt, enum hvm_intsrc src)
>                  + (isa_irq & 7));
>  
>      ASSERT(src == hvm_intsrc_lapic);
> -    return domain_vioapic(v->domain)->redirtbl[gsi].fields.vector;
> +    vioapic = gsi_vioapic(v->domain, gsi, &pin);
> +    if ( !vioapic )
> +    {
> +        gdprintk(XENLOG_WARNING, "Invalid GSI (%u) for platform timer\n", gsi);

Unless v == current at all times, gdprintk() is not suitable here, and
you'd rather want to include d->domain_id in what is being logged.

> @@ -110,9 +120,16 @@ static int pt_irq_masked(struct periodic_time *pt)
>      isa_irq = pt->irq;
>      gsi = hvm_isa_irq_to_gsi(isa_irq);
>      pic_imr = v->domain->arch.hvm_domain.vpic[isa_irq >> 3].imr;
> +    vioapic = gsi_vioapic(v->domain, gsi, &pin);
> +    if ( !vioapic )
> +    {
> +        gdprintk(XENLOG_WARNING, "Invalid GSI (%u) for platform timer\n", gsi);

Same here.

> --- a/xen/include/asm-x86/hvm/vioapic.h
> +++ b/xen/include/asm-x86/hvm/vioapic.h
> @@ -57,8 +57,10 @@ struct hvm_vioapic {
>  };
>  
>  #define hvm_vioapic_size(cnt) offsetof(struct hvm_vioapic, redirtbl[cnt])
> -#define domain_vioapic(d) ((d)->arch.hvm_domain.vioapic)
> +#define domain_vioapic(d, i) ((d)->arch.hvm_domain.vioapic[i])
>  #define vioapic_domain(v) ((v)->domain)
> +struct hvm_vioapic *gsi_vioapic(const struct domain *d, unsigned int gsi,
> +                                unsigned int *pin);

Please don't munge this together with macros, but with other
function declarations (or at least add a blank line in between).

Jan

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 4/8] x86/hvm: convert gsi_assert_count into a variable size array
  2017-03-31 15:16   ` Jan Beulich
@ 2017-04-03 16:18     ` Roger Pau Monne
  0 siblings, 0 replies; 20+ messages in thread
From: Roger Pau Monne @ 2017-04-03 16:18 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Andrew Cooper, boris.ostrovsky, xen-devel

On Fri, Mar 31, 2017 at 09:16:53AM -0600, Jan Beulich wrote:
> >>> On 29.03.17 at 16:47, <roger.pau@citrix.com> wrote:
> > Rearrange the fields of hvm_irq so that gsi_assert_count can be converted into
> > a variable size array and add a new field to account the number of GSIs.
> > 
> > Due to this changes the irq member in the hvm_domain struct also needs to
> > become a pointer set at runtime.
> > 
> > Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> 
> Reviewed-by: Jan Beulich <jbeulich@suse.com>
> with one possible adjustment:
> 
> > --- a/xen/arch/x86/hvm/irq.c
> > +++ b/xen/arch/x86/hvm/irq.c
> > @@ -69,6 +69,7 @@ static void __hvm_pci_intx_assert(
> >          return;
> >  
> >      gsi = hvm_pci_intx_gsi(device, intx);
> > +    ASSERT(gsi < hvm_irq->nr_gsis);
> >      if ( hvm_irq->gsi_assert_count[gsi]++ == 0 )
> >          assert_gsi(d, gsi);
> >  
> > @@ -99,6 +100,7 @@ static void __hvm_pci_intx_deassert(
> >          return;
> >  
> >      gsi = hvm_pci_intx_gsi(device, intx);
> > +    ASSERT(gsi < hvm_irq->nr_gsis);
> >      --hvm_irq->gsi_assert_count[gsi];
> 
> These ASSERT()s certainly don't make the situation worse after
> just this patch alone, but once the higher Dom0 count comes
> into play them turning into nothing on release builds is sub-
> optimal. In a few cases we've used (or at least have been
> considering using) something like
> 
>     if ( gsi >= hvm_irq->nr_gsis)
>     {
>         ASSERT_UNREACHABLE();
>         return;
>     }
> 
> to avoid the array overrun even in the release build case.
> Otoh it's only Dom0 which could actually cause this, so it
> wouldn't be a security issue as per our current classification.
> Andrew - do you have a specific opinion either way here?

Yes, I think your suggestion is better, it will trigger on debug builds while
not causing array overrun on production ones.

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 3/8] x86/irq: rename NR_HVM_IRQS and break it's dependency on VIOAPIC_NUM_PINS
  2017-03-31 15:01   ` Jan Beulich
@ 2017-04-04 10:15     ` Roger Pau Monne
  2017-04-04 10:18       ` Jan Beulich
  0 siblings, 1 reply; 20+ messages in thread
From: Roger Pau Monne @ 2017-04-04 10:15 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Andrew Cooper, boris.ostrovsky, xen-devel

On Fri, Mar 31, 2017 at 09:01:54AM -0600, Jan Beulich wrote:
> >>> On 29.03.17 at 16:47, <roger.pau@citrix.com> wrote:
> > Rename it to NR_HVM_DOMU_IRQS, and get it's value from the size of the DomU vIO
> > APIC redirection table.
> 
> The line wrapping here is slightly puzzling...
> 
> > --- a/xen/include/xen/hvm/irq.h
> > +++ b/xen/include/xen/hvm/irq.h
> > @@ -76,13 +76,13 @@ struct hvm_girq_dpci_mapping {
> >  #define NR_ISAIRQS  16
> >  #define NR_LINK     4
> >  #if defined(CONFIG_X86)
> > -# define NR_HVM_IRQS VIOAPIC_NUM_PINS
> > +# define NR_HVM_DOMU_IRQS ARRAY_SIZE(((struct hvm_hw_vioapic *)0)->redirtbl)
> 
> An abuse of NULL pointers like this is not the end of the world, but
> did you consider avoiding this by expressing things starting from
> current (which ought to be always in scope)? Or did you event try
> doing so, and it didn't work out for some reason (possibly header
> dependencies getting in the way)?

It complains with:

error: incomplete definition of type 'struct vcpu'

on some places, I guess I could try to fix it, but I'm not sure if it's worth
it.

Roger.

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH v3 3/8] x86/irq: rename NR_HVM_IRQS and break it's dependency on VIOAPIC_NUM_PINS
  2017-04-04 10:15     ` Roger Pau Monne
@ 2017-04-04 10:18       ` Jan Beulich
  0 siblings, 0 replies; 20+ messages in thread
From: Jan Beulich @ 2017-04-04 10:18 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: Andrew Cooper, boris.ostrovsky, xen-devel

>>> On 04.04.17 at 12:15, <roger.pau@citrix.com> wrote:
> On Fri, Mar 31, 2017 at 09:01:54AM -0600, Jan Beulich wrote:
>> >>> On 29.03.17 at 16:47, <roger.pau@citrix.com> wrote:
>> > Rename it to NR_HVM_DOMU_IRQS, and get it's value from the size of the DomU 
> vIO
>> > APIC redirection table.
>> 
>> The line wrapping here is slightly puzzling...
>> 
>> > --- a/xen/include/xen/hvm/irq.h
>> > +++ b/xen/include/xen/hvm/irq.h
>> > @@ -76,13 +76,13 @@ struct hvm_girq_dpci_mapping {
>> >  #define NR_ISAIRQS  16
>> >  #define NR_LINK     4
>> >  #if defined(CONFIG_X86)
>> > -# define NR_HVM_IRQS VIOAPIC_NUM_PINS
>> > +# define NR_HVM_DOMU_IRQS ARRAY_SIZE(((struct hvm_hw_vioapic *)0)->redirtbl)
>> 
>> An abuse of NULL pointers like this is not the end of the world, but
>> did you consider avoiding this by expressing things starting from
>> current (which ought to be always in scope)? Or did you event try
>> doing so, and it didn't work out for some reason (possibly header
>> dependencies getting in the way)?
> 
> It complains with:
> 
> error: incomplete definition of type 'struct vcpu'
> 
> on some places, I guess I could try to fix it, but I'm not sure if it's worth
> it.

Probably not.

Reviewed-by: Jan Beulich <jbeulich@suse.com>

Jan


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2017-04-04 10:19 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-29 14:39 [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne
2017-03-29 14:39 ` [PATCH v3 1/8] x86/vioapic: expand hvm_vioapic to contain vIO APIC internal state Roger Pau Monne
2017-03-31 14:52   ` Jan Beulich
2017-03-29 14:47 ` [PATCH v3 2/8] x86/hvm: introduce hvm_domain_irq macro Roger Pau Monne
2017-03-31  5:10   ` Tian, Kevin
2017-03-31 14:53   ` Jan Beulich
2017-03-29 14:47 ` [PATCH v3 3/8] x86/irq: rename NR_HVM_IRQS and break it's dependency on VIOAPIC_NUM_PINS Roger Pau Monne
2017-03-31 15:01   ` Jan Beulich
2017-04-04 10:15     ` Roger Pau Monne
2017-04-04 10:18       ` Jan Beulich
2017-03-29 14:47 ` [PATCH v3 4/8] x86/hvm: convert gsi_assert_count into a variable size array Roger Pau Monne
2017-03-31 15:16   ` Jan Beulich
2017-04-03 16:18     ` Roger Pau Monne
2017-03-29 14:47 ` [PATCH v3 5/8] x86/vioapic: allow the vIO APIC to have a variable number of pins Roger Pau Monne
2017-03-31 15:20   ` Jan Beulich
2017-03-29 14:47 ` [PATCH v3 6/8] x86/vioapic: introduce support for multiple vIO APICS Roger Pau Monne
2017-03-31 15:48   ` Jan Beulich
2017-03-29 14:47 ` [PATCH v3 7/8] x86/ioapic: add prototype for io_apic_gsi_base to io_apic.h Roger Pau Monne
2017-03-29 14:47 ` [PATCH v3 8/8] x86/vioapic: allow PVHv2 Dom0 to have more than one IO APIC Roger Pau Monne
2017-03-30  8:16 ` [PATCH v3 0/8] x86/vioapic: introduce support for multiple vIO APICs Roger Pau Monne

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.