arm/arm64: gicv3: support up to 8 redistributor regions
PATCH v3 1/1 arm/arm64: gicv3: support up to 8 redistributor regions
We need to support at least two redistributor regions in order to support more than 123 vcpus (we select 8 because that should be plenty). Also bump NR_CPUS to 512, since that's what KVM currently supports.
---
v3:
- add missing '++i' to the main loop in gicv3_set_redist_base [Christoffer]
v2:
- neater implementation by handling the number of redist regions more generally [Peter]
lib/arm/asm/gic-v3.h | 3 +++ lib/arm/asm/setup.h | 2 +- lib/arm/gic-v3.c | 24 ++++++++++++++---------- lib/arm/gic.c | 14 +++++++++----- 4 files changed, 27 insertions(+), 16 deletions(-)
lib/arm/asm/gic-v3.h +3 -0
@@ -49,8 +49,11 @@#include <asm/smp.h> #include <asm/io.h> +#define GICV3_NR_REDISTS 8 +struct gicv3_data {void *dist_base; +void *redist_bases[GICV3_NR_REDISTS ];void *redist_base[NR_CPUS ];unsigned int irq_nr; };
lib/arm/asm/setup.h +1 -1
@@ -9,7 +9,7 @@#include <asm/page.h> #include <asm/pgtable-hwdef.h> -#define NR_CPUS 255 +#define NR_CPUS 512extern u64 cpus[NR_CPUS ];/* per-cpu IDs (MPIDRs) */ extern int nr_cpus;
lib/arm/gic-v3.c +14 -10
@@ -9,17 +9,21 @@void gicv3_set_redist_base (size_t stride) {u32 aff =mpidr_compress (get_mpidr ()); -void *ptr = gicv3_data.redist_base[0 ];u64 typer; - -do { - typer =gicv3_read_typer (ptr +GICR_TYPER ); -if ((typer >>32 ) == aff) { -gicv3_redist_base () = ptr; -return ; - } - ptr += stride;/* skip RD_base, SGI_base, etc. */ - }while (!(typer &GICR_TYPER_LAST )); +int i =0 ; + +while (gicv3_data.redist_bases[i]) { +void *ptr = gicv3_data.redist_bases[i]; +do { + typer =gicv3_read_typer (ptr +GICR_TYPER ); +if ((typer >>32 ) == aff) { +gicv3_redist_base () = ptr; +return ; + } + ptr += stride;/* skip RD_base, SGI_base, etc. */ + }while (!(typer &GICR_TYPER_LAST )); + ++i; + }/* should never reach here */ assert (0 );
lib/arm/gic.c +9 -5
@@ -49,7 +49,7 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2)struct dt_pbus_reg reg;struct dt_device gic;struct dt_bus bus; -int node, ret; +int node, ret, i;dt_bus_init_defaults (&bus);dt_device_init (&gic, &bus,NULL );
@@ -66,9 +66,13 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2)assert (ret ==0 ); *base1 =ioremap (reg.addr, reg.size); - ret =dt_pbus_translate (&gic,1 , ®); -assert (ret ==0 ); - *base2 =ioremap (reg.addr, reg.size); +for (i =0 ; i <GICV3_NR_REDISTS ; ++i) { + ret =dt_pbus_translate (&gic, i +1 , ®); +if (ret == -FDT_ERR_NOTFOUND ) +break ; +assert (ret ==0 ); + base2[i] =ioremap (reg.addr, reg.size); + }return true; }
@@ -82,7 +86,7 @@ int gicv2_init(void)int gicv3_init (void ) {return gic_get_dt_bases ("arm,gic-v3" , &gicv3_data.dist_base, - &gicv3_data.redist_base[0 ]); + &gicv3_data.redist_bases[0 ]); }int gic_version (void )
Signature · 1 line
2.17.1
Quoted 7 lines · Andrew Jones
We need to support at least two redistributor regions in order to support more than 123 vcpus (we select 8 because that should be plenty). Also bump
NR_CPUSto 512, since that's what KVM currently supports.Signed-off-by Andrew Jones <[email protected]>Tested-by Christoffer Dall <[email protected]>
You can also add my R-B:
Quoted 121 lines
---
v3:
- add missing '++i' to the main loop ingicv3_set_redist_base[Christoffer]
v2:
- neater implementation by handling the number of redist regions more generally [Peter]lib/arm/asm/gic-v3.h | 3 +++ lib/arm/asm/setup.h | 2 +- lib/arm/gic-v3.c | 24 ++++++++++++++---------- lib/arm/gic.c | 14 +++++++++----- 4 files changed, 27 insertions(+), 16 deletions(-)lib/arm/asm/gic-v3.h +3
-0@@ -49,8 +49,11 @@#include <asm/smp.h> #include <asm/io.h> +#define GICV3_NR_REDISTS 8 +struct gicv3_data {void *dist_base; +void *redist_bases[GICV3_NR_REDISTS ];void *redist_base[NR_CPUS ];unsigned int irq_nr; };lib/arm/asm/setup.h +1
-1@@ -9,7 +9,7 @@#include <asm/page.h> #include <asm/pgtable-hwdef.h> -#define NR_CPUS 255 +#define NR_CPUS 512extern u64 cpus[NR_CPUS ];/* per-cpu IDs (MPIDRs) */ extern int nr_cpus;lib/arm/gic-v3.c +14
-10@@ -9,17 +9,21 @@void gicv3_set_redist_base (size_t stride) {u32 aff =mpidr_compress (get_mpidr ()); -void *ptr = gicv3_data.redist_base[0 ];u64 typer; - -do { - typer =gicv3_read_typer (ptr +GICR_TYPER ); -if ((typer >>32 ) == aff) { -gicv3_redist_base () = ptr; -return ; - } - ptr += stride;/* skip RD_base, SGI_base, etc. */ - }while (!(typer &GICR_TYPER_LAST )); +int i =0 ; + +while (gicv3_data.redist_bases[i]) { +void *ptr = gicv3_data.redist_bases[i]; +do { + typer =gicv3_read_typer (ptr +GICR_TYPER ); +if ((typer >>32 ) == aff) { +gicv3_redist_base () = ptr; +return ; + } + ptr += stride;/* skip RD_base, SGI_base, etc. */ + }while (!(typer &GICR_TYPER_LAST )); + ++i; + }/* should never reach here */ assert (0 );lib/arm/gic.c +9
-5@@ -49,7 +49,7 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2)struct dt_pbus_reg reg;struct dt_device gic;struct dt_bus bus; -int node, ret; +int node, ret, i;dt_bus_init_defaults (&bus);dt_device_init (&gic, &bus,NULL );@@ -66,9 +66,13 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2)assert (ret ==0 ); *base1 =ioremap (reg.addr, reg.size); - ret =dt_pbus_translate (&gic,1 , ®); -assert (ret ==0 ); - *base2 =ioremap (reg.addr, reg.size); +for (i =0 ; i <GICV3_NR_REDISTS ; ++i) { + ret =dt_pbus_translate (&gic, i +1 , ®); +if (ret == -FDT_ERR_NOTFOUND ) +break ; +assert (ret ==0 ); + base2[i] =ioremap (reg.addr, reg.size); + }return true; }@@ -82,7 +86,7 @@ int gicv2_init(void)int gicv3_init (void ) {return gic_get_dt_bases ("arm,gic-v3" , &gicv3_data.dist_base, - &gicv3_data.redist_base[0 ]); + &gicv3_data.redist_bases[0 ]); }int gic_version (void )Signature · 1 line
2.17.1
Quoted 118 lines · Andrew Jones
We need to support at least two redistributor regions in order to support more than 123 vcpus (we select 8 because that should be plenty). Also bump
NR_CPUSto 512, since that's what KVM currently supports.Signed-off-by Andrew Jones <[email protected]>Tested-by Christoffer Dall <[email protected]>---
v3:
- add missing '++i' to the main loop ingicv3_set_redist_base[Christoffer]
v2:
- neater implementation by handling the number of redist regions more generally [Peter]lib/arm/asm/gic-v3.h | 3 +++ lib/arm/asm/setup.h | 2 +- lib/arm/gic-v3.c | 24 ++++++++++++++---------- lib/arm/gic.c | 14 +++++++++----- 4 files changed, 27 insertions(+), 16 deletions(-)lib/arm/asm/gic-v3.h +3
-0@@ -49,8 +49,11 @@#include <asm/smp.h> #include <asm/io.h> +#define GICV3_NR_REDISTS 8 +struct gicv3_data {void *dist_base; +void *redist_bases[GICV3_NR_REDISTS ];void *redist_base[NR_CPUS ];unsigned int irq_nr; };lib/arm/asm/setup.h +1
-1@@ -9,7 +9,7 @@#include <asm/page.h> #include <asm/pgtable-hwdef.h> -#define NR_CPUS 255 +#define NR_CPUS 512extern u64 cpus[NR_CPUS ];/* per-cpu IDs (MPIDRs) */ extern int nr_cpus;lib/arm/gic-v3.c +14
-10@@ -9,17 +9,21 @@void gicv3_set_redist_base (size_t stride) {u32 aff =mpidr_compress (get_mpidr ()); -void *ptr = gicv3_data.redist_base[0 ];u64 typer; - -do { - typer =gicv3_read_typer (ptr +GICR_TYPER ); -if ((typer >>32 ) == aff) { -gicv3_redist_base () = ptr; -return ; - } - ptr += stride;/* skip RD_base, SGI_base, etc. */ - }while (!(typer &GICR_TYPER_LAST )); +int i =0 ; + +while (gicv3_data.redist_bases[i]) { +void *ptr = gicv3_data.redist_bases[i]; +do { + typer =gicv3_read_typer (ptr +GICR_TYPER ); +if ((typer >>32 ) == aff) { +gicv3_redist_base () = ptr; +return ; + } + ptr += stride;/* skip RD_base, SGI_base, etc. */ + }while (!(typer &GICR_TYPER_LAST )); + ++i; + }/* should never reach here */ assert (0 );lib/arm/gic.c +8
-4@@ -49,7 +49,7 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2)struct dt_pbus_reg reg;struct dt_device gic;struct dt_bus bus; -int node, ret; +int node, ret, i;dt_bus_init_defaults (&bus);dt_device_init (&gic, &bus,NULL );@@ -66,9 +66,13 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2)assert (ret ==0 ); *base1 =ioremap (reg.addr, reg.size); - ret =dt_pbus_translate (&gic,1 , ®); -assert (ret ==0 ); - *base2 =ioremap (reg.addr, reg.size); +for (i =0 ; i <GICV3_NR_REDISTS ; ++i) { + ret =dt_pbus_translate (&gic, i +1 , ®); +if (ret == -FDT_ERR_NOTFOUND ) +break ; +assert (ret ==0 ); + base2[i] =ioremap (reg.addr, reg.size); + }return true; }
lib/arm/gic.c int gicv2_init(void) · line 92
Quoted 8 lines
lib/arm/gic.c +1
-1@@ -82,7 +86,7 @@ int gicv2_init(void)int gicv3_init (void ) {return gic_get_dt_bases ("arm,gic-v3" , &gicv3_data.dist_base, - &gicv3_data.redist_base[0 ]); + &gicv3_data.redist_bases[0 ]); }int gic_version (void )
Queued, thanks.
Paolo