[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v4 12/17] xen/arm: ITS: Initialize LPI irq descriptors and route



Hi Vijay,

On 10/07/2015 09:42, vijay.kilari@xxxxxxxxx wrote:
diff --git a/xen/arch/arm/gic-v3.c b/xen/arch/arm/gic-v3.c
index e6004d2..53554e6 100644
--- a/xen/arch/arm/gic-v3.c
+++ b/xen/arch/arm/gic-v3.c
@@ -895,7 +895,7 @@ static void gicv3_update_lr(int lr, const struct 
pending_irq *p,
      val |= ((uint64_t)p->priority & 0xff) << GICH_LR_PRIORITY_SHIFT;
      val |= ((uint64_t)p->irq & GICH_LR_VIRTUAL_MASK) << GICH_LR_VIRTUAL_SHIFT;

-   if ( p->desc != NULL )
+   if ( p->desc != NULL && !(is_lpi(p->irq)) )

It seems that you replaced all the p->desc != NULL by "p->desc != NULL && !is_lpi(p->irq).

Why don't you avoid to set p->desc in this case?

You may also want to put some explanation in the commit message to explain why you don't have to set the GICH_LR.HW bit for LPIs.

         val |= GICH_LR_HW | (((uint64_t)p->desc->irq & GICH_LR_PHYSICAL_MASK)
                             << GICH_LR_PHYSICAL_SHIFT);

diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 3ebadcf..92d2be9 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -68,11 +68,18 @@ enum gic_version gic_hw_version(void)
     return gic_hw_ops->info->hw_version;
  }

+/* Only validates PPIs/SGIs/SPIs supported */

This comment seems wrong. The function doesn't validate the IRQ but return the number of Lines (i.e PPIs/SGIs/SPIs).

  unsigned int gic_number_lines(void)
  {
      return gic_hw_ops->info->nr_lines;
  }

[...]

  int gic_route_irq_to_guest(struct domain *d, unsigned int virq,
                             struct irq_desc *desc, unsigned int priority)
  {
@@ -454,7 +472,7 @@ static void gic_update_one_lr(struct vcpu *v, int i)
          if ( test_bit(GIC_IRQ_GUEST_ENABLED, &p->status) &&
               test_and_clear_bit(GIC_IRQ_GUEST_QUEUED, &p->status) )
          {
-            if ( p->desc == NULL )
+            if ( p->desc == NULL  || is_lpi(irq) )
              {
                   lr_val.state |= GICH_LR_PENDING;
                   gic_hw_ops->write_lr(i, &lr_val);
@@ -677,7 +695,7 @@ void gic_interrupt(struct cpu_user_regs *regs, int is_fiq)
          /* Reading IRQ will ACK it */
          irq = gic_hw_ops->read_irq();

-        if ( likely(irq >= 16 && irq < 1020) )
+        if ( (likely(irq >= 16 && irq < 1020)) || is_lpi(irq) )

Please move the is_lpi(irq) in likely.

          {
              local_irq_enable();
              do_IRQ(regs, irq, is_fiq);

[...]

@@ -208,7 +226,7 @@ int request_irq(unsigned int irq, unsigned int irqflags,
       * which interrupt is which (messes up the interrupt freeing
       * logic etc).
       */
-    if ( irq >= nr_irqs )
+    if ( irq >= nr_irqs && !is_lpi(irq) )

Technically nr_irqs should contain the total number of IRQ and not only the number of SPI/PPI/SGI.

Either modify nr_irqs or use gic_is_valid_irq which would do the same here.

          return -EINVAL;
      if ( !handler )
          return -EINVAL;
@@ -267,9 +285,14 @@ void do_IRQ(struct cpu_user_regs *regs, unsigned int irq, 
int is_fiq)
          set_bit(_IRQ_INPROGRESS, &desc->status);
          desc->arch.eoi_cpu = smp_processor_id();

+#ifdef CONFIG_ARM_64
+        if ( is_lpi(irq) )
+            vgic_vcpu_inject_lpi(info->d, irq);
+        else
+#endif
          /* the irq cannot be a PPI, we only support delivery of SPIs to
           * guests */
-        vgic_vcpu_inject_spi(info->d, info->virq);
+            vgic_vcpu_inject_spi(info->d, info->virq);
          goto out_no_end;
      }

@@ -436,7 +459,8 @@ err:
  bool_t is_assignable_irq(unsigned int irq)
  {
      /* For now, we can only route SPIs to the guest */
-    return ((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines()));
+    return (((irq >= NR_LOCAL_IRQS) && (irq < gic_number_lines())) ||
+              is_lpi(irq));

If you modify the function, please also modify the comment which become invalid now.

[...]

diff --git a/xen/arch/arm/vgic-v3-its.c b/xen/arch/arm/vgic-v3-its.c
index bbcc7bb..4649b07 100644
--- a/xen/arch/arm/vgic-v3-its.c
+++ b/xen/arch/arm/vgic-v3-its.c
@@ -625,6 +625,15 @@ err:
      return 0;
  }

+uint8_t vgic_its_get_priority(struct vcpu *v, uint32_t pid)
+{
+    uint8_t priority;
+
+    priority =  readb_relaxed(v->domain->arch.vits->prop_page + pid);

Why do you use readb_relaxed here? This should only be used for Device MMIO.

Although, you need to ensure that the value will be correctly synchronize if another CPU is writing in prop_page which is protected by prop_lock.

+    priority &= LPI_PRIORITY_MASK;
+
+    return priority;
+}
  static int vgic_v3_gits_lpi_mmio_read(struct vcpu *v, mmio_info_t *info)
  {
      uint32_t offset;

diff --git a/xen/include/asm-arm/gic.h b/xen/include/asm-arm/gic.h
index 69bf1ff..537ed3d 100644
--- a/xen/include/asm-arm/gic.h
+++ b/xen/include/asm-arm/gic.h
@@ -226,6 +226,9 @@ extern void gic_route_irq_to_xen(struct irq_desc *desc, 
const cpumask_t *cpu_mas
  extern int gic_route_irq_to_guest(struct domain *, unsigned int virq,
                                    struct irq_desc *desc,
                                    unsigned int priority);
+extern int gic_route_lpi_to_guest(struct domain *d, unsigned int virq,
+                                   struct irq_desc *desc,
+                                   unsigned int priority);

  /* Remove an IRQ passthrough to a guest */
  int gic_remove_irq_from_guest(struct domain *d, unsigned int virq,
@@ -282,8 +285,10 @@ extern void send_SGI_allbutself(enum gic_sgi sgi);
  /* print useful debug info */
  extern void gic_dump_info(struct vcpu *v);

-/* Number of interrupt lines */
+/* Number of interrupt lines (SPIs)*/

This is not really true. The interrupts lines is equals to PPIs + SGIs + SPIs.

  extern unsigned int gic_number_lines(void);
+/* Check if irq is valid SPI or LPI */

This comment is not true. This function is used to check that an IRQ is valid in general, not only for SPI or LPI.

+bool_t gic_is_valid_irq(unsigned int irq);
  /* Number of interrupt id bits supported */
  extern unsigned int gic_nr_id_bits(void);
  /* LPI support info */

Regards,

--
Julien Grall

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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.