All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tamas K Lengyel <tamas@tklengyel.com>
To: xen-devel@lists.xenproject.org
Cc: Julien Grall <julien.grall@arm.com>,
	Tamas K Lengyel <tamas@tklengyel.com>,
	Stefano Stabellini <sstabellini@kernel.org>
Subject: [PATCH v5 6/9] arm/vm_event: get/set registers
Date: Thu,  2 Jun 2016 16:52:23 -0600	[thread overview]
Message-ID: <1464907946-19242-6-git-send-email-tamas@tklengyel.com> (raw)
In-Reply-To: <1464907946-19242-1-git-send-email-tamas@tklengyel.com>

Add support for getting/setting registers through vm_event on ARM.
The set of registers can be expanded in the future to include other registers
as well if required. The set is limited to the GPRs, PC, CPSR and TTBR0/1 in
this patch.

Signed-off-by: Tamas K Lengyel <tamas@tklengyel.com>
Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Julien Grall <julien.grall@arm.com>

v5: Use x29/x30 as names instead of the Xen internal names on 64-bit
    Transmit all GPRs on 64-bit
v4: Use psr mode to determine whether to full 32-bit or 64-bit structs
---
 xen/arch/arm/Makefile          |   1 +
 xen/arch/arm/vm_event.c        | 159 +++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/vm_event.h |  11 ---
 xen/include/asm-x86/vm_event.h |   4 --
 xen/include/public/vm_event.h  |  74 ++++++++++++++++++-
 xen/include/xen/vm_event.h     |   3 +
 6 files changed, 234 insertions(+), 18 deletions(-)
 create mode 100644 xen/arch/arm/vm_event.c

diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile
index 344d3ad..7d2641c 100644
--- a/xen/arch/arm/Makefile
+++ b/xen/arch/arm/Makefile
@@ -42,6 +42,7 @@ obj-y += processor.o
 obj-y += smc.o
 obj-$(CONFIG_XSPLICE) += xsplice.o
 obj-y += monitor.o
+obj-y += vm_event.o
 
 #obj-bin-y += ....o
 
diff --git a/xen/arch/arm/vm_event.c b/xen/arch/arm/vm_event.c
new file mode 100644
index 0000000..6e92f8b
--- /dev/null
+++ b/xen/arch/arm/vm_event.c
@@ -0,0 +1,159 @@
+/*
+ * arch/arm/vm_event.c
+ *
+ * Architecture-specific vm_event handling routines
+ *
+ * Copyright (c) 2016 Tamas K Lengyel (tamas@tklengyel.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License v2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <xen/sched.h>
+#include <asm/vm_event.h>
+
+void vm_event_fill_regs(vm_event_request_t *req)
+{
+    const struct cpu_user_regs *regs = guest_cpu_user_regs();
+
+    req->data.regs.arm.cpsr = regs->cpsr;
+    req->data.regs.arm.ttbr0 = READ_SYSREG64(TTBR0_EL1);
+    req->data.regs.arm.ttbr1 = READ_SYSREG64(TTBR1_EL1);
+
+    if ( psr_mode_is_32bit(regs->cpsr) )
+    {
+        req->data.regs.arm.arch.arm32.r0 = regs->r0;
+        req->data.regs.arm.arch.arm32.r1 = regs->r1;
+        req->data.regs.arm.arch.arm32.r2 = regs->r2;
+        req->data.regs.arm.arch.arm32.r3 = regs->r3;
+        req->data.regs.arm.arch.arm32.r4 = regs->r4;
+        req->data.regs.arm.arch.arm32.r5 = regs->r5;
+        req->data.regs.arm.arch.arm32.r6 = regs->r6;
+        req->data.regs.arm.arch.arm32.r7 = regs->r7;
+        req->data.regs.arm.arch.arm32.r8 = regs->r8;
+        req->data.regs.arm.arch.arm32.r9 = regs->r9;
+        req->data.regs.arm.arch.arm32.r10 = regs->r10;
+        req->data.regs.arm.arch.arm32.r11 = regs->fp;
+        req->data.regs.arm.arch.arm32.r12 = regs->r12;
+        req->data.regs.arm.arch.arm32.pc = regs->pc32;
+    }
+#ifdef CONFIG_ARM_64
+    else
+    {
+        req->data.regs.arm.arch.arm64.x0 = regs->x0;
+        req->data.regs.arm.arch.arm64.x1 = regs->x1;
+        req->data.regs.arm.arch.arm64.x2 = regs->x2;
+        req->data.regs.arm.arch.arm64.x3 = regs->x3;
+        req->data.regs.arm.arch.arm64.x4 = regs->x4;
+        req->data.regs.arm.arch.arm64.x5 = regs->x5;
+        req->data.regs.arm.arch.arm64.x6 = regs->x6;
+        req->data.regs.arm.arch.arm64.x7 = regs->x7;
+        req->data.regs.arm.arch.arm64.x8 = regs->x8;
+        req->data.regs.arm.arch.arm64.x9 = regs->x9;
+        req->data.regs.arm.arch.arm64.x10 = regs->x10;
+        req->data.regs.arm.arch.arm64.x11 = regs->x11;
+        req->data.regs.arm.arch.arm64.x12 = regs->x12;
+        req->data.regs.arm.arch.arm64.x13 = regs->x13;
+        req->data.regs.arm.arch.arm64.x14 = regs->x14;
+        req->data.regs.arm.arch.arm64.x15 = regs->x15;
+        req->data.regs.arm.arch.arm64.x16 = regs->x16;
+        req->data.regs.arm.arch.arm64.x17 = regs->x17;
+        req->data.regs.arm.arch.arm64.x18 = regs->x18;
+        req->data.regs.arm.arch.arm64.x19 = regs->x19;
+        req->data.regs.arm.arch.arm64.x20 = regs->x20;
+        req->data.regs.arm.arch.arm64.x21 = regs->x21;
+        req->data.regs.arm.arch.arm64.x22 = regs->x22;
+        req->data.regs.arm.arch.arm64.x23 = regs->x23;
+        req->data.regs.arm.arch.arm64.x24 = regs->x24;
+        req->data.regs.arm.arch.arm64.x25 = regs->x25;
+        req->data.regs.arm.arch.arm64.x26 = regs->x26;
+        req->data.regs.arm.arch.arm64.x27 = regs->x27;
+        req->data.regs.arm.arch.arm64.x28 = regs->x28;
+        req->data.regs.arm.arch.arm64.x29 = regs->fp;
+        req->data.regs.arm.arch.arm64.x30 = regs->lr;
+        req->data.regs.arm.arch.arm64.pc = regs->pc;
+    }
+#endif
+}
+
+void vm_event_set_registers(struct vcpu *v, vm_event_response_t *rsp)
+{
+    struct cpu_user_regs *regs = &v->arch.cpu_info->guest_cpu_user_regs;
+
+    regs->cpsr = rsp->data.regs.arm.cpsr;
+    v->arch.ttbr0 = rsp->data.regs.arm.ttbr0;
+    v->arch.ttbr1 = rsp->data.regs.arm.ttbr1;
+
+    if ( psr_mode_is_32bit(regs->cpsr) )
+    {
+        regs->r0 = rsp->data.regs.arm.arch.arm32.r0;
+        regs->r1 = rsp->data.regs.arm.arch.arm32.r1;
+        regs->r2 = rsp->data.regs.arm.arch.arm32.r2;
+        regs->r3 = rsp->data.regs.arm.arch.arm32.r3;
+        regs->r4 = rsp->data.regs.arm.arch.arm32.r4;
+        regs->r5 = rsp->data.regs.arm.arch.arm32.r5;
+        regs->r6 = rsp->data.regs.arm.arch.arm32.r6;
+        regs->r7 = rsp->data.regs.arm.arch.arm32.r7;
+        regs->r8 = rsp->data.regs.arm.arch.arm32.r8;
+        regs->r9 = rsp->data.regs.arm.arch.arm32.r9;
+        regs->r10 = rsp->data.regs.arm.arch.arm32.r10;
+        regs->fp = rsp->data.regs.arm.arch.arm32.r11;
+        regs->r12 = rsp->data.regs.arm.arch.arm32.r12;
+        regs->pc32 = rsp->data.regs.arm.arch.arm32.pc;
+    }
+#ifdef CONFIG_ARM_64
+    else
+    {
+        regs->x0 = rsp->data.regs.arm.arch.arm64.x0;
+        regs->x1 = rsp->data.regs.arm.arch.arm64.x1;
+        regs->x2 = rsp->data.regs.arm.arch.arm64.x2;
+        regs->x3 = rsp->data.regs.arm.arch.arm64.x3;
+        regs->x4 = rsp->data.regs.arm.arch.arm64.x4;
+        regs->x5 = rsp->data.regs.arm.arch.arm64.x5;
+        regs->x6 = rsp->data.regs.arm.arch.arm64.x6;
+        regs->x7 = rsp->data.regs.arm.arch.arm64.x7;
+        regs->x8 = rsp->data.regs.arm.arch.arm64.x8;
+        regs->x9 = rsp->data.regs.arm.arch.arm64.x9;
+        regs->x10 = rsp->data.regs.arm.arch.arm64.x10;
+        regs->x11 = rsp->data.regs.arm.arch.arm64.x11;
+        regs->x12 = rsp->data.regs.arm.arch.arm64.x12;
+        regs->x13 = rsp->data.regs.arm.arch.arm64.x13;
+        regs->x14 = rsp->data.regs.arm.arch.arm64.x14;
+        regs->x15 = rsp->data.regs.arm.arch.arm64.x15;
+        regs->x16 = rsp->data.regs.arm.arch.arm64.x16;
+        regs->x17 = rsp->data.regs.arm.arch.arm64.x17;
+        regs->x18 = rsp->data.regs.arm.arch.arm64.x18;
+        regs->x19 = rsp->data.regs.arm.arch.arm64.x19;
+        regs->x20 = rsp->data.regs.arm.arch.arm64.x20;
+        regs->x21 = rsp->data.regs.arm.arch.arm64.x21;
+        regs->x22 = rsp->data.regs.arm.arch.arm64.x22;
+        regs->x23 = rsp->data.regs.arm.arch.arm64.x23;
+        regs->x24 = rsp->data.regs.arm.arch.arm64.x24;
+        regs->x25 = rsp->data.regs.arm.arch.arm64.x25;
+        regs->x26 = rsp->data.regs.arm.arch.arm64.x26;
+        regs->x27 = rsp->data.regs.arm.arch.arm64.x27;
+        regs->x28 = rsp->data.regs.arm.arch.arm64.x28;
+        regs->fp = rsp->data.regs.arm.arch.arm64.x29;
+        regs->lr = rsp->data.regs.arm.arch.arm64.x30;
+        regs->pc = rsp->data.regs.arm.arch.arm64.pc;
+    }
+#endif
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-arm/vm_event.h b/xen/include/asm-arm/vm_event.h
index a3fc4ce..a4922b3 100644
--- a/xen/include/asm-arm/vm_event.h
+++ b/xen/include/asm-arm/vm_event.h
@@ -48,15 +48,4 @@ void vm_event_register_write_resume(struct vcpu *v, vm_event_response_t *rsp)
     /* Not supported on ARM. */
 }
 
-static inline
-void vm_event_set_registers(struct vcpu *v, vm_event_response_t *rsp)
-{
-    /* Not supported on ARM. */
-}
-
-static inline void vm_event_fill_regs(vm_event_request_t *req)
-{
-    /* Not supported on ARM. */
-}
-
 #endif /* __ASM_ARM_VM_EVENT_H__ */
diff --git a/xen/include/asm-x86/vm_event.h b/xen/include/asm-x86/vm_event.h
index 026f42e..cf2077c 100644
--- a/xen/include/asm-x86/vm_event.h
+++ b/xen/include/asm-x86/vm_event.h
@@ -40,8 +40,4 @@ void vm_event_toggle_singlestep(struct domain *d, struct vcpu *v);
 
 void vm_event_register_write_resume(struct vcpu *v, vm_event_response_t *rsp);
 
-void vm_event_set_registers(struct vcpu *v, vm_event_response_t *rsp);
-
-void vm_event_fill_regs(vm_event_request_t *req);
-
 #endif /* __ASM_X86_VM_EVENT_H__ */
diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h
index 7976080..31801b2 100644
--- a/xen/include/public/vm_event.h
+++ b/xen/include/public/vm_event.h
@@ -129,8 +129,8 @@
 #define VM_EVENT_X86_XCR0   3
 
 /*
- * Using a custom struct (not hvm_hw_cpu) so as to not fill
- * the vm_event ring buffer too quickly.
+ * Using custom vCPU structs (i.e. not hvm_hw_cpu) for both x86 and ARM
+ * so as to not fill the vm_event ring buffer too quickly.
  */
 struct vm_event_regs_x86 {
     uint64_t rax;
@@ -168,6 +168,69 @@ struct vm_event_regs_x86 {
     uint32_t _pad;
 };
 
+struct vm_event_regs_arm32 {
+    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;
+    uint32_t r11;
+    uint32_t r12;
+    uint32_t pc;
+};
+
+struct vm_event_regs_arm64 {
+    uint64_t x0;
+    uint64_t x1;
+    uint64_t x2;
+    uint64_t x3;
+    uint64_t x4;
+    uint64_t x5;
+    uint64_t x6;
+    uint64_t x7;
+    uint64_t x8;
+    uint64_t x9;
+    uint64_t x10;
+    uint64_t x11;
+    uint64_t x12;
+    uint64_t x13;
+    uint64_t x14;
+    uint64_t x15;
+    uint64_t x16;
+    uint64_t x17;
+    uint64_t x18;
+    uint64_t x19;
+    uint64_t x20;
+    uint64_t x21;
+    uint64_t x22;
+    uint64_t x23;
+    uint64_t x24;
+    uint64_t x25;
+    uint64_t x26;
+    uint64_t x27;
+    uint64_t x28;
+    uint64_t x29;
+    uint64_t x30;
+    uint64_t pc;
+};
+
+struct vm_event_regs_arm {
+    uint32_t cpsr; /* PSR_MODE_BIT is set iff arm32 is used below */
+    uint32_t _pad;
+    uint64_t ttbr0;
+    uint64_t ttbr1;
+    union {
+        struct vm_event_regs_arm32 arm32;
+        struct vm_event_regs_arm64 arm64;
+    } arch;
+};
+
 /*
  * mem_access flag definitions
  *
@@ -236,10 +299,14 @@ struct vm_event_sharing {
     uint32_t _pad;
 };
 
+#define VM_EVENT_MAX_DATA_SIZE \
+    (sizeof(struct vm_event_regs_x86) > sizeof(struct vm_event_regs_arm) ? \
+        sizeof(struct vm_event_regs_x86) : sizeof(struct vm_event_regs_arm))
+
 struct vm_event_emul_read_data {
     uint32_t size;
     /* The struct is used in a union with vm_event_regs_x86. */
-    uint8_t  data[sizeof(struct vm_event_regs_x86) - sizeof(uint32_t)];
+    uint8_t  data[VM_EVENT_MAX_DATA_SIZE - sizeof(uint32_t)];
 };
 
 typedef struct vm_event_st {
@@ -264,6 +331,7 @@ typedef struct vm_event_st {
     union {
         union {
             struct vm_event_regs_x86 x86;
+            struct vm_event_regs_arm arm;
         } regs;
 
         struct vm_event_emul_read_data emul_read_data;
diff --git a/xen/include/xen/vm_event.h b/xen/include/xen/vm_event.h
index 89e6243..a5767ab 100644
--- a/xen/include/xen/vm_event.h
+++ b/xen/include/xen/vm_event.h
@@ -75,6 +75,9 @@ int vm_event_domctl(struct domain *d, xen_domctl_vm_event_op_t *vec,
 void vm_event_vcpu_pause(struct vcpu *v);
 void vm_event_vcpu_unpause(struct vcpu *v);
 
+void vm_event_fill_regs(vm_event_request_t *req);
+void vm_event_set_registers(struct vcpu *v, vm_event_response_t *rsp);
+
 /*
  * Monitor vm-events
  */
-- 
2.8.1


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

  parent reply	other threads:[~2016-06-02 22:52 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-02 22:52 [PATCH v5 1/9] vm_event: clear up return value of vm_event_monitor_traps Tamas K Lengyel
2016-06-02 22:52 ` [PATCH v5 2/9] monitor: Rename vm_event_monitor_get_capabilities Tamas K Lengyel
2016-06-17 19:07   ` Tamas K Lengyel
2016-06-21  9:20   ` Julien Grall
2016-06-02 22:52 ` [PATCH v5 3/9] monitor: Rename vm_event_monitor_guest_request Tamas K Lengyel
2016-06-17 19:10   ` Tamas K Lengyel
2016-06-21  9:18   ` Julien Grall
2016-06-02 22:52 ` [PATCH v5 4/9] monitor: Rename hvm/event to hvm/monitor Tamas K Lengyel
2016-06-02 22:52 ` [PATCH v5 5/9] monitor: ARM SMC events Tamas K Lengyel
2016-06-03  9:49   ` Julien Grall
2016-06-03 13:40     ` Tamas K Lengyel
2016-06-03 14:43       ` Julien Grall
2016-06-03 15:03         ` Tamas K Lengyel
2016-06-03 15:06           ` Julien Grall
2016-06-03 15:42             ` Tamas K Lengyel
2016-06-03 15:27         ` Tamas K Lengyel
2016-06-03 15:34           ` Tamas K Lengyel
2016-06-04  9:03             ` Edgar E. Iglesias
2016-06-04 17:40               ` Tamas K Lengyel
2016-06-06 10:07                 ` Julien Grall
     [not found]                   ` <CABfawh=tOsUP1dQi9oAZM+iy3rMmCKDW=VByT-L-xYdAMBiMKw@mail.gmail.com>
     [not found]                     ` <CABfawhkSXqky9WWp8NyKEUrH_ZzSJToxAncTeSYeKBg1q63rwg@mail.gmail.com>
2016-06-06 15:24                       ` Tamas K Lengyel
2016-06-06 15:54                         ` Julien Grall
2016-06-06 15:56                           ` Tamas K Lengyel
2016-06-06 16:14                             ` Tamas K Lengyel
2016-06-06 16:38                               ` Julien Grall
2016-06-06 17:28                                 ` Tamas K Lengyel
2016-06-07  7:13                                 ` Jan Beulich
2016-06-07 10:30                                   ` Stefano Stabellini
2016-06-07 16:06                                     ` Tamas K Lengyel
2016-06-02 22:52 ` Tamas K Lengyel [this message]
2016-06-03 10:34   ` [PATCH v5 6/9] arm/vm_event: get/set registers Jan Beulich
2016-06-03 19:27     ` Tamas K Lengyel
2016-06-02 22:52 ` [PATCH v5 7/9] tools/libxc: add xc_monitor_privileged_call Tamas K Lengyel
2016-06-02 22:52 ` [PATCH v5 8/9] x86/vm_event: Add HVM debug exception vm_events Tamas K Lengyel
2016-06-03 10:49   ` Jan Beulich
2016-06-03 13:29     ` Tamas K Lengyel
2016-06-03 14:23       ` Jan Beulich
2016-06-03 14:34         ` Tamas K Lengyel
2016-06-03 14:45           ` Jan Beulich
2016-06-03 14:51             ` Tamas K Lengyel
2016-06-02 22:52 ` [PATCH v5 9/9] tools/xen-access: add test-case for ARM SMC Tamas K Lengyel
2016-06-03  7:08 ` [PATCH v5 1/9] vm_event: clear up return value of vm_event_monitor_traps Razvan Cojocaru
2016-06-03 15:54 ` Jan Beulich
2016-06-03 16:03   ` Tamas K Lengyel
2016-06-17 19:09 ` Tamas K Lengyel
2016-06-24 10:58   ` Tian, Kevin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1464907946-19242-6-git-send-email-tamas@tklengyel.com \
    --to=tamas@tklengyel.com \
    --cc=julien.grall@arm.com \
    --cc=sstabellini@kernel.org \
    --cc=xen-devel@lists.xenproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.