x86: allow control domain to limit machine addresses given to a particular guest

This allows domains which make buggy assumptions about the maximum
possible MFN to be worked around.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
This commit is contained in:
Keir Fraser committed 2008-07-11 12:51:26 +01:00
1 parent 04e28c8d4f
commit 41296317a3
11 files changed
+140 -2

No files matched your search

+29
View File
@@ -993,6 +993,35 @@ int xc_domain_subscribe_for_suspend(
return do_domctl(xc_handle, &domctl);
}
int xc_domain_set_machine_address_size(int xc,
uint32_t domid,
unsigned int width)
{
DECLARE_DOMCTL;
memset(&domctl, 0, sizeof(domctl));
domctl.domain = domid;
domctl.cmd = XEN_DOMCTL_set_machine_address_size;
domctl.u.address_size.size = width;
return do_domctl(xc, &domctl);
}
int xc_domain_get_machine_address_size(int xc, uint32_t domid)
{
DECLARE_DOMCTL;
int rc;
memset(&domctl, 0, sizeof(domctl));
domctl.domain = domid;
domctl.cmd = XEN_DOMCTL_get_machine_address_size;
rc = do_domctl(xc, &domctl);
return rc == 0 ? domctl.u.address_size.size : rc;
}
/*
* Local variables:
* mode: C
+6
View File
@@ -1076,6 +1076,12 @@ int xc_domain_bind_pt_isa_irq(int xc_handle,
uint32_t domid,
uint8_t machine_irq);
int xc_domain_set_machine_address_size(int handle,
uint32_t domid,
unsigned int width);
int xc_domain_get_machine_address_size(int handle,
uint32_t domid);
/* Set the target domain */
int xc_domain_set_target(int xc_handle,
uint32_t domid,
+23
View File
@@ -843,6 +843,22 @@ static PyObject *pyxc_dom_set_cpuid(XcObject *self,
return pyxc_create_cpuid_dict(regs_transform);
}
static PyObject *pyxc_dom_set_machine_address_size(XcObject *self,
PyObject *args,
PyObject *kwds)
{
uint32_t dom, width;
if (!PyArg_ParseTuple(args, "ii", &dom, &width))
return NULL;
if (xc_domain_set_machine_address_size(self->xc_handle, dom, width) != 0)
return pyxc_error_to_exception();
Py_INCREF(zero);
return zero;
}
#endif /* __i386__ || __x86_64__ */
static PyObject *pyxc_hvm_build(XcObject *self,
@@ -1889,6 +1905,13 @@ static PyMethodDef pyxc_methods[] = {
"Set the default cpuid policy for a domain.\n"
" dom [int]: Identifier of domain.\n\n"
"Returns: [int] 0 on success; exception on error.\n" },
{ "domain_set_machine_address_size",
(PyCFunction)pyxc_dom_set_machine_address_size,
METH_VARARGS, "\n"
"Set maximum machine address size for this domain.\n"
" dom [int]: Identifier of domain.\n"
" width [int]: Maximum machine address width.\n" },
#endif
{ NULL, NULL, 0, NULL }
+1
View File
@@ -207,6 +207,7 @@ XENAPI_CFG_TYPES = {
'pci': str,
'cpuid' : dict,
'cpuid_check' : dict,
'machine_address_size': int,
}
# List of legacy configuration keys that have no equivalent in the
+5
View File
@@ -2223,6 +2223,11 @@ class XendDomainInfo:
shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024)
self.info['shadow_memory'] = shadow_cur
# machine address size
if self.info.has_key('machine_address_size'):
log.debug("_initDomain: setting maximum machine address size %d" % self.info['machine_address_size'])
xc.domain_set_machine_address_size(self.domid, self.info['machine_address_size'])
self._createChannels()
channel_details = self.image.createImage()
+8 -1
View File
@@ -563,6 +563,10 @@ gopts.var('cpuid_check', val="IN[,SIN]:eax=EAX,ebx=EBX,exc=ECX,edx=EDX",
fn=append_value, default=[],
use="""Cpuid check description.""")
gopts.var('machine_address_size', val='BITS',
fn=set_int, default=None,
use="""Maximum machine address size""")
def err(msg):
"""Print an error to stderr and exit.
"""
@@ -611,6 +615,9 @@ def configure_image(vals):
if vals.vhpt != 0:
config_image.append(['vhpt', vals.vhpt])
if vals.machine_address_size:
config_image.append(['machine_address_size', vals.machine_address_size])
return config_image
def configure_disks(config_devs, vals):
@@ -863,7 +870,7 @@ def make_config(vals):
'restart', 'on_poweroff',
'on_reboot', 'on_crash', 'vcpus', 'vcpu_avail', 'features',
'on_xend_start', 'on_xend_stop', 'target', 'cpuid',
'cpuid_check'])
'cpuid_check', 'machine_address_size'])
if vals.uuid is not None:
config.append(['uuid', vals.uuid])
+51
View File
@@ -490,6 +490,57 @@ long arch_do_domctl(
}
break;
case XEN_DOMCTL_set_machine_address_size:
{
struct domain *d;
ret = -ESRCH;
if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
break;
ret = xsm_machine_address_size(d, domctl->cmd);
if ( ret )
rcu_unlock_domain(d);
ret = -EBUSY;
if ( d->tot_pages > 0 )
goto set_machine_address_size_out;
d->arch.physaddr_bitsize = domctl->u.address_size.size;
ret = 0;
set_machine_address_size_out:
rcu_unlock_domain(d);
}
break;
case XEN_DOMCTL_get_machine_address_size:
{
struct domain *d;
ret = -ESRCH;
if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
break;
ret = xsm_machine_address_size(d, domctl->cmd);
if ( ret )
{
rcu_unlock_domain(d);
break;
}
domctl->u.address_size.size = d->arch.physaddr_bitsize;
ret = 0;
rcu_unlock_domain(d);
if ( copy_to_guest(u_domctl, domctl, 1) )
ret = -EFAULT;
}
break;
case XEN_DOMCTL_sendtrigger:
{
struct domain *d;
+2 -1
View File
@@ -475,7 +475,8 @@ int check_descriptor(const struct domain *dom, struct desc_struct *d)
void domain_set_alloc_bitsize(struct domain *d)
{
if ( !is_pv_32on64_domain(d) ||
(MACH2PHYS_COMPAT_NR_ENTRIES(d) >= max_page) )
(MACH2PHYS_COMPAT_NR_ENTRIES(d) >= max_page) ||
d->arch.physaddr_bitsize > 0 )
return;
d->arch.physaddr_bitsize =
/* 2^n entries can be contained in guest's p2m mapping space */
+8
View File
@@ -607,6 +607,14 @@ struct xen_domctl_subscribe {
typedef struct xen_domctl_subscribe xen_domctl_subscribe_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_subscribe_t);
/*
* Define the maximum machine address size which should be allocated
* to a guest.
*/
#define XEN_DOMCTL_set_machine_address_size 51
#define XEN_DOMCTL_get_machine_address_size 52
struct xen_domctl {
uint32_t cmd;
uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */
+6
View File
@@ -119,6 +119,7 @@ struct xsm_operations {
int (*hypercall_init) (struct domain *d);
int (*hvmcontext) (struct domain *d, uint32_t op);
int (*address_size) (struct domain *d, uint32_t op);
int (*machine_address_size) (struct domain *d, uint32_t op);
int (*hvm_param) (struct domain *d, unsigned long op);
int (*hvm_set_pci_intx_level) (struct domain *d);
int (*hvm_set_isa_irq_level) (struct domain *d);
@@ -448,6 +449,11 @@ static inline int xsm_address_size (struct domain *d, uint32_t cmd)
return xsm_call(address_size(d, cmd));
}
static inline int xsm_machine_address_size (struct domain *d, uint32_t cmd)
{
return xsm_call(machine_address_size(d, cmd));
}
static inline int xsm_hvm_param (struct domain *d, unsigned long op)
{
return xsm_call(hvm_param(d, op));
+1
View File
@@ -467,6 +467,7 @@ void xsm_fixup_ops (struct xsm_operations *ops)
set_to_dummy_if_null(ops, hypercall_init);
set_to_dummy_if_null(ops, hvmcontext);
set_to_dummy_if_null(ops, address_size);
set_to_dummy_if_null(ops, machine_address_size);
set_to_dummy_if_null(ops, hvm_param);
set_to_dummy_if_null(ops, hvm_set_pci_intx_level);
set_to_dummy_if_null(ops, hvm_set_isa_irq_level);
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.