Even though 'struct sgi' already supports for passing cluster_id,
gic_handle_sgir_write() looks only for target fields and triggers sgis
to its respective targets. This will fail in case of armv8 with affinity
routing enabled. So parse all the affinity levels in sgi before sending
sgi.

Suggested-by: Nikhil Devshatwar <[email protected]>
Signed-off-by: Nikhil Devshatwar <[email protected]>
Signed-off-by: Lokesh Vutla <[email protected]>
---
 hypervisor/arch/arm-common/irqchip.c        | 11 ++++++++---
 hypervisor/arch/arm/include/asm/sysregs.h   |  1 +
 hypervisor/arch/arm64/include/asm/sysregs.h |  1 +
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/hypervisor/arch/arm-common/irqchip.c 
b/hypervisor/arch/arm-common/irqchip.c
index 933df0d..b90b876 100644
--- a/hypervisor/arch/arm-common/irqchip.c
+++ b/hypervisor/arch/arm-common/irqchip.c
@@ -129,6 +129,7 @@ void gic_handle_sgir_write(struct sgi *sgi, bool 
affinity_routing)
 {
        struct per_cpu *cpu_data = this_cpu_data();
        unsigned long targets = sgi->targets;
+       u64 mpidr, cluster, core;
        unsigned int cpu;
 
        sgi->targets = 0;
@@ -138,13 +139,17 @@ void gic_handle_sgir_write(struct sgi *sgi, bool 
affinity_routing)
                irqchip_set_pending(cpu_data, sgi->id);
        else
                for_each_cpu(cpu, cpu_data->cell->cpu_set) {
+                       mpidr = per_cpu(cpu)->mpidr;
+                       cluster = mpidr & MPIDR_CLUSTERID_MASK;
+                       core = mpidr & MPIDR_AFF0_MASK;
+
                        if (sgi->routing_mode == 1) {
                                /* Route to all (cell) CPUs but the caller. */
                                if (cpu == cpu_data->cpu_id)
                                        continue;
                        } else if (affinity_routing) {
-                               if (!test_bit(cpu_data->mpidr & MPIDR_AFF0_MASK,
-                                             &targets))
+                               if (sgi->cluster_id != cluster ||
+                                   !test_bit(core, &targets))
                                        continue;
                        } else {
                                /*
@@ -164,7 +169,7 @@ void gic_handle_sgir_write(struct sgi *sgi, bool 
affinity_routing)
                         * as well. So this adjustment is only targeting the
                         * mode 0 case.
                         */
-                       sgi->targets |= (1 << cpu);
+                       sgi->targets |= (1 << core);
                }
 
        /* Let the other CPUS inject their SGIs */
diff --git a/hypervisor/arch/arm/include/asm/sysregs.h 
b/hypervisor/arch/arm/include/asm/sysregs.h
index 922d97a..797585b 100644
--- a/hypervisor/arch/arm/include/asm/sysregs.h
+++ b/hypervisor/arch/arm/include/asm/sysregs.h
@@ -57,6 +57,7 @@
 #define CTR_EL0                SYSREG_32(0, c0, c0, 1)
 #define MPIDR_EL1      SYSREG_32(0, c0, c0, 5)
 #define  MPIDR_CPUID_MASK      0x00ffffff
+#define  MPIDR_CLUSTERID_MASK  0x00ffff00
 #define  MPIDR_AFF0_MASK       0x000000ff
 #define  MPIDR_U_BIT           (1 << 30)
 #define  MPIDR_MP_BIT          (1 << 31)
diff --git a/hypervisor/arch/arm64/include/asm/sysregs.h 
b/hypervisor/arch/arm64/include/asm/sysregs.h
index 4451c77..24fb7d7 100644
--- a/hypervisor/arch/arm64/include/asm/sysregs.h
+++ b/hypervisor/arch/arm64/include/asm/sysregs.h
@@ -30,6 +30,7 @@
                        | PSR_MODE_EL1h)
 
 #define MPIDR_CPUID_MASK       0xff00ffffff
+#define MPIDR_CLUSTERID_MASK   0xff00ffff00
 #define MPIDR_AFF0_MASK                0x00000000ff
 #define MPIDR_U_BIT            (1 << 30)
 #define MPIDR_MP_BIT           (1 << 31)
-- 
2.13.0

-- 
You received this message because you are subscribed to the Google Groups 
"Jailhouse" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to