arm/vm_event: get/set registers

Add support for getting/setting registers through vm_event on ARM. Only
TTB/CR/R0/R1, PC and CPSR are sent as part of a request and only PC is set
as part of a response. The set of registers can be expanded in the future to
include other registers as well if necessary.

Signed-off-by: Tamas K Lengyel <tamas.lengyel@zentific.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Razvan Cojocaru <rcojocaru@bitdefender.com>
Acked-by: Stefano Stabellini <sstabellini@kernel.org>
This commit is contained in:
Tamas K Lengyel authored and Stefano Stabellini committed 2016-09-09 16:03:37 -07:00
1 parent 8a085e9d94
commit a3fe74e434
6 files changed
+72 -17

No files matched your search

+1
View File
@@ -43,6 +43,7 @@ obj-y += traps.o
obj-y += vgic.o
obj-y += vgic-v2.o
obj-$(CONFIG_ARM_64) += vgic-v3.o
obj-y += vm_event.o
obj-y += vtimer.o
obj-y += vpsci.o
obj-y += vuart.o
+52
View File
@@ -0,0 +1,52 @@
/*
* arch/arm/vm_event.c
*
* Architecture-specific vm_event handling routines
*
* Copyright (c) 2016 Tamas K Lengyel (tamas.lengyel@zentific.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.pc = regs->pc;
req->data.regs.arm.ttbcr = READ_SYSREG(TCR_EL1);
req->data.regs.arm.ttbr0 = READ_SYSREG64(TTBR0_EL1);
req->data.regs.arm.ttbr1 = READ_SYSREG64(TTBR1_EL1);
}
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;
/* vCPU should be paused */
ASSERT(atomic_read(&v->vm_event_pause_count));
regs->pc = rsp->data.regs.arm.pc;
}
/*
* Local variables:
* mode: C
* c-file-style: "BSD"
* c-basic-offset: 4
* indent-tabs-mode: nil
* End:
*/
-11
View File
@@ -45,15 +45,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__ */
-4
View File
@@ -39,8 +39,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__ */
+16 -2
View File
@@ -132,8 +132,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;
@@ -171,6 +171,19 @@ struct vm_event_regs_x86 {
uint32_t _pad;
};
/*
* Only the register 'pc' can be set on a vm_event response using the
* VM_EVENT_FLAG_SET_REGISTERS flag.
*/
struct vm_event_regs_arm {
uint64_t ttbr0;
uint64_t ttbr1;
uint64_t ttbcr;
uint64_t pc;
uint32_t cpsr;
uint32_t _pad;
};
/*
* mem_access flag definitions
*
@@ -275,6 +288,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;
+3
View File
@@ -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);
#endif /* __VM_EVENT_H__ */
/*
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.