Merge with xen-ia64-unstable.hg

This commit is contained in:
Keir Fraser committed 2007-04-13 16:07:48 +01:00
commit 3a8a387d6e
29 files changed
+464 -232

No files matched your search

+1 -1
View File
@@ -22,7 +22,7 @@
^\.pc
^TAGS$
^tags$
^build.*$
^build-.*$
^dist/.*$
^docs/.*\.aux$
^docs/.*\.dvi$
+4
View File
@@ -199,3 +199,7 @@ Xend (the Xen daemon) has the following runtime dependencies:
* For optional PAM support, PyPAM:
URL: http://www.pangalactic.org/PyPAM/
Debian: python-pam
* For optional XenAPI support in XM, PyXML:
URL: http://pyxml.sourceforge.net
YUM: PyXML
@@ -622,14 +622,14 @@ static int network_open(struct net_device *dev)
memset(&np->stats, 0, sizeof(np->stats));
spin_lock(&np->rx_lock);
spin_lock_bh(&np->rx_lock);
if (netfront_carrier_ok(np)) {
network_alloc_rx_buffers(dev);
np->rx.sring->rsp_event = np->rx.rsp_cons + 1;
if (RING_HAS_UNCONSUMED_RESPONSES(&np->rx))
netif_rx_schedule(dev);
}
spin_unlock(&np->rx_lock);
spin_unlock_bh(&np->rx_lock);
network_maybe_wake_tx(dev);
@@ -1307,7 +1307,7 @@ static int netif_poll(struct net_device *dev, int *pbudget)
int pages_flipped = 0;
int err;
spin_lock(&np->rx_lock);
spin_lock(&np->rx_lock); /* no need for spin_lock_bh() in ->poll() */
if (unlikely(!netfront_carrier_ok(np))) {
spin_unlock(&np->rx_lock);
@@ -1520,7 +1520,7 @@ static void netif_release_rx_bufs(struct netfront_info *np)
skb_queue_head_init(&free_list);
spin_lock(&np->rx_lock);
spin_lock_bh(&np->rx_lock);
for (id = 0; id < NET_RX_RING_SIZE; id++) {
if ((ref = np->grant_rx_ref[id]) == GRANT_INVALID_REF) {
@@ -1588,7 +1588,7 @@ static void netif_release_rx_bufs(struct netfront_info *np)
while ((skb = __skb_dequeue(&free_list)) != NULL)
dev_kfree_skb(skb);
spin_unlock(&np->rx_lock);
spin_unlock_bh(&np->rx_lock);
}
static int network_close(struct net_device *dev)
@@ -1708,8 +1708,8 @@ static int network_connect(struct net_device *dev)
IPRINTK("device %s has %sing receive path.\n",
dev->name, np->copying_receiver ? "copy" : "flipp");
spin_lock_bh(&np->rx_lock);
spin_lock_irq(&np->tx_lock);
spin_lock(&np->rx_lock);
/*
* Recovery procedure:
@@ -1761,8 +1761,8 @@ static int network_connect(struct net_device *dev)
network_tx_buf_gc(dev);
network_alloc_rx_buffers(dev);
spin_unlock(&np->rx_lock);
spin_unlock_irq(&np->tx_lock);
spin_unlock_bh(&np->rx_lock);
return 0;
}
@@ -1818,7 +1818,7 @@ static ssize_t store_rxbuf_min(struct class_device *cd,
if (target > RX_MAX_TARGET)
target = RX_MAX_TARGET;
spin_lock(&np->rx_lock);
spin_lock_bh(&np->rx_lock);
if (target > np->rx_max_target)
np->rx_max_target = target;
np->rx_min_target = target;
@@ -1827,7 +1827,7 @@ static ssize_t store_rxbuf_min(struct class_device *cd,
network_alloc_rx_buffers(netdev);
spin_unlock(&np->rx_lock);
spin_unlock_bh(&np->rx_lock);
return len;
}
@@ -1861,7 +1861,7 @@ static ssize_t store_rxbuf_max(struct class_device *cd,
if (target > RX_MAX_TARGET)
target = RX_MAX_TARGET;
spin_lock(&np->rx_lock);
spin_lock_bh(&np->rx_lock);
if (target < np->rx_min_target)
np->rx_min_target = target;
np->rx_max_target = target;
@@ -1870,7 +1870,7 @@ static ssize_t store_rxbuf_max(struct class_device *cd,
network_alloc_rx_buffers(netdev);
spin_unlock(&np->rx_lock);
spin_unlock_bh(&np->rx_lock);
return len;
}
@@ -2033,11 +2033,11 @@ inetdev_notify(struct notifier_block *this, unsigned long event, void *ptr)
static void netif_disconnect_backend(struct netfront_info *info)
{
/* Stop old i/f to prevent errors whilst we rebuild the state. */
spin_lock_bh(&info->rx_lock);
spin_lock_irq(&info->tx_lock);
spin_lock(&info->rx_lock);
netfront_carrier_off(info);
spin_unlock(&info->rx_lock);
spin_unlock_irq(&info->tx_lock);
spin_unlock_bh(&info->rx_lock);
if (info->irq)
unbind_from_irqhandler(info->irq, info->netdev);
+14 -25
View File
@@ -688,33 +688,22 @@ int xc_domain_restore(int xc_handle, int io_fd, uint32_t dom,
ERROR("error zeroing magic pages");
goto out;
}
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, magic_pfns[0]);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, magic_pfns[1]);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, magic_pfns[2]);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_EVTCHN, store_evtchn);
*store_mfn = magic_pfns[2];
/* Read vcpu contexts */
for ( i = 0; i <= max_vcpu_id; i++ )
if ( (rc = xc_set_hvm_param(xc_handle, dom,
HVM_PARAM_IOREQ_PFN, magic_pfns[0]))
|| (rc = xc_set_hvm_param(xc_handle, dom,
HVM_PARAM_BUFIOREQ_PFN, magic_pfns[1]))
|| (rc = xc_set_hvm_param(xc_handle, dom,
HVM_PARAM_STORE_PFN, magic_pfns[2]))
|| (rc = xc_set_hvm_param(xc_handle, dom,
HVM_PARAM_PAE_ENABLED, pae))
|| (rc = xc_set_hvm_param(xc_handle, dom,
HVM_PARAM_STORE_EVTCHN, store_evtchn)) )
{
if ( !(vcpumap & (1ULL << i)) )
continue;
if ( !read_exact(io_fd, &(ctxt), sizeof(ctxt)) )
{
ERROR("error read vcpu context.\n");
goto out;
}
if ( (rc = xc_vcpu_setcontext(xc_handle, dom, i, &ctxt)) )
{
ERROR("Could not set vcpu context, rc=%d", rc);
goto out;
}
rc = 1;
ERROR("error setting HVM params: %i", rc);
goto out;
}
*store_mfn = magic_pfns[2];
/* Read HVM context */
if ( !read_exact(io_fd, &rec_len, sizeof(uint32_t)) )
+21 -43
View File
@@ -378,8 +378,7 @@ static int analysis_phase(int xc_handle, uint32_t domid, int p2m_size,
static int suspend_and_state(int (*suspend)(int), int xc_handle, int io_fd,
int dom, xc_dominfo_t *info,
vcpu_guest_context_t *ctxt)
int dom, xc_dominfo_t *info)
{
int i = 0;
@@ -397,10 +396,6 @@ static int suspend_and_state(int (*suspend)(int), int xc_handle, int io_fd,
return -1;
}
if ( xc_vcpu_getcontext(xc_handle, dom, 0, ctxt) )
ERROR("Could not get vcpu context");
if ( info->dying )
{
ERROR("domain is dying");
@@ -663,10 +658,11 @@ static xen_pfn_t *xc_map_m2p(int xc_handle,
static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
int io_fd,
uint32_t dom,
vcpu_guest_context_t *ctxt,
unsigned long p2m_size,
shared_info_t *live_shinfo)
{
vcpu_guest_context_t ctxt;
/* Double and single indirect references to the live P2M table */
xen_pfn_t *live_p2m_frame_list_list = NULL;
xen_pfn_t *live_p2m_frame_list = NULL;
@@ -730,13 +726,19 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
}
}
if ( xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt) )
{
ERROR("Could not get vcpu context");
goto out;
}
/*
* Write an extended-info structure to inform the restore code that
* a PAE guest understands extended CR3 (PDPTs above 4GB). Turns off
* slow paths in the restore code.
*/
if ( (pt_levels == 3) &&
(ctxt->vm_assist & (1UL << VMASST_TYPE_pae_extended_cr3)) )
(ctxt.vm_assist & (1UL << VMASST_TYPE_pae_extended_cr3)) )
{
unsigned long signature = ~0UL;
uint32_t tot_sz = sizeof(struct vcpu_guest_context) + 8;
@@ -746,7 +748,7 @@ static xen_pfn_t *map_and_save_p2m_table(int xc_handle,
!write_exact(io_fd, &tot_sz, sizeof(tot_sz)) ||
!write_exact(io_fd, &chunk_sig, 4) ||
!write_exact(io_fd, &chunk_sz, sizeof(chunk_sz)) ||
!write_exact(io_fd, ctxt, sizeof(*ctxt)) )
!write_exact(io_fd, &ctxt, sizeof(ctxt)) )
{
ERROR("write: extended info");
goto out;
@@ -853,11 +855,6 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
return 1;
}
if ( xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt) )
{
ERROR("Could not get vcpu context");
goto out;
}
shared_info_frame = info.shared_info_frame;
/* Map the shared info frame */
@@ -900,7 +897,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
else
{
/* This is a non-live suspend. Suspend the domain .*/
if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info, &ctxt) )
if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info) )
{
ERROR("Domain appears not to have suspended");
goto out;
@@ -999,7 +996,7 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
/* Map the P2M table, and write the list of P2M frames */
live_p2m = map_and_save_p2m_table(xc_handle, io_fd, dom,
&ctxt, p2m_size, live_shinfo);
p2m_size, live_shinfo);
if ( live_p2m == NULL )
{
ERROR("Failed to map/save the p2m frame list");
@@ -1304,17 +1301,13 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
DPRINTF("Start last iteration\n");
last_iter = 1;
if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info,
&ctxt) )
if ( suspend_and_state(suspend, xc_handle, io_fd, dom, &info) )
{
ERROR("Domain appears not to have suspended");
goto out;
}
DPRINTF("SUSPEND shinfo %08lx eip %08lx edx %08lx\n",
info.shared_info_frame,
(unsigned long)ctxt.user_regs.eip,
(unsigned long)ctxt.user_regs.edx);
DPRINTF("SUSPEND shinfo %08lx\n", info.shared_info_frame);
}
if ( xc_shadow_control(xc_handle, dom,
@@ -1410,27 +1403,6 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
goto out;
}
/* Save vcpu contexts */
for ( i = 0; i <= info.max_vcpu_id; i++ )
{
if ( !(vcpumap & (1ULL << i)) )
continue;
if ( xc_vcpu_getcontext(xc_handle, dom, i, &ctxt) )
{
ERROR("HVM:Could not get vcpu context");
goto out;
}
DPRINTF("write vcpu %d context.\n", i);
if ( !write_exact(io_fd, &(ctxt), sizeof(ctxt)) )
{
ERROR("write vcpu context failed!\n");
goto out;
}
}
/* Get HVM context from Xen and save it too */
if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf,
hvm_buf_size)) == -1 )
@@ -1494,6 +1466,12 @@ int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
}
}
if ( xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt) )
{
ERROR("Could not get vcpu context");
goto out;
}
/* Canonicalise the suspend-record frame number. */
if ( !translate_mfn_to_pfn(&ctxt.user_regs.edx) )
{
-12
View File
@@ -198,18 +198,6 @@ __attribute__((weak))
return -1;
}
__attribute__((weak)) int xc_get_hvm_param(
int handle, domid_t dom, int param, unsigned long *value)
{
return -ENOSYS;
}
__attribute__((weak)) int xc_set_hvm_param(
int handle, domid_t dom, int param, unsigned long value)
{
return -ENOSYS;
}
/*
* Local variables:
* mode: C
+11 -7
View File
@@ -61,13 +61,6 @@ def get_active_partition(file):
if struct.unpack("<c", buf[poff:poff+1]) == ('\x80',):
return buf[poff:poff+16]
# type=0xee: GUID partition table
# XXX assume the first partition is active
if struct.unpack("<c", buf[poff+4:poff+5]) == ('\xee',):
os.lseek(fd, 0x400, 0)
buf = os.read(fd, 512)
return buf[24:40] # XXX buf[32:40]
# if there's not a partition marked as active, fall back to
# the first partition
return buf[446:446+16]
@@ -97,8 +90,16 @@ def get_solaris_slice(file, offset):
raise RuntimeError, "No root slice found"
def get_fs_offset_gpt(file):
fd = os.open(file, os.O_RDONLY)
# assume the first partition is an EFI system partition.
os.lseek(fd, SECTOR_SIZE * 2, 0)
buf = os.read(fd, 512)
return struct.unpack("<Q", buf[32:40])[0] * SECTOR_SIZE
FDISK_PART_SOLARIS=0xbf
FDISK_PART_SOLARIS_OLD=0x82
FDISK_PART_GPT=0xee
def get_fs_offset(file):
if not is_disk_image(file):
@@ -115,6 +116,9 @@ def get_fs_offset(file):
if type == FDISK_PART_SOLARIS or type == FDISK_PART_SOLARIS_OLD:
offset += get_solaris_slice(file, offset)
if type == FDISK_PART_GPT:
offset = get_fs_offset_gpt(file)
return offset
class GrubLineEditor(curses.textpad.Textbox):
+16 -1
View File
@@ -96,7 +96,10 @@ def datetime(when = None):
@param when The time in question, given as seconds since the epoch, UTC.
May be None, in which case the current time is used.
"""
return xmlrpclib.DateTime(time.gmtime(when))
if when is None:
return xmlrpclib.DateTime(time.gmtime())
else:
return xmlrpclib.DateTime(time.gmtime(when))
# ---------------------------------------------------
@@ -1304,6 +1307,7 @@ class XendAPI(object):
('set_memory_dynamic_max_live', None),
('set_memory_dynamic_min_live', None),
('send_trigger', None),
('migrate', None),
('destroy', None)]
VM_funcs = [('create', 'VM'),
@@ -1823,6 +1827,17 @@ class XendAPI(object):
xendom.domain_send_trigger(xeninfo.getDomid(), trigger, vcpu)
return xen_api_success_void()
def VM_migrate(self, _, vm_ref, destination_url, live, other_config):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
resource = other_config.get("resource", 0)
port = other_config.get("port", 0)
xendom.domain_migrate(xeninfo.getDomid(), destination_url,
bool(live), resource, port)
return xen_api_success_void()
def VM_save(self, _, vm_ref, dest, checkpoint):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
+4 -2
View File
@@ -150,8 +150,10 @@ class XendNode:
# Get a mapping from interface to bridge
if_to_br = dict(reduce(lambda ls,(b,ifs):[(i,b) for i in ifs] + ls,
Brctl.get_state().items(), []))
if_to_br = dict([(i,b)
for (b,ifs) in Brctl.get_state().items()
for i in ifs])
# initialise PIFs
saved_pifs = self.state_store.load_state('pif')
if saved_pifs:
+14 -3
View File
@@ -23,7 +23,7 @@ import sys
from xen.xm.opts import *
from main import server
from main import server, serverType, get_single_vm, SERVER_XEN_API
gopts = Opts(use="""[options] DOM HOST
@@ -60,5 +60,16 @@ def main(argv):
dom = args[0]
dst = args[1]
server.xend.domain.migrate(dom, dst, opts.vals.live, opts.vals.resource,
opts.vals.port)
if serverType == SERVER_XEN_API:
vm_ref = get_single_vm(dom)
other_config = {
"port": opts.vals.port,
"resource": opts.vals.resource
}
server.xenapi.VM.migrate(vm_ref, dst, bool(opts.vals.live),
other_config)
else:
server.xend.domain.migrate(dom, dst, opts.vals.live,
opts.vals.resource,
opts.vals.port)
+19 -3
View File
@@ -48,7 +48,7 @@ def get_name_description(node):
def get_text_in_child_node(node, child):
tag_node = node.getElementsByTagName(child)[0]
return tag_node.nodeValue
return " ".join([child.nodeValue for child in tag_node.childNodes])
def get_child_node_attribute(node, child, attribute):
tag_node = node.getElementsByTagName(child)[0]
@@ -264,7 +264,23 @@ class xenapi_create:
"platform":
get_child_nodes_as_dict(vm, "platform", "key", "value"),
"other_config":
get_child_nodes_as_dict(vm, "other_config", "key", "value")
get_child_nodes_as_dict(vm, "other_config", "key", "value"),
"PV_bootloader":
"",
"PV_kernel":
"",
"PV_ramdisk":
"",
"PV_args":
"",
"PV_bootloader_args":
"",
"HVM_boot_policy":
"",
"HVM_boot_params":
{},
"PCI_bus":
""
}
if len(vm.getElementsByTagName("pv")) > 0:
@@ -494,7 +510,7 @@ class sxp2xml:
# Make version tag
version = document.createElement("version")
version.appendChild(document.createTextNode("1.0"))
version.appendChild(document.createTextNode("0"))
vm.appendChild(version)
# Make pv or hvm tag
+6
View File
@@ -21,6 +21,12 @@
#include <xen/config.h>
#include <xen/lib.h>
extern void __xchg_called_with_bad_pointer(void);
void __xchg_called_with_bad_pointer(void)
{
BUG();
}
extern void __cmpxchg_called_with_bad_pointer(void);
void __cmpxchg_called_with_bad_pointer(void)
{
+1 -1
View File
@@ -229,7 +229,7 @@ int construct_dom0(struct domain *d,
/* Load the dom0 kernel. */
elf.dest = (void *)dst;
elf_load_binary(&elf);
v->arch.ctxt.pc = dst - rma;
v->arch.ctxt.pc = dst - rma + (parms.virt_entry - parms.virt_kstart);
dst = ALIGN_UP(dst + parms.virt_kend, PAGE_SIZE);
/* Load the initrd. */
+3 -2
View File
@@ -264,7 +264,7 @@ static ofdn_t ofd_chosen_props(void *m, const char *cmdline)
ofdn_t n;
ofdn_t p;
static const char path[] = "/chosen";
char bootargs[256];
char bootargs[256] = { 0, };
int bsz;
int sz;
int rm;
@@ -276,7 +276,8 @@ static ofdn_t ofd_chosen_props(void *m, const char *cmdline)
&path[1], sizeof (path) - 1);
}
strlcpy(bootargs, cmdline, sizeof(bootargs));
if (cmdline)
strlcpy(bootargs, cmdline, sizeof(bootargs));
bsz = strlen(bootargs) + 1;
rm = sizeof (bootargs) - bsz;
+3 -1
View File
@@ -1540,8 +1540,10 @@ void domain_relinquish_resources(struct domain *d)
relinquish_memory(d, &d->xenpage_list, PGT_l2_page_table);
relinquish_memory(d, &d->page_list, PGT_l2_page_table);
/* Free page used by xen oprofile buffer */
/* Free page used by xen oprofile buffer. */
free_xenoprof_pages(d);
hvm_domain_relinquish_resources(d);
}
void arch_dump_domain_info(struct domain *d)
+180 -42
View File
@@ -101,7 +101,7 @@ void hvm_set_guest_time(struct vcpu *v, u64 gtime)
u64 hvm_get_guest_time(struct vcpu *v)
{
u64 host_tsc;
u64 host_tsc;
rdtscll(host_tsc);
return host_tsc + v->arch.hvm_vcpu.cache_tsc_offset;
@@ -125,7 +125,7 @@ void hvm_do_resume(struct vcpu *v)
pt_thaw_time(v);
/* NB. Optimised for common case (p->state == STATE_IOREQ_NONE). */
p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
p = &get_ioreq(v)->vp_ioreq;
while ( p->state != STATE_IOREQ_NONE )
{
switch ( p->state )
@@ -146,6 +146,73 @@ void hvm_do_resume(struct vcpu *v)
}
}
static void hvm_init_ioreq_page(
struct domain *d, struct hvm_ioreq_page *iorp)
{
memset(iorp, 0, sizeof(*iorp));
spin_lock_init(&iorp->lock);
domain_pause(d);
}
static void hvm_destroy_ioreq_page(
struct domain *d, struct hvm_ioreq_page *iorp)
{
spin_lock(&iorp->lock);
ASSERT(d->is_dying);
if ( iorp->va != NULL )
{
unmap_domain_page_global(iorp->va);
put_page_and_type(iorp->page);
iorp->va = NULL;
}
spin_unlock(&iorp->lock);
}
static int hvm_set_ioreq_page(
struct domain *d, struct hvm_ioreq_page *iorp, unsigned long gmfn)
{
struct page_info *page;
unsigned long mfn;
void *va;
mfn = gmfn_to_mfn(d, gmfn);
if ( !mfn_valid(mfn) )
return -EINVAL;
page = mfn_to_page(mfn);
if ( !get_page_and_type(page, d, PGT_writable_page) )
return -EINVAL;
va = map_domain_page_global(mfn);
if ( va == NULL )
{
put_page_and_type(page);
return -ENOMEM;
}
spin_lock(&iorp->lock);
if ( (iorp->va != NULL) || d->is_dying )
{
spin_unlock(&iorp->lock);
unmap_domain_page_global(va);
put_page_and_type(mfn_to_page(mfn));
return -EINVAL;
}
iorp->va = va;
iorp->page = page;
spin_unlock(&iorp->lock);
domain_unpause(d);
return 0;
}
int hvm_domain_initialise(struct domain *d)
{
int rc;
@@ -158,10 +225,8 @@ int hvm_domain_initialise(struct domain *d)
}
spin_lock_init(&d->arch.hvm_domain.pbuf_lock);
spin_lock_init(&d->arch.hvm_domain.buffered_io_lock);
spin_lock_init(&d->arch.hvm_domain.irq_lock);
/* paging support will be determined inside paging.c */
rc = paging_enable(d, PG_refcounts|PG_translate|PG_external);
if ( rc != 0 )
return rc;
@@ -169,28 +234,31 @@ int hvm_domain_initialise(struct domain *d)
vpic_init(d);
vioapic_init(d);
hvm_init_ioreq_page(d, &d->arch.hvm_domain.ioreq);
hvm_init_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
return 0;
}
void hvm_domain_relinquish_resources(struct domain *d)
{
hvm_destroy_ioreq_page(d, &d->arch.hvm_domain.ioreq);
hvm_destroy_ioreq_page(d, &d->arch.hvm_domain.buf_ioreq);
}
void hvm_domain_destroy(struct domain *d)
{
pit_deinit(d);
rtc_deinit(d);
pmtimer_deinit(d);
hpet_deinit(d);
if ( d->arch.hvm_domain.shared_page_va )
unmap_domain_page_global(
(void *)d->arch.hvm_domain.shared_page_va);
if ( d->arch.hvm_domain.buffered_io_va )
unmap_domain_page_global((void *)d->arch.hvm_domain.buffered_io_va);
}
static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
{
struct vcpu *v;
struct hvm_hw_cpu ctxt;
struct vcpu_guest_context *vc;
for_each_vcpu(d, v)
{
@@ -199,7 +267,40 @@ static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
if ( test_bit(_VPF_down, &v->pause_flags) )
continue;
/* Architecture-specific vmcs/vmcb bits */
hvm_funcs.save_cpu_ctxt(v, &ctxt);
/* Other vcpu register state */
vc = &v->arch.guest_context;
if ( vc->flags & VGCF_i387_valid )
memcpy(ctxt.fpu_regs, &vc->fpu_ctxt, sizeof(ctxt.fpu_regs));
else
memset(ctxt.fpu_regs, 0, sizeof(ctxt.fpu_regs));
ctxt.rax = vc->user_regs.eax;
ctxt.rbx = vc->user_regs.ebx;
ctxt.rcx = vc->user_regs.ecx;
ctxt.rdx = vc->user_regs.edx;
ctxt.rbp = vc->user_regs.ebp;
ctxt.rsi = vc->user_regs.esi;
ctxt.rdi = vc->user_regs.edi;
/* %rsp handled by arch-specific call above */
#ifdef __x86_64__
ctxt.r8 = vc->user_regs.r8;
ctxt.r9 = vc->user_regs.r9;
ctxt.r10 = vc->user_regs.r10;
ctxt.r11 = vc->user_regs.r11;
ctxt.r12 = vc->user_regs.r12;
ctxt.r13 = vc->user_regs.r13;
ctxt.r14 = vc->user_regs.r14;
ctxt.r15 = vc->user_regs.r15;
#endif
ctxt.dr0 = vc->debugreg[0];
ctxt.dr1 = vc->debugreg[1];
ctxt.dr2 = vc->debugreg[2];
ctxt.dr3 = vc->debugreg[3];
ctxt.dr6 = vc->debugreg[6];
ctxt.dr7 = vc->debugreg[7];
if ( hvm_save_entry(CPU, v->vcpu_id, h, &ctxt) != 0 )
return 1;
}
@@ -208,9 +309,10 @@ static int hvm_save_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
{
int vcpuid;
int vcpuid, rc;
struct vcpu *v;
struct hvm_hw_cpu ctxt;
struct vcpu_guest_context *vc;
/* Which vcpu is this? */
vcpuid = hvm_load_instance(h);
@@ -219,13 +321,52 @@ static int hvm_load_cpu_ctxt(struct domain *d, hvm_domain_context_t *h)
gdprintk(XENLOG_ERR, "HVM restore: domain has no vcpu %u\n", vcpuid);
return -EINVAL;
}
vc = &v->arch.guest_context;
/* Need to init this vcpu before loading its contents */
LOCK_BIGLOCK(d);
if ( !v->is_initialised )
if ( (rc = boot_vcpu(d, vcpuid, vc)) != 0 )
return rc;
UNLOCK_BIGLOCK(d);
if ( hvm_load_entry(CPU, h, &ctxt) != 0 )
return -EINVAL;
/* Architecture-specific vmcs/vmcb bits */
if ( hvm_funcs.load_cpu_ctxt(v, &ctxt) < 0 )
return -EINVAL;
/* Other vcpu register state */
memcpy(&vc->fpu_ctxt, ctxt.fpu_regs, sizeof(ctxt.fpu_regs));
vc->user_regs.eax = ctxt.rax;
vc->user_regs.ebx = ctxt.rbx;
vc->user_regs.ecx = ctxt.rcx;
vc->user_regs.edx = ctxt.rdx;
vc->user_regs.ebp = ctxt.rbp;
vc->user_regs.esi = ctxt.rsi;
vc->user_regs.edi = ctxt.rdi;
vc->user_regs.esp = ctxt.rsp;
#ifdef __x86_64__
vc->user_regs.r8 = ctxt.r8;
vc->user_regs.r9 = ctxt.r9;
vc->user_regs.r10 = ctxt.r10;
vc->user_regs.r11 = ctxt.r11;
vc->user_regs.r12 = ctxt.r12;
vc->user_regs.r13 = ctxt.r13;
vc->user_regs.r14 = ctxt.r14;
vc->user_regs.r15 = ctxt.r15;
#endif
vc->debugreg[0] = ctxt.dr0;
vc->debugreg[1] = ctxt.dr1;
vc->debugreg[2] = ctxt.dr2;
vc->debugreg[3] = ctxt.dr3;
vc->debugreg[6] = ctxt.dr6;
vc->debugreg[7] = ctxt.dr7;
vc->flags = VGCF_i387_valid | VGCF_online;
v->fpu_initialised = 1;
/* Auxiliary processors should be woken immediately. */
if ( test_and_clear_bit(_VPF_down, &v->pause_flags) )
vcpu_wake(v);
@@ -250,10 +391,20 @@ int hvm_vcpu_initialise(struct vcpu *v)
}
/* Create ioreq event channel. */
v->arch.hvm_vcpu.xen_port = alloc_unbound_xen_event_channel(v, 0);
if ( get_sp(v->domain) && get_vio(v->domain, v->vcpu_id) )
get_vio(v->domain, v->vcpu_id)->vp_eport =
v->arch.hvm_vcpu.xen_port;
rc = alloc_unbound_xen_event_channel(v, 0);
if ( rc < 0 )
{
hvm_funcs.vcpu_destroy(v);
vlapic_destroy(v);
return rc;
}
/* Register ioreq event channel. */
v->arch.hvm_vcpu.xen_port = rc;
spin_lock(&v->domain->arch.hvm_domain.ioreq.lock);
if ( v->domain->arch.hvm_domain.ioreq.va != NULL )
get_ioreq(v)->vp_eport = v->arch.hvm_vcpu.xen_port;
spin_unlock(&v->domain->arch.hvm_domain.ioreq.lock);
INIT_LIST_HEAD(&v->arch.hvm_vcpu.tm_list);
@@ -334,7 +485,7 @@ void hvm_send_assist_req(struct vcpu *v)
if ( unlikely(!vcpu_start_shutdown_deferral(v)) )
return; /* implicitly bins the i/o operation */
p = &get_vio(v->domain, v->vcpu_id)->vp_ioreq;
p = &get_ioreq(v)->vp_ioreq;
if ( unlikely(p->state != STATE_IOREQ_NONE) )
{
/* This indicates a bug in the device model. Crash the domain. */
@@ -852,10 +1003,9 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
case HVMOP_get_param:
{
struct xen_hvm_param a;
struct hvm_ioreq_page *iorp;
struct domain *d;
struct vcpu *v;
unsigned long mfn;
void *p;
if ( copy_from_guest(&a, arg, 1) )
return -EFAULT;
@@ -882,30 +1032,18 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg)
switch ( a.index )
{
case HVM_PARAM_IOREQ_PFN:
if ( d->arch.hvm_domain.shared_page_va )
goto param_fail;
mfn = gmfn_to_mfn(d, a.value);
if ( mfn == INVALID_MFN )
goto param_fail;
p = map_domain_page_global(mfn);
if ( p == NULL )
goto param_fail;
d->arch.hvm_domain.shared_page_va = (unsigned long)p;
/* Initialise evtchn port info if VCPUs already created. */
for_each_vcpu ( d, v )
get_vio(d, v->vcpu_id)->vp_eport =
v->arch.hvm_vcpu.xen_port;
iorp = &d->arch.hvm_domain.ioreq;
rc = hvm_set_ioreq_page(d, iorp, a.value);
spin_lock(&iorp->lock);
if ( (rc == 0) && (iorp->va != NULL) )
/* Initialise evtchn port info if VCPUs already created. */
for_each_vcpu ( d, v )
get_ioreq(v)->vp_eport = v->arch.hvm_vcpu.xen_port;
spin_unlock(&iorp->lock);
break;
case HVM_PARAM_BUFIOREQ_PFN:
if ( d->arch.hvm_domain.buffered_io_va )
goto param_fail;
mfn = gmfn_to_mfn(d, a.value);
if ( mfn == INVALID_MFN )
goto param_fail;
p = map_domain_page_global(mfn);
if ( p == NULL )
goto param_fail;
d->arch.hvm_domain.buffered_io_va = (unsigned long)p;
case HVM_PARAM_BUFIOREQ_PFN:
iorp = &d->arch.hvm_domain.buf_ioreq;
rc = hvm_set_ioreq_page(d, iorp, a.value);
break;
case HVM_PARAM_CALLBACK_IRQ:
hvm_set_callback_via(d, a.value);
+12 -20
View File
@@ -158,34 +158,26 @@ static inline void hvm_mmio_access(struct vcpu *v,
int hvm_buffered_io_send(ioreq_t *p)
{
struct vcpu *v = current;
spinlock_t *buffered_io_lock;
buffered_iopage_t *buffered_iopage =
(buffered_iopage_t *)(v->domain->arch.hvm_domain.buffered_io_va);
unsigned long tmp_write_pointer = 0;
struct hvm_ioreq_page *iorp = &v->domain->arch.hvm_domain.buf_ioreq;
buffered_iopage_t *pg = iorp->va;
buffered_io_lock = &v->domain->arch.hvm_domain.buffered_io_lock;
spin_lock(buffered_io_lock);
spin_lock(&iorp->lock);
if ( buffered_iopage->write_pointer - buffered_iopage->read_pointer ==
(unsigned int)IOREQ_BUFFER_SLOT_NUM ) {
/* the queue is full.
* send the iopacket through the normal path.
* NOTE: The arithimetic operation could handle the situation for
* write_pointer overflow.
*/
spin_unlock(buffered_io_lock);
if ( (pg->write_pointer - pg->read_pointer) == IOREQ_BUFFER_SLOT_NUM )
{
/* The queue is full: send the iopacket through the normal path. */
spin_unlock(&iorp->lock);
return 0;
}
tmp_write_pointer = buffered_iopage->write_pointer % IOREQ_BUFFER_SLOT_NUM;
memcpy(&pg->ioreq[pg->write_pointer % IOREQ_BUFFER_SLOT_NUM],
p, sizeof(ioreq_t));
memcpy(&buffered_iopage->ioreq[tmp_write_pointer], p, sizeof(ioreq_t));
/*make the ioreq_t visible before write_pointer*/
/* Make the ioreq_t visible /before/ write_pointer. */
wmb();
buffered_iopage->write_pointer++;
pg->write_pointer++;
spin_unlock(buffered_io_lock);
spin_unlock(&iorp->lock);
return 1;
}
+1 -1
View File
@@ -832,7 +832,7 @@ void hvm_io_assist(void)
io_opp = &v->arch.hvm_vcpu.io_op;
regs = &io_opp->io_context;
vio = get_vio(d, v->vcpu_id);
vio = get_ioreq(v);
p = &vio->vp_ioreq;
if ( p->state != STATE_IORESP_READY )
+37 -9
View File
@@ -221,7 +221,6 @@ static inline unsigned long get_immediate(int ad_size, const unsigned char *inst
inst++; //skip ModR/M byte
if ( ad_size != WORD && mod != 3 && rm == 4 ) {
rm = *inst & 7;
inst++; //skip SIB byte
}
@@ -257,6 +256,33 @@ static inline unsigned long get_immediate(int ad_size, const unsigned char *inst
return val;
}
/* Some instructions, like "add $imm8, r/m16"/"MOV $imm32, r/m64" require
* the src immediate operand be sign-extented befere the op is executed. Here
* we always sign-extend the operand to a "unsigned long" variable.
*
* Note: to simplify the logic here, the sign-extension here may be performed
* redundantly against some instructions, like "MOV $imm16, r/m16" -- however
* this is harmless, since we always remember the operand's size.
*/
static inline unsigned long get_immediate_sign_ext(int ad_size,
const unsigned char *inst,
int op_size)
{
unsigned long result = get_immediate(ad_size, inst, op_size);
if ( op_size == QUAD )
op_size = LONG;
ASSERT( op_size == BYTE || op_size == WORD || op_size == LONG );
if ( result & (1UL << ((8*op_size) - 1)) )
{
unsigned long mask = ~0UL >> (8 * (sizeof(mask) - op_size));
result = ~mask | (result & mask);
}
return result;
}
static inline int get_index(const unsigned char *inst, unsigned char rex)
{
int mod, reg, rm;
@@ -394,7 +420,9 @@ static int mmio_decode(int address_bytes, unsigned char *opcode,
case 8:
if ( *op_size == 0 )
*op_size = rex & 0x8 ? QUAD : LONG;
if ( *ad_size == 0 )
if ( *ad_size == WORD )
*ad_size = LONG;
else if ( *ad_size == 0 )
*ad_size = QUAD;
break;
#endif
@@ -520,10 +548,10 @@ static int mmio_decode(int address_bytes, unsigned char *opcode,
/* opcode 0x83 always has a single byte operand */
if ( opcode[0] == 0x83 )
mmio_op->immediate =
(signed char)get_immediate(*ad_size, opcode + 1, BYTE);
get_immediate_sign_ext(*ad_size, opcode + 1, BYTE);
else
mmio_op->immediate =
get_immediate(*ad_size, opcode + 1, *op_size);
get_immediate_sign_ext(*ad_size, opcode + 1, *op_size);
mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
@@ -677,7 +705,7 @@ static int mmio_decode(int address_bytes, unsigned char *opcode,
mmio_op->operand[0] = mk_operand(*op_size, 0, 0, IMMEDIATE);
mmio_op->immediate =
get_immediate(*ad_size, opcode + 1, *op_size);
get_immediate_sign_ext(*ad_size, opcode + 1, *op_size);
mmio_op->operand[1] = mk_operand(*op_size, 0, 0, MEMORY);
return DECODE_success;
@@ -699,7 +727,7 @@ static int mmio_decode(int address_bytes, unsigned char *opcode,
mmio_op->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE);
mmio_op->immediate =
get_immediate(*ad_size, opcode + 1, *op_size);
get_immediate_sign_ext(*ad_size, opcode + 1, *op_size);
mmio_op->operand[1] = mk_operand(size_reg, 0, 0, MEMORY);
return DECODE_success;
@@ -838,7 +866,7 @@ void send_pio_req(unsigned long port, unsigned long count, int size,
port, count, size, value, dir, value_is_ptr);
}
vio = get_vio(v->domain, v->vcpu_id);
vio = get_ioreq(v);
if ( vio == NULL ) {
printk("bad shared page: %lx\n", (unsigned long) vio);
domain_crash_synchronous();
@@ -887,7 +915,7 @@ static void send_mmio_req(unsigned char type, unsigned long gpa,
type, gpa, count, size, value, dir, value_is_ptr);
}
vio = get_vio(v->domain, v->vcpu_id);
vio = get_ioreq(v);
if (vio == NULL) {
printk("bad shared page\n");
domain_crash_synchronous();
@@ -948,7 +976,7 @@ void send_invalidate_req(void)
vcpu_iodata_t *vio;
ioreq_t *p;
vio = get_vio(v->domain, v->vcpu_id);
vio = get_ioreq(v);
if ( vio == NULL )
{
printk("bad shared page: %lx\n", (unsigned long) vio);
+24 -9
View File
@@ -233,7 +233,7 @@ int svm_vmcb_save(struct vcpu *v, struct hvm_hw_cpu *c)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
c->eip = vmcb->rip;
c->rip = vmcb->rip;
#ifdef HVM_DEBUG_SUSPEND
printk("%s: eip=0x%"PRIx64".\n",
@@ -241,10 +241,11 @@ int svm_vmcb_save(struct vcpu *v, struct hvm_hw_cpu *c)
inst_len, c->eip);
#endif
c->esp = vmcb->rsp;
c->eflags = vmcb->rflags;
c->rsp = vmcb->rsp;
c->rflags = vmcb->rflags;
c->cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
c->cr2 = v->arch.hvm_svm.cpu_cr2;
c->cr3 = v->arch.hvm_svm.cpu_cr3;
c->cr4 = v->arch.hvm_svm.cpu_shadow_cr4;
@@ -315,14 +316,14 @@ int svm_vmcb_restore(struct vcpu *v, struct hvm_hw_cpu *c)
unsigned long mfn, old_base_mfn;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
vmcb->rip = c->eip;
vmcb->rsp = c->esp;
vmcb->rflags = c->eflags;
vmcb->rip = c->rip;
vmcb->rsp = c->rsp;
vmcb->rflags = c->rflags;
v->arch.hvm_svm.cpu_shadow_cr0 = c->cr0;
vmcb->cr0 = c->cr0 | X86_CR0_WP | X86_CR0_ET;
if ( !paging_mode_hap(v->domain) )
vmcb->cr0 |= X86_CR0_PG;
vmcb->cr0 = c->cr0 | X86_CR0_WP | X86_CR0_ET | X86_CR0_PG;
v->arch.hvm_svm.cpu_cr2 = c->cr2;
#ifdef HVM_DEBUG_SUSPEND
printk("%s: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n",
@@ -421,6 +422,19 @@ int svm_vmcb_restore(struct vcpu *v, struct hvm_hw_cpu *c)
vmcb->sysenter_esp = c->sysenter_esp;
vmcb->sysenter_eip = c->sysenter_eip;
/* update VMCB for nested paging restore */
if ( paging_mode_hap(v->domain) ) {
vmcb->cr0 = v->arch.hvm_svm.cpu_shadow_cr0;
vmcb->cr4 = v->arch.hvm_svm.cpu_shadow_cr4;
vmcb->cr3 = c->cr3;
vmcb->np_enable = 1;
vmcb->g_pat = 0x0007040600070406ULL; /* guest PAT */
vmcb->h_cr3 = pagetable_get_paddr(v->domain->arch.phys_table);
}
vmcb->dr6 = c->dr6;
vmcb->dr7 = c->dr7;
paging_update_paging_modes(v);
return 0;
@@ -440,6 +454,7 @@ void svm_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
data->msr_cstar = vmcb->cstar;
data->msr_syscall_mask = vmcb->sfmask;
data->msr_efer = v->arch.hvm_svm.cpu_shadow_efer;
data->msr_flags = -1ULL;
data->tsc = hvm_get_guest_time(v);
}
+13 -8
View File
@@ -370,11 +370,12 @@ static inline void __restore_debug_registers(struct vcpu *v)
int vmx_vmcs_save(struct vcpu *v, struct hvm_hw_cpu *c)
{
c->eip = __vmread(GUEST_RIP);
c->esp = __vmread(GUEST_RSP);
c->eflags = __vmread(GUEST_RFLAGS);
c->rip = __vmread(GUEST_RIP);
c->rsp = __vmread(GUEST_RSP);
c->rflags = __vmread(GUEST_RFLAGS);
c->cr0 = v->arch.hvm_vmx.cpu_shadow_cr0;
c->cr2 = v->arch.hvm_vmx.cpu_cr2;
c->cr3 = v->arch.hvm_vmx.cpu_cr3;
c->cr4 = v->arch.hvm_vmx.cpu_shadow_cr4;
@@ -444,13 +445,15 @@ int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c)
vmx_vmcs_enter(v);
__vmwrite(GUEST_RIP, c->eip);
__vmwrite(GUEST_RSP, c->esp);
__vmwrite(GUEST_RFLAGS, c->eflags);
__vmwrite(GUEST_RIP, c->rip);
__vmwrite(GUEST_RSP, c->rsp);
__vmwrite(GUEST_RFLAGS, c->rflags);
v->arch.hvm_vmx.cpu_shadow_cr0 = c->cr0;
__vmwrite(CR0_READ_SHADOW, v->arch.hvm_vmx.cpu_shadow_cr0);
v->arch.hvm_vmx.cpu_cr2 = c->cr2;
#ifdef HVM_DEBUG_SUSPEND
printk("vmx_vmcs_restore: cr3=0x%"PRIx64", cr0=0x%"PRIx64", cr4=0x%"PRIx64".\n",
c->cr3,
@@ -555,6 +558,8 @@ int vmx_vmcs_restore(struct vcpu *v, struct hvm_hw_cpu *c)
__vmwrite(GUEST_SYSENTER_ESP, c->sysenter_esp);
__vmwrite(GUEST_SYSENTER_EIP, c->sysenter_eip);
__vmwrite(GUEST_DR7, c->dr7);
vmx_vmcs_exit(v);
paging_update_paging_modes(v);
@@ -590,7 +595,7 @@ void vmx_save_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
data->shadow_gs = guest_state->shadow_gs;
/* save msrs */
data->flags = guest_flags;
data->msr_flags = guest_flags;
data->msr_lstar = guest_state->msrs[VMX_INDEX_MSR_LSTAR];
data->msr_star = guest_state->msrs[VMX_INDEX_MSR_STAR];
data->msr_cstar = guest_state->msrs[VMX_INDEX_MSR_CSTAR];
@@ -607,7 +612,7 @@ void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
struct vmx_msr_state *guest_state = &v->arch.hvm_vmx.msr_state;
/* restore msrs */
guest_state->flags = data->flags;
guest_state->flags = data->msr_flags;
guest_state->msrs[VMX_INDEX_MSR_LSTAR] = data->msr_lstar;
guest_state->msrs[VMX_INDEX_MSR_STAR] = data->msr_star;
guest_state->msrs[VMX_INDEX_MSR_CSTAR] = data->msr_cstar;
+13 -9
View File
@@ -2041,7 +2041,7 @@ int do_mmuext_op(
MEM_LOG("Error while pinning mfn %lx", mfn);
break;
}
if ( unlikely(test_and_set_bit(_PGT_pinned,
&page->u.inuse.type_info)) )
{
@@ -2054,14 +2054,18 @@ int do_mmuext_op(
/* A page is dirtied when its pin status is set. */
mark_dirty(d, mfn);
/*
* We can race domain destruction (domain_relinquish_resources).
* NB. The dying-flag test must happen /after/ setting PGT_pinned.
*/
if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) &&
this_cpu(percpu_mm_info).foreign->is_dying &&
test_and_clear_bit(_PGT_pinned, &page->u.inuse.type_info) )
put_page_and_type(page);
/* We can race domain destruction (domain_relinquish_resources). */
if ( unlikely(this_cpu(percpu_mm_info).foreign != NULL) )
{
int drop_ref;
spin_lock(&FOREIGNDOM->page_alloc_lock);
drop_ref = (FOREIGNDOM->is_dying &&
test_and_clear_bit(_PGT_pinned,
&page->u.inuse.type_info));
spin_unlock(&FOREIGNDOM->page_alloc_lock);
if ( drop_ref )
put_page_and_type(page);
}
break;
-3
View File
@@ -313,9 +313,6 @@ void domain_kill(struct domain *d)
return;
}
/* Tear down state /after/ setting the dying flag. */
smp_wmb();
gnttab_release_mappings(d);
domain_relinquish_resources(d);
put_domain(d);
+5 -1
View File
@@ -28,7 +28,11 @@
#include <asm/processor.h>
#include <asm/msr.h>
#define xchg(ptr,v) ((__typeof__(*(ptr)))__xchg((unsigned long)(v),(ptr),sizeof(*(ptr))))
#define xchg(ptr,x) \
({ \
__typeof__(*(ptr)) _x_ = (x); \
(__typeof__(*(ptr))) __xchg((ptr), (unsigned long)_x_, sizeof(*(ptr))); \
})
static __inline__ unsigned long
__xchg_u32(volatile int *m, unsigned long val)
+9 -3
View File
@@ -28,10 +28,16 @@
#include <public/hvm/params.h>
#include <public/hvm/save.h>
struct hvm_ioreq_page {
spinlock_t lock;
struct page_info *page;
void *va;
};
struct hvm_domain {
unsigned long shared_page_va;
unsigned long buffered_io_va;
spinlock_t buffered_io_lock;
struct hvm_ioreq_page ioreq;
struct hvm_ioreq_page buf_ioreq;
s64 tsc_frequency;
struct pl_time pl_time;
+1
View File
@@ -145,6 +145,7 @@ struct hvm_function_table {
extern struct hvm_function_table hvm_funcs;
int hvm_domain_initialise(struct domain *d);
void hvm_domain_relinquish_resources(struct domain *d);
void hvm_domain_destroy(struct domain *d);
int hvm_vcpu_initialise(struct vcpu *v);
+6 -7
View File
@@ -32,14 +32,13 @@
#define HVM_DEBUG 1
#endif
static inline shared_iopage_t *get_sp(struct domain *d)
static inline vcpu_iodata_t *get_ioreq(struct vcpu *v)
{
return (shared_iopage_t *) d->arch.hvm_domain.shared_page_va;
}
static inline vcpu_iodata_t *get_vio(struct domain *d, unsigned long cpu)
{
return &get_sp(d)->vcpu_iodata[cpu];
struct domain *d = v->domain;
shared_iopage_t *p = d->arch.hvm_domain.ioreq.va;
ASSERT((v == current) || spin_is_locked(&d->arch.hvm_domain.ioreq.lock));
ASSERT(d->arch.hvm_domain.ioreq.va != NULL);
return &p->vcpu_iodata[v->vcpu_id];
}
/* XXX these are really VMX specific */
+31 -4
View File
@@ -87,13 +87,40 @@ DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
*/
struct hvm_hw_cpu {
uint64_t eip;
uint64_t esp;
uint64_t eflags;
uint8_t fpu_regs[512];
uint64_t rax;
uint64_t rbx;
uint64_t rcx;
uint64_t rdx;
uint64_t rbp;
uint64_t rsi;
uint64_t rdi;
uint64_t rsp;
uint64_t r8;
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rip;
uint64_t rflags;
uint64_t cr0;
uint64_t cr2;
uint64_t cr3;
uint64_t cr4;
uint64_t dr0;
uint64_t dr1;
uint64_t dr2;
uint64_t dr3;
uint64_t dr6;
uint64_t dr7;
uint32_t cs_sel;
uint32_t ds_sel;
uint32_t es_sel;
@@ -142,9 +169,9 @@ struct hvm_hw_cpu {
/* msr for em64t */
uint64_t shadow_gs;
uint64_t flags;
/* msr content saved/restored. */
uint64_t msr_flags;
uint64_t msr_lstar;
uint64_t msr_star;
uint64_t msr_cstar;
+2 -2
View File
@@ -96,10 +96,10 @@ domain_mmap_cache_destroy(struct domain_mmap_cache *cache)
#else /* !CONFIG_DOMAIN_PAGE */
#define map_domain_page(mfn) maddr_to_virt((mfn)<<PAGE_SHIFT)
#define map_domain_page(mfn) mfn_to_virt(mfn)
#define unmap_domain_page(va) ((void)(va))
#define map_domain_page_global(mfn) maddr_to_virt((mfn)<<PAGE_SHIFT)
#define map_domain_page_global(mfn) mfn_to_virt(mfn)
#define unmap_domain_page_global(va) ((void)(va))
struct domain_mmap_cache {
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.