mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
[SHADOW] Clean up the DOM0_SHADOW_OP interface.
Also bump the dom0 interface version for tools (but not for dom0 kernel!). Signed-off-by: Keir Fraser <keir@xensource.com>
This commit is contained in:
1 parent
23e735cadd
commit
07f2bdb30d
8 files changed
+95
-67
No files matched your search
@@ -442,13 +442,12 @@ static int xc_hvm_build_internal(int xc_handle,
|
||||
}
|
||||
|
||||
/* HVM domains must be put into shadow2 mode at the start of day */
|
||||
if ( xc_shadow_control(xc_handle, domid, DOM0_SHADOW2_CONTROL_OP_ENABLE,
|
||||
if ( xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_ENABLE,
|
||||
NULL, 0, NULL,
|
||||
DOM0_SHADOW2_CONTROL_FLAG_ENABLE
|
||||
| DOM0_SHADOW2_CONTROL_FLAG_REFCOUNT
|
||||
| DOM0_SHADOW2_CONTROL_FLAG_TRANSLATE
|
||||
| DOM0_SHADOW2_CONTROL_FLAG_EXTERNAL,
|
||||
NULL) )
|
||||
DOM0_SHADOW_ENABLE_REFCOUNT |
|
||||
DOM0_SHADOW_ENABLE_TRANSLATE |
|
||||
DOM0_SHADOW_ENABLE_EXTERNAL,
|
||||
NULL) )
|
||||
{
|
||||
PERROR("Could not enable shadow paging for domain.\n");
|
||||
goto error_out;
|
||||
|
||||
@@ -346,11 +346,9 @@ static int analysis_phase(int xc_handle, uint32_t domid, int max_pfn,
|
||||
xc_shadow_control(xc_handle, domid, DOM0_SHADOW_CONTROL_OP_PEEK,
|
||||
NULL, 0, NULL, 0, &stats);
|
||||
|
||||
DPRINTF("now= %lld faults= %" PRId32 " dirty= %" PRId32
|
||||
" dirty_net= %" PRId32 " dirty_block= %" PRId32"\n",
|
||||
DPRINTF("now= %lld faults= %"PRId32" dirty= %"PRId32"\n",
|
||||
((now-start)+500)/1000,
|
||||
stats.fault_count, stats.dirty_count,
|
||||
stats.dirty_net_count, stats.dirty_block_count);
|
||||
stats.fault_count, stats.dirty_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -709,11 +709,11 @@ static PyObject *pyxc_shadow_mem_control(PyObject *self,
|
||||
return NULL;
|
||||
|
||||
if ( mbarg < 0 )
|
||||
op = DOM0_SHADOW2_CONTROL_OP_GET_ALLOCATION;
|
||||
op = DOM0_SHADOW_CONTROL_OP_GET_ALLOCATION;
|
||||
else
|
||||
{
|
||||
mb = mbarg;
|
||||
op = DOM0_SHADOW2_CONTROL_OP_SET_ALLOCATION;
|
||||
op = DOM0_SHADOW_CONTROL_OP_SET_ALLOCATION;
|
||||
}
|
||||
if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, &mb, 0, NULL) < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
@@ -653,11 +653,6 @@ int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc)
|
||||
}
|
||||
break;
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_FLUSH:
|
||||
atomic64_set(&d->arch.shadow_fault_count, 0);
|
||||
atomic64_set(&d->arch.shadow_dirty_count, 0);
|
||||
break;
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_CLEAN:
|
||||
{
|
||||
int nbr_longs;
|
||||
|
||||
@@ -2481,14 +2481,15 @@ static int shadow2_enable(struct domain *d, u32 mode)
|
||||
unsigned int old_pages;
|
||||
int rv = 0;
|
||||
|
||||
mode |= SHM2_enable;
|
||||
|
||||
domain_pause(d);
|
||||
shadow2_lock(d);
|
||||
|
||||
/* Sanity check the arguments */
|
||||
if ( d == current->domain
|
||||
|| shadow2_mode_enabled(d)
|
||||
|| !(mode & SHM2_enable)
|
||||
|| ((mode & SHM2_external) && !(mode & SHM2_translate)) )
|
||||
if ( (d == current->domain) ||
|
||||
shadow2_mode_enabled(d) ||
|
||||
((mode & SHM2_external) && !(mode & SHM2_translate)) )
|
||||
{
|
||||
rv = -EINVAL;
|
||||
goto out;
|
||||
@@ -2957,11 +2958,7 @@ static int shadow2_log_dirty_op(struct domain *d, dom0_shadow_control_t *sc)
|
||||
domain_pause(d);
|
||||
shadow2_lock(d);
|
||||
|
||||
if ( sc->op == DOM0_SHADOW_CONTROL_OP_CLEAN
|
||||
|| sc->op == DOM0_SHADOW_CONTROL_OP_FLUSH )
|
||||
clean = 1;
|
||||
else
|
||||
ASSERT(sc->op == DOM0_SHADOW_CONTROL_OP_PEEK);
|
||||
clean = (sc->op == DOM0_SHADOW_CONTROL_OP_CLEAN);
|
||||
|
||||
SHADOW2_DEBUG(LOGDIRTY, "log-dirty %s: dom %u faults=%u dirty=%u\n",
|
||||
(clean) ? "clean" : "peek",
|
||||
@@ -3111,25 +3108,27 @@ int shadow2_control_op(struct domain *d,
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_ENABLE_TEST:
|
||||
return shadow2_test_enable(d);
|
||||
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY:
|
||||
return shadow2_log_dirty_enable(d);
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_FLUSH:
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE:
|
||||
return shadow2_enable(d, SHM2_refcounts|SHM2_translate);
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_CLEAN:
|
||||
case DOM0_SHADOW_CONTROL_OP_PEEK:
|
||||
return shadow2_log_dirty_op(d, sc);
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_ENABLE:
|
||||
if ( sc->mode & DOM0_SHADOW_ENABLE_LOG_DIRTY )
|
||||
return shadow2_log_dirty_enable(d);
|
||||
return shadow2_enable(d, sc->mode << SHM2_shift);
|
||||
|
||||
|
||||
case DOM0_SHADOW2_CONTROL_OP_ENABLE:
|
||||
return shadow2_enable(d, sc->mode << SHM2_shift);
|
||||
|
||||
case DOM0_SHADOW2_CONTROL_OP_GET_ALLOCATION:
|
||||
case DOM0_SHADOW_CONTROL_OP_GET_ALLOCATION:
|
||||
sc->mb = shadow2_get_allocation(d);
|
||||
return 0;
|
||||
|
||||
case DOM0_SHADOW2_CONTROL_OP_SET_ALLOCATION:
|
||||
|
||||
case DOM0_SHADOW_CONTROL_OP_SET_ALLOCATION:
|
||||
rc = shadow2_set_allocation(d, sc->mb, &preempted);
|
||||
if ( preempted )
|
||||
/* Not finished. Set up to re-run the call. */
|
||||
@@ -3139,8 +3138,7 @@ int shadow2_control_op(struct domain *d,
|
||||
/* Finished. Return the new allocation */
|
||||
sc->mb = shadow2_get_allocation(d);
|
||||
return rc;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
SHADOW2_ERROR("Bad shadow op %u\n", sc->op);
|
||||
return -EINVAL;
|
||||
|
||||
@@ -141,7 +141,8 @@ long do_dom0_op(XEN_GUEST_HANDLE(dom0_op_t) u_dom0_op)
|
||||
if ( copy_from_guest(op, u_dom0_op, 1) )
|
||||
return -EFAULT;
|
||||
|
||||
if ( op->interface_version != DOM0_INTERFACE_VERSION )
|
||||
if ( (op->interface_version != DOM0_TOOLS_INTERFACE_VERSION) &&
|
||||
(op->interface_version != DOM0_KERNEL_INTERFACE_VERSION) )
|
||||
return -EACCES;
|
||||
|
||||
if ( acm_pre_dom0_op(op, &ssid) )
|
||||
|
||||
@@ -32,16 +32,16 @@
|
||||
|
||||
#define SHM2_shift 10
|
||||
/* We're in one of the shadow modes */
|
||||
#define SHM2_enable (DOM0_SHADOW2_CONTROL_FLAG_ENABLE << SHM2_shift)
|
||||
#define SHM2_enable (1U << SHM2_shift)
|
||||
/* Refcounts based on shadow tables instead of guest tables */
|
||||
#define SHM2_refcounts (DOM0_SHADOW2_CONTROL_FLAG_REFCOUNT << SHM2_shift)
|
||||
#define SHM2_refcounts (DOM0_SHADOW_ENABLE_REFCOUNT << SHM2_shift)
|
||||
/* Enable log dirty mode */
|
||||
#define SHM2_log_dirty (DOM0_SHADOW2_CONTROL_FLAG_LOG_DIRTY << SHM2_shift)
|
||||
#define SHM2_log_dirty (DOM0_SHADOW_ENABLE_LOG_DIRTY << SHM2_shift)
|
||||
/* Xen does p2m translation, not guest */
|
||||
#define SHM2_translate (DOM0_SHADOW2_CONTROL_FLAG_TRANSLATE << SHM2_shift)
|
||||
#define SHM2_translate (DOM0_SHADOW_ENABLE_TRANSLATE << SHM2_shift)
|
||||
/* Xen does not steal address space from the domain for its own booking;
|
||||
* requires VT or similar mechanisms */
|
||||
#define SHM2_external (DOM0_SHADOW2_CONTROL_FLAG_EXTERNAL << SHM2_shift)
|
||||
#define SHM2_external (DOM0_SHADOW_ENABLE_EXTERNAL << SHM2_shift)
|
||||
|
||||
#define shadow2_mode_enabled(_d) ((_d)->arch.shadow2.mode)
|
||||
#define shadow2_mode_refcounts(_d) ((_d)->arch.shadow2.mode & SHM2_refcounts)
|
||||
|
||||
@@ -18,8 +18,19 @@
|
||||
* Make sure you increment the interface version whenever you modify this file!
|
||||
* This makes sure that old versions of dom0 tools will stop working in a
|
||||
* well-defined way (rather than crashing the machine, for instance).
|
||||
*
|
||||
* Separate kernel from tools as the kernel uses a small subset of the dom0
|
||||
* operations and so it is unnecessary to break backward compatibility so
|
||||
* often.
|
||||
*/
|
||||
#define DOM0_INTERFACE_VERSION 0x03000001
|
||||
#define DOM0_TOOLS_INTERFACE_VERSION 0x13000001
|
||||
#define DOM0_KERNEL_INTERFACE_VERSION 0x03000001
|
||||
|
||||
#ifdef __XEN_TOOLS__
|
||||
#define DOM0_INTERFACE_VERSION DOM0_TOOLS_INTERFACE_VERSION
|
||||
#else
|
||||
#define DOM0_INTERFACE_VERSION DOM0_KERNEL_INTERFACE_VERSION
|
||||
#endif
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
@@ -253,32 +264,54 @@ DEFINE_XEN_GUEST_HANDLE(dom0_sched_id_t);
|
||||
*/
|
||||
#define DOM0_SHADOW_CONTROL 25
|
||||
|
||||
/* Disable shadow mode. */
|
||||
#define DOM0_SHADOW_CONTROL_OP_OFF 0
|
||||
#define DOM0_SHADOW_CONTROL_OP_ENABLE_TEST 1
|
||||
#define DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY 2
|
||||
#define DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE 3
|
||||
|
||||
#define DOM0_SHADOW_CONTROL_OP_FLUSH 10 /* table ops */
|
||||
/* Enable shadow mode (mode contains ORed DOM0_SHADOW_ENABLE_* flags). */
|
||||
#define DOM0_SHADOW_CONTROL_OP_ENABLE 32
|
||||
|
||||
/* Log-dirty bitmap operations. */
|
||||
/* Return the bitmap and clean internal copy for next round. */
|
||||
#define DOM0_SHADOW_CONTROL_OP_CLEAN 11
|
||||
/* Return the bitmap but do not modify internal copy. */
|
||||
#define DOM0_SHADOW_CONTROL_OP_PEEK 12
|
||||
|
||||
/* Shadow2 operations */
|
||||
#define DOM0_SHADOW2_CONTROL_OP_GET_ALLOCATION 30
|
||||
#define DOM0_SHADOW2_CONTROL_OP_SET_ALLOCATION 31
|
||||
#define DOM0_SHADOW2_CONTROL_OP_ENABLE 32
|
||||
/* Memory allocation accessors. */
|
||||
#define DOM0_SHADOW_CONTROL_OP_GET_ALLOCATION 30
|
||||
#define DOM0_SHADOW_CONTROL_OP_SET_ALLOCATION 31
|
||||
|
||||
/* Mode flags for Shadow2 enable op */
|
||||
#define DOM0_SHADOW2_CONTROL_FLAG_ENABLE (1 << 0)
|
||||
#define DOM0_SHADOW2_CONTROL_FLAG_REFCOUNT (1 << 1)
|
||||
#define DOM0_SHADOW2_CONTROL_FLAG_LOG_DIRTY (1 << 2)
|
||||
#define DOM0_SHADOW2_CONTROL_FLAG_TRANSLATE (1 << 3)
|
||||
#define DOM0_SHADOW2_CONTROL_FLAG_EXTERNAL (1 << 4)
|
||||
/* Legacy enable operations. */
|
||||
/* Equiv. to ENABLE with no mode flags. */
|
||||
#define DOM0_SHADOW_CONTROL_OP_ENABLE_TEST 1
|
||||
/* Equiv. to ENABLE with mode flag ENABLE_LOG_DIRTY. */
|
||||
#define DOM0_SHADOW_CONTROL_OP_ENABLE_LOGDIRTY 2
|
||||
/* Equiv. to ENABLE with mode flags ENABLE_REFCOUNT and ENABLE_TRANSLATE. */
|
||||
#define DOM0_SHADOW_CONTROL_OP_ENABLE_TRANSLATE 3
|
||||
|
||||
/* Mode flags for DOM0_SHADOW_CONTROL_OP_ENABLE. */
|
||||
/*
|
||||
* Shadow pagetables are refcounted: guest does not use explicit mmu
|
||||
* operations nor write-protect its pagetables.
|
||||
*/
|
||||
#define DOM0_SHADOW_ENABLE_REFCOUNT (1 << 1)
|
||||
/*
|
||||
* Log pages in a bitmap as they are dirtied.
|
||||
* Used for live relocation to determine which pages must be re-sent.
|
||||
*/
|
||||
#define DOM0_SHADOW_ENABLE_LOG_DIRTY (1 << 2)
|
||||
/*
|
||||
* Automatically translate GPFNs into MFNs.
|
||||
*/
|
||||
#define DOM0_SHADOW_ENABLE_TRANSLATE (1 << 3)
|
||||
/*
|
||||
* Xen does not steal virtual address space from the guest.
|
||||
* Requires HVM support.
|
||||
*/
|
||||
#define DOM0_SHADOW_ENABLE_EXTERNAL (1 << 4)
|
||||
|
||||
struct dom0_shadow_control_stats {
|
||||
uint32_t fault_count;
|
||||
uint32_t dirty_count;
|
||||
uint32_t dirty_net_count;
|
||||
uint32_t dirty_block_count;
|
||||
};
|
||||
typedef struct dom0_shadow_control_stats dom0_shadow_control_stats_t;
|
||||
DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_stats_t);
|
||||
@@ -286,13 +319,17 @@ DEFINE_XEN_GUEST_HANDLE(dom0_shadow_control_stats_t);
|
||||
struct dom0_shadow_control {
|
||||
/* IN variables. */
|
||||
domid_t domain;
|
||||
uint32_t op;
|
||||
uint32_t op; /* DOM0_SHADOW_CONTROL_OP_* */
|
||||
|
||||
/* OP_ENABLE */
|
||||
uint32_t mode; /* DOM0_SHADOW_ENABLE_* */
|
||||
|
||||
/* OP_GET_ALLOCATION / OP_SET_ALLOCATION */
|
||||
uint32_t mb; /* Shadow memory allocation in MB */
|
||||
|
||||
/* OP_PEEK / OP_CLEAN */
|
||||
XEN_GUEST_HANDLE(ulong) dirty_bitmap;
|
||||
/* IN/OUT variables. */
|
||||
uint64_t pages; /* size of buffer, updated with actual size */
|
||||
uint32_t mb; /* Shadow2 memory allocation in MB */
|
||||
uint32_t mode; /* Shadow2 mode to enable */
|
||||
/* OUT variables. */
|
||||
uint64_t pages; /* Size of buffer. Updated with actual size. */
|
||||
struct dom0_shadow_control_stats stats;
|
||||
};
|
||||
typedef struct dom0_shadow_control dom0_shadow_control_t;
|
||||
|
||||