Now that the hypervisor core is prepare for it, also convert the entry
path.

First, we have to extract some parameters from the hypervisor header and
the configuration, namely hypervisor and UART physical addresses. Their
virtual addresses are not build-time defined, both using the top 1-GB
page in the hypervisor address space. That reduces the likelihood of
address conflicts for the ID mapping of the trampoline page.

Our bootstrap page table now also has to contain an ID map of the
trampoline code. As hypervisor and UART share the same 1-GB page, they
can also share their level-1 and level-2 page tables. We map both as
2-MB pages. The trampoline page is mapped as 1-GB page and, thus,
requires an additional page table page. This structuring also simplifies
the setup because we no longer need to differentiate between various
cases.

The UART virtual address in the hypervisor header is now updated by the
entry code, taking the fixed 2-MB base address as well as the offset
into that page - based on the physical address - into account.

This change overcomes the ugly need to define a target-specific
JAILHOUSE_BASE in config.h.

Signed-off-by: Jan Kiszka <[email protected]>
---
 ci/jailhouse-config-amd-seattle.h                  |   1 -
 hypervisor/arch/arm64/asm-defines.c                |   7 +-
 hypervisor/arch/arm64/entry.S                      | 159 +++++++++++----------
 .../arch/arm64/include/asm/jailhouse_hypercall.h   |   2 -
 hypervisor/arch/arm64/include/asm/paging.h         |   3 +
 hypervisor/arch/arm64/include/asm/sections.h       |  19 +--
 6 files changed, 100 insertions(+), 91 deletions(-)

diff --git a/ci/jailhouse-config-amd-seattle.h 
b/ci/jailhouse-config-amd-seattle.h
index 99fdc8e..c8db9a1 100644
--- a/ci/jailhouse-config-amd-seattle.h
+++ b/ci/jailhouse-config-amd-seattle.h
@@ -2,4 +2,3 @@
 #define CONFIG_ARM_GIC_V2              1
 #define CONFIG_MACH_AMD_SEATTLE                1
 #define CONFIG_SERIAL_AMBA_PL011       1
-#define JAILHOUSE_BASE                 0x82fc000000
diff --git a/hypervisor/arch/arm64/asm-defines.c 
b/hypervisor/arch/arm64/asm-defines.c
index 3209918..2e9373d 100644
--- a/hypervisor/arch/arm64/asm-defines.c
+++ b/hypervisor/arch/arm64/asm-defines.c
@@ -20,7 +20,12 @@ void common(void);
 
 void common(void)
 {
-       OFFSET(DEBUG_CONSOLE_BASE, jailhouse_header, debug_console_base);
+       OFFSET(HEADER_MAX_CPUS, jailhouse_header, max_cpus);
+       OFFSET(HEADER_DEBUG_CONSOLE_VIRT, jailhouse_header, debug_console_base);
+       OFFSET(SYSCONFIG_DEBUG_CONSOLE_PHYS, jailhouse_system,
+              debug_console.phys_start);
+       OFFSET(SYSCONFIG_HYPERVISOR_PHYS, jailhouse_system,
+              hypervisor_memory.phys_start);
        BLANK();
 
        DEFINE(PERCPU_STACK_END,
diff --git a/hypervisor/arch/arm64/entry.S b/hypervisor/arch/arm64/entry.S
index 021a6a0..d1377c7 100644
--- a/hypervisor/arch/arm64/entry.S
+++ b/hypervisor/arch/arm64/entry.S
@@ -2,10 +2,12 @@
  * Jailhouse AArch64 support
  *
  * Copyright (C) 2015-2016 Huawei Technologies Duesseldorf GmbH
+ * Copyright (c) 2016 Siemens AG
  *
  * Authors:
  *  Antonios Motakis <[email protected]>
  *  Dmitry Voytik <[email protected]>
+ *  Jan Kiszka <[email protected]>
  *
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
@@ -19,6 +21,16 @@
 #define LINUX_HVC_GET_VECTORS          0
 #define LINUX_HVC_SET_VECTORS          1
 
+/* x11 must contain the virt-to-phys offset */
+.macro virt2phys, register
+       add     \register, \register, x11
+.endm
+
+/* x11 must contain the virt-to-phys offset */
+.macro phys2virt, register
+       sub     \register, \register, x11
+.endm
+
 /* Entry point for Linux loader module on JAILHOUSE_ENABLE */
        .text
        .globl arch_entry
@@ -28,7 +40,11 @@ arch_entry:
         *
         * We don't have access to our own address space yet, so we will
         * abuse some caller saved registers to preserve across calls:
-        * x15: physical UART address
+        * x11: virtual-to-physical address offset
+        * x12: physical hypervisor address
+        * x13: virtual hypervisor address
+        * x14: physical UART address
+        * x15: virtual UART address
         * x16: saved hyp vectors
         * x17: cpuid
         * x18: caller lr
@@ -36,14 +52,41 @@ arch_entry:
        mov     x17, x0
        mov     x18, x30
 
+       /* keep the Linux stub EL2 vectors for later */
+       mov     x0, #LINUX_HVC_GET_VECTORS
+       hvc     #0
+       mov     x16, x0
+
        /*
         * Access the just updated hypervisor_header prior to turning off the
         * MMU. Later, we will only read a stale memory content.
         */
-       adr     x15, hypervisor_header
-       ldr     x15, [x15, #DEBUG_CONSOLE_BASE]
+       adr     x0, hypervisor_header
+
+       ldr     x15, =UART_BASE
+
+       adrp    x1, __page_pool
+       ldrh    w2, [x0, #HEADER_MAX_CPUS]
+       lsl     x2, x2, #PERCPU_SIZE_SHIFT_ASM
+       add     x1, x1, x2
+       ldr     x14, [x1, #SYSCONFIG_DEBUG_CONSOLE_PHYS]
 
-       /* Note 1: After turning MMU off the CPU can start bypassing caches.
+       ldr     x13, =JAILHOUSE_BASE
+
+       ldr     x12, [x1, #SYSCONFIG_HYPERVISOR_PHYS]
+
+       sub     x11, x12, x13
+
+       /*
+        * Set jailhouse_header.debug_console_base to UART_BASE plus the offset
+        * into the UART's physical 2 MB page.
+        */
+       and     x1, x14, #0x1fffff
+       add     x15, x15, x1
+       str     x15, [x0, #HEADER_DEBUG_CONSOLE_VIRT]
+
+       /*
+        * Note 1: After turning MMU off the CPU can start bypassing caches.
         * But cached before data is kept in caches either until the CPU turns
         * MMU on again or other coherent agents move cached data out. That's
         * why there is no need to clean D-cache before turning MMU off.
@@ -56,15 +99,12 @@ arch_entry:
         * Invalidate is safe in guests.
         */
 
-       /* keep the linux stub EL2 vectors for later */
-       mov     x0, #LINUX_HVC_GET_VECTORS
-       hvc     #0
-       mov     x16, x0
-
        /* install bootstrap_vectors */
        mov     x0, #LINUX_HVC_SET_VECTORS
        ldr     x1, =bootstrap_vectors
+       virt2phys x1
        hvc     #0
+
        hvc     #0      /* bootstrap vectors enter EL2 at el2_entry */
        b       .       /* we don't expect to return here */
 
@@ -75,16 +115,18 @@ el2_entry:
        cmp     x1, #0x16
        b.ne    .               /* not hvc */
 
-       /* install jailhouse vectors */
-       adr     x1, hyp_vectors
-       msr     vbar_el2, x1
-
        /* init bootstrap page tables */
        bl      init_bootstrap_pt
 
        /* enable temporary mmu mapings for early initialization */
        adr     x0, bootstrap_pt_l0
-       bl      enable_mmu_el2
+       adr     x30, 1f         /* set lr manually to ensure... */
+       phys2virt x30           /* ...that we return to a virtual address */
+       b       enable_mmu_el2
+1:
+       /* install the final vectors */
+       adr     x1, hyp_vectors
+       msr     vbar_el2, x1
 
        mov     x0, x17         /* preserved cpuid, will be passed to entry */
        adrp    x1, __page_pool
@@ -241,82 +283,41 @@ init_bootstrap_pt:
         * initialization process. These tables will be replaced
         * during hypervisor initialization.
         *
-        * x0: physical address of hypervisor binary (2mb block)
-        * x1: physical address of uart to map (2mb block)
+        * x0: physical address of trampoline page
+        * x12: physical address of hypervisor binary
+        * x13: virtual address of hypervisor binary
+        * x14: physical address of uart to map
+        * x15: virtual address of uart to map
         *
         * These are referenced statically for now.
-        * AARCH64_TODO: remove the build time dependency, and take
-        * these values as input from the system configuration.
         *
         * Clobbers x0-x4,x8,x9
         */
-       ldr     x0, =JAILHOUSE_BASE
-       mov     x1, x15
-
-       /* l0 pt index for firmware and uart */
-       get_index x2, x0, 0
-       get_index x3, x1, 0
-
-       /* map the l1 table that includes the firmware */
-       set_table bootstrap_pt_l0, x2, bootstrap_pt_l1
+       adrp    x0, __trampoline_start
 
-       cmp     x2, x3
-       b.eq    1f
+       /* map the l1 table that includes the firmware and the uart */
+       get_index x2, x13, 0
+       set_table bootstrap_pt_l0, x2, bootstrap_pt_l1_hyp_uart
 
-       /*
-        * Case 1: firmware and uart reside on sepparate l0 entries
-        *         (512gb regions). The wildcard table is used as an
-        *         l1 table for the uart.
-        */
-       get_index x2, x0, 1
-       set_block bootstrap_pt_l1, x2, x0, 1 /* 1gb block for firmware */
+       /* map the l1 table that includes the trampoline */
+       get_index x3, x0, 0
+       set_table bootstrap_pt_l0, x3, bootstrap_pt_l1_trampoline
 
-       /* 512gb blocks are not supported by the hardware. Use the
-        * wildcard table to map a 1gb block for the uart */
-       set_table bootstrap_pt_l0, x3, bootstrap_pt_wildcard
-       get_index x3, x1, 1
-       set_block_dev bootstrap_pt_wildcard, x3, x1, 1
-
-       b       flush
-
-1:     get_index x2, x0, 1
-       get_index x3, x1, 1
-       cmp     x2, x3
-       b.eq    1f
-
-       /*
-        * Case 2: firwmare and uart reside on sepparate l1 entries.
-        *         Just map 1gb blocks, we don't need the wildcard.
-        */
-       set_block bootstrap_pt_l1, x2, x0, 1
-       set_block_dev bootstrap_pt_l1, x3, x1, 1
-
-       b       flush
-
-       /* l1 granularity not enough; attempt to map on l2 blocks (2mb) */
-1:     set_table bootstrap_pt_l1, x2, bootstrap_pt_wildcard
-       get_index x2, x0, 2
-       get_index x3, x1, 2
-       cmp     x2, x3
-       b.eq    1f
-
-       /*
-        * Case 3: firmware and uart reside on sepparate l2 entries,
-        *         we can still salvage the situation (2mb blocks).
-        *         We use the wildcard table for the l2 table for
-        *         the firmware and the uart.
-        */
-       set_block bootstrap_pt_wildcard, x2, x0, 2
-       set_block_dev bootstrap_pt_wildcard, x3, x1, 2
-       b       flush
+       /*  fill the l1 tables */
+       get_index x2, x13, 1
+       set_table bootstrap_pt_l1_hyp_uart, x2, bootstrap_pt_l2_hyp_uart
+       get_index x4, x0, 1
+       set_block bootstrap_pt_l1_trampoline, x4, x0, 1
 
-       /* uart and firmware within same 2MB block; cry now */
-1:     b       .
+       get_index x2, x13, 2
+       set_block bootstrap_pt_l2_hyp_uart, x2, x12, 2
+       get_index x3, x15, 2
+       set_block_dev bootstrap_pt_l2_hyp_uart, x3, x14, 2
 
-flush: adr     x0, bootstrap_pt_l0
-       mov     x1, PAGE_SIZE * 3
+       adrp    x0, bootstrap_pt_l0
+       mov     x1, PAGE_SIZE * 4
        mov     x2, DCACHE_INVALIDATE_ASM
-       b       arm_dcaches_flush       // will ret to caller
+       b       arm_dcaches_flush       /* will return to our caller */
 
 
 .macro ventry  label
diff --git a/hypervisor/arch/arm64/include/asm/jailhouse_hypercall.h 
b/hypervisor/arch/arm64/include/asm/jailhouse_hypercall.h
index 382e8b1..3a1b2c4 100644
--- a/hypervisor/arch/arm64/include/asm/jailhouse_hypercall.h
+++ b/hypervisor/arch/arm64/include/asm/jailhouse_hypercall.h
@@ -10,8 +10,6 @@
  * the COPYING file in the top-level directory.
  */
 
-#include <jailhouse/config.h>
-
 #define JAILHOUSE_CALL_INS             "hvc #0x4a48"
 #define JAILHOUSE_CALL_NUM_RESULT      "x0"
 #define JAILHOUSE_CALL_ARG1            "x1"
diff --git a/hypervisor/arch/arm64/include/asm/paging.h 
b/hypervisor/arch/arm64/include/asm/paging.h
index 03bae3a..ee74ce2 100644
--- a/hypervisor/arch/arm64/include/asm/paging.h
+++ b/hypervisor/arch/arm64/include/asm/paging.h
@@ -160,6 +160,9 @@
 
 #define INVALID_PHYS_ADDR      (~0UL)
 
+#define UART_BASE              0xffffc0000000
+#define JAILHOUSE_BASE         0xffffc0200000
+
 #define REMAP_BASE             0x00100000UL
 #define NUM_REMAP_BITMAP_PAGES 1
 
diff --git a/hypervisor/arch/arm64/include/asm/sections.h 
b/hypervisor/arch/arm64/include/asm/sections.h
index 721a8fb..cc39b40 100644
--- a/hypervisor/arch/arm64/include/asm/sections.h
+++ b/hypervisor/arch/arm64/include/asm/sections.h
@@ -2,29 +2,32 @@
  * Jailhouse AArch64 support
  *
  * Copyright (C) 2015-2016 Huawei Technologies Duesseldorf GmbH
+ * Copyright (c) 2016 Siemens AG
  *
  * Authors:
  *  Antonios Motakis <[email protected]>
+ *  Jan Kiszka <[email protected]>
  *
  * This work is licensed under the terms of the GNU GPL, version 2.  See
  * the COPYING file in the top-level directory.
  */
 
-/* We have no memory management during early init; three pages is the
- * minimum we can get away with to switch on the MMU with identity
- * mapping for they hypervisor firmware and the UART.
- *
- * TODO: find a way to avoid having these three empty pages in the
- * Jailhouse binary!
+/*
+ * We have no memory management during early init; four pages is the minimum we
+ * can get away with to switch on the MMU with mappings for the hypervisor
+ * firmware and the UART as well as identity mapping for the trampoline code
+ * page.
  */
 #define ARCH_SECTIONS                                                  \
        . = ALIGN(PAGE_SIZE);                                           \
        .bootstrap_page_tables : {                                      \
                bootstrap_pt_l0 = .;                                    \
                . = . + PAGE_SIZE;                                      \
-               bootstrap_pt_l1 = .;                                    \
+               bootstrap_pt_l1_hyp_uart = .;                           \
+               . = . + PAGE_SIZE;                                      \
+               bootstrap_pt_l1_trampoline = .;                         \
                . = . + PAGE_SIZE;                                      \
-               bootstrap_pt_wildcard = .;                              \
+               bootstrap_pt_l2_hyp_uart = .;                           \
                . = . + PAGE_SIZE;                                      \
        }                                                               \
        .trampoline : {                                                 \
-- 
2.1.4

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

Reply via email to