[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH V4] xen/vm_event: Clean up control-register-write vm_events
On 05/22/2015 10:36 AM, Jan Beulich wrote: >>>> On 21.05.15 at 15:00, <rcojocaru@xxxxxxxxxxxxxxx> wrote: >> --- a/xen/arch/x86/hvm/event.c >> +++ b/xen/arch/x86/hvm/event.c >> @@ -88,55 +88,29 @@ static int hvm_event_traps(uint8_t sync, >> vm_event_request_t *req) >> return 1; >> } >> >> -static inline >> -void hvm_event_cr(uint32_t reason, unsigned long value, >> - unsigned long old, bool_t onchangeonly, bool_t >> sync) >> +void hvm_event_cr(unsigned int index, unsigned long value, unsigned long >> old) >> { >> - if ( onchangeonly && value == old ) >> + struct arch_domain *currad = ¤t->domain->arch; >> + unsigned int ctrlreg_bitmask = monitor_ctrlreg_bitmask(index); >> + >> + if ( !(currad->monitor.write_ctrlreg_enabled & ctrlreg_bitmask) ) >> return; >> - else >> + >> + if ( !(currad->monitor.write_ctrlreg_onchangeonly & ctrlreg_bitmask) || >> + value != old ) >> { > > While this is now better than the previous if/else pair, I still don't > see why this can't be just a single if(). Ack, will change it to a single if. >> --- a/xen/arch/x86/hvm/hvm.c >> +++ b/xen/arch/x86/hvm/hvm.c >> @@ -2965,11 +2965,14 @@ out: >> int hvm_handle_xsetbv(u32 index, u64 new_bv) >> { >> struct segment_register sreg; >> + struct vcpu *curr = current; >> >> - hvm_get_segment_register(current, x86_seg_ss, &sreg); >> + hvm_get_segment_register(curr, x86_seg_ss, &sreg); >> if ( sreg.attr.fields.dpl != 0 ) >> goto err; >> >> + hvm_event_cr(VM_EVENT_X86_XCR0, new_bv, curr->arch.xcr0); >> + >> if ( handle_xsetbv(index, new_bv) ) >> goto err; > > So this is a pre event now, contrary to all others. Is that really a > good idea? And is it a good idea in the first place to introduce new > events in a patch titled "cleanup"? While it is indeed different from the rest of the CR events in that it is a pre-write, it is not however different from the MSR event, which is currently pre-write. As for introducing the new event, it's a trivial one-line change if we don't count the VM_EVENT_X86_XCR0 constant and the extra bit in the enabled, sync and onchangeonly fields. Should I drop the introduction of the XR0 event from this patch and come back to it in the following iteration of the series? > Also, for readability I wonder whether an identically named macro > wrapper around hvm_event_cr() wouldn't be a good idea, eliminating > the need to spell out VM_EVENT_X86_ at each use site. #define hvm_event_cr0(new, old) hvm_event_cr(VM_EVENT_X86_XCR0, new, old)? Sure. >> --- a/xen/arch/x86/monitor.c >> +++ b/xen/arch/x86/monitor.c >> @@ -67,59 +67,41 @@ int monitor_domctl(struct domain *d, struct >> xen_domctl_monitor_op *mop) >> >> switch ( mop->event ) >> { >> - case XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR0: >> + case XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG: >> { >> - bool_t status = ad->monitor.mov_to_cr0_enabled; >> - >> - rc = status_check(mop, status); >> - if ( rc ) >> - return rc; >> - >> - ad->monitor.mov_to_cr0_sync = mop->u.mov_to_cr.sync; >> - ad->monitor.mov_to_cr0_onchangeonly = mop->u.mov_to_cr.onchangeonly; >> - >> - domain_pause(d); >> - ad->monitor.mov_to_cr0_enabled = !status; >> - domain_unpause(d); >> - break; >> - } >> - >> - case XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR3: >> - { >> - bool_t status = ad->monitor.mov_to_cr3_enabled; >> + unsigned int ctrlreg_bitmask = >> + monitor_ctrlreg_bitmask(mop->u.mov_to_cr.index); >> + bool_t status = ad->monitor.write_ctrlreg_enabled & ctrlreg_bitmask; > > !!(ad->monitor.write_ctrlreg_enabled & ctrlreg_bitmask) Ack. >> --- a/xen/include/asm-x86/domain.h >> +++ b/xen/include/asm-x86/domain.h >> @@ -249,6 +249,8 @@ struct pv_domain >> struct mapcache_domain mapcache; >> }; >> >> +#define monitor_ctrlreg_bitmask(ctrlreg_index) (1 << ctrlreg_index) > > (1U << (ctrlreg_index)) would seem better to me. Also - does this > need to be in this header (which gets included basically everywhere)? Ack. As for the header, that's where the fields are (write_ctrlreg_enabled, sync and onchangeonly), and since several .c files use the fields it seemed the natural place to put the macros. >> @@ -1050,6 +1048,8 @@ struct xen_domctl_monitor_op { >> */ >> union { >> struct { >> + /* Which control register */ >> + uint8_t index; > > Okay, 8 bits here (which is reasonable), but ... > >> @@ -156,7 +158,8 @@ struct vm_event_mem_access { >> uint32_t _pad; >> }; >> >> -struct vm_event_mov_to_cr { >> +struct vm_event_write_ctrlreg { >> + uint64_t index; >> uint64_t new_value; >> uint64_t old_value; >> }; > > ... a full 64 bits here? 32 bits surely would do (with 32 bits of padding), > allowing slightly better accessing code on both the consumer and > producer sides. Ack, will modify it. I set it to 64 bits there because I thought I'd get free padding, but you're right, it's better to be explicit. Thanks, Razvan _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |