mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Merge branch 'staging' of ssh://xenbits.xen.org/home/xen/git/xen into staging
This commit is contained in:
commit
ecdae1cfaa
26 files changed
+189
-239
No files matched your search
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+5
-3
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
+15
-40
@@ -21,6 +21,8 @@
|
||||
|
||||
#include <xen/vm_event.h>
|
||||
#include <xen/paging.h>
|
||||
#include <asm/hvm/event.h>
|
||||
#include <asm/monitor.h>
|
||||
#include <public/vm_event.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include <asm/apic.h>
|
||||
#include <asm/hvm/nestedhvm.h>
|
||||
#include <asm/event.h>
|
||||
#include <asm/monitor.h>
|
||||
#include <public/arch-x86/cpuid.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
+3
-3
@@ -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;
|
||||
|
||||
@@ -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 )
|
||||
{
|
||||
|
||||
@@ -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)) )
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
+24
-41
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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__ */
|
||||
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -48,6 +48,34 @@
|
||||
#include <xen/types.h>
|
||||
#include <xen/list.h>
|
||||
#include <xen/spinlock.h>
|
||||
#include <xen/typesafe.h>
|
||||
|
||||
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;
|
||||
|
||||
@@ -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:
|
||||
*/
|
||||
@@ -1,15 +1,15 @@
|
||||
#if !defined(__XEN_VMAP_H__) && defined(VMAP_VIRT_START)
|
||||
#define __XEN_VMAP_H__
|
||||
|
||||
#include <xen/types.h>
|
||||
#include <xen/mm.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
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);
|
||||
|
||||