Re: [Xen-devel] [PATCH v5 05/30] ARM: GICv3: allocate LPI pending and property table

2017-04-06 Thread Julien Grall

Hi Andre,

On 06/04/17 15:37, Andre Przywara wrote:

On 06/04/17 13:58, Julien Grall wrote:

Hi Andre,

On 06/04/17 00:18, Andre Przywara wrote:

+static unsigned int max_lpi_bits = 20;
+integer_param("max_lpi_bits", max_lpi_bits);
+
+int gicv3_lpi_init_host_lpis(unsigned int host_lpi_bits)
+{
+/* An implementation needs to support at least 14 bits of LPI
IDs. */
+max_lpi_bits = max(max_lpi_bits, 14U);


I think we should warn the user if we don't use his command line. He
might think he can disable LPIs using it.


Done.
Shall this be a warning_add() as well or is a printk() sufficient?


I would go on classic printk. I was even thinking a panic as a user 
should not do this. It is up to you.


Cheers,

--
Julien Grall

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


Re: [Xen-devel] [PATCH v5 05/30] ARM: GICv3: allocate LPI pending and property table

2017-04-06 Thread Andre Przywara
Hi,

On 06/04/17 13:58, Julien Grall wrote:
> Hi Andre,
> 
> On 06/04/17 00:18, Andre Przywara wrote:
>> +static unsigned int max_lpi_bits = 20;
>> +integer_param("max_lpi_bits", max_lpi_bits);
>> +
>> +int gicv3_lpi_init_host_lpis(unsigned int host_lpi_bits)
>> +{
>> +/* An implementation needs to support at least 14 bits of LPI
>> IDs. */
>> +max_lpi_bits = max(max_lpi_bits, 14U);
> 
> I think we should warn the user if we don't use his command line. He
> might think he can disable LPIs using it.

Done.
Shall this be a warning_add() as well or is a printk() sufficient?

Cheers,
Andre.

>> +lpi_data.max_host_lpi_ids = BIT_ULL(min(host_lpi_bits,
>> max_lpi_bits));
>> +
>> +/*
>> + * Warn if the number of LPIs are quite high, as the user might
>> not want
>> + * to waste megabytes of memory for a mostly empty table.
>> + * It's very unlikely that we need more than 24 bits worth of LPIs.
>> + */
>> +if ( lpi_data.max_host_lpi_ids > BIT(24) )
>> +warning_add("Using high number of LPIs, limit memory usage
>> with max_lpi_bits\n");
>> +
>> +printk("GICv3: using at most %llu LPIs on the host.\n",
>> MAX_NR_HOST_LPIS);
>> +
>> +return 0;
>> +}
> 
> Cheers,
> 

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


Re: [Xen-devel] [PATCH v5 05/30] ARM: GICv3: allocate LPI pending and property table

2017-04-06 Thread Julien Grall

Hi Andre,

On 06/04/17 00:18, Andre Przywara wrote:

+static unsigned int max_lpi_bits = 20;
+integer_param("max_lpi_bits", max_lpi_bits);
+
+int gicv3_lpi_init_host_lpis(unsigned int host_lpi_bits)
+{
+/* An implementation needs to support at least 14 bits of LPI IDs. */
+max_lpi_bits = max(max_lpi_bits, 14U);


I think we should warn the user if we don't use his command line. He 
might think he can disable LPIs using it.



+lpi_data.max_host_lpi_ids = BIT_ULL(min(host_lpi_bits, max_lpi_bits));
+
+/*
+ * Warn if the number of LPIs are quite high, as the user might not want
+ * to waste megabytes of memory for a mostly empty table.
+ * It's very unlikely that we need more than 24 bits worth of LPIs.
+ */
+if ( lpi_data.max_host_lpi_ids > BIT(24) )
+warning_add("Using high number of LPIs, limit memory usage with 
max_lpi_bits\n");
+
+printk("GICv3: using at most %llu LPIs on the host.\n", MAX_NR_HOST_LPIS);
+
+return 0;
+}


Cheers,

--
Julien Grall

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


Re: [Xen-devel] [PATCH v5 05/30] ARM: GICv3: allocate LPI pending and property table

2017-04-05 Thread Stefano Stabellini
On Thu, 6 Apr 2017, Andre Przywara wrote:
> The ARM GICv3 provides a new kind of interrupt called LPIs.
> The pending bits and the configuration data (priority, enable bits) for
> those LPIs are stored in tables in normal memory, which software has to
> provide to the hardware.
> Allocate the required memory, initialize it and hand it over to each
> redistributor. The maximum number of LPIs to be used can be adjusted with
> the command line option "max_lpi_bits", which defaults to 20 bits,
> covering about one million LPIs.
> 
> Signed-off-by: Andre Przywara 

Reviewed-by: Stefano Stabellini 

> ---
>  docs/misc/xen-command-line.markdown |   9 ++
>  xen/arch/arm/Makefile   |   1 +
>  xen/arch/arm/gic-v3-lpi.c   | 221 
> 
>  xen/arch/arm/gic-v3.c   |  17 +++
>  xen/include/asm-arm/gic_v3_defs.h   |  52 +
>  xen/include/asm-arm/gic_v3_its.h|  15 ++-
>  xen/include/asm-arm/irq.h   |   8 ++
>  7 files changed, 322 insertions(+), 1 deletion(-)
>  create mode 100644 xen/arch/arm/gic-v3-lpi.c
> 
> diff --git a/docs/misc/xen-command-line.markdown 
> b/docs/misc/xen-command-line.markdown
> index 9eb85d6..6ef8633 100644
> --- a/docs/misc/xen-command-line.markdown
> +++ b/docs/misc/xen-command-line.markdown
> @@ -1172,6 +1172,15 @@ based interrupts. Any higher IRQs will be available 
> for use via PCI MSI.
>  ### maxcpus
>  > `= `
>  
> +### max\_lpi\_bits
> +> `= `
> +
> +Specifies the number of ARM GICv3 LPI interrupts to allocate on the host,
> +presented as the number of bits needed to encode it. This must be at least
> +14 and not exceed 32, and each LPI requires one byte (configuration) and
> +one pending bit to be allocated.
> +Defaults to 20 bits (to cover at most 1048576 interrupts).
> +
>  ### mce
>  > `= `
>  
> diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
> index 39c0a03..6be85ab 100644
> --- a/xen/arch/arm/Makefile
> +++ b/xen/arch/arm/Makefile
> @@ -19,6 +19,7 @@ obj-y += gic.o
>  obj-y += gic-v2.o
>  obj-$(CONFIG_HAS_GICV3) += gic-v3.o
>  obj-$(CONFIG_HAS_ITS) += gic-v3-its.o
> +obj-$(CONFIG_HAS_ITS) += gic-v3-lpi.o
>  obj-y += guestcopy.o
>  obj-y += hvm.o
>  obj-y += io.o
> diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c
> new file mode 100644
> index 000..7f99ec6
> --- /dev/null
> +++ b/xen/arch/arm/gic-v3-lpi.c
> @@ -0,0 +1,221 @@
> +/*
> + * xen/arch/arm/gic-v3-lpi.c
> + *
> + * ARM GICv3 Locality-specific Peripheral Interrupts (LPI) support
> + *
> + * Copyright (C) 2016,2017 - ARM Ltd
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; under version 2 of the License.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; If not, see .
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#define LPI_PROPTABLE_NEEDS_FLUSHING(1U << 0)
> +
> +/* Global state */
> +static struct {
> +/* The global LPI property table, shared by all redistributors. */
> +uint8_t *lpi_property;
> +/*
> + * Number of physical LPIs the host supports. This is a property of
> + * the GIC hardware. We depart from the habit of naming these things
> + * "physical" in Xen, as the GICv3/4 spec uses the term "physical LPI"
> + * in a different context to differentiate them from "virtual LPIs".
> + */
> +unsigned long long int max_host_lpi_ids;
> +unsigned int flags;
> +} lpi_data;
> +
> +struct lpi_redist_data {
> +void*pending_table;
> +};
> +
> +static DEFINE_PER_CPU(struct lpi_redist_data, lpi_redist);
> +
> +#define MAX_NR_HOST_LPIS   (lpi_data.max_host_lpi_ids - LPI_OFFSET)
> +
> +static int gicv3_lpi_allocate_pendtable(uint64_t *reg)
> +{
> +uint64_t val;
> +void *pendtable;
> +
> +if ( this_cpu(lpi_redist).pending_table )
> +return -EBUSY;
> +
> +val  = GIC_BASER_CACHE_RaWaWb << GICR_PENDBASER_INNER_CACHEABILITY_SHIFT;
> +val |= GIC_BASER_CACHE_SameAsInner << 
> GICR_PENDBASER_OUTER_CACHEABILITY_SHIFT;
> +val |= GIC_BASER_InnerShareable << GICR_PENDBASER_SHAREABILITY_SHIFT;
> +
> +/*
> + * The pending table holds one bit per LPI and even covers bits for
> + * interrupt IDs below 8192, so we allocate the full range.
> + * The GICv3 imposes a 64KB alignment requirement, also requires
> + * physically contiguous memory.
> + */
> +pendtable = 

[Xen-devel] [PATCH v5 05/30] ARM: GICv3: allocate LPI pending and property table

2017-04-05 Thread Andre Przywara
The ARM GICv3 provides a new kind of interrupt called LPIs.
The pending bits and the configuration data (priority, enable bits) for
those LPIs are stored in tables in normal memory, which software has to
provide to the hardware.
Allocate the required memory, initialize it and hand it over to each
redistributor. The maximum number of LPIs to be used can be adjusted with
the command line option "max_lpi_bits", which defaults to 20 bits,
covering about one million LPIs.

Signed-off-by: Andre Przywara 
---
 docs/misc/xen-command-line.markdown |   9 ++
 xen/arch/arm/Makefile   |   1 +
 xen/arch/arm/gic-v3-lpi.c   | 221 
 xen/arch/arm/gic-v3.c   |  17 +++
 xen/include/asm-arm/gic_v3_defs.h   |  52 +
 xen/include/asm-arm/gic_v3_its.h|  15 ++-
 xen/include/asm-arm/irq.h   |   8 ++
 7 files changed, 322 insertions(+), 1 deletion(-)
 create mode 100644 xen/arch/arm/gic-v3-lpi.c

diff --git a/docs/misc/xen-command-line.markdown 
b/docs/misc/xen-command-line.markdown
index 9eb85d6..6ef8633 100644
--- a/docs/misc/xen-command-line.markdown
+++ b/docs/misc/xen-command-line.markdown
@@ -1172,6 +1172,15 @@ based interrupts. Any higher IRQs will be available for 
use via PCI MSI.
 ### maxcpus
 > `= `
 
+### max\_lpi\_bits
+> `= `
+
+Specifies the number of ARM GICv3 LPI interrupts to allocate on the host,
+presented as the number of bits needed to encode it. This must be at least
+14 and not exceed 32, and each LPI requires one byte (configuration) and
+one pending bit to be allocated.
+Defaults to 20 bits (to cover at most 1048576 interrupts).
+
 ### mce
 > `= `
 
diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 39c0a03..6be85ab 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -19,6 +19,7 @@ obj-y += gic.o
 obj-y += gic-v2.o
 obj-$(CONFIG_HAS_GICV3) += gic-v3.o
 obj-$(CONFIG_HAS_ITS) += gic-v3-its.o
+obj-$(CONFIG_HAS_ITS) += gic-v3-lpi.o
 obj-y += guestcopy.o
 obj-y += hvm.o
 obj-y += io.o
diff --git a/xen/arch/arm/gic-v3-lpi.c b/xen/arch/arm/gic-v3-lpi.c
new file mode 100644
index 000..7f99ec6
--- /dev/null
+++ b/xen/arch/arm/gic-v3-lpi.c
@@ -0,0 +1,221 @@
+/*
+ * xen/arch/arm/gic-v3-lpi.c
+ *
+ * ARM GICv3 Locality-specific Peripheral Interrupts (LPI) support
+ *
+ * Copyright (C) 2016,2017 - ARM Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; under version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; If not, see .
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define LPI_PROPTABLE_NEEDS_FLUSHING(1U << 0)
+
+/* Global state */
+static struct {
+/* The global LPI property table, shared by all redistributors. */
+uint8_t *lpi_property;
+/*
+ * Number of physical LPIs the host supports. This is a property of
+ * the GIC hardware. We depart from the habit of naming these things
+ * "physical" in Xen, as the GICv3/4 spec uses the term "physical LPI"
+ * in a different context to differentiate them from "virtual LPIs".
+ */
+unsigned long long int max_host_lpi_ids;
+unsigned int flags;
+} lpi_data;
+
+struct lpi_redist_data {
+void*pending_table;
+};
+
+static DEFINE_PER_CPU(struct lpi_redist_data, lpi_redist);
+
+#define MAX_NR_HOST_LPIS   (lpi_data.max_host_lpi_ids - LPI_OFFSET)
+
+static int gicv3_lpi_allocate_pendtable(uint64_t *reg)
+{
+uint64_t val;
+void *pendtable;
+
+if ( this_cpu(lpi_redist).pending_table )
+return -EBUSY;
+
+val  = GIC_BASER_CACHE_RaWaWb << GICR_PENDBASER_INNER_CACHEABILITY_SHIFT;
+val |= GIC_BASER_CACHE_SameAsInner << 
GICR_PENDBASER_OUTER_CACHEABILITY_SHIFT;
+val |= GIC_BASER_InnerShareable << GICR_PENDBASER_SHAREABILITY_SHIFT;
+
+/*
+ * The pending table holds one bit per LPI and even covers bits for
+ * interrupt IDs below 8192, so we allocate the full range.
+ * The GICv3 imposes a 64KB alignment requirement, also requires
+ * physically contiguous memory.
+ */
+pendtable = _xzalloc(lpi_data.max_host_lpi_ids / 8, SZ_64K);
+if ( !pendtable )
+return -ENOMEM;
+
+/* Make sure the physical address can be encoded in the register. */
+if ( virt_to_maddr(pendtable) & ~GENMASK_ULL(51, 16) )
+{
+xfree(pendtable);
+return -ERANGE;
+}
+clean_and_invalidate_dcache_va_range(pendtable,
+