[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 25/45] xen: arm: separate guest user regs from internal guest state.



struct cpu_user_regs is currently used as both internal state
(specifically at the base of the stack) and a guest/toolstack
visible API (via struct vcpu_guest_context used by
XEN_DOMCTL_{g,s}etvcpucontext and VCPUOP_initialise).

This causes problems when we want to make the API 64-bit clean since
we don't really want to change the size of the on-stack struct.

So split into vcpu_guest_core_regs which is the API facing struct
and keep cpu_user_regs purely internal, translate between the two.

In the user API arrange for both 64- and 32-bit registers to be
included in a layout which does not differ depending on toolstack
architecture. Also switch to using the more formal banked register
names (e.g. with the _usr suffix) for clarity.

This is an ABI change. Note that the kernel doesn't currently use
this data structure so it affects the tools interface only.

Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 .gitignore                               |    3 +-
 tools/include/xen-foreign/Makefile       |    7 +-
 tools/include/xen-foreign/mkheader.py    |   31 +++++++-
 tools/include/xen-foreign/reference.size |   21 +++---
 tools/include/xen-foreign/structs.py     |    1 +
 tools/libxc/xc_dom_arm.c                 |   10 +-
 xen/arch/arm/arm32/Makefile              |    2 +
 xen/arch/arm/arm32/domain.c              |   51 ++++++++++++
 xen/arch/arm/arm64/Makefile              |    2 +
 xen/arch/arm/arm64/domain.c              |   66 ++++++++++++++++
 xen/arch/arm/domain.c                    |    4 +-
 xen/arch/arm/domctl.c                    |    4 +-
 xen/include/asm-arm/arm32/processor.h    |   52 ++++++++++++
 xen/include/asm-arm/arm64/processor.h    |   81 +++++++++++++++++++
 xen/include/asm-arm/current.h            |    1 +
 xen/include/asm-arm/processor.h          |    5 +
 xen/include/public/arch-arm.h            |  126 +++++++++++++++++++-----------
 17 files changed, 399 insertions(+), 68 deletions(-)
 create mode 100644 xen/arch/arm/arm32/domain.c
 create mode 100644 xen/arch/arm/arm64/domain.c

diff --git a/.gitignore b/.gitignore
index 462e291..d164224 100644
--- a/.gitignore
+++ b/.gitignore
@@ -357,7 +357,8 @@ tools/include/xen-foreign/checker.c
 tools/include/xen-foreign/structs.pyc
 tools/include/xen-foreign/x86_32.h
 tools/include/xen-foreign/x86_64.h
-tools/include/xen-foreign/arm.h
+tools/include/xen-foreign/arm32.h
+tools/include/xen-foreign/arm64.h
 
 .git
 tools/misc/xen-hptool
diff --git a/tools/include/xen-foreign/Makefile 
b/tools/include/xen-foreign/Makefile
index cfaf790..8e0be83 100644
--- a/tools/include/xen-foreign/Makefile
+++ b/tools/include/xen-foreign/Makefile
@@ -3,7 +3,7 @@ include $(XEN_ROOT)/tools/Rules.mk
 
 ROOT = $(XEN_ROOT)/xen/include/public
 
-architectures := arm x86_32 x86_64
+architectures := arm32 arm64 x86_32 x86_64
 headers := $(patsubst %, %.h, $(architectures))
 
 .PHONY: all clean check-headers
@@ -22,7 +22,10 @@ check-headers: checker
        diff -u reference.size tmp.size
        rm tmp.size
 
-arm.h: mkheader.py structs.py $(ROOT)/arch-arm.h
+arm32.h: mkheader.py structs.py $(ROOT)/arch-arm.h
+       $(PYTHON) $< $* $@ $(filter %.h,$^)
+
+arm64.h: mkheader.py structs.py $(ROOT)/arch-arm.h
        $(PYTHON) $< $* $@ $(filter %.h,$^)
 
 x86_32.h: mkheader.py structs.py $(ROOT)/arch-x86/xen-x86_32.h 
$(ROOT)/arch-x86/xen.h $(ROOT)/xen.h
diff --git a/tools/include/xen-foreign/mkheader.py 
b/tools/include/xen-foreign/mkheader.py
index d189b07..4ee9fb5 100644
--- a/tools/include/xen-foreign/mkheader.py
+++ b/tools/include/xen-foreign/mkheader.py
@@ -17,11 +17,37 @@ header = {};
 footer = {};
 
 #arm
-inttypes["arm"] = {
+inttypes["arm32"] = {
     "unsigned long" : "uint32_t",
     "long"          : "uint32_t",
     "xen_pfn_t"     : "uint64_t",
 };
+header["arm32"] = """
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+# define __DECL_REG(n64, n32) union { uint64_t __pad_ ## n64; uint32_t n32; }
+#else
+# define __DECL_REG(n64, n32) uint64_t n64
+#endif
+""";
+footer["arm32"] = """
+#undef __DECL_REG
+"""
+
+inttypes["arm64"] = {
+    "unsigned long" : "uint64_t",
+    "long"          : "uint64_t",
+    "xen_pfn_t"     : "uint64_t",
+};
+header["arm64"] = """
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+# define __DECL_REG(n64, n32) union { uint64_t n64; uint32_t n32; }
+#else
+# define __DECL_REG(n64, n32) uint64_t n64
+#endif
+""";
+footer["arm64"] = """
+#undef __DECL_REG
+"""
 
 # x86_32
 inttypes["x86_32"] = {
@@ -53,6 +79,9 @@ header["x86_64"] = """
 #endif
 #define __x86_64___X86_64 1
 """;
+footer["x86_64"] = """
+#undef __DECL_REG
+"""
 
 ###########################################################################
 # main
diff --git a/tools/include/xen-foreign/reference.size 
b/tools/include/xen-foreign/reference.size
index a2cbfd6..de36455 100644
--- a/tools/include/xen-foreign/reference.size
+++ b/tools/include/xen-foreign/reference.size
@@ -1,13 +1,14 @@
 
-structs                   |     arm  x86_32  x86_64
+structs                   |   arm32   arm64  x86_32  x86_64
 
-start_info                |       -    1112    1168
-trap_info                 |       -       8      16
-cpu_user_regs             |     160      68     200
-vcpu_guest_context        |     180    2800    5168
-arch_vcpu_info            |       -      24      16
-vcpu_time_info            |       -      32      32
-vcpu_info                 |       -      64      64
-arch_shared_info          |       -     268     280
-shared_info               |       -    2584    3368
+start_info                |       -       -    1112    1168
+trap_info                 |       -       -       8      16
+cpu_user_regs             |       -       -      68     200
+vcpu_guest_core_regs      |     304     304       -       -
+vcpu_guest_context        |     336     336    2800    5168
+arch_vcpu_info            |       -       -      24      16
+vcpu_time_info            |       -       -      32      32
+vcpu_info                 |       -       -      64      64
+arch_shared_info          |       -       -     268     280
+shared_info               |       -       -    2584    3368
 
diff --git a/tools/include/xen-foreign/structs.py 
b/tools/include/xen-foreign/structs.py
index 51a77c0..e3e8771 100644
--- a/tools/include/xen-foreign/structs.py
+++ b/tools/include/xen-foreign/structs.py
@@ -6,6 +6,7 @@ unions  = [ "vcpu_cr_regs",
 structs = [ "start_info",
             "trap_info",
             "cpu_user_regs",
+            "vcpu_guest_core_regs",
             "vcpu_guest_context",
             "arch_vcpu_info",
             "vcpu_time_info",
diff --git a/tools/libxc/xc_dom_arm.c b/tools/libxc/xc_dom_arm.c
index b743a6c..577b2a3 100644
--- a/tools/libxc/xc_dom_arm.c
+++ b/tools/libxc/xc_dom_arm.c
@@ -102,17 +102,17 @@ static int vcpu_arm(struct xc_dom_image *dom, void *ptr)
     /* clear everything */
     memset(ctxt, 0, sizeof(*ctxt));
 
-    ctxt->user_regs.pc = dom->parms.virt_entry;
+    ctxt->user_regs.pc32 = dom->parms.virt_entry;
 
     /* Linux boot protocol. See linux.Documentation/arm/Booting. */
-    ctxt->user_regs.r0 = 0; /* SBZ */
+    ctxt->user_regs.r0_usr = 0; /* SBZ */
     /* Machine ID: We use DTB therefore no machine id */
-    ctxt->user_regs.r1 = 0xffffffff;
+    ctxt->user_regs.r1_usr = 0xffffffff;
     /* ATAGS/DTB: We currently require that the guest kernel to be
      * using CONFIG_ARM_APPENDED_DTB. Ensure that r2 does not look
      * like a valid pointer to a set of ATAGS or a DTB.
      */
-    ctxt->user_regs.r2 = 0xffffffff;
+    ctxt->user_regs.r2_usr = 0xffffffff;
 
     ctxt->sctlr = /* #define SCTLR_BASE */0x00c50078;
 
@@ -125,7 +125,7 @@ static int vcpu_arm(struct xc_dom_image *dom, void *ptr)
     ctxt->flags = VGCF_online;
 
     DOMPRINTF("Initial state CPSR %#"PRIx32" PC %#"PRIx32,
-           ctxt->user_regs.cpsr, ctxt->user_regs.pc);
+           ctxt->user_regs.cpsr, ctxt->user_regs.pc32);
 
     return 0;
 }
diff --git a/xen/arch/arm/arm32/Makefile b/xen/arch/arm/arm32/Makefile
index 20931fa..29898ae 100644
--- a/xen/arch/arm/arm32/Makefile
+++ b/xen/arch/arm/arm32/Makefile
@@ -3,3 +3,5 @@ subdir-y += lib
 obj-y += entry.o
 obj-y += mode_switch.o
 obj-y += proc-ca15.o
+
+obj-y += domain.o
diff --git a/xen/arch/arm/arm32/domain.c b/xen/arch/arm/arm32/domain.c
new file mode 100644
index 0000000..f75a2c6
--- /dev/null
+++ b/xen/arch/arm/arm32/domain.c
@@ -0,0 +1,51 @@
+#include <xen/config.h>
+#include <xen/sched.h>
+
+#include <asm/domain.h>
+#include <asm/processor.h>
+
+#include <public/xen.h>
+
+/* C(hyp,user), hyp is Xen internal name, user is user API name. */
+
+#define ALLREGS \
+    C(r0,r0_usr);   C(r1,r1_usr);   C(r2,r2_usr);   C(r3,r3_usr);   \
+    C(r4,r4_usr);   C(r5,r5_usr);   C(r6,r6_usr);   C(r7,r7_usr);   \
+    C(r8,r8_usr);   C(r9,r9_usr);   C(r10,r10_usr); C(r11,r11_usr); \
+    C(r12,r12_usr); \
+    C(sp_usr,sp_usr); \
+    C(lr,lr_usr); \
+    C(spsr_irq,spsr_irq); C(lr_irq,lr_irq); C(sp_irq,sp_irq); \
+    C(spsr_svc,spsr_svc); C(lr_svc,lr_svc); C(sp_svc,sp_svc); \
+    C(spsr_abt,spsr_abt); C(lr_abt,lr_abt); C(sp_abt,sp_abt); \
+    C(spsr_und,spsr_und); C(lr_und,lr_und); C(sp_und,sp_und); \
+    C(spsr_fiq,spsr_fiq); C(sp_fiq,sp_fiq); C(sp_fiq,sp_fiq); \
+    C(r8_fiq,r8_fiq); C(r9_fiq,r9_fiq); \
+    C(r10_fiq,r10_fiq); C(r11_fiq,r11_fiq); C(r12_fiq,r12_fiq); \
+    C(pc,pc32); \
+    C(cpsr,cpsr)
+
+void vcpu_regs_hyp_to_user(const struct vcpu *vcpu,
+                           struct vcpu_guest_core_regs *regs)
+{
+#define C(hyp,user) regs->user = vcpu->arch.cpu_info->guest_cpu_user_regs.hyp
+    ALLREGS;
+#undef C
+}
+
+void vcpu_regs_user_to_hyp(struct vcpu *vcpu,
+                           const struct vcpu_guest_core_regs *regs)
+{
+#define C(hyp,user) vcpu->arch.cpu_info->guest_cpu_user_regs.hyp = regs->user
+    ALLREGS;
+#undef C
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/arm64/Makefile b/xen/arch/arm/arm64/Makefile
index c447eaa..815f305 100644
--- a/xen/arch/arm/arm64/Makefile
+++ b/xen/arch/arm/arm64/Makefile
@@ -1,3 +1,5 @@
 subdir-y += lib
 
 obj-y += mode_switch.o
+
+obj-y += domain.o
diff --git a/xen/arch/arm/arm64/domain.c b/xen/arch/arm/arm64/domain.c
new file mode 100644
index 0000000..05df29e
--- /dev/null
+++ b/xen/arch/arm/arm64/domain.c
@@ -0,0 +1,66 @@
+#include <xen/config.h>
+#include <xen/sched.h>
+
+#include <asm/domain.h>
+#include <asm/processor.h>
+
+#include <public/xen.h>
+
+/* C(hyp,user), hyp is Xen internal name, user is user API name. */
+
+#define ALLREGS \
+    C(x0,x0);   C(x1,x1);   C(x2,x2);   C(x3,x3);   \
+    C(x4,x4);   C(x5,x5);   C(x6,x6);   C(x7,x7);   \
+    C(x8,x8);   C(x9,x9);   C(x10,x10); C(x11,x11); \
+    C(x12,x12); C(x13,x13); C(x14,x14); C(x15,x15); \
+    C(x16,x16); C(x17,x17); C(x18,x18); C(x19,x19); \
+    C(x20,x20); C(x21,x21); C(x22,x22); C(x23,x23); \
+    C(x24,x24); C(x25,x25); C(x26,x26); C(x27,x27); \
+    C(x28,x28); C(fp,x29);  C(lr,x30);  C(pc,pc64); \
+    C(cpsr, cpsr); C(spsr_el1, spsr_el1)
+
+#define ALLREGS32 C(spsr_fiq, spsr_fiq); C(spsr_irq,spsr_irq); \
+                  C(spsr_und,spsr_und); C(spsr_abt,spsr_abt)
+
+#define ALLREGS64 C(sp_el0,sp_el0); C(sp_el1,sp_el1); C(elr_el1,elr_el1)
+
+void vcpu_regs_hyp_to_user(const struct vcpu *vcpu,
+                           struct vcpu_guest_core_regs *regs)
+{
+#define C(hyp,user) regs->user = vcpu->arch.cpu_info->guest_cpu_user_regs.hyp
+    ALLREGS;
+    if ( is_pv32_domain(vcpu->domain) )
+    {
+        ALLREGS32;
+    }
+    else
+    {
+        ALLREGS64;
+    }
+#undef C
+}
+
+void vcpu_regs_user_to_hyp(struct vcpu *vcpu,
+                           const struct vcpu_guest_core_regs *regs)
+{
+#define C(hyp,user) vcpu->arch.cpu_info->guest_cpu_user_regs.hyp = regs->user
+    ALLREGS;
+    if ( is_pv32_domain(vcpu->domain) )
+    {
+        ALLREGS32;
+    }
+    else
+    {
+        ALLREGS64;
+    }
+#undef C
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c
index 5506f78..a1b86d4 100644
--- a/xen/arch/arm/domain.c
+++ b/xen/arch/arm/domain.c
@@ -484,7 +484,7 @@ int arch_set_info_guest(
     struct vcpu *v, vcpu_guest_context_u c)
 {
     struct vcpu_guest_context *ctxt = c.nat;
-    struct cpu_user_regs *regs = &c.nat->user_regs;
+    struct vcpu_guest_core_regs *regs = &c.nat->user_regs;
 
     if ( !is_guest_psr(regs->cpsr) )
         return -EINVAL;
@@ -500,7 +500,7 @@ int arch_set_info_guest(
     if ( regs->spsr_fiq && !is_guest_psr(regs->spsr_fiq) )
         return -EINVAL;
 
-    v->arch.cpu_info->guest_cpu_user_regs = *regs;
+    vcpu_regs_user_to_hyp(v, regs);
 
     v->arch.sctlr = ctxt->sctlr;
     v->arch.ttbr0 = ctxt->ttbr0;
diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c
index c7ffd8a..15f8537 100644
--- a/xen/arch/arm/domctl.c
+++ b/xen/arch/arm/domctl.c
@@ -20,9 +20,9 @@ long arch_do_domctl(struct xen_domctl *domctl, struct domain 
*d,
 void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c)
 {
     struct vcpu_guest_context *ctxt = c.nat;
-    struct cpu_user_regs *regs = &c.nat->user_regs;
+    struct vcpu_guest_core_regs *regs = &c.nat->user_regs;
 
-    *regs = v->arch.cpu_info->guest_cpu_user_regs;
+    vcpu_regs_hyp_to_user(v, regs);
 
     ctxt->sctlr = v->arch.sctlr;
     ctxt->ttbr0 = v->arch.ttbr0;
diff --git a/xen/include/asm-arm/arm32/processor.h 
b/xen/include/asm-arm/arm32/processor.h
index 843fbd2..a782d96 100644
--- a/xen/include/asm-arm/arm32/processor.h
+++ b/xen/include/asm-arm/arm32/processor.h
@@ -1,6 +1,58 @@
 #ifndef __ASM_ARM_ARM32_PROCESSOR_H
 #define __ASM_ARM_ARM32_PROCESSOR_H
 
+#ifndef __ASSEMBLY__
+/* On stack VCPU state */
+struct cpu_user_regs
+{
+    uint32_t r0;
+    uint32_t r1;
+    uint32_t r2;
+    uint32_t r3;
+    uint32_t r4;
+    uint32_t r5;
+    uint32_t r6;
+    uint32_t r7;
+    uint32_t r8;
+    uint32_t r9;
+    uint32_t r10;
+    union {
+        uint32_t r11;
+        uint32_t fp;
+    };
+    uint32_t r12;
+
+    uint32_t sp; /* r13 - SP: Valid for Hyp. frames only, o/w banked (see 
below) */
+
+    /* r14 - LR: is the same physical register as LR_usr */
+    union {
+        uint32_t lr; /* r14 - LR: Valid for Hyp. Same physical register as 
lr_usr. */
+
+        uint32_t lr_usr;
+    };
+
+    uint32_t pc; /* Return IP */
+    uint32_t cpsr; /* Return mode */
+    uint32_t pad0; /* Doubleword-align the kernel half of the frame */
+
+    /* Outer guest frame only from here on... */
+
+    uint32_t sp_usr; /* LR_usr is the same register as LR, see above */
+
+    uint32_t sp_irq, lr_irq;
+    uint32_t sp_svc, lr_svc;
+    uint32_t sp_abt, lr_abt;
+    uint32_t sp_und, lr_und;
+
+    uint32_t r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq;
+    uint32_t sp_fiq, lr_fiq;
+
+    uint32_t spsr_svc, spsr_abt, spsr_und, spsr_irq, spsr_fiq;
+
+    uint32_t pad1; /* Doubleword-align the user half of the frame */
+};
+#endif
+
 /* Layout as used in assembly, with src/dest registers mixed in */
 #define __CP32(r, coproc, opc1, crn, crm, opc2) coproc, opc1, r, crn, crm, opc2
 #define __CP64(r1, r2, coproc, opc, crm) coproc, opc, r1, r2, crm
diff --git a/xen/include/asm-arm/arm64/processor.h 
b/xen/include/asm-arm/arm64/processor.h
index fdb0dab..b4602fa 100644
--- a/xen/include/asm-arm/arm64/processor.h
+++ b/xen/include/asm-arm/arm64/processor.h
@@ -3,6 +3,87 @@
 
 #ifndef __ASSEMBLY__
 
+/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */
+
+#define __DECL_REG(n64, n32) union {            \
+    uint64_t n64;                               \
+    uint32_t n32;                               \
+}
+
+/* On stack VCPU state */
+struct cpu_user_regs
+{
+    /*         Aarch64       Aarch32 */
+    __DECL_REG(x0,           r0/*_usr*/);
+    __DECL_REG(x1,           r1/*_usr*/);
+    __DECL_REG(x2,           r2/*_usr*/);
+    __DECL_REG(x3,           r3/*_usr*/);
+    __DECL_REG(x4,           r4/*_usr*/);
+    __DECL_REG(x5,           r5/*_usr*/);
+    __DECL_REG(x6,           r6/*_usr*/);
+    __DECL_REG(x7,           r7/*_usr*/);
+    __DECL_REG(x8,           r8/*_usr*/);
+    __DECL_REG(x9,           r9/*_usr*/);
+    __DECL_REG(x10,          r10/*_usr*/);
+    __DECL_REG(x11 ,         r11/*_usr*/);
+    __DECL_REG(x12,          r12/*_usr*/);
+
+    __DECL_REG(x13,          /* r13_usr */ sp_usr);
+    __DECL_REG(x14,          /* r14_usr */ lr_usr);
+
+    __DECL_REG(x15,          /* r13_hyp */ __unused_sp_hyp);
+
+    __DECL_REG(x16,          /* r14_irq */ lr_irq);
+    __DECL_REG(x17,          /* r13_irq */ sp_irq);
+
+    __DECL_REG(x18,          /* r14_svc */ lr_svc);
+    __DECL_REG(x19,          /* r13_svc */ sp_svc);
+
+    __DECL_REG(x20,          /* r14_abt */ lr_abt);
+    __DECL_REG(x21,          /* r13_abt */ sp_abt);
+
+    __DECL_REG(x22,          /* r14_und */ lr_und);
+    __DECL_REG(x23,          /* r13_und */ sp_und);
+
+    __DECL_REG(x24,          r8_fiq);
+    __DECL_REG(x25,          r9_fiq);
+    __DECL_REG(x26,          r10_fiq);
+    __DECL_REG(x27,          r11_fiq);
+    __DECL_REG(x28,          r12_fiq);
+    __DECL_REG(/* x29 */ fp, /* r13_fiq */ sp_fiq);
+    __DECL_REG(/* x30 */ lr, /* r14_fiq */ lr_fiq);
+
+    register_t sp; /* Valid for hypervisor frames */
+
+    /* Return address and mode */
+    __DECL_REG(pc,           pc32);             /* ELR_EL2 */
+    uint32_t cpsr;                              /* SPSR_EL2 */
+
+    uint64_t pad0;
+
+    /* Outer guest frame only from here on... */
+
+    union {
+        uint32_t spsr_el1;       /* AArch64 */
+        uint32_t spsr_svc;       /* AArch32 */
+    };
+
+    uint32_t pad1; /* Align */
+
+    /* AArch32 guests only */
+    uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt;
+
+    /* AArch64 guests only */
+    uint64_t sp_el0;
+    uint64_t sp_el1, elr_el1;
+
+    uint64_t pad2; /* Doubleword-align the user half of the frame */
+};
+
+#undef __DECL_REG
+
+/* Access to system registers */
+
 #define READ_SYSREG32(name) ({                          \
     uint32_t _r;                                        \
     asm volatile("mrs  %0, "#name : "=r" (_r));         \
diff --git a/xen/include/asm-arm/current.h b/xen/include/asm-arm/current.h
index d20d7a8..c9c8ac7 100644
--- a/xen/include/asm-arm/current.h
+++ b/xen/include/asm-arm/current.h
@@ -6,6 +6,7 @@
 #include <public/xen.h>
 
 #include <asm/percpu.h>
+#include <asm/processor.h>
 
 #ifndef __ASSEMBLY__
 
diff --git a/xen/include/asm-arm/processor.h b/xen/include/asm-arm/processor.h
index 8183d36..230c901 100644
--- a/xen/include/asm-arm/processor.h
+++ b/xen/include/asm-arm/processor.h
@@ -253,6 +253,11 @@ void show_registers(struct cpu_user_regs *regs);
 #define cpu_to_core(_cpu)   (0)
 #define cpu_to_socket(_cpu) (0)
 
+void vcpu_regs_hyp_to_user(const struct vcpu *vcpu,
+                           struct vcpu_guest_core_regs *regs);
+void vcpu_regs_user_to_hyp(struct vcpu *vcpu,
+                           const struct vcpu_guest_core_regs *regs);
+
 #endif /* __ASSEMBLY__ */
 #endif /* __ASM_ARM_PROCESSOR_H */
 /*
diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h
index d8788f2..53eec29 100644
--- a/xen/include/public/arch-arm.h
+++ b/xen/include/public/arch-arm.h
@@ -86,55 +86,91 @@
 #endif
 #define set_xen_guest_handle(hnd, val) set_xen_guest_handle_raw(hnd, val)
 
-struct cpu_user_regs
-{
-    uint32_t r0;
-    uint32_t r1;
-    uint32_t r2;
-    uint32_t r3;
-    uint32_t r4;
-    uint32_t r5;
-    uint32_t r6;
-    uint32_t r7;
-    uint32_t r8;
-    uint32_t r9;
-    uint32_t r10;
-    union {
-        uint32_t r11;
-        uint32_t fp;
-    };
-    uint32_t r12;
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+# ifdef __aarch64__
+/* Anonymous union includes both 32- and 64-bit names (e.g., r0/x0). */
+#   define __DECL_REG(n64, n32) union {          \
+        uint64_t n64;                            \
+        uint32_t n32;                            \
+    }
+# else
+/*
+ * Include a 64-bit padding field so that the layout is the same
+ * between 32- and 64-bit hypervisors.
+ */
+#   define __DECL_REG(n64, n32) union {          \
+        uint64_t __pad_##n64;                    \
+        uint32_t n32;                            \
+    }
+# endif
+#else
+/* Non-gcc sources must always use the proper 64-bit name (e.g., x0). */
+#define __DECL_REG(n64, n32) uint64_t n64
+#endif
 
-    uint32_t sp; /* r13 - SP: Valid for Hyp. frames only, o/w banked (see 
below) */
+struct vcpu_guest_core_regs
+{
+    /*         Aarch64       Aarch32 */
+    __DECL_REG(x0,           r0_usr);
+    __DECL_REG(x1,           r1_usr);
+    __DECL_REG(x2,           r2_usr);
+    __DECL_REG(x3,           r3_usr);
+    __DECL_REG(x4,           r4_usr);
+    __DECL_REG(x5,           r5_usr);
+    __DECL_REG(x6,           r6_usr);
+    __DECL_REG(x7,           r7_usr);
+    __DECL_REG(x8,           r8_usr);
+    __DECL_REG(x9,           r9_usr);
+    __DECL_REG(x10,          r10_usr);
+    __DECL_REG(x11,          r11_usr);
+    __DECL_REG(x12,          r12_usr);
+
+    __DECL_REG(x13,          sp_usr);
+    __DECL_REG(x14,          lr_usr);
+
+    __DECL_REG(x15,          __unused_sp_hyp);
+
+    __DECL_REG(x16,          lr_irq);
+    __DECL_REG(x17,          sp_irq);
+
+    __DECL_REG(x18,          lr_svc);
+    __DECL_REG(x19,          sp_svc);
+
+    __DECL_REG(x20,          lr_abt);
+    __DECL_REG(x21,          sp_abt);
+
+    __DECL_REG(x22,          lr_und);
+    __DECL_REG(x23,          sp_und);
+
+    __DECL_REG(x24,          r8_fiq);
+    __DECL_REG(x25,          r9_fiq);
+    __DECL_REG(x26,          r10_fiq);
+    __DECL_REG(x27,          r11_fiq);
+    __DECL_REG(x28,          r12_fiq);
+
+    __DECL_REG(x29,          sp_fiq);
+    __DECL_REG(x30,          lr_fiq);
+
+    /* Return address and mode */
+    __DECL_REG(pc64,         pc32);             /* ELR_EL2 */
+    uint32_t cpsr;                              /* SPSR_EL2 */
 
-    /* r14 - LR: is the same physical register as LR_usr */
     union {
-        uint32_t lr; /* r14 - LR: Valid for Hyp. Same physical register as 
lr_usr. */
-        uint32_t lr_usr;
+        uint32_t spsr_el1;       /* AArch64 */
+        uint32_t spsr_svc;       /* AArch32 */
     };
 
-    uint32_t pc; /* Return IP */
-    uint32_t cpsr; /* Return mode */
-    uint32_t pad0; /* Doubleword-align the kernel half of the frame */
+    /* AArch32 guests only */
+    uint32_t spsr_fiq, spsr_irq, spsr_und, spsr_abt;
 
-    /* Outer guest frame only from here on... */
-
-    uint32_t sp_usr; /* LR_usr is the same register as LR, see above */
-
-    uint32_t sp_irq, lr_irq;
-    uint32_t sp_svc, lr_svc;
-    uint32_t sp_abt, lr_abt;
-    uint32_t sp_und, lr_und;
-
-    uint32_t r8_fiq, r9_fiq, r10_fiq, r11_fiq, r12_fiq;
-    uint32_t sp_fiq, lr_fiq;
-
-    uint32_t spsr_svc, spsr_abt, spsr_und, spsr_irq, spsr_fiq;
-
-    uint32_t pad1; /* Doubleword-align the user half of the frame */
+    /* AArch64 guests only */
+    uint64_t sp_el0;
+    uint64_t sp_el1, elr_el1;
 };
-typedef struct cpu_user_regs cpu_user_regs_t;
-DEFINE_XEN_GUEST_HANDLE(cpu_user_regs_t);
+typedef struct vcpu_guest_core_regs vcpu_guest_core_regs_t;
+DEFINE_XEN_GUEST_HANDLE(vcpu_guest_core_regs_t);
+
+#undef __DECL_REG
 
 typedef uint64_t xen_pfn_t;
 #define PRI_xen_pfn PRIx64
@@ -151,10 +187,10 @@ struct vcpu_guest_context {
 #define VGCF_online                    (1<<_VGCF_online)
     uint32_t flags;                         /* VGCF_* */
 
-    struct cpu_user_regs user_regs;         /* User-level CPU registers     */
+    struct vcpu_guest_core_regs user_regs;  /* Core CPU registers */
 
-    uint32_t sctlr;
-    uint32_t ttbr0, ttbr1, ttbcr;
+    uint32_t sctlr, ttbcr;
+    uint64_t ttbr0, ttbr1;
 };
 typedef struct vcpu_guest_context vcpu_guest_context_t;
 DEFINE_XEN_GUEST_HANDLE(vcpu_guest_context_t);
-- 
1.7.2.5


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.