Re: [PATCH V2 3/5] kvm: arm64: Detect GIC version for proper ACPI vGIC probing

2015-06-10 Thread Marc Zyngier
On 10/06/15 05:16, Wei Huang wrote:
 There are two GICs (GICv2 and GICv3) supported by KVM. So it is necessary
 to find out GIC version before calling ACPI probing functions defined
 in vgic-v2.c and vgic-v3.c.
 
 This patch detects GIC version by checking gic_version field of GIC
 distributor, which was defined  since ACPI 6.0. In case of ACPI 5.1,
 we use manual hardware discovery to find out GIC version.
 
 NOTE: This patch is based on a recent patch by Hanjun Guo.

Well, this is really a duplicate of Hanjun's patch, and I'd rather have
some common infrastructure.

Surely it should be possible for the ACPI GIC code to export the
necessary entry points, or even to provide the required information?

Thanks,

M.

 
 Signed-off-by: Hanjun Guo hanjun@linaro.org
 Signed-off-by: Wei Huang w...@redhat.com
 ---
  include/kvm/arm_vgic.h |  18 +
  virt/kvm/arm/vgic-v2.c |  10 +
  virt/kvm/arm/vgic-v3.c |  10 +
  virt/kvm/arm/vgic.c| 100 
 -
  4 files changed, 137 insertions(+), 1 deletion(-)
 
 diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
 index 3ee732a..7a44b08 100644
 --- a/include/kvm/arm_vgic.h
 +++ b/include/kvm/arm_vgic.h
 @@ -24,6 +24,7 @@
  #include linux/irqreturn.h
  #include linux/spinlock.h
  #include linux/types.h
 +#include linux/acpi.h
  #include kvm/iodev.h
  
  #define VGIC_NR_IRQS_LEGACY  256
 @@ -335,10 +336,18 @@ int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
  int vgic_v2_dt_probe(struct device_node *vgic_node,
const struct vgic_ops **ops,
const struct vgic_params **params);
 +#ifdef CONFIG_ACPI
 +int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *,
 +const struct vgic_ops **ops,
 +const struct vgic_params **params);
 +#endif /* CONFIG_ACPI */
  #ifdef CONFIG_ARM_GIC_V3
  int vgic_v3_dt_probe(struct device_node *vgic_node,
const struct vgic_ops **ops,
const struct vgic_params **params);
 +int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *,
 +const struct vgic_ops **ops,
 +const struct vgic_params **params);
  #else
  static inline int vgic_v3_dt_probe(struct device_node *vgic_node,
  const struct vgic_ops **ops,
 @@ -346,6 +355,15 @@ static inline int vgic_v3_dt_probe(struct device_node 
 *vgic_node,
  {
   return -ENODEV;
  }
 +
 +#ifdef CONFIG_ACPI
 +int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *,
 +const struct vgic_ops **ops,
 +const struct vgic_params **params)
 +{
 + return -ENODEV;
 +}
 +#endif /* CONFIG_ACPI */
  #endif
  
  #endif
 diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
 index 295996f..711de82 100644
 --- a/virt/kvm/arm/vgic-v2.c
 +++ b/virt/kvm/arm/vgic-v2.c
 @@ -23,6 +23,7 @@
  #include linux/of.h
  #include linux/of_address.h
  #include linux/of_irq.h
 +#include linux/acpi.h
  
  #include linux/irqchip/arm-gic.h
  
 @@ -257,3 +258,12 @@ out:
   of_node_put(vgic_node);
   return ret;
  }
 +
 +#ifdef CONFIG_ACPI
 +int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
 +const struct vgic_ops **ops,
 +const struct vgic_params **params)
 +{
 + return -EINVAL;
 +}
 +#endif /* CONFIG_ACPI */
 diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
 index 91814e2..99d0f9f 100644
 --- a/virt/kvm/arm/vgic-v3.c
 +++ b/virt/kvm/arm/vgic-v3.c
 @@ -23,6 +23,7 @@
  #include linux/of.h
  #include linux/of_address.h
  #include linux/of_irq.h
 +#include linux/acpi.h
  
  #include linux/irqchip/arm-gic-v3.h
  
 @@ -285,3 +286,12 @@ out:
   of_node_put(vgic_node);
   return ret;
  }
 +
 +#ifdef CONFIG_ACPI
 +int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
 +const struct vgic_ops **ops,
 +const struct vgic_params **params)
 +{
 + return -EINVAL;
 +}
 +#endif /* CONFIG_ACPI */
 diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
 index b4010f0..cd09877 100644
 --- a/virt/kvm/arm/vgic.c
 +++ b/virt/kvm/arm/vgic.c
 @@ -28,6 +28,7 @@
  #include linux/acpi.h
  
  #include linux/irqchip/arm-gic.h
 +#include linux/irqchip/arm-gic-v3.h
  
  #include asm/kvm_emulate.h
  #include asm/kvm_arm.h
 @@ -2114,9 +2115,106 @@ static int kvm_vgic_dt_probe(void)
  }
  
  #ifdef CONFIG_ACPI
 +u8 gic_version = ACPI_MADT_GIC_VER_UNKNOWN;
 +phys_addr_t dist_phy_base;
 +static struct acpi_madt_generic_interrupt *vgic_acpi;
 +
 +static void gic_get_acpi_header(struct acpi_subtable_header *header)
 +{
 + vgic_acpi = (struct acpi_madt_generic_interrupt *)header;
 +}
 +
 +static int gic_parse_distributor(struct acpi_subtable_header *header,
 +  const unsigned long end)
 +{
 + struct acpi_madt_generic_distributor *dist;
 +
 + dist = (struct 

[PATCH V2 3/5] kvm: arm64: Detect GIC version for proper ACPI vGIC probing

2015-06-09 Thread Wei Huang
There are two GICs (GICv2 and GICv3) supported by KVM. So it is necessary
to find out GIC version before calling ACPI probing functions defined
in vgic-v2.c and vgic-v3.c.

This patch detects GIC version by checking gic_version field of GIC
distributor, which was defined  since ACPI 6.0. In case of ACPI 5.1,
we use manual hardware discovery to find out GIC version.

NOTE: This patch is based on a recent patch by Hanjun Guo.

Signed-off-by: Hanjun Guo hanjun@linaro.org
Signed-off-by: Wei Huang w...@redhat.com
---
 include/kvm/arm_vgic.h |  18 +
 virt/kvm/arm/vgic-v2.c |  10 +
 virt/kvm/arm/vgic-v3.c |  10 +
 virt/kvm/arm/vgic.c| 100 -
 4 files changed, 137 insertions(+), 1 deletion(-)

diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 3ee732a..7a44b08 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -24,6 +24,7 @@
 #include linux/irqreturn.h
 #include linux/spinlock.h
 #include linux/types.h
+#include linux/acpi.h
 #include kvm/iodev.h
 
 #define VGIC_NR_IRQS_LEGACY256
@@ -335,10 +336,18 @@ int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
 int vgic_v2_dt_probe(struct device_node *vgic_node,
 const struct vgic_ops **ops,
 const struct vgic_params **params);
+#ifdef CONFIG_ACPI
+int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params);
+#endif /* CONFIG_ACPI */
 #ifdef CONFIG_ARM_GIC_V3
 int vgic_v3_dt_probe(struct device_node *vgic_node,
 const struct vgic_ops **ops,
 const struct vgic_params **params);
+int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params);
 #else
 static inline int vgic_v3_dt_probe(struct device_node *vgic_node,
   const struct vgic_ops **ops,
@@ -346,6 +355,15 @@ static inline int vgic_v3_dt_probe(struct device_node 
*vgic_node,
 {
return -ENODEV;
 }
+
+#ifdef CONFIG_ACPI
+int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params)
+{
+   return -ENODEV;
+}
+#endif /* CONFIG_ACPI */
 #endif
 
 #endif
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index 295996f..711de82 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -23,6 +23,7 @@
 #include linux/of.h
 #include linux/of_address.h
 #include linux/of_irq.h
+#include linux/acpi.h
 
 #include linux/irqchip/arm-gic.h
 
@@ -257,3 +258,12 @@ out:
of_node_put(vgic_node);
return ret;
 }
+
+#ifdef CONFIG_ACPI
+int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params)
+{
+   return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index 91814e2..99d0f9f 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -23,6 +23,7 @@
 #include linux/of.h
 #include linux/of_address.h
 #include linux/of_irq.h
+#include linux/acpi.h
 
 #include linux/irqchip/arm-gic-v3.h
 
@@ -285,3 +286,12 @@ out:
of_node_put(vgic_node);
return ret;
 }
+
+#ifdef CONFIG_ACPI
+int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
+  const struct vgic_ops **ops,
+  const struct vgic_params **params)
+{
+   return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index b4010f0..cd09877 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -28,6 +28,7 @@
 #include linux/acpi.h
 
 #include linux/irqchip/arm-gic.h
+#include linux/irqchip/arm-gic-v3.h
 
 #include asm/kvm_emulate.h
 #include asm/kvm_arm.h
@@ -2114,9 +2115,106 @@ static int kvm_vgic_dt_probe(void)
 }
 
 #ifdef CONFIG_ACPI
+u8 gic_version = ACPI_MADT_GIC_VER_UNKNOWN;
+phys_addr_t dist_phy_base;
+static struct acpi_madt_generic_interrupt *vgic_acpi;
+
+static void gic_get_acpi_header(struct acpi_subtable_header *header)
+{
+   vgic_acpi = (struct acpi_madt_generic_interrupt *)header;
+}
+
+static int gic_parse_distributor(struct acpi_subtable_header *header,
+const unsigned long end)
+{
+   struct acpi_madt_generic_distributor *dist;
+
+   dist = (struct acpi_madt_generic_distributor *)header;
+
+   if (BAD_MADT_ENTRY(dist, end))
+   return -EINVAL;
+
+   gic_version = dist-gic_version;
+   dist_phy_base = dist-base_address;
+
+   return 0;
+}
+
+static int gic_match_redist(struct acpi_subtable_header *header,
+   const unsigned long end)
+{
+   return 0;
+}
+
+static bool