* [PATCH V1 0/5] Enable ACPI support for KVM ARM
@ 2015-05-28 5:34 Wei Huang
2015-05-28 5:34 ` [PATCH V1 1/5] kvm: arm64: Enable ACPI support for virt arch timer Wei Huang
` (4 more replies)
0 siblings, 5 replies; 9+ messages in thread
From: Wei Huang @ 2015-05-28 5:34 UTC (permalink / raw)
To: kvmarm, kvm, christoffer.dall, marc.zyngier, hanjun.guo,
a.spyridakis, wei
Initial ACPI support for ARM64 has been accepted into Linux kernel recently.
Now it is a good time to re-visit ACPI support for KVM. This patchset
enables ACPI for both arch_timer and vGIC by probing related ACPI tables
and does necessary initialization.
Note that Alexander Spyridaki submitted similar patches before. Some of
his ideas were borrowed in this patchset, but with substancial changes.
In addition we extend support for both GICv2 and GICv3.
This patchset would work better on top of recent GIC/IRQCHIP patches by
Hanjun Guo, who added support for gic_version in ACPI struct of GIC
distributor (search "ACPICA: Introduce GIC version for arm based system").
This patchset can be applied cleanly on top of Linx 4.1-rc1.
Wei Huang (5):
kvm: arm64: Enable ACPI support for virt arch timer
kvm: arm64: Dispatch virt GIC probing to device tree and ACPI
kvm: arm64: Detect GIC version for proper ACPI vGIC probing
kvm: arm64: Implement ACPI probing code for GICv2
kvm: arm64: Implement ACPI probing code for GICv3
include/kvm/arm_vgic.h | 36 +++++++++---
virt/kvm/arm/arch_timer.c | 64 ++++++++++++++++-----
virt/kvm/arm/vgic-v2.c | 65 +++++++++++++++++++--
virt/kvm/arm/vgic-v3.c | 56 +++++++++++++++++--
virt/kvm/arm/vgic.c | 140 ++++++++++++++++++++++++++++++++++++++++++----
5 files changed, 320 insertions(+), 41 deletions(-)
--
1.8.3.1
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH V1 1/5] kvm: arm64: Enable ACPI support for virt arch timer
2015-05-28 5:34 [PATCH V1 0/5] Enable ACPI support for KVM ARM Wei Huang
@ 2015-05-28 5:34 ` Wei Huang
2015-05-28 5:34 ` [PATCH V1 2/5] kvm: arm64: Dispatch virt GIC probing to device tree and ACPI Wei Huang
` (3 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Wei Huang @ 2015-05-28 5:34 UTC (permalink / raw)
To: kvmarm, kvm, christoffer.dall, marc.zyngier, hanjun.guo,
a.spyridakis, wei
This patches enables ACPI support for KVM virtual arch timer. It allows
KVM to parse ACPI table for arch timer PPI when DT table is not present.
Signed-off-by: Alexander Spyridaki <a.spyridakis@virtualopensystems.com>
Signed-off-by: Wei Huang <wei@redhat.com>
---
virt/kvm/arm/arch_timer.c | 64 +++++++++++++++++++++++++++++++++++++----------
1 file changed, 51 insertions(+), 13 deletions(-)
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c
index 98c95f2..7da9eb3 100644
--- a/virt/kvm/arm/arch_timer.c
+++ b/virt/kvm/arm/arch_timer.c
@@ -21,6 +21,7 @@
#include <linux/kvm.h>
#include <linux/kvm_host.h>
#include <linux/interrupt.h>
+#include <linux/acpi.h>
#include <clocksource/arm_arch_timer.h>
#include <asm/arch_timer.h>
@@ -274,9 +275,46 @@ static const struct of_device_id arch_timer_of_match[] = {
{},
};
-int kvm_timer_hyp_init(void)
+static int kvm_timer_ppi_dt_parse(unsigned int *ppi)
{
struct device_node *np;
+
+ np = of_find_matching_node(NULL, arch_timer_of_match);
+ if (!np)
+ return -ENODEV;
+
+ *ppi = irq_of_parse_and_map(np, 2);
+ if (*ppi == 0) {
+ of_node_put(np);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+#ifdef CONFIG_ACPI
+struct acpi_table_gtdt *gtdt_acpi;
+static void arch_timer_acpi_parse(struct acpi_table_header *table)
+{
+ gtdt_acpi = container_of(table, struct acpi_table_gtdt, header);
+}
+
+static int kvm_timer_ppi_acpi_parse(unsigned int *ppi)
+{
+ /* Get the interrupt number from the GTDT table */
+ acpi_table_parse(ACPI_SIG_GTDT,
+ (acpi_tbl_table_handler)arch_timer_acpi_parse);
+
+ if (!gtdt_acpi->virtual_timer_interrupt)
+ return -EINVAL;
+
+ *ppi = gtdt_acpi->virtual_timer_interrupt;
+ return 0;
+}
+#endif
+
+int kvm_timer_hyp_init(void)
+{
unsigned int ppi;
int err;
@@ -284,19 +322,20 @@ int kvm_timer_hyp_init(void)
if (!timecounter)
return -ENODEV;
- np = of_find_matching_node(NULL, arch_timer_of_match);
- if (!np) {
- kvm_err("kvm_arch_timer: can't find DT node\n");
- return -ENODEV;
- }
+ /* PPI parsing: try DT first, then ACPI */
+ err = kvm_timer_ppi_dt_parse(&ppi);
+#ifdef CONFIG_ACPI
+ if (err && !acpi_disabled)
+ err = kvm_timer_ppi_acpi_parse(&ppi);
+#endif
- ppi = irq_of_parse_and_map(np, 2);
- if (!ppi) {
- kvm_err("kvm_arch_timer: no virtual timer interrupt\n");
- err = -EINVAL;
- goto out;
+ if (err) {
+ kvm_err("kvm_arch_timer: can't find virtual timer info or "
+ "config virtual timer interrupt\n");
+ return err;
}
+ /* configure IRQ handler */
err = request_percpu_irq(ppi, kvm_arch_timer_handler,
"kvm guest timer", kvm_get_running_vcpus());
if (err) {
@@ -319,14 +358,13 @@ int kvm_timer_hyp_init(void)
goto out_free;
}
- kvm_info("%s IRQ%d\n", np->name, ppi);
+ kvm_info("timer IRQ%d\n", ppi);
on_each_cpu(kvm_timer_init_interrupt, NULL, 1);
goto out;
out_free:
free_percpu_irq(ppi, kvm_get_running_vcpus());
out:
- of_node_put(np);
return err;
}
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH V1 2/5] kvm: arm64: Dispatch virt GIC probing to device tree and ACPI
2015-05-28 5:34 [PATCH V1 0/5] Enable ACPI support for KVM ARM Wei Huang
2015-05-28 5:34 ` [PATCH V1 1/5] kvm: arm64: Enable ACPI support for virt arch timer Wei Huang
@ 2015-05-28 5:34 ` Wei Huang
2015-05-28 5:34 ` [PATCH V1 3/5] kvm: arm64: Detect GIC version for proper ACPI vGIC probing Wei Huang
` (2 subsequent siblings)
4 siblings, 0 replies; 9+ messages in thread
From: Wei Huang @ 2015-05-28 5:34 UTC (permalink / raw)
To: kvmarm, kvm, christoffer.dall, marc.zyngier, hanjun.guo,
a.spyridakis, wei
This patch creates a dispatch function to support virt GIC probing
in both device tree (DT) and ACPI environment. kvm_vgic_hyp_init()
will probe DT first. If failed, it will try ACPI.
Signed-off-by: Wei Huang <wei@redhat.com>
---
include/kvm/arm_vgic.h | 18 +++++++++---------
virt/kvm/arm/vgic-v2.c | 8 ++++----
virt/kvm/arm/vgic-v3.c | 8 ++++----
virt/kvm/arm/vgic.c | 42 +++++++++++++++++++++++++++++++-----------
4 files changed, 48 insertions(+), 28 deletions(-)
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 133ea00..3ee732a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -332,17 +332,17 @@ int kvm_vgic_vcpu_active_irq(struct kvm_vcpu *vcpu);
#define vgic_initialized(k) (!!((k)->arch.vgic.nr_cpus))
#define vgic_ready(k) ((k)->arch.vgic.ready)
-int vgic_v2_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params);
+int vgic_v2_dt_probe(struct device_node *vgic_node,
+ const struct vgic_ops **ops,
+ const struct vgic_params **params);
#ifdef CONFIG_ARM_GIC_V3
-int vgic_v3_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params);
+int vgic_v3_dt_probe(struct device_node *vgic_node,
+ const struct vgic_ops **ops,
+ const struct vgic_params **params);
#else
-static inline int vgic_v3_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params)
+static inline int vgic_v3_dt_probe(struct device_node *vgic_node,
+ const struct vgic_ops **ops,
+ const struct vgic_params **params)
{
return -ENODEV;
}
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index f9b9c7c..295996f 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -167,7 +167,7 @@ static const struct vgic_ops vgic_v2_ops = {
static struct vgic_params vgic_v2_params;
/**
- * vgic_v2_probe - probe for a GICv2 compatible interrupt controller in DT
+ * vgic_v2_dt_probe - probe for a GICv2 compatible interrupt controller in DT
* @node: pointer to the DT node
* @ops: address of a pointer to the GICv2 operations
* @params: address of a pointer to HW-specific parameters
@@ -176,9 +176,9 @@ static struct vgic_params vgic_v2_params;
* in *ops and the HW parameters in *params. Returns an error code
* otherwise.
*/
-int vgic_v2_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params)
+int vgic_v2_dt_probe(struct device_node *vgic_node,
+ const struct vgic_ops **ops,
+ const struct vgic_params **params)
{
int ret;
struct resource vctrl_res;
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index dff0602..91814e2 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -211,7 +211,7 @@ static const struct vgic_ops vgic_v3_ops = {
static struct vgic_params vgic_v3_params;
/**
- * vgic_v3_probe - probe for a GICv3 compatible interrupt controller in DT
+ * vgic_v3_dt_probe - probe for a GICv3 compatible interrupt controller in DT
* @node: pointer to the DT node
* @ops: address of a pointer to the GICv3 operations
* @params: address of a pointer to HW-specific parameters
@@ -220,9 +220,9 @@ static struct vgic_params vgic_v3_params;
* in *ops and the HW parameters in *params. Returns an error code
* otherwise.
*/
-int vgic_v3_probe(struct device_node *vgic_node,
- const struct vgic_ops **ops,
- const struct vgic_params **params)
+int vgic_v3_dt_probe(struct device_node *vgic_node,
+ const struct vgic_ops **ops,
+ const struct vgic_params **params)
{
int ret = 0;
u32 gicv_idx;
diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c
index 78fb820..b4010f0 100644
--- a/virt/kvm/arm/vgic.c
+++ b/virt/kvm/arm/vgic.c
@@ -25,6 +25,7 @@
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/uaccess.h>
+#include <linux/acpi.h>
#include <linux/irqchip/arm-gic.h>
@@ -2088,32 +2089,51 @@ static struct notifier_block vgic_cpu_nb = {
};
static const struct of_device_id vgic_ids[] = {
- { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, },
- { .compatible = "arm,cortex-a7-gic", .data = vgic_v2_probe, },
- { .compatible = "arm,gic-400", .data = vgic_v2_probe, },
- { .compatible = "arm,gic-v3", .data = vgic_v3_probe, },
+ { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_dt_probe, },
+ { .compatible = "arm,cortex-a7-gic", .data = vgic_v2_dt_probe, },
+ { .compatible = "arm,gic-400", .data = vgic_v2_dt_probe, },
+ { .compatible = "arm,gic-v3", .data = vgic_v3_dt_probe, },
{},
};
-int kvm_vgic_hyp_init(void)
+static int kvm_vgic_dt_probe(void)
{
const struct of_device_id *matched_id;
const int (*vgic_probe)(struct device_node *,const struct vgic_ops **,
const struct vgic_params **);
struct device_node *vgic_node;
- int ret;
vgic_node = of_find_matching_node_and_match(NULL,
vgic_ids, &matched_id);
- if (!vgic_node) {
- kvm_err("error: no compatible GIC node found\n");
+ if (!vgic_node)
return -ENODEV;
- }
vgic_probe = matched_id->data;
- ret = vgic_probe(vgic_node, &vgic_ops, &vgic);
- if (ret)
+
+ return vgic_probe(vgic_node, &vgic_ops, &vgic);
+}
+
+#ifdef CONFIG_ACPI
+static int kvm_vgic_acpi_probe(void)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_ACPI */
+
+int kvm_vgic_hyp_init(void)
+{
+ int ret;
+
+ ret = kvm_vgic_dt_probe();
+#ifdef CONFIG_ACPI
+ if (ret && !acpi_disabled)
+ ret = kvm_vgic_acpi_probe();
+#endif
+
+ if (ret) {
+ kvm_err("error: KVM vGIC probing failed\n");
return ret;
+ }
ret = request_percpu_irq(vgic->maint_irq, vgic_maintenance_handler,
"vgic", kvm_get_running_vcpus());
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH V1 3/5] kvm: arm64: Detect GIC version for proper ACPI vGIC probing
2015-05-28 5:34 [PATCH V1 0/5] Enable ACPI support for KVM ARM Wei Huang
2015-05-28 5:34 ` [PATCH V1 1/5] kvm: arm64: Enable ACPI support for virt arch timer Wei Huang
2015-05-28 5:34 ` [PATCH V1 2/5] kvm: arm64: Dispatch virt GIC probing to device tree and ACPI Wei Huang
@ 2015-05-28 5:34 ` Wei Huang
2015-05-28 5:34 ` [PATCH V1 4/5] kvm: arm64: Implement ACPI probing code for GICv2 Wei Huang
2015-05-28 5:34 ` [PATCH V1 5/5] kvm: arm64: Implement ACPI probing code for GICv3 Wei Huang
4 siblings, 0 replies; 9+ messages in thread
From: Wei Huang @ 2015-05-28 5:34 UTC (permalink / raw)
To: kvmarm, kvm, christoffer.dall, marc.zyngier, hanjun.guo,
a.spyridakis, wei
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.guo@linaro.org>
Signed-off-by: Wei Huang <wei@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 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 gic_redist_is_present(void)
+{
+ int count;
+
+ /* scan MADT table to find if we have redistributor entries */
+ count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_REDISTRIBUTOR,
+ gic_match_redist, 0);
+
+ return (count > 0) ? true : false;
+}
+
static int kvm_vgic_acpi_probe(void)
{
- return -EINVAL;
+ u32 reg;
+ int count;
+ void __iomem *dist_base;
+ int ret;
+
+ /* MADT table */
+ ret = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
+ (acpi_tbl_entry_handler)gic_get_acpi_header, 0);
+ if (!ret) {
+ pr_err("Failed to get MADT VGIC CPU entry\n");
+ return -ENODEV;
+ }
+
+ /* detect GIC version */
+ count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_DISTRIBUTOR,
+ gic_parse_distributor, 0);
+ if (count <= 0) {
+ pr_err("No valid GIC distributor entry exists\n");
+ return -ENODEV;
+ }
+ if (gic_version >= ACPI_MADT_GIC_VER_RESERVED) {
+ pr_err("Invalid GIC version %d in MADT\n", gic_version);
+ return -EINVAL;
+ }
+
+ /* falls back to manual hardware discovery under ACPI 5.1 */
+ if (gic_version == ACPI_MADT_GIC_VER_UNKNOWN) {
+ if (gic_redist_is_present()) {
+ dist_base = ioremap(dist_phy_base, SZ_64K);
+ if (!dist_base)
+ return -ENOMEM;
+
+ reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK;
+ if (reg == GIC_PIDR2_ARCH_GICv3)
+ gic_version = ACPI_MADT_GIC_VER_V3;
+ else
+ gic_version = ACPI_MADT_GIC_VER_V4;
+
+ iounmap(dist_base);
+ } else {
+ gic_version = ACPI_MADT_GIC_VER_V2;
+ }
+ }
+
+ switch (gic_version) {
+ case ACPI_MADT_GIC_VER_V2:
+ ret = vgic_v2_acpi_probe(vgic_acpi, &vgic_ops, &vgic);
+ break;
+ case ACPI_MADT_GIC_VER_V3:
+ ret = vgic_v3_acpi_probe(vgic_acpi, &vgic_ops, &vgic);
+ break;
+ default:
+ ret = -ENODEV;
+ }
+
+ return ret;
}
#endif /* CONFIG_ACPI */
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH V1 4/5] kvm: arm64: Implement ACPI probing code for GICv2
2015-05-28 5:34 [PATCH V1 0/5] Enable ACPI support for KVM ARM Wei Huang
` (2 preceding siblings ...)
2015-05-28 5:34 ` [PATCH V1 3/5] kvm: arm64: Detect GIC version for proper ACPI vGIC probing Wei Huang
@ 2015-05-28 5:34 ` Wei Huang
2015-05-29 14:06 ` Andrew Jones
2015-05-28 5:34 ` [PATCH V1 5/5] kvm: arm64: Implement ACPI probing code for GICv3 Wei Huang
4 siblings, 1 reply; 9+ messages in thread
From: Wei Huang @ 2015-05-28 5:34 UTC (permalink / raw)
To: kvmarm, kvm, christoffer.dall, marc.zyngier, hanjun.guo,
a.spyridakis, wei
This patches enables ACPI support for KVM virtual GICv2. KVM parses
ACPI table for virt GIC related information and initializes resources.
Signed-off-by: Alexander Spyridaki <a.spyridakis@virtualopensystems.com>
Signed-off-by: Wei Huang <wei@redhat.com>
---
virt/kvm/arm/vgic-v2.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
index 711de82..01ce8a3 100644
--- a/virt/kvm/arm/vgic-v2.c
+++ b/virt/kvm/arm/vgic-v2.c
@@ -264,6 +264,53 @@ int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
const struct vgic_ops **ops,
const struct vgic_params **params)
{
- return -EINVAL;
+ struct vgic_params *vgic = &vgic_v2_params;
+ int irq_mode, ret;
+
+ /* IRQ trigger mode */
+ irq_mode = (vgic_acpi->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
+ ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+ vgic->maint_irq = acpi_register_gsi(NULL, vgic_acpi->vgic_interrupt,
+ irq_mode, ACPI_ACTIVE_HIGH);
+ if (!vgic->maint_irq) {
+ kvm_err("Cannot register VGIC ACPI maintenance irq\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ /* GICH resource */
+ vgic->vctrl_base = ioremap(vgic_acpi->gich_base_address, SZ_8K);
+ if (!vgic->vctrl_base) {
+ kvm_err("cannot ioremap GICH memory\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ vgic->nr_lr = readl_relaxed(vgic->vctrl_base + GICH_VTR);
+ vgic->nr_lr = (vgic->nr_lr & 0x3f) + 1;
+
+ ret = create_hyp_io_mappings(vgic->vctrl_base,
+ vgic->vctrl_base + SZ_8K,
+ vgic_acpi->gich_base_address);
+ if (ret) {
+ kvm_err("Cannot map GICH into hyp\n");
+ goto out;
+ }
+
+ vgic->vcpu_base = vgic_acpi->gicv_base_address;
+ vgic->can_emulate_gicv2 = true;
+ kvm_register_device_ops(&kvm_arm_vgic_v2_ops, KVM_DEV_TYPE_ARM_VGIC_V2);
+
+ kvm_info("GICH base=0x%llx, GICV base=0x%llx, IRQ=%d\n",
+ (unsigned long long)vgic_acpi->gich_base_address,
+ (unsigned long long)vgic_acpi->gicv_base_address,
+ vgic->maint_irq);
+
+ vgic->type = VGIC_V2;
+ *ops = &vgic_v2_ops;
+ *params = vgic;
+
+out:
+ return ret;
}
#endif /* CONFIG_ACPI */
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH V1 5/5] kvm: arm64: Implement ACPI probing code for GICv3
2015-05-28 5:34 [PATCH V1 0/5] Enable ACPI support for KVM ARM Wei Huang
` (3 preceding siblings ...)
2015-05-28 5:34 ` [PATCH V1 4/5] kvm: arm64: Implement ACPI probing code for GICv2 Wei Huang
@ 2015-05-28 5:34 ` Wei Huang
4 siblings, 0 replies; 9+ messages in thread
From: Wei Huang @ 2015-05-28 5:34 UTC (permalink / raw)
To: kvmarm, kvm, christoffer.dall, marc.zyngier, hanjun.guo,
a.spyridakis, wei
This patches enables ACPI support for KVM virtual GICv3. KVM parses
ACPI table for virt GIC related information and initializes resources.
Signed-off-by: Wei Huang <wei@redhat.com>
---
virt/kvm/arm/vgic-v3.c | 40 +++++++++++++++++++++++++++++++++++++++-
1 file changed, 39 insertions(+), 1 deletion(-)
diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c
index 99d0f9f..2e4df78 100644
--- a/virt/kvm/arm/vgic-v3.c
+++ b/virt/kvm/arm/vgic-v3.c
@@ -292,6 +292,44 @@ int vgic_v3_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
const struct vgic_ops **ops,
const struct vgic_params **params)
{
- return -EINVAL;
+ int ret = 0;
+ struct vgic_params *vgic = &vgic_v3_params;
+ int irq_mode;
+
+ /* IRQ trigger mode */
+ irq_mode = (vgic_acpi->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
+ ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
+ vgic->maint_irq = acpi_register_gsi(NULL, vgic_acpi->vgic_interrupt,
+ irq_mode, ACPI_ACTIVE_HIGH);
+ if (!vgic->maint_irq) {
+ kvm_err("Cannot register VGIC ACPI maintenance irq\n");
+ ret = -ENXIO;
+ goto out;
+ }
+
+ ich_vtr_el2 = kvm_call_hyp(__vgic_v3_get_ich_vtr_el2);
+ vgic->nr_lr = (ich_vtr_el2 & 0xf) + 1;
+ vgic->can_emulate_gicv2 = false;
+
+ vgic->vcpu_base = vgic_acpi->gicv_base_address;
+
+ if (vgic->vcpu_base == 0)
+ kvm_info("disabling GICv2 emulation\n");
+ else {
+ vgic->can_emulate_gicv2 = true;
+ kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
+ KVM_DEV_TYPE_ARM_VGIC_V2);
+ }
+
+ kvm_register_device_ops(&kvm_arm_vgic_v3_ops, KVM_DEV_TYPE_ARM_VGIC_V3);
+
+ vgic->vctrl_base = NULL;
+ vgic->type = VGIC_V3;
+ vgic->max_gic_vcpus = KVM_MAX_VCPUS;
+
+ *ops = &vgic_v3_ops;
+ *params = vgic;
+out:
+ return ret;
}
#endif /* CONFIG_ACPI */
--
1.8.3.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH V1 4/5] kvm: arm64: Implement ACPI probing code for GICv2
2015-05-28 5:34 ` [PATCH V1 4/5] kvm: arm64: Implement ACPI probing code for GICv2 Wei Huang
@ 2015-05-29 14:06 ` Andrew Jones
2015-05-29 14:34 ` Wei Huang
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Jones @ 2015-05-29 14:06 UTC (permalink / raw)
To: Wei Huang
Cc: kvmarm, kvm, christoffer.dall, marc.zyngier, hanjun.guo,
a.spyridakis
On Thu, May 28, 2015 at 01:34:33AM -0400, Wei Huang wrote:
> This patches enables ACPI support for KVM virtual GICv2. KVM parses
> ACPI table for virt GIC related information and initializes resources.
>
> Signed-off-by: Alexander Spyridaki <a.spyridakis@virtualopensystems.com>
> Signed-off-by: Wei Huang <wei@redhat.com>
> ---
> virt/kvm/arm/vgic-v2.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
> 1 file changed, 48 insertions(+), 1 deletion(-)
>
> diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
> index 711de82..01ce8a3 100644
> --- a/virt/kvm/arm/vgic-v2.c
> +++ b/virt/kvm/arm/vgic-v2.c
> @@ -264,6 +264,53 @@ int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
> const struct vgic_ops **ops,
> const struct vgic_params **params)
> {
> - return -EINVAL;
> + struct vgic_params *vgic = &vgic_v2_params;
> + int irq_mode, ret;
> +
> + /* IRQ trigger mode */
> + irq_mode = (vgic_acpi->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
> + ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
> + vgic->maint_irq = acpi_register_gsi(NULL, vgic_acpi->vgic_interrupt,
> + irq_mode, ACPI_ACTIVE_HIGH);
> + if (!vgic->maint_irq) {
> + kvm_err("Cannot register VGIC ACPI maintenance irq\n");
> + ret = -ENXIO;
> + goto out;
> + }
> +
> + /* GICH resource */
> + vgic->vctrl_base = ioremap(vgic_acpi->gich_base_address, SZ_8K);
> + if (!vgic->vctrl_base) {
> + kvm_err("cannot ioremap GICH memory\n");
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + vgic->nr_lr = readl_relaxed(vgic->vctrl_base + GICH_VTR);
> + vgic->nr_lr = (vgic->nr_lr & 0x3f) + 1;
> +
> + ret = create_hyp_io_mappings(vgic->vctrl_base,
> + vgic->vctrl_base + SZ_8K,
> + vgic_acpi->gich_base_address);
> + if (ret) {
> + kvm_err("Cannot map GICH into hyp\n");
> + goto out;
> + }
> +
> + vgic->vcpu_base = vgic_acpi->gicv_base_address;
> + vgic->can_emulate_gicv2 = true;
> + kvm_register_device_ops(&kvm_arm_vgic_v2_ops, KVM_DEV_TYPE_ARM_VGIC_V2);
> +
> + kvm_info("GICH base=0x%llx, GICV base=0x%llx, IRQ=%d\n",
> + (unsigned long long)vgic_acpi->gich_base_address,
> + (unsigned long long)vgic_acpi->gicv_base_address,
> + vgic->maint_irq);
> +
> + vgic->type = VGIC_V2;
we're missing max_gic_vcpus here
vgic->max_gic_vcpus = VGIC_V2_MAX_CPUS;
> + *ops = &vgic_v2_ops;
> + *params = vgic;
> +
> +out:
> + return ret;
> }
> #endif /* CONFIG_ACPI */
> --
> 1.8.3.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH V1 4/5] kvm: arm64: Implement ACPI probing code for GICv2
2015-05-29 14:06 ` Andrew Jones
@ 2015-05-29 14:34 ` Wei Huang
0 siblings, 0 replies; 9+ messages in thread
From: Wei Huang @ 2015-05-29 14:34 UTC (permalink / raw)
To: Andrew Jones
Cc: kvmarm, kvm, christoffer.dall, marc.zyngier, hanjun.guo,
a.spyridakis
On 05/29/2015 09:06 AM, Andrew Jones wrote:
> On Thu, May 28, 2015 at 01:34:33AM -0400, Wei Huang wrote:
>> This patches enables ACPI support for KVM virtual GICv2. KVM parses
>> ACPI table for virt GIC related information and initializes resources.
>>
>> Signed-off-by: Alexander Spyridaki <a.spyridakis@virtualopensystems.com>
>> Signed-off-by: Wei Huang <wei@redhat.com>
>> ---
>> virt/kvm/arm/vgic-v2.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
>> 1 file changed, 48 insertions(+), 1 deletion(-)
>>
>> diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c
>> index 711de82..01ce8a3 100644
>> --- a/virt/kvm/arm/vgic-v2.c
>> +++ b/virt/kvm/arm/vgic-v2.c
>> @@ -264,6 +264,53 @@ int vgic_v2_acpi_probe(struct acpi_madt_generic_interrupt *vgic_acpi,
>> const struct vgic_ops **ops,
>> const struct vgic_params **params)
>> {
>> - return -EINVAL;
>> + struct vgic_params *vgic = &vgic_v2_params;
>> + int irq_mode, ret;
>> +
>> + /* IRQ trigger mode */
>> + irq_mode = (vgic_acpi->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
>> + ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
>> + vgic->maint_irq = acpi_register_gsi(NULL, vgic_acpi->vgic_interrupt,
>> + irq_mode, ACPI_ACTIVE_HIGH);
>> + if (!vgic->maint_irq) {
>> + kvm_err("Cannot register VGIC ACPI maintenance irq\n");
>> + ret = -ENXIO;
>> + goto out;
>> + }
>> +
>> + /* GICH resource */
>> + vgic->vctrl_base = ioremap(vgic_acpi->gich_base_address, SZ_8K);
>> + if (!vgic->vctrl_base) {
>> + kvm_err("cannot ioremap GICH memory\n");
>> + ret = -ENOMEM;
>> + goto out;
>> + }
>> +
>> + vgic->nr_lr = readl_relaxed(vgic->vctrl_base + GICH_VTR);
>> + vgic->nr_lr = (vgic->nr_lr & 0x3f) + 1;
>> +
>> + ret = create_hyp_io_mappings(vgic->vctrl_base,
>> + vgic->vctrl_base + SZ_8K,
>> + vgic_acpi->gich_base_address);
>> + if (ret) {
>> + kvm_err("Cannot map GICH into hyp\n");
>> + goto out;
>> + }
>> +
>> + vgic->vcpu_base = vgic_acpi->gicv_base_address;
>> + vgic->can_emulate_gicv2 = true;
>> + kvm_register_device_ops(&kvm_arm_vgic_v2_ops, KVM_DEV_TYPE_ARM_VGIC_V2);
>> +
>> + kvm_info("GICH base=0x%llx, GICV base=0x%llx, IRQ=%d\n",
>> + (unsigned long long)vgic_acpi->gich_base_address,
>> + (unsigned long long)vgic_acpi->gicv_base_address,
>> + vgic->maint_irq);
>> +
>> + vgic->type = VGIC_V2;
>
> we're missing max_gic_vcpus here
>
> vgic->max_gic_vcpus = VGIC_V2_MAX_CPUS;
Yes. Will fix in the next spin.
-Wei
>
>> + *ops = &vgic_v2_ops;
>> + *params = vgic;
>> +
>> +out:
>> + return ret;
>> }
>> #endif /* CONFIG_ACPI */
>> --
>> 1.8.3.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe kvm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH V1 0/5] Enable ACPI support for KVM ARM
[not found] <1432790628-15085-1-git-send-email-wei@redhat.com>
@ 2015-06-05 5:32 ` Wei Huang
0 siblings, 0 replies; 9+ messages in thread
From: Wei Huang @ 2015-06-05 5:32 UTC (permalink / raw)
To: kvmarm@lists.cs.columbia.edu
Cc: KVM, Marc Zyngier, christoffer.dall, Andrew Jones
Hi Christoffer and Marc,
Ping. Any comments on this patchset for V2?
Thanks,
-Wei
On 5/28/15 00:23, Wei Huang wrote:
> Initial ACPI support for ARM64 has been accepted into Linux kernel recently.
> Now it is a good time to re-visit ACPI support for KVM. This patchset
> enables ACPI for both arch_timer and vGIC by probing related ACPI tables
> and does necessary initialization.
>
> Note that Alexander Spyridaki submitted similar patches before. Some of
> his ideas were borrowed in this patchset, but with substancial changes.
> In addition we extend support for both GICv2 and GICv3.
>
> This patchset would work better on top of recent GIC/IRQCHIP patches by
> Hanjun Guo, who added support for gic_version in ACPI struct of GIC
> distributor (search "ACPICA: Introduce GIC version for arm based system").
>
> This patchset can be applied cleanly on top of Linx 4.1-rc1.
>
> Wei Huang (5):
> kvm: arm64: Enable ACPI support for virt arch timer
> kvm: arm64: Dispatch virt GIC probing to device tree and ACPI
> kvm: arm64: Detect GIC version for proper ACPI vGIC probing
> kvm: arm64: Implement ACPI probing code for GICv2
> kvm: arm64: Implement ACPI probing code for GICv3
>
> include/kvm/arm_vgic.h | 36 +++++++++---
> virt/kvm/arm/arch_timer.c | 64 ++++++++++++++++-----
> virt/kvm/arm/vgic-v2.c | 65 +++++++++++++++++++--
> virt/kvm/arm/vgic-v3.c | 56 +++++++++++++++++--
> virt/kvm/arm/vgic.c | 140 ++++++++++++++++++++++++++++++++++++++++++----
> 5 files changed, 320 insertions(+), 41 deletions(-)
>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2015-06-05 5:32 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-05-28 5:34 [PATCH V1 0/5] Enable ACPI support for KVM ARM Wei Huang
2015-05-28 5:34 ` [PATCH V1 1/5] kvm: arm64: Enable ACPI support for virt arch timer Wei Huang
2015-05-28 5:34 ` [PATCH V1 2/5] kvm: arm64: Dispatch virt GIC probing to device tree and ACPI Wei Huang
2015-05-28 5:34 ` [PATCH V1 3/5] kvm: arm64: Detect GIC version for proper ACPI vGIC probing Wei Huang
2015-05-28 5:34 ` [PATCH V1 4/5] kvm: arm64: Implement ACPI probing code for GICv2 Wei Huang
2015-05-29 14:06 ` Andrew Jones
2015-05-29 14:34 ` Wei Huang
2015-05-28 5:34 ` [PATCH V1 5/5] kvm: arm64: Implement ACPI probing code for GICv3 Wei Huang
[not found] <1432790628-15085-1-git-send-email-wei@redhat.com>
2015-06-05 5:32 ` [PATCH V1 0/5] Enable ACPI support for KVM ARM Wei Huang
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).