All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-21 19:20 ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
could do with some TLC (it cannot perform a soft-restart at HYP, and
has holes in the hyp-stub support in a number of places). In general,
it would be desirable for the 32bit behaviour to align on 64bit, if
only to ease maintenance.

This series implements the following:
- Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
- Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
  __hyp_reset_vectors
- Implement add the stub entry points in the KVM init code, which
  didn't implement any so far
- Convert the HYP code to use the init code stubs directly
- Some general cleanup as a result of these changes (which includes
  killing HVC_GET_VECTORS)
- Add some API documentation that covers the above

Patches 12 to 14 would be better squashed into 10 and 11, but I've
kept them separate so that I can take the blame for everything I've
broken.

I've tested this on arm (Cubietruck, Jetson TK1) and arm64 (Seattle),
both as host and guest. Keerthy has been kind enough to test the 32bit
code on DRA7-EVM, AM57XX-EVM and KEYSTONE-K2E-EVM.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-December/473472.html

* From v3:
  - Reworked the way we save/restore lr on arm64, making it EL2's job
  in a consistent way (these are the three initial patches)
  - Collected RBs, TBs and Acks from James, Keerthy and Russell
  - Rebased on 4.11-rc3

* From v2:
  - Kill HVC_GET_VECTORS and the corresponding __hyp_get_vectors

* From v1:
  - Fixed some glaring bugs (reported by Ard and James)
  - Tidy up stub vector export on 32bit (Ard)
  - Nicer VA/PA conversion on 32bit (Ard)
  - Updated cpu_v7_reset documentation
  - Cleaned up HYP reset on PM events
  - Minor stub documentation update

Marc Zyngier (26):
  arm64: hyp-stub: Stop pointlessly clobbering lr
  arm64: KVM: Move lr save/restore to do_el2_call
  arm64: hyp-stub: Don't save lr in the EL1 code
  arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
  arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init
    code
  arm64: KVM: Implement HVC_GET_VECTORS in the init code
  arm64: KVM: Allow the main HYP code to use the init hyp stub
    implementation
  arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
  arm64: KVM: Implement HVC_SOFT_RESTART in the init code
  ARM: KVM: Convert KVM to use HVC_GET_VECTORS
  ARM: Update cpu_v7_reset documentation
  ARM: hyp-stub: Use r1 for the soft-restart address
  ARM: Expose the VA/IDMAP offset
  ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
  ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
  ARM: KVM: Implement HVC_GET_VECTORS in the init code
  ARM: KVM: Allow the main HYP code to use the init hyp stub
    implementation
  ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
  ARM: KVM: Implement HVC_SOFT_RESTART in the init code
  arm/arm64: KVM: Use __hyp_reset_vectors() directly
  arm/arm64: KVM: Remove kvm_get_idmap_start
  arm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode
  ARM: decompressor: Remove __hyp_get_vectors usage
  ARM: hyp-stub/KVM: Kill __hyp_get_vectors
  arm64: hyp-stub/KVM: Kill __hyp_get_vectors
  arm/arm64: Add hyp-stub API documentation

Russell King (2):
  ARM: hyp-stub: improve ABI
  ARM: soft-reboot into same mode that we entered the kernel

 Documentation/virtual/kvm/arm/hyp-abi.txt | 45 ++++++++++++++++++++++++++++
 arch/arm/boot/compressed/head.S           |  5 +++-
 arch/arm/include/asm/kvm_asm.h            |  2 --
 arch/arm/include/asm/kvm_host.h           |  6 ----
 arch/arm/include/asm/kvm_mmu.h            |  1 -
 arch/arm/include/asm/proc-fns.h           |  4 +--
 arch/arm/include/asm/virt.h               | 12 +++++++-
 arch/arm/kernel/hyp-stub.S                | 39 +++++++++++++++++++-----
 arch/arm/kernel/reboot.c                  |  7 +++--
 arch/arm/kvm/arm.c                        | 25 ++++++----------
 arch/arm/kvm/hyp/hyp-entry.S              | 29 ++++++++++++++----
 arch/arm/kvm/init.S                       | 49 ++++++++++++++++++++++++++-----
 arch/arm/kvm/interrupts.S                 |  4 ---
 arch/arm/kvm/mmu.c                        |  5 ----
 arch/arm/mm/mmu.c                         |  5 ++++
 arch/arm/mm/proc-v7.S                     | 15 ++++++----
 arch/arm64/include/asm/kvm_asm.h          |  1 -
 arch/arm64/include/asm/kvm_host.h         |  7 -----
 arch/arm64/include/asm/kvm_mmu.h          |  1 -
 arch/arm64/include/asm/virt.h             | 17 +++++++----
 arch/arm64/kernel/hyp-stub.S              | 34 +++++++--------------
 arch/arm64/kvm/hyp-init.S                 | 45 +++++++++++++++++++++-------
 arch/arm64/kvm/hyp.S                      |  2 +-
 arch/arm64/kvm/hyp/hyp-entry.S            | 43 +++++++++++++--------------
 24 files changed, 266 insertions(+), 137 deletions(-)
 create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt

-- 
2.11.0

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-21 19:20 ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
could do with some TLC (it cannot perform a soft-restart at HYP, and
has holes in the hyp-stub support in a number of places). In general,
it would be desirable for the 32bit behaviour to align on 64bit, if
only to ease maintenance.

This series implements the following:
- Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
- Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
  __hyp_reset_vectors
- Implement add the stub entry points in the KVM init code, which
  didn't implement any so far
- Convert the HYP code to use the init code stubs directly
- Some general cleanup as a result of these changes (which includes
  killing HVC_GET_VECTORS)
- Add some API documentation that covers the above

Patches 12 to 14 would be better squashed into 10 and 11, but I've
kept them separate so that I can take the blame for everything I've
broken.

I've tested this on arm (Cubietruck, Jetson TK1) and arm64 (Seattle),
both as host and guest. Keerthy has been kind enough to test the 32bit
code on DRA7-EVM, AM57XX-EVM and KEYSTONE-K2E-EVM.

[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-December/473472.html

* From v3:
  - Reworked the way we save/restore lr on arm64, making it EL2's job
  in a consistent way (these are the three initial patches)
  - Collected RBs, TBs and Acks from James, Keerthy and Russell
  - Rebased on 4.11-rc3

* From v2:
  - Kill HVC_GET_VECTORS and the corresponding __hyp_get_vectors

* From v1:
  - Fixed some glaring bugs (reported by Ard and James)
  - Tidy up stub vector export on 32bit (Ard)
  - Nicer VA/PA conversion on 32bit (Ard)
  - Updated cpu_v7_reset documentation
  - Cleaned up HYP reset on PM events
  - Minor stub documentation update

Marc Zyngier (26):
  arm64: hyp-stub: Stop pointlessly clobbering lr
  arm64: KVM: Move lr save/restore to do_el2_call
  arm64: hyp-stub: Don't save lr in the EL1 code
  arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
  arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init
    code
  arm64: KVM: Implement HVC_GET_VECTORS in the init code
  arm64: KVM: Allow the main HYP code to use the init hyp stub
    implementation
  arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
  arm64: KVM: Implement HVC_SOFT_RESTART in the init code
  ARM: KVM: Convert KVM to use HVC_GET_VECTORS
  ARM: Update cpu_v7_reset documentation
  ARM: hyp-stub: Use r1 for the soft-restart address
  ARM: Expose the VA/IDMAP offset
  ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
  ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
  ARM: KVM: Implement HVC_GET_VECTORS in the init code
  ARM: KVM: Allow the main HYP code to use the init hyp stub
    implementation
  ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
  ARM: KVM: Implement HVC_SOFT_RESTART in the init code
  arm/arm64: KVM: Use __hyp_reset_vectors() directly
  arm/arm64: KVM: Remove kvm_get_idmap_start
  arm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode
  ARM: decompressor: Remove __hyp_get_vectors usage
  ARM: hyp-stub/KVM: Kill __hyp_get_vectors
  arm64: hyp-stub/KVM: Kill __hyp_get_vectors
  arm/arm64: Add hyp-stub API documentation

Russell King (2):
  ARM: hyp-stub: improve ABI
  ARM: soft-reboot into same mode that we entered the kernel

 Documentation/virtual/kvm/arm/hyp-abi.txt | 45 ++++++++++++++++++++++++++++
 arch/arm/boot/compressed/head.S           |  5 +++-
 arch/arm/include/asm/kvm_asm.h            |  2 --
 arch/arm/include/asm/kvm_host.h           |  6 ----
 arch/arm/include/asm/kvm_mmu.h            |  1 -
 arch/arm/include/asm/proc-fns.h           |  4 +--
 arch/arm/include/asm/virt.h               | 12 +++++++-
 arch/arm/kernel/hyp-stub.S                | 39 +++++++++++++++++++-----
 arch/arm/kernel/reboot.c                  |  7 +++--
 arch/arm/kvm/arm.c                        | 25 ++++++----------
 arch/arm/kvm/hyp/hyp-entry.S              | 29 ++++++++++++++----
 arch/arm/kvm/init.S                       | 49 ++++++++++++++++++++++++++-----
 arch/arm/kvm/interrupts.S                 |  4 ---
 arch/arm/kvm/mmu.c                        |  5 ----
 arch/arm/mm/mmu.c                         |  5 ++++
 arch/arm/mm/proc-v7.S                     | 15 ++++++----
 arch/arm64/include/asm/kvm_asm.h          |  1 -
 arch/arm64/include/asm/kvm_host.h         |  7 -----
 arch/arm64/include/asm/kvm_mmu.h          |  1 -
 arch/arm64/include/asm/virt.h             | 17 +++++++----
 arch/arm64/kernel/hyp-stub.S              | 34 +++++++--------------
 arch/arm64/kvm/hyp-init.S                 | 45 +++++++++++++++++++++-------
 arch/arm64/kvm/hyp.S                      |  2 +-
 arch/arm64/kvm/hyp/hyp-entry.S            | 43 +++++++++++++--------------
 24 files changed, 266 insertions(+), 137 deletions(-)
 create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt

-- 
2.11.0

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

* [PATCH v4 01/28] arm64: hyp-stub: Stop pointlessly clobbering lr
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

When entering the kernel hyp stub, we check whether or not we've
made it here through an HVC instruction, clobbering lr (aka x30)
in the process.

This is completely pointless, as HVC is the only way to get here
(all traps to EL2 are disabled, no interrupt override is applied).

So let's remove this bit of code whose only point is to corrupt
a valuable register.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/hyp-stub.S | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index d3b5f75e652e..e4215ad06930 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -55,12 +55,6 @@ ENDPROC(__hyp_stub_vectors)
 	.align 11
 
 el1_sync:
-	mrs	x30, esr_el2
-	lsr	x30, x30, #ESR_ELx_EC_SHIFT
-
-	cmp	x30, #ESR_ELx_EC_HVC64
-	b.ne	9f				// Not an HVC trap
-
 	cmp	x0, #HVC_GET_VECTORS
 	b.ne	1f
 	mrs	x0, vbar_el2
-- 
2.11.0

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

* [PATCH v4 01/28] arm64: hyp-stub: Stop pointlessly clobbering lr
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

When entering the kernel hyp stub, we check whether or not we've
made it here through an HVC instruction, clobbering lr (aka x30)
in the process.

This is completely pointless, as HVC is the only way to get here
(all traps to EL2 are disabled, no interrupt override is applied).

So let's remove this bit of code whose only point is to corrupt
a valuable register.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/hyp-stub.S | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index d3b5f75e652e..e4215ad06930 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -55,12 +55,6 @@ ENDPROC(__hyp_stub_vectors)
 	.align 11
 
 el1_sync:
-	mrs	x30, esr_el2
-	lsr	x30, x30, #ESR_ELx_EC_SHIFT
-
-	cmp	x30, #ESR_ELx_EC_HVC64
-	b.ne	9f				// Not an HVC trap
-
 	cmp	x0, #HVC_GET_VECTORS
 	b.ne	1f
 	mrs	x0, vbar_el2
-- 
2.11.0

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

* [PATCH v4 02/28] arm64: KVM: Move lr save/restore to do_el2_call
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

At the moment, we only save/restore lr if on VHE, as we rely only
the EL1 code to have preserved it in the non-VHE case.

As we're about to get rid of the latter, let's move the save/restore
code to the do_el2_call macro, unifying both code paths.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp/hyp-entry.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index 5e9052f087f2..d8ef788646c6 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -32,17 +32,17 @@
 	 * Shuffle the parameters before calling the function
 	 * pointed to in x0. Assumes parameters in x[1,2,3].
 	 */
+	str	lr, [sp, #-16]!
 	mov	lr, x0
 	mov	x0, x1
 	mov	x1, x2
 	mov	x2, x3
 	blr	lr
+	ldr	lr, [sp], #16
 .endm
 
 ENTRY(__vhe_hyp_call)
-	str	lr, [sp, #-16]!
 	do_el2_call
-	ldr	lr, [sp], #16
 	/*
 	 * We used to rely on having an exception return to get
 	 * an implicit isb. In the E2H case, we don't have it anymore.
-- 
2.11.0

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

* [PATCH v4 02/28] arm64: KVM: Move lr save/restore to do_el2_call
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

At the moment, we only save/restore lr if on VHE, as we rely only
the EL1 code to have preserved it in the non-VHE case.

As we're about to get rid of the latter, let's move the save/restore
code to the do_el2_call macro, unifying both code paths.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp/hyp-entry.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index 5e9052f087f2..d8ef788646c6 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -32,17 +32,17 @@
 	 * Shuffle the parameters before calling the function
 	 * pointed to in x0. Assumes parameters in x[1,2,3].
 	 */
+	str	lr, [sp, #-16]!
 	mov	lr, x0
 	mov	x0, x1
 	mov	x1, x2
 	mov	x2, x3
 	blr	lr
+	ldr	lr, [sp], #16
 .endm
 
 ENTRY(__vhe_hyp_call)
-	str	lr, [sp, #-16]!
 	do_el2_call
-	ldr	lr, [sp], #16
 	/*
 	 * We used to rely on having an exception return to get
 	 * an implicit isb. In the E2H case, we don't have it anymore.
-- 
2.11.0

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

* [PATCH v4 03/28] arm64: hyp-stub: Don't save lr in the EL1 code
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

The EL2 code is not corrupting lr anymore, so don't bother preserving
it in the EL1 trampoline code.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/hyp-stub.S | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index e4215ad06930..193dfb25ce2f 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -116,18 +116,14 @@ ENDPROC(\label)
  */
 
 ENTRY(__hyp_get_vectors)
-	str	lr, [sp, #-16]!
 	mov	x0, #HVC_GET_VECTORS
 	hvc	#0
-	ldr	lr, [sp], #16
 	ret
 ENDPROC(__hyp_get_vectors)
 
 ENTRY(__hyp_set_vectors)
-	str	lr, [sp, #-16]!
 	mov	x1, x0
 	mov	x0, #HVC_SET_VECTORS
 	hvc	#0
-	ldr	lr, [sp], #16
 	ret
 ENDPROC(__hyp_set_vectors)
-- 
2.11.0

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

* [PATCH v4 03/28] arm64: hyp-stub: Don't save lr in the EL1 code
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

The EL2 code is not corrupting lr anymore, so don't bother preserving
it in the EL1 trampoline code.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kernel/hyp-stub.S | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index e4215ad06930..193dfb25ce2f 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -116,18 +116,14 @@ ENDPROC(\label)
  */
 
 ENTRY(__hyp_get_vectors)
-	str	lr, [sp, #-16]!
 	mov	x0, #HVC_GET_VECTORS
 	hvc	#0
-	ldr	lr, [sp], #16
 	ret
 ENDPROC(__hyp_get_vectors)
 
 ENTRY(__hyp_set_vectors)
-	str	lr, [sp, #-16]!
 	mov	x1, x0
 	mov	x0, #HVC_SET_VECTORS
 	hvc	#0
-	ldr	lr, [sp], #16
 	ret
 ENDPROC(__hyp_set_vectors)
-- 
2.11.0

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

* [PATCH v4 04/28] arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Let's define a new stub hypercall that resets the HYP configuration
to its default: hyp-stub vectors, and MMU disabled.

Of course, for the hyp-stub itself, this is a trivial no-op.
Hypervisors will have a bit more work to do.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/virt.h |  9 +++++++++
 arch/arm64/kernel/hyp-stub.S  | 11 ++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 439f6b5d31f6..f24f1eb72dc0 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -39,6 +39,14 @@
  */
 #define HVC_SOFT_RESTART 2
 
+/*
+ * HVC_RESET_VECTORS - Restore the vectors to the original HYP stubs
+ */
+#define HVC_RESET_VECTORS 3
+
+/* Max number of HYP stub hypercalls */
+#define HVC_STUB_HCALL_NR 4
+
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
 
@@ -62,6 +70,7 @@ extern u32 __boot_cpu_mode[2];
 
 void __hyp_set_vectors(phys_addr_t phys_vector_base);
 phys_addr_t __hyp_get_vectors(void);
+void __hyp_reset_vectors(void);
 
 /* Reports the availability of HYP mode */
 static inline bool is_hyp_mode_available(void)
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 193dfb25ce2f..dd0a7522fbe1 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -73,8 +73,11 @@ el1_sync:
 	mov	x1, x3
 	br	x4				// no return
 
+3:	cmp	x0, #HVC_RESET_VECTORS
+	beq	9f				// Nothing to reset!
+
 	/* Someone called kvm_call_hyp() against the hyp-stub... */
-3:	mov	x0, #ARM_EXCEPTION_HYP_GONE
+	mov	x0, #ARM_EXCEPTION_HYP_GONE
 
 9:	eret
 ENDPROC(el1_sync)
@@ -127,3 +130,9 @@ ENTRY(__hyp_set_vectors)
 	hvc	#0
 	ret
 ENDPROC(__hyp_set_vectors)
+
+ENTRY(__hyp_reset_vectors)
+	mov	x0, #HVC_RESET_VECTORS
+	hvc	#0
+	ret
+ENDPROC(__hyp_reset_vectors)
-- 
2.11.0

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

* [PATCH v4 04/28] arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Let's define a new stub hypercall that resets the HYP configuration
to its default: hyp-stub vectors, and MMU disabled.

Of course, for the hyp-stub itself, this is a trivial no-op.
Hypervisors will have a bit more work to do.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/virt.h |  9 +++++++++
 arch/arm64/kernel/hyp-stub.S  | 11 ++++++++++-
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 439f6b5d31f6..f24f1eb72dc0 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -39,6 +39,14 @@
  */
 #define HVC_SOFT_RESTART 2
 
+/*
+ * HVC_RESET_VECTORS - Restore the vectors to the original HYP stubs
+ */
+#define HVC_RESET_VECTORS 3
+
+/* Max number of HYP stub hypercalls */
+#define HVC_STUB_HCALL_NR 4
+
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
 
@@ -62,6 +70,7 @@ extern u32 __boot_cpu_mode[2];
 
 void __hyp_set_vectors(phys_addr_t phys_vector_base);
 phys_addr_t __hyp_get_vectors(void);
+void __hyp_reset_vectors(void);
 
 /* Reports the availability of HYP mode */
 static inline bool is_hyp_mode_available(void)
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 193dfb25ce2f..dd0a7522fbe1 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -73,8 +73,11 @@ el1_sync:
 	mov	x1, x3
 	br	x4				// no return
 
+3:	cmp	x0, #HVC_RESET_VECTORS
+	beq	9f				// Nothing to reset!
+
 	/* Someone called kvm_call_hyp() against the hyp-stub... */
-3:	mov	x0, #ARM_EXCEPTION_HYP_GONE
+	mov	x0, #ARM_EXCEPTION_HYP_GONE
 
 9:	eret
 ENDPROC(el1_sync)
@@ -127,3 +130,9 @@ ENTRY(__hyp_set_vectors)
 	hvc	#0
 	ret
 ENDPROC(__hyp_set_vectors)
+
+ENTRY(__hyp_reset_vectors)
+	mov	x0, #HVC_RESET_VECTORS
+	hvc	#0
+	ret
+ENDPROC(__hyp_reset_vectors)
-- 
2.11.0

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

* [PATCH v4 05/28] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

In order to restore HYP mode to its original condition, KVM currently
implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
defined API, it becomes necessary to implement HVC_RESET_VECTORS.

This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
code, which so far lacked any form of hypercall support.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp-init.S | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 6b29d3d9e1f2..6cf98ccd10f2 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -22,6 +22,7 @@
 #include <asm/kvm_mmu.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/sysreg.h>
+#include <asm/virt.h>
 
 	.text
 	.pushsection	.hyp.idmap.text, "ax"
@@ -58,6 +59,9 @@ __invalid:
 	 * x2: HYP vectors
 	 */
 __do_hyp_init:
+	/* Check for a stub HVC call */
+	cmp	x0, #HVC_STUB_HCALL_NR
+	b.lo	__kvm_handle_stub_hvc
 
 	msr	ttbr0_el2, x0
 
@@ -119,6 +123,9 @@ __do_hyp_init:
 	eret
 ENDPROC(__kvm_hyp_init)
 
+ENTRY(__kvm_handle_stub_hvc)
+	cmp	x0, #HVC_RESET_VECTORS
+	b.ne	1f
 	/*
 	 * Reset kvm back to the hyp stub.
 	 */
@@ -133,9 +140,14 @@ ENTRY(__kvm_hyp_reset)
 	/* Install stub vectors */
 	adr_l	x0, __hyp_stub_vectors
 	msr	vbar_el2, x0
+	b	exit
 
+1:	mov	x0, #-1
+
+exit:
 	eret
 ENDPROC(__kvm_hyp_reset)
+ENDPROC(__kvm_handle_stub_hvc)
 
 	.ltorg
 
-- 
2.11.0

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

* [PATCH v4 05/28] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

In order to restore HYP mode to its original condition, KVM currently
implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
defined API, it becomes necessary to implement HVC_RESET_VECTORS.

This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
code, which so far lacked any form of hypercall support.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp-init.S | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 6b29d3d9e1f2..6cf98ccd10f2 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -22,6 +22,7 @@
 #include <asm/kvm_mmu.h>
 #include <asm/pgtable-hwdef.h>
 #include <asm/sysreg.h>
+#include <asm/virt.h>
 
 	.text
 	.pushsection	.hyp.idmap.text, "ax"
@@ -58,6 +59,9 @@ __invalid:
 	 * x2: HYP vectors
 	 */
 __do_hyp_init:
+	/* Check for a stub HVC call */
+	cmp	x0, #HVC_STUB_HCALL_NR
+	b.lo	__kvm_handle_stub_hvc
 
 	msr	ttbr0_el2, x0
 
@@ -119,6 +123,9 @@ __do_hyp_init:
 	eret
 ENDPROC(__kvm_hyp_init)
 
+ENTRY(__kvm_handle_stub_hvc)
+	cmp	x0, #HVC_RESET_VECTORS
+	b.ne	1f
 	/*
 	 * Reset kvm back to the hyp stub.
 	 */
@@ -133,9 +140,14 @@ ENTRY(__kvm_hyp_reset)
 	/* Install stub vectors */
 	adr_l	x0, __hyp_stub_vectors
 	msr	vbar_el2, x0
+	b	exit
 
+1:	mov	x0, #-1
+
+exit:
 	eret
 ENDPROC(__kvm_hyp_reset)
+ENDPROC(__kvm_handle_stub_hvc)
 
 	.ltorg
 
-- 
2.11.0

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

* [PATCH v4 06/28] arm64: KVM: Implement HVC_GET_VECTORS in the init code
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Now that we have an infrastructure to handle hypercalls in the KVM
init code, let's implement HVC_GET_VECTORS there.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp-init.S | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 6cf98ccd10f2..1d89995378e9 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -124,7 +124,12 @@ __do_hyp_init:
 ENDPROC(__kvm_hyp_init)
 
 ENTRY(__kvm_handle_stub_hvc)
-	cmp	x0, #HVC_RESET_VECTORS
+	cmp	x0, #HVC_GET_VECTORS
+	b.ne	1f
+	mrs	x0, vbar_el2
+	b	exit
+
+1:	cmp	x0, #HVC_RESET_VECTORS
 	b.ne	1f
 	/*
 	 * Reset kvm back to the hyp stub.
-- 
2.11.0

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

* [PATCH v4 06/28] arm64: KVM: Implement HVC_GET_VECTORS in the init code
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we have an infrastructure to handle hypercalls in the KVM
init code, let's implement HVC_GET_VECTORS there.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp-init.S | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 6cf98ccd10f2..1d89995378e9 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -124,7 +124,12 @@ __do_hyp_init:
 ENDPROC(__kvm_hyp_init)
 
 ENTRY(__kvm_handle_stub_hvc)
-	cmp	x0, #HVC_RESET_VECTORS
+	cmp	x0, #HVC_GET_VECTORS
+	b.ne	1f
+	mrs	x0, vbar_el2
+	b	exit
+
+1:	cmp	x0, #HVC_RESET_VECTORS
 	b.ne	1f
 	/*
 	 * Reset kvm back to the hyp stub.
-- 
2.11.0

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

* [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

We now have a full hyp-stub implementation in the KVM init code,
but the main KVM code only supports HVC_GET_VECTORS, which is not
enough.

Instead of reinventing the wheel, let's reuse the init implementation
by branching to the idmap page when called with a hyp-stub hypercall.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index d8ef788646c6..4f34c5996f86 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -87,10 +87,24 @@ alternative_endif
 	/* Here, we're pretty sure the host called HVC. */
 	ldp	x0, x1, [sp], #16
 
-	cmp	x0, #HVC_GET_VECTORS
-	b.ne	1f
-	mrs	x0, vbar_el2
-	b	2f
+	/* Check for a stub HVC call */
+	cmp	x0, #HVC_STUB_HCALL_NR
+	b.hs	1f
+
+	/*
+	 * Compute the idmap address of __kvm_handle_stub_hvc and
+	 * jump there. Since we use kimage_voffset, do not use the
+	 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead
+	 * (by loading it from the constant pool).
+	 *
+	 * Preserve x0-x4, which may contain stub parameters.
+	 */
+	ldr	x5, =__kvm_handle_stub_hvc
+	ldr_l	x6, kimage_voffset
+
+	/* x5 = __pa(x5) */
+	sub	x5, x5, x6
+	br	x5
 
 1:
 	/*
@@ -99,7 +113,7 @@ alternative_endif
 	kern_hyp_va	x0
 	do_el2_call
 
-2:	eret
+	eret
 
 el1_trap:
 	/*
-- 
2.11.0

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

* [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

We now have a full hyp-stub implementation in the KVM init code,
but the main KVM code only supports HVC_GET_VECTORS, which is not
enough.

Instead of reinventing the wheel, let's reuse the init implementation
by branching to the idmap page when called with a hyp-stub hypercall.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index d8ef788646c6..4f34c5996f86 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -87,10 +87,24 @@ alternative_endif
 	/* Here, we're pretty sure the host called HVC. */
 	ldp	x0, x1, [sp], #16
 
-	cmp	x0, #HVC_GET_VECTORS
-	b.ne	1f
-	mrs	x0, vbar_el2
-	b	2f
+	/* Check for a stub HVC call */
+	cmp	x0, #HVC_STUB_HCALL_NR
+	b.hs	1f
+
+	/*
+	 * Compute the idmap address of __kvm_handle_stub_hvc and
+	 * jump there. Since we use kimage_voffset, do not use the
+	 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead
+	 * (by loading it from the constant pool).
+	 *
+	 * Preserve x0-x4, which may contain stub parameters.
+	 */
+	ldr	x5, =__kvm_handle_stub_hvc
+	ldr_l	x6, kimage_voffset
+
+	/* x5 = __pa(x5) */
+	sub	x5, x5, x6
+	br	x5
 
 1:
 	/*
@@ -99,7 +113,7 @@ alternative_endif
 	kern_hyp_va	x0
 	do_el2_call
 
-2:	eret
+	eret
 
 el1_trap:
 	/*
-- 
2.11.0

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

* [PATCH v4 08/28] arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

We are now able to use the hyp stub to reset HYP mode. Time to
kiss __kvm_hyp_reset goodbye, and use __hyp_reset_vectors.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/kvm_asm.h  |  1 -
 arch/arm64/include/asm/kvm_host.h |  3 +--
 arch/arm64/kvm/hyp-init.S         |  2 --
 arch/arm64/kvm/hyp/hyp-entry.S    | 15 ---------------
 4 files changed, 1 insertion(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index ec3553eb9349..3e242f6613b3 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -47,7 +47,6 @@ struct kvm_vcpu;
 
 extern char __kvm_hyp_init[];
 extern char __kvm_hyp_init_end[];
-extern char __kvm_hyp_reset[];
 
 extern char __kvm_hyp_vector[];
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e7705e7bb07b..0355dd109956 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -362,11 +362,10 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
 	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
 }
 
-void __kvm_hyp_teardown(void);
 static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
 					phys_addr_t phys_idmap_start)
 {
-	kvm_call_hyp(__kvm_hyp_teardown, phys_idmap_start);
+	__hyp_reset_vectors();
 }
 
 static inline void kvm_arch_hardware_unsetup(void) {}
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 1d89995378e9..b53e95efc1c5 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -134,7 +134,6 @@ ENTRY(__kvm_handle_stub_hvc)
 	/*
 	 * Reset kvm back to the hyp stub.
 	 */
-ENTRY(__kvm_hyp_reset)
 	/* We're now in idmap, disable MMU */
 	mrs	x0, sctlr_el2
 	ldr	x1, =SCTLR_ELx_FLAGS
@@ -151,7 +150,6 @@ ENTRY(__kvm_hyp_reset)
 
 exit:
 	eret
-ENDPROC(__kvm_hyp_reset)
 ENDPROC(__kvm_handle_stub_hvc)
 
 	.ltorg
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index 4f34c5996f86..5170ce1021da 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -53,21 +53,6 @@ ENTRY(__vhe_hyp_call)
 	ret
 ENDPROC(__vhe_hyp_call)
 
-/*
- * Compute the idmap address of __kvm_hyp_reset based on the idmap
- * start passed as a parameter, and jump there.
- *
- * x0: HYP phys_idmap_start
- */
-ENTRY(__kvm_hyp_teardown)
-	mov	x4, x0
-	adr_l	x3, __kvm_hyp_reset
-
-	/* insert __kvm_hyp_reset()s offset into phys_idmap_start */
-	bfi	x4, x3, #0, #PAGE_SHIFT
-	br	x4
-ENDPROC(__kvm_hyp_teardown)
-	
 el1_sync:				// Guest trapped into EL2
 	stp	x0, x1, [sp, #-16]!
 
-- 
2.11.0

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

* [PATCH v4 08/28] arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

We are now able to use the hyp stub to reset HYP mode. Time to
kiss __kvm_hyp_reset goodbye, and use __hyp_reset_vectors.

Reviewed-by: James Morse <james.morse@arm.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/kvm_asm.h  |  1 -
 arch/arm64/include/asm/kvm_host.h |  3 +--
 arch/arm64/kvm/hyp-init.S         |  2 --
 arch/arm64/kvm/hyp/hyp-entry.S    | 15 ---------------
 4 files changed, 1 insertion(+), 20 deletions(-)

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index ec3553eb9349..3e242f6613b3 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -47,7 +47,6 @@ struct kvm_vcpu;
 
 extern char __kvm_hyp_init[];
 extern char __kvm_hyp_init_end[];
-extern char __kvm_hyp_reset[];
 
 extern char __kvm_hyp_vector[];
 
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index e7705e7bb07b..0355dd109956 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -362,11 +362,10 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
 	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
 }
 
-void __kvm_hyp_teardown(void);
 static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
 					phys_addr_t phys_idmap_start)
 {
-	kvm_call_hyp(__kvm_hyp_teardown, phys_idmap_start);
+	__hyp_reset_vectors();
 }
 
 static inline void kvm_arch_hardware_unsetup(void) {}
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 1d89995378e9..b53e95efc1c5 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -134,7 +134,6 @@ ENTRY(__kvm_handle_stub_hvc)
 	/*
 	 * Reset kvm back to the hyp stub.
 	 */
-ENTRY(__kvm_hyp_reset)
 	/* We're now in idmap, disable MMU */
 	mrs	x0, sctlr_el2
 	ldr	x1, =SCTLR_ELx_FLAGS
@@ -151,7 +150,6 @@ ENTRY(__kvm_hyp_reset)
 
 exit:
 	eret
-ENDPROC(__kvm_hyp_reset)
 ENDPROC(__kvm_handle_stub_hvc)
 
 	.ltorg
diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
index 4f34c5996f86..5170ce1021da 100644
--- a/arch/arm64/kvm/hyp/hyp-entry.S
+++ b/arch/arm64/kvm/hyp/hyp-entry.S
@@ -53,21 +53,6 @@ ENTRY(__vhe_hyp_call)
 	ret
 ENDPROC(__vhe_hyp_call)
 
-/*
- * Compute the idmap address of __kvm_hyp_reset based on the idmap
- * start passed as a parameter, and jump there.
- *
- * x0: HYP phys_idmap_start
- */
-ENTRY(__kvm_hyp_teardown)
-	mov	x4, x0
-	adr_l	x3, __kvm_hyp_reset
-
-	/* insert __kvm_hyp_reset()s offset into phys_idmap_start */
-	bfi	x4, x3, #0, #PAGE_SHIFT
-	br	x4
-ENDPROC(__kvm_hyp_teardown)
-	
 el1_sync:				// Guest trapped into EL2
 	stp	x0, x1, [sp, #-16]!
 
-- 
2.11.0

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

* [PATCH v4 09/28] arm64: KVM: Implement HVC_SOFT_RESTART in the init code
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Another missing stub hypercall is HVC_SOFT_RESTART. It turns out
that it is pretty easy to implement in terms of HVC_RESET_VECTORS
(since it needs to turn the MMU off).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp-init.S | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index b53e95efc1c5..128d6e9732b9 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -129,21 +129,36 @@ ENTRY(__kvm_handle_stub_hvc)
 	mrs	x0, vbar_el2
 	b	exit
 
+1:	cmp	x0, #HVC_SOFT_RESTART
+	b.ne	1f
+
+	/* This is where we're about to jump, staying at EL2 */
+	msr	elr_el2, x1
+	mov	x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT | PSR_MODE_EL2h)
+	msr	spsr_el2, x0
+
+	/* Shuffle the arguments, and don't come back */
+	mov	x0, x2
+	mov	x1, x3
+	mov	x2, x4
+	b	reset
+
 1:	cmp	x0, #HVC_RESET_VECTORS
 	b.ne	1f
+reset:
 	/*
-	 * Reset kvm back to the hyp stub.
+	 * Reset kvm back to the hyp stub. Do not clobber x0-x4 in
+	 * case we coming via HVC_SOFT_RESTART.
 	 */
-	/* We're now in idmap, disable MMU */
-	mrs	x0, sctlr_el2
-	ldr	x1, =SCTLR_ELx_FLAGS
-	bic	x0, x0, x1		// Clear SCTL_M and etc
-	msr	sctlr_el2, x0
+	mrs	x5, sctlr_el2
+	ldr	x6, =SCTLR_ELx_FLAGS
+	bic	x5, x5, x6		// Clear SCTL_M and etc
+	msr	sctlr_el2, x5
 	isb
 
 	/* Install stub vectors */
-	adr_l	x0, __hyp_stub_vectors
-	msr	vbar_el2, x0
+	adr_l	x5, __hyp_stub_vectors
+	msr	vbar_el2, x5
 	b	exit
 
 1:	mov	x0, #-1
-- 
2.11.0

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

* [PATCH v4 09/28] arm64: KVM: Implement HVC_SOFT_RESTART in the init code
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Another missing stub hypercall is HVC_SOFT_RESTART. It turns out
that it is pretty easy to implement in terms of HVC_RESET_VECTORS
(since it needs to turn the MMU off).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/kvm/hyp-init.S | 31 +++++++++++++++++++++++--------
 1 file changed, 23 insertions(+), 8 deletions(-)

diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index b53e95efc1c5..128d6e9732b9 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -129,21 +129,36 @@ ENTRY(__kvm_handle_stub_hvc)
 	mrs	x0, vbar_el2
 	b	exit
 
+1:	cmp	x0, #HVC_SOFT_RESTART
+	b.ne	1f
+
+	/* This is where we're about to jump, staying at EL2 */
+	msr	elr_el2, x1
+	mov	x0, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT | PSR_D_BIT | PSR_MODE_EL2h)
+	msr	spsr_el2, x0
+
+	/* Shuffle the arguments, and don't come back */
+	mov	x0, x2
+	mov	x1, x3
+	mov	x2, x4
+	b	reset
+
 1:	cmp	x0, #HVC_RESET_VECTORS
 	b.ne	1f
+reset:
 	/*
-	 * Reset kvm back to the hyp stub.
+	 * Reset kvm back to the hyp stub. Do not clobber x0-x4 in
+	 * case we coming via HVC_SOFT_RESTART.
 	 */
-	/* We're now in idmap, disable MMU */
-	mrs	x0, sctlr_el2
-	ldr	x1, =SCTLR_ELx_FLAGS
-	bic	x0, x0, x1		// Clear SCTL_M and etc
-	msr	sctlr_el2, x0
+	mrs	x5, sctlr_el2
+	ldr	x6, =SCTLR_ELx_FLAGS
+	bic	x5, x5, x6		// Clear SCTL_M and etc
+	msr	sctlr_el2, x5
 	isb
 
 	/* Install stub vectors */
-	adr_l	x0, __hyp_stub_vectors
-	msr	vbar_el2, x0
+	adr_l	x5, __hyp_stub_vectors
+	msr	vbar_el2, x5
 	b	exit
 
 1:	mov	x0, #-1
-- 
2.11.0

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

* [PATCH v4 10/28] ARM: hyp-stub: improve ABI
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Russell King, Keerthy

From: Russell King <rmk+kernel@armlinux.org.uk>

Improve the hyp-stub ABI to allow it to do more than just get/set the
vectors.  We follow the example in ARM64, where r0 is used as an opcode
with the other registers as an argument.

Tested-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kernel/hyp-stub.S | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 15d073ae5da2..f3e9ba5fb642 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -22,6 +22,9 @@
 #include <asm/assembler.h>
 #include <asm/virt.h>
 
+#define HVC_GET_VECTORS 0
+#define HVC_SET_VECTORS 1
+
 #ifndef ZIMAGE
 /*
  * For the kernel proper, we need to find out the CPU boot mode long after
@@ -202,9 +205,19 @@ ARM_BE8(orr	r7, r7, #(1 << 25))     @ HSCTLR.EE
 ENDPROC(__hyp_stub_install_secondary)
 
 __hyp_stub_do_trap:
-	cmp	r0, #-1
-	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
-	mcrne	p15, 4, r0, c12, c0, 0	@ set HVBAR
+	teq	r0, #HVC_GET_VECTORS
+	bne	1f
+	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
+	b	__hyp_stub_exit
+
+1:	teq	r0, #HVC_SET_VECTORS
+	bne	1f
+	mcr	p15, 4, r1, c12, c0, 0	@ set HVBAR
+	b	__hyp_stub_exit
+
+1:	mov	r0, #-1
+
+__hyp_stub_exit:
 	__ERET
 ENDPROC(__hyp_stub_do_trap)
 
@@ -231,10 +244,14 @@ ENDPROC(__hyp_stub_do_trap)
  * initialisation entry point.
  */
 ENTRY(__hyp_get_vectors)
-	mov	r0, #-1
+	mov	r0, #HVC_GET_VECTORS
+	__HVC(0)
+	ret	lr
 ENDPROC(__hyp_get_vectors)
-	@ fall through
+
 ENTRY(__hyp_set_vectors)
+	mov	r1, r0
+	mov	r0, #HVC_SET_VECTORS
 	__HVC(0)
 	ret	lr
 ENDPROC(__hyp_set_vectors)
-- 
2.11.0

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

* [PATCH v4 10/28] ARM: hyp-stub: improve ABI
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Russell King <rmk+kernel@armlinux.org.uk>

Improve the hyp-stub ABI to allow it to do more than just get/set the
vectors.  We follow the example in ARM64, where r0 is used as an opcode
with the other registers as an argument.

Tested-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kernel/hyp-stub.S | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 15d073ae5da2..f3e9ba5fb642 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -22,6 +22,9 @@
 #include <asm/assembler.h>
 #include <asm/virt.h>
 
+#define HVC_GET_VECTORS 0
+#define HVC_SET_VECTORS 1
+
 #ifndef ZIMAGE
 /*
  * For the kernel proper, we need to find out the CPU boot mode long after
@@ -202,9 +205,19 @@ ARM_BE8(orr	r7, r7, #(1 << 25))     @ HSCTLR.EE
 ENDPROC(__hyp_stub_install_secondary)
 
 __hyp_stub_do_trap:
-	cmp	r0, #-1
-	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
-	mcrne	p15, 4, r0, c12, c0, 0	@ set HVBAR
+	teq	r0, #HVC_GET_VECTORS
+	bne	1f
+	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
+	b	__hyp_stub_exit
+
+1:	teq	r0, #HVC_SET_VECTORS
+	bne	1f
+	mcr	p15, 4, r1, c12, c0, 0	@ set HVBAR
+	b	__hyp_stub_exit
+
+1:	mov	r0, #-1
+
+__hyp_stub_exit:
 	__ERET
 ENDPROC(__hyp_stub_do_trap)
 
@@ -231,10 +244,14 @@ ENDPROC(__hyp_stub_do_trap)
  * initialisation entry point.
  */
 ENTRY(__hyp_get_vectors)
-	mov	r0, #-1
+	mov	r0, #HVC_GET_VECTORS
+	__HVC(0)
+	ret	lr
 ENDPROC(__hyp_get_vectors)
-	@ fall through
+
 ENTRY(__hyp_set_vectors)
+	mov	r1, r0
+	mov	r0, #HVC_SET_VECTORS
 	__HVC(0)
 	ret	lr
 ENDPROC(__hyp_set_vectors)
-- 
2.11.0

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

* [PATCH v4 11/28] ARM: soft-reboot into same mode that we entered the kernel
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Russell King, Keerthy

From: Russell King <rmk+kernel@armlinux.org.uk>

When we soft-reboot (eg, kexec) from one kernel into the next, we need
to ensure that we enter the new kernel in the same processor mode as
when we were entered, so that (eg) the new kernel can install its own
hypervisor - the old kernel's hypervisor will have been overwritten.

In order to do this, we need to pass a flag to cpu_reset() so it knows
what to do, and we need to modify the kernel's own hypervisor stub to
allow it to handle a soft-reboot.

As we are always guaranteed to install our own hypervisor if we're
entered in HYP32 mode, and KVM will have moved itself out of the way
on kexec/normal reboot, we can assume that our hypervisor is in place
when we want to kexec, so changing our hypervisor API should not be a
problem.

Tested-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/proc-fns.h |  4 ++--
 arch/arm/kernel/hyp-stub.S      | 13 +++++++++++++
 arch/arm/kernel/reboot.c        |  7 +++++--
 arch/arm/mm/proc-v7.S           | 12 ++++++++----
 4 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 8877ad5ffe10..f2e1af45bd6f 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -43,7 +43,7 @@ extern struct processor {
 	/*
 	 * Special stuff for a reset
 	 */
-	void (*reset)(unsigned long addr) __attribute__((noreturn));
+	void (*reset)(unsigned long addr, bool hvc) __attribute__((noreturn));
 	/*
 	 * Idle the processor
 	 */
@@ -88,7 +88,7 @@ extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
 #else
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
 #endif
-extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+extern void cpu_reset(unsigned long addr, bool hvc) __attribute__((noreturn));
 
 /* These three are private to arch/arm/kernel/suspend.c */
 extern void cpu_do_suspend(void *);
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index f3e9ba5fb642..82915231c6f8 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -24,6 +24,7 @@
 
 #define HVC_GET_VECTORS 0
 #define HVC_SET_VECTORS 1
+#define HVC_SOFT_RESTART 2
 
 #ifndef ZIMAGE
 /*
@@ -215,6 +216,10 @@ __hyp_stub_do_trap:
 	mcr	p15, 4, r1, c12, c0, 0	@ set HVBAR
 	b	__hyp_stub_exit
 
+1:	teq	r0, #HVC_SOFT_RESTART
+	bne	1f
+	bx	r3
+
 1:	mov	r0, #-1
 
 __hyp_stub_exit:
@@ -256,6 +261,14 @@ ENTRY(__hyp_set_vectors)
 	ret	lr
 ENDPROC(__hyp_set_vectors)
 
+ENTRY(__hyp_soft_restart)
+	mov	r3, r0
+	mov	r0, #HVC_SOFT_RESTART
+	__HVC(0)
+	mov	r0, r3
+	ret	lr
+ENDPROC(__hyp_soft_restart)
+
 #ifndef ZIMAGE
 .align 2
 .L__boot_cpu_mode_offset:
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 3fa867a2aae6..3b2aa9a9fe26 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -12,10 +12,11 @@
 
 #include <asm/cacheflush.h>
 #include <asm/idmap.h>
+#include <asm/virt.h>
 
 #include "reboot.h"
 
-typedef void (*phys_reset_t)(unsigned long);
+typedef void (*phys_reset_t)(unsigned long, bool);
 
 /*
  * Function pointers to optional machine specific functions
@@ -51,7 +52,9 @@ static void __soft_restart(void *addr)
 
 	/* Switch to the identity mapping. */
 	phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
-	phys_reset((unsigned long)addr);
+
+	/* original stub should be restored by kvm */
+	phys_reset((unsigned long)addr, is_hyp_mode_available());
 
 	/* Should never get here. */
 	BUG();
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index d00d52c9de3e..1846ca4255d0 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -53,11 +53,15 @@ ENDPROC(cpu_v7_proc_fin)
 	.align	5
 	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_v7_reset)
-	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
-	bic	r1, r1, #0x1			@ ...............m
- THUMB(	bic	r1, r1, #1 << 30 )		@ SCTLR.TE (Thumb exceptions)
-	mcr	p15, 0, r1, c1, c0, 0		@ disable MMU
+	mrc	p15, 0, r2, c1, c0, 0		@ ctrl register
+	bic	r2, r2, #0x1			@ ...............m
+ THUMB(	bic	r2, r2, #1 << 30 )		@ SCTLR.TE (Thumb exceptions)
+	mcr	p15, 0, r2, c1, c0, 0		@ disable MMU
 	isb
+#ifdef CONFIG_ARM_VIRT_EXT
+	teq	r1, #0
+	bne	__hyp_soft_restart
+#endif
 	bx	r0
 ENDPROC(cpu_v7_reset)
 	.popsection
-- 
2.11.0

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

* [PATCH v4 11/28] ARM: soft-reboot into same mode that we entered the kernel
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

From: Russell King <rmk+kernel@armlinux.org.uk>

When we soft-reboot (eg, kexec) from one kernel into the next, we need
to ensure that we enter the new kernel in the same processor mode as
when we were entered, so that (eg) the new kernel can install its own
hypervisor - the old kernel's hypervisor will have been overwritten.

In order to do this, we need to pass a flag to cpu_reset() so it knows
what to do, and we need to modify the kernel's own hypervisor stub to
allow it to handle a soft-reboot.

As we are always guaranteed to install our own hypervisor if we're
entered in HYP32 mode, and KVM will have moved itself out of the way
on kexec/normal reboot, we can assume that our hypervisor is in place
when we want to kexec, so changing our hypervisor API should not be a
problem.

Tested-by: Keerthy <j-keerthy@ti.com>
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/proc-fns.h |  4 ++--
 arch/arm/kernel/hyp-stub.S      | 13 +++++++++++++
 arch/arm/kernel/reboot.c        |  7 +++++--
 arch/arm/mm/proc-v7.S           | 12 ++++++++----
 4 files changed, 28 insertions(+), 8 deletions(-)

diff --git a/arch/arm/include/asm/proc-fns.h b/arch/arm/include/asm/proc-fns.h
index 8877ad5ffe10..f2e1af45bd6f 100644
--- a/arch/arm/include/asm/proc-fns.h
+++ b/arch/arm/include/asm/proc-fns.h
@@ -43,7 +43,7 @@ extern struct processor {
 	/*
 	 * Special stuff for a reset
 	 */
-	void (*reset)(unsigned long addr) __attribute__((noreturn));
+	void (*reset)(unsigned long addr, bool hvc) __attribute__((noreturn));
 	/*
 	 * Idle the processor
 	 */
@@ -88,7 +88,7 @@ extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
 #else
 extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte, unsigned int ext);
 #endif
-extern void cpu_reset(unsigned long addr) __attribute__((noreturn));
+extern void cpu_reset(unsigned long addr, bool hvc) __attribute__((noreturn));
 
 /* These three are private to arch/arm/kernel/suspend.c */
 extern void cpu_do_suspend(void *);
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index f3e9ba5fb642..82915231c6f8 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -24,6 +24,7 @@
 
 #define HVC_GET_VECTORS 0
 #define HVC_SET_VECTORS 1
+#define HVC_SOFT_RESTART 2
 
 #ifndef ZIMAGE
 /*
@@ -215,6 +216,10 @@ __hyp_stub_do_trap:
 	mcr	p15, 4, r1, c12, c0, 0	@ set HVBAR
 	b	__hyp_stub_exit
 
+1:	teq	r0, #HVC_SOFT_RESTART
+	bne	1f
+	bx	r3
+
 1:	mov	r0, #-1
 
 __hyp_stub_exit:
@@ -256,6 +261,14 @@ ENTRY(__hyp_set_vectors)
 	ret	lr
 ENDPROC(__hyp_set_vectors)
 
+ENTRY(__hyp_soft_restart)
+	mov	r3, r0
+	mov	r0, #HVC_SOFT_RESTART
+	__HVC(0)
+	mov	r0, r3
+	ret	lr
+ENDPROC(__hyp_soft_restart)
+
 #ifndef ZIMAGE
 .align 2
 .L__boot_cpu_mode_offset:
diff --git a/arch/arm/kernel/reboot.c b/arch/arm/kernel/reboot.c
index 3fa867a2aae6..3b2aa9a9fe26 100644
--- a/arch/arm/kernel/reboot.c
+++ b/arch/arm/kernel/reboot.c
@@ -12,10 +12,11 @@
 
 #include <asm/cacheflush.h>
 #include <asm/idmap.h>
+#include <asm/virt.h>
 
 #include "reboot.h"
 
-typedef void (*phys_reset_t)(unsigned long);
+typedef void (*phys_reset_t)(unsigned long, bool);
 
 /*
  * Function pointers to optional machine specific functions
@@ -51,7 +52,9 @@ static void __soft_restart(void *addr)
 
 	/* Switch to the identity mapping. */
 	phys_reset = (phys_reset_t)virt_to_idmap(cpu_reset);
-	phys_reset((unsigned long)addr);
+
+	/* original stub should be restored by kvm */
+	phys_reset((unsigned long)addr, is_hyp_mode_available());
 
 	/* Should never get here. */
 	BUG();
diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index d00d52c9de3e..1846ca4255d0 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -53,11 +53,15 @@ ENDPROC(cpu_v7_proc_fin)
 	.align	5
 	.pushsection	.idmap.text, "ax"
 ENTRY(cpu_v7_reset)
-	mrc	p15, 0, r1, c1, c0, 0		@ ctrl register
-	bic	r1, r1, #0x1			@ ...............m
- THUMB(	bic	r1, r1, #1 << 30 )		@ SCTLR.TE (Thumb exceptions)
-	mcr	p15, 0, r1, c1, c0, 0		@ disable MMU
+	mrc	p15, 0, r2, c1, c0, 0		@ ctrl register
+	bic	r2, r2, #0x1			@ ...............m
+ THUMB(	bic	r2, r2, #1 << 30 )		@ SCTLR.TE (Thumb exceptions)
+	mcr	p15, 0, r2, c1, c0, 0		@ disable MMU
 	isb
+#ifdef CONFIG_ARM_VIRT_EXT
+	teq	r1, #0
+	bne	__hyp_soft_restart
+#endif
 	bx	r0
 ENDPROC(cpu_v7_reset)
 	.popsection
-- 
2.11.0

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

* [PATCH v4 12/28] ARM: KVM: Convert KVM to use HVC_GET_VECTORS
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

The conversion of the HYP stub ABI to something similar to arm64
left the KVM code broken, as it doesn't know about the new
stub numbering. Let's move the various #defines to virt.h, and
let KVM use HVC_GET_VECTORS.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/virt.h  | 8 ++++++++
 arch/arm/kernel/hyp-stub.S   | 4 ----
 arch/arm/kvm/hyp/hyp-entry.S | 2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 6dae1956c74d..4ea16fcaf2ed 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -94,6 +94,14 @@ extern char __hyp_text_start[];
 extern char __hyp_text_end[];
 #endif
 
+#else
+
+/* Only assembly code should need those */
+
+#define HVC_GET_VECTORS 0
+#define HVC_SET_VECTORS 1
+#define HVC_SOFT_RESTART 2
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* ! VIRT_H */
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 82915231c6f8..8301db963d83 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -22,10 +22,6 @@
 #include <asm/assembler.h>
 #include <asm/virt.h>
 
-#define HVC_GET_VECTORS 0
-#define HVC_SET_VECTORS 1
-#define HVC_SOFT_RESTART 2
-
 #ifndef ZIMAGE
 /*
  * For the kernel proper, we need to find out the CPU boot mode long after
diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
index 96beb53934c9..1f8db7d21fc5 100644
--- a/arch/arm/kvm/hyp/hyp-entry.S
+++ b/arch/arm/kvm/hyp/hyp-entry.S
@@ -127,7 +127,7 @@ hyp_hvc:
 	pop	{r0, r1, r2}
 
 	/* Check for __hyp_get_vectors */
-	cmp	r0, #-1
+	cmp	r0, #HVC_GET_VECTORS
 	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
 	beq	1f
 
-- 
2.11.0

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

* [PATCH v4 12/28] ARM: KVM: Convert KVM to use HVC_GET_VECTORS
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

The conversion of the HYP stub ABI to something similar to arm64
left the KVM code broken, as it doesn't know about the new
stub numbering. Let's move the various #defines to virt.h, and
let KVM use HVC_GET_VECTORS.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/virt.h  | 8 ++++++++
 arch/arm/kernel/hyp-stub.S   | 4 ----
 arch/arm/kvm/hyp/hyp-entry.S | 2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 6dae1956c74d..4ea16fcaf2ed 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -94,6 +94,14 @@ extern char __hyp_text_start[];
 extern char __hyp_text_end[];
 #endif
 
+#else
+
+/* Only assembly code should need those */
+
+#define HVC_GET_VECTORS 0
+#define HVC_SET_VECTORS 1
+#define HVC_SOFT_RESTART 2
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* ! VIRT_H */
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 82915231c6f8..8301db963d83 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -22,10 +22,6 @@
 #include <asm/assembler.h>
 #include <asm/virt.h>
 
-#define HVC_GET_VECTORS 0
-#define HVC_SET_VECTORS 1
-#define HVC_SOFT_RESTART 2
-
 #ifndef ZIMAGE
 /*
  * For the kernel proper, we need to find out the CPU boot mode long after
diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
index 96beb53934c9..1f8db7d21fc5 100644
--- a/arch/arm/kvm/hyp/hyp-entry.S
+++ b/arch/arm/kvm/hyp/hyp-entry.S
@@ -127,7 +127,7 @@ hyp_hvc:
 	pop	{r0, r1, r2}
 
 	/* Check for __hyp_get_vectors */
-	cmp	r0, #-1
+	cmp	r0, #HVC_GET_VECTORS
 	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
 	beq	1f
 
-- 
2.11.0

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

* [PATCH v4 13/28] ARM: Update cpu_v7_reset documentation
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

cpu_v7_reset() now takes a second parameter indicating whether
we should reboot in HYP or not. Update the documentation to
reflect this.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mm/proc-v7.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 1846ca4255d0..01d64c0b2563 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -39,13 +39,14 @@ ENTRY(cpu_v7_proc_fin)
 ENDPROC(cpu_v7_proc_fin)
 
 /*
- *	cpu_v7_reset(loc)
+ *	cpu_v7_reset(loc, hyp)
  *
  *	Perform a soft reset of the system.  Put the CPU into the
  *	same state as it would be if it had been reset, and branch
  *	to what would be the reset vector.
  *
  *	- loc   - location to jump to for soft reset
+ *	- hyp   - indicate if restart occurs in HYP mode
  *
  *	This code must be executed using a flat identity mapping with
  *      caches disabled.
-- 
2.11.0

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

* [PATCH v4 13/28] ARM: Update cpu_v7_reset documentation
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

cpu_v7_reset() now takes a second parameter indicating whether
we should reboot in HYP or not. Update the documentation to
reflect this.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mm/proc-v7.S | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/arm/mm/proc-v7.S b/arch/arm/mm/proc-v7.S
index 1846ca4255d0..01d64c0b2563 100644
--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -39,13 +39,14 @@ ENTRY(cpu_v7_proc_fin)
 ENDPROC(cpu_v7_proc_fin)
 
 /*
- *	cpu_v7_reset(loc)
+ *	cpu_v7_reset(loc, hyp)
  *
  *	Perform a soft reset of the system.  Put the CPU into the
  *	same state as it would be if it had been reset, and branch
  *	to what would be the reset vector.
  *
  *	- loc   - location to jump to for soft reset
+ *	- hyp   - indicate if restart occurs in HYP mode
  *
  *	This code must be executed using a flat identity mapping with
  *      caches disabled.
-- 
2.11.0

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

* [PATCH v4 14/28] ARM: hyp-stub: Use r1 for the soft-restart address
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

It is not really obvious why the restart address should be in r3
when communicated to the hyp-stub. r1 should be perfectly adequate,
and consistent with the rest of the code.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kernel/hyp-stub.S | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 8301db963d83..15eaa14322a7 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -214,7 +214,7 @@ __hyp_stub_do_trap:
 
 1:	teq	r0, #HVC_SOFT_RESTART
 	bne	1f
-	bx	r3
+	bx	r1
 
 1:	mov	r0, #-1
 
@@ -258,10 +258,9 @@ ENTRY(__hyp_set_vectors)
 ENDPROC(__hyp_set_vectors)
 
 ENTRY(__hyp_soft_restart)
-	mov	r3, r0
+	mov	r1, r0
 	mov	r0, #HVC_SOFT_RESTART
 	__HVC(0)
-	mov	r0, r3
 	ret	lr
 ENDPROC(__hyp_soft_restart)
 
-- 
2.11.0

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

* [PATCH v4 14/28] ARM: hyp-stub: Use r1 for the soft-restart address
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

It is not really obvious why the restart address should be in r3
when communicated to the hyp-stub. r1 should be perfectly adequate,
and consistent with the rest of the code.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kernel/hyp-stub.S | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 8301db963d83..15eaa14322a7 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -214,7 +214,7 @@ __hyp_stub_do_trap:
 
 1:	teq	r0, #HVC_SOFT_RESTART
 	bne	1f
-	bx	r3
+	bx	r1
 
 1:	mov	r0, #-1
 
@@ -258,10 +258,9 @@ ENTRY(__hyp_set_vectors)
 ENDPROC(__hyp_set_vectors)
 
 ENTRY(__hyp_soft_restart)
-	mov	r3, r0
+	mov	r1, r0
 	mov	r0, #HVC_SOFT_RESTART
 	__HVC(0)
-	mov	r0, r3
 	ret	lr
 ENDPROC(__hyp_soft_restart)
 
-- 
2.11.0

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

* [PATCH v4 15/28] ARM: Expose the VA/IDMAP offset
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

The KVM code needs to be able to compute the address of
symbols in its idmap page (the equivalent of a virt_to_idmap()
call). Unfortunately, virt_to_idmap is slightly complicated,
depending on the use of arch_phys_to_idmap_offset or not, and
none of that is readily available at HYP.

Instead, expose a single kimage_voffset variable which contains the
offset between a kernel VA and its idmap address, enabling the
VA->IDMAP conversion. This allows the KVM code to behave similarily
to its arm64 counterpart.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mm/mmu.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4e016d7f37b3..e98a2b5c4e85 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -87,6 +87,8 @@ struct cachepolicy {
 #define s2_policy(policy)	0
 #endif
 
+unsigned long kimage_voffset __ro_after_init;
+
 static struct cachepolicy cache_policies[] __initdata = {
 	{
 		.policy		= "uncached",
@@ -1635,4 +1637,7 @@ void __init paging_init(const struct machine_desc *mdesc)
 
 	empty_zero_page = virt_to_page(zero_page);
 	__flush_dcache_page(NULL, empty_zero_page);
+
+	/* Compute the virt/idmap offset, mostly for the sake of KVM */
+	kimage_voffset = (unsigned long)&kimage_voffset - virt_to_idmap(&kimage_voffset);
 }
-- 
2.11.0

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

* [PATCH v4 15/28] ARM: Expose the VA/IDMAP offset
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

The KVM code needs to be able to compute the address of
symbols in its idmap page (the equivalent of a virt_to_idmap()
call). Unfortunately, virt_to_idmap is slightly complicated,
depending on the use of arch_phys_to_idmap_offset or not, and
none of that is readily available at HYP.

Instead, expose a single kimage_voffset variable which contains the
offset between a kernel VA and its idmap address, enabling the
VA->IDMAP conversion. This allows the KVM code to behave similarily
to its arm64 counterpart.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/mm/mmu.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4e016d7f37b3..e98a2b5c4e85 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -87,6 +87,8 @@ struct cachepolicy {
 #define s2_policy(policy)	0
 #endif
 
+unsigned long kimage_voffset __ro_after_init;
+
 static struct cachepolicy cache_policies[] __initdata = {
 	{
 		.policy		= "uncached",
@@ -1635,4 +1637,7 @@ void __init paging_init(const struct machine_desc *mdesc)
 
 	empty_zero_page = virt_to_page(zero_page);
 	__flush_dcache_page(NULL, empty_zero_page);
+
+	/* Compute the virt/idmap offset, mostly for the sake of KVM */
+	kimage_voffset = (unsigned long)&kimage_voffset - virt_to_idmap(&kimage_voffset);
 }
-- 
2.11.0

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

* [PATCH v4 16/28] ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Let's define a new stub hypercall that resets the HYP configuration
to its default: hyp-stub vectors, and MMU disabled.

Of course, for the hyp-stub itself, this is a trivial no-op.
Hypervisors will have a bit more work to do.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/virt.h |  3 +++
 arch/arm/kernel/hyp-stub.S  | 11 ++++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 4ea16fcaf2ed..5186718aab68 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -101,6 +101,9 @@ extern char __hyp_text_end[];
 #define HVC_GET_VECTORS 0
 #define HVC_SET_VECTORS 1
 #define HVC_SOFT_RESTART 2
+#define HVC_RESET_VECTORS 3
+
+#define HVC_STUB_HCALL_NR 4
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 15eaa14322a7..21794d4a8f36 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -216,7 +216,10 @@ __hyp_stub_do_trap:
 	bne	1f
 	bx	r1
 
-1:	mov	r0, #-1
+1:	teq	r0, #HVC_RESET_VECTORS
+	beq	__hyp_stub_exit
+
+	mov	r0, #-1
 
 __hyp_stub_exit:
 	__ERET
@@ -264,6 +267,12 @@ ENTRY(__hyp_soft_restart)
 	ret	lr
 ENDPROC(__hyp_soft_restart)
 
+ENTRY(__hyp_reset_vectors)
+	mov	r0, #HVC_RESET_VECTORS
+	__HVC(0)
+	ret	lr
+ENDPROC(__hyp_reset_vectors)
+
 #ifndef ZIMAGE
 .align 2
 .L__boot_cpu_mode_offset:
-- 
2.11.0

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

* [PATCH v4 16/28] ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Let's define a new stub hypercall that resets the HYP configuration
to its default: hyp-stub vectors, and MMU disabled.

Of course, for the hyp-stub itself, this is a trivial no-op.
Hypervisors will have a bit more work to do.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/virt.h |  3 +++
 arch/arm/kernel/hyp-stub.S  | 11 ++++++++++-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 4ea16fcaf2ed..5186718aab68 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -101,6 +101,9 @@ extern char __hyp_text_end[];
 #define HVC_GET_VECTORS 0
 #define HVC_SET_VECTORS 1
 #define HVC_SOFT_RESTART 2
+#define HVC_RESET_VECTORS 3
+
+#define HVC_STUB_HCALL_NR 4
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 15eaa14322a7..21794d4a8f36 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -216,7 +216,10 @@ __hyp_stub_do_trap:
 	bne	1f
 	bx	r1
 
-1:	mov	r0, #-1
+1:	teq	r0, #HVC_RESET_VECTORS
+	beq	__hyp_stub_exit
+
+	mov	r0, #-1
 
 __hyp_stub_exit:
 	__ERET
@@ -264,6 +267,12 @@ ENTRY(__hyp_soft_restart)
 	ret	lr
 ENDPROC(__hyp_soft_restart)
 
+ENTRY(__hyp_reset_vectors)
+	mov	r0, #HVC_RESET_VECTORS
+	__HVC(0)
+	ret	lr
+ENDPROC(__hyp_reset_vectors)
+
 #ifndef ZIMAGE
 .align 2
 .L__boot_cpu_mode_offset:
-- 
2.11.0

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

* [PATCH v4 17/28] ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

In order to restore HYP mode to its original condition, KVM currently
implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
defined API, it becomes necessary to implement HVC_RESET_VECTORS.

This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
code, which so far lacked any form of hypercall support.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/virt.h |  1 +
 arch/arm/kernel/hyp-stub.S  |  2 +-
 arch/arm/kvm/init.S         | 33 +++++++++++++++++++++++++++------
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 5186718aab68..8d5625b790b5 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -54,6 +54,7 @@ static inline void sync_boot_mode(void)
 
 void __hyp_set_vectors(unsigned long phys_vector_base);
 unsigned long __hyp_get_vectors(void);
+void __hyp_reset_vectors(void);
 #else
 #define __boot_cpu_mode	(SVC_MODE)
 #define sync_boot_mode()
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 21794d4a8f36..3cb01e8a291d 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -280,7 +280,7 @@ ENDPROC(__hyp_reset_vectors)
 #endif
 
 .align 5
-__hyp_stub_vectors:
+ENTRY(__hyp_stub_vectors)
 __hyp_stub_reset:	W(b)	.
 __hyp_stub_und:		W(b)	.
 __hyp_stub_svc:		W(b)	.
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index bf89c919efc1..9b0c735a68f7 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -23,6 +23,7 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_arm.h>
 #include <asm/kvm_mmu.h>
+#include <asm/virt.h>
 
 /********************************************************************
  * Hypervisor initialization
@@ -39,6 +40,10 @@
  * - Setup the page tables
  * - Enable the MMU
  * - Profit! (or eret, if you only care about the code).
+ *
+ * Another possibility is to get a HYP stub hypercall.
+ * We discriminate between the two by checking if r0 contains a value
+ * that is less than HVC_STUB_HCALL_NR.
  */
 
 	.text
@@ -58,6 +63,10 @@ __kvm_hyp_init:
 	W(b)	.
 
 __do_hyp_init:
+	@ Check for a stub hypercall
+	cmp	r0, #HVC_STUB_HCALL_NR
+	blo	__kvm_handle_stub_hvc
+
 	@ Set stack pointer
 	mov	sp, r0
 
@@ -112,19 +121,31 @@ __do_hyp_init:
 
 	eret
 
-	@ r0 : stub vectors address
+ENTRY(__kvm_handle_stub_hvc)
+	cmp	r0, #HVC_RESET_VECTORS
+	bne	1f
 ENTRY(__kvm_hyp_reset)
 	/* We're now in idmap, disable MMU */
 	mrc	p15, 4, r1, c1, c0, 0	@ HSCTLR
-	ldr	r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
-	bic	r1, r1, r2
+	ldr	r0, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
+	bic	r1, r1, r0
 	mcr	p15, 4, r1, c1, c0, 0	@ HSCTLR
 
-	/* Install stub vectors */
-	mcr	p15, 4, r0, c12, c0, 0	@ HVBAR
-	isb
+	/*
+	 * Install stub vectors, using ardb's VA->PA trick.
+	 */
+0:	adr	r0, 0b					@ PA(0)
+	movw	r1, #:lower16:__hyp_stub_vectors - 0b   @ VA(stub) - VA(0)
+	movt	r1, #:upper16:__hyp_stub_vectors - 0b
+	add	r1, r1, r0				@ PA(stub)
+	mcr	p15, 4, r1, c12, c0, 0	@ HVBAR
+	b	exit
+
+1:	mov	r0, #-1
 
+exit:
 	eret
+ENDPROC(__kvm_handle_stub_hvc)
 ENDPROC(__kvm_hyp_reset)
 
 	.ltorg
-- 
2.11.0

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

* [PATCH v4 17/28] ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

In order to restore HYP mode to its original condition, KVM currently
implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
defined API, it becomes necessary to implement HVC_RESET_VECTORS.

This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
code, which so far lacked any form of hypercall support.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/virt.h |  1 +
 arch/arm/kernel/hyp-stub.S  |  2 +-
 arch/arm/kvm/init.S         | 33 +++++++++++++++++++++++++++------
 3 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 5186718aab68..8d5625b790b5 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -54,6 +54,7 @@ static inline void sync_boot_mode(void)
 
 void __hyp_set_vectors(unsigned long phys_vector_base);
 unsigned long __hyp_get_vectors(void);
+void __hyp_reset_vectors(void);
 #else
 #define __boot_cpu_mode	(SVC_MODE)
 #define sync_boot_mode()
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 21794d4a8f36..3cb01e8a291d 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -280,7 +280,7 @@ ENDPROC(__hyp_reset_vectors)
 #endif
 
 .align 5
-__hyp_stub_vectors:
+ENTRY(__hyp_stub_vectors)
 __hyp_stub_reset:	W(b)	.
 __hyp_stub_und:		W(b)	.
 __hyp_stub_svc:		W(b)	.
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index bf89c919efc1..9b0c735a68f7 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -23,6 +23,7 @@
 #include <asm/kvm_asm.h>
 #include <asm/kvm_arm.h>
 #include <asm/kvm_mmu.h>
+#include <asm/virt.h>
 
 /********************************************************************
  * Hypervisor initialization
@@ -39,6 +40,10 @@
  * - Setup the page tables
  * - Enable the MMU
  * - Profit! (or eret, if you only care about the code).
+ *
+ * Another possibility is to get a HYP stub hypercall.
+ * We discriminate between the two by checking if r0 contains a value
+ * that is less than HVC_STUB_HCALL_NR.
  */
 
 	.text
@@ -58,6 +63,10 @@ __kvm_hyp_init:
 	W(b)	.
 
 __do_hyp_init:
+	@ Check for a stub hypercall
+	cmp	r0, #HVC_STUB_HCALL_NR
+	blo	__kvm_handle_stub_hvc
+
 	@ Set stack pointer
 	mov	sp, r0
 
@@ -112,19 +121,31 @@ __do_hyp_init:
 
 	eret
 
-	@ r0 : stub vectors address
+ENTRY(__kvm_handle_stub_hvc)
+	cmp	r0, #HVC_RESET_VECTORS
+	bne	1f
 ENTRY(__kvm_hyp_reset)
 	/* We're now in idmap, disable MMU */
 	mrc	p15, 4, r1, c1, c0, 0	@ HSCTLR
-	ldr	r2, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
-	bic	r1, r1, r2
+	ldr	r0, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
+	bic	r1, r1, r0
 	mcr	p15, 4, r1, c1, c0, 0	@ HSCTLR
 
-	/* Install stub vectors */
-	mcr	p15, 4, r0, c12, c0, 0	@ HVBAR
-	isb
+	/*
+	 * Install stub vectors, using ardb's VA->PA trick.
+	 */
+0:	adr	r0, 0b					@ PA(0)
+	movw	r1, #:lower16:__hyp_stub_vectors - 0b   @ VA(stub) - VA(0)
+	movt	r1, #:upper16:__hyp_stub_vectors - 0b
+	add	r1, r1, r0				@ PA(stub)
+	mcr	p15, 4, r1, c12, c0, 0	@ HVBAR
+	b	exit
+
+1:	mov	r0, #-1
 
+exit:
 	eret
+ENDPROC(__kvm_handle_stub_hvc)
 ENDPROC(__kvm_hyp_reset)
 
 	.ltorg
-- 
2.11.0

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

* [PATCH v4 18/28] ARM: KVM: Implement HVC_GET_VECTORS in the init code
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Now that we have an infrastructure to handle hypercalls in the KVM
init code, let's implement HVC_GET_VECTORS there.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/init.S | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 9b0c735a68f7..0da120b71c2e 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -122,7 +122,12 @@ __do_hyp_init:
 	eret
 
 ENTRY(__kvm_handle_stub_hvc)
-	cmp	r0, #HVC_RESET_VECTORS
+	cmp	r0, #HVC_GET_VECTORS
+	bne	1f
+	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
+	b	exit
+
+1:	cmp	r0, #HVC_RESET_VECTORS
 	bne	1f
 ENTRY(__kvm_hyp_reset)
 	/* We're now in idmap, disable MMU */
-- 
2.11.0

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

* [PATCH v4 18/28] ARM: KVM: Implement HVC_GET_VECTORS in the init code
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Now that we have an infrastructure to handle hypercalls in the KVM
init code, let's implement HVC_GET_VECTORS there.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/init.S | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 9b0c735a68f7..0da120b71c2e 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -122,7 +122,12 @@ __do_hyp_init:
 	eret
 
 ENTRY(__kvm_handle_stub_hvc)
-	cmp	r0, #HVC_RESET_VECTORS
+	cmp	r0, #HVC_GET_VECTORS
+	bne	1f
+	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
+	b	exit
+
+1:	cmp	r0, #HVC_RESET_VECTORS
 	bne	1f
 ENTRY(__kvm_hyp_reset)
 	/* We're now in idmap, disable MMU */
-- 
2.11.0

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

* [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

We now have a full hyp-stub implementation in the KVM init code,
but the main KVM code only supports HVC_GET_VECTORS, which is not
enough.

Instead of reinventing the wheel, let's reuse the init implementation
by branching to the idmap page when called with a hyp-stub hypercall.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
index 1f8db7d21fc5..a35baa81fd23 100644
--- a/arch/arm/kvm/hyp/hyp-entry.S
+++ b/arch/arm/kvm/hyp/hyp-entry.S
@@ -126,11 +126,30 @@ hyp_hvc:
 	 */
 	pop	{r0, r1, r2}
 
-	/* Check for __hyp_get_vectors */
-	cmp	r0, #HVC_GET_VECTORS
-	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
-	beq	1f
+	/*
+	 * Check if we have a kernel function, which is guaranteed to be
+	 * bigger than the maximum hyp stub hypercall
+	 */
+	cmp	r0, #HVC_STUB_HCALL_NR
+	bhs	1f
 
+	/*
+	 * Not a kernel function, treat it as a stub hypercall.
+	 * Compute the physical address for __kvm_handle_stub_hvc
+	 * (as the code lives in the idmaped page) and branch there.
+	 * We hijack ip (r12) as a tmp register.
+	 */
+	push	{r1}
+	ldr	r1, =kimage_voffset
+	ldr	r1, [r1]
+	ldr	ip, =__kvm_handle_stub_hvc
+	sub	ip, ip, r1
+THUMB(	add	ip, ip, #1)
+	pop	{r1}
+
+	bx	ip
+
+1:
 	push	{lr}
 
 	mov	lr, r0
@@ -142,7 +161,7 @@ THUMB(	orr	lr, #1)
 	blx	lr			@ Call the HYP function
 
 	pop	{lr}
-1:	eret
+	eret
 
 guest_trap:
 	load_vcpu r0			@ Load VCPU pointer to r0
-- 
2.11.0

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

* [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

We now have a full hyp-stub implementation in the KVM init code,
but the main KVM code only supports HVC_GET_VECTORS, which is not
enough.

Instead of reinventing the wheel, let's reuse the init implementation
by branching to the idmap page when called with a hyp-stub hypercall.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
 1 file changed, 24 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
index 1f8db7d21fc5..a35baa81fd23 100644
--- a/arch/arm/kvm/hyp/hyp-entry.S
+++ b/arch/arm/kvm/hyp/hyp-entry.S
@@ -126,11 +126,30 @@ hyp_hvc:
 	 */
 	pop	{r0, r1, r2}
 
-	/* Check for __hyp_get_vectors */
-	cmp	r0, #HVC_GET_VECTORS
-	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
-	beq	1f
+	/*
+	 * Check if we have a kernel function, which is guaranteed to be
+	 * bigger than the maximum hyp stub hypercall
+	 */
+	cmp	r0, #HVC_STUB_HCALL_NR
+	bhs	1f
 
+	/*
+	 * Not a kernel function, treat it as a stub hypercall.
+	 * Compute the physical address for __kvm_handle_stub_hvc
+	 * (as the code lives in the idmaped page) and branch there.
+	 * We hijack ip (r12) as a tmp register.
+	 */
+	push	{r1}
+	ldr	r1, =kimage_voffset
+	ldr	r1, [r1]
+	ldr	ip, =__kvm_handle_stub_hvc
+	sub	ip, ip, r1
+THUMB(	add	ip, ip, #1)
+	pop	{r1}
+
+	bx	ip
+
+1:
 	push	{lr}
 
 	mov	lr, r0
@@ -142,7 +161,7 @@ THUMB(	orr	lr, #1)
 	blx	lr			@ Call the HYP function
 
 	pop	{lr}
-1:	eret
+	eret
 
 guest_trap:
 	load_vcpu r0			@ Load VCPU pointer to r0
-- 
2.11.0

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

* [PATCH v4 20/28] ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

We are now able to use the hyp stub to reset HYP mode. Time to
kiss __kvm_hyp_reset goodbye, and use __hyp_reset_vectors.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/kvm_asm.h  | 2 --
 arch/arm/include/asm/kvm_host.h | 2 +-
 arch/arm/kvm/init.S             | 2 --
 3 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 8ef05381984b..7ccb6f1aac5b 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -72,8 +72,6 @@ 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
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 31ee468ce667..adea30753185 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -273,7 +273,7 @@ static inline void __cpu_init_stage2(void)
 static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
 					phys_addr_t phys_idmap_start)
 {
-	kvm_call_hyp((void *)virt_to_idmap(__kvm_hyp_reset), vector_ptr);
+	__hyp_reset_vectors();
 }
 
 static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 0da120b71c2e..7335a510eee4 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -129,7 +129,6 @@ ENTRY(__kvm_handle_stub_hvc)
 
 1:	cmp	r0, #HVC_RESET_VECTORS
 	bne	1f
-ENTRY(__kvm_hyp_reset)
 	/* We're now in idmap, disable MMU */
 	mrc	p15, 4, r1, c1, c0, 0	@ HSCTLR
 	ldr	r0, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
@@ -151,7 +150,6 @@ ENTRY(__kvm_hyp_reset)
 exit:
 	eret
 ENDPROC(__kvm_handle_stub_hvc)
-ENDPROC(__kvm_hyp_reset)
 
 	.ltorg
 
-- 
2.11.0

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

* [PATCH v4 20/28] ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

We are now able to use the hyp stub to reset HYP mode. Time to
kiss __kvm_hyp_reset goodbye, and use __hyp_reset_vectors.

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/kvm_asm.h  | 2 --
 arch/arm/include/asm/kvm_host.h | 2 +-
 arch/arm/kvm/init.S             | 2 --
 3 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 8ef05381984b..7ccb6f1aac5b 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -72,8 +72,6 @@ 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
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 31ee468ce667..adea30753185 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -273,7 +273,7 @@ static inline void __cpu_init_stage2(void)
 static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
 					phys_addr_t phys_idmap_start)
 {
-	kvm_call_hyp((void *)virt_to_idmap(__kvm_hyp_reset), vector_ptr);
+	__hyp_reset_vectors();
 }
 
 static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 0da120b71c2e..7335a510eee4 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -129,7 +129,6 @@ ENTRY(__kvm_handle_stub_hvc)
 
 1:	cmp	r0, #HVC_RESET_VECTORS
 	bne	1f
-ENTRY(__kvm_hyp_reset)
 	/* We're now in idmap, disable MMU */
 	mrc	p15, 4, r1, c1, c0, 0	@ HSCTLR
 	ldr	r0, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
@@ -151,7 +150,6 @@ ENTRY(__kvm_hyp_reset)
 exit:
 	eret
 ENDPROC(__kvm_handle_stub_hvc)
-ENDPROC(__kvm_hyp_reset)
 
 	.ltorg
 
-- 
2.11.0

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

* [PATCH v4 21/28] ARM: KVM: Implement HVC_SOFT_RESTART in the init code
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Another missing stub hypercall is HVC_SOFT_RESTART. It turns out
that it is pretty easy to implement in terms of HVC_RESET_VECTORS
(since it needs to turn the MMU off).

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/init.S | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 7335a510eee4..c92e092103b2 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -127,8 +127,22 @@ ENTRY(__kvm_handle_stub_hvc)
 	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
 	b	exit
 
+1:	cmp	r0, #HVC_SOFT_RESTART
+	bne	1f
+
+	/* The target is expected in r1 */
+	msr	ELR_hyp, r1
+	mrs	r0, cpsr
+	bic	r0, r0, #MODE_MASK
+	orr	r0, r0, #HYP_MODE
+THUMB(	orr	r0, r0, #PSR_T_BIT	)
+	msr	spsr_cxsf, r0
+	b	reset
+
 1:	cmp	r0, #HVC_RESET_VECTORS
 	bne	1f
+
+reset:
 	/* We're now in idmap, disable MMU */
 	mrc	p15, 4, r1, c1, c0, 0	@ HSCTLR
 	ldr	r0, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
-- 
2.11.0

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

* [PATCH v4 21/28] ARM: KVM: Implement HVC_SOFT_RESTART in the init code
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Another missing stub hypercall is HVC_SOFT_RESTART. It turns out
that it is pretty easy to implement in terms of HVC_RESET_VECTORS
(since it needs to turn the MMU off).

Tested-by: Keerthy <j-keerthy@ti.com>
Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/init.S | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index 7335a510eee4..c92e092103b2 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -127,8 +127,22 @@ ENTRY(__kvm_handle_stub_hvc)
 	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
 	b	exit
 
+1:	cmp	r0, #HVC_SOFT_RESTART
+	bne	1f
+
+	/* The target is expected in r1 */
+	msr	ELR_hyp, r1
+	mrs	r0, cpsr
+	bic	r0, r0, #MODE_MASK
+	orr	r0, r0, #HYP_MODE
+THUMB(	orr	r0, r0, #PSR_T_BIT	)
+	msr	spsr_cxsf, r0
+	b	reset
+
 1:	cmp	r0, #HVC_RESET_VECTORS
 	bne	1f
+
+reset:
 	/* We're now in idmap, disable MMU */
 	mrc	p15, 4, r1, c1, c0, 0	@ HSCTLR
 	ldr	r0, =(HSCTLR_M | HSCTLR_A | HSCTLR_C | HSCTLR_I)
-- 
2.11.0

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

* [PATCH v4 22/28] arm/arm64: KVM: Use __hyp_reset_vectors() directly
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

__cpu_reset_hyp_mode doesn't need to be passed any argument now,
as the hyp-stub implementations are self-contained, and is now
reduced to just calling __hyp_reset_vectors(). Let's drop the
wrapper and use the stub hypercall directly.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/kvm_host.h   | 6 ------
 arch/arm/kvm/arm.c                | 3 +--
 arch/arm64/include/asm/kvm_host.h | 6 ------
 3 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index adea30753185..d488b8866bc9 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -270,12 +270,6 @@ static inline void __cpu_init_stage2(void)
 	kvm_call_hyp(__init_stage2_translation);
 }
 
-static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
-					phys_addr_t phys_idmap_start)
-{
-	__hyp_reset_vectors();
-}
-
 static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
 {
 	return 0;
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 96dba7cd8be7..57dd48d61796 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -1129,8 +1129,7 @@ static void cpu_hyp_reinit(void)
 static void cpu_hyp_reset(void)
 {
 	if (!is_kernel_in_hyp_mode())
-		__cpu_reset_hyp_mode(hyp_default_vectors,
-				     kvm_get_idmap_start());
+		__hyp_reset_vectors();
 }
 
 static void _kvm_arch_hardware_enable(void *discard)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0355dd109956..578df18f66b7 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -362,12 +362,6 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
 	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
 }
 
-static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
-					phys_addr_t phys_idmap_start)
-{
-	__hyp_reset_vectors();
-}
-
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
-- 
2.11.0

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

* [PATCH v4 22/28] arm/arm64: KVM: Use __hyp_reset_vectors() directly
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

__cpu_reset_hyp_mode doesn't need to be passed any argument now,
as the hyp-stub implementations are self-contained, and is now
reduced to just calling __hyp_reset_vectors(). Let's drop the
wrapper and use the stub hypercall directly.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/kvm_host.h   | 6 ------
 arch/arm/kvm/arm.c                | 3 +--
 arch/arm64/include/asm/kvm_host.h | 6 ------
 3 files changed, 1 insertion(+), 14 deletions(-)

diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index adea30753185..d488b8866bc9 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -270,12 +270,6 @@ static inline void __cpu_init_stage2(void)
 	kvm_call_hyp(__init_stage2_translation);
 }
 
-static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
-					phys_addr_t phys_idmap_start)
-{
-	__hyp_reset_vectors();
-}
-
 static inline int kvm_arch_dev_ioctl_check_extension(struct kvm *kvm, long ext)
 {
 	return 0;
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 96dba7cd8be7..57dd48d61796 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -1129,8 +1129,7 @@ static void cpu_hyp_reinit(void)
 static void cpu_hyp_reset(void)
 {
 	if (!is_kernel_in_hyp_mode())
-		__cpu_reset_hyp_mode(hyp_default_vectors,
-				     kvm_get_idmap_start());
+		__hyp_reset_vectors();
 }
 
 static void _kvm_arch_hardware_enable(void *discard)
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 0355dd109956..578df18f66b7 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -362,12 +362,6 @@ static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
 	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
 }
 
-static inline void __cpu_reset_hyp_mode(unsigned long vector_ptr,
-					phys_addr_t phys_idmap_start)
-{
-	__hyp_reset_vectors();
-}
-
 static inline void kvm_arch_hardware_unsetup(void) {}
 static inline void kvm_arch_sync_events(struct kvm *kvm) {}
 static inline void kvm_arch_vcpu_uninit(struct kvm_vcpu *vcpu) {}
-- 
2.11.0

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

* [PATCH v4 23/28] arm/arm64: KVM: Remove kvm_get_idmap_start
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

With __cpu_reset_hyp_mode having become fairly dumb, there is no
need for kvm_get_idmap_start anymore.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/kvm_mmu.h   | 1 -
 arch/arm/kvm/mmu.c               | 5 -----
 arch/arm64/include/asm/kvm_mmu.h | 1 -
 3 files changed, 7 deletions(-)

diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 95f38dcd611d..fa6f2174276b 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -56,7 +56,6 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
 
 phys_addr_t kvm_mmu_get_httbr(void);
 phys_addr_t kvm_get_idmap_vector(void);
-phys_addr_t kvm_get_idmap_start(void);
 int kvm_mmu_init(void);
 void kvm_clear_hyp_idmap(void);
 
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 962616fd4ddd..59f555b64dec 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1674,11 +1674,6 @@ phys_addr_t kvm_get_idmap_vector(void)
 	return hyp_idmap_vector;
 }
 
-phys_addr_t kvm_get_idmap_start(void)
-{
-	return hyp_idmap_start;
-}
-
 static int kvm_map_idmap_text(pgd_t *pgd)
 {
 	int err;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index ed1246014901..91d93a5d8fd3 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -155,7 +155,6 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
 
 phys_addr_t kvm_mmu_get_httbr(void);
 phys_addr_t kvm_get_idmap_vector(void);
-phys_addr_t kvm_get_idmap_start(void);
 int kvm_mmu_init(void);
 void kvm_clear_hyp_idmap(void);
 
-- 
2.11.0

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

* [PATCH v4 23/28] arm/arm64: KVM: Remove kvm_get_idmap_start
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

With __cpu_reset_hyp_mode having become fairly dumb, there is no
need for kvm_get_idmap_start anymore.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/kvm_mmu.h   | 1 -
 arch/arm/kvm/mmu.c               | 5 -----
 arch/arm64/include/asm/kvm_mmu.h | 1 -
 3 files changed, 7 deletions(-)

diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 95f38dcd611d..fa6f2174276b 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -56,7 +56,6 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
 
 phys_addr_t kvm_mmu_get_httbr(void);
 phys_addr_t kvm_get_idmap_vector(void);
-phys_addr_t kvm_get_idmap_start(void);
 int kvm_mmu_init(void);
 void kvm_clear_hyp_idmap(void);
 
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 962616fd4ddd..59f555b64dec 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1674,11 +1674,6 @@ phys_addr_t kvm_get_idmap_vector(void)
 	return hyp_idmap_vector;
 }
 
-phys_addr_t kvm_get_idmap_start(void)
-{
-	return hyp_idmap_start;
-}
-
 static int kvm_map_idmap_text(pgd_t *pgd)
 {
 	int err;
diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h
index ed1246014901..91d93a5d8fd3 100644
--- a/arch/arm64/include/asm/kvm_mmu.h
+++ b/arch/arm64/include/asm/kvm_mmu.h
@@ -155,7 +155,6 @@ void kvm_mmu_free_memory_caches(struct kvm_vcpu *vcpu);
 
 phys_addr_t kvm_mmu_get_httbr(void);
 phys_addr_t kvm_get_idmap_vector(void);
-phys_addr_t kvm_get_idmap_start(void);
 int kvm_mmu_init(void);
 void kvm_clear_hyp_idmap(void);
 
-- 
2.11.0

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

* [PATCH v4 24/28] arm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Instead of trying to compare the value given by __hyp_get_vectors(),
which doesn't offer any real guarantee to be the stub's address, use
HVC_RESET_VECTORS to make sure we're in a sane state to reinstall
KVM across PM events.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/arm.c | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 57dd48d61796..cbd3a3150090 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -53,7 +53,6 @@ __asm__(".arch_extension	virt");
 
 static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
 static kvm_cpu_context_t __percpu *kvm_host_cpu_state;
-static unsigned long hyp_default_vectors;
 
 /* Per-CPU variable containing the currently running vcpu. */
 static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
@@ -1112,8 +1111,16 @@ static void cpu_init_hyp_mode(void *dummy)
 	kvm_arm_init_debug();
 }
 
+static void cpu_hyp_reset(void)
+{
+	if (!is_kernel_in_hyp_mode())
+		__hyp_reset_vectors();
+}
+
 static void cpu_hyp_reinit(void)
 {
+	cpu_hyp_reset();
+
 	if (is_kernel_in_hyp_mode()) {
 		/*
 		 * __cpu_init_stage2() is safe to call even if the PM
@@ -1121,17 +1128,10 @@ static void cpu_hyp_reinit(void)
 		 */
 		__cpu_init_stage2();
 	} else {
-		if (__hyp_get_vectors() == hyp_default_vectors)
-			cpu_init_hyp_mode(NULL);
+		cpu_init_hyp_mode(NULL);
 	}
 }
 
-static void cpu_hyp_reset(void)
-{
-	if (!is_kernel_in_hyp_mode())
-		__hyp_reset_vectors();
-}
-
 static void _kvm_arch_hardware_enable(void *discard)
 {
 	if (!__this_cpu_read(kvm_arm_hardware_enabled)) {
@@ -1315,12 +1315,6 @@ static int init_hyp_mode(void)
 		goto out_err;
 
 	/*
-	 * It is probably enough to obtain the default on one
-	 * CPU. It's unlikely to be different on the others.
-	 */
-	hyp_default_vectors = __hyp_get_vectors();
-
-	/*
 	 * Allocate stack pages for Hypervisor-mode
 	 */
 	for_each_possible_cpu(cpu) {
-- 
2.11.0

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

* [PATCH v4 24/28] arm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of trying to compare the value given by __hyp_get_vectors(),
which doesn't offer any real guarantee to be the stub's address, use
HVC_RESET_VECTORS to make sure we're in a sane state to reinstall
KVM across PM events.

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/kvm/arm.c | 24 +++++++++---------------
 1 file changed, 9 insertions(+), 15 deletions(-)

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 57dd48d61796..cbd3a3150090 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -53,7 +53,6 @@ __asm__(".arch_extension	virt");
 
 static DEFINE_PER_CPU(unsigned long, kvm_arm_hyp_stack_page);
 static kvm_cpu_context_t __percpu *kvm_host_cpu_state;
-static unsigned long hyp_default_vectors;
 
 /* Per-CPU variable containing the currently running vcpu. */
 static DEFINE_PER_CPU(struct kvm_vcpu *, kvm_arm_running_vcpu);
@@ -1112,8 +1111,16 @@ static void cpu_init_hyp_mode(void *dummy)
 	kvm_arm_init_debug();
 }
 
+static void cpu_hyp_reset(void)
+{
+	if (!is_kernel_in_hyp_mode())
+		__hyp_reset_vectors();
+}
+
 static void cpu_hyp_reinit(void)
 {
+	cpu_hyp_reset();
+
 	if (is_kernel_in_hyp_mode()) {
 		/*
 		 * __cpu_init_stage2() is safe to call even if the PM
@@ -1121,17 +1128,10 @@ static void cpu_hyp_reinit(void)
 		 */
 		__cpu_init_stage2();
 	} else {
-		if (__hyp_get_vectors() == hyp_default_vectors)
-			cpu_init_hyp_mode(NULL);
+		cpu_init_hyp_mode(NULL);
 	}
 }
 
-static void cpu_hyp_reset(void)
-{
-	if (!is_kernel_in_hyp_mode())
-		__hyp_reset_vectors();
-}
-
 static void _kvm_arch_hardware_enable(void *discard)
 {
 	if (!__this_cpu_read(kvm_arm_hardware_enabled)) {
@@ -1315,12 +1315,6 @@ static int init_hyp_mode(void)
 		goto out_err;
 
 	/*
-	 * It is probably enough to obtain the default on one
-	 * CPU. It's unlikely to be different on the others.
-	 */
-	hyp_default_vectors = __hyp_get_vectors();
-
-	/*
 	 * Allocate stack pages for Hypervisor-mode
 	 */
 	for_each_possible_cpu(cpu) {
-- 
2.11.0

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

* [PATCH v4 25/28] ARM: decompressor: Remove __hyp_get_vectors usage
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

When the compressed image needs to be relocated to avoid being
overwritten by the decompression process, we need to relocate
the hyp vectors as well so that we can find them once the
decompression has taken effect.

For that, we perform the following calculation:
	u32 v = __hyp_get_vectors();
	v += offset;
	__hyp_set_vectors(v);

But we're guaranteed that the initial value of v as returned by
__hyp_get_vectors is always __hyp_stub_vectors, because we have
just set it by calling __hyp_stub_install.

So let's remove the use of __hyp_get_vectors, and directly use
__hyp_stub_vectors instead.

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/boot/compressed/head.S | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 9150f9732785..d58bb104c6e8 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -422,7 +422,10 @@ dtb_check_done:
 		cmp	r0, #HYP_MODE
 		bne	1f
 
-		bl	__hyp_get_vectors
+0:		adr	r0, 0b
+		movw	r1, #:lower16:__hyp_stub_vectors - 0b
+		movt	r1, #:upper16:__hyp_stub_vectors - 0b
+		add	r0, r0, r1
 		sub	r0, r0, r5
 		add	r0, r0, r10
 		bl	__hyp_set_vectors
-- 
2.11.0

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

* [PATCH v4 25/28] ARM: decompressor: Remove __hyp_get_vectors usage
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

When the compressed image needs to be relocated to avoid being
overwritten by the decompression process, we need to relocate
the hyp vectors as well so that we can find them once the
decompression has taken effect.

For that, we perform the following calculation:
	u32 v = __hyp_get_vectors();
	v += offset;
	__hyp_set_vectors(v);

But we're guaranteed that the initial value of v as returned by
__hyp_get_vectors is always __hyp_stub_vectors, because we have
just set it by calling __hyp_stub_install.

So let's remove the use of __hyp_get_vectors, and directly use
__hyp_stub_vectors instead.

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/boot/compressed/head.S | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 9150f9732785..d58bb104c6e8 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -422,7 +422,10 @@ dtb_check_done:
 		cmp	r0, #HYP_MODE
 		bne	1f
 
-		bl	__hyp_get_vectors
+0:		adr	r0, 0b
+		movw	r1, #:lower16:__hyp_stub_vectors - 0b
+		movt	r1, #:upper16:__hyp_stub_vectors - 0b
+		add	r0, r0, r1
 		sub	r0, r0, r5
 		add	r0, r0, r10
 		bl	__hyp_set_vectors
-- 
2.11.0

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

* [PATCH v4 26/28] ARM: hyp-stub/KVM: Kill __hyp_get_vectors
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Nobody is using __hyp_get_vectors anymore, so let's remove both
implementations (hyp-stub and KVM).

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/virt.h | 10 ++++------
 arch/arm/kernel/hyp-stub.S  | 13 +------------
 arch/arm/kvm/init.S         |  7 +------
 arch/arm/kvm/interrupts.S   |  4 ----
 4 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 8d5625b790b5..5f45969d4063 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -53,7 +53,6 @@ static inline void sync_boot_mode(void)
 }
 
 void __hyp_set_vectors(unsigned long phys_vector_base);
-unsigned long __hyp_get_vectors(void);
 void __hyp_reset_vectors(void);
 #else
 #define __boot_cpu_mode	(SVC_MODE)
@@ -99,12 +98,11 @@ extern char __hyp_text_end[];
 
 /* Only assembly code should need those */
 
-#define HVC_GET_VECTORS 0
-#define HVC_SET_VECTORS 1
-#define HVC_SOFT_RESTART 2
-#define HVC_RESET_VECTORS 3
+#define HVC_SET_VECTORS 0
+#define HVC_SOFT_RESTART 1
+#define HVC_RESET_VECTORS 2
 
-#define HVC_STUB_HCALL_NR 4
+#define HVC_STUB_HCALL_NR 3
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 3cb01e8a291d..68bf72777ac7 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -202,12 +202,7 @@ ARM_BE8(orr	r7, r7, #(1 << 25))     @ HSCTLR.EE
 ENDPROC(__hyp_stub_install_secondary)
 
 __hyp_stub_do_trap:
-	teq	r0, #HVC_GET_VECTORS
-	bne	1f
-	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
-	b	__hyp_stub_exit
-
-1:	teq	r0, #HVC_SET_VECTORS
+	teq	r0, #HVC_SET_VECTORS
 	bne	1f
 	mcr	p15, 4, r1, c12, c0, 0	@ set HVBAR
 	b	__hyp_stub_exit
@@ -247,12 +242,6 @@ ENDPROC(__hyp_stub_do_trap)
  * so you will need to set that to something sensible at the new hypervisor's
  * initialisation entry point.
  */
-ENTRY(__hyp_get_vectors)
-	mov	r0, #HVC_GET_VECTORS
-	__HVC(0)
-	ret	lr
-ENDPROC(__hyp_get_vectors)
-
 ENTRY(__hyp_set_vectors)
 	mov	r1, r0
 	mov	r0, #HVC_SET_VECTORS
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index c92e092103b2..3cff15152800 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -122,12 +122,7 @@ __do_hyp_init:
 	eret
 
 ENTRY(__kvm_handle_stub_hvc)
-	cmp	r0, #HVC_GET_VECTORS
-	bne	1f
-	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
-	b	exit
-
-1:	cmp	r0, #HVC_SOFT_RESTART
+	cmp	r0, #HVC_SOFT_RESTART
 	bne	1f
 
 	/* The target is expected in r1 */
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index b1bd316f14c0..80a1d6cd261c 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -37,10 +37,6 @@
  * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c).  Return values are
  * passed in r0 (strictly 32bit).
  *
- * A function pointer with a value of 0xffffffff has a special meaning,
- * and is used to implement __hyp_get_vectors in the same way as in
- * arch/arm/kernel/hyp_stub.S.
- *
  * The calling convention follows the standard AAPCS:
  *   r0 - r3: caller save
  *   r12:     caller save
-- 
2.11.0

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

* [PATCH v4 26/28] ARM: hyp-stub/KVM: Kill __hyp_get_vectors
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Nobody is using __hyp_get_vectors anymore, so let's remove both
implementations (hyp-stub and KVM).

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm/include/asm/virt.h | 10 ++++------
 arch/arm/kernel/hyp-stub.S  | 13 +------------
 arch/arm/kvm/init.S         |  7 +------
 arch/arm/kvm/interrupts.S   |  4 ----
 4 files changed, 6 insertions(+), 28 deletions(-)

diff --git a/arch/arm/include/asm/virt.h b/arch/arm/include/asm/virt.h
index 8d5625b790b5..5f45969d4063 100644
--- a/arch/arm/include/asm/virt.h
+++ b/arch/arm/include/asm/virt.h
@@ -53,7 +53,6 @@ static inline void sync_boot_mode(void)
 }
 
 void __hyp_set_vectors(unsigned long phys_vector_base);
-unsigned long __hyp_get_vectors(void);
 void __hyp_reset_vectors(void);
 #else
 #define __boot_cpu_mode	(SVC_MODE)
@@ -99,12 +98,11 @@ extern char __hyp_text_end[];
 
 /* Only assembly code should need those */
 
-#define HVC_GET_VECTORS 0
-#define HVC_SET_VECTORS 1
-#define HVC_SOFT_RESTART 2
-#define HVC_RESET_VECTORS 3
+#define HVC_SET_VECTORS 0
+#define HVC_SOFT_RESTART 1
+#define HVC_RESET_VECTORS 2
 
-#define HVC_STUB_HCALL_NR 4
+#define HVC_STUB_HCALL_NR 3
 
 #endif /* __ASSEMBLY__ */
 
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 3cb01e8a291d..68bf72777ac7 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -202,12 +202,7 @@ ARM_BE8(orr	r7, r7, #(1 << 25))     @ HSCTLR.EE
 ENDPROC(__hyp_stub_install_secondary)
 
 __hyp_stub_do_trap:
-	teq	r0, #HVC_GET_VECTORS
-	bne	1f
-	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
-	b	__hyp_stub_exit
-
-1:	teq	r0, #HVC_SET_VECTORS
+	teq	r0, #HVC_SET_VECTORS
 	bne	1f
 	mcr	p15, 4, r1, c12, c0, 0	@ set HVBAR
 	b	__hyp_stub_exit
@@ -247,12 +242,6 @@ ENDPROC(__hyp_stub_do_trap)
  * so you will need to set that to something sensible@the new hypervisor's
  * initialisation entry point.
  */
-ENTRY(__hyp_get_vectors)
-	mov	r0, #HVC_GET_VECTORS
-	__HVC(0)
-	ret	lr
-ENDPROC(__hyp_get_vectors)
-
 ENTRY(__hyp_set_vectors)
 	mov	r1, r0
 	mov	r0, #HVC_SET_VECTORS
diff --git a/arch/arm/kvm/init.S b/arch/arm/kvm/init.S
index c92e092103b2..3cff15152800 100644
--- a/arch/arm/kvm/init.S
+++ b/arch/arm/kvm/init.S
@@ -122,12 +122,7 @@ __do_hyp_init:
 	eret
 
 ENTRY(__kvm_handle_stub_hvc)
-	cmp	r0, #HVC_GET_VECTORS
-	bne	1f
-	mrc	p15, 4, r0, c12, c0, 0	@ get HVBAR
-	b	exit
-
-1:	cmp	r0, #HVC_SOFT_RESTART
+	cmp	r0, #HVC_SOFT_RESTART
 	bne	1f
 
 	/* The target is expected in r1 */
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index b1bd316f14c0..80a1d6cd261c 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -37,10 +37,6 @@
  * in Hyp mode (see init_hyp_mode in arch/arm/kvm/arm.c).  Return values are
  * passed in r0 (strictly 32bit).
  *
- * A function pointer with a value of 0xffffffff has a special meaning,
- * and is used to implement __hyp_get_vectors in the same way as in
- * arch/arm/kernel/hyp_stub.S.
- *
  * The calling convention follows the standard AAPCS:
  *   r0 - r3: caller save
  *   r12:     caller save
-- 
2.11.0

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

* [PATCH v4 27/28] arm64: hyp-stub/KVM: Kill __hyp_get_vectors
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

Nobody is using __hyp_get_vectors anymore, so let's remove both
implementations (hyp-stub and KVM).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/virt.h | 12 ++++--------
 arch/arm64/kernel/hyp-stub.S  | 13 +------------
 arch/arm64/kvm/hyp-init.S     |  7 +------
 arch/arm64/kvm/hyp.S          |  2 +-
 4 files changed, 7 insertions(+), 27 deletions(-)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index f24f1eb72dc0..a7c9dfdd6430 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -24,28 +24,25 @@
  * Any other value is used as a pointer to the function to call.
  */
 
-/* HVC_GET_VECTORS - Return the value of the vbar_el2 register. */
-#define HVC_GET_VECTORS 0
-
 /*
  * HVC_SET_VECTORS - Set the value of the vbar_el2 register.
  *
  * @x1: Physical address of the new vector table.
  */
-#define HVC_SET_VECTORS 1
+#define HVC_SET_VECTORS 0
 
 /*
  * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine.
  */
-#define HVC_SOFT_RESTART 2
+#define HVC_SOFT_RESTART 1
 
 /*
  * HVC_RESET_VECTORS - Restore the vectors to the original HYP stubs
  */
-#define HVC_RESET_VECTORS 3
+#define HVC_RESET_VECTORS 2
 
 /* Max number of HYP stub hypercalls */
-#define HVC_STUB_HCALL_NR 4
+#define HVC_STUB_HCALL_NR 3
 
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
@@ -69,7 +66,6 @@
 extern u32 __boot_cpu_mode[2];
 
 void __hyp_set_vectors(phys_addr_t phys_vector_base);
-phys_addr_t __hyp_get_vectors(void);
 void __hyp_reset_vectors(void);
 
 /* Reports the availability of HYP mode */
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index dd0a7522fbe1..210bd6b3849d 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -55,12 +55,7 @@ ENDPROC(__hyp_stub_vectors)
 	.align 11
 
 el1_sync:
-	cmp	x0, #HVC_GET_VECTORS
-	b.ne	1f
-	mrs	x0, vbar_el2
-	b	9f
-
-1:	cmp	x0, #HVC_SET_VECTORS
+	cmp	x0, #HVC_SET_VECTORS
 	b.ne	2f
 	msr	vbar_el2, x1
 	b	9f
@@ -118,12 +113,6 @@ ENDPROC(\label)
  * initialisation entry point.
  */
 
-ENTRY(__hyp_get_vectors)
-	mov	x0, #HVC_GET_VECTORS
-	hvc	#0
-	ret
-ENDPROC(__hyp_get_vectors)
-
 ENTRY(__hyp_set_vectors)
 	mov	x1, x0
 	mov	x0, #HVC_SET_VECTORS
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 128d6e9732b9..cf01cdb8bc61 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -124,12 +124,7 @@ __do_hyp_init:
 ENDPROC(__kvm_hyp_init)
 
 ENTRY(__kvm_handle_stub_hvc)
-	cmp	x0, #HVC_GET_VECTORS
-	b.ne	1f
-	mrs	x0, vbar_el2
-	b	exit
-
-1:	cmp	x0, #HVC_SOFT_RESTART
+	cmp	x0, #HVC_SOFT_RESTART
 	b.ne	1f
 
 	/* This is where we're about to jump, staying at EL2 */
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 2726635dceba..09391cf0c93c 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -36,7 +36,7 @@
  * passed in x0.
  *
  * A function pointer with a value less than 0xfff has a special meaning,
- * and is used to implement __hyp_get_vectors in the same way as in
+ * and is used to implement hyp stubs in the same way as in
  * arch/arm64/kernel/hyp_stub.S.
  * HVC behaves as a 'bl' call and will clobber lr.
  */
-- 
2.11.0

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

* [PATCH v4 27/28] arm64: hyp-stub/KVM: Kill __hyp_get_vectors
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

Nobody is using __hyp_get_vectors anymore, so let's remove both
implementations (hyp-stub and KVM).

Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 arch/arm64/include/asm/virt.h | 12 ++++--------
 arch/arm64/kernel/hyp-stub.S  | 13 +------------
 arch/arm64/kvm/hyp-init.S     |  7 +------
 arch/arm64/kvm/hyp.S          |  2 +-
 4 files changed, 7 insertions(+), 27 deletions(-)

diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index f24f1eb72dc0..a7c9dfdd6430 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -24,28 +24,25 @@
  * Any other value is used as a pointer to the function to call.
  */
 
-/* HVC_GET_VECTORS - Return the value of the vbar_el2 register. */
-#define HVC_GET_VECTORS 0
-
 /*
  * HVC_SET_VECTORS - Set the value of the vbar_el2 register.
  *
  * @x1: Physical address of the new vector table.
  */
-#define HVC_SET_VECTORS 1
+#define HVC_SET_VECTORS 0
 
 /*
  * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine.
  */
-#define HVC_SOFT_RESTART 2
+#define HVC_SOFT_RESTART 1
 
 /*
  * HVC_RESET_VECTORS - Restore the vectors to the original HYP stubs
  */
-#define HVC_RESET_VECTORS 3
+#define HVC_RESET_VECTORS 2
 
 /* Max number of HYP stub hypercalls */
-#define HVC_STUB_HCALL_NR 4
+#define HVC_STUB_HCALL_NR 3
 
 #define BOOT_CPU_MODE_EL1	(0xe11)
 #define BOOT_CPU_MODE_EL2	(0xe12)
@@ -69,7 +66,6 @@
 extern u32 __boot_cpu_mode[2];
 
 void __hyp_set_vectors(phys_addr_t phys_vector_base);
-phys_addr_t __hyp_get_vectors(void);
 void __hyp_reset_vectors(void);
 
 /* Reports the availability of HYP mode */
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index dd0a7522fbe1..210bd6b3849d 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -55,12 +55,7 @@ ENDPROC(__hyp_stub_vectors)
 	.align 11
 
 el1_sync:
-	cmp	x0, #HVC_GET_VECTORS
-	b.ne	1f
-	mrs	x0, vbar_el2
-	b	9f
-
-1:	cmp	x0, #HVC_SET_VECTORS
+	cmp	x0, #HVC_SET_VECTORS
 	b.ne	2f
 	msr	vbar_el2, x1
 	b	9f
@@ -118,12 +113,6 @@ ENDPROC(\label)
  * initialisation entry point.
  */
 
-ENTRY(__hyp_get_vectors)
-	mov	x0, #HVC_GET_VECTORS
-	hvc	#0
-	ret
-ENDPROC(__hyp_get_vectors)
-
 ENTRY(__hyp_set_vectors)
 	mov	x1, x0
 	mov	x0, #HVC_SET_VECTORS
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index 128d6e9732b9..cf01cdb8bc61 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -124,12 +124,7 @@ __do_hyp_init:
 ENDPROC(__kvm_hyp_init)
 
 ENTRY(__kvm_handle_stub_hvc)
-	cmp	x0, #HVC_GET_VECTORS
-	b.ne	1f
-	mrs	x0, vbar_el2
-	b	exit
-
-1:	cmp	x0, #HVC_SOFT_RESTART
+	cmp	x0, #HVC_SOFT_RESTART
 	b.ne	1f
 
 	/* This is where we're about to jump, staying at EL2 */
diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 2726635dceba..09391cf0c93c 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -36,7 +36,7 @@
  * passed in x0.
  *
  * A function pointer with a value less than 0xfff has a special meaning,
- * and is used to implement __hyp_get_vectors in the same way as in
+ * and is used to implement hyp stubs in the same way as in
  * arch/arm64/kernel/hyp_stub.S.
  * HVC behaves as a 'bl' call and will clobber lr.
  */
-- 
2.11.0

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

* [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-21 19:20   ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Russell King, Ard Biesheuvel, Catalin Marinas, Keerthy

In order to help people understanding the hyp-stub API that exists
between the host kernel and the hypervisor mode (whether a hypervisor
has been installed or not), let's document said API.

As with any form of documentation, I expect it to become obsolete
and completely misleading within 20 minutes after having being merged.

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt

diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
new file mode 100644
index 000000000000..a1e0314d2249
--- /dev/null
+++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
@@ -0,0 +1,45 @@
+* Internal ABI between the kernel and HYP
+
+This file documents the interaction between the Linux kernel and the
+hypervisor layer when running Linux as a hypervisor (for example
+KVM). It doesn't cover the interaction of the kernel with the
+hypervisor when running as a guest (under Xen, KVM or any other
+hypervisor), or any hypervisor-specific interaction when the kernel is
+used as a host.
+
+On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
+mode, but still needs to interact with it, allowing a built-in
+hypervisor to be either installed or torn down.
+
+In order to achieve this, the kernel must be booted at HYP (arm) or
+EL2 (arm64), allowing it to install a set of stubs before dropping to
+SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
+and only act on individual CPUs.
+
+Unless specified otherwise, any built-in hypervisor must implement
+these functions (see arch/arm{,64}/include/asm/virt.h):
+
+* r0/x0 = HVC_SET_VECTORS
+  r1/x1 = vectors
+
+  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
+  must be a physical address, and respect the alignment requirements
+  of the architecture. Only implemented by the initial stubs.
+
+* r0/x0 = HVC_RESET_VECTORS
+
+  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
+  value. This effectively disables an existing hypervisor.
+
+* r0/x0 = HVC_SOFT_RESTART
+  r1/x1 = restart address
+  x2 = x0's value when entering the next payload (arm64)
+  x3 = x1's value when entering the next payload (arm64)
+  x4 = x2's value when entering the next payload (arm64)
+
+  Mask all exceptions, disable the MMU, move the arguments into place
+  (arm64 only), and jump to the restart address while at HYP/EL2. This
+  hypercall is not expected to return to its caller.
+
+Any other value of r0/x0 triggers a hypervisor-specific handling,
+which is not documented here.
-- 
2.11.0

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

* [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
@ 2017-03-21 19:20   ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-21 19:20 UTC (permalink / raw)
  To: linux-arm-kernel

In order to help people understanding the hyp-stub API that exists
between the host kernel and the hypervisor mode (whether a hypervisor
has been installed or not), let's document said API.

As with any form of documentation, I expect it to become obsolete
and completely misleading within 20 minutes after having being merged.

Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
 Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)
 create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt

diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
new file mode 100644
index 000000000000..a1e0314d2249
--- /dev/null
+++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
@@ -0,0 +1,45 @@
+* Internal ABI between the kernel and HYP
+
+This file documents the interaction between the Linux kernel and the
+hypervisor layer when running Linux as a hypervisor (for example
+KVM). It doesn't cover the interaction of the kernel with the
+hypervisor when running as a guest (under Xen, KVM or any other
+hypervisor), or any hypervisor-specific interaction when the kernel is
+used as a host.
+
+On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
+mode, but still needs to interact with it, allowing a built-in
+hypervisor to be either installed or torn down.
+
+In order to achieve this, the kernel must be booted at HYP (arm) or
+EL2 (arm64), allowing it to install a set of stubs before dropping to
+SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
+and only act on individual CPUs.
+
+Unless specified otherwise, any built-in hypervisor must implement
+these functions (see arch/arm{,64}/include/asm/virt.h):
+
+* r0/x0 = HVC_SET_VECTORS
+  r1/x1 = vectors
+
+  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
+  must be a physical address, and respect the alignment requirements
+  of the architecture. Only implemented by the initial stubs.
+
+* r0/x0 = HVC_RESET_VECTORS
+
+  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
+  value. This effectively disables an existing hypervisor.
+
+* r0/x0 = HVC_SOFT_RESTART
+  r1/x1 = restart address
+  x2 = x0's value when entering the next payload (arm64)
+  x3 = x1's value when entering the next payload (arm64)
+  x4 = x2's value when entering the next payload (arm64)
+
+  Mask all exceptions, disable the MMU, move the arguments into place
+  (arm64 only), and jump to the restart address while at HYP/EL2. This
+  hypercall is not expected to return to its caller.
+
+Any other value of r0/x0 triggers a hypervisor-specific handling,
+which is not documented here.
-- 
2.11.0

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-22 13:37   ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-22 13:37 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

Hi Marc,


On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
> could do with some TLC (it cannot perform a soft-restart at HYP, and
> has holes in the hyp-stub support in a number of places). In general,
> it would be desirable for the 32bit behaviour to align on 64bit, if
> only to ease maintenance.
> 
> This series implements the following:
> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
>   __hyp_reset_vectors
> - Implement add the stub entry points in the KVM init code, which
>   didn't implement any so far
> - Convert the HYP code to use the init code stubs directly
> - Some general cleanup as a result of these changes (which includes
>   killing HVC_GET_VECTORS)
> - Add some API documentation that covers the above
> 
> Patches 12 to 14 would be better squashed into 10 and 11, but I've
> kept them separate so that I can take the blame for everything I've
> broken.

This series looks great overall.  I'm still going through the details of
the patches, but one high level questions:

What if we formalized the way to call a function in Hyp mode, whatever
its current configuration may be, via a specific HVC number.  That would
mean that the documentation say nothing of a hypervisor specific
implementaiton.

Could we then use that to initialize hyp mode for a hypervisor, i.e.
KVM, without having to actually change the vectors?  Couldn't we simply
use the the hvc stub to call a function in the physical address space,
and be rid of the concept of hyp-init alltogether?

I'm probably missing something, but let me know your thoughts.

Thanks,
-Christoffer

> 
> I've tested this on arm (Cubietruck, Jetson TK1) and arm64 (Seattle),
> both as host and guest. Keerthy has been kind enough to test the 32bit
> code on DRA7-EVM, AM57XX-EVM and KEYSTONE-K2E-EVM.
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-December/473472.html
> 
> * From v3:
>   - Reworked the way we save/restore lr on arm64, making it EL2's job
>   in a consistent way (these are the three initial patches)
>   - Collected RBs, TBs and Acks from James, Keerthy and Russell
>   - Rebased on 4.11-rc3
> 
> * From v2:
>   - Kill HVC_GET_VECTORS and the corresponding __hyp_get_vectors
> 
> * From v1:
>   - Fixed some glaring bugs (reported by Ard and James)
>   - Tidy up stub vector export on 32bit (Ard)
>   - Nicer VA/PA conversion on 32bit (Ard)
>   - Updated cpu_v7_reset documentation
>   - Cleaned up HYP reset on PM events
>   - Minor stub documentation update
> 
> Marc Zyngier (26):
>   arm64: hyp-stub: Stop pointlessly clobbering lr
>   arm64: KVM: Move lr save/restore to do_el2_call
>   arm64: hyp-stub: Don't save lr in the EL1 code
>   arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
>   arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init
>     code
>   arm64: KVM: Implement HVC_GET_VECTORS in the init code
>   arm64: KVM: Allow the main HYP code to use the init hyp stub
>     implementation
>   arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
>   arm64: KVM: Implement HVC_SOFT_RESTART in the init code
>   ARM: KVM: Convert KVM to use HVC_GET_VECTORS
>   ARM: Update cpu_v7_reset documentation
>   ARM: hyp-stub: Use r1 for the soft-restart address
>   ARM: Expose the VA/IDMAP offset
>   ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
>   ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
>   ARM: KVM: Implement HVC_GET_VECTORS in the init code
>   ARM: KVM: Allow the main HYP code to use the init hyp stub
>     implementation
>   ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
>   ARM: KVM: Implement HVC_SOFT_RESTART in the init code
>   arm/arm64: KVM: Use __hyp_reset_vectors() directly
>   arm/arm64: KVM: Remove kvm_get_idmap_start
>   arm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode
>   ARM: decompressor: Remove __hyp_get_vectors usage
>   ARM: hyp-stub/KVM: Kill __hyp_get_vectors
>   arm64: hyp-stub/KVM: Kill __hyp_get_vectors
>   arm/arm64: Add hyp-stub API documentation
> 
> Russell King (2):
>   ARM: hyp-stub: improve ABI
>   ARM: soft-reboot into same mode that we entered the kernel
> 
>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 ++++++++++++++++++++++++++++
>  arch/arm/boot/compressed/head.S           |  5 +++-
>  arch/arm/include/asm/kvm_asm.h            |  2 --
>  arch/arm/include/asm/kvm_host.h           |  6 ----
>  arch/arm/include/asm/kvm_mmu.h            |  1 -
>  arch/arm/include/asm/proc-fns.h           |  4 +--
>  arch/arm/include/asm/virt.h               | 12 +++++++-
>  arch/arm/kernel/hyp-stub.S                | 39 +++++++++++++++++++-----
>  arch/arm/kernel/reboot.c                  |  7 +++--
>  arch/arm/kvm/arm.c                        | 25 ++++++----------
>  arch/arm/kvm/hyp/hyp-entry.S              | 29 ++++++++++++++----
>  arch/arm/kvm/init.S                       | 49 ++++++++++++++++++++++++++-----
>  arch/arm/kvm/interrupts.S                 |  4 ---
>  arch/arm/kvm/mmu.c                        |  5 ----
>  arch/arm/mm/mmu.c                         |  5 ++++
>  arch/arm/mm/proc-v7.S                     | 15 ++++++----
>  arch/arm64/include/asm/kvm_asm.h          |  1 -
>  arch/arm64/include/asm/kvm_host.h         |  7 -----
>  arch/arm64/include/asm/kvm_mmu.h          |  1 -
>  arch/arm64/include/asm/virt.h             | 17 +++++++----
>  arch/arm64/kernel/hyp-stub.S              | 34 +++++++--------------
>  arch/arm64/kvm/hyp-init.S                 | 45 +++++++++++++++++++++-------
>  arch/arm64/kvm/hyp.S                      |  2 +-
>  arch/arm64/kvm/hyp/hyp-entry.S            | 43 +++++++++++++--------------
>  24 files changed, 266 insertions(+), 137 deletions(-)
>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
> 
> -- 
> 2.11.0
> 

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-22 13:37   ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-22 13:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,


On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
> could do with some TLC (it cannot perform a soft-restart at HYP, and
> has holes in the hyp-stub support in a number of places). In general,
> it would be desirable for the 32bit behaviour to align on 64bit, if
> only to ease maintenance.
> 
> This series implements the following:
> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
>   __hyp_reset_vectors
> - Implement add the stub entry points in the KVM init code, which
>   didn't implement any so far
> - Convert the HYP code to use the init code stubs directly
> - Some general cleanup as a result of these changes (which includes
>   killing HVC_GET_VECTORS)
> - Add some API documentation that covers the above
> 
> Patches 12 to 14 would be better squashed into 10 and 11, but I've
> kept them separate so that I can take the blame for everything I've
> broken.

This series looks great overall.  I'm still going through the details of
the patches, but one high level questions:

What if we formalized the way to call a function in Hyp mode, whatever
its current configuration may be, via a specific HVC number.  That would
mean that the documentation say nothing of a hypervisor specific
implementaiton.

Could we then use that to initialize hyp mode for a hypervisor, i.e.
KVM, without having to actually change the vectors?  Couldn't we simply
use the the hvc stub to call a function in the physical address space,
and be rid of the concept of hyp-init alltogether?

I'm probably missing something, but let me know your thoughts.

Thanks,
-Christoffer

> 
> I've tested this on arm (Cubietruck, Jetson TK1) and arm64 (Seattle),
> both as host and guest. Keerthy has been kind enough to test the 32bit
> code on DRA7-EVM, AM57XX-EVM and KEYSTONE-K2E-EVM.
> 
> [1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-December/473472.html
> 
> * From v3:
>   - Reworked the way we save/restore lr on arm64, making it EL2's job
>   in a consistent way (these are the three initial patches)
>   - Collected RBs, TBs and Acks from James, Keerthy and Russell
>   - Rebased on 4.11-rc3
> 
> * From v2:
>   - Kill HVC_GET_VECTORS and the corresponding __hyp_get_vectors
> 
> * From v1:
>   - Fixed some glaring bugs (reported by Ard and James)
>   - Tidy up stub vector export on 32bit (Ard)
>   - Nicer VA/PA conversion on 32bit (Ard)
>   - Updated cpu_v7_reset documentation
>   - Cleaned up HYP reset on PM events
>   - Minor stub documentation update
> 
> Marc Zyngier (26):
>   arm64: hyp-stub: Stop pointlessly clobbering lr
>   arm64: KVM: Move lr save/restore to do_el2_call
>   arm64: hyp-stub: Don't save lr in the EL1 code
>   arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
>   arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init
>     code
>   arm64: KVM: Implement HVC_GET_VECTORS in the init code
>   arm64: KVM: Allow the main HYP code to use the init hyp stub
>     implementation
>   arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
>   arm64: KVM: Implement HVC_SOFT_RESTART in the init code
>   ARM: KVM: Convert KVM to use HVC_GET_VECTORS
>   ARM: Update cpu_v7_reset documentation
>   ARM: hyp-stub: Use r1 for the soft-restart address
>   ARM: Expose the VA/IDMAP offset
>   ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
>   ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
>   ARM: KVM: Implement HVC_GET_VECTORS in the init code
>   ARM: KVM: Allow the main HYP code to use the init hyp stub
>     implementation
>   ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
>   ARM: KVM: Implement HVC_SOFT_RESTART in the init code
>   arm/arm64: KVM: Use __hyp_reset_vectors() directly
>   arm/arm64: KVM: Remove kvm_get_idmap_start
>   arm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode
>   ARM: decompressor: Remove __hyp_get_vectors usage
>   ARM: hyp-stub/KVM: Kill __hyp_get_vectors
>   arm64: hyp-stub/KVM: Kill __hyp_get_vectors
>   arm/arm64: Add hyp-stub API documentation
> 
> Russell King (2):
>   ARM: hyp-stub: improve ABI
>   ARM: soft-reboot into same mode that we entered the kernel
> 
>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 ++++++++++++++++++++++++++++
>  arch/arm/boot/compressed/head.S           |  5 +++-
>  arch/arm/include/asm/kvm_asm.h            |  2 --
>  arch/arm/include/asm/kvm_host.h           |  6 ----
>  arch/arm/include/asm/kvm_mmu.h            |  1 -
>  arch/arm/include/asm/proc-fns.h           |  4 +--
>  arch/arm/include/asm/virt.h               | 12 +++++++-
>  arch/arm/kernel/hyp-stub.S                | 39 +++++++++++++++++++-----
>  arch/arm/kernel/reboot.c                  |  7 +++--
>  arch/arm/kvm/arm.c                        | 25 ++++++----------
>  arch/arm/kvm/hyp/hyp-entry.S              | 29 ++++++++++++++----
>  arch/arm/kvm/init.S                       | 49 ++++++++++++++++++++++++++-----
>  arch/arm/kvm/interrupts.S                 |  4 ---
>  arch/arm/kvm/mmu.c                        |  5 ----
>  arch/arm/mm/mmu.c                         |  5 ++++
>  arch/arm/mm/proc-v7.S                     | 15 ++++++----
>  arch/arm64/include/asm/kvm_asm.h          |  1 -
>  arch/arm64/include/asm/kvm_host.h         |  7 -----
>  arch/arm64/include/asm/kvm_mmu.h          |  1 -
>  arch/arm64/include/asm/virt.h             | 17 +++++++----
>  arch/arm64/kernel/hyp-stub.S              | 34 +++++++--------------
>  arch/arm64/kvm/hyp-init.S                 | 45 +++++++++++++++++++++-------
>  arch/arm64/kvm/hyp.S                      |  2 +-
>  arch/arm64/kvm/hyp/hyp-entry.S            | 43 +++++++++++++--------------
>  24 files changed, 266 insertions(+), 137 deletions(-)
>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
> 
> -- 
> 2.11.0
> 

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-22 13:37   ` Christoffer Dall
@ 2017-03-22 16:14     ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-22 16:14 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: linux-arm-kernel, kvm, kvmarm, Russell King, Christoffer Dall,
	Mark Rutland, Catalin Marinas, James Morse, Ard Biesheuvel,
	Keerthy

Hi Christoffer,

On 22/03/17 13:37, Christoffer Dall wrote:
> Hi Marc,
> 
> 
> On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
>> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
>> could do with some TLC (it cannot perform a soft-restart at HYP, and
>> has holes in the hyp-stub support in a number of places). In general,
>> it would be desirable for the 32bit behaviour to align on 64bit, if
>> only to ease maintenance.
>>
>> This series implements the following:
>> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
>> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
>>   __hyp_reset_vectors
>> - Implement add the stub entry points in the KVM init code, which
>>   didn't implement any so far
>> - Convert the HYP code to use the init code stubs directly
>> - Some general cleanup as a result of these changes (which includes
>>   killing HVC_GET_VECTORS)
>> - Add some API documentation that covers the above
>>
>> Patches 12 to 14 would be better squashed into 10 and 11, but I've
>> kept them separate so that I can take the blame for everything I've
>> broken.
> 
> This series looks great overall.  I'm still going through the details of
> the patches, but one high level questions:
> 
> What if we formalized the way to call a function in Hyp mode, whatever
> its current configuration may be, via a specific HVC number.  That would
> mean that the documentation say nothing of a hypervisor specific
> implementaiton.

Do you mean an actual function call indirected via an HVC? Similar to
what we already do today for KVM when we want to call HYP functions?

> Could we then use that to initialize hyp mode for a hypervisor, i.e.
> KVM, without having to actually change the vectors?  Couldn't we simply
> use the the hvc stub to call a function in the physical address space,
> and be rid of the concept of hyp-init alltogether?

My problem here is when you say "in the physical space". Do you want to
be able to call such a function from any context? That's certainly
doable now, but I'm not completely sure of what we get.

Maybe I just don't see the use case - can you enlighten me?

Thanks,

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

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-22 16:14     ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-22 16:14 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Christoffer,

On 22/03/17 13:37, Christoffer Dall wrote:
> Hi Marc,
> 
> 
> On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
>> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
>> could do with some TLC (it cannot perform a soft-restart at HYP, and
>> has holes in the hyp-stub support in a number of places). In general,
>> it would be desirable for the 32bit behaviour to align on 64bit, if
>> only to ease maintenance.
>>
>> This series implements the following:
>> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
>> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
>>   __hyp_reset_vectors
>> - Implement add the stub entry points in the KVM init code, which
>>   didn't implement any so far
>> - Convert the HYP code to use the init code stubs directly
>> - Some general cleanup as a result of these changes (which includes
>>   killing HVC_GET_VECTORS)
>> - Add some API documentation that covers the above
>>
>> Patches 12 to 14 would be better squashed into 10 and 11, but I've
>> kept them separate so that I can take the blame for everything I've
>> broken.
> 
> This series looks great overall.  I'm still going through the details of
> the patches, but one high level questions:
> 
> What if we formalized the way to call a function in Hyp mode, whatever
> its current configuration may be, via a specific HVC number.  That would
> mean that the documentation say nothing of a hypervisor specific
> implementaiton.

Do you mean an actual function call indirected via an HVC? Similar to
what we already do today for KVM when we want to call HYP functions?

> Could we then use that to initialize hyp mode for a hypervisor, i.e.
> KVM, without having to actually change the vectors?  Couldn't we simply
> use the the hvc stub to call a function in the physical address space,
> and be rid of the concept of hyp-init alltogether?

My problem here is when you say "in the physical space". Do you want to
be able to call such a function from any context? That's certainly
doable now, but I'm not completely sure of what we get.

Maybe I just don't see the use case - can you enlighten me?

Thanks,

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

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-22 16:20   ` Catalin Marinas
  -1 siblings, 0 replies; 112+ messages in thread
From: Catalin Marinas @ 2017-03-22 16:20 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Keerthy, kvmarm, linux-arm-kernel

On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> * From v3:
>   - Reworked the way we save/restore lr on arm64, making it EL2's job
>   in a consistent way (these are the three initial patches)

Thanks for fixing up the lr use. Feel free to upstream it via the kvm
tree. For the whole series:

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

-- 
Catalin

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-22 16:20   ` Catalin Marinas
  0 siblings, 0 replies; 112+ messages in thread
From: Catalin Marinas @ 2017-03-22 16:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> * From v3:
>   - Reworked the way we save/restore lr on arm64, making it EL2's job
>   in a consistent way (these are the three initial patches)

Thanks for fixing up the lr use. Feel free to upstream it via the kvm
tree. For the whole series:

Acked-by: Catalin Marinas <catalin.marinas@arm.com>

-- 
Catalin

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-22 16:14     ` Marc Zyngier
@ 2017-03-22 17:27       ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-22 17:27 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Wed, Mar 22, 2017 at 04:14:44PM +0000, Marc Zyngier wrote:
> Hi Christoffer,
> 
> On 22/03/17 13:37, Christoffer Dall wrote:
> > Hi Marc,
> > 
> > 
> > On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> >> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
> >> could do with some TLC (it cannot perform a soft-restart at HYP, and
> >> has holes in the hyp-stub support in a number of places). In general,
> >> it would be desirable for the 32bit behaviour to align on 64bit, if
> >> only to ease maintenance.
> >>
> >> This series implements the following:
> >> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
> >> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
> >>   __hyp_reset_vectors
> >> - Implement add the stub entry points in the KVM init code, which
> >>   didn't implement any so far
> >> - Convert the HYP code to use the init code stubs directly
> >> - Some general cleanup as a result of these changes (which includes
> >>   killing HVC_GET_VECTORS)
> >> - Add some API documentation that covers the above
> >>
> >> Patches 12 to 14 would be better squashed into 10 and 11, but I've
> >> kept them separate so that I can take the blame for everything I've
> >> broken.
> > 
> > This series looks great overall.  I'm still going through the details of
> > the patches, but one high level questions:
> > 
> > What if we formalized the way to call a function in Hyp mode, whatever
> > its current configuration may be, via a specific HVC number.  That would
> > mean that the documentation say nothing of a hypervisor specific
> > implementaiton.
> 
> Do you mean an actual function call indirected via an HVC? Similar to
> what we already do today for KVM when we want to call HYP functions?

Yes exactly.  One question would be how to standardize that if the
caller is not tied to the thing owning Hyp, making it unclear if it can
rely on the thing working or not, but I'm not sure if that's any worse
than what we have today.

> > Could we then use that to initialize hyp mode for a hypervisor, i.e.
> > KVM, without having to actually change the vectors?  Couldn't we simply
> > use the the hvc stub to call a function in the physical address space,
> > and be rid of the concept of hyp-init alltogether?
> 
> My problem here is when you say "in the physical space". Do you want to
> be able to call such a function from any context? That's certainly
> doable now, but I'm not completely sure of what we get.
> 
> Maybe I just don't see the use case - can you enlighten me?
> 

I don't think there is a great use case beyond what we already do, it
would just be to have one set of hyp vectors fewer, so that either the
hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.

So instead of doing:
  __hyp_set_vectors(kvm_get_idmap_vector());
  hvc(); /* via the misused kvm_call_hyp thing */

you would do:

  __hyp_call_function(__kvm_hyp_init, arg1, arg2);

which would change the vector and initialize anything.

Not sure if that can work though, or if there are any downsides that I
haven't thought about?

Thanks,
-Christoffer

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-22 17:27       ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-22 17:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 22, 2017 at 04:14:44PM +0000, Marc Zyngier wrote:
> Hi Christoffer,
> 
> On 22/03/17 13:37, Christoffer Dall wrote:
> > Hi Marc,
> > 
> > 
> > On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> >> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
> >> could do with some TLC (it cannot perform a soft-restart at HYP, and
> >> has holes in the hyp-stub support in a number of places). In general,
> >> it would be desirable for the 32bit behaviour to align on 64bit, if
> >> only to ease maintenance.
> >>
> >> This series implements the following:
> >> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
> >> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
> >>   __hyp_reset_vectors
> >> - Implement add the stub entry points in the KVM init code, which
> >>   didn't implement any so far
> >> - Convert the HYP code to use the init code stubs directly
> >> - Some general cleanup as a result of these changes (which includes
> >>   killing HVC_GET_VECTORS)
> >> - Add some API documentation that covers the above
> >>
> >> Patches 12 to 14 would be better squashed into 10 and 11, but I've
> >> kept them separate so that I can take the blame for everything I've
> >> broken.
> > 
> > This series looks great overall.  I'm still going through the details of
> > the patches, but one high level questions:
> > 
> > What if we formalized the way to call a function in Hyp mode, whatever
> > its current configuration may be, via a specific HVC number.  That would
> > mean that the documentation say nothing of a hypervisor specific
> > implementaiton.
> 
> Do you mean an actual function call indirected via an HVC? Similar to
> what we already do today for KVM when we want to call HYP functions?

Yes exactly.  One question would be how to standardize that if the
caller is not tied to the thing owning Hyp, making it unclear if it can
rely on the thing working or not, but I'm not sure if that's any worse
than what we have today.

> > Could we then use that to initialize hyp mode for a hypervisor, i.e.
> > KVM, without having to actually change the vectors?  Couldn't we simply
> > use the the hvc stub to call a function in the physical address space,
> > and be rid of the concept of hyp-init alltogether?
> 
> My problem here is when you say "in the physical space". Do you want to
> be able to call such a function from any context? That's certainly
> doable now, but I'm not completely sure of what we get.
> 
> Maybe I just don't see the use case - can you enlighten me?
> 

I don't think there is a great use case beyond what we already do, it
would just be to have one set of hyp vectors fewer, so that either the
hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.

So instead of doing:
  __hyp_set_vectors(kvm_get_idmap_vector());
  hvc(); /* via the misused kvm_call_hyp thing */

you would do:

  __hyp_call_function(__kvm_hyp_init, arg1, arg2);

which would change the vector and initialize anything.

Not sure if that can work though, or if there are any downsides that I
haven't thought about?

Thanks,
-Christoffer

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-22 17:27       ` Christoffer Dall
@ 2017-03-23 10:53         ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-23 10:53 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On 22/03/17 17:27, Christoffer Dall wrote:
> On Wed, Mar 22, 2017 at 04:14:44PM +0000, Marc Zyngier wrote:
>> Hi Christoffer,
>>
>> On 22/03/17 13:37, Christoffer Dall wrote:
>>> Hi Marc,
>>>
>>>
>>> On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
>>>> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
>>>> could do with some TLC (it cannot perform a soft-restart at HYP, and
>>>> has holes in the hyp-stub support in a number of places). In general,
>>>> it would be desirable for the 32bit behaviour to align on 64bit, if
>>>> only to ease maintenance.
>>>>
>>>> This series implements the following:
>>>> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
>>>> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
>>>>   __hyp_reset_vectors
>>>> - Implement add the stub entry points in the KVM init code, which
>>>>   didn't implement any so far
>>>> - Convert the HYP code to use the init code stubs directly
>>>> - Some general cleanup as a result of these changes (which includes
>>>>   killing HVC_GET_VECTORS)
>>>> - Add some API documentation that covers the above
>>>>
>>>> Patches 12 to 14 would be better squashed into 10 and 11, but I've
>>>> kept them separate so that I can take the blame for everything I've
>>>> broken.
>>>
>>> This series looks great overall.  I'm still going through the details of
>>> the patches, but one high level questions:
>>>
>>> What if we formalized the way to call a function in Hyp mode, whatever
>>> its current configuration may be, via a specific HVC number.  That would
>>> mean that the documentation say nothing of a hypervisor specific
>>> implementaiton.
>>
>> Do you mean an actual function call indirected via an HVC? Similar to
>> what we already do today for KVM when we want to call HYP functions?
> 
> Yes exactly.  One question would be how to standardize that if the
> caller is not tied to the thing owning Hyp, making it unclear if it can
> rely on the thing working or not, but I'm not sure if that's any worse
> than what we have today.
> 
>>> Could we then use that to initialize hyp mode for a hypervisor, i.e.
>>> KVM, without having to actually change the vectors?  Couldn't we simply
>>> use the the hvc stub to call a function in the physical address space,
>>> and be rid of the concept of hyp-init alltogether?
>>
>> My problem here is when you say "in the physical space". Do you want to
>> be able to call such a function from any context? That's certainly
>> doable now, but I'm not completely sure of what we get.
>>
>> Maybe I just don't see the use case - can you enlighten me?
>>
> 
> I don't think there is a great use case beyond what we already do, it
> would just be to have one set of hyp vectors fewer, so that either the
> hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.
> 
> So instead of doing:
>   __hyp_set_vectors(kvm_get_idmap_vector());
>   hvc(); /* via the misused kvm_call_hyp thing */
> 
> you would do:
> 
>   __hyp_call_function(__kvm_hyp_init, arg1, arg2);
> 
> which would change the vector and initialize anything.
> 
> Not sure if that can work though, or if there are any downsides that I
> haven't thought about?

I've given it a go, and that seems to work, at least on arm64. We may 
have to set the vectors in a slightly different way on 32bit because 
we're going to run out of registers (we only have two left once we 
reach the function being called).

Another thing is that the function called is not really a function. It 
is an exception handler, as it has to end with an eret (or we may need 
to save LR in funky ways). The potential blocker for this is that the
32bit decompressor does use set_vectors in funky ways to deal with
relocation. If we get rid of set_vectors like I just did on 64bit,
we'll need to mess with that as well.

Anyway, here's the hack, 64bit only, quickly tested on Mustang. I'm not
completely sure this is any prettier, but it is certainly manageable.

Thoughts?

        M.

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index cbd3a3150090..9594e0acb331 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -1092,17 +1092,12 @@ static void cpu_init_hyp_mode(void *dummy)
 	phys_addr_t pgd_ptr;
 	unsigned long hyp_stack_ptr;
 	unsigned long stack_page;
-	unsigned long vector_ptr;
-
-	/* Switch from the HYP stub to our own HYP init vector */
-	__hyp_set_vectors(kvm_get_idmap_vector());
 
 	pgd_ptr = kvm_mmu_get_httbr();
 	stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
 	hyp_stack_ptr = stack_page + PAGE_SIZE;
-	vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
 
-	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
+	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr);
 	__cpu_init_stage2();
 
 	if (is_kernel_in_hyp_mode())
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 578df18f66b7..b314c77adfc1 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -339,6 +339,8 @@ void kvm_arm_resume_vcpu(struct kvm_vcpu *vcpu);
 
 u64 __kvm_call_hyp(void *hypfn, ...);
 #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__)
+u64 __hyp_call_func(void *hypfn, ...);
+#define hyp_call_func(f, ...) __hyp_call_func(kvm_ksym_ref(f), ##__VA_ARGS__)
 
 void force_vm_exit(const cpumask_t *mask);
 void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
@@ -352,14 +354,14 @@ int kvm_perf_teardown(void);
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
 
 static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
-				       unsigned long hyp_stack_ptr,
-				       unsigned long vector_ptr)
+				       unsigned long hyp_stack_ptr)
 {
 	/*
 	 * Call initialization code, and switch to the full blown
 	 * HYP code.
 	 */
-	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
+	__hyp_call_func(__kvm_hyp_init, pgd_ptr, hyp_stack_ptr,
+			kvm_ksym_ref(__kvm_hyp_vector));
 }
 
 static inline void kvm_arch_hardware_unsetup(void) {}
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index a7c9dfdd6430..478a64545f37 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -25,11 +25,12 @@
  */
 
 /*
- * HVC_SET_VECTORS - Set the value of the vbar_el2 register.
+ * HVC_CALL_FUNC - Call a function in the idmap
  *
- * @x1: Physical address of the new vector table.
+ * @x1: function address
+ * @x2-x5: parameters
  */
-#define HVC_SET_VECTORS 0
+#define HVC_CALL_FUNC	 0
 
 /*
  * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine.
@@ -41,6 +42,7 @@
  */
 #define HVC_RESET_VECTORS 2
 
+
 /* Max number of HYP stub hypercalls */
 #define HVC_STUB_HCALL_NR 3
 
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 210bd6b3849d..d99968333da1 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -55,10 +55,17 @@ ENDPROC(__hyp_stub_vectors)
 	.align 11
 
 el1_sync:
-	cmp	x0, #HVC_SET_VECTORS
+	cmp	x0, #HVC_CALL_FUNC
 	b.ne	2f
-	msr	vbar_el2, x1
-	b	9f
+	mov	x7, x1
+	mov	x0, x2
+	mov	x1, x3
+	mov	x2, x4
+	mov	x3, x5
+	mov	x4, x6
+	ldr_l	x6, kimage_voffset
+	sub	x7, x7, x6
+	br	x7
 
 2:	cmp	x0, #HVC_SOFT_RESTART
 	b.ne	3f
@@ -93,12 +100,7 @@ ENDPROC(\label)
 	invalid_vector	el1_error_invalid
 
 /*
- * __hyp_set_vectors: Call this after boot to set the initial hypervisor
- * vectors as part of hypervisor installation.  On an SMP system, this should
- * be called on each CPU.
- *
- * x0 must be the physical address of the new vector table, and must be
- * 2KB aligned.
+ * FIXME: Document __hyp_call_func...
  *
  * Before calling this, you must check that the stub hypervisor is installed
  * everywhere, by waiting for any secondary CPUs to be brought up and then
@@ -113,15 +115,20 @@ ENDPROC(\label)
  * initialisation entry point.
  */
 
-ENTRY(__hyp_set_vectors)
-	mov	x1, x0
-	mov	x0, #HVC_SET_VECTORS
-	hvc	#0
-	ret
-ENDPROC(__hyp_set_vectors)
-
 ENTRY(__hyp_reset_vectors)
 	mov	x0, #HVC_RESET_VECTORS
 	hvc	#0
 	ret
 ENDPROC(__hyp_reset_vectors)
+
+ENTRY(__hyp_call_func)
+	mov	x6, x5
+	mov	x5, x4
+	mov	x4, x3
+	mov	x3, x2
+	mov	x2, x1
+	mov	x1, x0
+	mov	x0, #HVC_CALL_FUNC
+	hvc	#0
+	ret
+ENDPROC(__hyp_call_func)
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index cf01cdb8bc61..aa48a30178c4 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -30,35 +30,11 @@
 	.align	11
 
 ENTRY(__kvm_hyp_init)
-	ventry	__invalid		// Synchronous EL2t
-	ventry	__invalid		// IRQ EL2t
-	ventry	__invalid		// FIQ EL2t
-	ventry	__invalid		// Error EL2t
-
-	ventry	__invalid		// Synchronous EL2h
-	ventry	__invalid		// IRQ EL2h
-	ventry	__invalid		// FIQ EL2h
-	ventry	__invalid		// Error EL2h
-
-	ventry	__do_hyp_init		// Synchronous 64-bit EL1
-	ventry	__invalid		// IRQ 64-bit EL1
-	ventry	__invalid		// FIQ 64-bit EL1
-	ventry	__invalid		// Error 64-bit EL1
-
-	ventry	__invalid		// Synchronous 32-bit EL1
-	ventry	__invalid		// IRQ 32-bit EL1
-	ventry	__invalid		// FIQ 32-bit EL1
-	ventry	__invalid		// Error 32-bit EL1
-
-__invalid:
-	b	.
-
 	/*
 	 * x0: HYP pgd
 	 * x1: HYP stack
 	 * x2: HYP vectors
 	 */
-__do_hyp_init:
 	/* Check for a stub HVC call */
 	cmp	x0, #HVC_STUB_HCALL_NR
 	b.lo	__kvm_handle_stub_hvc

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

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-23 10:53         ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-23 10:53 UTC (permalink / raw)
  To: linux-arm-kernel

On 22/03/17 17:27, Christoffer Dall wrote:
> On Wed, Mar 22, 2017 at 04:14:44PM +0000, Marc Zyngier wrote:
>> Hi Christoffer,
>>
>> On 22/03/17 13:37, Christoffer Dall wrote:
>>> Hi Marc,
>>>
>>>
>>> On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
>>>> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
>>>> could do with some TLC (it cannot perform a soft-restart at HYP, and
>>>> has holes in the hyp-stub support in a number of places). In general,
>>>> it would be desirable for the 32bit behaviour to align on 64bit, if
>>>> only to ease maintenance.
>>>>
>>>> This series implements the following:
>>>> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
>>>> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
>>>>   __hyp_reset_vectors
>>>> - Implement add the stub entry points in the KVM init code, which
>>>>   didn't implement any so far
>>>> - Convert the HYP code to use the init code stubs directly
>>>> - Some general cleanup as a result of these changes (which includes
>>>>   killing HVC_GET_VECTORS)
>>>> - Add some API documentation that covers the above
>>>>
>>>> Patches 12 to 14 would be better squashed into 10 and 11, but I've
>>>> kept them separate so that I can take the blame for everything I've
>>>> broken.
>>>
>>> This series looks great overall.  I'm still going through the details of
>>> the patches, but one high level questions:
>>>
>>> What if we formalized the way to call a function in Hyp mode, whatever
>>> its current configuration may be, via a specific HVC number.  That would
>>> mean that the documentation say nothing of a hypervisor specific
>>> implementaiton.
>>
>> Do you mean an actual function call indirected via an HVC? Similar to
>> what we already do today for KVM when we want to call HYP functions?
> 
> Yes exactly.  One question would be how to standardize that if the
> caller is not tied to the thing owning Hyp, making it unclear if it can
> rely on the thing working or not, but I'm not sure if that's any worse
> than what we have today.
> 
>>> Could we then use that to initialize hyp mode for a hypervisor, i.e.
>>> KVM, without having to actually change the vectors?  Couldn't we simply
>>> use the the hvc stub to call a function in the physical address space,
>>> and be rid of the concept of hyp-init alltogether?
>>
>> My problem here is when you say "in the physical space". Do you want to
>> be able to call such a function from any context? That's certainly
>> doable now, but I'm not completely sure of what we get.
>>
>> Maybe I just don't see the use case - can you enlighten me?
>>
> 
> I don't think there is a great use case beyond what we already do, it
> would just be to have one set of hyp vectors fewer, so that either the
> hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.
> 
> So instead of doing:
>   __hyp_set_vectors(kvm_get_idmap_vector());
>   hvc(); /* via the misused kvm_call_hyp thing */
> 
> you would do:
> 
>   __hyp_call_function(__kvm_hyp_init, arg1, arg2);
> 
> which would change the vector and initialize anything.
> 
> Not sure if that can work though, or if there are any downsides that I
> haven't thought about?

I've given it a go, and that seems to work, at least on arm64. We may 
have to set the vectors in a slightly different way on 32bit because 
we're going to run out of registers (we only have two left once we 
reach the function being called).

Another thing is that the function called is not really a function. It 
is an exception handler, as it has to end with an eret (or we may need 
to save LR in funky ways). The potential blocker for this is that the
32bit decompressor does use set_vectors in funky ways to deal with
relocation. If we get rid of set_vectors like I just did on 64bit,
we'll need to mess with that as well.

Anyway, here's the hack, 64bit only, quickly tested on Mustang. I'm not
completely sure this is any prettier, but it is certainly manageable.

Thoughts?

        M.

diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index cbd3a3150090..9594e0acb331 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -1092,17 +1092,12 @@ static void cpu_init_hyp_mode(void *dummy)
 	phys_addr_t pgd_ptr;
 	unsigned long hyp_stack_ptr;
 	unsigned long stack_page;
-	unsigned long vector_ptr;
-
-	/* Switch from the HYP stub to our own HYP init vector */
-	__hyp_set_vectors(kvm_get_idmap_vector());
 
 	pgd_ptr = kvm_mmu_get_httbr();
 	stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
 	hyp_stack_ptr = stack_page + PAGE_SIZE;
-	vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
 
-	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
+	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr);
 	__cpu_init_stage2();
 
 	if (is_kernel_in_hyp_mode())
diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
index 578df18f66b7..b314c77adfc1 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -339,6 +339,8 @@ void kvm_arm_resume_vcpu(struct kvm_vcpu *vcpu);
 
 u64 __kvm_call_hyp(void *hypfn, ...);
 #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__)
+u64 __hyp_call_func(void *hypfn, ...);
+#define hyp_call_func(f, ...) __hyp_call_func(kvm_ksym_ref(f), ##__VA_ARGS__)
 
 void force_vm_exit(const cpumask_t *mask);
 void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
@@ -352,14 +354,14 @@ int kvm_perf_teardown(void);
 struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
 
 static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
-				       unsigned long hyp_stack_ptr,
-				       unsigned long vector_ptr)
+				       unsigned long hyp_stack_ptr)
 {
 	/*
 	 * Call initialization code, and switch to the full blown
 	 * HYP code.
 	 */
-	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
+	__hyp_call_func(__kvm_hyp_init, pgd_ptr, hyp_stack_ptr,
+			kvm_ksym_ref(__kvm_hyp_vector));
 }
 
 static inline void kvm_arch_hardware_unsetup(void) {}
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index a7c9dfdd6430..478a64545f37 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -25,11 +25,12 @@
  */
 
 /*
- * HVC_SET_VECTORS - Set the value of the vbar_el2 register.
+ * HVC_CALL_FUNC - Call a function in the idmap
  *
- * @x1: Physical address of the new vector table.
+ * @x1: function address
+ * @x2-x5: parameters
  */
-#define HVC_SET_VECTORS 0
+#define HVC_CALL_FUNC	 0
 
 /*
  * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine.
@@ -41,6 +42,7 @@
  */
 #define HVC_RESET_VECTORS 2
 
+
 /* Max number of HYP stub hypercalls */
 #define HVC_STUB_HCALL_NR 3
 
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 210bd6b3849d..d99968333da1 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -55,10 +55,17 @@ ENDPROC(__hyp_stub_vectors)
 	.align 11
 
 el1_sync:
-	cmp	x0, #HVC_SET_VECTORS
+	cmp	x0, #HVC_CALL_FUNC
 	b.ne	2f
-	msr	vbar_el2, x1
-	b	9f
+	mov	x7, x1
+	mov	x0, x2
+	mov	x1, x3
+	mov	x2, x4
+	mov	x3, x5
+	mov	x4, x6
+	ldr_l	x6, kimage_voffset
+	sub	x7, x7, x6
+	br	x7
 
 2:	cmp	x0, #HVC_SOFT_RESTART
 	b.ne	3f
@@ -93,12 +100,7 @@ ENDPROC(\label)
 	invalid_vector	el1_error_invalid
 
 /*
- * __hyp_set_vectors: Call this after boot to set the initial hypervisor
- * vectors as part of hypervisor installation.  On an SMP system, this should
- * be called on each CPU.
- *
- * x0 must be the physical address of the new vector table, and must be
- * 2KB aligned.
+ * FIXME: Document __hyp_call_func...
  *
  * Before calling this, you must check that the stub hypervisor is installed
  * everywhere, by waiting for any secondary CPUs to be brought up and then
@@ -113,15 +115,20 @@ ENDPROC(\label)
  * initialisation entry point.
  */
 
-ENTRY(__hyp_set_vectors)
-	mov	x1, x0
-	mov	x0, #HVC_SET_VECTORS
-	hvc	#0
-	ret
-ENDPROC(__hyp_set_vectors)
-
 ENTRY(__hyp_reset_vectors)
 	mov	x0, #HVC_RESET_VECTORS
 	hvc	#0
 	ret
 ENDPROC(__hyp_reset_vectors)
+
+ENTRY(__hyp_call_func)
+	mov	x6, x5
+	mov	x5, x4
+	mov	x4, x3
+	mov	x3, x2
+	mov	x2, x1
+	mov	x1, x0
+	mov	x0, #HVC_CALL_FUNC
+	hvc	#0
+	ret
+ENDPROC(__hyp_call_func)
diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
index cf01cdb8bc61..aa48a30178c4 100644
--- a/arch/arm64/kvm/hyp-init.S
+++ b/arch/arm64/kvm/hyp-init.S
@@ -30,35 +30,11 @@
 	.align	11
 
 ENTRY(__kvm_hyp_init)
-	ventry	__invalid		// Synchronous EL2t
-	ventry	__invalid		// IRQ EL2t
-	ventry	__invalid		// FIQ EL2t
-	ventry	__invalid		// Error EL2t
-
-	ventry	__invalid		// Synchronous EL2h
-	ventry	__invalid		// IRQ EL2h
-	ventry	__invalid		// FIQ EL2h
-	ventry	__invalid		// Error EL2h
-
-	ventry	__do_hyp_init		// Synchronous 64-bit EL1
-	ventry	__invalid		// IRQ 64-bit EL1
-	ventry	__invalid		// FIQ 64-bit EL1
-	ventry	__invalid		// Error 64-bit EL1
-
-	ventry	__invalid		// Synchronous 32-bit EL1
-	ventry	__invalid		// IRQ 32-bit EL1
-	ventry	__invalid		// FIQ 32-bit EL1
-	ventry	__invalid		// Error 32-bit EL1
-
-__invalid:
-	b	.
-
 	/*
 	 * x0: HYP pgd
 	 * x1: HYP stack
 	 * x2: HYP vectors
 	 */
-__do_hyp_init:
 	/* Check for a stub HVC call */
 	cmp	x0, #HVC_STUB_HCALL_NR
 	b.lo	__kvm_handle_stub_hvc

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

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

* Re: [PATCH v4 02/28] arm64: KVM: Move lr save/restore to do_el2_call
  2017-03-21 19:20   ` Marc Zyngier
@ 2017-03-23 11:57     ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-23 11:57 UTC (permalink / raw)
  To: linux-arm-kernel, kvm, kvmarm
  Cc: Catalin Marinas, Keerthy, Russell King, Ard Biesheuvel

On 21/03/17 19:20, Marc Zyngier wrote:
> At the moment, we only save/restore lr if on VHE, as we rely only
> the EL1 code to have preserved it in the non-VHE case.
> 
> As we're about to get rid of the latter, let's move the save/restore
> code to the do_el2_call macro, unifying both code paths.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/kvm/hyp/hyp-entry.S | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> index 5e9052f087f2..d8ef788646c6 100644
> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> @@ -32,17 +32,17 @@
>  	 * Shuffle the parameters before calling the function
>  	 * pointed to in x0. Assumes parameters in x[1,2,3].
>  	 */
> +	str	lr, [sp, #-16]!
>  	mov	lr, x0
>  	mov	x0, x1
>  	mov	x1, x2
>  	mov	x2, x3
>  	blr	lr
> +	ldr	lr, [sp], #16
>  .endm
>  
>  ENTRY(__vhe_hyp_call)
> -	str	lr, [sp, #-16]!
>  	do_el2_call
> -	ldr	lr, [sp], #16
>  	/*
>  	 * We used to rely on having an exception return to get
>  	 * an implicit isb. In the E2H case, we don't have it anymore.
> 

As a follow-up on this patch, here's a nit I missed where we were still 
saving lr in the EL2 entry code. Doesn't affect functionality, but 
might as well clean that one up (and kill an obscure comment):

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 09391cf0c93c..952f6cb9cf72 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -38,13 +38,10 @@
  * A function pointer with a value less than 0xfff has a special meaning,
  * and is used to implement hyp stubs in the same way as in
  * arch/arm64/kernel/hyp_stub.S.
- * HVC behaves as a 'bl' call and will clobber lr.
  */
 ENTRY(__kvm_call_hyp)
 alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
-	str     lr, [sp, #-16]!
 	hvc	#0
-	ldr     lr, [sp], #16
 	ret
 alternative_else_nop_endif
 	b	__vhe_hyp_call

I'll squash it locally.

Thanks,

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

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

* [PATCH v4 02/28] arm64: KVM: Move lr save/restore to do_el2_call
@ 2017-03-23 11:57     ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-23 11:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 21/03/17 19:20, Marc Zyngier wrote:
> At the moment, we only save/restore lr if on VHE, as we rely only
> the EL1 code to have preserved it in the non-VHE case.
> 
> As we're about to get rid of the latter, let's move the save/restore
> code to the do_el2_call macro, unifying both code paths.
> 
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/kvm/hyp/hyp-entry.S | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> index 5e9052f087f2..d8ef788646c6 100644
> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> @@ -32,17 +32,17 @@
>  	 * Shuffle the parameters before calling the function
>  	 * pointed to in x0. Assumes parameters in x[1,2,3].
>  	 */
> +	str	lr, [sp, #-16]!
>  	mov	lr, x0
>  	mov	x0, x1
>  	mov	x1, x2
>  	mov	x2, x3
>  	blr	lr
> +	ldr	lr, [sp], #16
>  .endm
>  
>  ENTRY(__vhe_hyp_call)
> -	str	lr, [sp, #-16]!
>  	do_el2_call
> -	ldr	lr, [sp], #16
>  	/*
>  	 * We used to rely on having an exception return to get
>  	 * an implicit isb. In the E2H case, we don't have it anymore.
> 

As a follow-up on this patch, here's a nit I missed where we were still 
saving lr in the EL2 entry code. Doesn't affect functionality, but 
might as well clean that one up (and kill an obscure comment):

diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S
index 09391cf0c93c..952f6cb9cf72 100644
--- a/arch/arm64/kvm/hyp.S
+++ b/arch/arm64/kvm/hyp.S
@@ -38,13 +38,10 @@
  * A function pointer with a value less than 0xfff has a special meaning,
  * and is used to implement hyp stubs in the same way as in
  * arch/arm64/kernel/hyp_stub.S.
- * HVC behaves as a 'bl' call and will clobber lr.
  */
 ENTRY(__kvm_call_hyp)
 alternative_if_not ARM64_HAS_VIRT_HOST_EXTN
-	str     lr, [sp, #-16]!
 	hvc	#0
-	ldr     lr, [sp], #16
 	ret
 alternative_else_nop_endif
 	b	__vhe_hyp_call

I'll squash it locally.

Thanks,

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

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-23 10:53         ` Marc Zyngier
@ 2017-03-23 14:39           ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-23 14:39 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Thu, Mar 23, 2017 at 10:53:04AM +0000, Marc Zyngier wrote:
> On 22/03/17 17:27, Christoffer Dall wrote:
> > On Wed, Mar 22, 2017 at 04:14:44PM +0000, Marc Zyngier wrote:
> >> Hi Christoffer,
> >>
> >> On 22/03/17 13:37, Christoffer Dall wrote:
> >>> Hi Marc,
> >>>
> >>>
> >>> On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> >>>> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
> >>>> could do with some TLC (it cannot perform a soft-restart at HYP, and
> >>>> has holes in the hyp-stub support in a number of places). In general,
> >>>> it would be desirable for the 32bit behaviour to align on 64bit, if
> >>>> only to ease maintenance.
> >>>>
> >>>> This series implements the following:
> >>>> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
> >>>> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
> >>>>   __hyp_reset_vectors
> >>>> - Implement add the stub entry points in the KVM init code, which
> >>>>   didn't implement any so far
> >>>> - Convert the HYP code to use the init code stubs directly
> >>>> - Some general cleanup as a result of these changes (which includes
> >>>>   killing HVC_GET_VECTORS)
> >>>> - Add some API documentation that covers the above
> >>>>
> >>>> Patches 12 to 14 would be better squashed into 10 and 11, but I've
> >>>> kept them separate so that I can take the blame for everything I've
> >>>> broken.
> >>>
> >>> This series looks great overall.  I'm still going through the details of
> >>> the patches, but one high level questions:
> >>>
> >>> What if we formalized the way to call a function in Hyp mode, whatever
> >>> its current configuration may be, via a specific HVC number.  That would
> >>> mean that the documentation say nothing of a hypervisor specific
> >>> implementaiton.
> >>
> >> Do you mean an actual function call indirected via an HVC? Similar to
> >> what we already do today for KVM when we want to call HYP functions?
> > 
> > Yes exactly.  One question would be how to standardize that if the
> > caller is not tied to the thing owning Hyp, making it unclear if it can
> > rely on the thing working or not, but I'm not sure if that's any worse
> > than what we have today.
> > 
> >>> Could we then use that to initialize hyp mode for a hypervisor, i.e.
> >>> KVM, without having to actually change the vectors?  Couldn't we simply
> >>> use the the hvc stub to call a function in the physical address space,
> >>> and be rid of the concept of hyp-init alltogether?
> >>
> >> My problem here is when you say "in the physical space". Do you want to
> >> be able to call such a function from any context? That's certainly
> >> doable now, but I'm not completely sure of what we get.
> >>
> >> Maybe I just don't see the use case - can you enlighten me?
> >>
> > 
> > I don't think there is a great use case beyond what we already do, it
> > would just be to have one set of hyp vectors fewer, so that either the
> > hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.
> > 
> > So instead of doing:
> >   __hyp_set_vectors(kvm_get_idmap_vector());
> >   hvc(); /* via the misused kvm_call_hyp thing */
> > 
> > you would do:
> > 
> >   __hyp_call_function(__kvm_hyp_init, arg1, arg2);
> > 
> > which would change the vector and initialize anything.
> > 
> > Not sure if that can work though, or if there are any downsides that I
> > haven't thought about?
> 
> I've given it a go, and that seems to work, at least on arm64. We may 
> have to set the vectors in a slightly different way on 32bit because 
> we're going to run out of registers (we only have two left once we 
> reach the function being called).

Right, that's a challenge I clearly didn't foresee.

> 
> Another thing is that the function called is not really a function. It 
> is an exception handler, as it has to end with an eret (or we may need 
> to save LR in funky ways).

Shouldn't it have the same semantics as the KVM calling function thing
where it pushes the LR on the stack?  But of course, that requires
having a stack for each runtime that owns hyp mode at any given time.
Potentially not great.

If possible, the idea would be that you'd call functions, just like you
normally do, but the functions you call can choose to never return -
again just like a C function can do if it messes with your machine
configuration.

But maybe the idea is fundamentally flawed, if the only function
you'd ever call from the hyp stub is one that takes over the hyp world,
and then the original design was just based on using set_vectors.  Hmmm.


>  The potential blocker for this is that the
> 32bit decompressor does use set_vectors in funky ways to deal with
> relocation. If we get rid of set_vectors like I just did on 64bit,
> we'll need to mess with that as well.

Interesting.  I didn't think that we'd necessarily get rid of
set_vectors, but I agree with you that if we wanted to do this, it
should probably go.

> 
> Anyway, here's the hack, 64bit only, quickly tested on Mustang. I'm not
> completely sure this is any prettier, but it is certainly manageable.

There are two things I like about it.  First, it gets rid of the
'additional runtime' in hyp and second the changes to
cpu_init_hyp_mode() are quite nice, imho.

Thanks being said, this series is pretty nice as it is, so I don't want
to impose more work on you at the moment, so maybe we save your patch
snipped below for later if we want to consider looking at it some other
time?

Thanks,
-Christoffer

> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index cbd3a3150090..9594e0acb331 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -1092,17 +1092,12 @@ static void cpu_init_hyp_mode(void *dummy)
>  	phys_addr_t pgd_ptr;
>  	unsigned long hyp_stack_ptr;
>  	unsigned long stack_page;
> -	unsigned long vector_ptr;
> -
> -	/* Switch from the HYP stub to our own HYP init vector */
> -	__hyp_set_vectors(kvm_get_idmap_vector());
>  
>  	pgd_ptr = kvm_mmu_get_httbr();
>  	stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
>  	hyp_stack_ptr = stack_page + PAGE_SIZE;
> -	vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
>  
> -	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
> +	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr);
>  	__cpu_init_stage2();
>  
>  	if (is_kernel_in_hyp_mode())
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 578df18f66b7..b314c77adfc1 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -339,6 +339,8 @@ void kvm_arm_resume_vcpu(struct kvm_vcpu *vcpu);
>  
>  u64 __kvm_call_hyp(void *hypfn, ...);
>  #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__)
> +u64 __hyp_call_func(void *hypfn, ...);
> +#define hyp_call_func(f, ...) __hyp_call_func(kvm_ksym_ref(f), ##__VA_ARGS__)
>  
>  void force_vm_exit(const cpumask_t *mask);
>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
> @@ -352,14 +354,14 @@ int kvm_perf_teardown(void);
>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
>  
>  static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
> -				       unsigned long hyp_stack_ptr,
> -				       unsigned long vector_ptr)
> +				       unsigned long hyp_stack_ptr)
>  {
>  	/*
>  	 * Call initialization code, and switch to the full blown
>  	 * HYP code.
>  	 */
> -	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
> +	__hyp_call_func(__kvm_hyp_init, pgd_ptr, hyp_stack_ptr,
> +			kvm_ksym_ref(__kvm_hyp_vector));
>  }
>  
>  static inline void kvm_arch_hardware_unsetup(void) {}
> diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
> index a7c9dfdd6430..478a64545f37 100644
> --- a/arch/arm64/include/asm/virt.h
> +++ b/arch/arm64/include/asm/virt.h
> @@ -25,11 +25,12 @@
>   */
>  
>  /*
> - * HVC_SET_VECTORS - Set the value of the vbar_el2 register.
> + * HVC_CALL_FUNC - Call a function in the idmap
>   *
> - * @x1: Physical address of the new vector table.
> + * @x1: function address
> + * @x2-x5: parameters
>   */
> -#define HVC_SET_VECTORS 0
> +#define HVC_CALL_FUNC	 0
>  
>  /*
>   * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine.
> @@ -41,6 +42,7 @@
>   */
>  #define HVC_RESET_VECTORS 2
>  
> +
>  /* Max number of HYP stub hypercalls */
>  #define HVC_STUB_HCALL_NR 3
>  
> diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> index 210bd6b3849d..d99968333da1 100644
> --- a/arch/arm64/kernel/hyp-stub.S
> +++ b/arch/arm64/kernel/hyp-stub.S
> @@ -55,10 +55,17 @@ ENDPROC(__hyp_stub_vectors)
>  	.align 11
>  
>  el1_sync:
> -	cmp	x0, #HVC_SET_VECTORS
> +	cmp	x0, #HVC_CALL_FUNC
>  	b.ne	2f
> -	msr	vbar_el2, x1
> -	b	9f
> +	mov	x7, x1
> +	mov	x0, x2
> +	mov	x1, x3
> +	mov	x2, x4
> +	mov	x3, x5
> +	mov	x4, x6
> +	ldr_l	x6, kimage_voffset
> +	sub	x7, x7, x6
> +	br	x7
>  
>  2:	cmp	x0, #HVC_SOFT_RESTART
>  	b.ne	3f
> @@ -93,12 +100,7 @@ ENDPROC(\label)
>  	invalid_vector	el1_error_invalid
>  
>  /*
> - * __hyp_set_vectors: Call this after boot to set the initial hypervisor
> - * vectors as part of hypervisor installation.  On an SMP system, this should
> - * be called on each CPU.
> - *
> - * x0 must be the physical address of the new vector table, and must be
> - * 2KB aligned.
> + * FIXME: Document __hyp_call_func...
>   *
>   * Before calling this, you must check that the stub hypervisor is installed
>   * everywhere, by waiting for any secondary CPUs to be brought up and then
> @@ -113,15 +115,20 @@ ENDPROC(\label)
>   * initialisation entry point.
>   */
>  
> -ENTRY(__hyp_set_vectors)
> -	mov	x1, x0
> -	mov	x0, #HVC_SET_VECTORS
> -	hvc	#0
> -	ret
> -ENDPROC(__hyp_set_vectors)
> -
>  ENTRY(__hyp_reset_vectors)
>  	mov	x0, #HVC_RESET_VECTORS
>  	hvc	#0
>  	ret
>  ENDPROC(__hyp_reset_vectors)
> +
> +ENTRY(__hyp_call_func)
> +	mov	x6, x5
> +	mov	x5, x4
> +	mov	x4, x3
> +	mov	x3, x2
> +	mov	x2, x1
> +	mov	x1, x0
> +	mov	x0, #HVC_CALL_FUNC
> +	hvc	#0
> +	ret
> +ENDPROC(__hyp_call_func)
> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
> index cf01cdb8bc61..aa48a30178c4 100644
> --- a/arch/arm64/kvm/hyp-init.S
> +++ b/arch/arm64/kvm/hyp-init.S
> @@ -30,35 +30,11 @@
>  	.align	11
>  
>  ENTRY(__kvm_hyp_init)
> -	ventry	__invalid		// Synchronous EL2t
> -	ventry	__invalid		// IRQ EL2t
> -	ventry	__invalid		// FIQ EL2t
> -	ventry	__invalid		// Error EL2t
> -
> -	ventry	__invalid		// Synchronous EL2h
> -	ventry	__invalid		// IRQ EL2h
> -	ventry	__invalid		// FIQ EL2h
> -	ventry	__invalid		// Error EL2h
> -
> -	ventry	__do_hyp_init		// Synchronous 64-bit EL1
> -	ventry	__invalid		// IRQ 64-bit EL1
> -	ventry	__invalid		// FIQ 64-bit EL1
> -	ventry	__invalid		// Error 64-bit EL1
> -
> -	ventry	__invalid		// Synchronous 32-bit EL1
> -	ventry	__invalid		// IRQ 32-bit EL1
> -	ventry	__invalid		// FIQ 32-bit EL1
> -	ventry	__invalid		// Error 32-bit EL1
> -
> -__invalid:
> -	b	.
> -
>  	/*
>  	 * x0: HYP pgd
>  	 * x1: HYP stack
>  	 * x2: HYP vectors
>  	 */
> -__do_hyp_init:
>  	/* Check for a stub HVC call */
>  	cmp	x0, #HVC_STUB_HCALL_NR
>  	b.lo	__kvm_handle_stub_hvc
> 
> -- 
> Jazz is not dead. It just smells funny...

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-23 14:39           ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-23 14:39 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 23, 2017 at 10:53:04AM +0000, Marc Zyngier wrote:
> On 22/03/17 17:27, Christoffer Dall wrote:
> > On Wed, Mar 22, 2017 at 04:14:44PM +0000, Marc Zyngier wrote:
> >> Hi Christoffer,
> >>
> >> On 22/03/17 13:37, Christoffer Dall wrote:
> >>> Hi Marc,
> >>>
> >>>
> >>> On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> >>>> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
> >>>> could do with some TLC (it cannot perform a soft-restart at HYP, and
> >>>> has holes in the hyp-stub support in a number of places). In general,
> >>>> it would be desirable for the 32bit behaviour to align on 64bit, if
> >>>> only to ease maintenance.
> >>>>
> >>>> This series implements the following:
> >>>> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
> >>>> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
> >>>>   __hyp_reset_vectors
> >>>> - Implement add the stub entry points in the KVM init code, which
> >>>>   didn't implement any so far
> >>>> - Convert the HYP code to use the init code stubs directly
> >>>> - Some general cleanup as a result of these changes (which includes
> >>>>   killing HVC_GET_VECTORS)
> >>>> - Add some API documentation that covers the above
> >>>>
> >>>> Patches 12 to 14 would be better squashed into 10 and 11, but I've
> >>>> kept them separate so that I can take the blame for everything I've
> >>>> broken.
> >>>
> >>> This series looks great overall.  I'm still going through the details of
> >>> the patches, but one high level questions:
> >>>
> >>> What if we formalized the way to call a function in Hyp mode, whatever
> >>> its current configuration may be, via a specific HVC number.  That would
> >>> mean that the documentation say nothing of a hypervisor specific
> >>> implementaiton.
> >>
> >> Do you mean an actual function call indirected via an HVC? Similar to
> >> what we already do today for KVM when we want to call HYP functions?
> > 
> > Yes exactly.  One question would be how to standardize that if the
> > caller is not tied to the thing owning Hyp, making it unclear if it can
> > rely on the thing working or not, but I'm not sure if that's any worse
> > than what we have today.
> > 
> >>> Could we then use that to initialize hyp mode for a hypervisor, i.e.
> >>> KVM, without having to actually change the vectors?  Couldn't we simply
> >>> use the the hvc stub to call a function in the physical address space,
> >>> and be rid of the concept of hyp-init alltogether?
> >>
> >> My problem here is when you say "in the physical space". Do you want to
> >> be able to call such a function from any context? That's certainly
> >> doable now, but I'm not completely sure of what we get.
> >>
> >> Maybe I just don't see the use case - can you enlighten me?
> >>
> > 
> > I don't think there is a great use case beyond what we already do, it
> > would just be to have one set of hyp vectors fewer, so that either the
> > hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.
> > 
> > So instead of doing:
> >   __hyp_set_vectors(kvm_get_idmap_vector());
> >   hvc(); /* via the misused kvm_call_hyp thing */
> > 
> > you would do:
> > 
> >   __hyp_call_function(__kvm_hyp_init, arg1, arg2);
> > 
> > which would change the vector and initialize anything.
> > 
> > Not sure if that can work though, or if there are any downsides that I
> > haven't thought about?
> 
> I've given it a go, and that seems to work, at least on arm64. We may 
> have to set the vectors in a slightly different way on 32bit because 
> we're going to run out of registers (we only have two left once we 
> reach the function being called).

Right, that's a challenge I clearly didn't foresee.

> 
> Another thing is that the function called is not really a function. It 
> is an exception handler, as it has to end with an eret (or we may need 
> to save LR in funky ways).

Shouldn't it have the same semantics as the KVM calling function thing
where it pushes the LR on the stack?  But of course, that requires
having a stack for each runtime that owns hyp mode at any given time.
Potentially not great.

If possible, the idea would be that you'd call functions, just like you
normally do, but the functions you call can choose to never return -
again just like a C function can do if it messes with your machine
configuration.

But maybe the idea is fundamentally flawed, if the only function
you'd ever call from the hyp stub is one that takes over the hyp world,
and then the original design was just based on using set_vectors.  Hmmm.


>  The potential blocker for this is that the
> 32bit decompressor does use set_vectors in funky ways to deal with
> relocation. If we get rid of set_vectors like I just did on 64bit,
> we'll need to mess with that as well.

Interesting.  I didn't think that we'd necessarily get rid of
set_vectors, but I agree with you that if we wanted to do this, it
should probably go.

> 
> Anyway, here's the hack, 64bit only, quickly tested on Mustang. I'm not
> completely sure this is any prettier, but it is certainly manageable.

There are two things I like about it.  First, it gets rid of the
'additional runtime' in hyp and second the changes to
cpu_init_hyp_mode() are quite nice, imho.

Thanks being said, this series is pretty nice as it is, so I don't want
to impose more work on you at the moment, so maybe we save your patch
snipped below for later if we want to consider looking at it some other
time?

Thanks,
-Christoffer

> 
> diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
> index cbd3a3150090..9594e0acb331 100644
> --- a/arch/arm/kvm/arm.c
> +++ b/arch/arm/kvm/arm.c
> @@ -1092,17 +1092,12 @@ static void cpu_init_hyp_mode(void *dummy)
>  	phys_addr_t pgd_ptr;
>  	unsigned long hyp_stack_ptr;
>  	unsigned long stack_page;
> -	unsigned long vector_ptr;
> -
> -	/* Switch from the HYP stub to our own HYP init vector */
> -	__hyp_set_vectors(kvm_get_idmap_vector());
>  
>  	pgd_ptr = kvm_mmu_get_httbr();
>  	stack_page = __this_cpu_read(kvm_arm_hyp_stack_page);
>  	hyp_stack_ptr = stack_page + PAGE_SIZE;
> -	vector_ptr = (unsigned long)kvm_ksym_ref(__kvm_hyp_vector);
>  
> -	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr, vector_ptr);
> +	__cpu_init_hyp_mode(pgd_ptr, hyp_stack_ptr);
>  	__cpu_init_stage2();
>  
>  	if (is_kernel_in_hyp_mode())
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 578df18f66b7..b314c77adfc1 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -339,6 +339,8 @@ void kvm_arm_resume_vcpu(struct kvm_vcpu *vcpu);
>  
>  u64 __kvm_call_hyp(void *hypfn, ...);
>  #define kvm_call_hyp(f, ...) __kvm_call_hyp(kvm_ksym_ref(f), ##__VA_ARGS__)
> +u64 __hyp_call_func(void *hypfn, ...);
> +#define hyp_call_func(f, ...) __hyp_call_func(kvm_ksym_ref(f), ##__VA_ARGS__)
>  
>  void force_vm_exit(const cpumask_t *mask);
>  void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
> @@ -352,14 +354,14 @@ int kvm_perf_teardown(void);
>  struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
>  
>  static inline void __cpu_init_hyp_mode(phys_addr_t pgd_ptr,
> -				       unsigned long hyp_stack_ptr,
> -				       unsigned long vector_ptr)
> +				       unsigned long hyp_stack_ptr)
>  {
>  	/*
>  	 * Call initialization code, and switch to the full blown
>  	 * HYP code.
>  	 */
> -	__kvm_call_hyp((void *)pgd_ptr, hyp_stack_ptr, vector_ptr);
> +	__hyp_call_func(__kvm_hyp_init, pgd_ptr, hyp_stack_ptr,
> +			kvm_ksym_ref(__kvm_hyp_vector));
>  }
>  
>  static inline void kvm_arch_hardware_unsetup(void) {}
> diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
> index a7c9dfdd6430..478a64545f37 100644
> --- a/arch/arm64/include/asm/virt.h
> +++ b/arch/arm64/include/asm/virt.h
> @@ -25,11 +25,12 @@
>   */
>  
>  /*
> - * HVC_SET_VECTORS - Set the value of the vbar_el2 register.
> + * HVC_CALL_FUNC - Call a function in the idmap
>   *
> - * @x1: Physical address of the new vector table.
> + * @x1: function address
> + * @x2-x5: parameters
>   */
> -#define HVC_SET_VECTORS 0
> +#define HVC_CALL_FUNC	 0
>  
>  /*
>   * HVC_SOFT_RESTART - CPU soft reset, used by the cpu_soft_restart routine.
> @@ -41,6 +42,7 @@
>   */
>  #define HVC_RESET_VECTORS 2
>  
> +
>  /* Max number of HYP stub hypercalls */
>  #define HVC_STUB_HCALL_NR 3
>  
> diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
> index 210bd6b3849d..d99968333da1 100644
> --- a/arch/arm64/kernel/hyp-stub.S
> +++ b/arch/arm64/kernel/hyp-stub.S
> @@ -55,10 +55,17 @@ ENDPROC(__hyp_stub_vectors)
>  	.align 11
>  
>  el1_sync:
> -	cmp	x0, #HVC_SET_VECTORS
> +	cmp	x0, #HVC_CALL_FUNC
>  	b.ne	2f
> -	msr	vbar_el2, x1
> -	b	9f
> +	mov	x7, x1
> +	mov	x0, x2
> +	mov	x1, x3
> +	mov	x2, x4
> +	mov	x3, x5
> +	mov	x4, x6
> +	ldr_l	x6, kimage_voffset
> +	sub	x7, x7, x6
> +	br	x7
>  
>  2:	cmp	x0, #HVC_SOFT_RESTART
>  	b.ne	3f
> @@ -93,12 +100,7 @@ ENDPROC(\label)
>  	invalid_vector	el1_error_invalid
>  
>  /*
> - * __hyp_set_vectors: Call this after boot to set the initial hypervisor
> - * vectors as part of hypervisor installation.  On an SMP system, this should
> - * be called on each CPU.
> - *
> - * x0 must be the physical address of the new vector table, and must be
> - * 2KB aligned.
> + * FIXME: Document __hyp_call_func...
>   *
>   * Before calling this, you must check that the stub hypervisor is installed
>   * everywhere, by waiting for any secondary CPUs to be brought up and then
> @@ -113,15 +115,20 @@ ENDPROC(\label)
>   * initialisation entry point.
>   */
>  
> -ENTRY(__hyp_set_vectors)
> -	mov	x1, x0
> -	mov	x0, #HVC_SET_VECTORS
> -	hvc	#0
> -	ret
> -ENDPROC(__hyp_set_vectors)
> -
>  ENTRY(__hyp_reset_vectors)
>  	mov	x0, #HVC_RESET_VECTORS
>  	hvc	#0
>  	ret
>  ENDPROC(__hyp_reset_vectors)
> +
> +ENTRY(__hyp_call_func)
> +	mov	x6, x5
> +	mov	x5, x4
> +	mov	x4, x3
> +	mov	x3, x2
> +	mov	x2, x1
> +	mov	x1, x0
> +	mov	x0, #HVC_CALL_FUNC
> +	hvc	#0
> +	ret
> +ENDPROC(__hyp_call_func)
> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
> index cf01cdb8bc61..aa48a30178c4 100644
> --- a/arch/arm64/kvm/hyp-init.S
> +++ b/arch/arm64/kvm/hyp-init.S
> @@ -30,35 +30,11 @@
>  	.align	11
>  
>  ENTRY(__kvm_hyp_init)
> -	ventry	__invalid		// Synchronous EL2t
> -	ventry	__invalid		// IRQ EL2t
> -	ventry	__invalid		// FIQ EL2t
> -	ventry	__invalid		// Error EL2t
> -
> -	ventry	__invalid		// Synchronous EL2h
> -	ventry	__invalid		// IRQ EL2h
> -	ventry	__invalid		// FIQ EL2h
> -	ventry	__invalid		// Error EL2h
> -
> -	ventry	__do_hyp_init		// Synchronous 64-bit EL1
> -	ventry	__invalid		// IRQ 64-bit EL1
> -	ventry	__invalid		// FIQ 64-bit EL1
> -	ventry	__invalid		// Error 64-bit EL1
> -
> -	ventry	__invalid		// Synchronous 32-bit EL1
> -	ventry	__invalid		// IRQ 32-bit EL1
> -	ventry	__invalid		// FIQ 32-bit EL1
> -	ventry	__invalid		// Error 32-bit EL1
> -
> -__invalid:
> -	b	.
> -
>  	/*
>  	 * x0: HYP pgd
>  	 * x1: HYP stack
>  	 * x2: HYP vectors
>  	 */
> -__do_hyp_init:
>  	/* Check for a stub HVC call */
>  	cmp	x0, #HVC_STUB_HCALL_NR
>  	b.lo	__kvm_handle_stub_hvc
> 
> -- 
> Jazz is not dead. It just smells funny...

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-23 14:39           ` Christoffer Dall
@ 2017-03-23 15:16             ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-23 15:16 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On 23/03/17 14:39, Christoffer Dall wrote:
> On Thu, Mar 23, 2017 at 10:53:04AM +0000, Marc Zyngier wrote:
>> On 22/03/17 17:27, Christoffer Dall wrote:
>>>
>>> I don't think there is a great use case beyond what we already do, it
>>> would just be to have one set of hyp vectors fewer, so that either the
>>> hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.
>>>
>>> So instead of doing:
>>>   __hyp_set_vectors(kvm_get_idmap_vector());
>>>   hvc(); /* via the misused kvm_call_hyp thing */
>>>
>>> you would do:
>>>
>>>   __hyp_call_function(__kvm_hyp_init, arg1, arg2);
>>>
>>> which would change the vector and initialize anything.
>>>
>>> Not sure if that can work though, or if there are any downsides that I
>>> haven't thought about?
>>
>> I've given it a go, and that seems to work, at least on arm64. We may 
>> have to set the vectors in a slightly different way on 32bit because 
>> we're going to run out of registers (we only have two left once we 
>> reach the function being called).
> 
> Right, that's a challenge I clearly didn't foresee.
> 
>>
>> Another thing is that the function called is not really a function. It 
>> is an exception handler, as it has to end with an eret (or we may need 
>> to save LR in funky ways).
> 
> Shouldn't it have the same semantics as the KVM calling function thing
> where it pushes the LR on the stack?  But of course, that requires
> having a stack for each runtime that owns hyp mode at any given time.
> Potentially not great.

Indeed, and that's the point where I'm starting to think that we may be
trying to beautify something that may not be worth it.

> If possible, the idea would be that you'd call functions, just like you
> normally do, but the functions you call can choose to never return -
> again just like a C function can do if it messes with your machine
> configuration.
> 
> But maybe the idea is fundamentally flawed, if the only function
> you'd ever call from the hyp stub is one that takes over the hyp world,
> and then the original design was just based on using set_vectors.  Hmmm.

That's my point above. The only use case we have so far for this method
is to take over EL2. On the other have, I've noticed that the more I
rework this area, the more old stuff surfaces, ready to be nuked. Maybe
I should keep digging.

> 
>>  The potential blocker for this is that the
>> 32bit decompressor does use set_vectors in funky ways to deal with
>> relocation. If we get rid of set_vectors like I just did on 64bit,
>> we'll need to mess with that as well.
> 
> Interesting.  I didn't think that we'd necessarily get rid of
> set_vectors, but I agree with you that if we wanted to do this, it
> should probably go.
> 
>>
>> Anyway, here's the hack, 64bit only, quickly tested on Mustang. I'm not
>> completely sure this is any prettier, but it is certainly manageable.
> 
> There are two things I like about it.  First, it gets rid of the
> 'additional runtime' in hyp and second the changes to
> cpu_init_hyp_mode() are quite nice, imho.
> 
> Thanks being said, this series is pretty nice as it is, so I don't want
> to impose more work on you at the moment, so maybe we save your patch
> snipped below for later if we want to consider looking at it some other
> time?

What I can do is prepare an extra series that would include the
corresponding 32bit changes, and we then evaluate that separately. I
don't mind spending a bit of time on it.

Thanks,

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

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-23 15:16             ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-23 15:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 23/03/17 14:39, Christoffer Dall wrote:
> On Thu, Mar 23, 2017 at 10:53:04AM +0000, Marc Zyngier wrote:
>> On 22/03/17 17:27, Christoffer Dall wrote:
>>>
>>> I don't think there is a great use case beyond what we already do, it
>>> would just be to have one set of hyp vectors fewer, so that either the
>>> hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.
>>>
>>> So instead of doing:
>>>   __hyp_set_vectors(kvm_get_idmap_vector());
>>>   hvc(); /* via the misused kvm_call_hyp thing */
>>>
>>> you would do:
>>>
>>>   __hyp_call_function(__kvm_hyp_init, arg1, arg2);
>>>
>>> which would change the vector and initialize anything.
>>>
>>> Not sure if that can work though, or if there are any downsides that I
>>> haven't thought about?
>>
>> I've given it a go, and that seems to work, at least on arm64. We may 
>> have to set the vectors in a slightly different way on 32bit because 
>> we're going to run out of registers (we only have two left once we 
>> reach the function being called).
> 
> Right, that's a challenge I clearly didn't foresee.
> 
>>
>> Another thing is that the function called is not really a function. It 
>> is an exception handler, as it has to end with an eret (or we may need 
>> to save LR in funky ways).
> 
> Shouldn't it have the same semantics as the KVM calling function thing
> where it pushes the LR on the stack?  But of course, that requires
> having a stack for each runtime that owns hyp mode at any given time.
> Potentially not great.

Indeed, and that's the point where I'm starting to think that we may be
trying to beautify something that may not be worth it.

> If possible, the idea would be that you'd call functions, just like you
> normally do, but the functions you call can choose to never return -
> again just like a C function can do if it messes with your machine
> configuration.
> 
> But maybe the idea is fundamentally flawed, if the only function
> you'd ever call from the hyp stub is one that takes over the hyp world,
> and then the original design was just based on using set_vectors.  Hmmm.

That's my point above. The only use case we have so far for this method
is to take over EL2. On the other have, I've noticed that the more I
rework this area, the more old stuff surfaces, ready to be nuked. Maybe
I should keep digging.

> 
>>  The potential blocker for this is that the
>> 32bit decompressor does use set_vectors in funky ways to deal with
>> relocation. If we get rid of set_vectors like I just did on 64bit,
>> we'll need to mess with that as well.
> 
> Interesting.  I didn't think that we'd necessarily get rid of
> set_vectors, but I agree with you that if we wanted to do this, it
> should probably go.
> 
>>
>> Anyway, here's the hack, 64bit only, quickly tested on Mustang. I'm not
>> completely sure this is any prettier, but it is certainly manageable.
> 
> There are two things I like about it.  First, it gets rid of the
> 'additional runtime' in hyp and second the changes to
> cpu_init_hyp_mode() are quite nice, imho.
> 
> Thanks being said, this series is pretty nice as it is, so I don't want
> to impose more work on you at the moment, so maybe we save your patch
> snipped below for later if we want to consider looking at it some other
> time?

What I can do is prepare an extra series that would include the
corresponding 32bit changes, and we then evaluate that separately. I
don't mind spending a bit of time on it.

Thanks,

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

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-23 15:16             ` Marc Zyngier
@ 2017-03-23 15:45               ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-23 15:45 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvm, kvmarm, Russell King, Christoffer Dall,
	Mark Rutland, Catalin Marinas, James Morse, Ard Biesheuvel,
	Keerthy

On Thu, Mar 23, 2017 at 03:16:49PM +0000, Marc Zyngier wrote:
> On 23/03/17 14:39, Christoffer Dall wrote:
> > On Thu, Mar 23, 2017 at 10:53:04AM +0000, Marc Zyngier wrote:
> >> On 22/03/17 17:27, Christoffer Dall wrote:
> >>>
> >>> I don't think there is a great use case beyond what we already do, it
> >>> would just be to have one set of hyp vectors fewer, so that either the
> >>> hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.
> >>>
> >>> So instead of doing:
> >>>   __hyp_set_vectors(kvm_get_idmap_vector());
> >>>   hvc(); /* via the misused kvm_call_hyp thing */
> >>>
> >>> you would do:
> >>>
> >>>   __hyp_call_function(__kvm_hyp_init, arg1, arg2);
> >>>
> >>> which would change the vector and initialize anything.
> >>>
> >>> Not sure if that can work though, or if there are any downsides that I
> >>> haven't thought about?
> >>
> >> I've given it a go, and that seems to work, at least on arm64. We may 
> >> have to set the vectors in a slightly different way on 32bit because 
> >> we're going to run out of registers (we only have two left once we 
> >> reach the function being called).
> > 
> > Right, that's a challenge I clearly didn't foresee.
> > 
> >>
> >> Another thing is that the function called is not really a function. It 
> >> is an exception handler, as it has to end with an eret (or we may need 
> >> to save LR in funky ways).
> > 
> > Shouldn't it have the same semantics as the KVM calling function thing
> > where it pushes the LR on the stack?  But of course, that requires
> > having a stack for each runtime that owns hyp mode at any given time.
> > Potentially not great.
> 
> Indeed, and that's the point where I'm starting to think that we may be
> trying to beautify something that may not be worth it.
> 
> > If possible, the idea would be that you'd call functions, just like you
> > normally do, but the functions you call can choose to never return -
> > again just like a C function can do if it messes with your machine
> > configuration.
> > 
> > But maybe the idea is fundamentally flawed, if the only function
> > you'd ever call from the hyp stub is one that takes over the hyp world,
> > and then the original design was just based on using set_vectors.  Hmmm.
> 
> That's my point above. The only use case we have so far for this method
> is to take over EL2. On the other have, I've noticed that the more I
> rework this area, the more old stuff surfaces, ready to be nuked. Maybe
> I should keep digging.
> 
> > 
> >>  The potential blocker for this is that the
> >> 32bit decompressor does use set_vectors in funky ways to deal with
> >> relocation. If we get rid of set_vectors like I just did on 64bit,
> >> we'll need to mess with that as well.
> > 
> > Interesting.  I didn't think that we'd necessarily get rid of
> > set_vectors, but I agree with you that if we wanted to do this, it
> > should probably go.
> > 
> >>
> >> Anyway, here's the hack, 64bit only, quickly tested on Mustang. I'm not
> >> completely sure this is any prettier, but it is certainly manageable.
> > 
> > There are two things I like about it.  First, it gets rid of the
> > 'additional runtime' in hyp and second the changes to
> > cpu_init_hyp_mode() are quite nice, imho.
> > 
> > Thanks being said, this series is pretty nice as it is, so I don't want
> > to impose more work on you at the moment, so maybe we save your patch
> > snipped below for later if we want to consider looking at it some other
> > time?
> 
> What I can do is prepare an extra series that would include the
> corresponding 32bit changes, and we then evaluate that separately. I
> don't mind spending a bit of time on it.
> 

At this point I definitely think we should separate those efforts, and
get this series merged.  If you feel like looking at the other aspect,
that's great, and we can also have a look together at some point (I
could at least write the documentation), but let's do it in two stages.

/me stops making noise and goes back to reviewing the series at hand.

Thanks,
-Christoffer

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-23 15:45               ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-23 15:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 23, 2017 at 03:16:49PM +0000, Marc Zyngier wrote:
> On 23/03/17 14:39, Christoffer Dall wrote:
> > On Thu, Mar 23, 2017 at 10:53:04AM +0000, Marc Zyngier wrote:
> >> On 22/03/17 17:27, Christoffer Dall wrote:
> >>>
> >>> I don't think there is a great use case beyond what we already do, it
> >>> would just be to have one set of hyp vectors fewer, so that either the
> >>> hyp stub is in place, or a hypervisor is in place, not kvm-init vectors.
> >>>
> >>> So instead of doing:
> >>>   __hyp_set_vectors(kvm_get_idmap_vector());
> >>>   hvc(); /* via the misused kvm_call_hyp thing */
> >>>
> >>> you would do:
> >>>
> >>>   __hyp_call_function(__kvm_hyp_init, arg1, arg2);
> >>>
> >>> which would change the vector and initialize anything.
> >>>
> >>> Not sure if that can work though, or if there are any downsides that I
> >>> haven't thought about?
> >>
> >> I've given it a go, and that seems to work, at least on arm64. We may 
> >> have to set the vectors in a slightly different way on 32bit because 
> >> we're going to run out of registers (we only have two left once we 
> >> reach the function being called).
> > 
> > Right, that's a challenge I clearly didn't foresee.
> > 
> >>
> >> Another thing is that the function called is not really a function. It 
> >> is an exception handler, as it has to end with an eret (or we may need 
> >> to save LR in funky ways).
> > 
> > Shouldn't it have the same semantics as the KVM calling function thing
> > where it pushes the LR on the stack?  But of course, that requires
> > having a stack for each runtime that owns hyp mode at any given time.
> > Potentially not great.
> 
> Indeed, and that's the point where I'm starting to think that we may be
> trying to beautify something that may not be worth it.
> 
> > If possible, the idea would be that you'd call functions, just like you
> > normally do, but the functions you call can choose to never return -
> > again just like a C function can do if it messes with your machine
> > configuration.
> > 
> > But maybe the idea is fundamentally flawed, if the only function
> > you'd ever call from the hyp stub is one that takes over the hyp world,
> > and then the original design was just based on using set_vectors.  Hmmm.
> 
> That's my point above. The only use case we have so far for this method
> is to take over EL2. On the other have, I've noticed that the more I
> rework this area, the more old stuff surfaces, ready to be nuked. Maybe
> I should keep digging.
> 
> > 
> >>  The potential blocker for this is that the
> >> 32bit decompressor does use set_vectors in funky ways to deal with
> >> relocation. If we get rid of set_vectors like I just did on 64bit,
> >> we'll need to mess with that as well.
> > 
> > Interesting.  I didn't think that we'd necessarily get rid of
> > set_vectors, but I agree with you that if we wanted to do this, it
> > should probably go.
> > 
> >>
> >> Anyway, here's the hack, 64bit only, quickly tested on Mustang. I'm not
> >> completely sure this is any prettier, but it is certainly manageable.
> > 
> > There are two things I like about it.  First, it gets rid of the
> > 'additional runtime' in hyp and second the changes to
> > cpu_init_hyp_mode() are quite nice, imho.
> > 
> > Thanks being said, this series is pretty nice as it is, so I don't want
> > to impose more work on you at the moment, so maybe we save your patch
> > snipped below for later if we want to consider looking at it some other
> > time?
> 
> What I can do is prepare an extra series that would include the
> corresponding 32bit changes, and we then evaluate that separately. I
> don't mind spending a bit of time on it.
> 

At this point I definitely think we should separate those efforts, and
get this series merged.  If you feel like looking at the other aspect,
that's great, and we can also have a look together at some point (I
could at least write the documentation), but let's do it in two stages.

/me stops making noise and goes back to reviewing the series at hand.

Thanks,
-Christoffer

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

* Re: [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
  2017-03-21 19:20   ` Marc Zyngier
@ 2017-03-24 14:33     ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:33 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
> In order to help people understanding the hyp-stub API that exists
> between the host kernel and the hypervisor mode (whether a hypervisor
> has been installed or not), let's document said API.
> 
> As with any form of documentation, I expect it to become obsolete
> and completely misleading within 20 minutes after having being merged.

I don't think this last sentence belongs in the commit message.

> 
> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
> 
> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
> new file mode 100644
> index 000000000000..a1e0314d2249
> --- /dev/null
> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
> @@ -0,0 +1,45 @@
> +* Internal ABI between the kernel and HYP
> +
> +This file documents the interaction between the Linux kernel and the
> +hypervisor layer when running Linux as a hypervisor (for example
> +KVM). It doesn't cover the interaction of the kernel with the
> +hypervisor when running as a guest (under Xen, KVM or any other
> +hypervisor), or any hypervisor-specific interaction when the kernel is
> +used as a host.
> +
> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
> +mode, but still needs to interact with it, allowing a built-in
> +hypervisor to be either installed or torn down.
> +
> +In order to achieve this, the kernel must be booted at HYP (arm) or
> +EL2 (arm64), allowing it to install a set of stubs before dropping to
> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
> +and only act on individual CPUs.
> +
> +Unless specified otherwise, any built-in hypervisor must implement
> +these functions (see arch/arm{,64}/include/asm/virt.h):
> +
> +* r0/x0 = HVC_SET_VECTORS
> +  r1/x1 = vectors
> +
> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
> +  must be a physical address, and respect the alignment requirements
> +  of the architecture. Only implemented by the initial stubs.

Does this last sentence mean that KVM doesn't implement this function?


> +
> +* r0/x0 = HVC_RESET_VECTORS
> +
> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
> +  value. This effectively disables an existing hypervisor.

What's the 'default value' ?  Could we say to the physical address of
the hypervisor stub's exception vector?

> +
> +* r0/x0 = HVC_SOFT_RESTART
> +  r1/x1 = restart address
> +  x2 = x0's value when entering the next payload (arm64)
> +  x3 = x1's value when entering the next payload (arm64)
> +  x4 = x2's value when entering the next payload (arm64)
> +
> +  Mask all exceptions, disable the MMU, move the arguments into place
> +  (arm64 only), and jump to the restart address while at HYP/EL2. This
> +  hypercall is not expected to return to its caller.
> +
> +Any other value of r0/x0 triggers a hypervisor-specific handling,
> +which is not documented here.
> -- 
> 2.11.0
> 

Thanks,
-Christoffer

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

* [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
@ 2017-03-24 14:33     ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
> In order to help people understanding the hyp-stub API that exists
> between the host kernel and the hypervisor mode (whether a hypervisor
> has been installed or not), let's document said API.
> 
> As with any form of documentation, I expect it to become obsolete
> and completely misleading within 20 minutes after having being merged.

I don't think this last sentence belongs in the commit message.

> 
> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
>  1 file changed, 45 insertions(+)
>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
> 
> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
> new file mode 100644
> index 000000000000..a1e0314d2249
> --- /dev/null
> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
> @@ -0,0 +1,45 @@
> +* Internal ABI between the kernel and HYP
> +
> +This file documents the interaction between the Linux kernel and the
> +hypervisor layer when running Linux as a hypervisor (for example
> +KVM). It doesn't cover the interaction of the kernel with the
> +hypervisor when running as a guest (under Xen, KVM or any other
> +hypervisor), or any hypervisor-specific interaction when the kernel is
> +used as a host.
> +
> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
> +mode, but still needs to interact with it, allowing a built-in
> +hypervisor to be either installed or torn down.
> +
> +In order to achieve this, the kernel must be booted at HYP (arm) or
> +EL2 (arm64), allowing it to install a set of stubs before dropping to
> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
> +and only act on individual CPUs.
> +
> +Unless specified otherwise, any built-in hypervisor must implement
> +these functions (see arch/arm{,64}/include/asm/virt.h):
> +
> +* r0/x0 = HVC_SET_VECTORS
> +  r1/x1 = vectors
> +
> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
> +  must be a physical address, and respect the alignment requirements
> +  of the architecture. Only implemented by the initial stubs.

Does this last sentence mean that KVM doesn't implement this function?


> +
> +* r0/x0 = HVC_RESET_VECTORS
> +
> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
> +  value. This effectively disables an existing hypervisor.

What's the 'default value' ?  Could we say to the physical address of
the hypervisor stub's exception vector?

> +
> +* r0/x0 = HVC_SOFT_RESTART
> +  r1/x1 = restart address
> +  x2 = x0's value when entering the next payload (arm64)
> +  x3 = x1's value when entering the next payload (arm64)
> +  x4 = x2's value when entering the next payload (arm64)
> +
> +  Mask all exceptions, disable the MMU, move the arguments into place
> +  (arm64 only), and jump to the restart address while at HYP/EL2. This
> +  hypercall is not expected to return to its caller.
> +
> +Any other value of r0/x0 triggers a hypervisor-specific handling,
> +which is not documented here.
> -- 
> 2.11.0
> 

Thanks,
-Christoffer

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

* Re: [PATCH v4 05/28] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
  2017-03-21 19:20   ` Marc Zyngier
@ 2017-03-24 14:33     ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:33 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvm, kvmarm, Russell King, Christoffer Dall,
	Mark Rutland, Catalin Marinas, James Morse, Ard Biesheuvel,
	Keerthy

On Tue, Mar 21, 2017 at 07:20:35PM +0000, Marc Zyngier wrote:
> In order to restore HYP mode to its original condition, KVM currently
> implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
> defined API, it becomes necessary to implement HVC_RESET_VECTORS.
> 
> This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
> code, which so far lacked any form of hypercall support.
> 
> Reviewed-by: James Morse <james.morse@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/kvm/hyp-init.S | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
> index 6b29d3d9e1f2..6cf98ccd10f2 100644
> --- a/arch/arm64/kvm/hyp-init.S
> +++ b/arch/arm64/kvm/hyp-init.S
> @@ -22,6 +22,7 @@
>  #include <asm/kvm_mmu.h>
>  #include <asm/pgtable-hwdef.h>
>  #include <asm/sysreg.h>
> +#include <asm/virt.h>
>  
>  	.text
>  	.pushsection	.hyp.idmap.text, "ax"
> @@ -58,6 +59,9 @@ __invalid:
>  	 * x2: HYP vectors
>  	 */
>  __do_hyp_init:
> +	/* Check for a stub HVC call */
> +	cmp	x0, #HVC_STUB_HCALL_NR
> +	b.lo	__kvm_handle_stub_hvc
>  
>  	msr	ttbr0_el2, x0
>  
> @@ -119,6 +123,9 @@ __do_hyp_init:
>  	eret
>  ENDPROC(__kvm_hyp_init)
>  
> +ENTRY(__kvm_handle_stub_hvc)
> +	cmp	x0, #HVC_RESET_VECTORS
> +	b.ne	1f
>  	/*
>  	 * Reset kvm back to the hyp stub.
>  	 */
> @@ -133,9 +140,14 @@ ENTRY(__kvm_hyp_reset)
>  	/* Install stub vectors */
>  	adr_l	x0, __hyp_stub_vectors
>  	msr	vbar_el2, x0
> +	b	exit
>  
> +1:	mov	x0, #-1

nit: do we have the -1 return value documented somewhere and should we
define it as HVC_SUB_ERR_RETURN or something like that?

> +
> +exit:
>  	eret
>  ENDPROC(__kvm_hyp_reset)
> +ENDPROC(__kvm_handle_stub_hvc)
>  
>  	.ltorg
>  
> -- 
> 2.11.0
> 

Thanks,
-Christoffer

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

* [PATCH v4 05/28] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
@ 2017-03-24 14:33     ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 21, 2017 at 07:20:35PM +0000, Marc Zyngier wrote:
> In order to restore HYP mode to its original condition, KVM currently
> implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
> defined API, it becomes necessary to implement HVC_RESET_VECTORS.
> 
> This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
> code, which so far lacked any form of hypercall support.
> 
> Reviewed-by: James Morse <james.morse@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/kvm/hyp-init.S | 12 ++++++++++++
>  1 file changed, 12 insertions(+)
> 
> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
> index 6b29d3d9e1f2..6cf98ccd10f2 100644
> --- a/arch/arm64/kvm/hyp-init.S
> +++ b/arch/arm64/kvm/hyp-init.S
> @@ -22,6 +22,7 @@
>  #include <asm/kvm_mmu.h>
>  #include <asm/pgtable-hwdef.h>
>  #include <asm/sysreg.h>
> +#include <asm/virt.h>
>  
>  	.text
>  	.pushsection	.hyp.idmap.text, "ax"
> @@ -58,6 +59,9 @@ __invalid:
>  	 * x2: HYP vectors
>  	 */
>  __do_hyp_init:
> +	/* Check for a stub HVC call */
> +	cmp	x0, #HVC_STUB_HCALL_NR
> +	b.lo	__kvm_handle_stub_hvc
>  
>  	msr	ttbr0_el2, x0
>  
> @@ -119,6 +123,9 @@ __do_hyp_init:
>  	eret
>  ENDPROC(__kvm_hyp_init)
>  
> +ENTRY(__kvm_handle_stub_hvc)
> +	cmp	x0, #HVC_RESET_VECTORS
> +	b.ne	1f
>  	/*
>  	 * Reset kvm back to the hyp stub.
>  	 */
> @@ -133,9 +140,14 @@ ENTRY(__kvm_hyp_reset)
>  	/* Install stub vectors */
>  	adr_l	x0, __hyp_stub_vectors
>  	msr	vbar_el2, x0
> +	b	exit
>  
> +1:	mov	x0, #-1

nit: do we have the -1 return value documented somewhere and should we
define it as HVC_SUB_ERR_RETURN or something like that?

> +
> +exit:
>  	eret
>  ENDPROC(__kvm_hyp_reset)
> +ENDPROC(__kvm_handle_stub_hvc)
>  
>  	.ltorg
>  
> -- 
> 2.11.0
> 

Thanks,
-Christoffer

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

* Re: [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-03-21 19:20   ` Marc Zyngier
@ 2017-03-24 14:33     ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:33 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvm, kvmarm, Russell King, Christoffer Dall,
	Mark Rutland, Catalin Marinas, James Morse, Ard Biesheuvel,
	Keerthy

On Tue, Mar 21, 2017 at 07:20:37PM +0000, Marc Zyngier wrote:
> We now have a full hyp-stub implementation in the KVM init code,
> but the main KVM code only supports HVC_GET_VECTORS, which is not
> enough.
> 
> Instead of reinventing the wheel, let's reuse the init implementation
> by branching to the idmap page when called with a hyp-stub hypercall.
> 
> Reviewed-by: James Morse <james.morse@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++-----
>  1 file changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> index d8ef788646c6..4f34c5996f86 100644
> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> @@ -87,10 +87,24 @@ alternative_endif
>  	/* Here, we're pretty sure the host called HVC. */
>  	ldp	x0, x1, [sp], #16
>  
> -	cmp	x0, #HVC_GET_VECTORS
> -	b.ne	1f
> -	mrs	x0, vbar_el2
> -	b	2f
> +	/* Check for a stub HVC call */
> +	cmp	x0, #HVC_STUB_HCALL_NR
> +	b.hs	1f
> +
> +	/*
> +	 * Compute the idmap address of __kvm_handle_stub_hvc and
> +	 * jump there. Since we use kimage_voffset, do not use the
> +	 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead
> +	 * (by loading it from the constant pool).
> +	 *
> +	 * Preserve x0-x4, which may contain stub parameters.
> +	 */
> +	ldr	x5, =__kvm_handle_stub_hvc
> +	ldr_l	x6, kimage_voffset

Isn't it a bit dodgy to just overwrite x5 and x6 in something which is
not a function?  I know that in practice this always gets called through
a function call and we can rely on the calling convention, but this can
break if you issue a hypercall to KVM's HVC sub implementation using
inline assembly, I think.

Am I missing something here?

> +
> +	/* x5 = __pa(x5) */
> +	sub	x5, x5, x6
> +	br	x5
>  
>  1:
>  	/*
> @@ -99,7 +113,7 @@ alternative_endif
>  	kern_hyp_va	x0
>  	do_el2_call
>  
> -2:	eret
> +	eret
>  
>  el1_trap:
>  	/*
> -- 
> 2.11.0
> 

Thanks,
-Christoffer

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

* [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-03-24 14:33     ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 21, 2017 at 07:20:37PM +0000, Marc Zyngier wrote:
> We now have a full hyp-stub implementation in the KVM init code,
> but the main KVM code only supports HVC_GET_VECTORS, which is not
> enough.
> 
> Instead of reinventing the wheel, let's reuse the init implementation
> by branching to the idmap page when called with a hyp-stub hypercall.
> 
> Reviewed-by: James Morse <james.morse@arm.com>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++-----
>  1 file changed, 19 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> index d8ef788646c6..4f34c5996f86 100644
> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> @@ -87,10 +87,24 @@ alternative_endif
>  	/* Here, we're pretty sure the host called HVC. */
>  	ldp	x0, x1, [sp], #16
>  
> -	cmp	x0, #HVC_GET_VECTORS
> -	b.ne	1f
> -	mrs	x0, vbar_el2
> -	b	2f
> +	/* Check for a stub HVC call */
> +	cmp	x0, #HVC_STUB_HCALL_NR
> +	b.hs	1f
> +
> +	/*
> +	 * Compute the idmap address of __kvm_handle_stub_hvc and
> +	 * jump there. Since we use kimage_voffset, do not use the
> +	 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead
> +	 * (by loading it from the constant pool).
> +	 *
> +	 * Preserve x0-x4, which may contain stub parameters.
> +	 */
> +	ldr	x5, =__kvm_handle_stub_hvc
> +	ldr_l	x6, kimage_voffset

Isn't it a bit dodgy to just overwrite x5 and x6 in something which is
not a function?  I know that in practice this always gets called through
a function call and we can rely on the calling convention, but this can
break if you issue a hypercall to KVM's HVC sub implementation using
inline assembly, I think.

Am I missing something here?

> +
> +	/* x5 = __pa(x5) */
> +	sub	x5, x5, x6
> +	br	x5
>  
>  1:
>  	/*
> @@ -99,7 +113,7 @@ alternative_endif
>  	kern_hyp_va	x0
>  	do_el2_call
>  
> -2:	eret
> +	eret
>  
>  el1_trap:
>  	/*
> -- 
> 2.11.0
> 

Thanks,
-Christoffer

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

* Re: [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-03-21 19:20   ` Marc Zyngier
@ 2017-03-24 14:34     ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:34 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvm, kvmarm, Russell King, Christoffer Dall,
	Mark Rutland, Catalin Marinas, James Morse, Ard Biesheuvel,
	Keerthy

On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
> We now have a full hyp-stub implementation in the KVM init code,
> but the main KVM code only supports HVC_GET_VECTORS, which is not
> enough.
> 
> Instead of reinventing the wheel, let's reuse the init implementation
> by branching to the idmap page when called with a hyp-stub hypercall.
> 
> Tested-by: Keerthy <j-keerthy@ti.com>
> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
>  1 file changed, 24 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
> index 1f8db7d21fc5..a35baa81fd23 100644
> --- a/arch/arm/kvm/hyp/hyp-entry.S
> +++ b/arch/arm/kvm/hyp/hyp-entry.S
> @@ -126,11 +126,30 @@ hyp_hvc:
>  	 */
>  	pop	{r0, r1, r2}
>  
> -	/* Check for __hyp_get_vectors */
> -	cmp	r0, #HVC_GET_VECTORS
> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
> -	beq	1f
> +	/*
> +	 * Check if we have a kernel function, which is guaranteed to be
> +	 * bigger than the maximum hyp stub hypercall
> +	 */
> +	cmp	r0, #HVC_STUB_HCALL_NR
> +	bhs	1f
>  
> +	/*
> +	 * Not a kernel function, treat it as a stub hypercall.
> +	 * Compute the physical address for __kvm_handle_stub_hvc
> +	 * (as the code lives in the idmaped page) and branch there.
> +	 * We hijack ip (r12) as a tmp register.
> +	 */

How can we just clobber r12 and be sure we don't corrupt the caller?

> +	push	{r1}
> +	ldr	r1, =kimage_voffset
> +	ldr	r1, [r1]
> +	ldr	ip, =__kvm_handle_stub_hvc
> +	sub	ip, ip, r1
> +THUMB(	add	ip, ip, #1)
> +	pop	{r1}
> +
> +	bx	ip
> +
> +1:
>  	push	{lr}
>  
>  	mov	lr, r0
> @@ -142,7 +161,7 @@ THUMB(	orr	lr, #1)
>  	blx	lr			@ Call the HYP function
>  
>  	pop	{lr}
> -1:	eret
> +	eret
>  
>  guest_trap:
>  	load_vcpu r0			@ Load VCPU pointer to r0
> -- 
> 2.11.0
> 

Thanks,
-Christoffer

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

* [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-03-24 14:34     ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
> We now have a full hyp-stub implementation in the KVM init code,
> but the main KVM code only supports HVC_GET_VECTORS, which is not
> enough.
> 
> Instead of reinventing the wheel, let's reuse the init implementation
> by branching to the idmap page when called with a hyp-stub hypercall.
> 
> Tested-by: Keerthy <j-keerthy@ti.com>
> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
>  1 file changed, 24 insertions(+), 5 deletions(-)
> 
> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
> index 1f8db7d21fc5..a35baa81fd23 100644
> --- a/arch/arm/kvm/hyp/hyp-entry.S
> +++ b/arch/arm/kvm/hyp/hyp-entry.S
> @@ -126,11 +126,30 @@ hyp_hvc:
>  	 */
>  	pop	{r0, r1, r2}
>  
> -	/* Check for __hyp_get_vectors */
> -	cmp	r0, #HVC_GET_VECTORS
> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
> -	beq	1f
> +	/*
> +	 * Check if we have a kernel function, which is guaranteed to be
> +	 * bigger than the maximum hyp stub hypercall
> +	 */
> +	cmp	r0, #HVC_STUB_HCALL_NR
> +	bhs	1f
>  
> +	/*
> +	 * Not a kernel function, treat it as a stub hypercall.
> +	 * Compute the physical address for __kvm_handle_stub_hvc
> +	 * (as the code lives in the idmaped page) and branch there.
> +	 * We hijack ip (r12) as a tmp register.
> +	 */

How can we just clobber r12 and be sure we don't corrupt the caller?

> +	push	{r1}
> +	ldr	r1, =kimage_voffset
> +	ldr	r1, [r1]
> +	ldr	ip, =__kvm_handle_stub_hvc
> +	sub	ip, ip, r1
> +THUMB(	add	ip, ip, #1)
> +	pop	{r1}
> +
> +	bx	ip
> +
> +1:
>  	push	{lr}
>  
>  	mov	lr, r0
> @@ -142,7 +161,7 @@ THUMB(	orr	lr, #1)
>  	blx	lr			@ Call the HYP function
>  
>  	pop	{lr}
> -1:	eret
> +	eret
>  
>  guest_trap:
>  	load_vcpu r0			@ Load VCPU pointer to r0
> -- 
> 2.11.0
> 

Thanks,
-Christoffer

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

* Re: [PATCH v4 25/28] ARM: decompressor: Remove __hyp_get_vectors usage
  2017-03-21 19:20   ` Marc Zyngier
@ 2017-03-24 14:34     ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:34 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Tue, Mar 21, 2017 at 07:20:55PM +0000, Marc Zyngier wrote:
> When the compressed image needs to be relocated to avoid being
> overwritten by the decompression process, we need to relocate
> the hyp vectors as well so that we can find them once the
> decompression has taken effect.
> 
> For that, we perform the following calculation:
> 	u32 v = __hyp_get_vectors();
> 	v += offset;
> 	__hyp_set_vectors(v);
> 
> But we're guaranteed that the initial value of v as returned by
> __hyp_get_vectors is always __hyp_stub_vectors, because we have
> just set it by calling __hyp_stub_install.
> 
> So let's remove the use of __hyp_get_vectors, and directly use
> __hyp_stub_vectors instead.
> 
> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/boot/compressed/head.S | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index 9150f9732785..d58bb104c6e8 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -422,7 +422,10 @@ dtb_check_done:
>  		cmp	r0, #HYP_MODE
>  		bne	1f
>  
> -		bl	__hyp_get_vectors
> +0:		adr	r0, 0b
> +		movw	r1, #:lower16:__hyp_stub_vectors - 0b
> +		movt	r1, #:upper16:__hyp_stub_vectors - 0b
> +		add	r0, r0, r1

nit: you could add a comment explaining what r0 ends up containing,
because I'm pretty sure this will feel obscure when not read in the
context of this series with your commit message above.

>  		sub	r0, r0, r5
>  		add	r0, r0, r10
>  		bl	__hyp_set_vectors
> -- 
> 2.11.0
> 

Nevertheless:

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

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

* [PATCH v4 25/28] ARM: decompressor: Remove __hyp_get_vectors usage
@ 2017-03-24 14:34     ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:34 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Mar 21, 2017 at 07:20:55PM +0000, Marc Zyngier wrote:
> When the compressed image needs to be relocated to avoid being
> overwritten by the decompression process, we need to relocate
> the hyp vectors as well so that we can find them once the
> decompression has taken effect.
> 
> For that, we perform the following calculation:
> 	u32 v = __hyp_get_vectors();
> 	v += offset;
> 	__hyp_set_vectors(v);
> 
> But we're guaranteed that the initial value of v as returned by
> __hyp_get_vectors is always __hyp_stub_vectors, because we have
> just set it by calling __hyp_stub_install.
> 
> So let's remove the use of __hyp_get_vectors, and directly use
> __hyp_stub_vectors instead.
> 
> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
>  arch/arm/boot/compressed/head.S | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
> index 9150f9732785..d58bb104c6e8 100644
> --- a/arch/arm/boot/compressed/head.S
> +++ b/arch/arm/boot/compressed/head.S
> @@ -422,7 +422,10 @@ dtb_check_done:
>  		cmp	r0, #HYP_MODE
>  		bne	1f
>  
> -		bl	__hyp_get_vectors
> +0:		adr	r0, 0b
> +		movw	r1, #:lower16:__hyp_stub_vectors - 0b
> +		movt	r1, #:upper16:__hyp_stub_vectors - 0b
> +		add	r0, r0, r1

nit: you could add a comment explaining what r0 ends up containing,
because I'm pretty sure this will feel obscure when not read in the
context of this series with your commit message above.

>  		sub	r0, r0, r5
>  		add	r0, r0, r10
>  		bl	__hyp_set_vectors
> -- 
> 2.11.0
> 

Nevertheless:

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

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

* Re: [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
  2017-03-21 19:20 ` Marc Zyngier
@ 2017-03-24 14:36   ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:36 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvm, kvmarm, Russell King, Christoffer Dall,
	Mark Rutland, Catalin Marinas, James Morse, Ard Biesheuvel,
	Keerthy

Hi Marc,

On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
> could do with some TLC (it cannot perform a soft-restart at HYP, and
> has holes in the hyp-stub support in a number of places). In general,
> it would be desirable for the 32bit behaviour to align on 64bit, if
> only to ease maintenance.
> 
> This series implements the following:
> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
>   __hyp_reset_vectors
> - Implement add the stub entry points in the KVM init code, which
>   didn't implement any so far
> - Convert the HYP code to use the init code stubs directly
> - Some general cleanup as a result of these changes (which includes
>   killing HVC_GET_VECTORS)
> - Add some API documentation that covers the above
> 
> Patches 12 to 14 would be better squashed into 10 and 11, but I've
> kept them separate so that I can take the blame for everything I've
> broken.
> 
> I've tested this on arm (Cubietruck, Jetson TK1) and arm64 (Seattle),
> both as host and guest. Keerthy has been kind enough to test the 32bit
> code on DRA7-EVM, AM57XX-EVM and KEYSTONE-K2E-EVM.


For the series, except where I had some minor questions:

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


Thanks,
-Christoffer

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

* [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-03-24 14:36   ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Marc,

On Tue, Mar 21, 2017 at 07:20:30PM +0000, Marc Zyngier wrote:
> As noticed by RMK in this thread[1], the hyp-stub API on 32bit ARM
> could do with some TLC (it cannot perform a soft-restart at HYP, and
> has holes in the hyp-stub support in a number of places). In general,
> it would be desirable for the 32bit behaviour to align on 64bit, if
> only to ease maintenance.
> 
> This series implements the following:
> - Add HVC_[GS]ET_VECTORS and HVC_SOFT_RESTART to the 32bit code
> - Add HVC_RESET_VECTORS to both arm and arm64, removing the need for
>   __hyp_reset_vectors
> - Implement add the stub entry points in the KVM init code, which
>   didn't implement any so far
> - Convert the HYP code to use the init code stubs directly
> - Some general cleanup as a result of these changes (which includes
>   killing HVC_GET_VECTORS)
> - Add some API documentation that covers the above
> 
> Patches 12 to 14 would be better squashed into 10 and 11, but I've
> kept them separate so that I can take the blame for everything I've
> broken.
> 
> I've tested this on arm (Cubietruck, Jetson TK1) and arm64 (Seattle),
> both as host and guest. Keerthy has been kind enough to test the 32bit
> code on DRA7-EVM, AM57XX-EVM and KEYSTONE-K2E-EVM.


For the series, except where I had some minor questions:

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


Thanks,
-Christoffer

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

* Re: [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
  2017-03-24 14:33     ` Christoffer Dall
@ 2017-03-24 14:42       ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 14:42 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On 24/03/17 14:33, Christoffer Dall wrote:
> On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
>> In order to help people understanding the hyp-stub API that exists
>> between the host kernel and the hypervisor mode (whether a hypervisor
>> has been installed or not), let's document said API.
>>
>> As with any form of documentation, I expect it to become obsolete
>> and completely misleading within 20 minutes after having being merged.
> 
> I don't think this last sentence belongs in the commit message.
> 
>>
>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
>>  1 file changed, 45 insertions(+)
>>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
>>
>> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
>> new file mode 100644
>> index 000000000000..a1e0314d2249
>> --- /dev/null
>> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
>> @@ -0,0 +1,45 @@
>> +* Internal ABI between the kernel and HYP
>> +
>> +This file documents the interaction between the Linux kernel and the
>> +hypervisor layer when running Linux as a hypervisor (for example
>> +KVM). It doesn't cover the interaction of the kernel with the
>> +hypervisor when running as a guest (under Xen, KVM or any other
>> +hypervisor), or any hypervisor-specific interaction when the kernel is
>> +used as a host.
>> +
>> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
>> +mode, but still needs to interact with it, allowing a built-in
>> +hypervisor to be either installed or torn down.
>> +
>> +In order to achieve this, the kernel must be booted at HYP (arm) or
>> +EL2 (arm64), allowing it to install a set of stubs before dropping to
>> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
>> +and only act on individual CPUs.
>> +
>> +Unless specified otherwise, any built-in hypervisor must implement
>> +these functions (see arch/arm{,64}/include/asm/virt.h):
>> +
>> +* r0/x0 = HVC_SET_VECTORS
>> +  r1/x1 = vectors
>> +
>> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
>> +  must be a physical address, and respect the alignment requirements
>> +  of the architecture. Only implemented by the initial stubs.
> 
> Does this last sentence mean that KVM doesn't implement this function?

Indeed. Directly setting the vectors is inherently unsafe (MMU could
still be ON, for example), hence the HVC_SET_VECTORS operation that
allow this to be done safely (RESET followed by SET).

> 
>> +
>> +* r0/x0 = HVC_RESET_VECTORS
>> +
>> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
>> +  value. This effectively disables an existing hypervisor.
> 
> What's the 'default value' ?  Could we say to the physical address of
> the hypervisor stub's exception vector?

Shouldn't that be the kernel stub's exception vector?

Thanks,

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

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

* [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
@ 2017-03-24 14:42       ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 14:42 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/03/17 14:33, Christoffer Dall wrote:
> On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
>> In order to help people understanding the hyp-stub API that exists
>> between the host kernel and the hypervisor mode (whether a hypervisor
>> has been installed or not), let's document said API.
>>
>> As with any form of documentation, I expect it to become obsolete
>> and completely misleading within 20 minutes after having being merged.
> 
> I don't think this last sentence belongs in the commit message.
> 
>>
>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
>>  1 file changed, 45 insertions(+)
>>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
>>
>> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
>> new file mode 100644
>> index 000000000000..a1e0314d2249
>> --- /dev/null
>> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
>> @@ -0,0 +1,45 @@
>> +* Internal ABI between the kernel and HYP
>> +
>> +This file documents the interaction between the Linux kernel and the
>> +hypervisor layer when running Linux as a hypervisor (for example
>> +KVM). It doesn't cover the interaction of the kernel with the
>> +hypervisor when running as a guest (under Xen, KVM or any other
>> +hypervisor), or any hypervisor-specific interaction when the kernel is
>> +used as a host.
>> +
>> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
>> +mode, but still needs to interact with it, allowing a built-in
>> +hypervisor to be either installed or torn down.
>> +
>> +In order to achieve this, the kernel must be booted at HYP (arm) or
>> +EL2 (arm64), allowing it to install a set of stubs before dropping to
>> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
>> +and only act on individual CPUs.
>> +
>> +Unless specified otherwise, any built-in hypervisor must implement
>> +these functions (see arch/arm{,64}/include/asm/virt.h):
>> +
>> +* r0/x0 = HVC_SET_VECTORS
>> +  r1/x1 = vectors
>> +
>> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
>> +  must be a physical address, and respect the alignment requirements
>> +  of the architecture. Only implemented by the initial stubs.
> 
> Does this last sentence mean that KVM doesn't implement this function?

Indeed. Directly setting the vectors is inherently unsafe (MMU could
still be ON, for example), hence the HVC_SET_VECTORS operation that
allow this to be done safely (RESET followed by SET).

> 
>> +
>> +* r0/x0 = HVC_RESET_VECTORS
>> +
>> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
>> +  value. This effectively disables an existing hypervisor.
> 
> What's the 'default value' ?  Could we say to the physical address of
> the hypervisor stub's exception vector?

Shouldn't that be the kernel stub's exception vector?

Thanks,

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

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

* Re: [PATCH v4 05/28] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
  2017-03-24 14:33     ` Christoffer Dall
@ 2017-03-24 14:45       ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 14:45 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On 24/03/17 14:33, Christoffer Dall wrote:
> On Tue, Mar 21, 2017 at 07:20:35PM +0000, Marc Zyngier wrote:
>> In order to restore HYP mode to its original condition, KVM currently
>> implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
>> defined API, it becomes necessary to implement HVC_RESET_VECTORS.
>>
>> This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
>> code, which so far lacked any form of hypercall support.
>>
>> Reviewed-by: James Morse <james.morse@arm.com>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/kvm/hyp-init.S | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
>> index 6b29d3d9e1f2..6cf98ccd10f2 100644
>> --- a/arch/arm64/kvm/hyp-init.S
>> +++ b/arch/arm64/kvm/hyp-init.S
>> @@ -22,6 +22,7 @@
>>  #include <asm/kvm_mmu.h>
>>  #include <asm/pgtable-hwdef.h>
>>  #include <asm/sysreg.h>
>> +#include <asm/virt.h>
>>  
>>  	.text
>>  	.pushsection	.hyp.idmap.text, "ax"
>> @@ -58,6 +59,9 @@ __invalid:
>>  	 * x2: HYP vectors
>>  	 */
>>  __do_hyp_init:
>> +	/* Check for a stub HVC call */
>> +	cmp	x0, #HVC_STUB_HCALL_NR
>> +	b.lo	__kvm_handle_stub_hvc
>>  
>>  	msr	ttbr0_el2, x0
>>  
>> @@ -119,6 +123,9 @@ __do_hyp_init:
>>  	eret
>>  ENDPROC(__kvm_hyp_init)
>>  
>> +ENTRY(__kvm_handle_stub_hvc)
>> +	cmp	x0, #HVC_RESET_VECTORS
>> +	b.ne	1f
>>  	/*
>>  	 * Reset kvm back to the hyp stub.
>>  	 */
>> @@ -133,9 +140,14 @@ ENTRY(__kvm_hyp_reset)
>>  	/* Install stub vectors */
>>  	adr_l	x0, __hyp_stub_vectors
>>  	msr	vbar_el2, x0
>> +	b	exit
>>  
>> +1:	mov	x0, #-1
> 
> nit: do we have the -1 return value documented somewhere and should we
> define it as HVC_SUB_ERR_RETURN or something like that?

Indeed, this is something that is a bit dodgy. arm64 returns
ARM_EXCEPTION_HYP_GONE, which is really a KVM exception code (and isn't
-1 either). I'll try to tighten this up a bit.

Thanks,

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

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

* [PATCH v4 05/28] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code
@ 2017-03-24 14:45       ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 14:45 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/03/17 14:33, Christoffer Dall wrote:
> On Tue, Mar 21, 2017 at 07:20:35PM +0000, Marc Zyngier wrote:
>> In order to restore HYP mode to its original condition, KVM currently
>> implements __kvm_hyp_reset(). As we're moving towards a hyp-stub
>> defined API, it becomes necessary to implement HVC_RESET_VECTORS.
>>
>> This patch adds the HVC_RESET_VECTORS hypercall to the KVM init
>> code, which so far lacked any form of hypercall support.
>>
>> Reviewed-by: James Morse <james.morse@arm.com>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/kvm/hyp-init.S | 12 ++++++++++++
>>  1 file changed, 12 insertions(+)
>>
>> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
>> index 6b29d3d9e1f2..6cf98ccd10f2 100644
>> --- a/arch/arm64/kvm/hyp-init.S
>> +++ b/arch/arm64/kvm/hyp-init.S
>> @@ -22,6 +22,7 @@
>>  #include <asm/kvm_mmu.h>
>>  #include <asm/pgtable-hwdef.h>
>>  #include <asm/sysreg.h>
>> +#include <asm/virt.h>
>>  
>>  	.text
>>  	.pushsection	.hyp.idmap.text, "ax"
>> @@ -58,6 +59,9 @@ __invalid:
>>  	 * x2: HYP vectors
>>  	 */
>>  __do_hyp_init:
>> +	/* Check for a stub HVC call */
>> +	cmp	x0, #HVC_STUB_HCALL_NR
>> +	b.lo	__kvm_handle_stub_hvc
>>  
>>  	msr	ttbr0_el2, x0
>>  
>> @@ -119,6 +123,9 @@ __do_hyp_init:
>>  	eret
>>  ENDPROC(__kvm_hyp_init)
>>  
>> +ENTRY(__kvm_handle_stub_hvc)
>> +	cmp	x0, #HVC_RESET_VECTORS
>> +	b.ne	1f
>>  	/*
>>  	 * Reset kvm back to the hyp stub.
>>  	 */
>> @@ -133,9 +140,14 @@ ENTRY(__kvm_hyp_reset)
>>  	/* Install stub vectors */
>>  	adr_l	x0, __hyp_stub_vectors
>>  	msr	vbar_el2, x0
>> +	b	exit
>>  
>> +1:	mov	x0, #-1
> 
> nit: do we have the -1 return value documented somewhere and should we
> define it as HVC_SUB_ERR_RETURN or something like that?

Indeed, this is something that is a bit dodgy. arm64 returns
ARM_EXCEPTION_HYP_GONE, which is really a KVM exception code (and isn't
-1 either). I'll try to tighten this up a bit.

Thanks,

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

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

* Re: [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-03-24 14:33     ` Christoffer Dall
@ 2017-03-24 14:56       ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 14:56 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On 24/03/17 14:33, Christoffer Dall wrote:
> On Tue, Mar 21, 2017 at 07:20:37PM +0000, Marc Zyngier wrote:
>> We now have a full hyp-stub implementation in the KVM init code,
>> but the main KVM code only supports HVC_GET_VECTORS, which is not
>> enough.
>>
>> Instead of reinventing the wheel, let's reuse the init implementation
>> by branching to the idmap page when called with a hyp-stub hypercall.
>>
>> Reviewed-by: James Morse <james.morse@arm.com>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++-----
>>  1 file changed, 19 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
>> index d8ef788646c6..4f34c5996f86 100644
>> --- a/arch/arm64/kvm/hyp/hyp-entry.S
>> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
>> @@ -87,10 +87,24 @@ alternative_endif
>>  	/* Here, we're pretty sure the host called HVC. */
>>  	ldp	x0, x1, [sp], #16
>>  
>> -	cmp	x0, #HVC_GET_VECTORS
>> -	b.ne	1f
>> -	mrs	x0, vbar_el2
>> -	b	2f
>> +	/* Check for a stub HVC call */
>> +	cmp	x0, #HVC_STUB_HCALL_NR
>> +	b.hs	1f
>> +
>> +	/*
>> +	 * Compute the idmap address of __kvm_handle_stub_hvc and
>> +	 * jump there. Since we use kimage_voffset, do not use the
>> +	 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead
>> +	 * (by loading it from the constant pool).
>> +	 *
>> +	 * Preserve x0-x4, which may contain stub parameters.
>> +	 */
>> +	ldr	x5, =__kvm_handle_stub_hvc
>> +	ldr_l	x6, kimage_voffset
> 
> Isn't it a bit dodgy to just overwrite x5 and x6 in something which is
> not a function?  I know that in practice this always gets called through
> a function call and we can rely on the calling convention, but this can
> break if you issue a hypercall to KVM's HVC sub implementation using
> inline assembly, I think.
> 
> Am I missing something here?

I don't think you're missing anything. We're definitely relying on
getting there via a function call which is going to preserve the
caller-saved registers.

The only case where we issue a naked HVC call is when we use
HVC_SOFT_RESTART. At this point, corrupted registers is not much of a worry.

Now, I see two ways of dealing with this:
- We save x5/x6 on the stack, restoring them in the stub handler , right
before the eret
- Or we simply document the behaviour in asm/virt.h so that people
adding new stub methods know the restrictions.

Thoughts?

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

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

* [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-03-24 14:56       ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 14:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/03/17 14:33, Christoffer Dall wrote:
> On Tue, Mar 21, 2017 at 07:20:37PM +0000, Marc Zyngier wrote:
>> We now have a full hyp-stub implementation in the KVM init code,
>> but the main KVM code only supports HVC_GET_VECTORS, which is not
>> enough.
>>
>> Instead of reinventing the wheel, let's reuse the init implementation
>> by branching to the idmap page when called with a hyp-stub hypercall.
>>
>> Reviewed-by: James Morse <james.morse@arm.com>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++-----
>>  1 file changed, 19 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
>> index d8ef788646c6..4f34c5996f86 100644
>> --- a/arch/arm64/kvm/hyp/hyp-entry.S
>> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
>> @@ -87,10 +87,24 @@ alternative_endif
>>  	/* Here, we're pretty sure the host called HVC. */
>>  	ldp	x0, x1, [sp], #16
>>  
>> -	cmp	x0, #HVC_GET_VECTORS
>> -	b.ne	1f
>> -	mrs	x0, vbar_el2
>> -	b	2f
>> +	/* Check for a stub HVC call */
>> +	cmp	x0, #HVC_STUB_HCALL_NR
>> +	b.hs	1f
>> +
>> +	/*
>> +	 * Compute the idmap address of __kvm_handle_stub_hvc and
>> +	 * jump there. Since we use kimage_voffset, do not use the
>> +	 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead
>> +	 * (by loading it from the constant pool).
>> +	 *
>> +	 * Preserve x0-x4, which may contain stub parameters.
>> +	 */
>> +	ldr	x5, =__kvm_handle_stub_hvc
>> +	ldr_l	x6, kimage_voffset
> 
> Isn't it a bit dodgy to just overwrite x5 and x6 in something which is
> not a function?  I know that in practice this always gets called through
> a function call and we can rely on the calling convention, but this can
> break if you issue a hypercall to KVM's HVC sub implementation using
> inline assembly, I think.
> 
> Am I missing something here?

I don't think you're missing anything. We're definitely relying on
getting there via a function call which is going to preserve the
caller-saved registers.

The only case where we issue a naked HVC call is when we use
HVC_SOFT_RESTART. At this point, corrupted registers is not much of a worry.

Now, I see two ways of dealing with this:
- We save x5/x6 on the stack, restoring them in the stub handler , right
before the eret
- Or we simply document the behaviour in asm/virt.h so that people
adding new stub methods know the restrictions.

Thoughts?

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

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

* Re: [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-03-24 14:34     ` Christoffer Dall
@ 2017-03-24 15:01       ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 15:01 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: linux-arm-kernel, kvm, kvmarm, Russell King, Christoffer Dall,
	Mark Rutland, Catalin Marinas, James Morse, Ard Biesheuvel,
	Keerthy

On 24/03/17 14:34, Christoffer Dall wrote:
> On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
>> We now have a full hyp-stub implementation in the KVM init code,
>> but the main KVM code only supports HVC_GET_VECTORS, which is not
>> enough.
>>
>> Instead of reinventing the wheel, let's reuse the init implementation
>> by branching to the idmap page when called with a hyp-stub hypercall.
>>
>> Tested-by: Keerthy <j-keerthy@ti.com>
>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
>>  1 file changed, 24 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
>> index 1f8db7d21fc5..a35baa81fd23 100644
>> --- a/arch/arm/kvm/hyp/hyp-entry.S
>> +++ b/arch/arm/kvm/hyp/hyp-entry.S
>> @@ -126,11 +126,30 @@ hyp_hvc:
>>  	 */
>>  	pop	{r0, r1, r2}
>>  
>> -	/* Check for __hyp_get_vectors */
>> -	cmp	r0, #HVC_GET_VECTORS
>> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
>> -	beq	1f
>> +	/*
>> +	 * Check if we have a kernel function, which is guaranteed to be
>> +	 * bigger than the maximum hyp stub hypercall
>> +	 */
>> +	cmp	r0, #HVC_STUB_HCALL_NR
>> +	bhs	1f
>>  
>> +	/*
>> +	 * Not a kernel function, treat it as a stub hypercall.
>> +	 * Compute the physical address for __kvm_handle_stub_hvc
>> +	 * (as the code lives in the idmaped page) and branch there.
>> +	 * We hijack ip (r12) as a tmp register.
>> +	 */
> 
> How can we just clobber r12 and be sure we don't corrupt the caller?

r12 (aka ip) is allowed to be clobbered by the linker (used by inserted
code veneers, for example). Given that this is a standalone object, we
can safely assume that r12 has been saved if it was used by the caller.

Here is what the PCS says:

"Register r12 (IP) may be used by a linker as a scratch register between
a routine and any subroutine it calls (for details, see
§5.3.1.1, Use of IP by the linker). It can also be used within a routine
to hold intermediate values between subroutine calls."

Thanks,

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

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

* [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-03-24 15:01       ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/03/17 14:34, Christoffer Dall wrote:
> On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
>> We now have a full hyp-stub implementation in the KVM init code,
>> but the main KVM code only supports HVC_GET_VECTORS, which is not
>> enough.
>>
>> Instead of reinventing the wheel, let's reuse the init implementation
>> by branching to the idmap page when called with a hyp-stub hypercall.
>>
>> Tested-by: Keerthy <j-keerthy@ti.com>
>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
>>  1 file changed, 24 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
>> index 1f8db7d21fc5..a35baa81fd23 100644
>> --- a/arch/arm/kvm/hyp/hyp-entry.S
>> +++ b/arch/arm/kvm/hyp/hyp-entry.S
>> @@ -126,11 +126,30 @@ hyp_hvc:
>>  	 */
>>  	pop	{r0, r1, r2}
>>  
>> -	/* Check for __hyp_get_vectors */
>> -	cmp	r0, #HVC_GET_VECTORS
>> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
>> -	beq	1f
>> +	/*
>> +	 * Check if we have a kernel function, which is guaranteed to be
>> +	 * bigger than the maximum hyp stub hypercall
>> +	 */
>> +	cmp	r0, #HVC_STUB_HCALL_NR
>> +	bhs	1f
>>  
>> +	/*
>> +	 * Not a kernel function, treat it as a stub hypercall.
>> +	 * Compute the physical address for __kvm_handle_stub_hvc
>> +	 * (as the code lives in the idmaped page) and branch there.
>> +	 * We hijack ip (r12) as a tmp register.
>> +	 */
> 
> How can we just clobber r12 and be sure we don't corrupt the caller?

r12 (aka ip) is allowed to be clobbered by the linker (used by inserted
code veneers, for example). Given that this is a standalone object, we
can safely assume that r12 has been saved if it was used by the caller.

Here is what the PCS says:

"Register r12 (IP) may be used by a linker as a scratch register between
a routine and any subroutine it calls (for details, see
?5.3.1.1, Use of IP by the linker). It can also be used within a routine
to hold intermediate values between subroutine calls."

Thanks,

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

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

* Re: [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
  2017-03-24 14:42       ` Marc Zyngier
@ 2017-03-24 15:23         ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 15:23 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Fri, Mar 24, 2017 at 02:42:13PM +0000, Marc Zyngier wrote:
> On 24/03/17 14:33, Christoffer Dall wrote:
> > On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
> >> In order to help people understanding the hyp-stub API that exists
> >> between the host kernel and the hypervisor mode (whether a hypervisor
> >> has been installed or not), let's document said API.
> >>
> >> As with any form of documentation, I expect it to become obsolete
> >> and completely misleading within 20 minutes after having being merged.
> > 
> > I don't think this last sentence belongs in the commit message.
> > 
> >>
> >> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
> >>  1 file changed, 45 insertions(+)
> >>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
> >>
> >> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
> >> new file mode 100644
> >> index 000000000000..a1e0314d2249
> >> --- /dev/null
> >> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
> >> @@ -0,0 +1,45 @@
> >> +* Internal ABI between the kernel and HYP
> >> +
> >> +This file documents the interaction between the Linux kernel and the
> >> +hypervisor layer when running Linux as a hypervisor (for example
> >> +KVM). It doesn't cover the interaction of the kernel with the
> >> +hypervisor when running as a guest (under Xen, KVM or any other
> >> +hypervisor), or any hypervisor-specific interaction when the kernel is
> >> +used as a host.
> >> +
> >> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
> >> +mode, but still needs to interact with it, allowing a built-in
> >> +hypervisor to be either installed or torn down.
> >> +
> >> +In order to achieve this, the kernel must be booted at HYP (arm) or
> >> +EL2 (arm64), allowing it to install a set of stubs before dropping to
> >> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
> >> +and only act on individual CPUs.
> >> +
> >> +Unless specified otherwise, any built-in hypervisor must implement
> >> +these functions (see arch/arm{,64}/include/asm/virt.h):
> >> +
> >> +* r0/x0 = HVC_SET_VECTORS
> >> +  r1/x1 = vectors
> >> +
> >> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
> >> +  must be a physical address, and respect the alignment requirements
> >> +  of the architecture. Only implemented by the initial stubs.
> > 
> > Does this last sentence mean that KVM doesn't implement this function?
> 
> Indeed. 

I think the wording could be improved to "Only implemented by the
initial stubs, not by Linux hypervisors."

> Directly setting the vectors is inherently unsafe (MMU could
> still be ON, for example), hence the HVC_SET_VECTORS operation that
> allow this to be done safely (RESET followed by SET).
> 

Hmm, is it any less safe than setting the vectors using the hyp stubs?
In the initial case, we're relying on the caller knowing that the MMU is
off, and that the stubs are in place, otherwise it doesn't make sense.

But I think the point is just that we don't have a need to change the
vector from within KVM; we only have a need to set the vector when going
from stub->kvm, and we have a need to reset the whole thing (including
turning off the MMU) when going from kvm->stub.

Anyhow, my comment was just about the wording, as I had some nagging
doubt when I read the patch.

> > 
> >> +
> >> +* r0/x0 = HVC_RESET_VECTORS
> >> +
> >> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
> >> +  value. This effectively disables an existing hypervisor.
> > 
> > What's the 'default value' ?  Could we say to the physical address of
> > the hypervisor stub's exception vector?
> 
> Shouldn't that be the kernel stub's exception vector?
> 

Yeah, the "initials stubs' exception vector" is probably the most
coherent thing we can use here.

Thanks,
-Christoffer

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

* [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
@ 2017-03-24 15:23         ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 15:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 24, 2017 at 02:42:13PM +0000, Marc Zyngier wrote:
> On 24/03/17 14:33, Christoffer Dall wrote:
> > On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
> >> In order to help people understanding the hyp-stub API that exists
> >> between the host kernel and the hypervisor mode (whether a hypervisor
> >> has been installed or not), let's document said API.
> >>
> >> As with any form of documentation, I expect it to become obsolete
> >> and completely misleading within 20 minutes after having being merged.
> > 
> > I don't think this last sentence belongs in the commit message.
> > 
> >>
> >> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
> >>  1 file changed, 45 insertions(+)
> >>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
> >>
> >> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
> >> new file mode 100644
> >> index 000000000000..a1e0314d2249
> >> --- /dev/null
> >> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
> >> @@ -0,0 +1,45 @@
> >> +* Internal ABI between the kernel and HYP
> >> +
> >> +This file documents the interaction between the Linux kernel and the
> >> +hypervisor layer when running Linux as a hypervisor (for example
> >> +KVM). It doesn't cover the interaction of the kernel with the
> >> +hypervisor when running as a guest (under Xen, KVM or any other
> >> +hypervisor), or any hypervisor-specific interaction when the kernel is
> >> +used as a host.
> >> +
> >> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
> >> +mode, but still needs to interact with it, allowing a built-in
> >> +hypervisor to be either installed or torn down.
> >> +
> >> +In order to achieve this, the kernel must be booted at HYP (arm) or
> >> +EL2 (arm64), allowing it to install a set of stubs before dropping to
> >> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
> >> +and only act on individual CPUs.
> >> +
> >> +Unless specified otherwise, any built-in hypervisor must implement
> >> +these functions (see arch/arm{,64}/include/asm/virt.h):
> >> +
> >> +* r0/x0 = HVC_SET_VECTORS
> >> +  r1/x1 = vectors
> >> +
> >> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
> >> +  must be a physical address, and respect the alignment requirements
> >> +  of the architecture. Only implemented by the initial stubs.
> > 
> > Does this last sentence mean that KVM doesn't implement this function?
> 
> Indeed. 

I think the wording could be improved to "Only implemented by the
initial stubs, not by Linux hypervisors."

> Directly setting the vectors is inherently unsafe (MMU could
> still be ON, for example), hence the HVC_SET_VECTORS operation that
> allow this to be done safely (RESET followed by SET).
> 

Hmm, is it any less safe than setting the vectors using the hyp stubs?
In the initial case, we're relying on the caller knowing that the MMU is
off, and that the stubs are in place, otherwise it doesn't make sense.

But I think the point is just that we don't have a need to change the
vector from within KVM; we only have a need to set the vector when going
from stub->kvm, and we have a need to reset the whole thing (including
turning off the MMU) when going from kvm->stub.

Anyhow, my comment was just about the wording, as I had some nagging
doubt when I read the patch.

> > 
> >> +
> >> +* r0/x0 = HVC_RESET_VECTORS
> >> +
> >> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
> >> +  value. This effectively disables an existing hypervisor.
> > 
> > What's the 'default value' ?  Could we say to the physical address of
> > the hypervisor stub's exception vector?
> 
> Shouldn't that be the kernel stub's exception vector?
> 

Yeah, the "initials stubs' exception vector" is probably the most
coherent thing we can use here.

Thanks,
-Christoffer

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

* Re: [PATCH v4 25/28] ARM: decompressor: Remove __hyp_get_vectors usage
  2017-03-24 14:34     ` Christoffer Dall
@ 2017-03-24 15:26       ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 15:26 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Fri, Mar 24 2017 at  2:34:40 pm GMT, Christoffer Dall <cdall@linaro.org> wrote:
> On Tue, Mar 21, 2017 at 07:20:55PM +0000, Marc Zyngier wrote:
>> When the compressed image needs to be relocated to avoid being
>> overwritten by the decompression process, we need to relocate
>> the hyp vectors as well so that we can find them once the
>> decompression has taken effect.
>> 
>> For that, we perform the following calculation:
>> 	u32 v = __hyp_get_vectors();
>> 	v += offset;
>> 	__hyp_set_vectors(v);
>> 
>> But we're guaranteed that the initial value of v as returned by
>> __hyp_get_vectors is always __hyp_stub_vectors, because we have
>> just set it by calling __hyp_stub_install.
>> 
>> So let's remove the use of __hyp_get_vectors, and directly use
>> __hyp_stub_vectors instead.
>> 
>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm/boot/compressed/head.S | 5 ++++-
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
>> index 9150f9732785..d58bb104c6e8 100644
>> --- a/arch/arm/boot/compressed/head.S
>> +++ b/arch/arm/boot/compressed/head.S
>> @@ -422,7 +422,10 @@ dtb_check_done:
>>  		cmp	r0, #HYP_MODE
>>  		bne	1f
>>  
>> -		bl	__hyp_get_vectors
>> +0:		adr	r0, 0b
>> +		movw	r1, #:lower16:__hyp_stub_vectors - 0b
>> +		movt	r1, #:upper16:__hyp_stub_vectors - 0b
>> +		add	r0, r0, r1
>
> nit: you could add a comment explaining what r0 ends up containing,
> because I'm pretty sure this will feel obscure when not read in the
> context of this series with your commit message above.

Sure. This is "Ard's magic stuff" - I'll document that.

Thanks,

	M.
-- 
Jazz is not dead, it just smell funny.

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

* [PATCH v4 25/28] ARM: decompressor: Remove __hyp_get_vectors usage
@ 2017-03-24 15:26       ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 15:26 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 24 2017 at  2:34:40 pm GMT, Christoffer Dall <cdall@linaro.org> wrote:
> On Tue, Mar 21, 2017 at 07:20:55PM +0000, Marc Zyngier wrote:
>> When the compressed image needs to be relocated to avoid being
>> overwritten by the decompression process, we need to relocate
>> the hyp vectors as well so that we can find them once the
>> decompression has taken effect.
>> 
>> For that, we perform the following calculation:
>> 	u32 v = __hyp_get_vectors();
>> 	v += offset;
>> 	__hyp_set_vectors(v);
>> 
>> But we're guaranteed that the initial value of v as returned by
>> __hyp_get_vectors is always __hyp_stub_vectors, because we have
>> just set it by calling __hyp_stub_install.
>> 
>> So let's remove the use of __hyp_get_vectors, and directly use
>> __hyp_stub_vectors instead.
>> 
>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>> ---
>>  arch/arm/boot/compressed/head.S | 5 ++++-
>>  1 file changed, 4 insertions(+), 1 deletion(-)
>> 
>> diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
>> index 9150f9732785..d58bb104c6e8 100644
>> --- a/arch/arm/boot/compressed/head.S
>> +++ b/arch/arm/boot/compressed/head.S
>> @@ -422,7 +422,10 @@ dtb_check_done:
>>  		cmp	r0, #HYP_MODE
>>  		bne	1f
>>  
>> -		bl	__hyp_get_vectors
>> +0:		adr	r0, 0b
>> +		movw	r1, #:lower16:__hyp_stub_vectors - 0b
>> +		movt	r1, #:upper16:__hyp_stub_vectors - 0b
>> +		add	r0, r0, r1
>
> nit: you could add a comment explaining what r0 ends up containing,
> because I'm pretty sure this will feel obscure when not read in the
> context of this series with your commit message above.

Sure. This is "Ard's magic stuff" - I'll document that.

Thanks,

	M.
-- 
Jazz is not dead, it just smell funny.

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

* Re: [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
  2017-03-24 15:23         ` Christoffer Dall
@ 2017-03-24 15:57           ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 15:57 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On 24/03/17 15:23, Christoffer Dall wrote:
> On Fri, Mar 24, 2017 at 02:42:13PM +0000, Marc Zyngier wrote:
>> On 24/03/17 14:33, Christoffer Dall wrote:
>>> On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
>>>> In order to help people understanding the hyp-stub API that exists
>>>> between the host kernel and the hypervisor mode (whether a hypervisor
>>>> has been installed or not), let's document said API.
>>>>
>>>> As with any form of documentation, I expect it to become obsolete
>>>> and completely misleading within 20 minutes after having being merged.
>>>
>>> I don't think this last sentence belongs in the commit message.
>>>
>>>>
>>>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> ---
>>>>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
>>>>  1 file changed, 45 insertions(+)
>>>>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
>>>>
>>>> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
>>>> new file mode 100644
>>>> index 000000000000..a1e0314d2249
>>>> --- /dev/null
>>>> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
>>>> @@ -0,0 +1,45 @@
>>>> +* Internal ABI between the kernel and HYP
>>>> +
>>>> +This file documents the interaction between the Linux kernel and the
>>>> +hypervisor layer when running Linux as a hypervisor (for example
>>>> +KVM). It doesn't cover the interaction of the kernel with the
>>>> +hypervisor when running as a guest (under Xen, KVM or any other
>>>> +hypervisor), or any hypervisor-specific interaction when the kernel is
>>>> +used as a host.
>>>> +
>>>> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
>>>> +mode, but still needs to interact with it, allowing a built-in
>>>> +hypervisor to be either installed or torn down.
>>>> +
>>>> +In order to achieve this, the kernel must be booted at HYP (arm) or
>>>> +EL2 (arm64), allowing it to install a set of stubs before dropping to
>>>> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
>>>> +and only act on individual CPUs.
>>>> +
>>>> +Unless specified otherwise, any built-in hypervisor must implement
>>>> +these functions (see arch/arm{,64}/include/asm/virt.h):
>>>> +
>>>> +* r0/x0 = HVC_SET_VECTORS
>>>> +  r1/x1 = vectors
>>>> +
>>>> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
>>>> +  must be a physical address, and respect the alignment requirements
>>>> +  of the architecture. Only implemented by the initial stubs.
>>>
>>> Does this last sentence mean that KVM doesn't implement this function?
>>
>> Indeed. 
> 
> I think the wording could be improved to "Only implemented by the
> initial stubs, not by Linux hypervisors."

Looks good to me, I'll use that.

>> Directly setting the vectors is inherently unsafe (MMU could
>> still be ON, for example), hence the HVC_SET_VECTORS operation that
>> allow this to be done safely (RESET followed by SET).
>>
> 
> Hmm, is it any less safe than setting the vectors using the hyp stubs?
> In the initial case, we're relying on the caller knowing that the MMU is
> off, and that the stubs are in place, otherwise it doesn't make sense.

That's why I was implying here that RESET+SET is the safe way of doing
it. Another solution may be to make SET imply RESET, and keep it
implemented always?

> But I think the point is just that we don't have a need to change the
> vector from within KVM; we only have a need to set the vector when going
> from stub->kvm, and we have a need to reset the whole thing (including
> turning off the MMU) when going from kvm->stub.

Exactly. The current API doesn't try to cater for all possible cases. It
just make sure that KVM can be installed and torn down safely.

> Anyhow, my comment was just about the wording, as I had some nagging
> doubt when I read the patch.
> 
>>>
>>>> +
>>>> +* r0/x0 = HVC_RESET_VECTORS
>>>> +
>>>> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
>>>> +  value. This effectively disables an existing hypervisor.
>>>
>>> What's the 'default value' ?  Could we say to the physical address of
>>> the hypervisor stub's exception vector?
>>
>> Shouldn't that be the kernel stub's exception vector?
>>
> 
> Yeah, the "initials stubs' exception vector" is probably the most
> coherent thing we can use here.

I'll use that when respinning it.

Thanks,

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

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

* [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
@ 2017-03-24 15:57           ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-03-24 15:57 UTC (permalink / raw)
  To: linux-arm-kernel

On 24/03/17 15:23, Christoffer Dall wrote:
> On Fri, Mar 24, 2017 at 02:42:13PM +0000, Marc Zyngier wrote:
>> On 24/03/17 14:33, Christoffer Dall wrote:
>>> On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
>>>> In order to help people understanding the hyp-stub API that exists
>>>> between the host kernel and the hypervisor mode (whether a hypervisor
>>>> has been installed or not), let's document said API.
>>>>
>>>> As with any form of documentation, I expect it to become obsolete
>>>> and completely misleading within 20 minutes after having being merged.
>>>
>>> I don't think this last sentence belongs in the commit message.
>>>
>>>>
>>>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> ---
>>>>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
>>>>  1 file changed, 45 insertions(+)
>>>>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
>>>>
>>>> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
>>>> new file mode 100644
>>>> index 000000000000..a1e0314d2249
>>>> --- /dev/null
>>>> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
>>>> @@ -0,0 +1,45 @@
>>>> +* Internal ABI between the kernel and HYP
>>>> +
>>>> +This file documents the interaction between the Linux kernel and the
>>>> +hypervisor layer when running Linux as a hypervisor (for example
>>>> +KVM). It doesn't cover the interaction of the kernel with the
>>>> +hypervisor when running as a guest (under Xen, KVM or any other
>>>> +hypervisor), or any hypervisor-specific interaction when the kernel is
>>>> +used as a host.
>>>> +
>>>> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
>>>> +mode, but still needs to interact with it, allowing a built-in
>>>> +hypervisor to be either installed or torn down.
>>>> +
>>>> +In order to achieve this, the kernel must be booted at HYP (arm) or
>>>> +EL2 (arm64), allowing it to install a set of stubs before dropping to
>>>> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
>>>> +and only act on individual CPUs.
>>>> +
>>>> +Unless specified otherwise, any built-in hypervisor must implement
>>>> +these functions (see arch/arm{,64}/include/asm/virt.h):
>>>> +
>>>> +* r0/x0 = HVC_SET_VECTORS
>>>> +  r1/x1 = vectors
>>>> +
>>>> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
>>>> +  must be a physical address, and respect the alignment requirements
>>>> +  of the architecture. Only implemented by the initial stubs.
>>>
>>> Does this last sentence mean that KVM doesn't implement this function?
>>
>> Indeed. 
> 
> I think the wording could be improved to "Only implemented by the
> initial stubs, not by Linux hypervisors."

Looks good to me, I'll use that.

>> Directly setting the vectors is inherently unsafe (MMU could
>> still be ON, for example), hence the HVC_SET_VECTORS operation that
>> allow this to be done safely (RESET followed by SET).
>>
> 
> Hmm, is it any less safe than setting the vectors using the hyp stubs?
> In the initial case, we're relying on the caller knowing that the MMU is
> off, and that the stubs are in place, otherwise it doesn't make sense.

That's why I was implying here that RESET+SET is the safe way of doing
it. Another solution may be to make SET imply RESET, and keep it
implemented always?

> But I think the point is just that we don't have a need to change the
> vector from within KVM; we only have a need to set the vector when going
> from stub->kvm, and we have a need to reset the whole thing (including
> turning off the MMU) when going from kvm->stub.

Exactly. The current API doesn't try to cater for all possible cases. It
just make sure that KVM can be installed and torn down safely.

> Anyhow, my comment was just about the wording, as I had some nagging
> doubt when I read the patch.
> 
>>>
>>>> +
>>>> +* r0/x0 = HVC_RESET_VECTORS
>>>> +
>>>> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
>>>> +  value. This effectively disables an existing hypervisor.
>>>
>>> What's the 'default value' ?  Could we say to the physical address of
>>> the hypervisor stub's exception vector?
>>
>> Shouldn't that be the kernel stub's exception vector?
>>
> 
> Yeah, the "initials stubs' exception vector" is probably the most
> coherent thing we can use here.

I'll use that when respinning it.

Thanks,

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

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

* Re: [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
  2017-03-24 15:57           ` Marc Zyngier
@ 2017-03-24 16:03             ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 16:03 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Fri, Mar 24, 2017 at 03:57:41PM +0000, Marc Zyngier wrote:
> On 24/03/17 15:23, Christoffer Dall wrote:
> > On Fri, Mar 24, 2017 at 02:42:13PM +0000, Marc Zyngier wrote:
> >> On 24/03/17 14:33, Christoffer Dall wrote:
> >>> On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
> >>>> In order to help people understanding the hyp-stub API that exists
> >>>> between the host kernel and the hypervisor mode (whether a hypervisor
> >>>> has been installed or not), let's document said API.
> >>>>
> >>>> As with any form of documentation, I expect it to become obsolete
> >>>> and completely misleading within 20 minutes after having being merged.
> >>>
> >>> I don't think this last sentence belongs in the commit message.
> >>>
> >>>>
> >>>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> >>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >>>> ---
> >>>>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
> >>>>  1 file changed, 45 insertions(+)
> >>>>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
> >>>>
> >>>> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
> >>>> new file mode 100644
> >>>> index 000000000000..a1e0314d2249
> >>>> --- /dev/null
> >>>> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
> >>>> @@ -0,0 +1,45 @@
> >>>> +* Internal ABI between the kernel and HYP
> >>>> +
> >>>> +This file documents the interaction between the Linux kernel and the
> >>>> +hypervisor layer when running Linux as a hypervisor (for example
> >>>> +KVM). It doesn't cover the interaction of the kernel with the
> >>>> +hypervisor when running as a guest (under Xen, KVM or any other
> >>>> +hypervisor), or any hypervisor-specific interaction when the kernel is
> >>>> +used as a host.
> >>>> +
> >>>> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
> >>>> +mode, but still needs to interact with it, allowing a built-in
> >>>> +hypervisor to be either installed or torn down.
> >>>> +
> >>>> +In order to achieve this, the kernel must be booted at HYP (arm) or
> >>>> +EL2 (arm64), allowing it to install a set of stubs before dropping to
> >>>> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
> >>>> +and only act on individual CPUs.
> >>>> +
> >>>> +Unless specified otherwise, any built-in hypervisor must implement
> >>>> +these functions (see arch/arm{,64}/include/asm/virt.h):
> >>>> +
> >>>> +* r0/x0 = HVC_SET_VECTORS
> >>>> +  r1/x1 = vectors
> >>>> +
> >>>> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
> >>>> +  must be a physical address, and respect the alignment requirements
> >>>> +  of the architecture. Only implemented by the initial stubs.
> >>>
> >>> Does this last sentence mean that KVM doesn't implement this function?
> >>
> >> Indeed. 
> > 
> > I think the wording could be improved to "Only implemented by the
> > initial stubs, not by Linux hypervisors."
> 
> Looks good to me, I'll use that.
> 
> >> Directly setting the vectors is inherently unsafe (MMU could
> >> still be ON, for example), hence the HVC_SET_VECTORS operation that
> >> allow this to be done safely (RESET followed by SET).
> >>
> > 
> > Hmm, is it any less safe than setting the vectors using the hyp stubs?
> > In the initial case, we're relying on the caller knowing that the MMU is
> > off, and that the stubs are in place, otherwise it doesn't make sense.
> 
> That's why I was implying here that RESET+SET is the safe way of doing
> it. Another solution may be to make SET imply RESET, and keep it
> implemented always?
> 

Meh, I think these patches are as stable as is required for the use
cases at hand, so let's not introduce more churn in these patches.

> > But I think the point is just that we don't have a need to change the
> > vector from within KVM; we only have a need to set the vector when going
> > from stub->kvm, and we have a need to reset the whole thing (including
> > turning off the MMU) when going from kvm->stub.
> 
> Exactly. The current API doesn't try to cater for all possible cases. It
> just make sure that KVM can be installed and torn down safely.
> 

Fair enough.

> > Anyhow, my comment was just about the wording, as I had some nagging
> > doubt when I read the patch.
> > 
> >>>
> >>>> +
> >>>> +* r0/x0 = HVC_RESET_VECTORS
> >>>> +
> >>>> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
> >>>> +  value. This effectively disables an existing hypervisor.
> >>>
> >>> What's the 'default value' ?  Could we say to the physical address of
> >>> the hypervisor stub's exception vector?
> >>
> >> Shouldn't that be the kernel stub's exception vector?
> >>
> > 
> > Yeah, the "initials stubs' exception vector" is probably the most
> > coherent thing we can use here.
> 
> I'll use that when respinning it.
> 

Thanks,
-Christoffer

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

* [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation
@ 2017-03-24 16:03             ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-03-24 16:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 24, 2017 at 03:57:41PM +0000, Marc Zyngier wrote:
> On 24/03/17 15:23, Christoffer Dall wrote:
> > On Fri, Mar 24, 2017 at 02:42:13PM +0000, Marc Zyngier wrote:
> >> On 24/03/17 14:33, Christoffer Dall wrote:
> >>> On Tue, Mar 21, 2017 at 07:20:58PM +0000, Marc Zyngier wrote:
> >>>> In order to help people understanding the hyp-stub API that exists
> >>>> between the host kernel and the hypervisor mode (whether a hypervisor
> >>>> has been installed or not), let's document said API.
> >>>>
> >>>> As with any form of documentation, I expect it to become obsolete
> >>>> and completely misleading within 20 minutes after having being merged.
> >>>
> >>> I don't think this last sentence belongs in the commit message.
> >>>
> >>>>
> >>>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> >>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >>>> ---
> >>>>  Documentation/virtual/kvm/arm/hyp-abi.txt | 45 +++++++++++++++++++++++++++++++
> >>>>  1 file changed, 45 insertions(+)
> >>>>  create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
> >>>>
> >>>> diff --git a/Documentation/virtual/kvm/arm/hyp-abi.txt b/Documentation/virtual/kvm/arm/hyp-abi.txt
> >>>> new file mode 100644
> >>>> index 000000000000..a1e0314d2249
> >>>> --- /dev/null
> >>>> +++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
> >>>> @@ -0,0 +1,45 @@
> >>>> +* Internal ABI between the kernel and HYP
> >>>> +
> >>>> +This file documents the interaction between the Linux kernel and the
> >>>> +hypervisor layer when running Linux as a hypervisor (for example
> >>>> +KVM). It doesn't cover the interaction of the kernel with the
> >>>> +hypervisor when running as a guest (under Xen, KVM or any other
> >>>> +hypervisor), or any hypervisor-specific interaction when the kernel is
> >>>> +used as a host.
> >>>> +
> >>>> +On arm and arm64 (without VHE), the kernel doesn't run in hypervisor
> >>>> +mode, but still needs to interact with it, allowing a built-in
> >>>> +hypervisor to be either installed or torn down.
> >>>> +
> >>>> +In order to achieve this, the kernel must be booted at HYP (arm) or
> >>>> +EL2 (arm64), allowing it to install a set of stubs before dropping to
> >>>> +SVC/EL1. These stubs are accessible by using a 'hvc #0' instruction,
> >>>> +and only act on individual CPUs.
> >>>> +
> >>>> +Unless specified otherwise, any built-in hypervisor must implement
> >>>> +these functions (see arch/arm{,64}/include/asm/virt.h):
> >>>> +
> >>>> +* r0/x0 = HVC_SET_VECTORS
> >>>> +  r1/x1 = vectors
> >>>> +
> >>>> +  Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 'vectors'
> >>>> +  must be a physical address, and respect the alignment requirements
> >>>> +  of the architecture. Only implemented by the initial stubs.
> >>>
> >>> Does this last sentence mean that KVM doesn't implement this function?
> >>
> >> Indeed. 
> > 
> > I think the wording could be improved to "Only implemented by the
> > initial stubs, not by Linux hypervisors."
> 
> Looks good to me, I'll use that.
> 
> >> Directly setting the vectors is inherently unsafe (MMU could
> >> still be ON, for example), hence the HVC_SET_VECTORS operation that
> >> allow this to be done safely (RESET followed by SET).
> >>
> > 
> > Hmm, is it any less safe than setting the vectors using the hyp stubs?
> > In the initial case, we're relying on the caller knowing that the MMU is
> > off, and that the stubs are in place, otherwise it doesn't make sense.
> 
> That's why I was implying here that RESET+SET is the safe way of doing
> it. Another solution may be to make SET imply RESET, and keep it
> implemented always?
> 

Meh, I think these patches are as stable as is required for the use
cases at hand, so let's not introduce more churn in these patches.

> > But I think the point is just that we don't have a need to change the
> > vector from within KVM; we only have a need to set the vector when going
> > from stub->kvm, and we have a need to reset the whole thing (including
> > turning off the MMU) when going from kvm->stub.
> 
> Exactly. The current API doesn't try to cater for all possible cases. It
> just make sure that KVM can be installed and torn down safely.
> 

Fair enough.

> > Anyhow, my comment was just about the wording, as I had some nagging
> > doubt when I read the patch.
> > 
> >>>
> >>>> +
> >>>> +* r0/x0 = HVC_RESET_VECTORS
> >>>> +
> >>>> +  Turn HYP/EL2 MMU off, and reset HVBAR/VBAR_EL2 to the default
> >>>> +  value. This effectively disables an existing hypervisor.
> >>>
> >>> What's the 'default value' ?  Could we say to the physical address of
> >>> the hypervisor stub's exception vector?
> >>
> >> Shouldn't that be the kernel stub's exception vector?
> >>
> > 
> > Yeah, the "initials stubs' exception vector" is probably the most
> > coherent thing we can use here.
> 
> I'll use that when respinning it.
> 

Thanks,
-Christoffer

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

* Re: [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-03-24 14:56       ` Marc Zyngier
@ 2017-04-03 17:28         ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-04-03 17:28 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Fri, Mar 24, 2017 at 02:56:51PM +0000, Marc Zyngier wrote:
> On 24/03/17 14:33, Christoffer Dall wrote:
> > On Tue, Mar 21, 2017 at 07:20:37PM +0000, Marc Zyngier wrote:
> >> We now have a full hyp-stub implementation in the KVM init code,
> >> but the main KVM code only supports HVC_GET_VECTORS, which is not
> >> enough.
> >>
> >> Instead of reinventing the wheel, let's reuse the init implementation
> >> by branching to the idmap page when called with a hyp-stub hypercall.
> >>
> >> Reviewed-by: James Morse <james.morse@arm.com>
> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++-----
> >>  1 file changed, 19 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> >> index d8ef788646c6..4f34c5996f86 100644
> >> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> >> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> >> @@ -87,10 +87,24 @@ alternative_endif
> >>  	/* Here, we're pretty sure the host called HVC. */
> >>  	ldp	x0, x1, [sp], #16
> >>  
> >> -	cmp	x0, #HVC_GET_VECTORS
> >> -	b.ne	1f
> >> -	mrs	x0, vbar_el2
> >> -	b	2f
> >> +	/* Check for a stub HVC call */
> >> +	cmp	x0, #HVC_STUB_HCALL_NR
> >> +	b.hs	1f
> >> +
> >> +	/*
> >> +	 * Compute the idmap address of __kvm_handle_stub_hvc and
> >> +	 * jump there. Since we use kimage_voffset, do not use the
> >> +	 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead
> >> +	 * (by loading it from the constant pool).
> >> +	 *
> >> +	 * Preserve x0-x4, which may contain stub parameters.
> >> +	 */
> >> +	ldr	x5, =__kvm_handle_stub_hvc
> >> +	ldr_l	x6, kimage_voffset
> > 
> > Isn't it a bit dodgy to just overwrite x5 and x6 in something which is
> > not a function?  I know that in practice this always gets called through
> > a function call and we can rely on the calling convention, but this can
> > break if you issue a hypercall to KVM's HVC sub implementation using
> > inline assembly, I think.
> > 
> > Am I missing something here?
> 
> I don't think you're missing anything. We're definitely relying on
> getting there via a function call which is going to preserve the
> caller-saved registers.
> 
> The only case where we issue a naked HVC call is when we use
> HVC_SOFT_RESTART. At this point, corrupted registers is not much of a worry.
> 
> Now, I see two ways of dealing with this:
> - We save x5/x6 on the stack, restoring them in the stub handler , right
> before the eret
> - Or we simply document the behaviour in asm/virt.h so that people
> adding new stub methods know the restrictions.
> 
> Thoughts?
> 

I'm perfectly happy with documenting the feature and documenting it
here.  It just felt arbitrary to me when I read the code that we could
just step on x5/x6.

Thanks,
-Christoffer

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

* [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-04-03 17:28         ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-04-03 17:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 24, 2017 at 02:56:51PM +0000, Marc Zyngier wrote:
> On 24/03/17 14:33, Christoffer Dall wrote:
> > On Tue, Mar 21, 2017 at 07:20:37PM +0000, Marc Zyngier wrote:
> >> We now have a full hyp-stub implementation in the KVM init code,
> >> but the main KVM code only supports HVC_GET_VECTORS, which is not
> >> enough.
> >>
> >> Instead of reinventing the wheel, let's reuse the init implementation
> >> by branching to the idmap page when called with a hyp-stub hypercall.
> >>
> >> Reviewed-by: James Morse <james.morse@arm.com>
> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  arch/arm64/kvm/hyp/hyp-entry.S | 24 +++++++++++++++++++-----
> >>  1 file changed, 19 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/arch/arm64/kvm/hyp/hyp-entry.S b/arch/arm64/kvm/hyp/hyp-entry.S
> >> index d8ef788646c6..4f34c5996f86 100644
> >> --- a/arch/arm64/kvm/hyp/hyp-entry.S
> >> +++ b/arch/arm64/kvm/hyp/hyp-entry.S
> >> @@ -87,10 +87,24 @@ alternative_endif
> >>  	/* Here, we're pretty sure the host called HVC. */
> >>  	ldp	x0, x1, [sp], #16
> >>  
> >> -	cmp	x0, #HVC_GET_VECTORS
> >> -	b.ne	1f
> >> -	mrs	x0, vbar_el2
> >> -	b	2f
> >> +	/* Check for a stub HVC call */
> >> +	cmp	x0, #HVC_STUB_HCALL_NR
> >> +	b.hs	1f
> >> +
> >> +	/*
> >> +	 * Compute the idmap address of __kvm_handle_stub_hvc and
> >> +	 * jump there. Since we use kimage_voffset, do not use the
> >> +	 * HYP VA for __kvm_handle_stub_hvc, but the kernel VA instead
> >> +	 * (by loading it from the constant pool).
> >> +	 *
> >> +	 * Preserve x0-x4, which may contain stub parameters.
> >> +	 */
> >> +	ldr	x5, =__kvm_handle_stub_hvc
> >> +	ldr_l	x6, kimage_voffset
> > 
> > Isn't it a bit dodgy to just overwrite x5 and x6 in something which is
> > not a function?  I know that in practice this always gets called through
> > a function call and we can rely on the calling convention, but this can
> > break if you issue a hypercall to KVM's HVC sub implementation using
> > inline assembly, I think.
> > 
> > Am I missing something here?
> 
> I don't think you're missing anything. We're definitely relying on
> getting there via a function call which is going to preserve the
> caller-saved registers.
> 
> The only case where we issue a naked HVC call is when we use
> HVC_SOFT_RESTART. At this point, corrupted registers is not much of a worry.
> 
> Now, I see two ways of dealing with this:
> - We save x5/x6 on the stack, restoring them in the stub handler , right
> before the eret
> - Or we simply document the behaviour in asm/virt.h so that people
> adding new stub methods know the restrictions.
> 
> Thoughts?
> 

I'm perfectly happy with documenting the feature and documenting it
here.  It just felt arbitrary to me when I read the code that we could
just step on x5/x6.

Thanks,
-Christoffer

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

* Re: [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-03-24 15:01       ` Marc Zyngier
@ 2017-04-03 17:32         ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-04-03 17:32 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On Fri, Mar 24, 2017 at 03:01:23PM +0000, Marc Zyngier wrote:
> On 24/03/17 14:34, Christoffer Dall wrote:
> > On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
> >> We now have a full hyp-stub implementation in the KVM init code,
> >> but the main KVM code only supports HVC_GET_VECTORS, which is not
> >> enough.
> >>
> >> Instead of reinventing the wheel, let's reuse the init implementation
> >> by branching to the idmap page when called with a hyp-stub hypercall.
> >>
> >> Tested-by: Keerthy <j-keerthy@ti.com>
> >> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
> >>  1 file changed, 24 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
> >> index 1f8db7d21fc5..a35baa81fd23 100644
> >> --- a/arch/arm/kvm/hyp/hyp-entry.S
> >> +++ b/arch/arm/kvm/hyp/hyp-entry.S
> >> @@ -126,11 +126,30 @@ hyp_hvc:
> >>  	 */
> >>  	pop	{r0, r1, r2}
> >>  
> >> -	/* Check for __hyp_get_vectors */
> >> -	cmp	r0, #HVC_GET_VECTORS
> >> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
> >> -	beq	1f
> >> +	/*
> >> +	 * Check if we have a kernel function, which is guaranteed to be
> >> +	 * bigger than the maximum hyp stub hypercall
> >> +	 */
> >> +	cmp	r0, #HVC_STUB_HCALL_NR
> >> +	bhs	1f
> >>  
> >> +	/*
> >> +	 * Not a kernel function, treat it as a stub hypercall.
> >> +	 * Compute the physical address for __kvm_handle_stub_hvc
> >> +	 * (as the code lives in the idmaped page) and branch there.
> >> +	 * We hijack ip (r12) as a tmp register.
> >> +	 */
> > 
> > How can we just clobber r12 and be sure we don't corrupt the caller?
> 
> r12 (aka ip) is allowed to be clobbered by the linker (used by inserted
> code veneers, for example). Given that this is a standalone object, we
> can safely assume that r12 has been saved if it was used by the caller.
> 
> Here is what the PCS says:
> 
> "Register r12 (IP) may be used by a linker as a scratch register between
> a routine and any subroutine it calls (for details, see
> §5.3.1.1, Use of IP by the linker). It can also be used within a routine
> to hold intermediate values between subroutine calls."
> 

So isn't this similar to my comment on the arm64 code, which relies on
this being called via a function call, as opposed to directly issuring
an HVC via inline assembly?

If so, documenting this limitation/restriction/feature would be nice.

Thanks,
-Christoffer

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

* [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-04-03 17:32         ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-04-03 17:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 24, 2017 at 03:01:23PM +0000, Marc Zyngier wrote:
> On 24/03/17 14:34, Christoffer Dall wrote:
> > On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
> >> We now have a full hyp-stub implementation in the KVM init code,
> >> but the main KVM code only supports HVC_GET_VECTORS, which is not
> >> enough.
> >>
> >> Instead of reinventing the wheel, let's reuse the init implementation
> >> by branching to the idmap page when called with a hyp-stub hypercall.
> >>
> >> Tested-by: Keerthy <j-keerthy@ti.com>
> >> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> >> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >> ---
> >>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
> >>  1 file changed, 24 insertions(+), 5 deletions(-)
> >>
> >> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
> >> index 1f8db7d21fc5..a35baa81fd23 100644
> >> --- a/arch/arm/kvm/hyp/hyp-entry.S
> >> +++ b/arch/arm/kvm/hyp/hyp-entry.S
> >> @@ -126,11 +126,30 @@ hyp_hvc:
> >>  	 */
> >>  	pop	{r0, r1, r2}
> >>  
> >> -	/* Check for __hyp_get_vectors */
> >> -	cmp	r0, #HVC_GET_VECTORS
> >> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
> >> -	beq	1f
> >> +	/*
> >> +	 * Check if we have a kernel function, which is guaranteed to be
> >> +	 * bigger than the maximum hyp stub hypercall
> >> +	 */
> >> +	cmp	r0, #HVC_STUB_HCALL_NR
> >> +	bhs	1f
> >>  
> >> +	/*
> >> +	 * Not a kernel function, treat it as a stub hypercall.
> >> +	 * Compute the physical address for __kvm_handle_stub_hvc
> >> +	 * (as the code lives in the idmaped page) and branch there.
> >> +	 * We hijack ip (r12) as a tmp register.
> >> +	 */
> > 
> > How can we just clobber r12 and be sure we don't corrupt the caller?
> 
> r12 (aka ip) is allowed to be clobbered by the linker (used by inserted
> code veneers, for example). Given that this is a standalone object, we
> can safely assume that r12 has been saved if it was used by the caller.
> 
> Here is what the PCS says:
> 
> "Register r12 (IP) may be used by a linker as a scratch register between
> a routine and any subroutine it calls (for details, see
> ?5.3.1.1, Use of IP by the linker). It can also be used within a routine
> to hold intermediate values between subroutine calls."
> 

So isn't this similar to my comment on the arm64 code, which relies on
this being called via a function call, as opposed to directly issuring
an HVC via inline assembly?

If so, documenting this limitation/restriction/feature would be nice.

Thanks,
-Christoffer

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

* Re: [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-04-03 17:32         ` Christoffer Dall
@ 2017-04-03 17:51           ` Marc Zyngier
  -1 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-04-03 17:51 UTC (permalink / raw)
  To: Christoffer Dall
  Cc: Russell King, kvm, Ard Biesheuvel, Catalin Marinas,
	linux-arm-kernel, Keerthy, kvmarm

On 03/04/17 18:32, Christoffer Dall wrote:
> On Fri, Mar 24, 2017 at 03:01:23PM +0000, Marc Zyngier wrote:
>> On 24/03/17 14:34, Christoffer Dall wrote:
>>> On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
>>>> We now have a full hyp-stub implementation in the KVM init code,
>>>> but the main KVM code only supports HVC_GET_VECTORS, which is not
>>>> enough.
>>>>
>>>> Instead of reinventing the wheel, let's reuse the init implementation
>>>> by branching to the idmap page when called with a hyp-stub hypercall.
>>>>
>>>> Tested-by: Keerthy <j-keerthy@ti.com>
>>>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> ---
>>>>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
>>>>  1 file changed, 24 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
>>>> index 1f8db7d21fc5..a35baa81fd23 100644
>>>> --- a/arch/arm/kvm/hyp/hyp-entry.S
>>>> +++ b/arch/arm/kvm/hyp/hyp-entry.S
>>>> @@ -126,11 +126,30 @@ hyp_hvc:
>>>>  	 */
>>>>  	pop	{r0, r1, r2}
>>>>  
>>>> -	/* Check for __hyp_get_vectors */
>>>> -	cmp	r0, #HVC_GET_VECTORS
>>>> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
>>>> -	beq	1f
>>>> +	/*
>>>> +	 * Check if we have a kernel function, which is guaranteed to be
>>>> +	 * bigger than the maximum hyp stub hypercall
>>>> +	 */
>>>> +	cmp	r0, #HVC_STUB_HCALL_NR
>>>> +	bhs	1f
>>>>  
>>>> +	/*
>>>> +	 * Not a kernel function, treat it as a stub hypercall.
>>>> +	 * Compute the physical address for __kvm_handle_stub_hvc
>>>> +	 * (as the code lives in the idmaped page) and branch there.
>>>> +	 * We hijack ip (r12) as a tmp register.
>>>> +	 */
>>>
>>> How can we just clobber r12 and be sure we don't corrupt the caller?
>>
>> r12 (aka ip) is allowed to be clobbered by the linker (used by inserted
>> code veneers, for example). Given that this is a standalone object, we
>> can safely assume that r12 has been saved if it was used by the caller.
>>
>> Here is what the PCS says:
>>
>> "Register r12 (IP) may be used by a linker as a scratch register between
>> a routine and any subroutine it calls (for details, see
>> §5.3.1.1, Use of IP by the linker). It can also be used within a routine
>> to hold intermediate values between subroutine calls."
>>
> 
> So isn't this similar to my comment on the arm64 code, which relies on
> this being called via a function call, as opposed to directly issuring
> an HVC via inline assembly?

Indeed, this is the exact same thing.

> If so, documenting this limitation/restriction/feature would be nice.

I've added the following to the documentation:

"A stub hypercall is allowed to clobber any of the caller-saved
registers (x0-x18 on arm64, r0-r3 and ip on arm). It is thus recommended
to use a function call to perform the hypercall."

Does this work for you?

Thanks,

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

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

* [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-04-03 17:51           ` Marc Zyngier
  0 siblings, 0 replies; 112+ messages in thread
From: Marc Zyngier @ 2017-04-03 17:51 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/04/17 18:32, Christoffer Dall wrote:
> On Fri, Mar 24, 2017 at 03:01:23PM +0000, Marc Zyngier wrote:
>> On 24/03/17 14:34, Christoffer Dall wrote:
>>> On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
>>>> We now have a full hyp-stub implementation in the KVM init code,
>>>> but the main KVM code only supports HVC_GET_VECTORS, which is not
>>>> enough.
>>>>
>>>> Instead of reinventing the wheel, let's reuse the init implementation
>>>> by branching to the idmap page when called with a hyp-stub hypercall.
>>>>
>>>> Tested-by: Keerthy <j-keerthy@ti.com>
>>>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
>>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
>>>> ---
>>>>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
>>>>  1 file changed, 24 insertions(+), 5 deletions(-)
>>>>
>>>> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
>>>> index 1f8db7d21fc5..a35baa81fd23 100644
>>>> --- a/arch/arm/kvm/hyp/hyp-entry.S
>>>> +++ b/arch/arm/kvm/hyp/hyp-entry.S
>>>> @@ -126,11 +126,30 @@ hyp_hvc:
>>>>  	 */
>>>>  	pop	{r0, r1, r2}
>>>>  
>>>> -	/* Check for __hyp_get_vectors */
>>>> -	cmp	r0, #HVC_GET_VECTORS
>>>> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
>>>> -	beq	1f
>>>> +	/*
>>>> +	 * Check if we have a kernel function, which is guaranteed to be
>>>> +	 * bigger than the maximum hyp stub hypercall
>>>> +	 */
>>>> +	cmp	r0, #HVC_STUB_HCALL_NR
>>>> +	bhs	1f
>>>>  
>>>> +	/*
>>>> +	 * Not a kernel function, treat it as a stub hypercall.
>>>> +	 * Compute the physical address for __kvm_handle_stub_hvc
>>>> +	 * (as the code lives in the idmaped page) and branch there.
>>>> +	 * We hijack ip (r12) as a tmp register.
>>>> +	 */
>>>
>>> How can we just clobber r12 and be sure we don't corrupt the caller?
>>
>> r12 (aka ip) is allowed to be clobbered by the linker (used by inserted
>> code veneers, for example). Given that this is a standalone object, we
>> can safely assume that r12 has been saved if it was used by the caller.
>>
>> Here is what the PCS says:
>>
>> "Register r12 (IP) may be used by a linker as a scratch register between
>> a routine and any subroutine it calls (for details, see
>> ?5.3.1.1, Use of IP by the linker). It can also be used within a routine
>> to hold intermediate values between subroutine calls."
>>
> 
> So isn't this similar to my comment on the arm64 code, which relies on
> this being called via a function call, as opposed to directly issuring
> an HVC via inline assembly?

Indeed, this is the exact same thing.

> If so, documenting this limitation/restriction/feature would be nice.

I've added the following to the documentation:

"A stub hypercall is allowed to clobber any of the caller-saved
registers (x0-x18 on arm64, r0-r3 and ip on arm). It is thus recommended
to use a function call to perform the hypercall."

Does this work for you?

Thanks,

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

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

* Re: [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
  2017-04-03 17:51           ` Marc Zyngier
@ 2017-04-04  7:36             ` Christoffer Dall
  -1 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-04-04  7:36 UTC (permalink / raw)
  To: Marc Zyngier
  Cc: linux-arm-kernel, kvm, kvmarm, Russell King, Christoffer Dall,
	Mark Rutland, Catalin Marinas, James Morse, Ard Biesheuvel,
	Keerthy

On Mon, Apr 03, 2017 at 06:51:02PM +0100, Marc Zyngier wrote:
> On 03/04/17 18:32, Christoffer Dall wrote:
> > On Fri, Mar 24, 2017 at 03:01:23PM +0000, Marc Zyngier wrote:
> >> On 24/03/17 14:34, Christoffer Dall wrote:
> >>> On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
> >>>> We now have a full hyp-stub implementation in the KVM init code,
> >>>> but the main KVM code only supports HVC_GET_VECTORS, which is not
> >>>> enough.
> >>>>
> >>>> Instead of reinventing the wheel, let's reuse the init implementation
> >>>> by branching to the idmap page when called with a hyp-stub hypercall.
> >>>>
> >>>> Tested-by: Keerthy <j-keerthy@ti.com>
> >>>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> >>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >>>> ---
> >>>>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
> >>>>  1 file changed, 24 insertions(+), 5 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
> >>>> index 1f8db7d21fc5..a35baa81fd23 100644
> >>>> --- a/arch/arm/kvm/hyp/hyp-entry.S
> >>>> +++ b/arch/arm/kvm/hyp/hyp-entry.S
> >>>> @@ -126,11 +126,30 @@ hyp_hvc:
> >>>>  	 */
> >>>>  	pop	{r0, r1, r2}
> >>>>  
> >>>> -	/* Check for __hyp_get_vectors */
> >>>> -	cmp	r0, #HVC_GET_VECTORS
> >>>> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
> >>>> -	beq	1f
> >>>> +	/*
> >>>> +	 * Check if we have a kernel function, which is guaranteed to be
> >>>> +	 * bigger than the maximum hyp stub hypercall
> >>>> +	 */
> >>>> +	cmp	r0, #HVC_STUB_HCALL_NR
> >>>> +	bhs	1f
> >>>>  
> >>>> +	/*
> >>>> +	 * Not a kernel function, treat it as a stub hypercall.
> >>>> +	 * Compute the physical address for __kvm_handle_stub_hvc
> >>>> +	 * (as the code lives in the idmaped page) and branch there.
> >>>> +	 * We hijack ip (r12) as a tmp register.
> >>>> +	 */
> >>>
> >>> How can we just clobber r12 and be sure we don't corrupt the caller?
> >>
> >> r12 (aka ip) is allowed to be clobbered by the linker (used by inserted
> >> code veneers, for example). Given that this is a standalone object, we
> >> can safely assume that r12 has been saved if it was used by the caller.
> >>
> >> Here is what the PCS says:
> >>
> >> "Register r12 (IP) may be used by a linker as a scratch register between
> >> a routine and any subroutine it calls (for details, see
> >> §5.3.1.1, Use of IP by the linker). It can also be used within a routine
> >> to hold intermediate values between subroutine calls."
> >>
> > 
> > So isn't this similar to my comment on the arm64 code, which relies on
> > this being called via a function call, as opposed to directly issuring
> > an HVC via inline assembly?
> 
> Indeed, this is the exact same thing.
> 
> > If so, documenting this limitation/restriction/feature would be nice.
> 
> I've added the following to the documentation:
> 
> "A stub hypercall is allowed to clobber any of the caller-saved
> registers (x0-x18 on arm64, r0-r3 and ip on arm). It is thus recommended
> to use a function call to perform the hypercall."
> 
> Does this work for you?
> 
It very much does.

Thanks,
-Christoffer

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

* [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
@ 2017-04-04  7:36             ` Christoffer Dall
  0 siblings, 0 replies; 112+ messages in thread
From: Christoffer Dall @ 2017-04-04  7:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Apr 03, 2017 at 06:51:02PM +0100, Marc Zyngier wrote:
> On 03/04/17 18:32, Christoffer Dall wrote:
> > On Fri, Mar 24, 2017 at 03:01:23PM +0000, Marc Zyngier wrote:
> >> On 24/03/17 14:34, Christoffer Dall wrote:
> >>> On Tue, Mar 21, 2017 at 07:20:49PM +0000, Marc Zyngier wrote:
> >>>> We now have a full hyp-stub implementation in the KVM init code,
> >>>> but the main KVM code only supports HVC_GET_VECTORS, which is not
> >>>> enough.
> >>>>
> >>>> Instead of reinventing the wheel, let's reuse the init implementation
> >>>> by branching to the idmap page when called with a hyp-stub hypercall.
> >>>>
> >>>> Tested-by: Keerthy <j-keerthy@ti.com>
> >>>> Acked-by: Russell King <rmk+kernel@armlinux.org.uk>
> >>>> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> >>>> ---
> >>>>  arch/arm/kvm/hyp/hyp-entry.S | 29 ++++++++++++++++++++++++-----
> >>>>  1 file changed, 24 insertions(+), 5 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm/kvm/hyp/hyp-entry.S b/arch/arm/kvm/hyp/hyp-entry.S
> >>>> index 1f8db7d21fc5..a35baa81fd23 100644
> >>>> --- a/arch/arm/kvm/hyp/hyp-entry.S
> >>>> +++ b/arch/arm/kvm/hyp/hyp-entry.S
> >>>> @@ -126,11 +126,30 @@ hyp_hvc:
> >>>>  	 */
> >>>>  	pop	{r0, r1, r2}
> >>>>  
> >>>> -	/* Check for __hyp_get_vectors */
> >>>> -	cmp	r0, #HVC_GET_VECTORS
> >>>> -	mrceq	p15, 4, r0, c12, c0, 0	@ get HVBAR
> >>>> -	beq	1f
> >>>> +	/*
> >>>> +	 * Check if we have a kernel function, which is guaranteed to be
> >>>> +	 * bigger than the maximum hyp stub hypercall
> >>>> +	 */
> >>>> +	cmp	r0, #HVC_STUB_HCALL_NR
> >>>> +	bhs	1f
> >>>>  
> >>>> +	/*
> >>>> +	 * Not a kernel function, treat it as a stub hypercall.
> >>>> +	 * Compute the physical address for __kvm_handle_stub_hvc
> >>>> +	 * (as the code lives in the idmaped page) and branch there.
> >>>> +	 * We hijack ip (r12) as a tmp register.
> >>>> +	 */
> >>>
> >>> How can we just clobber r12 and be sure we don't corrupt the caller?
> >>
> >> r12 (aka ip) is allowed to be clobbered by the linker (used by inserted
> >> code veneers, for example). Given that this is a standalone object, we
> >> can safely assume that r12 has been saved if it was used by the caller.
> >>
> >> Here is what the PCS says:
> >>
> >> "Register r12 (IP) may be used by a linker as a scratch register between
> >> a routine and any subroutine it calls (for details, see
> >> ?5.3.1.1, Use of IP by the linker). It can also be used within a routine
> >> to hold intermediate values between subroutine calls."
> >>
> > 
> > So isn't this similar to my comment on the arm64 code, which relies on
> > this being called via a function call, as opposed to directly issuring
> > an HVC via inline assembly?
> 
> Indeed, this is the exact same thing.
> 
> > If so, documenting this limitation/restriction/feature would be nice.
> 
> I've added the following to the documentation:
> 
> "A stub hypercall is allowed to clobber any of the caller-saved
> registers (x0-x18 on arm64, r0-r3 and ip on arm). It is thus recommended
> to use a function call to perform the hypercall."
> 
> Does this work for you?
> 
It very much does.

Thanks,
-Christoffer

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

end of thread, other threads:[~2017-04-04  7:36 UTC | newest]

Thread overview: 112+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-03-21 19:20 [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
2017-03-21 19:20 ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 01/28] arm64: hyp-stub: Stop pointlessly clobbering lr Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 02/28] arm64: KVM: Move lr save/restore to do_el2_call Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-23 11:57   ` Marc Zyngier
2017-03-23 11:57     ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 03/28] arm64: hyp-stub: Don't save lr in the EL1 code Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 04/28] arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 05/28] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-24 14:33   ` Christoffer Dall
2017-03-24 14:33     ` Christoffer Dall
2017-03-24 14:45     ` Marc Zyngier
2017-03-24 14:45       ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 06/28] arm64: KVM: Implement HVC_GET_VECTORS " Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 07/28] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-24 14:33   ` Christoffer Dall
2017-03-24 14:33     ` Christoffer Dall
2017-03-24 14:56     ` Marc Zyngier
2017-03-24 14:56       ` Marc Zyngier
2017-04-03 17:28       ` Christoffer Dall
2017-04-03 17:28         ` Christoffer Dall
2017-03-21 19:20 ` [PATCH v4 08/28] arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 09/28] arm64: KVM: Implement HVC_SOFT_RESTART in the init code Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 10/28] ARM: hyp-stub: improve ABI Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 11/28] ARM: soft-reboot into same mode that we entered the kernel Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 12/28] ARM: KVM: Convert KVM to use HVC_GET_VECTORS Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 13/28] ARM: Update cpu_v7_reset documentation Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 14/28] ARM: hyp-stub: Use r1 for the soft-restart address Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 15/28] ARM: Expose the VA/IDMAP offset Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 16/28] ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 17/28] ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall in the init code Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 18/28] ARM: KVM: Implement HVC_GET_VECTORS " Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 19/28] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-24 14:34   ` Christoffer Dall
2017-03-24 14:34     ` Christoffer Dall
2017-03-24 15:01     ` Marc Zyngier
2017-03-24 15:01       ` Marc Zyngier
2017-04-03 17:32       ` Christoffer Dall
2017-04-03 17:32         ` Christoffer Dall
2017-04-03 17:51         ` Marc Zyngier
2017-04-03 17:51           ` Marc Zyngier
2017-04-04  7:36           ` Christoffer Dall
2017-04-04  7:36             ` Christoffer Dall
2017-03-21 19:20 ` [PATCH v4 20/28] ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 21/28] ARM: KVM: Implement HVC_SOFT_RESTART in the init code Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 22/28] arm/arm64: KVM: Use __hyp_reset_vectors() directly Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 23/28] arm/arm64: KVM: Remove kvm_get_idmap_start Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 24/28] arm/arm64: KVM: Use HVC_RESET_VECTORS to reinit HYP mode Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 25/28] ARM: decompressor: Remove __hyp_get_vectors usage Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-24 14:34   ` Christoffer Dall
2017-03-24 14:34     ` Christoffer Dall
2017-03-24 15:26     ` Marc Zyngier
2017-03-24 15:26       ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 26/28] ARM: hyp-stub/KVM: Kill __hyp_get_vectors Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 27/28] arm64: " Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-21 19:20 ` [PATCH v4 28/28] arm/arm64: Add hyp-stub API documentation Marc Zyngier
2017-03-21 19:20   ` Marc Zyngier
2017-03-24 14:33   ` Christoffer Dall
2017-03-24 14:33     ` Christoffer Dall
2017-03-24 14:42     ` Marc Zyngier
2017-03-24 14:42       ` Marc Zyngier
2017-03-24 15:23       ` Christoffer Dall
2017-03-24 15:23         ` Christoffer Dall
2017-03-24 15:57         ` Marc Zyngier
2017-03-24 15:57           ` Marc Zyngier
2017-03-24 16:03           ` Christoffer Dall
2017-03-24 16:03             ` Christoffer Dall
2017-03-22 13:37 ` [PATCH v4 00/28] arm/arm64: KVM: Rework the hyp-stub API Christoffer Dall
2017-03-22 13:37   ` Christoffer Dall
2017-03-22 16:14   ` Marc Zyngier
2017-03-22 16:14     ` Marc Zyngier
2017-03-22 17:27     ` Christoffer Dall
2017-03-22 17:27       ` Christoffer Dall
2017-03-23 10:53       ` Marc Zyngier
2017-03-23 10:53         ` Marc Zyngier
2017-03-23 14:39         ` Christoffer Dall
2017-03-23 14:39           ` Christoffer Dall
2017-03-23 15:16           ` Marc Zyngier
2017-03-23 15:16             ` Marc Zyngier
2017-03-23 15:45             ` Christoffer Dall
2017-03-23 15:45               ` Christoffer Dall
2017-03-22 16:20 ` Catalin Marinas
2017-03-22 16:20   ` Catalin Marinas
2017-03-24 14:36 ` Christoffer Dall
2017-03-24 14:36   ` Christoffer Dall

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.