diff mbox

[RFC,v1,16/21] ARM: NUMA: Extract proximity from SRAT table

Message ID 1486655834-9708-17-git-send-email-vijay.kilari@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Vijay Kilari Feb. 9, 2017, 3:57 p.m. UTC
From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>

Register SRAT entry handler for type
ACPI_SRAT_TYPE_GICC_AFFINITY to parse SRAT table
and extract proximity for all CPU IDs.

Signed-off-by: Vijaya Kumar <Vijaya.Kumar@cavium.com>
---
 xen/arch/arm/acpi_numa.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++
 xen/drivers/acpi/numa.c   | 37 +++++++++++++++++++++++++++++++
 xen/drivers/acpi/osl.c    |  2 ++
 xen/include/acpi/actbl1.h | 17 ++++++++++++++-
 xen/include/xen/acpi.h    | 39 +++++++++++++++++++++++++++++++++
 5 files changed, 149 insertions(+), 1 deletion(-)

Comments

Julien Grall March 2, 2017, 5:21 p.m. UTC | #1
(+ Jan as ACPI maintainer)

Hello Vijay,

On 09/02/17 15:57, vijay.kilari@gmail.com wrote:
> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
>
> Register SRAT entry handler for type
> ACPI_SRAT_TYPE_GICC_AFFINITY to parse SRAT table
> and extract proximity for all CPU IDs.
>
> Signed-off-by: Vijaya Kumar <Vijaya.Kumar@cavium.com>
> ---
>  xen/arch/arm/acpi_numa.c  | 55 +++++++++++++++++++++++++++++++++++++++++++++++
>  xen/drivers/acpi/numa.c   | 37 +++++++++++++++++++++++++++++++
>  xen/drivers/acpi/osl.c    |  2 ++
>  xen/include/acpi/actbl1.h | 17 ++++++++++++++-
>  xen/include/xen/acpi.h    | 39 +++++++++++++++++++++++++++++++++
>  5 files changed, 149 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/acpi_numa.c b/xen/arch/arm/acpi_numa.c
> index 3ee87f2..f659275 100644
> --- a/xen/arch/arm/acpi_numa.c
> +++ b/xen/arch/arm/acpi_numa.c
> @@ -105,6 +105,61 @@ static int __init acpi_parse_madt_handler(struct acpi_subtable_header *header,
>      return 0;
>  }
>
> +/* Callback for Proximity Domain -> ACPI processor UID mapping */
> +void __init acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa)
> +{
> +    int pxm, node;
> +    u64 mpidr = 0;

mpidr does not need to be set to 0.

> +    static u32 cpus_in_srat;
> +
> +    if ( srat_disabled() )
> +        return;
> +
> +    if ( pa->header.length < sizeof(struct acpi_srat_gicc_affinity) )
> +    {
> +        printk(XENLOG_WARNING "SRAT: Invalid SRAT header length: %d\n",
> +               pa->header.length);
> +        bad_srat();
> +        return;
> +    }
> +
> +    if ( !(pa->flags & ACPI_SRAT_GICC_ENABLED) )
> +        return;
> +
> +    if ( cpus_in_srat >= NR_CPUS )
> +    {
> +        printk(XENLOG_WARNING

This should be XENLOG_ERROR.

> +               "SRAT: cpu_to_node_map[%d] is too small to fit all cpus\n",
> +               NR_CPUS);
> +        return;
> +    }
> +
> +    pxm = pa->proximity_domain;
> +    node = setup_node(pxm);
> +    if ( node == NUMA_NO_NODE || node >= MAX_NUMNODES )

Looking at the implementation of setup_node, node will either be equal 
to NUMA_NO_NODE or valid. It is not possible to have node >= MAX_NUMNODES.

> +    {
> +        printk(XENLOG_WARNING "SRAT: Too many proximity domains %d\n", pxm);

setup_node is already printing an error if we have too many proximity 
domains. So no need to duplicate twice.

> +        bad_srat();
> +        return;
> +    }
> +
> +    mpidr = acpi_get_cpu_mpidr(pa->acpi_processor_uid);
> +    if ( mpidr == MPIDR_INVALID )
> +    {
> +        printk(XENLOG_WARNING

s/XENLOG_WARNING/XENLOG_ERROR/

> +               "SRAT: PXM %d with ACPI ID %d has no valid MPIDR in MADT\n",
> +               pxm, pa->acpi_processor_uid);
> +        bad_srat();
> +        return;
> +    }
> +
> +    node_set(node, numa_nodes_parsed);
> +    cpus_in_srat++;
> +    acpi_numa = 1;
> +    printk(XENLOG_INFO "SRAT: PXM %d -> MPIDR 0x%lx -> Node %d\n",
> +           pxm, mpidr, node);
> +}
> +
>  void __init acpi_map_uid_to_mpidr(void)
>  {
>      int i;
> diff --git a/xen/drivers/acpi/numa.c b/xen/drivers/acpi/numa.c
> index 50bf9f8..ce22e88 100644
> --- a/xen/drivers/acpi/numa.c
> +++ b/xen/drivers/acpi/numa.c
> @@ -25,9 +25,11 @@
>  #include <xen/init.h>
>  #include <xen/types.h>
>  #include <xen/errno.h>
> +#include <xen/mm.h>

Why do you need to inlucde xen/mm.h and ...

>  #include <xen/acpi.h>
>  #include <xen/numa.h>
>  #include <acpi/acmacros.h>
> +#include <asm/mm.h>

asm/mm.h?

>
>  #define ACPI_NUMA	0x80000000
>  #define _COMPONENT	ACPI_NUMA
> @@ -105,6 +107,21 @@ void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header)
>  		}
>  #endif				/* ACPI_DEBUG_OUTPUT */
>  		break;
> +       case ACPI_SRAT_TYPE_GICC_AFFINITY:
> +#ifdef ACPI_DEBUG_OUTPUT
> +		{
> +			struct acpi_srat_gicc_affinity *p =
> +			    (struct acpi_srat_gicc_affinity *)header;
> +			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
> +					  "SRAT Processor (acpi id[0x%04x]) in"
> +					  " proximity domain %d %s\n",
> +					  p->acpi_processor_uid,
> +					  p->proximity_domain,
> +					  (p->flags & ACPI_SRAT_GICC_ENABLED) ?
> +					  "enabled" : "disabled");
> +		}
> +#endif                         /* ACPI_DEBUG_OUTPUT */
> +               break;
>  	default:
>  		printk(KERN_WARNING PREFIX
>  		       "Found unsupported SRAT entry (type = %#x)\n",
> @@ -185,6 +202,24 @@ int __init acpi_parse_srat(struct acpi_table_header *table)
>  	return 0;
>  }
>
> +static int __init
> +acpi_parse_gicc_affinity(struct acpi_subtable_header *header,
> +			 const unsigned long end)
> +{
> +	const struct acpi_srat_gicc_affinity *processor_affinity
> +			= (struct acpi_srat_gicc_affinity *)header;
> +
> +	if (!processor_affinity)
> +		return -EINVAL;
> +
> +	acpi_table_print_srat_entry(header);
> +
> +	/* let architecture-dependent part to do it */
> +	acpi_numa_gicc_affinity_init(processor_affinity);
> +
> +	return 0;
> +}
> +
>  int __init
>  acpi_table_parse_srat(int id, acpi_madt_entry_handler handler,
>  		      unsigned int max_entries)
> @@ -205,6 +240,8 @@ int __init acpi_numa_init(void)
>  		acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
>  				      acpi_parse_memory_affinity,
>  				      NR_NODE_MEMBLKS);
> +		acpi_table_parse_srat(ACPI_SRAT_TYPE_GICC_AFFINITY,
> +				      acpi_parse_gicc_affinity, NR_CPUS);
>  	}
>
>  	/* SLIT: System Locality Information Table */
> diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
> index 7199047..7046816 100644
> --- a/xen/drivers/acpi/osl.c
> +++ b/xen/drivers/acpi/osl.c
> @@ -29,6 +29,7 @@
>  #include <xen/pfn.h>
>  #include <xen/types.h>
>  #include <xen/errno.h>
> +#include <xen/mm.h>
>  #include <xen/acpi.h>
>  #include <xen/numa.h>
>  #include <acpi/acmacros.h>
> @@ -39,6 +40,7 @@
>  #include <xen/efi.h>
>  #include <xen/vmap.h>
>  #include <xen/kconfig.h>
> +#include <asm/mm.h>
>
>  #define _COMPONENT		ACPI_OS_SERVICES
>  ACPI_MODULE_NAME("osl")
> diff --git a/xen/include/acpi/actbl1.h b/xen/include/acpi/actbl1.h
> index e199136..b84bfba 100644
> --- a/xen/include/acpi/actbl1.h
> +++ b/xen/include/acpi/actbl1.h
> @@ -949,7 +949,8 @@ enum acpi_srat_type {
>  	ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
>  	ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
>  	ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
> -	ACPI_SRAT_TYPE_RESERVED = 3	/* 3 and greater are reserved */
> +	ACPI_SRAT_TYPE_GICC_AFFINITY = 3,
> +	ACPI_SRAT_TYPE_RESERVED = 4	/* 4 and greater are reserved */
>  };
>
>  /*
> @@ -1007,6 +1008,20 @@ struct acpi_srat_x2apic_cpu_affinity {
>
>  #define ACPI_SRAT_CPU_ENABLED       (1)	/* 00: Use affinity structure */
>
> +/* 3: GICC Affinity (ACPI 5.1) */
> +
> +struct acpi_srat_gicc_affinity {
> +	struct acpi_subtable_header header;
> +	u32 proximity_domain;
> +	u32 acpi_processor_uid;
> +	u32 flags;
> +	u32 clock_domain;
> +};
> +
> +/* Flags for struct acpi_srat_gicc_affinity */
> +
> +#define ACPI_SRAT_GICC_ENABLED     (1)  /* 00: Use affinity structure */
> +
>  /* Reset to default packing */
>
>  #pragma pack()
> diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
> index 30ec0ee..67fe1bb 100644
> --- a/xen/include/xen/acpi.h
> +++ b/xen/include/xen/acpi.h
> @@ -92,10 +92,49 @@ void acpi_table_print_srat_entry (struct acpi_subtable_header *srat);
>
>  /* the following four functions are architecture-dependent */
>  void acpi_numa_slit_init (struct acpi_table_slit *slit);
> +#if defined(CONFIG_X86)
>  void acpi_numa_processor_affinity_init(const struct acpi_srat_cpu_affinity *);
>  void acpi_numa_x2apic_affinity_init(const struct acpi_srat_x2apic_cpu_affinity *);
>  void acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity *);
>  void acpi_numa_arch_fixup(void);
> +static inline void
> +acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa)
> +{
> +	return;
> +}
> +#elif defined(CONFIG_ARM)
> +static inline void
> +acpi_numa_processor_affinity_init(const struct acpi_srat_cpu_affinity *cpu_aff)
> +{
> +	return;
> +}
> +static inline void
> +acpi_numa_x2apic_affinity_init(const struct acpi_srat_x2apic_cpu_affinity *x2apic)
> +{
> +	return;
> +}
> +#if defined(CONFIG_ACPI_NUMA)
> +void acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa);
> +void acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity *);
> +void acpi_numa_arch_fixup(void);
> +#else
> +static inline void
> +acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa)
> +{
> +	return;
> +}
> +static inline void
> +acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity *ma)
> +{
> +	return;
> +}
> +static inline void
> +acpi_numa_arch_fixup(void)
> +{
> +	return;
> +}
> +#endif /* CONFIG_ACPI_NUMA */

This is quite disgusting. We should avoid any #ifdef CONFIG_{X86,ARM} in 
common header.

Also, x2apic and gicc are respectively x86-specific and arm-specific. So 
I think we should move the parsing in a separate arch-depend function to 
avoid those ifdery.

By that I mean having a function acpi_table_arch_parse_srat that will 
parse x2apci on x86 and gicc on ARM. Jan, what do you think?

Cheers,

> +#endif /* CONFIG_X86 */
>
>  #ifdef CONFIG_ACPI_HOTPLUG_CPU
>  /* Arch dependent functions for cpu hotplug support */
>
Vijay Kilari March 3, 2017, 12:39 p.m. UTC | #2
On Thu, Mar 2, 2017 at 10:51 PM, Julien Grall <julien.grall@arm.com> wrote:
> (+ Jan as ACPI maintainer)
>
> Hello Vijay,
>
> On 09/02/17 15:57, vijay.kilari@gmail.com wrote:
>>
>> From: Vijaya Kumar K <Vijaya.Kumar@cavium.com>
>>
>> Register SRAT entry handler for type
>> ACPI_SRAT_TYPE_GICC_AFFINITY to parse SRAT table
>> and extract proximity for all CPU IDs.
>>
>> Signed-off-by: Vijaya Kumar <Vijaya.Kumar@cavium.com>
>> ---
>>  xen/arch/arm/acpi_numa.c  | 55
>> +++++++++++++++++++++++++++++++++++++++++++++++
>>  xen/drivers/acpi/numa.c   | 37 +++++++++++++++++++++++++++++++
>>  xen/drivers/acpi/osl.c    |  2 ++
>>  xen/include/acpi/actbl1.h | 17 ++++++++++++++-
>>  xen/include/xen/acpi.h    | 39 +++++++++++++++++++++++++++++++++
>>  5 files changed, 149 insertions(+), 1 deletion(-)
>>
>> diff --git a/xen/arch/arm/acpi_numa.c b/xen/arch/arm/acpi_numa.c
>> index 3ee87f2..f659275 100644
>> --- a/xen/arch/arm/acpi_numa.c
>> +++ b/xen/arch/arm/acpi_numa.c
>> @@ -105,6 +105,61 @@ static int __init acpi_parse_madt_handler(struct
>> acpi_subtable_header *header,
>>      return 0;
>>  }
>>
>> +/* Callback for Proximity Domain -> ACPI processor UID mapping */
>> +void __init acpi_numa_gicc_affinity_init(const struct
>> acpi_srat_gicc_affinity *pa)
>> +{
>> +    int pxm, node;
>> +    u64 mpidr = 0;
>
>
> mpidr does not need to be set to 0.
>
>> +    static u32 cpus_in_srat;
>> +
>> +    if ( srat_disabled() )
>> +        return;
>> +
>> +    if ( pa->header.length < sizeof(struct acpi_srat_gicc_affinity) )
>> +    {
>> +        printk(XENLOG_WARNING "SRAT: Invalid SRAT header length: %d\n",
>> +               pa->header.length);
>> +        bad_srat();
>> +        return;
>> +    }
>> +
>> +    if ( !(pa->flags & ACPI_SRAT_GICC_ENABLED) )
>> +        return;
>> +
>> +    if ( cpus_in_srat >= NR_CPUS )
>> +    {
>> +        printk(XENLOG_WARNING
>
>
> This should be XENLOG_ERROR.
OK
>
>> +               "SRAT: cpu_to_node_map[%d] is too small to fit all
>> cpus\n",
>> +               NR_CPUS);
>> +        return;
>> +    }
>> +
>> +    pxm = pa->proximity_domain;
>> +    node = setup_node(pxm);
>> +    if ( node == NUMA_NO_NODE || node >= MAX_NUMNODES )
>
>
> Looking at the implementation of setup_node, node will either be equal to
> NUMA_NO_NODE or valid. It is not possible to have node >= MAX_NUMNODES.
ok
>
>> +    {
>> +        printk(XENLOG_WARNING "SRAT: Too many proximity domains %d\n",
>> pxm);
>
>
> setup_node is already printing an error if we have too many proximity
> domains. So no need to duplicate twice.
ok
>
>> +        bad_srat();
>> +        return;
>> +    }
>> +
>> +    mpidr = acpi_get_cpu_mpidr(pa->acpi_processor_uid);
>> +    if ( mpidr == MPIDR_INVALID )
>> +    {
>> +        printk(XENLOG_WARNING
>
>
> s/XENLOG_WARNING/XENLOG_ERROR/
>
>> +               "SRAT: PXM %d with ACPI ID %d has no valid MPIDR in
>> MADT\n",
>> +               pxm, pa->acpi_processor_uid);
>> +        bad_srat();
>> +        return;
>> +    }
>> +
>> +    node_set(node, numa_nodes_parsed);
>> +    cpus_in_srat++;
>> +    acpi_numa = 1;
>> +    printk(XENLOG_INFO "SRAT: PXM %d -> MPIDR 0x%lx -> Node %d\n",
>> +           pxm, mpidr, node);
>> +}
>> +
>>  void __init acpi_map_uid_to_mpidr(void)
>>  {
>>      int i;
>> diff --git a/xen/drivers/acpi/numa.c b/xen/drivers/acpi/numa.c
>> index 50bf9f8..ce22e88 100644
>> --- a/xen/drivers/acpi/numa.c
>> +++ b/xen/drivers/acpi/numa.c
>> @@ -25,9 +25,11 @@
>>  #include <xen/init.h>
>>  #include <xen/types.h>
>>  #include <xen/errno.h>
>> +#include <xen/mm.h>
>
>
> Why do you need to inlucde xen/mm.h and ...
>
>>  #include <xen/acpi.h>
>>  #include <xen/numa.h>
>>  #include <acpi/acmacros.h>
>> +#include <asm/mm.h>
>
>
> asm/mm.h?

I remember when CONFIG_ACPI +CONFIG_NUMA is enabled
there is compilation error.

>
>
>>
>>  #define ACPI_NUMA      0x80000000
>>  #define _COMPONENT     ACPI_NUMA
>> @@ -105,6 +107,21 @@ void __init acpi_table_print_srat_entry(struct
>> acpi_subtable_header * header)
>>                 }
>>  #endif                         /* ACPI_DEBUG_OUTPUT */
>>                 break;
>> +       case ACPI_SRAT_TYPE_GICC_AFFINITY:
>> +#ifdef ACPI_DEBUG_OUTPUT
>> +               {
>> +                       struct acpi_srat_gicc_affinity *p =
>> +                           (struct acpi_srat_gicc_affinity *)header;
>> +                       ACPI_DEBUG_PRINT((ACPI_DB_INFO,
>> +                                         "SRAT Processor (acpi
>> id[0x%04x]) in"
>> +                                         " proximity domain %d %s\n",
>> +                                         p->acpi_processor_uid,
>> +                                         p->proximity_domain,
>> +                                         (p->flags &
>> ACPI_SRAT_GICC_ENABLED) ?
>> +                                         "enabled" : "disabled");
>> +               }
>> +#endif                         /* ACPI_DEBUG_OUTPUT */
>> +               break;
>>         default:
>>                 printk(KERN_WARNING PREFIX
>>                        "Found unsupported SRAT entry (type = %#x)\n",
>> @@ -185,6 +202,24 @@ int __init acpi_parse_srat(struct acpi_table_header
>> *table)
>>         return 0;
>>  }
>>
>> +static int __init
>> +acpi_parse_gicc_affinity(struct acpi_subtable_header *header,
>> +                        const unsigned long end)
>> +{
>> +       const struct acpi_srat_gicc_affinity *processor_affinity
>> +                       = (struct acpi_srat_gicc_affinity *)header;
>> +
>> +       if (!processor_affinity)
>> +               return -EINVAL;
>> +
>> +       acpi_table_print_srat_entry(header);
>> +
>> +       /* let architecture-dependent part to do it */
>> +       acpi_numa_gicc_affinity_init(processor_affinity);
>> +
>> +       return 0;
>> +}
>> +
>>  int __init
>>  acpi_table_parse_srat(int id, acpi_madt_entry_handler handler,
>>                       unsigned int max_entries)
>> @@ -205,6 +240,8 @@ int __init acpi_numa_init(void)
>>                 acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
>>                                       acpi_parse_memory_affinity,
>>                                       NR_NODE_MEMBLKS);
>> +               acpi_table_parse_srat(ACPI_SRAT_TYPE_GICC_AFFINITY,
>> +                                     acpi_parse_gicc_affinity, NR_CPUS);
>>         }
>>
>>         /* SLIT: System Locality Information Table */
>> diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
>> index 7199047..7046816 100644
>> --- a/xen/drivers/acpi/osl.c
>> +++ b/xen/drivers/acpi/osl.c
>> @@ -29,6 +29,7 @@
>>  #include <xen/pfn.h>
>>  #include <xen/types.h>
>>  #include <xen/errno.h>
>> +#include <xen/mm.h>
>>  #include <xen/acpi.h>
>>  #include <xen/numa.h>
>>  #include <acpi/acmacros.h>
>> @@ -39,6 +40,7 @@
>>  #include <xen/efi.h>
>>  #include <xen/vmap.h>
>>  #include <xen/kconfig.h>
>> +#include <asm/mm.h>
>>
>>  #define _COMPONENT             ACPI_OS_SERVICES
>>  ACPI_MODULE_NAME("osl")
>> diff --git a/xen/include/acpi/actbl1.h b/xen/include/acpi/actbl1.h
>> index e199136..b84bfba 100644
>> --- a/xen/include/acpi/actbl1.h
>> +++ b/xen/include/acpi/actbl1.h
>> @@ -949,7 +949,8 @@ enum acpi_srat_type {
>>         ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
>>         ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
>>         ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
>> -       ACPI_SRAT_TYPE_RESERVED = 3     /* 3 and greater are reserved */
>> +       ACPI_SRAT_TYPE_GICC_AFFINITY = 3,
>> +       ACPI_SRAT_TYPE_RESERVED = 4     /* 4 and greater are reserved */
>>  };
>>
>>  /*
>> @@ -1007,6 +1008,20 @@ struct acpi_srat_x2apic_cpu_affinity {
>>
>>  #define ACPI_SRAT_CPU_ENABLED       (1)        /* 00: Use affinity
>> structure */
>>
>> +/* 3: GICC Affinity (ACPI 5.1) */
>> +
>> +struct acpi_srat_gicc_affinity {
>> +       struct acpi_subtable_header header;
>> +       u32 proximity_domain;
>> +       u32 acpi_processor_uid;
>> +       u32 flags;
>> +       u32 clock_domain;
>> +};
>> +
>> +/* Flags for struct acpi_srat_gicc_affinity */
>> +
>> +#define ACPI_SRAT_GICC_ENABLED     (1)  /* 00: Use affinity structure */
>> +
>>  /* Reset to default packing */
>>
>>  #pragma pack()
>> diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
>> index 30ec0ee..67fe1bb 100644
>> --- a/xen/include/xen/acpi.h
>> +++ b/xen/include/xen/acpi.h
>> @@ -92,10 +92,49 @@ void acpi_table_print_srat_entry (struct
>> acpi_subtable_header *srat);
>>
>>  /* the following four functions are architecture-dependent */
>>  void acpi_numa_slit_init (struct acpi_table_slit *slit);
>> +#if defined(CONFIG_X86)
>>  void acpi_numa_processor_affinity_init(const struct
>> acpi_srat_cpu_affinity *);
>>  void acpi_numa_x2apic_affinity_init(const struct
>> acpi_srat_x2apic_cpu_affinity *);
>>  void acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity
>> *);
>>  void acpi_numa_arch_fixup(void);
>> +static inline void
>> +acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa)
>> +{
>> +       return;
>> +}
>> +#elif defined(CONFIG_ARM)
>> +static inline void
>> +acpi_numa_processor_affinity_init(const struct acpi_srat_cpu_affinity
>> *cpu_aff)
>> +{
>> +       return;
>> +}
>> +static inline void
>> +acpi_numa_x2apic_affinity_init(const struct acpi_srat_x2apic_cpu_affinity
>> *x2apic)
>> +{
>> +       return;
>> +}
>> +#if defined(CONFIG_ACPI_NUMA)
>> +void acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity
>> *pa);
>> +void acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity
>> *);
>> +void acpi_numa_arch_fixup(void);
>> +#else
>> +static inline void
>> +acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa)
>> +{
>> +       return;
>> +}
>> +static inline void
>> +acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity *ma)
>> +{
>> +       return;
>> +}
>> +static inline void
>> +acpi_numa_arch_fixup(void)
>> +{
>> +       return;
>> +}
>> +#endif /* CONFIG_ACPI_NUMA */
>
>
> This is quite disgusting. We should avoid any #ifdef CONFIG_{X86,ARM} in
> common header.
>
> Also, x2apic and gicc are respectively x86-specific and arm-specific. So I
> think we should move the parsing in a separate arch-depend function to avoid
> those ifdery.
>
> By that I mean having a function acpi_table_arch_parse_srat that will parse
> x2apci on x86 and gicc on ARM. Jan, what do you think?

Linux also follows similar approach
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/acpi.h?id=refs/tags/v4.10#n265

Regards
Vijay
Julien Grall March 3, 2017, 1:44 p.m. UTC | #3
Hello Vijay,

On 03/03/17 12:39, Vijay Kilari wrote:
> On Thu, Mar 2, 2017 at 10:51 PM, Julien Grall <julien.grall@arm.com> wrote:
>>> diff --git a/xen/drivers/acpi/numa.c b/xen/drivers/acpi/numa.c
>>> index 50bf9f8..ce22e88 100644
>>> --- a/xen/drivers/acpi/numa.c
>>> +++ b/xen/drivers/acpi/numa.c
>>> @@ -25,9 +25,11 @@
>>>  #include <xen/init.h>
>>>  #include <xen/types.h>
>>>  #include <xen/errno.h>
>>> +#include <xen/mm.h>
>>
>>
>> Why do you need to inlucde xen/mm.h and ...
>>
>>>  #include <xen/acpi.h>
>>>  #include <xen/numa.h>
>>>  #include <acpi/acmacros.h>
>>> +#include <asm/mm.h>
>>
>>
>> asm/mm.h?
>
> I remember when CONFIG_ACPI +CONFIG_NUMA is enabled
> there is compilation error.

Regarding asm/mm.h, it is already included by xen/mm.h. So no point to 
add it.

Now regarding xen/mm.h, just saying there is a compilation error is not 
helpful. Can you expand why it is needed?

[...]

>> This is quite disgusting. We should avoid any #ifdef CONFIG_{X86,ARM} in
>> common header.
>>
>> Also, x2apic and gicc are respectively x86-specific and arm-specific. So I
>> think we should move the parsing in a separate arch-depend function to avoid
>> those ifdery.
>>
>> By that I mean having a function acpi_table_arch_parse_srat that will parse
>> x2apci on x86 and gicc on ARM. Jan, what do you think?
>
> Linux also follows similar approach
> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/acpi.h?id=refs/tags/v4.10#n265

So? What are you trying to prove?

The linux version is much readable than yours. Anyway, we should limit 
CONFIG_{X86,ARM} ifdefery in common code.

Currently, I see no point to have those ifdefery when it is possible to 
add an arch-depend function.

Regards,
Vijay Kilari March 3, 2017, 1:50 p.m. UTC | #4
On Fri, Mar 3, 2017 at 7:14 PM, Julien Grall <julien.grall@arm.com> wrote:
> Hello Vijay,
>
> On 03/03/17 12:39, Vijay Kilari wrote:
>>
>> On Thu, Mar 2, 2017 at 10:51 PM, Julien Grall <julien.grall@arm.com>
>> wrote:
>>>>
>>>> diff --git a/xen/drivers/acpi/numa.c b/xen/drivers/acpi/numa.c
>>>> index 50bf9f8..ce22e88 100644
>>>> --- a/xen/drivers/acpi/numa.c
>>>> +++ b/xen/drivers/acpi/numa.c
>>>> @@ -25,9 +25,11 @@
>>>>  #include <xen/init.h>
>>>>  #include <xen/types.h>
>>>>  #include <xen/errno.h>
>>>> +#include <xen/mm.h>
>>>
>>>
>>>
>>> Why do you need to inlucde xen/mm.h and ...
>>>
>>>>  #include <xen/acpi.h>
>>>>  #include <xen/numa.h>
>>>>  #include <acpi/acmacros.h>
>>>> +#include <asm/mm.h>
>>>
>>>
>>>
>>> asm/mm.h?
>>
>>
>> I remember when CONFIG_ACPI +CONFIG_NUMA is enabled
>> there is compilation error.
>
>
> Regarding asm/mm.h, it is already included by xen/mm.h. So no point to add
> it.
>
> Now regarding xen/mm.h, just saying there is a compilation error is not
> helpful. Can you expand why it is needed?

I remember just adding xen/mm.h has not solved the problem. Anyway I
will check this
when I work for next revision.

>
> [...]
>
>>> This is quite disgusting. We should avoid any #ifdef CONFIG_{X86,ARM} in
>>> common header.
>>>
>>> Also, x2apic and gicc are respectively x86-specific and arm-specific. So
>>> I
>>> think we should move the parsing in a separate arch-depend function to
>>> avoid
>>> those ifdery.
>>>
>>> By that I mean having a function acpi_table_arch_parse_srat that will
>>> parse
>>> x2apci on x86 and gicc on ARM. Jan, what do you think?
>>
>>
>> Linux also follows similar approach
>>
>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/acpi.h?id=refs/tags/v4.10#n265
>
>
> So? What are you trying to prove?
>
> The linux version is much readable than yours. Anyway, we should limit
> CONFIG_{X86,ARM} ifdefery in common code.
>
> Currently, I see no point to have those ifdefery when it is possible to add
> an arch-depend function.

This is because in xen we have another level of config CONFIG_ACPI_NUMA.
I have plans to reuse cpu and memory part next revision.

Regards
Vijay
Julien Grall March 3, 2017, 1:52 p.m. UTC | #5
On 03/03/17 13:50, Vijay Kilari wrote:
> On Fri, Mar 3, 2017 at 7:14 PM, Julien Grall <julien.grall@arm.com> wrote:
>>>> This is quite disgusting. We should avoid any #ifdef CONFIG_{X86,ARM} in
>>>> common header.
>>>>
>>>> Also, x2apic and gicc are respectively x86-specific and arm-specific. So
>>>> I
>>>> think we should move the parsing in a separate arch-depend function to
>>>> avoid
>>>> those ifdery.
>>>>
>>>> By that I mean having a function acpi_table_arch_parse_srat that will
>>>> parse
>>>> x2apci on x86 and gicc on ARM. Jan, what do you think?
>>>
>>>
>>> Linux also follows similar approach
>>>
>>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/acpi.h?id=refs/tags/v4.10#n265
>>
>>
>> So? What are you trying to prove?
>>
>> The linux version is much readable than yours. Anyway, we should limit
>> CONFIG_{X86,ARM} ifdefery in common code.
>>
>> Currently, I see no point to have those ifdefery when it is possible to add
>> an arch-depend function.
>
> This is because in xen we have another level of config CONFIG_ACPI_NUMA.
> I have plans to reuse cpu and memory part next revision.

This does not explain why you want to do like Linux.
Vijay Kilari March 3, 2017, 2:45 p.m. UTC | #6
On Fri, Mar 3, 2017 at 7:22 PM, Julien Grall <julien.grall@arm.com> wrote:
>
>
> On 03/03/17 13:50, Vijay Kilari wrote:
>>
>> On Fri, Mar 3, 2017 at 7:14 PM, Julien Grall <julien.grall@arm.com> wrote:
>>>>>
>>>>> This is quite disgusting. We should avoid any #ifdef CONFIG_{X86,ARM}
>>>>> in
>>>>> common header.
>>>>>
>>>>> Also, x2apic and gicc are respectively x86-specific and arm-specific.
>>>>> So
>>>>> I
>>>>> think we should move the parsing in a separate arch-depend function to
>>>>> avoid
>>>>> those ifdery.
>>>>>
>>>>> By that I mean having a function acpi_table_arch_parse_srat that will
>>>>> parse
>>>>> x2apci on x86 and gicc on ARM. Jan, what do you think?
>>>>
>>>>
>>>>
>>>> Linux also follows similar approach
>>>>
>>>>
>>>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/acpi.h?id=refs/tags/v4.10#n265
>>>
>>>
>>>
>>> So? What are you trying to prove?
>>>
>>> The linux version is much readable than yours. Anyway, we should limit
>>> CONFIG_{X86,ARM} ifdefery in common code.
>>>
>>> Currently, I see no point to have those ifdefery when it is possible to
>>> add
>>> an arch-depend function.
>>
>>
>> This is because in xen we have another level of config CONFIG_ACPI_NUMA.
>> I have plans to reuse cpu and memory part next revision.
>
>
> This does not explain why you want to do like Linux.

Basically want to reuse xen/drivers/acpi/numa.c which is common for
both x86 and ARM.
If not, then we have move some arch specific as you mentioned.

I have another idea where in, if all the NUMA ACPI code is programmed under
CONFIG_NUMA and only initialization is kept under CONFIG_ACPI_NUMA
similar to x86
then we don't need to pollute this header much and limit the changes.

I will try to implement this and see how simple it can go and let you know. OK?

>
> --
> Julien Grall
Julien Grall March 3, 2017, 2:52 p.m. UTC | #7
On 03/03/17 14:45, Vijay Kilari wrote:
> On Fri, Mar 3, 2017 at 7:22 PM, Julien Grall <julien.grall@arm.com> wrote:
>>
>>
>> On 03/03/17 13:50, Vijay Kilari wrote:
>>>
>>> On Fri, Mar 3, 2017 at 7:14 PM, Julien Grall <julien.grall@arm.com> wrote:
>>>>>>
>>>>>> This is quite disgusting. We should avoid any #ifdef CONFIG_{X86,ARM}
>>>>>> in
>>>>>> common header.
>>>>>>
>>>>>> Also, x2apic and gicc are respectively x86-specific and arm-specific.
>>>>>> So
>>>>>> I
>>>>>> think we should move the parsing in a separate arch-depend function to
>>>>>> avoid
>>>>>> those ifdery.
>>>>>>
>>>>>> By that I mean having a function acpi_table_arch_parse_srat that will
>>>>>> parse
>>>>>> x2apci on x86 and gicc on ARM. Jan, what do you think?
>>>>>
>>>>>
>>>>>
>>>>> Linux also follows similar approach
>>>>>
>>>>>
>>>>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/acpi.h?id=refs/tags/v4.10#n265
>>>>
>>>>
>>>>
>>>> So? What are you trying to prove?
>>>>
>>>> The linux version is much readable than yours. Anyway, we should limit
>>>> CONFIG_{X86,ARM} ifdefery in common code.
>>>>
>>>> Currently, I see no point to have those ifdefery when it is possible to
>>>> add
>>>> an arch-depend function.
>>>
>>>
>>> This is because in xen we have another level of config CONFIG_ACPI_NUMA.
>>> I have plans to reuse cpu and memory part next revision.
>>
>>
>> This does not explain why you want to do like Linux.
>
> Basically want to reuse xen/drivers/acpi/numa.c which is common for
> both x86 and ARM.
> If not, then we have move some arch specific as you mentioned.

I think you misunderstood what I suggested. I only asked to do something 
like:

int __init acpi_numa_init(void)
{
	if (!acpi_parse_table(....)) {
		acpi_table_parse_srat(TYPE_CPU_AFFINITY);
		acpi_table_parse_srat(TYPE_MEMORY_AFFINITY);
		acpi_table_arch_parse_srat();
	}
}

And then for x86

void acpi_table_arch_parse_start(void)
{
	acpi_table_parse_srat(TYPE_X2APIC_CPU_AFFINITY);
}

And for ARM

void acpi_table_arch_parse_start(void)
{
	acpi_table_parse_srat(TYPE_GICC_AFFINITY);
}


The code is still as common but a function is called for arch specific 
setup. This does not require any ifdefery.

>
> I have another idea where in, if all the NUMA ACPI code is programmed under
> CONFIG_NUMA and only initialization is kept under CONFIG_ACPI_NUMA
> similar to x86
> then we don't need to pollute this header much and limit the changes.
>
> I will try to implement this and see how simple it can go and let you know. OK?

I don't want to see the common header polluted with #ifdef CONFIG_X86 
and #ifdef CONFIG_ARM. This is just not right.

Cheers,
Vijay Kilari March 3, 2017, 3:16 p.m. UTC | #8
On Fri, Mar 3, 2017 at 8:22 PM, Julien Grall <julien.grall@arm.com> wrote:
>
>
> On 03/03/17 14:45, Vijay Kilari wrote:
>>
>> On Fri, Mar 3, 2017 at 7:22 PM, Julien Grall <julien.grall@arm.com> wrote:
>>>
>>>
>>>
>>> On 03/03/17 13:50, Vijay Kilari wrote:
>>>>
>>>>
>>>> On Fri, Mar 3, 2017 at 7:14 PM, Julien Grall <julien.grall@arm.com>
>>>> wrote:
>>>>>>>
>>>>>>>
>>>>>>> This is quite disgusting. We should avoid any #ifdef CONFIG_{X86,ARM}
>>>>>>> in
>>>>>>> common header.
>>>>>>>
>>>>>>> Also, x2apic and gicc are respectively x86-specific and arm-specific.
>>>>>>> So
>>>>>>> I
>>>>>>> think we should move the parsing in a separate arch-depend function
>>>>>>> to
>>>>>>> avoid
>>>>>>> those ifdery.
>>>>>>>
>>>>>>> By that I mean having a function acpi_table_arch_parse_srat that will
>>>>>>> parse
>>>>>>> x2apci on x86 and gicc on ARM. Jan, what do you think?
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Linux also follows similar approach
>>>>>>
>>>>>>
>>>>>>
>>>>>> https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/include/linux/acpi.h?id=refs/tags/v4.10#n265
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> So? What are you trying to prove?
>>>>>
>>>>> The linux version is much readable than yours. Anyway, we should limit
>>>>> CONFIG_{X86,ARM} ifdefery in common code.
>>>>>
>>>>> Currently, I see no point to have those ifdefery when it is possible to
>>>>> add
>>>>> an arch-depend function.
>>>>
>>>>
>>>>
>>>> This is because in xen we have another level of config CONFIG_ACPI_NUMA.
>>>> I have plans to reuse cpu and memory part next revision.
>>>
>>>
>>>
>>> This does not explain why you want to do like Linux.
>>
>>
>> Basically want to reuse xen/drivers/acpi/numa.c which is common for
>> both x86 and ARM.
>> If not, then we have move some arch specific as you mentioned.
>
>
> I think you misunderstood what I suggested. I only asked to do something
> like:

Got it.
>
> int __init acpi_numa_init(void)
> {
>         if (!acpi_parse_table(....)) {
>                 acpi_table_parse_srat(TYPE_CPU_AFFINITY);

This is not defined for ARM. We have to make this also arch specific.
So all arch specific code from xen/drivers/acpi/numa.c should be moved
to arch specific to xen/arch/x86/srat.c

>                 acpi_table_parse_srat(TYPE_MEMORY_AFFINITY);
>                 acpi_table_arch_parse_srat();
>         }
> }
>
> And then for x86
>
> void acpi_table_arch_parse_start(void)
> {
>         acpi_table_parse_srat(TYPE_X2APIC_CPU_AFFINITY);
> }
>
> And for ARM
>
> void acpi_table_arch_parse_start(void)
> {
>         acpi_table_parse_srat(TYPE_GICC_AFFINITY);
> }
>
>
> The code is still as common but a function is called for arch specific
> setup. This does not require any ifdefery.
>
>>
>> I have another idea where in, if all the NUMA ACPI code is programmed
>> under
>> CONFIG_NUMA and only initialization is kept under CONFIG_ACPI_NUMA
>> similar to x86
>> then we don't need to pollute this header much and limit the changes.
>>
>> I will try to implement this and see how simple it can go and let you
>> know. OK?
>
>
> I don't want to see the common header polluted with #ifdef CONFIG_X86 and
> #ifdef CONFIG_ARM. This is just not right.
>
> Cheers,
>
> --
> Julien Grall
Jan Beulich March 3, 2017, 3:22 p.m. UTC | #9
>>> On 03.03.17 at 16:16, <vijay.kilari@gmail.com> wrote:
> On Fri, Mar 3, 2017 at 8:22 PM, Julien Grall <julien.grall@arm.com> wrote:
>> int __init acpi_numa_init(void)
>> {
>>         if (!acpi_parse_table(....)) {
>>                 acpi_table_parse_srat(TYPE_CPU_AFFINITY);
> 
> This is not defined for ARM. We have to make this also arch specific.
> So all arch specific code from xen/drivers/acpi/numa.c should be moved
> to arch specific to xen/arch/x86/srat.c

There surely is a way to specify processor affinity on ARM?

Jan
Vijay Kilari March 10, 2017, 10:53 a.m. UTC | #10
On Fri, Mar 3, 2017 at 8:52 PM, Jan Beulich <JBeulich@suse.com> wrote:
>>>> On 03.03.17 at 16:16, <vijay.kilari@gmail.com> wrote:
>> On Fri, Mar 3, 2017 at 8:22 PM, Julien Grall <julien.grall@arm.com> wrote:
>>> int __init acpi_numa_init(void)
>>> {
>>>         if (!acpi_parse_table(....)) {
>>>                 acpi_table_parse_srat(TYPE_CPU_AFFINITY);
>>
>> This is not defined for ARM. We have to make this also arch specific.
>> So all arch specific code from xen/drivers/acpi/numa.c should be moved
>> to arch specific to xen/arch/x86/srat.c
>
> There surely is a way to specify processor affinity on ARM?

In ARM, we use ACPI_SRAT_TYPE_GICC_AFFINITY type entry in SRAT
to extract cpu to proximity mapping
diff mbox

Patch

diff --git a/xen/arch/arm/acpi_numa.c b/xen/arch/arm/acpi_numa.c
index 3ee87f2..f659275 100644
--- a/xen/arch/arm/acpi_numa.c
+++ b/xen/arch/arm/acpi_numa.c
@@ -105,6 +105,61 @@  static int __init acpi_parse_madt_handler(struct acpi_subtable_header *header,
     return 0;
 }
 
+/* Callback for Proximity Domain -> ACPI processor UID mapping */
+void __init acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa)
+{
+    int pxm, node;
+    u64 mpidr = 0;
+    static u32 cpus_in_srat;
+
+    if ( srat_disabled() )
+        return;
+
+    if ( pa->header.length < sizeof(struct acpi_srat_gicc_affinity) )
+    {
+        printk(XENLOG_WARNING "SRAT: Invalid SRAT header length: %d\n",
+               pa->header.length);
+        bad_srat();
+        return;
+    }
+
+    if ( !(pa->flags & ACPI_SRAT_GICC_ENABLED) )
+        return;
+
+    if ( cpus_in_srat >= NR_CPUS )
+    {
+        printk(XENLOG_WARNING
+               "SRAT: cpu_to_node_map[%d] is too small to fit all cpus\n",
+               NR_CPUS);
+        return;
+    }
+
+    pxm = pa->proximity_domain;
+    node = setup_node(pxm);
+    if ( node == NUMA_NO_NODE || node >= MAX_NUMNODES )
+    {
+        printk(XENLOG_WARNING "SRAT: Too many proximity domains %d\n", pxm);
+        bad_srat();
+        return;
+    }
+
+    mpidr = acpi_get_cpu_mpidr(pa->acpi_processor_uid);
+    if ( mpidr == MPIDR_INVALID )
+    {
+        printk(XENLOG_WARNING
+               "SRAT: PXM %d with ACPI ID %d has no valid MPIDR in MADT\n",
+               pxm, pa->acpi_processor_uid);
+        bad_srat();
+        return;
+    }
+
+    node_set(node, numa_nodes_parsed);
+    cpus_in_srat++;
+    acpi_numa = 1;
+    printk(XENLOG_INFO "SRAT: PXM %d -> MPIDR 0x%lx -> Node %d\n",
+           pxm, mpidr, node);
+}
+
 void __init acpi_map_uid_to_mpidr(void)
 {
     int i;
diff --git a/xen/drivers/acpi/numa.c b/xen/drivers/acpi/numa.c
index 50bf9f8..ce22e88 100644
--- a/xen/drivers/acpi/numa.c
+++ b/xen/drivers/acpi/numa.c
@@ -25,9 +25,11 @@ 
 #include <xen/init.h>
 #include <xen/types.h>
 #include <xen/errno.h>
+#include <xen/mm.h>
 #include <xen/acpi.h>
 #include <xen/numa.h>
 #include <acpi/acmacros.h>
+#include <asm/mm.h>
 
 #define ACPI_NUMA	0x80000000
 #define _COMPONENT	ACPI_NUMA
@@ -105,6 +107,21 @@  void __init acpi_table_print_srat_entry(struct acpi_subtable_header * header)
 		}
 #endif				/* ACPI_DEBUG_OUTPUT */
 		break;
+       case ACPI_SRAT_TYPE_GICC_AFFINITY:
+#ifdef ACPI_DEBUG_OUTPUT
+		{
+			struct acpi_srat_gicc_affinity *p =
+			    (struct acpi_srat_gicc_affinity *)header;
+			ACPI_DEBUG_PRINT((ACPI_DB_INFO,
+					  "SRAT Processor (acpi id[0x%04x]) in"
+					  " proximity domain %d %s\n",
+					  p->acpi_processor_uid,
+					  p->proximity_domain,
+					  (p->flags & ACPI_SRAT_GICC_ENABLED) ?
+					  "enabled" : "disabled");
+		}
+#endif                         /* ACPI_DEBUG_OUTPUT */
+               break;
 	default:
 		printk(KERN_WARNING PREFIX
 		       "Found unsupported SRAT entry (type = %#x)\n",
@@ -185,6 +202,24 @@  int __init acpi_parse_srat(struct acpi_table_header *table)
 	return 0;
 }
 
+static int __init
+acpi_parse_gicc_affinity(struct acpi_subtable_header *header,
+			 const unsigned long end)
+{
+	const struct acpi_srat_gicc_affinity *processor_affinity
+			= (struct acpi_srat_gicc_affinity *)header;
+
+	if (!processor_affinity)
+		return -EINVAL;
+
+	acpi_table_print_srat_entry(header);
+
+	/* let architecture-dependent part to do it */
+	acpi_numa_gicc_affinity_init(processor_affinity);
+
+	return 0;
+}
+
 int __init
 acpi_table_parse_srat(int id, acpi_madt_entry_handler handler,
 		      unsigned int max_entries)
@@ -205,6 +240,8 @@  int __init acpi_numa_init(void)
 		acpi_table_parse_srat(ACPI_SRAT_TYPE_MEMORY_AFFINITY,
 				      acpi_parse_memory_affinity,
 				      NR_NODE_MEMBLKS);
+		acpi_table_parse_srat(ACPI_SRAT_TYPE_GICC_AFFINITY,
+				      acpi_parse_gicc_affinity, NR_CPUS);
 	}
 
 	/* SLIT: System Locality Information Table */
diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c
index 7199047..7046816 100644
--- a/xen/drivers/acpi/osl.c
+++ b/xen/drivers/acpi/osl.c
@@ -29,6 +29,7 @@ 
 #include <xen/pfn.h>
 #include <xen/types.h>
 #include <xen/errno.h>
+#include <xen/mm.h>
 #include <xen/acpi.h>
 #include <xen/numa.h>
 #include <acpi/acmacros.h>
@@ -39,6 +40,7 @@ 
 #include <xen/efi.h>
 #include <xen/vmap.h>
 #include <xen/kconfig.h>
+#include <asm/mm.h>
 
 #define _COMPONENT		ACPI_OS_SERVICES
 ACPI_MODULE_NAME("osl")
diff --git a/xen/include/acpi/actbl1.h b/xen/include/acpi/actbl1.h
index e199136..b84bfba 100644
--- a/xen/include/acpi/actbl1.h
+++ b/xen/include/acpi/actbl1.h
@@ -949,7 +949,8 @@  enum acpi_srat_type {
 	ACPI_SRAT_TYPE_CPU_AFFINITY = 0,
 	ACPI_SRAT_TYPE_MEMORY_AFFINITY = 1,
 	ACPI_SRAT_TYPE_X2APIC_CPU_AFFINITY = 2,
-	ACPI_SRAT_TYPE_RESERVED = 3	/* 3 and greater are reserved */
+	ACPI_SRAT_TYPE_GICC_AFFINITY = 3,
+	ACPI_SRAT_TYPE_RESERVED = 4	/* 4 and greater are reserved */
 };
 
 /*
@@ -1007,6 +1008,20 @@  struct acpi_srat_x2apic_cpu_affinity {
 
 #define ACPI_SRAT_CPU_ENABLED       (1)	/* 00: Use affinity structure */
 
+/* 3: GICC Affinity (ACPI 5.1) */
+
+struct acpi_srat_gicc_affinity {
+	struct acpi_subtable_header header;
+	u32 proximity_domain;
+	u32 acpi_processor_uid;
+	u32 flags;
+	u32 clock_domain;
+};
+
+/* Flags for struct acpi_srat_gicc_affinity */
+
+#define ACPI_SRAT_GICC_ENABLED     (1)  /* 00: Use affinity structure */
+
 /* Reset to default packing */
 
 #pragma pack()
diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h
index 30ec0ee..67fe1bb 100644
--- a/xen/include/xen/acpi.h
+++ b/xen/include/xen/acpi.h
@@ -92,10 +92,49 @@  void acpi_table_print_srat_entry (struct acpi_subtable_header *srat);
 
 /* the following four functions are architecture-dependent */
 void acpi_numa_slit_init (struct acpi_table_slit *slit);
+#if defined(CONFIG_X86)
 void acpi_numa_processor_affinity_init(const struct acpi_srat_cpu_affinity *);
 void acpi_numa_x2apic_affinity_init(const struct acpi_srat_x2apic_cpu_affinity *);
 void acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity *);
 void acpi_numa_arch_fixup(void);
+static inline void
+acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa)
+{
+	return;
+}
+#elif defined(CONFIG_ARM)
+static inline void
+acpi_numa_processor_affinity_init(const struct acpi_srat_cpu_affinity *cpu_aff)
+{
+	return;
+}
+static inline void
+acpi_numa_x2apic_affinity_init(const struct acpi_srat_x2apic_cpu_affinity *x2apic)
+{
+	return;
+}
+#if defined(CONFIG_ACPI_NUMA)
+void acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa);
+void acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity *);
+void acpi_numa_arch_fixup(void);
+#else
+static inline void
+acpi_numa_gicc_affinity_init(const struct acpi_srat_gicc_affinity *pa)
+{
+	return;
+}
+static inline void
+acpi_numa_memory_affinity_init(const struct acpi_srat_mem_affinity *ma)
+{
+	return;
+}
+static inline void
+acpi_numa_arch_fixup(void)
+{
+	return;
+}
+#endif /* CONFIG_ACPI_NUMA */
+#endif /* CONFIG_X86 */
 
 #ifdef CONFIG_ACPI_HOTPLUG_CPU
 /* Arch dependent functions for cpu hotplug support */