* [PATCH kvm-unit-tests] arm/arm64: gicv3: support two redistributor regions
@ 2018-09-03 16:45 Andrew Jones
2018-09-04 0:49 ` Peter Maydell
0 siblings, 1 reply; 3+ messages in thread
From: Andrew Jones @ 2018-09-03 16:45 UTC (permalink / raw)
To: kvmarm; +Cc: marc.zyngier
We need to support two redistributor regions in order to support
more than 123 vcpus. Also bump NR_CPUS to 512, since that's what
KVM currently supports.
Signed-off-by: Andrew Jones <drjones@redhat.com>
---
So far only regression tested on TCG.
lib/arm/asm/gic-v3.h | 20 +++++++++++++++++---
lib/arm/asm/setup.h | 2 +-
lib/arm/gic-v3.c | 39 +++++++++++++++++++++++++++++----------
lib/arm/gic.c | 16 +++++++++++++---
4 files changed, 60 insertions(+), 17 deletions(-)
diff --git a/lib/arm/asm/gic-v3.h b/lib/arm/asm/gic-v3.h
index 1dceb9541f62..a04e58bd438b 100644
--- a/lib/arm/asm/gic-v3.h
+++ b/lib/arm/asm/gic-v3.h
@@ -49,16 +49,30 @@
#include <asm/smp.h>
#include <asm/io.h>
+#define GICV3_REDIST0_NR_CPUS 123
+
struct gicv3_data {
void *dist_base;
- void *redist_base[NR_CPUS];
+ void *redist_base[GICV3_REDIST0_NR_CPUS];
+ void *redist2_base[NR_CPUS - GICV3_REDIST0_NR_CPUS];
unsigned int irq_nr;
};
extern struct gicv3_data gicv3_data;
+#define gicv3_redist_base() \
+({ \
+ int __cpu = smp_processor_id(); \
+ void *__base; \
+ \
+ if (__cpu < GICV3_REDIST0_NR_CPUS) \
+ __base = gicv3_data.redist_base[__cpu]; \
+ else \
+ __base = gicv3_data.redist2_base[__cpu - GICV3_REDIST0_NR_CPUS]; \
+ \
+ __base; \
+})
#define gicv3_dist_base() (gicv3_data.dist_base)
-#define gicv3_redist_base() (gicv3_data.redist_base[smp_processor_id()])
-#define gicv3_sgi_base() (gicv3_data.redist_base[smp_processor_id()] + SZ_64K)
+#define gicv3_sgi_base() (gicv3_redist_base() + SZ_64K)
extern int gicv3_init(void);
extern void gicv3_enable_defaults(void);
diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h
index b57ea13b9dd2..3215814603e4 100644
--- a/lib/arm/asm/setup.h
+++ b/lib/arm/asm/setup.h
@@ -9,7 +9,7 @@
#include <asm/page.h>
#include <asm/pgtable-hwdef.h>
-#define NR_CPUS 255
+#define NR_CPUS 512
extern u64 cpus[NR_CPUS]; /* per-cpu IDs (MPIDRs) */
extern int nr_cpus;
diff --git a/lib/arm/gic-v3.c b/lib/arm/gic-v3.c
index 9b3fa5730478..e7a48c988cab 100644
--- a/lib/arm/gic-v3.c
+++ b/lib/arm/gic-v3.c
@@ -6,20 +6,39 @@
#include <asm/gic.h>
#include <asm/io.h>
+static void __gicv3_set_redist_base(void *ptr)
+{
+ int cpu = smp_processor_id();
+
+ if (cpu < GICV3_REDIST0_NR_CPUS)
+ gicv3_data.redist_base[cpu] = ptr;
+ else
+ gicv3_data.redist2_base[cpu - GICV3_REDIST0_NR_CPUS] = ptr;
+}
+
void gicv3_set_redist_base(size_t stride)
{
u32 aff = mpidr_compress(get_mpidr());
- void *ptr = gicv3_data.redist_base[0];
+ void *redist_base[] = {
+ gicv3_data.redist_base[0],
+ gicv3_data.redist2_base[0],
+ };
+ void *ptr;
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 (redist_base[i]) {
+ ptr = redist_base[i];
+ do {
+ typer = gicv3_read_typer(ptr + GICR_TYPER);
+ if ((typer >> 32) == aff) {
+ __gicv3_set_redist_base(ptr);
+ return;
+ }
+ ptr += stride; /* skip RD_base, SGI_base, etc. */
+ } while (!(typer & GICR_TYPER_LAST));
+ ++i;
+ }
/* should never reach here */
assert(0);
diff --git a/lib/arm/gic.c b/lib/arm/gic.c
index 59273b1716d6..81973c47d487 100644
--- a/lib/arm/gic.c
+++ b/lib/arm/gic.c
@@ -44,7 +44,7 @@ static const struct gic_common_ops gicv3_common_ops = {
* Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt
*/
static bool
-gic_get_dt_bases(const char *compatible, void **base1, void **base2)
+gic_get_dt_bases(const char *compatible, void **base1, void **base2, void **base3)
{
struct dt_pbus_reg reg;
struct dt_device gic;
@@ -70,19 +70,29 @@ gic_get_dt_bases(const char *compatible, void **base1, void **base2)
assert(ret == 0);
*base2 = ioremap(reg.addr, reg.size);
+ if (base3) {
+ ret = dt_pbus_translate(&gic, 2, ®);
+ if (ret != -FDT_ERR_NOTFOUND) {
+ assert(ret == 0);
+ *base3 = ioremap(reg.addr, reg.size);
+ } else {
+ *base3 = NULL;
+ }
+ }
+
return true;
}
int gicv2_init(void)
{
return gic_get_dt_bases("arm,cortex-a15-gic",
- &gicv2_data.dist_base, &gicv2_data.cpu_base);
+ &gicv2_data.dist_base, &gicv2_data.cpu_base, NULL);
}
int gicv3_init(void)
{
return gic_get_dt_bases("arm,gic-v3", &gicv3_data.dist_base,
- &gicv3_data.redist_base[0]);
+ &gicv3_data.redist_base[0], &gicv3_data.redist2_base[0]);
}
int gic_version(void)
--
2.17.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH kvm-unit-tests] arm/arm64: gicv3: support two redistributor regions
2018-09-03 16:45 [PATCH kvm-unit-tests] arm/arm64: gicv3: support two redistributor regions Andrew Jones
@ 2018-09-04 0:49 ` Peter Maydell
2018-09-04 7:02 ` Andrew Jones
0 siblings, 1 reply; 3+ messages in thread
From: Peter Maydell @ 2018-09-04 0:49 UTC (permalink / raw)
To: Andrew Jones; +Cc: Marc Zyngier, kvmarm
On 3 September 2018 at 17:45, Andrew Jones <drjones@redhat.com> wrote:
> We need to support two redistributor regions in order to support
> more than 123 vcpus. Also bump NR_CPUS to 512, since that's what
> KVM currently supports.
Wouldn't it be neater to support the arbitrary number
of redistributor regions that the h/w spec allows and
the dt can describe, rather than just the specific case
of 2 regions that QEMU happens to use ?
thanks
-- PMM
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH kvm-unit-tests] arm/arm64: gicv3: support two redistributor regions
2018-09-04 0:49 ` Peter Maydell
@ 2018-09-04 7:02 ` Andrew Jones
0 siblings, 0 replies; 3+ messages in thread
From: Andrew Jones @ 2018-09-04 7:02 UTC (permalink / raw)
To: Peter Maydell; +Cc: Marc Zyngier, kvmarm
On Tue, Sep 04, 2018 at 01:49:11AM +0100, Peter Maydell wrote:
> On 3 September 2018 at 17:45, Andrew Jones <drjones@redhat.com> wrote:
> > We need to support two redistributor regions in order to support
> > more than 123 vcpus. Also bump NR_CPUS to 512, since that's what
> > KVM currently supports.
>
> Wouldn't it be neater to support the arbitrary number
> of redistributor regions that the h/w spec allows and
> the dt can describe, rather than just the specific case
> of 2 regions that QEMU happens to use ?
>
It would be nicer, and I suppose it would be pretty easy to do
as well. kvm-unit-tests/arm has always been a balance between being
over-engineered for its purposes and being too hacky. In this case,
I was probably too hacky. Although KVM only supports up to 512 VCPUS
right now and these two regions support up to 635, so it'll be a while
before a third region will be needed.
If I find time I'll send a v2, but in the meantime it'd be good to
get test results with this version to be sure I didn't miss anything
else.
Thanks,
drew
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-09-04 7:02 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-03 16:45 [PATCH kvm-unit-tests] arm/arm64: gicv3: support two redistributor regions Andrew Jones
2018-09-04 0:49 ` Peter Maydell
2018-09-04 7:02 ` Andrew Jones
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.