All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/10] ARM: KVM: Support for vgic-v3
@ 2016-09-12 14:49 ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

Hi,

This is an attempt to make use vgic-v3 under arch/arm since
save-restore functionality got re-written in C and can be shared
between arm/arm64 like it has already been done for vgic-v2 and timer.

With this patches I'm able to get 32 core an AArch32 ARMv8 guest boot:

...
GICv3: CPU31: found redistributor 703 region 0:0x000000003ffd0000
CPU31: thread -1, cpu 3, socket 7, mpidr 80000703
Brought up 32 CPUs
SMP: Total of 32 processors activated (768.00 BogoMIPS).
CPU: All CPU(s) started in SVC mode.
...

Additionally, quite lightweight test based on Self IPI guest test[1]
has been run with up to 255 cpus.

[1] http://www.spinics.net/lists/kvm/msg128974.html

Changelog:

    v3 -> v4   
       - rebased on v4.8-rc6
       - dropped hyp_data in preference to embedding the static key
         in kvm_vgic_global_state
       - GICv3 cpu sysreg mappings were moved out to separate patch
       - vgic patch was split into two: changes extract_bytes() and
         fixes for compiler's warnings
       - change for MPIDR_AFFINITY_LEVEL was dropped
       - 32-bit system register accessors were moved under
         CONFIG_CPU_CP15

    v2 -> v3
       - rebased on v4.8-rc5
       - commit messages are reworked to be more precise and clear (I
         hope so)
       - MPIDR_HWID_BITMASK is used to discard Aff3 in
         MPIDR_AFFINITY_LEVEL macro
       - cast to u64 is used instead of abuse of GENMASK_ULL while
         building value for typer register
       - static keys are used to select GIC backend
       - config option to guard ITS code is moved to separate patch

    v1 -> v2
       - rebased on v4.8-rc2
       - introduced guard for ITS code

Thanks!

Vladimir Murzin (10):
  arm64: KVM: Use static keys for selecting the GIC backend
  arm64: KVM: Move GIC accessors to arch_gicv3.h
  arm64: KVM: Move vgic-v3 save/restore to virt/kvm/arm/hyp
  KVM: arm64: vgic-its: Introduce config option to guard ITS specific
    code
  KVM: arm: vgic: Fix compiler warnings when built for 32-bit
  KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host
    systems
  ARM: Introduce MPIDR_LEVEL_SHIFT macro
  ARM: Move system register accessors to asm/cp15.h
  ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
  ARM: KVM: Support vgic-v3

 arch/arm/include/asm/arch_gicv3.h                 |   91 +++++++++++++++++----
 arch/arm/include/asm/cp15.h                       |   15 ++++
 arch/arm/include/asm/cputype.h                    |    1 +
 arch/arm/include/asm/kvm_asm.h                    |    3 +
 arch/arm/include/asm/kvm_host.h                   |    5 ++
 arch/arm/include/asm/kvm_hyp.h                    |   18 +---
 arch/arm/include/uapi/asm/kvm.h                   |    7 ++
 arch/arm/kvm/Makefile                             |    2 +
 arch/arm/kvm/coproc.c                             |   35 ++++++++
 arch/arm/kvm/hyp/Makefile                         |    1 +
 arch/arm/kvm/hyp/switch.c                         |   12 ++-
 arch/arm64/include/asm/arch_gicv3.h               |   13 +++
 arch/arm64/kvm/Kconfig                            |    4 +-
 arch/arm64/kvm/hyp/Makefile                       |    2 +-
 arch/arm64/kvm/hyp/switch.c                       |   21 ++---
 include/kvm/arm_vgic.h                            |   12 +--
 {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c |   13 ---
 virt/kvm/arm/vgic/vgic-init.c                     |    4 +
 virt/kvm/arm/vgic/vgic-kvm-device.c               |   11 +--
 virt/kvm/arm/vgic/vgic-mmio-v3.c                  |    8 +-
 virt/kvm/arm/vgic/vgic-mmio.c                     |    2 -
 virt/kvm/arm/vgic/vgic-mmio.h                     |    4 +-
 virt/kvm/arm/vgic/vgic.c                          |    2 +-
 virt/kvm/arm/vgic/vgic.h                          |   54 +-----------
 24 files changed, 205 insertions(+), 135 deletions(-)
 rename {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c (96%)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 00/10] ARM: KVM: Support for vgic-v3
@ 2016-09-12 14:49 ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This is an attempt to make use vgic-v3 under arch/arm since
save-restore functionality got re-written in C and can be shared
between arm/arm64 like it has already been done for vgic-v2 and timer.

With this patches I'm able to get 32 core an AArch32 ARMv8 guest boot:

...
GICv3: CPU31: found redistributor 703 region 0:0x000000003ffd0000
CPU31: thread -1, cpu 3, socket 7, mpidr 80000703
Brought up 32 CPUs
SMP: Total of 32 processors activated (768.00 BogoMIPS).
CPU: All CPU(s) started in SVC mode.
...

Additionally, quite lightweight test based on Self IPI guest test[1]
has been run with up to 255 cpus.

[1] http://www.spinics.net/lists/kvm/msg128974.html

Changelog:

    v3 -> v4   
       - rebased on v4.8-rc6
       - dropped hyp_data in preference to embedding the static key
         in kvm_vgic_global_state
       - GICv3 cpu sysreg mappings were moved out to separate patch
       - vgic patch was split into two: changes extract_bytes() and
         fixes for compiler's warnings
       - change for MPIDR_AFFINITY_LEVEL was dropped
       - 32-bit system register accessors were moved under
         CONFIG_CPU_CP15

    v2 -> v3
       - rebased on v4.8-rc5
       - commit messages are reworked to be more precise and clear (I
         hope so)
       - MPIDR_HWID_BITMASK is used to discard Aff3 in
         MPIDR_AFFINITY_LEVEL macro
       - cast to u64 is used instead of abuse of GENMASK_ULL while
         building value for typer register
       - static keys are used to select GIC backend
       - config option to guard ITS code is moved to separate patch

    v1 -> v2
       - rebased on v4.8-rc2
       - introduced guard for ITS code

Thanks!

Vladimir Murzin (10):
  arm64: KVM: Use static keys for selecting the GIC backend
  arm64: KVM: Move GIC accessors to arch_gicv3.h
  arm64: KVM: Move vgic-v3 save/restore to virt/kvm/arm/hyp
  KVM: arm64: vgic-its: Introduce config option to guard ITS specific
    code
  KVM: arm: vgic: Fix compiler warnings when built for 32-bit
  KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host
    systems
  ARM: Introduce MPIDR_LEVEL_SHIFT macro
  ARM: Move system register accessors to asm/cp15.h
  ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
  ARM: KVM: Support vgic-v3

 arch/arm/include/asm/arch_gicv3.h                 |   91 +++++++++++++++++----
 arch/arm/include/asm/cp15.h                       |   15 ++++
 arch/arm/include/asm/cputype.h                    |    1 +
 arch/arm/include/asm/kvm_asm.h                    |    3 +
 arch/arm/include/asm/kvm_host.h                   |    5 ++
 arch/arm/include/asm/kvm_hyp.h                    |   18 +---
 arch/arm/include/uapi/asm/kvm.h                   |    7 ++
 arch/arm/kvm/Makefile                             |    2 +
 arch/arm/kvm/coproc.c                             |   35 ++++++++
 arch/arm/kvm/hyp/Makefile                         |    1 +
 arch/arm/kvm/hyp/switch.c                         |   12 ++-
 arch/arm64/include/asm/arch_gicv3.h               |   13 +++
 arch/arm64/kvm/Kconfig                            |    4 +-
 arch/arm64/kvm/hyp/Makefile                       |    2 +-
 arch/arm64/kvm/hyp/switch.c                       |   21 ++---
 include/kvm/arm_vgic.h                            |   12 +--
 {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c |   13 ---
 virt/kvm/arm/vgic/vgic-init.c                     |    4 +
 virt/kvm/arm/vgic/vgic-kvm-device.c               |   11 +--
 virt/kvm/arm/vgic/vgic-mmio-v3.c                  |    8 +-
 virt/kvm/arm/vgic/vgic-mmio.c                     |    2 -
 virt/kvm/arm/vgic/vgic-mmio.h                     |    4 +-
 virt/kvm/arm/vgic/vgic.c                          |    2 +-
 virt/kvm/arm/vgic/vgic.h                          |   54 +-----------
 24 files changed, 205 insertions(+), 135 deletions(-)
 rename {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c (96%)

-- 
1.7.9.5

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

Currently GIC backend is selected via alternative framework and this
is fine. We are going to introduce vgic-v3 to 32-bit world and there
we don't have patching framework in hand, so we can either check
support for GICv3 every time we need to choose which backend to use or
try to optimise it by using static keys. The later looks quite
promising because we can share logic involved in selecting GIC backend
between architectures if both uses static keys.

This patch moves arm64 from alternative to static keys framework for
selecting GIC backend. For that we embed static key into vgic_global
and enable the key during vgic initialisation based on what has
already been exposed by the host GIC driver.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
 include/kvm/arm_vgic.h        |    4 ++++
 virt/kvm/arm/vgic/vgic-init.c |    4 ++++
 virt/kvm/arm/vgic/vgic.c      |    2 +-
 4 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 5a84b45..d5c4cc5 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -16,6 +16,8 @@
  */
 
 #include <linux/types.h>
+#include <linux/jump_label.h>
+
 #include <asm/kvm_asm.h>
 #include <asm/kvm_hyp.h>
 
@@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
 	write_sysreg(0, vttbr_el2);
 }
 
-static hyp_alternate_select(__vgic_call_save_state,
-			    __vgic_v2_save_state, __vgic_v3_save_state,
-			    ARM64_HAS_SYSREG_GIC_CPUIF);
-
-static hyp_alternate_select(__vgic_call_restore_state,
-			    __vgic_v2_restore_state, __vgic_v3_restore_state,
-			    ARM64_HAS_SYSREG_GIC_CPUIF);
-
 static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
 {
-	__vgic_call_save_state()(vcpu);
+	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+		__vgic_v3_save_state(vcpu);
+	else
+		__vgic_v2_save_state(vcpu);
+
 	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
 }
 
@@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
 	val |= vcpu->arch.irq_lines;
 	write_sysreg(val, hcr_el2);
 
-	__vgic_call_restore_state()(vcpu);
+	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+		__vgic_v3_restore_state(vcpu);
+	else
+		__vgic_v2_restore_state(vcpu);
 }
 
 static bool __hyp_text __true_value(void)
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 19b698e..994665a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <kvm/iodev.h>
 #include <linux/list.h>
+#include <linux/jump_label.h>
 
 #define VGIC_V3_MAX_CPUS	255
 #define VGIC_V2_MAX_CPUS	8
@@ -63,6 +64,9 @@ struct vgic_global {
 
 	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
 	bool			can_emulate_gicv2;
+
+	/* GIC system register CPU interface */
+	struct static_key_false gicv3_cpuif;
 };
 
 extern struct vgic_global kvm_vgic_global_state;
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index 83777c1..14d6718 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
 		break;
 	case GIC_V3:
 		ret = vgic_v3_probe(gic_kvm_info);
+		if (!ret) {
+			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
+			kvm_info("GIC system register CPU interface\n");
+		}
 		break;
 	default:
 		ret = -ENODEV;
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index e83b7fe..8a529a7 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -29,7 +29,7 @@
 #define DEBUG_SPINLOCK_BUG_ON(p)
 #endif
 
-struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
+struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
 
 /*
  * Locking order is always:
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Currently GIC backend is selected via alternative framework and this
is fine. We are going to introduce vgic-v3 to 32-bit world and there
we don't have patching framework in hand, so we can either check
support for GICv3 every time we need to choose which backend to use or
try to optimise it by using static keys. The later looks quite
promising because we can share logic involved in selecting GIC backend
between architectures if both uses static keys.

This patch moves arm64 from alternative to static keys framework for
selecting GIC backend. For that we embed static key into vgic_global
and enable the key during vgic initialisation based on what has
already been exposed by the host GIC driver.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
 include/kvm/arm_vgic.h        |    4 ++++
 virt/kvm/arm/vgic/vgic-init.c |    4 ++++
 virt/kvm/arm/vgic/vgic.c      |    2 +-
 4 files changed, 20 insertions(+), 11 deletions(-)

diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
index 5a84b45..d5c4cc5 100644
--- a/arch/arm64/kvm/hyp/switch.c
+++ b/arch/arm64/kvm/hyp/switch.c
@@ -16,6 +16,8 @@
  */
 
 #include <linux/types.h>
+#include <linux/jump_label.h>
+
 #include <asm/kvm_asm.h>
 #include <asm/kvm_hyp.h>
 
@@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
 	write_sysreg(0, vttbr_el2);
 }
 
-static hyp_alternate_select(__vgic_call_save_state,
-			    __vgic_v2_save_state, __vgic_v3_save_state,
-			    ARM64_HAS_SYSREG_GIC_CPUIF);
-
-static hyp_alternate_select(__vgic_call_restore_state,
-			    __vgic_v2_restore_state, __vgic_v3_restore_state,
-			    ARM64_HAS_SYSREG_GIC_CPUIF);
-
 static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
 {
-	__vgic_call_save_state()(vcpu);
+	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+		__vgic_v3_save_state(vcpu);
+	else
+		__vgic_v2_save_state(vcpu);
+
 	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
 }
 
@@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
 	val |= vcpu->arch.irq_lines;
 	write_sysreg(val, hcr_el2);
 
-	__vgic_call_restore_state()(vcpu);
+	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+		__vgic_v3_restore_state(vcpu);
+	else
+		__vgic_v2_restore_state(vcpu);
 }
 
 static bool __hyp_text __true_value(void)
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 19b698e..994665a 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -23,6 +23,7 @@
 #include <linux/types.h>
 #include <kvm/iodev.h>
 #include <linux/list.h>
+#include <linux/jump_label.h>
 
 #define VGIC_V3_MAX_CPUS	255
 #define VGIC_V2_MAX_CPUS	8
@@ -63,6 +64,9 @@ struct vgic_global {
 
 	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
 	bool			can_emulate_gicv2;
+
+	/* GIC system register CPU interface */
+	struct static_key_false gicv3_cpuif;
 };
 
 extern struct vgic_global kvm_vgic_global_state;
diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
index 83777c1..14d6718 100644
--- a/virt/kvm/arm/vgic/vgic-init.c
+++ b/virt/kvm/arm/vgic/vgic-init.c
@@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
 		break;
 	case GIC_V3:
 		ret = vgic_v3_probe(gic_kvm_info);
+		if (!ret) {
+			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
+			kvm_info("GIC system register CPU interface\n");
+		}
 		break;
 	default:
 		ret = -ENODEV;
diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
index e83b7fe..8a529a7 100644
--- a/virt/kvm/arm/vgic/vgic.c
+++ b/virt/kvm/arm/vgic/vgic.c
@@ -29,7 +29,7 @@
 #define DEBUG_SPINLOCK_BUG_ON(p)
 #endif
 
-struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
+struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
 
 /*
  * Locking order is always:
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 02/10] arm64: KVM: Move GIC accessors to arch_gicv3.h
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

Since we are going to share vgic-v3 save/restore code with ARM keep
arch specific accessors separately.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_gicv3.h |   13 +++++++++++++
 arch/arm64/kvm/hyp/vgic-v3-sr.c     |   13 -------------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 8ec88e5..ae7dbd7 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -79,6 +79,19 @@
 #include <linux/stringify.h>
 #include <asm/barrier.h>
 
+#define read_gicreg(r)							\
+	({								\
+		u64 reg;						\
+		asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg));	\
+		reg;							\
+	})
+
+#define write_gicreg(v,r)						\
+	do {								\
+		u64 __val = (v);					\
+		asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
+	} while (0)
+
 /*
  * Low-level accessors
  *
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index 5f8f80b..f2dbd2e 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -24,19 +24,6 @@
 #define vtr_to_max_lr_idx(v)		((v) & 0xf)
 #define vtr_to_nr_pri_bits(v)		(((u32)(v) >> 29) + 1)
 
-#define read_gicreg(r)							\
-	({								\
-		u64 reg;						\
-		asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg));	\
-		reg;							\
-	})
-
-#define write_gicreg(v,r)						\
-	do {								\
-		u64 __val = (v);					\
-		asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
-	} while (0)
-
 static u64 __hyp_text __gic_v3_get_lr(unsigned int lr)
 {
 	switch (lr & 0xf) {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 02/10] arm64: KVM: Move GIC accessors to arch_gicv3.h
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Since we are going to share vgic-v3 save/restore code with ARM keep
arch specific accessors separately.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Christoffer Dall <christoffer.dall@linaro.org>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/arch_gicv3.h |   13 +++++++++++++
 arch/arm64/kvm/hyp/vgic-v3-sr.c     |   13 -------------
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/arch/arm64/include/asm/arch_gicv3.h b/arch/arm64/include/asm/arch_gicv3.h
index 8ec88e5..ae7dbd7 100644
--- a/arch/arm64/include/asm/arch_gicv3.h
+++ b/arch/arm64/include/asm/arch_gicv3.h
@@ -79,6 +79,19 @@
 #include <linux/stringify.h>
 #include <asm/barrier.h>
 
+#define read_gicreg(r)							\
+	({								\
+		u64 reg;						\
+		asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg));	\
+		reg;							\
+	})
+
+#define write_gicreg(v,r)						\
+	do {								\
+		u64 __val = (v);					\
+		asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
+	} while (0)
+
 /*
  * Low-level accessors
  *
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/arch/arm64/kvm/hyp/vgic-v3-sr.c
index 5f8f80b..f2dbd2e 100644
--- a/arch/arm64/kvm/hyp/vgic-v3-sr.c
+++ b/arch/arm64/kvm/hyp/vgic-v3-sr.c
@@ -24,19 +24,6 @@
 #define vtr_to_max_lr_idx(v)		((v) & 0xf)
 #define vtr_to_nr_pri_bits(v)		(((u32)(v) >> 29) + 1)
 
-#define read_gicreg(r)							\
-	({								\
-		u64 reg;						\
-		asm volatile("mrs_s %0, " __stringify(r) : "=r" (reg));	\
-		reg;							\
-	})
-
-#define write_gicreg(v,r)						\
-	do {								\
-		u64 __val = (v);					\
-		asm volatile("msr_s " __stringify(r) ", %0" : : "r" (__val));\
-	} while (0)
-
 static u64 __hyp_text __gic_v3_get_lr(unsigned int lr)
 {
 	switch (lr & 0xf) {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 03/10] arm64: KVM: Move vgic-v3 save/restore to virt/kvm/arm/hyp
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

So we can reuse the code under arch/arm

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp/Makefile                       |    2 +-
 {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c |    0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c (100%)

diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
index 0c85feb..aaf42ae 100644
--- a/arch/arm64/kvm/hyp/Makefile
+++ b/arch/arm64/kvm/hyp/Makefile
@@ -5,9 +5,9 @@
 KVM=../../../../virt/kvm
 
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
 
-obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += entry.o
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
similarity index 100%
rename from arch/arm64/kvm/hyp/vgic-v3-sr.c
rename to virt/kvm/arm/hyp/vgic-v3-sr.c
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 03/10] arm64: KVM: Move vgic-v3 save/restore to virt/kvm/arm/hyp
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

So we can reuse the code under arch/arm

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp/Makefile                       |    2 +-
 {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c |    0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename {arch/arm64/kvm => virt/kvm/arm}/hyp/vgic-v3-sr.c (100%)

diff --git a/arch/arm64/kvm/hyp/Makefile b/arch/arm64/kvm/hyp/Makefile
index 0c85feb..aaf42ae 100644
--- a/arch/arm64/kvm/hyp/Makefile
+++ b/arch/arm64/kvm/hyp/Makefile
@@ -5,9 +5,9 @@
 KVM=../../../../virt/kvm
 
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
 
-obj-$(CONFIG_KVM_ARM_HOST) += vgic-v3-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += sysreg-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += debug-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += entry.o
diff --git a/arch/arm64/kvm/hyp/vgic-v3-sr.c b/virt/kvm/arm/hyp/vgic-v3-sr.c
similarity index 100%
rename from arch/arm64/kvm/hyp/vgic-v3-sr.c
rename to virt/kvm/arm/hyp/vgic-v3-sr.c
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 04/10] KVM: arm64: vgic-its: Introduce config option to guard ITS specific code
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

By now ITS code guarded with KVM_ARM_VGIC_V3 config option which was
introduced to hide everything specific to vgic-v3 from 32-bit world.
We are going to support vgic-v3 in 32-bit world and KVM_ARM_VGIC_V3
will gone, but we don't have support for ITS there yet and we need to
continue keeping ITS away.
Introduce the new config option to prevent ITS code being build in
32-bit mode when support for vgic-v3 is done.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/Kconfig              |    4 ++++
 virt/kvm/arm/vgic/vgic-kvm-device.c |    3 +++
 virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 ++
 virt/kvm/arm/vgic/vgic.h            |    4 ++++
 4 files changed, 13 insertions(+)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 9c9edc9..7ba9164 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -16,6 +16,9 @@ menuconfig VIRTUALIZATION
 
 if VIRTUALIZATION
 
+config KVM_ARM_VGIC_V3_ITS
+	bool
+
 config KVM_ARM_VGIC_V3
 	bool
 
@@ -35,6 +38,7 @@ config KVM
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
 	select KVM_ARM_VGIC_V3
+	select KVM_ARM_VGIC_V3_ITS
 	select KVM_ARM_PMU if HW_PERF_EVENTS
 	select HAVE_KVM_MSI
 	select HAVE_KVM_IRQCHIP
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index 1813f93..f3811b3 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -223,9 +223,12 @@ int kvm_register_vgic_device(unsigned long type)
 	case KVM_DEV_TYPE_ARM_VGIC_V3:
 		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
 					      KVM_DEV_TYPE_ARM_VGIC_V3);
+
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 		if (ret)
 			break;
 		ret = kvm_vgic_register_its_device();
+#endif
 		break;
 #endif
 	}
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 90d8181..acbe691 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -42,6 +42,7 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
 	return reg | ((u64)val << lower);
 }
 
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 bool vgic_has_its(struct kvm *kvm)
 {
 	struct vgic_dist *dist = &kvm->arch.vgic;
@@ -51,6 +52,7 @@ bool vgic_has_its(struct kvm *kvm)
 
 	return dist->has_its;
 }
+#endif
 
 static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
 					    gpa_t addr, unsigned int len)
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 6c4625c..100045f 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -84,11 +84,15 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu);
 int vgic_v3_probe(const struct gic_kvm_info *info);
 int vgic_v3_map_resources(struct kvm *kvm);
 int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
+
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 int vgic_register_its_iodevs(struct kvm *kvm);
 bool vgic_has_its(struct kvm *kvm);
 int kvm_vgic_register_its_device(void);
 void vgic_enable_lpis(struct kvm_vcpu *vcpu);
 int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
+#endif
+
 #else
 static inline void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
 {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 04/10] KVM: arm64: vgic-its: Introduce config option to guard ITS specific code
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

By now ITS code guarded with KVM_ARM_VGIC_V3 config option which was
introduced to hide everything specific to vgic-v3 from 32-bit world.
We are going to support vgic-v3 in 32-bit world and KVM_ARM_VGIC_V3
will gone, but we don't have support for ITS there yet and we need to
continue keeping ITS away.
Introduce the new config option to prevent ITS code being build in
32-bit mode when support for vgic-v3 is done.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
Acked-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/Kconfig              |    4 ++++
 virt/kvm/arm/vgic/vgic-kvm-device.c |    3 +++
 virt/kvm/arm/vgic/vgic-mmio-v3.c    |    2 ++
 virt/kvm/arm/vgic/vgic.h            |    4 ++++
 4 files changed, 13 insertions(+)

diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 9c9edc9..7ba9164 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -16,6 +16,9 @@ menuconfig VIRTUALIZATION
 
 if VIRTUALIZATION
 
+config KVM_ARM_VGIC_V3_ITS
+	bool
+
 config KVM_ARM_VGIC_V3
 	bool
 
@@ -35,6 +38,7 @@ config KVM
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
 	select KVM_ARM_VGIC_V3
+	select KVM_ARM_VGIC_V3_ITS
 	select KVM_ARM_PMU if HW_PERF_EVENTS
 	select HAVE_KVM_MSI
 	select HAVE_KVM_IRQCHIP
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index 1813f93..f3811b3 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -223,9 +223,12 @@ int kvm_register_vgic_device(unsigned long type)
 	case KVM_DEV_TYPE_ARM_VGIC_V3:
 		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
 					      KVM_DEV_TYPE_ARM_VGIC_V3);
+
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 		if (ret)
 			break;
 		ret = kvm_vgic_register_its_device();
+#endif
 		break;
 #endif
 	}
diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 90d8181..acbe691 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -42,6 +42,7 @@ u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
 	return reg | ((u64)val << lower);
 }
 
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 bool vgic_has_its(struct kvm *kvm)
 {
 	struct vgic_dist *dist = &kvm->arch.vgic;
@@ -51,6 +52,7 @@ bool vgic_has_its(struct kvm *kvm)
 
 	return dist->has_its;
 }
+#endif
 
 static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
 					    gpa_t addr, unsigned int len)
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 6c4625c..100045f 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -84,11 +84,15 @@ void vgic_v3_enable(struct kvm_vcpu *vcpu);
 int vgic_v3_probe(const struct gic_kvm_info *info);
 int vgic_v3_map_resources(struct kvm *kvm);
 int vgic_register_redist_iodevs(struct kvm *kvm, gpa_t dist_base_address);
+
+#ifdef CONFIG_KVM_ARM_VGIC_V3_ITS
 int vgic_register_its_iodevs(struct kvm *kvm);
 bool vgic_has_its(struct kvm *kvm);
 int kvm_vgic_register_its_device(void);
 void vgic_enable_lpis(struct kvm_vcpu *vcpu);
 int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
+#endif
+
 #else
 static inline void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
 {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 05/10] KVM: arm: vgic: Fix compiler warnings when built for 32-bit
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

Well, this patch is looking ahead of time, but we'll get following
compiler warnings as soon as we introduce vgic-v3 to 32-bit world

  CC      arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.o
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_mmio_read_v3r_typer':
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:184:35: warning: left shift count >= width of type [-Wshift-count-overflow]
  value = (mpidr & GENMASK(23, 0)) << 32;
                                   ^
In file included from ./include/linux/kernel.h:10:0,
                 from ./include/asm-generic/bug.h:13,
                 from ./arch/arm/include/asm/bug.h:59,
                 from ./include/linux/bug.h:4,
                 from ./include/linux/io.h:23,
                 from ./arch/arm/include/asm/arch_gicv3.h:23,
                 from ./include/linux/irqchip/arm-gic-v3.h:411,
                 from arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:14:
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_v3_dispatch_sgi':
./include/linux/bitops.h:6:24: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define BIT(nr)   (1UL << (nr))
                        ^
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:614:20: note: in expansion of macro 'BIT'
  broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
                    ^
Let's fix them now.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 virt/kvm/arm/vgic/vgic-mmio-v3.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index acbe691..6385ed5 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -181,7 +181,7 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
 	int target_vcpu_id = vcpu->vcpu_id;
 	u64 value;
 
-	value = (mpidr & GENMASK(23, 0)) << 32;
+	value = (u64)(mpidr & GENMASK(23, 0)) << 32;
 	value |= ((target_vcpu_id & 0xffff) << 8);
 	if (target_vcpu_id == atomic_read(&vcpu->kvm->online_vcpus) - 1)
 		value |= GICR_TYPER_LAST;
@@ -611,7 +611,7 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
 	bool broadcast;
 
 	sgi = (reg & ICC_SGI1R_SGI_ID_MASK) >> ICC_SGI1R_SGI_ID_SHIFT;
-	broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
+	broadcast = reg & BIT_ULL(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
 	target_cpus = (reg & ICC_SGI1R_TARGET_LIST_MASK) >> ICC_SGI1R_TARGET_LIST_SHIFT;
 	mpidr = SGI_AFFINITY_LEVEL(reg, 3);
 	mpidr |= SGI_AFFINITY_LEVEL(reg, 2);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 05/10] KVM: arm: vgic: Fix compiler warnings when built for 32-bit
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Well, this patch is looking ahead of time, but we'll get following
compiler warnings as soon as we introduce vgic-v3 to 32-bit world

  CC      arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.o
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_mmio_read_v3r_typer':
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:184:35: warning: left shift count >= width of type [-Wshift-count-overflow]
  value = (mpidr & GENMASK(23, 0)) << 32;
                                   ^
In file included from ./include/linux/kernel.h:10:0,
                 from ./include/asm-generic/bug.h:13,
                 from ./arch/arm/include/asm/bug.h:59,
                 from ./include/linux/bug.h:4,
                 from ./include/linux/io.h:23,
                 from ./arch/arm/include/asm/arch_gicv3.h:23,
                 from ./include/linux/irqchip/arm-gic-v3.h:411,
                 from arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:14:
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_v3_dispatch_sgi':
./include/linux/bitops.h:6:24: warning: left shift count >= width of type [-Wshift-count-overflow]
 #define BIT(nr)   (1UL << (nr))
                        ^
arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:614:20: note: in expansion of macro 'BIT'
  broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
                    ^
Let's fix them now.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 virt/kvm/arm/vgic/vgic-mmio-v3.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index acbe691..6385ed5 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -181,7 +181,7 @@ static unsigned long vgic_mmio_read_v3r_typer(struct kvm_vcpu *vcpu,
 	int target_vcpu_id = vcpu->vcpu_id;
 	u64 value;
 
-	value = (mpidr & GENMASK(23, 0)) << 32;
+	value = (u64)(mpidr & GENMASK(23, 0)) << 32;
 	value |= ((target_vcpu_id & 0xffff) << 8);
 	if (target_vcpu_id == atomic_read(&vcpu->kvm->online_vcpus) - 1)
 		value |= GICR_TYPER_LAST;
@@ -611,7 +611,7 @@ void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
 	bool broadcast;
 
 	sgi = (reg & ICC_SGI1R_SGI_ID_MASK) >> ICC_SGI1R_SGI_ID_SHIFT;
-	broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
+	broadcast = reg & BIT_ULL(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
 	target_cpus = (reg & ICC_SGI1R_TARGET_LIST_MASK) >> ICC_SGI1R_TARGET_LIST_SHIFT;
 	mpidr = SGI_AFFINITY_LEVEL(reg, 3);
 	mpidr |= SGI_AFFINITY_LEVEL(reg, 2);
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 06/10] KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host systems
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

We have couple of 64-bit registers defined in GICv3 architecture, so
unsigned long accesses to these registers will only access a single
32-bit part of that regitser. On the other hand these registers can't
be accessed as 64-bit with a single instruction like ldrd/strd or
ldmia/stmia if we run a 32-bit host because KVM does not support
access to MMIO space done by these instructions.

It means that a 32-bit guest accesses these registers in 32-bit
chunks, so the only thing we need to do is to ensure that
extract_bytes() always takes 64-bit data.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 virt/kvm/arm/vgic/vgic-mmio-v3.c |    2 +-
 virt/kvm/arm/vgic/vgic-mmio.h    |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 6385ed5..0d3c76a 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -23,7 +23,7 @@
 #include "vgic-mmio.h"
 
 /* extract @num bytes at @offset bytes offset in data */
-unsigned long extract_bytes(unsigned long data, unsigned int offset,
+unsigned long extract_bytes(u64 data, unsigned int offset,
 			    unsigned int num)
 {
 	return (data >> (offset * 8)) & GENMASK_ULL(num * 8 - 1, 0);
diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
index 0b3ecf9..80f92ce 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.h
+++ b/virt/kvm/arm/vgic/vgic-mmio.h
@@ -96,7 +96,7 @@ unsigned long vgic_data_mmio_bus_to_host(const void *val, unsigned int len);
 void vgic_data_host_to_mmio_bus(void *buf, unsigned int len,
 				unsigned long data);
 
-unsigned long extract_bytes(unsigned long data, unsigned int offset,
+unsigned long extract_bytes(u64 data, unsigned int offset,
 			    unsigned int num);
 
 u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 06/10] KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host systems
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

We have couple of 64-bit registers defined in GICv3 architecture, so
unsigned long accesses to these registers will only access a single
32-bit part of that regitser. On the other hand these registers can't
be accessed as 64-bit with a single instruction like ldrd/strd or
ldmia/stmia if we run a 32-bit host because KVM does not support
access to MMIO space done by these instructions.

It means that a 32-bit guest accesses these registers in 32-bit
chunks, so the only thing we need to do is to ensure that
extract_bytes() always takes 64-bit data.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 virt/kvm/arm/vgic/vgic-mmio-v3.c |    2 +-
 virt/kvm/arm/vgic/vgic-mmio.h    |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
index 6385ed5..0d3c76a 100644
--- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
+++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
@@ -23,7 +23,7 @@
 #include "vgic-mmio.h"
 
 /* extract @num bytes at @offset bytes offset in data */
-unsigned long extract_bytes(unsigned long data, unsigned int offset,
+unsigned long extract_bytes(u64 data, unsigned int offset,
 			    unsigned int num)
 {
 	return (data >> (offset * 8)) & GENMASK_ULL(num * 8 - 1, 0);
diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
index 0b3ecf9..80f92ce 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.h
+++ b/virt/kvm/arm/vgic/vgic-mmio.h
@@ -96,7 +96,7 @@ unsigned long vgic_data_mmio_bus_to_host(const void *val, unsigned int len);
 void vgic_data_host_to_mmio_bus(void *buf, unsigned int len,
 				unsigned long data);
 
-unsigned long extract_bytes(unsigned long data, unsigned int offset,
+unsigned long extract_bytes(u64 data, unsigned int offset,
 			    unsigned int num);
 
 u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, Russell King, linux-arm-kernel

vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
encode the affinity in a form compatible with ICC_SGI* registers.
Unfortunately, that macro is missing on ARM, so let's add it.

Cc: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/cputype.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 1ee94c7..e2d94c1 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -55,6 +55,7 @@
 
 #define MPIDR_LEVEL_BITS 8
 #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
+#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
 
 #define MPIDR_AFFINITY_LEVEL(mpidr, level) \
 	((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
encode the affinity in a form compatible with ICC_SGI* registers.
Unfortunately, that macro is missing on ARM, so let's add it.

Cc: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/cputype.h |    1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
index 1ee94c7..e2d94c1 100644
--- a/arch/arm/include/asm/cputype.h
+++ b/arch/arm/include/asm/cputype.h
@@ -55,6 +55,7 @@
 
 #define MPIDR_LEVEL_BITS 8
 #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
+#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
 
 #define MPIDR_AFFINITY_LEVEL(mpidr, level) \
 	((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 08/10] ARM: Move system register accessors to asm/cp15.h
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, Russell King, linux-arm-kernel

Headers linux/irqchip/arm-gic.v3.h and arch/arm/include/asm/kvm_hyp.h
are included in virt/kvm/arm/hyp/vgic-v3-sr.c and both define macros
called __ACCESS_CP15 and __ACCESS_CP15_64 which obviously creates a
conflict. These macros were introduced independently for GIC and KVM
and, in fact, do the same thing.

As an option we could add prefixes to KVM and GIC version of macros so
they won't clash, but it'd introduce code duplication.  Alternatively,
we could keep macro in, say, GIC header and include it in KVM one (or
vice versa), but such dependency would not look nicer.

So we follow arm64 way (it handles this via sysreg.h) and move only
single set of macros to asm/cp15.h

Cc: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/arch_gicv3.h |   27 +++++++++++----------------
 arch/arm/include/asm/cp15.h       |   15 +++++++++++++++
 arch/arm/include/asm/kvm_hyp.h    |   15 +--------------
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index e08d151..af25c32 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -22,9 +22,7 @@
 
 #include <linux/io.h>
 #include <asm/barrier.h>
-
-#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	p15, Op1, %0, CRn, CRm, Op2
-#define __ACCESS_CP15_64(Op1, CRm)		p15, Op1, %Q0, %R0, CRm
+#include <asm/cp15.h>
 
 #define ICC_EOIR1			__ACCESS_CP15(c12, 0, c12, 1)
 #define ICC_DIR				__ACCESS_CP15(c12, 0, c11, 1)
@@ -102,58 +100,55 @@
 
 static inline void gic_write_eoir(u32 irq)
 {
-	asm volatile("mcr " __stringify(ICC_EOIR1) : : "r" (irq));
+	write_sysreg(irq, ICC_EOIR1);
 	isb();
 }
 
 static inline void gic_write_dir(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_DIR) : : "r" (val));
+	write_sysreg(val, ICC_DIR);
 	isb();
 }
 
 static inline u32 gic_read_iar(void)
 {
-	u32 irqstat;
+	u32 irqstat = read_sysreg(ICC_IAR1);
 
-	asm volatile("mrc " __stringify(ICC_IAR1) : "=r" (irqstat));
 	dsb(sy);
+
 	return irqstat;
 }
 
 static inline void gic_write_pmr(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
+	write_sysreg(val, ICC_PMR);
 }
 
 static inline void gic_write_ctlr(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_CTLR) : : "r" (val));
+	write_sysreg(val, ICC_CTLR);
 	isb();
 }
 
 static inline void gic_write_grpen1(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
+	write_sysreg(val, ICC_IGRPEN1);
 	isb();
 }
 
 static inline void gic_write_sgi1r(u64 val)
 {
-	asm volatile("mcrr " __stringify(ICC_SGI1R) : : "r" (val));
+	write_sysreg(val, ICC_SGI1R);
 }
 
 static inline u32 gic_read_sre(void)
 {
-	u32 val;
-
-	asm volatile("mrc " __stringify(ICC_SRE) : "=r" (val));
-	return val;
+	return read_sysreg(ICC_SRE);
 }
 
 static inline void gic_write_sre(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_SRE) : : "r" (val));
+	write_sysreg(val, ICC_SRE);
 	isb();
 }
 
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
index c3f1152..dbdbce1 100644
--- a/arch/arm/include/asm/cp15.h
+++ b/arch/arm/include/asm/cp15.h
@@ -49,6 +49,21 @@
 
 #ifdef CONFIG_CPU_CP15
 
+#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
+	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
+#define __ACCESS_CP15_64(Op1, CRm)		\
+	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
+
+#define __read_sysreg(r, w, c, t) ({				\
+	t __val;						\
+	asm volatile(r " " c : "=r" (__val));			\
+	__val;							\
+})
+#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)
+
+#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
+#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
+
 extern unsigned long cr_alignment;	/* defined in entry-armv.S */
 
 static inline unsigned long get_cr(void)
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
index 6eaff28..e604ad68 100644
--- a/arch/arm/include/asm/kvm_hyp.h
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -20,28 +20,15 @@
 
 #include <linux/compiler.h>
 #include <linux/kvm_host.h>
+#include <asm/cp15.h>
 #include <asm/kvm_mmu.h>
 #include <asm/vfp.h>
 
 #define __hyp_text __section(.hyp.text) notrace
 
-#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
-	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
-#define __ACCESS_CP15_64(Op1, CRm)		\
-	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
 #define __ACCESS_VFP(CRn)			\
 	"mrc", "mcr", __stringify(p10, 7, %0, CRn, cr0, 0), u32
 
-#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
-#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
-
-#define __read_sysreg(r, w, c, t) ({				\
-	t __val;						\
-	asm volatile(r " " c : "=r" (__val));			\
-	__val;							\
-})
-#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)
-
 #define write_special(v, r)					\
 	asm volatile("msr " __stringify(r) ", %0" : : "r" (v))
 #define read_special(r) ({					\
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 08/10] ARM: Move system register accessors to asm/cp15.h
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

Headers linux/irqchip/arm-gic.v3.h and arch/arm/include/asm/kvm_hyp.h
are included in virt/kvm/arm/hyp/vgic-v3-sr.c and both define macros
called __ACCESS_CP15 and __ACCESS_CP15_64 which obviously creates a
conflict. These macros were introduced independently for GIC and KVM
and, in fact, do the same thing.

As an option we could add prefixes to KVM and GIC version of macros so
they won't clash, but it'd introduce code duplication.  Alternatively,
we could keep macro in, say, GIC header and include it in KVM one (or
vice versa), but such dependency would not look nicer.

So we follow arm64 way (it handles this via sysreg.h) and move only
single set of macros to asm/cp15.h

Cc: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/arch_gicv3.h |   27 +++++++++++----------------
 arch/arm/include/asm/cp15.h       |   15 +++++++++++++++
 arch/arm/include/asm/kvm_hyp.h    |   15 +--------------
 3 files changed, 27 insertions(+), 30 deletions(-)

diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index e08d151..af25c32 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -22,9 +22,7 @@
 
 #include <linux/io.h>
 #include <asm/barrier.h>
-
-#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	p15, Op1, %0, CRn, CRm, Op2
-#define __ACCESS_CP15_64(Op1, CRm)		p15, Op1, %Q0, %R0, CRm
+#include <asm/cp15.h>
 
 #define ICC_EOIR1			__ACCESS_CP15(c12, 0, c12, 1)
 #define ICC_DIR				__ACCESS_CP15(c12, 0, c11, 1)
@@ -102,58 +100,55 @@
 
 static inline void gic_write_eoir(u32 irq)
 {
-	asm volatile("mcr " __stringify(ICC_EOIR1) : : "r" (irq));
+	write_sysreg(irq, ICC_EOIR1);
 	isb();
 }
 
 static inline void gic_write_dir(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_DIR) : : "r" (val));
+	write_sysreg(val, ICC_DIR);
 	isb();
 }
 
 static inline u32 gic_read_iar(void)
 {
-	u32 irqstat;
+	u32 irqstat = read_sysreg(ICC_IAR1);
 
-	asm volatile("mrc " __stringify(ICC_IAR1) : "=r" (irqstat));
 	dsb(sy);
+
 	return irqstat;
 }
 
 static inline void gic_write_pmr(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
+	write_sysreg(val, ICC_PMR);
 }
 
 static inline void gic_write_ctlr(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_CTLR) : : "r" (val));
+	write_sysreg(val, ICC_CTLR);
 	isb();
 }
 
 static inline void gic_write_grpen1(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
+	write_sysreg(val, ICC_IGRPEN1);
 	isb();
 }
 
 static inline void gic_write_sgi1r(u64 val)
 {
-	asm volatile("mcrr " __stringify(ICC_SGI1R) : : "r" (val));
+	write_sysreg(val, ICC_SGI1R);
 }
 
 static inline u32 gic_read_sre(void)
 {
-	u32 val;
-
-	asm volatile("mrc " __stringify(ICC_SRE) : "=r" (val));
-	return val;
+	return read_sysreg(ICC_SRE);
 }
 
 static inline void gic_write_sre(u32 val)
 {
-	asm volatile("mcr " __stringify(ICC_SRE) : : "r" (val));
+	write_sysreg(val, ICC_SRE);
 	isb();
 }
 
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
index c3f1152..dbdbce1 100644
--- a/arch/arm/include/asm/cp15.h
+++ b/arch/arm/include/asm/cp15.h
@@ -49,6 +49,21 @@
 
 #ifdef CONFIG_CPU_CP15
 
+#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
+	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
+#define __ACCESS_CP15_64(Op1, CRm)		\
+	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
+
+#define __read_sysreg(r, w, c, t) ({				\
+	t __val;						\
+	asm volatile(r " " c : "=r" (__val));			\
+	__val;							\
+})
+#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)
+
+#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
+#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
+
 extern unsigned long cr_alignment;	/* defined in entry-armv.S */
 
 static inline unsigned long get_cr(void)
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
index 6eaff28..e604ad68 100644
--- a/arch/arm/include/asm/kvm_hyp.h
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -20,28 +20,15 @@
 
 #include <linux/compiler.h>
 #include <linux/kvm_host.h>
+#include <asm/cp15.h>
 #include <asm/kvm_mmu.h>
 #include <asm/vfp.h>
 
 #define __hyp_text __section(.hyp.text) notrace
 
-#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
-	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
-#define __ACCESS_CP15_64(Op1, CRm)		\
-	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
 #define __ACCESS_VFP(CRn)			\
 	"mrc", "mcr", __stringify(p10, 7, %0, CRn, cr0, 0), u32
 
-#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
-#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
-
-#define __read_sysreg(r, w, c, t) ({				\
-	t __val;						\
-	asm volatile(r " " c : "=r" (__val));			\
-	__val;							\
-})
-#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)
-
 #define write_special(v, r)					\
 	asm volatile("msr " __stringify(r) ", %0" : : "r" (v))
 #define read_special(r) ({					\
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 09/10] ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

vgic-v3 save/restore routines are written in such way that they map
arm64 system register naming nicely, but it does not fit to arm
world. To keep virt/kvm/arm/hyp/vgic-v3-sr.c untouched we create a
mapping with a function for each register mapping the 32-bit to the
64-bit accessors.

Please, note that 64-bit wide ICH_LR is split in two 32-bit halves
(ICH_LR and ICH_LRC) accessed independently.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/arch_gicv3.h |   64 +++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index af25c32..996848e 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -96,6 +96,70 @@
 #define ICH_AP1R2			__AP1Rx(2)
 #define ICH_AP1R3			__AP1Rx(3)
 
+/* A32-to-A64 mappings used by VGIC save/restore */
+
+#define CPUIF_MAP(a32, a64)			\
+static inline void write_ ## a64(u32 val)	\
+{						\
+	write_sysreg(val, a32);			\
+}						\
+static inline u32 read_ ## a64(void)		\
+{						\
+	return read_sysreg(a32); 		\
+}						\
+
+#define CPUIF_MAP_LO_HI(a32lo, a32hi, a64)	\
+static inline void write_ ## a64(u64 val)	\
+{						\
+	write_sysreg(lower_32_bits(val), a32lo);\
+	write_sysreg(upper_32_bits(val), a32hi);\
+}						\
+static inline u64 read_ ## a64(void)		\
+{						\
+	u64 val = read_sysreg(a32lo);		\
+						\
+	val |=	(u64)read_sysreg(a32hi) << 32;	\
+						\
+	return val; 				\
+}
+
+CPUIF_MAP(ICH_HCR, ICH_HCR_EL2)
+CPUIF_MAP(ICH_VTR, ICH_VTR_EL2)
+CPUIF_MAP(ICH_MISR, ICH_MISR_EL2)
+CPUIF_MAP(ICH_EISR, ICH_EISR_EL2)
+CPUIF_MAP(ICH_ELSR, ICH_ELSR_EL2)
+CPUIF_MAP(ICH_VMCR, ICH_VMCR_EL2)
+CPUIF_MAP(ICH_AP0R3, ICH_AP0R3_EL2)
+CPUIF_MAP(ICH_AP0R2, ICH_AP0R2_EL2)
+CPUIF_MAP(ICH_AP0R1, ICH_AP0R1_EL2)
+CPUIF_MAP(ICH_AP0R0, ICH_AP0R0_EL2)
+CPUIF_MAP(ICH_AP1R3, ICH_AP1R3_EL2)
+CPUIF_MAP(ICH_AP1R2, ICH_AP1R2_EL2)
+CPUIF_MAP(ICH_AP1R1, ICH_AP1R1_EL2)
+CPUIF_MAP(ICH_AP1R0, ICH_AP1R0_EL2)
+CPUIF_MAP(ICC_HSRE, ICC_SRE_EL2)
+CPUIF_MAP(ICC_SRE, ICC_SRE_EL1)
+
+CPUIF_MAP_LO_HI(ICH_LR15, ICH_LRC15, ICH_LR15_EL2)
+CPUIF_MAP_LO_HI(ICH_LR14, ICH_LRC14, ICH_LR14_EL2)
+CPUIF_MAP_LO_HI(ICH_LR13, ICH_LRC13, ICH_LR13_EL2)
+CPUIF_MAP_LO_HI(ICH_LR12, ICH_LRC12, ICH_LR12_EL2)
+CPUIF_MAP_LO_HI(ICH_LR11, ICH_LRC11, ICH_LR11_EL2)
+CPUIF_MAP_LO_HI(ICH_LR10, ICH_LRC10, ICH_LR10_EL2)
+CPUIF_MAP_LO_HI(ICH_LR9, ICH_LRC9, ICH_LR9_EL2)
+CPUIF_MAP_LO_HI(ICH_LR8, ICH_LRC8, ICH_LR8_EL2)
+CPUIF_MAP_LO_HI(ICH_LR7, ICH_LRC7, ICH_LR7_EL2)
+CPUIF_MAP_LO_HI(ICH_LR6, ICH_LRC6, ICH_LR6_EL2)
+CPUIF_MAP_LO_HI(ICH_LR5, ICH_LRC5, ICH_LR5_EL2)
+CPUIF_MAP_LO_HI(ICH_LR4, ICH_LRC4, ICH_LR4_EL2)
+CPUIF_MAP_LO_HI(ICH_LR3, ICH_LRC3, ICH_LR3_EL2)
+CPUIF_MAP_LO_HI(ICH_LR2, ICH_LRC2, ICH_LR2_EL2)
+CPUIF_MAP_LO_HI(ICH_LR1, ICH_LRC1, ICH_LR1_EL2)
+CPUIF_MAP_LO_HI(ICH_LR0, ICH_LRC0, ICH_LR0_EL2)
+
+#define read_gicreg(r)                 read_##r()
+#define write_gicreg(v, r)             write_##r(v)
+
 /* Low-level accessors */
 
 static inline void gic_write_eoir(u32 irq)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 09/10] ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

vgic-v3 save/restore routines are written in such way that they map
arm64 system register naming nicely, but it does not fit to arm
world. To keep virt/kvm/arm/hyp/vgic-v3-sr.c untouched we create a
mapping with a function for each register mapping the 32-bit to the
64-bit accessors.

Please, note that 64-bit wide ICH_LR is split in two 32-bit halves
(ICH_LR and ICH_LRC) accessed independently.

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/arch_gicv3.h |   64 +++++++++++++++++++++++++++++++++++++
 1 file changed, 64 insertions(+)

diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
index af25c32..996848e 100644
--- a/arch/arm/include/asm/arch_gicv3.h
+++ b/arch/arm/include/asm/arch_gicv3.h
@@ -96,6 +96,70 @@
 #define ICH_AP1R2			__AP1Rx(2)
 #define ICH_AP1R3			__AP1Rx(3)
 
+/* A32-to-A64 mappings used by VGIC save/restore */
+
+#define CPUIF_MAP(a32, a64)			\
+static inline void write_ ## a64(u32 val)	\
+{						\
+	write_sysreg(val, a32);			\
+}						\
+static inline u32 read_ ## a64(void)		\
+{						\
+	return read_sysreg(a32); 		\
+}						\
+
+#define CPUIF_MAP_LO_HI(a32lo, a32hi, a64)	\
+static inline void write_ ## a64(u64 val)	\
+{						\
+	write_sysreg(lower_32_bits(val), a32lo);\
+	write_sysreg(upper_32_bits(val), a32hi);\
+}						\
+static inline u64 read_ ## a64(void)		\
+{						\
+	u64 val = read_sysreg(a32lo);		\
+						\
+	val |=	(u64)read_sysreg(a32hi) << 32;	\
+						\
+	return val; 				\
+}
+
+CPUIF_MAP(ICH_HCR, ICH_HCR_EL2)
+CPUIF_MAP(ICH_VTR, ICH_VTR_EL2)
+CPUIF_MAP(ICH_MISR, ICH_MISR_EL2)
+CPUIF_MAP(ICH_EISR, ICH_EISR_EL2)
+CPUIF_MAP(ICH_ELSR, ICH_ELSR_EL2)
+CPUIF_MAP(ICH_VMCR, ICH_VMCR_EL2)
+CPUIF_MAP(ICH_AP0R3, ICH_AP0R3_EL2)
+CPUIF_MAP(ICH_AP0R2, ICH_AP0R2_EL2)
+CPUIF_MAP(ICH_AP0R1, ICH_AP0R1_EL2)
+CPUIF_MAP(ICH_AP0R0, ICH_AP0R0_EL2)
+CPUIF_MAP(ICH_AP1R3, ICH_AP1R3_EL2)
+CPUIF_MAP(ICH_AP1R2, ICH_AP1R2_EL2)
+CPUIF_MAP(ICH_AP1R1, ICH_AP1R1_EL2)
+CPUIF_MAP(ICH_AP1R0, ICH_AP1R0_EL2)
+CPUIF_MAP(ICC_HSRE, ICC_SRE_EL2)
+CPUIF_MAP(ICC_SRE, ICC_SRE_EL1)
+
+CPUIF_MAP_LO_HI(ICH_LR15, ICH_LRC15, ICH_LR15_EL2)
+CPUIF_MAP_LO_HI(ICH_LR14, ICH_LRC14, ICH_LR14_EL2)
+CPUIF_MAP_LO_HI(ICH_LR13, ICH_LRC13, ICH_LR13_EL2)
+CPUIF_MAP_LO_HI(ICH_LR12, ICH_LRC12, ICH_LR12_EL2)
+CPUIF_MAP_LO_HI(ICH_LR11, ICH_LRC11, ICH_LR11_EL2)
+CPUIF_MAP_LO_HI(ICH_LR10, ICH_LRC10, ICH_LR10_EL2)
+CPUIF_MAP_LO_HI(ICH_LR9, ICH_LRC9, ICH_LR9_EL2)
+CPUIF_MAP_LO_HI(ICH_LR8, ICH_LRC8, ICH_LR8_EL2)
+CPUIF_MAP_LO_HI(ICH_LR7, ICH_LRC7, ICH_LR7_EL2)
+CPUIF_MAP_LO_HI(ICH_LR6, ICH_LRC6, ICH_LR6_EL2)
+CPUIF_MAP_LO_HI(ICH_LR5, ICH_LRC5, ICH_LR5_EL2)
+CPUIF_MAP_LO_HI(ICH_LR4, ICH_LRC4, ICH_LR4_EL2)
+CPUIF_MAP_LO_HI(ICH_LR3, ICH_LRC3, ICH_LR3_EL2)
+CPUIF_MAP_LO_HI(ICH_LR2, ICH_LRC2, ICH_LR2_EL2)
+CPUIF_MAP_LO_HI(ICH_LR1, ICH_LRC1, ICH_LR1_EL2)
+CPUIF_MAP_LO_HI(ICH_LR0, ICH_LRC0, ICH_LR0_EL2)
+
+#define read_gicreg(r)                 read_##r()
+#define write_gicreg(v, r)             write_##r(v)
+
 /* Low-level accessors */
 
 static inline void gic_write_eoir(u32 irq)
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 10/10] ARM: KVM: Support vgic-v3
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-12 14:49   ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: kvmarm; +Cc: marc.zyngier, andre.przywara, linux-arm-kernel

This patch allows to build and use vgic-v3 in 32-bit mode.

Unfortunately, it can not be split in several steps without extra
stubs to keep patches independent and bisectable.  For instance,
virt/kvm/arm/vgic/vgic-v3.c uses function from vgic-v3-sr.c, handling
access to GICv3 cpu interface from the guest requires vgic_v3.vgic_sre
to be already defined.

It is how support has been done:

* handle SGI requests from the guest

* report configured SRE on access to GICv3 cpu interface from the guest

* required vgic-v3 macros are provided via uapi.h

* static keys are used to select GIC backend

* to make vgic-v3 build KVM_ARM_VGIC_V3 guard is removed along with
  the static inlines

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/kvm_asm.h      |    3 ++
 arch/arm/include/asm/kvm_host.h     |    5 ++++
 arch/arm/include/asm/kvm_hyp.h      |    3 ++
 arch/arm/include/uapi/asm/kvm.h     |    7 +++++
 arch/arm/kvm/Makefile               |    2 ++
 arch/arm/kvm/coproc.c               |   35 +++++++++++++++++++++++
 arch/arm/kvm/hyp/Makefile           |    1 +
 arch/arm/kvm/hyp/switch.c           |   12 ++++++--
 arch/arm64/kvm/Kconfig              |    4 ---
 include/kvm/arm_vgic.h              |    8 ------
 virt/kvm/arm/vgic/vgic-kvm-device.c |    8 ------
 virt/kvm/arm/vgic/vgic-mmio.c       |    2 --
 virt/kvm/arm/vgic/vgic-mmio.h       |    2 --
 virt/kvm/arm/vgic/vgic.h            |   54 -----------------------------------
 14 files changed, 66 insertions(+), 80 deletions(-)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 58faff5..dfccf94 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -68,6 +68,9 @@ extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 extern void __init_stage2_translation(void);
 
 extern void __kvm_hyp_reset(unsigned long);
+
+extern u64 __vgic_v3_get_ich_vtr_el2(void);
+extern void __vgic_v3_init_lrs(void);
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index de338d9..c2c40a7 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -39,7 +39,12 @@
 
 #include <kvm/arm_vgic.h>
 
+
+#ifdef CONFIG_ARM_GIC_V3
+#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
+#else
 #define KVM_MAX_VCPUS VGIC_V2_MAX_CPUS
+#endif
 
 #define KVM_REQ_VCPU_EXIT	8
 
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
index e604ad68..343135e 100644
--- a/arch/arm/include/asm/kvm_hyp.h
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -106,6 +106,9 @@ void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
 void __sysreg_save_state(struct kvm_cpu_context *ctxt);
 void __sysreg_restore_state(struct kvm_cpu_context *ctxt);
 
+void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
+void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
+
 void asmlinkage __vfp_save_state(struct vfp_hard_struct *vfp);
 void asmlinkage __vfp_restore_state(struct vfp_hard_struct *vfp);
 static inline bool __vfp_enabled(void)
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index a2b3eb3..b38c10c 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -84,6 +84,13 @@ struct kvm_regs {
 #define KVM_VGIC_V2_DIST_SIZE		0x1000
 #define KVM_VGIC_V2_CPU_SIZE		0x2000
 
+/* Supported VGICv3 address types  */
+#define KVM_VGIC_V3_ADDR_TYPE_DIST	2
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
+
+#define KVM_VGIC_V3_DIST_SIZE		SZ_64K
+#define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
+
 #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
 #define KVM_ARM_VCPU_PSCI_0_2		1 /* CPU uses PSCI v0.2 */
 
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index 10d77a6..043d817f 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -26,8 +26,10 @@ obj-y += $(KVM)/arm/vgic/vgic.o
 obj-y += $(KVM)/arm/vgic/vgic-init.o
 obj-y += $(KVM)/arm/vgic/vgic-irqfd.o
 obj-y += $(KVM)/arm/vgic/vgic-v2.o
+obj-y += $(KVM)/arm/vgic/vgic-v3.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
+obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
 obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
 obj-y += $(KVM)/irqchip.o
 obj-y += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 1bb2b79..3e5e419 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -228,6 +228,35 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool access_gic_sgi(struct kvm_vcpu *vcpu,
+			   const struct coproc_params *p,
+			   const struct coproc_reg *r)
+{
+	u64 reg;
+
+	if (!p->is_write)
+		return read_from_write_only(vcpu, p);
+
+	reg = (u64)*vcpu_reg(vcpu, p->Rt2) << 32;
+	reg |= *vcpu_reg(vcpu, p->Rt1) ;
+
+	vgic_v3_dispatch_sgi(vcpu, reg);
+
+	return true;
+}
+
+static bool access_gic_sre(struct kvm_vcpu *vcpu,
+			   const struct coproc_params *p,
+			   const struct coproc_reg *r)
+{
+	if (p->is_write)
+		return ignore_write(vcpu, p);
+
+	*vcpu_reg(vcpu, p->Rt1) = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
+
+	return true;
+}
+
 /*
  * We could trap ID_DFR0 and tell the guest we don't support performance
  * monitoring.  Unfortunately the patch to make the kernel check ID_DFR0 was
@@ -361,10 +390,16 @@ static const struct coproc_reg cp15_regs[] = {
 	{ CRn(10), CRm( 3), Op1( 0), Op2( 1), is32,
 			access_vm_reg, reset_unknown, c10_AMAIR1},
 
+	/* ICC_SGI1R */
+	{ CRm64(12), Op1( 0), is64, access_gic_sgi},
+
 	/* VBAR: swapped by interrupt.S. */
 	{ CRn(12), CRm( 0), Op1( 0), Op2( 0), is32,
 			NULL, reset_val, c12_VBAR, 0x00000000 },
 
+	/* ICC_SRE */
+	{ CRn(12), CRm(12), Op1( 0), Op2(5), is32, access_gic_sre },
+
 	/* CONTEXTIDR/TPIDRURW/TPIDRURO/TPIDRPRW: swapped by interrupt.S. */
 	{ CRn(13), CRm( 0), Op1( 0), Op2( 1), is32,
 			access_vm_reg, reset_val, c13_CID, 0x00000000 },
diff --git a/arch/arm/kvm/hyp/Makefile b/arch/arm/kvm/hyp/Makefile
index 8dfa5f7..3023bb5 100644
--- a/arch/arm/kvm/hyp/Makefile
+++ b/arch/arm/kvm/hyp/Makefile
@@ -5,6 +5,7 @@
 KVM=../../../../virt/kvm
 
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
 
 obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
diff --git a/arch/arm/kvm/hyp/switch.c b/arch/arm/kvm/hyp/switch.c
index b13caa9..5c65a0b 100644
--- a/arch/arm/kvm/hyp/switch.c
+++ b/arch/arm/kvm/hyp/switch.c
@@ -14,6 +14,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#include <linux/jump_label.h>
 
 #include <asm/kvm_asm.h>
 #include <asm/kvm_hyp.h>
@@ -74,14 +75,21 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
 	write_sysreg(read_sysreg(MIDR), VPIDR);
 }
 
+
 static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
 {
-	__vgic_v2_save_state(vcpu);
+	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+		__vgic_v3_save_state(vcpu);
+	else
+		__vgic_v2_save_state(vcpu);
 }
 
 static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
 {
-	__vgic_v2_restore_state(vcpu);
+	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+		__vgic_v3_restore_state(vcpu);
+	else
+		__vgic_v2_restore_state(vcpu);
 }
 
 static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 7ba9164..6eaf12c 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -19,9 +19,6 @@ if VIRTUALIZATION
 config KVM_ARM_VGIC_V3_ITS
 	bool
 
-config KVM_ARM_VGIC_V3
-	bool
-
 config KVM
 	bool "Kernel-based Virtual Machine (KVM) support"
 	depends on OF
@@ -37,7 +34,6 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
-	select KVM_ARM_VGIC_V3
 	select KVM_ARM_VGIC_V3_ITS
 	select KVM_ARM_PMU if HW_PERF_EVENTS
 	select HAVE_KVM_MSI
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 994665a..843e286 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -221,7 +221,6 @@ struct vgic_v2_cpu_if {
 };
 
 struct vgic_v3_cpu_if {
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 	u32		vgic_hcr;
 	u32		vgic_vmcr;
 	u32		vgic_sre;	/* Restored only, change ignored */
@@ -231,7 +230,6 @@ struct vgic_v3_cpu_if {
 	u32		vgic_ap0r[4];
 	u32		vgic_ap1r[4];
 	u64		vgic_lr[VGIC_V3_MAX_LRS];
-#endif
 };
 
 struct vgic_cpu {
@@ -298,13 +296,7 @@ bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu);
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
-#else
-static inline void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
-{
-}
-#endif
 
 /**
  * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index f3811b3..4dc026a 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -71,7 +71,6 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
 		addr_ptr = &vgic->vgic_cpu_base;
 		alignment = SZ_4K;
 		break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 	case KVM_VGIC_V3_ADDR_TYPE_DIST:
 		type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
 		addr_ptr = &vgic->vgic_dist_base;
@@ -82,7 +81,6 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
 		addr_ptr = &vgic->vgic_redist_base;
 		alignment = SZ_64K;
 		break;
-#endif
 	default:
 		r = -ENODEV;
 		goto out;
@@ -219,7 +217,6 @@ int kvm_register_vgic_device(unsigned long type)
 		ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
 					      KVM_DEV_TYPE_ARM_VGIC_V2);
 		break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 	case KVM_DEV_TYPE_ARM_VGIC_V3:
 		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
 					      KVM_DEV_TYPE_ARM_VGIC_V3);
@@ -230,7 +227,6 @@ int kvm_register_vgic_device(unsigned long type)
 		ret = kvm_vgic_register_its_device();
 #endif
 		break;
-#endif
 	}
 
 	return ret;
@@ -392,8 +388,6 @@ struct kvm_device_ops kvm_arm_vgic_v2_ops = {
 
 /* V3 ops */
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3
-
 static int vgic_v3_set_attr(struct kvm_device *dev,
 			    struct kvm_device_attr *attr)
 {
@@ -436,5 +430,3 @@ struct kvm_device_ops kvm_arm_vgic_v3_ops = {
 	.get_attr = vgic_v3_get_attr,
 	.has_attr = vgic_v3_has_attr,
 };
-
-#endif /* CONFIG_KVM_ARM_VGIC_V3 */
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index 3bad3c5..e18b30d 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -550,11 +550,9 @@ int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address,
 	case VGIC_V2:
 		len = vgic_v2_init_dist_iodev(io_device);
 		break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 	case VGIC_V3:
 		len = vgic_v3_init_dist_iodev(io_device);
 		break;
-#endif
 	default:
 		BUG_ON(1);
 	}
diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
index 80f92ce..4c34d39 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.h
+++ b/virt/kvm/arm/vgic/vgic-mmio.h
@@ -162,12 +162,10 @@ unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev);
 
 unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev);
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 u64 vgic_sanitise_outer_cacheability(u64 reg);
 u64 vgic_sanitise_inner_cacheability(u64 reg);
 u64 vgic_sanitise_shareability(u64 reg);
 u64 vgic_sanitise_field(u64 reg, u64 field_mask, int field_shift,
 			u64 (*sanitise_fn)(u64));
-#endif
 
 #endif
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 100045f..9d9e014 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -72,7 +72,6 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
 	kref_get(&irq->refcount);
 }
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu);
 void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu);
 void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr);
@@ -91,60 +90,7 @@ bool vgic_has_its(struct kvm *kvm);
 int kvm_vgic_register_its_device(void);
 void vgic_enable_lpis(struct kvm_vcpu *vcpu);
 int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
-#endif
-
 #else
-static inline void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline void vgic_v3_populate_lr(struct kvm_vcpu *vcpu,
-				       struct vgic_irq *irq, int lr)
-{
-}
-
-static inline void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr)
-{
-}
-
-static inline void vgic_v3_set_underflow(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline
-void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
-{
-}
-
-static inline
-void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
-{
-}
-
-static inline void vgic_v3_enable(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline int vgic_v3_probe(const struct gic_kvm_info *info)
-{
-	return -ENODEV;
-}
-
-static inline int vgic_v3_map_resources(struct kvm *kvm)
-{
-	return -ENODEV;
-}
-
-static inline int vgic_register_redist_iodevs(struct kvm *kvm,
-					      gpa_t dist_base_address)
-{
-	return -ENODEV;
-}
-
 static inline int vgic_register_its_iodevs(struct kvm *kvm)
 {
 	return -ENODEV;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* [PATCH v4 10/10] ARM: KVM: Support vgic-v3
@ 2016-09-12 14:49   ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-12 14:49 UTC (permalink / raw)
  To: linux-arm-kernel

This patch allows to build and use vgic-v3 in 32-bit mode.

Unfortunately, it can not be split in several steps without extra
stubs to keep patches independent and bisectable.  For instance,
virt/kvm/arm/vgic/vgic-v3.c uses function from vgic-v3-sr.c, handling
access to GICv3 cpu interface from the guest requires vgic_v3.vgic_sre
to be already defined.

It is how support has been done:

* handle SGI requests from the guest

* report configured SRE on access to GICv3 cpu interface from the guest

* required vgic-v3 macros are provided via uapi.h

* static keys are used to select GIC backend

* to make vgic-v3 build KVM_ARM_VGIC_V3 guard is removed along with
  the static inlines

Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
---
 arch/arm/include/asm/kvm_asm.h      |    3 ++
 arch/arm/include/asm/kvm_host.h     |    5 ++++
 arch/arm/include/asm/kvm_hyp.h      |    3 ++
 arch/arm/include/uapi/asm/kvm.h     |    7 +++++
 arch/arm/kvm/Makefile               |    2 ++
 arch/arm/kvm/coproc.c               |   35 +++++++++++++++++++++++
 arch/arm/kvm/hyp/Makefile           |    1 +
 arch/arm/kvm/hyp/switch.c           |   12 ++++++--
 arch/arm64/kvm/Kconfig              |    4 ---
 include/kvm/arm_vgic.h              |    8 ------
 virt/kvm/arm/vgic/vgic-kvm-device.c |    8 ------
 virt/kvm/arm/vgic/vgic-mmio.c       |    2 --
 virt/kvm/arm/vgic/vgic-mmio.h       |    2 --
 virt/kvm/arm/vgic/vgic.h            |   54 -----------------------------------
 14 files changed, 66 insertions(+), 80 deletions(-)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 58faff5..dfccf94 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -68,6 +68,9 @@ extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
 extern void __init_stage2_translation(void);
 
 extern void __kvm_hyp_reset(unsigned long);
+
+extern u64 __vgic_v3_get_ich_vtr_el2(void);
+extern void __vgic_v3_init_lrs(void);
 #endif
 
 #endif /* __ARM_KVM_ASM_H__ */
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index de338d9..c2c40a7 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -39,7 +39,12 @@
 
 #include <kvm/arm_vgic.h>
 
+
+#ifdef CONFIG_ARM_GIC_V3
+#define KVM_MAX_VCPUS VGIC_V3_MAX_CPUS
+#else
 #define KVM_MAX_VCPUS VGIC_V2_MAX_CPUS
+#endif
 
 #define KVM_REQ_VCPU_EXIT	8
 
diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
index e604ad68..343135e 100644
--- a/arch/arm/include/asm/kvm_hyp.h
+++ b/arch/arm/include/asm/kvm_hyp.h
@@ -106,6 +106,9 @@ void __vgic_v2_restore_state(struct kvm_vcpu *vcpu);
 void __sysreg_save_state(struct kvm_cpu_context *ctxt);
 void __sysreg_restore_state(struct kvm_cpu_context *ctxt);
 
+void __vgic_v3_save_state(struct kvm_vcpu *vcpu);
+void __vgic_v3_restore_state(struct kvm_vcpu *vcpu);
+
 void asmlinkage __vfp_save_state(struct vfp_hard_struct *vfp);
 void asmlinkage __vfp_restore_state(struct vfp_hard_struct *vfp);
 static inline bool __vfp_enabled(void)
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index a2b3eb3..b38c10c 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -84,6 +84,13 @@ struct kvm_regs {
 #define KVM_VGIC_V2_DIST_SIZE		0x1000
 #define KVM_VGIC_V2_CPU_SIZE		0x2000
 
+/* Supported VGICv3 address types  */
+#define KVM_VGIC_V3_ADDR_TYPE_DIST	2
+#define KVM_VGIC_V3_ADDR_TYPE_REDIST	3
+
+#define KVM_VGIC_V3_DIST_SIZE		SZ_64K
+#define KVM_VGIC_V3_REDIST_SIZE		(2 * SZ_64K)
+
 #define KVM_ARM_VCPU_POWER_OFF		0 /* CPU is started in OFF state */
 #define KVM_ARM_VCPU_PSCI_0_2		1 /* CPU uses PSCI v0.2 */
 
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index 10d77a6..043d817f 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -26,8 +26,10 @@ obj-y += $(KVM)/arm/vgic/vgic.o
 obj-y += $(KVM)/arm/vgic/vgic-init.o
 obj-y += $(KVM)/arm/vgic/vgic-irqfd.o
 obj-y += $(KVM)/arm/vgic/vgic-v2.o
+obj-y += $(KVM)/arm/vgic/vgic-v3.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio.o
 obj-y += $(KVM)/arm/vgic/vgic-mmio-v2.o
+obj-y += $(KVM)/arm/vgic/vgic-mmio-v3.o
 obj-y += $(KVM)/arm/vgic/vgic-kvm-device.o
 obj-y += $(KVM)/irqchip.o
 obj-y += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 1bb2b79..3e5e419 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -228,6 +228,35 @@ bool access_vm_reg(struct kvm_vcpu *vcpu,
 	return true;
 }
 
+static bool access_gic_sgi(struct kvm_vcpu *vcpu,
+			   const struct coproc_params *p,
+			   const struct coproc_reg *r)
+{
+	u64 reg;
+
+	if (!p->is_write)
+		return read_from_write_only(vcpu, p);
+
+	reg = (u64)*vcpu_reg(vcpu, p->Rt2) << 32;
+	reg |= *vcpu_reg(vcpu, p->Rt1) ;
+
+	vgic_v3_dispatch_sgi(vcpu, reg);
+
+	return true;
+}
+
+static bool access_gic_sre(struct kvm_vcpu *vcpu,
+			   const struct coproc_params *p,
+			   const struct coproc_reg *r)
+{
+	if (p->is_write)
+		return ignore_write(vcpu, p);
+
+	*vcpu_reg(vcpu, p->Rt1) = vcpu->arch.vgic_cpu.vgic_v3.vgic_sre;
+
+	return true;
+}
+
 /*
  * We could trap ID_DFR0 and tell the guest we don't support performance
  * monitoring.  Unfortunately the patch to make the kernel check ID_DFR0 was
@@ -361,10 +390,16 @@ static const struct coproc_reg cp15_regs[] = {
 	{ CRn(10), CRm( 3), Op1( 0), Op2( 1), is32,
 			access_vm_reg, reset_unknown, c10_AMAIR1},
 
+	/* ICC_SGI1R */
+	{ CRm64(12), Op1( 0), is64, access_gic_sgi},
+
 	/* VBAR: swapped by interrupt.S. */
 	{ CRn(12), CRm( 0), Op1( 0), Op2( 0), is32,
 			NULL, reset_val, c12_VBAR, 0x00000000 },
 
+	/* ICC_SRE */
+	{ CRn(12), CRm(12), Op1( 0), Op2(5), is32, access_gic_sre },
+
 	/* CONTEXTIDR/TPIDRURW/TPIDRURO/TPIDRPRW: swapped by interrupt.S. */
 	{ CRn(13), CRm( 0), Op1( 0), Op2( 1), is32,
 			access_vm_reg, reset_val, c13_CID, 0x00000000 },
diff --git a/arch/arm/kvm/hyp/Makefile b/arch/arm/kvm/hyp/Makefile
index 8dfa5f7..3023bb5 100644
--- a/arch/arm/kvm/hyp/Makefile
+++ b/arch/arm/kvm/hyp/Makefile
@@ -5,6 +5,7 @@
 KVM=../../../../virt/kvm
 
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v2-sr.o
+obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/vgic-v3-sr.o
 obj-$(CONFIG_KVM_ARM_HOST) += $(KVM)/arm/hyp/timer-sr.o
 
 obj-$(CONFIG_KVM_ARM_HOST) += tlb.o
diff --git a/arch/arm/kvm/hyp/switch.c b/arch/arm/kvm/hyp/switch.c
index b13caa9..5c65a0b 100644
--- a/arch/arm/kvm/hyp/switch.c
+++ b/arch/arm/kvm/hyp/switch.c
@@ -14,6 +14,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
+#include <linux/jump_label.h>
 
 #include <asm/kvm_asm.h>
 #include <asm/kvm_hyp.h>
@@ -74,14 +75,21 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
 	write_sysreg(read_sysreg(MIDR), VPIDR);
 }
 
+
 static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
 {
-	__vgic_v2_save_state(vcpu);
+	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+		__vgic_v3_save_state(vcpu);
+	else
+		__vgic_v2_save_state(vcpu);
 }
 
 static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
 {
-	__vgic_v2_restore_state(vcpu);
+	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
+		__vgic_v3_restore_state(vcpu);
+	else
+		__vgic_v2_restore_state(vcpu);
 }
 
 static bool __hyp_text __populate_fault_info(struct kvm_vcpu *vcpu)
diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig
index 7ba9164..6eaf12c 100644
--- a/arch/arm64/kvm/Kconfig
+++ b/arch/arm64/kvm/Kconfig
@@ -19,9 +19,6 @@ if VIRTUALIZATION
 config KVM_ARM_VGIC_V3_ITS
 	bool
 
-config KVM_ARM_VGIC_V3
-	bool
-
 config KVM
 	bool "Kernel-based Virtual Machine (KVM) support"
 	depends on OF
@@ -37,7 +34,6 @@ config KVM
 	select KVM_VFIO
 	select HAVE_KVM_EVENTFD
 	select HAVE_KVM_IRQFD
-	select KVM_ARM_VGIC_V3
 	select KVM_ARM_VGIC_V3_ITS
 	select KVM_ARM_PMU if HW_PERF_EVENTS
 	select HAVE_KVM_MSI
diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
index 994665a..843e286 100644
--- a/include/kvm/arm_vgic.h
+++ b/include/kvm/arm_vgic.h
@@ -221,7 +221,6 @@ struct vgic_v2_cpu_if {
 };
 
 struct vgic_v3_cpu_if {
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 	u32		vgic_hcr;
 	u32		vgic_vmcr;
 	u32		vgic_sre;	/* Restored only, change ignored */
@@ -231,7 +230,6 @@ struct vgic_v3_cpu_if {
 	u32		vgic_ap0r[4];
 	u32		vgic_ap1r[4];
 	u64		vgic_lr[VGIC_V3_MAX_LRS];
-#endif
 };
 
 struct vgic_cpu {
@@ -298,13 +296,7 @@ bool kvm_vcpu_has_pending_irqs(struct kvm_vcpu *vcpu);
 void kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu);
 void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu);
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg);
-#else
-static inline void vgic_v3_dispatch_sgi(struct kvm_vcpu *vcpu, u64 reg)
-{
-}
-#endif
 
 /**
  * kvm_vgic_get_max_vcpus - Get the maximum number of VCPUs allowed by HW
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c
index f3811b3..4dc026a 100644
--- a/virt/kvm/arm/vgic/vgic-kvm-device.c
+++ b/virt/kvm/arm/vgic/vgic-kvm-device.c
@@ -71,7 +71,6 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
 		addr_ptr = &vgic->vgic_cpu_base;
 		alignment = SZ_4K;
 		break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 	case KVM_VGIC_V3_ADDR_TYPE_DIST:
 		type_needed = KVM_DEV_TYPE_ARM_VGIC_V3;
 		addr_ptr = &vgic->vgic_dist_base;
@@ -82,7 +81,6 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write)
 		addr_ptr = &vgic->vgic_redist_base;
 		alignment = SZ_64K;
 		break;
-#endif
 	default:
 		r = -ENODEV;
 		goto out;
@@ -219,7 +217,6 @@ int kvm_register_vgic_device(unsigned long type)
 		ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops,
 					      KVM_DEV_TYPE_ARM_VGIC_V2);
 		break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 	case KVM_DEV_TYPE_ARM_VGIC_V3:
 		ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops,
 					      KVM_DEV_TYPE_ARM_VGIC_V3);
@@ -230,7 +227,6 @@ int kvm_register_vgic_device(unsigned long type)
 		ret = kvm_vgic_register_its_device();
 #endif
 		break;
-#endif
 	}
 
 	return ret;
@@ -392,8 +388,6 @@ struct kvm_device_ops kvm_arm_vgic_v2_ops = {
 
 /* V3 ops */
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3
-
 static int vgic_v3_set_attr(struct kvm_device *dev,
 			    struct kvm_device_attr *attr)
 {
@@ -436,5 +430,3 @@ struct kvm_device_ops kvm_arm_vgic_v3_ops = {
 	.get_attr = vgic_v3_get_attr,
 	.has_attr = vgic_v3_has_attr,
 };
-
-#endif /* CONFIG_KVM_ARM_VGIC_V3 */
diff --git a/virt/kvm/arm/vgic/vgic-mmio.c b/virt/kvm/arm/vgic/vgic-mmio.c
index 3bad3c5..e18b30d 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.c
+++ b/virt/kvm/arm/vgic/vgic-mmio.c
@@ -550,11 +550,9 @@ int vgic_register_dist_iodev(struct kvm *kvm, gpa_t dist_base_address,
 	case VGIC_V2:
 		len = vgic_v2_init_dist_iodev(io_device);
 		break;
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 	case VGIC_V3:
 		len = vgic_v3_init_dist_iodev(io_device);
 		break;
-#endif
 	default:
 		BUG_ON(1);
 	}
diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
index 80f92ce..4c34d39 100644
--- a/virt/kvm/arm/vgic/vgic-mmio.h
+++ b/virt/kvm/arm/vgic/vgic-mmio.h
@@ -162,12 +162,10 @@ unsigned int vgic_v2_init_dist_iodev(struct vgic_io_device *dev);
 
 unsigned int vgic_v3_init_dist_iodev(struct vgic_io_device *dev);
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 u64 vgic_sanitise_outer_cacheability(u64 reg);
 u64 vgic_sanitise_inner_cacheability(u64 reg);
 u64 vgic_sanitise_shareability(u64 reg);
 u64 vgic_sanitise_field(u64 reg, u64 field_mask, int field_shift,
 			u64 (*sanitise_fn)(u64));
-#endif
 
 #endif
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h
index 100045f..9d9e014 100644
--- a/virt/kvm/arm/vgic/vgic.h
+++ b/virt/kvm/arm/vgic/vgic.h
@@ -72,7 +72,6 @@ static inline void vgic_get_irq_kref(struct vgic_irq *irq)
 	kref_get(&irq->refcount);
 }
 
-#ifdef CONFIG_KVM_ARM_VGIC_V3
 void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu);
 void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu);
 void vgic_v3_populate_lr(struct kvm_vcpu *vcpu, struct vgic_irq *irq, int lr);
@@ -91,60 +90,7 @@ bool vgic_has_its(struct kvm *kvm);
 int kvm_vgic_register_its_device(void);
 void vgic_enable_lpis(struct kvm_vcpu *vcpu);
 int vgic_its_inject_msi(struct kvm *kvm, struct kvm_msi *msi);
-#endif
-
 #else
-static inline void vgic_v3_process_maintenance(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline void vgic_v3_fold_lr_state(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline void vgic_v3_populate_lr(struct kvm_vcpu *vcpu,
-				       struct vgic_irq *irq, int lr)
-{
-}
-
-static inline void vgic_v3_clear_lr(struct kvm_vcpu *vcpu, int lr)
-{
-}
-
-static inline void vgic_v3_set_underflow(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline
-void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
-{
-}
-
-static inline
-void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr)
-{
-}
-
-static inline void vgic_v3_enable(struct kvm_vcpu *vcpu)
-{
-}
-
-static inline int vgic_v3_probe(const struct gic_kvm_info *info)
-{
-	return -ENODEV;
-}
-
-static inline int vgic_v3_map_resources(struct kvm *kvm)
-{
-	return -ENODEV;
-}
-
-static inline int vgic_register_redist_iodevs(struct kvm *kvm,
-					      gpa_t dist_base_address)
-{
-	return -ENODEV;
-}
-
 static inline int vgic_register_its_iodevs(struct kvm *kvm)
 {
 	return -ENODEV;
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:20     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:20 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
> Currently GIC backend is selected via alternative framework and this
> is fine. We are going to introduce vgic-v3 to 32-bit world and there
> we don't have patching framework in hand, so we can either check
> support for GICv3 every time we need to choose which backend to use or
> try to optimise it by using static keys. The later looks quite
> promising because we can share logic involved in selecting GIC backend
> between architectures if both uses static keys.
> 
> This patch moves arm64 from alternative to static keys framework for
> selecting GIC backend. For that we embed static key into vgic_global
> and enable the key during vgic initialisation based on what has
> already been exposed by the host GIC driver.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>  include/kvm/arm_vgic.h        |    4 ++++
>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>  4 files changed, 20 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 5a84b45..d5c4cc5 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -16,6 +16,8 @@
>   */
>  
>  #include <linux/types.h>
> +#include <linux/jump_label.h>
> +
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_hyp.h>
>  
> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
>  	write_sysreg(0, vttbr_el2);
>  }
>  
> -static hyp_alternate_select(__vgic_call_save_state,
> -			    __vgic_v2_save_state, __vgic_v3_save_state,
> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> -
> -static hyp_alternate_select(__vgic_call_restore_state,
> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> -
>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>  {
> -	__vgic_call_save_state()(vcpu);
> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))

It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
hardware becomes mainstream), but as we don't have another primitive for
the 'default disabled' case, I suppose that's the best we can do.

> +		__vgic_v3_save_state(vcpu);
> +	else
> +		__vgic_v2_save_state(vcpu);
> +
>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
>  }
>  
> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>  	val |= vcpu->arch.irq_lines;
>  	write_sysreg(val, hcr_el2);
>  
> -	__vgic_call_restore_state()(vcpu);
> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> +		__vgic_v3_restore_state(vcpu);
> +	else
> +		__vgic_v2_restore_state(vcpu);
>  }
>  
>  static bool __hyp_text __true_value(void)
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 19b698e..994665a 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -23,6 +23,7 @@
>  #include <linux/types.h>
>  #include <kvm/iodev.h>
>  #include <linux/list.h>
> +#include <linux/jump_label.h>
>  
>  #define VGIC_V3_MAX_CPUS	255
>  #define VGIC_V2_MAX_CPUS	8
> @@ -63,6 +64,9 @@ struct vgic_global {
>  
>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
>  	bool			can_emulate_gicv2;
> +
> +	/* GIC system register CPU interface */
> +	struct static_key_false gicv3_cpuif;

Documentation/static-keys.txt says that we are not supposed to use
struct static_key_false directly.  This will obviously work quite
nicely, but we could consider adding a pair of
DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
but obviously this will need an ack from other maintainers.

Thoughts?


>  };
>  
>  extern struct vgic_global kvm_vgic_global_state;
> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
> index 83777c1..14d6718 100644
> --- a/virt/kvm/arm/vgic/vgic-init.c
> +++ b/virt/kvm/arm/vgic/vgic-init.c
> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
>  		break;
>  	case GIC_V3:
>  		ret = vgic_v3_probe(gic_kvm_info);
> +		if (!ret) {
> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
> +			kvm_info("GIC system register CPU interface\n");

nit: add enabled to the info message?

> +		}
>  		break;
>  	default:
>  		ret = -ENODEV;
> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> index e83b7fe..8a529a7 100644
> --- a/virt/kvm/arm/vgic/vgic.c
> +++ b/virt/kvm/arm/vgic/vgic.c
> @@ -29,7 +29,7 @@
>  #define DEBUG_SPINLOCK_BUG_ON(p)
>  #endif
>  
> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
>  
>  /*
>   * Locking order is always:
> -- 
> 1.7.9.5
> 

Overall this looks really nice, as long as we're clear on the static
keys stuff.

Thanks!
-Christoffer

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
@ 2016-09-13  8:20     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
> Currently GIC backend is selected via alternative framework and this
> is fine. We are going to introduce vgic-v3 to 32-bit world and there
> we don't have patching framework in hand, so we can either check
> support for GICv3 every time we need to choose which backend to use or
> try to optimise it by using static keys. The later looks quite
> promising because we can share logic involved in selecting GIC backend
> between architectures if both uses static keys.
> 
> This patch moves arm64 from alternative to static keys framework for
> selecting GIC backend. For that we embed static key into vgic_global
> and enable the key during vgic initialisation based on what has
> already been exposed by the host GIC driver.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>  include/kvm/arm_vgic.h        |    4 ++++
>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>  4 files changed, 20 insertions(+), 11 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> index 5a84b45..d5c4cc5 100644
> --- a/arch/arm64/kvm/hyp/switch.c
> +++ b/arch/arm64/kvm/hyp/switch.c
> @@ -16,6 +16,8 @@
>   */
>  
>  #include <linux/types.h>
> +#include <linux/jump_label.h>
> +
>  #include <asm/kvm_asm.h>
>  #include <asm/kvm_hyp.h>
>  
> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
>  	write_sysreg(0, vttbr_el2);
>  }
>  
> -static hyp_alternate_select(__vgic_call_save_state,
> -			    __vgic_v2_save_state, __vgic_v3_save_state,
> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> -
> -static hyp_alternate_select(__vgic_call_restore_state,
> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> -
>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>  {
> -	__vgic_call_save_state()(vcpu);
> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))

It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
hardware becomes mainstream), but as we don't have another primitive for
the 'default disabled' case, I suppose that's the best we can do.

> +		__vgic_v3_save_state(vcpu);
> +	else
> +		__vgic_v2_save_state(vcpu);
> +
>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
>  }
>  
> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>  	val |= vcpu->arch.irq_lines;
>  	write_sysreg(val, hcr_el2);
>  
> -	__vgic_call_restore_state()(vcpu);
> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> +		__vgic_v3_restore_state(vcpu);
> +	else
> +		__vgic_v2_restore_state(vcpu);
>  }
>  
>  static bool __hyp_text __true_value(void)
> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> index 19b698e..994665a 100644
> --- a/include/kvm/arm_vgic.h
> +++ b/include/kvm/arm_vgic.h
> @@ -23,6 +23,7 @@
>  #include <linux/types.h>
>  #include <kvm/iodev.h>
>  #include <linux/list.h>
> +#include <linux/jump_label.h>
>  
>  #define VGIC_V3_MAX_CPUS	255
>  #define VGIC_V2_MAX_CPUS	8
> @@ -63,6 +64,9 @@ struct vgic_global {
>  
>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
>  	bool			can_emulate_gicv2;
> +
> +	/* GIC system register CPU interface */
> +	struct static_key_false gicv3_cpuif;

Documentation/static-keys.txt says that we are not supposed to use
struct static_key_false directly.  This will obviously work quite
nicely, but we could consider adding a pair of
DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
but obviously this will need an ack from other maintainers.

Thoughts?


>  };
>  
>  extern struct vgic_global kvm_vgic_global_state;
> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
> index 83777c1..14d6718 100644
> --- a/virt/kvm/arm/vgic/vgic-init.c
> +++ b/virt/kvm/arm/vgic/vgic-init.c
> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
>  		break;
>  	case GIC_V3:
>  		ret = vgic_v3_probe(gic_kvm_info);
> +		if (!ret) {
> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
> +			kvm_info("GIC system register CPU interface\n");

nit: add enabled to the info message?

> +		}
>  		break;
>  	default:
>  		ret = -ENODEV;
> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> index e83b7fe..8a529a7 100644
> --- a/virt/kvm/arm/vgic/vgic.c
> +++ b/virt/kvm/arm/vgic/vgic.c
> @@ -29,7 +29,7 @@
>  #define DEBUG_SPINLOCK_BUG_ON(p)
>  #endif
>  
> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
>  
>  /*
>   * Locking order is always:
> -- 
> 1.7.9.5
> 

Overall this looks really nice, as long as we're clear on the static
keys stuff.

Thanks!
-Christoffer

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:38     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:38 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: marc.zyngier, andre.przywara, Russell King, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
> encode the affinity in a form compatible with ICC_SGI* registers.
> Unfortunately, that macro is missing on ARM, so let's add it.
> 
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/cputype.h |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
> index 1ee94c7..e2d94c1 100644
> --- a/arch/arm/include/asm/cputype.h
> +++ b/arch/arm/include/asm/cputype.h
> @@ -55,6 +55,7 @@
>  
>  #define MPIDR_LEVEL_BITS 8
>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>  

I'm not sure I follow the correctness of this completely.

This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
may have something in the Aff3 field, which we now shift left 24 bits,
but that is not the Aff3 field of AArch32's MPIDR.

What is the rationale for this making sense again?

Thanks,
-Christoffer

>  #define MPIDR_AFFINITY_LEVEL(mpidr, level) \
>  	((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-13  8:38     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
> encode the affinity in a form compatible with ICC_SGI* registers.
> Unfortunately, that macro is missing on ARM, so let's add it.
> 
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/cputype.h |    1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
> index 1ee94c7..e2d94c1 100644
> --- a/arch/arm/include/asm/cputype.h
> +++ b/arch/arm/include/asm/cputype.h
> @@ -55,6 +55,7 @@
>  
>  #define MPIDR_LEVEL_BITS 8
>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>  

I'm not sure I follow the correctness of this completely.

This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
may have something in the Aff3 field, which we now shift left 24 bits,
but that is not the Aff3 field of AArch32's MPIDR.

What is the rationale for this making sense again?

Thanks,
-Christoffer

>  #define MPIDR_AFFINITY_LEVEL(mpidr, level) \
>  	((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 03/10] arm64: KVM: Move vgic-v3 save/restore to virt/kvm/arm/hyp
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:51     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:51 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:17PM +0100, Vladimir Murzin wrote:
> So we can reuse the code under arch/arm
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 03/10] arm64: KVM: Move vgic-v3 save/restore to virt/kvm/arm/hyp
@ 2016-09-13  8:51     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:17PM +0100, Vladimir Murzin wrote:
> So we can reuse the code under arch/arm
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 04/10] KVM: arm64: vgic-its: Introduce config option to guard ITS specific code
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:51     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:51 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:18PM +0100, Vladimir Murzin wrote:
> By now ITS code guarded with KVM_ARM_VGIC_V3 config option which was
> introduced to hide everything specific to vgic-v3 from 32-bit world.
> We are going to support vgic-v3 in 32-bit world and KVM_ARM_VGIC_V3
> will gone, but we don't have support for ITS there yet and we need to
> continue keeping ITS away.
> Introduce the new config option to prevent ITS code being build in
> 32-bit mode when support for vgic-v3 is done.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 04/10] KVM: arm64: vgic-its: Introduce config option to guard ITS specific code
@ 2016-09-13  8:51     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:18PM +0100, Vladimir Murzin wrote:
> By now ITS code guarded with KVM_ARM_VGIC_V3 config option which was
> introduced to hide everything specific to vgic-v3 from 32-bit world.
> We are going to support vgic-v3 in 32-bit world and KVM_ARM_VGIC_V3
> will gone, but we don't have support for ITS there yet and we need to
> continue keeping ITS away.
> Introduce the new config option to prevent ITS code being build in
> 32-bit mode when support for vgic-v3 is done.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> Acked-by: Marc Zyngier <marc.zyngier@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 05/10] KVM: arm: vgic: Fix compiler warnings when built for 32-bit
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:51     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:51 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:19PM +0100, Vladimir Murzin wrote:
> Well, this patch is looking ahead of time, but we'll get following
> compiler warnings as soon as we introduce vgic-v3 to 32-bit world
> 
>   CC      arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.o
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_mmio_read_v3r_typer':
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:184:35: warning: left shift count >= width of type [-Wshift-count-overflow]
>   value = (mpidr & GENMASK(23, 0)) << 32;
>                                    ^
> In file included from ./include/linux/kernel.h:10:0,
>                  from ./include/asm-generic/bug.h:13,
>                  from ./arch/arm/include/asm/bug.h:59,
>                  from ./include/linux/bug.h:4,
>                  from ./include/linux/io.h:23,
>                  from ./arch/arm/include/asm/arch_gicv3.h:23,
>                  from ./include/linux/irqchip/arm-gic-v3.h:411,
>                  from arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:14:
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_v3_dispatch_sgi':
> ./include/linux/bitops.h:6:24: warning: left shift count >= width of type [-Wshift-count-overflow]
>  #define BIT(nr)   (1UL << (nr))
>                         ^
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:614:20: note: in expansion of macro 'BIT'
>   broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
>                     ^
> Let's fix them now.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 05/10] KVM: arm: vgic: Fix compiler warnings when built for 32-bit
@ 2016-09-13  8:51     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:19PM +0100, Vladimir Murzin wrote:
> Well, this patch is looking ahead of time, but we'll get following
> compiler warnings as soon as we introduce vgic-v3 to 32-bit world
> 
>   CC      arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.o
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_mmio_read_v3r_typer':
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:184:35: warning: left shift count >= width of type [-Wshift-count-overflow]
>   value = (mpidr & GENMASK(23, 0)) << 32;
>                                    ^
> In file included from ./include/linux/kernel.h:10:0,
>                  from ./include/asm-generic/bug.h:13,
>                  from ./arch/arm/include/asm/bug.h:59,
>                  from ./include/linux/bug.h:4,
>                  from ./include/linux/io.h:23,
>                  from ./arch/arm/include/asm/arch_gicv3.h:23,
>                  from ./include/linux/irqchip/arm-gic-v3.h:411,
>                  from arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:14:
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_v3_dispatch_sgi':
> ./include/linux/bitops.h:6:24: warning: left shift count >= width of type [-Wshift-count-overflow]
>  #define BIT(nr)   (1UL << (nr))
>                         ^
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:614:20: note: in expansion of macro 'BIT'
>   broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
>                     ^
> Let's fix them now.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 06/10] KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host systems
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:51     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:51 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:20PM +0100, Vladimir Murzin wrote:
> We have couple of 64-bit registers defined in GICv3 architecture, so
> unsigned long accesses to these registers will only access a single
> 32-bit part of that regitser. On the other hand these registers can't
> be accessed as 64-bit with a single instruction like ldrd/strd or
> ldmia/stmia if we run a 32-bit host because KVM does not support
> access to MMIO space done by these instructions.
> 
> It means that a 32-bit guest accesses these registers in 32-bit
> chunks, so the only thing we need to do is to ensure that
> extract_bytes() always takes 64-bit data.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
>  virt/kvm/arm/vgic/vgic-mmio-v3.c |    2 +-
>  virt/kvm/arm/vgic/vgic-mmio.h    |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> index 6385ed5..0d3c76a 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> @@ -23,7 +23,7 @@
>  #include "vgic-mmio.h"
>  
>  /* extract @num bytes at @offset bytes offset in data */
> -unsigned long extract_bytes(unsigned long data, unsigned int offset,
> +unsigned long extract_bytes(u64 data, unsigned int offset,
>  			    unsigned int num)
>  {
>  	return (data >> (offset * 8)) & GENMASK_ULL(num * 8 - 1, 0);
> diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
> index 0b3ecf9..80f92ce 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio.h
> +++ b/virt/kvm/arm/vgic/vgic-mmio.h
> @@ -96,7 +96,7 @@ unsigned long vgic_data_mmio_bus_to_host(const void *val, unsigned int len);
>  void vgic_data_host_to_mmio_bus(void *buf, unsigned int len,
>  				unsigned long data);
>  
> -unsigned long extract_bytes(unsigned long data, unsigned int offset,
> +unsigned long extract_bytes(u64 data, unsigned int offset,
>  			    unsigned int num);
>  
>  u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 06/10] KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host systems
@ 2016-09-13  8:51     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:20PM +0100, Vladimir Murzin wrote:
> We have couple of 64-bit registers defined in GICv3 architecture, so
> unsigned long accesses to these registers will only access a single
> 32-bit part of that regitser. On the other hand these registers can't
> be accessed as 64-bit with a single instruction like ldrd/strd or
> ldmia/stmia if we run a 32-bit host because KVM does not support
> access to MMIO space done by these instructions.
> 
> It means that a 32-bit guest accesses these registers in 32-bit
> chunks, so the only thing we need to do is to ensure that
> extract_bytes() always takes 64-bit data.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
>  virt/kvm/arm/vgic/vgic-mmio-v3.c |    2 +-
>  virt/kvm/arm/vgic/vgic-mmio.h    |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/virt/kvm/arm/vgic/vgic-mmio-v3.c b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> index 6385ed5..0d3c76a 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio-v3.c
> +++ b/virt/kvm/arm/vgic/vgic-mmio-v3.c
> @@ -23,7 +23,7 @@
>  #include "vgic-mmio.h"
>  
>  /* extract @num bytes at @offset bytes offset in data */
> -unsigned long extract_bytes(unsigned long data, unsigned int offset,
> +unsigned long extract_bytes(u64 data, unsigned int offset,
>  			    unsigned int num)
>  {
>  	return (data >> (offset * 8)) & GENMASK_ULL(num * 8 - 1, 0);
> diff --git a/virt/kvm/arm/vgic/vgic-mmio.h b/virt/kvm/arm/vgic/vgic-mmio.h
> index 0b3ecf9..80f92ce 100644
> --- a/virt/kvm/arm/vgic/vgic-mmio.h
> +++ b/virt/kvm/arm/vgic/vgic-mmio.h
> @@ -96,7 +96,7 @@ unsigned long vgic_data_mmio_bus_to_host(const void *val, unsigned int len);
>  void vgic_data_host_to_mmio_bus(void *buf, unsigned int len,
>  				unsigned long data);
>  
> -unsigned long extract_bytes(unsigned long data, unsigned int offset,
> +unsigned long extract_bytes(u64 data, unsigned int offset,
>  			    unsigned int num);
>  
>  u64 update_64bit_reg(u64 reg, unsigned int offset, unsigned int len,
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 08/10] ARM: Move system register accessors to asm/cp15.h
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:52     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:52 UTC (permalink / raw)
  To: Vladimir Murzin
  Cc: marc.zyngier, andre.przywara, Russell King, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:22PM +0100, Vladimir Murzin wrote:
> Headers linux/irqchip/arm-gic.v3.h and arch/arm/include/asm/kvm_hyp.h
> are included in virt/kvm/arm/hyp/vgic-v3-sr.c and both define macros
> called __ACCESS_CP15 and __ACCESS_CP15_64 which obviously creates a
> conflict. These macros were introduced independently for GIC and KVM
> and, in fact, do the same thing.
> 
> As an option we could add prefixes to KVM and GIC version of macros so
> they won't clash, but it'd introduce code duplication.  Alternatively,
> we could keep macro in, say, GIC header and include it in KVM one (or
> vice versa), but such dependency would not look nicer.
> 
> So we follow arm64 way (it handles this via sysreg.h) and move only
> single set of macros to asm/cp15.h
> 
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
>  arch/arm/include/asm/arch_gicv3.h |   27 +++++++++++----------------
>  arch/arm/include/asm/cp15.h       |   15 +++++++++++++++
>  arch/arm/include/asm/kvm_hyp.h    |   15 +--------------
>  3 files changed, 27 insertions(+), 30 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
> index e08d151..af25c32 100644
> --- a/arch/arm/include/asm/arch_gicv3.h
> +++ b/arch/arm/include/asm/arch_gicv3.h
> @@ -22,9 +22,7 @@
>  
>  #include <linux/io.h>
>  #include <asm/barrier.h>
> -
> -#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	p15, Op1, %0, CRn, CRm, Op2
> -#define __ACCESS_CP15_64(Op1, CRm)		p15, Op1, %Q0, %R0, CRm
> +#include <asm/cp15.h>
>  
>  #define ICC_EOIR1			__ACCESS_CP15(c12, 0, c12, 1)
>  #define ICC_DIR				__ACCESS_CP15(c12, 0, c11, 1)
> @@ -102,58 +100,55 @@
>  
>  static inline void gic_write_eoir(u32 irq)
>  {
> -	asm volatile("mcr " __stringify(ICC_EOIR1) : : "r" (irq));
> +	write_sysreg(irq, ICC_EOIR1);
>  	isb();
>  }
>  
>  static inline void gic_write_dir(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_DIR) : : "r" (val));
> +	write_sysreg(val, ICC_DIR);
>  	isb();
>  }
>  
>  static inline u32 gic_read_iar(void)
>  {
> -	u32 irqstat;
> +	u32 irqstat = read_sysreg(ICC_IAR1);
>  
> -	asm volatile("mrc " __stringify(ICC_IAR1) : "=r" (irqstat));
>  	dsb(sy);
> +
>  	return irqstat;
>  }
>  
>  static inline void gic_write_pmr(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
> +	write_sysreg(val, ICC_PMR);
>  }
>  
>  static inline void gic_write_ctlr(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_CTLR) : : "r" (val));
> +	write_sysreg(val, ICC_CTLR);
>  	isb();
>  }
>  
>  static inline void gic_write_grpen1(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
> +	write_sysreg(val, ICC_IGRPEN1);
>  	isb();
>  }
>  
>  static inline void gic_write_sgi1r(u64 val)
>  {
> -	asm volatile("mcrr " __stringify(ICC_SGI1R) : : "r" (val));
> +	write_sysreg(val, ICC_SGI1R);
>  }
>  
>  static inline u32 gic_read_sre(void)
>  {
> -	u32 val;
> -
> -	asm volatile("mrc " __stringify(ICC_SRE) : "=r" (val));
> -	return val;
> +	return read_sysreg(ICC_SRE);
>  }
>  
>  static inline void gic_write_sre(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_SRE) : : "r" (val));
> +	write_sysreg(val, ICC_SRE);
>  	isb();
>  }
>  
> diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
> index c3f1152..dbdbce1 100644
> --- a/arch/arm/include/asm/cp15.h
> +++ b/arch/arm/include/asm/cp15.h
> @@ -49,6 +49,21 @@
>  
>  #ifdef CONFIG_CPU_CP15
>  
> +#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
> +	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
> +#define __ACCESS_CP15_64(Op1, CRm)		\
> +	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
> +
> +#define __read_sysreg(r, w, c, t) ({				\
> +	t __val;						\
> +	asm volatile(r " " c : "=r" (__val));			\
> +	__val;							\
> +})
> +#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)
> +
> +#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
> +#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
> +
>  extern unsigned long cr_alignment;	/* defined in entry-armv.S */
>  
>  static inline unsigned long get_cr(void)
> diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
> index 6eaff28..e604ad68 100644
> --- a/arch/arm/include/asm/kvm_hyp.h
> +++ b/arch/arm/include/asm/kvm_hyp.h
> @@ -20,28 +20,15 @@
>  
>  #include <linux/compiler.h>
>  #include <linux/kvm_host.h>
> +#include <asm/cp15.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/vfp.h>
>  
>  #define __hyp_text __section(.hyp.text) notrace
>  
> -#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
> -	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
> -#define __ACCESS_CP15_64(Op1, CRm)		\
> -	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
>  #define __ACCESS_VFP(CRn)			\
>  	"mrc", "mcr", __stringify(p10, 7, %0, CRn, cr0, 0), u32
>  
> -#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
> -#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
> -
> -#define __read_sysreg(r, w, c, t) ({				\
> -	t __val;						\
> -	asm volatile(r " " c : "=r" (__val));			\
> -	__val;							\
> -})
> -#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)
> -
>  #define write_special(v, r)					\
>  	asm volatile("msr " __stringify(r) ", %0" : : "r" (v))
>  #define read_special(r) ({					\
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 08/10] ARM: Move system register accessors to asm/cp15.h
@ 2016-09-13  8:52     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:22PM +0100, Vladimir Murzin wrote:
> Headers linux/irqchip/arm-gic.v3.h and arch/arm/include/asm/kvm_hyp.h
> are included in virt/kvm/arm/hyp/vgic-v3-sr.c and both define macros
> called __ACCESS_CP15 and __ACCESS_CP15_64 which obviously creates a
> conflict. These macros were introduced independently for GIC and KVM
> and, in fact, do the same thing.
> 
> As an option we could add prefixes to KVM and GIC version of macros so
> they won't clash, but it'd introduce code duplication.  Alternatively,
> we could keep macro in, say, GIC header and include it in KVM one (or
> vice versa), but such dependency would not look nicer.
> 
> So we follow arm64 way (it handles this via sysreg.h) and move only
> single set of macros to asm/cp15.h
> 
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

> ---
>  arch/arm/include/asm/arch_gicv3.h |   27 +++++++++++----------------
>  arch/arm/include/asm/cp15.h       |   15 +++++++++++++++
>  arch/arm/include/asm/kvm_hyp.h    |   15 +--------------
>  3 files changed, 27 insertions(+), 30 deletions(-)
> 
> diff --git a/arch/arm/include/asm/arch_gicv3.h b/arch/arm/include/asm/arch_gicv3.h
> index e08d151..af25c32 100644
> --- a/arch/arm/include/asm/arch_gicv3.h
> +++ b/arch/arm/include/asm/arch_gicv3.h
> @@ -22,9 +22,7 @@
>  
>  #include <linux/io.h>
>  #include <asm/barrier.h>
> -
> -#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	p15, Op1, %0, CRn, CRm, Op2
> -#define __ACCESS_CP15_64(Op1, CRm)		p15, Op1, %Q0, %R0, CRm
> +#include <asm/cp15.h>
>  
>  #define ICC_EOIR1			__ACCESS_CP15(c12, 0, c12, 1)
>  #define ICC_DIR				__ACCESS_CP15(c12, 0, c11, 1)
> @@ -102,58 +100,55 @@
>  
>  static inline void gic_write_eoir(u32 irq)
>  {
> -	asm volatile("mcr " __stringify(ICC_EOIR1) : : "r" (irq));
> +	write_sysreg(irq, ICC_EOIR1);
>  	isb();
>  }
>  
>  static inline void gic_write_dir(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_DIR) : : "r" (val));
> +	write_sysreg(val, ICC_DIR);
>  	isb();
>  }
>  
>  static inline u32 gic_read_iar(void)
>  {
> -	u32 irqstat;
> +	u32 irqstat = read_sysreg(ICC_IAR1);
>  
> -	asm volatile("mrc " __stringify(ICC_IAR1) : "=r" (irqstat));
>  	dsb(sy);
> +
>  	return irqstat;
>  }
>  
>  static inline void gic_write_pmr(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_PMR) : : "r" (val));
> +	write_sysreg(val, ICC_PMR);
>  }
>  
>  static inline void gic_write_ctlr(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_CTLR) : : "r" (val));
> +	write_sysreg(val, ICC_CTLR);
>  	isb();
>  }
>  
>  static inline void gic_write_grpen1(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_IGRPEN1) : : "r" (val));
> +	write_sysreg(val, ICC_IGRPEN1);
>  	isb();
>  }
>  
>  static inline void gic_write_sgi1r(u64 val)
>  {
> -	asm volatile("mcrr " __stringify(ICC_SGI1R) : : "r" (val));
> +	write_sysreg(val, ICC_SGI1R);
>  }
>  
>  static inline u32 gic_read_sre(void)
>  {
> -	u32 val;
> -
> -	asm volatile("mrc " __stringify(ICC_SRE) : "=r" (val));
> -	return val;
> +	return read_sysreg(ICC_SRE);
>  }
>  
>  static inline void gic_write_sre(u32 val)
>  {
> -	asm volatile("mcr " __stringify(ICC_SRE) : : "r" (val));
> +	write_sysreg(val, ICC_SRE);
>  	isb();
>  }
>  
> diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
> index c3f1152..dbdbce1 100644
> --- a/arch/arm/include/asm/cp15.h
> +++ b/arch/arm/include/asm/cp15.h
> @@ -49,6 +49,21 @@
>  
>  #ifdef CONFIG_CPU_CP15
>  
> +#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
> +	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
> +#define __ACCESS_CP15_64(Op1, CRm)		\
> +	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
> +
> +#define __read_sysreg(r, w, c, t) ({				\
> +	t __val;						\
> +	asm volatile(r " " c : "=r" (__val));			\
> +	__val;							\
> +})
> +#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)
> +
> +#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
> +#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
> +
>  extern unsigned long cr_alignment;	/* defined in entry-armv.S */
>  
>  static inline unsigned long get_cr(void)
> diff --git a/arch/arm/include/asm/kvm_hyp.h b/arch/arm/include/asm/kvm_hyp.h
> index 6eaff28..e604ad68 100644
> --- a/arch/arm/include/asm/kvm_hyp.h
> +++ b/arch/arm/include/asm/kvm_hyp.h
> @@ -20,28 +20,15 @@
>  
>  #include <linux/compiler.h>
>  #include <linux/kvm_host.h>
> +#include <asm/cp15.h>
>  #include <asm/kvm_mmu.h>
>  #include <asm/vfp.h>
>  
>  #define __hyp_text __section(.hyp.text) notrace
>  
> -#define __ACCESS_CP15(CRn, Op1, CRm, Op2)	\
> -	"mrc", "mcr", __stringify(p15, Op1, %0, CRn, CRm, Op2), u32
> -#define __ACCESS_CP15_64(Op1, CRm)		\
> -	"mrrc", "mcrr", __stringify(p15, Op1, %Q0, %R0, CRm), u64
>  #define __ACCESS_VFP(CRn)			\
>  	"mrc", "mcr", __stringify(p10, 7, %0, CRn, cr0, 0), u32
>  
> -#define __write_sysreg(v, r, w, c, t)	asm volatile(w " " c : : "r" ((t)(v)))
> -#define write_sysreg(v, ...)		__write_sysreg(v, __VA_ARGS__)
> -
> -#define __read_sysreg(r, w, c, t) ({				\
> -	t __val;						\
> -	asm volatile(r " " c : "=r" (__val));			\
> -	__val;							\
> -})
> -#define read_sysreg(...)		__read_sysreg(__VA_ARGS__)
> -
>  #define write_special(v, r)					\
>  	asm volatile("msr " __stringify(r) ", %0" : : "r" (v))
>  #define read_special(r) ({					\
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 09/10] ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:52     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:52 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:23PM +0100, Vladimir Murzin wrote:
> vgic-v3 save/restore routines are written in such way that they map
> arm64 system register naming nicely, but it does not fit to arm
> world. To keep virt/kvm/arm/hyp/vgic-v3-sr.c untouched we create a
> mapping with a function for each register mapping the 32-bit to the
> 64-bit accessors.
> 
> Please, note that 64-bit wide ICH_LR is split in two 32-bit halves
> (ICH_LR and ICH_LRC) accessed independently.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 09/10] ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
@ 2016-09-13  8:52     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:23PM +0100, Vladimir Murzin wrote:
> vgic-v3 save/restore routines are written in such way that they map
> arm64 system register naming nicely, but it does not fit to arm
> world. To keep virt/kvm/arm/hyp/vgic-v3-sr.c untouched we create a
> mapping with a function for each register mapping the 32-bit to the
> 64-bit accessors.
> 
> Please, note that 64-bit wide ICH_LR is split in two 32-bit halves
> (ICH_LR and ICH_LRC) accessed independently.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Acked-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 10/10] ARM: KVM: Support vgic-v3
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-13  8:52     ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:52 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:24PM +0100, Vladimir Murzin wrote:
> This patch allows to build and use vgic-v3 in 32-bit mode.
> 
> Unfortunately, it can not be split in several steps without extra
> stubs to keep patches independent and bisectable.  For instance,
> virt/kvm/arm/vgic/vgic-v3.c uses function from vgic-v3-sr.c, handling
> access to GICv3 cpu interface from the guest requires vgic_v3.vgic_sre
> to be already defined.
> 
> It is how support has been done:
> 
> * handle SGI requests from the guest
> 
> * report configured SRE on access to GICv3 cpu interface from the guest
> 
> * required vgic-v3 macros are provided via uapi.h
> 
> * static keys are used to select GIC backend
> 
> * to make vgic-v3 build KVM_ARM_VGIC_V3 guard is removed along with
>   the static inlines
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 10/10] ARM: KVM: Support vgic-v3
@ 2016-09-13  8:52     ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  8:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Sep 12, 2016 at 03:49:24PM +0100, Vladimir Murzin wrote:
> This patch allows to build and use vgic-v3 in 32-bit mode.
> 
> Unfortunately, it can not be split in several steps without extra
> stubs to keep patches independent and bisectable.  For instance,
> virt/kvm/arm/vgic/vgic-v3.c uses function from vgic-v3-sr.c, handling
> access to GICv3 cpu interface from the guest requires vgic_v3.vgic_sre
> to be already defined.
> 
> It is how support has been done:
> 
> * handle SGI requests from the guest
> 
> * report configured SRE on access to GICv3 cpu interface from the guest
> 
> * required vgic-v3 macros are provided via uapi.h
> 
> * static keys are used to select GIC backend
> 
> * to make vgic-v3 build KVM_ARM_VGIC_V3 guard is removed along with
>   the static inlines
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>

Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org>

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-13  8:38     ` Christoffer Dall
@ 2016-09-13  9:04       ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-13  9:04 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: marc.zyngier, andre.przywara, Russell King, kvmarm, linux-arm-kernel

On 13/09/16 09:38, Christoffer Dall wrote:
> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>> encode the affinity in a form compatible with ICC_SGI* registers.
>> Unfortunately, that macro is missing on ARM, so let's add it.
>>
>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>> ---
>>  arch/arm/include/asm/cputype.h |    1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>> index 1ee94c7..e2d94c1 100644
>> --- a/arch/arm/include/asm/cputype.h
>> +++ b/arch/arm/include/asm/cputype.h
>> @@ -55,6 +55,7 @@
>>  
>>  #define MPIDR_LEVEL_BITS 8
>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>  
> 
> I'm not sure I follow the correctness of this completely.
> 
> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
> may have something in the Aff3 field, which we now shift left 24 bits,
> but that is not the Aff3 field of AArch32's MPIDR.
> 
> What is the rationale for this making sense again?

IIUC, in such case we construct mpidr which won't match in match_mpidr()
with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
sent to the guest.

Since we get that u64 value from the guest, I'd think it is something
wrong is going on in the guest in case Aff3 is non-zero; however, we can
hide it by zeroing out SGI Aff3 bits in access_gic_sgi().

Cheers
Vladimir

> 
> Thanks,
> -Christoffer
> 
>>  #define MPIDR_AFFINITY_LEVEL(mpidr, level) \
>>  	((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
>> -- 
>> 1.7.9.5
>>
> 
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-13  9:04       ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-13  9:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/09/16 09:38, Christoffer Dall wrote:
> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>> encode the affinity in a form compatible with ICC_SGI* registers.
>> Unfortunately, that macro is missing on ARM, so let's add it.
>>
>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>> ---
>>  arch/arm/include/asm/cputype.h |    1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>> index 1ee94c7..e2d94c1 100644
>> --- a/arch/arm/include/asm/cputype.h
>> +++ b/arch/arm/include/asm/cputype.h
>> @@ -55,6 +55,7 @@
>>  
>>  #define MPIDR_LEVEL_BITS 8
>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>  
> 
> I'm not sure I follow the correctness of this completely.
> 
> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
> may have something in the Aff3 field, which we now shift left 24 bits,
> but that is not the Aff3 field of AArch32's MPIDR.
> 
> What is the rationale for this making sense again?

IIUC, in such case we construct mpidr which won't match in match_mpidr()
with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
sent to the guest.

Since we get that u64 value from the guest, I'd think it is something
wrong is going on in the guest in case Aff3 is non-zero; however, we can
hide it by zeroing out SGI Aff3 bits in access_gic_sgi().

Cheers
Vladimir

> 
> Thanks,
> -Christoffer
> 
>>  #define MPIDR_AFFINITY_LEVEL(mpidr, level) \
>>  	((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
>> -- 
>> 1.7.9.5
>>
> 
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
  2016-09-13  8:20     ` Christoffer Dall
@ 2016-09-13  9:11       ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-13  9:11 UTC (permalink / raw)
  To: Christoffer Dall, Vladimir Murzin
  Cc: andre.przywara, kvmarm, linux-arm-kernel

On 13/09/16 09:20, Christoffer Dall wrote:
> On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
>> Currently GIC backend is selected via alternative framework and this
>> is fine. We are going to introduce vgic-v3 to 32-bit world and there
>> we don't have patching framework in hand, so we can either check
>> support for GICv3 every time we need to choose which backend to use or
>> try to optimise it by using static keys. The later looks quite
>> promising because we can share logic involved in selecting GIC backend
>> between architectures if both uses static keys.
>>
>> This patch moves arm64 from alternative to static keys framework for
>> selecting GIC backend. For that we embed static key into vgic_global
>> and enable the key during vgic initialisation based on what has
>> already been exposed by the host GIC driver.
>>
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>> ---
>>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>>  include/kvm/arm_vgic.h        |    4 ++++
>>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>>  4 files changed, 20 insertions(+), 11 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>> index 5a84b45..d5c4cc5 100644
>> --- a/arch/arm64/kvm/hyp/switch.c
>> +++ b/arch/arm64/kvm/hyp/switch.c
>> @@ -16,6 +16,8 @@
>>   */
>>  
>>  #include <linux/types.h>
>> +#include <linux/jump_label.h>
>> +
>>  #include <asm/kvm_asm.h>
>>  #include <asm/kvm_hyp.h>
>>  
>> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
>>  	write_sysreg(0, vttbr_el2);
>>  }
>>  
>> -static hyp_alternate_select(__vgic_call_save_state,
>> -			    __vgic_v2_save_state, __vgic_v3_save_state,
>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>> -
>> -static hyp_alternate_select(__vgic_call_restore_state,
>> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>> -
>>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>>  {
>> -	__vgic_call_save_state()(vcpu);
>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> 
> It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
> hardware becomes mainstream), but as we don't have another primitive for
> the 'default disabled' case, I suppose that's the best we can do.

We could always revert the "likelihood" of that test once GICv3 has
conquered the world. Or start patching the 32bit kernel like we do for
64bit...

> 
>> +		__vgic_v3_save_state(vcpu);
>> +	else
>> +		__vgic_v2_save_state(vcpu);
>> +
>>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
>>  }
>>  
>> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>>  	val |= vcpu->arch.irq_lines;
>>  	write_sysreg(val, hcr_el2);
>>  
>> -	__vgic_call_restore_state()(vcpu);
>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>> +		__vgic_v3_restore_state(vcpu);
>> +	else
>> +		__vgic_v2_restore_state(vcpu);
>>  }
>>  
>>  static bool __hyp_text __true_value(void)
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 19b698e..994665a 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -23,6 +23,7 @@
>>  #include <linux/types.h>
>>  #include <kvm/iodev.h>
>>  #include <linux/list.h>
>> +#include <linux/jump_label.h>
>>  
>>  #define VGIC_V3_MAX_CPUS	255
>>  #define VGIC_V2_MAX_CPUS	8
>> @@ -63,6 +64,9 @@ struct vgic_global {
>>  
>>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
>>  	bool			can_emulate_gicv2;
>> +
>> +	/* GIC system register CPU interface */
>> +	struct static_key_false gicv3_cpuif;
> 
> Documentation/static-keys.txt says that we are not supposed to use
> struct static_key_false directly.  This will obviously work quite
> nicely, but we could consider adding a pair of
> DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
> but obviously this will need an ack from other maintainers.
> 
> Thoughts?

Grepping through the tree shows that we're not the only abusers of this
(dynamic debug is far worse!). Happy to write the additional macros and
submit them if nobody beats me to it.

> 
> 
>>  };
>>  
>>  extern struct vgic_global kvm_vgic_global_state;
>> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
>> index 83777c1..14d6718 100644
>> --- a/virt/kvm/arm/vgic/vgic-init.c
>> +++ b/virt/kvm/arm/vgic/vgic-init.c
>> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
>>  		break;
>>  	case GIC_V3:
>>  		ret = vgic_v3_probe(gic_kvm_info);
>> +		if (!ret) {
>> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
>> +			kvm_info("GIC system register CPU interface\n");
> 
> nit: add enabled to the info message?
> 
>> +		}
>>  		break;
>>  	default:
>>  		ret = -ENODEV;
>> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
>> index e83b7fe..8a529a7 100644
>> --- a/virt/kvm/arm/vgic/vgic.c
>> +++ b/virt/kvm/arm/vgic/vgic.c
>> @@ -29,7 +29,7 @@
>>  #define DEBUG_SPINLOCK_BUG_ON(p)
>>  #endif
>>  
>> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
>> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
>>  
>>  /*
>>   * Locking order is always:
>> -- 
>> 1.7.9.5
>>
> 
> Overall this looks really nice, as long as we're clear on the static
> keys stuff.

Indeed, we should get this sorted, though I'm not sure this should be a
blocker for this code.

Thanks,
	
	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
@ 2016-09-13  9:11       ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-13  9:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/09/16 09:20, Christoffer Dall wrote:
> On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
>> Currently GIC backend is selected via alternative framework and this
>> is fine. We are going to introduce vgic-v3 to 32-bit world and there
>> we don't have patching framework in hand, so we can either check
>> support for GICv3 every time we need to choose which backend to use or
>> try to optimise it by using static keys. The later looks quite
>> promising because we can share logic involved in selecting GIC backend
>> between architectures if both uses static keys.
>>
>> This patch moves arm64 from alternative to static keys framework for
>> selecting GIC backend. For that we embed static key into vgic_global
>> and enable the key during vgic initialisation based on what has
>> already been exposed by the host GIC driver.
>>
>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>> ---
>>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>>  include/kvm/arm_vgic.h        |    4 ++++
>>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>>  4 files changed, 20 insertions(+), 11 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>> index 5a84b45..d5c4cc5 100644
>> --- a/arch/arm64/kvm/hyp/switch.c
>> +++ b/arch/arm64/kvm/hyp/switch.c
>> @@ -16,6 +16,8 @@
>>   */
>>  
>>  #include <linux/types.h>
>> +#include <linux/jump_label.h>
>> +
>>  #include <asm/kvm_asm.h>
>>  #include <asm/kvm_hyp.h>
>>  
>> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
>>  	write_sysreg(0, vttbr_el2);
>>  }
>>  
>> -static hyp_alternate_select(__vgic_call_save_state,
>> -			    __vgic_v2_save_state, __vgic_v3_save_state,
>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>> -
>> -static hyp_alternate_select(__vgic_call_restore_state,
>> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>> -
>>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>>  {
>> -	__vgic_call_save_state()(vcpu);
>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> 
> It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
> hardware becomes mainstream), but as we don't have another primitive for
> the 'default disabled' case, I suppose that's the best we can do.

We could always revert the "likelihood" of that test once GICv3 has
conquered the world. Or start patching the 32bit kernel like we do for
64bit...

> 
>> +		__vgic_v3_save_state(vcpu);
>> +	else
>> +		__vgic_v2_save_state(vcpu);
>> +
>>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
>>  }
>>  
>> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>>  	val |= vcpu->arch.irq_lines;
>>  	write_sysreg(val, hcr_el2);
>>  
>> -	__vgic_call_restore_state()(vcpu);
>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>> +		__vgic_v3_restore_state(vcpu);
>> +	else
>> +		__vgic_v2_restore_state(vcpu);
>>  }
>>  
>>  static bool __hyp_text __true_value(void)
>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>> index 19b698e..994665a 100644
>> --- a/include/kvm/arm_vgic.h
>> +++ b/include/kvm/arm_vgic.h
>> @@ -23,6 +23,7 @@
>>  #include <linux/types.h>
>>  #include <kvm/iodev.h>
>>  #include <linux/list.h>
>> +#include <linux/jump_label.h>
>>  
>>  #define VGIC_V3_MAX_CPUS	255
>>  #define VGIC_V2_MAX_CPUS	8
>> @@ -63,6 +64,9 @@ struct vgic_global {
>>  
>>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
>>  	bool			can_emulate_gicv2;
>> +
>> +	/* GIC system register CPU interface */
>> +	struct static_key_false gicv3_cpuif;
> 
> Documentation/static-keys.txt says that we are not supposed to use
> struct static_key_false directly.  This will obviously work quite
> nicely, but we could consider adding a pair of
> DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
> but obviously this will need an ack from other maintainers.
> 
> Thoughts?

Grepping through the tree shows that we're not the only abusers of this
(dynamic debug is far worse!). Happy to write the additional macros and
submit them if nobody beats me to it.

> 
> 
>>  };
>>  
>>  extern struct vgic_global kvm_vgic_global_state;
>> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
>> index 83777c1..14d6718 100644
>> --- a/virt/kvm/arm/vgic/vgic-init.c
>> +++ b/virt/kvm/arm/vgic/vgic-init.c
>> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
>>  		break;
>>  	case GIC_V3:
>>  		ret = vgic_v3_probe(gic_kvm_info);
>> +		if (!ret) {
>> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
>> +			kvm_info("GIC system register CPU interface\n");
> 
> nit: add enabled to the info message?
> 
>> +		}
>>  		break;
>>  	default:
>>  		ret = -ENODEV;
>> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
>> index e83b7fe..8a529a7 100644
>> --- a/virt/kvm/arm/vgic/vgic.c
>> +++ b/virt/kvm/arm/vgic/vgic.c
>> @@ -29,7 +29,7 @@
>>  #define DEBUG_SPINLOCK_BUG_ON(p)
>>  #endif
>>  
>> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
>> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
>>  
>>  /*
>>   * Locking order is always:
>> -- 
>> 1.7.9.5
>>
> 
> Overall this looks really nice, as long as we're clear on the static
> keys stuff.

Indeed, we should get this sorted, though I'm not sure this should be a
blocker for this code.

Thanks,
	
	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
  2016-09-13  9:11       ` Marc Zyngier
@ 2016-09-13  9:22         ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  9:22 UTC (permalink / raw)
  To: Marc Zyngier; +Cc: andre.przywara, kvmarm, linux-arm-kernel

On Tue, Sep 13, 2016 at 10:11:10AM +0100, Marc Zyngier wrote:
> On 13/09/16 09:20, Christoffer Dall wrote:
> > On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
> >> Currently GIC backend is selected via alternative framework and this
> >> is fine. We are going to introduce vgic-v3 to 32-bit world and there
> >> we don't have patching framework in hand, so we can either check
> >> support for GICv3 every time we need to choose which backend to use or
> >> try to optimise it by using static keys. The later looks quite
> >> promising because we can share logic involved in selecting GIC backend
> >> between architectures if both uses static keys.
> >>
> >> This patch moves arm64 from alternative to static keys framework for
> >> selecting GIC backend. For that we embed static key into vgic_global
> >> and enable the key during vgic initialisation based on what has
> >> already been exposed by the host GIC driver.
> >>
> >> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
> >>  include/kvm/arm_vgic.h        |    4 ++++
> >>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
> >>  virt/kvm/arm/vgic/vgic.c      |    2 +-
> >>  4 files changed, 20 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> >> index 5a84b45..d5c4cc5 100644
> >> --- a/arch/arm64/kvm/hyp/switch.c
> >> +++ b/arch/arm64/kvm/hyp/switch.c
> >> @@ -16,6 +16,8 @@
> >>   */
> >>  
> >>  #include <linux/types.h>
> >> +#include <linux/jump_label.h>
> >> +
> >>  #include <asm/kvm_asm.h>
> >>  #include <asm/kvm_hyp.h>
> >>  
> >> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
> >>  	write_sysreg(0, vttbr_el2);
> >>  }
> >>  
> >> -static hyp_alternate_select(__vgic_call_save_state,
> >> -			    __vgic_v2_save_state, __vgic_v3_save_state,
> >> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> >> -
> >> -static hyp_alternate_select(__vgic_call_restore_state,
> >> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
> >> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> >> -
> >>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
> >>  {
> >> -	__vgic_call_save_state()(vcpu);
> >> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> > 
> > It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
> > hardware becomes mainstream), but as we don't have another primitive for
> > the 'default disabled' case, I suppose that's the best we can do.
> 
> We could always revert the "likelihood" of that test once GICv3 has
> conquered the world. Or start patching the 32bit kernel like we do for
> 64bit...
> 
> > 
> >> +		__vgic_v3_save_state(vcpu);
> >> +	else
> >> +		__vgic_v2_save_state(vcpu);
> >> +
> >>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
> >>  }
> >>  
> >> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
> >>  	val |= vcpu->arch.irq_lines;
> >>  	write_sysreg(val, hcr_el2);
> >>  
> >> -	__vgic_call_restore_state()(vcpu);
> >> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> >> +		__vgic_v3_restore_state(vcpu);
> >> +	else
> >> +		__vgic_v2_restore_state(vcpu);
> >>  }
> >>  
> >>  static bool __hyp_text __true_value(void)
> >> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >> index 19b698e..994665a 100644
> >> --- a/include/kvm/arm_vgic.h
> >> +++ b/include/kvm/arm_vgic.h
> >> @@ -23,6 +23,7 @@
> >>  #include <linux/types.h>
> >>  #include <kvm/iodev.h>
> >>  #include <linux/list.h>
> >> +#include <linux/jump_label.h>
> >>  
> >>  #define VGIC_V3_MAX_CPUS	255
> >>  #define VGIC_V2_MAX_CPUS	8
> >> @@ -63,6 +64,9 @@ struct vgic_global {
> >>  
> >>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
> >>  	bool			can_emulate_gicv2;
> >> +
> >> +	/* GIC system register CPU interface */
> >> +	struct static_key_false gicv3_cpuif;
> > 
> > Documentation/static-keys.txt says that we are not supposed to use
> > struct static_key_false directly.  This will obviously work quite
> > nicely, but we could consider adding a pair of
> > DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
> > but obviously this will need an ack from other maintainers.
> > 
> > Thoughts?
> 
> Grepping through the tree shows that we're not the only abusers of this
> (dynamic debug is far worse!). Happy to write the additional macros and
> submit them if nobody beats me to it.
> 
> > 
> > 
> >>  };
> >>  
> >>  extern struct vgic_global kvm_vgic_global_state;
> >> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
> >> index 83777c1..14d6718 100644
> >> --- a/virt/kvm/arm/vgic/vgic-init.c
> >> +++ b/virt/kvm/arm/vgic/vgic-init.c
> >> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
> >>  		break;
> >>  	case GIC_V3:
> >>  		ret = vgic_v3_probe(gic_kvm_info);
> >> +		if (!ret) {
> >> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
> >> +			kvm_info("GIC system register CPU interface\n");
> > 
> > nit: add enabled to the info message?
> > 
> >> +		}
> >>  		break;
> >>  	default:
> >>  		ret = -ENODEV;
> >> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> >> index e83b7fe..8a529a7 100644
> >> --- a/virt/kvm/arm/vgic/vgic.c
> >> +++ b/virt/kvm/arm/vgic/vgic.c
> >> @@ -29,7 +29,7 @@
> >>  #define DEBUG_SPINLOCK_BUG_ON(p)
> >>  #endif
> >>  
> >> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
> >> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
> >>  
> >>  /*
> >>   * Locking order is always:
> >> -- 
> >> 1.7.9.5
> >>
> > 
> > Overall this looks really nice, as long as we're clear on the static
> > keys stuff.
> 
> Indeed, we should get this sorted, though I'm not sure this should be a
> blocker for this code.
> 
Agreed, let's ship it!
-Christoffer

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
@ 2016-09-13  9:22         ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-13  9:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Sep 13, 2016 at 10:11:10AM +0100, Marc Zyngier wrote:
> On 13/09/16 09:20, Christoffer Dall wrote:
> > On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
> >> Currently GIC backend is selected via alternative framework and this
> >> is fine. We are going to introduce vgic-v3 to 32-bit world and there
> >> we don't have patching framework in hand, so we can either check
> >> support for GICv3 every time we need to choose which backend to use or
> >> try to optimise it by using static keys. The later looks quite
> >> promising because we can share logic involved in selecting GIC backend
> >> between architectures if both uses static keys.
> >>
> >> This patch moves arm64 from alternative to static keys framework for
> >> selecting GIC backend. For that we embed static key into vgic_global
> >> and enable the key during vgic initialisation based on what has
> >> already been exposed by the host GIC driver.
> >>
> >> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
> >>  include/kvm/arm_vgic.h        |    4 ++++
> >>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
> >>  virt/kvm/arm/vgic/vgic.c      |    2 +-
> >>  4 files changed, 20 insertions(+), 11 deletions(-)
> >>
> >> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> >> index 5a84b45..d5c4cc5 100644
> >> --- a/arch/arm64/kvm/hyp/switch.c
> >> +++ b/arch/arm64/kvm/hyp/switch.c
> >> @@ -16,6 +16,8 @@
> >>   */
> >>  
> >>  #include <linux/types.h>
> >> +#include <linux/jump_label.h>
> >> +
> >>  #include <asm/kvm_asm.h>
> >>  #include <asm/kvm_hyp.h>
> >>  
> >> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
> >>  	write_sysreg(0, vttbr_el2);
> >>  }
> >>  
> >> -static hyp_alternate_select(__vgic_call_save_state,
> >> -			    __vgic_v2_save_state, __vgic_v3_save_state,
> >> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> >> -
> >> -static hyp_alternate_select(__vgic_call_restore_state,
> >> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
> >> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> >> -
> >>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
> >>  {
> >> -	__vgic_call_save_state()(vcpu);
> >> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> > 
> > It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
> > hardware becomes mainstream), but as we don't have another primitive for
> > the 'default disabled' case, I suppose that's the best we can do.
> 
> We could always revert the "likelihood" of that test once GICv3 has
> conquered the world. Or start patching the 32bit kernel like we do for
> 64bit...
> 
> > 
> >> +		__vgic_v3_save_state(vcpu);
> >> +	else
> >> +		__vgic_v2_save_state(vcpu);
> >> +
> >>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
> >>  }
> >>  
> >> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
> >>  	val |= vcpu->arch.irq_lines;
> >>  	write_sysreg(val, hcr_el2);
> >>  
> >> -	__vgic_call_restore_state()(vcpu);
> >> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> >> +		__vgic_v3_restore_state(vcpu);
> >> +	else
> >> +		__vgic_v2_restore_state(vcpu);
> >>  }
> >>  
> >>  static bool __hyp_text __true_value(void)
> >> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >> index 19b698e..994665a 100644
> >> --- a/include/kvm/arm_vgic.h
> >> +++ b/include/kvm/arm_vgic.h
> >> @@ -23,6 +23,7 @@
> >>  #include <linux/types.h>
> >>  #include <kvm/iodev.h>
> >>  #include <linux/list.h>
> >> +#include <linux/jump_label.h>
> >>  
> >>  #define VGIC_V3_MAX_CPUS	255
> >>  #define VGIC_V2_MAX_CPUS	8
> >> @@ -63,6 +64,9 @@ struct vgic_global {
> >>  
> >>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
> >>  	bool			can_emulate_gicv2;
> >> +
> >> +	/* GIC system register CPU interface */
> >> +	struct static_key_false gicv3_cpuif;
> > 
> > Documentation/static-keys.txt says that we are not supposed to use
> > struct static_key_false directly.  This will obviously work quite
> > nicely, but we could consider adding a pair of
> > DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
> > but obviously this will need an ack from other maintainers.
> > 
> > Thoughts?
> 
> Grepping through the tree shows that we're not the only abusers of this
> (dynamic debug is far worse!). Happy to write the additional macros and
> submit them if nobody beats me to it.
> 
> > 
> > 
> >>  };
> >>  
> >>  extern struct vgic_global kvm_vgic_global_state;
> >> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
> >> index 83777c1..14d6718 100644
> >> --- a/virt/kvm/arm/vgic/vgic-init.c
> >> +++ b/virt/kvm/arm/vgic/vgic-init.c
> >> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
> >>  		break;
> >>  	case GIC_V3:
> >>  		ret = vgic_v3_probe(gic_kvm_info);
> >> +		if (!ret) {
> >> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
> >> +			kvm_info("GIC system register CPU interface\n");
> > 
> > nit: add enabled to the info message?
> > 
> >> +		}
> >>  		break;
> >>  	default:
> >>  		ret = -ENODEV;
> >> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> >> index e83b7fe..8a529a7 100644
> >> --- a/virt/kvm/arm/vgic/vgic.c
> >> +++ b/virt/kvm/arm/vgic/vgic.c
> >> @@ -29,7 +29,7 @@
> >>  #define DEBUG_SPINLOCK_BUG_ON(p)
> >>  #endif
> >>  
> >> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
> >> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
> >>  
> >>  /*
> >>   * Locking order is always:
> >> -- 
> >> 1.7.9.5
> >>
> > 
> > Overall this looks really nice, as long as we're clear on the static
> > keys stuff.
> 
> Indeed, we should get this sorted, though I'm not sure this should be a
> blocker for this code.
> 
Agreed, let's ship it!
-Christoffer

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-13  9:04       ` Vladimir Murzin
@ 2016-09-13 10:12         ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-13 10:12 UTC (permalink / raw)
  To: Vladimir Murzin, Christoffer Dall
  Cc: andre.przywara, Russell King, kvmarm, linux-arm-kernel

On 13/09/16 10:04, Vladimir Murzin wrote:
> On 13/09/16 09:38, Christoffer Dall wrote:
>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>
>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>> ---
>>>  arch/arm/include/asm/cputype.h |    1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>> index 1ee94c7..e2d94c1 100644
>>> --- a/arch/arm/include/asm/cputype.h
>>> +++ b/arch/arm/include/asm/cputype.h
>>> @@ -55,6 +55,7 @@
>>>  
>>>  #define MPIDR_LEVEL_BITS 8
>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>  
>>
>> I'm not sure I follow the correctness of this completely.
>>
>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>> may have something in the Aff3 field, which we now shift left 24 bits,
>> but that is not the Aff3 field of AArch32's MPIDR.
>>
>> What is the rationale for this making sense again?
> 
> IIUC, in such case we construct mpidr which won't match in match_mpidr()
> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
> sent to the guest.
> 
> Since we get that u64 value from the guest, I'd think it is something
> wrong is going on in the guest in case Aff3 is non-zero; however, we can
> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().

I don't think zeroing Aff3 is the right move, as the spec doesn't say
that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
the spec says (in the context of the target list): "If a bit is 1 and
the bit does not correspond to a valid target PE, the bit must be
ignored by the Distributor".

This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
ignore that SGI because there is no way we can actually deliver it.

Could you cook a small patch that would go on top of this series?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-13 10:12         ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-13 10:12 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/09/16 10:04, Vladimir Murzin wrote:
> On 13/09/16 09:38, Christoffer Dall wrote:
>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>
>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>> ---
>>>  arch/arm/include/asm/cputype.h |    1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>> index 1ee94c7..e2d94c1 100644
>>> --- a/arch/arm/include/asm/cputype.h
>>> +++ b/arch/arm/include/asm/cputype.h
>>> @@ -55,6 +55,7 @@
>>>  
>>>  #define MPIDR_LEVEL_BITS 8
>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>  
>>
>> I'm not sure I follow the correctness of this completely.
>>
>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>> may have something in the Aff3 field, which we now shift left 24 bits,
>> but that is not the Aff3 field of AArch32's MPIDR.
>>
>> What is the rationale for this making sense again?
> 
> IIUC, in such case we construct mpidr which won't match in match_mpidr()
> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
> sent to the guest.
> 
> Since we get that u64 value from the guest, I'd think it is something
> wrong is going on in the guest in case Aff3 is non-zero; however, we can
> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().

I don't think zeroing Aff3 is the right move, as the spec doesn't say
that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
the spec says (in the context of the target list): "If a bit is 1 and
the bit does not correspond to a valid target PE, the bit must be
ignored by the Distributor".

This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
ignore that SGI because there is no way we can actually deliver it.

Could you cook a small patch that would go on top of this series?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-13 10:12         ` Marc Zyngier
@ 2016-09-13 10:32           ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-13 10:32 UTC (permalink / raw)
  To: Marc Zyngier, Christoffer Dall
  Cc: andre.przywara, Russell King, kvmarm, linux-arm-kernel

On 13/09/16 11:12, Marc Zyngier wrote:
> On 13/09/16 10:04, Vladimir Murzin wrote:
>> On 13/09/16 09:38, Christoffer Dall wrote:
>>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>>
>>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>> ---
>>>>  arch/arm/include/asm/cputype.h |    1 +
>>>>  1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>>> index 1ee94c7..e2d94c1 100644
>>>> --- a/arch/arm/include/asm/cputype.h
>>>> +++ b/arch/arm/include/asm/cputype.h
>>>> @@ -55,6 +55,7 @@
>>>>  
>>>>  #define MPIDR_LEVEL_BITS 8
>>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>>  
>>>
>>> I'm not sure I follow the correctness of this completely.
>>>
>>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>>> may have something in the Aff3 field, which we now shift left 24 bits,
>>> but that is not the Aff3 field of AArch32's MPIDR.
>>>
>>> What is the rationale for this making sense again?
>>
>> IIUC, in such case we construct mpidr which won't match in match_mpidr()
>> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
>> sent to the guest.
>>
>> Since we get that u64 value from the guest, I'd think it is something
>> wrong is going on in the guest in case Aff3 is non-zero; however, we can
>> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().
> 
> I don't think zeroing Aff3 is the right move, as the spec doesn't say
> that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
> the spec says (in the context of the target list): "If a bit is 1 and
> the bit does not correspond to a valid target PE, the bit must be
> ignored by the Distributor".
> 
> This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
> ignore that SGI because there is no way we can actually deliver it.
> 
> Could you cook a small patch that would go on top of this series?

I assume you've meant ICC_SGI1R.IRM, aka broadcast. In this case,
vgic_v3_dispatch_sgi() seems already matches the logic you've described:

- if IRM == 1, send to everyone except self without check for mpidr
- if IRM == 0, send to target iff matched to a valid mpidr

Am I missing something?

Thanks
Vladimir

> 
> Thanks,
> 
> 	M.
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-13 10:32           ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-13 10:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/09/16 11:12, Marc Zyngier wrote:
> On 13/09/16 10:04, Vladimir Murzin wrote:
>> On 13/09/16 09:38, Christoffer Dall wrote:
>>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>>
>>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>> ---
>>>>  arch/arm/include/asm/cputype.h |    1 +
>>>>  1 file changed, 1 insertion(+)
>>>>
>>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>>> index 1ee94c7..e2d94c1 100644
>>>> --- a/arch/arm/include/asm/cputype.h
>>>> +++ b/arch/arm/include/asm/cputype.h
>>>> @@ -55,6 +55,7 @@
>>>>  
>>>>  #define MPIDR_LEVEL_BITS 8
>>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>>  
>>>
>>> I'm not sure I follow the correctness of this completely.
>>>
>>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>>> may have something in the Aff3 field, which we now shift left 24 bits,
>>> but that is not the Aff3 field of AArch32's MPIDR.
>>>
>>> What is the rationale for this making sense again?
>>
>> IIUC, in such case we construct mpidr which won't match in match_mpidr()
>> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
>> sent to the guest.
>>
>> Since we get that u64 value from the guest, I'd think it is something
>> wrong is going on in the guest in case Aff3 is non-zero; however, we can
>> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().
> 
> I don't think zeroing Aff3 is the right move, as the spec doesn't say
> that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
> the spec says (in the context of the target list): "If a bit is 1 and
> the bit does not correspond to a valid target PE, the bit must be
> ignored by the Distributor".
> 
> This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
> ignore that SGI because there is no way we can actually deliver it.
> 
> Could you cook a small patch that would go on top of this series?

I assume you've meant ICC_SGI1R.IRM, aka broadcast. In this case,
vgic_v3_dispatch_sgi() seems already matches the logic you've described:

- if IRM == 1, send to everyone except self without check for mpidr
- if IRM == 0, send to target iff matched to a valid mpidr

Am I missing something?

Thanks
Vladimir

> 
> Thanks,
> 
> 	M.
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-13 10:32           ` Vladimir Murzin
@ 2016-09-13 10:44             ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-13 10:44 UTC (permalink / raw)
  To: Vladimir Murzin, Christoffer Dall
  Cc: andre.przywara, Russell King, kvmarm, linux-arm-kernel

On 13/09/16 11:32, Vladimir Murzin wrote:
> On 13/09/16 11:12, Marc Zyngier wrote:
>> On 13/09/16 10:04, Vladimir Murzin wrote:
>>> On 13/09/16 09:38, Christoffer Dall wrote:
>>>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>>>
>>>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>> ---
>>>>>  arch/arm/include/asm/cputype.h |    1 +
>>>>>  1 file changed, 1 insertion(+)
>>>>>
>>>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>>>> index 1ee94c7..e2d94c1 100644
>>>>> --- a/arch/arm/include/asm/cputype.h
>>>>> +++ b/arch/arm/include/asm/cputype.h
>>>>> @@ -55,6 +55,7 @@
>>>>>  
>>>>>  #define MPIDR_LEVEL_BITS 8
>>>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>>>  
>>>>
>>>> I'm not sure I follow the correctness of this completely.
>>>>
>>>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>>>> may have something in the Aff3 field, which we now shift left 24 bits,
>>>> but that is not the Aff3 field of AArch32's MPIDR.
>>>>
>>>> What is the rationale for this making sense again?
>>>
>>> IIUC, in such case we construct mpidr which won't match in match_mpidr()
>>> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
>>> sent to the guest.
>>>
>>> Since we get that u64 value from the guest, I'd think it is something
>>> wrong is going on in the guest in case Aff3 is non-zero; however, we can
>>> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().
>>
>> I don't think zeroing Aff3 is the right move, as the spec doesn't say
>> that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
>> the spec says (in the context of the target list): "If a bit is 1 and
>> the bit does not correspond to a valid target PE, the bit must be
>> ignored by the Distributor".
>>
>> This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
>> ignore that SGI because there is no way we can actually deliver it.
>>
>> Could you cook a small patch that would go on top of this series?
> 
> I assume you've meant ICC_SGI1R.IRM, aka broadcast. In this case,

Yes, sorry.

> vgic_v3_dispatch_sgi() seems already matches the logic you've described:
> 
> - if IRM == 1, send to everyone except self without check for mpidr
> - if IRM == 0, send to target iff matched to a valid mpidr
> 
> Am I missing something?

Not much. My only ask was that if Aff3 was set, we could take the
shortcut of not calling vgic_v3_dispatch_sgi() at all and return
immediately. But as you said, we already deal with the case of invalid
MPIDRs.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-13 10:44             ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-13 10:44 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/09/16 11:32, Vladimir Murzin wrote:
> On 13/09/16 11:12, Marc Zyngier wrote:
>> On 13/09/16 10:04, Vladimir Murzin wrote:
>>> On 13/09/16 09:38, Christoffer Dall wrote:
>>>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>>>
>>>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>> ---
>>>>>  arch/arm/include/asm/cputype.h |    1 +
>>>>>  1 file changed, 1 insertion(+)
>>>>>
>>>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>>>> index 1ee94c7..e2d94c1 100644
>>>>> --- a/arch/arm/include/asm/cputype.h
>>>>> +++ b/arch/arm/include/asm/cputype.h
>>>>> @@ -55,6 +55,7 @@
>>>>>  
>>>>>  #define MPIDR_LEVEL_BITS 8
>>>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>>>  
>>>>
>>>> I'm not sure I follow the correctness of this completely.
>>>>
>>>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>>>> may have something in the Aff3 field, which we now shift left 24 bits,
>>>> but that is not the Aff3 field of AArch32's MPIDR.
>>>>
>>>> What is the rationale for this making sense again?
>>>
>>> IIUC, in such case we construct mpidr which won't match in match_mpidr()
>>> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
>>> sent to the guest.
>>>
>>> Since we get that u64 value from the guest, I'd think it is something
>>> wrong is going on in the guest in case Aff3 is non-zero; however, we can
>>> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().
>>
>> I don't think zeroing Aff3 is the right move, as the spec doesn't say
>> that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
>> the spec says (in the context of the target list): "If a bit is 1 and
>> the bit does not correspond to a valid target PE, the bit must be
>> ignored by the Distributor".
>>
>> This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
>> ignore that SGI because there is no way we can actually deliver it.
>>
>> Could you cook a small patch that would go on top of this series?
> 
> I assume you've meant ICC_SGI1R.IRM, aka broadcast. In this case,

Yes, sorry.

> vgic_v3_dispatch_sgi() seems already matches the logic you've described:
> 
> - if IRM == 1, send to everyone except self without check for mpidr
> - if IRM == 0, send to target iff matched to a valid mpidr
> 
> Am I missing something?

Not much. My only ask was that if Aff3 was set, we could take the
shortcut of not calling vgic_v3_dispatch_sgi() at all and return
immediately. But as you said, we already deal with the case of invalid
MPIDRs.

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
  2016-09-13  9:22         ` Christoffer Dall
@ 2016-09-14 15:20           ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-14 15:20 UTC (permalink / raw)
  To: Christoffer Dall, Marc Zyngier; +Cc: andre.przywara, kvmarm, linux-arm-kernel

On 13/09/16 10:22, Christoffer Dall wrote:
> On Tue, Sep 13, 2016 at 10:11:10AM +0100, Marc Zyngier wrote:
>> On 13/09/16 09:20, Christoffer Dall wrote:
>>> On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
>>>> Currently GIC backend is selected via alternative framework and this
>>>> is fine. We are going to introduce vgic-v3 to 32-bit world and there
>>>> we don't have patching framework in hand, so we can either check
>>>> support for GICv3 every time we need to choose which backend to use or
>>>> try to optimise it by using static keys. The later looks quite
>>>> promising because we can share logic involved in selecting GIC backend
>>>> between architectures if both uses static keys.
>>>>
>>>> This patch moves arm64 from alternative to static keys framework for
>>>> selecting GIC backend. For that we embed static key into vgic_global
>>>> and enable the key during vgic initialisation based on what has
>>>> already been exposed by the host GIC driver.
>>>>
>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>> ---
>>>>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>>>>  include/kvm/arm_vgic.h        |    4 ++++
>>>>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>>>>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>>>>  4 files changed, 20 insertions(+), 11 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>>> index 5a84b45..d5c4cc5 100644
>>>> --- a/arch/arm64/kvm/hyp/switch.c
>>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>>> @@ -16,6 +16,8 @@
>>>>   */
>>>>  
>>>>  #include <linux/types.h>
>>>> +#include <linux/jump_label.h>
>>>> +
>>>>  #include <asm/kvm_asm.h>
>>>>  #include <asm/kvm_hyp.h>
>>>>  
>>>> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
>>>>  	write_sysreg(0, vttbr_el2);
>>>>  }
>>>>  
>>>> -static hyp_alternate_select(__vgic_call_save_state,
>>>> -			    __vgic_v2_save_state, __vgic_v3_save_state,
>>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>>>> -
>>>> -static hyp_alternate_select(__vgic_call_restore_state,
>>>> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
>>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>>>> -
>>>>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>>>>  {
>>>> -	__vgic_call_save_state()(vcpu);
>>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>>>
>>> It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
>>> hardware becomes mainstream), but as we don't have another primitive for
>>> the 'default disabled' case, I suppose that's the best we can do.
>>
>> We could always revert the "likelihood" of that test once GICv3 has
>> conquered the world. Or start patching the 32bit kernel like we do for
>> 64bit...
>>
>>>
>>>> +		__vgic_v3_save_state(vcpu);
>>>> +	else
>>>> +		__vgic_v2_save_state(vcpu);
>>>> +
>>>>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
>>>>  }
>>>>  
>>>> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>>>>  	val |= vcpu->arch.irq_lines;
>>>>  	write_sysreg(val, hcr_el2);
>>>>  
>>>> -	__vgic_call_restore_state()(vcpu);
>>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>>>> +		__vgic_v3_restore_state(vcpu);
>>>> +	else
>>>> +		__vgic_v2_restore_state(vcpu);
>>>>  }
>>>>  
>>>>  static bool __hyp_text __true_value(void)
>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>> index 19b698e..994665a 100644
>>>> --- a/include/kvm/arm_vgic.h
>>>> +++ b/include/kvm/arm_vgic.h
>>>> @@ -23,6 +23,7 @@
>>>>  #include <linux/types.h>
>>>>  #include <kvm/iodev.h>
>>>>  #include <linux/list.h>
>>>> +#include <linux/jump_label.h>
>>>>  
>>>>  #define VGIC_V3_MAX_CPUS	255
>>>>  #define VGIC_V2_MAX_CPUS	8
>>>> @@ -63,6 +64,9 @@ struct vgic_global {
>>>>  
>>>>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
>>>>  	bool			can_emulate_gicv2;
>>>> +
>>>> +	/* GIC system register CPU interface */
>>>> +	struct static_key_false gicv3_cpuif;
>>>
>>> Documentation/static-keys.txt says that we are not supposed to use
>>> struct static_key_false directly.  This will obviously work quite
>>> nicely, but we could consider adding a pair of
>>> DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
>>> but obviously this will need an ack from other maintainers.
>>>
>>> Thoughts?
>>
>> Grepping through the tree shows that we're not the only abusers of this
>> (dynamic debug is far worse!). Happy to write the additional macros and
>> submit them if nobody beats me to it.
>>
>>>
>>>
>>>>  };
>>>>  
>>>>  extern struct vgic_global kvm_vgic_global_state;
>>>> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
>>>> index 83777c1..14d6718 100644
>>>> --- a/virt/kvm/arm/vgic/vgic-init.c
>>>> +++ b/virt/kvm/arm/vgic/vgic-init.c
>>>> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
>>>>  		break;
>>>>  	case GIC_V3:
>>>>  		ret = vgic_v3_probe(gic_kvm_info);
>>>> +		if (!ret) {
>>>> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
>>>> +			kvm_info("GIC system register CPU interface\n");
>>>
>>> nit: add enabled to the info message?
>>>
>>>> +		}
>>>>  		break;
>>>>  	default:
>>>>  		ret = -ENODEV;
>>>> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
>>>> index e83b7fe..8a529a7 100644
>>>> --- a/virt/kvm/arm/vgic/vgic.c
>>>> +++ b/virt/kvm/arm/vgic/vgic.c
>>>> @@ -29,7 +29,7 @@
>>>>  #define DEBUG_SPINLOCK_BUG_ON(p)
>>>>  #endif
>>>>  
>>>> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
>>>> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
>>>>  
>>>>  /*
>>>>   * Locking order is always:
>>>> -- 
>>>> 1.7.9.5
>>>>
>>>
>>> Overall this looks really nice, as long as we're clear on the static
>>> keys stuff.
>>
>> Indeed, we should get this sorted, though I'm not sure this should be a
>> blocker for this code.
>>
> Agreed, let's ship it!

To make it clear, should I respin with "enabled" into the info message
and macros for static keys?

Cheers
Vladimir

> -Christoffer
> 
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
@ 2016-09-14 15:20           ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-14 15:20 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/09/16 10:22, Christoffer Dall wrote:
> On Tue, Sep 13, 2016 at 10:11:10AM +0100, Marc Zyngier wrote:
>> On 13/09/16 09:20, Christoffer Dall wrote:
>>> On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
>>>> Currently GIC backend is selected via alternative framework and this
>>>> is fine. We are going to introduce vgic-v3 to 32-bit world and there
>>>> we don't have patching framework in hand, so we can either check
>>>> support for GICv3 every time we need to choose which backend to use or
>>>> try to optimise it by using static keys. The later looks quite
>>>> promising because we can share logic involved in selecting GIC backend
>>>> between architectures if both uses static keys.
>>>>
>>>> This patch moves arm64 from alternative to static keys framework for
>>>> selecting GIC backend. For that we embed static key into vgic_global
>>>> and enable the key during vgic initialisation based on what has
>>>> already been exposed by the host GIC driver.
>>>>
>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>> ---
>>>>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>>>>  include/kvm/arm_vgic.h        |    4 ++++
>>>>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>>>>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>>>>  4 files changed, 20 insertions(+), 11 deletions(-)
>>>>
>>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>>> index 5a84b45..d5c4cc5 100644
>>>> --- a/arch/arm64/kvm/hyp/switch.c
>>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>>> @@ -16,6 +16,8 @@
>>>>   */
>>>>  
>>>>  #include <linux/types.h>
>>>> +#include <linux/jump_label.h>
>>>> +
>>>>  #include <asm/kvm_asm.h>
>>>>  #include <asm/kvm_hyp.h>
>>>>  
>>>> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
>>>>  	write_sysreg(0, vttbr_el2);
>>>>  }
>>>>  
>>>> -static hyp_alternate_select(__vgic_call_save_state,
>>>> -			    __vgic_v2_save_state, __vgic_v3_save_state,
>>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>>>> -
>>>> -static hyp_alternate_select(__vgic_call_restore_state,
>>>> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
>>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>>>> -
>>>>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>>>>  {
>>>> -	__vgic_call_save_state()(vcpu);
>>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>>>
>>> It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
>>> hardware becomes mainstream), but as we don't have another primitive for
>>> the 'default disabled' case, I suppose that's the best we can do.
>>
>> We could always revert the "likelihood" of that test once GICv3 has
>> conquered the world. Or start patching the 32bit kernel like we do for
>> 64bit...
>>
>>>
>>>> +		__vgic_v3_save_state(vcpu);
>>>> +	else
>>>> +		__vgic_v2_save_state(vcpu);
>>>> +
>>>>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
>>>>  }
>>>>  
>>>> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>>>>  	val |= vcpu->arch.irq_lines;
>>>>  	write_sysreg(val, hcr_el2);
>>>>  
>>>> -	__vgic_call_restore_state()(vcpu);
>>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>>>> +		__vgic_v3_restore_state(vcpu);
>>>> +	else
>>>> +		__vgic_v2_restore_state(vcpu);
>>>>  }
>>>>  
>>>>  static bool __hyp_text __true_value(void)
>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>> index 19b698e..994665a 100644
>>>> --- a/include/kvm/arm_vgic.h
>>>> +++ b/include/kvm/arm_vgic.h
>>>> @@ -23,6 +23,7 @@
>>>>  #include <linux/types.h>
>>>>  #include <kvm/iodev.h>
>>>>  #include <linux/list.h>
>>>> +#include <linux/jump_label.h>
>>>>  
>>>>  #define VGIC_V3_MAX_CPUS	255
>>>>  #define VGIC_V2_MAX_CPUS	8
>>>> @@ -63,6 +64,9 @@ struct vgic_global {
>>>>  
>>>>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
>>>>  	bool			can_emulate_gicv2;
>>>> +
>>>> +	/* GIC system register CPU interface */
>>>> +	struct static_key_false gicv3_cpuif;
>>>
>>> Documentation/static-keys.txt says that we are not supposed to use
>>> struct static_key_false directly.  This will obviously work quite
>>> nicely, but we could consider adding a pair of
>>> DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
>>> but obviously this will need an ack from other maintainers.
>>>
>>> Thoughts?
>>
>> Grepping through the tree shows that we're not the only abusers of this
>> (dynamic debug is far worse!). Happy to write the additional macros and
>> submit them if nobody beats me to it.
>>
>>>
>>>
>>>>  };
>>>>  
>>>>  extern struct vgic_global kvm_vgic_global_state;
>>>> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
>>>> index 83777c1..14d6718 100644
>>>> --- a/virt/kvm/arm/vgic/vgic-init.c
>>>> +++ b/virt/kvm/arm/vgic/vgic-init.c
>>>> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
>>>>  		break;
>>>>  	case GIC_V3:
>>>>  		ret = vgic_v3_probe(gic_kvm_info);
>>>> +		if (!ret) {
>>>> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
>>>> +			kvm_info("GIC system register CPU interface\n");
>>>
>>> nit: add enabled to the info message?
>>>
>>>> +		}
>>>>  		break;
>>>>  	default:
>>>>  		ret = -ENODEV;
>>>> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
>>>> index e83b7fe..8a529a7 100644
>>>> --- a/virt/kvm/arm/vgic/vgic.c
>>>> +++ b/virt/kvm/arm/vgic/vgic.c
>>>> @@ -29,7 +29,7 @@
>>>>  #define DEBUG_SPINLOCK_BUG_ON(p)
>>>>  #endif
>>>>  
>>>> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
>>>> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
>>>>  
>>>>  /*
>>>>   * Locking order is always:
>>>> -- 
>>>> 1.7.9.5
>>>>
>>>
>>> Overall this looks really nice, as long as we're clear on the static
>>> keys stuff.
>>
>> Indeed, we should get this sorted, though I'm not sure this should be a
>> blocker for this code.
>>
> Agreed, let's ship it!

To make it clear, should I respin with "enabled" into the info message
and macros for static keys?

Cheers
Vladimir

> -Christoffer
> 
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-13 10:44             ` Marc Zyngier
@ 2016-09-14 15:21               ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-14 15:21 UTC (permalink / raw)
  To: Marc Zyngier, Christoffer Dall
  Cc: andre.przywara, Russell King, kvmarm, linux-arm-kernel

On 13/09/16 11:44, Marc Zyngier wrote:
> On 13/09/16 11:32, Vladimir Murzin wrote:
>> On 13/09/16 11:12, Marc Zyngier wrote:
>>> On 13/09/16 10:04, Vladimir Murzin wrote:
>>>> On 13/09/16 09:38, Christoffer Dall wrote:
>>>>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>>>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>>>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>>>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>>>>
>>>>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>>> ---
>>>>>>  arch/arm/include/asm/cputype.h |    1 +
>>>>>>  1 file changed, 1 insertion(+)
>>>>>>
>>>>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>>>>> index 1ee94c7..e2d94c1 100644
>>>>>> --- a/arch/arm/include/asm/cputype.h
>>>>>> +++ b/arch/arm/include/asm/cputype.h
>>>>>> @@ -55,6 +55,7 @@
>>>>>>  
>>>>>>  #define MPIDR_LEVEL_BITS 8
>>>>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>>>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>>>>  
>>>>>
>>>>> I'm not sure I follow the correctness of this completely.
>>>>>
>>>>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>>>>> may have something in the Aff3 field, which we now shift left 24 bits,
>>>>> but that is not the Aff3 field of AArch32's MPIDR.
>>>>>
>>>>> What is the rationale for this making sense again?
>>>>
>>>> IIUC, in such case we construct mpidr which won't match in match_mpidr()
>>>> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
>>>> sent to the guest.
>>>>
>>>> Since we get that u64 value from the guest, I'd think it is something
>>>> wrong is going on in the guest in case Aff3 is non-zero; however, we can
>>>> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().
>>>
>>> I don't think zeroing Aff3 is the right move, as the spec doesn't say
>>> that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
>>> the spec says (in the context of the target list): "If a bit is 1 and
>>> the bit does not correspond to a valid target PE, the bit must be
>>> ignored by the Distributor".
>>>
>>> This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
>>> ignore that SGI because there is no way we can actually deliver it.
>>>
>>> Could you cook a small patch that would go on top of this series?
>>
>> I assume you've meant ICC_SGI1R.IRM, aka broadcast. In this case,
> 
> Yes, sorry.
> 
>> vgic_v3_dispatch_sgi() seems already matches the logic you've described:
>>
>> - if IRM == 1, send to everyone except self without check for mpidr
>> - if IRM == 0, send to target iff matched to a valid mpidr
>>
>> Am I missing something?
> 
> Not much. My only ask was that if Aff3 was set, we could take the
> shortcut of not calling vgic_v3_dispatch_sgi() at all and return
> immediately. But as you said, we already deal with the case of invalid
> MPIDRs.
> 

Anything I can do to make this patch better?

Cheers
Vladimir

> Thanks,
> 
> 	M.
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-14 15:21               ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-14 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

On 13/09/16 11:44, Marc Zyngier wrote:
> On 13/09/16 11:32, Vladimir Murzin wrote:
>> On 13/09/16 11:12, Marc Zyngier wrote:
>>> On 13/09/16 10:04, Vladimir Murzin wrote:
>>>> On 13/09/16 09:38, Christoffer Dall wrote:
>>>>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>>>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>>>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>>>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>>>>
>>>>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>>> ---
>>>>>>  arch/arm/include/asm/cputype.h |    1 +
>>>>>>  1 file changed, 1 insertion(+)
>>>>>>
>>>>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>>>>> index 1ee94c7..e2d94c1 100644
>>>>>> --- a/arch/arm/include/asm/cputype.h
>>>>>> +++ b/arch/arm/include/asm/cputype.h
>>>>>> @@ -55,6 +55,7 @@
>>>>>>  
>>>>>>  #define MPIDR_LEVEL_BITS 8
>>>>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>>>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>>>>  
>>>>>
>>>>> I'm not sure I follow the correctness of this completely.
>>>>>
>>>>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>>>>> may have something in the Aff3 field, which we now shift left 24 bits,
>>>>> but that is not the Aff3 field of AArch32's MPIDR.
>>>>>
>>>>> What is the rationale for this making sense again?
>>>>
>>>> IIUC, in such case we construct mpidr which won't match in match_mpidr()
>>>> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
>>>> sent to the guest.
>>>>
>>>> Since we get that u64 value from the guest, I'd think it is something
>>>> wrong is going on in the guest in case Aff3 is non-zero; however, we can
>>>> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().
>>>
>>> I don't think zeroing Aff3 is the right move, as the spec doesn't say
>>> that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
>>> the spec says (in the context of the target list): "If a bit is 1 and
>>> the bit does not correspond to a valid target PE, the bit must be
>>> ignored by the Distributor".
>>>
>>> This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
>>> ignore that SGI because there is no way we can actually deliver it.
>>>
>>> Could you cook a small patch that would go on top of this series?
>>
>> I assume you've meant ICC_SGI1R.IRM, aka broadcast. In this case,
> 
> Yes, sorry.
> 
>> vgic_v3_dispatch_sgi() seems already matches the logic you've described:
>>
>> - if IRM == 1, send to everyone except self without check for mpidr
>> - if IRM == 0, send to target iff matched to a valid mpidr
>>
>> Am I missing something?
> 
> Not much. My only ask was that if Aff3 was set, we could take the
> shortcut of not calling vgic_v3_dispatch_sgi() at all and return
> immediately. But as you said, we already deal with the case of invalid
> MPIDRs.
> 

Anything I can do to make this patch better?

Cheers
Vladimir

> Thanks,
> 
> 	M.
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
  2016-09-14 15:20           ` Vladimir Murzin
@ 2016-09-14 15:47             ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-14 15:47 UTC (permalink / raw)
  To: Vladimir Murzin, Christoffer Dall
  Cc: andre.przywara, kvmarm, linux-arm-kernel

On 14/09/16 16:20, Vladimir Murzin wrote:
> On 13/09/16 10:22, Christoffer Dall wrote:
>> On Tue, Sep 13, 2016 at 10:11:10AM +0100, Marc Zyngier wrote:
>>> On 13/09/16 09:20, Christoffer Dall wrote:
>>>> On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
>>>>> Currently GIC backend is selected via alternative framework and this
>>>>> is fine. We are going to introduce vgic-v3 to 32-bit world and there
>>>>> we don't have patching framework in hand, so we can either check
>>>>> support for GICv3 every time we need to choose which backend to use or
>>>>> try to optimise it by using static keys. The later looks quite
>>>>> promising because we can share logic involved in selecting GIC backend
>>>>> between architectures if both uses static keys.
>>>>>
>>>>> This patch moves arm64 from alternative to static keys framework for
>>>>> selecting GIC backend. For that we embed static key into vgic_global
>>>>> and enable the key during vgic initialisation based on what has
>>>>> already been exposed by the host GIC driver.
>>>>>
>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>> ---
>>>>>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>>>>>  include/kvm/arm_vgic.h        |    4 ++++
>>>>>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>>>>>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>>>>>  4 files changed, 20 insertions(+), 11 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>>>> index 5a84b45..d5c4cc5 100644
>>>>> --- a/arch/arm64/kvm/hyp/switch.c
>>>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>>>> @@ -16,6 +16,8 @@
>>>>>   */
>>>>>  
>>>>>  #include <linux/types.h>
>>>>> +#include <linux/jump_label.h>
>>>>> +
>>>>>  #include <asm/kvm_asm.h>
>>>>>  #include <asm/kvm_hyp.h>
>>>>>  
>>>>> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
>>>>>  	write_sysreg(0, vttbr_el2);
>>>>>  }
>>>>>  
>>>>> -static hyp_alternate_select(__vgic_call_save_state,
>>>>> -			    __vgic_v2_save_state, __vgic_v3_save_state,
>>>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>>>>> -
>>>>> -static hyp_alternate_select(__vgic_call_restore_state,
>>>>> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
>>>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>>>>> -
>>>>>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>>>>>  {
>>>>> -	__vgic_call_save_state()(vcpu);
>>>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>>>>
>>>> It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
>>>> hardware becomes mainstream), but as we don't have another primitive for
>>>> the 'default disabled' case, I suppose that's the best we can do.
>>>
>>> We could always revert the "likelihood" of that test once GICv3 has
>>> conquered the world. Or start patching the 32bit kernel like we do for
>>> 64bit...
>>>
>>>>
>>>>> +		__vgic_v3_save_state(vcpu);
>>>>> +	else
>>>>> +		__vgic_v2_save_state(vcpu);
>>>>> +
>>>>>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
>>>>>  }
>>>>>  
>>>>> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>>>>>  	val |= vcpu->arch.irq_lines;
>>>>>  	write_sysreg(val, hcr_el2);
>>>>>  
>>>>> -	__vgic_call_restore_state()(vcpu);
>>>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>>>>> +		__vgic_v3_restore_state(vcpu);
>>>>> +	else
>>>>> +		__vgic_v2_restore_state(vcpu);
>>>>>  }
>>>>>  
>>>>>  static bool __hyp_text __true_value(void)
>>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>>> index 19b698e..994665a 100644
>>>>> --- a/include/kvm/arm_vgic.h
>>>>> +++ b/include/kvm/arm_vgic.h
>>>>> @@ -23,6 +23,7 @@
>>>>>  #include <linux/types.h>
>>>>>  #include <kvm/iodev.h>
>>>>>  #include <linux/list.h>
>>>>> +#include <linux/jump_label.h>
>>>>>  
>>>>>  #define VGIC_V3_MAX_CPUS	255
>>>>>  #define VGIC_V2_MAX_CPUS	8
>>>>> @@ -63,6 +64,9 @@ struct vgic_global {
>>>>>  
>>>>>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
>>>>>  	bool			can_emulate_gicv2;
>>>>> +
>>>>> +	/* GIC system register CPU interface */
>>>>> +	struct static_key_false gicv3_cpuif;
>>>>
>>>> Documentation/static-keys.txt says that we are not supposed to use
>>>> struct static_key_false directly.  This will obviously work quite
>>>> nicely, but we could consider adding a pair of
>>>> DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
>>>> but obviously this will need an ack from other maintainers.
>>>>
>>>> Thoughts?
>>>
>>> Grepping through the tree shows that we're not the only abusers of this
>>> (dynamic debug is far worse!). Happy to write the additional macros and
>>> submit them if nobody beats me to it.
>>>
>>>>
>>>>
>>>>>  };
>>>>>  
>>>>>  extern struct vgic_global kvm_vgic_global_state;
>>>>> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
>>>>> index 83777c1..14d6718 100644
>>>>> --- a/virt/kvm/arm/vgic/vgic-init.c
>>>>> +++ b/virt/kvm/arm/vgic/vgic-init.c
>>>>> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
>>>>>  		break;
>>>>>  	case GIC_V3:
>>>>>  		ret = vgic_v3_probe(gic_kvm_info);
>>>>> +		if (!ret) {
>>>>> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
>>>>> +			kvm_info("GIC system register CPU interface\n");
>>>>
>>>> nit: add enabled to the info message?
>>>>
>>>>> +		}
>>>>>  		break;
>>>>>  	default:
>>>>>  		ret = -ENODEV;
>>>>> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
>>>>> index e83b7fe..8a529a7 100644
>>>>> --- a/virt/kvm/arm/vgic/vgic.c
>>>>> +++ b/virt/kvm/arm/vgic/vgic.c
>>>>> @@ -29,7 +29,7 @@
>>>>>  #define DEBUG_SPINLOCK_BUG_ON(p)
>>>>>  #endif
>>>>>  
>>>>> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
>>>>> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
>>>>>  
>>>>>  /*
>>>>>   * Locking order is always:
>>>>> -- 
>>>>> 1.7.9.5
>>>>>
>>>>
>>>> Overall this looks really nice, as long as we're clear on the static
>>>> keys stuff.
>>>
>>> Indeed, we should get this sorted, though I'm not sure this should be a
>>> blocker for this code.
>>>
>> Agreed, let's ship it!
> 
> To make it clear, should I respin with "enabled" into the info message
> and macros for static keys?

I think we can fix the message up when applying the patches. As for the
macros, we should have a separate series that does it treewide.

Christoffer?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
@ 2016-09-14 15:47             ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-14 15:47 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/09/16 16:20, Vladimir Murzin wrote:
> On 13/09/16 10:22, Christoffer Dall wrote:
>> On Tue, Sep 13, 2016 at 10:11:10AM +0100, Marc Zyngier wrote:
>>> On 13/09/16 09:20, Christoffer Dall wrote:
>>>> On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
>>>>> Currently GIC backend is selected via alternative framework and this
>>>>> is fine. We are going to introduce vgic-v3 to 32-bit world and there
>>>>> we don't have patching framework in hand, so we can either check
>>>>> support for GICv3 every time we need to choose which backend to use or
>>>>> try to optimise it by using static keys. The later looks quite
>>>>> promising because we can share logic involved in selecting GIC backend
>>>>> between architectures if both uses static keys.
>>>>>
>>>>> This patch moves arm64 from alternative to static keys framework for
>>>>> selecting GIC backend. For that we embed static key into vgic_global
>>>>> and enable the key during vgic initialisation based on what has
>>>>> already been exposed by the host GIC driver.
>>>>>
>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>> ---
>>>>>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>>>>>  include/kvm/arm_vgic.h        |    4 ++++
>>>>>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>>>>>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>>>>>  4 files changed, 20 insertions(+), 11 deletions(-)
>>>>>
>>>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
>>>>> index 5a84b45..d5c4cc5 100644
>>>>> --- a/arch/arm64/kvm/hyp/switch.c
>>>>> +++ b/arch/arm64/kvm/hyp/switch.c
>>>>> @@ -16,6 +16,8 @@
>>>>>   */
>>>>>  
>>>>>  #include <linux/types.h>
>>>>> +#include <linux/jump_label.h>
>>>>> +
>>>>>  #include <asm/kvm_asm.h>
>>>>>  #include <asm/kvm_hyp.h>
>>>>>  
>>>>> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
>>>>>  	write_sysreg(0, vttbr_el2);
>>>>>  }
>>>>>  
>>>>> -static hyp_alternate_select(__vgic_call_save_state,
>>>>> -			    __vgic_v2_save_state, __vgic_v3_save_state,
>>>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>>>>> -
>>>>> -static hyp_alternate_select(__vgic_call_restore_state,
>>>>> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
>>>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
>>>>> -
>>>>>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
>>>>>  {
>>>>> -	__vgic_call_save_state()(vcpu);
>>>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>>>>
>>>> It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
>>>> hardware becomes mainstream), but as we don't have another primitive for
>>>> the 'default disabled' case, I suppose that's the best we can do.
>>>
>>> We could always revert the "likelihood" of that test once GICv3 has
>>> conquered the world. Or start patching the 32bit kernel like we do for
>>> 64bit...
>>>
>>>>
>>>>> +		__vgic_v3_save_state(vcpu);
>>>>> +	else
>>>>> +		__vgic_v2_save_state(vcpu);
>>>>> +
>>>>>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
>>>>>  }
>>>>>  
>>>>> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
>>>>>  	val |= vcpu->arch.irq_lines;
>>>>>  	write_sysreg(val, hcr_el2);
>>>>>  
>>>>> -	__vgic_call_restore_state()(vcpu);
>>>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
>>>>> +		__vgic_v3_restore_state(vcpu);
>>>>> +	else
>>>>> +		__vgic_v2_restore_state(vcpu);
>>>>>  }
>>>>>  
>>>>>  static bool __hyp_text __true_value(void)
>>>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
>>>>> index 19b698e..994665a 100644
>>>>> --- a/include/kvm/arm_vgic.h
>>>>> +++ b/include/kvm/arm_vgic.h
>>>>> @@ -23,6 +23,7 @@
>>>>>  #include <linux/types.h>
>>>>>  #include <kvm/iodev.h>
>>>>>  #include <linux/list.h>
>>>>> +#include <linux/jump_label.h>
>>>>>  
>>>>>  #define VGIC_V3_MAX_CPUS	255
>>>>>  #define VGIC_V2_MAX_CPUS	8
>>>>> @@ -63,6 +64,9 @@ struct vgic_global {
>>>>>  
>>>>>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
>>>>>  	bool			can_emulate_gicv2;
>>>>> +
>>>>> +	/* GIC system register CPU interface */
>>>>> +	struct static_key_false gicv3_cpuif;
>>>>
>>>> Documentation/static-keys.txt says that we are not supposed to use
>>>> struct static_key_false directly.  This will obviously work quite
>>>> nicely, but we could consider adding a pair of
>>>> DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
>>>> but obviously this will need an ack from other maintainers.
>>>>
>>>> Thoughts?
>>>
>>> Grepping through the tree shows that we're not the only abusers of this
>>> (dynamic debug is far worse!). Happy to write the additional macros and
>>> submit them if nobody beats me to it.
>>>
>>>>
>>>>
>>>>>  };
>>>>>  
>>>>>  extern struct vgic_global kvm_vgic_global_state;
>>>>> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
>>>>> index 83777c1..14d6718 100644
>>>>> --- a/virt/kvm/arm/vgic/vgic-init.c
>>>>> +++ b/virt/kvm/arm/vgic/vgic-init.c
>>>>> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
>>>>>  		break;
>>>>>  	case GIC_V3:
>>>>>  		ret = vgic_v3_probe(gic_kvm_info);
>>>>> +		if (!ret) {
>>>>> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
>>>>> +			kvm_info("GIC system register CPU interface\n");
>>>>
>>>> nit: add enabled to the info message?
>>>>
>>>>> +		}
>>>>>  		break;
>>>>>  	default:
>>>>>  		ret = -ENODEV;
>>>>> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
>>>>> index e83b7fe..8a529a7 100644
>>>>> --- a/virt/kvm/arm/vgic/vgic.c
>>>>> +++ b/virt/kvm/arm/vgic/vgic.c
>>>>> @@ -29,7 +29,7 @@
>>>>>  #define DEBUG_SPINLOCK_BUG_ON(p)
>>>>>  #endif
>>>>>  
>>>>> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
>>>>> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
>>>>>  
>>>>>  /*
>>>>>   * Locking order is always:
>>>>> -- 
>>>>> 1.7.9.5
>>>>>
>>>>
>>>> Overall this looks really nice, as long as we're clear on the static
>>>> keys stuff.
>>>
>>> Indeed, we should get this sorted, though I'm not sure this should be a
>>> blocker for this code.
>>>
>> Agreed, let's ship it!
> 
> To make it clear, should I respin with "enabled" into the info message
> and macros for static keys?

I think we can fix the message up when applying the patches. As for the
macros, we should have a separate series that does it treewide.

Christoffer?

Thanks,

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-14 15:21               ` Vladimir Murzin
@ 2016-09-14 15:50                 ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-14 15:50 UTC (permalink / raw)
  To: Vladimir Murzin, Christoffer Dall
  Cc: andre.przywara, Russell King, kvmarm, linux-arm-kernel

On 14/09/16 16:21, Vladimir Murzin wrote:
> On 13/09/16 11:44, Marc Zyngier wrote:
>> On 13/09/16 11:32, Vladimir Murzin wrote:
>>> On 13/09/16 11:12, Marc Zyngier wrote:
>>>> On 13/09/16 10:04, Vladimir Murzin wrote:
>>>>> On 13/09/16 09:38, Christoffer Dall wrote:
>>>>>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>>>>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>>>>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>>>>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>>>>>
>>>>>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>>>> ---
>>>>>>>  arch/arm/include/asm/cputype.h |    1 +
>>>>>>>  1 file changed, 1 insertion(+)
>>>>>>>
>>>>>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>>>>>> index 1ee94c7..e2d94c1 100644
>>>>>>> --- a/arch/arm/include/asm/cputype.h
>>>>>>> +++ b/arch/arm/include/asm/cputype.h
>>>>>>> @@ -55,6 +55,7 @@
>>>>>>>  
>>>>>>>  #define MPIDR_LEVEL_BITS 8
>>>>>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>>>>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>>>>>  
>>>>>>
>>>>>> I'm not sure I follow the correctness of this completely.
>>>>>>
>>>>>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>>>>>> may have something in the Aff3 field, which we now shift left 24 bits,
>>>>>> but that is not the Aff3 field of AArch32's MPIDR.
>>>>>>
>>>>>> What is the rationale for this making sense again?
>>>>>
>>>>> IIUC, in such case we construct mpidr which won't match in match_mpidr()
>>>>> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
>>>>> sent to the guest.
>>>>>
>>>>> Since we get that u64 value from the guest, I'd think it is something
>>>>> wrong is going on in the guest in case Aff3 is non-zero; however, we can
>>>>> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().
>>>>
>>>> I don't think zeroing Aff3 is the right move, as the spec doesn't say
>>>> that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
>>>> the spec says (in the context of the target list): "If a bit is 1 and
>>>> the bit does not correspond to a valid target PE, the bit must be
>>>> ignored by the Distributor".
>>>>
>>>> This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
>>>> ignore that SGI because there is no way we can actually deliver it.
>>>>
>>>> Could you cook a small patch that would go on top of this series?
>>>
>>> I assume you've meant ICC_SGI1R.IRM, aka broadcast. In this case,
>>
>> Yes, sorry.
>>
>>> vgic_v3_dispatch_sgi() seems already matches the logic you've described:
>>>
>>> - if IRM == 1, send to everyone except self without check for mpidr
>>> - if IRM == 0, send to target iff matched to a valid mpidr
>>>
>>> Am I missing something?
>>
>> Not much. My only ask was that if Aff3 was set, we could take the
>> shortcut of not calling vgic_v3_dispatch_sgi() at all and return
>> immediately. But as you said, we already deal with the case of invalid
>> MPIDRs.
>>
> 
> Anything I can do to make this patch better?

I'm OK with it as it is. The shortcut doesn't bring anything useful, so
let's not optimise for an invalid case.

FWIW: Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-14 15:50                 ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-14 15:50 UTC (permalink / raw)
  To: linux-arm-kernel

On 14/09/16 16:21, Vladimir Murzin wrote:
> On 13/09/16 11:44, Marc Zyngier wrote:
>> On 13/09/16 11:32, Vladimir Murzin wrote:
>>> On 13/09/16 11:12, Marc Zyngier wrote:
>>>> On 13/09/16 10:04, Vladimir Murzin wrote:
>>>>> On 13/09/16 09:38, Christoffer Dall wrote:
>>>>>> On Mon, Sep 12, 2016 at 03:49:21PM +0100, Vladimir Murzin wrote:
>>>>>>> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
>>>>>>> encode the affinity in a form compatible with ICC_SGI* registers.
>>>>>>> Unfortunately, that macro is missing on ARM, so let's add it.
>>>>>>>
>>>>>>> Cc: Russell King <rmk+kernel@armlinux.org.uk>
>>>>>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
>>>>>>> ---
>>>>>>>  arch/arm/include/asm/cputype.h |    1 +
>>>>>>>  1 file changed, 1 insertion(+)
>>>>>>>
>>>>>>> diff --git a/arch/arm/include/asm/cputype.h b/arch/arm/include/asm/cputype.h
>>>>>>> index 1ee94c7..e2d94c1 100644
>>>>>>> --- a/arch/arm/include/asm/cputype.h
>>>>>>> +++ b/arch/arm/include/asm/cputype.h
>>>>>>> @@ -55,6 +55,7 @@
>>>>>>>  
>>>>>>>  #define MPIDR_LEVEL_BITS 8
>>>>>>>  #define MPIDR_LEVEL_MASK ((1 << MPIDR_LEVEL_BITS) - 1)
>>>>>>> +#define MPIDR_LEVEL_SHIFT(level) (MPIDR_LEVEL_BITS * level)
>>>>>>>  
>>>>>>
>>>>>> I'm not sure I follow the correctness of this completely.
>>>>>>
>>>>>> This is called from vgic_v3_dispatch_sgi, which takes a u64 value, which
>>>>>> may have something in the Aff3 field, which we now shift left 24 bits,
>>>>>> but that is not the Aff3 field of AArch32's MPIDR.
>>>>>>
>>>>>> What is the rationale for this making sense again?
>>>>>
>>>>> IIUC, in such case we construct mpidr which won't match in match_mpidr()
>>>>> with the value we get from kvm_vcpu_get_mpidr_aff() and no SGI will be
>>>>> sent to the guest.
>>>>>
>>>>> Since we get that u64 value from the guest, I'd think it is something
>>>>> wrong is going on in the guest in case Aff3 is non-zero; however, we can
>>>>> hide it by zeroing out SGI Aff3 bits in access_gic_sgi().
>>>>
>>>> I don't think zeroing Aff3 is the right move, as the spec doesn't say
>>>> that Aff3 should be ignored in a write to ICC_SGI1R. On the other hand,
>>>> the spec says (in the context of the target list): "If a bit is 1 and
>>>> the bit does not correspond to a valid target PE, the bit must be
>>>> ignored by the Distributor".
>>>>
>>>> This makes me think that, unless ICC_SGI1R.IMR is set, we should simply
>>>> ignore that SGI because there is no way we can actually deliver it.
>>>>
>>>> Could you cook a small patch that would go on top of this series?
>>>
>>> I assume you've meant ICC_SGI1R.IRM, aka broadcast. In this case,
>>
>> Yes, sorry.
>>
>>> vgic_v3_dispatch_sgi() seems already matches the logic you've described:
>>>
>>> - if IRM == 1, send to everyone except self without check for mpidr
>>> - if IRM == 0, send to target iff matched to a valid mpidr
>>>
>>> Am I missing something?
>>
>> Not much. My only ask was that if Aff3 was set, we could take the
>> shortcut of not calling vgic_v3_dispatch_sgi() at all and return
>> immediately. But as you said, we already deal with the case of invalid
>> MPIDRs.
>>
> 
> Anything I can do to make this patch better?

I'm OK with it as it is. The shortcut doesn't bring anything useful, so
let's not optimise for an invalid case.

FWIW: Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
  2016-09-14 15:20           ` Vladimir Murzin
@ 2016-09-15  9:03             ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-15  9:03 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: Marc Zyngier, andre.przywara, kvmarm, linux-arm-kernel

On Wed, Sep 14, 2016 at 04:20:00PM +0100, Vladimir Murzin wrote:
> On 13/09/16 10:22, Christoffer Dall wrote:
> > On Tue, Sep 13, 2016 at 10:11:10AM +0100, Marc Zyngier wrote:
> >> On 13/09/16 09:20, Christoffer Dall wrote:
> >>> On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
> >>>> Currently GIC backend is selected via alternative framework and this
> >>>> is fine. We are going to introduce vgic-v3 to 32-bit world and there
> >>>> we don't have patching framework in hand, so we can either check
> >>>> support for GICv3 every time we need to choose which backend to use or
> >>>> try to optimise it by using static keys. The later looks quite
> >>>> promising because we can share logic involved in selecting GIC backend
> >>>> between architectures if both uses static keys.
> >>>>
> >>>> This patch moves arm64 from alternative to static keys framework for
> >>>> selecting GIC backend. For that we embed static key into vgic_global
> >>>> and enable the key during vgic initialisation based on what has
> >>>> already been exposed by the host GIC driver.
> >>>>
> >>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> >>>> ---
> >>>>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
> >>>>  include/kvm/arm_vgic.h        |    4 ++++
> >>>>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
> >>>>  virt/kvm/arm/vgic/vgic.c      |    2 +-
> >>>>  4 files changed, 20 insertions(+), 11 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> >>>> index 5a84b45..d5c4cc5 100644
> >>>> --- a/arch/arm64/kvm/hyp/switch.c
> >>>> +++ b/arch/arm64/kvm/hyp/switch.c
> >>>> @@ -16,6 +16,8 @@
> >>>>   */
> >>>>  
> >>>>  #include <linux/types.h>
> >>>> +#include <linux/jump_label.h>
> >>>> +
> >>>>  #include <asm/kvm_asm.h>
> >>>>  #include <asm/kvm_hyp.h>
> >>>>  
> >>>> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
> >>>>  	write_sysreg(0, vttbr_el2);
> >>>>  }
> >>>>  
> >>>> -static hyp_alternate_select(__vgic_call_save_state,
> >>>> -			    __vgic_v2_save_state, __vgic_v3_save_state,
> >>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> >>>> -
> >>>> -static hyp_alternate_select(__vgic_call_restore_state,
> >>>> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
> >>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> >>>> -
> >>>>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
> >>>>  {
> >>>> -	__vgic_call_save_state()(vcpu);
> >>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> >>>
> >>> It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
> >>> hardware becomes mainstream), but as we don't have another primitive for
> >>> the 'default disabled' case, I suppose that's the best we can do.
> >>
> >> We could always revert the "likelihood" of that test once GICv3 has
> >> conquered the world. Or start patching the 32bit kernel like we do for
> >> 64bit...
> >>
> >>>
> >>>> +		__vgic_v3_save_state(vcpu);
> >>>> +	else
> >>>> +		__vgic_v2_save_state(vcpu);
> >>>> +
> >>>>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
> >>>>  }
> >>>>  
> >>>> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
> >>>>  	val |= vcpu->arch.irq_lines;
> >>>>  	write_sysreg(val, hcr_el2);
> >>>>  
> >>>> -	__vgic_call_restore_state()(vcpu);
> >>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> >>>> +		__vgic_v3_restore_state(vcpu);
> >>>> +	else
> >>>> +		__vgic_v2_restore_state(vcpu);
> >>>>  }
> >>>>  
> >>>>  static bool __hyp_text __true_value(void)
> >>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >>>> index 19b698e..994665a 100644
> >>>> --- a/include/kvm/arm_vgic.h
> >>>> +++ b/include/kvm/arm_vgic.h
> >>>> @@ -23,6 +23,7 @@
> >>>>  #include <linux/types.h>
> >>>>  #include <kvm/iodev.h>
> >>>>  #include <linux/list.h>
> >>>> +#include <linux/jump_label.h>
> >>>>  
> >>>>  #define VGIC_V3_MAX_CPUS	255
> >>>>  #define VGIC_V2_MAX_CPUS	8
> >>>> @@ -63,6 +64,9 @@ struct vgic_global {
> >>>>  
> >>>>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
> >>>>  	bool			can_emulate_gicv2;
> >>>> +
> >>>> +	/* GIC system register CPU interface */
> >>>> +	struct static_key_false gicv3_cpuif;
> >>>
> >>> Documentation/static-keys.txt says that we are not supposed to use
> >>> struct static_key_false directly.  This will obviously work quite
> >>> nicely, but we could consider adding a pair of
> >>> DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
> >>> but obviously this will need an ack from other maintainers.
> >>>
> >>> Thoughts?
> >>
> >> Grepping through the tree shows that we're not the only abusers of this
> >> (dynamic debug is far worse!). Happy to write the additional macros and
> >> submit them if nobody beats me to it.
> >>
> >>>
> >>>
> >>>>  };
> >>>>  
> >>>>  extern struct vgic_global kvm_vgic_global_state;
> >>>> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
> >>>> index 83777c1..14d6718 100644
> >>>> --- a/virt/kvm/arm/vgic/vgic-init.c
> >>>> +++ b/virt/kvm/arm/vgic/vgic-init.c
> >>>> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
> >>>>  		break;
> >>>>  	case GIC_V3:
> >>>>  		ret = vgic_v3_probe(gic_kvm_info);
> >>>> +		if (!ret) {
> >>>> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
> >>>> +			kvm_info("GIC system register CPU interface\n");
> >>>
> >>> nit: add enabled to the info message?
> >>>
> >>>> +		}
> >>>>  		break;
> >>>>  	default:
> >>>>  		ret = -ENODEV;
> >>>> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> >>>> index e83b7fe..8a529a7 100644
> >>>> --- a/virt/kvm/arm/vgic/vgic.c
> >>>> +++ b/virt/kvm/arm/vgic/vgic.c
> >>>> @@ -29,7 +29,7 @@
> >>>>  #define DEBUG_SPINLOCK_BUG_ON(p)
> >>>>  #endif
> >>>>  
> >>>> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
> >>>> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
> >>>>  
> >>>>  /*
> >>>>   * Locking order is always:
> >>>> -- 
> >>>> 1.7.9.5
> >>>>
> >>>
> >>> Overall this looks really nice, as long as we're clear on the static
> >>> keys stuff.
> >>
> >> Indeed, we should get this sorted, though I'm not sure this should be a
> >> blocker for this code.
> >>
> > Agreed, let's ship it!
> 
> To make it clear, should I respin with "enabled" into the info message
> and macros for static keys?
> 
No, I can fix up the info message and we can worry aboutt he macros
later.  Marc said he would be happy to do that :)

-Christoffer

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
@ 2016-09-15  9:03             ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-15  9:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Sep 14, 2016 at 04:20:00PM +0100, Vladimir Murzin wrote:
> On 13/09/16 10:22, Christoffer Dall wrote:
> > On Tue, Sep 13, 2016 at 10:11:10AM +0100, Marc Zyngier wrote:
> >> On 13/09/16 09:20, Christoffer Dall wrote:
> >>> On Mon, Sep 12, 2016 at 03:49:15PM +0100, Vladimir Murzin wrote:
> >>>> Currently GIC backend is selected via alternative framework and this
> >>>> is fine. We are going to introduce vgic-v3 to 32-bit world and there
> >>>> we don't have patching framework in hand, so we can either check
> >>>> support for GICv3 every time we need to choose which backend to use or
> >>>> try to optimise it by using static keys. The later looks quite
> >>>> promising because we can share logic involved in selecting GIC backend
> >>>> between architectures if both uses static keys.
> >>>>
> >>>> This patch moves arm64 from alternative to static keys framework for
> >>>> selecting GIC backend. For that we embed static key into vgic_global
> >>>> and enable the key during vgic initialisation based on what has
> >>>> already been exposed by the host GIC driver.
> >>>>
> >>>> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> >>>> ---
> >>>>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
> >>>>  include/kvm/arm_vgic.h        |    4 ++++
> >>>>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
> >>>>  virt/kvm/arm/vgic/vgic.c      |    2 +-
> >>>>  4 files changed, 20 insertions(+), 11 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c
> >>>> index 5a84b45..d5c4cc5 100644
> >>>> --- a/arch/arm64/kvm/hyp/switch.c
> >>>> +++ b/arch/arm64/kvm/hyp/switch.c
> >>>> @@ -16,6 +16,8 @@
> >>>>   */
> >>>>  
> >>>>  #include <linux/types.h>
> >>>> +#include <linux/jump_label.h>
> >>>> +
> >>>>  #include <asm/kvm_asm.h>
> >>>>  #include <asm/kvm_hyp.h>
> >>>>  
> >>>> @@ -126,17 +128,13 @@ static void __hyp_text __deactivate_vm(struct kvm_vcpu *vcpu)
> >>>>  	write_sysreg(0, vttbr_el2);
> >>>>  }
> >>>>  
> >>>> -static hyp_alternate_select(__vgic_call_save_state,
> >>>> -			    __vgic_v2_save_state, __vgic_v3_save_state,
> >>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> >>>> -
> >>>> -static hyp_alternate_select(__vgic_call_restore_state,
> >>>> -			    __vgic_v2_restore_state, __vgic_v3_restore_state,
> >>>> -			    ARM64_HAS_SYSREG_GIC_CPUIF);
> >>>> -
> >>>>  static void __hyp_text __vgic_save_state(struct kvm_vcpu *vcpu)
> >>>>  {
> >>>> -	__vgic_call_save_state()(vcpu);
> >>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> >>>
> >>> It's a bit weird that we use _unlikely for GICv3 (at least if/when GICv3
> >>> hardware becomes mainstream), but as we don't have another primitive for
> >>> the 'default disabled' case, I suppose that's the best we can do.
> >>
> >> We could always revert the "likelihood" of that test once GICv3 has
> >> conquered the world. Or start patching the 32bit kernel like we do for
> >> 64bit...
> >>
> >>>
> >>>> +		__vgic_v3_save_state(vcpu);
> >>>> +	else
> >>>> +		__vgic_v2_save_state(vcpu);
> >>>> +
> >>>>  	write_sysreg(read_sysreg(hcr_el2) & ~HCR_INT_OVERRIDE, hcr_el2);
> >>>>  }
> >>>>  
> >>>> @@ -149,7 +147,10 @@ static void __hyp_text __vgic_restore_state(struct kvm_vcpu *vcpu)
> >>>>  	val |= vcpu->arch.irq_lines;
> >>>>  	write_sysreg(val, hcr_el2);
> >>>>  
> >>>> -	__vgic_call_restore_state()(vcpu);
> >>>> +	if (static_branch_unlikely(&kvm_vgic_global_state.gicv3_cpuif))
> >>>> +		__vgic_v3_restore_state(vcpu);
> >>>> +	else
> >>>> +		__vgic_v2_restore_state(vcpu);
> >>>>  }
> >>>>  
> >>>>  static bool __hyp_text __true_value(void)
> >>>> diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h
> >>>> index 19b698e..994665a 100644
> >>>> --- a/include/kvm/arm_vgic.h
> >>>> +++ b/include/kvm/arm_vgic.h
> >>>> @@ -23,6 +23,7 @@
> >>>>  #include <linux/types.h>
> >>>>  #include <kvm/iodev.h>
> >>>>  #include <linux/list.h>
> >>>> +#include <linux/jump_label.h>
> >>>>  
> >>>>  #define VGIC_V3_MAX_CPUS	255
> >>>>  #define VGIC_V2_MAX_CPUS	8
> >>>> @@ -63,6 +64,9 @@ struct vgic_global {
> >>>>  
> >>>>  	/* Only needed for the legacy KVM_CREATE_IRQCHIP */
> >>>>  	bool			can_emulate_gicv2;
> >>>> +
> >>>> +	/* GIC system register CPU interface */
> >>>> +	struct static_key_false gicv3_cpuif;
> >>>
> >>> Documentation/static-keys.txt says that we are not supposed to use
> >>> struct static_key_false directly.  This will obviously work quite
> >>> nicely, but we could consider adding a pair of
> >>> DECLARE_STATIC_KEY_TRUE/FALSE macros that don't have the assignments,
> >>> but obviously this will need an ack from other maintainers.
> >>>
> >>> Thoughts?
> >>
> >> Grepping through the tree shows that we're not the only abusers of this
> >> (dynamic debug is far worse!). Happy to write the additional macros and
> >> submit them if nobody beats me to it.
> >>
> >>>
> >>>
> >>>>  };
> >>>>  
> >>>>  extern struct vgic_global kvm_vgic_global_state;
> >>>> diff --git a/virt/kvm/arm/vgic/vgic-init.c b/virt/kvm/arm/vgic/vgic-init.c
> >>>> index 83777c1..14d6718 100644
> >>>> --- a/virt/kvm/arm/vgic/vgic-init.c
> >>>> +++ b/virt/kvm/arm/vgic/vgic-init.c
> >>>> @@ -405,6 +405,10 @@ int kvm_vgic_hyp_init(void)
> >>>>  		break;
> >>>>  	case GIC_V3:
> >>>>  		ret = vgic_v3_probe(gic_kvm_info);
> >>>> +		if (!ret) {
> >>>> +			static_branch_enable(&kvm_vgic_global_state.gicv3_cpuif);
> >>>> +			kvm_info("GIC system register CPU interface\n");
> >>>
> >>> nit: add enabled to the info message?
> >>>
> >>>> +		}
> >>>>  		break;
> >>>>  	default:
> >>>>  		ret = -ENODEV;
> >>>> diff --git a/virt/kvm/arm/vgic/vgic.c b/virt/kvm/arm/vgic/vgic.c
> >>>> index e83b7fe..8a529a7 100644
> >>>> --- a/virt/kvm/arm/vgic/vgic.c
> >>>> +++ b/virt/kvm/arm/vgic/vgic.c
> >>>> @@ -29,7 +29,7 @@
> >>>>  #define DEBUG_SPINLOCK_BUG_ON(p)
> >>>>  #endif
> >>>>  
> >>>> -struct vgic_global __section(.hyp.text) kvm_vgic_global_state;
> >>>> +struct vgic_global __section(.hyp.text) kvm_vgic_global_state = {.gicv3_cpuif = STATIC_KEY_FALSE_INIT,};
> >>>>  
> >>>>  /*
> >>>>   * Locking order is always:
> >>>> -- 
> >>>> 1.7.9.5
> >>>>
> >>>
> >>> Overall this looks really nice, as long as we're clear on the static
> >>> keys stuff.
> >>
> >> Indeed, we should get this sorted, though I'm not sure this should be a
> >> blocker for this code.
> >>
> > Agreed, let's ship it!
> 
> To make it clear, should I respin with "enabled" into the info message
> and macros for static keys?
> 
No, I can fix up the info message and we can worry aboutt he macros
later.  Marc said he would be happy to do that :)

-Christoffer

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 00/10] ARM: KVM: Support for vgic-v3
  2016-09-12 14:49 ` Vladimir Murzin
@ 2016-09-15  9:13   ` Christoffer Dall
  -1 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-15  9:13 UTC (permalink / raw)
  To: Vladimir Murzin; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

Hi Valdimir,

On Mon, Sep 12, 2016 at 03:49:14PM +0100, Vladimir Murzin wrote:
> Hi,
> 
> This is an attempt to make use vgic-v3 under arch/arm since
> save-restore functionality got re-written in C and can be shared
> between arm/arm64 like it has already been done for vgic-v2 and timer.
> 
> With this patches I'm able to get 32 core an AArch32 ARMv8 guest boot:
> 
> ...
> GICv3: CPU31: found redistributor 703 region 0:0x000000003ffd0000
> CPU31: thread -1, cpu 3, socket 7, mpidr 80000703
> Brought up 32 CPUs
> SMP: Total of 32 processors activated (768.00 BogoMIPS).
> CPU: All CPU(s) started in SVC mode.
> ...
> 
> Additionally, quite lightweight test based on Self IPI guest test[1]
> has been run with up to 255 cpus.
> 
I have applied this to kvmarm/queue, fixing up a few trivial conflicts,
and I have changed the kvm_info message.

If you could test the integrated branch with GICv3 on a 32-bit platform,
that would be great.

I'll give people a few days to give their acks to the non-KVM part of
the series and will then put it in next.

Thanks for the work,
-Christoffer

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 00/10] ARM: KVM: Support for vgic-v3
@ 2016-09-15  9:13   ` Christoffer Dall
  0 siblings, 0 replies; 80+ messages in thread
From: Christoffer Dall @ 2016-09-15  9:13 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Valdimir,

On Mon, Sep 12, 2016 at 03:49:14PM +0100, Vladimir Murzin wrote:
> Hi,
> 
> This is an attempt to make use vgic-v3 under arch/arm since
> save-restore functionality got re-written in C and can be shared
> between arm/arm64 like it has already been done for vgic-v2 and timer.
> 
> With this patches I'm able to get 32 core an AArch32 ARMv8 guest boot:
> 
> ...
> GICv3: CPU31: found redistributor 703 region 0:0x000000003ffd0000
> CPU31: thread -1, cpu 3, socket 7, mpidr 80000703
> Brought up 32 CPUs
> SMP: Total of 32 processors activated (768.00 BogoMIPS).
> CPU: All CPU(s) started in SVC mode.
> ...
> 
> Additionally, quite lightweight test based on Self IPI guest test[1]
> has been run with up to 255 cpus.
> 
I have applied this to kvmarm/queue, fixing up a few trivial conflicts,
and I have changed the kvm_info message.

If you could test the integrated branch with GICv3 on a 32-bit platform,
that would be great.

I'll give people a few days to give their acks to the non-KVM part of
the series and will then put it in next.

Thanks for the work,
-Christoffer

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 00/10] ARM: KVM: Support for vgic-v3
  2016-09-15  9:13   ` Christoffer Dall
@ 2016-09-15 10:33     ` Vladimir Murzin
  -1 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-15 10:33 UTC (permalink / raw)
  To: Christoffer Dall; +Cc: marc.zyngier, andre.przywara, kvmarm, linux-arm-kernel

Hi Christoffer,

On 15/09/16 10:13, Christoffer Dall wrote:
> Hi Valdimir,
> 
> On Mon, Sep 12, 2016 at 03:49:14PM +0100, Vladimir Murzin wrote:
>> Hi,
>>
>> This is an attempt to make use vgic-v3 under arch/arm since
>> save-restore functionality got re-written in C and can be shared
>> between arm/arm64 like it has already been done for vgic-v2 and timer.
>>
>> With this patches I'm able to get 32 core an AArch32 ARMv8 guest boot:
>>
>> ...
>> GICv3: CPU31: found redistributor 703 region 0:0x000000003ffd0000
>> CPU31: thread -1, cpu 3, socket 7, mpidr 80000703
>> Brought up 32 CPUs
>> SMP: Total of 32 processors activated (768.00 BogoMIPS).
>> CPU: All CPU(s) started in SVC mode.
>> ...
>>
>> Additionally, quite lightweight test based on Self IPI guest test[1]
>> has been run with up to 255 cpus.
>>
> I have applied this to kvmarm/queue, fixing up a few trivial conflicts,
> and I have changed the kvm_info message.

Great!

> 
> If you could test the integrated branch with GICv3 on a 32-bit platform,
> that would be great.

I've just pulled kvmarm/queue and started testing.

> 
> I'll give people a few days to give their acks to the non-KVM part of
> the series and will then put it in next.
> 

Thanks!
Vladimir

> Thanks for the work,
> -Christoffer
> 
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 00/10] ARM: KVM: Support for vgic-v3
@ 2016-09-15 10:33     ` Vladimir Murzin
  0 siblings, 0 replies; 80+ messages in thread
From: Vladimir Murzin @ 2016-09-15 10:33 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 15/09/16 10:13, Christoffer Dall wrote:
> Hi Valdimir,
> 
> On Mon, Sep 12, 2016 at 03:49:14PM +0100, Vladimir Murzin wrote:
>> Hi,
>>
>> This is an attempt to make use vgic-v3 under arch/arm since
>> save-restore functionality got re-written in C and can be shared
>> between arm/arm64 like it has already been done for vgic-v2 and timer.
>>
>> With this patches I'm able to get 32 core an AArch32 ARMv8 guest boot:
>>
>> ...
>> GICv3: CPU31: found redistributor 703 region 0:0x000000003ffd0000
>> CPU31: thread -1, cpu 3, socket 7, mpidr 80000703
>> Brought up 32 CPUs
>> SMP: Total of 32 processors activated (768.00 BogoMIPS).
>> CPU: All CPU(s) started in SVC mode.
>> ...
>>
>> Additionally, quite lightweight test based on Self IPI guest test[1]
>> has been run with up to 255 cpus.
>>
> I have applied this to kvmarm/queue, fixing up a few trivial conflicts,
> and I have changed the kvm_info message.

Great!

> 
> If you could test the integrated branch with GICv3 on a 32-bit platform,
> that would be great.

I've just pulled kvmarm/queue and started testing.

> 
> I'll give people a few days to give their acks to the non-KVM part of
> the series and will then put it in next.
> 

Thanks!
Vladimir

> Thanks for the work,
> -Christoffer
> 
> 

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 09/10] ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-22  9:57     ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22  9:57 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm; +Cc: andre.przywara, linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> vgic-v3 save/restore routines are written in such way that they map
> arm64 system register naming nicely, but it does not fit to arm
> world. To keep virt/kvm/arm/hyp/vgic-v3-sr.c untouched we create a
> mapping with a function for each register mapping the 32-bit to the
> 64-bit accessors.
> 
> Please, note that 64-bit wide ICH_LR is split in two 32-bit halves
> (ICH_LR and ICH_LRC) accessed independently.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/arch_gicv3.h |   64 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 64 insertions(+)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 09/10] ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers
@ 2016-09-22  9:57     ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22  9:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> vgic-v3 save/restore routines are written in such way that they map
> arm64 system register naming nicely, but it does not fit to arm
> world. To keep virt/kvm/arm/hyp/vgic-v3-sr.c untouched we create a
> mapping with a function for each register mapping the 32-bit to the
> 64-bit accessors.
> 
> Please, note that 64-bit wide ICH_LR is split in two 32-bit halves
> (ICH_LR and ICH_LRC) accessed independently.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/arch_gicv3.h |   64 +++++++++++++++++++++++++++++++++++++
>  1 file changed, 64 insertions(+)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 10/10] ARM: KVM: Support vgic-v3
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-22  9:58     ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22  9:58 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm; +Cc: andre.przywara, linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> This patch allows to build and use vgic-v3 in 32-bit mode.
> 
> Unfortunately, it can not be split in several steps without extra
> stubs to keep patches independent and bisectable.  For instance,
> virt/kvm/arm/vgic/vgic-v3.c uses function from vgic-v3-sr.c, handling
> access to GICv3 cpu interface from the guest requires vgic_v3.vgic_sre
> to be already defined.
> 
> It is how support has been done:
> 
> * handle SGI requests from the guest
> 
> * report configured SRE on access to GICv3 cpu interface from the guest
> 
> * required vgic-v3 macros are provided via uapi.h
> 
> * static keys are used to select GIC backend
> 
> * to make vgic-v3 build KVM_ARM_VGIC_V3 guard is removed along with
>   the static inlines
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/kvm_asm.h      |    3 ++
>  arch/arm/include/asm/kvm_host.h     |    5 ++++
>  arch/arm/include/asm/kvm_hyp.h      |    3 ++
>  arch/arm/include/uapi/asm/kvm.h     |    7 +++++
>  arch/arm/kvm/Makefile               |    2 ++
>  arch/arm/kvm/coproc.c               |   35 +++++++++++++++++++++++
>  arch/arm/kvm/hyp/Makefile           |    1 +
>  arch/arm/kvm/hyp/switch.c           |   12 ++++++--
>  arch/arm64/kvm/Kconfig              |    4 ---
>  include/kvm/arm_vgic.h              |    8 ------
>  virt/kvm/arm/vgic/vgic-kvm-device.c |    8 ------
>  virt/kvm/arm/vgic/vgic-mmio.c       |    2 --
>  virt/kvm/arm/vgic/vgic-mmio.h       |    2 --
>  virt/kvm/arm/vgic/vgic.h            |   54 -----------------------------------
>  14 files changed, 66 insertions(+), 80 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 10/10] ARM: KVM: Support vgic-v3
@ 2016-09-22  9:58     ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22  9:58 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> This patch allows to build and use vgic-v3 in 32-bit mode.
> 
> Unfortunately, it can not be split in several steps without extra
> stubs to keep patches independent and bisectable.  For instance,
> virt/kvm/arm/vgic/vgic-v3.c uses function from vgic-v3-sr.c, handling
> access to GICv3 cpu interface from the guest requires vgic_v3.vgic_sre
> to be already defined.
> 
> It is how support has been done:
> 
> * handle SGI requests from the guest
> 
> * report configured SRE on access to GICv3 cpu interface from the guest
> 
> * required vgic-v3 macros are provided via uapi.h
> 
> * static keys are used to select GIC backend
> 
> * to make vgic-v3 build KVM_ARM_VGIC_V3 guard is removed along with
>   the static inlines
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/kvm_asm.h      |    3 ++
>  arch/arm/include/asm/kvm_host.h     |    5 ++++
>  arch/arm/include/asm/kvm_hyp.h      |    3 ++
>  arch/arm/include/uapi/asm/kvm.h     |    7 +++++
>  arch/arm/kvm/Makefile               |    2 ++
>  arch/arm/kvm/coproc.c               |   35 +++++++++++++++++++++++
>  arch/arm/kvm/hyp/Makefile           |    1 +
>  arch/arm/kvm/hyp/switch.c           |   12 ++++++--
>  arch/arm64/kvm/Kconfig              |    4 ---
>  include/kvm/arm_vgic.h              |    8 ------
>  virt/kvm/arm/vgic/vgic-kvm-device.c |    8 ------
>  virt/kvm/arm/vgic/vgic-mmio.c       |    2 --
>  virt/kvm/arm/vgic/vgic-mmio.h       |    2 --
>  virt/kvm/arm/vgic/vgic.h            |   54 -----------------------------------
>  14 files changed, 66 insertions(+), 80 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 08/10] ARM: Move system register accessors to asm/cp15.h
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-22  9:59     ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22  9:59 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm; +Cc: andre.przywara, Russell King, linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> Headers linux/irqchip/arm-gic.v3.h and arch/arm/include/asm/kvm_hyp.h
> are included in virt/kvm/arm/hyp/vgic-v3-sr.c and both define macros
> called __ACCESS_CP15 and __ACCESS_CP15_64 which obviously creates a
> conflict. These macros were introduced independently for GIC and KVM
> and, in fact, do the same thing.
> 
> As an option we could add prefixes to KVM and GIC version of macros so
> they won't clash, but it'd introduce code duplication.  Alternatively,
> we could keep macro in, say, GIC header and include it in KVM one (or
> vice versa), but such dependency would not look nicer.
> 
> So we follow arm64 way (it handles this via sysreg.h) and move only
> single set of macros to asm/cp15.h
> 
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/arch_gicv3.h |   27 +++++++++++----------------
>  arch/arm/include/asm/cp15.h       |   15 +++++++++++++++
>  arch/arm/include/asm/kvm_hyp.h    |   15 +--------------
>  3 files changed, 27 insertions(+), 30 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 08/10] ARM: Move system register accessors to asm/cp15.h
@ 2016-09-22  9:59     ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22  9:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> Headers linux/irqchip/arm-gic.v3.h and arch/arm/include/asm/kvm_hyp.h
> are included in virt/kvm/arm/hyp/vgic-v3-sr.c and both define macros
> called __ACCESS_CP15 and __ACCESS_CP15_64 which obviously creates a
> conflict. These macros were introduced independently for GIC and KVM
> and, in fact, do the same thing.
> 
> As an option we could add prefixes to KVM and GIC version of macros so
> they won't clash, but it'd introduce code duplication.  Alternatively,
> we could keep macro in, say, GIC header and include it in KVM one (or
> vice versa), but such dependency would not look nicer.
> 
> So we follow arm64 way (it handles this via sysreg.h) and move only
> single set of macros to asm/cp15.h
> 
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/arch_gicv3.h |   27 +++++++++++----------------
>  arch/arm/include/asm/cp15.h       |   15 +++++++++++++++
>  arch/arm/include/asm/kvm_hyp.h    |   15 +--------------
>  3 files changed, 27 insertions(+), 30 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-22  9:59     ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22  9:59 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm; +Cc: andre.przywara, Russell King, linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
> encode the affinity in a form compatible with ICC_SGI* registers.
> Unfortunately, that macro is missing on ARM, so let's add it.
> 
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/cputype.h |    1 +
>  1 file changed, 1 insertion(+)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro
@ 2016-09-22  9:59     ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22  9:59 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> vgic-v3 driver uses architecture specific MPIDR_LEVEL_SHIFT macro to
> encode the affinity in a form compatible with ICC_SGI* registers.
> Unfortunately, that macro is missing on ARM, so let's add it.
> 
> Cc: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm/include/asm/cputype.h |    1 +
>  1 file changed, 1 insertion(+)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 06/10] KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host systems
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-22 10:00     ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22 10:00 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm; +Cc: andre.przywara, linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> We have couple of 64-bit registers defined in GICv3 architecture, so
> unsigned long accesses to these registers will only access a single
> 32-bit part of that regitser. On the other hand these registers can't
> be accessed as 64-bit with a single instruction like ldrd/strd or
> ldmia/stmia if we run a 32-bit host because KVM does not support
> access to MMIO space done by these instructions.
> 
> It means that a 32-bit guest accesses these registers in 32-bit
> chunks, so the only thing we need to do is to ensure that
> extract_bytes() always takes 64-bit data.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  virt/kvm/arm/vgic/vgic-mmio-v3.c |    2 +-
>  virt/kvm/arm/vgic/vgic-mmio.h    |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 06/10] KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host systems
@ 2016-09-22 10:00     ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22 10:00 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> We have couple of 64-bit registers defined in GICv3 architecture, so
> unsigned long accesses to these registers will only access a single
> 32-bit part of that regitser. On the other hand these registers can't
> be accessed as 64-bit with a single instruction like ldrd/strd or
> ldmia/stmia if we run a 32-bit host because KVM does not support
> access to MMIO space done by these instructions.
> 
> It means that a 32-bit guest accesses these registers in 32-bit
> chunks, so the only thing we need to do is to ensure that
> extract_bytes() always takes 64-bit data.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  virt/kvm/arm/vgic/vgic-mmio-v3.c |    2 +-
>  virt/kvm/arm/vgic/vgic-mmio.h    |    2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-22 10:01     ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22 10:01 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm; +Cc: andre.przywara, linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> Currently GIC backend is selected via alternative framework and this
> is fine. We are going to introduce vgic-v3 to 32-bit world and there
> we don't have patching framework in hand, so we can either check
> support for GICv3 every time we need to choose which backend to use or
> try to optimise it by using static keys. The later looks quite
> promising because we can share logic involved in selecting GIC backend
> between architectures if both uses static keys.
> 
> This patch moves arm64 from alternative to static keys framework for
> selecting GIC backend. For that we embed static key into vgic_global
> and enable the key during vgic initialisation based on what has
> already been exposed by the host GIC driver.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>  include/kvm/arm_vgic.h        |    4 ++++
>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>  4 files changed, 20 insertions(+), 11 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend
@ 2016-09-22 10:01     ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22 10:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> Currently GIC backend is selected via alternative framework and this
> is fine. We are going to introduce vgic-v3 to 32-bit world and there
> we don't have patching framework in hand, so we can either check
> support for GICv3 every time we need to choose which backend to use or
> try to optimise it by using static keys. The later looks quite
> promising because we can share logic involved in selecting GIC backend
> between architectures if both uses static keys.
> 
> This patch moves arm64 from alternative to static keys framework for
> selecting GIC backend. For that we embed static key into vgic_global
> and enable the key during vgic initialisation based on what has
> already been exposed by the host GIC driver.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  arch/arm64/kvm/hyp/switch.c   |   21 +++++++++++----------
>  include/kvm/arm_vgic.h        |    4 ++++
>  virt/kvm/arm/vgic/vgic-init.c |    4 ++++
>  virt/kvm/arm/vgic/vgic.c      |    2 +-
>  4 files changed, 20 insertions(+), 11 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* Re: [PATCH v4 05/10] KVM: arm: vgic: Fix compiler warnings when built for 32-bit
  2016-09-12 14:49   ` Vladimir Murzin
@ 2016-09-22 10:01     ` Marc Zyngier
  -1 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22 10:01 UTC (permalink / raw)
  To: Vladimir Murzin, kvmarm; +Cc: andre.przywara, linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> Well, this patch is looking ahead of time, but we'll get following
> compiler warnings as soon as we introduce vgic-v3 to 32-bit world
> 
>   CC      arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.o
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_mmio_read_v3r_typer':
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:184:35: warning: left shift count >= width of type [-Wshift-count-overflow]
>   value = (mpidr & GENMASK(23, 0)) << 32;
>                                    ^
> In file included from ./include/linux/kernel.h:10:0,
>                  from ./include/asm-generic/bug.h:13,
>                  from ./arch/arm/include/asm/bug.h:59,
>                  from ./include/linux/bug.h:4,
>                  from ./include/linux/io.h:23,
>                  from ./arch/arm/include/asm/arch_gicv3.h:23,
>                  from ./include/linux/irqchip/arm-gic-v3.h:411,
>                  from arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:14:
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_v3_dispatch_sgi':
> ./include/linux/bitops.h:6:24: warning: left shift count >= width of type [-Wshift-count-overflow]
>  #define BIT(nr)   (1UL << (nr))
>                         ^
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:614:20: note: in expansion of macro 'BIT'
>   broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
>                     ^
> Let's fix them now.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  virt/kvm/arm/vgic/vgic-mmio-v3.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

* [PATCH v4 05/10] KVM: arm: vgic: Fix compiler warnings when built for 32-bit
@ 2016-09-22 10:01     ` Marc Zyngier
  0 siblings, 0 replies; 80+ messages in thread
From: Marc Zyngier @ 2016-09-22 10:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/16 15:49, Vladimir Murzin wrote:
> Well, this patch is looking ahead of time, but we'll get following
> compiler warnings as soon as we introduce vgic-v3 to 32-bit world
> 
>   CC      arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.o
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_mmio_read_v3r_typer':
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:184:35: warning: left shift count >= width of type [-Wshift-count-overflow]
>   value = (mpidr & GENMASK(23, 0)) << 32;
>                                    ^
> In file included from ./include/linux/kernel.h:10:0,
>                  from ./include/asm-generic/bug.h:13,
>                  from ./arch/arm/include/asm/bug.h:59,
>                  from ./include/linux/bug.h:4,
>                  from ./include/linux/io.h:23,
>                  from ./arch/arm/include/asm/arch_gicv3.h:23,
>                  from ./include/linux/irqchip/arm-gic-v3.h:411,
>                  from arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:14:
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c: In function 'vgic_v3_dispatch_sgi':
> ./include/linux/bitops.h:6:24: warning: left shift count >= width of type [-Wshift-count-overflow]
>  #define BIT(nr)   (1UL << (nr))
>                         ^
> arch/arm/kvm/../../../virt/kvm/arm/vgic/vgic-mmio-v3.c:614:20: note: in expansion of macro 'BIT'
>   broadcast = reg & BIT(ICC_SGI1R_IRQ_ROUTING_MODE_BIT);
>                     ^
> Let's fix them now.
> 
> Signed-off-by: Vladimir Murzin <vladimir.murzin@arm.com>
> ---
>  virt/kvm/arm/vgic/vgic-mmio-v3.c |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)

Acked-by: Marc Zyngier <marc.zyngier@arm.com>

	M.
-- 
Jazz is not dead. It just smells funny...

^ permalink raw reply	[flat|nested] 80+ messages in thread

end of thread, other threads:[~2016-09-22 10:01 UTC | newest]

Thread overview: 80+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-12 14:49 [PATCH v4 00/10] ARM: KVM: Support for vgic-v3 Vladimir Murzin
2016-09-12 14:49 ` Vladimir Murzin
2016-09-12 14:49 ` [PATCH v4 01/10] arm64: KVM: Use static keys for selecting the GIC backend Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:20   ` Christoffer Dall
2016-09-13  8:20     ` Christoffer Dall
2016-09-13  9:11     ` Marc Zyngier
2016-09-13  9:11       ` Marc Zyngier
2016-09-13  9:22       ` Christoffer Dall
2016-09-13  9:22         ` Christoffer Dall
2016-09-14 15:20         ` Vladimir Murzin
2016-09-14 15:20           ` Vladimir Murzin
2016-09-14 15:47           ` Marc Zyngier
2016-09-14 15:47             ` Marc Zyngier
2016-09-15  9:03           ` Christoffer Dall
2016-09-15  9:03             ` Christoffer Dall
2016-09-22 10:01   ` Marc Zyngier
2016-09-22 10:01     ` Marc Zyngier
2016-09-12 14:49 ` [PATCH v4 02/10] arm64: KVM: Move GIC accessors to arch_gicv3.h Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-12 14:49 ` [PATCH v4 03/10] arm64: KVM: Move vgic-v3 save/restore to virt/kvm/arm/hyp Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:51   ` Christoffer Dall
2016-09-13  8:51     ` Christoffer Dall
2016-09-12 14:49 ` [PATCH v4 04/10] KVM: arm64: vgic-its: Introduce config option to guard ITS specific code Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:51   ` Christoffer Dall
2016-09-13  8:51     ` Christoffer Dall
2016-09-12 14:49 ` [PATCH v4 05/10] KVM: arm: vgic: Fix compiler warnings when built for 32-bit Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:51   ` Christoffer Dall
2016-09-13  8:51     ` Christoffer Dall
2016-09-22 10:01   ` Marc Zyngier
2016-09-22 10:01     ` Marc Zyngier
2016-09-12 14:49 ` [PATCH v4 06/10] KVM: arm: vgic: Support 64-bit data manipulation on 32-bit host systems Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:51   ` Christoffer Dall
2016-09-13  8:51     ` Christoffer Dall
2016-09-22 10:00   ` Marc Zyngier
2016-09-22 10:00     ` Marc Zyngier
2016-09-12 14:49 ` [PATCH v4 07/10] ARM: Introduce MPIDR_LEVEL_SHIFT macro Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:38   ` Christoffer Dall
2016-09-13  8:38     ` Christoffer Dall
2016-09-13  9:04     ` Vladimir Murzin
2016-09-13  9:04       ` Vladimir Murzin
2016-09-13 10:12       ` Marc Zyngier
2016-09-13 10:12         ` Marc Zyngier
2016-09-13 10:32         ` Vladimir Murzin
2016-09-13 10:32           ` Vladimir Murzin
2016-09-13 10:44           ` Marc Zyngier
2016-09-13 10:44             ` Marc Zyngier
2016-09-14 15:21             ` Vladimir Murzin
2016-09-14 15:21               ` Vladimir Murzin
2016-09-14 15:50               ` Marc Zyngier
2016-09-14 15:50                 ` Marc Zyngier
2016-09-22  9:59   ` Marc Zyngier
2016-09-22  9:59     ` Marc Zyngier
2016-09-12 14:49 ` [PATCH v4 08/10] ARM: Move system register accessors to asm/cp15.h Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:52   ` Christoffer Dall
2016-09-13  8:52     ` Christoffer Dall
2016-09-22  9:59   ` Marc Zyngier
2016-09-22  9:59     ` Marc Zyngier
2016-09-12 14:49 ` [PATCH v4 09/10] ARM: gic-v3: Introduce 32-to-64-bit mappings for GICv3 cpu registers Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:52   ` Christoffer Dall
2016-09-13  8:52     ` Christoffer Dall
2016-09-22  9:57   ` Marc Zyngier
2016-09-22  9:57     ` Marc Zyngier
2016-09-12 14:49 ` [PATCH v4 10/10] ARM: KVM: Support vgic-v3 Vladimir Murzin
2016-09-12 14:49   ` Vladimir Murzin
2016-09-13  8:52   ` Christoffer Dall
2016-09-13  8:52     ` Christoffer Dall
2016-09-22  9:58   ` Marc Zyngier
2016-09-22  9:58     ` Marc Zyngier
2016-09-15  9:13 ` [PATCH v4 00/10] ARM: KVM: Support for vgic-v3 Christoffer Dall
2016-09-15  9:13   ` Christoffer Dall
2016-09-15 10:33   ` Vladimir Murzin
2016-09-15 10:33     ` Vladimir Murzin

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.