[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH] vm_event: Implement ARM SMC events
On Mon, Apr 11, 2016 at 01:47:22PM -0600, Tamas K Lengyel wrote: > From: Tamas K Lengyel <tklengyel@xxxxxxxxxxxxx> > > The ARM SMC instructions are already configured to trap to Xen by default. In > this patch we allow a user-space process in a privileged domain to receive > notification of when such event happens through the vm_event subsystem. > > This patch will likely needs to be broken up into several smaller patches. > Right now what this patch adds (and could be broken into smaller patches > accordingly): > - Implement monitor_op domctl handler for SOFTWARE_BREAKPOINTs on ARM > - Implement vm_event register fill/set routines for ARM. This required > removing the function from common as the function prototype now > differs on the two archs. > - Sending notification as SOFTWARE_BREAKPOINT vm_event from the SMC trap > handlers. > - Extend the xen-access test tool to receive SMC notification and step > the PC manually in the reply. > > I'm sending it as an RFC to gather feedback on what has been overlooked in > this > revision. This patch has been tested on a Cubietruck board and works fine, > but would probably not work on 64-bit boards. I only have some small nitpicking. > +++ b/xen/arch/arm/traps.c > @@ -41,6 +41,7 @@ > #include <asm/mmio.h> > #include <asm/cpufeature.h> > #include <asm/flushtlb.h> > +#include <asm/vm_event.h> > > #include "decode.h" > #include "vtimer.h" > @@ -2449,6 +2450,21 @@ bad_data_abort: > inject_dabt_exception(regs, info.gva, hsr.len); > } > > +static void do_trap_smc(struct cpu_user_regs *regs) > +{ > + int rc = 0; Newline here > + if ( current->domain->arch.monitor.software_breakpoint_enabled ) > + { > + rc = vm_event_smc(regs); > + } > + > + if ( rc != 1 ) > + { > + GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr)); This differs a bit from below. Should there be an comment explaining why we expect it be only in 32-bit mode? > + inject_undef32_exception(regs); Below you do inject_undef64_exception? Perhaps there should be an check if it is 32 or 64-bit? > + } > +} > + > static void enter_hypervisor_head(struct cpu_user_regs *regs) > { > if ( guest_mode(regs) ) > @@ -2524,7 +2540,7 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs > *regs) > */ > GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr)); > perfc_incr(trap_smc32); > - inject_undef32_exception(regs); > + do_trap_smc(regs); > break; > case HSR_EC_HVC32: > GUEST_BUG_ON(!psr_mode_is_32bit(regs->cpsr)); > @@ -2557,7 +2573,7 @@ asmlinkage void do_trap_hypervisor(struct cpu_user_regs > *regs) > */ > GUEST_BUG_ON(psr_mode_is_32bit(regs->cpsr)); > perfc_incr(trap_smc64); > - inject_undef64_exception(regs, hsr.len); > + do_trap_smc(regs); As in here.. Now it will call inject_undef32_exception. That can't be healthy? > break; > case HSR_EC_SYSREG: > GUEST_BUG_ON(psr_mode_is_32bit(regs->cpsr)); > diff --git a/xen/arch/arm/vm_event.c b/xen/arch/arm/vm_event.c > new file mode 100644 > index 0000000..d997313 > --- /dev/null > +++ b/xen/arch/arm/vm_event.c > @@ -0,0 +1,95 @@ > +/* > + * arch/arm/vm_event.c > + * > + * Architecture-specific vm_event handling routines > + * > + * Copyright (c) 2015 Tamas K Lengyel (tamas@xxxxxxxxxxxxx) 2016? Also .. shouldn't the company be attributed as well? I see BitDefender on some of them so not sure what hte relationship you have with them. > + * > + * 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> > + > +static inline > +void vm_event_fill_regs(vm_event_request_t *req, > + const struct cpu_user_regs *regs) > +{ > + req->data.regs.arm.r0 = regs->r0; > + req->data.regs.arm.r1 = regs->r1; > + req->data.regs.arm.r2 = regs->r2; > + req->data.regs.arm.r3 = regs->r3; > + req->data.regs.arm.r4 = regs->r4; > + req->data.regs.arm.r5 = regs->r5; > + req->data.regs.arm.r6 = regs->r6; > + req->data.regs.arm.r7 = regs->r7; > + req->data.regs.arm.r8 = regs->r8; > + req->data.regs.arm.r9 = regs->r9; > + req->data.regs.arm.r10 = regs->r10; > + req->data.regs.arm.r11 = regs->r11; > + req->data.regs.arm.r12 = regs->r12; > + req->data.regs.arm.sp = regs->sp; > + req->data.regs.arm.lr = regs->lr; > + req->data.regs.arm.pc = regs->pc; > + 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); > +} > + > +void vm_event_set_registers(struct vcpu *v, vm_event_response_t *rsp) > +{ > + v->arch.cpu_info->guest_cpu_user_regs.r0 = rsp->data.regs.arm.r0; > + v->arch.cpu_info->guest_cpu_user_regs.r1 = rsp->data.regs.arm.r1; > + v->arch.cpu_info->guest_cpu_user_regs.r2 = rsp->data.regs.arm.r2; > + v->arch.cpu_info->guest_cpu_user_regs.r3 = rsp->data.regs.arm.r3; > + v->arch.cpu_info->guest_cpu_user_regs.r4 = rsp->data.regs.arm.r4; > + v->arch.cpu_info->guest_cpu_user_regs.r5 = rsp->data.regs.arm.r5; > + v->arch.cpu_info->guest_cpu_user_regs.r6 = rsp->data.regs.arm.r6; > + v->arch.cpu_info->guest_cpu_user_regs.r7 = rsp->data.regs.arm.r7; > + v->arch.cpu_info->guest_cpu_user_regs.r8 = rsp->data.regs.arm.r8; > + v->arch.cpu_info->guest_cpu_user_regs.r9 = rsp->data.regs.arm.r9; > + v->arch.cpu_info->guest_cpu_user_regs.r10 = rsp->data.regs.arm.r10; > + v->arch.cpu_info->guest_cpu_user_regs.r11 = rsp->data.regs.arm.r11; > + v->arch.cpu_info->guest_cpu_user_regs.r12 = rsp->data.regs.arm.r12; > + v->arch.cpu_info->guest_cpu_user_regs.sp = rsp->data.regs.arm.sp; > + v->arch.cpu_info->guest_cpu_user_regs.lr = rsp->data.regs.arm.lr; > + v->arch.cpu_info->guest_cpu_user_regs.pc = rsp->data.regs.arm.pc; > + v->arch.cpu_info->guest_cpu_user_regs.cpsr = rsp->data.regs.arm.cpsr; > + v->arch.ttbr0 = rsp->data.regs.arm.ttbr0; > + v->arch.ttbr1 = rsp->data.regs.arm.ttbr1; > +} > + > +int vm_event_smc(const struct cpu_user_regs *regs) { > + struct vcpu *curr = current; > + struct arch_domain *ad = &curr->domain->arch; > + vm_event_request_t req = { 0 }; > + > + if ( !ad->monitor.software_breakpoint_enabled ) > + return 0; > + > + req.reason = VM_EVENT_REASON_SOFTWARE_BREAKPOINT; > + req.vcpu_id = curr->vcpu_id; > + > + vm_event_fill_regs(&req, regs); > + > + return vm_event_monitor_traps(curr, 1, &req); Perhaps a comment right past 1 explaining what this mystical 1 value means? _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |