|
[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 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().
> --- 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"?
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.
> --- 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)
> --- 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)?
> @@ -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.
Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |