All of lore.kernel.org
 help / color / mirror / Atom feed
From: Christoffer Dall <christoffer.dall@linaro.org>
To: Julien Grall <julien.grall@arm.com>
Cc: kvmarm@lists.cs.columbia.edu, marc.zyngier@arm.com,
	fu.wei@linaro.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, wei@redhat.com,
	al.stone@linaro.org, gg@slimlogic.co.uk,
	Thomas Gleixner <tglx@linutronix.de>,
	Jason Cooper <jason@lakedaemon.net>
Subject: Re: [PATCH v5 6/9] irqchip/gic-v3: Parse and export virtual GIC information
Date: Wed, 6 Apr 2016 19:22:28 +0200	[thread overview]
Message-ID: <20160406172228.GE8961@cbox> (raw)
In-Reply-To: <1459769860-6629-7-git-send-email-julien.grall@arm.com>

On Mon, Apr 04, 2016 at 12:37:37PM +0100, Julien Grall wrote:
> Fill up the recently introduced gic_kvm_info with the hardware
> information used for virtualization.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> 
> ---
>     Changes in v5:
>         - Remove the alignment check for GICV. It's already done in the
>         KVM code.
>         - Fix initialization of KVM with ACPI.
> 
>     Changes in v4:
>         - Change the flow to call gic_kvm_set_info only when all the
>         mandatory information are valid.
>         - Remove unecessary code in ACPI parsing (the virtual control
>         interface doesn't exist for GICv3).
>         - Rework commit message
>         - Rework the ACPI support as it didn't collect hardware info for
>         virtualization when there is more than 1 redistributor region
> 
>     Changes in v3:
>         - Add ACPI support
> 
>     Changes in v2:
>         - Use 0 rather than a negative value to know when the maintenance IRQ
>         is not present.
>         - Use resource for vcpu and vctrl
> ---
>  drivers/irqchip/irq-gic-v3.c           | 110 ++++++++++++++++++++++++++++++++-
>  include/linux/irqchip/arm-gic-common.h |   1 +
>  2 files changed, 110 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 50e87e6..08afbfe 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -28,6 +28,7 @@
>  #include <linux/slab.h>
>  
>  #include <linux/irqchip.h>
> +#include <linux/irqchip/arm-gic-common.h>
>  #include <linux/irqchip/arm-gic-v3.h>
>  
>  #include <asm/cputype.h>
> @@ -56,6 +57,8 @@ struct gic_chip_data {
>  static struct gic_chip_data gic_data __read_mostly;
>  static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
>  
> +static struct gic_kvm_info gic_v3_kvm_info;
> +
>  #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
>  #define gic_data_rdist_sgi_base()	(gic_data_rdist_rd_base() + SZ_64K)
> @@ -901,6 +904,30 @@ static int __init gic_validate_dist_version(void __iomem *dist_base)
>  	return 0;
>  }
>  
> +static void __init gic_of_setup_kvm_info(struct device_node *node)
> +{
> +	int ret;
> +	struct resource r;
> +	u32 gicv_idx;
> +
> +	gic_v3_kvm_info.type = GIC_V3;
> +
> +	gic_v3_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);
> +	if (!gic_v3_kvm_info.maint_irq)
> +		return;
> +
> +	if (of_property_read_u32(node, "#redistributor-regions",
> +				 &gicv_idx))
> +		gicv_idx = 1;
> +
> +	gicv_idx += 3;	/* Also skip GICD, GICC, GICH */
> +	ret = of_address_to_resource(node, gicv_idx, &r);
> +	if (!ret)
> +		gic_v3_kvm_info.vcpu = r;
> +
> +	gic_set_kvm_info(&gic_v3_kvm_info);
> +}
> +
>  static int __init gic_of_init(struct device_node *node, struct device_node *parent)
>  {
>  	void __iomem *dist_base;
> @@ -952,8 +979,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>  
>  	err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
>  			     redist_stride, &node->fwnode);
> -	if (!err)
> +	if (!err) {
> +		gic_of_setup_kvm_info(node);
>  		return 0;
> +	}
>  
>  out_unmap_rdist:
>  	for (i = 0; i < nr_redist_regions; i++)
> @@ -974,6 +1003,9 @@ static struct
>  	struct redist_region *redist_regs;
>  	u32 nr_redist_regions;
>  	bool single_redist;
> +	u32 maint_irq;
> +	int maint_irq_mode;
> +	phys_addr_t vcpu_base;
>  } acpi_data __initdata;
>  
>  static void __init
> @@ -1110,7 +1142,81 @@ static bool __init acpi_validate_gic_table(struct acpi_subtable_header *header,
>  	return true;
>  }
>  
> +static int __init gic_acpi_parse_virt_madt_gicc(struct acpi_subtable_header *header,
> +						const unsigned long end)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +		(struct acpi_madt_generic_interrupt *)header;
> +	int maint_irq_mode;
> +	static int first_madt = true;
> +
> +	maint_irq_mode = (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
> +		ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
> +
> +	if (first_madt) {
> +		first_madt = false;
> +
> +		acpi_data.maint_irq = gicc->vgic_interrupt;
> +		acpi_data.maint_irq_mode = maint_irq_mode;
> +		acpi_data.vcpu_base = gicc->gicv_base_address;
> +
> +		return 0;
> +	}
> +
> +	/*
> +	 * The maintenance interrupt and GICV should be the same for every CPU
> +	 */
> +	if ((acpi_data.maint_irq != gicc->vgic_interrupt) ||
> +	    (acpi_data.maint_irq_mode != maint_irq_mode) ||
> +	    (acpi_data.vcpu_base != gicc->gicv_base_address))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static bool __init gic_acpi_collect_virt_info(void)
> +{
> +	int count;
> +
> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
> +				      gic_acpi_parse_virt_madt_gicc, 0);
> +
> +	return (count > 0);
> +}
> +
>  #define ACPI_GICV3_DIST_MEM_SIZE (SZ_64K)
> +#define ACPI_GICV2_VCTRL_MEM_SIZE	(SZ_4K)
> +#define ACPI_GICV2_VCPU_MEM_SIZE	(SZ_8K)
> +
> +static void __init gic_acpi_setup_kvm_info(void)
> +{
> +	int irq;
> +
> +	if (!gic_acpi_collect_virt_info()) {
> +		pr_warn("Unable to get hardware information used for virtualization\n");

perhaps this should say something about gicv3 as well?

> +		return;
> +	}
> +
> +	gic_v3_kvm_info.type = GIC_V3;
> +
> +	irq = acpi_register_gsi(NULL, acpi_data.maint_irq,
> +				acpi_data.maint_irq_mode,
> +				ACPI_ACTIVE_HIGH);
> +	if (irq <= 0)
> +		return;
> +
> +	gic_v3_kvm_info.maint_irq = irq;
> +
> +	if (acpi_data.vcpu_base) {
> +		struct resource *vcpu = &gic_v3_kvm_info.vcpu;
> +
> +		vcpu->flags = IORESOURCE_MEM;
> +		vcpu->start = acpi_data.vcpu_base;
> +		vcpu->end = vcpu->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
> +	}
> +
> +	gic_set_kvm_info(&gic_v3_kvm_info);
> +}
>  
>  static int __init
>  gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
> @@ -1159,6 +1265,8 @@ gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
>  		goto out_fwhandle_free;
>  
>  	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
> +	gic_acpi_setup_kvm_info();
> +
>  	return 0;
>  
>  out_fwhandle_free:
> diff --git a/include/linux/irqchip/arm-gic-common.h b/include/linux/irqchip/arm-gic-common.h
> index ef34f6f..c647b05 100644
> --- a/include/linux/irqchip/arm-gic-common.h
> +++ b/include/linux/irqchip/arm-gic-common.h
> @@ -15,6 +15,7 @@
>  
>  enum gic_type {
>  	GIC_V2,
> +	GIC_V3,
>  };
>  
>  struct gic_kvm_info {
> -- 
> 1.9.1
> 

Otherwise (with my extremely limited acpi understanding):

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

WARNING: multiple messages have this Message-ID (diff)
From: Christoffer Dall <christoffer.dall@linaro.org>
To: Julien Grall <julien.grall@arm.com>
Cc: al.stone@linaro.org, kvm@vger.kernel.org, marc.zyngier@arm.com,
	Jason Cooper <jason@lakedaemon.net>,
	linux-kernel@vger.kernel.org, fu.wei@linaro.org,
	Thomas Gleixner <tglx@linutronix.de>,
	kvmarm@lists.cs.columbia.edu,
	linux-arm-kernel@lists.infradead.org, gg@slimlogic.co.uk
Subject: Re: [PATCH v5 6/9] irqchip/gic-v3: Parse and export virtual GIC information
Date: Wed, 6 Apr 2016 19:22:28 +0200	[thread overview]
Message-ID: <20160406172228.GE8961@cbox> (raw)
In-Reply-To: <1459769860-6629-7-git-send-email-julien.grall@arm.com>

On Mon, Apr 04, 2016 at 12:37:37PM +0100, Julien Grall wrote:
> Fill up the recently introduced gic_kvm_info with the hardware
> information used for virtualization.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> 
> ---
>     Changes in v5:
>         - Remove the alignment check for GICV. It's already done in the
>         KVM code.
>         - Fix initialization of KVM with ACPI.
> 
>     Changes in v4:
>         - Change the flow to call gic_kvm_set_info only when all the
>         mandatory information are valid.
>         - Remove unecessary code in ACPI parsing (the virtual control
>         interface doesn't exist for GICv3).
>         - Rework commit message
>         - Rework the ACPI support as it didn't collect hardware info for
>         virtualization when there is more than 1 redistributor region
> 
>     Changes in v3:
>         - Add ACPI support
> 
>     Changes in v2:
>         - Use 0 rather than a negative value to know when the maintenance IRQ
>         is not present.
>         - Use resource for vcpu and vctrl
> ---
>  drivers/irqchip/irq-gic-v3.c           | 110 ++++++++++++++++++++++++++++++++-
>  include/linux/irqchip/arm-gic-common.h |   1 +
>  2 files changed, 110 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 50e87e6..08afbfe 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -28,6 +28,7 @@
>  #include <linux/slab.h>
>  
>  #include <linux/irqchip.h>
> +#include <linux/irqchip/arm-gic-common.h>
>  #include <linux/irqchip/arm-gic-v3.h>
>  
>  #include <asm/cputype.h>
> @@ -56,6 +57,8 @@ struct gic_chip_data {
>  static struct gic_chip_data gic_data __read_mostly;
>  static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
>  
> +static struct gic_kvm_info gic_v3_kvm_info;
> +
>  #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
>  #define gic_data_rdist_sgi_base()	(gic_data_rdist_rd_base() + SZ_64K)
> @@ -901,6 +904,30 @@ static int __init gic_validate_dist_version(void __iomem *dist_base)
>  	return 0;
>  }
>  
> +static void __init gic_of_setup_kvm_info(struct device_node *node)
> +{
> +	int ret;
> +	struct resource r;
> +	u32 gicv_idx;
> +
> +	gic_v3_kvm_info.type = GIC_V3;
> +
> +	gic_v3_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);
> +	if (!gic_v3_kvm_info.maint_irq)
> +		return;
> +
> +	if (of_property_read_u32(node, "#redistributor-regions",
> +				 &gicv_idx))
> +		gicv_idx = 1;
> +
> +	gicv_idx += 3;	/* Also skip GICD, GICC, GICH */
> +	ret = of_address_to_resource(node, gicv_idx, &r);
> +	if (!ret)
> +		gic_v3_kvm_info.vcpu = r;
> +
> +	gic_set_kvm_info(&gic_v3_kvm_info);
> +}
> +
>  static int __init gic_of_init(struct device_node *node, struct device_node *parent)
>  {
>  	void __iomem *dist_base;
> @@ -952,8 +979,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>  
>  	err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
>  			     redist_stride, &node->fwnode);
> -	if (!err)
> +	if (!err) {
> +		gic_of_setup_kvm_info(node);
>  		return 0;
> +	}
>  
>  out_unmap_rdist:
>  	for (i = 0; i < nr_redist_regions; i++)
> @@ -974,6 +1003,9 @@ static struct
>  	struct redist_region *redist_regs;
>  	u32 nr_redist_regions;
>  	bool single_redist;
> +	u32 maint_irq;
> +	int maint_irq_mode;
> +	phys_addr_t vcpu_base;
>  } acpi_data __initdata;
>  
>  static void __init
> @@ -1110,7 +1142,81 @@ static bool __init acpi_validate_gic_table(struct acpi_subtable_header *header,
>  	return true;
>  }
>  
> +static int __init gic_acpi_parse_virt_madt_gicc(struct acpi_subtable_header *header,
> +						const unsigned long end)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +		(struct acpi_madt_generic_interrupt *)header;
> +	int maint_irq_mode;
> +	static int first_madt = true;
> +
> +	maint_irq_mode = (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
> +		ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
> +
> +	if (first_madt) {
> +		first_madt = false;
> +
> +		acpi_data.maint_irq = gicc->vgic_interrupt;
> +		acpi_data.maint_irq_mode = maint_irq_mode;
> +		acpi_data.vcpu_base = gicc->gicv_base_address;
> +
> +		return 0;
> +	}
> +
> +	/*
> +	 * The maintenance interrupt and GICV should be the same for every CPU
> +	 */
> +	if ((acpi_data.maint_irq != gicc->vgic_interrupt) ||
> +	    (acpi_data.maint_irq_mode != maint_irq_mode) ||
> +	    (acpi_data.vcpu_base != gicc->gicv_base_address))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static bool __init gic_acpi_collect_virt_info(void)
> +{
> +	int count;
> +
> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
> +				      gic_acpi_parse_virt_madt_gicc, 0);
> +
> +	return (count > 0);
> +}
> +
>  #define ACPI_GICV3_DIST_MEM_SIZE (SZ_64K)
> +#define ACPI_GICV2_VCTRL_MEM_SIZE	(SZ_4K)
> +#define ACPI_GICV2_VCPU_MEM_SIZE	(SZ_8K)
> +
> +static void __init gic_acpi_setup_kvm_info(void)
> +{
> +	int irq;
> +
> +	if (!gic_acpi_collect_virt_info()) {
> +		pr_warn("Unable to get hardware information used for virtualization\n");

perhaps this should say something about gicv3 as well?

> +		return;
> +	}
> +
> +	gic_v3_kvm_info.type = GIC_V3;
> +
> +	irq = acpi_register_gsi(NULL, acpi_data.maint_irq,
> +				acpi_data.maint_irq_mode,
> +				ACPI_ACTIVE_HIGH);
> +	if (irq <= 0)
> +		return;
> +
> +	gic_v3_kvm_info.maint_irq = irq;
> +
> +	if (acpi_data.vcpu_base) {
> +		struct resource *vcpu = &gic_v3_kvm_info.vcpu;
> +
> +		vcpu->flags = IORESOURCE_MEM;
> +		vcpu->start = acpi_data.vcpu_base;
> +		vcpu->end = vcpu->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
> +	}
> +
> +	gic_set_kvm_info(&gic_v3_kvm_info);
> +}
>  
>  static int __init
>  gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
> @@ -1159,6 +1265,8 @@ gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
>  		goto out_fwhandle_free;
>  
>  	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
> +	gic_acpi_setup_kvm_info();
> +
>  	return 0;
>  
>  out_fwhandle_free:
> diff --git a/include/linux/irqchip/arm-gic-common.h b/include/linux/irqchip/arm-gic-common.h
> index ef34f6f..c647b05 100644
> --- a/include/linux/irqchip/arm-gic-common.h
> +++ b/include/linux/irqchip/arm-gic-common.h
> @@ -15,6 +15,7 @@
>  
>  enum gic_type {
>  	GIC_V2,
> +	GIC_V3,
>  };
>  
>  struct gic_kvm_info {
> -- 
> 1.9.1
> 

Otherwise (with my extremely limited acpi understanding):

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

WARNING: multiple messages have this Message-ID (diff)
From: christoffer.dall@linaro.org (Christoffer Dall)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v5 6/9] irqchip/gic-v3: Parse and export virtual GIC information
Date: Wed, 6 Apr 2016 19:22:28 +0200	[thread overview]
Message-ID: <20160406172228.GE8961@cbox> (raw)
In-Reply-To: <1459769860-6629-7-git-send-email-julien.grall@arm.com>

On Mon, Apr 04, 2016 at 12:37:37PM +0100, Julien Grall wrote:
> Fill up the recently introduced gic_kvm_info with the hardware
> information used for virtualization.
> 
> Signed-off-by: Julien Grall <julien.grall@arm.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Jason Cooper <jason@lakedaemon.net>
> Cc: Marc Zyngier <marc.zyngier@arm.com>
> 
> ---
>     Changes in v5:
>         - Remove the alignment check for GICV. It's already done in the
>         KVM code.
>         - Fix initialization of KVM with ACPI.
> 
>     Changes in v4:
>         - Change the flow to call gic_kvm_set_info only when all the
>         mandatory information are valid.
>         - Remove unecessary code in ACPI parsing (the virtual control
>         interface doesn't exist for GICv3).
>         - Rework commit message
>         - Rework the ACPI support as it didn't collect hardware info for
>         virtualization when there is more than 1 redistributor region
> 
>     Changes in v3:
>         - Add ACPI support
> 
>     Changes in v2:
>         - Use 0 rather than a negative value to know when the maintenance IRQ
>         is not present.
>         - Use resource for vcpu and vctrl
> ---
>  drivers/irqchip/irq-gic-v3.c           | 110 ++++++++++++++++++++++++++++++++-
>  include/linux/irqchip/arm-gic-common.h |   1 +
>  2 files changed, 110 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c
> index 50e87e6..08afbfe 100644
> --- a/drivers/irqchip/irq-gic-v3.c
> +++ b/drivers/irqchip/irq-gic-v3.c
> @@ -28,6 +28,7 @@
>  #include <linux/slab.h>
>  
>  #include <linux/irqchip.h>
> +#include <linux/irqchip/arm-gic-common.h>
>  #include <linux/irqchip/arm-gic-v3.h>
>  
>  #include <asm/cputype.h>
> @@ -56,6 +57,8 @@ struct gic_chip_data {
>  static struct gic_chip_data gic_data __read_mostly;
>  static struct static_key supports_deactivate = STATIC_KEY_INIT_TRUE;
>  
> +static struct gic_kvm_info gic_v3_kvm_info;
> +
>  #define gic_data_rdist()		(this_cpu_ptr(gic_data.rdists.rdist))
>  #define gic_data_rdist_rd_base()	(gic_data_rdist()->rd_base)
>  #define gic_data_rdist_sgi_base()	(gic_data_rdist_rd_base() + SZ_64K)
> @@ -901,6 +904,30 @@ static int __init gic_validate_dist_version(void __iomem *dist_base)
>  	return 0;
>  }
>  
> +static void __init gic_of_setup_kvm_info(struct device_node *node)
> +{
> +	int ret;
> +	struct resource r;
> +	u32 gicv_idx;
> +
> +	gic_v3_kvm_info.type = GIC_V3;
> +
> +	gic_v3_kvm_info.maint_irq = irq_of_parse_and_map(node, 0);
> +	if (!gic_v3_kvm_info.maint_irq)
> +		return;
> +
> +	if (of_property_read_u32(node, "#redistributor-regions",
> +				 &gicv_idx))
> +		gicv_idx = 1;
> +
> +	gicv_idx += 3;	/* Also skip GICD, GICC, GICH */
> +	ret = of_address_to_resource(node, gicv_idx, &r);
> +	if (!ret)
> +		gic_v3_kvm_info.vcpu = r;
> +
> +	gic_set_kvm_info(&gic_v3_kvm_info);
> +}
> +
>  static int __init gic_of_init(struct device_node *node, struct device_node *parent)
>  {
>  	void __iomem *dist_base;
> @@ -952,8 +979,10 @@ static int __init gic_of_init(struct device_node *node, struct device_node *pare
>  
>  	err = gic_init_bases(dist_base, rdist_regs, nr_redist_regions,
>  			     redist_stride, &node->fwnode);
> -	if (!err)
> +	if (!err) {
> +		gic_of_setup_kvm_info(node);
>  		return 0;
> +	}
>  
>  out_unmap_rdist:
>  	for (i = 0; i < nr_redist_regions; i++)
> @@ -974,6 +1003,9 @@ static struct
>  	struct redist_region *redist_regs;
>  	u32 nr_redist_regions;
>  	bool single_redist;
> +	u32 maint_irq;
> +	int maint_irq_mode;
> +	phys_addr_t vcpu_base;
>  } acpi_data __initdata;
>  
>  static void __init
> @@ -1110,7 +1142,81 @@ static bool __init acpi_validate_gic_table(struct acpi_subtable_header *header,
>  	return true;
>  }
>  
> +static int __init gic_acpi_parse_virt_madt_gicc(struct acpi_subtable_header *header,
> +						const unsigned long end)
> +{
> +	struct acpi_madt_generic_interrupt *gicc =
> +		(struct acpi_madt_generic_interrupt *)header;
> +	int maint_irq_mode;
> +	static int first_madt = true;
> +
> +	maint_irq_mode = (gicc->flags & ACPI_MADT_VGIC_IRQ_MODE) ?
> +		ACPI_EDGE_SENSITIVE : ACPI_LEVEL_SENSITIVE;
> +
> +	if (first_madt) {
> +		first_madt = false;
> +
> +		acpi_data.maint_irq = gicc->vgic_interrupt;
> +		acpi_data.maint_irq_mode = maint_irq_mode;
> +		acpi_data.vcpu_base = gicc->gicv_base_address;
> +
> +		return 0;
> +	}
> +
> +	/*
> +	 * The maintenance interrupt and GICV should be the same for every CPU
> +	 */
> +	if ((acpi_data.maint_irq != gicc->vgic_interrupt) ||
> +	    (acpi_data.maint_irq_mode != maint_irq_mode) ||
> +	    (acpi_data.vcpu_base != gicc->gicv_base_address))
> +		return -EINVAL;
> +
> +	return 0;
> +}
> +
> +static bool __init gic_acpi_collect_virt_info(void)
> +{
> +	int count;
> +
> +	count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
> +				      gic_acpi_parse_virt_madt_gicc, 0);
> +
> +	return (count > 0);
> +}
> +
>  #define ACPI_GICV3_DIST_MEM_SIZE (SZ_64K)
> +#define ACPI_GICV2_VCTRL_MEM_SIZE	(SZ_4K)
> +#define ACPI_GICV2_VCPU_MEM_SIZE	(SZ_8K)
> +
> +static void __init gic_acpi_setup_kvm_info(void)
> +{
> +	int irq;
> +
> +	if (!gic_acpi_collect_virt_info()) {
> +		pr_warn("Unable to get hardware information used for virtualization\n");

perhaps this should say something about gicv3 as well?

> +		return;
> +	}
> +
> +	gic_v3_kvm_info.type = GIC_V3;
> +
> +	irq = acpi_register_gsi(NULL, acpi_data.maint_irq,
> +				acpi_data.maint_irq_mode,
> +				ACPI_ACTIVE_HIGH);
> +	if (irq <= 0)
> +		return;
> +
> +	gic_v3_kvm_info.maint_irq = irq;
> +
> +	if (acpi_data.vcpu_base) {
> +		struct resource *vcpu = &gic_v3_kvm_info.vcpu;
> +
> +		vcpu->flags = IORESOURCE_MEM;
> +		vcpu->start = acpi_data.vcpu_base;
> +		vcpu->end = vcpu->start + ACPI_GICV2_VCPU_MEM_SIZE - 1;
> +	}
> +
> +	gic_set_kvm_info(&gic_v3_kvm_info);
> +}
>  
>  static int __init
>  gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
> @@ -1159,6 +1265,8 @@ gic_acpi_init(struct acpi_subtable_header *header, const unsigned long end)
>  		goto out_fwhandle_free;
>  
>  	acpi_set_irq_model(ACPI_IRQ_MODEL_GIC, domain_handle);
> +	gic_acpi_setup_kvm_info();
> +
>  	return 0;
>  
>  out_fwhandle_free:
> diff --git a/include/linux/irqchip/arm-gic-common.h b/include/linux/irqchip/arm-gic-common.h
> index ef34f6f..c647b05 100644
> --- a/include/linux/irqchip/arm-gic-common.h
> +++ b/include/linux/irqchip/arm-gic-common.h
> @@ -15,6 +15,7 @@
>  
>  enum gic_type {
>  	GIC_V2,
> +	GIC_V3,
>  };
>  
>  struct gic_kvm_info {
> -- 
> 1.9.1
> 

Otherwise (with my extremely limited acpi understanding):

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

  reply	other threads:[~2016-04-06 17:22 UTC|newest]

Thread overview: 90+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-04 11:37 [PATCH v5 0/9] arm64: Add support for KVM with ACPI Julien Grall
2016-04-04 11:37 ` Julien Grall
2016-04-04 11:37 ` Julien Grall
2016-04-04 11:37 ` [PATCH v5 1/9] clocksource: arm_arch_timer: Gather KVM specific information in a structure Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-06 17:26   ` Christoffer Dall
2016-04-06 17:26     ` Christoffer Dall
2016-04-06 17:26     ` Christoffer Dall
2016-04-04 11:37 ` [PATCH v5 2/9] clocksource: arm_arch_timer: Extend arch_timer_kvm_info to get the virtual IRQ Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-06 17:26   ` Christoffer Dall
2016-04-06 17:26     ` Christoffer Dall
2016-04-06 17:26     ` Christoffer Dall
2016-04-04 11:37 ` [PATCH v5 3/9] irqchip/gic-v2: Gather ACPI specific data in a single structure Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-11  2:47   ` Hanjun Guo
2016-04-11  2:47     ` Hanjun Guo
2016-04-11  2:47     ` Hanjun Guo
2016-04-04 11:37 ` [PATCH v5 4/9] irqchip/gic-v2: Parse and export virtual GIC information Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-06 17:04   ` Christoffer Dall
2016-04-06 17:04     ` Christoffer Dall
2016-04-06 17:04     ` Christoffer Dall
2016-04-06 17:40     ` Julien Grall
2016-04-06 17:40       ` Julien Grall
2016-04-06 17:40       ` Julien Grall
2016-04-11  3:17   ` Hanjun Guo
2016-04-11  3:17     ` Hanjun Guo
2016-04-11  3:17     ` Hanjun Guo
2016-04-11 13:54     ` Julien Grall
2016-04-11 13:54       ` Julien Grall
2016-04-11 13:54       ` Julien Grall
2016-04-04 11:37 ` [PATCH v5 5/9] irqchip/gic-v3: Gather all ACPI specific data in a single structure Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-06 17:26   ` Christoffer Dall
2016-04-06 17:26     ` Christoffer Dall
2016-04-06 17:26     ` Christoffer Dall
2016-04-11  5:21   ` Hanjun Guo
2016-04-11  5:21     ` Hanjun Guo
2016-04-11  5:21     ` Hanjun Guo
2016-04-04 11:37 ` [PATCH v5 6/9] irqchip/gic-v3: Parse and export virtual GIC information Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-06 17:22   ` Christoffer Dall [this message]
2016-04-06 17:22     ` Christoffer Dall
2016-04-06 17:22     ` Christoffer Dall
2016-04-06 17:45     ` Julien Grall
2016-04-06 17:45       ` Julien Grall
2016-04-06 17:45       ` Julien Grall
2016-04-09  2:29   ` Shanker Donthineni
2016-04-09  2:29     ` Shanker Donthineni
2016-04-09  2:29     ` Shanker Donthineni
2016-04-11 14:03     ` Julien Grall
2016-04-11 14:03       ` Julien Grall
2016-04-11 14:03       ` Julien Grall
2016-04-11  5:27   ` Hanjun Guo
2016-04-11  5:27     ` Hanjun Guo
2016-04-11  5:27     ` Hanjun Guo
2016-04-11 14:27     ` Julien Grall
2016-04-11 14:27       ` Julien Grall
2016-04-11 14:27       ` Julien Grall
2016-04-11 15:25       ` Shanker Donthineni
2016-04-11 15:25         ` Shanker Donthineni
2016-04-11 15:25         ` Shanker Donthineni
2016-04-13 10:11         ` Hanjun Guo
2016-04-13 10:11           ` Hanjun Guo
2016-04-13 10:11           ` Hanjun Guo
2016-04-04 11:37 ` [PATCH v5 7/9] KVM: arm/arm64: arch_timer: Rely on the arch timer to parse the firmware tables Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37 ` [PATCH v5 8/9] KVM: arm/arm64: vgic: Rely on the GIC driver " Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-06 17:25   ` Christoffer Dall
2016-04-06 17:25     ` Christoffer Dall
2016-04-06 17:25     ` Christoffer Dall
2016-04-04 11:37 ` [PATCH v5 9/9] clocksource: arm_arch_timer: Remove arch_timer_get_timecounter Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-04 11:37   ` Julien Grall
2016-04-06 17:28 ` [PATCH v5 0/9] arm64: Add support for KVM with ACPI Christoffer Dall
2016-04-06 17:28   ` Christoffer Dall
2016-04-06 17:28   ` Christoffer Dall
2016-04-06 17:49   ` Julien Grall
2016-04-06 17:49     ` Julien Grall
2016-04-06 17:49     ` Julien Grall

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160406172228.GE8961@cbox \
    --to=christoffer.dall@linaro.org \
    --cc=al.stone@linaro.org \
    --cc=fu.wei@linaro.org \
    --cc=gg@slimlogic.co.uk \
    --cc=jason@lakedaemon.net \
    --cc=julien.grall@arm.com \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=marc.zyngier@arm.com \
    --cc=tglx@linutronix.de \
    --cc=wei@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.