* [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API
@ 2017-02-17 15:44 Marc Zyngier
2017-02-17 15:44 ` [PATCH 01/20] arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
` (19 more replies)
0 siblings, 20 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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).
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
- Add some API documentation that covers the above
Patches 9 and 10 would be better squashed into 7 and 8, but I've kept
separate so that I can take the blame for everything I've broken.
This has been tested on arm and arm64, both as host and guest.
[1] http://lists.infradead.org/pipermail/linux-arm-kernel/2016-December/473472.html
Marc Zyngier (18):
arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall
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: 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
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: Simplify __cpu_reset_hyp_mode
arm/arm64: KVM: Remove kvm_get_idmap_start
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 | 48 +++++++++++++++++++++++++
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 | 11 ++++++
arch/arm/kernel/hyp-stub.S | 44 ++++++++++++++++++++---
arch/arm/kernel/reboot.c | 7 ++--
arch/arm/kvm/arm.c | 3 +-
arch/arm/kvm/hyp/hyp-entry.S | 29 +++++++++++++---
arch/arm/kvm/init.S | 58 ++++++++++++++++++++++++++-----
arch/arm/kvm/mmu.c | 5 ---
arch/arm/mm/mmu.c | 5 +++
arch/arm/mm/proc-v7.S | 12 ++++---
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 | 8 +++++
arch/arm64/kernel/hyp-stub.S | 13 ++++++-
arch/arm64/kvm/hyp-init.S | 50 ++++++++++++++++++++------
arch/arm64/kvm/hyp/hyp-entry.S | 39 ++++++++++-----------
21 files changed, 278 insertions(+), 76 deletions(-)
create mode 100644 Documentation/virtual/kvm/arm/hyp-abi.txt
--
2.11.0
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 01/20] arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 02/20] arm64: KVM: " Marc Zyngier
` (18 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/virt.h | 8 ++++++++
arch/arm64/kernel/hyp-stub.S | 13 ++++++++++++-
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 439f6b5d31f6..6d085a4d6cf1 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)
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index d3b5f75e652e..a162182d5662 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -79,8 +79,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)
@@ -137,3 +140,11 @@ ENTRY(__hyp_set_vectors)
ldr lr, [sp], #16
ret
ENDPROC(__hyp_set_vectors)
+
+ENTRY(__hyp_reset_vectors)
+ str lr, [sp, #-16]!
+ mov x0, #HVC_RESET_VECTORS
+ hvc #0
+ ldr lr, [sp], #16
+ ret
+ENDPROC(__hyp_reset_vectors)
--
2.11.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 02/20] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
2017-02-17 15:44 ` [PATCH 01/20] arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-20 16:54 ` James Morse
2017-02-17 15:44 ` [PATCH 03/20] arm64: KVM: Implement HVC_GET_VECTORS in the init code Marc Zyngier
` (17 subsequent siblings)
19 siblings, 1 reply; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
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..948f331c7f32 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 x2, #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] 27+ messages in thread
* [PATCH 03/20] arm64: KVM: Implement HVC_GET_VECTORS in the init code
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
2017-02-17 15:44 ` [PATCH 01/20] arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
2017-02-17 15:44 ` [PATCH 02/20] arm64: KVM: " Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 04/20] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation Marc Zyngier
` (16 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
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 948f331c7f32..2c7b86bb5483 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] 27+ messages in thread
* [PATCH 04/20] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (2 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 03/20] arm64: KVM: Implement HVC_GET_VECTORS in the init code Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 05/20] arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors Marc Zyngier
` (15 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
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 5e9052f087f2..21eeb2552f33 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] 27+ messages in thread
* [PATCH 05/20] arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (3 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 04/20] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 06/20] arm64: KVM: Implement HVC_SOFT_RESTART in the init code Marc Zyngier
` (14 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm64/include/asm/kvm_asm.h | 1 -
arch/arm64/include/asm/kvm_host.h | 4 ++--
arch/arm64/kvm/hyp-init.S | 2 --
arch/arm64/kvm/hyp/hyp-entry.S | 15 ---------------
4 files changed, 2 insertions(+), 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 e5050388e062..2e493e9a671e 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -361,11 +361,11 @@ 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);
+ extern void __hyp_reset_vectors(void);
+ __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 2c7b86bb5483..d12a232abd81 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 21eeb2552f33..1277f81b63b7 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] 27+ messages in thread
* [PATCH 06/20] arm64: KVM: Implement HVC_SOFT_RESTART in the init code
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (4 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 05/20] arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 07/20] ARM: hyp-stub: improve ABI Marc Zyngier
` (13 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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 d12a232abd81..586a35b4aaf3 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] 27+ messages in thread
* [PATCH 07/20] ARM: hyp-stub: improve ABI
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (5 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 06/20] arm64: KVM: Implement HVC_SOFT_RESTART in the init code Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 08/20] ARM: soft-reboot into same mode that we entered the kernel Marc Zyngier
` (12 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
Signed-off-by: Russell King <rmk+kernel@armlinux.org.uk>
---
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] 27+ messages in thread
* [PATCH 08/20] ARM: soft-reboot into same mode that we entered the kernel
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (6 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 07/20] ARM: hyp-stub: improve ABI Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 09/20] ARM: KVM: Convert KVM to use HVC_GET_VECTORS Marc Zyngier
` (11 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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>
---
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] 27+ messages in thread
* [PATCH 09/20] ARM: KVM: Convert KVM to use HVC_GET_VECTORS
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (7 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 08/20] ARM: soft-reboot into same mode that we entered the kernel Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 10/20] ARM: hyp-stub: Use r1 for the soft-restart address Marc Zyngier
` (10 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
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] 27+ messages in thread
* [PATCH 10/20] ARM: hyp-stub: Use r1 for the soft-restart address
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (8 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 09/20] ARM: KVM: Convert KVM to use HVC_GET_VECTORS Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-19 8:22 ` Ard Biesheuvel
2017-02-17 15:44 ` [PATCH 11/20] ARM: Expose the VA/IDMAP offset Marc Zyngier
` (9 subsequent siblings)
19 siblings, 1 reply; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/kernel/hyp-stub.S | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index 8301db963d83..8fa521bd63d2 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,8 @@ ENTRY(__hyp_set_vectors)
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)
--
2.11.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 11/20] ARM: Expose the VA/IDMAP offset
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (9 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 10/20] ARM: hyp-stub: Use r1 for the soft-restart address Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 12/20] ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
` (8 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
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 4001dd15818d..d9bb3ae876ad 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",
@@ -1654,4 +1656,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] 27+ messages in thread
* [PATCH 12/20] ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (10 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 11/20] ARM: Expose the VA/IDMAP offset Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 13/20] ARM: KVM: " Marc Zyngier
` (7 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
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 8fa521bd63d2..cf6d801f89e8 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
@@ -263,6 +266,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] 27+ messages in thread
* [PATCH 13/20] ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (11 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 12/20] ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-19 8:07 ` Ard Biesheuvel
2017-02-19 11:42 ` Ard Biesheuvel
2017-02-17 15:44 ` [PATCH 14/20] ARM: KVM: Implement HVC_GET_VECTORS in the init code Marc Zyngier
` (6 subsequent siblings)
19 siblings, 2 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/kernel/hyp-stub.S | 1 +
arch/arm/kvm/init.S | 37 +++++++++++++++++++++++++++++++------
2 files changed, 32 insertions(+), 6 deletions(-)
diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
index cf6d801f89e8..171a09cdf6b3 100644
--- a/arch/arm/kernel/hyp-stub.S
+++ b/arch/arm/kernel/hyp-stub.S
@@ -280,6 +280,7 @@ ENDPROC(__hyp_reset_vectors)
.align 5
__hyp_stub_vectors:
+.global __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..b0138118fac4 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,22 +121,38 @@ __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. We cannot use 'adr' to get to the
+ * stub vectors, hence having to play the VA->PA game.
+ */
+ adr r0, .L__va2pa @ PA
+ ldr r1, [r0] @ VA
+ sub r0, r0, r1 @ PA - VA
+ ldr r1, =__hyp_stub_vectors
+ add r1, r1, r0
+ 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
+.L__va2pa:
+ .word .
.globl __kvm_hyp_init_end
__kvm_hyp_init_end:
--
2.11.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 14/20] ARM: KVM: Implement HVC_GET_VECTORS in the init code
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (12 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 13/20] ARM: KVM: " Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 15/20] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation Marc Zyngier
` (5 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
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 b0138118fac4..438b148d47fd 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] 27+ messages in thread
* [PATCH 15/20] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (13 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 14/20] ARM: KVM: Implement HVC_GET_VECTORS in the init code Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 16/20] ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors Marc Zyngier
` (4 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
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] 27+ messages in thread
* [PATCH 16/20] ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (14 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 15/20] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 17/20] ARM: KVM: Implement HVC_SOFT_RESTART in the init code Marc Zyngier
` (3 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/kvm_asm.h | 2 --
arch/arm/include/asm/kvm_host.h | 3 ++-
arch/arm/kvm/init.S | 2 --
3 files changed, 2 insertions(+), 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 d5423ab15ed5..1962c5086897 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -277,7 +277,8 @@ 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);
+ extern void __hyp_reset_vectors(void);
+ __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 438b148d47fd..0ec1a83d03ea 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)
@@ -153,7 +152,6 @@ ENTRY(__kvm_hyp_reset)
exit:
eret
ENDPROC(__kvm_handle_stub_hvc)
-ENDPROC(__kvm_hyp_reset)
.ltorg
.L__va2pa:
--
2.11.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 17/20] ARM: KVM: Implement HVC_SOFT_RESTART in the init code
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (15 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 16/20] ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 18/20] arm/arm64: KVM: Simplify __cpu_reset_hyp_mode Marc Zyngier
` (2 subsequent siblings)
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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/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 0ec1a83d03ea..489e0f79ac2c 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] 27+ messages in thread
* [PATCH 18/20] arm/arm64: KVM: Simplify __cpu_reset_hyp_mode
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (16 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 17/20] ARM: KVM: Implement HVC_SOFT_RESTART in the init code Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 19/20] arm/arm64: KVM: Remove kvm_get_idmap_start Marc Zyngier
2017-02-17 15:44 ` [PATCH 20/20] arm/arm64: Add hyp-stub API documentation Marc Zyngier
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
arch/arm/include/asm/kvm_host.h | 3 +--
arch/arm/kvm/arm.c | 3 +--
arch/arm64/include/asm/kvm_host.h | 3 +--
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 1962c5086897..370d7c6d6e7a 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -274,8 +274,7 @@ 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)
+static inline void __cpu_reset_hyp_mode(void)
{
extern void __hyp_reset_vectors(void);
__hyp_reset_vectors();
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 9d7446456e0c..00b5205e8955 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -1122,8 +1122,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());
+ __cpu_reset_hyp_mode();
}
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 2e493e9a671e..8c8aae7cfe19 100644
--- a/arch/arm64/include/asm/kvm_host.h
+++ b/arch/arm64/include/asm/kvm_host.h
@@ -361,8 +361,7 @@ 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)
+static inline void __cpu_reset_hyp_mode(void)
{
extern void __hyp_reset_vectors(void);
__hyp_reset_vectors();
--
2.11.0
^ permalink raw reply related [flat|nested] 27+ messages in thread
* [PATCH 19/20] arm/arm64: KVM: Remove kvm_get_idmap_start
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (17 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 18/20] arm/arm64: KVM: Simplify __cpu_reset_hyp_mode Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 20/20] arm/arm64: Add hyp-stub API documentation Marc Zyngier
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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 74a44727f8e1..646a4d4236ba 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 a5265edbeeab..12ab3372f240 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -1677,11 +1677,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 6f72fe8b0e3e..ff1282344ece 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] 27+ messages in thread
* [PATCH 20/20] arm/arm64: Add hyp-stub API documentation
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
` (18 preceding siblings ...)
2017-02-17 15:44 ` [PATCH 19/20] arm/arm64: KVM: Remove kvm_get_idmap_start Marc Zyngier
@ 2017-02-17 15:44 ` Marc Zyngier
19 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-17 15:44 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 as with any form of documentation, I expect it to become obsolete
and completely misleading within 20 minutes after having being merged.
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
---
Documentation/virtual/kvm/arm/hyp-abi.txt | 48 +++++++++++++++++++++++++++++++
1 file changed, 48 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..ad3e16fe723c
--- /dev/null
+++ b/Documentation/virtual/kvm/arm/hyp-abi.txt
@@ -0,0 +1,48 @@
+* 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_GET_VECTORS
+
+ Return the current value of HVBAR/VBAR_EL2 in r0/x0.
+
+* r0/x0 = HVC_SET_VECTORS
+ r1/x1 = vectors
+
+ Set HVBAR/VBAR_EL2 to 'vectors' to enable a hypervisor. 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] 27+ messages in thread
* [PATCH 13/20] ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall
2017-02-17 15:44 ` [PATCH 13/20] ARM: KVM: " Marc Zyngier
@ 2017-02-19 8:07 ` Ard Biesheuvel
2017-02-19 11:19 ` Marc Zyngier
2017-02-19 11:42 ` Ard Biesheuvel
1 sibling, 1 reply; 27+ messages in thread
From: Ard Biesheuvel @ 2017-02-19 8:07 UTC (permalink / raw)
To: linux-arm-kernel
On 17 February 2017 at 15:44, Marc Zyngier <marc.zyngier@arm.com> 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.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> arch/arm/kernel/hyp-stub.S | 1 +
> arch/arm/kvm/init.S | 37 +++++++++++++++++++++++++++++++------
> 2 files changed, 32 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> index cf6d801f89e8..171a09cdf6b3 100644
> --- a/arch/arm/kernel/hyp-stub.S
> +++ b/arch/arm/kernel/hyp-stub.S
> @@ -280,6 +280,7 @@ ENDPROC(__hyp_reset_vectors)
>
> .align 5
> __hyp_stub_vectors:
> +.global __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..b0138118fac4 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,22 +121,38 @@ __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. We cannot use 'adr' to get to the
> + * stub vectors, hence having to play the VA->PA game.
> + */
> + adr r0, .L__va2pa @ PA
> + ldr r1, [r0] @ VA
> + sub r0, r0, r1 @ PA - VA
> + ldr r1, =__hyp_stub_vectors
Since we're guaranteed to be on v7, how about something like
0:adr r0, 0b
movw r1, #:lower16:__hyp_stub_vectors - 0b
movt r1, #:upper16:__hyp_stub_vectors - 0b
> + add r1, r1, r0
> + 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
> +.L__va2pa:
> + .word .
>
> .globl __kvm_hyp_init_end
> __kvm_hyp_init_end:
> --
> 2.11.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 10/20] ARM: hyp-stub: Use r1 for the soft-restart address
2017-02-17 15:44 ` [PATCH 10/20] ARM: hyp-stub: Use r1 for the soft-restart address Marc Zyngier
@ 2017-02-19 8:22 ` Ard Biesheuvel
2017-02-19 11:09 ` Marc Zyngier
0 siblings, 1 reply; 27+ messages in thread
From: Ard Biesheuvel @ 2017-02-19 8:22 UTC (permalink / raw)
To: linux-arm-kernel
On 17 February 2017 at 15:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
> 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.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> arch/arm/kernel/hyp-stub.S | 4 +---
> 1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> index 8301db963d83..8fa521bd63d2 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,8 @@ ENTRY(__hyp_set_vectors)
> 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)
>
/me confused. How does the address end up in r1?
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 10/20] ARM: hyp-stub: Use r1 for the soft-restart address
2017-02-19 8:22 ` Ard Biesheuvel
@ 2017-02-19 11:09 ` Marc Zyngier
0 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-19 11:09 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, 19 Feb 2017 08:22:23 +0000
Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 17 February 2017 at 15:44, Marc Zyngier <marc.zyngier@arm.com> wrote:
> > 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.
> >
> > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> > ---
> > arch/arm/kernel/hyp-stub.S | 4 +---
> > 1 file changed, 1 insertion(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> > index 8301db963d83..8fa521bd63d2 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,8 @@ ENTRY(__hyp_set_vectors)
> > 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)
> >
>
> /me confused. How does the address end up in r1?
I'm now very confused too. I just gave it another go on my A7 platform,
and it restarted just right, even if there is obviously junk in r1.
Guess I'm just bloody lucky.
Thanks for the heads up, I'll fix that for v2.
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 13/20] ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall
2017-02-19 8:07 ` Ard Biesheuvel
@ 2017-02-19 11:19 ` Marc Zyngier
0 siblings, 0 replies; 27+ messages in thread
From: Marc Zyngier @ 2017-02-19 11:19 UTC (permalink / raw)
To: linux-arm-kernel
On Sun, 19 Feb 2017 08:07:22 +0000
Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> On 17 February 2017 at 15:44, Marc Zyngier <marc.zyngier@arm.com> 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.
> >
> > Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> > ---
> > arch/arm/kernel/hyp-stub.S | 1 +
> > arch/arm/kvm/init.S | 37 +++++++++++++++++++++++++++++++------
> > 2 files changed, 32 insertions(+), 6 deletions(-)
> >
> > diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> > index cf6d801f89e8..171a09cdf6b3 100644
> > --- a/arch/arm/kernel/hyp-stub.S
> > +++ b/arch/arm/kernel/hyp-stub.S
> > @@ -280,6 +280,7 @@ ENDPROC(__hyp_reset_vectors)
> >
> > .align 5
> > __hyp_stub_vectors:
> > +.global __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..b0138118fac4 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,22 +121,38 @@ __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. We cannot use 'adr' to get to the
> > + * stub vectors, hence having to play the VA->PA game.
> > + */
> > + adr r0, .L__va2pa @ PA
> > + ldr r1, [r0] @ VA
> > + sub r0, r0, r1 @ PA - VA
> > + ldr r1, =__hyp_stub_vectors
>
> Since we're guaranteed to be on v7, how about something like
> 0:adr r0, 0b
> movw r1, #:lower16:__hyp_stub_vectors - 0b
> movt r1, #:upper16:__hyp_stub_vectors - 0b
Ah, very nice! It hurts my brain, but it is very nice indeed! I'll
borrow that for v2.
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 13/20] ARM: KVM: Implement HVC_RESET_VECTORS stub hypercall
2017-02-17 15:44 ` [PATCH 13/20] ARM: KVM: " Marc Zyngier
2017-02-19 8:07 ` Ard Biesheuvel
@ 2017-02-19 11:42 ` Ard Biesheuvel
1 sibling, 0 replies; 27+ messages in thread
From: Ard Biesheuvel @ 2017-02-19 11:42 UTC (permalink / raw)
To: linux-arm-kernel
On 17 February 2017 at 15:44, Marc Zyngier <marc.zyngier@arm.com> 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.
>
> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
> ---
> arch/arm/kernel/hyp-stub.S | 1 +
> arch/arm/kvm/init.S | 37 +++++++++++++++++++++++++++++++------
> 2 files changed, 32 insertions(+), 6 deletions(-)
>
> diff --git a/arch/arm/kernel/hyp-stub.S b/arch/arm/kernel/hyp-stub.S
> index cf6d801f89e8..171a09cdf6b3 100644
> --- a/arch/arm/kernel/hyp-stub.S
> +++ b/arch/arm/kernel/hyp-stub.S
> @@ -280,6 +280,7 @@ ENDPROC(__hyp_reset_vectors)
>
> .align 5
> __hyp_stub_vectors:
> +.global __hyp_stub_vectors
Oh, and (nit:) perhaps use
ENTRY(__hyp_stub_vectors)
here?
> __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..b0138118fac4 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,22 +121,38 @@ __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. We cannot use 'adr' to get to the
> + * stub vectors, hence having to play the VA->PA game.
> + */
> + adr r0, .L__va2pa @ PA
> + ldr r1, [r0] @ VA
> + sub r0, r0, r1 @ PA - VA
> + ldr r1, =__hyp_stub_vectors
> + add r1, r1, r0
> + 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
> +.L__va2pa:
> + .word .
>
> .globl __kvm_hyp_init_end
> __kvm_hyp_init_end:
> --
> 2.11.0
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 27+ messages in thread
* [PATCH 02/20] arm64: KVM: Implement HVC_RESET_VECTORS stub hypercall
2017-02-17 15:44 ` [PATCH 02/20] arm64: KVM: " Marc Zyngier
@ 2017-02-20 16:54 ` James Morse
0 siblings, 0 replies; 27+ messages in thread
From: James Morse @ 2017-02-20 16:54 UTC (permalink / raw)
To: linux-arm-kernel
Hi Marc,
On 17/02/17 15:44, 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.
> diff --git a/arch/arm64/kvm/hyp-init.S b/arch/arm64/kvm/hyp-init.S
> index 6b29d3d9e1f2..948f331c7f32 100644
> --- a/arch/arm64/kvm/hyp-init.S
> +++ b/arch/arm64/kvm/hyp-init.S
> @@ -58,6 +59,9 @@ __invalid:
> * x2: HYP vectors
> */
> __do_hyp_init:
> + /* Check for a stub HVC call */
> + cmp x2, #HVC_STUB_HCALL_NR
Nit: x2 -> x0?
> + 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.
> */
Thanks,
James
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2017-02-20 16:54 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-02-17 15:44 [PATCH 00/20] arm/arm64: KVM: Rework the hyp-stub API Marc Zyngier
2017-02-17 15:44 ` [PATCH 01/20] arm64: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
2017-02-17 15:44 ` [PATCH 02/20] arm64: KVM: " Marc Zyngier
2017-02-20 16:54 ` James Morse
2017-02-17 15:44 ` [PATCH 03/20] arm64: KVM: Implement HVC_GET_VECTORS in the init code Marc Zyngier
2017-02-17 15:44 ` [PATCH 04/20] arm64: KVM: Allow the main HYP code to use the init hyp stub implementation Marc Zyngier
2017-02-17 15:44 ` [PATCH 05/20] arm64: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors Marc Zyngier
2017-02-17 15:44 ` [PATCH 06/20] arm64: KVM: Implement HVC_SOFT_RESTART in the init code Marc Zyngier
2017-02-17 15:44 ` [PATCH 07/20] ARM: hyp-stub: improve ABI Marc Zyngier
2017-02-17 15:44 ` [PATCH 08/20] ARM: soft-reboot into same mode that we entered the kernel Marc Zyngier
2017-02-17 15:44 ` [PATCH 09/20] ARM: KVM: Convert KVM to use HVC_GET_VECTORS Marc Zyngier
2017-02-17 15:44 ` [PATCH 10/20] ARM: hyp-stub: Use r1 for the soft-restart address Marc Zyngier
2017-02-19 8:22 ` Ard Biesheuvel
2017-02-19 11:09 ` Marc Zyngier
2017-02-17 15:44 ` [PATCH 11/20] ARM: Expose the VA/IDMAP offset Marc Zyngier
2017-02-17 15:44 ` [PATCH 12/20] ARM: hyp-stub: Implement HVC_RESET_VECTORS stub hypercall Marc Zyngier
2017-02-17 15:44 ` [PATCH 13/20] ARM: KVM: " Marc Zyngier
2017-02-19 8:07 ` Ard Biesheuvel
2017-02-19 11:19 ` Marc Zyngier
2017-02-19 11:42 ` Ard Biesheuvel
2017-02-17 15:44 ` [PATCH 14/20] ARM: KVM: Implement HVC_GET_VECTORS in the init code Marc Zyngier
2017-02-17 15:44 ` [PATCH 15/20] ARM: KVM: Allow the main HYP code to use the init hyp stub implementation Marc Zyngier
2017-02-17 15:44 ` [PATCH 16/20] ARM: KVM: Convert __cpu_reset_hyp_mode to using __hyp_reset_vectors Marc Zyngier
2017-02-17 15:44 ` [PATCH 17/20] ARM: KVM: Implement HVC_SOFT_RESTART in the init code Marc Zyngier
2017-02-17 15:44 ` [PATCH 18/20] arm/arm64: KVM: Simplify __cpu_reset_hyp_mode Marc Zyngier
2017-02-17 15:44 ` [PATCH 19/20] arm/arm64: KVM: Remove kvm_get_idmap_start Marc Zyngier
2017-02-17 15:44 ` [PATCH 20/20] arm/arm64: Add hyp-stub API documentation Marc Zyngier
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).