diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 100b89c2d7..50fa9e7b16 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -2375,12 +2375,9 @@ int xc_mem_access_disable_emulate(xc_interface *xch, domid_t domain_id); void *xc_monitor_enable(xc_interface *xch, domid_t domain_id, uint32_t *port); int xc_monitor_disable(xc_interface *xch, domid_t domain_id); int xc_monitor_resume(xc_interface *xch, domid_t domain_id); -int xc_monitor_mov_to_cr0(xc_interface *xch, domid_t domain_id, bool enable, - bool sync, bool onchangeonly); -int xc_monitor_mov_to_cr3(xc_interface *xch, domid_t domain_id, bool enable, - bool sync, bool onchangeonly); -int xc_monitor_mov_to_cr4(xc_interface *xch, domid_t domain_id, bool enable, - bool sync, bool onchangeonly); +int xc_monitor_write_ctrlreg(xc_interface *xch, domid_t domain_id, + uint16_t index, bool enable, bool sync, + bool onchangeonly); int xc_monitor_mov_to_msr(xc_interface *xch, domid_t domain_id, bool enable, bool extended_capture); int xc_monitor_singlestep(xc_interface *xch, domid_t domain_id, bool enable); diff --git a/tools/libxc/xc_monitor.c b/tools/libxc/xc_monitor.c index 87ad968706..63013deb89 100644 --- a/tools/libxc/xc_monitor.c +++ b/tools/libxc/xc_monitor.c @@ -45,8 +45,9 @@ int xc_monitor_resume(xc_interface *xch, domid_t domain_id) NULL); } -int xc_monitor_mov_to_cr0(xc_interface *xch, domid_t domain_id, bool enable, - bool sync, bool onchangeonly) +int xc_monitor_write_ctrlreg(xc_interface *xch, domid_t domain_id, + uint16_t index, bool enable, bool sync, + bool onchangeonly) { DECLARE_DOMCTL; @@ -54,39 +55,8 @@ int xc_monitor_mov_to_cr0(xc_interface *xch, domid_t domain_id, bool enable, domctl.domain = domain_id; domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE : XEN_DOMCTL_MONITOR_OP_DISABLE; - domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR0; - domctl.u.monitor_op.u.mov_to_cr.sync = sync; - domctl.u.monitor_op.u.mov_to_cr.onchangeonly = onchangeonly; - - return do_domctl(xch, &domctl); -} - -int xc_monitor_mov_to_cr3(xc_interface *xch, domid_t domain_id, bool enable, - bool sync, bool onchangeonly) -{ - DECLARE_DOMCTL; - - domctl.cmd = XEN_DOMCTL_monitor_op; - domctl.domain = domain_id; - domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE - : XEN_DOMCTL_MONITOR_OP_DISABLE; - domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR3; - domctl.u.monitor_op.u.mov_to_cr.sync = sync; - domctl.u.monitor_op.u.mov_to_cr.onchangeonly = onchangeonly; - - return do_domctl(xch, &domctl); -} - -int xc_monitor_mov_to_cr4(xc_interface *xch, domid_t domain_id, bool enable, - bool sync, bool onchangeonly) -{ - DECLARE_DOMCTL; - - domctl.cmd = XEN_DOMCTL_monitor_op; - domctl.domain = domain_id; - domctl.u.monitor_op.op = enable ? XEN_DOMCTL_MONITOR_OP_ENABLE - : XEN_DOMCTL_MONITOR_OP_DISABLE; - domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR4; + domctl.u.monitor_op.event = XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG; + domctl.u.monitor_op.u.mov_to_cr.index = index; domctl.u.monitor_op.u.mov_to_cr.sync = sync; domctl.u.monitor_op.u.mov_to_cr.onchangeonly = onchangeonly; diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c index a91ea774f1..feabe3404f 100644 --- a/xen/arch/arm/mm.c +++ b/xen/arch/arm/mm.c @@ -273,7 +273,9 @@ void clear_fixmap(unsigned map) #ifdef CONFIG_DOMAIN_PAGE void *map_domain_page_global(unsigned long mfn) { - return vmap(&mfn, 1); + mfn_t m = _mfn(mfn); + + return vmap(&m, 1); } void unmap_domain_page_global(const void *va) @@ -794,10 +796,10 @@ void *__init arch_vmap_virt_end(void) */ void *ioremap_attr(paddr_t pa, size_t len, unsigned int attributes) { - unsigned long pfn = PFN_DOWN(pa); + mfn_t mfn = _mfn(PFN_DOWN(pa)); unsigned int offs = pa & (PAGE_SIZE - 1); unsigned int nr = PFN_UP(offs + len); - void *ptr = __vmap(&pfn, nr, 1, 1, attributes); + void *ptr = __vmap(&mfn, nr, 1, 1, attributes); if ( ptr == NULL ) return NULL; diff --git a/xen/arch/x86/domain_page.c b/xen/arch/x86/domain_page.c index 79549987b8..8f3217b5ea 100644 --- a/xen/arch/x86/domain_page.c +++ b/xen/arch/x86/domain_page.c @@ -322,6 +322,7 @@ int mapcache_vcpu_init(struct vcpu *v) void *map_domain_page_global(unsigned long mfn) { + mfn_t m = _mfn(mfn); ASSERT(!in_irq() && local_irq_is_enabled()); #ifdef NDEBUG @@ -329,7 +330,7 @@ void *map_domain_page_global(unsigned long mfn) return mfn_to_virt(mfn); #endif - return vmap(&mfn, 1); + return vmap(&m, 1); } void unmap_domain_page_global(const void *ptr) diff --git a/xen/arch/x86/hvm/event.c b/xen/arch/x86/hvm/event.c index 9d5f9f3572..53b9ca401d 100644 --- a/xen/arch/x86/hvm/event.c +++ b/xen/arch/x86/hvm/event.c @@ -21,6 +21,8 @@ #include #include +#include +#include #include static void hvm_event_fill_regs(vm_event_request_t *req) @@ -88,55 +90,28 @@ 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 ) - return; - else + struct arch_domain *currad = ¤t->domain->arch; + unsigned int ctrlreg_bitmask = monitor_ctrlreg_bitmask(index); + + if ( (currad->monitor.write_ctrlreg_enabled & ctrlreg_bitmask) && + (!(currad->monitor.write_ctrlreg_onchangeonly & ctrlreg_bitmask) || + value != old) ) { vm_event_request_t req = { - .reason = reason, + .reason = VM_EVENT_REASON_WRITE_CTRLREG, .vcpu_id = current->vcpu_id, - .u.mov_to_cr.new_value = value, - .u.mov_to_cr.old_value = old + .u.write_ctrlreg.index = index, + .u.write_ctrlreg.new_value = value, + .u.write_ctrlreg.old_value = old }; - hvm_event_traps(sync, &req); + hvm_event_traps(currad->monitor.write_ctrlreg_sync & ctrlreg_bitmask, + &req); } } -void hvm_event_cr0(unsigned long value, unsigned long old) -{ - struct arch_domain *currad = ¤t->domain->arch; - - if ( currad->monitor.mov_to_cr0_enabled ) - hvm_event_cr(VM_EVENT_REASON_MOV_TO_CR0, value, old, - currad->monitor.mov_to_cr0_onchangeonly, - currad->monitor.mov_to_cr0_sync); -} - -void hvm_event_cr3(unsigned long value, unsigned long old) -{ - struct arch_domain *currad = ¤t->domain->arch; - - if ( currad->monitor.mov_to_cr3_enabled ) - hvm_event_cr(VM_EVENT_REASON_MOV_TO_CR3, value, old, - currad->monitor.mov_to_cr3_onchangeonly, - currad->monitor.mov_to_cr3_sync); -} - -void hvm_event_cr4(unsigned long value, unsigned long old) -{ - struct arch_domain *currad = ¤t->domain->arch; - - if ( currad->monitor.mov_to_cr4_enabled ) - hvm_event_cr(VM_EVENT_REASON_MOV_TO_CR4, value, old, - currad->monitor.mov_to_cr4_onchangeonly, - currad->monitor.mov_to_cr4_sync); -} - void hvm_event_msr(unsigned int msr, uint64_t value) { struct vcpu *curr = current; diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 89423fa162..b1023bb894 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -2985,11 +2985,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_crX(XCR0, new_bv, curr->arch.xcr0); + if ( handle_xsetbv(index, new_bv) ) goto err; @@ -3287,7 +3290,7 @@ int hvm_set_cr0(unsigned long value) hvm_funcs.handle_cd(v, value); hvm_update_cr(v, 0, value); - hvm_event_cr0(value, old_value); + hvm_event_crX(CR0, value, old_value); if ( (value ^ old_value) & X86_CR0_PG ) { if ( !nestedhvm_vmswitch_in_progress(v) && nestedhvm_vcpu_in_guestmode(v) ) @@ -3328,7 +3331,7 @@ int hvm_set_cr3(unsigned long value) old=v->arch.hvm_vcpu.guest_cr[3]; v->arch.hvm_vcpu.guest_cr[3] = value; paging_update_cr3(v); - hvm_event_cr3(value, old); + hvm_event_crX(CR3, value, old); return X86EMUL_OKAY; bad_cr3: @@ -3369,7 +3372,7 @@ int hvm_set_cr4(unsigned long value) } hvm_update_cr(v, 4, value); - hvm_event_cr4(value, old_cr); + hvm_event_crX(CR4, value, old_cr); /* * Modifying CR4.{PSE,PAE,PGE,SMEP}, or clearing CR4.PCIDE diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 74f563f151..af257db4da 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -57,6 +57,7 @@ #include #include #include +#include #include static bool_t __initdata opt_force_ept; @@ -1262,7 +1263,8 @@ static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr) v->arch.hvm_vmx.exec_control |= cr3_ctls; /* Trap CR3 updates if CR3 memory events are enabled. */ - if ( v->domain->arch.monitor.mov_to_cr3_enabled ) + if ( v->domain->arch.monitor.write_ctrlreg_enabled & + monitor_ctrlreg_bitmask(VM_EVENT_X86_CR3) ) v->arch.hvm_vmx.exec_control |= CPU_BASED_CR3_LOAD_EXITING; vmx_update_cpu_exec_control(v); @@ -2010,7 +2012,7 @@ static int vmx_cr_access(unsigned long exit_qualification) unsigned long old = curr->arch.hvm_vcpu.guest_cr[0]; curr->arch.hvm_vcpu.guest_cr[0] &= ~X86_CR0_TS; vmx_update_guest_cr(curr, 0); - hvm_event_cr0(curr->arch.hvm_vcpu.guest_cr[0], old); + hvm_event_crX(CR0, curr->arch.hvm_vcpu.guest_cr[0], old); HVMTRACE_0D(CLTS); break; } diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 7a7a85402d..1c0783f507 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -5883,10 +5883,10 @@ void *__init arch_vmap_virt_end(void) void __iomem *ioremap(paddr_t pa, size_t len) { - unsigned long pfn = PFN_DOWN(pa); + mfn_t mfn = _mfn(PFN_DOWN(pa)); void *va; - WARN_ON(page_is_ram_type(pfn, RAM_TYPE_CONVENTIONAL)); + WARN_ON(page_is_ram_type(mfn_x(mfn), RAM_TYPE_CONVENTIONAL)); /* The low first Mb is always mapped. */ if ( !((pa + len - 1) >> 20) ) @@ -5896,7 +5896,7 @@ void __iomem *ioremap(paddr_t pa, size_t len) unsigned int offs = pa & (PAGE_SIZE - 1); unsigned int nr = PFN_UP(offs + len); - va = __vmap(&pfn, nr, 1, 1, PAGE_HYPERVISOR_NOCACHE) + offs; + va = __vmap(&mfn, nr, 1, 1, PAGE_HYPERVISOR_NOCACHE) + offs; } return (void __force __iomem *)va; diff --git a/xen/arch/x86/mm/hap/hap.c b/xen/arch/x86/mm/hap/hap.c index cea7990fe9..d0d3f1e645 100644 --- a/xen/arch/x86/mm/hap/hap.c +++ b/xen/arch/x86/mm/hap/hap.c @@ -464,13 +464,6 @@ int hap_enable(struct domain *d, u32 mode) domain_pause(d); - /* error check */ - if ( (d == current->domain) ) - { - rv = -EINVAL; - goto out; - } - old_pages = d->arch.paging.hap.total_pages; if ( old_pages == 0 ) { diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 654bacc72f..919b15b777 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -2972,8 +2972,7 @@ int shadow_enable(struct domain *d, u32 mode) domain_pause(d); /* Sanity check the arguments */ - if ( (d == current->domain) || - shadow_mode_enabled(d) || + if ( shadow_mode_enabled(d) || ((mode & PG_translate) && !(mode & PG_refcounts)) || ((mode & PG_external) && !(mode & PG_translate)) ) { diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 43e70d8900..6edac715ee 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -4670,7 +4670,7 @@ static void *emulate_map_dest(struct vcpu *v, } else { - unsigned long mfns[2]; + mfn_t mfns[2]; /* Cross-page emulated writes are only supported for HVM guests; * PV guests ought to know better */ @@ -4689,8 +4689,8 @@ static void *emulate_map_dest(struct vcpu *v, /* Cross-page writes mean probably not a pagetable */ sh_remove_shadows(d, sh_ctxt->mfn2, 0, 0 /* Slow, can fail */ ); - mfns[0] = mfn_x(sh_ctxt->mfn1); - mfns[1] = mfn_x(sh_ctxt->mfn2); + mfns[0] = sh_ctxt->mfn1; + mfns[1] = sh_ctxt->mfn2; map = vmap(mfns, 2); if ( !map ) return MAPPING_UNHANDLEABLE; diff --git a/xen/arch/x86/monitor.c b/xen/arch/x86/monitor.c index d7b1c18ce6..896acf79c5 100644 --- a/xen/arch/x86/monitor.c +++ b/xen/arch/x86/monitor.c @@ -67,59 +67,42 @@ 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); struct vcpu *v; rc = status_check(mop, status); if ( rc ) return rc; - ad->monitor.mov_to_cr3_sync = mop->u.mov_to_cr.sync; - ad->monitor.mov_to_cr3_onchangeonly = mop->u.mov_to_cr.onchangeonly; + if ( mop->u.mov_to_cr.sync ) + ad->monitor.write_ctrlreg_sync |= ctrlreg_bitmask; + else + ad->monitor.write_ctrlreg_sync &= ~ctrlreg_bitmask; + + if ( mop->u.mov_to_cr.onchangeonly ) + ad->monitor.write_ctrlreg_onchangeonly |= ctrlreg_bitmask; + else + ad->monitor.write_ctrlreg_onchangeonly &= ~ctrlreg_bitmask; domain_pause(d); - ad->monitor.mov_to_cr3_enabled = !status; + + if ( !status ) + ad->monitor.write_ctrlreg_enabled |= ctrlreg_bitmask; + else + ad->monitor.write_ctrlreg_enabled &= ~ctrlreg_bitmask; + domain_unpause(d); - /* Latches new CR3 mask through CR0 code */ - for_each_vcpu ( d, v ) - hvm_funcs.update_guest_cr(v, 0); - break; - } + if ( mop->u.mov_to_cr.index == VM_EVENT_X86_CR3 ) + /* Latches new CR3 mask through CR0 code */ + for_each_vcpu ( d, v ) + hvm_funcs.update_guest_cr(v, 0); - case XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR4: - { - bool_t status = ad->monitor.mov_to_cr4_enabled; - - rc = status_check(mop, status); - if ( rc ) - return rc; - - ad->monitor.mov_to_cr4_sync = mop->u.mov_to_cr.sync; - ad->monitor.mov_to_cr4_onchangeonly = mop->u.mov_to_cr.onchangeonly; - - domain_pause(d); - ad->monitor.mov_to_cr4_enabled = !status; - domain_unpause(d); break; } diff --git a/xen/common/vmap.c b/xen/common/vmap.c index ac66a8c41b..c57239ff0a 100644 --- a/xen/common/vmap.c +++ b/xen/common/vmap.c @@ -181,7 +181,7 @@ void vm_free(const void *va) spin_unlock(&vm_lock); } -void *__vmap(const unsigned long *mfn, unsigned int granularity, +void *__vmap(const mfn_t *mfn, unsigned int granularity, unsigned int nr, unsigned int align, unsigned int flags) { void *va = vm_alloc(nr * granularity, align); @@ -189,7 +189,7 @@ void *__vmap(const unsigned long *mfn, unsigned int granularity, for ( ; va && nr--; ++mfn, cur += PAGE_SIZE * granularity ) { - if ( map_pages_to_xen(cur, *mfn, granularity, flags) ) + if ( map_pages_to_xen(cur, mfn_x(*mfn), granularity, flags) ) { vunmap(va); va = NULL; @@ -199,7 +199,7 @@ void *__vmap(const unsigned long *mfn, unsigned int granularity, return va; } -void *vmap(const unsigned long *mfn, unsigned int nr) +void *vmap(const mfn_t *mfn, unsigned int nr) { return __vmap(mfn, 1, nr, 1, PAGE_HYPERVISOR); } @@ -218,7 +218,7 @@ void vunmap(const void *va) void *vmalloc(size_t size) { - unsigned long *mfn; + mfn_t *mfn; size_t pages, i; struct page_info *pg; void *va; @@ -226,7 +226,7 @@ void *vmalloc(size_t size) ASSERT(size); pages = PFN_UP(size); - mfn = xmalloc_array(unsigned long, pages); + mfn = xmalloc_array(mfn_t, pages); if ( mfn == NULL ) return NULL; @@ -235,7 +235,7 @@ void *vmalloc(size_t size) pg = alloc_domheap_page(NULL, 0); if ( pg == NULL ) goto error; - mfn[i] = page_to_mfn(pg); + mfn[i] = _mfn(page_to_mfn(pg)); } va = vmap(mfn, pages); @@ -247,7 +247,7 @@ void *vmalloc(size_t size) error: while ( i-- ) - free_domheap_page(mfn_to_page(mfn[i])); + free_domheap_page(mfn_to_page(mfn_x(mfn[i]))); xfree(mfn); return NULL; } diff --git a/xen/drivers/acpi/osl.c b/xen/drivers/acpi/osl.c index 93c983ca9d..4c09859631 100644 --- a/xen/drivers/acpi/osl.c +++ b/xen/drivers/acpi/osl.c @@ -88,13 +88,14 @@ void __iomem * acpi_os_map_memory(acpi_physical_address phys, acpi_size size) { if (system_state >= SYS_STATE_active) { - unsigned long pfn = PFN_DOWN(phys); + mfn_t mfn = _mfn(PFN_DOWN(phys)); unsigned int offs = phys & (PAGE_SIZE - 1); /* The low first Mb is always mapped. */ if ( !((phys + size - 1) >> 20) ) return __va(phys); - return __vmap(&pfn, PFN_UP(offs + size), 1, 1, PAGE_HYPERVISOR_NOCACHE) + offs; + return __vmap(&mfn, PFN_UP(offs + size), 1, 1, + PAGE_HYPERVISOR_NOCACHE) + offs; } return __acpi_map_table(phys, size); } diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h index c0afcec271..3601140daa 100644 --- a/xen/include/asm-arm/mm.h +++ b/xen/include/asm-arm/mm.h @@ -310,8 +310,6 @@ static inline int relinquish_shared_pages(struct domain *d) return 0; } -#define INVALID_MFN (~0UL) - /* Xen always owns P2M on ARM */ #define set_gpfn_from_mfn(mfn, pfn) do { (void) (mfn), (void)(pfn); } while (0) #define mfn_to_gmfn(_d, mfn) (mfn) diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 45b5283d8d..a3c117f169 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -341,15 +341,9 @@ struct arch_domain /* Monitor options */ struct { - uint16_t mov_to_cr0_enabled : 1; - uint16_t mov_to_cr0_sync : 1; - uint16_t mov_to_cr0_onchangeonly : 1; - uint16_t mov_to_cr3_enabled : 1; - uint16_t mov_to_cr3_sync : 1; - uint16_t mov_to_cr3_onchangeonly : 1; - uint16_t mov_to_cr4_enabled : 1; - uint16_t mov_to_cr4_sync : 1; - uint16_t mov_to_cr4_onchangeonly : 1; + uint16_t write_ctrlreg_enabled : 4; + uint16_t write_ctrlreg_sync : 4; + uint16_t write_ctrlreg_onchangeonly : 4; uint16_t mov_to_msr_enabled : 1; uint16_t mov_to_msr_extended : 1; uint16_t singlestep_enabled : 1; diff --git a/xen/include/asm-x86/guest_pt.h b/xen/include/asm-x86/guest_pt.h index d2a82506ed..cf21617a0a 100644 --- a/xen/include/asm-x86/guest_pt.h +++ b/xen/include/asm-x86/guest_pt.h @@ -33,15 +33,6 @@ #error GUEST_PAGING_LEVELS not defined #endif -/* Type of the guest's frame numbers */ -TYPE_SAFE(unsigned long,gfn) -#define PRI_gfn "05lx" - -#ifndef gfn_t -#define gfn_t /* Grep fodder: gfn_t, _gfn() and gfn_x() are defined above */ -#undef gfn_t -#endif - #define VALID_GFN(m) (m != INVALID_GFN) static inline int diff --git a/xen/include/asm-x86/hvm/event.h b/xen/include/asm-x86/hvm/event.h index bb757a12c3..819ef96ecd 100644 --- a/xen/include/asm-x86/hvm/event.h +++ b/xen/include/asm-x86/hvm/event.h @@ -19,9 +19,9 @@ #define __ASM_X86_HVM_EVENT_H__ /* Called for current VCPU on crX/MSR changes by guest */ -void hvm_event_cr0(unsigned long value, unsigned long old); -void hvm_event_cr3(unsigned long value, unsigned long old); -void hvm_event_cr4(unsigned long value, unsigned long old); +void hvm_event_cr(unsigned int index, unsigned long value, unsigned long old); +#define hvm_event_crX(what, new, old) \ + hvm_event_cr(VM_EVENT_X86_##what, new, old) void hvm_event_msr(unsigned int msr, uint64_t value); /* Called for current VCPU: returns -1 if no listener */ int hvm_event_int3(unsigned long gla); diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index d1f95c85d9..8595c38f2c 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -433,41 +433,6 @@ extern paddr_t mem_hotplug; * guest L2 page), etc... */ -/* With this defined, we do some ugly things to force the compiler to - * give us type safety between mfns and gfns and other integers. - * TYPE_SAFE(int foo) defines a foo_t, and _foo() and foo_x() functions - * that translate beween int and foo_t. - * - * It does have some performance cost because the types now have - * a different storage attribute, so may not want it on all the time. */ - -#ifndef NDEBUG -#define TYPE_SAFETY 1 -#endif - -#ifdef TYPE_SAFETY -#define TYPE_SAFE(_type,_name) \ -typedef struct { _type _name; } _name##_t; \ -static inline _name##_t _##_name(_type n) { return (_name##_t) { n }; } \ -static inline _type _name##_x(_name##_t n) { return n._name; } -#else -#define TYPE_SAFE(_type,_name) \ -typedef _type _name##_t; \ -static inline _name##_t _##_name(_type n) { return n; } \ -static inline _type _name##_x(_name##_t n) { return n; } -#endif - -TYPE_SAFE(unsigned long,mfn); - -#ifndef mfn_t -#define mfn_t /* Grep fodder: mfn_t, _mfn() and mfn_x() are defined above */ -#undef mfn_t -#endif - -/* Macro for printk formats: use as printk("%"PRI_mfn"\n", mfn_x(foo)); */ -#define PRI_mfn "05lx" - - /* * The MPT (machine->physical mapping table) is an array of word-sized * values, indexed on machine frame number. It is expected that guest OSes @@ -510,8 +475,6 @@ extern struct rangeset *mmio_ro_ranges; ? get_gpfn_from_mfn(mfn) \ : (mfn) ) -#define INVALID_MFN (~0UL) - #define compat_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) #define compat_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) diff --git a/xen/include/asm-x86/monitor.h b/xen/include/asm-x86/monitor.h index 21b3e5b40c..d5815db7ab 100644 --- a/xen/include/asm-x86/monitor.h +++ b/xen/include/asm-x86/monitor.h @@ -26,6 +26,8 @@ struct domain; struct xen_domctl_monitor_op; +#define monitor_ctrlreg_bitmask(ctrlreg_index) (1U << (ctrlreg_index)) + int monitor_domctl(struct domain *d, struct xen_domctl_monitor_op *op); #endif /* __ASM_X86_MONITOR_H__ */ diff --git a/xen/include/asm-x86/paging.h b/xen/include/asm-x86/paging.h index c99324cf82..9c326651f0 100644 --- a/xen/include/asm-x86/paging.h +++ b/xen/include/asm-x86/paging.h @@ -255,7 +255,6 @@ static inline int paging_invlpg(struct vcpu *v, unsigned long va) * pfec[0] is used to determine which kind of access this is when * walking the tables. The caller should set the PFEC_page_present bit * in pfec[0]; in the failure case, that bit will be cleared if appropriate. */ -#define INVALID_GFN (-1UL) unsigned long paging_gva_to_gfn(struct vcpu *v, unsigned long va, uint32_t *pfec); diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 88f8002ec1..bc45ea5698 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -1008,12 +1008,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_psr_cmt_op_t); #define XEN_DOMCTL_MONITOR_OP_ENABLE 0 #define XEN_DOMCTL_MONITOR_OP_DISABLE 1 -#define XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR0 0 -#define XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR3 1 -#define XEN_DOMCTL_MONITOR_EVENT_MOV_TO_CR4 2 -#define XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR 3 -#define XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP 4 -#define XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT 5 +#define XEN_DOMCTL_MONITOR_EVENT_WRITE_CTRLREG 0 +#define XEN_DOMCTL_MONITOR_EVENT_MOV_TO_MSR 1 +#define XEN_DOMCTL_MONITOR_EVENT_SINGLESTEP 2 +#define XEN_DOMCTL_MONITOR_EVENT_SOFTWARE_BREAKPOINT 3 struct xen_domctl_monitor_op { uint32_t op; /* XEN_DOMCTL_MONITOR_OP_* */ @@ -1024,6 +1022,8 @@ struct xen_domctl_monitor_op { */ union { struct { + /* Which control register */ + uint8_t index; /* Pause vCPU until response */ uint8_t sync; /* Send event only on a change of value */ diff --git a/xen/include/public/vm_event.h b/xen/include/public/vm_event.h index c7426de0e1..577e971bf9 100644 --- a/xen/include/public/vm_event.h +++ b/xen/include/public/vm_event.h @@ -60,22 +60,24 @@ #define VM_EVENT_REASON_MEM_SHARING 2 /* Memory paging event */ #define VM_EVENT_REASON_MEM_PAGING 3 -/* CR0 was updated */ -#define VM_EVENT_REASON_MOV_TO_CR0 4 -/* CR3 was updated */ -#define VM_EVENT_REASON_MOV_TO_CR3 5 -/* CR4 was updated */ -#define VM_EVENT_REASON_MOV_TO_CR4 6 +/* A control register was updated */ +#define VM_EVENT_REASON_WRITE_CTRLREG 4 /* An MSR was updated. */ -#define VM_EVENT_REASON_MOV_TO_MSR 7 +#define VM_EVENT_REASON_MOV_TO_MSR 5 /* Debug operation executed (e.g. int3) */ -#define VM_EVENT_REASON_SOFTWARE_BREAKPOINT 8 +#define VM_EVENT_REASON_SOFTWARE_BREAKPOINT 6 /* Single-step (e.g. MTF) */ -#define VM_EVENT_REASON_SINGLESTEP 9 +#define VM_EVENT_REASON_SINGLESTEP 7 + +/* Supported values for the vm_event_write_ctrlreg index. */ +#define VM_EVENT_X86_CR0 0 +#define VM_EVENT_X86_CR3 1 +#define VM_EVENT_X86_CR4 2 +#define VM_EVENT_X86_XCR0 3 /* * Using a custom struct (not hvm_hw_cpu) so as to not fill - * the mem_event ring buffer too quickly. + * the vm_event ring buffer too quickly. */ struct vm_event_regs_x86 { uint64_t rax; @@ -156,14 +158,15 @@ struct vm_event_mem_access { uint32_t _pad; }; -struct vm_event_mov_to_cr { +struct vm_event_write_ctrlreg { + uint32_t index; + uint32_t _pad; uint64_t new_value; uint64_t old_value; }; struct vm_event_debug { uint64_t gfn; - uint32_t _pad; }; struct vm_event_mov_to_msr { @@ -196,7 +199,7 @@ typedef struct vm_event_st { struct vm_event_paging mem_paging; struct vm_event_sharing mem_sharing; struct vm_event_mem_access mem_access; - struct vm_event_mov_to_cr mov_to_cr; + struct vm_event_write_ctrlreg write_ctrlreg; struct vm_event_mov_to_msr mov_to_msr; struct vm_event_debug software_breakpoint; struct vm_event_debug singlestep; diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index a7563cd9f8..876d37035c 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -48,6 +48,34 @@ #include #include #include +#include + +TYPE_SAFE(unsigned long, mfn); +#define PRI_mfn "05lx" +#define INVALID_MFN (~0UL) + +#ifndef mfn_t +#define mfn_t /* Grep fodder: mfn_t, _mfn() and mfn_x() are defined above */ +#undef mfn_t +#endif + +TYPE_SAFE(unsigned long, gfn); +#define PRI_gfn "05lx" +#define INVALID_GFN (~0UL) + +#ifndef gfn_t +#define gfn_t /* Grep fodder: gfn_t, _gfn() and gfn_x() are defined above */ +#undef gfn_t +#endif + +TYPE_SAFE(unsigned long, pfn); +#define PRI_pfn "05lx" +#define INVALID_PFN (~0UL) + +#ifndef pfn_t +#define pfn_t /* Grep fodder: pfn_t, _pfn() and pfn_x() are defined above */ +#undef pfn_t +#endif struct domain; struct page_info; diff --git a/xen/include/xen/typesafe.h b/xen/include/xen/typesafe.h new file mode 100644 index 0000000000..7ecd3b4a8d --- /dev/null +++ b/xen/include/xen/typesafe.h @@ -0,0 +1,46 @@ +#ifndef __XEN_TYPESAFE_H__ +#define __XEN_TYPESAFE_H__ + +/* + * Compiler games to gain type safety between different logical integers. + * + * TYPE_SAFE($TYPE, $FOO) declares: + * * $FOO_t which encapsulates $TYPE + * * _$FOO() which boxes a $TYPE as a $FOO_t + * * $FOO_x() which unboxes a $FOO_t to $TYPE + * + * This makes a $FOO_t and a $BAR_t incompatible even when the box the same + * $TYPE. + * + * It does have some performance cost because the types now have a different + * storage attribute, so type safety is only enforced in a debug build. + * Non-debug builds degrade to a simple typedef and noops for the functions. + */ + +#ifndef NDEBUG + +#define TYPE_SAFE(_type, _name) \ + typedef struct { _type _name; } _name##_t; \ + static inline _name##_t _##_name(_type n) { return (_name##_t) { n }; } \ + static inline _type _name##_x(_name##_t n) { return n._name; } + +#else + +#define TYPE_SAFE(_type, _name) \ + typedef _type _name##_t; \ + static inline _name##_t _##_name(_type n) { return n; } \ + static inline _type _name##_x(_name##_t n) { return n; } + +#endif + +#endif /* __XEN_TYPESAFE_H__ */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/xen/vmap.h b/xen/include/xen/vmap.h index a13591ddc5..5671ac86a9 100644 --- a/xen/include/xen/vmap.h +++ b/xen/include/xen/vmap.h @@ -1,15 +1,15 @@ #if !defined(__XEN_VMAP_H__) && defined(VMAP_VIRT_START) #define __XEN_VMAP_H__ -#include +#include #include void *vm_alloc(unsigned int nr, unsigned int align); void vm_free(const void *); -void *__vmap(const unsigned long *mfn, unsigned int granularity, +void *__vmap(const mfn_t *mfn, unsigned int granularity, unsigned int nr, unsigned int align, unsigned int flags); -void *vmap(const unsigned long *mfn, unsigned int nr); +void *vmap(const mfn_t *mfn, unsigned int nr); void vunmap(const void *); void *vmalloc(size_t size); void *vzalloc(size_t size);