From 6f7731e676b04a091bc5e9c4fbd41b0d73587051 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 09:27:28 +0100 Subject: [PATCH 001/142] Hide the VMX cpu feature from unmodified Guests. Signed-Off-By: Nitin A Kamble --- xen/arch/x86/vmx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index 28d996e4a5..632a4e47b0 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -471,6 +471,7 @@ static void vmx_vmexit_do_cpuid(unsigned long input, struct cpu_user_regs *regs) #endif /* Unsupportable for virtualised CPUs. */ + clear_bit(X86_FEATURE_VMXE & 31, &ecx); clear_bit(X86_FEATURE_MWAIT & 31, &ecx); } From c27ad917f234f19717a861491b9c8e9114df2044 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 09:28:12 +0100 Subject: [PATCH 002/142] The NAT scripts currently work, but the changes below decrease user error and allow the netmask to be passed in. Signed-off-by: Jon Mason --- tools/examples/vif-nat | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/tools/examples/vif-nat b/tools/examples/vif-nat index f268fdcedc..a86bd91dd9 100644 --- a/tools/examples/vif-nat +++ b/tools/examples/vif-nat @@ -23,7 +23,6 @@ # Exit if anything goes wrong set -e export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH -echo "*vif-nat $*" >&2 # Operation name. OP=$1 @@ -35,17 +34,25 @@ for arg ; do export "${arg}" ; done # Required parameters. Fail if not set. domain=${domain:?} vif=${vif:?} -ip=${ip:?} +ip=${ip:-'169.254.1.1/24'} #if not defined, give a default address -# strip /netmask +echo "*vif-nat $OP domain=$domain vif=$vif ip=$ip" >&2 + +#determine ip address and netmask vif_ip=`echo ${ip} | awk -F/ '{print $1}'` +bits=`echo ${ip} | awk -F/ '{print $2}'` +intmask=$(( ((0xFFFFFFFF << ((32 - $bits)))) & 0xFFFFFFFF )) +netmask=$(( (($intmask & 0xFF000000)) >> 24 )) +netmask=$netmask.$(( (($intmask & 0x00FF0000)) >> 16 )) +netmask=$netmask.$(( (($intmask & 0x0000FF00)) >> 8 )) +netmask=$netmask.$(( $intmask & 0x000000FF )) main_ip=`ifconfig eth0 | grep "inet addr:" | sed -e 's/.*inet addr:\(\w\w*\.\w\w*\.\w\w*\.\w\w*\).*/\1/'` # Are we going up or down? case $OP in up) - ifconfig ${vif} ${vif_ip} netmask 255.255.255.0 up + ifconfig ${vif} ${vif_ip} netmask ${netmask} up echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp iptcmd='-A' ipcmd='a' From 7ca9b327cdeea2d9a0238eeb869d991715fcb052 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 09:29:52 +0100 Subject: [PATCH 003/142] Error print on err path. Signed-off-by: srparish@us.ibm.com --- tools/libxc/xc_linux_build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index df88c8f440..2c984bf5ea 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -502,7 +502,7 @@ static int setup_guest(int xc_handle, if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) ) { - printf("Initial guest OS requires too much space\n" + PERROR("Initial guest OS requires too much space\n" "(%luMB is greater than %luMB limit)\n", (v_end-dsi.v_start)>>20, (nr_pages<>20); goto error_out; From e4c8d0db290c0d101f0ee3163aaf98008f60b270 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 09:31:53 +0100 Subject: [PATCH 004/142] Fix PAE overflow in xc_linux_build. Signed-off-by: srparish@us.ibm.com --- tools/libxc/xc_linux_build.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 2c984bf5ea..3b0f28676f 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -500,11 +500,11 @@ static int setup_guest(int xc_handle, _p(dsi.v_start), _p(v_end)); printf(" ENTRY ADDRESS: %p\n", _p(dsi.v_kernentry)); - if ( (v_end - dsi.v_start) > (nr_pages * PAGE_SIZE) ) + if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages ) { - PERROR("Initial guest OS requires too much space\n" + printf("Initial guest OS requires too much space\n" "(%luMB is greater than %luMB limit)\n", - (v_end-dsi.v_start)>>20, (nr_pages<>20); + (v_end-dsi.v_start)>>20, nr_pages>>(20-PAGE_SHIFT)); goto error_out; } From f7c1a9cd63c03f6f5843c0e918c445303d861d94 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 09:33:03 +0100 Subject: [PATCH 005/142] This patch implements select() functionality on /dev/vtpm and fixes some other problems. Signed-off-by: Stefan Berger --- linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c | 10 ++++++++-- linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c | 9 ++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c index f5c0ccb10a..0a8d70528c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -680,9 +681,14 @@ vtpm_op_release(struct inode *inode, struct file *file) } static unsigned int -vtpm_op_poll(struct file *file, struct poll_table_struct *pst) +vtpm_op_poll(struct file *file, struct poll_table_struct *pts) { - return 0; + unsigned int flags = POLLOUT | POLLWRNORM; + poll_wait(file, &dataex.wait_queue, pts); + if (!list_empty(&dataex.pending_pak)) { + flags |= POLLIN | POLLRDNORM; + } + return flags; } static struct file_operations vtpm_ops = { diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c index 09ffb02002..9276c19354 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmfront/tpmfront.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -372,7 +373,7 @@ again: info->watch.callback = watch_for_status; err = register_xenbus_watch(&info->watch); if (err) { - message = "registering watch on backend"; + xenbus_dev_error(dev, err, "registering watch on backend"); goto destroy_tpmring; } @@ -398,6 +399,8 @@ static int tpmfront_probe(struct xenbus_device *dev, int err; struct tpmfront_info *info; int handle; + int len = max(XS_WATCH_PATH, XS_WATCH_TOKEN) + 1; + const char *vec[len]; err = xenbus_scanf(NULL, dev->nodename, "handle", "%i", &handle); @@ -427,6 +430,10 @@ static int tpmfront_probe(struct xenbus_device *dev, return err; } + vec[XS_WATCH_PATH] = info->watch.node; + vec[XS_WATCH_TOKEN] = NULL; + watch_for_status(&info->watch, vec, len); + return 0; } From e8d5405d57851adc5f02e5147fa72868414a1d5d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 09:34:27 +0100 Subject: [PATCH 006/142] Fix compilation problems with xenstore. Signed-off-by: Jerone Young --- tools/xenstore/xs_tdb_dump.c | 6 +++--- tools/xenstore/xsls.c | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/tools/xenstore/xs_tdb_dump.c b/tools/xenstore/xs_tdb_dump.c index a68f19fc2b..f7e54fbe75 100644 --- a/tools/xenstore/xs_tdb_dump.c +++ b/tools/xenstore/xs_tdb_dump.c @@ -53,17 +53,17 @@ int main(int argc, char *argv[]) hdr = (void *)data.dptr; if (data.dsize < sizeof(*hdr)) fprintf(stderr, "%.*s: BAD truncated\n", - key.dsize, key.dptr); + (int)key.dsize, key.dptr); else if (data.dsize != total_size(hdr)) fprintf(stderr, "%.*s: BAD length %i for %i/%i/%i (%i)\n", - key.dsize, key.dptr, data.dsize, + (int)key.dsize, key.dptr, (int)data.dsize, hdr->num_perms, hdr->datalen, hdr->childlen, total_size(hdr)); else { unsigned int i; char *p; - printf("%.*s: ", key.dsize, key.dptr); + printf("%.*s: ", (int)key.dsize, key.dptr); for (i = 0; i < hdr->num_perms; i++) printf("%s%c%i", i == 0 ? "" : ",", diff --git a/tools/xenstore/xsls.c b/tools/xenstore/xsls.c index f8cf24536a..781fc6d7a8 100644 --- a/tools/xenstore/xsls.c +++ b/tools/xenstore/xsls.c @@ -8,7 +8,8 @@ void print_dir(struct xs_handle *h, char *path, int cur_depth) { char **e; char newpath[512], *val; - int num, i, len; + int i; + unsigned int num, len; e = xs_directory(h, NULL, path, &num); if (e == NULL) @@ -25,7 +26,7 @@ void print_dir(struct xs_handle *h, char *path, int cur_depth) if (val == NULL) printf(":\n"); else if ((unsigned)len > (151 - strlen(e[i]))) - printf(" = \"%.*s...\"\n", 148 - strlen(e[i]), val); + printf(" = \"%.*s...\"\n", (int)(148 - strlen(e[i])), val); else printf(" = \"%s\"\n", val); free(val); From 2543c86b2a4974cbaf2efc78bcc873fb57f650f9 Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 10:07:04 +0100 Subject: [PATCH 007/142] Issue diagnostics if xm is being run as a non-root user. This used to happen, but the triggering error has moved, so the diagnostics were broken. Signed-off-by: Ewan Mellor --- tools/python/xen/xm/main.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 082bdb6367..11e2ff7194 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -688,11 +688,16 @@ def main(argv=sys.argv): if rc: usage() except socket.error, ex: - print >>sys.stderr, ex - err("Error connecting to xend, is xend running?") + if os.geteuid() != 0: + err("Most commands need root access. Please try again as root.") + else: + err("Error connecting to xend: %s. Is xend running?" % ex[1]) sys.exit(1) except IOError: - err("Most commands need root access. Please try again as root") + if os.geteuid() != 0: + err("Most commands need root access. Please try again as root.") + else: + err("Error connecting to xend: %s." % ex[1]) sys.exit(1) except xen.xend.XendError.XendError, ex: if len(args) > 0: From 9887530801ed4feddca24ddbe0e38b3fc5af2f2c Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 10:08:01 +0100 Subject: [PATCH 008/142] Change import that was confusing pylint (this is a pylint bug, I think). Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/blkif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index 3782fa5a00..5f791428bb 100644 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -23,7 +23,7 @@ import string from xen.util import blkif from xen.xend import sxp -from DevController import DevController +from xen.xend.server.DevController import DevController class BlkifController(DevController): From e2c103e4851e41622adfe762ab34f7518f8c371e Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 10:11:35 +0100 Subject: [PATCH 009/142] Fix deadlock in XendDomainInfo when a domain is cleaned up. We are renaming the domain, to make it clear that it is a zombie, but this renaming cannot check the uniqueness of the new name, because this causes a deadlock with XendDomain. Instead, we allow the name to be non-unique for the case of zombie domains. Change the locking in waitForShutdown and state_set to be robust in the face of exceptions. Rename the STATE_VM_ constants to STATE_DOM_. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomain.py | 4 +- tools/python/xen/xend/XendDomainInfo.py | 54 ++++++++++++------------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 7809c80fd9..7b1ea4a759 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -57,7 +57,7 @@ class XendDomain: # So we stuff the XendDomain instance (self) into xroot's components. xroot.add_component("xen.xend.XendDomain", self) self.domains = {} - self.domains_lock = threading.Condition() + self.domains_lock = threading.RLock() self.watchReleaseDomain() self.domains_lock.acquire() @@ -318,7 +318,7 @@ class XendDomain: n = len(matching) if n == 1: return matching[0] - elif n > 1: + elif n > 1 and not d.isTerminated(): log.error('Name uniqueness has been violated for name %s! ' 'Recovering by renaming:', name) for d in matching: diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index cc949d15e0..3d008c5d3f 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -78,8 +78,8 @@ restart_modes = [ "rename-restart" ] -STATE_VM_OK = "ok" -STATE_VM_TERMINATED = "terminated" +STATE_DOM_OK = 1 +STATE_DOM_SHUTDOWN = 2 """Flag for a block device backend domain.""" SIF_BLK_BE_DOMAIN = (1<<4) @@ -293,7 +293,7 @@ def parseConfig(config): restart = get_cfg('restart') if restart: def handle_restart(event, val): - if not event in result: + if result[event] is None: result[event] = val if restart == "onreboot": @@ -384,7 +384,7 @@ class XendDomainInfo: self.console_channel = None self.console_mfn = None - self.state = STATE_VM_OK + self.state = STATE_DOM_OK self.state_updated = threading.Condition() self.refresh_shutdown_lock = threading.Condition() @@ -708,7 +708,7 @@ class XendDomainInfo: self.clearRestart() if reason == 'suspend': - self.state_set(STATE_VM_TERMINATED) + self.state_set(STATE_DOM_SHUTDOWN) # Don't destroy the domain. XendCheckpoint will do # this once it has finished. elif reason in ['poweroff', 'reboot']: @@ -821,19 +821,31 @@ class XendDomainInfo: def state_set(self, state): self.state_updated.acquire() - if self.state != state: - self.state = state - self.state_updated.notifyAll() - self.state_updated.release() + try: + if self.state != state: + self.state = state + self.state_updated.notifyAll() + finally: + self.state_updated.release() ## public: def waitForShutdown(self): self.state_updated.acquire() - while self.state == STATE_VM_OK: - self.state_updated.wait() - self.state_updated.release() + try: + while self.state == STATE_DOM_OK: + self.state_updated.wait() + finally: + self.state_updated.release() + + + def isShutdown(self): + self.state_updated.acquire() + try: + return self.state == STATE_DOM_SHUTDOWN + finally: + self.state_updated.release() def __str__(self): @@ -1065,11 +1077,11 @@ class XendDomainInfo: try: if not self.info['name'].startswith(ZOMBIE_PREFIX): - self.info['name'] = self.generateZombieName() + self.info['name'] = ZOMBIE_PREFIX + self.info['name'] except: log.exception("Renaming Zombie failed.") - self.state_set(STATE_VM_TERMINATED) + self.state_set(STATE_DOM_SHUTDOWN) def cleanupVm(self): @@ -1274,7 +1286,7 @@ class XendDomainInfo: log.info("Preserving dead domain %s (%d).", self.info['name'], self.domid) self.storeDom('xend/shutdown_completed', 'True') - self.state_set(STATE_VM_TERMINATED) + self.state_set(STATE_DOM_SHUTDOWN) ## public: @@ -1304,18 +1316,6 @@ class XendDomainInfo: n += 1 - def generateZombieName(self): - n = 0 - name = ZOMBIE_PREFIX + self.info['name'] - while True: - try: - self.check_name(name) - return name - except VmError: - n += 1 - name = "%s%d-%s" % (ZOMBIE_PREFIX, n, self.info['name']) - - def configure_bootloader(self): if not self.info['bootloader']: return From d8263e8dbaf5ef1445bee0662143a0fcb6d43466 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 11:07:37 +0100 Subject: [PATCH 010/142] Fix Xen public interfaces and the tools to consistently use stdint-format bitsize types (uint32_t and friends). Signed-off-by: Keir Fraser --- tools/blktap/parallax/block-async.c | 8 +- tools/blktap/parallax/block-async.h | 8 +- tools/blktap/parallax/blockstore.c | 40 +- tools/blktap/parallax/blockstore.h | 48 +-- tools/blktap/parallax/blockstored.c | 16 +- tools/blktap/parallax/bstest.c | 6 +- tools/blktap/parallax/parallax.c | 12 +- tools/blktap/parallax/radix.c | 42 +- tools/blktap/parallax/radix.h | 12 +- tools/blktap/parallax/requests-async.c | 32 +- tools/blktap/parallax/requests-async.h | 10 +- tools/blktap/parallax/snaplog.c | 2 +- tools/blktap/parallax/snaplog.h | 8 +- tools/blktap/parallax/vdi.c | 4 +- tools/blktap/parallax/vdi.h | 16 +- tools/blktap/parallax/vdi_create.c | 2 +- tools/blktap/parallax/vdi_fill.c | 10 +- tools/blktap/parallax/vdi_snap.c | 4 +- tools/blktap/parallax/vdi_snap_delete.c | 2 +- tools/blktap/parallax/vdi_snap_list.c | 4 +- tools/blktap/parallax/vdi_unittest.c | 20 +- tools/blktap/parallax/vdi_validate.c | 10 +- tools/blktap/ublkback/ublkbacklib.c | 6 +- tools/console/daemon/io.c | 2 +- .../gdb/gdbserver/linux-xen-low.c | 2 +- tools/debugger/libxendebug/xendebug.c | 80 ++-- tools/debugger/libxendebug/xendebug.h | 56 +-- tools/debugger/pdb/linux-2.6-module/debug.c | 20 +- .../debugger/pdb/linux-2.6-module/pdb_debug.h | 4 +- .../pdb/linux-2.6-module/pdb_module.h | 50 +-- tools/debugger/pdb/pdb_caml_domain.c | 4 +- tools/debugger/pdb/pdb_caml_evtchn.c | 4 +- tools/debugger/pdb/pdb_caml_process.c | 2 +- tools/debugger/pdb/pdb_caml_xc.c | 2 +- tools/debugger/pdb/pdb_caml_xcs.c | 4 +- tools/firmware/acpi/acpi2_0.h | 206 ++++----- tools/firmware/acpi/acpi_build.c | 58 +-- tools/firmware/vmxassist/vm86.c | 2 +- tools/firmware/vmxassist/vm86.h | 9 - tools/ioemu/hw/ioapic.c | 4 +- tools/ioemu/target-i386-dm/helper2.c | 12 +- tools/ioemu/vl.c | 6 +- tools/libxc/xc_bvtsched.c | 12 +- tools/libxc/xc_core.c | 4 +- tools/libxc/xc_domain.c | 44 +- tools/libxc/xc_evtchn.c | 6 +- tools/libxc/xc_gnttab.c | 30 +- tools/libxc/xc_ia64_stubs.c | 10 +- tools/libxc/xc_linux_build.c | 24 +- tools/libxc/xc_linux_restore.c | 2 +- tools/libxc/xc_linux_save.c | 8 +- tools/libxc/xc_load_aout9.c | 18 +- tools/libxc/xc_load_bin.c | 20 +- tools/libxc/xc_load_elf.c | 8 +- tools/libxc/xc_misc.c | 2 +- tools/libxc/xc_physdev.c | 2 +- tools/libxc/xc_private.c | 28 +- tools/libxc/xc_ptrace.c | 4 +- tools/libxc/xc_ptrace_core.c | 2 +- tools/libxc/xc_sedf.c | 4 +- tools/libxc/xc_vmx_build.c | 26 +- tools/libxc/xenctrl.h | 140 +++---- tools/libxc/xg_private.h | 16 +- tools/python/xen/lowlevel/xc/xc.c | 58 +-- tools/python/xen/lowlevel/xs/xs.c | 1 + tools/security/Makefile | 4 +- tools/security/secpol_compat.h | 14 - tools/security/secpol_tool.c | 2 +- tools/security/secpol_xml2bin.c | 2 +- tools/xenstat/libxenstat/src/xen-interface.h | 10 - tools/xenstore/fake_libxc.c | 7 +- tools/xenstore/tdb.c | 64 +-- tools/xenstore/tdb.h | 26 +- tools/xenstore/xenstored_core.c | 16 +- tools/xenstore/xenstored_core.h | 4 +- tools/xenstore/xenstored_domain.c | 45 +- tools/xenstore/xenstored_transaction.c | 4 +- tools/xenstore/xenstored_transaction.h | 2 +- tools/xenstore/xs.c | 11 +- tools/xenstore/xs.h | 15 +- tools/xenstore/xs_crashme.c | 44 +- tools/xenstore/xs_lib.c | 2 +- tools/xenstore/xs_lib.h | 4 +- tools/xenstore/xs_random.c | 44 +- tools/xenstore/xs_tdb_dump.c | 8 +- tools/xenstore/xs_test.c | 2 +- tools/xentrace/xenctx.c | 2 +- tools/xentrace/xentrace.c | 9 +- xen/include/public/acm.h | 128 +++--- xen/include/public/acm_ops.h | 41 +- xen/include/public/arch-ia64.h | 392 +++++++++--------- xen/include/public/arch-x86_32.h | 63 +-- xen/include/public/arch-x86_64.h | 70 ++-- xen/include/public/dom0_ops.h | 152 +++---- xen/include/public/event_channel.h | 64 +-- xen/include/public/grant_table.h | 50 ++- xen/include/public/io/blkif.h | 22 +- xen/include/public/io/console.h | 12 +- xen/include/public/io/ioreq.h | 56 ++- xen/include/public/io/netif.h | 36 +- xen/include/public/io/ring.h | 10 + xen/include/public/io/tpmif.h | 16 +- xen/include/public/io/usbif.h | 66 --- xen/include/public/io/vmx_vlapic.h | 50 ++- xen/include/public/io/xs_wire.h | 19 +- xen/include/public/memory.h | 10 + xen/include/public/physdev.h | 22 +- xen/include/public/sched.h | 10 + xen/include/public/sched_ctl.h | 44 +- xen/include/public/trace.h | 14 +- xen/include/public/vcpu.h | 10 + xen/include/public/version.h | 10 + xen/include/public/vmx_assist.h | 131 +++--- xen/include/public/xen.h | 54 ++- xen/include/xen/types.h | 16 +- 115 files changed, 1689 insertions(+), 1538 deletions(-) delete mode 100644 tools/security/secpol_compat.h delete mode 100644 xen/include/public/io/usbif.h diff --git a/tools/blktap/parallax/block-async.c b/tools/blktap/parallax/block-async.c index 294a4670d9..50f12b0491 100755 --- a/tools/blktap/parallax/block-async.c +++ b/tools/blktap/parallax/block-async.c @@ -31,11 +31,11 @@ */ struct read_args { - u64 addr; + uint64_t addr; }; struct write_args { - u64 addr; + uint64_t addr; char *block; }; @@ -94,7 +94,7 @@ static void init_pending_io(void) } -void block_read(u64 addr, io_cb_t cb, void *param) +void block_read(uint64_t addr, io_cb_t cb, void *param) { struct pending_io_req *req; @@ -113,7 +113,7 @@ void block_read(u64 addr, io_cb_t cb, void *param) } -void block_write(u64 addr, char *block, io_cb_t cb, void *param) +void block_write(uint64_t addr, char *block, io_cb_t cb, void *param) { struct pending_io_req *req; diff --git a/tools/blktap/parallax/block-async.h b/tools/blktap/parallax/block-async.h index 094ca63685..685d13ccc5 100755 --- a/tools/blktap/parallax/block-async.h +++ b/tools/blktap/parallax/block-async.h @@ -14,7 +14,7 @@ struct io_ret { enum {IO_ADDR_T, IO_BLOCK_T, IO_INT_T} type; union { - u64 a; + uint64_t a; char *b; int i; } u; @@ -38,8 +38,8 @@ struct radix_lock { }; void radix_lock_init(struct radix_lock *r); -void block_read(u64 addr, io_cb_t cb, void *param); -void block_write(u64 addr, char *block, io_cb_t cb, void *param); +void block_read(uint64_t addr, io_cb_t cb, void *param); +void block_write(uint64_t addr, char *block, io_cb_t cb, void *param); void block_alloc(char *block, io_cb_t cb, void *param); void block_rlock(struct radix_lock *r, int row, io_cb_t cb, void *param); void block_wlock(struct radix_lock *r, int row, io_cb_t cb, void *param); @@ -47,7 +47,7 @@ void block_runlock(struct radix_lock *r, int row, io_cb_t cb, void *param); void block_wunlock(struct radix_lock *r, int row, io_cb_t cb, void *param); void init_block_async(void); -static inline u64 IO_ADDR(struct io_ret r) +static inline uint64_t IO_ADDR(struct io_ret r) { assert(r.type == IO_ADDR_T); return r.u.a; diff --git a/tools/blktap/parallax/blockstore.c b/tools/blktap/parallax/blockstore.c index e15ddcd760..7967edb555 100644 --- a/tools/blktap/parallax/blockstore.c +++ b/tools/blktap/parallax/blockstore.c @@ -132,9 +132,9 @@ pthread_mutex_t ptmutex_luid; #define ENTER_LUID_CR pthread_mutex_lock(&ptmutex_luid) #define LEAVE_LUID_CR pthread_mutex_unlock(&ptmutex_luid) -static u64 luid_cnt = 0x1000ULL; -u64 new_luid(void) { - u64 luid; +static uint64_t luid_cnt = 0x1000ULL; +uint64_t new_luid(void) { + uint64_t luid; ENTER_LUID_CR; luid = luid_cnt++; LEAVE_LUID_CR; @@ -539,7 +539,7 @@ pthread_t pthread_recv; * Reading * *****************************************************************************/ -void *readblock_indiv(int server, u64 id) { +void *readblock_indiv(int server, uint64_t id) { void *block; bsq_t *qe; int len, rc; @@ -616,9 +616,9 @@ void *readblock_indiv(int server, u64 id) { * * @return: pointer to block, NULL on error */ -void *readblock(u64 id) { +void *readblock(uint64_t id) { int map = (int)BSID_MAP(id); - u64 xid; + uint64_t xid; static int i = CLUSTER_MAX_REPLICAS - 1; void *block = NULL; @@ -670,7 +670,7 @@ void *readblock(u64 id) { * Writing * *****************************************************************************/ -bsq_t *writeblock_indiv(int server, u64 id, void *block) { +bsq_t *writeblock_indiv(int server, uint64_t id, void *block) { bsq_t *qe; int len; @@ -709,7 +709,7 @@ bsq_t *writeblock_indiv(int server, u64 id, void *block) { * * @return: zero on success, -1 on failure */ -int writeblock(u64 id, void *block) { +int writeblock(uint64_t id, void *block) { int map = (int)BSID_MAP(id); int rep0 = bsclusters[map].servers[0]; @@ -805,11 +805,11 @@ int writeblock(u64 id, void *block) { * * @return: new id of block on disk */ -u64 allocblock(void *block) { +uint64_t allocblock(void *block) { return allocblock_hint(block, 0); } -bsq_t *allocblock_hint_indiv(int server, void *block, u64 hint) { +bsq_t *allocblock_hint_indiv(int server, void *block, uint64_t hint) { bsq_t *qe; int len; @@ -846,14 +846,14 @@ bsq_t *allocblock_hint_indiv(int server, void *block, u64 hint) { * * @return: new id of block on disk */ -u64 allocblock_hint(void *block, u64 hint) { +uint64_t allocblock_hint(void *block, uint64_t hint) { int map = (int)hint; int rep0 = bsclusters[map].servers[0]; int rep1 = bsclusters[map].servers[1]; int rep2 = bsclusters[map].servers[2]; bsq_t *reqs[3]; int rc; - u64 id0, id1, id2; + uint64_t id0, id1, id2; reqs[0] = reqs[1] = reqs[2] = NULL; @@ -938,7 +938,7 @@ u64 allocblock_hint(void *block, u64 hint) { * @return: pointer to block, NULL on error */ -void *readblock(u64 id) { +void *readblock(uint64_t id) { void *block; int block_fp; @@ -980,7 +980,7 @@ err: * * @return: zero on success, -1 on failure */ -int writeblock(u64 id, void *block) { +int writeblock(uint64_t id, void *block) { int block_fp; @@ -1014,8 +1014,8 @@ err: * @return: new id of block on disk */ -u64 allocblock(void *block) { - u64 lb; +uint64_t allocblock(void *block) { + uint64_t lb; off64_t pos; int block_fp; @@ -1057,7 +1057,7 @@ err: * * @return: new id of block on disk */ -u64 allocblock_hint(void *block, u64 hint) { +uint64_t allocblock_hint(void *block, uint64_t hint) { return allocblock(block); } @@ -1109,7 +1109,7 @@ static freeblock_t *new_freeblock(void) return fb; } -void releaseblock(u64 id) +void releaseblock(uint64_t id) { blockstore_super_t *bs_super; freeblock_t *fl_current; @@ -1154,7 +1154,7 @@ void freelist_count(int print_each) { blockstore_super_t *bs_super; freeblock_t *fb; - u64 total = 0, next; + uint64_t total = 0, next; bs_super = (blockstore_super_t *) readblock(BLOCKSTORE_SUPER); @@ -1205,7 +1205,7 @@ int __init_blockstore(void) { int i; blockstore_super_t *bs_super; - u64 ret; + uint64_t ret; int block_fp; #ifdef BLOCKSTORE_REMOTE diff --git a/tools/blktap/parallax/blockstore.h b/tools/blktap/parallax/blockstore.h index 9f2592ecf2..d96db32800 100644 --- a/tools/blktap/parallax/blockstore.h +++ b/tools/blktap/parallax/blockstore.h @@ -21,33 +21,33 @@ #define SECTOR_SHIFT 9 #endif -#define FREEBLOCK_SIZE (BLOCK_SIZE / sizeof(u64)) - (3 * sizeof(u64)) +#define FREEBLOCK_SIZE (BLOCK_SIZE / sizeof(uint64_t)) - (3 * sizeof(uint64_t)) #define FREEBLOCK_MAGIC 0x0fee0fee0fee0feeULL typedef struct { - u64 magic; - u64 next; - u64 count; - u64 list[FREEBLOCK_SIZE]; + uint64_t magic; + uint64_t next; + uint64_t count; + uint64_t list[FREEBLOCK_SIZE]; } freeblock_t; #define BLOCKSTORE_MAGIC 0xaaaaaaa00aaaaaaaULL #define BLOCKSTORE_SUPER 1ULL typedef struct { - u64 magic; - u64 freelist_full; - u64 freelist_current; + uint64_t magic; + uint64_t freelist_full; + uint64_t freelist_current; } blockstore_super_t; extern void *newblock(); -extern void *readblock(u64 id); -extern u64 allocblock(void *block); -extern u64 allocblock_hint(void *block, u64 hint); -extern int writeblock(u64 id, void *block); +extern void *readblock(uint64_t id); +extern uint64_t allocblock(void *block); +extern uint64_t allocblock_hint(void *block, uint64_t hint); +extern int writeblock(uint64_t id, void *block); /* Add this blockid to a freelist, to be recycled by the allocator. */ -extern void releaseblock(u64 id); +extern void releaseblock(uint64_t id); /* this is a memory free() operation for block-sized allocations */ extern void freeblock(void *block); @@ -55,17 +55,17 @@ extern int __init_blockstore(void); /* debug for freelist. */ void freelist_count(int print_each); -#define ALLOCFAIL (((u64)(-1))) +#define ALLOCFAIL (((uint64_t)(-1))) /* Distribution */ #define BLOCKSTORED_PORT 9346 struct bshdr_t_struct { - u32 operation; - u32 flags; - u64 id; - u64 luid; + uint32_t operation; + uint32_t flags; + uint64_t id; + uint64_t luid; } __attribute__ ((packed)); typedef struct bshdr_t_struct bshdr_t; @@ -76,9 +76,9 @@ struct bsmsg_t_struct { typedef struct bsmsg_t_struct bsmsg_t; -#define MSGBUFSIZE_OP sizeof(u32) -#define MSGBUFSIZE_FLAGS (sizeof(u32) + sizeof(u32)) -#define MSGBUFSIZE_ID (sizeof(u32) + sizeof(u32) + sizeof(u64) + sizeof(u64)) +#define MSGBUFSIZE_OP sizeof(uint32_t) +#define MSGBUFSIZE_FLAGS (sizeof(uint32_t) + sizeof(uint32_t)) +#define MSGBUFSIZE_ID (sizeof(uint32_t) + sizeof(uint32_t) + sizeof(uint64_t) + sizeof(uint64_t)) #define MSGBUFSIZE_BLOCK sizeof(bsmsg_t) #define BSOP_READBLOCK 0x01 @@ -113,9 +113,9 @@ typedef struct bsmsg_t_struct bsmsg_t; #define BSID_REPLICA2(_id) (((_id)>>40)&0xfffffULL) #define BSID_MAP(_id) (((_id)>>60)&0xfULL) -#define BSID(_map, _rep0, _rep1, _rep2) ((((u64)(_map))<<60) | \ - (((u64)(_rep2))<<40) | \ - (((u64)(_rep1))<<20) | ((u64)(_rep0))) +#define BSID(_map, _rep0, _rep1, _rep2) ((((uint64_t)(_map))<<60) | \ + (((uint64_t)(_rep2))<<40) | \ + (((uint64_t)(_rep1))<<20) | ((uint64_t)(_rep0))) typedef struct bsserver_t_struct { char *hostname; diff --git a/tools/blktap/parallax/blockstored.c b/tools/blktap/parallax/blockstored.c index 6b86cb182f..1ed2489b6c 100644 --- a/tools/blktap/parallax/blockstored.c +++ b/tools/blktap/parallax/blockstored.c @@ -21,9 +21,9 @@ //#define BSDEBUG -int readblock_into(u64 id, void *block); +int readblock_into(uint64_t id, void *block); -int open_socket(u16 port) { +int open_socket(uint16_t port) { struct sockaddr_in sn; int sock; @@ -75,7 +75,7 @@ void service_loop(void) { int rc, len; struct sockaddr_in from; size_t slen = sizeof(from); - u64 bid; + uint64_t bid; len = recvfrom(bssock, (void *)&msgbuf, sizeof(msgbuf), 0, (struct sockaddr *)&from, &slen); @@ -155,7 +155,7 @@ void service_loop(void) { * @return: 0 if OK, other on error */ -int readblock_into(u64 id, void *block) { +int readblock_into(uint64_t id, void *block) { if (lseek64(block_fp, ((off64_t) id - 1LL) * BLOCK_SIZE, SEEK_SET) < 0) { printf ("%Ld\n", (id - 1) * BLOCK_SIZE); perror("readblock lseek"); @@ -175,7 +175,7 @@ int readblock_into(u64 id, void *block) { * * @return: zero on success, -1 on failure */ -int writeblock(u64 id, void *block) { +int writeblock(uint64_t id, void *block) { if (lseek64(block_fp, ((off64_t) id - 1LL) * BLOCK_SIZE, SEEK_SET) < 0) { perror("writeblock lseek"); return -1; @@ -193,10 +193,10 @@ int writeblock(u64 id, void *block) { * * @return: new id of block on disk */ -static u64 lastblock = 0; +static uint64_t lastblock = 0; -u64 allocblock(void *block) { - u64 lb; +uint64_t allocblock(void *block) { + uint64_t lb; off64_t pos; retry: diff --git a/tools/blktap/parallax/bstest.c b/tools/blktap/parallax/bstest.c index 5476ea1b74..f81dd94e64 100644 --- a/tools/blktap/parallax/bstest.c +++ b/tools/blktap/parallax/bstest.c @@ -22,7 +22,7 @@ #include #include "blockstore.h" -int direct(char *host, u32 op, u64 id, int len) { +int direct(char *host, uint32_t op, uint64_t id, int len) { struct sockaddr_in sn, peer; int sock; bsmsg_t msgbuf; @@ -99,8 +99,8 @@ int direct(char *host, u32 op, u64 id, int len) { int main (int argc, char **argv) { - u32 op = 0; - u64 id = 0; + uint32_t op = 0; + uint64_t id = 0; int len = 0, rc; void *block; diff --git a/tools/blktap/parallax/parallax.c b/tools/blktap/parallax/parallax.c index 46cdec4496..822604dffa 100644 --- a/tools/blktap/parallax/parallax.c +++ b/tools/blktap/parallax/parallax.c @@ -330,8 +330,8 @@ pending_t pending_list[MAX_REQUESTS]; struct cb_param { pending_t *pent; int segment; - u64 sector; - u64 vblock; /* for debug printing -- can be removed. */ + uint64_t sector; + uint64_t vblock; /* for debug printing -- can be removed. */ }; static void read_cb(struct io_ret r, void *in_param) @@ -393,9 +393,9 @@ static void read_cb(struct io_ret r, void *in_param) int parallax_read(blkif_request_t *req, blkif_t *blkif) { blkif_response_t *rsp; - u64 vblock, gblock; + uint64_t vblock, gblock; vdi_t *vdi; - u64 sector; + uint64_t sector; int i; char *dpage, *spage; pending_t *pent; @@ -475,9 +475,9 @@ static void write_cb(struct io_ret r, void *in_param) int parallax_write(blkif_request_t *req, blkif_t *blkif) { blkif_response_t *rsp; - u64 sector; + uint64_t sector; int i, writable = 0; - u64 vblock, gblock; + uint64_t vblock, gblock; char *spage; unsigned long size, offset, start; vdi_t *vdi; diff --git a/tools/blktap/parallax/radix.c b/tools/blktap/parallax/radix.c index a9f148e336..2463d7223a 100644 --- a/tools/blktap/parallax/radix.c +++ b/tools/blktap/parallax/radix.c @@ -33,7 +33,7 @@ static int rcache_count = 0; typedef struct rcache_st { radix_tree_node *node; - u64 id; + uint64_t id; struct rcache_st *hash_next; struct rcache_st *cache_next; struct rcache_st *cache_prev; @@ -55,7 +55,7 @@ void __rcache_init(void) } -void rcache_write(u64 id, radix_tree_node *node) +void rcache_write(uint64_t id, radix_tree_node *node) { rcache_t *r, *tmp, **curs; @@ -135,7 +135,7 @@ done: pthread_mutex_unlock(&rcache_mutex); } -radix_tree_node *rcache_read(u64 id) +radix_tree_node *rcache_read(uint64_t id) { rcache_t *r, *tmp; radix_tree_node *node = NULL; @@ -181,7 +181,7 @@ done: } -void *rc_readblock(u64 id) +void *rc_readblock(uint64_t id) { void *ret; @@ -197,9 +197,9 @@ void *rc_readblock(u64 id) return(ret); } -u64 rc_allocblock(void *block) +uint64_t rc_allocblock(void *block) { - u64 ret; + uint64_t ret; ret = allocblock(block); @@ -209,7 +209,7 @@ u64 rc_allocblock(void *block) return(ret); } -int rc_writeblock(u64 id, void *block) +int rc_writeblock(uint64_t id, void *block) { int ret; @@ -233,9 +233,9 @@ radix_tree_node cloneblock(radix_tree_node block); * whether or not the block is writable, including the return * values of update and snapshot */ -u64 lookup(int height, u64 root, u64 key); -u64 update(int height, u64 root, u64 key, u64 val); -u64 snapshot(u64 root); +uint64_t lookup(int height, uint64_t root, uint64_t key); +uint64_t update(int height, uint64_t root, uint64_t key, uint64_t val); +uint64_t snapshot(uint64_t root); /** * cloneblock: clone an existing block in memory @@ -264,9 +264,9 @@ radix_tree_node cloneblock(radix_tree_node block) { * @return: value on success, zero on error */ -u64 lookup(int height, u64 root, u64 key) { +uint64_t lookup(int height, uint64_t root, uint64_t key) { radix_tree_node node; - u64 mask = ONE; + uint64_t mask = ONE; assert(key >> height == 0); @@ -275,7 +275,7 @@ u64 lookup(int height, u64 root, u64 key) { /* now carve off equal sized chunks at each step */ for (;;) { - u64 oldroot; + uint64_t oldroot; #ifdef DEBUG printf("lookup: height=%3d root=%3Ld offset=%3d%s\n", height, root, @@ -314,9 +314,9 @@ u64 lookup(int height, u64 root, u64 key) { * @returns: (possibly new) root id on success (with LSB=1), 0 on failure */ -u64 update(int height, u64 root, u64 key, u64 val) { +uint64_t update(int height, uint64_t root, uint64_t key, uint64_t val) { int offset; - u64 child; + uint64_t child; radix_tree_node node; /* base case--return val */ @@ -390,7 +390,7 @@ u64 update(int height, u64 root, u64 key, u64 val) { * * @return: new root node, 0 on error */ -u64 snapshot(u64 root) { +uint64_t snapshot(uint64_t root) { radix_tree_node node, newnode; if ((node = rc_readblock(getid(root))) == NULL) @@ -418,7 +418,7 @@ u64 snapshot(u64 root) { * child are okay...) */ -int collapse(int height, u64 proot, u64 croot) +int collapse(int height, uint64_t proot, uint64_t croot) { int i, numlinks, ret, total = 0; radix_tree_node pnode, cnode; @@ -480,7 +480,7 @@ int collapse(int height, u64 proot, u64 croot) } -void print_root(u64 root, int height, FILE *dot_f) +void print_root(uint64_t root, int height, FILE *dot_f) { FILE *f; int i; @@ -558,9 +558,9 @@ void print_root(u64 root, int height, FILE *dot_f) #ifdef RADIX_STANDALONE int main(int argc, char **argv) { - u64 key = ZERO, val = ZERO; - u64 root = writable(2ULL); - u64 p = ZERO, c = ZERO; + uint64_t key = ZERO, val = ZERO; + uint64_t root = writable(2ULL); + uint64_t p = ZERO, c = ZERO; int v; char buff[4096]; diff --git a/tools/blktap/parallax/radix.h b/tools/blktap/parallax/radix.h index 61ea2205f8..c091d6d8f6 100644 --- a/tools/blktap/parallax/radix.h +++ b/tools/blktap/parallax/radix.h @@ -24,7 +24,7 @@ #define RADIX_TREE_MAP_MASK 0x1ff #define RADIX_TREE_MAP_ENTRIES 512 -typedef u64 *radix_tree_node; +typedef uint64_t *radix_tree_node; /* @@ -33,11 +33,11 @@ typedef u64 *radix_tree_node; * whether or not the block is writable, including the return * values of update and snapshot */ -u64 lookup(int height, u64 root, u64 key); -u64 update(int height, u64 root, u64 key, u64 val); -u64 snapshot(u64 root); -int collapse(int height, u64 proot, u64 croot); -int isprivate(int height, u64 root, u64 key); +uint64_t lookup(int height, uint64_t root, uint64_t key); +uint64_t update(int height, uint64_t root, uint64_t key, uint64_t val); +uint64_t snapshot(uint64_t root); +int collapse(int height, uint64_t proot, uint64_t croot); +int isprivate(int height, uint64_t root, uint64_t key); void __rcache_init(void); diff --git a/tools/blktap/parallax/requests-async.c b/tools/blktap/parallax/requests-async.c index 45f98be67a..e89cb909ba 100755 --- a/tools/blktap/parallax/requests-async.c +++ b/tools/blktap/parallax/requests-async.c @@ -27,14 +27,14 @@ #endif struct block_info { - u32 crc; - u32 unused; + uint32_t crc; + uint32_t unused; }; struct io_req { enum { IO_OP_READ, IO_OP_WRITE } op; - u64 root; - u64 vaddr; + uint64_t root; + uint64_t vaddr; int state; io_cb_t cb; void *param; @@ -44,7 +44,7 @@ struct io_req { struct io_ret retval;/* holds the return while we unlock. */ char *block; /* the block to write */ radix_tree_node radix[3]; - u64 radix_addr[3]; + uint64_t radix_addr[3]; struct block_info bi; }; @@ -129,7 +129,7 @@ enum radix_offsets { static void read_cb(struct io_ret ret, void *param); static void write_cb(struct io_ret ret, void *param); -int vdi_read(vdi_t *vdi, u64 vaddr, io_cb_t cb, void *param) +int vdi_read(vdi_t *vdi, uint64_t vaddr, io_cb_t cb, void *param) { struct io_req *req; @@ -156,7 +156,7 @@ int vdi_read(vdi_t *vdi, u64 vaddr, io_cb_t cb, void *param) } -int vdi_write(vdi_t *vdi, u64 vaddr, char *block, +int vdi_write(vdi_t *vdi, uint64_t vaddr, char *block, io_cb_t cb, void *param) { struct io_req *req; @@ -177,8 +177,8 @@ int vdi_write(vdi_t *vdi, u64 vaddr, char *block, req->block = block; /* Todo: add a pseodoheader to the block to include some location */ /* information in the CRC as well. */ - req->bi.crc = (u32) crc32(0L, Z_NULL, 0); - req->bi.crc = (u32) crc32(req->bi.crc, block, BLOCK_SIZE); + req->bi.crc = (uint32_t) crc32(0L, Z_NULL, 0); + req->bi.crc = (uint32_t) crc32(req->bi.crc, block, BLOCK_SIZE); req->bi.unused = 0xdeadbeef; req->cb = cb; @@ -196,7 +196,7 @@ static void read_cb(struct io_ret ret, void *param) { struct io_req *req = (struct io_req *)param; radix_tree_node node; - u64 idx; + uint64_t idx; char *block; void *req_param; @@ -268,15 +268,15 @@ static void read_cb(struct io_ret ret, void *param) } case READ_DATA: { - u32 crc; + uint32_t crc; DPRINTF("READ_DATA\n"); block = IO_BLOCK(ret); if (block == NULL) goto fail; /* crc check */ - crc = (u32) crc32(0L, Z_NULL, 0); - crc = (u32) crc32(crc, block, BLOCK_SIZE); + crc = (uint32_t) crc32(0L, Z_NULL, 0); + crc = (uint32_t) crc32(crc, block, BLOCK_SIZE); if (crc != req->bi.crc) { /* TODO: add a retry loop here. */ /* Do this after the cache is added -- make sure to */ @@ -359,7 +359,7 @@ static void write_cb(struct io_ret r, void *param) { struct io_req *req = (struct io_req *)param; radix_tree_node node; - u64 a, addr; + uint64_t a, addr; void *req_param; struct block_info *bi; @@ -721,7 +721,7 @@ static void write_cb(struct io_ret r, void *param) } } -char *vdi_read_s(vdi_t *vdi, u64 vaddr) +char *vdi_read_s(vdi_t *vdi, uint64_t vaddr) { pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; char *block = NULL; @@ -742,7 +742,7 @@ char *vdi_read_s(vdi_t *vdi, u64 vaddr) } -int vdi_write_s(vdi_t *vdi, u64 vaddr, char *block) +int vdi_write_s(vdi_t *vdi, uint64_t vaddr, char *block) { pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER; int ret, result; diff --git a/tools/blktap/parallax/requests-async.h b/tools/blktap/parallax/requests-async.h index 331a18fb39..b917bb8f07 100755 --- a/tools/blktap/parallax/requests-async.h +++ b/tools/blktap/parallax/requests-async.h @@ -10,18 +10,18 @@ #define getid(x) (((x)>>1)&0x7fffffffffffffffLLU) #define iswritable(x) (((x) & 1LLU) != 0) #define writable(x) (((x) << 1) | 1LLU) -#define readonly(x) ((u64)((x) << 1)) +#define readonly(x) ((uint64_t)((x) << 1)) */ #define VADDR_MASK 0x0000000003ffffffLLU /* 26-bits = 256Gig */ #define VALID_VADDR(x) (((x) & VADDR_MASK) == (x)) -int vdi_read (vdi_t *vdi, u64 vaddr, io_cb_t cb, void *param); -int vdi_write(vdi_t *vdi, u64 vaddr, char *block, io_cb_t cb, void *param); +int vdi_read (vdi_t *vdi, uint64_t vaddr, io_cb_t cb, void *param); +int vdi_write(vdi_t *vdi, uint64_t vaddr, char *block, io_cb_t cb, void *param); /* synchronous versions: */ -char *vdi_read_s (vdi_t *vdi, u64 vaddr); -int vdi_write_s(vdi_t *vdi, u64 vaddr, char *block); +char *vdi_read_s (vdi_t *vdi, uint64_t vaddr); +int vdi_write_s(vdi_t *vdi, uint64_t vaddr, char *block); #define ERR_BAD_VADDR -1 #define ERR_NOMEM -2 diff --git a/tools/blktap/parallax/snaplog.c b/tools/blktap/parallax/snaplog.c index 072497fe72..ae0361e4f1 100644 --- a/tools/blktap/parallax/snaplog.c +++ b/tools/blktap/parallax/snaplog.c @@ -24,7 +24,7 @@ -snap_block_t *snap_get_block(u64 block) +snap_block_t *snap_get_block(uint64_t block) { snap_block_t *blk = (snap_block_t *)readblock(block); diff --git a/tools/blktap/parallax/snaplog.h b/tools/blktap/parallax/snaplog.h index 02748bdedb..4d3fae1ed9 100644 --- a/tools/blktap/parallax/snaplog.h +++ b/tools/blktap/parallax/snaplog.h @@ -13,12 +13,12 @@ #define __SNAPLOG_H__ typedef struct snap_id { - u64 block; + uint64_t block; unsigned int index; } snap_id_t; typedef struct snap_rec { - u64 radix_root; + uint64_t radix_root; struct timeval timestamp; /* flags: */ unsigned deleted:1; @@ -38,7 +38,7 @@ int snap_get_id(snap_id_t *id, snap_rec_t *target); static const snap_id_t null_snap_id = { 0, 0 }; typedef struct snap_block_hdr { - u64 magic; + uint64_t magic; snap_id_t parent_block; /* parent block within this chain */ snap_id_t fork_block; /* where this log was forked */ unsigned log_entries; /* total entries since forking */ @@ -56,6 +56,6 @@ typedef struct snap_block { } snap_block_t; -snap_block_t *snap_get_block(u64 block); +snap_block_t *snap_get_block(uint64_t block); #endif /* __SNAPLOG_H__ */ diff --git a/tools/blktap/parallax/vdi.c b/tools/blktap/parallax/vdi.c index f3181b86b2..8b8b4a357b 100644 --- a/tools/blktap/parallax/vdi.c +++ b/tools/blktap/parallax/vdi.c @@ -132,9 +132,9 @@ vdi_t *vdi_create(snap_id_t *parent_snap, char *name) /* vdi_get and vdi_put currently act more like alloc/free -- they don't * do refcount-based allocation. */ -vdi_t *vdi_get(u64 vdi_id) +vdi_t *vdi_get(uint64_t vdi_id) { - u64 vdi_blk; + uint64_t vdi_blk; vdi_t *vdi; vdi_blk = lookup(VDI_REG_HEIGHT, VDI_RADIX_ROOT, vdi_id); diff --git a/tools/blktap/parallax/vdi.h b/tools/blktap/parallax/vdi.h index 462fa03299..71a73f88ab 100644 --- a/tools/blktap/parallax/vdi.h +++ b/tools/blktap/parallax/vdi.h @@ -21,9 +21,9 @@ typedef struct vdi { - u64 id; /* unique vdi id -- used by the registry */ - u64 block; /* block where this vdi lives (also unique)*/ - u64 radix_root; /* radix root node for block mappings */ + uint64_t id; /* unique vdi id -- used by the registry */ + uint64_t block; /* block where this vdi lives (also unique)*/ + uint64_t radix_root; /* radix root node for block mappings */ snap_id_t snap; /* next snapshot slot for this VDI */ struct vdi *next; /* used to hash-chain in blkif. */ blkif_vdev_t vdevice; /* currently mounted as... */ @@ -34,19 +34,19 @@ typedef struct vdi { #define VDI_REG_MAGIC 0xff00ff0bb0ff00ffLL typedef struct vdi_registry { - u64 magic; - u64 nr_vdis; + uint64_t magic; + uint64_t nr_vdis; } vdi_registry_t; int __init_vdi(void); -vdi_t *vdi_get(u64 vdi_id); +vdi_t *vdi_get(uint64_t vdi_id); void vdi_put(vdi_t *vdi); vdi_registry_t *get_vdi_registry(void); vdi_t *vdi_create(snap_id_t *parent_snap, char *name); -u64 vdi_lookup_block(vdi_t *vdi, u64 vdi_block, int *writable); -void vdi_update_block(vdi_t *vdi, u64 vdi_block, u64 g_block); +uint64_t vdi_lookup_block(vdi_t *vdi, uint64_t vdi_block, int *writable); +void vdi_update_block(vdi_t *vdi, uint64_t vdi_block, uint64_t g_block); void vdi_snapshot(vdi_t *vdi); diff --git a/tools/blktap/parallax/vdi_create.c b/tools/blktap/parallax/vdi_create.c index 1d40b86c24..329d205d3b 100644 --- a/tools/blktap/parallax/vdi_create.c +++ b/tools/blktap/parallax/vdi_create.c @@ -33,7 +33,7 @@ int main(int argc, char *argv[]) name[VDI_NAME_SZ] = '\0'; if ( argc > 3 ) { - id.block = (u64) atoll(argv[2]); + id.block = (uint64_t) atoll(argv[2]); id.index = (unsigned int) atol (argv[3]); from_snap = 1; } diff --git a/tools/blktap/parallax/vdi_fill.c b/tools/blktap/parallax/vdi_fill.c index 61025862f7..b4270087e0 100644 --- a/tools/blktap/parallax/vdi_fill.c +++ b/tools/blktap/parallax/vdi_fill.c @@ -22,13 +22,13 @@ int main(int argc, char *argv[]) { vdi_t *vdi; - u64 id; + uint64_t id; int fd; struct stat st; - u64 tot_size; + uint64_t tot_size; char spage[BLOCK_SIZE]; char *dpage; - u64 vblock = 0, count=0; + uint64_t vblock = 0, count=0; __init_blockstore(); init_block_async(); @@ -39,7 +39,7 @@ int main(int argc, char *argv[]) exit(-1); } - id = (u64) atoll(argv[1]); + id = (uint64_t) atoll(argv[1]); vdi = vdi_get( id ); @@ -60,7 +60,7 @@ int main(int argc, char *argv[]) exit(-1); } - tot_size = (u64) st.st_size; + tot_size = (uint64_t) st.st_size; printf("Filling VDI %Ld with %Ld bytes.\n", id, tot_size); printf("%011Ld blocks total\n", tot_size / BLOCK_SIZE); diff --git a/tools/blktap/parallax/vdi_snap.c b/tools/blktap/parallax/vdi_snap.c index 3b09898dc6..059753e434 100644 --- a/tools/blktap/parallax/vdi_snap.c +++ b/tools/blktap/parallax/vdi_snap.c @@ -17,7 +17,7 @@ int main(int argc, char *argv[]) { vdi_t *vdi; - u64 id; + uint64_t id; __init_blockstore(); __init_vdi(); @@ -27,7 +27,7 @@ int main(int argc, char *argv[]) exit(-1); } - id = (u64) atoll(argv[1]); + id = (uint64_t) atoll(argv[1]); vdi = vdi_get(id); diff --git a/tools/blktap/parallax/vdi_snap_delete.c b/tools/blktap/parallax/vdi_snap_delete.c index 0160ccad83..32b5a4e739 100644 --- a/tools/blktap/parallax/vdi_snap_delete.c +++ b/tools/blktap/parallax/vdi_snap_delete.c @@ -34,7 +34,7 @@ int main(int argc, char *argv[]) exit(-1); } - id.block = (u64) atoll(argv[1]); + id.block = (uint64_t) atoll(argv[1]); id.index = (unsigned int) atol (argv[2]); c_id = id; diff --git a/tools/blktap/parallax/vdi_snap_list.c b/tools/blktap/parallax/vdi_snap_list.c index 044397495d..e94915a223 100644 --- a/tools/blktap/parallax/vdi_snap_list.c +++ b/tools/blktap/parallax/vdi_snap_list.c @@ -18,7 +18,7 @@ int main(int argc, char *argv[]) { vdi_t *vdi; - u64 id; + uint64_t id; int i, max_snaps = -1; snap_block_t *blk; snap_id_t sid; @@ -32,7 +32,7 @@ int main(int argc, char *argv[]) exit(-1); } - id = (u64) atoll(argv[1]); + id = (uint64_t) atoll(argv[1]); if ( argc > 2 ) { max_snaps = atoi(argv[2]); diff --git a/tools/blktap/parallax/vdi_unittest.c b/tools/blktap/parallax/vdi_unittest.c index 77ecc833be..e988f8e771 100644 --- a/tools/blktap/parallax/vdi_unittest.c +++ b/tools/blktap/parallax/vdi_unittest.c @@ -39,9 +39,9 @@ void fill_test_pages(void) zero_page = newblock(); } -inline u64 make_vaddr(u64 L1, u64 L2, u64 L3) +inline uint64_t make_vaddr(uint64_t L1, uint64_t L2, uint64_t L3) { - u64 ret = L1; + uint64_t ret = L1; ret = (ret << 9) | L2; ret = (ret << 9) | L3; @@ -49,9 +49,9 @@ inline u64 make_vaddr(u64 L1, u64 L2, u64 L3) return ret; } -void touch_block(vdi_t *vdi, u64 L1, u64 L2, u64 L3) +void touch_block(vdi_t *vdi, uint64_t L1, uint64_t L2, uint64_t L3) { - u64 vaddr; + uint64_t vaddr; char *page = pages[next_page++]; char *rpage = NULL; @@ -76,9 +76,9 @@ void touch_block(vdi_t *vdi, u64 L1, u64 L2, u64 L3) freeblock(rpage); } -void test_block(vdi_t *vdi, u64 L1, u64 L2, u64 L3, char *page) +void test_block(vdi_t *vdi, uint64_t L1, uint64_t L2, uint64_t L3, char *page) { - u64 vaddr; + uint64_t vaddr; char *rpage = NULL; printf("TEST (%3Lu, %3Lu, %3Lu)\n", L1, L2, L3); @@ -103,7 +103,7 @@ void test_block(vdi_t *vdi, u64 L1, u64 L2, u64 L3, char *page) void coverage_test(vdi_t *vdi) { - u64 vaddr; + uint64_t vaddr; int i, j, k; /* Do a series of writes and reads to test all paths through the @@ -155,13 +155,13 @@ void coverage_test(vdi_t *vdi) int main(int argc, char *argv[]) { vdi_t *vdi; - u64 id; + uint64_t id; int fd; struct stat st; - u64 tot_size; + uint64_t tot_size; char spage[BLOCK_SIZE]; char *dpage; - u64 vblock = 0, count=0; + uint64_t vblock = 0, count=0; __init_blockstore(); init_block_async(); diff --git a/tools/blktap/parallax/vdi_validate.c b/tools/blktap/parallax/vdi_validate.c index de7a62d3e9..01d72c5c89 100644 --- a/tools/blktap/parallax/vdi_validate.c +++ b/tools/blktap/parallax/vdi_validate.c @@ -23,13 +23,13 @@ int main(int argc, char *argv[]) { vdi_t *vdi; - u64 id; + uint64_t id; int fd; struct stat st; - u64 tot_size; + uint64_t tot_size; char spage[BLOCK_SIZE], *dpage; char *vpage; - u64 vblock = 0, count=0; + uint64_t vblock = 0, count=0; __init_blockstore(); init_block_async(); @@ -40,7 +40,7 @@ int main(int argc, char *argv[]) exit(-1); } - id = (u64) atoll(argv[1]); + id = (uint64_t) atoll(argv[1]); vdi = vdi_get( id ); @@ -61,7 +61,7 @@ int main(int argc, char *argv[]) exit(-1); } - tot_size = (u64) st.st_size; + tot_size = (uint64_t) st.st_size; printf("Testing VDI %Ld (%Ld bytes).\n", id, tot_size); printf(" "); diff --git a/tools/blktap/ublkback/ublkbacklib.c b/tools/blktap/ublkback/ublkbacklib.c index 767be7b5e3..28b2a92806 100644 --- a/tools/blktap/ublkback/ublkbacklib.c +++ b/tools/blktap/ublkback/ublkbacklib.c @@ -112,7 +112,7 @@ int ublkback_response(blkif_t *blkif, blkif_response_t *rsp, int batch_done); typedef struct image { /* These need to turn into an array/rbtree for multi-disk support. */ int fd; - u64 fsid; + uint64_t fsid; blkif_vdev_t vdevice; long int size; long int secsize; @@ -190,7 +190,7 @@ int ublkback_new_blkif(blkif_t *blkif) } */ if (image->size == 0) - image->size =((u64) 16836057); + image->size =((uint64_t) 16836057); image->secsize = 512; image->info = 0; @@ -215,7 +215,7 @@ static int batch_count = 0; int ublkback_request(blkif_t *blkif, blkif_request_t *req, int batch_done) { int fd; - u64 sector; + uint64_t sector; char *spage, *dpage; int ret, i, idx; blkif_response_t *rsp; diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index 990303b5e8..fc772b7580 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -474,7 +474,7 @@ static void handle_tty_write(struct domain *dom) static void handle_ring_read(struct domain *dom) { - u16 v; + uint16_t v; if (!read_sync(dom->evtchn_fd, &v, sizeof(v))) return; diff --git a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c index 8d7ff017bf..dcc56cb3d5 100644 --- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c +++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/linux-xen-low.c @@ -38,7 +38,7 @@ #include #define TRACE_ENTER /* printf("enter %s\n", __FUNCTION__) */ -long (*myptrace)(int xc_handle, enum __ptrace_request, u32, long, long); +long (*myptrace)(int xc_handle, enum __ptrace_request, uint32_t, long, long); int (*myxcwait)(int xc_handle, int domain, int *status, int options) ; static int xc_handle; diff --git a/tools/debugger/libxendebug/xendebug.c b/tools/debugger/libxendebug/xendebug.c index f0d8be326f..cb939a7424 100644 --- a/tools/debugger/libxendebug/xendebug.c +++ b/tools/debugger/libxendebug/xendebug.c @@ -41,8 +41,8 @@ typedef struct bwcpoint /* break/watch/catch point */ { struct list_head list; unsigned long address; - u32 domain; - u8 old_value; /* old value for software bkpt */ + uint32_t domain; + uint8_t old_value; /* old value for software bkpt */ } bwcpoint_t, *bwcpoint_p; static bwcpoint_t bwcpoint_list; @@ -52,7 +52,7 @@ static bwcpoint_t bwcpoint_list; typedef struct domain_context /* local cache of domain state */ { struct list_head list; - u32 domid; + uint32_t domid; boolean valid[MAX_VIRT_CPUS]; vcpu_guest_context_t context[MAX_VIRT_CPUS]; @@ -92,7 +92,7 @@ xendebug_initialize() /**************/ static domain_context_p -xendebug_domain_context_search (u32 domid) +xendebug_domain_context_search (uint32_t domid) { struct list_head *entry; domain_context_p ctxt; @@ -107,7 +107,7 @@ xendebug_domain_context_search (u32 domid) } static __inline__ domain_context_p -xendebug_get_context (int xc_handle, u32 domid, u32 vcpu) +xendebug_get_context (int xc_handle, uint32_t domid, uint32_t vcpu) { int rc; domain_context_p ctxt; @@ -130,7 +130,7 @@ xendebug_get_context (int xc_handle, u32 domid, u32 vcpu) } static __inline__ int -xendebug_set_context (int xc_handle, domain_context_p ctxt, u32 vcpu) +xendebug_set_context (int xc_handle, domain_context_p ctxt, uint32_t vcpu) { dom0_op_t op; int rc; @@ -157,8 +157,8 @@ xendebug_set_context (int xc_handle, domain_context_p ctxt, u32 vcpu) int xendebug_attach(int xc_handle, - u32 domid, - u32 vcpu) + uint32_t domid, + uint32_t vcpu) { domain_context_p ctxt; @@ -176,8 +176,8 @@ xendebug_attach(int xc_handle, int xendebug_detach(int xc_handle, - u32 domid, - u32 vcpu) + uint32_t domid, + uint32_t vcpu) { domain_context_p ctxt; @@ -197,8 +197,8 @@ xendebug_detach(int xc_handle, int xendebug_read_registers(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, cpu_user_regs_t **regs) { domain_context_p ctxt; @@ -218,8 +218,8 @@ xendebug_read_registers(int xc_handle, int xendebug_read_fpregisters (int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, char **regs) { domain_context_p ctxt; @@ -239,8 +239,8 @@ xendebug_read_fpregisters (int xc_handle, int xendebug_write_registers(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, cpu_user_regs_t *regs) { domain_context_p ctxt; @@ -260,8 +260,8 @@ xendebug_write_registers(int xc_handle, int xendebug_step(int xc_handle, - u32 domid, - u32 vcpu) + uint32_t domid, + uint32_t vcpu) { domain_context_p ctxt; int rc; @@ -282,8 +282,8 @@ xendebug_step(int xc_handle, int xendebug_continue(int xc_handle, - u32 domid, - u32 vcpu) + uint32_t domid, + uint32_t vcpu) { domain_context_p ctxt; int rc; @@ -310,8 +310,8 @@ xendebug_continue(int xc_handle, /* access to one page */ static int -xendebug_memory_page (domain_context_p ctxt, int xc_handle, u32 vcpu, - int protection, unsigned long address, int length, u8 *buffer) +xendebug_memory_page (domain_context_p ctxt, int xc_handle, uint32_t vcpu, + int protection, unsigned long address, int length, uint8_t *buffer) { vcpu_guest_context_t *vcpu_ctxt = &ctxt->context[vcpu]; unsigned long pde, page; @@ -406,8 +406,8 @@ xendebug_memory_page (domain_context_p ctxt, int xc_handle, u32 vcpu, /* divide a memory operation into accesses to individual pages */ static int -xendebug_memory_op (domain_context_p ctxt, int xc_handle, u32 vcpu, - int protection, unsigned long address, int length, u8 *buffer) +xendebug_memory_op (domain_context_p ctxt, int xc_handle, uint32_t vcpu, + int protection, unsigned long address, int length, uint8_t *buffer) { int remain; /* number of bytes to touch past this page */ int bytes = 0; @@ -429,11 +429,11 @@ xendebug_memory_op (domain_context_p ctxt, int xc_handle, u32 vcpu, int xendebug_read_memory(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, unsigned long address, - u32 length, - u8 *data) + uint32_t length, + uint8_t *data) { domain_context_p ctxt; @@ -449,11 +449,11 @@ xendebug_read_memory(int xc_handle, int xendebug_write_memory(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, unsigned long address, - u32 length, - u8 *data) + uint32_t length, + uint8_t *data) { domain_context_p ctxt; @@ -469,13 +469,13 @@ xendebug_write_memory(int xc_handle, int xendebug_insert_memory_breakpoint(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, unsigned long address, - u32 length) + uint32_t length) { bwcpoint_p bkpt; - u8 breakpoint_opcode = 0xcc; + uint8_t breakpoint_opcode = 0xcc; printf("insert breakpoint %d:%lx %d\n", domid, address, length); @@ -515,10 +515,10 @@ xendebug_insert_memory_breakpoint(int xc_handle, int xendebug_remove_memory_breakpoint(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, unsigned long address, - u32 length) + uint32_t length) { bwcpoint_p bkpt = NULL; @@ -552,7 +552,7 @@ int xendebug_query_domain_stop(int xc_handle, int *dom_list, int dom_list_size) { xc_dominfo_t *info; - u32 first_dom = 0; + uint32_t first_dom = 0; int max_doms = 1024; int nr_doms, loop; int count = 0; diff --git a/tools/debugger/libxendebug/xendebug.h b/tools/debugger/libxendebug/xendebug.h index 41be10df5f..dfd2c3e2d3 100644 --- a/tools/debugger/libxendebug/xendebug.h +++ b/tools/debugger/libxendebug/xendebug.h @@ -12,63 +12,63 @@ #include int xendebug_attach(int xc_handle, - u32 domid, - u32 vcpu); + uint32_t domid, + uint32_t vcpu); int xendebug_detach(int xc_handle, - u32 domid, - u32 vcpu); + uint32_t domid, + uint32_t vcpu); int xendebug_read_registers(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, cpu_user_regs_t **regs); int xendebug_read_fpregisters (int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, char **regs); int xendebug_write_registers(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, cpu_user_regs_t *regs); int xendebug_step(int xc_handle, - u32 domid, - u32 vcpu); + uint32_t domid, + uint32_t vcpu); int xendebug_continue(int xc_handle, - u32 domid, - u32 vcpu); + uint32_t domid, + uint32_t vcpu); int xendebug_read_memory(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, unsigned long address, - u32 length, - u8 *data); + uint32_t length, + uint8_t *data); int xendebug_write_memory(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, unsigned long address, - u32 length, - u8 *data); + uint32_t length, + uint8_t *data); int xendebug_insert_memory_breakpoint(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, unsigned long address, - u32 length); + uint32_t length); int xendebug_remove_memory_breakpoint(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, unsigned long address, - u32 length); + uint32_t length); int xendebug_query_domain_stop(int xc_handle, int *dom_list, diff --git a/tools/debugger/pdb/linux-2.6-module/debug.c b/tools/debugger/pdb/linux-2.6-module/debug.c index 00955313f5..03d306ddde 100644 --- a/tools/debugger/pdb/linux-2.6-module/debug.c +++ b/tools/debugger/pdb/linux-2.6-module/debug.c @@ -29,13 +29,13 @@ typedef struct bwcpoint /* break/watch/catch point */ unsigned long address; int length; - u8 type; /* BWC_??? */ - u8 mode; /* for BWC_PAGE, the current protection mode */ - u32 process; - u8 error; /* error occured when enabling: don't disable. */ + uint8_t type; /* BWC_??? */ + uint8_t mode; /* for BWC_PAGE, the current protection mode */ + uint32_t process; + uint8_t error; /* error occured when enabling: don't disable. */ /* original values */ - u8 orig_bkpt; /* single byte breakpoint */ + uint8_t orig_bkpt; /* single byte breakpoint */ pte_t orig_pte; struct list_head watchpt_read_list; /* read watchpoints on this page */ @@ -109,7 +109,7 @@ pdb_bwc_print_list (void) } bwcpoint_p -pdb_search_watchpoint (u32 process, unsigned long address) +pdb_search_watchpoint (uint32_t process, unsigned long address) { bwcpoint_p bwc_watch = (bwcpoint_p) 0; bwcpoint_p bwc_entry = (bwcpoint_p) 0; @@ -150,7 +150,7 @@ pdb_search_watchpoint (u32 process, unsigned long address) int pdb_suspend (struct task_struct *target) { - u32 rc = 0; + uint32_t rc = 0; force_sig(SIGSTOP, target); /* force_sig_specific ??? */ @@ -364,11 +364,11 @@ pdb_step (struct task_struct *target) int pdb_insert_memory_breakpoint (struct task_struct *target, - unsigned long address, u32 length) + unsigned long address, uint32_t length) { int rc = 0; bwcpoint_p bkpt; - u8 breakpoint_opcode = 0xcc; + uint8_t breakpoint_opcode = 0xcc; printk("insert breakpoint %d:%lx len: %d\n", target->pid, address, length); @@ -399,7 +399,7 @@ pdb_insert_memory_breakpoint (struct task_struct *target, int pdb_remove_memory_breakpoint (struct task_struct *target, - unsigned long address, u32 length) + unsigned long address, uint32_t length) { int rc = 0; bwcpoint_p bkpt = NULL; diff --git a/tools/debugger/pdb/linux-2.6-module/pdb_debug.h b/tools/debugger/pdb/linux-2.6-module/pdb_debug.h index 7993464c31..89adbc0b0d 100644 --- a/tools/debugger/pdb/linux-2.6-module/pdb_debug.h +++ b/tools/debugger/pdb/linux-2.6-module/pdb_debug.h @@ -18,9 +18,9 @@ int pdb_continue (struct task_struct *target); int pdb_step (struct task_struct *target); int pdb_insert_memory_breakpoint (struct task_struct *target, - unsigned long address, u32 length); + unsigned long address, uint32_t length); int pdb_remove_memory_breakpoint (struct task_struct *target, - unsigned long address, u32 length); + unsigned long address, uint32_t length); int pdb_insert_watchpoint (struct task_struct *target, pdb_op_watchpt_p watchpt); int pdb_remove_watchpoint (struct task_struct *target, diff --git a/tools/debugger/pdb/linux-2.6-module/pdb_module.h b/tools/debugger/pdb/linux-2.6-module/pdb_module.h index a7e679ecdf..472403d69e 100644 --- a/tools/debugger/pdb/linux-2.6-module/pdb_module.h +++ b/tools/debugger/pdb/linux-2.6-module/pdb_module.h @@ -9,7 +9,7 @@ #define PDB_OPCODE_ATTACH 2 typedef struct pdb_op_attach { - u32 domain; + uint32_t domain; } pdb_op_attach_t, *pdb_op_attach_p; #define PDB_OPCODE_DETACH 3 @@ -17,43 +17,43 @@ typedef struct pdb_op_attach #define PDB_OPCODE_RD_REG 4 typedef struct pdb_op_rd_reg { - u32 reg; - u32 value; + uint32_t reg; + uint32_t value; } pdb_op_rd_reg_t, *pdb_op_rd_reg_p; #define PDB_OPCODE_RD_REGS 5 typedef struct pdb_op_rd_regs { - u32 reg[GDB_REGISTER_FRAME_SIZE]; + uint32_t reg[GDB_REGISTER_FRAME_SIZE]; } pdb_op_rd_regs_t, *pdb_op_rd_regs_p; #define PDB_OPCODE_WR_REG 6 typedef struct pdb_op_wr_reg { - u32 reg; - u32 value; + uint32_t reg; + uint32_t value; } pdb_op_wr_reg_t, *pdb_op_wr_reg_p; #define PDB_OPCODE_RD_MEM 7 typedef struct pdb_op_rd_mem_req { - u32 address; - u32 length; + uint32_t address; + uint32_t length; } pdb_op_rd_mem_req_t, *pdb_op_rd_mem_req_p; typedef struct pdb_op_rd_mem_resp { - u32 address; - u32 length; - u8 data[1024]; + uint32_t address; + uint32_t length; + uint8_t data[1024]; } pdb_op_rd_mem_resp_t, *pdb_op_rd_mem_resp_p; #define PDB_OPCODE_WR_MEM 8 typedef struct pdb_op_wr_mem { - u32 address; - u32 length; - u8 data[1024]; /* arbitrary */ + uint32_t address; + uint32_t length; + uint8_t data[1024]; /* arbitrary */ } pdb_op_wr_mem_t, *pdb_op_wr_mem_p; #define PDB_OPCODE_CONTINUE 9 @@ -63,8 +63,8 @@ typedef struct pdb_op_wr_mem #define PDB_OPCODE_CLR_BKPT 12 typedef struct pdb_op_bkpt { - u32 address; - u32 length; + uint32_t address; + uint32_t length; } pdb_op_bkpt_t, *pdb_op_bkpt_p; #define PDB_OPCODE_SET_WATCHPT 13 @@ -79,16 +79,16 @@ typedef struct pdb_op_watchpt #define BWC_WATCH_WRITE 102 #define BWC_WATCH_READ 103 #define BWC_WATCH_ACCESS 104 - u32 type; - u32 address; - u32 length; + uint32_t type; + uint32_t address; + uint32_t length; } pdb_op_watchpt_t, *pdb_op_watchpt_p; typedef struct { - u8 operation; /* PDB_OPCODE_??? */ - u32 process; + uint8_t operation; /* PDB_OPCODE_??? */ + uint32_t process; union { pdb_op_attach_t attach; @@ -107,10 +107,10 @@ typedef struct #define PDB_RESPONSE_ERROR -1 typedef struct { - u8 operation; /* copied from request */ - u32 domain; - u32 process; - s16 status; /* PDB_RESPONSE_??? */ + uint8_t operation; /* copied from request */ + uint32_t domain; + uint32_t process; + int16_t status; /* PDB_RESPONSE_??? */ union { pdb_op_rd_reg_t rd_reg; diff --git a/tools/debugger/pdb/pdb_caml_domain.c b/tools/debugger/pdb/pdb_caml_domain.c index 482f7df5fa..15058ffb45 100644 --- a/tools/debugger/pdb/pdb_caml_domain.c +++ b/tools/debugger/pdb/pdb_caml_domain.c @@ -204,7 +204,7 @@ dom_read_memory (value context, value address, value length) int loop; char *buffer; unsigned long my_address = Int32_val(address); - u32 my_length = Int_val(length); + uint32_t my_length = Int_val(length); printf ("(pdb) read memory\n"); @@ -260,7 +260,7 @@ dom_write_memory (value context, value address, value val_list) char buffer[4096]; /* a big buffer */ unsigned long my_address; - u32 length = 0; + uint32_t length = 0; printf ("(pdb) write memory\n"); diff --git a/tools/debugger/pdb/pdb_caml_evtchn.c b/tools/debugger/pdb/pdb_caml_evtchn.c index 0a3e0ae823..8107814156 100644 --- a/tools/debugger/pdb/pdb_caml_evtchn.c +++ b/tools/debugger/pdb/pdb_caml_evtchn.c @@ -125,7 +125,7 @@ evtchn_read (value fd) { CAMLparam1(fd); - u16 v; + uint16_t v; int bytes; int rc = -1; int myfd = Int_val(fd); @@ -168,7 +168,7 @@ evtchn_unmask (value fd, value idx) CAMLparam1(fd); int myfd = Int_val(fd); - u16 myidx = Int_val(idx); + uint16_t myidx = Int_val(idx); (void)write(myfd, &myidx, sizeof(myidx)); diff --git a/tools/debugger/pdb/pdb_caml_process.c b/tools/debugger/pdb/pdb_caml_process.c index c91a01147a..f332e1653e 100644 --- a/tools/debugger/pdb/pdb_caml_process.c +++ b/tools/debugger/pdb/pdb_caml_process.c @@ -404,7 +404,7 @@ proc_write_memory (value context, value address, value val_list) context_t ctx; pdb_request_t req; - u32 length = 0; + uint32_t length = 0; decode_context(&ctx, context); diff --git a/tools/debugger/pdb/pdb_caml_xc.c b/tools/debugger/pdb/pdb_caml_xc.c index 1bd1fdfb01..6a1fe8e492 100644 --- a/tools/debugger/pdb/pdb_caml_xc.c +++ b/tools/debugger/pdb/pdb_caml_xc.c @@ -151,7 +151,7 @@ evtchn_bind_interdomain (value remote_domain) } void * -map_ring(u32 dom, unsigned long mfn ) +map_ring(uint32_t dom, unsigned long mfn ) { return xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, mfn); diff --git a/tools/debugger/pdb/pdb_caml_xcs.c b/tools/debugger/pdb/pdb_caml_xcs.c index cdf4ddb4b5..974cf83925 100644 --- a/tools/debugger/pdb/pdb_caml_xcs.c +++ b/tools/debugger/pdb/pdb_caml_xcs.c @@ -36,7 +36,7 @@ static int control_fd = -1; #include "pdb_module.h" #include "pdb_caml_xen.h" -void *map_ring(u32 dom, unsigned long mfn ); +void *map_ring(uint32_t dom, unsigned long mfn ); /* * xcs_initialize_ring : int -> int32 -> int32 @@ -180,7 +180,7 @@ xcs_connect (value path, value msg_type) char *my_path = String_val(path); int my_msg_type = Int_val(msg_type); struct sockaddr_un addr; - u32 session_id = 0; + uint32_t session_id = 0; int data_fd; int ret, len; xcs_msg_t msg; diff --git a/tools/firmware/acpi/acpi2_0.h b/tools/firmware/acpi/acpi2_0.h index 4136b3f74a..5cdb0a6203 100644 --- a/tools/firmware/acpi/acpi2_0.h +++ b/tools/firmware/acpi/acpi2_0.h @@ -18,7 +18,21 @@ #ifndef _ACPI_2_0_H_ #define _ACPI_2_0_H_ -#include "xenctrl.h" // for u8, u16, u32, u64 definition +typedef unsigned char uint8_t; +typedef signed char int8_t; +typedef unsigned short uint16_t; +typedef signed short int16_t; +typedef unsigned int uint32_t; +typedef signed int int32_t; +#ifdef __i386__ +typedef unsigned long long uint64_t; +typedef signed long long int64_t; +#else +typedef unsigned long uint64_t; +typedef signed long int64_t; +#endif + +#include #pragma pack (1) @@ -27,15 +41,15 @@ // typedef struct { - u32 Signature; - u32 Length; - u8 Revision; - u8 Checksum; - u8 OemId[6]; - u64 OemTableId; - u32 OemRevision; - u32 CreatorId; - u32 CreatorRevision; + uint32_t Signature; + uint32_t Length; + uint8_t Revision; + uint8_t Checksum; + uint8_t OemId[6]; + uint64_t OemTableId; + uint32_t OemRevision; + uint32_t CreatorId; + uint32_t CreatorRevision; } ACPI_TABLE_HEADER; @@ -49,11 +63,11 @@ typedef struct { // ACPI 2.0 Generic Address Space definition // typedef struct { - u8 AddressSpaceId; - u8 RegisterBitWidth; - u8 RegisterBitOffset; - u8 Reserved; - u64 Address; + uint8_t AddressSpaceId; + uint8_t RegisterBitWidth; + uint8_t RegisterBitOffset; + uint8_t Reserved; + uint64_t Address; } ACPI_GENERIC_ADDRESS_STRUCTURE; // @@ -70,11 +84,11 @@ typedef struct { // Root System Description Pointer Structure in ACPI 1.0 // typedef struct { - u64 Signature; - u8 Checksum; - u8 OemId[6]; - u8 Reserved; - u32 RsdtAddress; + uint64_t Signature; + uint8_t Checksum; + uint8_t OemId[6]; + uint8_t Reserved; + uint32_t RsdtAddress; } ACPI_1_0_RSDP; @@ -82,15 +96,15 @@ typedef struct { // Root System Description Pointer Structure // typedef struct { - u64 Signature; - u8 Checksum; - u8 OemId[6]; - u8 Revision; - u32 RsdtAddress; - u32 Length; - u64 XsdtAddress; - u8 ExtendedChecksum; - u8 Reserved[3]; + uint64_t Signature; + uint8_t Checksum; + uint8_t OemId[6]; + uint8_t Revision; + uint32_t RsdtAddress; + uint32_t Length; + uint64_t XsdtAddress; + uint8_t ExtendedChecksum; + uint8_t Reserved[3]; } ACPI_2_0_RSDP; @@ -105,7 +119,7 @@ typedef struct { typedef struct { ACPI_TABLE_HEADER Header; - u32 Entry[ACPI_MAX_NUM_TABLES]; + uint32_t Entry[ACPI_MAX_NUM_TABLES]; }ACPI_2_0_RSDT; // @@ -120,7 +134,7 @@ typedef struct { typedef struct _ACPI_2_0_XSDT{ ACPI_TABLE_HEADER Header; - u64 Entry[ACPI_MAX_NUM_TABLES]; + uint64_t Entry[ACPI_MAX_NUM_TABLES]; }ACPI_2_0_XSDT; #define ACPI_2_0_XSDT_REVISION 0x01 @@ -130,49 +144,49 @@ typedef struct _ACPI_2_0_XSDT{ typedef struct { ACPI_TABLE_HEADER Header; - u32 FirmwareCtrl; - u32 Dsdt; - u8 Reserved0; - u8 PreferredPmProfile; - u16 SciInt; - u32 SmiCmd; - u8 AcpiEnable; - u8 AcpiDisable; - u8 S4BiosReq; - u8 PstateCnt; - u32 Pm1aEvtBlk; - u32 Pm1bEvtBlk; - u32 Pm1aCntBlk; - u32 Pm1bCntBlk; - u32 Pm2CntBlk; - u32 PmTmrBlk; - u32 Gpe0Blk; - u32 Gpe1Blk; - u8 Pm1EvtLen; - u8 Pm1CntLen; - u8 Pm2CntLen; - u8 PmTmrLen; - u8 Gpe0BlkLen; - u8 Gpe1BlkLen; - u8 Gpe1Base; - u8 CstCnt; - u16 PLvl2Lat; - u16 PLvl3Lat; - u16 FlushSize; - u16 FlushStride; - u8 DutyOffset; - u8 DutyWidth; - u8 DayAlrm; - u8 MonAlrm; - u8 Century; - u16 IaPcBootArch; - u8 Reserved1; - u32 Flags; + uint32_t FirmwareCtrl; + uint32_t Dsdt; + uint8_t Reserved0; + uint8_t PreferredPmProfile; + uint16_t SciInt; + uint32_t SmiCmd; + uint8_t AcpiEnable; + uint8_t AcpiDisable; + uint8_t S4BiosReq; + uint8_t PstateCnt; + uint32_t Pm1aEvtBlk; + uint32_t Pm1bEvtBlk; + uint32_t Pm1aCntBlk; + uint32_t Pm1bCntBlk; + uint32_t Pm2CntBlk; + uint32_t PmTmrBlk; + uint32_t Gpe0Blk; + uint32_t Gpe1Blk; + uint8_t Pm1EvtLen; + uint8_t Pm1CntLen; + uint8_t Pm2CntLen; + uint8_t PmTmrLen; + uint8_t Gpe0BlkLen; + uint8_t Gpe1BlkLen; + uint8_t Gpe1Base; + uint8_t CstCnt; + uint16_t PLvl2Lat; + uint16_t PLvl3Lat; + uint16_t FlushSize; + uint16_t FlushStride; + uint8_t DutyOffset; + uint8_t DutyWidth; + uint8_t DayAlrm; + uint8_t MonAlrm; + uint8_t Century; + uint16_t IaPcBootArch; + uint8_t Reserved1; + uint32_t Flags; ACPI_GENERIC_ADDRESS_STRUCTURE ResetReg; - u8 ResetValue; - u8 Reserved2[3]; - u64 XFirmwareCtrl; - u64 XDsdt; + uint8_t ResetValue; + uint8_t Reserved2[3]; + uint64_t XFirmwareCtrl; + uint64_t XDsdt; ACPI_GENERIC_ADDRESS_STRUCTURE XPm1aEvtBlk; ACPI_GENERIC_ADDRESS_STRUCTURE XPm1bEvtBlk; ACPI_GENERIC_ADDRESS_STRUCTURE XPm1aCntBlk; @@ -212,15 +226,15 @@ typedef struct { // Firmware ACPI Control Structure (FACS) // typedef struct { - u32 Signature; - u32 Length; - u32 HardwareSignature; - u32 FirmwareWakingVector; - u32 GlobalLock; - u32 Flags; - u64 XFirmwareWakingVector; - u8 Version; - u8 Reserved[31]; + uint32_t Signature; + uint32_t Length; + uint32_t HardwareSignature; + uint32_t FirmwareWakingVector; + uint32_t GlobalLock; + uint32_t Flags; + uint64_t XFirmwareWakingVector; + uint8_t Version; + uint8_t Reserved[31]; } ACPI_2_0_FACS; #define ACPI_2_0_FACS_VERSION 0x01 @@ -230,8 +244,8 @@ typedef struct { // typedef struct { ACPI_TABLE_HEADER Header; - u32 LocalApicAddress; - u32 Flags; + uint32_t LocalApicAddress; + uint32_t Flags; } ACPI_2_0_MADT; #define ACPI_2_0_MADT_REVISION 0x01 @@ -263,11 +277,11 @@ typedef struct { // typedef struct { - u8 Type; - u8 Length; - u8 AcpiProcessorId; - u8 ApicId; - u32 Flags; + uint8_t Type; + uint8_t Length; + uint8_t AcpiProcessorId; + uint8_t ApicId; + uint32_t Flags; } ACPI_LOCAL_APIC_STRUCTURE; // @@ -281,12 +295,12 @@ typedef struct { // typedef struct { - u8 Type; - u8 Length; - u8 IoApicId; - u8 Reserved; - u32 IoApicAddress; - u32 GlobalSystemInterruptBase; + uint8_t Type; + uint8_t Length; + uint8_t IoApicId; + uint8_t Reserved; + uint32_t IoApicAddress; + uint32_t GlobalSystemInterruptBase; } ACPI_IO_APIC_STRUCTURE; // Tabel Signature @@ -312,6 +326,6 @@ typedef struct { #define ACPI_TABLE_SIZE (2*1024) //Currently 2K is enough void -AcpiBuildTable(u8* buf); +AcpiBuildTable(uint8_t* buf); #endif diff --git a/tools/firmware/acpi/acpi_build.c b/tools/firmware/acpi/acpi_build.c index f947d2707d..7c58265309 100644 --- a/tools/firmware/acpi/acpi_build.c +++ b/tools/firmware/acpi/acpi_build.c @@ -37,21 +37,21 @@ typedef struct _ACPI_TABLE_ALL{ ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *Madt; ACPI_2_0_FACS *Facs; unsigned char* Dsdt; - u32 RsdpOffset; - u32 RsdtOffset; - u32 XsdtOffset; - u32 FadtOffset; - u32 MadtOffset; - u32 FacsOffset; - u32 DsdtOffset; + uint32_t RsdpOffset; + uint32_t RsdtOffset; + uint32_t XsdtOffset; + uint32_t FadtOffset; + uint32_t MadtOffset; + uint32_t FacsOffset; + uint32_t DsdtOffset; }ACPI_TABLE_ALL; static void MemCopy(void* src, void* dst, int len){ - u8* src0=src; - u8* dst0=dst; + uint8_t* src0=src; + uint8_t* dst0=dst; while(len--){ *(dst0++)=*(src0++); @@ -62,8 +62,8 @@ static void SetCheckSum( void* Table, - u32 ChecksumOffset, - u32 Length + uint32_t ChecksumOffset, + uint32_t Length ) /* * Routine Description: @@ -76,23 +76,23 @@ SetCheckSum( * Length: Length of Table */ { - u8 Sum = 0; - u8 *Ptr; + uint8_t Sum = 0; + uint8_t *Ptr; Ptr=Table; Ptr[ChecksumOffset]=0; while (Length--) { - Sum = (u8)(Sum + (*Ptr++)); + Sum = (uint8_t)(Sum + (*Ptr++)); } Ptr = Table; - Ptr[ChecksumOffset] = (u8) (0xff - Sum + 1); + Ptr[ChecksumOffset] = (uint8_t) (0xff - Sum + 1); } // // FIELD_OFFSET - returns the byte offset to a field within a structure // -#define FIELD_OFFSET(TYPE,Field) ((u32)(&(((TYPE *) 0)->Field))) +#define FIELD_OFFSET(TYPE,Field) ((uint32_t)(&(((TYPE *) 0)->Field))) static void @@ -106,9 +106,9 @@ UpdateTable( */ { // RSDP Update - table->Rsdp->RsdtAddress = (u32)(ACPI_PHYSICAL_ADDRESS+ + table->Rsdp->RsdtAddress = (uint32_t)(ACPI_PHYSICAL_ADDRESS+ table->RsdtOffset); - table->Rsdp->XsdtAddress = (u64)(ACPI_PHYSICAL_ADDRESS+ + table->Rsdp->XsdtAddress = (uint64_t)(ACPI_PHYSICAL_ADDRESS+ table->XsdtOffset); SetCheckSum(table->Rsdp, FIELD_OFFSET(ACPI_1_0_RSDP, Checksum), @@ -122,37 +122,37 @@ UpdateTable( //RSDT Update - table->Rsdt->Entry[0] = (u32)(ACPI_PHYSICAL_ADDRESS + + table->Rsdt->Entry[0] = (uint32_t)(ACPI_PHYSICAL_ADDRESS + table->FadtOffset); - table->Rsdt->Entry[1] = (u32)(ACPI_PHYSICAL_ADDRESS + + table->Rsdt->Entry[1] = (uint32_t)(ACPI_PHYSICAL_ADDRESS + table->MadtOffset); table->Rsdt->Header.Length = sizeof (ACPI_TABLE_HEADER) + - 2*sizeof(u32); + 2*sizeof(uint32_t); SetCheckSum(table->Rsdt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum), table->Rsdt->Header.Length ); //XSDT Update - table->Xsdt->Entry[0] = (u64)(ACPI_PHYSICAL_ADDRESS + + table->Xsdt->Entry[0] = (uint64_t)(ACPI_PHYSICAL_ADDRESS + table->FadtOffset); - table->Xsdt->Entry[1] = (u64)(ACPI_PHYSICAL_ADDRESS + + table->Xsdt->Entry[1] = (uint64_t)(ACPI_PHYSICAL_ADDRESS + table->MadtOffset); table->Xsdt->Header.Length = sizeof (ACPI_TABLE_HEADER) + - 2*sizeof(u64); + 2*sizeof(uint64_t); SetCheckSum(table->Xsdt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum), table->Xsdt->Header.Length ); // FADT Update - table->Fadt->Dsdt = (u32)(ACPI_PHYSICAL_ADDRESS + + table->Fadt->Dsdt = (uint32_t)(ACPI_PHYSICAL_ADDRESS + table->DsdtOffset); - table->Fadt->XDsdt = (u64)(ACPI_PHYSICAL_ADDRESS + + table->Fadt->XDsdt = (uint64_t)(ACPI_PHYSICAL_ADDRESS + table->DsdtOffset); - table->Fadt->FirmwareCtrl = (u32)(ACPI_PHYSICAL_ADDRESS + + table->Fadt->FirmwareCtrl = (uint32_t)(ACPI_PHYSICAL_ADDRESS + table->FacsOffset); - table->Fadt->XFirmwareCtrl = (u64)(ACPI_PHYSICAL_ADDRESS + + table->Fadt->XFirmwareCtrl = (uint64_t)(ACPI_PHYSICAL_ADDRESS + table->FacsOffset); SetCheckSum(table->Fadt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum), @@ -167,7 +167,7 @@ UpdateTable( } void -AcpiBuildTable(u8* buf) +AcpiBuildTable(uint8_t* buf) /* * Copy all the ACPI table to buffer * Buffer Layout: diff --git a/tools/firmware/vmxassist/vm86.c b/tools/firmware/vmxassist/vm86.c index 8d040812c0..48fb6159fa 100644 --- a/tools/firmware/vmxassist/vm86.c +++ b/tools/firmware/vmxassist/vm86.c @@ -465,7 +465,7 @@ movcr(struct regs *regs, unsigned prefix, unsigned opc) * Emulate a segment load in protected mode */ int -load_seg(unsigned long sel, u32 *base, u32 *limit, union vmcs_arbytes *arbytes) +load_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union vmcs_arbytes *arbytes) { unsigned long long entry; diff --git a/tools/firmware/vmxassist/vm86.h b/tools/firmware/vmxassist/vm86.h index b15493215f..2b6c64d183 100644 --- a/tools/firmware/vmxassist/vm86.h +++ b/tools/firmware/vmxassist/vm86.h @@ -22,15 +22,6 @@ #ifndef __ASSEMBLY__ #include - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; #endif #include diff --git a/tools/ioemu/hw/ioapic.c b/tools/ioemu/hw/ioapic.c index b15e6d1fb6..99ea751069 100644 --- a/tools/ioemu/hw/ioapic.c +++ b/tools/ioemu/hw/ioapic.c @@ -493,7 +493,7 @@ ioapic_deliver(IOAPICState *s, int irqno){ } } -static inline int __fls(u32 word) +static inline int __fls(uint32_t word) { int bit; __asm__("bsrl %1,%0" @@ -581,7 +581,7 @@ ioapic_legacy_irq(int irq, int level) ioapic_set_irq(ioapic, irq, level); } -static inline int find_highest_bit(u32 *data, int length){ +static inline int find_highest_bit(uint32_t *data, int length){ while(length && !data[--length]); return __fls(data[length]) + 32 * length; } diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c index 5f0c3712cc..0acb6fe29e 100644 --- a/tools/ioemu/target-i386-dm/helper2.c +++ b/tools/ioemu/target-i386-dm/helper2.c @@ -122,7 +122,7 @@ target_ulong cpu_get_phys_page_debug(CPUState *env, target_ulong addr) //the evtchn fd for polling int evtchn_fd = -1; //the evtchn port for polling the notification, should be inputed as bochs's parameter -u16 ioreq_remote_port, ioreq_local_port; +uint16_t ioreq_remote_port, ioreq_local_port; //some functions to handle the io req packet void @@ -157,9 +157,9 @@ ioreq_t* __cpu_get_ioreq(void) ioreq_t* cpu_get_ioreq(void) { int rc; - u16 buf[2]; - rc = read(evtchn_fd, buf, 2); - if (rc == 2 && buf[0] == ioreq_local_port){//got only one matched 16bit port index + uint16_t port; + rc = read(evtchn_fd, &port, sizeof(port)); + if ((rc == sizeof(port)) && (port == ioreq_local_port)) { // unmask the wanted port again write(evtchn_fd, &ioreq_local_port, 2); @@ -208,13 +208,13 @@ extern void cpu_physical_memory_rw(target_phys_addr_t addr, uint8_t *buf, int len, int is_write); static inline void -read_physical(u64 addr, unsigned long size, void *val) +read_physical(uint64_t addr, unsigned long size, void *val) { return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 0); } static inline void -write_physical(u64 addr, unsigned long size, void *val) +write_physical(uint64_t addr, unsigned long size, void *val) { return cpu_physical_memory_rw((target_phys_addr_t)addr, val, size, 1); } diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index ae2761b813..a8e04da269 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -2382,7 +2382,7 @@ get_vl2_table(unsigned long count, unsigned long start) } int -setup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long *mem_page_array, unsigned long *page_table_array, unsigned long v_start, unsigned long v_end) +setup_mapping(int xc_handle, uint32_t dom, unsigned long toptab, unsigned long *mem_page_array, unsigned long *page_table_array, unsigned long v_start, unsigned long v_end) { l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; l2_pgentry_t *vl2tab[4] = {NULL, NULL, NULL, NULL}; @@ -2449,7 +2449,7 @@ error_out: } void -unsetup_mapping(int xc_handle, u32 dom, unsigned long toptab, unsigned long v_start, unsigned long v_end) +unsetup_mapping(int xc_handle, uint32_t dom, unsigned long toptab, unsigned long v_start, unsigned long v_end) { l1_pgentry_t *vl1tab=NULL, *vl1e=NULL; l2_pgentry_t *vl2tab[4], *vl2e=NULL, *vl2_table = NULL; @@ -2806,7 +2806,7 @@ int main(int argc, char **argv) case QEMU_OPTION_p: { - extern u16 ioreq_remote_port; + extern uint16_t ioreq_remote_port; ioreq_remote_port = atoi(optarg); printf("port: %d\n", ioreq_remote_port); } diff --git a/tools/libxc/xc_bvtsched.c b/tools/libxc/xc_bvtsched.c index 783ab30318..fc43383dc4 100644 --- a/tools/libxc/xc_bvtsched.c +++ b/tools/libxc/xc_bvtsched.c @@ -39,10 +39,10 @@ int xc_bvtsched_global_get(int xc_handle, } int xc_bvtsched_domain_set(int xc_handle, - u32 domid, - u32 mcuadv, + uint32_t domid, + uint32_t mcuadv, int warpback, - s32 warpvalue, + int32_t warpvalue, long long warpl, long long warpu) { @@ -64,10 +64,10 @@ int xc_bvtsched_domain_set(int xc_handle, int xc_bvtsched_domain_get(int xc_handle, - u32 domid, - u32 *mcuadv, + uint32_t domid, + uint32_t *mcuadv, int *warpback, - s32 *warpvalue, + int32_t *warpvalue, long long *warpl, long long *warpu) { diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c index dc0387129d..7c24b0b0bf 100644 --- a/tools/libxc/xc_core.c +++ b/tools/libxc/xc_core.c @@ -11,7 +11,7 @@ static int copy_from_domain_page(int xc_handle, - u32 domid, + uint32_t domid, unsigned long *page_array, unsigned long src_pfn, void *dst_page) @@ -27,7 +27,7 @@ copy_from_domain_page(int xc_handle, int xc_domain_dumpcore(int xc_handle, - u32 domid, + uint32_t domid, const char *corename) { unsigned long nr_pages; diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 054fc6de7c..5a7995d46b 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -10,8 +10,8 @@ #include int xc_domain_create(int xc_handle, - u32 ssidref, - u32 *pdomid) + uint32_t ssidref, + uint32_t *pdomid) { int err; dom0_op_t op; @@ -22,13 +22,13 @@ int xc_domain_create(int xc_handle, if ( (err = do_dom0_op(xc_handle, &op)) != 0 ) return err; - *pdomid = (u16)op.u.createdomain.domain; + *pdomid = (uint16_t)op.u.createdomain.domain; return 0; } int xc_domain_pause(int xc_handle, - u32 domid) + uint32_t domid) { dom0_op_t op; op.cmd = DOM0_PAUSEDOMAIN; @@ -38,7 +38,7 @@ int xc_domain_pause(int xc_handle, int xc_domain_unpause(int xc_handle, - u32 domid) + uint32_t domid) { dom0_op_t op; op.cmd = DOM0_UNPAUSEDOMAIN; @@ -48,7 +48,7 @@ int xc_domain_unpause(int xc_handle, int xc_domain_destroy(int xc_handle, - u32 domid) + uint32_t domid) { dom0_op_t op; op.cmd = DOM0_DESTROYDOMAIN; @@ -57,7 +57,7 @@ int xc_domain_destroy(int xc_handle, } int xc_domain_pincpu(int xc_handle, - u32 domid, + uint32_t domid, int vcpu, cpumap_t *cpumap) { @@ -71,12 +71,12 @@ int xc_domain_pincpu(int xc_handle, int xc_domain_getinfo(int xc_handle, - u32 first_domid, + uint32_t first_domid, unsigned int max_doms, xc_dominfo_t *info) { unsigned int nr_doms; - u32 next_domid = first_domid; + uint32_t next_domid = first_domid; dom0_op_t op; int rc = 0; @@ -88,7 +88,7 @@ int xc_domain_getinfo(int xc_handle, op.u.getdomaininfo.domain = (domid_t)next_domid; if ( (rc = do_dom0_op(xc_handle, &op)) < 0 ) break; - info->domid = (u16)op.u.getdomaininfo.domain; + info->domid = (uint16_t)op.u.getdomaininfo.domain; info->dying = !!(op.u.getdomaininfo.flags & DOMFLAGS_DYING); info->shutdown = !!(op.u.getdomaininfo.flags & DOMFLAGS_SHUTDOWN); @@ -117,7 +117,7 @@ int xc_domain_getinfo(int xc_handle, memcpy(&info->cpumap, &op.u.getdomaininfo.cpumap, sizeof(info->cpumap)); - next_domid = (u16)op.u.getdomaininfo.domain + 1; + next_domid = (uint16_t)op.u.getdomaininfo.domain + 1; info++; } @@ -127,7 +127,7 @@ int xc_domain_getinfo(int xc_handle, } int xc_domain_getinfolist(int xc_handle, - u32 first_domain, + uint32_t first_domain, unsigned int max_domains, xc_domaininfo_t *info) { @@ -154,8 +154,8 @@ int xc_domain_getinfolist(int xc_handle, } int xc_domain_get_vcpu_context(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, vcpu_guest_context_t *ctxt) { int rc; @@ -163,7 +163,7 @@ int xc_domain_get_vcpu_context(int xc_handle, op.cmd = DOM0_GETVCPUCONTEXT; op.u.getvcpucontext.domain = (domid_t)domid; - op.u.getvcpucontext.vcpu = (u16)vcpu; + op.u.getvcpucontext.vcpu = (uint16_t)vcpu; op.u.getvcpucontext.ctxt = ctxt; if ( (ctxt != NULL) && @@ -183,7 +183,7 @@ int xc_domain_get_vcpu_context(int xc_handle, int xc_shadow_control(int xc_handle, - u32 domid, + uint32_t domid, unsigned int sop, unsigned long *dirty_bitmap, unsigned long pages, @@ -207,7 +207,7 @@ int xc_shadow_control(int xc_handle, } int xc_domain_setcpuweight(int xc_handle, - u32 domid, + uint32_t domid, float weight) { int sched_id; @@ -221,9 +221,9 @@ int xc_domain_setcpuweight(int xc_handle, { case SCHED_BVT: { - u32 mcuadv; + uint32_t mcuadv; int warpback; - s32 warpvalue; + int32_t warpvalue; long long warpl; long long warpu; @@ -250,7 +250,7 @@ int xc_domain_setcpuweight(int xc_handle, } int xc_domain_setmaxmem(int xc_handle, - u32 domid, + uint32_t domid, unsigned int max_memkb) { dom0_op_t op; @@ -261,7 +261,7 @@ int xc_domain_setmaxmem(int xc_handle, } int xc_domain_memory_increase_reservation(int xc_handle, - u32 domid, + uint32_t domid, unsigned long nr_extents, unsigned int extent_order, unsigned int address_bits, @@ -293,7 +293,7 @@ int xc_domain_memory_increase_reservation(int xc_handle, } int xc_domain_memory_decrease_reservation(int xc_handle, - u32 domid, + uint32_t domid, unsigned long nr_extents, unsigned int extent_order, unsigned long *extent_start) diff --git a/tools/libxc/xc_evtchn.c b/tools/libxc/xc_evtchn.c index a318889b85..af79ef384a 100644 --- a/tools/libxc/xc_evtchn.c +++ b/tools/libxc/xc_evtchn.c @@ -33,8 +33,8 @@ static int do_evtchn_op(int xc_handle, evtchn_op_t *op) int xc_evtchn_alloc_unbound(int xc_handle, - u32 dom, - u32 remote_dom) + uint32_t dom, + uint32_t remote_dom) { int rc; evtchn_op_t op = { @@ -50,7 +50,7 @@ int xc_evtchn_alloc_unbound(int xc_handle, int xc_evtchn_status(int xc_handle, - u32 dom, + uint32_t dom, int port, xc_evtchn_status_t *status) { diff --git a/tools/libxc/xc_gnttab.c b/tools/libxc/xc_gnttab.c index 0f2d717519..fd9df4c1b2 100644 --- a/tools/libxc/xc_gnttab.c +++ b/tools/libxc/xc_gnttab.c @@ -40,12 +40,12 @@ do_gnttab_op(int xc_handle, int xc_gnttab_map_grant_ref(int xc_handle, - u64 host_virt_addr, - u32 dom, - u16 ref, - u16 flags, - s16 *handle, - u64 *dev_bus_addr) + uint64_t host_virt_addr, + uint32_t dom, + uint16_t ref, + uint16_t flags, + int16_t *handle, + uint64_t *dev_bus_addr) { struct gnttab_map_grant_ref op; int rc; @@ -67,10 +67,10 @@ int xc_gnttab_map_grant_ref(int xc_handle, int xc_gnttab_unmap_grant_ref(int xc_handle, - u64 host_virt_addr, - u64 dev_bus_addr, - u16 handle, - s16 *status) + uint64_t host_virt_addr, + uint64_t dev_bus_addr, + uint16_t handle, + int16_t *status) { struct gnttab_unmap_grant_ref op; int rc; @@ -89,9 +89,9 @@ int xc_gnttab_unmap_grant_ref(int xc_handle, } int xc_gnttab_setup_table(int xc_handle, - u32 dom, - u16 nr_frames, - s16 *status, + uint32_t dom, + uint16_t nr_frames, + int16_t *status, unsigned long **frame_list) { struct gnttab_setup_table op; @@ -111,8 +111,8 @@ int xc_gnttab_setup_table(int xc_handle, } int xc_gnttab_dump_table(int xc_handle, - u32 dom, - s16 *status) + uint32_t dom, + int16_t *status) { struct gnttab_dump_table op; int rc; diff --git a/tools/libxc/xc_ia64_stubs.c b/tools/libxc/xc_ia64_stubs.c index 84e53b95fc..f1e8a46a0b 100644 --- a/tools/libxc/xc_ia64_stubs.c +++ b/tools/libxc/xc_ia64_stubs.c @@ -1,14 +1,14 @@ #include "xg_private.h" #include "xenguest.h" -int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters, - u32 max_factor, u32 flags) +int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, + uint32_t max_factor, uint32_t flags) { PERROR("xc_linux_save not implemented\n"); return -1; } -int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, +int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pfns, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn) { @@ -17,7 +17,7 @@ int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, } int xc_vmx_build(int xc_handle, - u32 domid, + uint32_t domid, int memsize, const char *image_name, struct mem_map *mem_mapp, @@ -35,7 +35,7 @@ int xc_vmx_build(int xc_handle, int xc_plan9_build(int xc_handle, - u32 domid, + uint32_t domid, const char *image_name, const char *cmdline, unsigned int control_evtchn, unsigned long flags) diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 3b0f28676f..9ed257edf3 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -64,7 +64,7 @@ static int probeimageformat(char *image, #define alloc_pt(ltab, vltab) \ do { \ - ltab = (u64)page_array[ppt_alloc++] << PAGE_SHIFT; \ + ltab = (uint64_t)page_array[ppt_alloc++] << PAGE_SHIFT; \ if ( vltab != NULL ) \ munmap(vltab, PAGE_SIZE); \ if ( (vltab = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, \ @@ -76,7 +76,7 @@ do { \ #if defined(__i386__) -static int setup_pg_tables(int xc_handle, u32 dom, +static int setup_pg_tables(int xc_handle, uint32_t dom, vcpu_guest_context_t *ctxt, unsigned long dsi_v_start, unsigned long v_end, @@ -123,7 +123,7 @@ static int setup_pg_tables(int xc_handle, u32 dom, return -1; } -static int setup_pg_tables_pae(int xc_handle, u32 dom, +static int setup_pg_tables_pae(int xc_handle, uint32_t dom, vcpu_guest_context_t *ctxt, unsigned long dsi_v_start, unsigned long v_end, @@ -134,7 +134,7 @@ static int setup_pg_tables_pae(int xc_handle, u32 dom, l1_pgentry_64_t *vl1tab = NULL, *vl1e = NULL; l2_pgentry_64_t *vl2tab = NULL, *vl2e = NULL; l3_pgentry_64_t *vl3tab = NULL, *vl3e = NULL; - u64 l1tab, l2tab, l3tab; + uint64_t l1tab, l2tab, l3tab; unsigned long ppt_alloc, count, nmfn; /* First allocate page for page dir. */ @@ -173,7 +173,7 @@ static int setup_pg_tables_pae(int xc_handle, u32 dom, *vl2e++ = l1tab | L2_PROT; } - *vl1e = ((u64)page_array[count] << PAGE_SHIFT) | L1_PROT; + *vl1e = ((uint64_t)page_array[count] << PAGE_SHIFT) | L1_PROT; if ( (count >= ((vpt_start-dsi_v_start)>>PAGE_SHIFT)) && (count < ((vpt_end -dsi_v_start)>>PAGE_SHIFT)) ) *vl1e &= ~_PAGE_RW; @@ -199,7 +199,7 @@ static int setup_pg_tables_pae(int xc_handle, u32 dom, #if defined(__x86_64__) -static int setup_pg_tables_64(int xc_handle, u32 dom, +static int setup_pg_tables_64(int xc_handle, uint32_t dom, vcpu_guest_context_t *ctxt, unsigned long dsi_v_start, unsigned long v_end, @@ -280,7 +280,7 @@ static int setup_pg_tables_64(int xc_handle, u32 dom, #ifdef __ia64__ #include /* for FPSR_DEFAULT */ static int setup_guest(int xc_handle, - u32 dom, + uint32_t dom, char *image, unsigned long image_size, gzFile initrd_gfd, unsigned long initrd_len, unsigned long nr_pages, @@ -346,7 +346,7 @@ static int setup_guest(int xc_handle, *store_mfn = page_array[1]; *console_mfn = page_array[2]; printf("store_mfn: 0x%lx, console_mfn: 0x%lx\n", - (u64)store_mfn, (u64)console_mfn); + (uint64_t)store_mfn, (uint64_t)console_mfn); start_info = xc_map_foreign_range( xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, page_array[0]); @@ -367,7 +367,7 @@ static int setup_guest(int xc_handle, } #else /* x86 */ static int setup_guest(int xc_handle, - u32 dom, + uint32_t dom, char *image, unsigned long image_size, gzFile initrd_gfd, unsigned long initrd_len, unsigned long nr_pages, @@ -573,7 +573,7 @@ static int setup_guest(int xc_handle, { if ( xc_add_mmu_update( xc_handle, mmu, - ((u64)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, + ((uint64_t)page_array[count] << PAGE_SHIFT) | MMU_MACHPHYS_UPDATE, count) ) { fprintf(stderr,"m2p update failure p=%lx m=%lx\n", @@ -679,7 +679,7 @@ static int setup_guest(int xc_handle, #endif int xc_linux_build(int xc_handle, - u32 domid, + uint32_t domid, const char *image_name, const char *ramdisk_name, const char *cmdline, @@ -735,7 +735,7 @@ int xc_linux_build(int xc_handle, op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; if ( (xc_dom0_op(xc_handle, &op) < 0) || - ((u16)op.u.getdomaininfo.domain != domid) ) + ((uint16_t)op.u.getdomaininfo.domain != domid) ) { PERROR("Could not get info on domain"); goto error_out; diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 1d8cfacf0f..53ae53279d 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -51,7 +51,7 @@ read_exact(int fd, void *buf, size_t count) return r; } -int xc_linux_restore(int xc_handle, int io_fd, u32 dom, unsigned long nr_pfns, +int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pfns, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn) { diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index ba3aff36a6..e62b76f716 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -245,7 +245,7 @@ ratewrite(int io_fd, void *buf, int n) return write(io_fd, buf, n); } -static int print_stats( int xc_handle, u32 domid, +static int print_stats( int xc_handle, uint32_t domid, int pages_sent, xc_shadow_control_stats_t *stats, int print ) { @@ -299,7 +299,7 @@ static int print_stats( int xc_handle, u32 domid, return 0; } -static int analysis_phase( int xc_handle, u32 domid, +static int analysis_phase( int xc_handle, uint32_t domid, int nr_pfns, unsigned long *arr, int runs ) { long long start, now; @@ -399,8 +399,8 @@ static int suspend_and_state(int xc_handle, int io_fd, int dom, return -1; } -int xc_linux_save(int xc_handle, int io_fd, u32 dom, u32 max_iters, - u32 max_factor, u32 flags) +int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, + uint32_t max_factor, uint32_t flags) { xc_dominfo_t info; diff --git a/tools/libxc/xc_load_aout9.c b/tools/libxc/xc_load_aout9.c index ab937ebb93..9a6ce0be41 100644 --- a/tools/libxc/xc_load_aout9.c +++ b/tools/libxc/xc_load_aout9.c @@ -18,8 +18,8 @@ #define KOFFSET(_p) ((_p)&~KZERO) static int parseaout9image(char *, unsigned long, struct domain_setup_info *); -static int loadaout9image(char *, unsigned long, int, u32, unsigned long *, struct domain_setup_info *); -static void copyout(int, u32, unsigned long *, unsigned long, void *, int); +static int loadaout9image(char *, unsigned long, int, uint32_t, unsigned long *, struct domain_setup_info *); +static void copyout(int, uint32_t, unsigned long *, unsigned long, void *, int); struct Exec *get_header(char *, unsigned long, struct Exec *); @@ -79,7 +79,7 @@ static int loadaout9image( char *image, unsigned long image_size, - int xch, u32 dom, + int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi) { @@ -108,7 +108,7 @@ loadaout9image( */ static void copyout( - int xch, u32 dom, + int xch, uint32_t dom, unsigned long *parray, unsigned long addr, void *buf, @@ -135,8 +135,8 @@ copyout( } } -#define swap16(_v) ((((u16)(_v)>>8)&0xff)|(((u16)(_v)&0xff)<<8)) -#define swap32(_v) (((u32)swap16((u16)(_v))<<16)|(u32)swap16((u32)((_v)>>16))) +#define swap16(_v) ((((uint16_t)(_v)>>8)&0xff)|(((uint16_t)(_v)&0xff)<<8)) +#define swap32(_v) (((uint32_t)swap16((uint16_t)(_v))<<16)|(uint32_t)swap16((uint32_t)((_v)>>16))) /* * Decode the header from the start of image and return it. @@ -147,7 +147,7 @@ get_header( unsigned long image_size, struct Exec *ehdr) { - u32 *v, x; + uint32_t *v, x; int i; if (A9_MAGIC == 0) @@ -157,9 +157,9 @@ get_header( return 0; /* ... all big endian words */ - v = (u32 *)ehdr; + v = (uint32_t *)ehdr; for (i = 0; i < sizeof(*ehdr); i += 4) { - x = *(u32 *)&image[i]; + x = *(uint32_t *)&image[i]; v[i/4] = swap32(x); } diff --git a/tools/libxc/xc_load_bin.c b/tools/libxc/xc_load_bin.c index 39d4969149..e92ca69cdd 100644 --- a/tools/libxc/xc_load_bin.c +++ b/tools/libxc/xc_load_bin.c @@ -11,14 +11,14 @@ * The layout of the xen_bin_image table is: * * Offset Type Name Note - * 0 u32 magic required - * 4 u32 flags required - * 8 u32 checksum required - * 12 u32 header_addr required - * 16 u32 load_addr required - * 20 u32 load_end_addr required - * 24 u32 bss_end_addr required - * 28 u32 entry_addr required + * 0 uint32_t magic required + * 4 uint32_t flags required + * 8 uint32_t checksum required + * 12 uint32_t header_addr required + * 16 uint32_t load_addr required + * 20 uint32_t load_end_addr required + * 24 uint32_t bss_end_addr required + * 28 uint32_t entry_addr required * * - magic * Magic number identifying the table. For images to be loaded by Xen 3, the @@ -105,7 +105,7 @@ parsebinimage( char *image, unsigned long image_size, struct domain_setup_info *dsi); static int loadbinimage( - char *image, unsigned long image_size, int xch, u32 dom, + char *image, unsigned long image_size, int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi); int probe_bin(char *image, @@ -237,7 +237,7 @@ static int parsebinimage(char *image, static int loadbinimage( - char *image, unsigned long image_size, int xch, u32 dom, + char *image, unsigned long image_size, int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi) { unsigned long size; diff --git a/tools/libxc/xc_load_elf.c b/tools/libxc/xc_load_elf.c index 38d492ed2f..9d00be1e78 100644 --- a/tools/libxc/xc_load_elf.c +++ b/tools/libxc/xc_load_elf.c @@ -22,11 +22,11 @@ parseelfimage( char *image, unsigned long image_size, struct domain_setup_info *dsi); static int loadelfimage( - char *image, unsigned long image_size, int xch, u32 dom, + char *image, unsigned long image_size, int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi); static int loadelfsymtab( - char *image, int xch, u32 dom, unsigned long *parray, + char *image, int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi); int probe_elf(char *image, @@ -168,7 +168,7 @@ static int parseelfimage(char *image, static int loadelfimage( - char *image, unsigned long elfsize, int xch, u32 dom, + char *image, unsigned long elfsize, int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi) { Elf_Ehdr *ehdr = (Elf_Ehdr *)image; @@ -219,7 +219,7 @@ loadelfimage( static int loadelfsymtab( - char *image, int xch, u32 dom, unsigned long *parray, + char *image, int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi) { Elf_Ehdr *ehdr = (Elf_Ehdr *)image, *sym_ehdr; diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index 8ed13af848..ab263689c5 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -83,7 +83,7 @@ int xc_sched_id(int xc_handle, } int xc_perfc_control(int xc_handle, - u32 op, + uint32_t op, xc_perfc_desc_t *desc) { int rc; diff --git a/tools/libxc/xc_physdev.c b/tools/libxc/xc_physdev.c index 94fe34dc52..9a4358c026 100644 --- a/tools/libxc/xc_physdev.c +++ b/tools/libxc/xc_physdev.c @@ -10,7 +10,7 @@ #include "xc_private.h" int xc_physdev_pci_access_modify(int xc_handle, - u32 domid, + uint32_t domid, int bus, int dev, int func, diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 2f9ae9556d..c5ebf3ee39 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -8,7 +8,7 @@ #include "xc_private.h" #include -void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot, +void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot, unsigned long *arr, int num ) { privcmd_mmapbatch_t ioctlx; @@ -35,7 +35,7 @@ void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot, /*******************/ -void *xc_map_foreign_range(int xc_handle, u32 dom, +void *xc_map_foreign_range(int xc_handle, uint32_t dom, int size, int prot, unsigned long mfn ) { @@ -66,7 +66,7 @@ void *xc_map_foreign_range(int xc_handle, u32 dom, /* NB: arr must be mlock'ed */ int xc_get_pfn_type_batch(int xc_handle, - u32 dom, int num, unsigned long *arr) + uint32_t dom, int num, unsigned long *arr) { dom0_op_t op; op.cmd = DOM0_GETPAGEFRAMEINFO2; @@ -79,7 +79,7 @@ int xc_get_pfn_type_batch(int xc_handle, #define GETPFN_ERR (~0U) unsigned int get_pfn_type(int xc_handle, unsigned long mfn, - u32 dom) + uint32_t dom) { dom0_op_t op; op.cmd = DOM0_GETPAGEFRAMEINFO; @@ -258,7 +258,7 @@ long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu ) op.cmd = DOM0_GETVCPUCONTEXT; op.u.getvcpucontext.domain = (domid_t)domid; - op.u.getvcpucontext.vcpu = (u16)vcpu; + op.u.getvcpucontext.vcpu = (uint16_t)vcpu; op.u.getvcpucontext.ctxt = NULL; if ( (do_dom0_op(xc_handle, &op) < 0) ) { @@ -282,7 +282,7 @@ unsigned long xc_get_m2p_start_mfn ( int xc_handle ) } int xc_get_pfn_list(int xc_handle, - u32 domid, + uint32_t domid, unsigned long *pfn_buf, unsigned long max_pfns) { @@ -324,7 +324,7 @@ int xc_get_pfn_list(int xc_handle, #ifdef __ia64__ int xc_ia64_get_pfn_list(int xc_handle, - u32 domid, + uint32_t domid, unsigned long *pfn_buf, unsigned int start_page, unsigned int nr_pages) @@ -352,7 +352,7 @@ int xc_ia64_get_pfn_list(int xc_handle, return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; } -long xc_get_max_pages(int xc_handle, u32 domid) +long xc_get_max_pages(int xc_handle, uint32_t domid) { dom0_op_t op; op.cmd = DOM0_GETDOMAININFO; @@ -362,7 +362,7 @@ long xc_get_max_pages(int xc_handle, u32 domid) } #endif -long xc_get_tot_pages(int xc_handle, u32 domid) +long xc_get_tot_pages(int xc_handle, uint32_t domid) { dom0_op_t op; op.cmd = DOM0_GETDOMAININFO; @@ -372,7 +372,7 @@ long xc_get_tot_pages(int xc_handle, u32 domid) } int xc_copy_to_domain_page(int xc_handle, - u32 domid, + uint32_t domid, unsigned long dst_pfn, void *src_page) { @@ -387,8 +387,8 @@ int xc_copy_to_domain_page(int xc_handle, unsigned long xc_get_filesz(int fd) { - u16 sig; - u32 _sz = 0; + uint16_t sig; + uint32_t _sz = 0; unsigned long sz; lseek(fd, 0, SEEK_SET); @@ -408,7 +408,7 @@ unsigned long xc_get_filesz(int fd) } void xc_map_memcpy(unsigned long dst, char *src, unsigned long size, - int xch, u32 dom, unsigned long *parray, + int xch, uint32_t dom, unsigned long *parray, unsigned long vstart) { char *va; @@ -460,7 +460,7 @@ int xc_version(int xc_handle, int cmd, void *arg) } unsigned long xc_make_page_below_4G( - int xc_handle, u32 domid, unsigned long mfn) + int xc_handle, uint32_t domid, unsigned long mfn) { unsigned long new_mfn; diff --git a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c index f1170d30f0..5bddbbff1f 100644 --- a/tools/libxc/xc_ptrace.c +++ b/tools/libxc/xc_ptrace.c @@ -138,7 +138,7 @@ map_domain_va_pae( int perm) { unsigned long l2p, l1p, p, va = (unsigned long)guest_va; - u64 *l3, *l2, *l1; + uint64_t *l3, *l2, *l1; static void *v; FETCH_REGS(cpu); @@ -319,7 +319,7 @@ long xc_ptrace( int xc_handle, enum __ptrace_request request, - u32 domid, + uint32_t domid, long eaddr, long edata) { diff --git a/tools/libxc/xc_ptrace_core.c b/tools/libxc/xc_ptrace_core.c index ffb23cea2d..43463b65a3 100644 --- a/tools/libxc/xc_ptrace_core.c +++ b/tools/libxc/xc_ptrace_core.c @@ -222,7 +222,7 @@ long xc_ptrace_core( int xc_handle, enum __ptrace_request request, - u32 domfd, + uint32_t domfd, long eaddr, long edata) { diff --git a/tools/libxc/xc_sedf.c b/tools/libxc/xc_sedf.c index a3a0598a7d..64984afa12 100644 --- a/tools/libxc/xc_sedf.c +++ b/tools/libxc/xc_sedf.c @@ -11,7 +11,7 @@ #include "xc_private.h" int xc_sedf_domain_set(int xc_handle, - u32 domid, u64 period, u64 slice,u64 latency, u16 extratime,u16 weight) + uint32_t domid, uint64_t period, uint64_t slice,uint64_t latency, uint16_t extratime,uint16_t weight) { dom0_op_t op; struct sedf_adjdom *p = &op.u.adjustdom.u.sedf; @@ -29,7 +29,7 @@ int xc_sedf_domain_set(int xc_handle, return do_dom0_op(xc_handle, &op); } -int xc_sedf_domain_get(int xc_handle, u32 domid, u64 *period, u64 *slice, u64* latency, u16* extratime, u16* weight) +int xc_sedf_domain_get(int xc_handle, uint32_t domid, uint64_t *period, uint64_t *slice, uint64_t* latency, uint16_t* extratime, uint16_t* weight) { dom0_op_t op; int ret; diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index a4d14c0dd0..5dd55e94f7 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -34,9 +34,9 @@ #define E820_MAP_OFFSET 0x000002D0 struct e820entry { - u64 addr; - u64 size; - u32 type; + uint64_t addr; + uint64_t size; + uint32_t type; } __attribute__((packed)); #define round_pgup(_p) (((_p)+(PAGE_SIZE-1))&PAGE_MASK) @@ -47,7 +47,7 @@ parseelfimage( char *elfbase, unsigned long elfsize, struct domain_setup_info *dsi); static int loadelfimage( - char *elfbase, int xch, u32 dom, unsigned long *parray, + char *elfbase, int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi); static unsigned char build_e820map(void *e820_page, unsigned long mem_size) @@ -122,7 +122,7 @@ static unsigned char build_e820map(void *e820_page, unsigned long mem_size) */ #define VCPU_MAGIC 0x76637075 /* "vcpu" */ static int -set_nr_vcpus(int xc_handle, u32 dom, unsigned long *pfn_list, +set_nr_vcpus(int xc_handle, uint32_t dom, unsigned long *pfn_list, struct domain_setup_info *dsi, unsigned long vcpus) { char *va_map; @@ -144,7 +144,7 @@ set_nr_vcpus(int xc_handle, u32 dom, unsigned long *pfn_list, } #ifdef __i386__ -static int zap_mmio_range(int xc_handle, u32 dom, +static int zap_mmio_range(int xc_handle, uint32_t dom, l2_pgentry_32_t *vl2tab, unsigned long mmio_range_start, unsigned long mmio_range_size) @@ -173,7 +173,7 @@ static int zap_mmio_range(int xc_handle, u32 dom, return 0; } -static int zap_mmio_ranges(int xc_handle, u32 dom, unsigned long l2tab, +static int zap_mmio_ranges(int xc_handle, uint32_t dom, unsigned long l2tab, unsigned char e820_map_nr, unsigned char *e820map) { unsigned int i; @@ -197,7 +197,7 @@ static int zap_mmio_ranges(int xc_handle, u32 dom, unsigned long l2tab, return 0; } #else -static int zap_mmio_range(int xc_handle, u32 dom, +static int zap_mmio_range(int xc_handle, uint32_t dom, l3_pgentry_t *vl3tab, unsigned long mmio_range_start, unsigned long mmio_range_size) @@ -247,7 +247,7 @@ static int zap_mmio_range(int xc_handle, u32 dom, return 0; } -static int zap_mmio_ranges(int xc_handle, u32 dom, unsigned long l3tab, +static int zap_mmio_ranges(int xc_handle, uint32_t dom, unsigned long l3tab, unsigned char e820_map_nr, unsigned char *e820map) { unsigned int i; @@ -271,7 +271,7 @@ static int zap_mmio_ranges(int xc_handle, u32 dom, unsigned long l3tab, #endif static int setup_guest(int xc_handle, - u32 dom, int memsize, + uint32_t dom, int memsize, char *image, unsigned long image_size, unsigned long nr_pages, vcpu_guest_context_t *ctxt, @@ -595,7 +595,7 @@ static int vmx_identify(void) } int xc_vmx_build(int xc_handle, - u32 domid, + uint32_t domid, int memsize, const char *image_name, unsigned int control_evtchn, @@ -635,7 +635,7 @@ int xc_vmx_build(int xc_handle, op.cmd = DOM0_GETDOMAININFO; op.u.getdomaininfo.domain = (domid_t)domid; if ( (xc_dom0_op(xc_handle, &op) < 0) || - ((u16)op.u.getdomaininfo.domain != domid) ) + ((uint16_t)op.u.getdomaininfo.domain != domid) ) { PERROR("Could not get info on domain"); goto error_out; @@ -790,7 +790,7 @@ static int parseelfimage(char *elfbase, static int loadelfimage( - char *elfbase, int xch, u32 dom, unsigned long *parray, + char *elfbase, int xch, uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi) { Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfbase; diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 5ba19a891b..7cd50df0b3 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -10,16 +10,6 @@ #define XENCTRL_H #include - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; - #include #include #include @@ -105,14 +95,14 @@ typedef struct xc_core_header { long xc_ptrace( int xc_handle, enum __ptrace_request request, - u32 domid, + uint32_t domid, long addr, long data); long xc_ptrace_core( int xc_handle, enum __ptrace_request request, - u32 domid, + uint32_t domid, long addr, long data); @@ -133,28 +123,28 @@ int xc_waitdomain_core( */ typedef struct { - u32 domid; - u32 ssidref; + uint32_t domid; + uint32_t ssidref; unsigned int dying:1, crashed:1, shutdown:1, paused:1, blocked:1, running:1; unsigned int shutdown_reason; /* only meaningful if shutdown==1 */ unsigned long nr_pages; unsigned long shared_info_frame; - u64 cpu_time; + uint64_t cpu_time; unsigned long max_memkb; unsigned int vcpus; - s32 vcpu_to_cpu[MAX_VIRT_CPUS]; + int32_t vcpu_to_cpu[MAX_VIRT_CPUS]; cpumap_t cpumap[MAX_VIRT_CPUS]; } xc_dominfo_t; typedef dom0_getdomaininfo_t xc_domaininfo_t; int xc_domain_create(int xc_handle, - u32 ssidref, - u32 *pdomid); + uint32_t ssidref, + uint32_t *pdomid); int xc_domain_dumpcore(int xc_handle, - u32 domid, + uint32_t domid, const char *corename); @@ -167,7 +157,7 @@ int xc_domain_dumpcore(int xc_handle, * @return 0 on success, -1 on failure. */ int xc_domain_pause(int xc_handle, - u32 domid); + uint32_t domid); /** * This function unpauses a domain. The domain should have been previously * paused. @@ -177,7 +167,7 @@ int xc_domain_pause(int xc_handle, * return 0 on success, -1 on failure */ int xc_domain_unpause(int xc_handle, - u32 domid); + uint32_t domid); /** * This function will destroy a domain. Destroying a domain removes the domain @@ -189,9 +179,9 @@ int xc_domain_unpause(int xc_handle, * @return 0 on success, -1 on failure */ int xc_domain_destroy(int xc_handle, - u32 domid); + uint32_t domid); int xc_domain_pincpu(int xc_handle, - u32 domid, + uint32_t domid, int vcpu, cpumap_t *cpumap); /** @@ -210,7 +200,7 @@ int xc_domain_pincpu(int xc_handle, * @return the number of domains enumerated or -1 on error */ int xc_domain_getinfo(int xc_handle, - u32 first_domid, + uint32_t first_domid, unsigned int max_doms, xc_dominfo_t *info); @@ -228,7 +218,7 @@ int xc_domain_getinfo(int xc_handle, * @return the number of domains enumerated or -1 on error */ int xc_domain_getinfolist(int xc_handle, - u32 first_domain, + uint32_t first_domain, unsigned int max_domains, xc_domaininfo_t *info); @@ -244,12 +234,12 @@ int xc_domain_getinfolist(int xc_handle, * @return 0 on success, -1 on failure */ int xc_domain_get_vcpu_context(int xc_handle, - u32 domid, - u32 vcpu, + uint32_t domid, + uint32_t vcpu, vcpu_guest_context_t *ctxt); int xc_domain_setcpuweight(int xc_handle, - u32 domid, + uint32_t domid, float weight); long long xc_domain_get_cpu_usage(int xc_handle, domid_t domid, @@ -258,7 +248,7 @@ long long xc_domain_get_cpu_usage(int xc_handle, typedef dom0_shadow_control_stats_t xc_shadow_control_stats_t; int xc_shadow_control(int xc_handle, - u32 domid, + uint32_t domid, unsigned int sop, unsigned long *dirty_bitmap, unsigned long pages, @@ -268,10 +258,10 @@ int xc_bvtsched_global_set(int xc_handle, unsigned long ctx_allow); int xc_bvtsched_domain_set(int xc_handle, - u32 domid, - u32 mcuadv, + uint32_t domid, + uint32_t mcuadv, int warpback, - s32 warpvalue, + int32_t warpvalue, long long warpl, long long warpu); @@ -279,20 +269,24 @@ int xc_bvtsched_global_get(int xc_handle, unsigned long *ctx_allow); int xc_bvtsched_domain_get(int xc_handle, - u32 domid, - u32 *mcuadv, + uint32_t domid, + uint32_t *mcuadv, int *warpback, - s32 *warpvalue, + int32_t *warpvalue, long long *warpl, long long *warpu); int xc_sedf_domain_set(int xc_handle, - u32 domid, - u64 period, u64 slice, u64 latency, u16 extratime, u16 weight); + uint32_t domid, + uint64_t period, uint64_t slice, + uint64_t latency, uint16_t extratime, + uint16_t weight); int xc_sedf_domain_get(int xc_handle, - u32 domid, - u64* period, u64 *slice, u64 *latency, u16 *extratime, u16* weight); + uint32_t domid, + uint64_t* period, uint64_t *slice, + uint64_t *latency, uint16_t *extratime, + uint16_t *weight); typedef evtchn_status_t xc_evtchn_status_t; @@ -311,16 +305,16 @@ typedef evtchn_status_t xc_evtchn_status_t; * @return allocated port (in @dom) on success, -1 on failure */ int xc_evtchn_alloc_unbound(int xc_handle, - u32 dom, - u32 remote_dom); + uint32_t dom, + uint32_t remote_dom); int xc_evtchn_status(int xc_handle, - u32 dom, /* may be DOMID_SELF */ + uint32_t dom, /* may be DOMID_SELF */ int port, xc_evtchn_status_t *status); int xc_physdev_pci_access_modify(int xc_handle, - u32 domid, + uint32_t domid, int bus, int dev, int func, @@ -339,29 +333,29 @@ int xc_sched_id(int xc_handle, int *sched_id); int xc_domain_setmaxmem(int xc_handle, - u32 domid, + uint32_t domid, unsigned int max_memkb); int xc_domain_memory_increase_reservation(int xc_handle, - u32 domid, + uint32_t domid, unsigned long nr_extents, unsigned int extent_order, unsigned int address_bits, unsigned long *extent_start); int xc_domain_memory_decrease_reservation(int xc_handle, - u32 domid, + uint32_t domid, unsigned long nr_extents, unsigned int extent_order, unsigned long *extent_start); -unsigned long xc_make_page_below_4G(int xc_handle, u32 domid, +unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid, unsigned long mfn); typedef dom0_perfc_desc_t xc_perfc_desc_t; /* IMPORTANT: The caller is responsible for mlock()'ing the @desc array. */ int xc_perfc_control(int xc_handle, - u32 op, + uint32_t op, xc_perfc_desc_t *desc); /* read/write msr */ @@ -384,27 +378,29 @@ int xc_msr_write(int xc_handle, int cpu_mask, int msr, unsigned int low, * @parm prot same flag as in mmap(). * @parm mfn the frame address to map. */ -void *xc_map_foreign_range(int xc_handle, u32 dom, +void *xc_map_foreign_range(int xc_handle, uint32_t dom, int size, int prot, unsigned long mfn ); -void *xc_map_foreign_batch(int xc_handle, u32 dom, int prot, +void *xc_map_foreign_batch(int xc_handle, uint32_t dom, int prot, unsigned long *arr, int num ); -int xc_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, +int xc_get_pfn_list(int xc_handle, uint32_t domid, unsigned long *pfn_buf, unsigned long max_pfns); -int xc_ia64_get_pfn_list(int xc_handle, u32 domid, unsigned long *pfn_buf, - unsigned int start_page, unsigned int nr_pages); +int xc_ia64_get_pfn_list(int xc_handle, uint32_t domid, + unsigned long *pfn_buf, + unsigned int start_page, unsigned int nr_pages); -long xc_get_max_pages(int xc_handle, u32 domid); +long xc_get_max_pages(int xc_handle, uint32_t domid); int xc_mmuext_op(int xc_handle, struct mmuext_op *op, unsigned int nr_ops, domid_t dom); int xc_memory_op(int xc_handle, int cmd, void *arg); -int xc_get_pfn_type_batch(int xc_handle, u32 dom, int num, unsigned long *arr); +int xc_get_pfn_type_batch(int xc_handle, uint32_t dom, + int num, unsigned long *arr); /*\ @@ -438,33 +434,33 @@ int xc_grant_interface_open(void); */ int xc_grant_interface_close(int xc_handle); -int xc_gnttab_map_grant_ref(int xc_handle, - u64 host_virt_addr, - u32 dom, - u16 ref, - u16 flags, - s16 *handle, - u64 *dev_bus_addr); +int xc_gnttab_map_grant_ref(int xc_handle, + uint64_t host_virt_addr, + uint32_t dom, + uint16_t ref, + uint16_t flags, + int16_t *handle, + uint64_t *dev_bus_addr); int xc_gnttab_unmap_grant_ref(int xc_handle, - u64 host_virt_addr, - u64 dev_bus_addr, - u16 handle, - s16 *status); + uint64_t host_virt_addr, + uint64_t dev_bus_addr, + uint16_t handle, + int16_t *status); int xc_gnttab_setup_table(int xc_handle, - u32 dom, - u16 nr_frames, - s16 *status, + uint32_t dom, + uint16_t nr_frames, + int16_t *status, unsigned long **frame_list); /* Grant debug builds only: */ int xc_gnttab_dump_table(int xc_handle, - u32 dom, - s16 *status); + uint32_t dom, + int16_t *status); /* Get current total pages allocated to a domain. */ -long xc_get_tot_pages(int xc_handle, u32 domid); +long xc_get_tot_pages(int xc_handle, uint32_t domid); /* Execute a privileged dom0 operation. */ int xc_dom0_op(int xc_handle, dom0_op_t *op); diff --git a/tools/libxc/xg_private.h b/tools/libxc/xg_private.h index 186b68940a..b79b6310a9 100644 --- a/tools/libxc/xg_private.h +++ b/tools/libxc/xg_private.h @@ -60,11 +60,11 @@ unsigned long csum_page (void * page); #define PAGE_SIZE (1UL << PAGE_SHIFT) #define PAGE_MASK (~(PAGE_SIZE-1)) -typedef u32 l1_pgentry_32_t; -typedef u32 l2_pgentry_32_t; -typedef u64 l1_pgentry_64_t; -typedef u64 l2_pgentry_64_t; -typedef u64 l3_pgentry_64_t; +typedef uint32_t l1_pgentry_32_t; +typedef uint32_t l2_pgentry_32_t; +typedef uint64_t l1_pgentry_64_t; +typedef uint64_t l2_pgentry_64_t; +typedef uint64_t l3_pgentry_64_t; typedef unsigned long l1_pgentry_t; typedef unsigned long l2_pgentry_t; #if defined(__x86_64__) @@ -129,7 +129,7 @@ struct domain_setup_info typedef int (*parseimagefunc)(char *image, unsigned long image_size, struct domain_setup_info *dsi); typedef int (*loadimagefunc)(char *image, unsigned long image_size, int xch, - u32 dom, unsigned long *parray, + uint32_t dom, unsigned long *parray, struct domain_setup_info *dsi); struct load_funcs @@ -153,13 +153,13 @@ typedef struct mfn_mapper { unsigned long xc_get_m2p_start_mfn (int xc_handle); -int xc_copy_to_domain_page(int xc_handle, u32 domid, +int xc_copy_to_domain_page(int xc_handle, uint32_t domid, unsigned long dst_pfn, void *src_page); unsigned long xc_get_filesz(int fd); void xc_map_memcpy(unsigned long dst, char *src, unsigned long size, - int xch, u32 dom, unsigned long *parray, + int xch, uint32_t dom, unsigned long *parray, unsigned long vstart); int pin_table(int xc_handle, unsigned int type, unsigned long mfn, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index c78c5061ed..8e8c9ecd03 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -42,7 +42,7 @@ static PyObject *pyxc_domain_dumpcore(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; char *corefile; static char *kwd_list[] = { "dom", "corefile", NULL }; @@ -77,9 +77,9 @@ static PyObject *pyxc_domain_create(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom = 0; + uint32_t dom = 0; int ret; - u32 ssidref = 0x0; + uint32_t ssidref = 0x0; static char *kwd_list[] = { "dom", "ssidref", NULL }; @@ -99,7 +99,7 @@ static PyObject *pyxc_domain_pause(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; static char *kwd_list[] = { "dom", NULL }; @@ -119,7 +119,7 @@ static PyObject *pyxc_domain_unpause(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; static char *kwd_list[] = { "dom", NULL }; @@ -139,7 +139,7 @@ static PyObject *pyxc_domain_destroy(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; static char *kwd_list[] = { "dom", NULL }; @@ -159,7 +159,7 @@ static PyObject *pyxc_domain_pincpu(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; int vcpu = 0; cpumap_t cpumap = 0xFFFFFFFF; @@ -182,7 +182,7 @@ static PyObject *pyxc_domain_setcpuweight(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; float cpuweight = 1; static char *kwd_list[] = { "dom", "cpuweight", NULL }; @@ -205,7 +205,7 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, XcObject *xc = (XcObject *)self; PyObject *list, *vcpu_list, *cpumap_list, *info_dict; - u32 first_dom = 0; + uint32_t first_dom = 0; int max_doms = 1024, nr_doms, i, j; xc_dominfo_t *info; @@ -270,7 +270,7 @@ static PyObject *pyxc_linux_build(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; char *image, *ramdisk = NULL, *cmdline = ""; int flags = 0, vcpus = 1; int store_evtchn, console_evtchn; @@ -308,7 +308,7 @@ static PyObject *pyxc_vmx_build(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; char *image; int control_evtchn, store_evtchn; int flags = 0, vcpus = 1; @@ -373,10 +373,10 @@ static PyObject *pyxc_bvtsched_domain_set(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; - u32 mcuadv; + uint32_t dom; + uint32_t mcuadv; int warpback; - s32 warpvalue; + int32_t warpvalue; long long warpl; long long warpu; @@ -401,10 +401,10 @@ static PyObject *pyxc_bvtsched_domain_get(PyObject *self, PyObject *kwds) { XcObject *xc = (XcObject *)self; - u32 dom; - u32 mcuadv; + uint32_t dom; + uint32_t mcuadv; int warpback; - s32 warpvalue; + int32_t warpvalue; long long warpl; long long warpu; @@ -432,7 +432,7 @@ static PyObject *pyxc_evtchn_alloc_unbound(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom, remote_dom; + uint32_t dom, remote_dom; int port; static char *kwd_list[] = { "dom", "remote_dom", NULL }; @@ -454,7 +454,7 @@ static PyObject *pyxc_evtchn_status(PyObject *self, XcObject *xc = (XcObject *)self; PyObject *dict; - u32 dom = DOMID_SELF; + uint32_t dom = DOMID_SELF; int port, ret; xc_evtchn_status_t status; @@ -507,7 +507,7 @@ static PyObject *pyxc_physdev_pci_access_modify(PyObject *self, PyObject *kwds) { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; int bus, dev, func, enable, ret; static char *kwd_list[] = { "dom", "bus", "dev", "func", "enable", NULL }; @@ -635,9 +635,9 @@ static PyObject *pyxc_sedf_domain_set(PyObject *self, PyObject *kwds) { XcObject *xc = (XcObject *)self; - u32 domid; - u64 period, slice, latency; - u16 extratime, weight; + uint32_t domid; + uint64_t period, slice, latency; + uint16_t extratime, weight; static char *kwd_list[] = { "dom", "period", "slice", "latency", "extratime", "weight",NULL }; @@ -658,9 +658,9 @@ static PyObject *pyxc_sedf_domain_get(PyObject *self, PyObject *kwds) { XcObject *xc = (XcObject *)self; - u32 domid; - u64 period, slice,latency; - u16 weight, extratime; + uint32_t domid; + uint64_t period, slice,latency; + uint16_t weight, extratime; static char *kwd_list[] = { "dom", NULL }; @@ -685,7 +685,7 @@ static PyObject *pyxc_shadow_control(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; int op=0; static char *kwd_list[] = { "dom", "op", NULL }; @@ -707,7 +707,7 @@ static PyObject *pyxc_domain_setmaxmem(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; unsigned int maxmem_kb; static char *kwd_list[] = { "dom", "maxmem_kb", NULL }; @@ -729,7 +729,7 @@ static PyObject *pyxc_domain_memory_increase_reservation(PyObject *self, { XcObject *xc = (XcObject *)self; - u32 dom; + uint32_t dom; unsigned long mem_kb; unsigned int extent_order = 0 , address_bits = 0; unsigned long nr_extents; diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c index be3e0ad4c2..48a317dd88 100644 --- a/tools/python/xen/lowlevel/xs/xs.c +++ b/tools/python/xen/lowlevel/xs/xs.c @@ -28,6 +28,7 @@ #include #include +#include #include "xs.h" /** @file diff --git a/tools/security/Makefile b/tools/security/Makefile index 23a6eea078..7123edb515 100644 --- a/tools/security/Makefile +++ b/tools/security/Makefile @@ -47,10 +47,10 @@ build: mk-symlinks chmod 700 ./updategrub.sh chmod 700 ./getlabel.sh -secpol_tool : secpol_tool.c secpol_compat.h +secpol_tool : secpol_tool.c $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $< -secpol_xml2bin : secpol_xml2bin.c secpol_xml2bin.h secpol_compat.h +secpol_xml2bin : secpol_xml2bin.c secpol_xml2bin.h $(CC) $(CPPFLAGS) $(CFLAGS) $(CFLAGS_XML2BIN) $(VALIDATE_SCHEMA) -o $@ $< clean: diff --git a/tools/security/secpol_compat.h b/tools/security/secpol_compat.h deleted file mode 100644 index 7f497ba2fc..0000000000 --- a/tools/security/secpol_compat.h +++ /dev/null @@ -1,14 +0,0 @@ -/* secpol_compat.h - * 'translates' data types necessary to - * include - */ -#include - -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; diff --git a/tools/security/secpol_tool.c b/tools/security/secpol_tool.c index e5d4e34298..1fd24cad93 100644 --- a/tools/security/secpol_tool.c +++ b/tools/security/secpol_tool.c @@ -33,7 +33,7 @@ #include #include #include -#include "secpol_compat.h" +#include #include #include #include diff --git a/tools/security/secpol_xml2bin.c b/tools/security/secpol_xml2bin.c index aaa3744f08..4bfd8ed68b 100644 --- a/tools/security/secpol_xml2bin.c +++ b/tools/security/secpol_xml2bin.c @@ -37,7 +37,7 @@ #include #include #include -#include "secpol_compat.h" +#include #include #include "secpol_xml2bin.h" diff --git a/tools/xenstat/libxenstat/src/xen-interface.h b/tools/xenstat/libxenstat/src/xen-interface.h index 8d8c403147..2cda13583e 100644 --- a/tools/xenstat/libxenstat/src/xen-interface.h +++ b/tools/xenstat/libxenstat/src/xen-interface.h @@ -16,16 +16,6 @@ */ #include - -typedef int8_t s8; -typedef int16_t s16; -typedef int32_t s32; -typedef int64_t s64; -typedef uint8_t u8; -typedef uint16_t u16; -typedef uint32_t u32; -typedef uint64_t u64; - #include #include #include diff --git a/tools/xenstore/fake_libxc.c b/tools/xenstore/fake_libxc.c index 5a02b2e597..14025ec089 100644 --- a/tools/xenstore/fake_libxc.c +++ b/tools/xenstore/fake_libxc.c @@ -30,10 +30,11 @@ #include "xenstored_core.h" #include "xenstored_domain.h" #include "xenstored_test.h" +#include static int sigfd; static int xs_test_pid; -static u16 port; +static uint16_t port; /* The event channel maps to a signal, shared page to an mmapped file. */ void evtchn_notify(int local_port) @@ -43,7 +44,7 @@ void evtchn_notify(int local_port) barf_perror("fake event channel failed"); } -void *xc_map_foreign_range(int xc_handle, u32 dom __attribute__((unused)), +void *xc_map_foreign_range(int xc_handle, uint32_t dom __attribute__((unused)), int size, int prot, unsigned long mfn __attribute__((unused))) { @@ -83,7 +84,7 @@ int xc_interface_close(int xc_handle) } int xc_domain_getinfo(int xc_handle __attribute__((unused)), - u32 first_domid, unsigned int max_doms, + uint32_t first_domid, unsigned int max_doms, xc_dominfo_t *info) { assert(max_doms == 1); diff --git a/tools/xenstore/tdb.c b/tools/xenstore/tdb.c index 558d5fd16d..fdf3d5a837 100644 --- a/tools/xenstore/tdb.c +++ b/tools/xenstore/tdb.c @@ -154,9 +154,9 @@ static void tdb_mmap(TDB_CONTEXT *tdb) } /* Endian conversion: we only ever deal with 4 byte quantities */ -static void *convert(void *buf, u32 size) +static void *convert(void *buf, uint32_t size) { - u32 i, *p = buf; + uint32_t i, *p = buf; for (i = 0; i < size / 4; i++) p[i] = TDB_BYTEREV(p[i]); return buf; @@ -171,8 +171,8 @@ struct list_struct { tdb_len rec_len; /* total byte length of record */ tdb_len key_len; /* byte length of key */ tdb_len data_len; /* byte length of data */ - u32 full_hash; /* the full 32 bit hash of the key */ - u32 magic; /* try to catch errors */ + uint32_t full_hash; /* the full 32 bit hash of the key */ + uint32_t magic; /* try to catch errors */ /* the following union is implied: union { char record[rec_len]; @@ -180,7 +180,7 @@ struct list_struct { char key[key_len]; char data[data_len]; } - u32 totalsize; (tailer) + uint32_t totalsize; (tailer) } */ }; @@ -294,10 +294,10 @@ static int tdb_unlock(TDB_CONTEXT *tdb, int list, } /* This is based on the hash algorithm from gdbm */ -static u32 default_tdb_hash(TDB_DATA *key) +static uint32_t default_tdb_hash(TDB_DATA *key) { - u32 value; /* Used to compute the hash value. */ - u32 i; /* Used to cycle through random values. */ + uint32_t value; /* Used to compute the hash value. */ + uint32_t i; /* Used to cycle through random values. */ /* Set the initial value from the key size. */ for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) @@ -399,7 +399,7 @@ static int tdb_read(TDB_CONTEXT *tdb,tdb_off off,void *buf,tdb_len len,int cv) static int tdb_key_eq(TDB_CONTEXT *tdb, tdb_off off, TDB_DATA key) { char buf[64]; - u32 len; + uint32_t len; if (tdb_oob(tdb, off + key.dsize, 0) != 0) return -1; @@ -1030,7 +1030,7 @@ static int tdb_new_database(TDB_CONTEXT *tdb, int hash_size) /* Returns 0 on fail. On success, return offset of record, and fills in rec */ -static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, +static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, uint32_t hash, struct list_struct *r) { tdb_off rec_ptr; @@ -1058,10 +1058,10 @@ static tdb_off tdb_find(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, } /* As tdb_find, but if you succeed, keep the lock */ -static tdb_off tdb_find_lock_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, int locktype, +static tdb_off tdb_find_lock_hash(TDB_CONTEXT *tdb, TDB_DATA key, uint32_t hash, int locktype, struct list_struct *rec) { - u32 rec_ptr; + uint32_t rec_ptr; if (tdb_lock(tdb, BUCKET(hash), locktype) == -1) return 0; @@ -1089,7 +1089,7 @@ static struct tdb_errname { /* Error string for the last tdb error */ const char *tdb_errorstr(TDB_CONTEXT *tdb) { - u32 i; + uint32_t i; for (i = 0; i < sizeof(emap) / sizeof(struct tdb_errname); i++) if (tdb->ecode == emap[i].ecode) return emap[i].estring; @@ -1101,7 +1101,7 @@ const char *tdb_errorstr(TDB_CONTEXT *tdb) on failure return -1. */ -static int tdb_update_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA dbuf) +static int tdb_update_hash(TDB_CONTEXT *tdb, TDB_DATA key, uint32_t hash, TDB_DATA dbuf) { struct list_struct rec; tdb_off rec_ptr; @@ -1141,7 +1141,7 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) tdb_off rec_ptr; struct list_struct rec; TDB_DATA ret; - u32 hash; + uint32_t hash; /* find which hash bucket it is in */ hash = tdb->hash_fn(&key); @@ -1161,7 +1161,7 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) this doesn't match the conventions in the rest of this module, but is compatible with gdbm */ -static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) +static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, uint32_t hash) { struct list_struct rec; @@ -1173,7 +1173,7 @@ static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) { - u32 hash = tdb->hash_fn(&key); + uint32_t hash = tdb->hash_fn(&key); return tdb_exists_hash(tdb, key, hash); } @@ -1210,7 +1210,7 @@ static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off) static int unlock_record(TDB_CONTEXT *tdb, tdb_off off) { struct tdb_traverse_lock *i; - u32 count = 0; + uint32_t count = 0; if (off == 0) return 0; @@ -1293,10 +1293,10 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock, system (testing using ldbtest). */ if (!tlock->off && tlock->hash != 0) { - u32 off; + uint32_t off; if (tdb->map_ptr) { for (;tlock->hash < tdb->header.hash_size;tlock->hash++) { - if (0 != *(u32 *)(TDB_HASH_TOP(tlock->hash) + (unsigned char *)tdb->map_ptr)) { + if (0 != *(uint32_t *)(TDB_HASH_TOP(tlock->hash) + (unsigned char *)tdb->map_ptr)) { break; } } @@ -1459,7 +1459,7 @@ TDB_DATA tdb_firstkey(TDB_CONTEXT *tdb) /* find the next entry in the database, returning its key */ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey) { - u32 oldhash; + uint32_t oldhash; TDB_DATA key = tdb_null; struct list_struct rec; char *k = NULL; @@ -1513,7 +1513,7 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey) } /* delete an entry in the database given a key */ -static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) +static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, uint32_t hash) { tdb_off rec_ptr; struct list_struct rec; @@ -1529,7 +1529,7 @@ static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) { - u32 hash = tdb->hash_fn(&key); + uint32_t hash = tdb->hash_fn(&key); return tdb_delete_hash(tdb, key, hash); } @@ -1541,7 +1541,7 @@ int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) { struct list_struct rec; - u32 hash; + uint32_t hash; tdb_off rec_ptr; char *p = NULL; int ret = 0; @@ -1622,7 +1622,7 @@ fail: is <= the old data size and the key exists. on failure return -1. Record must be locked before calling. */ -static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA new_dbuf) +static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, uint32_t hash, TDB_DATA new_dbuf) { struct list_struct rec; tdb_off rec_ptr; @@ -1656,7 +1656,7 @@ static int tdb_append_inplace(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash, TDB_DATA int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) { struct list_struct rec; - u32 hash; + uint32_t hash; tdb_off rec_ptr; char *p = NULL; int ret = 0; @@ -1790,7 +1790,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, struct stat st; int rev = 0, locked = 0; uint8_t *vp; - u32 vertest; + uint32_t vertest; if (!(tdb = talloc_zero(name, TDB_CONTEXT))) { /* Can't log this */ @@ -1869,8 +1869,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, rev = (tdb->flags & TDB_CONVERT); } vp = (uint8_t *)&tdb->header.version; - vertest = (((u32)vp[0]) << 24) | (((u32)vp[1]) << 16) | - (((u32)vp[2]) << 8) | (u32)vp[3]; + vertest = (((uint32_t)vp[0]) << 24) | (((uint32_t)vp[1]) << 16) | + (((uint32_t)vp[2]) << 8) | (uint32_t)vp[3]; tdb->flags |= (vertest==TDB_VERSION) ? TDB_BIGENDIAN : 0; if (!rev) tdb->flags &= ~TDB_CONVERT; @@ -2000,7 +2000,7 @@ int tdb_close(TDB_CONTEXT *tdb) /* lock/unlock entire database */ int tdb_lockall(TDB_CONTEXT *tdb) { - u32 i; + uint32_t i; /* There are no locks on read-only dbs */ if (tdb->read_only) @@ -2011,7 +2011,7 @@ int tdb_lockall(TDB_CONTEXT *tdb) /* If error, release locks we have... */ if (i < tdb->header.hash_size) { - u32 j; + uint32_t j; for ( j = 0; j < i; j++) tdb_unlock(tdb, j, F_WRLCK); @@ -2022,7 +2022,7 @@ int tdb_lockall(TDB_CONTEXT *tdb) } void tdb_unlockall(TDB_CONTEXT *tdb) { - u32 i; + uint32_t i; for (i=0; i < tdb->header.hash_size; i++) tdb_unlock(tdb, i, F_WRLCK); } diff --git a/tools/xenstore/tdb.h b/tools/xenstore/tdb.h index d0e782de50..84d2df3a0e 100644 --- a/tools/xenstore/tdb.h +++ b/tools/xenstore/tdb.h @@ -53,8 +53,8 @@ enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT, TDB_ERR_NOEXIST}; -#ifndef u32 -#define u32 unsigned +#ifndef uint32_t +#define uint32_t unsigned #endif typedef struct TDB_DATA { @@ -62,27 +62,27 @@ typedef struct TDB_DATA { size_t dsize; } TDB_DATA; -typedef u32 tdb_len; -typedef u32 tdb_off; +typedef uint32_t tdb_len; +typedef uint32_t tdb_off; /* this is stored at the front of every database */ struct tdb_header { char magic_food[32]; /* for /etc/magic */ - u32 version; /* version of the code */ - u32 hash_size; /* number of hash entries */ + uint32_t version; /* version of the code */ + uint32_t hash_size; /* number of hash entries */ tdb_off rwlocks; tdb_off reserved[31]; }; struct tdb_lock_type { - u32 count; - u32 ltype; + uint32_t count; + uint32_t ltype; }; struct tdb_traverse_lock { struct tdb_traverse_lock *next; - u32 off; - u32 hash; + uint32_t off; + uint32_t hash; }; #ifndef PRINTF_ATTRIBUTE @@ -99,19 +99,19 @@ typedef struct tdb_context { struct tdb_lock_type *locked; /* array of chain locks */ enum TDB_ERROR ecode; /* error code for last tdb error */ struct tdb_header header; /* a cached copy of the header */ - u32 flags; /* the flags passed to tdb_open */ + uint32_t flags; /* the flags passed to tdb_open */ struct tdb_traverse_lock travlocks; /* current traversal locks */ struct tdb_context *next; /* all tdbs to avoid multiple opens */ dev_t device; /* uniquely identifies this tdb */ ino_t inode; /* uniquely identifies this tdb */ void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...) PRINTF_ATTRIBUTE(3,4); /* logging function */ - u32 (*hash_fn)(TDB_DATA *key); + uint32_t (*hash_fn)(TDB_DATA *key); int open_flags; /* flags used in the open - needed by reopen */ } TDB_CONTEXT; typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *); typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...); -typedef u32 (*tdb_hash_func)(TDB_DATA *key); +typedef uint32_t (*tdb_hash_func)(TDB_DATA *key); TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags, int open_flags, mode_t mode); diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index d87f9b9dce..baa78bd1a3 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -378,7 +378,7 @@ bool is_child(const char *child, const char *parent) static struct node *read_node(struct connection *conn, const char *name) { TDB_DATA key, data; - u32 *p; + uint32_t *p; struct node *node; key.dptr = (void *)name; @@ -400,7 +400,7 @@ static struct node *read_node(struct connection *conn, const char *name) talloc_steal(node, data.dptr); /* Datalen, childlen, number of permissions */ - p = (u32 *)data.dptr; + p = (uint32_t *)data.dptr; node->num_perms = p[0]; node->datalen = p[1]; node->childlen = p[2]; @@ -423,14 +423,14 @@ static bool write_node(struct connection *conn, const struct node *node) key.dptr = (void *)node->name; key.dsize = strlen(node->name); - data.dsize = 3*sizeof(u32) + data.dsize = 3*sizeof(uint32_t) + node->num_perms*sizeof(node->perms[0]) + node->datalen + node->childlen; data.dptr = talloc_size(node, data.dsize); - ((u32 *)data.dptr)[0] = node->num_perms; - ((u32 *)data.dptr)[1] = node->datalen; - ((u32 *)data.dptr)[2] = node->childlen; - p = data.dptr + 3 * sizeof(u32); + ((uint32_t *)data.dptr)[0] = node->num_perms; + ((uint32_t *)data.dptr)[1] = node->datalen; + ((uint32_t *)data.dptr)[2] = node->childlen; + p = data.dptr + 3 * sizeof(uint32_t); memcpy(p, node->perms, node->num_perms*sizeof(node->perms[0])); p += node->num_perms*sizeof(node->perms[0]); @@ -668,7 +668,7 @@ static char *perms_to_strings(const void *ctx, { unsigned int i; char *strings = NULL; - char buffer[MAX_STRLEN(domid_t) + 1]; + char buffer[MAX_STRLEN(unsigned int) + 1]; for (*len = 0, i = 0; i < num; i++) { if (!xs_perm_to_string(&perms[i], buffer)) diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index 600e95a6f8..e8f4a28c65 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -60,7 +60,7 @@ struct connection int fd; /* Who am I? 0 for socket connections. */ - domid_t id; + unsigned int id; /* Is this a read-only connection? */ bool can_write; @@ -76,7 +76,7 @@ struct connection /* List of in-progress transactions. */ struct list_head transaction_list; - u32 next_transaction_id; + uint32_t next_transaction_id; /* The domain I'm associated with, if any. */ struct domain *domain; diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index f2b847c4e9..d9c45507c7 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -36,6 +36,7 @@ #include "xenstored_watch.h" #include "xenstored_test.h" +#include #include static int *xc_handle; @@ -48,14 +49,14 @@ struct domain struct list_head list; /* The id of this domain */ - domid_t domid; + unsigned int domid; /* Event channel port */ - u16 port; + uint16_t port; /* The remote end of the event channel, used only to validate repeated domain introductions. */ - u16 remote_port; + uint16_t remote_port; /* The mfn associated with the event channel, used only to validate repeated domain introductions. */ @@ -81,9 +82,9 @@ static LIST_HEAD(domains); struct ringbuf_head { - u32 write; /* Next place to write to */ - u32 read; /* Next place to read from */ - u8 flags; + uint32_t write; /* Next place to write to */ + uint32_t read; /* Next place to read from */ + uint8_t flags; char buf[0]; } __attribute__((packed)); @@ -106,9 +107,9 @@ static bool check_buffer(const struct ringbuf_head *h) /* We can't fill last byte: would look like empty buffer. */ static void *get_output_chunk(const struct ringbuf_head *h, - void *buf, u32 *len) + void *buf, uint32_t *len) { - u32 read_mark; + uint32_t read_mark; if (h->read == 0) read_mark = ringbuf_datasize - 1; @@ -123,7 +124,7 @@ static void *get_output_chunk(const struct ringbuf_head *h, } static const void *get_input_chunk(const struct ringbuf_head *h, - const void *buf, u32 *len) + const void *buf, uint32_t *len) { /* Here to the end of buffer, unless they haven't written some. */ *len = ringbuf_datasize - h->read; @@ -132,14 +133,14 @@ static const void *get_input_chunk(const struct ringbuf_head *h, return buf + h->read; } -static void update_output_chunk(struct ringbuf_head *h, u32 len) +static void update_output_chunk(struct ringbuf_head *h, uint32_t len) { h->write += len; if (h->write == ringbuf_datasize) h->write = 0; } -static void update_input_chunk(struct ringbuf_head *h, u32 len) +static void update_input_chunk(struct ringbuf_head *h, uint32_t len) { h->read += len; if (h->read == ringbuf_datasize) @@ -148,7 +149,7 @@ static void update_input_chunk(struct ringbuf_head *h, u32 len) static bool buffer_has_input(const struct ringbuf_head *h) { - u32 len; + uint32_t len; get_input_chunk(h, NULL, &len); return (len != 0); @@ -156,7 +157,7 @@ static bool buffer_has_input(const struct ringbuf_head *h) static bool buffer_has_output_room(const struct ringbuf_head *h) { - u32 len; + uint32_t len; get_output_chunk(h, NULL, &len); return (len != 0); @@ -164,7 +165,7 @@ static bool buffer_has_output_room(const struct ringbuf_head *h) static int writechn(struct connection *conn, const void *data, unsigned int len) { - u32 avail; + uint32_t avail; void *dest; struct ringbuf_head h; @@ -189,7 +190,7 @@ static int writechn(struct connection *conn, const void *data, unsigned int len) static int readchn(struct connection *conn, void *data, unsigned int len) { - u32 avail; + uint32_t avail; const void *src; struct ringbuf_head h; bool was_full; @@ -268,7 +269,7 @@ static void domain_cleanup(void) /* We scan all domains rather than use the information given here. */ void handle_event(void) { - u16 port; + uint16_t port; if (read(event_fd, &port, sizeof(port)) != sizeof(port)) barf_perror("Failed to read from event fd"); @@ -293,7 +294,7 @@ bool domain_can_write(struct connection *conn) buffer_has_output_room(conn->domain->output)); } -static struct domain *new_domain(void *context, domid_t domid, +static struct domain *new_domain(void *context, unsigned int domid, unsigned long mfn, int port, const char *path) { @@ -338,7 +339,7 @@ static struct domain *new_domain(void *context, domid_t domid, } -static struct domain *find_domain_by_domid(domid_t domid) +static struct domain *find_domain_by_domid(unsigned int domid) { struct domain *i; @@ -355,9 +356,9 @@ void do_introduce(struct connection *conn, struct buffered_data *in) { struct domain *domain; char *vec[4]; - domid_t domid; + unsigned int domid; unsigned long mfn; - u16 port; + uint16_t port; const char *path; if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { @@ -414,7 +415,7 @@ void do_introduce(struct connection *conn, struct buffered_data *in) void do_release(struct connection *conn, const char *domid_str) { struct domain *domain; - domid_t domid; + unsigned int domid; if (!domid_str) { send_error(conn, EINVAL); @@ -453,7 +454,7 @@ void do_release(struct connection *conn, const char *domid_str) void do_get_domain_path(struct connection *conn, const char *domid_str) { struct domain *domain; - domid_t domid; + unsigned int domid; if (!domid_str) { send_error(conn, EINVAL); diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c index 988ea5d0fb..f9d844e045 100644 --- a/tools/xenstore/xenstored_transaction.c +++ b/tools/xenstore/xenstored_transaction.c @@ -53,7 +53,7 @@ struct transaction struct list_head list; /* Connection-local identifier for this transaction. */ - u32 id; + uint32_t id; /* Generation when transaction started. */ unsigned int generation; @@ -107,7 +107,7 @@ static int destroy_transaction(void *_transaction) return 0; } -struct transaction *transaction_lookup(struct connection *conn, u32 id) +struct transaction *transaction_lookup(struct connection *conn, uint32_t id) { struct transaction *trans; diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h index 992791f7a9..1fc30dff50 100644 --- a/tools/xenstore/xenstored_transaction.h +++ b/tools/xenstore/xenstored_transaction.h @@ -25,7 +25,7 @@ struct transaction; void do_transaction_start(struct connection *conn, struct buffered_data *node); void do_transaction_end(struct connection *conn, const char *arg); -struct transaction *transaction_lookup(struct connection *conn, u32 id); +struct transaction *transaction_lookup(struct connection *conn, uint32_t id); /* This node was changed: can fail and longjmp. */ void add_change_node(struct transaction *trans, const char *node, diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c index e8a870e2a8..18e875e801 100644 --- a/tools/xenstore/xs.c +++ b/tools/xenstore/xs.c @@ -304,7 +304,7 @@ static void *xs_talkv(struct xs_handle *h, struct xs_transaction_handle *t, unsigned int i; struct sigaction ignorepipe, oldact; - msg.tx_id = (u32)(unsigned long)t; + msg.tx_id = (uint32_t)(unsigned long)t; msg.type = type; msg.len = 0; for (i = 0; i < num_vecs; i++) @@ -510,7 +510,7 @@ bool xs_set_permissions(struct xs_handle *h, iov[0].iov_len = strlen(path) + 1; for (i = 0; i < num_perms; i++) { - char buffer[MAX_STRLEN(domid_t)+1]; + char buffer[MAX_STRLEN(unsigned int)+1]; if (!xs_perm_to_string(&perms[i], buffer)) goto unwind; @@ -672,7 +672,8 @@ bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t, * This tells the store daemon about a shared memory page and event channel * associated with a domain: the domain uses these to communicate. */ -bool xs_introduce_domain(struct xs_handle *h, domid_t domid, unsigned long mfn, +bool xs_introduce_domain(struct xs_handle *h, + unsigned int domid, unsigned long mfn, unsigned int eventchn, const char *path) { char domid_str[MAX_STRLEN(domid)]; @@ -697,7 +698,7 @@ bool xs_introduce_domain(struct xs_handle *h, domid_t domid, unsigned long mfn, ARRAY_SIZE(iov), NULL)); } -bool xs_release_domain(struct xs_handle *h, domid_t domid) +bool xs_release_domain(struct xs_handle *h, unsigned int domid) { char domid_str[MAX_STRLEN(domid)]; @@ -706,7 +707,7 @@ bool xs_release_domain(struct xs_handle *h, domid_t domid) return xs_bool(xs_single(h, NULL, XS_RELEASE, domid_str, NULL)); } -char *xs_get_domain_path(struct xs_handle *h, domid_t domid) +char *xs_get_domain_path(struct xs_handle *h, unsigned int domid) { char domid_str[MAX_STRLEN(domid)]; diff --git a/tools/xenstore/xs.h b/tools/xenstore/xs.h index 133884ad52..92007458d3 100644 --- a/tools/xenstore/xs.h +++ b/tools/xenstore/xs.h @@ -124,20 +124,23 @@ bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t, bool abort); /* Introduce a new domain. - * This tells the store daemon about a shared memory page, event channel - * and store path associated with a domain: the domain uses these to communicate. + * This tells the store daemon about a shared memory page, event channel and + * store path associated with a domain: the domain uses these to communicate. */ -bool xs_introduce_domain(struct xs_handle *h, domid_t domid, unsigned long mfn, - unsigned int eventchn, const char *path); +bool xs_introduce_domain(struct xs_handle *h, + unsigned int domid, + unsigned long mfn, + unsigned int eventchn, + const char *path); /* Release a domain. * Tells the store domain to release the memory page to the domain. */ -bool xs_release_domain(struct xs_handle *h, domid_t domid); +bool xs_release_domain(struct xs_handle *h, unsigned int domid); /* Query the home path of a domain. */ -char *xs_get_domain_path(struct xs_handle *h, domid_t domid); +char *xs_get_domain_path(struct xs_handle *h, unsigned int domid); /* Only useful for DEBUG versions */ char *xs_debug_command(struct xs_handle *h, const char *cmd, diff --git a/tools/xenstore/xs_crashme.c b/tools/xenstore/xs_crashme.c index 9d708ba2eb..ea5bd92509 100644 --- a/tools/xenstore/xs_crashme.c +++ b/tools/xenstore/xs_crashme.c @@ -68,19 +68,19 @@ * of bytes. No alignment or length assumptions are made about * the input key. */ -static inline u32 jhash(const void *key, u32 length, u32 initval) +static inline uint32_t jhash(const void *key, uint32_t length, uint32_t initval) { - u32 a, b, c, len; - const u8 *k = key; + uint32_t a, b, c, len; + const uint8_t *k = key; len = length; a = b = JHASH_GOLDEN_RATIO; c = initval; while (len >= 12) { - a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24)); - b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24)); - c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24)); + a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) +((uint32_t)k[3]<<24)); + b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) +((uint32_t)k[7]<<24)); + c += (k[8] +((uint32_t)k[9]<<8) +((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24)); __jhash_mix(a,b,c); @@ -90,16 +90,16 @@ static inline u32 jhash(const void *key, u32 length, u32 initval) c += length; switch (len) { - case 11: c += ((u32)k[10]<<24); - case 10: c += ((u32)k[9]<<16); - case 9 : c += ((u32)k[8]<<8); - case 8 : b += ((u32)k[7]<<24); - case 7 : b += ((u32)k[6]<<16); - case 6 : b += ((u32)k[5]<<8); + case 11: c += ((uint32_t)k[10]<<24); + case 10: c += ((uint32_t)k[9]<<16); + case 9 : c += ((uint32_t)k[8]<<8); + case 8 : b += ((uint32_t)k[7]<<24); + case 7 : b += ((uint32_t)k[6]<<16); + case 6 : b += ((uint32_t)k[5]<<8); case 5 : b += k[4]; - case 4 : a += ((u32)k[3]<<24); - case 3 : a += ((u32)k[2]<<16); - case 2 : a += ((u32)k[1]<<8); + case 4 : a += ((uint32_t)k[3]<<24); + case 3 : a += ((uint32_t)k[2]<<16); + case 2 : a += ((uint32_t)k[1]<<8); case 1 : a += k[0]; }; @@ -108,12 +108,12 @@ static inline u32 jhash(const void *key, u32 length, u32 initval) return c; } -/* A special optimized version that handles 1 or more of u32s. - * The length parameter here is the number of u32s in the key. +/* A special optimized version that handles 1 or more of uint32_ts. + * The length parameter here is the number of uint32_ts in the key. */ -static inline u32 jhash2(u32 *k, u32 length, u32 initval) +static inline uint32_t jhash2(uint32_t *k, uint32_t length, uint32_t initval) { - u32 a, b, c, len; + uint32_t a, b, c, len; a = b = JHASH_GOLDEN_RATIO; c = initval; @@ -146,7 +146,7 @@ static inline u32 jhash2(u32 *k, u32 length, u32 initval) * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally * done at the end is not done here. */ -static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) +static inline uint32_t jhash_3words(uint32_t a, uint32_t b, uint32_t c, uint32_t initval) { a += JHASH_GOLDEN_RATIO; b += JHASH_GOLDEN_RATIO; @@ -157,12 +157,12 @@ static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) return c; } -static inline u32 jhash_2words(u32 a, u32 b, u32 initval) +static inline uint32_t jhash_2words(uint32_t a, uint32_t b, uint32_t initval) { return jhash_3words(a, b, 0, initval); } -static inline u32 jhash_1word(u32 a, u32 initval) +static inline uint32_t jhash_1word(uint32_t a, uint32_t initval) { return jhash_3words(a, 0, 0, initval); } diff --git a/tools/xenstore/xs_lib.c b/tools/xenstore/xs_lib.c index a469578993..226a8487f7 100644 --- a/tools/xenstore/xs_lib.c +++ b/tools/xenstore/xs_lib.c @@ -135,7 +135,7 @@ bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num, return true; } -/* Convert permissions to a string (up to len MAX_STRLEN(domid_t)+1). */ +/* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */ bool xs_perm_to_string(const struct xs_permissions *perm, char *buffer) { switch (perm->perms) { diff --git a/tools/xenstore/xs_lib.h b/tools/xenstore/xs_lib.h index d446a1cc9c..c62c457e61 100644 --- a/tools/xenstore/xs_lib.h +++ b/tools/xenstore/xs_lib.h @@ -22,8 +22,8 @@ #include #include -#include #include +#include #include /* Bitmask of permissions. */ @@ -58,7 +58,7 @@ bool xs_write_all(int fd, const void *data, unsigned int len); bool xs_strings_to_perms(struct xs_permissions *perms, unsigned int num, const char *strings); -/* Convert permissions to a string (up to len MAX_STRLEN(domid_t)+1). */ +/* Convert permissions to a string (up to len MAX_STRLEN(unsigned int)+1). */ bool xs_perm_to_string(const struct xs_permissions *perm, char *buffer); /* Given a string and a length, count how many strings (nul terms). */ diff --git a/tools/xenstore/xs_random.c b/tools/xenstore/xs_random.c index 3538bcca95..fdd723bb2a 100644 --- a/tools/xenstore/xs_random.c +++ b/tools/xenstore/xs_random.c @@ -594,19 +594,19 @@ static char *dump(struct ops *ops, void *h) * of bytes. No alignment or length assumptions are made about * the input key. */ -static inline u32 jhash(const void *key, u32 length, u32 initval) +static inline uint32_t jhash(const void *key, uint32_t length, uint32_t initval) { - u32 a, b, c, len; - const u8 *k = key; + uint32_t a, b, c, len; + const uint8_t *k = key; len = length; a = b = JHASH_GOLDEN_RATIO; c = initval; while (len >= 12) { - a += (k[0] +((u32)k[1]<<8) +((u32)k[2]<<16) +((u32)k[3]<<24)); - b += (k[4] +((u32)k[5]<<8) +((u32)k[6]<<16) +((u32)k[7]<<24)); - c += (k[8] +((u32)k[9]<<8) +((u32)k[10]<<16)+((u32)k[11]<<24)); + a += (k[0] +((uint32_t)k[1]<<8) +((uint32_t)k[2]<<16) +((uint32_t)k[3]<<24)); + b += (k[4] +((uint32_t)k[5]<<8) +((uint32_t)k[6]<<16) +((uint32_t)k[7]<<24)); + c += (k[8] +((uint32_t)k[9]<<8) +((uint32_t)k[10]<<16)+((uint32_t)k[11]<<24)); __jhash_mix(a,b,c); @@ -616,16 +616,16 @@ static inline u32 jhash(const void *key, u32 length, u32 initval) c += length; switch (len) { - case 11: c += ((u32)k[10]<<24); - case 10: c += ((u32)k[9]<<16); - case 9 : c += ((u32)k[8]<<8); - case 8 : b += ((u32)k[7]<<24); - case 7 : b += ((u32)k[6]<<16); - case 6 : b += ((u32)k[5]<<8); + case 11: c += ((uint32_t)k[10]<<24); + case 10: c += ((uint32_t)k[9]<<16); + case 9 : c += ((uint32_t)k[8]<<8); + case 8 : b += ((uint32_t)k[7]<<24); + case 7 : b += ((uint32_t)k[6]<<16); + case 6 : b += ((uint32_t)k[5]<<8); case 5 : b += k[4]; - case 4 : a += ((u32)k[3]<<24); - case 3 : a += ((u32)k[2]<<16); - case 2 : a += ((u32)k[1]<<8); + case 4 : a += ((uint32_t)k[3]<<24); + case 3 : a += ((uint32_t)k[2]<<16); + case 2 : a += ((uint32_t)k[1]<<8); case 1 : a += k[0]; }; @@ -634,12 +634,12 @@ static inline u32 jhash(const void *key, u32 length, u32 initval) return c; } -/* A special optimized version that handles 1 or more of u32s. - * The length parameter here is the number of u32s in the key. +/* A special optimized version that handles 1 or more of uint32_ts. + * The length parameter here is the number of uint32_ts in the key. */ -static inline u32 jhash2(u32 *k, u32 length, u32 initval) +static inline uint32_t jhash2(uint32_t *k, uint32_t length, uint32_t initval) { - u32 a, b, c, len; + uint32_t a, b, c, len; a = b = JHASH_GOLDEN_RATIO; c = initval; @@ -672,7 +672,7 @@ static inline u32 jhash2(u32 *k, u32 length, u32 initval) * NOTE: In partilar the "c += length; __jhash_mix(a,b,c);" normally * done at the end is not done here. */ -static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) +static inline uint32_t jhash_3words(uint32_t a, uint32_t b, uint32_t c, uint32_t initval) { a += JHASH_GOLDEN_RATIO; b += JHASH_GOLDEN_RATIO; @@ -683,12 +683,12 @@ static inline u32 jhash_3words(u32 a, u32 b, u32 c, u32 initval) return c; } -static inline u32 jhash_2words(u32 a, u32 b, u32 initval) +static inline uint32_t jhash_2words(uint32_t a, uint32_t b, uint32_t initval) { return jhash_3words(a, b, 0, initval); } -static inline u32 jhash_1word(u32 a, u32 initval) +static inline uint32_t jhash_1word(uint32_t a, uint32_t initval) { return jhash_3words(a, 0, 0, initval); } diff --git a/tools/xenstore/xs_tdb_dump.c b/tools/xenstore/xs_tdb_dump.c index f7e54fbe75..5f1382f41b 100644 --- a/tools/xenstore/xs_tdb_dump.c +++ b/tools/xenstore/xs_tdb_dump.c @@ -11,13 +11,13 @@ #include "utils.h" struct record_hdr { - u32 num_perms; - u32 datalen; - u32 childlen; + uint32_t num_perms; + uint32_t datalen; + uint32_t childlen; struct xs_permissions perms[0]; }; -static u32 total_size(struct record_hdr *hdr) +static uint32_t total_size(struct record_hdr *hdr) { return sizeof(*hdr) + hdr->num_perms * sizeof(struct xs_permissions) + hdr->datalen + hdr->childlen; diff --git a/tools/xenstore/xs_test.c b/tools/xenstore/xs_test.c index 9e49bdfb87..1f59df6873 100644 --- a/tools/xenstore/xs_test.c +++ b/tools/xenstore/xs_test.c @@ -561,7 +561,7 @@ static void do_introduce(unsigned int handle, /* Tell them the event channel and our PID. */ *(int *)((void *)out + 32) = getpid(); - *(u16 *)((void *)out + 36) = atoi(eventchn); + *(uint16_t *)((void *)out + 36) = atoi(eventchn); if (!xs_introduce_domain(handles[handle], atoi(domid), atol(mfn), atoi(eventchn), path)) { diff --git a/tools/xentrace/xenctx.c b/tools/xentrace/xenctx.c index 777604e369..fbfd341cd8 100644 --- a/tools/xentrace/xenctx.c +++ b/tools/xentrace/xenctx.c @@ -81,7 +81,7 @@ void print_ctx(vcpu_guest_context_t *ctx1) } #endif -void dump_ctx(u32 domid, u32 vcpu) +void dump_ctx(uint32_t domid, uint32_t vcpu) { int ret; vcpu_guest_context_t ctx; diff --git a/tools/xentrace/xentrace.c b/tools/xentrace/xentrace.c index b8b9baa38d..f927a24f83 100644 --- a/tools/xentrace/xentrace.c +++ b/tools/xentrace/xentrace.c @@ -45,8 +45,8 @@ typedef struct settings_st { char *outfile; struct timespec poll_sleep; unsigned long new_data_thresh; - u32 evt_mask; - u32 cpu_mask; + uint32_t evt_mask; + uint32_t cpu_mask; } settings_t; settings_t opts; @@ -168,7 +168,7 @@ struct t_buf *map_tbufs(unsigned long tbufs_mfn, unsigned int num, * @type: the new mask type,0-event mask, 1-cpu mask * */ -void set_mask(u32 mask, int type) +void set_mask(uint32_t mask, int type) { int ret; dom0_op_t op; /* dom0 op we'll build */ @@ -496,7 +496,8 @@ const struct argp parser_def = "\v" "This tool is used to capture trace buffer data from Xen. The data is " "output in a binary format, in the following order:\n\n" - " CPU(uint) TSC(u64) EVENT(u32) D1 D2 D3 D4 D5 (all u32)\n\n" + " CPU(uint) TSC(uint64_t) EVENT(uint32_t) D1 D2 D3 D4 D5 " + "(all uint32_t)\n\n" "The output should be parsed using the tool xentrace_format, which can " "produce human-readable output in ASCII format." }; diff --git a/xen/include/public/acm.h b/xen/include/public/acm.h index e43d00de15..b5820b8d34 100644 --- a/xen/include/public/acm.h +++ b/xen/include/public/acm.h @@ -8,7 +8,7 @@ * * Contributors: * Stefan Berger - * added network byte order support for binary policies + * added network byte order support for binary policies * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -41,24 +41,24 @@ #endif /* default ssid reference value if not supplied */ -#define ACM_DEFAULT_SSID 0x0 +#define ACM_DEFAULT_SSID 0x0 #define ACM_DEFAULT_LOCAL_SSID 0x0 /* Internal ACM ERROR types */ -#define ACM_OK 0 -#define ACM_UNDEF -1 -#define ACM_INIT_SSID_ERROR -2 -#define ACM_INIT_SOID_ERROR -3 -#define ACM_ERROR -4 +#define ACM_OK 0 +#define ACM_UNDEF -1 +#define ACM_INIT_SSID_ERROR -2 +#define ACM_INIT_SOID_ERROR -3 +#define ACM_ERROR -4 /* External ACCESS DECISIONS */ -#define ACM_ACCESS_PERMITTED 0 -#define ACM_ACCESS_DENIED -111 -#define ACM_NULL_POINTER_ERROR -200 +#define ACM_ACCESS_PERMITTED 0 +#define ACM_ACCESS_DENIED -111 +#define ACM_NULL_POINTER_ERROR -200 /* primary policy in lower 4 bits */ -#define ACM_NULL_POLICY 0 -#define ACM_CHINESE_WALL_POLICY 1 +#define ACM_NULL_POLICY 0 +#define ACM_CHINESE_WALL_POLICY 1 #define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2 /* combinations have secondary policy component in higher 4bit */ @@ -67,7 +67,7 @@ /* policy: */ #define ACM_POLICY_NAME(X) \ - ((X) == (ACM_NULL_POLICY)) ? "NULL policy" : \ + ((X) == (ACM_NULL_POLICY)) ? "NULL policy" : \ ((X) == (ACM_CHINESE_WALL_POLICY)) ? "CHINESE WALL policy" : \ ((X) == (ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "SIMPLE TYPE ENFORCEMENT policy" : \ ((X) == (ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "CHINESE WALL AND SIMPLE TYPE ENFORCEMENT policy" : \ @@ -77,17 +77,17 @@ * whenever the interpretation of the related * policy's data structure changes */ -#define ACM_POLICY_VERSION 1 -#define ACM_CHWALL_VERSION 1 -#define ACM_STE_VERSION 1 +#define ACM_POLICY_VERSION 1 +#define ACM_CHWALL_VERSION 1 +#define ACM_STE_VERSION 1 /* defines a ssid reference used by xen */ -typedef u32 ssidref_t; +typedef uint32_t ssidref_t; /* -------security policy relevant type definitions-------- */ /* type identifier; compares to "equal" or "not equal" */ -typedef u16 domaintype_t; +typedef uint16_t domaintype_t; /* CHINESE WALL POLICY DATA STRUCTURES * @@ -109,7 +109,7 @@ typedef u16 domaintype_t; * with type i and is "1" otherwise. */ /* high-16 = version, low-16 = check magic */ -#define ACM_MAGIC 0x0001debc +#define ACM_MAGIC 0x0001debc /* each offset in bytes from start of the struct they * are part of */ @@ -123,62 +123,72 @@ typedef u16 domaintype_t; * tools that assume packed representations (e.g. the java tool) */ struct acm_policy_buffer { - u32 policy_version; /* ACM_POLICY_VERSION */ - u32 magic; - u32 len; - u32 primary_policy_code; - u32 primary_buffer_offset; - u32 secondary_policy_code; - u32 secondary_buffer_offset; + uint32_t policy_version; /* ACM_POLICY_VERSION */ + uint32_t magic; + uint32_t len; + uint32_t primary_policy_code; + uint32_t primary_buffer_offset; + uint32_t secondary_policy_code; + uint32_t secondary_buffer_offset; }; struct acm_chwall_policy_buffer { - u32 policy_version; /* ACM_CHWALL_VERSION */ - u32 policy_code; - u32 chwall_max_types; - u32 chwall_max_ssidrefs; - u32 chwall_max_conflictsets; - u32 chwall_ssid_offset; - u32 chwall_conflict_sets_offset; - u32 chwall_running_types_offset; - u32 chwall_conflict_aggregate_offset; + uint32_t policy_version; /* ACM_CHWALL_VERSION */ + uint32_t policy_code; + uint32_t chwall_max_types; + uint32_t chwall_max_ssidrefs; + uint32_t chwall_max_conflictsets; + uint32_t chwall_ssid_offset; + uint32_t chwall_conflict_sets_offset; + uint32_t chwall_running_types_offset; + uint32_t chwall_conflict_aggregate_offset; }; struct acm_ste_policy_buffer { - u32 policy_version; /* ACM_STE_VERSION */ - u32 policy_code; - u32 ste_max_types; - u32 ste_max_ssidrefs; - u32 ste_ssid_offset; + uint32_t policy_version; /* ACM_STE_VERSION */ + uint32_t policy_code; + uint32_t ste_max_types; + uint32_t ste_max_ssidrefs; + uint32_t ste_ssid_offset; }; struct acm_stats_buffer { - u32 magic; - u32 len; - u32 primary_policy_code; - u32 primary_stats_offset; - u32 secondary_policy_code; - u32 secondary_stats_offset; + uint32_t magic; + uint32_t len; + uint32_t primary_policy_code; + uint32_t primary_stats_offset; + uint32_t secondary_policy_code; + uint32_t secondary_stats_offset; }; struct acm_ste_stats_buffer { - u32 ec_eval_count; - u32 gt_eval_count; - u32 ec_denied_count; - u32 gt_denied_count; - u32 ec_cachehit_count; - u32 gt_cachehit_count; + uint32_t ec_eval_count; + uint32_t gt_eval_count; + uint32_t ec_denied_count; + uint32_t gt_denied_count; + uint32_t ec_cachehit_count; + uint32_t gt_cachehit_count; }; struct acm_ssid_buffer { - u32 len; + uint32_t len; ssidref_t ssidref; - u32 primary_policy_code; - u32 primary_max_types; - u32 primary_types_offset; - u32 secondary_policy_code; - u32 secondary_max_types; - u32 secondary_types_offset; + uint32_t primary_policy_code; + uint32_t primary_max_types; + uint32_t primary_types_offset; + uint32_t secondary_policy_code; + uint32_t secondary_max_types; + uint32_t secondary_types_offset; }; #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/acm_ops.h b/xen/include/public/acm_ops.h index 6389ee5f86..18165bdff2 100644 --- a/xen/include/public/acm_ops.h +++ b/xen/include/public/acm_ops.h @@ -1,4 +1,3 @@ - /****************************************************************************** * acm_ops.h * @@ -32,44 +31,44 @@ /************************************************************************/ -#define ACM_SETPOLICY 4 +#define ACM_SETPOLICY 4 typedef struct acm_setpolicy { /* OUT variables */ void *pushcache; - u16 pushcache_size; + uint16_t pushcache_size; } acm_setpolicy_t; -#define ACM_GETPOLICY 5 +#define ACM_GETPOLICY 5 typedef struct acm_getpolicy { /* OUT variables */ void *pullcache; - u16 pullcache_size; + uint16_t pullcache_size; } acm_getpolicy_t; -#define ACM_DUMPSTATS 6 +#define ACM_DUMPSTATS 6 typedef struct acm_dumpstats { void *pullcache; - u16 pullcache_size; + uint16_t pullcache_size; } acm_dumpstats_t; -#define ACM_GETSSID 7 +#define ACM_GETSSID 7 enum get_type {UNSET, SSIDREF, DOMAINID}; typedef struct acm_getssid { - enum get_type get_ssid_by; - union { - domaintype_t domainid; - ssidref_t ssidref; - } id; + enum get_type get_ssid_by; + union { + domaintype_t domainid; + ssidref_t ssidref; + } id; void *ssidbuf; - u16 ssidbuf_size; + uint16_t ssidbuf_size; } acm_getssid_t; typedef struct acm_op { - u32 cmd; - u32 interface_version; /* ACM_INTERFACE_VERSION */ + uint32_t cmd; + uint32_t interface_version; /* ACM_INTERFACE_VERSION */ union { acm_setpolicy_t setpolicy; acm_getpolicy_t getpolicy; @@ -79,3 +78,13 @@ typedef struct acm_op { } acm_op_t; #endif /* __XEN_PUBLIC_ACM_OPS_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index e6e5c48f8e..dd555e1c4d 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -13,30 +13,30 @@ #ifndef __ASSEMBLY__ -#define MAX_NR_SECTION 32 // at most 32 memory holes +#define MAX_NR_SECTION 32 /* at most 32 memory holes */ typedef struct { - unsigned long start; /* start of memory hole */ - unsigned long end; /* end of memory hole */ + unsigned long start; /* start of memory hole */ + unsigned long end; /* end of memory hole */ } mm_section_t; typedef struct { - unsigned long mfn : 56; - unsigned long type: 8; + unsigned long mfn : 56; + unsigned long type: 8; } pmt_entry_t; -#define GPFN_MEM (0UL << 56) /* Guest pfn is normal mem */ -#define GPFN_FRAME_BUFFER (1UL << 56) /* VGA framebuffer */ -#define GPFN_LOW_MMIO (2UL << 56) /* Low MMIO range */ -#define GPFN_PIB (3UL << 56) /* PIB base */ -#define GPFN_IOSAPIC (4UL << 56) /* IOSAPIC base */ -#define GPFN_LEGACY_IO (5UL << 56) /* Legacy I/O base */ -#define GPFN_GFW (6UL << 56) /* Guest Firmware */ -#define GPFN_HIGH_MMIO (7UL << 56) /* High MMIO range */ +#define GPFN_MEM (0UL << 56) /* Guest pfn is normal mem */ +#define GPFN_FRAME_BUFFER (1UL << 56) /* VGA framebuffer */ +#define GPFN_LOW_MMIO (2UL << 56) /* Low MMIO range */ +#define GPFN_PIB (3UL << 56) /* PIB base */ +#define GPFN_IOSAPIC (4UL << 56) /* IOSAPIC base */ +#define GPFN_LEGACY_IO (5UL << 56) /* Legacy I/O base */ +#define GPFN_GFW (6UL << 56) /* Guest Firmware */ +#define GPFN_HIGH_MMIO (7UL << 56) /* High MMIO range */ -#define GPFN_IO_MASK (7UL << 56) /* Guest pfn is I/O type */ -#define GPFN_INV_MASK (31UL << 59) /* Guest pfn is invalid */ +#define GPFN_IO_MASK (7UL << 56) /* Guest pfn is I/O type */ +#define GPFN_INV_MASK (31UL << 59) /* Guest pfn is invalid */ -#define INVALID_MFN (~0UL) +#define INVALID_MFN (~0UL) /* * NB. This may become a 64-bit count with no shift. If this happens then the @@ -48,198 +48,198 @@ typedef struct { } tsc_timestamp_t; /* 8 bytes */ struct pt_fpreg { - union { - unsigned long bits[2]; - long double __dummy; /* force 16-byte alignment */ - } u; + union { + unsigned long bits[2]; + long double __dummy; /* force 16-byte alignment */ + } u; }; typedef struct cpu_user_regs{ - /* The following registers are saved by SAVE_MIN: */ - unsigned long b6; /* scratch */ - unsigned long b7; /* scratch */ + /* The following registers are saved by SAVE_MIN: */ + unsigned long b6; /* scratch */ + unsigned long b7; /* scratch */ - unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */ - unsigned long ar_ssd; /* reserved for future use (scratch) */ + unsigned long ar_csd; /* used by cmp8xchg16 (scratch) */ + unsigned long ar_ssd; /* reserved for future use (scratch) */ - unsigned long r8; /* scratch (return value register 0) */ - unsigned long r9; /* scratch (return value register 1) */ - unsigned long r10; /* scratch (return value register 2) */ - unsigned long r11; /* scratch (return value register 3) */ + unsigned long r8; /* scratch (return value register 0) */ + unsigned long r9; /* scratch (return value register 1) */ + unsigned long r10; /* scratch (return value register 2) */ + unsigned long r11; /* scratch (return value register 3) */ - unsigned long cr_ipsr; /* interrupted task's psr */ - unsigned long cr_iip; /* interrupted task's instruction pointer */ - unsigned long cr_ifs; /* interrupted task's function state */ + unsigned long cr_ipsr; /* interrupted task's psr */ + unsigned long cr_iip; /* interrupted task's instruction pointer */ + unsigned long cr_ifs; /* interrupted task's function state */ - unsigned long ar_unat; /* interrupted task's NaT register (preserved) */ - unsigned long ar_pfs; /* prev function state */ - unsigned long ar_rsc; /* RSE configuration */ - /* The following two are valid only if cr_ipsr.cpl > 0: */ - unsigned long ar_rnat; /* RSE NaT */ - unsigned long ar_bspstore; /* RSE bspstore */ + unsigned long ar_unat; /* interrupted task's NaT register (preserved) */ + unsigned long ar_pfs; /* prev function state */ + unsigned long ar_rsc; /* RSE configuration */ + /* The following two are valid only if cr_ipsr.cpl > 0: */ + unsigned long ar_rnat; /* RSE NaT */ + unsigned long ar_bspstore; /* RSE bspstore */ - unsigned long pr; /* 64 predicate registers (1 bit each) */ - unsigned long b0; /* return pointer (bp) */ - unsigned long loadrs; /* size of dirty partition << 16 */ + unsigned long pr; /* 64 predicate registers (1 bit each) */ + unsigned long b0; /* return pointer (bp) */ + unsigned long loadrs; /* size of dirty partition << 16 */ - unsigned long r1; /* the gp pointer */ - unsigned long r12; /* interrupted task's memory stack pointer */ - unsigned long r13; /* thread pointer */ + unsigned long r1; /* the gp pointer */ + unsigned long r12; /* interrupted task's memory stack pointer */ + unsigned long r13; /* thread pointer */ - unsigned long ar_fpsr; /* floating point status (preserved) */ - unsigned long r15; /* scratch */ + unsigned long ar_fpsr; /* floating point status (preserved) */ + unsigned long r15; /* scratch */ - /* The remaining registers are NOT saved for system calls. */ + /* The remaining registers are NOT saved for system calls. */ - unsigned long r14; /* scratch */ - unsigned long r2; /* scratch */ - unsigned long r3; /* scratch */ - unsigned long r16; /* scratch */ - unsigned long r17; /* scratch */ - unsigned long r18; /* scratch */ - unsigned long r19; /* scratch */ - unsigned long r20; /* scratch */ - unsigned long r21; /* scratch */ - unsigned long r22; /* scratch */ - unsigned long r23; /* scratch */ - unsigned long r24; /* scratch */ - unsigned long r25; /* scratch */ - unsigned long r26; /* scratch */ - unsigned long r27; /* scratch */ - unsigned long r28; /* scratch */ - unsigned long r29; /* scratch */ - unsigned long r30; /* scratch */ - unsigned long r31; /* scratch */ - unsigned long ar_ccv; /* compare/exchange value (scratch) */ + unsigned long r14; /* scratch */ + unsigned long r2; /* scratch */ + unsigned long r3; /* scratch */ + unsigned long r16; /* scratch */ + unsigned long r17; /* scratch */ + unsigned long r18; /* scratch */ + unsigned long r19; /* scratch */ + unsigned long r20; /* scratch */ + unsigned long r21; /* scratch */ + unsigned long r22; /* scratch */ + unsigned long r23; /* scratch */ + unsigned long r24; /* scratch */ + unsigned long r25; /* scratch */ + unsigned long r26; /* scratch */ + unsigned long r27; /* scratch */ + unsigned long r28; /* scratch */ + unsigned long r29; /* scratch */ + unsigned long r30; /* scratch */ + unsigned long r31; /* scratch */ + unsigned long ar_ccv; /* compare/exchange value (scratch) */ - /* - * Floating point registers that the kernel considers scratch: - */ - struct pt_fpreg f6; /* scratch */ - struct pt_fpreg f7; /* scratch */ - struct pt_fpreg f8; /* scratch */ - struct pt_fpreg f9; /* scratch */ - struct pt_fpreg f10; /* scratch */ - struct pt_fpreg f11; /* scratch */ - unsigned long r4; /* preserved */ - unsigned long r5; /* preserved */ - unsigned long r6; /* preserved */ - unsigned long r7; /* preserved */ - unsigned long eml_unat; /* used for emulating instruction */ + /* + * Floating point registers that the kernel considers scratch: + */ + struct pt_fpreg f6; /* scratch */ + struct pt_fpreg f7; /* scratch */ + struct pt_fpreg f8; /* scratch */ + struct pt_fpreg f9; /* scratch */ + struct pt_fpreg f10; /* scratch */ + struct pt_fpreg f11; /* scratch */ + unsigned long r4; /* preserved */ + unsigned long r5; /* preserved */ + unsigned long r6; /* preserved */ + unsigned long r7; /* preserved */ + unsigned long eml_unat; /* used for emulating instruction */ unsigned long rfi_pfs; /* used for elulating rfi */ }cpu_user_regs_t; typedef union { - unsigned long value; - struct { - int a_int:1; - int a_from_int_cr:1; - int a_to_int_cr:1; - int a_from_psr:1; - int a_from_cpuid:1; - int a_cover:1; - int a_bsw:1; - long reserved:57; - }; + unsigned long value; + struct { + int a_int:1; + int a_from_int_cr:1; + int a_to_int_cr:1; + int a_from_psr:1; + int a_from_cpuid:1; + int a_cover:1; + int a_bsw:1; + long reserved:57; + }; } vac_t; typedef union { - unsigned long value; - struct { - int d_vmsw:1; - int d_extint:1; - int d_ibr_dbr:1; - int d_pmc:1; - int d_to_pmd:1; - int d_itm:1; - long reserved:58; - }; + unsigned long value; + struct { + int d_vmsw:1; + int d_extint:1; + int d_ibr_dbr:1; + int d_pmc:1; + int d_to_pmd:1; + int d_itm:1; + long reserved:58; + }; } vdc_t; typedef struct { - vac_t vac; - vdc_t vdc; - unsigned long virt_env_vaddr; - unsigned long reserved1[29]; - unsigned long vhpi; - unsigned long reserved2[95]; - union { - unsigned long vgr[16]; - unsigned long bank1_regs[16]; // bank1 regs (r16-r31) when bank0 active - }; - union { - unsigned long vbgr[16]; - unsigned long bank0_regs[16]; // bank0 regs (r16-r31) when bank1 active - }; - unsigned long vnat; - unsigned long vbnat; - unsigned long vcpuid[5]; - unsigned long reserved3[11]; - unsigned long vpsr; - unsigned long vpr; - unsigned long reserved4[76]; - union { - unsigned long vcr[128]; - struct { - unsigned long dcr; // CR0 - unsigned long itm; - unsigned long iva; - unsigned long rsv1[5]; - unsigned long pta; // CR8 - unsigned long rsv2[7]; - unsigned long ipsr; // CR16 - unsigned long isr; - unsigned long rsv3; - unsigned long iip; - unsigned long ifa; - unsigned long itir; - unsigned long iipa; - unsigned long ifs; - unsigned long iim; // CR24 - unsigned long iha; - unsigned long rsv4[38]; - unsigned long lid; // CR64 - unsigned long ivr; - unsigned long tpr; - unsigned long eoi; - unsigned long irr[4]; - unsigned long itv; // CR72 - unsigned long pmv; - unsigned long cmcv; - unsigned long rsv5[5]; - unsigned long lrr0; // CR80 - unsigned long lrr1; - unsigned long rsv6[46]; - }; - }; - union { - unsigned long reserved5[128]; - struct { - unsigned long precover_ifs; - unsigned long unat; // not sure if this is needed until NaT arch is done - int interrupt_collection_enabled; // virtual psr.ic - int interrupt_delivery_enabled; // virtual psr.i - int pending_interruption; - int incomplete_regframe; // see SDM vol2 6.8 - unsigned long delivery_mask[4]; - int metaphysical_mode; // 1 = use metaphys mapping, 0 = use virtual - int banknum; // 0 or 1, which virtual register bank is active - unsigned long rrs[8]; // region registers - unsigned long krs[8]; // kernel registers - unsigned long pkrs[8]; // protection key registers - unsigned long tmp[8]; // temp registers (e.g. for hyperprivops) - // FIXME: tmp[8] temp'ly being used for virtual psr.pp - }; + vac_t vac; + vdc_t vdc; + unsigned long virt_env_vaddr; + unsigned long reserved1[29]; + unsigned long vhpi; + unsigned long reserved2[95]; + union { + unsigned long vgr[16]; + unsigned long bank1_regs[16]; // bank1 regs (r16-r31) when bank0 active + }; + union { + unsigned long vbgr[16]; + unsigned long bank0_regs[16]; // bank0 regs (r16-r31) when bank1 active + }; + unsigned long vnat; + unsigned long vbnat; + unsigned long vcpuid[5]; + unsigned long reserved3[11]; + unsigned long vpsr; + unsigned long vpr; + unsigned long reserved4[76]; + union { + unsigned long vcr[128]; + struct { + unsigned long dcr; // CR0 + unsigned long itm; + unsigned long iva; + unsigned long rsv1[5]; + unsigned long pta; // CR8 + unsigned long rsv2[7]; + unsigned long ipsr; // CR16 + unsigned long isr; + unsigned long rsv3; + unsigned long iip; + unsigned long ifa; + unsigned long itir; + unsigned long iipa; + unsigned long ifs; + unsigned long iim; // CR24 + unsigned long iha; + unsigned long rsv4[38]; + unsigned long lid; // CR64 + unsigned long ivr; + unsigned long tpr; + unsigned long eoi; + unsigned long irr[4]; + unsigned long itv; // CR72 + unsigned long pmv; + unsigned long cmcv; + unsigned long rsv5[5]; + unsigned long lrr0; // CR80 + unsigned long lrr1; + unsigned long rsv6[46]; }; - unsigned long reserved6[3456]; - unsigned long vmm_avail[128]; - unsigned long reserved7[4096]; + }; + union { + unsigned long reserved5[128]; + struct { + unsigned long precover_ifs; + unsigned long unat; // not sure if this is needed until NaT arch is done + int interrupt_collection_enabled; // virtual psr.ic + int interrupt_delivery_enabled; // virtual psr.i + int pending_interruption; + int incomplete_regframe; // see SDM vol2 6.8 + unsigned long delivery_mask[4]; + int metaphysical_mode; // 1 = use metaphys mapping, 0 = use virtual + int banknum; // 0 or 1, which virtual register bank is active + unsigned long rrs[8]; // region registers + unsigned long krs[8]; // kernel registers + unsigned long pkrs[8]; // protection key registers + unsigned long tmp[8]; // temp registers (e.g. for hyperprivops) + // FIXME: tmp[8] temp'ly being used for virtual psr.pp + }; + }; + unsigned long reserved6[3456]; + unsigned long vmm_avail[128]; + unsigned long reserved7[4096]; } mapped_regs_t; typedef struct { - mapped_regs_t *privregs; - int evtchn_vector; + mapped_regs_t *privregs; + int evtchn_vector; } arch_vcpu_info_t; typedef mapped_regs_t vpd_t; @@ -247,25 +247,35 @@ typedef mapped_regs_t vpd_t; #define __ARCH_HAS_VCPU_INFO typedef struct { - unsigned int flags; - unsigned long start_info_pfn; -} arch_shared_info_t; // DON'T PACK + unsigned int flags; + unsigned long start_info_pfn; +} arch_shared_info_t; // DON'T PACK typedef struct vcpu_guest_context { #define VGCF_FPU_VALID (1<<0) #define VGCF_VMX_GUEST (1<<1) #define VGCF_IN_KERNEL (1<<2) - unsigned long flags; /* VGCF_* flags */ - unsigned long pt_base; /* PMT table base */ - unsigned long share_io_pg; /* Shared page for I/O emulation */ - unsigned long sys_pgnr; /* System pages out of domain memory */ - unsigned long vm_assist; /* VMASST_TYPE_* bitmap, now none on IPF */ + unsigned long flags; /* VGCF_* flags */ + unsigned long pt_base; /* PMT table base */ + unsigned long share_io_pg; /* Shared page for I/O emulation */ + unsigned long sys_pgnr; /* System pages out of domain memory */ + unsigned long vm_assist; /* VMASST_TYPE_* bitmap, now none on IPF */ - cpu_user_regs_t regs; - arch_vcpu_info_t vcpu; - arch_shared_info_t shared; + cpu_user_regs_t regs; + arch_vcpu_info_t vcpu; + arch_shared_info_t shared; } vcpu_guest_context_t; #endif /* !__ASSEMBLY__ */ #endif /* __HYPERVISOR_IF_IA64_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/arch-x86_32.h b/xen/include/public/arch-x86_32.h index f6c3ea9246..4b13ccc94c 100644 --- a/xen/include/public/arch-x86_32.h +++ b/xen/include/public/arch-x86_32.h @@ -44,7 +44,6 @@ /* And the trap vector is... */ #define TRAP_INSTR "int $0x82" - /* * Virtual addresses beyond this are not modifiable by guest OSes. The * machine->physical mapping table starts at this address, read-only. @@ -71,36 +70,36 @@ #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl)) #define TI_SET_IF(_ti,_if) ((_ti)->flags |= ((!!(_if))<<2)) typedef struct trap_info { - u8 vector; /* exception vector */ - u8 flags; /* 0-3: privilege level; 4: clear event enable? */ - u16 cs; /* code selector */ + uint8_t vector; /* exception vector */ + uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */ + uint16_t cs; /* code selector */ unsigned long address; /* code offset */ } trap_info_t; typedef struct cpu_user_regs { - u32 ebx; - u32 ecx; - u32 edx; - u32 esi; - u32 edi; - u32 ebp; - u32 eax; - u16 error_code; /* private */ - u16 entry_vector; /* private */ - u32 eip; - u16 cs; - u8 saved_upcall_mask; - u8 _pad0; - u32 eflags; - u32 esp; - u16 ss, _pad1; - u16 es, _pad2; - u16 ds, _pad3; - u16 fs, _pad4; - u16 gs, _pad5; + uint32_t ebx; + uint32_t ecx; + uint32_t edx; + uint32_t esi; + uint32_t edi; + uint32_t ebp; + uint32_t eax; + uint16_t error_code; /* private */ + uint16_t entry_vector; /* private */ + uint32_t eip; + uint16_t cs; + uint8_t saved_upcall_mask; + uint8_t _pad0; + uint32_t eflags; + uint32_t esp; + uint16_t ss, _pad1; + uint16_t es, _pad2; + uint16_t ds, _pad3; + uint16_t fs, _pad4; + uint16_t gs, _pad5; } cpu_user_regs_t; -typedef u64 tsc_timestamp_t; /* RDTSC timestamp */ +typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ /* * The following is all CPU context. Note that the fpu_ctxt block is filled @@ -129,12 +128,20 @@ typedef struct vcpu_guest_context { typedef struct arch_shared_info { unsigned long max_pfn; /* max pfn that appears in table */ + /* Frame containing list of mfns containing list of mfns containing p2m. */ unsigned long pfn_to_mfn_frame_list_list; - /* frame containing list of mfns - containing list of mfns - containing the p2m table. */ } arch_shared_info_t; #endif #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/arch-x86_64.h b/xen/include/public/arch-x86_64.h index 04eae96852..366be67fca 100644 --- a/xen/include/public/arch-x86_64.h +++ b/xen/include/public/arch-x86_64.h @@ -99,7 +99,7 @@ #define VGCF_IN_SYSCALL (1<<8) struct switch_to_user { /* Top of stack (%rsp at point of hypercall). */ - u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; + uint64_t rax, r11, rcx, flags, rip, cs, rflags, rsp, ss; /* Bottom of switch_to_user stack frame. */ }; @@ -118,54 +118,54 @@ struct switch_to_user { #define TI_SET_DPL(_ti,_dpl) ((_ti)->flags |= (_dpl)) #define TI_SET_IF(_ti,_if) ((_ti)->flags |= ((!!(_if))<<2)) typedef struct trap_info { - u8 vector; /* exception vector */ - u8 flags; /* 0-3: privilege level; 4: clear event enable? */ - u16 cs; /* code selector */ + uint8_t vector; /* exception vector */ + uint8_t flags; /* 0-3: privilege level; 4: clear event enable? */ + uint16_t cs; /* code selector */ unsigned long address; /* code offset */ } trap_info_t; #ifdef __GNUC__ /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ -#define __DECL_REG(name) union { u64 r ## name, e ## name; } +#define __DECL_REG(name) union { uint64_t r ## name, e ## name; } #else /* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ -#define __DECL_REG(name) u64 r ## name +#define __DECL_REG(name) uint64_t r ## name #endif typedef struct cpu_user_regs { - u64 r15; - u64 r14; - u64 r13; - u64 r12; + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; __DECL_REG(bp); __DECL_REG(bx); - u64 r11; - u64 r10; - u64 r9; - u64 r8; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; __DECL_REG(ax); __DECL_REG(cx); __DECL_REG(dx); __DECL_REG(si); __DECL_REG(di); - u32 error_code; /* private */ - u32 entry_vector; /* private */ + uint32_t error_code; /* private */ + uint32_t entry_vector; /* private */ __DECL_REG(ip); - u16 cs, _pad0[1]; - u8 saved_upcall_mask; - u8 _pad1[3]; + uint16_t cs, _pad0[1]; + uint8_t saved_upcall_mask; + uint8_t _pad1[3]; __DECL_REG(flags); __DECL_REG(sp); - u16 ss, _pad2[3]; - u16 es, _pad3[3]; - u16 ds, _pad4[3]; - u16 fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */ - u16 gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_user. */ + uint16_t ss, _pad2[3]; + uint16_t es, _pad3[3]; + uint16_t ds, _pad4[3]; + uint16_t fs, _pad5[3]; /* Non-zero => takes precedence over fs_base. */ + uint16_t gs, _pad6[3]; /* Non-zero => takes precedence over gs_base_usr. */ } cpu_user_regs_t; #undef __DECL_REG -typedef u64 tsc_timestamp_t; /* RDTSC timestamp */ +typedef uint64_t tsc_timestamp_t; /* RDTSC timestamp */ /* * The following is all CPU context. Note that the fpu_ctxt block is filled @@ -190,19 +190,27 @@ typedef struct vcpu_guest_context { unsigned long syscall_callback_eip; unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ /* Segment base addresses. */ - u64 fs_base; - u64 gs_base_kernel; - u64 gs_base_user; + uint64_t fs_base; + uint64_t gs_base_kernel; + uint64_t gs_base_user; } vcpu_guest_context_t; typedef struct arch_shared_info { unsigned long max_pfn; /* max pfn that appears in table */ + /* Frame containing list of mfns containing list of mfns containing p2m. */ unsigned long pfn_to_mfn_frame_list_list; - /* frame containing list of mfns - containing list of mfns - containing the p2m table. */ } arch_shared_info_t; #endif /* !__ASSEMBLY__ */ #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 9b8accfa4d..d09953aab3 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -44,7 +44,7 @@ typedef struct sched_adjdom_cmd dom0_adjustdom_t; #define DOM0_CREATEDOMAIN 8 typedef struct { /* IN parameters */ - u32 ssidref; + uint32_t ssidref; /* IN/OUT parameters. */ /* Identifier for new domain (auto-allocate if zero is specified). */ domid_t domain; @@ -53,7 +53,7 @@ typedef struct { #define DOM0_DESTROYDOMAIN 9 typedef struct { /* IN variables. */ - domid_t domain; + domid_t domain; } dom0_destroydomain_t; #define DOM0_PAUSEDOMAIN 10 @@ -82,22 +82,22 @@ typedef struct { #define DOMFLAGS_CPUSHIFT 8 #define DOMFLAGS_SHUTDOWNMASK 255 /* DOMFLAGS_SHUTDOWN guest-supplied code. */ #define DOMFLAGS_SHUTDOWNSHIFT 16 - u32 flags; + uint32_t flags; unsigned long tot_pages; unsigned long max_pages; unsigned long shared_info_frame; /* MFN of shared_info struct */ - u64 cpu_time; - u32 n_vcpu; - s32 vcpu_to_cpu[MAX_VIRT_CPUS]; /* current mapping */ + uint64_t cpu_time; + uint32_t n_vcpu; + int32_t vcpu_to_cpu[MAX_VIRT_CPUS]; /* current mapping */ cpumap_t cpumap[MAX_VIRT_CPUS]; /* allowable mapping */ - u32 ssidref; + uint32_t ssidref; } dom0_getdomaininfo_t; #define DOM0_SETDOMAININFO 13 typedef struct { /* IN variables. */ - domid_t domain; - u16 vcpu; + domid_t domain; + uint16_t vcpu; /* IN/OUT parameters */ vcpu_guest_context_t *ctxt; } dom0_setdomaininfo_t; @@ -105,29 +105,29 @@ typedef struct { #define DOM0_MSR 15 typedef struct { /* IN variables. */ - u32 write; - u32 cpu_mask; - u32 msr; - u32 in1; - u32 in2; + uint32_t write; + uint32_t cpu_mask; + uint32_t msr; + uint32_t in1; + uint32_t in2; /* OUT variables. */ - u32 out1; - u32 out2; + uint32_t out1; + uint32_t out2; } dom0_msr_t; #define DOM0_DEBUG 16 typedef struct { /* IN variables. */ - domid_t domain; - u8 opcode; - u32 in1; - u32 in2; - u32 in3; - u32 in4; + domid_t domain; + uint8_t opcode; + uint32_t in1; + uint32_t in2; + uint32_t in3; + uint32_t in4; /* OUT variables. */ - u32 status; - u32 out1; - u32 out2; + uint32_t status; + uint32_t out1; + uint32_t out2; } dom0_debug_t; /* @@ -137,9 +137,9 @@ typedef struct { #define DOM0_SETTIME 17 typedef struct { /* IN variables. */ - u32 secs; - u32 nsecs; - u64 system_time; + uint32_t secs; + uint32_t nsecs; + uint64_t system_time; } dom0_settime_t; #define DOM0_GETPAGEFRAMEINFO 18 @@ -159,7 +159,7 @@ typedef struct { domid_t domain; /* To which domain does the frame belong? */ /* OUT variables. */ /* Is the page PINNED to a type? */ - u32 type; /* see above type defs */ + uint32_t type; /* see above type defs */ } dom0_getpageframeinfo_t; /* @@ -168,10 +168,10 @@ typedef struct { #define DOM0_READCONSOLE 19 typedef struct { /* IN variables. */ - u32 clear; /* Non-zero -> clear after reading. */ + uint32_t clear; /* Non-zero -> clear after reading. */ /* IN/OUT variables. */ char *buffer; /* In: Buffer start; Out: Used buffer start */ - u32 count; /* In: Buffer size; Out: Used buffer size */ + uint32_t count; /* In: Buffer size; Out: Used buffer size */ } dom0_readconsole_t; /* @@ -181,7 +181,7 @@ typedef struct { typedef struct { /* IN variables. */ domid_t domain; - u16 vcpu; + uint16_t vcpu; cpumap_t *cpumap; } dom0_pincpudomain_t; @@ -192,13 +192,13 @@ typedef struct { #define DOM0_TBUF_GET_INFO 0 #define DOM0_TBUF_SET_CPU_MASK 1 #define DOM0_TBUF_SET_EVT_MASK 2 - u8 op; + uint8_t op; /* IN/OUT variables */ unsigned long cpu_mask; - u32 evt_mask; + uint32_t evt_mask; /* OUT variables */ unsigned long buffer_mfn; - u32 size; + uint32_t size; } dom0_tbufcontrol_t; /* @@ -206,14 +206,14 @@ typedef struct { */ #define DOM0_PHYSINFO 22 typedef struct { - u32 threads_per_core; - u32 cores_per_socket; - u32 sockets_per_node; - u32 nr_nodes; - u32 cpu_khz; + uint32_t threads_per_core; + uint32_t cores_per_socket; + uint32_t sockets_per_node; + uint32_t nr_nodes; + uint32_t cpu_khz; unsigned long total_pages; unsigned long free_pages; - u32 hw_cap[8]; + uint32_t hw_cap[8]; } dom0_physinfo_t; /* @@ -222,7 +222,7 @@ typedef struct { #define DOM0_SCHED_ID 24 typedef struct { /* OUT variable */ - u32 sched_id; + uint32_t sched_id; } dom0_sched_id_t; /* @@ -241,16 +241,16 @@ typedef struct { typedef struct dom0_shadow_control { - u32 fault_count; - u32 dirty_count; - u32 dirty_net_count; - u32 dirty_block_count; + uint32_t fault_count; + uint32_t dirty_count; + uint32_t dirty_net_count; + uint32_t dirty_block_count; } dom0_shadow_control_stats_t; typedef struct { /* IN variables. */ domid_t domain; - u32 op; + uint32_t op; unsigned long *dirty_bitmap; /* pointer to locked buffer */ /* IN/OUT variables. */ unsigned long pages; /* size of buffer, updated with actual size */ @@ -286,10 +286,10 @@ typedef struct { /* IN variables. */ unsigned long pfn; unsigned long nr_pfns; - u32 type; + uint32_t type; /* OUT variables. */ - u32 handle; - u32 reg; + uint32_t handle; + uint32_t reg; } dom0_add_memtype_t; /* @@ -302,19 +302,19 @@ typedef struct { #define DOM0_DEL_MEMTYPE 32 typedef struct { /* IN variables. */ - u32 handle; - u32 reg; + uint32_t handle; + uint32_t reg; } dom0_del_memtype_t; /* Read current type of an MTRR (x86-specific). */ #define DOM0_READ_MEMTYPE 33 typedef struct { /* IN variables. */ - u32 reg; + uint32_t reg; /* OUT variables. */ unsigned long pfn; unsigned long nr_pfns; - u32 type; + uint32_t type; } dom0_read_memtype_t; /* Interface for controlling Xen software performance counters. */ @@ -323,39 +323,39 @@ typedef struct { #define DOM0_PERFCCONTROL_OP_RESET 1 /* Reset all counters to zero. */ #define DOM0_PERFCCONTROL_OP_QUERY 2 /* Get perfctr information. */ typedef struct { - u8 name[80]; /* name of perf counter */ - u32 nr_vals; /* number of values for this counter */ - u32 vals[64]; /* array of values */ + uint8_t name[80]; /* name of perf counter */ + uint32_t nr_vals; /* number of values for this counter */ + uint32_t vals[64]; /* array of values */ } dom0_perfc_desc_t; typedef struct { /* IN variables. */ - u32 op; /* DOM0_PERFCCONTROL_OP_??? */ + uint32_t op; /* DOM0_PERFCCONTROL_OP_??? */ /* OUT variables. */ - u32 nr_counters; /* number of counters */ + uint32_t nr_counters; /* number of counters */ dom0_perfc_desc_t *desc; /* counter information (or NULL) */ } dom0_perfccontrol_t; #define DOM0_MICROCODE 35 typedef struct { /* IN variables. */ - void *data; /* Pointer to microcode data */ - u32 length; /* Length of microcode data. */ + void *data; /* Pointer to microcode data */ + uint32_t length; /* Length of microcode data. */ } dom0_microcode_t; #define DOM0_IOPORT_PERMISSION 36 typedef struct { - domid_t domain; /* domain to be affected */ - u16 first_port; /* first port int range */ - u16 nr_ports; /* size of port range */ - u16 allow_access; /* allow or deny access to range? */ + domid_t domain; /* domain to be affected */ + uint16_t first_port; /* first port int range */ + uint16_t nr_ports; /* size of port range */ + uint16_t allow_access; /* allow or deny access to range? */ } dom0_ioport_permission_t; #define DOM0_GETVCPUCONTEXT 37 typedef struct { - domid_t domain; /* domain to be affected */ - u16 vcpu; /* vcpu # */ + domid_t domain; /* domain to be affected */ + uint16_t vcpu; /* vcpu # */ vcpu_guest_context_t *ctxt; /* NB. IN/OUT variable. */ - u64 cpu_time; + uint64_t cpu_time; } dom0_getvcpucontext_t; #define DOM0_GETDOMAININFOLIST 38 @@ -382,14 +382,14 @@ typedef struct { /* OUT variables. */ int nr_map_entries; struct dom0_memory_map_entry { - u64 start, end; + uint64_t start, end; int is_ram; } *memory_map; } dom0_physical_memory_map_t; typedef struct { - u32 cmd; - u32 interface_version; /* DOM0_INTERFACE_VERSION */ + uint32_t cmd; + uint32_t interface_version; /* DOM0_INTERFACE_VERSION */ union { dom0_createdomain_t createdomain; dom0_pausedomain_t pausedomain; @@ -426,3 +426,13 @@ typedef struct { } dom0_op_t; #endif /* __XEN_PUBLIC_DOM0_OPS_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/event_channel.h b/xen/include/public/event_channel.h index b5b9ac99fc..18bbd97c86 100644 --- a/xen/include/public/event_channel.h +++ b/xen/include/public/event_channel.h @@ -19,9 +19,9 @@ #define EVTCHNOP_alloc_unbound 6 typedef struct evtchn_alloc_unbound { /* IN parameters */ - domid_t dom, remote_dom; + domid_t dom, remote_dom; /* OUT parameters */ - u32 port; + uint32_t port; } evtchn_alloc_unbound_t; /* @@ -34,10 +34,10 @@ typedef struct evtchn_alloc_unbound { #define EVTCHNOP_bind_interdomain 0 typedef struct evtchn_bind_interdomain { /* IN parameters. */ - domid_t remote_dom; - u32 remote_port; + domid_t remote_dom; + uint32_t remote_port; /* OUT parameters. */ - u32 local_port; + uint32_t local_port; } evtchn_bind_interdomain_t; /* @@ -51,10 +51,10 @@ typedef struct evtchn_bind_interdomain { #define EVTCHNOP_bind_virq 1 typedef struct evtchn_bind_virq { /* IN parameters. */ - u32 virq; - u32 vcpu; + uint32_t virq; + uint32_t vcpu; /* OUT parameters. */ - u32 port; + uint32_t port; } evtchn_bind_virq_t; /* @@ -66,11 +66,11 @@ typedef struct evtchn_bind_virq { #define EVTCHNOP_bind_pirq 2 typedef struct evtchn_bind_pirq { /* IN parameters. */ - u32 pirq; + uint32_t pirq; #define BIND_PIRQ__WILL_SHARE 1 - u32 flags; /* BIND_PIRQ__* */ + uint32_t flags; /* BIND_PIRQ__* */ /* OUT parameters. */ - u32 port; + uint32_t port; } evtchn_bind_pirq_t; /* @@ -81,9 +81,9 @@ typedef struct evtchn_bind_pirq { */ #define EVTCHNOP_bind_ipi 7 typedef struct evtchn_bind_ipi { - u32 vcpu; + uint32_t vcpu; /* OUT parameters. */ - u32 port; + uint32_t port; } evtchn_bind_ipi_t; /* @@ -94,7 +94,7 @@ typedef struct evtchn_bind_ipi { #define EVTCHNOP_close 3 typedef struct evtchn_close { /* IN parameters. */ - u32 port; + uint32_t port; } evtchn_close_t; /* @@ -104,7 +104,7 @@ typedef struct evtchn_close { #define EVTCHNOP_send 4 typedef struct evtchn_send { /* IN parameters. */ - u32 port; + uint32_t port; } evtchn_send_t; /* @@ -118,8 +118,8 @@ typedef struct evtchn_send { #define EVTCHNOP_status 5 typedef struct evtchn_status { /* IN parameters */ - domid_t dom; - u32 port; + domid_t dom; + uint32_t port; /* OUT parameters */ #define EVTCHNSTAT_closed 0 /* Channel is not in use. */ #define EVTCHNSTAT_unbound 1 /* Channel is waiting interdom connection.*/ @@ -127,18 +127,18 @@ typedef struct evtchn_status { #define EVTCHNSTAT_pirq 3 /* Channel is bound to a phys IRQ line. */ #define EVTCHNSTAT_virq 4 /* Channel is bound to a virtual IRQ line */ #define EVTCHNSTAT_ipi 5 /* Channel is bound to a virtual IPI line */ - u32 status; - u32 vcpu; /* VCPU to which this channel is bound. */ + uint32_t status; + uint32_t vcpu; /* VCPU to which this channel is bound. */ union { struct { - domid_t dom; + domid_t dom; } unbound; /* EVTCHNSTAT_unbound */ struct { - domid_t dom; - u32 port; + domid_t dom; + uint32_t port; } interdomain; /* EVTCHNSTAT_interdomain */ - u32 pirq; /* EVTCHNSTAT_pirq */ - u32 virq; /* EVTCHNSTAT_virq */ + uint32_t pirq; /* EVTCHNSTAT_pirq */ + uint32_t virq; /* EVTCHNSTAT_virq */ } u; } evtchn_status_t; @@ -155,12 +155,12 @@ typedef struct evtchn_status { #define EVTCHNOP_bind_vcpu 8 typedef struct evtchn_bind_vcpu { /* IN parameters. */ - u32 port; - u32 vcpu; + uint32_t port; + uint32_t vcpu; } evtchn_bind_vcpu_t; typedef struct evtchn_op { - u32 cmd; /* EVTCHNOP_* */ + uint32_t cmd; /* EVTCHNOP_* */ union { evtchn_alloc_unbound_t alloc_unbound; evtchn_bind_interdomain_t bind_interdomain; @@ -175,3 +175,13 @@ typedef struct evtchn_op { } evtchn_op_t; #endif /* __XEN_PUBLIC_EVENT_CHANNEL_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/grant_table.h b/xen/include/public/grant_table.h index 5fbed7c5d9..eb1ccdd935 100644 --- a/xen/include/public/grant_table.h +++ b/xen/include/public/grant_table.h @@ -73,14 +73,14 @@ */ typedef struct grant_entry { /* GTF_xxx: various type and flag information. [XEN,GST] */ - u16 flags; + uint16_t flags; /* The domain being granted foreign privileges. [GST] */ domid_t domid; /* * GTF_permit_access: Frame that @domid is allowed to map and access. [GST] * GTF_accept_transfer: Frame whose ownership transferred by @domid. [XEN] */ - u32 frame; + uint32_t frame; } grant_entry_t; /* @@ -131,7 +131,7 @@ typedef struct grant_entry { /* * Reference to a grant entry in a specified domain's grant table. */ -typedef u16 grant_ref_t; +typedef uint16_t grant_ref_t; /* * GNTTABOP_map_grant_ref: Map the grant entry (,) for access @@ -153,13 +153,13 @@ typedef u16 grant_ref_t; #define GNTTABOP_map_grant_ref 0 typedef struct gnttab_map_grant_ref { /* IN parameters. */ - u64 host_addr; - domid_t dom; + uint64_t host_addr; + domid_t dom; grant_ref_t ref; - u16 flags; /* GNTMAP_* */ + uint16_t flags; /* GNTMAP_* */ /* OUT parameters. */ - s16 handle; /* +ve: handle; -ve: GNTST_* */ - u64 dev_bus_addr; + int16_t handle; /* +ve: handle; -ve: GNTST_* */ + uint64_t dev_bus_addr; } gnttab_map_grant_ref_t; /* @@ -176,11 +176,11 @@ typedef struct gnttab_map_grant_ref { #define GNTTABOP_unmap_grant_ref 1 typedef struct gnttab_unmap_grant_ref { /* IN parameters. */ - u64 host_addr; - u64 dev_bus_addr; - u16 handle; + uint64_t host_addr; + uint64_t dev_bus_addr; + uint16_t handle; /* OUT parameters. */ - s16 status; /* GNTST_* */ + int16_t status; /* GNTST_* */ } gnttab_unmap_grant_ref_t; /* @@ -195,10 +195,10 @@ typedef struct gnttab_unmap_grant_ref { #define GNTTABOP_setup_table 2 typedef struct gnttab_setup_table { /* IN parameters. */ - domid_t dom; - u16 nr_frames; + domid_t dom; + uint16_t nr_frames; /* OUT parameters. */ - s16 status; /* GNTST_* */ + int16_t status; /* GNTST_* */ unsigned long *frame_list; } gnttab_setup_table_t; @@ -209,9 +209,9 @@ typedef struct gnttab_setup_table { #define GNTTABOP_dump_table 3 typedef struct gnttab_dump_table { /* IN parameters. */ - domid_t dom; + domid_t dom; /* OUT parameters. */ - s16 status; /* GNTST_* */ + int16_t status; /* GNTST_* */ } gnttab_dump_table_t; /* @@ -223,10 +223,10 @@ typedef struct gnttab_dump_table { typedef struct { /* IN parameters. */ unsigned long mfn; - domid_t domid; - grant_ref_t ref; + domid_t domid; + grant_ref_t ref; /* OUT parameters. */ - s16 status; + int16_t status; } gnttab_transfer_t; /* @@ -283,3 +283,13 @@ typedef struct { } #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/blkif.h b/xen/include/public/io/blkif.h index c57ff15d25..0f25768708 100644 --- a/xen/include/public/io/blkif.h +++ b/xen/include/public/io/blkif.h @@ -12,9 +12,9 @@ #include "ring.h" #ifndef blkif_vdev_t -#define blkif_vdev_t u16 +#define blkif_vdev_t uint16_t #endif -#define blkif_sector_t u64 +#define blkif_sector_t uint64_t #define BLKIF_OP_READ 0 #define BLKIF_OP_WRITE 1 @@ -30,8 +30,8 @@ #define BLKIF_MAX_SEGMENTS_PER_REQUEST 11 typedef struct blkif_request { - u8 operation; /* BLKIF_OP_??? */ - u8 nr_segments; /* number of segments */ + uint8_t operation; /* BLKIF_OP_??? */ + uint8_t nr_segments; /* number of segments */ blkif_vdev_t handle; /* only for read/write requests */ unsigned long id; /* private guest value, echoed in resp */ blkif_sector_t sector_number;/* start sector idx on disk (r/w only) */ @@ -51,8 +51,8 @@ typedef struct blkif_request { typedef struct blkif_response { unsigned long id; /* copied from request */ - u8 operation; /* copied from request */ - s16 status; /* BLKIF_RSP_??? */ + uint8_t operation; /* copied from request */ + int16_t status; /* BLKIF_RSP_??? */ } blkif_response_t; #define BLKIF_RSP_ERROR -1 /* non-specific 'error' */ @@ -72,3 +72,13 @@ DEFINE_RING_TYPES(blkif, blkif_request_t, blkif_response_t); #define VDISK_READONLY 0x4 #endif /* __XEN_PUBLIC_IO_BLKIF_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/console.h b/xen/include/public/io/console.h index a43729e467..cb59b24ffc 100644 --- a/xen/include/public/io/console.h +++ b/xen/include/public/io/console.h @@ -9,7 +9,7 @@ #ifndef __XEN_PUBLIC_IO_CONSOLE_H__ #define __XEN_PUBLIC_IO_CONSOLE_H__ -typedef u32 XENCONS_RING_IDX; +typedef uint32_t XENCONS_RING_IDX; #define MASK_XENCONS_IDX(idx, ring) ((idx) & (sizeof(ring)-1)) @@ -21,3 +21,13 @@ struct xencons_interface { }; #endif /* __XEN_PUBLIC_IO_CONSOLE_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/ioreq.h b/xen/include/public/io/ioreq.h index 5e0b66e501..d502171bbf 100644 --- a/xen/include/public/io/ioreq.h +++ b/xen/include/public/io/ioreq.h @@ -29,11 +29,11 @@ #define STATE_IORESP_READY 3 #define STATE_IORESP_HOOK 4 -#define IOREQ_TYPE_PIO 0 /* pio */ -#define IOREQ_TYPE_COPY 1 /* mmio ops */ -#define IOREQ_TYPE_AND 2 -#define IOREQ_TYPE_OR 3 -#define IOREQ_TYPE_XOR 4 +#define IOREQ_TYPE_PIO 0 /* pio */ +#define IOREQ_TYPE_COPY 1 /* mmio ops */ +#define IOREQ_TYPE_AND 2 +#define IOREQ_TYPE_OR 3 +#define IOREQ_TYPE_XOR 4 /* * VMExit dispatcher should cooperate with instruction decoder to @@ -41,38 +41,48 @@ * virq */ typedef struct { - u64 addr; /* physical address */ - u64 size; /* size in bytes */ - u64 count; /* for rep prefixes */ + uint64_t addr; /* physical address */ + uint64_t size; /* size in bytes */ + uint64_t count; /* for rep prefixes */ union { - u64 data; /* data */ - void *pdata; /* pointer to data */ + uint64_t data; /* data */ + void *pdata; /* pointer to data */ } u; - u8 state:4; - u8 pdata_valid:1; /* if 1, use pdata above */ - u8 dir:1; /* 1=read, 0=write */ - u8 df:1; - u8 type; /* I/O type */ + uint8_t state:4; + uint8_t pdata_valid:1; /* if 1, use pdata above */ + uint8_t dir:1; /* 1=read, 0=write */ + uint8_t df:1; + uint8_t type; /* I/O type */ } ioreq_t; #define MAX_VECTOR 256 #define BITS_PER_BYTE 8 -#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(u64))) +#define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t))) typedef struct { - u64 pic_intr[INTR_LEN]; - u64 pic_mask[INTR_LEN]; - int eport; /* Event channel port */ + uint64_t pic_intr[INTR_LEN]; + uint64_t pic_mask[INTR_LEN]; + int eport; /* Event channel port */ } global_iodata_t; typedef struct { - ioreq_t vp_ioreq; - unsigned long vp_intr[INTR_LEN]; + ioreq_t vp_ioreq; + unsigned long vp_intr[INTR_LEN]; } vcpu_iodata_t; typedef struct { - global_iodata_t sp_global; - vcpu_iodata_t vcpu_iodata[1]; + global_iodata_t sp_global; + vcpu_iodata_t vcpu_iodata[1]; } shared_iopage_t; #endif /* _IOREQ_H_ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/netif.h b/xen/include/public/io/netif.h index 6778159175..498cbd1e97 100644 --- a/xen/include/public/io/netif.h +++ b/xen/include/public/io/netif.h @@ -11,34 +11,34 @@ typedef struct netif_tx_request { grant_ref_t gref; /* Reference to buffer page */ - u16 offset:15; /* Offset within buffer page */ - u16 csum_blank:1; /* Proto csum field blank? */ - u16 id; /* Echoed in response message. */ - u16 size; /* Packet size in bytes. */ + uint16_t offset:15; /* Offset within buffer page */ + uint16_t csum_blank:1; /* Proto csum field blank? */ + uint16_t id; /* Echoed in response message. */ + uint16_t size; /* Packet size in bytes. */ } netif_tx_request_t; typedef struct netif_tx_response { - u16 id; - s8 status; + uint16_t id; + int8_t status; } netif_tx_response_t; typedef struct { - u16 id; /* Echoed in response message. */ - grant_ref_t gref; /* Reference to incoming granted frame */ + uint16_t id; /* Echoed in response message. */ + grant_ref_t gref; /* Reference to incoming granted frame */ } netif_rx_request_t; typedef struct { - u16 offset; /* Offset in page of start of received packet */ - u16 csum_valid; /* Protocol checksum is validated? */ - u16 id; - s16 status; /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */ + uint16_t offset; /* Offset in page of start of received packet */ + uint16_t csum_valid; /* Protocol checksum is validated? */ + uint16_t id; + int16_t status; /* -ve: BLKIF_RSP_* ; +ve: Rx'ed pkt size. */ } netif_rx_response_t; /* * We use a special capitalised type name because it is _essential_ that all * arithmetic on indexes is done on an integer type of the correct size. */ -typedef u32 NETIF_RING_IDX; +typedef uint32_t NETIF_RING_IDX; /* * Ring indexes are 'free running'. That is, they are not stored modulo the @@ -91,3 +91,13 @@ typedef struct netif_rx_interface { #define NETIF_RSP_OKAY 0 #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/ring.h b/xen/include/public/io/ring.h index 710aabfa2a..f52ccdc392 100644 --- a/xen/include/public/io/ring.h +++ b/xen/include/public/io/ring.h @@ -197,3 +197,13 @@ typedef struct __name##_back_ring __name##_back_ring_t (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r)) #endif /* __XEN_PUBLIC_IO_RING_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/tpmif.h b/xen/include/public/io/tpmif.h index 29ad2d227f..0ad0a1e81e 100644 --- a/xen/include/public/io/tpmif.h +++ b/xen/include/public/io/tpmif.h @@ -19,15 +19,15 @@ typedef struct { unsigned long addr; /* Machine address of packet. */ int ref; /* grant table access reference */ - u16 id; /* Echoed in response message. */ - u16 size; /* Packet size in bytes. */ + uint16_t id; /* Echoed in response message. */ + uint16_t size; /* Packet size in bytes. */ } tpmif_tx_request_t; /* * The TPMIF_TX_RING_SIZE defines the number of pages the * front-end and backend can exchange (= size of array). */ -typedef u32 TPMIF_RING_IDX; +typedef uint32_t TPMIF_RING_IDX; #define TPMIF_TX_RING_SIZE 10 @@ -42,3 +42,13 @@ typedef struct { } tpmif_tx_interface_t; #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/usbif.h b/xen/include/public/io/usbif.h deleted file mode 100644 index ff4e1480f2..0000000000 --- a/xen/include/public/io/usbif.h +++ /dev/null @@ -1,66 +0,0 @@ -/****************************************************************************** - * usbif.h - * - * Unified block-device I/O interface for Xen guest OSes. - * - * Copyright (c) 2003-2004, Keir Fraser - */ - -#ifndef __SHARED_USBIF_H__ -#define __SHARED_USBIF_H__ - -#define usbif_vdev_t u16 -#define usbif_sector_t u64 - -#define USBIF_OP_IO 0 /* Request IO to a device */ -#define USBIF_OP_PROBE 1 /* Is there a device on this port? */ -#define USBIF_OP_RESET 2 /* Reset a virtual USB port. */ - -typedef struct { - unsigned long id; /* private guest value, echoed in resp */ - u8 operation; /* USBIF_OP_??? */ - u8 __pad1; - usbif_vdev_t port; /* guest virtual USB port */ - unsigned long devnum :7; /* Device address, as seen by the guest.*/ - unsigned long endpoint :4; /* Device endpoint. */ - unsigned long direction :1; /* Pipe direction. */ - unsigned long speed :1; /* Pipe speed. */ - unsigned long pipe_type :2; /* Pipe type (iso, bulk, int, ctrl) */ - unsigned long __pad2 :18; - unsigned long transfer_buffer; /* Machine address */ - unsigned long length; /* Buffer length */ - unsigned long transfer_flags; /* For now just pass Linux transfer - * flags - this may change. */ - unsigned char setup[8]; /* Embed setup packets directly. */ - unsigned long iso_schedule; /* Machine address of transfer sched (iso - * only) */ - unsigned long num_iso; /* length of iso schedule */ - unsigned long timeout; /* timeout in ms */ -} usbif_request_t; - -/* Data we need to pass: - * - Transparently handle short packets or complain at us? - */ - -typedef struct { - unsigned long id; /* copied from request */ - u8 operation; /* copied from request */ - u8 data; /* Small chunk of in-band data */ - s16 status; /* USBIF_RSP_??? */ - unsigned long transfer_mutex; /* Used for cancelling requests atomically. */ - unsigned long length; /* How much data we really got */ -} usbif_response_t; - -#define USBIF_RSP_ERROR -1 /* non-specific 'error' */ -#define USBIF_RSP_OKAY 0 /* non-specific 'okay' */ - -DEFINE_RING_TYPES(usbif, usbif_request_t, usbif_response_t); - -typedef struct { - unsigned long length; /* IN = expected, OUT = actual */ - unsigned long buffer_offset; /* IN offset in buffer specified in main - packet */ - unsigned long status; /* OUT Status for this packet. */ -} usbif_iso_t; - -#endif /* __SHARED_USBIF_H__ */ diff --git a/xen/include/public/io/vmx_vlapic.h b/xen/include/public/io/vmx_vlapic.h index c414329628..5a8162b2e1 100644 --- a/xen/include/public/io/vmx_vlapic.h +++ b/xen/include/public/io/vmx_vlapic.h @@ -25,33 +25,43 @@ #define VL_STATE_EOI_LOCK 3 #define VLOCAL_APIC_MAX_INTS 256 -#define VLAPIC_INT_COUNT (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(u64))) -#define VLAPIC_INT_COUNT_32 (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(u32))) +#define VLAPIC_INT_COUNT (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(uint64_t))) +#define VLAPIC_INT_COUNT_32 (VLOCAL_APIC_MAX_INTS/(BITS_PER_BYTE * sizeof(uint32_t))) struct vapic_bus_message{ - u8 deliv_mode:4; /* deliver mode, including fixed, LPRI, etc */ - u8 level:1; /* level or edge */ - u8 trig_mod:1; /* assert or disassert */ - u8 reserved:2; - u8 vector; + uint8_t deliv_mode:4; /* deliver mode, including fixed, LPRI, etc */ + uint8_t level:1; /* level or edge */ + uint8_t trig_mod:1; /* assert or disassert */ + uint8_t reserved:2; + uint8_t vector; }; typedef struct { /* interrupt for PIC and ext type IOAPIC interrupt */ - u64 vl_ext_intr[VLAPIC_INT_COUNT]; - u64 vl_ext_intr_mask[VLAPIC_INT_COUNT]; - u64 vl_apic_intr[VLAPIC_INT_COUNT]; - u64 vl_apic_tmr[VLAPIC_INT_COUNT]; - u64 vl_eoi[VLAPIC_INT_COUNT]; - u32 vl_lapic_id; - u32 direct_intr; - u32 vl_apr; - u32 vl_logical_dest; - u32 vl_dest_format; - u32 vl_arb_id; - u32 vl_state; - u32 apic_msg_count; + uint64_t vl_ext_intr[VLAPIC_INT_COUNT]; + uint64_t vl_ext_intr_mask[VLAPIC_INT_COUNT]; + uint64_t vl_apic_intr[VLAPIC_INT_COUNT]; + uint64_t vl_apic_tmr[VLAPIC_INT_COUNT]; + uint64_t vl_eoi[VLAPIC_INT_COUNT]; + uint32_t vl_lapic_id; + uint32_t direct_intr; + uint32_t vl_apr; + uint32_t vl_logical_dest; + uint32_t vl_dest_format; + uint32_t vl_arb_id; + uint32_t vl_state; + uint32_t apic_msg_count; struct vapic_bus_message vl_apic_msg[24]; } vlapic_info; #endif /* _VMX_VLAPIC_H_ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/io/xs_wire.h b/xen/include/public/io/xs_wire.h index 4ab5633b8a..8f9fa047af 100644 --- a/xen/include/public/io/xs_wire.h +++ b/xen/include/public/io/xs_wire.h @@ -76,12 +76,13 @@ static struct xsd_errors xsd_errors[] __attribute__((unused)) = { XSD_ERROR(EAGAIN), XSD_ERROR(EISCONN), }; + struct xsd_sockmsg { - u32 type; /* XS_??? */ - u32 req_id;/* Request identifier, echoed in daemon's response. */ - u32 tx_id; /* Transaction id (0 if not related to a transaction). */ - u32 len; /* Length of data following this. */ + uint32_t type; /* XS_??? */ + uint32_t req_id;/* Request identifier, echoed in daemon's response. */ + uint32_t tx_id; /* Transaction id (0 if not related to a transaction). */ + uint32_t len; /* Length of data following this. */ /* Generally followed by nul-terminated string(s). */ }; @@ -93,3 +94,13 @@ enum xs_watch_type }; #endif /* _XS_WIRE_H */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index 7b94d47b8a..8a5f70c5b1 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -48,3 +48,13 @@ typedef struct xen_memory_reservation { } xen_memory_reservation_t; #endif /* __XEN_PUBLIC_MEMORY_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/physdev.h b/xen/include/public/physdev.h index 4a324ac470..9124ca5474 100644 --- a/xen/include/public/physdev.h +++ b/xen/include/public/physdev.h @@ -13,41 +13,41 @@ typedef struct physdevop_irq_status_query { /* IN */ - u32 irq; + uint32_t irq; /* OUT */ /* Need to call PHYSDEVOP_IRQ_UNMASK_NOTIFY when the IRQ has been serviced? */ #define PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY (1<<0) - u32 flags; + uint32_t flags; } physdevop_irq_status_query_t; typedef struct physdevop_set_iopl { /* IN */ - u32 iopl; + uint32_t iopl; } physdevop_set_iopl_t; typedef struct physdevop_set_iobitmap { /* IN */ - u8 *bitmap; - u32 nr_ports; + uint8_t *bitmap; + uint32_t nr_ports; } physdevop_set_iobitmap_t; typedef struct physdevop_apic { /* IN */ - u32 apic; - u32 offset; + uint32_t apic; + uint32_t offset; /* IN or OUT */ - u32 value; + uint32_t value; } physdevop_apic_t; typedef struct physdevop_irq { /* IN */ - u32 irq; + uint32_t irq; /* OUT */ - u32 vector; + uint32_t vector; } physdevop_irq_t; typedef struct physdev_op { - u32 cmd; + uint32_t cmd; union { physdevop_irq_status_query_t irq_status_query; physdevop_set_iopl_t set_iopl; diff --git a/xen/include/public/sched.h b/xen/include/public/sched.h index 5659e57026..a1a03de7ab 100644 --- a/xen/include/public/sched.h +++ b/xen/include/public/sched.h @@ -48,3 +48,13 @@ #define SHUTDOWN_crash 3 /* Tell controller we've crashed. */ #endif /* __XEN_PUBLIC_SCHED_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/sched_ctl.h b/xen/include/public/sched_ctl.h index 74566c7fed..11b40c06f8 100644 --- a/xen/include/public/sched_ctl.h +++ b/xen/include/public/sched_ctl.h @@ -20,39 +20,49 @@ * parameters */ struct sched_ctl_cmd { - u32 sched_id; - u32 direction; + uint32_t sched_id; + uint32_t direction; union { struct bvt_ctl { - u32 ctx_allow; + uint32_t ctx_allow; } bvt; } u; }; struct sched_adjdom_cmd { - u32 sched_id; - u32 direction; - domid_t domain; + uint32_t sched_id; + uint32_t direction; + domid_t domain; union { struct bvt_adjdom { - u32 mcu_adv; /* mcu advance: inverse of weight */ - u32 warpback; /* warp? */ - s32 warpvalue; /* warp value */ - long long warpl; /* warp limit */ - long long warpu; /* unwarp time requirement */ + uint32_t mcu_adv; /* mcu advance: inverse of weight */ + uint32_t warpback; /* warp? */ + int32_t warpvalue; /* warp value */ + int64_t warpl; /* warp limit */ + int64_t warpu; /* unwarp time requirement */ } bvt; - struct sedf_adjdom + struct sedf_adjdom { - u64 period; - u64 slice; - u64 latency; - u16 extratime; - u16 weight; + uint64_t period; + uint64_t slice; + uint64_t latency; + uint16_t extratime; + uint16_t weight; } sedf; } u; }; #endif /* __XEN_PUBLIC_SCHED_CTL_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h index dfd55fdcf5..9b3c4d5c0c 100644 --- a/xen/include/public/trace.h +++ b/xen/include/public/trace.h @@ -55,8 +55,8 @@ /* This structure represents a single trace buffer record. */ struct t_rec { - u64 cycles; /* cycle counter timestamp */ - u32 event; /* event ID */ + uint64_t cycles; /* cycle counter timestamp */ + uint32_t event; /* event ID */ unsigned long data[5]; /* event data items */ }; @@ -75,3 +75,13 @@ struct t_buf { }; #endif /* __XEN_PUBLIC_TRACE_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/vcpu.h b/xen/include/public/vcpu.h index ff5e463a0d..fa9537f1fe 100644 --- a/xen/include/public/vcpu.h +++ b/xen/include/public/vcpu.h @@ -52,3 +52,13 @@ #define VCPUOP_is_up 3 #endif /* __XEN_PUBLIC_VCPU_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/version.h b/xen/include/public/version.h index f2a0c962ca..80489adcd1 100644 --- a/xen/include/public/version.h +++ b/xen/include/public/version.h @@ -40,3 +40,13 @@ typedef struct xen_parameters_info { } xen_parameters_info_t; #endif /* __XEN_PUBLIC_VERSION_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/vmx_assist.h b/xen/include/public/vmx_assist.h index 6136ce983d..22664656a4 100644 --- a/xen/include/public/vmx_assist.h +++ b/xen/include/public/vmx_assist.h @@ -21,81 +21,90 @@ #ifndef _VMX_ASSIST_H_ #define _VMX_ASSIST_H_ -#define VMXASSIST_BASE 0xD0000 -#define VMXASSIST_MAGIC 0x17101966 -#define VMXASSIST_MAGIC_OFFSET (VMXASSIST_BASE+8) +#define VMXASSIST_BASE 0xD0000 +#define VMXASSIST_MAGIC 0x17101966 +#define VMXASSIST_MAGIC_OFFSET (VMXASSIST_BASE+8) -#define VMXASSIST_NEW_CONTEXT (VMXASSIST_BASE + 12) -#define VMXASSIST_OLD_CONTEXT (VMXASSIST_NEW_CONTEXT + 4) +#define VMXASSIST_NEW_CONTEXT (VMXASSIST_BASE + 12) +#define VMXASSIST_OLD_CONTEXT (VMXASSIST_NEW_CONTEXT + 4) #ifndef __ASSEMBLY__ union vmcs_arbytes { - struct arbyte_fields { - unsigned int seg_type : 4, - s : 1, - dpl : 2, - p : 1, - reserved0 : 4, - avl : 1, - reserved1 : 1, - default_ops_size: 1, - g : 1, - null_bit : 1, - reserved2 : 15; - } fields; - unsigned int bytes; + struct arbyte_fields { + unsigned int seg_type : 4, + s : 1, + dpl : 2, + p : 1, + reserved0 : 4, + avl : 1, + reserved1 : 1, + default_ops_size: 1, + g : 1, + null_bit : 1, + reserved2 : 15; + } fields; + unsigned int bytes; }; /* * World switch state */ typedef struct vmx_assist_context { - u32 eip; /* execution pointer */ - u32 esp; /* stack point */ - u32 eflags; /* flags register */ - u32 cr0; - u32 cr3; /* page table directory */ - u32 cr4; - u32 idtr_limit; /* idt */ - u32 idtr_base; - u32 gdtr_limit; /* gdt */ - u32 gdtr_base; - u32 cs_sel; /* cs selector */ - u32 cs_limit; - u32 cs_base; - union vmcs_arbytes cs_arbytes; - u32 ds_sel; /* ds selector */ - u32 ds_limit; - u32 ds_base; - union vmcs_arbytes ds_arbytes; - u32 es_sel; /* es selector */ - u32 es_limit; - u32 es_base; - union vmcs_arbytes es_arbytes; - u32 ss_sel; /* ss selector */ - u32 ss_limit; - u32 ss_base; - union vmcs_arbytes ss_arbytes; - u32 fs_sel; /* fs selector */ - u32 fs_limit; - u32 fs_base; - union vmcs_arbytes fs_arbytes; - u32 gs_sel; /* gs selector */ - u32 gs_limit; - u32 gs_base; - union vmcs_arbytes gs_arbytes; - u32 tr_sel; /* task selector */ - u32 tr_limit; - u32 tr_base; - union vmcs_arbytes tr_arbytes; - u32 ldtr_sel; /* ldtr selector */ - u32 ldtr_limit; - u32 ldtr_base; - union vmcs_arbytes ldtr_arbytes; + uint32_t eip; /* execution pointer */ + uint32_t esp; /* stack pointer */ + uint32_t eflags; /* flags register */ + uint32_t cr0; + uint32_t cr3; /* page table directory */ + uint32_t cr4; + uint32_t idtr_limit; /* idt */ + uint32_t idtr_base; + uint32_t gdtr_limit; /* gdt */ + uint32_t gdtr_base; + uint32_t cs_sel; /* cs selector */ + uint32_t cs_limit; + uint32_t cs_base; + union vmcs_arbytes cs_arbytes; + uint32_t ds_sel; /* ds selector */ + uint32_t ds_limit; + uint32_t ds_base; + union vmcs_arbytes ds_arbytes; + uint32_t es_sel; /* es selector */ + uint32_t es_limit; + uint32_t es_base; + union vmcs_arbytes es_arbytes; + uint32_t ss_sel; /* ss selector */ + uint32_t ss_limit; + uint32_t ss_base; + union vmcs_arbytes ss_arbytes; + uint32_t fs_sel; /* fs selector */ + uint32_t fs_limit; + uint32_t fs_base; + union vmcs_arbytes fs_arbytes; + uint32_t gs_sel; /* gs selector */ + uint32_t gs_limit; + uint32_t gs_base; + union vmcs_arbytes gs_arbytes; + uint32_t tr_sel; /* task selector */ + uint32_t tr_limit; + uint32_t tr_base; + union vmcs_arbytes tr_arbytes; + uint32_t ldtr_sel; /* ldtr selector */ + uint32_t ldtr_limit; + uint32_t ldtr_base; + union vmcs_arbytes ldtr_arbytes; } vmx_assist_context_t; #endif /* __ASSEMBLY__ */ #endif /* _VMX_ASSIST_H_ */ +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 8d85d6663c..d6a3098f2f 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -213,7 +213,7 @@ struct mmuext_op { #ifndef __ASSEMBLY__ -typedef u16 domid_t; +typedef uint16_t domid_t; /* Domain ids >= DOMID_FIRST_RESERVED cannot be used for ordinary domains. */ #define DOMID_FIRST_RESERVED (0x7FF0U) @@ -246,8 +246,8 @@ typedef u16 domid_t; */ typedef struct { - u64 ptr; /* Machine address of PTE. */ - u64 val; /* New contents of PTE. */ + uint64_t ptr; /* Machine address of PTE. */ + uint64_t val; /* New contents of PTE. */ } mmu_update_t; /* @@ -293,9 +293,9 @@ typedef struct vcpu_info { * an upcall activation. The mask is cleared when the VCPU requests * to block: this avoids wakeup-waiting races. */ - u8 evtchn_upcall_pending; - u8 evtchn_upcall_mask; - u32 evtchn_pending_sel; + uint8_t evtchn_upcall_pending; + uint8_t evtchn_upcall_mask; + uint32_t evtchn_pending_sel; #ifdef __ARCH_HAS_VCPU_INFO arch_vcpu_info_t arch; #endif @@ -311,17 +311,17 @@ typedef struct vcpu_time_info { * The correct way to interact with the version number is similar to * Linux's seqlock: see the implementations of read_seqbegin/read_seqretry. */ - u32 version; - u64 tsc_timestamp; /* TSC at last update of time vals. */ - u64 system_time; /* Time, in nanosecs, since boot. */ + uint32_t version; + uint64_t tsc_timestamp; /* TSC at last update of time vals. */ + uint64_t system_time; /* Time, in nanosecs, since boot. */ /* * Current system time: * system_time + ((tsc - tsc_timestamp) << tsc_shift) * tsc_to_system_mul * CPU frequency (Hz): * ((10^9 << 32) / tsc_to_system_mul) >> tsc_shift */ - u32 tsc_to_system_mul; - s8 tsc_shift; + uint32_t tsc_to_system_mul; + int8_t tsc_shift; } vcpu_time_info_t; /* @@ -333,7 +333,7 @@ typedef struct shared_info { vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS]; - u32 n_vcpu; + uint32_t n_vcpu; /* * A domain can have up to 1024 "event channels" on which it can send @@ -366,16 +366,16 @@ typedef struct shared_info { * 32-bit selector to be set. Each bit in the selector covers a 32-bit * word in the PENDING bitfield array. */ - u32 evtchn_pending[32]; - u32 evtchn_mask[32]; + uint32_t evtchn_pending[32]; + uint32_t evtchn_mask[32]; /* * Wallclock time: updated only by control software. Guests should base * their gettimeofday() syscall on this wallclock-base value. */ - u32 wc_version; /* Version counter: see vcpu_time_info_t. */ - u32 wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */ - u32 wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */ + uint32_t wc_version; /* Version counter: see vcpu_time_info_t. */ + uint32_t wc_sec; /* Secs 00:00:00 UTC, Jan 1, 1970. */ + uint32_t wc_nsec; /* Nsecs 00:00:00 UTC, Jan 1, 1970. */ arch_shared_info_t arch; @@ -411,18 +411,18 @@ typedef struct start_info { /* THE FOLLOWING ARE FILLED IN BOTH ON INITIAL BOOT AND ON RESUME. */ unsigned long nr_pages; /* Total pages allocated to this domain. */ unsigned long shared_info; /* MACHINE address of shared info struct. */ - u32 flags; /* SIF_xxx flags. */ + uint32_t flags; /* SIF_xxx flags. */ unsigned long store_mfn; /* MACHINE page number of shared page. */ - u16 store_evtchn; /* Event channel for store communication. */ + uint16_t store_evtchn; /* Event channel for store communication. */ unsigned long console_mfn; /* MACHINE address of console page. */ - u16 console_evtchn; /* Event channel for console messages. */ + uint16_t console_evtchn; /* Event channel for console messages. */ /* THE FOLLOWING ARE ONLY FILLED IN ON INITIAL BOOT (NOT RESUME). */ unsigned long pt_base; /* VIRTUAL address of page directory. */ unsigned long nr_pt_frames; /* Number of bootstrap p.t. frames. */ unsigned long mfn_list; /* VIRTUAL address of page-frame list. */ unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */ unsigned long mod_len; /* Size (bytes) of pre-loaded module. */ - s8 cmd_line[MAX_GUEST_CMDLINE]; + int8_t cmd_line[MAX_GUEST_CMDLINE]; } start_info_t; /* These flags are passed in the 'flags' field of start_info_t. */ @@ -435,8 +435,18 @@ typedef struct start_info { /* For use in guest OSes. */ extern shared_info_t *HYPERVISOR_shared_info; -typedef u64 cpumap_t; +typedef uint64_t cpumap_t; #endif /* !__ASSEMBLY__ */ #endif /* __XEN_PUBLIC_XEN_H__ */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/xen/types.h b/xen/include/xen/types.h index ab045d9387..8bafc73156 100644 --- a/xen/include/xen/types.h +++ b/xen/include/xen/types.h @@ -32,23 +32,21 @@ typedef unsigned short ushort; typedef unsigned int uint; typedef unsigned long ulong; -#ifndef __BIT_TYPES_DEFINED__ -#define __BIT_TYPES_DEFINED__ - +typedef __u8 uint8_t; typedef __u8 u_int8_t; typedef __s8 int8_t; + +typedef __u16 uint16_t; typedef __u16 u_int16_t; typedef __s16 int16_t; + +typedef __u32 uint32_t; typedef __u32 u_int32_t; typedef __s32 int32_t; -#endif /* !(__BIT_TYPES_DEFINED__) */ - -typedef __u8 uint8_t; -typedef __u16 uint16_t; -typedef __u32 uint32_t; typedef __u64 uint64_t; - +typedef __u64 u_int64_t; +typedef __s64 int64_t; struct domain; struct vcpu; From 3bf766cdf115b968c95d20cb2ea8f721228ed544 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 11:13:00 +0100 Subject: [PATCH 011/142] Better cast for ptr->int in residerfs module. Signed-off-by: Keir Fraser --- tools/pygrub/src/fsys/reiser/reisermodule.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pygrub/src/fsys/reiser/reisermodule.c b/tools/pygrub/src/fsys/reiser/reisermodule.c index 6f2161114a..9eb4e1e638 100644 --- a/tools/pygrub/src/fsys/reiser/reisermodule.c +++ b/tools/pygrub/src/fsys/reiser/reisermodule.c @@ -46,7 +46,7 @@ void file_dal_close(dal_t *dal) { if (!dal) return; - close((size_t)dal->dev); + close((int)(unsigned long)dal->dev); dal_free(dal); } From c7a76688b934975b6b3008518dc5184d62fb818e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 11:47:16 +0100 Subject: [PATCH 012/142] Fix vcpu-hotplug xenbus watch handler and setup. Signed-off-by: Keir Fraser --- .../arch/xen/i386/kernel/smpboot.c | 137 ++++++------------ 1 file changed, 41 insertions(+), 96 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c index 6152c349c4..267bd31cd5 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -64,6 +64,7 @@ #include #include +#include /* Set if we find a B stepping CPU */ static int __initdata smp_b_stepping; @@ -1289,117 +1290,51 @@ void __devinit smp_prepare_boot_cpu(void) } #ifdef CONFIG_HOTPLUG_CPU -#include -/* hotplug down/up funtion pointer and target vcpu */ -struct vcpu_hotplug_handler_t { - void (*fn) (int vcpu); - u32 vcpu; -}; -static struct vcpu_hotplug_handler_t vcpu_hotplug_handler; -static int vcpu_hotplug_cpu_process(void *unused) +static void handle_vcpu_hotplug_event( + struct xenbus_watch *watch, const char **vec, unsigned int len) { - struct vcpu_hotplug_handler_t *handler = &vcpu_hotplug_handler; + int err, cpu; + char dir[32], state[32]; + char *cpustr; + const char *node = vec[XS_WATCH_PATH]; - if (handler->fn) { - (*(handler->fn)) (handler->vcpu); - handler->fn = NULL; + if ((cpustr = strstr(node, "cpu/")) == NULL) + return; + + sscanf(cpustr, "cpu/%d", &cpu); + + sprintf(dir, "cpu/%d", cpu); + err = xenbus_scanf(NULL, dir, "availability", "%s", state); + if (err != 1) { + printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); + return; } - return 0; + + if (strcmp(state, "online") == 0) + (void)cpu_up(cpu); + else if (strcmp(state, "offline") == 0) + (void)cpu_down(cpu); + else + printk(KERN_ERR "XENBUS: unknown state(%s) on node(%s)\n", + state, node); } -static void __vcpu_hotplug_handler(void *unused) -{ - int err; - - err = kernel_thread(vcpu_hotplug_cpu_process, - NULL, CLONE_FS | CLONE_FILES); - if (err < 0) - printk(KERN_ALERT "Error creating hotplug_cpu process!\n"); -} - -static void handle_vcpu_hotplug_event(struct xenbus_watch *, const char *); -static struct notifier_block xsn_cpu; - -/* xenbus watch struct */ -static struct xenbus_watch cpu_watch = { - .node = "cpu", - .callback = handle_vcpu_hotplug_event -}; - static int setup_cpu_watcher(struct notifier_block *notifier, unsigned long event, void *data) { - int err; - - err = register_xenbus_watch(&cpu_watch); - if (err) - printk("Failed to register watch on /cpu\n"); - + static struct xenbus_watch cpu_watch = { + .node = "cpu", + .callback = handle_vcpu_hotplug_event }; + (void)register_xenbus_watch(&cpu_watch); return NOTIFY_DONE; } -static void handle_vcpu_hotplug_event(struct xenbus_watch *watch, const char *node) -{ - static DECLARE_WORK(vcpu_hotplug_work, __vcpu_hotplug_handler, NULL); - struct vcpu_hotplug_handler_t *handler = &vcpu_hotplug_handler; - ssize_t ret; - int err, cpu; - char state[8]; - char dir[32]; - char *cpustr; - - /* get a pointer to start of cpu string */ - if ((cpustr = strstr(node, "cpu/")) != NULL) { - - /* find which cpu state changed, note vcpu for handler */ - sscanf(cpustr, "cpu/%d", &cpu); - handler->vcpu = cpu; - - /* calc the dir for xenbus read */ - sprintf(dir, "cpu/%d", cpu); - - /* make sure watch that was triggered is changes to the correct key */ - if ((strcmp(node + strlen(dir), "/availability")) != 0) - return; - - /* get the state value */ - err = xenbus_scanf(NULL, dir, "availability", "%s", state); - - if (err != 1) { - printk(KERN_ERR - "XENBUS: Unable to read cpu state\n"); - return; - } - - /* if we detect a state change, take action */ - if (strcmp(state, "online") == 0) { - /* offline -> online */ - if (!cpu_isset(cpu, cpu_online_map)) { - handler->fn = (void *)&cpu_up; - ret = schedule_work(&vcpu_hotplug_work); - } - } else if (strcmp(state, "offline") == 0) { - /* online -> offline */ - if (cpu_isset(cpu, cpu_online_map)) { - handler->fn = (void *)&cpu_down; - ret = schedule_work(&vcpu_hotplug_work); - } - } else { - printk(KERN_ERR - "XENBUS: unknown state(%s) on node(%s)\n", state, - node); - } - } - return; -} - static int __init setup_vcpu_hotplug_event(void) { - xsn_cpu.notifier_call = setup_cpu_watcher; - + static struct notifier_block xsn_cpu = { + .notifier_call = setup_cpu_watcher }; register_xenstore_notifier(&xsn_cpu); - return 0; } @@ -1623,3 +1558,13 @@ void vcpu_prepare(int vcpu) (void)HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt); (void)HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL); } + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ From bd0321055f271a12599e5e6502b6f1243f6d3eee Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 11:51:52 +0100 Subject: [PATCH 013/142] Added missing __init__.py. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/tests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 tools/python/xen/xend/tests/__init__.py diff --git a/tools/python/xen/xend/tests/__init__.py b/tools/python/xen/xend/tests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 1d47535f5fe312b1d0e6ef94f4914517ecc53bef Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 12:03:03 +0100 Subject: [PATCH 014/142] Fix the handling of EAGAIN from the transaction_end; we were failing to do any work if the transaction caused a retry, because optind had been obliterated. Achieve this by splitting the main body of the loop off to a separate function, meaning that we get rid of the goto out at the same time. Signed-off-by: Ewan Mellor --- tools/xenstore/xenstore_client.c | 122 +++++++++++++++---------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/tools/xenstore/xenstore_client.c b/tools/xenstore/xenstore_client.c index e4ef31caec..f70f95557c 100644 --- a/tools/xenstore/xenstore_client.c +++ b/tools/xenstore/xenstore_client.c @@ -4,6 +4,7 @@ * this archive for more details. * * Copyright (C) 2005 by Christian Limpach + * Copyright (C) 2005 XenSource Ltd. * */ @@ -28,16 +29,71 @@ usage(const char *progname) #endif } + +static int +perform(int optind, int argc, char **argv, struct xs_handle *xsh, + struct xs_transaction_handle *xth, int prefix) +{ + while (optind < argc) { +#if defined(CLIENT_read) + char *val = xs_read(xsh, xth, argv[optind], NULL); + if (val == NULL) { + warnx("couldn't read path %s", argv[optind]); + return 1; + } + if (prefix) + printf("%s: ", argv[optind]); + printf("%s\n", val); + free(val); + optind++; +#elif defined(CLIENT_write) + if (!xs_write(xsh, xth, argv[optind], argv[optind + 1], + strlen(argv[optind + 1]))) { + warnx("could not write path %s", argv[optind]); + return 1; + } + optind += 2; +#elif defined(CLIENT_rm) + if (!xs_rm(xsh, xth, argv[optind])) { + warnx("could not remove path %s", argv[optind]); + return 1; + } + optind++; +#elif defined(CLIENT_exists) + char *val = xs_read(xsh, xth, argv[optind], NULL); + if (val == NULL) { + return 1; + } + free(val); + optind++; +#elif defined(CLIENT_list) + unsigned int i, num; + char **list = xs_directory(xsh, xth, argv[optind], &num); + if (list == NULL) { + warnx("could not list path %s", argv[optind]); + return 1; + } + for (i = 0; i < num; i++) { + if (prefix) + printf("%s/", argv[optind]); + printf("%s\n", list[i]); + } + free(list); + optind++; +#endif + } + + return 0; +} + + int main(int argc, char **argv) { struct xs_handle *xsh; struct xs_transaction_handle *xth; - bool success; int ret = 0, socket = 0; -#if defined(CLIENT_read) || defined(CLIENT_list) int prefix = 0; -#endif while (1) { int c, index = 0; @@ -93,65 +149,9 @@ main(int argc, char **argv) if (xth == NULL) errx(1, "couldn't start transaction"); - while (optind < argc) { -#if defined(CLIENT_read) - char *val = xs_read(xsh, xth, argv[optind], NULL); - if (val == NULL) { - warnx("couldn't read path %s", argv[optind]); - ret = 1; - goto out; - } - if (prefix) - printf("%s: ", argv[optind]); - printf("%s\n", val); - free(val); - optind++; -#elif defined(CLIENT_write) - success = xs_write(xsh, xth, argv[optind], argv[optind + 1], - strlen(argv[optind + 1])); - if (!success) { - warnx("could not write path %s", argv[optind]); - ret = 1; - goto out; - } - optind += 2; -#elif defined(CLIENT_rm) - success = xs_rm(xsh, xth, argv[optind]); - if (!success) { - warnx("could not remove path %s", argv[optind]); - ret = 1; - goto out; - } - optind++; -#elif defined(CLIENT_exists) - char *val = xs_read(xsh, xth, argv[optind], NULL); - if (val == NULL) { - ret = 1; - goto out; - } - free(val); - optind++; -#elif defined(CLIENT_list) - unsigned int i, num; - char **list = xs_directory(xsh, xth, argv[optind], &num); - if (list == NULL) { - warnx("could not list path %s", argv[optind]); - ret = 1; - goto out; - } - for (i = 0; i < num; i++) { - if (prefix) - printf("%s/", argv[optind]); - printf("%s\n", list[i]); - } - free(list); - optind++; -#endif - } + ret = perform(optind, argc, argv, xsh, xth, prefix); - out: - success = xs_transaction_end(xsh, xth, ret ? true : false); - if (!success) { + if (!xs_transaction_end(xsh, xth, ret)) { if (ret == 0 && errno == EAGAIN) goto again; errx(1, "couldn't end transaction"); From db778d68ddf6a1a77cad714c6f0be6ff1ebae402 Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 12:04:45 +0100 Subject: [PATCH 015/142] Explicitly state which architectures are going to use /usr/lib64, to allow for the fact that Itanium does not. Signed-off-by: Ewan Mellor --- tools/python/xen/util/auxbin.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/util/auxbin.py b/tools/python/xen/util/auxbin.py index b6ba6cff9f..06cd500b4b 100644 --- a/tools/python/xen/util/auxbin.py +++ b/tools/python/xen/util/auxbin.py @@ -19,6 +19,10 @@ LIB_BIN_32 = "/usr/lib/xen/bin" LIB_BIN_64 = "/usr/lib64/xen/bin" +## The architectures on which the LIB_BIN_64 directory is used. This +# deliberately excludes ia64. +LIB_64_ARCHS = [ 'x86_64', 'ppc64', 's390x', 'sparc64'] + import os import os.path @@ -38,7 +42,7 @@ def pathTo(exe): def path(): machine = os.uname()[4] - if machine.find('64') != -1 and os.path.exists(LIB_BIN_64): + if machine in LIB_64_ARCHS and os.path.exists(LIB_BIN_64): return LIB_BIN_64 else: return LIB_BIN_32 From c74a06ff247221354c995ea0a025bcdeef59698e Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 12:54:43 +0100 Subject: [PATCH 016/142] Improve error message. --- tools/python/xen/xend/server/DevController.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/DevController.py b/tools/python/xen/xend/server/DevController.py index 1b94f14525..8141e890b1 100644 --- a/tools/python/xen/xend/server/DevController.py +++ b/tools/python/xen/xend/server/DevController.py @@ -82,7 +82,7 @@ class DevController: if backpath: xstransact.Remove(backpath) else: - raise VmError("Device not connected") + raise VmError("Device %s not connected" % devid) def configurations(self): From 0041d06c9531207693fb29c02c5dd0044945f7e8 Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 12:56:52 +0100 Subject: [PATCH 017/142] Don't try and call DevController if we can't destroy a device ourselves, because we are already inside the ValueError exception handler, so we know that the give device identifier is not an integer, and DevController.destroyDevice only accepts integers. Fixes bug #315. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/blkif.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index 5f791428bb..a15edf0963 100644 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -96,6 +96,4 @@ class BlkifController(DevController): if self.readBackend(i, 'dev') == devid: DevController.destroyDevice(self, i) return - # Try this, but it's almost certainly going to throw VmError, - # since we can't find the device. - DevController.destroyDevice(self, int(devid)) + raise VmError("Device %s not connected" % devid) From 5ca91af2f8fbcac9dfa1ed61c7045dac9b6cd722 Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 13:00:55 +0100 Subject: [PATCH 018/142] Ignore any watches that fire for which we do not have a registration. This can happen if there are watches in flight at the same time as a deregistration, and also seems to happen spuriously on xend restart. This fixes the Invalid token error that has been seen on xend restart. Signed-off-by: Ewan Mellor --- tools/python/xen/lowlevel/xs/xs.c | 10 ++++++++-- tools/python/xen/xend/xenstore/xswatch.py | 16 +++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c index 48a317dd88..b676419227 100644 --- a/tools/python/xen/lowlevel/xs/xs.c +++ b/tools/python/xen/lowlevel/xs/xs.c @@ -513,6 +513,7 @@ static PyObject *xspy_read_watch(PyObject *self, PyObject *args, goto exit; if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec)) goto exit; +again: Py_BEGIN_ALLOW_THREADS xsval = xs_read_watch(xh, &num); Py_END_ALLOW_THREADS @@ -529,8 +530,13 @@ static PyObject *xspy_read_watch(PyObject *self, PyObject *args, break; } if (i == PyList_Size(xsh->watches)) { - PyErr_SetString(PyExc_RuntimeError, "invalid token"); - goto exit; + /* We do not have a registered watch for the one that has just fired. + Ignore this -- a watch that has been recently deregistered can still + have watches in transit. This is a blocking method, so go back to + read again. + */ + free(xsval); + goto again; } /* Create tuple (path, token). */ val = Py_BuildValue("(sO)", xsval[XS_WATCH_PATH], token); diff --git a/tools/python/xen/xend/xenstore/xswatch.py b/tools/python/xen/xend/xenstore/xswatch.py index 8a2da8d12c..3fc0f75645 100644 --- a/tools/python/xen/xend/xenstore/xswatch.py +++ b/tools/python/xen/xend/xenstore/xswatch.py @@ -10,6 +10,9 @@ import threading from xen.lowlevel import xs from xen.xend.xenstore.xsutil import xshandle +from xen.xend.XendLogging import log + + class xswatch: watchThread = None @@ -41,10 +44,13 @@ class xswatch: while True: try: we = cls.xs.read_watch() - except RuntimeError, ex: - print ex - raise - watch = we[1] - watch.fn(*watch.args, **watch.kwargs) + watch = we[1] + watch.fn(*watch.args, **watch.kwargs) + except: + log.exception("read_watch failed") + # Ignore this exception -- there's no point throwing it + # further on because that will just kill the watcher thread, + # which achieves nothing. + watchMain = classmethod(watchMain) From f95154b372faea9e32256bebb7100f222545f82a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 13:03:10 +0100 Subject: [PATCH 019/142] Fix firmware build for cross-compilation. Signed-off-by: Keir Fraser --- tools/firmware/acpi/acpi_gen.c | 64 ++++++++++++++----------------- tools/firmware/vmxassist/Makefile | 28 +++++++------- 2 files changed, 43 insertions(+), 49 deletions(-) diff --git a/tools/firmware/acpi/acpi_gen.c b/tools/firmware/acpi/acpi_gen.c index f8951b118a..25c0ca7917 100644 --- a/tools/firmware/acpi/acpi_gen.c +++ b/tools/firmware/acpi/acpi_gen.c @@ -16,44 +16,38 @@ * */ #include "acpi2_0.h" -#include "stdio.h" +#include +#include +#include -/* - * Generate acpi table - * write acpi table to binary: acpitable.bin - * - */ - -#define USAGE "Usage: acpi_gen filename \n" \ - " generage acpitable and write to the binary \n" \ - " filename - the binary name\n" +#define USAGE "Usage: acpi_gen filename \n" \ + " generage acpitable and write to the binary \n" \ + " filename - the binary name\n" +int main(int argc, char **argv) +{ + char *filename; + char buf[ACPI_TABLE_SIZE] = { 0 }; + FILE *f; -int main(int argc, char** argv){ - char* filename; - char buf[ACPI_TABLE_SIZE]; - FILE* f=NULL; - int i; + if (argc < 2) { + fprintf(stderr,"%s",USAGE); + exit(1); + } - for (i=0; i vmxassist.tmp - ${LD} -o vmxassist ${LDFLAGS} -nostdlib --fatal-warnings -N -T vmxassist.tmp ${OBJECTS} +vmxassist.bin: vmxassist.ld $(OBJECTS) + $(CPP) $(DEFINES) vmxassist.ld > vmxassist.tmp + $(LD) -o vmxassist $(LDFLAGS) -nostdlib --fatal-warnings -N -T vmxassist.tmp $(OBJECTS) nm -n vmxassist > vmxassist.sym - ${OBJCOPY} vmxassist vmxassist.tmp + $(OBJCOPY) vmxassist vmxassist.tmp dd if=vmxassist.tmp of=vmxassist.bin ibs=512 conv=sync rm -f vmxassist.tmp head.o: machine.h head.S - ${CC} ${CFLAGS} -D__ASSEMBLY__ ${DEFINES} -c head.S + $(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c head.S trap.o: machine.h offsets.h trap.S - ${CC} ${CFLAGS} -D__ASSEMBLY__ ${DEFINES} -c trap.S + $(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c trap.S vm86.o: machine.h vm86.c - ${CC} ${CFLAGS} -c vm86.c + $(CC) $(CFLAGS) -c vm86.c setup.o: machine.h setup.c - ${CC} ${CFLAGS} -c setup.c + $(CC) $(CFLAGS) -c setup.c util.o: machine.h util.c - ${CC} ${CFLAGS} -c util.c + $(CC) $(CFLAGS) -c util.c roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin ../vgabios/VGABIOS-lgpl-latest.cirrus.bin vmxassist.bin ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h @@ -81,10 +81,10 @@ offsets.h: gen ./gen > offsets.h gen: gen.c - ${CC} ${CFLAGS} -o gen gen.c + $(HOSTCC) $(HOSTCFLAGS) -I. $(XENINC) -o gen gen.c clean: rm -f vmxassist vmxassist.tmp vmxassist.bin vmxassist.run vmxassist.sym head.s roms.h acpi.h - rm -f vmxloader vmxloader.tmp vmxloader.o ${OBJECTS} + rm -f vmxloader vmxloader.tmp vmxloader.o $(OBJECTS) rm -f gen gen.o offsets.h From 3e500e67eba43c1a59313a3835502ad58b11166b Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 13:13:32 +0100 Subject: [PATCH 020/142] Make the error reporting back to xm just a little bit less insane, and fix a missing import inside blkif. Fix the command parsing for op_device_destroy and op_device_configure -- the device IDs should be strings, to allow the user to specify devices by name as well as number. This is the second half to the fixes for bug #315. Signed-off-by: Ewan Mellor --- tools/python/xen/web/SrvBase.py | 2 +- tools/python/xen/xend/server/SrvDomain.py | 4 ++-- tools/python/xen/xend/server/blkif.py | 1 + tools/python/xen/xm/main.py | 6 ++---- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/tools/python/xen/web/SrvBase.py b/tools/python/xen/web/SrvBase.py index 11b1d48f24..59eb313b3e 100644 --- a/tools/python/xen/web/SrvBase.py +++ b/tools/python/xen/web/SrvBase.py @@ -86,7 +86,7 @@ class SrvBase(resource.Resource): except Exception, exn: log.exception("Request %s failed.", op) if req.useSxp(): - return ['xend.err', "Exception: " + str(exn)] + return ['xend.err', str(exn)] else: return "

%s

" % str(exn) diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index a5c5dbfee7..535d9323f4 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -146,13 +146,13 @@ class SrvDomain(SrvDir): def op_device_destroy(self, op, req): return self.call(self.dom.destroyDevice, [['type', 'str'], - ['dev', 'int']], + ['dev', 'str']], req) def op_device_configure(self, op, req): return self.call(self.dom.device_configure, [['config', 'sxpr'], - ['dev', 'int']], + ['dev', 'str']], req) diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index a15edf0963..d60607f0f4 100644 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -22,6 +22,7 @@ import string from xen.util import blkif from xen.xend import sxp +from xen.xend.XendError import VmError from xen.xend.server.DevController import DevController diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 11e2ff7194..54d72195bc 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -169,11 +169,9 @@ def handle_xend_error(cmd, dom, ex): if error == "Not found" and dom != None: err("Domain '%s' not found when running 'xm %s'" % (dom, cmd)) sys.exit(1) - elif error == "Exception: Device not connected": - err("Device not connected") - sys.exit(1) else: - raise ex + err(error) + sys.exit(1) ######################################################################### From 337e9007fc219683adbeb58d7c20fd80fd34083e Mon Sep 17 00:00:00 2001 From: "emellor@ewan" Date: Wed, 12 Oct 2005 13:21:06 +0100 Subject: [PATCH 021/142] Merged. From a442cd731d342fbfd989b20eeb3ae78855554673 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 16:15:02 +0100 Subject: [PATCH 022/142] Fix 64-bit compile warnings in firmware. Signed-off-by: Keir Fraser --- tools/firmware/vmxassist/gen.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tools/firmware/vmxassist/gen.c b/tools/firmware/vmxassist/gen.c index 3cdea7240f..2dcb229ee8 100644 --- a/tools/firmware/vmxassist/gen.c +++ b/tools/firmware/vmxassist/gen.c @@ -27,26 +27,26 @@ main(void) { printf("/* MACHINE GENERATED; DO NOT EDIT */\n"); printf("#define VMX_ASSIST_CTX_GS_SEL 0x%x\n", - offsetof(struct vmx_assist_context, gs_sel)); + (unsigned int)offsetof(struct vmx_assist_context, gs_sel)); printf("#define VMX_ASSIST_CTX_FS_SEL 0x%x\n", - offsetof(struct vmx_assist_context, fs_sel)); + (unsigned int)offsetof(struct vmx_assist_context, fs_sel)); printf("#define VMX_ASSIST_CTX_DS_SEL 0x%x\n", - offsetof(struct vmx_assist_context, ds_sel)); + (unsigned int)offsetof(struct vmx_assist_context, ds_sel)); printf("#define VMX_ASSIST_CTX_ES_SEL 0x%x\n", - offsetof(struct vmx_assist_context, es_sel)); + (unsigned int)offsetof(struct vmx_assist_context, es_sel)); printf("#define VMX_ASSIST_CTX_SS_SEL 0x%x\n", - offsetof(struct vmx_assist_context, ss_sel)); + (unsigned int)offsetof(struct vmx_assist_context, ss_sel)); printf("#define VMX_ASSIST_CTX_ESP 0x%x\n", - offsetof(struct vmx_assist_context, esp)); + (unsigned int)offsetof(struct vmx_assist_context, esp)); printf("#define VMX_ASSIST_CTX_EFLAGS 0x%x\n", - offsetof(struct vmx_assist_context, eflags)); + (unsigned int)offsetof(struct vmx_assist_context, eflags)); printf("#define VMX_ASSIST_CTX_CS_SEL 0x%x\n", - offsetof(struct vmx_assist_context, cs_sel)); + (unsigned int)offsetof(struct vmx_assist_context, cs_sel)); printf("#define VMX_ASSIST_CTX_EIP 0x%x\n", - offsetof(struct vmx_assist_context, eip)); + (unsigned int)offsetof(struct vmx_assist_context, eip)); printf("#define VMX_ASSIST_CTX_CR0 0x%x\n", - offsetof(struct vmx_assist_context, cr0)); + (unsigned int)offsetof(struct vmx_assist_context, cr0)); return 0; } From 523636b3b7ef8c0e4202461d56b702ccbfcbb501 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 16:34:49 +0100 Subject: [PATCH 023/142] New dom0_op to set max vcpus for a domain. Signed-off-by: Ryan Harper Signed-off-by: Keir Fraser --- tools/libxc/xc_domain.c | 9 +++ tools/libxc/xenctrl.h | 11 ++++ tools/python/xen/lowlevel/xc/xc.c | 28 +++++++++ tools/python/xen/xend/XendDomainInfo.py | 4 ++ xen/arch/ia64/xen/domain.c | 74 ++++++++--------------- xen/arch/x86/domain.c | 52 ++++++++-------- xen/arch/x86/domain_build.c | 13 ++-- xen/arch/x86/mm.c | 4 +- xen/arch/x86/vmx.c | 2 +- xen/common/dom0_ops.c | 73 +++++++++++++++++------ xen/common/domain.c | 72 +++++++--------------- xen/common/sched_sedf.c | 4 +- xen/common/schedule.c | 79 ++++++++++--------------- xen/include/public/dom0_ops.h | 8 +++ xen/include/xen/domain.h | 9 +-- xen/include/xen/sched.h | 62 +++++++++---------- 16 files changed, 268 insertions(+), 236 deletions(-) diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 5a7995d46b..2ce970962a 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -329,6 +329,15 @@ int xc_domain_memory_decrease_reservation(int xc_handle, return err; } +int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max) +{ + dom0_op_t op; + op.cmd = DOM0_MAX_VCPUS; + op.u.max_vcpus.domain = (domid_t)domid; + op.u.max_vcpus.max = max; + return do_dom0_op(xc_handle, &op); +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 7cd50df0b3..158269caf7 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -147,6 +147,17 @@ int xc_domain_dumpcore(int xc_handle, uint32_t domid, const char *corename); +/* + * This function sets the maximum number vcpus that a domian may create. + * + * @parm xc_handle a handle to an open hypervisor interface. + * @parm domid the domain id in which vcpus are to be created. + * @parm max the maximum number of vcpus that the domain may create. + * @return 0 on success, -1 on failure. + */ +int xc_domain_max_vcpus(int xc_handle, + uint32_t domid, + unsigned int max); /** * This function pauses a domain. A paused domain still exists in memory diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 8e8c9ecd03..03f4ed2415 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -93,6 +93,26 @@ static PyObject *pyxc_domain_create(PyObject *self, return PyInt_FromLong(dom); } +static PyObject *pyxc_domain_max_vcpus(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + + uint32_t dom, max; + + static char *kwd_list[] = { "dom", "max", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "ii", kwd_list, &dom, &max) ) + return NULL; + + if ( xc_domain_max_vcpus(xc->xc_handle, dom, max) != 0 ) + return PyErr_SetFromErrno(xc_error); + + Py_INCREF(zero); + return zero; +} + static PyObject *pyxc_domain_pause(PyObject *self, PyObject *args, PyObject *kwds) @@ -783,6 +803,14 @@ static PyMethodDef pyxc_methods[] = { " dom [int, 0]: Domain identifier to use (allocated if zero).\n" "Returns: [int] new domain identifier; -1 on error.\n" }, + { "domain_max_vcpus", + (PyCFunction)pyxc_domain_max_vcpus, + METH_VARARGS | METH_KEYWORDS, "\n" + "Set the maximum number of VCPUs a domain may create.\n" + " dom [int, 0]: Domain identifier to use.\n" + " max [int, 0]: New maximum number of VCPUs in domain.\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + { "domain_dumpcore", (PyCFunction)pyxc_domain_dumpcore, METH_VARARGS | METH_KEYWORDS, "\n" diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 3d008c5d3f..c4c1bd742d 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1030,6 +1030,10 @@ class XendDomainInfo: self.image.handleBootloading() xc.domain_setcpuweight(self.domid, self.info['cpu_weight']) + + # Set maximum number of vcpus in domain + xc.domain_max_vcpus(self.domid, int(self.info['vcpus'])); + # XXX Merge with configure_maxmem? m = self.image.getDomainMemory(self.info['memory_KiB']) xc.domain_setmaxmem(self.domid, m) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 4cd54a0b8c..64eda8638b 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -149,14 +149,24 @@ void startup_cpu_idle_loop(void) continue_cpu_idle_loop(); } -struct vcpu *arch_alloc_vcpu_struct(void) +struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) { - /* Per-vp stack is used here. So we need keep vcpu - * same page as per-vp stack */ - return alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER); + struct vcpu *v; + + if ((v = alloc_xenheap_pages(KERNEL_STACK_SIZE_ORDER)) == NULL) + return NULL; + + memset(v, 0, sizeof(*v)); + memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch)); + v->arch.privregs = + alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); + printf("arch_vcpu_info=%p\n", v->arch.privregs); + memset(v->arch.privregs, 0, PAGE_SIZE); + + return v; } -void arch_free_vcpu_struct(struct vcpu *v) +void free_vcpu_struct(struct vcpu *v) { free_xenheap_pages(v, KERNEL_STACK_SIZE_ORDER); } @@ -194,12 +204,6 @@ void arch_do_createdomain(struct vcpu *v) while (1); } memset(d->shared_info, 0, PAGE_SIZE); -#if 0 - d->vcpu[0].arch.privregs = - alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); - printf("arch_vcpu_info=%p\n", d->vcpu[0].arch.privregs); - memset(d->vcpu.arch.privregs, 0, PAGE_SIZE); -#endif v->vcpu_info = &(d->shared_info->vcpu_data[0]); d->max_pages = (128UL*1024*1024)/PAGE_SIZE; // 128MB default // FIXME @@ -249,13 +253,6 @@ void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) printf("arch_getdomaininfo_ctxt\n"); c->regs = *regs; c->vcpu.evtchn_vector = v->vcpu_info->arch.evtchn_vector; -#if 0 - if (c->vcpu.privregs && copy_to_user(c->vcpu.privregs, - v->vcpu_info->arch.privregs, sizeof(mapped_regs_t))) { - printk("Bad ctxt address: 0x%lx\n", c->vcpu.privregs); - return -EFAULT; - } -#endif c->shared = v->domain->shared_info->arch; } @@ -279,12 +276,7 @@ int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) vmx_setup_platform(v, c); } - else{ - v->arch.privregs = - alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); - printf("arch_vcpu_info=%p\n", v->arch.privregs); - memset(v->arch.privregs, 0, PAGE_SIZE); - } + *regs = c->regs; new_thread(v, regs->cr_iip, 0, 0); @@ -304,18 +296,6 @@ int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) return 0; } -void arch_do_boot_vcpu(struct vcpu *v) -{ - struct domain *d = v->domain; - printf("arch_do_boot_vcpu: not implemented\n"); - - d->vcpu[v->vcpu_id]->arch.privregs = - alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); - printf("arch_vcpu_info=%p\n", d->vcpu[v->vcpu_id]->arch.privregs); - memset(d->vcpu[v->vcpu_id]->arch.privregs, 0, PAGE_SIZE); - return; -} - void domain_relinquish_resources(struct domain *d) { /* FIXME */ @@ -824,12 +804,12 @@ int construct_dom0(struct domain *d, unsigned long ret, progress = 0; //printf("construct_dom0: starting\n"); - /* Sanity! */ + #ifndef CLONE_DOMAIN0 - if ( d != dom0 ) - BUG(); - if ( test_bit(_DOMF_constructed, &d->domain_flags) ) - BUG(); + /* Sanity! */ + BUG_ON(d != dom0); + BUG_ON(d->vcpu[0] == NULL); + BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags)); #endif memset(&dsi, 0, sizeof(struct domain_setup_info)); @@ -992,14 +972,8 @@ int construct_dom0(struct domain *d, printk("Dom0: 0x%lx, domain: 0x%lx\n", (u64)dom0, (u64)d); if (vmx_dom0) vmx_final_setup_domain(dom0); - else{ - d->vcpu[0]->arch.privregs = - alloc_xenheap_pages(get_order(sizeof(mapped_regs_t))); - printf("arch_vcpu_info=%p\n", d->vcpu[0]->arch.privregs); - memset(d->vcpu[0]->arch.privregs, 0, PAGE_SIZE); - } - set_bit(_DOMF_constructed, &d->domain_flags); + set_bit(_VCPUF_initialised, &v->vcpu_flags); new_thread(v, pkern_entry, 0, 0); physdev_init_dom0(d); @@ -1031,7 +1005,7 @@ int construct_domU(struct domain *d, unsigned long pkern_entry; #ifndef DOMU_AUTO_RESTART - if ( test_bit(_DOMF_constructed, &d->domain_flags) ) BUG(); + BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags)); #endif printk("*** LOADING DOMAIN %d ***\n",d->domain_id); @@ -1051,7 +1025,7 @@ int construct_domU(struct domain *d, loaddomainelfimage(d,image_start); printk("loaddomainelfimage returns\n"); - set_bit(_DOMF_constructed, &d->domain_flags); + set_bit(_VCPUF_initialised, &v->vcpu_flags); printk("calling new_thread, entry=%p\n",pkern_entry); #ifdef DOMU_AUTO_RESTART diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index f921f700ba..25302d0f5f 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -212,21 +212,35 @@ void dump_pageframe_info(struct domain *d) page->u.inuse.type_info); } -struct vcpu *arch_alloc_vcpu_struct(void) +struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) { - return xmalloc(struct vcpu); + struct vcpu *v; + + if ( (v = xmalloc(struct vcpu)) == NULL ) + return NULL; + + memset(v, 0, sizeof(*v)); + + memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch)); + v->arch.flags = TF_kernel_mode; + + if ( (v->vcpu_id = vcpu_id) != 0 ) + { + v->arch.schedule_tail = d->vcpu[0]->arch.schedule_tail; + v->arch.perdomain_ptes = + d->arch.mm_perdomain_pt + (vcpu_id << PDPT_VCPU_SHIFT); + v->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] = + l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); + } + + return v; } -/* We assume that vcpu 0 is always the last one to be freed in a - domain i.e. if v->vcpu_id == 0, the domain should be - single-processor. */ -void arch_free_vcpu_struct(struct vcpu *v) +void free_vcpu_struct(struct vcpu *v) { - struct vcpu *p; - for_each_vcpu(v->domain, p) { - if (p->next_in_list == v) - p->next_in_list = v->next_in_list; - } + BUG_ON(v->next_in_list != NULL); + if ( v->vcpu_id != 0 ) + v->domain->vcpu[v->vcpu_id - 1]->next_in_list = NULL; xfree(v); } @@ -243,8 +257,6 @@ void arch_do_createdomain(struct vcpu *v) { struct domain *d = v->domain; - v->arch.flags = TF_kernel_mode; - if ( is_idle_task(d) ) return; @@ -291,20 +303,6 @@ void arch_do_createdomain(struct vcpu *v) INIT_LIST_HEAD(&d->arch.free_shadow_frames); } -void arch_do_boot_vcpu(struct vcpu *v) -{ - struct domain *d = v->domain; - - v->arch.flags = TF_kernel_mode; - - v->arch.schedule_tail = d->vcpu[0]->arch.schedule_tail; - - v->arch.perdomain_ptes = - d->arch.mm_perdomain_pt + (v->vcpu_id << PDPT_VCPU_SHIFT); - v->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] = - l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); -} - void vcpu_migrate_cpu(struct vcpu *v, int newcpu) { if ( v->processor == newcpu ) diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 0d1795150b..bf8129a572 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -146,10 +147,9 @@ int construct_dom0(struct domain *d, struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn); /* Sanity! */ - if ( d->domain_id != 0 ) - BUG(); - if ( test_bit(_DOMF_constructed, &d->domain_flags) ) - BUG(); + BUG_ON(d->domain_id != 0); + BUG_ON(d->vcpu[0] == NULL); + BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags)); memset(&dsi, 0, sizeof(struct domain_setup_info)); dsi.image_addr = (unsigned long)image_start; @@ -559,6 +559,9 @@ int construct_dom0(struct domain *d, d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; d->shared_info->n_vcpu = num_online_cpus(); + for ( i = 1; i < d->shared_info->n_vcpu; i++ ) + (void)alloc_vcpu(d, i); + /* Set up monitor table */ update_pagetables(v); @@ -657,7 +660,7 @@ int construct_dom0(struct domain *d, init_domain_time(d); - set_bit(_DOMF_constructed, &d->domain_flags); + set_bit(_VCPUF_initialised, &v->vcpu_flags); new_thread(v, dsi.v_kernentry, vstack_end, vstartinfo_start); diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 96908204b4..a99dda64db 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -185,7 +185,7 @@ void arch_init_memory(void) * Any Xen-heap pages that we will allow to be mapped will have * their domain field set to dom_xen. */ - dom_xen = alloc_domain_struct(); + dom_xen = alloc_domain(); atomic_set(&dom_xen->refcnt, 1); dom_xen->domain_id = DOMID_XEN; @@ -194,7 +194,7 @@ void arch_init_memory(void) * This domain owns I/O pages that are within the range of the pfn_info * array. Mappings occur at the priv of the caller. */ - dom_io = alloc_domain_struct(); + dom_io = alloc_domain(); atomic_set(&dom_io->refcnt, 1); dom_io->domain_id = DOMID_IO; diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index 632a4e47b0..dd5a6b87e6 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -1674,7 +1674,7 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) store_cpu_user_regs(®s); __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS, PENDING_DEBUG_EXC_BS); - set_bit(_VCPUF_ctrl_pause, ¤t->vcpu_flags); + domain_pause_for_debugger(); do_sched_op(SCHEDOP_yield); break; diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 9964714d03..e6ffa59438 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -44,28 +44,24 @@ static void getdomaininfo(struct domain *d, dom0_getdomaininfo_t *info) struct vcpu *v; u64 cpu_time = 0; int vcpu_count = 0; - int flags = DOMFLAGS_PAUSED | DOMFLAGS_BLOCKED; + int flags = DOMFLAGS_BLOCKED; info->domain = d->domain_id; memset(&info->vcpu_to_cpu, -1, sizeof(info->vcpu_to_cpu)); memset(&info->cpumap, 0, sizeof(info->cpumap)); - + /* - * - domain is marked as paused or blocked only if all its vcpus - * are paused or blocked + * - domain is marked as blocked only if all its vcpus are blocked * - domain is marked as running if any of its vcpus is running * - only map vcpus that aren't down. Note, at some point we may * wish to demux the -1 value to indicate down vs. not-ever-booted - * */ for_each_vcpu ( d, v ) { /* only map vcpus that are up */ if ( !(test_bit(_VCPUF_down, &v->vcpu_flags)) ) info->vcpu_to_cpu[v->vcpu_id] = v->processor; info->cpumap[v->vcpu_id] = v->cpumap; - if ( !(v->vcpu_flags & VCPUF_ctrl_pause) ) - flags &= ~DOMFLAGS_PAUSED; if ( !(v->vcpu_flags & VCPUF_blocked) ) flags &= ~DOMFLAGS_BLOCKED; if ( v->vcpu_flags & VCPUF_running ) @@ -78,8 +74,9 @@ static void getdomaininfo(struct domain *d, dom0_getdomaininfo_t *info) info->n_vcpu = vcpu_count; info->flags = flags | - ((d->domain_flags & DOMF_dying) ? DOMFLAGS_DYING : 0) | - ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) | + ((d->domain_flags & DOMF_dying) ? DOMFLAGS_DYING : 0) | + ((d->domain_flags & DOMF_shutdown) ? DOMFLAGS_SHUTDOWN : 0) | + ((d->domain_flags & DOMF_ctrl_pause) ? DOMFLAGS_PAUSED : 0) | d->shutdown_code << DOMFLAGS_SHUTDOWNSHIFT; if (d->ssid != NULL) @@ -97,6 +94,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) long ret = 0; dom0_op_t curop, *op = &curop; void *ssid = NULL; /* save security ptr between pre and post/fail hooks */ + static spinlock_t dom0_lock = SPIN_LOCK_UNLOCKED; if ( !IS_PRIV(current->domain) ) return -EPERM; @@ -110,6 +108,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op) if ( acm_pre_dom0_op(op, &ssid) ) return -EACCES; + spin_lock(&dom0_lock); + switch ( op->cmd ) { @@ -150,7 +150,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) { ret = -EINVAL; if ( (d != current->domain) && - test_bit(_DOMF_constructed, &d->domain_flags) ) + test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) ) { domain_unpause_by_systemcontroller(d); ret = 0; @@ -167,17 +167,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op) domid_t dom; struct vcpu *v; unsigned int i, cnt[NR_CPUS] = { 0 }; - static spinlock_t alloc_lock = SPIN_LOCK_UNLOCKED; static domid_t rover = 0; - spin_lock(&alloc_lock); - dom = op->u.createdomain.domain; if ( (dom > 0) && (dom < DOMID_FIRST_RESERVED) ) { ret = -EINVAL; if ( !is_free_domid(dom) ) - goto alloc_out; + break; } else { @@ -191,7 +188,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) ret = -ENOMEM; if ( dom == rover ) - goto alloc_out; + break; rover = dom; } @@ -215,15 +212,51 @@ long do_dom0_op(dom0_op_t *u_dom0_op) ret = -ENOMEM; if ( (d = do_createdomain(dom, pro)) == NULL ) - goto alloc_out; + break; ret = 0; op->u.createdomain.domain = d->domain_id; copy_to_user(u_dom0_op, op, sizeof(*op)); + } + break; - alloc_out: - spin_unlock(&alloc_lock); + case DOM0_MAX_VCPUS: + { + struct domain *d; + unsigned int i, max = op->u.max_vcpus.max; + + ret = -EINVAL; + if ( max > MAX_VIRT_CPUS ) + break; + + ret = -ESRCH; + if ( (d = find_domain_by_id(op->u.max_vcpus.domain)) == NULL ) + break; + + /* + * Can only create new VCPUs while the domain is not fully constructed + * (and hence not runnable). Xen needs auditing for races before + * removing this check. + */ + ret = -EINVAL; + if ( test_bit(_VCPUF_initialised, &d->vcpu[0]->vcpu_flags) ) + goto maxvcpu_out; + + /* We cannot reduce maximum VCPUs. */ + ret = -EINVAL; + if ( (max != MAX_VIRT_CPUS) && (d->vcpu[max] != NULL) ) + goto maxvcpu_out; + + ret = -ENOMEM; + for ( i = 0; i < max; i++ ) + if ( (d->vcpu[i] == NULL) && (alloc_vcpu(d, i) == NULL) ) + goto maxvcpu_out; + + ret = 0; + + maxvcpu_out: + put_domain(d); } break; @@ -535,10 +568,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op) ret = arch_do_dom0_op(op,u_dom0_op); } + + spin_unlock(&dom0_lock); + if (!ret) acm_post_dom0_op(op, ssid); else acm_fail_dom0_op(op, ssid); + return ret; } diff --git a/xen/common/domain.c b/xen/common/domain.c index 99e4e354ee..1627c97a75 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -33,7 +33,7 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) struct domain *d, **pd; struct vcpu *v; - if ( (d = alloc_domain_struct()) == NULL ) + if ( (d = alloc_domain()) == NULL ) return NULL; v = d->vcpu[0]; @@ -52,12 +52,14 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) if ( d->domain_id == IDLE_DOMAIN_ID ) set_bit(_DOMF_idle_domain, &d->domain_flags); + else + set_bit(_DOMF_ctrl_pause, &d->domain_flags); if ( !is_idle_task(d) && ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) ) { evtchn_destroy(d); - free_domain_struct(d); + free_domain(d); return NULL; } @@ -224,11 +226,9 @@ void domain_pause_for_debugger(void) * must issue a PAUSEDOMAIN command to ensure that all execution * has ceased and guest state is committed to memory. */ + set_bit(_DOMF_ctrl_pause, &d->domain_flags); for_each_vcpu ( d, v ) - { - set_bit(_VCPUF_ctrl_pause, &v->vcpu_flags); vcpu_sleep_nosync(v); - } send_guest_virq(dom0->vcpu[0], VIRQ_DEBUGGER); } @@ -267,7 +267,7 @@ void domain_destruct(struct domain *d) free_perdomain_pt(d); free_xenheap_page(d->shared_info); - free_domain_struct(d); + free_domain(d); send_guest_virq(dom0->vcpu[0], VIRQ_DOM_EXC); } @@ -310,10 +310,11 @@ void domain_pause_by_systemcontroller(struct domain *d) { struct vcpu *v; - for_each_vcpu ( d, v ) + BUG_ON(current->domain == d); + + if ( !test_and_set_bit(_DOMF_ctrl_pause, &d->domain_flags) ) { - BUG_ON(v == current); - if ( !test_and_set_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) ) + for_each_vcpu ( d, v ) vcpu_sleep_sync(v); } } @@ -322,9 +323,9 @@ void domain_unpause_by_systemcontroller(struct domain *d) { struct vcpu *v; - for_each_vcpu ( d, v ) + if ( test_and_clear_bit(_DOMF_ctrl_pause, &d->domain_flags) ) { - if ( test_and_clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags) ) + for_each_vcpu ( d, v ) vcpu_wake(v); } } @@ -345,61 +346,32 @@ int set_info_guest(struct domain *d, dom0_setdomaininfo_t *setdomaininfo) if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) ) return -EINVAL; - if (test_bit(_DOMF_constructed, &d->domain_flags) && - !test_bit(_VCPUF_ctrl_pause, &v->vcpu_flags)) + if ( !test_bit(_DOMF_ctrl_pause, &d->domain_flags) ) return -EINVAL; if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) return -ENOMEM; - if ( copy_from_user(c, setdomaininfo->ctxt, sizeof(*c)) ) - { - rc = -EFAULT; - goto out; - } - - if ( (rc = arch_set_info_guest(v, c)) != 0 ) - goto out; + rc = -EFAULT; + if ( copy_from_user(c, setdomaininfo->ctxt, sizeof(*c)) == 0 ) + rc = arch_set_info_guest(v, c); - set_bit(_DOMF_constructed, &d->domain_flags); - - out: xfree(c); return rc; } int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) { - struct vcpu *v; + struct vcpu *v = d->vcpu[vcpuid]; int rc; - ASSERT(d->vcpu[vcpuid] == NULL); - - if ( alloc_vcpu_struct(d, vcpuid) == NULL ) - return -ENOMEM; - - v = d->vcpu[vcpuid]; - - atomic_set(&v->pausecnt, 0); - v->cpumap = CPUMAP_RUNANYWHERE; - - memcpy(&v->arch, &idle0_vcpu.arch, sizeof(v->arch)); - - arch_do_boot_vcpu(v); + BUG_ON(test_bit(_VCPUF_initialised, &v->vcpu_flags)); if ( (rc = arch_set_info_guest(v, ctxt)) != 0 ) - goto out; + return rc; sched_add_domain(v); - set_bit(_VCPUF_down, &v->vcpu_flags); - clear_bit(_VCPUF_ctrl_pause, &v->vcpu_flags); - - return 0; - - out: - arch_free_vcpu_struct(d->vcpu[vcpuid]); - d->vcpu[vcpuid] = NULL; return rc; } @@ -413,7 +385,7 @@ long do_vcpu_op(int cmd, int vcpuid, void *arg) if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) ) return -EINVAL; - if ( ((v = d->vcpu[vcpuid]) == NULL) && (cmd != VCPUOP_initialise) ) + if ( (v = d->vcpu[vcpuid]) == NULL ) return -ENOENT; switch ( cmd ) @@ -433,7 +405,9 @@ long do_vcpu_op(int cmd, int vcpuid, void *arg) } LOCK_BIGLOCK(d); - rc = (d->vcpu[vcpuid] == NULL) ? boot_vcpu(d, vcpuid, ctxt) : -EEXIST; + rc = -EEXIST; + if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + rc = boot_vcpu(d, vcpuid, ctxt); UNLOCK_BIGLOCK(d); xfree(ctxt); diff --git a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c index b6b2f83c71..9fb52e4099 100644 --- a/xen/common/sched_sedf.c +++ b/xen/common/sched_sedf.c @@ -1122,10 +1122,10 @@ static inline int should_switch(struct vcpu* cur, void sedf_wake(struct vcpu *d) { s_time_t now = NOW(); struct sedf_vcpu_info* inf = EDOM_INFO(d); - + PRINT(3, "sedf_wake was called, domain-id %i.%i\n",d->domain->domain_id, d->vcpu_id); - + if (unlikely(is_idle_task(d->domain))) return; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index c7bafd2d71..e45c7f6582 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -80,69 +80,59 @@ static struct scheduler ops; /* Per-CPU periodic timer sends an event to the currently-executing domain. */ static struct ac_timer t_timer[NR_CPUS]; -void free_domain_struct(struct domain *d) +void free_domain(struct domain *d) { int i; SCHED_OP(free_task, d); - /* vcpu 0 has to be the last one destructed. */ - for (i = MAX_VIRT_CPUS-1; i >= 0; i--) - if ( d->vcpu[i] ) - arch_free_vcpu_struct(d->vcpu[i]); + + for ( i = MAX_VIRT_CPUS-1; i >= 0; i-- ) + if ( d->vcpu[i] != NULL ) + free_vcpu_struct(d->vcpu[i]); xfree(d); } -struct vcpu *alloc_vcpu_struct( - struct domain *d, unsigned long vcpu) +struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id) { - struct vcpu *v, *vc; + struct vcpu *v; - ASSERT( d->vcpu[vcpu] == NULL ); + BUG_ON(d->vcpu[vcpu_id] != NULL); - if ( (v = arch_alloc_vcpu_struct()) == NULL ) + if ( (v = alloc_vcpu_struct(d, vcpu_id)) == NULL ) return NULL; - memset(v, 0, sizeof(*v)); - - d->vcpu[vcpu] = v; v->domain = d; - v->vcpu_id = vcpu; + v->vcpu_id = vcpu_id; + atomic_set(&v->pausecnt, 0); + v->cpumap = CPUMAP_RUNANYWHERE; + + d->vcpu[vcpu_id] = v; if ( SCHED_OP(alloc_task, v) < 0 ) - goto out; - - if ( vcpu != 0 ) { - v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id]; - - for_each_vcpu( d, vc ) - { - if ( (vc->next_in_list == NULL) || - (vc->next_in_list->vcpu_id > vcpu) ) - break; - } - v->next_in_list = vc->next_in_list; - vc->next_in_list = v; - - if (test_bit(_VCPUF_cpu_pinned, &vc->vcpu_flags)) { - v->processor = (vc->processor + 1) % num_online_cpus(); - set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags); - } else { - v->processor = (vc->processor + 1) % num_online_cpus(); - } + d->vcpu[vcpu_id] = NULL; + free_vcpu_struct(v); + return NULL; } + if ( vcpu_id == 0 ) + return v; + + v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id]; + + d->vcpu[v->vcpu_id-1]->next_in_list = v; + + v->processor = (d->vcpu[0]->processor + 1) % num_online_cpus(); + if ( test_bit(_VCPUF_cpu_pinned, &d->vcpu[0]->vcpu_flags) ) + set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags); + + set_bit(_VCPUF_down, &v->vcpu_flags); + return v; - - out: - d->vcpu[vcpu] = NULL; - arch_free_vcpu_struct(v); - - return NULL; } -struct domain *alloc_domain_struct(void) +struct domain *alloc_domain(void) { struct domain *d; @@ -151,7 +141,7 @@ struct domain *alloc_domain_struct(void) memset(d, 0, sizeof(*d)); - if ( alloc_vcpu_struct(d, 0) == NULL ) + if ( alloc_vcpu(d, 0) == NULL ) goto out; return d; @@ -177,11 +167,6 @@ void sched_add_domain(struct vcpu *v) schedule_data[v->processor].idle = v; set_bit(_VCPUF_running, &v->vcpu_flags); } - else - { - /* Must be unpaused by control software to start execution. */ - set_bit(_VCPUF_ctrl_pause, &v->vcpu_flags); - } SCHED_OP(add_task, v); TRACE_2D(TRC_SCHED_DOM_ADD, d->domain_id, v->vcpu_id); diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index d09953aab3..3d6a524781 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -387,6 +387,13 @@ typedef struct { } *memory_map; } dom0_physical_memory_map_t; +#define DOM0_MAX_VCPUS 41 +typedef struct { + domid_t domain; /* domain to be affected */ + unsigned int max; /* maximum number of vcpus */ +} dom0_max_vcpus_t; + + typedef struct { uint32_t cmd; uint32_t interface_version; /* DOM0_INTERFACE_VERSION */ @@ -422,6 +429,7 @@ typedef struct { dom0_getdomaininfolist_t getdomaininfolist; dom0_platform_quirk_t platform_quirk; dom0_physical_memory_map_t physical_memory_map; + dom0_max_vcpus_t max_vcpus; } u; } dom0_op_t; diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index cf3a192260..3baf56babd 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -2,18 +2,19 @@ #ifndef __XEN_DOMAIN_H__ #define __XEN_DOMAIN_H__ +extern int boot_vcpu( + struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt); + /* * Arch-specifics. */ -struct vcpu *arch_alloc_vcpu_struct(void); +struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id); -extern void arch_free_vcpu_struct(struct vcpu *v); +extern void free_vcpu_struct(struct vcpu *v); extern void arch_do_createdomain(struct vcpu *v); -extern void arch_do_boot_vcpu(struct vcpu *v); - extern int arch_set_info_guest( struct vcpu *v, struct vcpu_guest_context *c); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index e7b06ff4ca..61ae51c576 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -61,7 +61,8 @@ struct vcpu vcpu_info_t *vcpu_info; struct domain *domain; - struct vcpu *next_in_list; + + struct vcpu *next_in_list; struct ac_timer timer; /* one-shot timer for timeout values */ unsigned long sleep_tick; /* tick at which this vcpu started sleep */ @@ -166,11 +167,10 @@ extern struct vcpu *idle_task[NR_CPUS]; #define IDLE_DOMAIN_ID (0x7FFFU) #define is_idle_task(_d) (test_bit(_DOMF_idle_domain, &(_d)->domain_flags)) -struct vcpu *alloc_vcpu_struct(struct domain *d, - unsigned long vcpu); +struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id); -void free_domain_struct(struct domain *d); -struct domain *alloc_domain_struct(); +struct domain *alloc_domain(void); +void free_domain(struct domain *d); #define DOMAIN_DESTRUCTED (1<<31) /* assumes atomic_t is >= 32 bits */ #define put_domain(_d) \ @@ -327,13 +327,15 @@ unsigned long __hypercall_create_continuation( extern struct domain *domain_hash[DOMAIN_HASH_SIZE]; extern struct domain *domain_list; -#define for_each_domain(_d) \ - for ( (_d) = domain_list; (_d) != NULL; (_d) = (_d)->next_in_list ) +#define for_each_domain(_d) \ + for ( (_d) = domain_list; \ + (_d) != NULL; \ + (_d) = (_d)->next_in_list ) -#define for_each_vcpu(_d,_ed) \ - for ( (_ed) = (_d)->vcpu[0]; \ - (_ed) != NULL; \ - (_ed) = (_ed)->next_in_list ) +#define for_each_vcpu(_d,_v) \ + for ( (_v) = (_d)->vcpu[0]; \ + (_v) != NULL; \ + (_v) = (_v)->next_in_list ) /* * Per-VCPU flags (vcpu_flags). @@ -345,57 +347,55 @@ extern struct domain *domain_list; #define _VCPUF_fpu_dirtied 1 #define VCPUF_fpu_dirtied (1UL<<_VCPUF_fpu_dirtied) /* Domain is blocked waiting for an event. */ -#define _VCPUF_blocked 3 +#define _VCPUF_blocked 2 #define VCPUF_blocked (1UL<<_VCPUF_blocked) - /* Domain is paused by controller software. */ -#define _VCPUF_ctrl_pause 4 -#define VCPUF_ctrl_pause (1UL<<_VCPUF_ctrl_pause) /* Currently running on a CPU? */ -#define _VCPUF_running 5 +#define _VCPUF_running 3 #define VCPUF_running (1UL<<_VCPUF_running) /* Disables auto-migration between CPUs. */ -#define _VCPUF_cpu_pinned 6 +#define _VCPUF_cpu_pinned 4 #define VCPUF_cpu_pinned (1UL<<_VCPUF_cpu_pinned) /* Domain migrated between CPUs. */ -#define _VCPUF_cpu_migrated 7 +#define _VCPUF_cpu_migrated 5 #define VCPUF_cpu_migrated (1UL<<_VCPUF_cpu_migrated) /* Initialization completed. */ -#define _VCPUF_initialised 8 +#define _VCPUF_initialised 6 #define VCPUF_initialised (1UL<<_VCPUF_initialised) /* VCPU is not-runnable */ -#define _VCPUF_down 9 +#define _VCPUF_down 7 #define VCPUF_down (1UL<<_VCPUF_down) /* * Per-domain flags (domain_flags). */ - /* Has the guest OS been fully built yet? */ -#define _DOMF_constructed 0 -#define DOMF_constructed (1UL<<_DOMF_constructed) /* Is this one of the per-CPU idle domains? */ -#define _DOMF_idle_domain 1 +#define _DOMF_idle_domain 0 #define DOMF_idle_domain (1UL<<_DOMF_idle_domain) /* Is this domain privileged? */ -#define _DOMF_privileged 2 +#define _DOMF_privileged 1 #define DOMF_privileged (1UL<<_DOMF_privileged) /* May this domain do IO to physical devices? */ -#define _DOMF_physdev_access 3 +#define _DOMF_physdev_access 2 #define DOMF_physdev_access (1UL<<_DOMF_physdev_access) /* Guest shut itself down for some reason. */ -#define _DOMF_shutdown 4 +#define _DOMF_shutdown 3 #define DOMF_shutdown (1UL<<_DOMF_shutdown) /* Guest is in process of shutting itself down (becomes DOMF_shutdown). */ -#define _DOMF_shuttingdown 5 +#define _DOMF_shuttingdown 4 #define DOMF_shuttingdown (1UL<<_DOMF_shuttingdown) /* Death rattle. */ -#define _DOMF_dying 6 +#define _DOMF_dying 5 #define DOMF_dying (1UL<<_DOMF_dying) + /* Domain is paused by controller software. */ +#define _DOMF_ctrl_pause 6 +#define DOMF_ctrl_pause (1UL<<_DOMF_ctrl_pause) static inline int domain_runnable(struct vcpu *v) { return ( (atomic_read(&v->pausecnt) == 0) && - !(v->vcpu_flags & (VCPUF_blocked|VCPUF_ctrl_pause|VCPUF_down)) && - !(v->domain->domain_flags & (DOMF_shutdown|DOMF_shuttingdown)) ); + !(v->vcpu_flags & (VCPUF_blocked|VCPUF_down)) && + !(v->domain->domain_flags & + (DOMF_shutdown|DOMF_shuttingdown|DOMF_ctrl_pause)) ); } void vcpu_pause(struct vcpu *v); From be8d1a5fd56230af34fa75fda693f9dd92b8b23e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 16:42:35 +0100 Subject: [PATCH 024/142] Fix error output to stderr in xc_linux_build. Signed-off-by: Scott Parish --- tools/libxc/xc_linux_build.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 9ed257edf3..5cdb568bc0 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -502,7 +502,7 @@ static int setup_guest(int xc_handle, if ( ((v_end - dsi.v_start)>>PAGE_SHIFT) > nr_pages ) { - printf("Initial guest OS requires too much space\n" + PERROR("Initial guest OS requires too much space\n" "(%luMB is greater than %luMB limit)\n", (v_end-dsi.v_start)>>20, nr_pages>>(20-PAGE_SHIFT)); goto error_out; From 5677e95f23bc4a643e1c9c9381601bb28a5e405d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 17:00:29 +0100 Subject: [PATCH 025/142] Keir moved barriers, Competence questions are raised: Correctness withers. Signed-off-by: Rusty Russell --- .../drivers/xen/xenbus/xenbus_comms.c | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c index a4842df4af..6a6af390ec 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c @@ -130,7 +130,7 @@ int xb_write(const void *data, unsigned len) wait_event_interruptible(xb_waitq, output_avail(out)); - mb(); + /* Make local copy of header to check for sanity. */ h = *out; if (!check_buffer(&h)) return -EIO; @@ -140,10 +140,20 @@ int xb_write(const void *data, unsigned len) continue; if (avail > len) avail = len; + + /* Make sure we read header before we write data + * (implied by data-dependency, but let's play safe). */ + mb(); + memcpy(dst, data, avail); data += avail; len -= avail; + + /* Other side must not see new header until data is there. */ + wmb(); update_output_chunk(out, avail); + + /* This implies mb() before other side sees interrupt. */ notify_remote_via_evtchn(xen_start_info->store_evtchn); } while (len != 0); @@ -171,7 +181,6 @@ int xb_read(void *data, unsigned len) wait_event_interruptible(xb_waitq, xs_input_avail()); - mb(); h = *in; if (!check_buffer(&h)) return -EIO; @@ -183,13 +192,21 @@ int xb_read(void *data, unsigned len) avail = len; was_full = !output_avail(&h); + /* We must read header before we read data. */ + rmb(); + memcpy(data, src, avail); data += avail; len -= avail; + + /* Other side must not see free space until we've copied out */ + mb(); + update_input_chunk(in, avail); pr_debug("Finished read of %i bytes (%i to go)\n", avail, len); /* If it was full, tell them we've taken some. */ if (was_full) + /* Implies mb(): they will see new header. */ notify_remote_via_evtchn(xen_start_info->store_evtchn); } From dc8499433a8f7dcbd38e75352a64a54128d592c0 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 17:01:38 +0100 Subject: [PATCH 026/142] Refactor domain/vcpu allocation to be more separated. Signed-off-by: Keir Fraser --- xen/arch/x86/domain_build.c | 2 +- xen/common/dom0_ops.c | 12 +++++++++--- xen/common/domain.c | 19 +++++++++---------- xen/common/schedule.c | 35 ++++++++++++----------------------- xen/include/xen/sched.h | 3 ++- 5 files changed, 33 insertions(+), 38 deletions(-) diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index bf8129a572..69b0ddd58b 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -560,7 +560,7 @@ int construct_dom0(struct domain *d, d->shared_info->n_vcpu = num_online_cpus(); for ( i = 1; i < d->shared_info->n_vcpu; i++ ) - (void)alloc_vcpu(d, i); + (void)alloc_vcpu(d, i, i % num_online_cpus()); /* Set up monitor table */ update_pagetables(v); diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index e6ffa59438..458255d3db 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -224,7 +224,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_MAX_VCPUS: { struct domain *d; - unsigned int i, max = op->u.max_vcpus.max; + unsigned int i, max = op->u.max_vcpus.max, cpu; ret = -EINVAL; if ( max > MAX_VIRT_CPUS ) @@ -250,8 +250,14 @@ long do_dom0_op(dom0_op_t *u_dom0_op) ret = -ENOMEM; for ( i = 0; i < max; i++ ) - if ( (d->vcpu[i] == NULL) && (alloc_vcpu(d, i) == NULL) ) - goto maxvcpu_out; + { + if ( d->vcpu[i] == NULL ) + { + cpu = (d->vcpu[i-1]->processor + 1) % num_online_cpus(); + if ( alloc_vcpu(d, i, cpu) == NULL ) + goto maxvcpu_out; + } + } ret = 0; diff --git a/xen/common/domain.c b/xen/common/domain.c index 1627c97a75..96c3b0a083 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -36,16 +36,11 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) if ( (d = alloc_domain()) == NULL ) return NULL; - v = d->vcpu[0]; + d->domain_id = dom_id; atomic_set(&d->refcnt, 1); - atomic_set(&v->pausecnt, 0); - - d->domain_id = dom_id; - v->processor = cpu; spin_lock_init(&d->big_lock); - spin_lock_init(&d->page_alloc_lock); INIT_LIST_HEAD(&d->page_list); INIT_LIST_HEAD(&d->xenpage_list); @@ -63,10 +58,16 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) return NULL; } + if ( (v = alloc_vcpu(d, 0, cpu)) == NULL ) + { + grant_table_destroy(d); + evtchn_destroy(d); + free_domain(d); + return NULL; + } + arch_do_createdomain(v); - sched_add_domain(v); - if ( !is_idle_task(d) ) { write_lock(&domlist_lock); @@ -370,8 +371,6 @@ int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) if ( (rc = arch_set_info_guest(v, ctxt)) != 0 ) return rc; - sched_add_domain(v); - return rc; } diff --git a/xen/common/schedule.c b/xen/common/schedule.c index e45c7f6582..4c58a8d68e 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -93,7 +93,8 @@ void free_domain(struct domain *d) xfree(d); } -struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id) +struct vcpu *alloc_vcpu( + struct domain *d, unsigned int vcpu_id, unsigned int cpu_id) { struct vcpu *v; @@ -104,6 +105,7 @@ struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id) v->domain = d; v->vcpu_id = vcpu_id; + v->processor = cpu_id; atomic_set(&v->pausecnt, 0); v->cpumap = CPUMAP_RUNANYWHERE; @@ -116,18 +118,14 @@ struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id) return NULL; } - if ( vcpu_id == 0 ) - return v; + sched_add_domain(v); - v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id]; - - d->vcpu[v->vcpu_id-1]->next_in_list = v; - - v->processor = (d->vcpu[0]->processor + 1) % num_online_cpus(); - if ( test_bit(_VCPUF_cpu_pinned, &d->vcpu[0]->vcpu_flags) ) - set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags); - - set_bit(_VCPUF_down, &v->vcpu_flags); + if ( vcpu_id != 0 ) + { + v->vcpu_info = &d->shared_info->vcpu_data[vcpu_id]; + d->vcpu[v->vcpu_id-1]->next_in_list = v; + set_bit(_VCPUF_down, &v->vcpu_flags); + } return v; } @@ -136,19 +134,10 @@ struct domain *alloc_domain(void) { struct domain *d; - if ( (d = xmalloc(struct domain)) == NULL ) - return NULL; - - memset(d, 0, sizeof(*d)); - - if ( alloc_vcpu(d, 0) == NULL ) - goto out; + if ( (d = xmalloc(struct domain)) != NULL ) + memset(d, 0, sizeof(*d)); return d; - - out: - xfree(d); - return NULL; } /* diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 61ae51c576..6f8a43d384 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -167,7 +167,8 @@ extern struct vcpu *idle_task[NR_CPUS]; #define IDLE_DOMAIN_ID (0x7FFFU) #define is_idle_task(_d) (test_bit(_DOMF_idle_domain, &(_d)->domain_flags)) -struct vcpu *alloc_vcpu(struct domain *d, unsigned int vcpu_id); +struct vcpu *alloc_vcpu( + struct domain *d, unsigned int vcpu_id, unsigned int cpu_id); struct domain *alloc_domain(void); void free_domain(struct domain *d); From 98adab9284a3687a705d6e94e1d9852b41ce6c24 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 17:04:11 +0100 Subject: [PATCH 027/142] Add a option for enabling ne2000 NIC device model Signed-off-by: Yan Li Signed-off-by: Xiaofeng Ling Signed-off-by: Edwin Zhai --- tools/examples/xmexample.vmx | 5 +++++ tools/ioemu/hw/pc.c | 6 +++--- tools/ioemu/vl.c | 12 ++++++------ tools/ioemu/vl.h | 2 +- tools/python/xen/xend/image.py | 5 +++-- tools/python/xen/xm/create.py | 6 +++++- 6 files changed, 23 insertions(+), 13 deletions(-) diff --git a/tools/examples/xmexample.vmx b/tools/examples/xmexample.vmx index 89f934ddd9..a15ad321a9 100644 --- a/tools/examples/xmexample.vmx +++ b/tools/examples/xmexample.vmx @@ -117,6 +117,11 @@ vncviewer=1 #nographic=0 +#---------------------------------------------------------------------------- +# enable ne2000, default = 0(use pcnet) +ne2000=0 + + #----------------------------------------------------------------------------- # enable audio support #enable-audio=1 diff --git a/tools/ioemu/hw/pc.c b/tools/ioemu/hw/pc.c index 92464250eb..97db4aaa94 100644 --- a/tools/ioemu/hw/pc.c +++ b/tools/ioemu/hw/pc.c @@ -541,10 +541,10 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, if (pci_enabled) { for(i = 0; i < nb_nics; i++) { - if (nic_pcnet) - pci_pcnet_init(pci_bus, &nd_table[i]); + if (nic_ne2000) + pci_ne2000_init(pci_bus, &nd_table[i]); else - pci_ne2000_init(pci_bus, &nd_table[i]); + pci_pcnet_init(pci_bus, &nd_table[i]); } pci_piix3_ide_init(pci_bus, bs_table); #ifdef APIC_SUPPORT diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index a8e04da269..56cf52314e 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -125,7 +125,7 @@ QEMUTimer *gui_timer; QEMUTimer *polling_timer; int vm_running; int audio_enabled = 0; -int nic_pcnet = 1; +int nic_ne2000 = 0; int vcpus = 1; int sb16_enabled = 1; int adlib_enabled = 1; @@ -2130,7 +2130,7 @@ void help(void) "-prep Simulate a PREP system (default is PowerMAC)\n" "-g WxH[xDEPTH] Set the initial VGA graphic mode\n" #endif - "-nic-pcnet simulate an AMD PC-Net PCI ethernet adaptor\n" + "-nic-ne2000 simulate an Realtek ne2k PCI ethernet adaptor\n" "\n" "Network options:\n" "-nics n simulate 'n' network cards [default=1]\n" @@ -2247,7 +2247,7 @@ enum { QEMU_OPTION_no_code_copy, QEMU_OPTION_vcpus, QEMU_OPTION_pci, - QEMU_OPTION_nic_pcnet, + QEMU_OPTION_nic_ne2000, QEMU_OPTION_isa, QEMU_OPTION_prep, QEMU_OPTION_k, @@ -2334,7 +2334,7 @@ const QEMUOption qemu_options[] = { /* temporary options */ { "pci", 0, QEMU_OPTION_pci }, - { "nic-pcnet", 0, QEMU_OPTION_nic_pcnet }, + { "nic-ne2000", 0, QEMU_OPTION_nic_ne2000 }, { "cirrusvga", 0, QEMU_OPTION_cirrusvga }, { "vgaacc", HAS_ARG, QEMU_OPTION_vgaacc }, { NULL }, @@ -2839,8 +2839,8 @@ int main(int argc, char **argv) case QEMU_OPTION_pci: pci_enabled = 1; break; - case QEMU_OPTION_nic_pcnet: - nic_pcnet = 1; + case QEMU_OPTION_nic_ne2000: + nic_ne2000 = 1; break; case QEMU_OPTION_isa: pci_enabled = 0; diff --git a/tools/ioemu/vl.h b/tools/ioemu/vl.h index 26f562f913..c26409c30f 100644 --- a/tools/ioemu/vl.h +++ b/tools/ioemu/vl.h @@ -602,7 +602,7 @@ void pci_ne2000_init(PCIBus *bus, NetDriverState *nd); /* pcnet.c */ -extern int nic_pcnet; +extern int nic_ne2000; void pci_pcnet_init(PCIBus *bus, NetDriverState *nd); diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 9ad3d29f00..16208786a5 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -257,7 +257,7 @@ class VmxImageHandler(ImageHandler): # Return a list of cmd line args to the device models based on the # xm config file def parseDeviceModelArgs(self, imageConfig, deviceConfig): - dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', + dmargs = [ 'cdrom', 'boot', 'fda', 'fdb', 'ne2000', 'localtime', 'serial', 'stdvga', 'isa', 'vcpus' ] ret = [] for a in dmargs: @@ -265,9 +265,10 @@ class VmxImageHandler(ImageHandler): # python doesn't allow '-' in variable names if a == 'stdvga': a = 'std-vga' + if a == 'ne2000': a = 'nic-ne2000' # Handle booleans gracefully - if a in ['localtime', 'std-vga', 'isa']: + if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000']: if v != None: v = int(v) log.debug("args: %s, val: %s" % (a,v)) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 5da1acc3da..e506fcc9b6 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -364,6 +364,10 @@ gopts.var('nographic', val='no|yes', fn=set_bool, default=0, use="Should device models use graphics?") +gopts.var('ne2000', val='no|yes', + fn=set_bool, default=0, + use="Should device models use ne2000?") + gopts.var('vnc', val='', fn=set_value, default=None, use="""Should the device model use VNC?""") @@ -540,7 +544,7 @@ def configure_vmx(opts, config_image, vals): """ args = [ 'memmap', 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb', 'localtime', 'serial', 'macaddr', 'stdvga', - 'isa', 'nographic', 'vnc', 'vncviewer', 'sdl', 'display'] + 'isa', 'nographic', 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000'] for a in args: if (vals.__dict__[a]): config_image.append([a, vals.__dict__[a]]) From a54918631e149cc4af436a4cfab0f72edd04181d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 18:18:43 +0100 Subject: [PATCH 028/142] Fix xsls build dependency. Signed-off-by: Keir Fraser --- tools/xenstore/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index 453f1abeb7..efae68ae3e 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -40,8 +40,8 @@ $(CLIENTS): xenstore-%: xenstore_%.o $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c $(COMPILE.c) -DCLIENT_$(*F) -o $@ $< -xsls: xsls.o - $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@ +xsls: xsls.o libxenstore.so + $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@ xenstored_test: xenstored_core_test.o xenstored_watch_test.o xenstored_domain_test.o xenstored_transaction_test.o xs_lib.o talloc_test.o fake_libxc.o utils.o tdb.o $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@ From 3b83e00b150c901d768eab0ef63a581b41bd2def Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 18:25:40 +0100 Subject: [PATCH 029/142] Change xenstore-domain messaging protocol to match what we use for other inter-domain comms (power-of-two-sized rings, and free-running indexes). The interface is defined in the spirit of the console protocol, so maybe some chance of merging them together later? Signed-off-by: Keir Fraser --- .../drivers/xen/xenbus/xenbus_comms.c | 143 +++++----------- tools/xenstore/xenstored_core.c | 2 +- tools/xenstore/xenstored_domain.c | 160 +++++++----------- tools/xenstore/xs_test.c | 129 ++++++-------- xen/include/public/io/xs_wire.h | 11 ++ 5 files changed, 163 insertions(+), 282 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c index 6a6af390ec..e3863a2c79 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c @@ -33,164 +33,114 @@ #include #include #include +#include #include "xenbus_comms.h" -#define RINGBUF_DATASIZE ((PAGE_SIZE / 2) - sizeof(struct ringbuf_head)) -struct ringbuf_head -{ - u32 write; /* Next place to write to */ - u32 read; /* Next place to read from */ - u8 flags; - char buf[0]; -} __attribute__((packed)); - static int xenbus_irq; DECLARE_WAIT_QUEUE_HEAD(xb_waitq); -static inline struct ringbuf_head *outbuf(void) +static inline struct xenstore_domain_interface *xenstore_domain_interface(void) { return mfn_to_virt(xen_start_info->store_mfn); } -static inline struct ringbuf_head *inbuf(void) -{ - return mfn_to_virt(xen_start_info->store_mfn) + PAGE_SIZE/2; -} - static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs) { wake_up(&xb_waitq); return IRQ_HANDLED; } -static int check_buffer(const struct ringbuf_head *h) +static int check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) { - return (h->write < RINGBUF_DATASIZE && h->read < RINGBUF_DATASIZE); + return ((prod - cons) <= XENSTORE_RING_SIZE); } -/* We can't fill last byte: would look like empty buffer. */ -static void *get_output_chunk(const struct ringbuf_head *h, - void *buf, u32 *len) +static void *get_output_chunk(XENSTORE_RING_IDX cons, + XENSTORE_RING_IDX prod, + char *buf, uint32_t *len) { - u32 read_mark; - - if (h->read == 0) - read_mark = RINGBUF_DATASIZE - 1; - else - read_mark = h->read - 1; - - /* Here to the end of buffer, unless they haven't read some out. */ - *len = RINGBUF_DATASIZE - h->write; - if (read_mark >= h->write) - *len = read_mark - h->write; - return buf + h->write; + *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod); + if ((XENSTORE_RING_SIZE - (prod - cons)) < *len) + *len = XENSTORE_RING_SIZE - (prod - cons); + return buf + MASK_XENSTORE_IDX(prod); } -static const void *get_input_chunk(const struct ringbuf_head *h, - const void *buf, u32 *len) +static const void *get_input_chunk(XENSTORE_RING_IDX cons, + XENSTORE_RING_IDX prod, + const char *buf, uint32_t *len) { - /* Here to the end of buffer, unless they haven't written some. */ - *len = RINGBUF_DATASIZE - h->read; - if (h->write >= h->read) - *len = h->write - h->read; - return buf + h->read; -} - -static void update_output_chunk(struct ringbuf_head *h, u32 len) -{ - h->write += len; - if (h->write == RINGBUF_DATASIZE) - h->write = 0; -} - -static void update_input_chunk(struct ringbuf_head *h, u32 len) -{ - h->read += len; - if (h->read == RINGBUF_DATASIZE) - h->read = 0; -} - -static int output_avail(struct ringbuf_head *out) -{ - unsigned int avail; - - get_output_chunk(out, out->buf, &avail); - return avail != 0; + *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons); + if ((prod - cons) < *len) + *len = prod - cons; + return buf + MASK_XENSTORE_IDX(cons); } int xb_write(const void *data, unsigned len) { - struct ringbuf_head h; - struct ringbuf_head *out = outbuf(); + struct xenstore_domain_interface *intf = xenstore_domain_interface(); + XENSTORE_RING_IDX cons, prod; - do { + while (len != 0) { void *dst; unsigned int avail; - wait_event_interruptible(xb_waitq, output_avail(out)); + wait_event_interruptible(xb_waitq, + (intf->req_prod - intf->req_cons) != + XENSTORE_RING_SIZE); - /* Make local copy of header to check for sanity. */ - h = *out; - if (!check_buffer(&h)) + /* Read indexes, then verify. */ + cons = intf->req_cons; + prod = intf->req_prod; + mb(); + if (!check_indexes(cons, prod)) return -EIO; - dst = get_output_chunk(&h, out->buf, &avail); + dst = get_output_chunk(cons, prod, intf->req, &avail); if (avail == 0) continue; if (avail > len) avail = len; - /* Make sure we read header before we write data - * (implied by data-dependency, but let's play safe). */ - mb(); - memcpy(dst, data, avail); data += avail; len -= avail; /* Other side must not see new header until data is there. */ wmb(); - update_output_chunk(out, avail); + intf->req_prod += avail; /* This implies mb() before other side sees interrupt. */ notify_remote_via_evtchn(xen_start_info->store_evtchn); - } while (len != 0); + } return 0; } -int xs_input_avail(void) -{ - unsigned int avail; - struct ringbuf_head *in = inbuf(); - - get_input_chunk(in, in->buf, &avail); - return avail != 0; -} - int xb_read(void *data, unsigned len) { - struct ringbuf_head h; - struct ringbuf_head *in = inbuf(); - int was_full; + struct xenstore_domain_interface *intf = xenstore_domain_interface(); + XENSTORE_RING_IDX cons, prod; while (len != 0) { unsigned int avail; const char *src; - wait_event_interruptible(xb_waitq, xs_input_avail()); + wait_event_interruptible(xb_waitq, + intf->rsp_cons != intf->rsp_prod); - h = *in; - if (!check_buffer(&h)) + /* Read indexes, then verify. */ + cons = intf->rsp_cons; + prod = intf->rsp_prod; + mb(); + if (!check_indexes(cons, prod)) return -EIO; - src = get_input_chunk(&h, in->buf, &avail); + src = get_input_chunk(cons, prod, intf->rsp, &avail); if (avail == 0) continue; if (avail > len) avail = len; - was_full = !output_avail(&h); /* We must read header before we read data. */ rmb(); @@ -201,13 +151,12 @@ int xb_read(void *data, unsigned len) /* Other side must not see free space until we've copied out */ mb(); + intf->rsp_cons += avail; - update_input_chunk(in, avail); pr_debug("Finished read of %i bytes (%i to go)\n", avail, len); - /* If it was full, tell them we've taken some. */ - if (was_full) - /* Implies mb(): they will see new header. */ - notify_remote_via_evtchn(xen_start_info->store_evtchn); + + /* Implies mb(): they will see new header. */ + notify_remote_via_evtchn(xen_start_info->store_evtchn); } return 0; diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index baa78bd1a3..3fbad0728d 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -1586,7 +1586,7 @@ int main(int argc, char *argv[]) goto more; } - if (domain_can_write(i)) { + if (domain_can_write(i) && !list_empty(&i->out_list)) { handle_output(i); goto more; } diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index d9c45507c7..74558b1ec9 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -42,7 +42,6 @@ static int *xc_handle; static int eventchn_fd; static int virq_port; -static unsigned int ringbuf_datasize; struct domain { @@ -66,10 +65,7 @@ struct domain char *path; /* Shared page. */ - void *page; - - /* Input and output ringbuffer heads. */ - struct ringbuf_head *input, *output; + struct xenstore_domain_interface *interface; /* The connection associated with this. */ struct connection *conn; @@ -80,14 +76,6 @@ struct domain static LIST_HEAD(domains); -struct ringbuf_head -{ - uint32_t write; /* Next place to write to */ - uint32_t read; /* Next place to read from */ - uint8_t flags; - char buf[0]; -} __attribute__((packed)); - #ifndef TESTING static void evtchn_notify(int port) { @@ -100,91 +88,57 @@ extern void evtchn_notify(int port); #endif /* FIXME: Mark connection as broken (close it?) when this happens. */ -static bool check_buffer(const struct ringbuf_head *h) +static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) { - return (h->write < ringbuf_datasize && h->read < ringbuf_datasize); + return ((prod - cons) <= XENSTORE_RING_SIZE); } -/* We can't fill last byte: would look like empty buffer. */ -static void *get_output_chunk(const struct ringbuf_head *h, - void *buf, uint32_t *len) +static void *get_output_chunk(XENSTORE_RING_IDX cons, + XENSTORE_RING_IDX prod, + char *buf, uint32_t *len) { - uint32_t read_mark; - - if (h->read == 0) - read_mark = ringbuf_datasize - 1; - else - read_mark = h->read - 1; - - /* Here to the end of buffer, unless they haven't read some out. */ - *len = ringbuf_datasize - h->write; - if (read_mark >= h->write) - *len = read_mark - h->write; - return buf + h->write; + *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod); + if ((XENSTORE_RING_SIZE - (prod - cons)) < *len) + *len = XENSTORE_RING_SIZE - (prod - cons); + return buf + MASK_XENSTORE_IDX(prod); } -static const void *get_input_chunk(const struct ringbuf_head *h, - const void *buf, uint32_t *len) +static const void *get_input_chunk(XENSTORE_RING_IDX cons, + XENSTORE_RING_IDX prod, + const char *buf, uint32_t *len) { - /* Here to the end of buffer, unless they haven't written some. */ - *len = ringbuf_datasize - h->read; - if (h->write >= h->read) - *len = h->write - h->read; - return buf + h->read; -} - -static void update_output_chunk(struct ringbuf_head *h, uint32_t len) -{ - h->write += len; - if (h->write == ringbuf_datasize) - h->write = 0; -} - -static void update_input_chunk(struct ringbuf_head *h, uint32_t len) -{ - h->read += len; - if (h->read == ringbuf_datasize) - h->read = 0; -} - -static bool buffer_has_input(const struct ringbuf_head *h) -{ - uint32_t len; - - get_input_chunk(h, NULL, &len); - return (len != 0); -} - -static bool buffer_has_output_room(const struct ringbuf_head *h) -{ - uint32_t len; - - get_output_chunk(h, NULL, &len); - return (len != 0); + *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons); + if ((prod - cons) < *len) + *len = prod - cons; + return buf + MASK_XENSTORE_IDX(cons); } static int writechn(struct connection *conn, const void *data, unsigned int len) { uint32_t avail; void *dest; - struct ringbuf_head h; + struct xenstore_domain_interface *intf = conn->domain->interface; + XENSTORE_RING_IDX cons, prod; - /* Must read head once, and before anything else, and verified. */ - h = *conn->domain->output; + /* Must read indexes once, and before anything else, and verified. */ + cons = intf->rsp_cons; + prod = intf->rsp_prod; mb(); - if (!check_buffer(&h)) { + if (!check_indexes(cons, prod)) { errno = EIO; return -1; } - dest = get_output_chunk(&h, conn->domain->output->buf, &avail); + dest = get_output_chunk(cons, prod, intf->rsp, &avail); if (avail < len) len = avail; memcpy(dest, data, len); mb(); - update_output_chunk(conn->domain->output, len); + intf->rsp_prod += len; + evtchn_notify(conn->domain->port); + return len; } @@ -192,32 +146,29 @@ static int readchn(struct connection *conn, void *data, unsigned int len) { uint32_t avail; const void *src; - struct ringbuf_head h; - bool was_full; + struct xenstore_domain_interface *intf = conn->domain->interface; + XENSTORE_RING_IDX cons, prod; - /* Must read head once, and before anything else, and verified. */ - h = *conn->domain->input; + /* Must read indexes once, and before anything else, and verified. */ + cons = intf->req_cons; + prod = intf->req_prod; mb(); - if (!check_buffer(&h)) { + if (!check_indexes(cons, prod)) { errno = EIO; return -1; } - src = get_input_chunk(&h, conn->domain->input->buf, &avail); + src = get_input_chunk(cons, prod, intf->req, &avail); if (avail < len) len = avail; - was_full = !buffer_has_output_room(&h); memcpy(data, src, len); mb(); - update_input_chunk(conn->domain->input, len); - /* FIXME: Probably not neccessary. */ - mb(); + intf->req_cons += len; + + evtchn_notify(conn->domain->port); - /* If it was full, tell them we've taken some. */ - if (was_full) - evtchn_notify(conn->domain->port); return len; } @@ -234,8 +185,8 @@ static int destroy_domain(void *_domain) eprintf("> Unbinding port %i failed!\n", domain->port); } - if (domain->page) - munmap(domain->page, getpagesize()); + if (domain->interface) + munmap(domain->interface, getpagesize()); return 0; } @@ -285,13 +236,14 @@ void handle_event(void) bool domain_can_read(struct connection *conn) { - return buffer_has_input(conn->domain->input); + struct xenstore_domain_interface *intf = conn->domain->interface; + return (intf->req_cons != intf->req_prod); } bool domain_can_write(struct connection *conn) { - return (!list_empty(&conn->out_list) && - buffer_has_output_room(conn->domain->output)); + struct xenstore_domain_interface *intf = conn->domain->interface; + return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE); } static struct domain *new_domain(void *context, unsigned int domid, @@ -307,20 +259,15 @@ static struct domain *new_domain(void *context, unsigned int domid, domain->shutdown = 0; domain->domid = domid; domain->path = talloc_strdup(domain, path); - domain->page = xc_map_foreign_range(*xc_handle, domain->domid, - getpagesize(), - PROT_READ|PROT_WRITE, - mfn); - if (!domain->page) + domain->interface = xc_map_foreign_range( + *xc_handle, domain->domid, + getpagesize(), PROT_READ|PROT_WRITE, mfn); + if (!domain->interface) return NULL; list_add(&domain->list, &domains); talloc_set_destructor(domain, destroy_domain); - /* One in each half of page. */ - domain->input = domain->page; - domain->output = domain->page + getpagesize()/2; - /* Tell kernel we're interested in this event. */ bind.remote_domain = domid; bind.remote_port = port; @@ -504,9 +451,6 @@ int domain_init(void) struct ioctl_evtchn_bind_virq bind; int rc; - /* The size of the ringbuffer: half a page minus head structure. */ - ringbuf_datasize = getpagesize() / 2 - sizeof(struct ringbuf_head); - xc_handle = talloc(talloc_autofree_context(), int); if (!xc_handle) barf_perror("Failed to allocate domain handle"); @@ -548,3 +492,13 @@ int domain_init(void) return eventchn_fd; } + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff --git a/tools/xenstore/xs_test.c b/tools/xenstore/xs_test.c index 1f59df6873..9c2ae92568 100644 --- a/tools/xenstore/xs_test.c +++ b/tools/xenstore/xs_test.c @@ -50,72 +50,33 @@ static bool readonly = false; static bool print_input = false; static unsigned int linenum = 0; -struct ringbuf_head -{ - uint32_t write; /* Next place to write to */ - uint32_t read; /* Next place to read from */ - uint8_t flags; - char buf[0]; -} __attribute__((packed)); - -static struct ringbuf_head *out, *in; -static unsigned int ringbuf_datasize; static int daemon_pid; +static struct xenstore_domain_interface *interface; /* FIXME: Mark connection as broken (close it?) when this happens. */ -static bool check_buffer(const struct ringbuf_head *h) +static bool check_indexes(XENSTORE_RING_IDX cons, XENSTORE_RING_IDX prod) { - return (h->write < ringbuf_datasize && h->read < ringbuf_datasize); + return ((prod - cons) <= XENSTORE_RING_SIZE); } -/* We can't fill last byte: would look like empty buffer. */ -static void *get_output_chunk(const struct ringbuf_head *h, - void *buf, uint32_t *len) +static void *get_output_chunk(XENSTORE_RING_IDX cons, + XENSTORE_RING_IDX prod, + char *buf, uint32_t *len) { - uint32_t read_mark; - - if (h->read == 0) - read_mark = ringbuf_datasize - 1; - else - read_mark = h->read - 1; - - /* Here to the end of buffer, unless they haven't read some out. */ - *len = ringbuf_datasize - h->write; - if (read_mark >= h->write) - *len = read_mark - h->write; - return buf + h->write; + *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(prod); + if ((XENSTORE_RING_SIZE - (prod - cons)) < *len) + *len = XENSTORE_RING_SIZE - (prod - cons); + return buf + MASK_XENSTORE_IDX(prod); } -static const void *get_input_chunk(const struct ringbuf_head *h, - const void *buf, uint32_t *len) +static const void *get_input_chunk(XENSTORE_RING_IDX cons, + XENSTORE_RING_IDX prod, + const char *buf, uint32_t *len) { - /* Here to the end of buffer, unless they haven't written some. */ - *len = ringbuf_datasize - h->read; - if (h->write >= h->read) - *len = h->write - h->read; - return buf + h->read; -} - -static int output_avail(struct ringbuf_head *out) -{ - unsigned int avail; - - get_output_chunk(out, out->buf, &avail); - return avail != 0; -} - -static void update_output_chunk(struct ringbuf_head *h, uint32_t len) -{ - h->write += len; - if (h->write == ringbuf_datasize) - h->write = 0; -} - -static void update_input_chunk(struct ringbuf_head *h, uint32_t len) -{ - h->read += len; - if (h->read == ringbuf_datasize) - h->read = 0; + *len = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(cons); + if ((prod - cons) < *len) + *len = prod - cons; + return buf + MASK_XENSTORE_IDX(cons); } /* FIXME: We spin, and we're sloppy. */ @@ -123,25 +84,28 @@ static bool read_all_shmem(int fd __attribute__((unused)), void *data, unsigned int len) { unsigned int avail; - int was_full; + struct xenstore_domain_interface *intf = interface; + XENSTORE_RING_IDX cons, prod; + const void *src; - if (!check_buffer(in)) - barf("Corrupt buffer"); - - was_full = !output_avail(in); while (len) { - const void *src = get_input_chunk(in, in->buf, &avail); + cons = intf->rsp_cons; + prod = intf->rsp_prod; + if (!check_indexes(cons, prod)) + barf("Corrupt buffer"); + + src = get_input_chunk(cons, prod, intf->rsp, &avail); if (avail > len) avail = len; memcpy(data, src, avail); data += avail; len -= avail; - update_input_chunk(in, avail); + intf->rsp_cons += avail; } /* Tell other end we read something. */ - if (was_full) - kill(daemon_pid, SIGUSR2); + kill(daemon_pid, SIGUSR2); + return true; } @@ -149,22 +113,28 @@ static bool write_all_shmem(int fd __attribute__((unused)), const void *data, unsigned int len) { uint32_t avail; - - if (!check_buffer(out)) - barf("Corrupt buffer"); + struct xenstore_domain_interface *intf = interface; + XENSTORE_RING_IDX cons, prod; + void *dst; while (len) { - void *dst = get_output_chunk(out, out->buf, &avail); + cons = intf->req_cons; + prod = intf->req_prod; + if (!check_indexes(cons, prod)) + barf("Corrupt buffer"); + + dst = get_output_chunk(cons, prod, intf->req, &avail); if (avail > len) avail = len; memcpy(dst, data, avail); data += avail; len -= avail; - update_output_chunk(out, avail); + intf->req_prod += avail; } /* Tell other end we wrote something. */ kill(daemon_pid, SIGUSR2); + return true; } @@ -552,21 +522,21 @@ static void do_introduce(unsigned int handle, break; fd = open("/tmp/xcmap", O_RDWR); - /* Set in and out pointers. */ - out = mmap(NULL, getpagesize(), PROT_WRITE|PROT_READ, MAP_SHARED,fd,0); - if (out == MAP_FAILED) + /* Set shared comms page. */ + interface = mmap(NULL, getpagesize(), PROT_WRITE|PROT_READ, + MAP_SHARED,fd,0); + if (interface == MAP_FAILED) barf_perror("Failed to map /tmp/xcmap page"); - in = (void *)out + getpagesize() / 2; close(fd); /* Tell them the event channel and our PID. */ - *(int *)((void *)out + 32) = getpid(); - *(uint16_t *)((void *)out + 36) = atoi(eventchn); + *(int *)((void *)interface + 32) = getpid(); + *(uint16_t *)((void *)interface + 36) = atoi(eventchn); if (!xs_introduce_domain(handles[handle], atoi(domid), atol(mfn), atoi(eventchn), path)) { failed(handle); - munmap(out, getpagesize()); + munmap(interface, getpagesize()); return; } output("handle is %i\n", i); @@ -576,7 +546,7 @@ static void do_introduce(unsigned int handle, handles[i]->fd = -2; /* Read in daemon pid. */ - daemon_pid = *(int *)((void *)out + 32); + daemon_pid = *(int *)((void *)interface + 32); } static void do_release(unsigned int handle, const char *domid) @@ -823,9 +793,6 @@ int main(int argc, char *argv[]) usage(); - /* The size of the ringbuffer: half a page minus head structure. */ - ringbuf_datasize = getpagesize() / 2 - sizeof(struct ringbuf_head); - signal(SIGALRM, alarmed); while (fgets(line, sizeof(line), stdin)) do_command(0, line); diff --git a/xen/include/public/io/xs_wire.h b/xen/include/public/io/xs_wire.h index 8f9fa047af..88d6b1f212 100644 --- a/xen/include/public/io/xs_wire.h +++ b/xen/include/public/io/xs_wire.h @@ -93,6 +93,17 @@ enum xs_watch_type XS_WATCH_TOKEN, }; +/* Inter-domain shared memory communications. */ +#define XENSTORE_RING_SIZE 1024 +typedef uint32_t XENSTORE_RING_IDX; +#define MASK_XENSTORE_IDX(idx) ((idx) & (XENSTORE_RING_SIZE-1)) +struct xenstore_domain_interface { + char req[XENSTORE_RING_SIZE]; /* Requests to xenstore daemon. */ + char rsp[XENSTORE_RING_SIZE]; /* Replies and async watch events. */ + XENSTORE_RING_IDX req_cons, req_prod; + XENSTORE_RING_IDX rsp_cons, rsp_prod; +}; + #endif /* _XS_WIRE_H */ /* From 22abd373134fb2ec0d9dbc615a49431515e7b22a Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 18:43:26 +0100 Subject: [PATCH 030/142] Disable watch callbacks while running the driver probe callback. Signed-off-by: Christian Limpach --- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 8 +++++++- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index 09d0d8db95..4471f10d32 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -39,6 +39,8 @@ #include #include "xenbus_comms.h" +extern struct semaphore xenwatch_mutex; + #define streq(a, b) (strcmp((a), (b)) == 0) static struct notifier_block *xenstore_chain; @@ -205,6 +207,7 @@ static int xenbus_dev_probe(struct device *_dev) struct xenbus_device *dev = to_xenbus_device(_dev); struct xenbus_driver *drv = to_xenbus_driver(_dev->driver); const struct xenbus_device_id *id; + int ret; if (!drv->probe) return -ENODEV; @@ -213,7 +216,10 @@ static int xenbus_dev_probe(struct device *_dev) if (!id) return -ENODEV; - return drv->probe(dev, id); + down(&xenwatch_mutex); + ret = drv->probe(dev, id); + up(&xenwatch_mutex); + return ret; } static int xenbus_dev_remove(struct device *_dev) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c index ad44cf100a..efaffe2393 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c @@ -92,7 +92,7 @@ static DEFINE_SPINLOCK(watch_events_lock); * carrying out work. */ static pid_t xenwatch_pid; -static DECLARE_MUTEX(xenwatch_mutex); +/* static */ DECLARE_MUTEX(xenwatch_mutex); static DECLARE_WAIT_QUEUE_HEAD(watch_events_waitq); static int get_error(const char *errorstring) From 4e5630275d61645acaeb553b927723d187bd0627 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 20:58:51 +0100 Subject: [PATCH 031/142] Disable watch callbacks only during driver registration instead of all probes. Signed-off-by: Christian Limpach --- .../drivers/xen/xenbus/xenbus_probe.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index 4471f10d32..e04798a562 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -207,7 +207,6 @@ static int xenbus_dev_probe(struct device *_dev) struct xenbus_device *dev = to_xenbus_device(_dev); struct xenbus_driver *drv = to_xenbus_driver(_dev->driver); const struct xenbus_device_id *id; - int ret; if (!drv->probe) return -ENODEV; @@ -216,10 +215,7 @@ static int xenbus_dev_probe(struct device *_dev) if (!id) return -ENODEV; - down(&xenwatch_mutex); - ret = drv->probe(dev, id); - up(&xenwatch_mutex); - return ret; + return drv->probe(dev, id); } static int xenbus_dev_remove(struct device *_dev) @@ -235,13 +231,18 @@ static int xenbus_dev_remove(struct device *_dev) static int xenbus_register_driver_common(struct xenbus_driver *drv, struct xen_bus_type *bus) { + int ret; + drv->driver.name = drv->name; drv->driver.bus = &bus->bus; drv->driver.owner = drv->owner; drv->driver.probe = xenbus_dev_probe; drv->driver.remove = xenbus_dev_remove; - return driver_register(&drv->driver); + down(&xenwatch_mutex); + ret = driver_register(&drv->driver); + up(&xenwatch_mutex); + return ret; } int xenbus_register_driver(struct xenbus_driver *drv) From dfc0b259c1b59b8b22e4a4b9fa2651deec42bc9d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 12 Oct 2005 21:10:14 +0100 Subject: [PATCH 032/142] Add memory barriers to console ring accesses. Similar to what Rusty uses for xenbus messaging. Signed-off-by: Keir Fraser --- .../drivers/xen/console/xencons_ring.c | 33 +++++--- tools/console/daemon/io.c | 76 ++++++++++--------- 2 files changed, 62 insertions(+), 47 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c index 0b37773575..9dcb60b5c8 100644 --- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c +++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c @@ -34,14 +34,18 @@ int xencons_ring_send(const char *data, unsigned len) { int sent = 0; struct xencons_interface *intf = xencons_interface(); + XENCONS_RING_IDX cons, prod; - while ((sent < len) && - (intf->out_prod - intf->out_cons) < sizeof(intf->out)) { - intf->out[MASK_XENCONS_IDX(intf->out_prod, intf->out)] = - data[sent]; - intf->out_prod++; - sent++; - } + cons = intf->out_cons; + prod = intf->out_prod; + mb(); + BUG_ON((prod - cons) > sizeof(intf->out)); + + while ((sent < len) && ((prod - cons) < sizeof(intf->out))) + intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; + + wmb(); + intf->out_prod = prod; /* Use evtchn: this is called early, before irq is set up. */ notify_remote_via_evtchn(xen_start_info->console_evtchn); @@ -52,16 +56,23 @@ int xencons_ring_send(const char *data, unsigned len) static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs) { struct xencons_interface *intf = xencons_interface(); + XENCONS_RING_IDX cons, prod; - while (intf->in_cons != intf->in_prod) { + cons = intf->in_cons; + prod = intf->in_prod; + mb(); + BUG_ON((prod - cons) > sizeof(intf->in)); + + while (cons != prod) { if (xencons_receiver != NULL) xencons_receiver( - intf->in + MASK_XENCONS_IDX(intf->in_cons, - intf->in), + intf->in + MASK_XENCONS_IDX(cons++, intf->in), 1, regs); - intf->in_cons++; } + wmb(); + intf->in_cons = cons; + return IRQ_HANDLED; } diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index fc772b7580..9039a96525 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -79,44 +79,43 @@ static void evtchn_notify(struct domain *dom) static void buffer_append(struct domain *dom) { struct buffer *buffer = &dom->buffer; - size_t size; - XENCONS_RING_IDX oldcons; - int notify = 0; + XENCONS_RING_IDX cons, prod, size; struct xencons_interface *intf = dom->interface; - while ((size = (intf->out_prod - intf->out_cons)) != 0) { - notify = 1; + cons = intf->out_cons; + prod = intf->out_prod; + mb(); - if ((buffer->capacity - buffer->size) < size) { - buffer->capacity += (size + 1024); - buffer->data = realloc(buffer->data, buffer->capacity); - if (buffer->data == NULL) { - dolog(LOG_ERR, "Memory allocation failed"); - exit(ENOMEM); - } - } + size = prod - cons; + if ((size == 0) || (size > sizeof(intf->out))) + return; - oldcons = intf->out_cons; - while ((intf->out_cons - oldcons) < size) { - buffer->data[buffer->size] = intf->out[ - MASK_XENCONS_IDX(intf->out_cons, intf->out)]; - buffer->size++; - intf->out_cons++; - } - - if (buffer->max_capacity && - buffer->size > buffer->max_capacity) { - memmove(buffer->data + (buffer->size - - buffer->max_capacity), - buffer->data, buffer->max_capacity); - buffer->data = realloc(buffer->data, - buffer->max_capacity); - buffer->capacity = buffer->max_capacity; + if ((buffer->capacity - buffer->size) < size) { + buffer->capacity += (size + 1024); + buffer->data = realloc(buffer->data, buffer->capacity); + if (buffer->data == NULL) { + dolog(LOG_ERR, "Memory allocation failed"); + exit(ENOMEM); } } - if (notify) - evtchn_notify(dom); + while (cons != prod) + buffer->data[buffer->size++] = intf->out[ + MASK_XENCONS_IDX(cons++, intf->out)]; + + mb(); + intf->out_cons = cons; + evtchn_notify(dom); + + if (buffer->max_capacity && + buffer->size > buffer->max_capacity) { + memmove(buffer->data + (buffer->size - + buffer->max_capacity), + buffer->data, buffer->max_capacity); + buffer->data = realloc(buffer->data, + buffer->max_capacity); + buffer->capacity = buffer->max_capacity; + } } static bool buffer_empty(struct buffer *buffer) @@ -419,10 +418,14 @@ static void handle_tty_read(struct domain *dom) char msg[80]; int i; struct xencons_interface *intf = dom->interface; - XENCONS_RING_IDX filled = intf->in_prod - intf->in_cons; + XENCONS_RING_IDX cons, prod; - if (sizeof(intf->in) > filled) - len = sizeof(intf->in) - filled; + cons = intf->in_cons; + prod = intf->in_prod; + mb(); + + if (sizeof(intf->in) > (prod - cons)) + len = sizeof(intf->in) - (prod - cons); if (len > sizeof(msg)) len = sizeof(msg); @@ -441,10 +444,11 @@ static void handle_tty_read(struct domain *dom) } } else if (domain_is_valid(dom->domid)) { for (i = 0; i < len; i++) { - intf->in[MASK_XENCONS_IDX(intf->in_prod, intf->in)] = + intf->in[MASK_XENCONS_IDX(prod++, intf->in)] = msg[i]; - intf->in_prod++; } + wmb(); + intf->in_prod = prod; evtchn_notify(dom); } else { close(dom->tty_fd); From ac9725dff60cf88ef535d816a58366eba60d91ae Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 13 Oct 2005 08:06:27 +0100 Subject: [PATCH 033/142] Currently, we mark an IO request to STATE_IOREQ_READY state before calling IO handlers in xen HV, i.e. vmx_portio_intercept or vmx_mmio_intercept. Actually, STATE_IOREQ_READY means it's ready for DM handling, only if IO handlers in xen HV won't handle it, it should be passed to DM. This patch fixes this issue. Signed-off-by: Yunhong Jiang Signed-off-by: Xin Li Signed-off-by: Nakajima Jun --- xen/arch/x86/vmx.c | 4 ++-- xen/arch/x86/vmx_platform.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index dd5a6b87e6..c403002bef 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -646,14 +646,14 @@ void send_pio_req(struct cpu_user_regs *regs, unsigned long port, } else p->u.data = value; - p->state = STATE_IOREQ_READY; - if (vmx_portio_intercept(p)) { /* no blocking & no evtchn notification */ clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags); return; } + p->state = STATE_IOREQ_READY; + evtchn_send(iopacket_port(v->domain)); vmx_wait_io(); } diff --git a/xen/arch/x86/vmx_platform.c b/xen/arch/x86/vmx_platform.c index cef786b14a..cd1a5b3b02 100644 --- a/xen/arch/x86/vmx_platform.c +++ b/xen/arch/x86/vmx_platform.c @@ -643,14 +643,14 @@ void send_mmio_req(unsigned char type, unsigned long gpa, } else p->u.data = value; - p->state = STATE_IOREQ_READY; - if (vmx_mmio_intercept(p)){ p->state = STATE_IORESP_READY; vmx_io_assist(v); return; } + p->state = STATE_IOREQ_READY; + evtchn_send(iopacket_port(v->domain)); vmx_wait_io(); } From 349f04a5df6a911baa8c2f241ebcc37811562f4b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 13 Oct 2005 08:38:49 +0100 Subject: [PATCH 034/142] NS_PER_TICK must be a s64 quantity. It is compared with possibly -ve values which we do not want to 'promote' to big +ve values. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c index ea09ebbb95..1157270955 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c @@ -122,7 +122,8 @@ static u32 shadow_tv_version; static u64 processed_system_time; /* System time (ns) at last processing. */ static DEFINE_PER_CPU(u64, processed_system_time); -#define NS_PER_TICK (1000000000ULL/HZ) +/* Must be signed, as it's compared with s64 quantities which can be -ve. */ +#define NS_PER_TICK (1000000000LL/HZ) static inline void __normalize_time(time_t *sec, s64 *nsec) { @@ -235,9 +236,9 @@ static void __update_wallclock(time_t sec, long nsec) /* Adjust wall-clock time base based on wall_jiffies ticks. */ wc_nsec = processed_system_time; - wc_nsec += (u64)sec * 1000000000ULL; - wc_nsec += (u64)nsec; - wc_nsec -= (jiffies - wall_jiffies) * (u64)(NSEC_PER_SEC / HZ); + wc_nsec += sec * (u64)NSEC_PER_SEC; + wc_nsec += nsec; + wc_nsec -= (jiffies - wall_jiffies) * (u64)NS_PER_TICK; /* Split wallclock base into seconds and nanoseconds. */ tmp = wc_nsec; @@ -437,7 +438,7 @@ int do_settimeofday(struct timespec *tv) * be stale, so we can retry with fresh ones. */ for ( ; ; ) { - nsec = (s64)tv->tv_nsec - (s64)get_nsec_offset(shadow); + nsec = tv->tv_nsec - get_nsec_offset(shadow); if (time_values_up_to_date(cpu)) break; get_time_values_from_xen(); @@ -558,7 +559,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) } while (!time_values_up_to_date(cpu)); - if (unlikely(delta < (s64)-1000000) || unlikely(delta_cpu < 0)) { + if (unlikely(delta < -1000000LL) || unlikely(delta_cpu < 0)) { printk("Timer ISR/%d: Time went backwards: " "delta=%lld cpu_delta=%lld shadow=%lld " "off=%lld processed=%lld cpu_processed=%lld\n", @@ -802,7 +803,7 @@ static inline u64 jiffies_to_st(unsigned long j) * but that's ok: we'll just end up with a shorter timeout. */ if (delta < 1) delta = 1; - st = processed_system_time + ((u64)delta * NS_PER_TICK); + st = processed_system_time + (delta * (u64)NS_PER_TICK); } while (read_seqretry(&xtime_lock, seq)); return st; From b5d8fa2d8759e16e22b3368f6eb14a7a24712e5f Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 13 Oct 2005 11:12:11 +0100 Subject: [PATCH 035/142] Fix client dependency on libxenstore in Makefile. Signed-off-by: Keir Fraser --- tools/xenstore/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/xenstore/Makefile b/tools/xenstore/Makefile index efae68ae3e..32194309d1 100644 --- a/tools/xenstore/Makefile +++ b/tools/xenstore/Makefile @@ -34,8 +34,8 @@ testcode: xs_test xenstored_test xs_random xenstored: xenstored_core.o xenstored_watch.o xenstored_domain.o xenstored_transaction.o xs_lib.o talloc.o utils.o tdb.o $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -o $@ -$(CLIENTS): xenstore-%: xenstore_%.o - $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@ +$(CLIENTS): xenstore-%: xenstore_%.o libxenstore.so + $(LINK.o) $< $(LOADLIBES) $(LDLIBS) -lxenctrl -L. -lxenstore -o $@ $(CLIENTS_OBJS): xenstore_%.o: xenstore_client.c $(COMPILE.c) -DCLIENT_$(*F) -o $@ $< From 8abc2d5b4ef5b573606a4d84fe3abf8b248fd871 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 13 Oct 2005 15:19:29 +0100 Subject: [PATCH 036/142] Fix multi-cpu save/restore after the max_vcpu patch. Signed-off-by: Keir Fraser --- tools/python/xen/xend/XendDomainInfo.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index c4c1bd742d..b387df108d 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1012,6 +1012,8 @@ class XendDomainInfo: # shutdown_start_time from killing the domain, for example. self.removeDom() + # Set maximum number of vcpus in domain + xc.domain_max_vcpus(self.domid, int(self.info['vcpus'])) def initDomain(self): log.debug('XendDomainInfo.initDomain: %s %s %s', @@ -1031,9 +1033,6 @@ class XendDomainInfo: xc.domain_setcpuweight(self.domid, self.info['cpu_weight']) - # Set maximum number of vcpus in domain - xc.domain_max_vcpus(self.domid, int(self.info['vcpus'])); - # XXX Merge with configure_maxmem? m = self.image.getDomainMemory(self.info['memory_KiB']) xc.domain_setmaxmem(self.domid, m) From 043da08cae916a02d887d152d398c8825e6feda1 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Thu, 13 Oct 2005 15:25:42 +0100 Subject: [PATCH 037/142] Fix broken test for zombies. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomain.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 7b1ea4a759..66668ef6e9 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -313,12 +313,13 @@ class XendDomain: def domain_lookup_by_name_nr(self, name): self.domains_lock.acquire() try: - matching = filter(lambda d: d.getName() == name, - self.domains.values()) + matching = filter( + lambda d: d.getName() == name and not d.isShutdown(), + self.domains.values()) n = len(matching) if n == 1: return matching[0] - elif n > 1 and not d.isTerminated(): + elif n > 1: log.error('Name uniqueness has been violated for name %s! ' 'Recovering by renaming:', name) for d in matching: From 9394398ccfe0971ce79bf8c0e02da8444c25dc65 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 13 Oct 2005 17:08:59 +0100 Subject: [PATCH 038/142] Cleanup CPU hotplug and save/restore. Next step is to simplify SMP initial boot and then should be easy to merge i386 and x86/64 smpboot.c. Signed-off-by: Keir Fraser --- .../arch/xen/i386/kernel/process.c | 55 +------- .../arch/xen/i386/kernel/smpboot.c | 120 ++++++------------ .../arch/xen/i386/kernel/time.c | 33 ++--- linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c | 12 +- .../arch/xen/x86_64/kernel/smpboot.c | 8 +- .../drivers/xen/console/console.c | 2 +- .../drivers/xen/netback/netback.c | 2 +- linux-2.6-xen-sparse/include/asm-xen/evtchn.h | 8 +- 8 files changed, 66 insertions(+), 174 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c index db8cbed8cd..3328dc94ff 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/process.c @@ -112,44 +112,6 @@ void xen_idle(void) } } -#ifdef CONFIG_HOTPLUG_CPU -#include -#ifdef CONFIG_SMP -extern void smp_suspend(void); -extern void smp_resume(void); -#endif -/* We don't actually take CPU down, just spin without interrupts. */ -static inline void play_dead(void) -{ - /* Death loop */ - while (__get_cpu_var(cpu_state) != CPU_UP_PREPARE) - HYPERVISOR_sched_op(SCHEDOP_yield, 0); - - __flush_tlb_all(); - /* - * Restore IPI/IRQ mappings before marking online to prevent - * race between pending interrupts and restoration of handler. - */ -#ifdef CONFIG_SMP - local_irq_enable(); /* XXX Needed for smp_resume(). Clean me up. */ - smp_resume(); -#endif - cpu_set(smp_processor_id(), cpu_online_map); -} -#else -static inline void play_dead(void) -{ - BUG(); -} -#endif /* CONFIG_HOTPLUG_CPU */ - -void cpu_restore(void) -{ - play_dead(); - local_irq_enable(); - cpu_idle(); -} - /* * The idle thread. There's no useful work to be * done, so just try to conserve power and have a @@ -158,7 +120,9 @@ void cpu_restore(void) */ void cpu_idle (void) { +#if defined(CONFIG_HOTPLUG_CPU) int cpu = _smp_processor_id(); +#endif /* endless idle loop with no priority at all */ while (1) { @@ -168,23 +132,12 @@ void cpu_idle (void) __get_cpu_var(cpu_idle_state) = 0; rmb(); +#if defined(CONFIG_HOTPLUG_CPU) if (cpu_is_offline(cpu)) { - local_irq_disable(); -#ifdef CONFIG_SMP - smp_suspend(); -#endif -#if defined(CONFIG_XEN) && defined(CONFIG_HOTPLUG_CPU) - /* Ack it. From this point on until - we get woken up, we're not allowed - to take any locks. In particular, - don't printk. */ - __get_cpu_var(cpu_state) = CPU_DEAD; - /* Tell hypervisor to take vcpu down. */ HYPERVISOR_vcpu_op(VCPUOP_down, cpu, NULL); -#endif - play_dead(); local_irq_enable(); } +#endif __get_cpu_var(irq_stat).idle_timestamp = jiffies; xen_idle(); diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c index 267bd31cd5..b13abf720e 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -66,6 +66,9 @@ #include #include +static void xen_smp_intr_init(unsigned int cpu); +static void xen_smp_intr_exit(unsigned int cpu); + /* Set if we find a B stepping CPU */ static int __initdata smp_b_stepping; @@ -352,9 +355,9 @@ static atomic_t init_deasserted; static void __init smp_callin(void) { int cpuid, phys_id; +#if 0 unsigned long timeout; -#if 0 /* * If waken up by an INIT in an 82489DX configuration * we may get here before an INIT-deassert IPI reaches @@ -376,6 +379,7 @@ static void __init smp_callin(void) } Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id); +#if 0 /* * STARTUP IPIs are fragile beasts as they might sometimes * trigger some glue motherboard logic. Complete APIC bus @@ -403,7 +407,6 @@ static void __init smp_callin(void) BUG(); } -#if 0 /* * the boot CPU has finished the init stage and is spinning * on callin_map until we finish. We are free to set up this @@ -448,8 +451,6 @@ static void __init smp_callin(void) static int cpucount; -extern void local_setup_timer(void); - /* * Activate a secondary processor. */ @@ -464,8 +465,6 @@ static void __init start_secondary(void *unused) smp_callin(); while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) rep_nop(); - local_setup_timer(); - smp_intr_init(); local_irq_enable(); /* * low-memory mappings have been cleared, flush them from @@ -1133,7 +1132,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) return; } - smp_intr_init(); + xen_smp_intr_init(0); #if 0 connect_bsp_APIC(); @@ -1340,29 +1339,6 @@ static int __init setup_vcpu_hotplug_event(void) subsys_initcall(setup_vcpu_hotplug_event); -/* must be called with the cpucontrol mutex held */ -static int __devinit cpu_enable(unsigned int cpu) -{ -#ifdef CONFIG_SMP_ALTERNATIVES - if (num_online_cpus() == 1) - prepare_for_smp(); -#endif - - /* get the target out of its holding state */ - per_cpu(cpu_state, cpu) = CPU_UP_PREPARE; - wmb(); - - /* wait for the processor to ack it. timeout? */ - while (!cpu_online(cpu)) - cpu_relax(); - - fixup_irqs(cpu_online_map); - - /* counter the disable in fixup_irqs() */ - local_irq_enable(); - return 0; -} - int __cpu_disable(void) { cpumask_t map = cpu_online_map; @@ -1385,27 +1361,22 @@ int __cpu_disable(void) /* It's now safe to remove this processor from the online map */ cpu_clear(cpu, cpu_online_map); -#ifdef CONFIG_SMP_ALTERNATIVES - if (num_online_cpus() == 1) - unprepare_for_smp(); -#endif - return 0; } void __cpu_die(unsigned int cpu) { - /* We don't do anything here: idle task is faking death itself. */ - unsigned int i; - - for (i = 0; i < 10; i++) { - /* They ack this in play_dead by setting CPU_DEAD */ - if (per_cpu(cpu_state, cpu) == CPU_DEAD) - return; + while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { current->state = TASK_UNINTERRUPTIBLE; schedule_timeout(HZ/10); } - printk(KERN_ERR "CPU %u didn't die...\n", cpu); + + xen_smp_intr_exit(cpu); + +#ifdef CONFIG_SMP_ALTERNATIVES + if (num_online_cpus() == 1) + unprepare_for_smp(); +#endif } #else /* ... !CONFIG_HOTPLUG_CPU */ @@ -1430,23 +1401,16 @@ int __devinit __cpu_up(unsigned int cpu) return -EIO; } -#ifdef CONFIG_HOTPLUG_CPU -#ifdef CONFIG_XEN - /* Tell hypervisor to bring vcpu up. */ - HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); -#endif - /* Already up, and in cpu_quiescent now? */ - if (cpu_isset(cpu, smp_commenced_mask)) { - cpu_enable(cpu); - return 0; - } +#ifdef CONFIG_SMP_ALTERNATIVES + if (num_online_cpus() == 1) + prepare_for_smp(); #endif - local_irq_enable(); - /* Unleash the CPU! */ + xen_smp_intr_init(cpu); cpu_set(cpu, smp_commenced_mask); - while (!cpu_isset(cpu, cpu_online_map)) - mb(); + cpu_set(cpu, cpu_online_map); + HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); + return 0; } @@ -1468,48 +1432,38 @@ void __init smp_cpus_done(unsigned int max_cpus) extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *); extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *); -void smp_intr_init(void) -{ - int cpu = smp_processor_id(); +extern void local_setup_timer(unsigned int cpu); +extern void local_teardown_timer(unsigned int cpu); +static void xen_smp_intr_init(unsigned int cpu) +{ per_cpu(resched_irq, cpu) = - bind_ipi_to_irq(RESCHEDULE_VECTOR); + bind_ipi_to_irq(RESCHEDULE_VECTOR, cpu); sprintf(resched_name[cpu], "resched%d", cpu); BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, SA_INTERRUPT, resched_name[cpu], NULL)); per_cpu(callfunc_irq, cpu) = - bind_ipi_to_irq(CALL_FUNCTION_VECTOR); + bind_ipi_to_irq(CALL_FUNCTION_VECTOR, cpu); sprintf(callfunc_name[cpu], "callfunc%d", cpu); BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), smp_call_function_interrupt, SA_INTERRUPT, callfunc_name[cpu], NULL)); + + if (cpu != 0) + local_setup_timer(cpu); } -static void smp_intr_exit(void) +static void xen_smp_intr_exit(unsigned int cpu) { - int cpu = smp_processor_id(); + if (cpu != 0) + local_teardown_timer(cpu); free_irq(per_cpu(resched_irq, cpu), NULL); - unbind_ipi_from_irq(RESCHEDULE_VECTOR); + unbind_ipi_from_irq(RESCHEDULE_VECTOR, cpu); free_irq(per_cpu(callfunc_irq, cpu), NULL); - unbind_ipi_from_irq(CALL_FUNCTION_VECTOR); -} - -extern void local_setup_timer_irq(void); -extern void local_teardown_timer_irq(void); - -void smp_suspend(void) -{ - local_teardown_timer_irq(); - smp_intr_exit(); -} - -void smp_resume(void) -{ - smp_intr_init(); - local_setup_timer(); + unbind_ipi_from_irq(CALL_FUNCTION_VECTOR, cpu); } void vcpu_prepare(int vcpu) @@ -1517,7 +1471,6 @@ void vcpu_prepare(int vcpu) extern void hypervisor_callback(void); extern void failsafe_callback(void); extern void smp_trap_init(trap_info_t *); - extern void cpu_restore(void); vcpu_guest_context_t ctxt; struct task_struct *idle = idle_task(vcpu); @@ -1532,7 +1485,7 @@ void vcpu_prepare(int vcpu) ctxt.user_regs.gs = 0; ctxt.user_regs.ss = __KERNEL_DS; ctxt.user_regs.cs = __KERNEL_CS; - ctxt.user_regs.eip = (unsigned long)cpu_restore; + ctxt.user_regs.eip = (unsigned long)cpu_idle; ctxt.user_regs.esp = idle->thread.esp; ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING1; @@ -1556,7 +1509,6 @@ void vcpu_prepare(int vcpu) ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT; (void)HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt); - (void)HYPERVISOR_vcpu_op(VCPUOP_up, vcpu, NULL); } /* diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c index 1157270955..cfc1a49e7d 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/time.c @@ -785,7 +785,7 @@ void __init time_init(void) rdtscll(vxtime.last_tsc); #endif - per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER); + per_cpu(timer_irq, 0) = bind_virq_to_irq(VIRQ_TIMER, 0); (void)setup_irq(per_cpu(timer_irq, 0), &irq_timer); } @@ -852,21 +852,12 @@ void time_resume(void) #ifdef CONFIG_SMP static char timer_name[NR_CPUS][15]; -void local_setup_timer_irq(void) -{ - int cpu = smp_processor_id(); - if (cpu == 0) - return; - per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER); - sprintf(timer_name[cpu], "timer%d", cpu); - BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt, - SA_INTERRUPT, timer_name[cpu], NULL)); -} - -void local_setup_timer(void) +void local_setup_timer(unsigned int cpu) { - int seq, cpu = smp_processor_id(); + int seq; + + BUG_ON(cpu == 0); do { seq = read_seqbegin(&xtime_lock); @@ -874,17 +865,17 @@ void local_setup_timer(void) per_cpu(shadow_time, cpu).system_timestamp; } while (read_seqretry(&xtime_lock, seq)); - local_setup_timer_irq(); + per_cpu(timer_irq, cpu) = bind_virq_to_irq(VIRQ_TIMER, cpu); + sprintf(timer_name[cpu], "timer%d", cpu); + BUG_ON(request_irq(per_cpu(timer_irq, cpu), timer_interrupt, + SA_INTERRUPT, timer_name[cpu], NULL)); } -void local_teardown_timer_irq(void) +void local_teardown_timer(unsigned int cpu) { - int cpu = smp_processor_id(); - - if (cpu == 0) - return; + BUG_ON(cpu == 0); free_irq(per_cpu(timer_irq, cpu), NULL); - unbind_virq_from_irq(VIRQ_TIMER); + unbind_virq_from_irq(VIRQ_TIMER, cpu); } #endif diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c index 6a85441f7f..cb0e1f9783 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c @@ -178,11 +178,10 @@ static int find_unbound_irq(void) return irq; } -int bind_virq_to_irq(int virq) +int bind_virq_to_irq(int virq, int cpu) { evtchn_op_t op = { .cmd = EVTCHNOP_bind_virq }; int evtchn, irq; - int cpu = smp_processor_id(); spin_lock(&irq_mapping_update_lock); @@ -209,10 +208,9 @@ int bind_virq_to_irq(int virq) } EXPORT_SYMBOL(bind_virq_to_irq); -void unbind_virq_from_irq(int virq) +void unbind_virq_from_irq(int virq, int cpu) { evtchn_op_t op = { .cmd = EVTCHNOP_close }; - int cpu = smp_processor_id(); int irq = per_cpu(virq_to_irq, cpu)[virq]; int evtchn = irq_to_evtchn[irq]; @@ -240,11 +238,10 @@ void unbind_virq_from_irq(int virq) } EXPORT_SYMBOL(unbind_virq_from_irq); -int bind_ipi_to_irq(int ipi) +int bind_ipi_to_irq(int ipi, int cpu) { evtchn_op_t op = { .cmd = EVTCHNOP_bind_ipi }; int evtchn, irq; - int cpu = smp_processor_id(); spin_lock(&irq_mapping_update_lock); @@ -272,10 +269,9 @@ int bind_ipi_to_irq(int ipi) } EXPORT_SYMBOL(bind_ipi_to_irq); -void unbind_ipi_from_irq(int ipi) +void unbind_ipi_from_irq(int ipi, int cpu) { evtchn_op_t op = { .cmd = EVTCHNOP_close }; - int cpu = smp_processor_id(); int evtchn = per_cpu(ipi_to_evtchn, cpu)[ipi]; int irq = evtchn_to_irq[evtchn]; diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c index 1fb1ceab86..349f0309e5 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c @@ -1224,13 +1224,13 @@ void smp_intr_init(void) int cpu = smp_processor_id(); per_cpu(resched_irq, cpu) = - bind_ipi_to_irq(RESCHEDULE_VECTOR); + bind_ipi_to_irq(RESCHEDULE_VECTOR, cpu); sprintf(resched_name[cpu], "resched%d", cpu); BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, SA_INTERRUPT, resched_name[cpu], NULL)); per_cpu(callfunc_irq, cpu) = - bind_ipi_to_irq(CALL_FUNCTION_VECTOR); + bind_ipi_to_irq(CALL_FUNCTION_VECTOR, cpu); sprintf(callfunc_name[cpu], "callfunc%d", cpu); BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), smp_call_function_interrupt, @@ -1242,10 +1242,10 @@ static void smp_intr_exit(void) int cpu = smp_processor_id(); free_irq(per_cpu(resched_irq, cpu), NULL); - unbind_ipi_from_irq(RESCHEDULE_VECTOR); + unbind_ipi_from_irq(RESCHEDULE_VECTOR, cpu); free_irq(per_cpu(callfunc_irq, cpu), NULL); - unbind_ipi_from_irq(CALL_FUNCTION_VECTOR); + unbind_ipi_from_irq(CALL_FUNCTION_VECTOR, cpu); } extern void local_setup_timer_irq(void); diff --git a/linux-2.6-xen-sparse/drivers/xen/console/console.c b/linux-2.6-xen-sparse/drivers/xen/console/console.c index 1206e4ea6a..1a23f4495e 100644 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c @@ -768,7 +768,7 @@ static int __init xencons_init(void) #endif if (xen_start_info->flags & SIF_INITDOMAIN) { - xencons_priv_irq = bind_virq_to_irq(VIRQ_CONSOLE); + xencons_priv_irq = bind_virq_to_irq(VIRQ_CONSOLE, 0); (void)request_irq(xencons_priv_irq, xencons_priv_interrupt, 0, "console", NULL); } else { diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index 3408bb40cc..1c29a97f9d 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -817,7 +817,7 @@ static int __init netback_init(void) netif_xenbus_init(); - (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG), + (void)request_irq(bind_virq_to_irq(VIRQ_DEBUG, 0), netif_be_dbg, SA_SHIRQ, "net-be-dbg", &netif_be_dbg); diff --git a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h index a38b8732a1..f2523926d8 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h @@ -44,12 +44,12 @@ */ /* Dynamically bind a VIRQ source to Linux IRQ space. */ -extern int bind_virq_to_irq(int virq); -extern void unbind_virq_from_irq(int virq); +extern int bind_virq_to_irq(int virq, int cpu); +extern void unbind_virq_from_irq(int virq, int cpu); /* Dynamically bind an IPI source to Linux IRQ space. */ -extern int bind_ipi_to_irq(int ipi); -extern void unbind_ipi_from_irq(int ipi); +extern int bind_ipi_to_irq(int ipi, int cpu); +extern void unbind_ipi_from_irq(int ipi, int cpu); /* * Dynamically bind an event-channel port to an IRQ-like callback handler. From 7e6a2a32881d6e6356bbf4eb1461458c95a380d1 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Thu, 13 Oct 2005 17:49:56 +0100 Subject: [PATCH 039/142] Remove the diagnostic/recovery when two domains end up with the same name. It was working around bugs that have gone, and is now more dangerous than useful -- deadlock is a possibility with this code now. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomain.py | 11 ++--------- tools/python/xen/xend/XendDomainInfo.py | 22 ---------------------- 2 files changed, 2 insertions(+), 31 deletions(-) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 66668ef6e9..ce4007b984 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -313,18 +313,11 @@ class XendDomain: def domain_lookup_by_name_nr(self, name): self.domains_lock.acquire() try: - matching = filter( - lambda d: d.getName() == name and not d.isShutdown(), - self.domains.values()) + matching = filter(lambda d: d.getName() == name, + self.domains.values()) n = len(matching) if n == 1: return matching[0] - elif n > 1: - log.error('Name uniqueness has been violated for name %s! ' - 'Recovering by renaming:', name) - for d in matching: - d.renameUniquely() - return None finally: self.domains_lock.release() diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index b387df108d..0ff379f7b9 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -840,14 +840,6 @@ class XendDomainInfo: self.state_updated.release() - def isShutdown(self): - self.state_updated.acquire() - try: - return self.state == STATE_DOM_SHUTDOWN - finally: - self.state_updated.release() - - def __str__(self): s = " Date: Thu, 13 Oct 2005 17:55:15 +0100 Subject: [PATCH 040/142] Revert accidental commit. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/event.py | 18 ++++++++---------- xen/Rules.mk | 2 +- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/tools/python/xen/xend/server/event.py b/tools/python/xen/xend/server/event.py index 359f774cf7..bf0521c764 100644 --- a/tools/python/xen/xend/server/event.py +++ b/tools/python/xen/xend/server/event.py @@ -185,13 +185,11 @@ class EventFactory(protocol.ServerFactory): return EventProtocol(self.daemon) def listenEvent(daemon): - pass - -# factory = EventFactory(daemon) -# if xroot.get_xend_unix_server(): -# path = '/var/lib/xend/event-socket' -# unix.listenUNIX(path, factory) -# if xroot.get_xend_http_server(): -# port = xroot.get_xend_event_port() -# interface = xroot.get_xend_address() -# tcp.listenTCP(port, factory, interface=interface) + factory = EventFactory(daemon) + if xroot.get_xend_unix_server(): + path = '/var/lib/xend/event-socket' + unix.listenUNIX(path, factory) + if xroot.get_xend_http_server(): + port = xroot.get_xend_event_port() + interface = xroot.get_xend_address() + tcp.listenTCP(port, factory, interface=interface) diff --git a/xen/Rules.mk b/xen/Rules.mk index 6756753a2c..d57ca65e51 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -3,7 +3,7 @@ # 'make clean' before rebuilding. # verbose ?= y -debug ?= y +debug ?= n perfc ?= n perfc_arrays?= n trace ?= n From 1843c48dd1240e814dd5fc4aabf8ae6d4923ce8e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 13 Oct 2005 17:58:01 +0100 Subject: [PATCH 041/142] Because of a bug with reference counting against the target guest page when searching the list for L1 shadow pages to write protect that page (at shadow_promote(), which is called by alloc_shadow_page()), the code was always scanning _all_ the entries in the hash list. The length of the hash list can be >500 for L1 shadow pages, and for each page we needed to check all the PTEs in the page. The patch attached does the following things: - Correct the reference count (for the target guest page) so that=20 it can exit the loop when all the L1 shadow pages to modify are found. Even with this, we can search the entire list if the page is at=20 the end. - Try to avoid the search in the hash list, by having a back pointer (as a hint) to the shadow page pfn. For most cases,=20 there is a single translation for the guest page in the shadow. - Cleanups, remove the nested function fix_entry With those, the kernel build performance, for example, was improved approximately by 20%, 40% on 32-bit, 64-bit unmodified Linux guests, respectively. Tested log-dirty mode for plain 32-bit as well. Signed-off-by: Jun Nakajima Signed-off-by: Asit Mallick --- xen/arch/x86/shadow.c | 115 ++++++++++++++----------------- xen/arch/x86/shadow32.c | 127 +++++++++++++++-------------------- xen/arch/x86/shadow_public.c | 7 +- xen/include/asm-x86/shadow.h | 20 +++++- 4 files changed, 129 insertions(+), 140 deletions(-) diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index 18e44cc9c0..dfea7b4f43 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -616,13 +616,6 @@ static void shadow_map_l1_into_current_l2(unsigned long va) pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(entries - 1)) << L1_PAGETABLE_SHIFT; spl1e = (l1_pgentry_t *) __shadow_get_l1e(v, pt_va, &tmp_sl1e); - /* - gpl1e = &(linear_pg_table[l1_linear_offset(va) & - ~(L1_PAGETABLE_ENTRIES-1)]); - - spl1e = &(shadow_linear_pg_table[l1_linear_offset(va) & - ~(L1_PAGETABLE_ENTRIES-1)]);*/ - for ( i = 0; i < GUEST_L1_PAGETABLE_ENTRIES; i++ ) { l1pte_propagate_from_guest(d, gpl1e[i], &sl1e); @@ -645,7 +638,8 @@ static void shadow_map_l1_into_current_l2(unsigned long va) min = i; if ( likely(i > max) ) max = i; - } + set_guest_back_ptr(d, sl1e, sl1mfn, i); + } frame_table[sl1mfn].tlbflush_timestamp = SHADOW_ENCODE_MIN_MAX(min, max); @@ -716,8 +710,8 @@ shadow_set_l1e(unsigned long va, l1_pgentry_t new_spte, int create_l1_shadow) } } + set_guest_back_ptr(d, new_spte, l2e_get_pfn(sl2e), l1_table_offset(va)); __shadow_set_l1e(v, va, &new_spte); - shadow_update_min_max(l2e_get_pfn(sl2e), l1_table_offset(va)); } @@ -1135,6 +1129,24 @@ decrease_writable_pte_prediction(struct domain *d, unsigned long gpfn, unsigned } } +static int fix_entry( + struct domain *d, + l1_pgentry_t *pt, u32 *found, int is_l1_shadow, u32 max_refs_to_find) +{ + l1_pgentry_t old = *pt; + l1_pgentry_t new = old; + + l1e_remove_flags(new,_PAGE_RW); + if ( is_l1_shadow && !shadow_get_page_from_l1e(new, d) ) + BUG(); + (*found)++; + *pt = new; + if ( is_l1_shadow ) + shadow_put_page_from_l1e(old, d); + + return (*found == max_refs_to_find); +} + static u32 remove_all_write_access_in_ptpage( struct domain *d, unsigned long pt_pfn, unsigned long pt_mfn, unsigned long readonly_gpfn, unsigned long readonly_gmfn, @@ -1156,49 +1168,28 @@ static u32 remove_all_write_access_in_ptpage( match = l1e_from_pfn(readonly_gmfn, flags); - // returns true if all refs have been found and fixed. - // - int fix_entry(int i) - { - l1_pgentry_t old = pt[i]; - l1_pgentry_t new = old; + if ( shadow_mode_external(d) ) { + i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask) + >> PGT_va_shift; - l1e_remove_flags(new,_PAGE_RW); - if ( is_l1_shadow && !shadow_get_page_from_l1e(new, d) ) - BUG(); - found++; - pt[i] = new; - if ( is_l1_shadow ) - shadow_put_page_from_l1e(old, d); - -#if 0 - printk("removed write access to pfn=%lx mfn=%lx in smfn=%lx entry %x " - "is_l1_shadow=%d\n", - readonly_gpfn, readonly_gmfn, pt_mfn, i, is_l1_shadow); -#endif - - return (found == max_refs_to_find); - } - - i = readonly_gpfn & (GUEST_L1_PAGETABLE_ENTRIES - 1); - if ( !l1e_has_changed(pt[i], match, flags) && fix_entry(i) ) - { - perfc_incrc(remove_write_fast_exit); - increase_writable_pte_prediction(d, readonly_gpfn, prediction); - unmap_domain_page(pt); - return found; + if ( (i >= 0 && i <= L1_PAGETABLE_ENTRIES) && + !l1e_has_changed(pt[i], match, flags) && + fix_entry(d, &pt[i], &found, is_l1_shadow, max_refs_to_find) && + !prediction ) + goto out; } for (i = 0; i < GUEST_L1_PAGETABLE_ENTRIES; i++) { - if ( unlikely(!l1e_has_changed(pt[i], match, flags)) && fix_entry(i) ) + if ( unlikely(!l1e_has_changed(pt[i], match, flags)) && + fix_entry(d, &pt[i], &found, is_l1_shadow, max_refs_to_find) ) break; } +out: unmap_domain_page(pt); return found; -#undef MATCH_ENTRY } static int remove_all_write_access( @@ -1206,8 +1197,8 @@ static int remove_all_write_access( { int i; struct shadow_status *a; - u32 found = 0, fixups, write_refs; - unsigned long prediction, predicted_gpfn, predicted_smfn; + u32 found = 0, write_refs; + unsigned long predicted_smfn; ASSERT(shadow_lock_is_acquired(d)); ASSERT(VALID_MFN(readonly_gmfn)); @@ -1238,26 +1229,18 @@ static int remove_all_write_access( return 1; } - // Before searching all the L1 page tables, check the typical culprit first - // - if ( (prediction = predict_writable_pte_page(d, readonly_gpfn)) ) - { - predicted_gpfn = prediction & PGT_mfn_mask; - if ( (predicted_smfn = __shadow_status(d, predicted_gpfn, PGT_l1_shadow)) && - (fixups = remove_all_write_access_in_ptpage(d, predicted_gpfn, predicted_smfn, readonly_gpfn, readonly_gmfn, write_refs, prediction)) ) - { - found += fixups; - if ( found == write_refs ) - { - perfc_incrc(remove_write_predicted); - return 1; - } - } - else - { - perfc_incrc(remove_write_bad_prediction); - decrease_writable_pte_prediction(d, readonly_gpfn, prediction); - } + if ( shadow_mode_external(d) ) { + if (write_refs-- == 0) + return 0; + + // Use the back pointer to locate the shadow page that can contain + // the PTE of interest + if ( (predicted_smfn = frame_table[readonly_gmfn].tlbflush_timestamp) ) { + found += remove_all_write_access_in_ptpage( + d, predicted_smfn, predicted_smfn, readonly_gpfn, readonly_gmfn, write_refs, 0); + if ( found == write_refs ) + return 0; + } } // Search all the shadow L1 page tables... @@ -1276,7 +1259,7 @@ static int remove_all_write_access( { found += remove_all_write_access_in_ptpage(d, a->gpfn_and_flags & PGT_mfn_mask, a->smfn, readonly_gpfn, readonly_gmfn, write_refs - found, a->gpfn_and_flags & PGT_mfn_mask); if ( found == write_refs ) - return 1; + return 0; } a = a->next; @@ -1376,7 +1359,7 @@ static int resync_all(struct domain *d, u32 stype) guest_l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) ) { need_flush |= validate_pte_change(d, guest1[i], &shadow1[i]); - + set_guest_back_ptr(d, shadow1[i], smfn, i); // can't update snapshots of linear page tables -- they // are used multiple times... // @@ -1604,6 +1587,8 @@ static void sync_all(struct domain *d) !shadow_get_page_from_l1e(npte, d) ) BUG(); *ppte = npte; + set_guest_back_ptr(d, npte, (entry->writable_pl1e) >> PAGE_SHIFT, + (entry->writable_pl1e & ~PAGE_MASK)/sizeof(l1_pgentry_t)); shadow_put_page_from_l1e(opte, d); unmap_domain_page(ppte); diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index dbdbd52a8a..0b88448181 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -1032,7 +1032,12 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) if ( !get_page_type(page, PGT_writable_page) ) BUG(); put_page_type(page); - + /* + * We use tlbflush_timestamp as back pointer to smfn, and need to + * clean up it. + */ + if ( shadow_mode_external(d) ) + page->tlbflush_timestamp = 0; list_ent = page->list.next; } } @@ -1390,18 +1395,6 @@ int shadow_mode_control(struct domain *d, dom0_shadow_control_t *sc) return rc; } -/* - * XXX KAF: Why is this VMX specific? - */ -void vmx_shadow_clear_state(struct domain *d) -{ - SH_VVLOG("%s:", __func__); - shadow_lock(d); - free_shadow_pages(d); - shadow_unlock(d); - update_pagetables(d->vcpu[0]); -} - unsigned long gpfn_to_mfn_foreign(struct domain *d, unsigned long gpfn) { @@ -1462,14 +1455,10 @@ shadow_hl2_table(struct domain *d, unsigned long gpfn, unsigned long gmfn, hl2 = map_domain_page(hl2mfn); -#ifdef __i386__ if ( shadow_mode_external(d) ) limit = L2_PAGETABLE_ENTRIES; else limit = DOMAIN_ENTRIES_PER_L2_PAGETABLE; -#else - limit = 0; /* XXX x86/64 XXX */ -#endif memset(hl2, 0, limit * sizeof(l1_pgentry_t)); @@ -1665,6 +1654,7 @@ void shadow_map_l1_into_current_l2(unsigned long va) min = i; if ( likely(i > max) ) max = i; + set_guest_back_ptr(d, sl1e, sl1mfn, i); } frame_table[sl1mfn].tlbflush_timestamp = @@ -2072,6 +2062,24 @@ free_writable_pte_predictions(struct domain *d) } } +static int fix_entry( + struct domain *d, + l1_pgentry_t *pt, u32 *found, int is_l1_shadow, u32 max_refs_to_find) +{ + l1_pgentry_t old = *pt; + l1_pgentry_t new = old; + + l1e_remove_flags(new,_PAGE_RW); + if ( is_l1_shadow && !shadow_get_page_from_l1e(new, d) ) + BUG(); + (*found)++; + *pt = new; + if ( is_l1_shadow ) + shadow_put_page_from_l1e(old, d); + + return (*found == max_refs_to_find); +} + static u32 remove_all_write_access_in_ptpage( struct domain *d, unsigned long pt_pfn, unsigned long pt_mfn, unsigned long readonly_gpfn, unsigned long readonly_gmfn, @@ -2088,49 +2096,28 @@ static u32 remove_all_write_access_in_ptpage( match = l1e_from_pfn(readonly_gmfn, flags); - // returns true if all refs have been found and fixed. - // - int fix_entry(int i) - { - l1_pgentry_t old = pt[i]; - l1_pgentry_t new = old; + if ( shadow_mode_external(d) ) { + i = (frame_table[readonly_gmfn].u.inuse.type_info & PGT_va_mask) + >> PGT_va_shift; - l1e_remove_flags(new,_PAGE_RW); - if ( is_l1_shadow && !shadow_get_page_from_l1e(new, d) ) - BUG(); - found++; - pt[i] = new; - if ( is_l1_shadow ) - shadow_put_page_from_l1e(old, d); - -#if 0 - printk("removed write access to pfn=%lx mfn=%lx in smfn=%lx entry %x " - "is_l1_shadow=%d\n", - readonly_gpfn, readonly_gmfn, pt_mfn, i, is_l1_shadow); -#endif - - return (found == max_refs_to_find); + if ( (i >= 0 && i <= L1_PAGETABLE_ENTRIES) && + !l1e_has_changed(pt[i], match, flags) && + fix_entry(d, &pt[i], &found, is_l1_shadow, max_refs_to_find) && + !prediction ) + goto out; } - i = readonly_gpfn & (L1_PAGETABLE_ENTRIES - 1); - if ( !l1e_has_changed(pt[i], match, flags) && fix_entry(i) ) - { - perfc_incrc(remove_write_fast_exit); - increase_writable_pte_prediction(d, readonly_gpfn, prediction); - unmap_domain_page(pt); - return found; - } - for (i = 0; i < L1_PAGETABLE_ENTRIES; i++) { - if ( unlikely(!l1e_has_changed(pt[i], match, flags)) && fix_entry(i) ) + if ( unlikely(!l1e_has_changed(pt[i], match, flags)) && + fix_entry(d, &pt[i], &found, is_l1_shadow, max_refs_to_find) ) break; } +out: unmap_domain_page(pt); return found; -#undef MATCH_ENTRY } int shadow_remove_all_write_access( @@ -2138,8 +2125,8 @@ int shadow_remove_all_write_access( { int i; struct shadow_status *a; - u32 found = 0, fixups, write_refs; - unsigned long prediction, predicted_gpfn, predicted_smfn; + u32 found = 0, write_refs; + unsigned long predicted_smfn; ASSERT(shadow_lock_is_acquired(d)); ASSERT(VALID_MFN(readonly_gmfn)); @@ -2169,27 +2156,19 @@ int shadow_remove_all_write_access( perfc_incrc(remove_write_no_work); return 1; } + + if ( shadow_mode_external(d) ) { + if (write_refs-- == 0) + return 0; - // Before searching all the L1 page tables, check the typical culprit first - // - if ( (prediction = predict_writable_pte_page(d, readonly_gpfn)) ) - { - predicted_gpfn = prediction & PGT_mfn_mask; - if ( (predicted_smfn = __shadow_status(d, predicted_gpfn, PGT_l1_shadow)) && - (fixups = remove_all_write_access_in_ptpage(d, predicted_gpfn, predicted_smfn, readonly_gpfn, readonly_gmfn, write_refs, prediction)) ) - { - found += fixups; - if ( found == write_refs ) - { - perfc_incrc(remove_write_predicted); - return 1; - } - } - else - { - perfc_incrc(remove_write_bad_prediction); - decrease_writable_pte_prediction(d, readonly_gpfn, prediction); - } + // Use the back pointer to locate the shadow page that can contain + // the PTE of interest + if ( (predicted_smfn = frame_table[readonly_gmfn].tlbflush_timestamp) ) { + found += remove_all_write_access_in_ptpage( + d, predicted_smfn, predicted_smfn, readonly_gpfn, readonly_gmfn, write_refs, 0); + if ( found == write_refs ) + return 0; + } } // Search all the shadow L1 page tables... @@ -2203,7 +2182,7 @@ int shadow_remove_all_write_access( { found += remove_all_write_access_in_ptpage(d, a->gpfn_and_flags & PGT_mfn_mask, a->smfn, readonly_gpfn, readonly_gmfn, write_refs - found, a->gpfn_and_flags & PGT_mfn_mask); if ( found == write_refs ) - return 1; + return 0; } a = a->next; @@ -2376,12 +2355,12 @@ static int resync_all(struct domain *d, u32 stype) l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) ) { need_flush |= validate_pte_change(d, guest1[i], &shadow1[i]); + set_guest_back_ptr(d, shadow1[i], smfn, i); // can't update snapshots of linear page tables -- they // are used multiple times... // // snapshot[i] = new_pte; - changed++; } } @@ -2530,6 +2509,8 @@ void __shadow_sync_all(struct domain *d) !shadow_get_page_from_l1e(npte, d) ) BUG(); *ppte = npte; + set_guest_back_ptr(d, npte, (entry->writable_pl1e) >> PAGE_SHIFT, + (entry->writable_pl1e & ~PAGE_MASK)/sizeof(l1_pgentry_t)); shadow_put_page_from_l1e(opte, d); unmap_domain_page(ppte); diff --git a/xen/arch/x86/shadow_public.c b/xen/arch/x86/shadow_public.c index 292ef81e7d..36266128df 100644 --- a/xen/arch/x86/shadow_public.c +++ b/xen/arch/x86/shadow_public.c @@ -1095,7 +1095,12 @@ int __shadow_mode_enable(struct domain *d, unsigned int mode) if ( !get_page_type(page, PGT_writable_page) ) BUG(); put_page_type(page); - + /* + * We use tlbflush_timestamp as back pointer to smfn, and need to + * clean up it. + */ + if ( shadow_mode_external(d) ) + page->tlbflush_timestamp = 0; list_ent = page->list.next; } } diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index 0e48038889..3e2f3b9d6a 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -718,6 +718,23 @@ shadow_unpin(unsigned long smfn) put_shadow_ref(smfn); } +/* + * SMP issue. The following code assumes the shadow lock is held. Re-visit + * when working on finer-gained locks for shadow. + */ +static inline void set_guest_back_ptr( + struct domain *d, l1_pgentry_t spte, unsigned long smfn, unsigned int index) +{ + if ( shadow_mode_external(d) ) { + unsigned long gmfn; + + ASSERT(shadow_lock_is_acquired(d)); + gmfn = l1e_get_pfn(spte); + frame_table[gmfn].tlbflush_timestamp = smfn; + frame_table[gmfn].u.inuse.type_info &= ~PGT_va_mask; + frame_table[gmfn].u.inuse.type_info |= (unsigned long) index << PGT_va_shift; + } +} /************************************************************************/ #if CONFIG_PAGING_LEVELS <= 2 @@ -1611,10 +1628,11 @@ shadow_set_l1e(unsigned long va, l1_pgentry_t new_spte, int create_l1_shadow) if ( l1e_get_flags(old_spte) & _PAGE_PRESENT ) shadow_put_page_from_l1e(old_spte, d); } + } + set_guest_back_ptr(d, new_spte, l2e_get_pfn(sl2e), l1_table_offset(va)); shadow_linear_pg_table[l1_linear_offset(va)] = new_spte; - shadow_update_min_max(l2e_get_pfn(sl2e), l1_table_offset(va)); } #endif From 1109d74507b5fa2276adcd406664261296268257 Mon Sep 17 00:00:00 2001 From: "jrb44@plym.cl.cam.ac.uk" Date: Thu, 13 Oct 2005 20:16:02 +0100 Subject: [PATCH 042/142] Fixed 64 bit Linux build. Fixes from Ian Pratt. extern declaration of bind_ipi was out of sync with the definition of the function. Signed-off-by: James Bulpin --- linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c index 349f0309e5..ef56d19e9a 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c @@ -683,7 +683,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) extern void hypervisor_callback(void); extern void failsafe_callback(void); extern void smp_trap_init(trap_info_t *); - int i; #endif /* * We can't use kernel_thread since we must avoid to @@ -1210,7 +1209,6 @@ void __cpuinit smp_cpus_done(unsigned int max_cpus) } #ifdef CONFIG_XEN -extern int bind_ipi_to_irq(int ipi); extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *); extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *); From 86d80f8f02e46957ebdf2a3823b703bd8f5123c1 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Thu, 13 Oct 2005 23:16:03 +0100 Subject: [PATCH 043/142] Patch for typo causing multiple output in xm list -l, courtesy of Laura Ramirez . Signed-off-by: Ewan Mellor --- tools/python/xen/xm/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 54d72195bc..3df329c9ac 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -233,7 +233,7 @@ def xm_list(args): if use_long: for dom in doms: - PrettyPrint.prettyprint(doms) + PrettyPrint.prettyprint(dom) else: domsinfo = map(parse_doms_info, doms) From 5dc12fe2424c7cbaffd1292083a5c30ecb9d965c Mon Sep 17 00:00:00 2001 From: "iap10@firebug.cl.cam.ac.uk" Date: Fri, 14 Oct 2005 01:42:34 +0100 Subject: [PATCH 044/142] Remove unused x86_64 functions. Signed-off-by: ian@xensource.com --- .../arch/xen/x86_64/kernel/smpboot.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c index ef56d19e9a..48abf11507 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c @@ -1246,21 +1246,6 @@ static void smp_intr_exit(void) unbind_ipi_from_irq(CALL_FUNCTION_VECTOR, cpu); } -extern void local_setup_timer_irq(void); -extern void local_teardown_timer_irq(void); - -void smp_suspend(void) -{ - local_teardown_timer_irq(); - smp_intr_exit(); -} - -void smp_resume(void) -{ - smp_intr_init(); - local_setup_timer_irq(); -} - void vcpu_prepare(int vcpu) { } From 30ce2a9295a53f989897497df0c195dc597b00d6 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 14 Oct 2005 15:40:48 +0100 Subject: [PATCH 045/142] Store an opaque handle (tools uuid) in the domain structure within Xen. Refactor GETVCPUCONTEXT into an op of the same name plus a new op GETVCPUINFO. Move the cpumap and cpu info arrays from GETDOMAININFO and move into new GETVCPUINFO. Signed-off-by: Keir Fraser --- tools/libxc/xc_core.c | 17 +-- tools/libxc/xc_domain.c | 22 ++- tools/libxc/xc_private.c | 9 +- tools/libxc/xenctrl.h | 13 +- tools/python/xen/lowlevel/xc/xc.c | 62 +++++--- tools/python/xen/xend/XendDomainInfo.py | 3 +- tools/python/xen/xm/main.py | 4 +- tools/xenstat/libxenstat/src/xen-interface.c | 11 +- xen/arch/x86/setup.c | 3 + xen/common/dom0_ops.c | 147 +++++++++---------- xen/common/keyhandler.c | 8 +- xen/include/public/dom0_ops.h | 28 +++- xen/include/public/xen.h | 2 + xen/include/xen/sched.h | 3 + 14 files changed, 179 insertions(+), 153 deletions(-) diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c index 7c24b0b0bf..4694c0fe2f 100644 --- a/tools/libxc/xc_core.c +++ b/tools/libxc/xc_core.c @@ -33,7 +33,7 @@ xc_domain_dumpcore(int xc_handle, unsigned long nr_pages; unsigned long *page_array; xc_dominfo_t info; - int i, j, vcpu_map_size, dump_fd; + int i, j, dump_fd; char *dump_mem, *dump_mem_start = NULL; struct xc_core_header header; vcpu_guest_context_t ctxt[MAX_VIRT_CPUS]; @@ -54,18 +54,9 @@ xc_domain_dumpcore(int xc_handle, goto error_out; } - vcpu_map_size = sizeof(info.vcpu_to_cpu) / sizeof(info.vcpu_to_cpu[0]); - - for (i = 0, j = 0; i < vcpu_map_size; i++) { - if (info.vcpu_to_cpu[i] == -1) { - continue; - } - if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[j])) { - PERROR("Could not get all vcpu contexts for domain"); - goto error_out; - } - j++; - } + for (i = 0, j = 0; i < 32; i++) + if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[j]) == 0) + j++; nr_pages = info.nr_pages; diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 2ce970962a..6404b3f307 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -11,6 +11,7 @@ int xc_domain_create(int xc_handle, uint32_t ssidref, + xen_domain_handle_t handle, uint32_t *pdomid) { int err; @@ -19,6 +20,7 @@ int xc_domain_create(int xc_handle, op.cmd = DOM0_CREATEDOMAIN; op.u.createdomain.domain = (domid_t)*pdomid; op.u.createdomain.ssidref = ssidref; + memcpy(op.u.createdomain.handle, handle, sizeof(xen_domain_handle_t)); if ( (err = do_dom0_op(xc_handle, &op)) != 0 ) return err; @@ -59,7 +61,7 @@ int xc_domain_destroy(int xc_handle, int xc_domain_pincpu(int xc_handle, uint32_t domid, int vcpu, - cpumap_t *cpumap) + cpumap_t cpumap) { dom0_op_t op; op.cmd = DOM0_PINCPUDOMAIN; @@ -112,10 +114,9 @@ int xc_domain_getinfo(int xc_handle, info->shared_info_frame = op.u.getdomaininfo.shared_info_frame; info->cpu_time = op.u.getdomaininfo.cpu_time; info->vcpus = op.u.getdomaininfo.n_vcpu; - memcpy(&info->vcpu_to_cpu, &op.u.getdomaininfo.vcpu_to_cpu, - sizeof(info->vcpu_to_cpu)); - memcpy(&info->cpumap, &op.u.getdomaininfo.cpumap, - sizeof(info->cpumap)); + + memcpy(info->handle, op.u.getdomaininfo.handle, + sizeof(xen_domain_handle_t)); next_domid = (uint16_t)op.u.getdomaininfo.domain + 1; info++; @@ -166,19 +167,14 @@ int xc_domain_get_vcpu_context(int xc_handle, op.u.getvcpucontext.vcpu = (uint16_t)vcpu; op.u.getvcpucontext.ctxt = ctxt; - if ( (ctxt != NULL) && - ((rc = mlock(ctxt, sizeof(*ctxt))) != 0) ) + if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 ) return rc; rc = do_dom0_op(xc_handle, &op); - if ( ctxt != NULL ) - safe_munlock(ctxt, sizeof(*ctxt)); + safe_munlock(ctxt, sizeof(*ctxt)); - if ( rc > 0 ) - return -ESRCH; - else - return rc; + return rc; } diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index c5ebf3ee39..94cc947400 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -256,16 +256,15 @@ long long xc_domain_get_cpu_usage( int xc_handle, domid_t domid, int vcpu ) { dom0_op_t op; - op.cmd = DOM0_GETVCPUCONTEXT; - op.u.getvcpucontext.domain = (domid_t)domid; - op.u.getvcpucontext.vcpu = (uint16_t)vcpu; - op.u.getvcpucontext.ctxt = NULL; + op.cmd = DOM0_GETVCPUINFO; + op.u.getvcpuinfo.domain = (domid_t)domid; + op.u.getvcpuinfo.vcpu = (uint16_t)vcpu; if ( (do_dom0_op(xc_handle, &op) < 0) ) { PERROR("Could not get info on domain"); return -1; } - return op.u.getvcpucontext.cpu_time; + return op.u.getvcpuinfo.cpu_time; } diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 158269caf7..a5bfb62ac8 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -123,23 +123,23 @@ int xc_waitdomain_core( */ typedef struct { - uint32_t domid; - uint32_t ssidref; + uint32_t domid; + uint32_t ssidref; unsigned int dying:1, crashed:1, shutdown:1, paused:1, blocked:1, running:1; unsigned int shutdown_reason; /* only meaningful if shutdown==1 */ unsigned long nr_pages; unsigned long shared_info_frame; - uint64_t cpu_time; + uint64_t cpu_time; unsigned long max_memkb; unsigned int vcpus; - int32_t vcpu_to_cpu[MAX_VIRT_CPUS]; - cpumap_t cpumap[MAX_VIRT_CPUS]; + xen_domain_handle_t handle; } xc_dominfo_t; typedef dom0_getdomaininfo_t xc_domaininfo_t; int xc_domain_create(int xc_handle, uint32_t ssidref, + xen_domain_handle_t handle, uint32_t *pdomid); @@ -194,7 +194,8 @@ int xc_domain_destroy(int xc_handle, int xc_domain_pincpu(int xc_handle, uint32_t domid, int vcpu, - cpumap_t *cpumap); + cpumap_t cpumap); + /** * This function will return information about one or more domains. It is * designed to iterate over the list of domains. If a single domain is diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 03f4ed2415..4108e1ff30 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -77,17 +77,41 @@ static PyObject *pyxc_domain_create(PyObject *self, { XcObject *xc = (XcObject *)self; - uint32_t dom = 0; - int ret; - uint32_t ssidref = 0x0; + uint32_t dom = 0; + int ret, i; + uint32_t ssidref = 0; + PyObject *pyhandle = NULL; + xen_domain_handle_t handle = { + 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef, + 0xde, 0xad, 0xbe, 0xef, 0xde, 0xad, 0xbe, 0xef }; - static char *kwd_list[] = { "dom", "ssidref", NULL }; + static char *kwd_list[] = { "dom", "ssidref", "handle", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|ii", kwd_list, - &dom, &ssidref)) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiO", kwd_list, + &dom, &ssidref, &pyhandle)) return NULL; - if ( (ret = xc_domain_create(xc->xc_handle, ssidref, &dom)) < 0 ) + if ( pyhandle != NULL ) + { + if ( !PyList_Check(pyhandle) || + (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) ) + { + out_exception: + errno = EINVAL; + PyErr_SetFromErrno(xc_error); + return NULL; + } + + for ( i = 0; i < sizeof(xen_domain_handle_t); i++ ) + { + PyObject *p = PyList_GetItem(pyhandle, i); + if ( !PyInt_Check(p) ) + goto out_exception; + handle[i] = (uint8_t)PyInt_AsLong(p); + } + } + + if ( (ret = xc_domain_create(xc->xc_handle, ssidref, handle, &dom)) < 0 ) return PyErr_SetFromErrno(xc_error); return PyInt_FromLong(dom); @@ -181,7 +205,7 @@ static PyObject *pyxc_domain_pincpu(PyObject *self, uint32_t dom; int vcpu = 0; - cpumap_t cpumap = 0xFFFFFFFF; + cpumap_t cpumap = ~0ULL; static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL }; @@ -189,7 +213,7 @@ static PyObject *pyxc_domain_pincpu(PyObject *self, &dom, &vcpu, &cpumap) ) return NULL; - if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, &cpumap) != 0 ) + if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, cpumap) != 0 ) return PyErr_SetFromErrno(xc_error); Py_INCREF(zero); @@ -223,7 +247,7 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, PyObject *kwds) { XcObject *xc = (XcObject *)self; - PyObject *list, *vcpu_list, *cpumap_list, *info_dict; + PyObject *list, *info_dict; uint32_t first_dom = 0; int max_doms = 1024, nr_doms, i, j; @@ -249,15 +273,9 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, list = PyList_New(nr_doms); for ( i = 0 ; i < nr_doms; i++ ) { - vcpu_list = PyList_New(MAX_VIRT_CPUS); - cpumap_list = PyList_New(MAX_VIRT_CPUS); - for ( j = 0; j < MAX_VIRT_CPUS; j++ ) { - PyList_SetItem( vcpu_list, j, - Py_BuildValue("i", info[i].vcpu_to_cpu[j])); - PyList_SetItem( cpumap_list, j, - Py_BuildValue("i", info[i].cpumap[j])); - } - + PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t)); + for ( j = 0; j < sizeof(xen_domain_handle_t); j++ ) + PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j])); info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" ",s:l,s:L,s:l,s:i,s:i}", "dom", info[i].domid, @@ -273,10 +291,8 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, "maxmem_kb", info[i].max_memkb, "ssidref", info[i].ssidref, "shutdown_reason", info[i].shutdown_reason); - PyDict_SetItemString( info_dict, "vcpu_to_cpu", vcpu_list ); - PyDict_SetItemString( info_dict, "cpumap", cpumap_list ); - PyList_SetItem( list, i, info_dict); - + PyDict_SetItemString(info_dict, "handle", pyhandle); + PyList_SetItem(list, i, info_dict); } free(info); diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 0ff379f7b9..612188db0c 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1377,8 +1377,7 @@ class XendDomainInfo: # target = 0 means use all processors if target > 0: # count the number of online vcpus (cpu values in v2c map >= 0) - vcpu_to_cpu = dom_get(dom)['vcpu_to_cpu'] - vcpus_online = len(filter(lambda x: x >= 0, vcpu_to_cpu)) + vcpus_online = dom_get(dom)['vcpus'] log.debug("found %d vcpus online", vcpus_online) # disable any extra vcpus that are online over the requested target diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 3df329c9ac..a3e35f993b 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -270,9 +270,9 @@ def parse_doms_info(info): vcpuinfo['dom'] = int(sxp.child_value(info, 'domid', '-1')) vcpuinfo['vcpu'] = int(count) vcpuinfo['cpu'] = int(cpu) - vcpuinfo['cpumap'] = int(cpumap[count])&mask + #vcpuinfo['cpumap'] = int(cpumap[count])&mask count = count + 1 - dominfo['vcpulist'].append(vcpuinfo) + #dominfo['vcpulist'].append(vcpuinfo) return dominfo def xm_brief_list(domsinfo): diff --git a/tools/xenstat/libxenstat/src/xen-interface.c b/tools/xenstat/libxenstat/src/xen-interface.c index 9358494d11..e0f9de7c07 100644 --- a/tools/xenstat/libxenstat/src/xen-interface.c +++ b/tools/xenstat/libxenstat/src/xen-interface.c @@ -178,16 +178,15 @@ long long xi_get_vcpu_usage(xi_handle *handle, unsigned int domain, unsigned int vcpu) { dom0_op_t op; - op.u.getvcpucontext.domain = domain; - op.u.getvcpucontext.vcpu = vcpu; - op.u.getvcpucontext.ctxt = NULL; + op.u.getvcpuinfo.domain = domain; + op.u.getvcpuinfo.vcpu = vcpu; - if (xi_make_dom0_op(handle, &op, DOM0_GETVCPUCONTEXT) < 0) { - perror("DOM0_GETVCPUCONTEXT Hypercall failed"); + if (xi_make_dom0_op(handle, &op, DOM0_GETVCPUINFO) < 0) { + perror("DOM0_GETVCPUINFO Hypercall failed"); return -1; } - return op.u.getvcpucontext.cpu_time; + return op.u.getvcpuinfo.cpu_time; } /* gets xen version information from hypervisor */ diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 5131250cbb..208142e119 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -420,6 +420,9 @@ void __init __start_xen(multiboot_info_t *mbi) nr_pages << (PAGE_SHIFT - 10)); total_pages = nr_pages; + /* Sanity check for unwanted bloat of dom0_op_t structure. */ + BUG_ON(sizeof(((dom0_op_t *)0)->u) != sizeof(((dom0_op_t *)0)->u.pad)); + init_frametable(); end_boot_allocator(); diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 458255d3db..d1d2bfcefa 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -48,26 +48,20 @@ static void getdomaininfo(struct domain *d, dom0_getdomaininfo_t *info) info->domain = d->domain_id; - memset(&info->vcpu_to_cpu, -1, sizeof(info->vcpu_to_cpu)); - memset(&info->cpumap, 0, sizeof(info->cpumap)); - /* * - domain is marked as blocked only if all its vcpus are blocked * - domain is marked as running if any of its vcpus is running - * - only map vcpus that aren't down. Note, at some point we may - * wish to demux the -1 value to indicate down vs. not-ever-booted */ for_each_vcpu ( d, v ) { - /* only map vcpus that are up */ - if ( !(test_bit(_VCPUF_down, &v->vcpu_flags)) ) - info->vcpu_to_cpu[v->vcpu_id] = v->processor; - info->cpumap[v->vcpu_id] = v->cpumap; - if ( !(v->vcpu_flags & VCPUF_blocked) ) - flags &= ~DOMFLAGS_BLOCKED; - if ( v->vcpu_flags & VCPUF_running ) - flags |= DOMFLAGS_RUNNING; cpu_time += v->cpu_time; - vcpu_count++; + if ( !test_bit(_VCPUF_down, &v->vcpu_flags) ) + { + if ( !(v->vcpu_flags & VCPUF_blocked) ) + flags &= ~DOMFLAGS_BLOCKED; + if ( v->vcpu_flags & VCPUF_running ) + flags |= DOMFLAGS_RUNNING; + vcpu_count++; + } } info->cpu_time = cpu_time; @@ -87,6 +81,8 @@ static void getdomaininfo(struct domain *d, dom0_getdomaininfo_t *info) info->tot_pages = d->tot_pages; info->max_pages = d->max_pages; info->shared_info_frame = __pa(d->shared_info) >> PAGE_SHIFT; + + memcpy(info->handle, d->handle, sizeof(xen_domain_handle_t)); } long do_dom0_op(dom0_op_t *u_dom0_op) @@ -214,6 +210,9 @@ long do_dom0_op(dom0_op_t *u_dom0_op) if ( (d = do_createdomain(dom, pro)) == NULL ) break; + memcpy(d->handle, op->u.createdomain.handle, + sizeof(xen_domain_handle_t)); + ret = 0; op->u.createdomain.domain = d->domain_id; @@ -288,8 +287,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) domid_t dom = op->u.pincpudomain.domain; struct domain *d = find_domain_by_id(dom); struct vcpu *v; - cpumap_t cpumap; - if ( d == NULL ) { @@ -320,26 +317,17 @@ long do_dom0_op(dom0_op_t *u_dom0_op) break; } - if ( copy_from_user(&cpumap, op->u.pincpudomain.cpumap, - sizeof(cpumap)) ) - { - ret = -EFAULT; - put_domain(d); - break; - } + v->cpumap = op->u.pincpudomain.cpumap; - /* update cpumap for this vcpu */ - v->cpumap = cpumap; - - if ( cpumap == CPUMAP_RUNANYWHERE ) + if ( v->cpumap == CPUMAP_RUNANYWHERE ) { clear_bit(_VCPUF_cpu_pinned, &v->vcpu_flags); } else { /* pick a new cpu from the usable map */ - int new_cpu = (int)find_first_set_bit(cpumap) % num_online_cpus(); - + int new_cpu; + new_cpu = (int)find_first_set_bit(v->cpumap) % num_online_cpus(); vcpu_pause(v); vcpu_migrate_cpu(v, new_cpu); set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags); @@ -394,6 +382,8 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; + + case DOM0_GETDOMAININFOLIST: { struct domain *d; @@ -446,66 +436,73 @@ long do_dom0_op(dom0_op_t *u_dom0_op) struct vcpu_guest_context *c; struct domain *d; struct vcpu *v; - int i; - d = find_domain_by_id(op->u.getvcpucontext.domain); - if ( d == NULL ) - { - ret = -ESRCH; + ret = -ESRCH; + if ( (d = find_domain_by_id(op->u.getvcpucontext.domain)) == NULL ) break; - } + ret = -EINVAL; if ( op->u.getvcpucontext.vcpu >= MAX_VIRT_CPUS ) - { - ret = -EINVAL; - put_domain(d); - break; - } + goto getvcpucontext_out; - /* find first valid vcpu starting from request. */ - v = NULL; - for ( i = op->u.getvcpucontext.vcpu; i < MAX_VIRT_CPUS; i++ ) - { - v = d->vcpu[i]; - if ( v != NULL && !(test_bit(_VCPUF_down, &v->vcpu_flags)) ) - break; - } - - if ( v == NULL ) - { - ret = -ESRCH; - put_domain(d); - break; - } + ret = -ESRCH; + v = d->vcpu[op->u.getvcpucontext.vcpu]; + if ( (v == NULL) || test_bit(_VCPUF_down, &v->vcpu_flags) ) + goto getvcpucontext_out; - op->u.getvcpucontext.cpu_time = v->cpu_time; + ret = -ENOMEM; + if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) + goto getvcpucontext_out; - if ( op->u.getvcpucontext.ctxt != NULL ) - { - if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) - { - ret = -ENOMEM; - put_domain(d); - break; - } + if ( v != current ) + vcpu_pause(v); - if ( v != current ) - vcpu_pause(v); + arch_getdomaininfo_ctxt(v,c); + ret = 0; - arch_getdomaininfo_ctxt(v,c); + if ( v != current ) + vcpu_unpause(v); - if ( v != current ) - vcpu_unpause(v); + if ( copy_to_user(op->u.getvcpucontext.ctxt, c, sizeof(*c)) ) + ret = -EFAULT; - if ( copy_to_user(op->u.getvcpucontext.ctxt, c, sizeof(*c)) ) - ret = -EINVAL; - - xfree(c); - } + xfree(c); if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) - ret = -EINVAL; + ret = -EFAULT; + getvcpucontext_out: + put_domain(d); + } + break; + + case DOM0_GETVCPUINFO: + { + struct domain *d; + struct vcpu *v; + + ret = -ESRCH; + if ( (d = find_domain_by_id(op->u.getvcpuinfo.domain)) == NULL ) + break; + + ret = -EINVAL; + if ( op->u.getvcpuinfo.vcpu >= MAX_VIRT_CPUS ) + goto getvcpuinfo_out; + + ret = -ESRCH; + v = d->vcpu[op->u.getvcpuinfo.vcpu]; + if ( (v == NULL) || test_bit(_VCPUF_down, &v->vcpu_flags) ) + goto getvcpuinfo_out; + + op->u.getvcpuinfo.cpu_time = v->cpu_time; + op->u.getvcpuinfo.cpu = v->processor; + op->u.getvcpuinfo.cpumap = v->cpumap; + ret = 0; + + if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) + ret = -EFAULT; + + getvcpuinfo_out: put_domain(d); } break; diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index f7136addda..0f1bbb9872 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -99,7 +99,7 @@ static void halt_machine(unsigned char key, struct cpu_user_regs *regs) static void do_task_queues(unsigned char key) { struct domain *d; - struct vcpu *v; + struct vcpu *v; s_time_t now = NOW(); printk("'%c' pressed -> dumping task queues (now=0x%X:%08X)\n", key, @@ -112,6 +112,12 @@ static void do_task_queues(unsigned char key) printk("Xen: DOM %u, flags=%lx refcnt=%d nr_pages=%d " "xenheap_pages=%d\n", d->domain_id, d->domain_flags, atomic_read(&d->refcnt), d->tot_pages, d->xenheap_pages); + printk(" handle=%02x%02x%02x%02x-%02x%02x%02x%02x-" + "%02x%02x%02x%02x-%02x%02x%02x%02x\n", + d->handle[ 0], d->handle[ 1], d->handle[ 2], d->handle[ 3], + d->handle[ 4], d->handle[ 5], d->handle[ 6], d->handle[ 7], + d->handle[ 8], d->handle[ 9], d->handle[10], d->handle[11], + d->handle[12], d->handle[13], d->handle[14], d->handle[15]); dump_pageframe_info(d); diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 3d6a524781..528f9afc69 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -45,6 +45,7 @@ typedef struct sched_adjdom_cmd dom0_adjustdom_t; typedef struct { /* IN parameters */ uint32_t ssidref; + xen_domain_handle_t handle; /* IN/OUT parameters. */ /* Identifier for new domain (auto-allocate if zero is specified). */ domid_t domain; @@ -88,9 +89,8 @@ typedef struct { unsigned long shared_info_frame; /* MFN of shared_info struct */ uint64_t cpu_time; uint32_t n_vcpu; - int32_t vcpu_to_cpu[MAX_VIRT_CPUS]; /* current mapping */ - cpumap_t cpumap[MAX_VIRT_CPUS]; /* allowable mapping */ uint32_t ssidref; + xen_domain_handle_t handle; } dom0_getdomaininfo_t; #define DOM0_SETDOMAININFO 13 @@ -180,9 +180,9 @@ typedef struct { #define DOM0_PINCPUDOMAIN 20 typedef struct { /* IN variables. */ - domid_t domain; - uint16_t vcpu; - cpumap_t *cpumap; + domid_t domain; + uint16_t vcpu; + cpumap_t cpumap; } dom0_pincpudomain_t; /* Get trace buffers machine base address */ @@ -352,12 +352,24 @@ typedef struct { #define DOM0_GETVCPUCONTEXT 37 typedef struct { + /* IN variables. */ domid_t domain; /* domain to be affected */ uint16_t vcpu; /* vcpu # */ - vcpu_guest_context_t *ctxt; /* NB. IN/OUT variable. */ - uint64_t cpu_time; + /* OUT variables. */ + vcpu_guest_context_t *ctxt; } dom0_getvcpucontext_t; +#define DOM0_GETVCPUINFO 43 +typedef struct { + /* IN variables. */ + domid_t domain; /* domain to be affected */ + uint16_t vcpu; /* vcpu # */ + /* OUT variables. */ + uint64_t cpu_time; + uint32_t cpu; /* current mapping */ + cpumap_t cpumap; /* allowable mapping */ +} dom0_getvcpuinfo_t; + #define DOM0_GETDOMAININFOLIST 38 typedef struct { /* IN variables. */ @@ -426,10 +438,12 @@ typedef struct { dom0_microcode_t microcode; dom0_ioport_permission_t ioport_permission; dom0_getvcpucontext_t getvcpucontext; + dom0_getvcpuinfo_t getvcpuinfo; dom0_getdomaininfolist_t getdomaininfolist; dom0_platform_quirk_t platform_quirk; dom0_physical_memory_map_t physical_memory_map; dom0_max_vcpus_t max_vcpus; + uint8_t pad[128]; } u; } dom0_op_t; diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index d6a3098f2f..c0111b5027 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -437,6 +437,8 @@ extern shared_info_t *HYPERVISOR_shared_info; typedef uint64_t cpumap_t; +typedef uint8_t xen_domain_handle_t[16]; + #endif /* !__ASSEMBLY__ */ #endif /* __XEN_PUBLIC_XEN_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 6f8a43d384..4250205268 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -139,6 +139,9 @@ struct domain struct arch_domain arch; void *ssid; /* sHype security subject identifier */ + + /* Control-plane tools handle for this domain. */ + xen_domain_handle_t handle; }; struct domain_setup_info From 349d3745d33362148579094f1d3c68a6091f04ae Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 14 Oct 2005 16:01:11 +0100 Subject: [PATCH 046/142] In addition to setting opaque handle during domain creation, allow it to be changed after creation via DOM0_SETDOMAINHANDLE operation (and libxc xc_domain_sethandle, and via Pyhton wrapper fn). Signed-off-by: Keir Fraser --- tools/libxc/xc_domain.c | 10 +++++++ tools/libxc/xenctrl.h | 2 ++ tools/python/xen/lowlevel/xc/xc.c | 49 +++++++++++++++++++++++++++++++ xen/common/dom0_ops.c | 15 ++++++++++ xen/include/public/dom0_ops.h | 6 ++++ 5 files changed, 82 insertions(+) diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 6404b3f307..4b43ed9bf9 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -334,6 +334,16 @@ int xc_domain_max_vcpus(int xc_handle, uint32_t domid, unsigned int max) return do_dom0_op(xc_handle, &op); } +int xc_domain_sethandle(int xc_handle, uint32_t domid, + xen_domain_handle_t handle) +{ + dom0_op_t op; + op.cmd = DOM0_SETDOMAINHANDLE; + op.u.setdomainhandle.domain = (domid_t)domid; + memcpy(op.u.setdomainhandle.handle, handle, sizeof(xen_domain_handle_t)); + return do_dom0_op(xc_handle, &op); +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index a5bfb62ac8..464810edf5 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -257,6 +257,8 @@ long long xc_domain_get_cpu_usage(int xc_handle, domid_t domid, int vcpu); +int xc_domain_sethandle(int xc_handle, uint32_t domid, + xen_domain_handle_t handle); typedef dom0_shadow_control_stats_t xc_shadow_control_stats_t; int xc_shadow_control(int xc_handle, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 4108e1ff30..bd554284ff 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -242,6 +242,47 @@ static PyObject *pyxc_domain_setcpuweight(PyObject *self, return zero; } +static PyObject *pyxc_domain_sethandle(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + + int i; + uint32_t dom; + PyObject *pyhandle; + xen_domain_handle_t handle; + + static char *kwd_list[] = { "dom", "handle", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iO", kwd_list, + &dom, &pyhandle) ) + return NULL; + + if ( !PyList_Check(pyhandle) || + (PyList_Size(pyhandle) != sizeof(xen_domain_handle_t)) ) + { + out_exception: + errno = EINVAL; + PyErr_SetFromErrno(xc_error); + return NULL; + } + + for ( i = 0; i < sizeof(xen_domain_handle_t); i++ ) + { + PyObject *p = PyList_GetItem(pyhandle, i); + if ( !PyInt_Check(p) ) + goto out_exception; + handle[i] = (uint8_t)PyInt_AsLong(p); + } + + if ( xc_domain_sethandle(xc->xc_handle, dom, handle) < 0 ) + return PyErr_SetFromErrno(xc_error); + + Py_INCREF(zero); + return zero; +} + static PyObject *pyxc_domain_getinfo(PyObject *self, PyObject *args, PyObject *kwds) @@ -873,6 +914,14 @@ static PyMethodDef pyxc_methods[] = { " cpuweight [float, 1]: VCPU being pinned.\n" "Returns: [int] 0 on success; -1 on error.\n" }, + { "domain_sethandle", + (PyCFunction)pyxc_domain_sethandle, + METH_VARARGS | METH_KEYWORDS, "\n" + "Set domain's opaque handle.\n" + " dom [int]: Identifier of domain.\n" + " handle [list of 16 ints]: New opaque handle.\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + { "domain_getinfo", (PyCFunction)pyxc_domain_getinfo, METH_VARARGS | METH_KEYWORDS, "\n" diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index d1d2bfcefa..9541adbbf8 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -557,6 +557,21 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; + case DOM0_SETDOMAINHANDLE: + { + struct domain *d; + ret = -ESRCH; + d = find_domain_by_id(op->u.setdomainhandle.domain); + if ( d != NULL ) + { + memcpy(d->handle, op->u.setdomainhandle.handle, + sizeof(xen_domain_handle_t)); + put_domain(d); + ret = 0; + } + } + break; + #ifdef PERF_COUNTERS case DOM0_PERFCCONTROL: { diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 528f9afc69..9402feb30e 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -405,6 +405,11 @@ typedef struct { unsigned int max; /* maximum number of vcpus */ } dom0_max_vcpus_t; +#define DOM0_SETDOMAINHANDLE 44 +typedef struct { + domid_t domain; + xen_domain_handle_t handle; +} dom0_setdomainhandle_t; typedef struct { uint32_t cmd; @@ -443,6 +448,7 @@ typedef struct { dom0_platform_quirk_t platform_quirk; dom0_physical_memory_map_t physical_memory_map; dom0_max_vcpus_t max_vcpus; + dom0_setdomainhandle_t setdomainhandle; uint8_t pad[128]; } u; } dom0_op_t; From 192fc23b5a39487b516e6488d2e5d3f70ede736a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 14 Oct 2005 18:27:25 +0100 Subject: [PATCH 047/142] This should fix time stopped / going slow problems that various users have been seeing. Signed-off-by: Keir Fraser --- xen/arch/x86/time.c | 51 ++++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index e7202174f8..f91c377999 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -61,13 +61,24 @@ struct cpu_time { static struct cpu_time cpu_time[NR_CPUS]; -/* Protected by platform_timer_lock. */ +/* + * Protected by platform_timer_lock, which must be acquired with interrupts + * disabled because pit_overflow() is called from PIT ch0 interrupt context. + */ static s_time_t stime_platform_stamp; static u64 platform_timer_stamp; static struct time_scale platform_timer_scale; static spinlock_t platform_timer_lock = SPIN_LOCK_UNLOCKED; static u64 (*read_platform_count)(void); +/* + * Folding 16-bit PIT into 64-bit software counter is a really critical + * operation! We therefore do it directly in PIT ch0 interrupt handler, + * based on this flag. + */ +static int using_pit; +static void pit_overflow(void); + /* * 32-bit division of integer dividend and integer divisor yielding * 32-bit fractional quotient. @@ -135,14 +146,16 @@ static inline u64 scale_delta(u64 delta, struct time_scale *scale) void timer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) { + ASSERT(local_irq_is_enabled()); + if ( timer_ack ) { extern spinlock_t i8259A_lock; - spin_lock(&i8259A_lock); + spin_lock_irq(&i8259A_lock); outb(0x0c, 0x20); /* Ack the IRQ; AEOI will end it automatically. */ inb(0x20); - spin_unlock(&i8259A_lock); + spin_unlock_irq(&i8259A_lock); } /* Update jiffies counter. */ @@ -151,6 +164,9 @@ void timer_interrupt(int irq, void *dev_id, struct cpu_user_regs *regs) /* Rough hack to allow accurate timers to sort-of-work with no APIC. */ if ( !cpu_has_apic ) raise_softirq(AC_TIMER_SOFTIRQ); + + if ( using_pit ) + pit_overflow(); } static struct irqaction irq0 = { timer_interrupt, "timer", NULL}; @@ -280,7 +296,6 @@ static char *freq_string(u64 freq) /* Protected by platform_timer_lock. */ static u64 pit_counter64; static u16 pit_stamp; -static struct ac_timer pit_overflow_timer; static u16 pit_read_counter(void) { @@ -292,17 +307,15 @@ static u16 pit_read_counter(void) return count; } -static void pit_overflow(void *unused) +static void pit_overflow(void) { u16 counter; - spin_lock(&platform_timer_lock); + spin_lock_irq(&platform_timer_lock); counter = pit_read_counter(); pit_counter64 += (u16)(pit_stamp - counter); pit_stamp = counter; - spin_unlock(&platform_timer_lock); - - set_ac_timer(&pit_overflow_timer, NOW() + MILLISECS(20)); + spin_unlock_irq(&platform_timer_lock); } static u64 read_pit_count(void) @@ -314,12 +327,12 @@ static int init_pit(void) { read_platform_count = read_pit_count; - init_ac_timer(&pit_overflow_timer, pit_overflow, NULL, 0); - pit_overflow(NULL); + pit_overflow(); platform_timer_stamp = pit_counter64; set_time_scale(&platform_timer_scale, CLOCK_TICK_RATE); printk("Platform timer is %s PIT\n", freq_string(CLOCK_TICK_RATE)); + using_pit = 1; return 1; } @@ -337,11 +350,11 @@ static void hpet_overflow(void *unused) { u32 counter; - spin_lock(&platform_timer_lock); + spin_lock_irq(&platform_timer_lock); counter = hpet_read32(HPET_COUNTER); hpet_counter64 += (u32)(counter - hpet_stamp); hpet_stamp = counter; - spin_unlock(&platform_timer_lock); + spin_unlock_irq(&platform_timer_lock); set_ac_timer(&hpet_overflow_timer, NOW() + hpet_overflow_period); } @@ -455,11 +468,11 @@ static void cyclone_overflow(void *unused) { u32 counter; - spin_lock(&platform_timer_lock); + spin_lock_irq(&platform_timer_lock); counter = *cyclone_timer; cyclone_counter64 += (u32)(counter - cyclone_stamp); cyclone_stamp = counter; - spin_unlock(&platform_timer_lock); + spin_unlock_irq(&platform_timer_lock); set_ac_timer(&cyclone_overflow_timer, NOW() + MILLISECS(20000)); } @@ -526,10 +539,10 @@ static s_time_t read_platform_stime(void) u64 counter; s_time_t stime; - spin_lock(&platform_timer_lock); + spin_lock_irq(&platform_timer_lock); counter = read_platform_count(); stime = __read_platform_stime(counter); - spin_unlock(&platform_timer_lock); + spin_unlock_irq(&platform_timer_lock); return stime; } @@ -539,12 +552,12 @@ static void platform_time_calibration(void) u64 counter; s_time_t stamp; - spin_lock(&platform_timer_lock); + spin_lock_irq(&platform_timer_lock); counter = read_platform_count(); stamp = __read_platform_stime(counter); stime_platform_stamp = stamp; platform_timer_stamp = counter; - spin_unlock(&platform_timer_lock); + spin_unlock_irq(&platform_timer_lock); } static void init_platform_timer(void) From 37df8941646e7f5b9399d6ff6a21803aa281007b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 14 Oct 2005 22:15:21 +0100 Subject: [PATCH 048/142] machine_specific_memory_setup() makes the following call to setup e820: add_memory_region(0, PFN_PHYS(max_pfn), E820_RAM); Since max_pfn is (rightly) an unsigned long, we overflow for the current definition of PFN_PHYS. Attached is my preferred solution as it will hopefully avoid similar situations that may come up in the future. Signed-off-by: srparish@us.ibm.com --- linux-2.6-xen-sparse/include/asm-xen/asm-i386/setup.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/setup.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/setup.h index 5161768219..5fd2eadc12 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/setup.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/setup.h @@ -8,7 +8,7 @@ #define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) #define PFN_DOWN(x) ((x) >> PAGE_SHIFT) -#define PFN_PHYS(x) ((x) << PAGE_SHIFT) +#define PFN_PHYS(x) ((unsigned long long)(x) << PAGE_SHIFT) /* * Reserved space for vmalloc and iomap - defined in asm/page.h From 6a5cdc1492f3b4021be1bca651184e794c412035 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 00:20:35 +0100 Subject: [PATCH 049/142] Enable hotplug cpus in -xen x86_32 kernel. Suggested by Ryan Harper Signed-off-by: ian@xensource.com --- .../arch/xen/configs/xen_defconfig_x86_32 | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 index 9321cfb0cf..63e1d4cc9c 100644 --- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 +++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.12-xen -# Wed Aug 3 10:04:25 2005 +# Linux kernel version: 2.6.12-xen0 +# Sat Oct 15 00:13:28 2005 # CONFIG_XEN=y CONFIG_ARCH_XEN=y @@ -151,17 +151,15 @@ CONFIG_HAVE_DEC_LOCK=y # CONFIG_REGPARM is not set CONFIG_X86_LOCAL_APIC=y CONFIG_X86_IO_APIC=y -# CONFIG_HOTPLUG_CPU is not set +CONFIG_HOTPLUG_CPU=y # # Bus options (PCI, PCMCIA, EISA, MCA, ISA) # CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set # CONFIG_PCI_GOMMCONFIG is not set # CONFIG_PCI_GODIRECT is not set CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y CONFIG_PCI_DIRECT=y CONFIG_PCI_MMCONFIG=y # CONFIG_PCIEPORTBUS is not set @@ -199,8 +197,6 @@ CONFIG_PCCARD_NONSTATIC=m # CONFIG_HOTPLUG_PCI=m CONFIG_HOTPLUG_PCI_FAKE=m -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_IBM is not set # CONFIG_HOTPLUG_PCI_ACPI is not set CONFIG_HOTPLUG_PCI_CPCI=y CONFIG_HOTPLUG_PCI_CPCI_ZT5550=m @@ -2667,6 +2663,7 @@ CONFIG_ACPI_BUTTON=m CONFIG_ACPI_VIDEO=m CONFIG_ACPI_FAN=m CONFIG_ACPI_PROCESSOR=m +# CONFIG_ACPI_HOTPLUG_CPU is not set CONFIG_ACPI_THERMAL=m CONFIG_ACPI_ASUS=m CONFIG_ACPI_IBM=m @@ -2694,7 +2691,7 @@ CONFIG_EXT3_FS_POSIX_ACL=y CONFIG_EXT3_FS_SECURITY=y CONFIG_JBD=m # CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=m +CONFIG_FS_MBCACHE=y CONFIG_REISERFS_FS=m # CONFIG_REISERFS_CHECK is not set # CONFIG_REISERFS_PROC_INFO is not set From b606206a63620d4969e0ddc6de62675ab6ffdf6e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 07:43:08 +0100 Subject: [PATCH 050/142] add BT instruction support to VMX MMIO decoder. Also extends TEST and OR instructions support for 16/32 bit operations, these are needed for windows. Signed-off-by: Xin Li Signed-off-by: Chengyuan Li Signed-off-by: Nakajima Jun --- xen/arch/x86/vmx_io.c | 11 +++ xen/arch/x86/vmx_platform.c | 103 +++++++++++++++++++++-------- xen/include/asm-x86/vmx_platform.h | 5 +- 3 files changed, 90 insertions(+), 29 deletions(-) diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 8809d21704..1d904e43a9 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -624,6 +624,17 @@ static void vmx_mmio_assist(struct cpu_user_regs *regs, ioreq_t *p, set_eflags_SF(size, diff, regs); set_eflags_PF(size, diff, regs); break; + + case INSTR_BT: + index = operand_index(src); + value = get_reg_value(size, index, 0, regs); + + if (p->u.data & (1 << (value & ((1 << 5) - 1)))) + regs->eflags |= X86_EFLAGS_CF; + else + regs->eflags &= ~X86_EFLAGS_CF; + + break; } load_cpu_user_regs(regs); diff --git a/xen/arch/x86/vmx_platform.c b/xen/arch/x86/vmx_platform.c index cd1a5b3b02..87647ef1f7 100644 --- a/xen/arch/x86/vmx_platform.c +++ b/xen/arch/x86/vmx_platform.c @@ -371,7 +371,7 @@ static int vmx_decode(unsigned char *opcode, struct instruction *instr) unsigned long eflags; int index, vm86 = 0; unsigned char rex = 0; - unsigned char tmp_size = 0; + unsigned char size_reg = 0; init_instruction(instr); @@ -428,33 +428,47 @@ static int vmx_decode(unsigned char *opcode, struct instruction *instr) case 0x80: case 0x81: - if (((opcode[1] >> 3) & 7) == 7) { /* cmp $imm, m32/16 */ - instr->instr = INSTR_CMP; + { + unsigned char ins_subtype = (opcode[1] >> 3) & 7; - if (opcode[0] == 0x80) - GET_OP_SIZE_FOR_BYTE(instr->op_size); - else + if (opcode[0] == 0x80) { + GET_OP_SIZE_FOR_BYTE(size_reg); + instr->op_size = BYTE; + } else { GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); + size_reg = instr->op_size; + } - instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE); - instr->immediate = get_immediate(vm86, opcode+1, BYTE); - instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY); + instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE); + instr->immediate = get_immediate(vm86, opcode+1, instr->op_size); + instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY); - return DECODE_success; - } else - return DECODE_failure; + switch (ins_subtype) { + case 7: /* cmp $imm, m32/16 */ + instr->instr = INSTR_CMP; + return DECODE_success; + + case 1: /* or $imm, m32/16 */ + instr->instr = INSTR_OR; + return DECODE_success; + + default: + printf("%x, This opcode isn't handled yet!\n", *opcode); + return DECODE_failure; + } + } case 0x84: /* test m8, r8 */ instr->instr = INSTR_TEST; instr->op_size = BYTE; - GET_OP_SIZE_FOR_BYTE(tmp_size); - return mem_reg(tmp_size, opcode, instr, rex); + GET_OP_SIZE_FOR_BYTE(size_reg); + return mem_reg(size_reg, opcode, instr, rex); case 0x88: /* mov r8, m8 */ instr->instr = INSTR_MOV; instr->op_size = BYTE; - GET_OP_SIZE_FOR_BYTE(tmp_size); - return reg_mem(tmp_size, opcode, instr, rex); + GET_OP_SIZE_FOR_BYTE(size_reg); + return reg_mem(size_reg, opcode, instr, rex); case 0x89: /* mov r32/16, m32/16 */ instr->instr = INSTR_MOV; @@ -464,8 +478,8 @@ static int vmx_decode(unsigned char *opcode, struct instruction *instr) case 0x8A: /* mov m8, r8 */ instr->instr = INSTR_MOV; instr->op_size = BYTE; - GET_OP_SIZE_FOR_BYTE(tmp_size); - return mem_reg(tmp_size, opcode, instr, rex); + GET_OP_SIZE_FOR_BYTE(size_reg); + return mem_reg(size_reg, opcode, instr, rex); case 0x8B: /* mov m32/16, r32/16 */ instr->instr = INSTR_MOV; @@ -475,8 +489,8 @@ static int vmx_decode(unsigned char *opcode, struct instruction *instr) case 0xA0: /* mov , al */ instr->instr = INSTR_MOV; instr->op_size = BYTE; - GET_OP_SIZE_FOR_BYTE(tmp_size); - return mem_acc(tmp_size, instr); + GET_OP_SIZE_FOR_BYTE(size_reg); + return mem_acc(size_reg, instr); case 0xA1: /* mov , ax/eax */ instr->instr = INSTR_MOV; @@ -486,8 +500,8 @@ static int vmx_decode(unsigned char *opcode, struct instruction *instr) case 0xA2: /* mov al, */ instr->instr = INSTR_MOV; instr->op_size = BYTE; - GET_OP_SIZE_FOR_BYTE(tmp_size); - return acc_mem(tmp_size, instr); + GET_OP_SIZE_FOR_BYTE(size_reg); + return acc_mem(size_reg, instr); case 0xA3: /* mov ax/eax, */ instr->instr = INSTR_MOV; @@ -541,13 +555,21 @@ static int vmx_decode(unsigned char *opcode, struct instruction *instr) return DECODE_failure; case 0xF6: - if (((opcode[1] >> 3) & 7) == 0) { /* testb $imm8, m8 */ + case 0xF7: + if (((opcode[1] >> 3) & 7) == 0) { /* test $imm8/16/32, m8/16/32 */ instr->instr = INSTR_TEST; - instr->op_size = BYTE; - instr->operand[0] = mk_operand(instr->op_size, 0, 0, IMMEDIATE); + if (opcode[0] == 0xF6) { + GET_OP_SIZE_FOR_BYTE(size_reg); + instr->op_size = BYTE; + } else { + GET_OP_SIZE_FOR_NONEBYTE(instr->op_size); + size_reg = instr->op_size; + } + + instr->operand[0] = mk_operand(size_reg, 0, 0, IMMEDIATE); instr->immediate = get_immediate(vm86, opcode+1, instr->op_size); - instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY); + instr->operand[1] = mk_operand(size_reg, 0, 0, MEMORY); return DECODE_success; } else @@ -583,6 +605,14 @@ static int vmx_decode(unsigned char *opcode, struct instruction *instr) instr->operand[0] = mk_operand(instr->op_size, 0, 0, MEMORY); return DECODE_success; + case 0xA3: /* bt r32, m32 */ + instr->instr = INSTR_BT; + index = get_index(opcode + 1, rex); + instr->op_size = LONG; + instr->operand[0] = mk_operand(instr->op_size, index, 0, REGISTER); + instr->operand[1] = mk_operand(instr->op_size, 0, 0, MEMORY); + return DECODE_success; + default: printf("0f %x, This opcode isn't handled yet\n", *opcode); return DECODE_failure; @@ -843,9 +873,28 @@ void handle_mmio(unsigned long va, unsigned long gpa) mmio_opp->immediate = mmio_inst.immediate; /* send the request and wait for the value */ - send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, mmio_inst.op_size, 0, IOREQ_READ, 0); + send_mmio_req(IOREQ_TYPE_COPY, gpa, 1, + mmio_inst.op_size, 0, IOREQ_READ, 0); break; + case INSTR_BT: + { + unsigned long value = 0; + int index, size; + + mmio_opp->instr = mmio_inst.instr; + mmio_opp->operand[0] = mmio_inst.operand[0]; /* bit offset */ + mmio_opp->operand[1] = mmio_inst.operand[1]; /* bit base */ + + index = operand_index(mmio_inst.operand[0]); + size = operand_size(mmio_inst.operand[0]); + value = get_reg_value(size, index, 0, regs); + + send_mmio_req(IOREQ_TYPE_COPY, gpa + (value >> 5), 1, + mmio_inst.op_size, 0, IOREQ_READ, 0); + break; + } + default: printf("Unhandled MMIO instruction\n"); domain_crash_synchronous(); diff --git a/xen/include/asm-x86/vmx_platform.h b/xen/include/asm-x86/vmx_platform.h index a7a0e80641..1dd3cf7c74 100644 --- a/xen/include/asm-x86/vmx_platform.h +++ b/xen/include/asm-x86/vmx_platform.h @@ -27,8 +27,8 @@ #define MAX_OPERAND_NUM 2 -#define mk_operand(size, index, seg, flag) \ - (((size) << 24) | ((index) << 16) | ((seg) << 8) | (flag)) +#define mk_operand(size_reg, index, seg, flag) \ + (((size_reg) << 24) | ((index) << 16) | ((seg) << 8) | (flag)) #define operand_size(operand) \ ((operand >> 24) & 0xFF) @@ -63,6 +63,7 @@ #define INSTR_MOVZ 8 #define INSTR_STOS 9 #define INSTR_TEST 10 +#define INSTR_BT 11 struct instruction { __s8 instr; /* instruction type */ From 0044805a7385869eac2dc522808fc533a2abb8f5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 08:33:19 +0100 Subject: [PATCH 051/142] Fix NAT for domU checksum offload. Signed-off-by: Jon Mason --- patches/linux-2.6.12/net-csum.patch | 45 +++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/patches/linux-2.6.12/net-csum.patch b/patches/linux-2.6.12/net-csum.patch index 37a1fbf9c1..4f744a250f 100644 --- a/patches/linux-2.6.12/net-csum.patch +++ b/patches/linux-2.6.12/net-csum.patch @@ -9,3 +9,48 @@ diff -ur linux-2.6.11/net/ipv4/netfilter/ip_conntrack_proto_udp.c linux-2.6.11-c && csum_tcpudp_magic(iph->saddr, iph->daddr, udplen, IPPROTO_UDP, skb->ip_summed == CHECKSUM_HW ? skb->csum : skb_checksum(skb, iph->ihl*4, udplen, 0))) { + +--- ../xen-unstable.hg/linux-2.6.12-xen0/net/ipv4/netfilter/ip_nat_proto_udp.c 2005-06-17 14:48:29.000000000 -0500 ++++ linux-2.6-xen-sparse/net/ipv4/netfilter/ip_nat_proto_udp.c 2005-10-14 15:17:53.000000000 -0500 +@@ -112,11 +112,19 @@ udp_manip_pkt(struct sk_buff **pskb, + newport = tuple->dst.u.udp.port; + portptr = &hdr->dest; + } +- if (hdr->check) /* 0 is a special case meaning no checksum */ +- hdr->check = ip_nat_cheat_check(~oldip, newip, ++ ++ if (hdr->check) { /* 0 is a special case meaning no checksum */ ++ if ((*pskb)->proto_csum_blank) { ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, ++ ip_nat_cheat_check(*portptr ^ 0xFFFF, ++ newport, hdr->check)); ++ } else { ++ hdr->check = ip_nat_cheat_check(~oldip, newip, + ip_nat_cheat_check(*portptr ^ 0xFFFF, + newport, + hdr->check)); ++ } ++ } + *portptr = newport; + return 1; + } +--- ../xen-unstable.hg/linux-2.6.12-xen0/net/ipv4/netfilter/ip_nat_proto_tcp.c 2005-06-17 14:48:29.000000000 -0500 ++++ linux-2.6-xen-sparse/net/ipv4/netfilter/ip_nat_proto_tcp.c 2005-10-14 16:41:20.000000000 -0500 +@@ -127,10 +127,16 @@ tcp_manip_pkt(struct sk_buff **pskb, + if (hdrsize < sizeof(*hdr)) + return 1; + +- hdr->check = ip_nat_cheat_check(~oldip, newip, ++ if ((*pskb)->proto_csum_blank) { ++ hdr->check = ip_nat_cheat_check(oldip, ~newip, ++ ip_nat_cheat_check(oldport ^ 0xFFFF, ++ newport, hdr->check)); ++ } else { ++ hdr->check = ip_nat_cheat_check(~oldip, newip, + ip_nat_cheat_check(oldport ^ 0xFFFF, + newport, + hdr->check)); ++ } + return 1; + } + From 5519fdc24af5a81d62547b094dbb9cd5ce1c7b3a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 08:52:22 +0100 Subject: [PATCH 052/142] Extend VCPUINFO dom0_op to return status information about run state of the VCPU. VCPUCONTEXT returns info about hotplugged VCPUs. Signed-off-by: Keir Fraser --- xen/common/dom0_ops.c | 8 +++++--- xen/include/public/dom0_ops.h | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 9541adbbf8..5d1f17adc7 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -447,7 +447,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) ret = -ESRCH; v = d->vcpu[op->u.getvcpucontext.vcpu]; - if ( (v == NULL) || test_bit(_VCPUF_down, &v->vcpu_flags) ) + if ( (v == NULL) || !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) goto getvcpucontext_out; ret = -ENOMEM; @@ -490,10 +490,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op) goto getvcpuinfo_out; ret = -ESRCH; - v = d->vcpu[op->u.getvcpuinfo.vcpu]; - if ( (v == NULL) || test_bit(_VCPUF_down, &v->vcpu_flags) ) + if ( (v = d->vcpu[op->u.getvcpuinfo.vcpu]) == NULL ) goto getvcpuinfo_out; + op->u.getvcpuinfo.online = !test_bit(_VCPUF_down, &v->vcpu_flags); + op->u.getvcpuinfo.blocked = test_bit(_VCPUF_blocked, &v->vcpu_flags); + op->u.getvcpuinfo.running = test_bit(_VCPUF_running, &v->vcpu_flags); op->u.getvcpuinfo.cpu_time = v->cpu_time; op->u.getvcpuinfo.cpu = v->processor; op->u.getvcpuinfo.cpumap = v->cpumap; diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 9402feb30e..9556d43f57 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -365,7 +365,10 @@ typedef struct { domid_t domain; /* domain to be affected */ uint16_t vcpu; /* vcpu # */ /* OUT variables. */ - uint64_t cpu_time; + uint8_t online; /* currently online (not hotplugged)? */ + uint8_t blocked; /* blocked waiting for an event? */ + uint8_t running; /* currently scheduled on its CPU? */ + uint64_t cpu_time; /* total cpu time consumed (ns) */ uint32_t cpu; /* current mapping */ cpumap_t cpumap; /* allowable mapping */ } dom0_getvcpuinfo_t; From a9634a6106b5ea444557428333dd717e861b2b8c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 09:32:10 +0100 Subject: [PATCH 053/142] At least for the time being, GETVCPUCONTEXT needs to work even for uninitialised VCPUs. xc_linux_build() depends on it (rather stupidly). Signed-off-by: Keir Fraser --- xen/common/dom0_ops.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 5d1f17adc7..9c682dffce 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -446,8 +446,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) goto getvcpucontext_out; ret = -ESRCH; - v = d->vcpu[op->u.getvcpucontext.vcpu]; - if ( (v == NULL) || !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + if ( (v = d->vcpu[op->u.getvcpucontext.vcpu]) == NULL ) goto getvcpucontext_out; ret = -ENOMEM; From 9f7fae040f0dda775703f4c5f3731230bd5f6f68 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Sat, 15 Oct 2005 12:52:38 +0100 Subject: [PATCH 054/142] Added --tidy flag to xenstore-rm that recursively removes any empty directories left by the primary removal. Signed-off-by: Ewan Mellor --- tools/xenstore/xenstore_client.c | 81 ++++++++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 8 deletions(-) diff --git a/tools/xenstore/xenstore_client.c b/tools/xenstore/xenstore_client.c index f70f95557c..d18b2de5e1 100644 --- a/tools/xenstore/xenstore_client.c +++ b/tools/xenstore/xenstore_client.c @@ -24,15 +24,32 @@ usage(const char *progname) errx(1, "Usage: %s [-h] [-p] [-s] key [...]", progname); #elif defined(CLIENT_write) errx(1, "Usage: %s [-h] [-s] key value [...]", progname); -#elif defined(CLIENT_rm) || defined(CLIENT_exists) || defined(CLIENT_list) +#elif defined(CLIENT_rm) + errx(1, "Usage: %s [-h] [-s] [-t] key [...]", progname); +#elif defined(CLIENT_exists) || defined(CLIENT_list) errx(1, "Usage: %s [-h] [-s] key [...]", progname); #endif } +#if defined(CLIENT_rm) +static int +do_rm(char * path, struct xs_handle *xsh, struct xs_transaction_handle *xth) +{ + if (xs_rm(xsh, xth, path)) { + return 0; + } + else { + warnx("could not remove path %s", path); + return 1; + } +} +#endif + + static int perform(int optind, int argc, char **argv, struct xs_handle *xsh, - struct xs_transaction_handle *xth, int prefix) + struct xs_transaction_handle *xth, int prefix, int tidy) { while (optind < argc) { #if defined(CLIENT_read) @@ -54,10 +71,49 @@ perform(int optind, int argc, char **argv, struct xs_handle *xsh, } optind += 2; #elif defined(CLIENT_rm) - if (!xs_rm(xsh, xth, argv[optind])) { - warnx("could not remove path %s", argv[optind]); - return 1; - } + /* Remove the specified path. If the tidy flag is set, then also + remove any containing directories that are both empty and have no + value attached, and repeat, recursing all the way up to the root if + necessary. + */ + + char *path = argv[optind]; + + if (tidy) { + /* Copy path, because we can't modify argv because we will need it + again if xs_transaction_end gives us EAGAIN. */ + char *p = malloc(strlen(path) + 1); + strcpy(p, path); + path = p; + + again: + if (do_rm(path, xsh, xth)) { + return 1; + } + + char *slash = strrchr(p, '/'); + if (slash) { + char *val; + *slash = '\0'; + val = xs_read(xsh, xth, p, NULL); + if (val && strlen(val) == 0) { + unsigned int num; + char ** list = xs_directory(xsh, xth, p, &num); + + if (list && num == 0) { + goto again; + } + } + } + + free(path); + } + else { + if (do_rm(path, xsh, xth)) { + return 1; + } + } + optind++; #elif defined(CLIENT_exists) char *val = xs_read(xsh, xth, argv[optind], NULL); @@ -94,21 +150,26 @@ main(int argc, char **argv) struct xs_transaction_handle *xth; int ret = 0, socket = 0; int prefix = 0; + int tidy = 0; while (1) { int c, index = 0; static struct option long_options[] = { {"help", 0, 0, 'h'}, + {"socket", 0, 0, 's'}, #if defined(CLIENT_read) || defined(CLIENT_list) {"prefix", 0, 0, 'p'}, +#elif defined(CLIENT_rm) + {"tidy", 0, 0, 't'}, #endif - {"socket", 0, 0, 's'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "hs" #if defined(CLIENT_read) || defined(CLIENT_list) "p" +#elif defined(CLIENT_rm) + "t" #endif , long_options, &index); if (c == -1) @@ -125,6 +186,10 @@ main(int argc, char **argv) case 'p': prefix = 1; break; +#elif defined(CLIENT_rm) + case 't': + tidy = 1; + break; #endif } } @@ -149,7 +214,7 @@ main(int argc, char **argv) if (xth == NULL) errx(1, "couldn't start transaction"); - ret = perform(optind, argc, argv, xsh, xth, prefix); + ret = perform(optind, argc, argv, xsh, xth, prefix, tidy); if (!xs_transaction_end(xsh, xth, ret)) { if (ret == 0 && errno == EAGAIN) From 86234f86b5c644686c03aaceccdf78f089cb9f77 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Sat, 15 Oct 2005 12:55:03 +0100 Subject: [PATCH 055/142] Fix installation decision to make the DISTDIR and DESTDIR absolute before comparing them. Signed-off-by: Ewan Mellor --- tools/examples/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/examples/Makefile b/tools/examples/Makefile index 83a9f7c101..f94a222466 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -32,7 +32,9 @@ XEN_HOTPLUG_SCRIPTS = xen-backend.agent UDEV_RULES_DIR = /etc/udev/rules.d UDEV_RULES = xen-backend.rules -ifeq ($(findstring $(DISTDIR),$(DESTDIR)),$(DISTDIR)) +DI = $(shell readlink -f $(DISTDIR)) +DE = $(shell readlink -f $(DESTDIR)) +ifeq ($(findstring $(DI),$(DE)),$(DI)) HOTPLUGS=install-hotplug install-udev else ifeq ($(shell [ -x /sbin/udev ] && [ ! -z `udev -V` ] && [ `/sbin/udev -V` -ge 059 ] && echo 1),1) From da1385d8e8f7176e1c437fae1d7b727215b213c6 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Sat, 15 Oct 2005 12:56:07 +0100 Subject: [PATCH 056/142] Use new -t flag on xenstore-rm to keep the store pruned when devices go away. Signed-off-by: Ewan Mellor --- tools/examples/xen-backend.agent | 2 +- tools/examples/xen-backend.rules | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/examples/xen-backend.agent b/tools/examples/xen-backend.agent index 27af3359bf..1d47e16e4f 100755 --- a/tools/examples/xen-backend.agent +++ b/tools/examples/xen-backend.agent @@ -22,7 +22,7 @@ case "$ACTION" in ;; esac # remove device backend store entries - xenstore-rm "$XENBUS_PATH" + xenstore-rm -t "$XENBUS_PATH" ;; online) case "$PHYSDEVDRIVER" in diff --git a/tools/examples/xen-backend.rules b/tools/examples/xen-backend.rules index 3eb5a7d56a..b68dbd4914 100644 --- a/tools/examples/xen-backend.rules +++ b/tools/examples/xen-backend.rules @@ -1,4 +1,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ACTION=="add", RUN+="/etc/xen/scripts/block bind" SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ACTION=="remove", RUN+="/etc/xen/scripts/block unbind" SUBSYSTEM=="xen-backend", KERNEL=="vif*", ENV{PHYSDEVDRIVER}=="vif", ACTION=="online", RUN+="$env{script} up" -SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/usr/bin/xenstore-rm $env{XENBUS_PATH}" +SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/usr/bin/xenstore-rm -t $env{XENBUS_PATH}" From 1fbda7544544b7009d91fc3f5068ff9c8daa3d42 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 16:25:05 +0100 Subject: [PATCH 057/142] Detect failure to create shutdown process and retry twice per second until it succeeds. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/kernel/reboot.c | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c index ced2d54582..a8f42dc3e7 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c @@ -26,7 +26,6 @@ // the distinction when we return the reason code to them. #define SHUTDOWN_HALT 4 - void machine_restart(char * __unused) { /* We really want to get pending console data out before we die. */ @@ -60,6 +59,8 @@ EXPORT_SYMBOL(machine_power_off); /* Ignore multiple shutdown requests. */ static int shutting_down = SHUTDOWN_INVALID; +static void __shutdown_handler(void *unused); +static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); #ifndef CONFIG_HOTPLUG_CPU #define cpu_down(x) (-EOPNOTSUPP) @@ -243,41 +244,47 @@ static int shutdown_process(void *__unused) return 0; } -static struct task_struct *kthread_create_on_cpu(int (*f)(void *arg), - void *arg, - const char *name, - int cpu) +static int kthread_create_on_cpu(int (*f)(void *arg), + void *arg, + const char *name, + int cpu) { struct task_struct *p; p = kthread_create(f, arg, name); + if (IS_ERR(p)) + return PTR_ERR(p); kthread_bind(p, cpu); wake_up_process(p); - return p; + return 0; } static void __shutdown_handler(void *unused) { int err; - if (shutting_down != SHUTDOWN_SUSPEND) { + if (shutting_down != SHUTDOWN_SUSPEND) err = kernel_thread(shutdown_process, NULL, CLONE_FS | CLONE_FILES); - if ( err < 0 ) - printk(KERN_ALERT "Error creating shutdown " - "process!\n"); - } else { - kthread_create_on_cpu(__do_suspend, NULL, "suspender", 0); + else + err = kthread_create_on_cpu(__do_suspend, NULL, "suspend", 0); + + if ( err < 0 ) { + printk(KERN_WARNING "Error creating shutdown process (%d): " + "retrying...\n", -err); + schedule_delayed_work(&shutdown_work, HZ/2); } } static void shutdown_handler(struct xenbus_watch *watch, const char **vec, unsigned int len) { - static DECLARE_WORK(shutdown_work, __shutdown_handler, NULL); char *str; struct xenbus_transaction *xbt; int err; + if (shutting_down != SHUTDOWN_INVALID) + goto out; + again: xbt = xenbus_transaction_start(); if (IS_ERR(xbt)) @@ -312,6 +319,7 @@ static void shutdown_handler(struct xenbus_watch *watch, kfree(str); + out: if (shutting_down != SHUTDOWN_INVALID) schedule_work(&shutdown_work); } From 918a5c1de8f413e81e4758a2dda56fed58f588e3 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 16:25:29 +0100 Subject: [PATCH 058/142] Remove bogus error message in libxenctrl. Signed-off-by: Keir Fraser --- tools/libxc/xc_private.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/tools/libxc/xc_private.c b/tools/libxc/xc_private.c index 94cc947400..ea3798ebca 100644 --- a/tools/libxc/xc_private.c +++ b/tools/libxc/xc_private.c @@ -114,11 +114,7 @@ int xc_mmuext_op( goto out1; } - if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) - { - fprintf(stderr, "Dom_mmuext operation failed (rc=%ld errno=%d)-- need to" - " rebuild the user-space tool set?\n",ret,errno); - } + ret = do_xen_hypercall(xc_handle, &hypercall); safe_munlock(op, nr_ops*sizeof(*op)); @@ -227,11 +223,7 @@ int xc_memory_op(int xc_handle, break; } - if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 ) - { - fprintf(stderr, "hypercall failed (rc=%ld errno=%d)-- need to" - " rebuild the user-space tool set?\n",ret,errno); - } + ret = do_xen_hypercall(xc_handle, &hypercall); switch ( cmd ) { From 70a2469320fd8ab2a91aac0357a93be143ece2c3 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 16:26:03 +0100 Subject: [PATCH 059/142] Fix invalidation of shadow LDT on SMP systems. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index a99dda64db..8fcb246906 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -582,6 +582,7 @@ void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d) unsigned long pfn = l1e_get_pfn(l1e); struct pfn_info *page = &frame_table[pfn]; struct domain *e; + struct vcpu *v; if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) || !pfn_valid(pfn) ) return; @@ -615,10 +616,12 @@ void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d) /* We expect this is rare so we blow the entire shadow LDT. */ if ( unlikely(((page->u.inuse.type_info & PGT_type_mask) == PGT_ldt_page)) && - unlikely(((page->u.inuse.type_info & PGT_count_mask) != 0)) ) - - // XXX SMP BUG? - invalidate_shadow_ldt(e->vcpu[0]); + unlikely(((page->u.inuse.type_info & PGT_count_mask) != 0)) && + (d == e) ) + { + for_each_vcpu ( d, v ) + invalidate_shadow_ldt(v); + } put_page(page); } } @@ -1311,7 +1314,7 @@ void free_page_type(struct pfn_info *page, unsigned long type) } } - switch (type & PGT_type_mask) + switch ( type & PGT_type_mask ) { case PGT_l1_page_table: free_l1_table(page); From ed80a0a187509cbeb38d50685dca361d2c3face3 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 15 Oct 2005 17:19:43 +0100 Subject: [PATCH 060/142] Flush writable pagetable state whenever a domain is synchronously paused (by Xen or by domain0), or when it shuts down. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 15 +++++++++++---- xen/common/domain.c | 4 ++++ xen/include/asm-x86/mm.h | 7 ++++++- 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 8fcb246906..3554c011cf 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1755,7 +1755,7 @@ int do_mmuext_op( goto pin_page; case MMUEXT_UNPIN_TABLE: - if ( unlikely(!(okay = get_page_from_pagenr(mfn, FOREIGNDOM))) ) + if ( unlikely(!(okay = get_page_from_pagenr(mfn, d))) ) { MEM_LOG("Mfn %lx bad domain (dom=%p)", mfn, page_get_owner(page)); @@ -2908,6 +2908,7 @@ int revalidate_l1( { l1_pgentry_t ol1e, nl1e; int modified = 0, i; + struct vcpu *v; for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) { @@ -2940,7 +2941,11 @@ int revalidate_l1( */ memcpy(&l1page[i], &snapshot[i], (L1_PAGETABLE_ENTRIES - i) * sizeof(l1_pgentry_t)); - domain_crash(); + + /* Crash the offending domain. */ + set_bit(_DOMF_ctrl_pause, &d->domain_flags); + for_each_vcpu ( d, v ) + vcpu_sleep_nosync(v); break; } @@ -3019,8 +3024,8 @@ void ptwr_flush(struct domain *d, const int which) modified = revalidate_l1(d, pl1e, d->arch.ptwr[which].page); unmap_domain_page(pl1e); perfc_incr_histo(wpt_updates, modified, PT_UPDATES); - ptwr_eip_stat_update( d->arch.ptwr[which].eip, d->domain_id, modified); - d->arch.ptwr[which].prev_nr_updates = modified; + ptwr_eip_stat_update(d->arch.ptwr[which].eip, d->domain_id, modified); + d->arch.ptwr[which].prev_nr_updates = modified; /* * STEP 3. Reattach the L1 p.t. page into the current address space. @@ -3369,7 +3374,9 @@ int ptwr_init(struct domain *d) void ptwr_destroy(struct domain *d) { + LOCK_BIGLOCK(d); cleanup_writable_pagetable(d); + UNLOCK_BIGLOCK(d); free_xenheap_page(d->arch.ptwr[PTWR_PT_ACTIVE].page); free_xenheap_page(d->arch.ptwr[PTWR_PT_INACTIVE].page); } diff --git a/xen/common/domain.c b/xen/common/domain.c index 96c3b0a083..7a50d0e74b 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -290,6 +290,8 @@ void domain_pause(struct domain *d) atomic_inc(&v->pausecnt); vcpu_sleep_sync(v); } + + sync_pagetable_state(d); } void vcpu_unpause(struct vcpu *v) @@ -318,6 +320,8 @@ void domain_pause_by_systemcontroller(struct domain *d) for_each_vcpu ( d, v ) vcpu_sleep_sync(v); } + + sync_pagetable_state(d); } void domain_unpause_by_systemcontroller(struct domain *d) diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index 9b79f86d6f..a13346c25b 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -336,7 +336,12 @@ int ptwr_do_page_fault(struct domain *, unsigned long, int revalidate_l1(struct domain *, l1_pgentry_t *, l1_pgentry_t *); void cleanup_writable_pagetable(struct domain *d); -#define sync_pagetable_state(d) cleanup_writable_pagetable(d) +#define sync_pagetable_state(d) \ + do { \ + LOCK_BIGLOCK(d); \ + cleanup_writable_pagetable(d); \ + UNLOCK_BIGLOCK(d); \ + } while ( 0 ) int audit_adjust_pgtables(struct domain *d, int dir, int noisy); From 8ac022c344d1868d0513d0b1a7e698787a7ce0f1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 16 Oct 2005 11:45:51 +0100 Subject: [PATCH 061/142] Fix local_irq_save() and irqs_disabled() to be preemption-safe. Signed-off-by: Keir Fraser --- .../include/asm-xen/asm-i386/system.h | 32 +++++++++---------- .../include/asm-xen/asm-x86_64/system.h | 32 +++++++++---------- 2 files changed, 30 insertions(+), 34 deletions(-) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h index f930c4cec6..592f20023e 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/system.h @@ -497,22 +497,11 @@ __asm__ __volatile__("6667:movl %1, %0\n6668:\n" \ * includes these barriers, for example. */ -/* - * Don't use smp_processor_id() in preemptible code: debug builds will barf. - * It's okay in these cases as we only read the upcall mask in preemptible - * regions, which is always safe. - */ -#ifdef CONFIG_SMP -#define __this_cpu() __smp_processor_id() -#else -#define __this_cpu() 0 -#endif - #define __cli() \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 1; \ preempt_enable_no_resched(); \ barrier(); \ @@ -523,7 +512,7 @@ do { \ vcpu_info_t *_vcpu; \ barrier(); \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 0; \ barrier(); /* unmask then check (avoid races) */ \ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ @@ -534,8 +523,10 @@ do { \ #define __save_flags(x) \ do { \ vcpu_info_t *_vcpu; \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + preempt_disable(); \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ (x) = _vcpu->evtchn_upcall_mask; \ + preempt_enable(); \ } while (0) #define __restore_flags(x) \ @@ -543,7 +534,7 @@ do { \ vcpu_info_t *_vcpu; \ barrier(); \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \ barrier(); /* unmask then check (avoid races) */ \ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ @@ -559,7 +550,7 @@ do { \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ (x) = _vcpu->evtchn_upcall_mask; \ _vcpu->evtchn_upcall_mask = 1; \ preempt_enable_no_resched(); \ @@ -572,8 +563,15 @@ do { \ #define local_irq_disable() __cli() #define local_irq_enable() __sti() +/* Cannot use preempt_enable() here as we would recurse in preempt_sched(). */ #define irqs_disabled() \ - HYPERVISOR_shared_info->vcpu_data[__this_cpu()].evtchn_upcall_mask +({ int ___x; \ + vcpu_info_t *_vcpu; \ + preempt_disable(); \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + ___x = (_vcpu->evtchn_upcall_mask != 0); \ + preempt_enable_no_resched(); \ + ___x; }) /* * disable hlt during certain critical i/o operations diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h index cf3badc58c..bbecfc56ed 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/system.h @@ -321,22 +321,11 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, * includes these barriers, for example. */ -/* - * Don't use smp_processor_id() in preemptible code: debug builds will barf. - * It's okay in these cases as we only read the upcall mask in preemptible - * regions, which is always safe. - */ -#ifdef CONFIG_SMP -#define __this_cpu() __smp_processor_id() -#else -#define __this_cpu() 0 -#endif - #define __cli() \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 1; \ preempt_enable_no_resched(); \ barrier(); \ @@ -347,7 +336,7 @@ do { \ vcpu_info_t *_vcpu; \ barrier(); \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ _vcpu->evtchn_upcall_mask = 0; \ barrier(); /* unmask then check (avoid races) */ \ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ @@ -358,8 +347,10 @@ do { \ #define __save_flags(x) \ do { \ vcpu_info_t *_vcpu; \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + preempt_disable(); \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ (x) = _vcpu->evtchn_upcall_mask; \ + preempt_enable(); \ } while (0) #define __restore_flags(x) \ @@ -367,7 +358,7 @@ do { \ vcpu_info_t *_vcpu; \ barrier(); \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ if ((_vcpu->evtchn_upcall_mask = (x)) == 0) { \ barrier(); /* unmask then check (avoid races) */ \ if ( unlikely(_vcpu->evtchn_upcall_pending) ) \ @@ -383,7 +374,7 @@ do { \ do { \ vcpu_info_t *_vcpu; \ preempt_disable(); \ - _vcpu = &HYPERVISOR_shared_info->vcpu_data[__this_cpu()]; \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ (x) = _vcpu->evtchn_upcall_mask; \ _vcpu->evtchn_upcall_mask = 1; \ preempt_enable_no_resched(); \ @@ -398,8 +389,15 @@ void cpu_idle_wait(void); #define local_irq_disable() __cli() #define local_irq_enable() __sti() +/* Cannot use preempt_enable() here as we would recurse in preempt_sched(). */ #define irqs_disabled() \ - HYPERVISOR_shared_info->vcpu_data[__this_cpu()].evtchn_upcall_mask +({ int ___x; \ + vcpu_info_t *_vcpu; \ + preempt_disable(); \ + _vcpu = &HYPERVISOR_shared_info->vcpu_data[smp_processor_id()]; \ + ___x = (_vcpu->evtchn_upcall_mask != 0); \ + preempt_enable_no_resched(); \ + ___x; }) /* * disable hlt during certain critical i/o operations From e21acec89ddbeb0d4db072779998fcdbf581ca7e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 16 Oct 2005 12:34:37 +0100 Subject: [PATCH 062/142] Small cleanup in hotplug script. Signed-off-by: Keir Fraser --- tools/examples/xen-backend.agent | 7 +------ tools/examples/xen-backend.rules | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/tools/examples/xen-backend.agent b/tools/examples/xen-backend.agent index 1d47e16e4f..105572102b 100755 --- a/tools/examples/xen-backend.agent +++ b/tools/examples/xen-backend.agent @@ -1,10 +1,5 @@ #! /bin/sh -#ACTION=add -#DEVPATH=/devices/xen-backend/vif-1-0 -#PHYSDEVDRIVER=vif -#XENBUS_TYPE=vif - PATH=/etc/xen/scripts:$PATH case "$ACTION" in @@ -25,7 +20,7 @@ case "$ACTION" in xenstore-rm -t "$XENBUS_PATH" ;; online) - case "$PHYSDEVDRIVER" in + case "$XENBUS_TYPE" in vif) [ -n "$script" ] && $script up ;; diff --git a/tools/examples/xen-backend.rules b/tools/examples/xen-backend.rules index b68dbd4914..514768b13c 100644 --- a/tools/examples/xen-backend.rules +++ b/tools/examples/xen-backend.rules @@ -1,4 +1,4 @@ SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ACTION=="add", RUN+="/etc/xen/scripts/block bind" SUBSYSTEM=="xen-backend", KERNEL=="vbd*", ACTION=="remove", RUN+="/etc/xen/scripts/block unbind" -SUBSYSTEM=="xen-backend", KERNEL=="vif*", ENV{PHYSDEVDRIVER}=="vif", ACTION=="online", RUN+="$env{script} up" +SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} up" SUBSYSTEM=="xen-backend", ACTION=="remove", RUN+="/usr/bin/xenstore-rm -t $env{XENBUS_PATH}" From ec82f54895da4932edc67d190ccf592f219f1f01 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 16 Oct 2005 17:25:15 +0100 Subject: [PATCH 063/142] Clean up debug tracing in mm and mm audit code. Signed-off-by: Keir Fraser --- tools/libxc/xc_linux_restore.c | 2 ++ xen/arch/x86/audit.c | 10 ---------- xen/arch/x86/mm.c | 27 +++++++++++++++++---------- 3 files changed, 19 insertions(+), 20 deletions(-) diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 53ae53279d..2e27db651d 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -43,6 +43,8 @@ read_exact(int fd, void *buf, size_t count) while (r < count) { s = read(fd, &b[r], count - r); + if ((s == -1) && (errno == EINTR)) + continue; if (s <= 0) break; r += s; diff --git a/xen/arch/x86/audit.c b/xen/arch/x86/audit.c index 97e48ef77c..d14f105560 100644 --- a/xen/arch/x86/audit.c +++ b/xen/arch/x86/audit.c @@ -516,16 +516,6 @@ int audit_adjust_pgtables(struct domain *d, int dir, int noisy) d->domain_id, mfn, page->u.inuse.type_info); errors++; } - - if ( (page->u.inuse.type_info & PGT_pinned) != PGT_pinned ) - { - if ( !VM_ASSIST(d, VMASST_TYPE_writable_pagetables) ) - { - printk("Audit %d: L1 mfn=%lx not pinned t=%" - PRtype_info "\n", - d->domain_id, mfn, page->u.inuse.type_info); - } - } } } diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 3554c011cf..a292bb12f9 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -366,9 +366,6 @@ static int get_page_and_type_from_pagenr(unsigned long page_nr, if ( unlikely(!get_page_type(page, type)) ) { - if ( (type & PGT_type_mask) != PGT_l1_page_table ) - MEM_LOG("Bad page type for pfn %lx (%" PRtype_info ")", - page_nr, page->u.inuse.type_info); put_page(page); return 0; } @@ -438,6 +435,7 @@ get_page_from_l1e( { unsigned long mfn = l1e_get_pfn(l1e); struct pfn_info *page = &frame_table[mfn]; + int okay; extern int domain_iomem_in_pfn(struct domain *d, unsigned long pfn); if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) ) @@ -470,9 +468,17 @@ get_page_from_l1e( d = dom_io; } - return ((l1e_get_flags(l1e) & _PAGE_RW) ? + okay = ((l1e_get_flags(l1e) & _PAGE_RW) ? get_page_and_type(page, d, PGT_writable_page) : get_page(page, d)); + if ( !okay ) + { + MEM_LOG("Error getting mfn %lx (pfn %lx) from L1 entry %" PRIpte + " for dom%d", + mfn, get_pfn_from_mfn(mfn), l1e_get_intpte(l1e), d->domain_id); + } + + return okay; } @@ -682,6 +688,7 @@ static int alloc_l1_table(struct pfn_info *page) return 1; fail: + MEM_LOG("Failure in alloc_l1_table: entry %d", i); while ( i-- > 0 ) if ( is_guest_l1_slot(i) ) put_page_from_l1e(pl1e[i], d); @@ -841,6 +848,7 @@ static int alloc_l2_table(struct pfn_info *page, unsigned long type) return 1; fail: + MEM_LOG("Failure in alloc_l2_table: entry %d", i); while ( i-- > 0 ) if ( is_guest_l2_slot(type, i) ) put_page_from_l2e(pl2e[i], pfn); @@ -1453,7 +1461,7 @@ int get_page_type(struct pfn_info *page, unsigned long type) if ( ((x & PGT_type_mask) != PGT_l2_page_table) || ((type & PGT_type_mask) != PGT_l1_page_table) ) MEM_LOG("Bad type (saw %" PRtype_info - "!= exp %" PRtype_info ") " + " != exp %" PRtype_info ") " "for mfn %lx (pfn %lx)", x, type, page_to_pfn(page), get_pfn_from_mfn(page_to_pfn(page))); @@ -1494,11 +1502,10 @@ int get_page_type(struct pfn_info *page, unsigned long type) /* Try to validate page type; drop the new reference on failure. */ if ( unlikely(!alloc_page_type(page, type)) ) { - MEM_LOG("Error while validating pfn %lx for type %" PRtype_info "." - " caf=%08x taf=%" PRtype_info, - page_to_pfn(page), type, - page->count_info, - page->u.inuse.type_info); + MEM_LOG("Error while validating mfn %lx (pfn %lx) for type %" + PRtype_info ": caf=%08x taf=%" PRtype_info, + page_to_pfn(page), get_pfn_from_mfn(page_to_pfn(page)), + type, page->count_info, page->u.inuse.type_info); /* Noone else can get a reference. We hold the only ref. */ page->u.inuse.type_info = 0; return 0; From 981d9b117d4ad6b759af0c42a044050ab06207f5 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 17 Oct 2005 11:36:36 +0100 Subject: [PATCH 064/142] Plumb GETVCPUINFO dom0_op through to Python. Remove n_vcpu field from GETDOMAININFO: replaced with nr_online_vcpus and max_vcpu_id (both plumbed through to Python). TODO: Remove 'vcpus' entry in getdomaininfo Python dictionary. TODO: Don't represent 'cpumap' as a bitmap in Python. It would be more sensible to represent as a list of integer CPU numbers. Signed-off-by: Keir Fraser --- tools/libxc/xc_core.c | 19 ++++----- tools/libxc/xc_domain.c | 22 ++++++++++- tools/libxc/xenctrl.h | 10 ++++- tools/python/xen/lowlevel/xc/xc.c | 53 +++++++++++++++++++++++++- tools/xenstat/libxenstat/src/xenstat.c | 2 +- xen/common/dom0_ops.c | 6 +-- xen/include/public/dom0_ops.h | 3 +- 7 files changed, 97 insertions(+), 18 deletions(-) diff --git a/tools/libxc/xc_core.c b/tools/libxc/xc_core.c index 4694c0fe2f..207fbe8fb1 100644 --- a/tools/libxc/xc_core.c +++ b/tools/libxc/xc_core.c @@ -33,10 +33,10 @@ xc_domain_dumpcore(int xc_handle, unsigned long nr_pages; unsigned long *page_array; xc_dominfo_t info; - int i, j, dump_fd; + int i, nr_vcpus = 0, dump_fd; char *dump_mem, *dump_mem_start = NULL; struct xc_core_header header; - vcpu_guest_context_t ctxt[MAX_VIRT_CPUS]; + vcpu_guest_context_t ctxt[MAX_VIRT_CPUS]; if ((dump_fd = open(corename, O_CREAT|O_RDWR, S_IWUSR|S_IRUSR)) < 0) { @@ -54,24 +54,25 @@ xc_domain_dumpcore(int xc_handle, goto error_out; } - for (i = 0, j = 0; i < 32; i++) - if (xc_domain_get_vcpu_context(xc_handle, domid, i, &ctxt[j]) == 0) - j++; + for (i = 0; i < info.max_vcpu_id; i++) + if (xc_domain_get_vcpu_context(xc_handle, domid, + i, &ctxt[nr_vcpus]) == 0) + nr_vcpus++; nr_pages = info.nr_pages; header.xch_magic = 0xF00FEBED; - header.xch_nr_vcpus = info.vcpus; + header.xch_nr_vcpus = nr_vcpus; header.xch_nr_pages = nr_pages; header.xch_ctxt_offset = sizeof(struct xc_core_header); header.xch_index_offset = sizeof(struct xc_core_header) + - sizeof(vcpu_guest_context_t)*info.vcpus; + sizeof(vcpu_guest_context_t)*nr_vcpus; header.xch_pages_offset = round_pgup(sizeof(struct xc_core_header) + - (sizeof(vcpu_guest_context_t) * info.vcpus) + + (sizeof(vcpu_guest_context_t) * nr_vcpus) + (nr_pages * sizeof(unsigned long))); write(dump_fd, &header, sizeof(struct xc_core_header)); - write(dump_fd, &ctxt, sizeof(ctxt[0]) * info.vcpus); + write(dump_fd, &ctxt, sizeof(ctxt[0]) * nr_vcpus); if ((page_array = malloc(nr_pages * sizeof(unsigned long))) == NULL) { printf("Could not allocate memory\n"); diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c index 4b43ed9bf9..f98049f67f 100644 --- a/tools/libxc/xc_domain.c +++ b/tools/libxc/xc_domain.c @@ -113,7 +113,8 @@ int xc_domain_getinfo(int xc_handle, info->max_memkb = op.u.getdomaininfo.max_pages << (PAGE_SHIFT - 10); info->shared_info_frame = op.u.getdomaininfo.shared_info_frame; info->cpu_time = op.u.getdomaininfo.cpu_time; - info->vcpus = op.u.getdomaininfo.n_vcpu; + info->nr_online_vcpus = op.u.getdomaininfo.nr_online_vcpus; + info->max_vcpu_id = op.u.getdomaininfo.max_vcpu_id; memcpy(info->handle, op.u.getdomaininfo.handle, sizeof(xen_domain_handle_t)); @@ -344,6 +345,25 @@ int xc_domain_sethandle(int xc_handle, uint32_t domid, return do_dom0_op(xc_handle, &op); } +int xc_domain_get_vcpu_info(int xc_handle, + uint32_t domid, + uint32_t vcpu, + xc_vcpuinfo_t *info) +{ + int rc; + dom0_op_t op; + + op.cmd = DOM0_GETVCPUINFO; + op.u.getvcpuinfo.domain = (domid_t)domid; + op.u.getvcpuinfo.vcpu = (uint16_t)vcpu; + + rc = do_dom0_op(xc_handle, &op); + + memcpy(info, &op.u.getvcpuinfo, sizeof(*info)); + + return rc; +} + /* * Local variables: * mode: C diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 464810edf5..818a29df24 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -132,7 +132,8 @@ typedef struct { unsigned long shared_info_frame; uint64_t cpu_time; unsigned long max_memkb; - unsigned int vcpus; + unsigned int nr_online_vcpus; + unsigned int max_vcpu_id; xen_domain_handle_t handle; } xc_dominfo_t; @@ -250,6 +251,13 @@ int xc_domain_get_vcpu_context(int xc_handle, uint32_t vcpu, vcpu_guest_context_t *ctxt); +typedef dom0_getvcpuinfo_t xc_vcpuinfo_t; +int xc_domain_get_vcpu_info(int xc_handle, + uint32_t domid, + uint32_t vcpu, + xc_vcpuinfo_t *info); + + int xc_domain_setcpuweight(int xc_handle, uint32_t domid, float weight); diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index bd554284ff..38032042a2 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -317,10 +317,13 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t)); for ( j = 0; j < sizeof(xen_domain_handle_t); j++ ) PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j])); - info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" + info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" ",s:l,s:L,s:l,s:i,s:i}", "dom", info[i].domid, - "vcpus", info[i].vcpus, + /* XXX 'vcpus' field is obsolete! */ + "vcpus", info[i].nr_online_vcpus, + "online_vcpus", info[i].nr_online_vcpus, + "max_vcpu_id", info[i].max_vcpu_id, "dying", info[i].dying, "crashed", info[i].crashed, "shutdown", info[i].shutdown, @@ -341,6 +344,38 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, return list; } +static PyObject *pyxc_vcpu_getinfo(PyObject *self, + PyObject *args, + PyObject *kwds) +{ + XcObject *xc = (XcObject *)self; + PyObject *info_dict; + + uint32_t dom, vcpu = 0; + xc_vcpuinfo_t info; + int rc; + + static char *kwd_list[] = { "dom", "vcpu", NULL }; + + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, + &dom, &vcpu) ) + return NULL; + + rc = xc_domain_get_vcpu_info(xc->xc_handle, dom, vcpu, &info); + if ( rc < 0 ) + return PyErr_SetFromErrno(xc_error); + + info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i,s:i,s:i}", + "online", info.online, + "blocked", info.blocked, + "running", info.running, + "cpu_time", info.cpu_time, + "cpu", info.cpu, + "cpumap", info.cpumap); + + return info_dict; +} + static PyObject *pyxc_linux_build(PyObject *self, PyObject *args, PyObject *kwds) @@ -948,6 +983,20 @@ static PyMethodDef pyxc_methods[] = { "reason why it shut itself down.\n" " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" }, + { "vcpu_getinfo", + (PyCFunction)pyxc_vcpu_getinfo, + METH_VARARGS | METH_KEYWORDS, "\n" + "Get information regarding a VCPU.\n" + " dom [int]: Domain to retrieve info about.\n" + " vcpu [int, 0]: VCPU to retrieve info about.\n\n" + "Returns: [dict]\n" + " online [int]: Bool - Is this VCPU currently online?\n" + " blocked [int]: Bool - Is this VCPU blocked waiting for an event?\n" + " running [int]: Bool - Is this VCPU currently running on a CPU?\n" + " cpu_time [long]: CPU time consumed, in nanoseconds\n" + " cpumap [int]: Bitmap of CPUs this VCPU can run on\n" + " cpu [int]: CPU that this VCPU is currently bound to\n" }, + { "linux_build", (PyCFunction)pyxc_linux_build, METH_VARARGS | METH_KEYWORDS, "\n" diff --git a/tools/xenstat/libxenstat/src/xenstat.c b/tools/xenstat/libxenstat/src/xenstat.c index c58a720bb8..d9b18dbcd0 100644 --- a/tools/xenstat/libxenstat/src/xenstat.c +++ b/tools/xenstat/libxenstat/src/xenstat.c @@ -229,7 +229,7 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags) domain->id = domaininfo[i].domain; domain->state = domaininfo[i].flags; domain->cpu_ns = domaininfo[i].cpu_time; - domain->num_vcpus = domaininfo[i].n_vcpu; + domain->num_vcpus = domaininfo[i].nr_online_vcpus; domain->vcpus = NULL; domain->cur_mem = ((unsigned long long)domaininfo[i].tot_pages) diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 9c682dffce..76b4a020fa 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -43,10 +43,10 @@ static void getdomaininfo(struct domain *d, dom0_getdomaininfo_t *info) { struct vcpu *v; u64 cpu_time = 0; - int vcpu_count = 0; int flags = DOMFLAGS_BLOCKED; info->domain = d->domain_id; + info->nr_online_vcpus = 0; /* * - domain is marked as blocked only if all its vcpus are blocked @@ -54,18 +54,18 @@ static void getdomaininfo(struct domain *d, dom0_getdomaininfo_t *info) */ for_each_vcpu ( d, v ) { cpu_time += v->cpu_time; + info->max_vcpu_id = v->vcpu_id; if ( !test_bit(_VCPUF_down, &v->vcpu_flags) ) { if ( !(v->vcpu_flags & VCPUF_blocked) ) flags &= ~DOMFLAGS_BLOCKED; if ( v->vcpu_flags & VCPUF_running ) flags |= DOMFLAGS_RUNNING; - vcpu_count++; + info->nr_online_vcpus++; } } info->cpu_time = cpu_time; - info->n_vcpu = vcpu_count; info->flags = flags | ((d->domain_flags & DOMF_dying) ? DOMFLAGS_DYING : 0) | diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 9556d43f57..1af736de7b 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -88,7 +88,8 @@ typedef struct { unsigned long max_pages; unsigned long shared_info_frame; /* MFN of shared_info struct */ uint64_t cpu_time; - uint32_t n_vcpu; + uint32_t nr_online_vcpus; /* Number of VCPUs currently online. */ + uint32_t max_vcpu_id; /* Maximum VCPUID in use by this domain. */ uint32_t ssidref; xen_domain_handle_t handle; } dom0_getdomaininfo_t; From 37964af428fda1eb26d16afce019c597584c4572 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 17 Oct 2005 13:50:28 +0100 Subject: [PATCH 065/142] Added a TRACE log level, for those versions of Python that do not have it, and moved XendDomainInfo.update's debugging onto that level, as it has become overly verbose. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomainInfo.py | 9 ++++++--- tools/python/xen/xend/XendLogging.py | 8 ++++++++ 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 612188db0c..9e98b2cb55 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -24,6 +24,7 @@ Author: Mike Wray """ +import logging import string import time import threading @@ -38,7 +39,6 @@ from xen.xend import scheduler from xen.xend import sxp from xen.xend import XendRoot from xen.xend.XendBootloader import bootloader -from xen.xend.XendLogging import log from xen.xend.XendError import XendError, VmError from xen.xend.XendRoot import get_component @@ -102,6 +102,9 @@ ZOMBIE_PREFIX = 'Zombie-' xc = xen.lowlevel.xc.new() xroot = XendRoot.instance() +log = logging.getLogger("xend.XendDomainInfo") +#log.setLevel(logging.TRACE) + ## Configuration entries that we expect to round-trip -- be read from the # config file or xc, written to save-files (i.e. through sxpr), and reused as @@ -802,7 +805,7 @@ class XendDomainInfo: """Update with info from xc.domain_getinfo(). """ - log.debug("XendDomainInfo.update(%s) on domain %d", info, self.domid) + log.trace("XendDomainInfo.update(%s) on domain %d", info, self.domid) if not info: info = dom_get(self.domid) @@ -813,7 +816,7 @@ class XendDomainInfo: self.validateInfo() self.refreshShutdown(info) - log.debug("XendDomainInfo.update done on domain %d: %s", self.domid, + log.trace("XendDomainInfo.update done on domain %d: %s", self.domid, self.info) diff --git a/tools/python/xen/xend/XendLogging.py b/tools/python/xen/xend/XendLogging.py index 8e54d94bf1..053bf4703e 100644 --- a/tools/python/xen/xend/XendLogging.py +++ b/tools/python/xen/xend/XendLogging.py @@ -27,6 +27,14 @@ __all__ = [ 'log', 'init', 'getLogFilename', 'addLogStderr', 'removeLogStderr' ] +if not 'TRACE' in logging.__dict__: + logging.TRACE = logging.DEBUG - 1 + logging.addLevelName(logging.TRACE,'TRACE') + def trace(self, *args, **kwargs): + self.log(logging.TRACE, *args, **kwargs) + logging.Logger.trace = trace + + log = logging.getLogger("xend") From 689c39e019d8adb9d2e9f7db3911e4db87536e76 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 17 Oct 2005 14:02:36 +0100 Subject: [PATCH 066/142] Force RTC driver to fail to load in domU by preventing it from binding to IRQ8. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c index cb0e1f9783..80e017684b 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c @@ -42,6 +42,7 @@ #include #include #include +#include /* RTC_IRQ */ /* * This lock protects updates to the following mapping and reference-count @@ -744,6 +745,13 @@ void __init init_IRQ(void) { irq_bindcount[pirq_to_irq(i)] = 1; +#ifdef RTC_IRQ + /* If not domain 0, force our RTC driver to fail its probe. */ + if ((i == RTC_IRQ) && + !(xen_start_info->flags & SIF_INITDOMAIN)) + continue; +#endif + irq_desc[pirq_to_irq(i)].status = IRQ_DISABLED; irq_desc[pirq_to_irq(i)].action = 0; irq_desc[pirq_to_irq(i)].depth = 1; From 238ca03bd451220cc54549ac860b452766a2d9c4 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 17 Oct 2005 14:07:47 +0100 Subject: [PATCH 067/142] Replace xm vcpu-enable and xm vcpu-disable with one command, xm set-vcpus, which sets the number of active CPUs. Xend then toggles the VCPUs to ensure a contiguous group of them are enabled. Added a server command to get VCPU information, and use this info to fix xm vcpu-list. That xm command now has extra information, too. CPU == -1 is no longer used as an indicator for a VCPU that is disabled -- a separate state field is available, and the CPU is set merely to '-'. Individual CPU time is now available. Deprecated xm list -v. -v is conventionally used for --verbose, so using it to list vcpus is confusing. Furthermore, we already have an equivalent command xm vcpu-list. Tidied up the horrendous xm list / xm vcpu-list code. Removed the vcpus field from the dict returned by xc_domain_getinfo, and the vcpu_to_cpu map from the sxpr returned for xm list. Move the dom0_enforce_vcpus code into XendDomain. Signed-off-by: Ewan Mellor --- tools/python/xen/lowlevel/xc/xc.c | 7 +- tools/python/xen/xend/XendClient.py | 12 +- tools/python/xen/xend/XendDomain.py | 9 +- tools/python/xen/xend/XendDomainInfo.py | 119 +++++++------ tools/python/xen/xend/server/SrvDomain.py | 16 +- tools/python/xen/xm/main.py | 201 +++++++++++----------- 6 files changed, 196 insertions(+), 168 deletions(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 38032042a2..4a11ef77c5 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -317,11 +317,9 @@ static PyObject *pyxc_domain_getinfo(PyObject *self, PyObject *pyhandle = PyList_New(sizeof(xen_domain_handle_t)); for ( j = 0; j < sizeof(xen_domain_handle_t); j++ ) PyList_SetItem(pyhandle, j, PyInt_FromLong(info[i].handle[j])); - info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" + info_dict = Py_BuildValue("{s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i,s:i" ",s:l,s:L,s:l,s:i,s:i}", "dom", info[i].domid, - /* XXX 'vcpus' field is obsolete! */ - "vcpus", info[i].nr_online_vcpus, "online_vcpus", info[i].nr_online_vcpus, "max_vcpu_id", info[i].max_vcpu_id, "dying", info[i].dying, @@ -980,8 +978,7 @@ static PyMethodDef pyxc_methods[] = { " maxmem_kb [int]: Maximum memory limit, in kilobytes\n" " cpu_time [long]: CPU time consumed, in nanoseconds\n" " shutdown_reason [int]: Numeric code from guest OS, explaining " - "reason why it shut itself down.\n" - " vcpu_to_cpu [[int]]: List that maps VCPUS to CPUS\n" }, + "reason why it shut itself down.\n" }, { "vcpu_getinfo", (PyCFunction)pyxc_vcpu_getinfo, diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 39c57dc8b8..22f8fc7571 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -199,6 +199,9 @@ class Xend: def xend_list_domains(self): return self.xendGet(self.domainurl(), {'detail': '1'}) + def xend_domain_vcpuinfo(self, dom): + return self.xendGet(self.domainurl(dom), {'op': 'vcpuinfo'}) + def xend_domain_create(self, conf): return self.xendPost(self.domainurl(), {'op' : 'create', @@ -286,11 +289,10 @@ class Xend: 'target' : mem_target }) return val - def xend_domain_vcpu_hotplug(self, id, vcpu, state): - return self.xendPost(self.domainurl(id), - {'op' : 'vcpu_hotplug', - 'vcpu' : vcpu, - 'state' : state }) + def xend_domain_set_vcpus(self, dom, vcpus): + return self.xendPost(self.domainurl(dom), + {'op' : 'set_vcpus', + 'vcpus' : vcpus }) def xend_domain_vif_limit(self, id, vif, credit, period): return self.xendPost(self.domainurl(id), diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index ce4007b984..6f1ab9b84e 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -129,7 +129,14 @@ class XendDomain: def dom0_setup(self): """Expects to be protected by the domains_lock.""" dom0 = self.domains[PRIV_DOMAIN] - dom0.dom0_enforce_vcpus() + + # get max number of vcpus to use for dom0 from config + target = int(xroot.get_dom0_vcpus()) + log.debug("number of vcpus to use is %d", target) + + # target == 0 means use all processors + if target > 0: + self.setVCpuCount(target) def _add_domain(self, info): diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 9e98b2cb55..79fdd38a9a 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -133,8 +133,6 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [ # its VCPUs. This is translated to # /cpu//availability = {online,offline} for use # by the guest domain. -# vcpu_to_cpu: the current mapping between virtual CPUs and the physical -# CPU it is using. # cpumap: a list of bitmaps, one for each VCPU, giving the physical # CPUs that that VCPU may use. # cpu: a configuration setting requesting that VCPU 0 is pinned to @@ -392,6 +390,8 @@ class XendDomainInfo: self.refresh_shutdown_lock = threading.Condition() + ## private: + def augmentInfo(self): """Augment self.info, as given to us through {@link #recreate}, with values taken from the store. This recovers those values known to xend @@ -544,25 +544,36 @@ class XendDomainInfo: def gatherVm(self, *args): return xstransact.Gather(self.vmpath, *args) + + ## public: + def storeVm(self, *args): return xstransact.Store(self.vmpath, *args) + + ## private: + def readDom(self, *args): return xstransact.Read(self.dompath, *args) def writeDom(self, *args): return xstransact.Write(self.dompath, *args) + + ## public: + def removeDom(self, *args): return xstransact.Remove(self.dompath, *args) - def gatherDom(self, *args): - return xstransact.Gather(self.dompath, *args) + + ## private: def storeDom(self, *args): return xstransact.Store(self.dompath, *args) + ## public: + def storeVmDetails(self): to_store = { 'uuid': self.uuid, @@ -596,18 +607,26 @@ class XendDomainInfo: if v: to_store[k] = str(v) + to_store.update(self.vcpuDomDetails()) + + log.debug("Storing domain details: %s", to_store) + + self.writeDom(to_store) + + + ## private: + + def vcpuDomDetails(self): def availability(n): if self.info['vcpu_avail'] & (1 << n): return 'online' else: return 'offline' + result = {} for v in range(0, self.info['vcpus']): - to_store["cpu/%d/availability" % v] = availability(v) - - log.debug("Storing domain details: %s", to_store) - - self.writeDom(to_store) + result["cpu/%d/availability" % v] = availability(v) + return result def setDomid(self, domid): @@ -635,9 +654,17 @@ class XendDomainInfo: def getUuid(self): return self.uuid + def getVCpuCount(self): return self.info['vcpus'] + + def setVCpuCount(self, vcpus): + self.info['vcpu_avail'] = (1 << vcpus) - 1 + self.storeVm('vcpu_avail', self.info['vcpu_avail']) + self.writeDom(self.vcpuDomDetails()) + + def getSsidref(self): return self.info['ssidref'] @@ -872,12 +899,12 @@ class XendDomainInfo: return self.getDeviceController(deviceClass).destroyDevice(devid) - ## private: - def getDeviceSxprs(self, deviceClass): return self.getDeviceController(deviceClass).sxprs() + ## private: + def getDeviceConfigurations(self, deviceClass): return self.getDeviceController(deviceClass).configurations() @@ -932,11 +959,6 @@ class XendDomainInfo: if self.infoIsSet('cpu_time'): sxpr.append(['cpu_time', self.info['cpu_time']/1e9]) sxpr.append(['vcpus', self.info['vcpus']]) - if self.infoIsSet('cpumap'): - sxpr.append(['cpumap', self.info['cpumap']]) - if self.infoIsSet('vcpu_to_cpu'): - sxpr.append(['cpu', self.info['vcpu_to_cpu'][0]]) - sxpr.append(['vcpu_to_cpu', self.prettyVCpuMap()]) if self.infoIsSet('start_time'): up_time = time.time() - self.info['start_time'] @@ -951,13 +973,34 @@ class XendDomainInfo: return sxpr + def getVCPUInfo(self): + try: + # We include the domain name and ID, to help xm. + sxpr = ['domain', + ['domid', self.domid], + ['name', self.info['name']], + ['vcpu_count', self.info['vcpus']]] + + for i in range(0, self.info['vcpus']): + info = xc.vcpu_getinfo(self.domid, i) + + sxpr.append(['vcpu', + ['number', i], + ['online', info['online']], + ['blocked', info['blocked']], + ['running', info['running']], + ['cpu_time', info['cpu_time'] / 1e9], + ['cpu', info['cpu']], + ['cpumap', info['cpumap']]]) + + return sxpr + + except RuntimeError, exn: + raise XendError(str(exn)) + + ## private: - def prettyVCpuMap(self): - return '|'.join(map(str, - self.info['vcpu_to_cpu'][0:self.info['vcpus']])) - - def check_name(self, name): """Check if a vm name is valid. Valid names contain alphabetic characters, digits, or characters in '_-.:/+'. @@ -1335,22 +1378,6 @@ class XendDomainInfo: xc.domain_setmaxmem(self.domid, maxmem_kb = m) - def vcpu_hotplug(self, vcpu, state): - """Disable or enable VCPU in domain. - """ - if vcpu > self.info['vcpus']: - log.error("Invalid VCPU %d" % vcpu) - return - if int(state) == 0: - self.info['vcpu_avail'] &= ~(1 << vcpu) - availability = "offline" - else: - self.info['vcpu_avail'] &= (1 << vcpu) - availability = "online" - self.storeVm('vcpu_avail', self.info['vcpu_avail']) - self.storeDom("cpu/%d/availability" % vcpu, availability) - - def send_sysrq(self, key): asserts.isCharConvertible(key) @@ -1371,24 +1398,6 @@ class XendDomainInfo: raise - def dom0_enforce_vcpus(self): - dom = 0 - # get max number of vcpus to use for dom0 from config - target = int(xroot.get_dom0_vcpus()) - log.debug("number of vcpus to use is %d", target) - - # target = 0 means use all processors - if target > 0: - # count the number of online vcpus (cpu values in v2c map >= 0) - vcpus_online = dom_get(dom)['vcpus'] - log.debug("found %d vcpus online", vcpus_online) - - # disable any extra vcpus that are online over the requested target - for vcpu in range(target, vcpus_online): - log.info("enforcement is disabling DOM%d VCPU%d", dom, vcpu) - self.vcpu_hotplug(vcpu, 0) - - def infoIsSet(self, name): return name in self.info and self.info[name] is not None diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index 535d9323f4..5278506cc4 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -165,17 +165,25 @@ class SrvDomain(SrvDir): val = fn(req.args, {'dom': self.dom.domid}) return val - def op_vcpu_hotplug(self, op, req): - return self.call(self.dom.vcpu_hotplug, - [['vcpu', 'int'], - ['state', 'int']], + def op_set_vcpus(self, op, req): + return self.call(self.dom.setVCpuCount, + [['vcpus', 'int']], req) + + def op_vcpuinfo(self, _1, req): + return self.call(self.dom.getVCPUInfo, [], req) + + def render_POST(self, req): return self.perform(req) def render_GET(self, req): op = req.args.get('op') + + if op and op[0] in ['vcpuinfo']: + return self.perform(req) + # # XXX SMH: below may be useful once again if we ever try to get # the raw 'web' interface to xend working once more. But for now diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index a3e35f993b..e2545c53cd 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -71,8 +71,7 @@ longhelp = """Usage: xm [args] xm full list of subcommands: Domain Commands: - console attach to console of DomId - cpus-list get the list of cpus for a VCPU + console attach to console of DomId create create a domain destroy terminate a domain immediately domid convert a domain name to a domain id @@ -88,10 +87,9 @@ xm full list of subcommands: shutdown [-w|-a] shutdown a domain sysrq send a sysrq to a domain unpause unpause a paused domain - vcpu-enable enable VCPU in a domain - vcpu-disable disable VCPU in a domain - vcpu-list get the list of VCPUs for a domain - vcpu-pin set which cpus a VCPU can use. + set-vcpus enable the specified number of VCPUs in a domain + vcpu-list list the VCPUs for a domain + vcpu-pin set which cpus a VCPU can use. Xen Host Commands: dmesg [--clear] read or clear Xen's message buffer @@ -209,6 +207,15 @@ def xm_restore(args): if id is not None: server.xend_domain_unpause(domid) + +def getDomains(domain_names): + from xen.xend.XendClient import server + if domain_names: + return map(server.xend_domain, domain_names) + else: + return server.xend_list_domains() + + def xm_list(args): use_long = 0 show_vcpus = 0 @@ -218,80 +225,105 @@ def xm_list(args): err(opterr) sys.exit(1) - n = len(params) for (k, v) in options: if k in ['-l', '--long']: use_long = 1 if k in ['-v', '--vcpus']: show_vcpus = 1 - from xen.xend.XendClient import server - if n == 0: - doms = server.xend_list_domains() - else: - doms = map(server.xend_domain, params) - - if use_long: - for dom in doms: - PrettyPrint.prettyprint(dom) - else: - domsinfo = map(parse_doms_info, doms) + if show_vcpus: + print >>sys.stderr, ( + "xm list -v is deprecated. Please use xm vcpu-list.") + xm_vcpu_list(params) + return + + doms = getDomains(params) + + if use_long: + map(PrettyPrint.prettyprint, doms) + else: + xm_brief_list(doms) - if show_vcpus: - xm_show_vcpus(domsinfo) - else: - xm_brief_list(domsinfo) def parse_doms_info(info): - dominfo = {} - dominfo['dom'] = int(sxp.child_value(info, 'domid', '-1')) - dominfo['name'] = sxp.child_value(info, 'name', '??') - dominfo['mem'] = int(sxp.child_value(info, 'memory', '0')) - dominfo['cpu'] = str(sxp.child_value(info, 'cpu', '0')) - dominfo['vcpus'] = int(sxp.child_value(info, 'vcpus', '0')) - # if there is more than 1 cpu, the value doesn't mean much - if dominfo['vcpus'] > 1: - dominfo['cpu'] = '-' - dominfo['state'] = sxp.child_value(info, 'state', '??') - dominfo['cpu_time'] = float(sxp.child_value(info, 'cpu_time', '0')) - # security identifiers - if ((int(sxp.child_value(info, 'ssidref', '0'))) != 0): - dominfo['ssidref1'] = int(sxp.child_value(info, 'ssidref', '0')) & 0xffff - dominfo['ssidref2'] = (int(sxp.child_value(info, 'ssidref', '0')) >> 16) & 0xffff - # get out the vcpu information - dominfo['vcpulist'] = [] - vcpu_to_cpu = sxp.child_value(info, 'vcpu_to_cpu', '-1').split('|') - cpumap = sxp.child_value(info, 'cpumap', []) - mask = ((int(sxp.child_value(info, 'vcpus', '0')))**2) - 1 - count = 0 - for cpu in vcpu_to_cpu: - vcpuinfo = {} - vcpuinfo['name'] = sxp.child_value(info, 'name', '??') - vcpuinfo['dom'] = int(sxp.child_value(info, 'domid', '-1')) - vcpuinfo['vcpu'] = int(count) - vcpuinfo['cpu'] = int(cpu) - #vcpuinfo['cpumap'] = int(cpumap[count])&mask - count = count + 1 - #dominfo['vcpulist'].append(vcpuinfo) - return dominfo - -def xm_brief_list(domsinfo): - print 'Name ID Mem(MiB) CPU VCPUs State Time(s)' - for dominfo in domsinfo: - if dominfo.has_key("ssidref1"): - print ("%(name)-16s %(dom)3d %(mem)8d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f s:%(ssidref2)02x/p:%(ssidref1)02x" % dominfo) - else: - print ("%(name)-16s %(dom)3d %(mem)8d %(cpu)3s %(vcpus)5d %(state)5s %(cpu_time)7.1f" % dominfo) + def get_info(n, t, d): + return t(sxp.child_value(info, n, d)) + + return { + 'dom' : get_info('domid', int, -1), + 'name' : get_info('name', str, '??'), + 'mem' : get_info('memory', int, 0), + 'vcpus' : get_info('vcpus', int, 0), + 'state' : get_info('state', str, '??'), + 'cpu_time' : get_info('cpu_time', float, 0), + 'ssidref' : get_info('ssidref', int, 0), + } + + +def xm_brief_list(doms): + print 'Name ID Mem(MiB) VCPUs State Time(s)' + for dom in doms: + d = parse_doms_info(dom) + if (d['ssidref'] != 0): + d['ssidstr'] = (" s:%04x/p:%04x" % + ((d['ssidref'] >> 16) & 0xffff, + d['ssidref'] & 0xffff)) + else: + d['ssidstr'] = "" + print ("%(name)-32s %(dom)3d %(mem)8d %(vcpus)5d %(state)5s %(cpu_time)7.1f%(ssidstr)s" % d) -def xm_show_vcpus(domsinfo): - print 'Name Id VCPU CPU CPUMAP' - for dominfo in domsinfo: - for vcpuinfo in dominfo['vcpulist']: - print ("%(name)-16s %(dom)3d %(vcpu)4d %(cpu)3d 0x%(cpumap)x" % - vcpuinfo) def xm_vcpu_list(args): - xm_list(["-v"] + args) + print 'Name ID VCPU CPU State Time(s) CPU Map' + + from xen.xend.XendClient import server + if args: + dominfo = map(server.xend_domain_vcpuinfo, args) + else: + doms = server.xend_list_domains() + dominfo = map( + lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')), + doms) + + for dom in dominfo: + def get_info(n): + return sxp.child_value(dom, n) + + name = get_info('name') + domid = int(get_info('domid')) + + + for vcpu in sxp.children(dom, 'vcpu'): + def vinfo(n, t): + return t(sxp.child_value(vcpu, n)) + + number = vinfo('number', int) + cpu = vinfo('cpu', int) + cpumap = vinfo('cpumap', int) + online = vinfo('online', int) + cpu_time = vinfo('cpu_time', float) + running = vinfo('running', int) + blocked = vinfo('blocked', int) + + if online: + c = str(cpu) + if running: + s = 'r' + else: + s = '-' + if blocked: + s += 'b' + else: + s += '-' + s += '-' + else: + c = "-" + s = "--p" + + print ( + "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f 0x%(cpumap)x" % + locals()) + def xm_reboot(args): arg_check(args,1,"reboot") @@ -338,8 +370,6 @@ def cpu_make_map(cpulist): return cpumap def xm_vcpu_pin(args): - arg_check(args, 3, "vcpu-pin") - dom = args[0] vcpu = int(args[1]) cpumap = cpu_make_map(args[2]) @@ -348,8 +378,6 @@ def xm_vcpu_pin(args): server.xend_domain_pincpu(dom, vcpu, cpumap) def xm_mem_max(args): - arg_check(args, 2, "mem-max") - dom = args[0] mem = int_unit(args[1], 'm') @@ -357,36 +385,15 @@ def xm_mem_max(args): server.xend_domain_maxmem_set(dom, mem) def xm_mem_set(args): - arg_check(args, 2, "mem-set") - dom = args[0] mem_target = int_unit(args[1], 'm') from xen.xend.XendClient import server server.xend_domain_mem_target_set(dom, mem_target) -# TODO: why does this lookup by name? and what if that fails!? -def xm_vcpu_enable(args): - arg_check(args, 2, "vcpu-enable") - - name = args[0] - vcpu = int(args[1]) - +def xm_set_vcpus(args): from xen.xend.XendClient import server - dom = server.xend_domain(name) - id = sxp.child_value(dom, 'domid') - server.xend_domain_vcpu_hotplug(id, vcpu, 1) - -def xm_vcpu_disable(args): - arg_check(args, 2, "vcpu-disable") - - name = args[0] - vcpu = int(args[1]) - - from xen.xend.XendClient import server - dom = server.xend_domain(name) - id = sxp.child_value(dom, 'domid') - server.xend_domain_vcpu_hotplug(id, vcpu, 0) + server.xend_domain_set_vcpus(args[0], int(args[1])) def xm_domid(args): name = args[0] @@ -586,9 +593,7 @@ commands = { "mem-set": xm_mem_set, # cpu commands "vcpu-pin": xm_vcpu_pin, -# "cpus-list": xm_cpus_list, - "vcpu-enable": xm_vcpu_enable, - "vcpu-disable": xm_vcpu_disable, + "set-vcpus": xm_set_vcpus, "vcpu-list": xm_vcpu_list, # special "pause": xm_pause, From 3afe806f6fc892fe7ba31e2d7f2059d0ac1766da Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 17 Oct 2005 15:15:17 +0100 Subject: [PATCH 068/142] Make the event-channel pending and mask arrays consist of longs. Thi sensures appropriate alignment for architectures that require it, and also allows us to naturally support up to 4096 event channels per 64-bit guest. Moved 'n_vcpu' field from shared_info to start_info. Really it ought to disappear altogether as the info can be derived from xenstore. Fix a weird bug in XendDomainInfo where 'vcpus' information for a domain defaults to floating point value 1.0 rather than integer 1. This looks like a Python bug to me, but in any case it is 'fixed' by explicitly converting the default value to an integer. Signed-off-by: Keir Fraser --- .../arch/ia64/xen/drivers/evtchn_ia64.c | 8 ++--- .../arch/xen/i386/kernel/smpboot.c | 8 ++--- linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c | 12 +++---- .../arch/xen/x86_64/kernel/smpboot.c | 4 +-- .../asm-xen/asm-i386/mach-xen/smpboot_hooks.h | 2 +- .../asm-x86_64/mach-xen/smpboot_hooks.h | 2 +- linux-2.6-xen-sparse/include/asm-xen/evtchn.h | 5 +-- tools/libxc/xc_linux_build.c | 4 +-- tools/libxc/xc_vmx_build.c | 3 -- tools/python/xen/xend/XendDomainInfo.py | 2 +- xen/arch/ia64/vmx/vmx_support.c | 8 ++--- xen/arch/x86/domain_build.c | 8 ++--- xen/arch/x86/vmx_io.c | 12 +++---- xen/common/keyhandler.c | 2 +- xen/include/public/xen.h | 36 ++++++++++--------- xen/include/xen/event.h | 9 ++--- xen/include/xen/sched.h | 2 +- 17 files changed, 62 insertions(+), 65 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c index bd576ce869..0027b82a62 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/evtchn_ia64.c @@ -94,7 +94,7 @@ void notify_remote_via_irq(int irq) irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) { - u32 l1, l2; + unsigned long l1, l2; unsigned int l1i, l2i, port; irqreturn_t (*handler)(int, void *, struct pt_regs *); shared_info_t *s = HYPERVISOR_shared_info; @@ -108,14 +108,14 @@ irqreturn_t evtchn_interrupt(int irq, void *dev_id, struct pt_regs *regs) while ( l1 != 0 ) { l1i = __ffs(l1); - l1 &= ~(1 << l1i); + l1 &= ~(1UL << l1i); while ( (l2 = s->evtchn_pending[l1i] & ~s->evtchn_mask[l1i]) != 0 ) { l2i = __ffs(l2); - l2 &= ~(1 << l2i); + l2 &= ~(1UL << l2i); - port = (l1i << 5) + l2i; + port = (l1i * BITS_PER_LONG) + l2i; if ( (handler = evtchns[port].handler) != NULL ) { clear_evtchn(port); diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c index b13abf720e..01e245e3ab 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c @@ -1123,7 +1123,7 @@ static void __init smp_boot_cpus(unsigned int max_cpus) * If SMP should be disabled, then really disable it! */ if (!max_cpus) { - HYPERVISOR_shared_info->n_vcpu = 1; + xen_start_info->n_vcpu = 1; printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); smpboot_clear_io_apic_irqs(); #if 0 @@ -1153,12 +1153,10 @@ static void __init smp_boot_cpus(unsigned int max_cpus) */ Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map)); #endif - Dprintk("CPU present map: %lx\n", - (1UL << HYPERVISOR_shared_info->n_vcpu) - 1); + Dprintk("CPU present map: %lx\n", (1UL << xen_start_info->n_vcpu) - 1); kicked = 1; - for (cpu = 1; kicked < NR_CPUS && - cpu < HYPERVISOR_shared_info->n_vcpu; cpu++) { + for (cpu = 1; kicked < NR_CPUS && cpu < xen_start_info->n_vcpu; cpu++) { if (max_cpus <= cpucount+1) continue; diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c index 80e017684b..1d27f11910 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/evtchn.c @@ -71,8 +71,8 @@ static unsigned long pirq_needs_unmask_notify[NR_PIRQS/sizeof(unsigned long)]; #ifdef CONFIG_SMP -static u8 cpu_evtchn[NR_EVENT_CHANNELS]; -static u32 cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/32]; +static u8 cpu_evtchn[NR_EVENT_CHANNELS]; +static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG]; #define active_evtchns(cpu,sh,idx) \ ((sh)->evtchn_pending[idx] & \ @@ -137,7 +137,7 @@ EXPORT_SYMBOL(force_evtchn_callback); /* NB. Interrupts are disabled on entry. */ asmlinkage void evtchn_do_upcall(struct pt_regs *regs) { - u32 l1, l2; + unsigned long l1, l2; unsigned int l1i, l2i, port; int irq, cpu = smp_processor_id(); shared_info_t *s = HYPERVISOR_shared_info; @@ -149,13 +149,13 @@ asmlinkage void evtchn_do_upcall(struct pt_regs *regs) l1 = xchg(&vcpu_info->evtchn_pending_sel, 0); while (l1 != 0) { l1i = __ffs(l1); - l1 &= ~(1 << l1i); + l1 &= ~(1UL << l1i); while ((l2 = active_evtchns(cpu, s, l1i)) != 0) { l2i = __ffs(l2); - l2 &= ~(1 << l2i); + l2 &= ~(1UL << l2i); - port = (l1i << 5) + l2i; + port = (l1i * BITS_PER_LONG) + l2i; if ((irq = evtchn_to_irq[port]) != -1) do_IRQ(irq, regs); else diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c index 48abf11507..b48b559a45 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c @@ -1045,7 +1045,7 @@ static int __cpuinit smp_sanity_check(unsigned max_cpus) */ if (!max_cpus) { #ifdef CONFIG_XEN - HYPERVISOR_shared_info->n_vcpu = 1; + xen_start_info->n_vcpu = 1; #endif printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); #ifndef CONFIG_XEN @@ -1082,7 +1082,7 @@ void __cpuinit smp_prepare_cpus(unsigned int max_cpus) int apicid = cpu_present_to_apicid(i); if (physid_isset(apicid, phys_cpu_present_map)) { #else - if (i < HYPERVISOR_shared_info->n_vcpu) { + if (i < xen_start_info->n_vcpu) { #endif cpu_set(i, cpu_present_map); /* possible map would be different if we supported real diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h index 28adeaf244..fa85aa2cfe 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h @@ -52,4 +52,4 @@ static inline void smpboot_setup_io_apic(void) } -#define smp_found_config (HYPERVISOR_shared_info->n_vcpu > 1) +#define smp_found_config (xen_start_info->n_vcpu > 1) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h index 28adeaf244..fa85aa2cfe 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h @@ -52,4 +52,4 @@ static inline void smpboot_setup_io_apic(void) } -#define smp_found_config (HYPERVISOR_shared_info->n_vcpu > 1) +#define smp_found_config (xen_start_info->n_vcpu > 1) diff --git a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h index f2523926d8..127cf8e72f 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/evtchn.h +++ b/linux-2.6-xen-sparse/include/asm-xen/evtchn.h @@ -99,8 +99,9 @@ static inline void unmask_evtchn(int port) * like a real IO-APIC we 'lose the interrupt edge' if the channel is * masked. */ - if (synch_test_bit (port, &s->evtchn_pending[0]) && - !synch_test_and_set_bit(port>>5, &vcpu_info->evtchn_pending_sel)) { + if (synch_test_bit(port, &s->evtchn_pending[0]) && + !synch_test_and_set_bit(port / BITS_PER_LONG, + &vcpu_info->evtchn_pending_sel)) { vcpu_info->evtchn_upcall_pending = 1; if (!vcpu_info->evtchn_upcall_mask) force_evtchn_callback(); diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 5cdb568bc0..1185fc020e 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -636,6 +636,7 @@ static int setup_guest(int xc_handle, start_info->store_evtchn = store_evtchn; start_info->console_mfn = *console_mfn; start_info->console_evtchn = console_evtchn; + start_info->n_vcpu = vcpus; if ( initrd_len != 0 ) { start_info->mod_start = vinitrd_start; @@ -653,9 +654,6 @@ static int setup_guest(int xc_handle, for ( i = 0; i < MAX_VIRT_CPUS; i++ ) shared_info->vcpu_data[i].evtchn_upcall_mask = 1; - shared_info->n_vcpu = vcpus; - printf(" VCPUS: %d\n", shared_info->n_vcpu); - munmap(shared_info, PAGE_SIZE); /* Send the page update requests down to the hypervisor. */ diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index 5dd55e94f7..2f8a5ec72d 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -519,9 +519,6 @@ static int setup_guest(int xc_handle, for ( i = 0; i < MAX_VIRT_CPUS; i++ ) shared_info->vcpu_data[i].evtchn_upcall_mask = 1; - shared_info->n_vcpu = vcpus; - printf(" VCPUS: %d\n", shared_info->n_vcpu); - munmap(shared_info, PAGE_SIZE); /* Populate the event channel port in the shared page */ diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 79fdd38a9a..3615aed8d9 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -439,7 +439,7 @@ class XendDomainInfo: defaultInfo('on_crash', lambda: "restart") defaultInfo('cpu', lambda: None) defaultInfo('cpu_weight', lambda: 1.0) - defaultInfo('vcpus', lambda: 1) + defaultInfo('vcpus', lambda: int(1)) defaultInfo('vcpu_avail', lambda: (1 << self.info['vcpus']) - 1) defaultInfo('bootloader', lambda: None) defaultInfo('backend', lambda: []) diff --git a/xen/arch/ia64/vmx/vmx_support.c b/xen/arch/ia64/vmx/vmx_support.c index afd0f650d0..4da31f2332 100644 --- a/xen/arch/ia64/vmx/vmx_support.c +++ b/xen/arch/ia64/vmx/vmx_support.c @@ -49,7 +49,7 @@ void vmx_wait_io(void) */ if (test_and_clear_bit(port, &d->shared_info->evtchn_pending[0])) { - clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel); + clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel); clear_bit(0, &v->vcpu_info->evtchn_upcall_pending); vmx_io_assist(v); } @@ -67,7 +67,7 @@ void vmx_wait_io(void) * nothing losed. Next loop will check I/O channel to fix this * window. */ - clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel); + clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel); } else break; @@ -139,8 +139,8 @@ void vmx_intr_assist(struct vcpu *v) /* Clear indicator specific to interrupt delivered from DM */ if (test_and_clear_bit(port, &d->shared_info->evtchn_pending[0])) { - if (!d->shared_info->evtchn_pending[port >> 5]) - clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel); + if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG]) + clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel); if (!v->vcpu_info->evtchn_pending_sel) clear_bit(0, &v->vcpu_info->evtchn_upcall_pending); diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 69b0ddd58b..38a3cb2c99 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -557,10 +557,9 @@ int construct_dom0(struct domain *d, /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) d->shared_info->vcpu_data[i].evtchn_upcall_mask = 1; - d->shared_info->n_vcpu = num_online_cpus(); - for ( i = 1; i < d->shared_info->n_vcpu; i++ ) - (void)alloc_vcpu(d, i, i % num_online_cpus()); + for ( i = 1; i < num_online_cpus(); i++ ) + (void)alloc_vcpu(d, i, i); /* Set up monitor table */ update_pagetables(v); @@ -588,7 +587,8 @@ int construct_dom0(struct domain *d, /* Set up start info area. */ si = (start_info_t *)vstartinfo_start; memset(si, 0, PAGE_SIZE); - si->nr_pages = nr_pages; + si->nr_pages = nr_pages; + si->n_vcpu = num_online_cpus(); if ( opt_dom0_translate ) { diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 1d904e43a9..e6536b31a1 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -684,15 +684,15 @@ int vmx_clear_pending_io_event(struct vcpu *v) struct domain *d = v->domain; int port = iopacket_port(d); - /* evtchn_pending is shared by other event channels in 0-31 range */ - if (!d->shared_info->evtchn_pending[port>>5]) - clear_bit(port>>5, &v->vcpu_info->evtchn_pending_sel); + /* evtchn_pending_sel bit is shared by other event channels. */ + if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG]) + clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel); - /* Note: VMX domains may need upcalls as well */ + /* Note: VMX domains may need upcalls as well. */ if (!v->vcpu_info->evtchn_pending_sel) clear_bit(0, &v->vcpu_info->evtchn_upcall_pending); - /* clear the pending bit for port */ + /* Clear the pending bit for port. */ return test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]); } @@ -726,7 +726,7 @@ void vmx_wait_io() break; /* Events other than IOPACKET_PORT might have woken us up. In that case, safely go back to sleep. */ - clear_bit(port>>5, ¤t->vcpu_info->evtchn_pending_sel); + clear_bit(port/BITS_PER_LONG, ¤t->vcpu_info->evtchn_pending_sel); clear_bit(0, ¤t->vcpu_info->evtchn_upcall_pending); } while(1); } diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 0f1bbb9872..acbfd094bc 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -136,7 +136,7 @@ static void do_task_queues(unsigned char key) &d->shared_info->evtchn_pending[0]), test_bit(v->virq_to_evtchn[VIRQ_DEBUG], &d->shared_info->evtchn_mask[0]), - test_bit(v->virq_to_evtchn[VIRQ_DEBUG]>>5, + test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel)); send_guest_virq(v, VIRQ_DEBUG); } diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index c0111b5027..3c2d0094f2 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -260,8 +260,11 @@ typedef struct unsigned long args[6]; } multicall_entry_t; -/* Event channel endpoints per domain. */ -#define NR_EVENT_CHANNELS 1024 +/* + * Event channel endpoints per domain: + * 1024 if a long is 32 bits; 4096 if a long is 64 bits. + */ +#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64) /* * Per-VCPU information goes here. This will be cleaned up more when Xen @@ -295,7 +298,7 @@ typedef struct vcpu_info { */ uint8_t evtchn_upcall_pending; uint8_t evtchn_upcall_mask; - uint32_t evtchn_pending_sel; + unsigned long evtchn_pending_sel; #ifdef __ARCH_HAS_VCPU_INFO arch_vcpu_info_t arch; #endif @@ -333,16 +336,14 @@ typedef struct shared_info { vcpu_time_info_t vcpu_time[MAX_VIRT_CPUS]; - uint32_t n_vcpu; - /* - * A domain can have up to 1024 "event channels" on which it can send - * and receive asynchronous event notifications. There are three classes - * of event that are delivered by this mechanism: + * A domain can create "event channels" on which it can send and receive + * asynchronous event notifications. There are three classes of event that + * are delivered by this mechanism: * 1. Bi-directional inter- and intra-domain connections. Domains must - * arrange out-of-band to set up a connection (usually the setup - * is initiated and organised by a privileged third party such as - * software running in domain 0). + * arrange out-of-band to set up a connection (usually by allocating + * an unbound 'listener' port and avertising that via a storage service + * such as xenstore). * 2. Physical interrupts. A domain with suitable hardware-access * privileges can bind an event-channel port to a physical interrupt * source. @@ -350,8 +351,8 @@ typedef struct shared_info { * port to a virtual interrupt source, such as the virtual-timer * device or the emergency console. * - * Event channels are addressed by a "port index" between 0 and 1023. - * Each channel is associated with two bits of information: + * Event channels are addressed by a "port index". Each channel is + * associated with two bits of information: * 1. PENDING -- notifies the domain that there is a pending notification * to be processed. This bit is cleared by the guest. * 2. MASK -- if this bit is clear then a 0->1 transition of PENDING @@ -363,11 +364,11 @@ typedef struct shared_info { * * To expedite scanning of pending notifications, any 0->1 pending * transition on an unmasked channel causes a corresponding bit in a - * 32-bit selector to be set. Each bit in the selector covers a 32-bit - * word in the PENDING bitfield array. + * per-vcpu selector word to be set. Each bit in the selector covers a + * 'C long' in the PENDING bitfield array. */ - uint32_t evtchn_pending[32]; - uint32_t evtchn_mask[32]; + unsigned long evtchn_pending[sizeof(unsigned long) * 8]; + unsigned long evtchn_mask[sizeof(unsigned long) * 8]; /* * Wallclock time: updated only by control software. Guests should base @@ -422,6 +423,7 @@ typedef struct start_info { unsigned long mfn_list; /* VIRTUAL address of page-frame list. */ unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */ unsigned long mod_len; /* Size (bytes) of pre-loaded module. */ + uint32_t n_vcpu; int8_t cmd_line[MAX_GUEST_CMDLINE]; } start_info_t; diff --git a/xen/include/xen/event.h b/xen/include/xen/event.h index 8f527b0c83..e8a8bc2b5b 100644 --- a/xen/include/xen/event.h +++ b/xen/include/xen/event.h @@ -28,10 +28,11 @@ static inline void evtchn_set_pending(struct vcpu *v, int port) shared_info_t *s = d->shared_info; /* These four operations must happen in strict order. */ - if ( !test_and_set_bit(port, &s->evtchn_pending[0]) && - !test_bit (port, &s->evtchn_mask[0]) && - !test_and_set_bit(port>>5, &v->vcpu_info->evtchn_pending_sel) && - !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) ) + if ( !test_and_set_bit(port, &s->evtchn_pending[0]) && + !test_bit (port, &s->evtchn_mask[0]) && + !test_and_set_bit(port / BITS_PER_LONG, + &v->vcpu_info->evtchn_pending_sel) && + !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) ) { evtchn_notify(v); } diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 4250205268..0f012456af 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -19,7 +19,7 @@ extern rwlock_t domlist_lock; /* A global pointer to the initial domain (DOM0). */ extern struct domain *dom0; -#define MAX_EVTCHNS 1024 +#define MAX_EVTCHNS NR_EVENT_CHANNELS #define EVTCHNS_PER_BUCKET 128 #define NR_EVTCHN_BUCKETS (MAX_EVTCHNS / EVTCHNS_PER_BUCKET) From dc66fe31f3bd4a63d95be94a0e6144ce102ea460 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 17 Oct 2005 15:54:28 +0100 Subject: [PATCH 069/142] Remove useless SIF_XXX_BE_DOMAIN driver flags. Signed-off-by: Keir Fraser --- .../drivers/xen/blkback/blkback.c | 4 -- .../drivers/xen/blkfront/blkfront.c | 14 +------ .../drivers/xen/blktap/blktap.c | 6 +-- .../drivers/xen/netback/netback.c | 6 --- .../drivers/xen/tpmback/tpmback.c | 5 --- .../include/asm-xen/asm-i386/hypervisor.h | 2 + .../include/asm-xen/asm-ia64/hypervisor.h | 1 + tools/python/xen/xend/XendDomainInfo.py | 40 ++++--------------- xen/arch/ia64/xen/domain.c | 2 +- xen/include/public/xen.h | 6 --- 10 files changed, 13 insertions(+), 73 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c index c769342255..c9d812695e 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c @@ -494,10 +494,6 @@ static int __init blkif_init(void) int i; struct page *page; - if (!(xen_start_info->flags & SIF_INITDOMAIN) && - !(xen_start_info->flags & SIF_BLK_BE_DOMAIN)) - return 0; - blkif_interface_init(); page = balloon_alloc_empty_page_range(MMAP_PAGES); diff --git a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c index edb5360cd7..671f16038c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c @@ -725,21 +725,9 @@ static struct xenbus_driver blkfront = { .suspend = blkfront_suspend, }; -static void __init init_blk_xenbus(void) -{ - xenbus_register_driver(&blkfront); -} - static int __init xlblk_init(void) { - if ((xen_start_info->flags & SIF_INITDOMAIN) || - (xen_start_info->flags & SIF_BLK_BE_DOMAIN) ) - return 0; - - IPRINTK("Initialising virtual block device driver\n"); - - init_blk_xenbus(); - + xenbus_register_driver(&blkfront); return 0; } diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c index 748dcdd2c0..dacedfc227 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c @@ -861,11 +861,7 @@ static int __init blkif_init(void) { int i, j, err; struct page *page; -/* - if ( !(xen_start_info->flags & SIF_INITDOMAIN) && - !(xen_start_info->flags & SIF_BLK_BE_DOMAIN) ) - return 0; -*/ + blkif_interface_init(); page = balloon_alloc_empty_page_range(MMAP_PAGES); diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c index 1c29a97f9d..656ed94ded 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c @@ -781,12 +781,6 @@ static int __init netback_init(void) int i; struct page *page; - if (!(xen_start_info->flags & SIF_NET_BE_DOMAIN) && - !(xen_start_info->flags & SIF_INITDOMAIN)) - return 0; - - IPRINTK("Initialising Xen netif backend.\n"); - /* We can increase reservation by this much in net_rx_action(). */ balloon_update_driver_allowance(NETIF_RX_RING_SIZE); diff --git a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c index 0a8d70528c..9b02556e56 100644 --- a/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c +++ b/linux-2.6-xen-sparse/drivers/xen/tpmback/tpmback.c @@ -1076,11 +1076,6 @@ static int __init tpmback_init(void) { int rc; - if (!(xen_start_info->flags & SIF_TPM_BE_DOMAIN) && - !(xen_start_info->flags & SIF_INITDOMAIN)) { - printk(KERN_ALERT "Neither TPM-BE Domain nor INIT domain!\n"); - return 0; - } if ((rc = misc_register(&ibmvtpms_miscdevice)) != 0) { printk(KERN_ALERT "Could not register misc device for TPM BE.\n"); diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h index 55c8761913..06015e6ccb 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/hypervisor.h @@ -50,6 +50,8 @@ # endif #endif +extern shared_info_t *HYPERVISOR_shared_info; + /* arch/xen/i386/kernel/setup.c */ extern start_info_t *xen_start_info; diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypervisor.h b/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypervisor.h index 6890c67d7d..da4303f9b6 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypervisor.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypervisor.h @@ -39,6 +39,7 @@ #include #include +extern shared_info_t *HYPERVISOR_shared_info; extern start_info_t *xen_start_info; void force_evtchn_callback(void); diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 3615aed8d9..2c92da390e 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -81,19 +81,8 @@ restart_modes = [ STATE_DOM_OK = 1 STATE_DOM_SHUTDOWN = 2 -"""Flag for a block device backend domain.""" -SIF_BLK_BE_DOMAIN = (1<<4) - -"""Flag for a net device backend domain.""" -SIF_NET_BE_DOMAIN = (1<<5) - -"""Flag for a TPM device backend domain.""" -SIF_TPM_BE_DOMAIN = (1<<7) - - SHUTDOWN_TIMEOUT = 30 - DOMROOT = '/local/domain/' VMROOT = '/vm/' @@ -512,11 +501,6 @@ class XendDomainInfo: if self.info['maxmem_KiB'] > self.info['memory_KiB']: self.info['maxmem_KiB'] = self.info['memory_KiB'] - # Validate the given backend names. - for s in self.info['backend']: - if s not in backendFlags: - raise VmError('Invalid backend type: %s' % s) - for (n, c) in self.info['device']: if not n or not c or n not in controllerClasses: raise VmError('invalid device (%s, %s)' % @@ -678,8 +662,7 @@ class XendDomainInfo: def getBackendFlags(self): - return reduce(lambda x, y: x | backendFlags[y], - self.info['backend'], 0) + return 0 def refreshShutdown(self, xeninfo = None): @@ -1409,25 +1392,16 @@ class XendDomainInfo: implements the device control specific to that device-class.""" controllerClasses = {} - -"""A map of backend names and the corresponding flag.""" -backendFlags = {} - - -def addControllerClass(device_class, backend_name, backend_flag, cls): +def addControllerClass(device_class, backend_name, cls): """Register a subclass of DevController to handle the named device-class. - - @param backend_flag One of the SIF_XYZ_BE_DOMAIN constants, or None if - no flag is to be set. """ cls.deviceClass = device_class - backendFlags[backend_name] = backend_flag controllerClasses[device_class] = cls from xen.xend.server import blkif, netif, tpmif, pciif, usbif -addControllerClass('vbd', 'blkif', SIF_BLK_BE_DOMAIN, blkif.BlkifController) -addControllerClass('vif', 'netif', SIF_NET_BE_DOMAIN, netif.NetifController) -addControllerClass('vtpm', 'tpmif', SIF_TPM_BE_DOMAIN, tpmif.TPMifController) -addControllerClass('pci', 'pciif', None, pciif.PciController) -addControllerClass('usb', 'usbif', None, usbif.UsbifController) +addControllerClass('vbd', 'blkif', blkif.BlkifController) +addControllerClass('vif', 'netif', netif.NetifController) +addControllerClass('vtpm', 'tpmif', tpmif.TPMifController) +addControllerClass('pci', 'pciif', pciif.PciController) +addControllerClass('usb', 'usbif', usbif.UsbifController) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 64eda8638b..e77d1d1498 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -351,7 +351,7 @@ void new_thread(struct vcpu *v, } VCPU(v, banknum) = 1; VCPU(v, metaphysical_mode) = 1; - d->shared_info->arch.flags = (d == dom0) ? (SIF_INITDOMAIN|SIF_PRIVILEGED|SIF_BLK_BE_DOMAIN|SIF_NET_BE_DOMAIN|SIF_USB_BE_DOMAIN) : 0; + d->shared_info->arch.flags = (d == dom0) ? (SIF_INITDOMAIN|SIF_PRIVILEGED) : 0; } } diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 3c2d0094f2..c88113ab6c 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -430,12 +430,6 @@ typedef struct start_info { /* These flags are passed in the 'flags' field of start_info_t. */ #define SIF_PRIVILEGED (1<<0) /* Is the domain privileged? */ #define SIF_INITDOMAIN (1<<1) /* Is this the initial control domain? */ -#define SIF_BLK_BE_DOMAIN (1<<4) /* Is this a block backend domain? */ -#define SIF_NET_BE_DOMAIN (1<<5) /* Is this a net backend domain? */ -#define SIF_USB_BE_DOMAIN (1<<6) /* Is this a usb backend domain? */ -#define SIF_TPM_BE_DOMAIN (1<<7) /* Is this a TPM backend domain? */ -/* For use in guest OSes. */ -extern shared_info_t *HYPERVISOR_shared_info; typedef uint64_t cpumap_t; From 706fcdf4de51d825c80d3695664df34bc5ea01ff Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 17 Oct 2005 16:22:05 +0100 Subject: [PATCH 070/142] Have xenstored initialise its connections, meaning that xend can be out of that loop completely -- the xc_init_store, initDomainStore calls can all go. Have xenstored understand where the local domain information goes. Xend no longer has to generate a path and pass it to xenstored through xs_introduce_domain -- we just allow xenstored to generate the path, and then call GetDomainPath later. There is still some work required to tidy this up. Change the uuid module to generate uuids as lists of bytes, not in the stringified form. Added a unit test for that module. Change the semantics of Xend restart, relying on these changes to the xenstored semantics and earlier changes to add an opaque handle to the hypervisor's domain-specific data block. The semantics are now clearer, as Xend can validate whether the details in the store match the current live domain. Added a usage statement to xenstored. Some of this code is by Steven Hand. Signed-off-by: Ewan Mellor --- .../drivers/xen/privcmd/privcmd.c | 37 ----- .../drivers/xen/xenbus/xenbus_comms.c | 15 +- .../drivers/xen/xenbus/xenbus_probe.c | 140 ++++++++++++++---- .../include/asm-xen/linux-public/privcmd.h | 2 - tools/libxc/xc_misc.c | 5 - tools/libxc/xenctrl.h | 15 +- tools/python/xen/lowlevel/xc/xc.c | 24 --- tools/python/xen/lowlevel/xs/xs.c | 10 +- tools/python/xen/xend/XendCheckpoint.py | 9 +- tools/python/xen/xend/XendDomain.py | 39 ++--- tools/python/xen/xend/XendDomainInfo.py | 110 +++++++------- tools/python/xen/xend/uuid.py | 20 ++- tools/python/xen/xend/xenstore/xsutil.py | 4 +- tools/xenstore/xenstored_core.c | 41 ++++- tools/xenstore/xenstored_domain.c | 78 +++++++--- tools/xenstore/xs.c | 6 +- tools/xenstore/xs.h | 4 +- 17 files changed, 312 insertions(+), 247 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c index 6ed338bab1..b13f22a771 100644 --- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c +++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c @@ -25,8 +25,6 @@ #include #include #include -#include -#include #include #include #include @@ -219,41 +217,6 @@ static int privcmd_ioctl(struct inode *inode, struct file *file, } break; - case IOCTL_PRIVCMD_INITDOMAIN_STORE: { - extern int do_xenbus_probe(void*); - unsigned long page; - - if (xen_start_info->store_evtchn != 0) { - ret = xen_start_info->store_mfn; - break; - } - - /* Allocate page. */ - page = get_zeroed_page(GFP_KERNEL); - if (!page) { - ret = -ENOMEM; - break; - } - - /* We don't refcnt properly, so set reserved on page. - * (this allocation is permanent) */ - SetPageReserved(virt_to_page(page)); - - /* Initial connect. Setup channel and page. */ - xen_start_info->store_evtchn = data; - xen_start_info->store_mfn = - pfn_to_mfn(virt_to_phys((void *)page) >> - PAGE_SHIFT); - ret = xen_start_info->store_mfn; - - /* - ** Complete initialization of xenbus (viz. set up the - ** connection to xenstored now that it has started). - */ - kthread_run(do_xenbus_probe, NULL, "xenbus_probe"); - } - break; - default: ret = -EINVAL; break; diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c index e3863a2c79..a1e83f7800 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c @@ -36,7 +36,11 @@ #include #include "xenbus_comms.h" -static int xenbus_irq; +static int xenbus_irq = 0; + +extern void xenbus_probe(void *); +extern int xenstored_ready; +static DECLARE_WORK(probe_work, xenbus_probe, NULL); DECLARE_WAIT_QUEUE_HEAD(xb_waitq); @@ -47,6 +51,11 @@ static inline struct xenstore_domain_interface *xenstore_domain_interface(void) static irqreturn_t wake_waiting(int irq, void *unused, struct pt_regs *regs) { + if(unlikely(xenstored_ready == 0)) { + xenstored_ready = 1; + schedule_work(&probe_work); + } + wake_up(&xb_waitq); return IRQ_HANDLED; } @@ -169,10 +178,6 @@ int xb_init_comms(void) if (xenbus_irq) unbind_evtchn_from_irqhandler(xenbus_irq, &xb_waitq); - xenbus_irq = 0; - - if (!xen_start_info->store_evtchn) - return 0; err = bind_evtchn_to_irqhandler( xen_start_info->store_evtchn, wake_waiting, diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index e04798a562..e5c9de1139 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -27,16 +27,25 @@ */ #define DEBUG -#include -#include -#include #include #include #include #include #include -#include +#include #include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + #include "xenbus_comms.h" extern struct semaphore xenwatch_mutex; @@ -634,15 +643,19 @@ void xenbus_resume(void) bus_for_each_dev(&xenbus_backend.bus, NULL, NULL, resume_dev); } + +/* A flag to determine if xenstored is 'ready' (i.e. has started) */ +int xenstored_ready = 0; + + int register_xenstore_notifier(struct notifier_block *nb) { int ret = 0; - if (xen_start_info->store_evtchn) { + if(xenstored_ready > 0) ret = nb->notifier_call(nb, 0, NULL); - } else { + else notifier_chain_register(&xenstore_chain, nb); - } return ret; } @@ -654,22 +667,11 @@ void unregister_xenstore_notifier(struct notifier_block *nb) } EXPORT_SYMBOL(unregister_xenstore_notifier); -/* -** Called either from below xenbus_probe_init() initcall (for domUs) -** or, for dom0, from a thread created in privcmd/privcmd.c (after -** the user-space tools have invoked initDomainStore()) -*/ -int do_xenbus_probe(void *unused) -{ - int err = 0; - /* Initialize the interface to xenstore. */ - err = xs_init(); - if (err) { - printk("XENBUS: Error initializing xenstore comms:" - " %i\n", err); - return err; - } + +void xenbus_probe(void *unused) +{ + BUG_ON((xenstored_ready <= 0)); /* Enumerate devices in xenstore. */ xenbus_probe_devices(&xenbus_frontend); @@ -682,27 +684,101 @@ int do_xenbus_probe(void *unused) /* Notify others that xenstore is up */ notifier_call_chain(&xenstore_chain, 0, 0); - return 0; + return; } + +static struct proc_dir_entry *xsd_mfn_intf; +static struct proc_dir_entry *xsd_port_intf; + + +static int xsd_mfn_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + len = sprintf(page, "%ld", xen_start_info->store_mfn); + *eof = 1; + return len; +} + +static int xsd_port_read(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + int len; + + len = sprintf(page, "%d", xen_start_info->store_evtchn); + *eof = 1; + return len; +} + + static int __init xenbus_probe_init(void) { - if (xen_init() < 0) - return -ENODEV; + int err = 0; + /* + ** Domain0 doesn't have a store_evtchn or store_mfn yet. + */ + int dom0 = (xen_start_info->store_evtchn == 0); + printk("xenbus_probe_init\n"); + + if (xen_init() < 0) { + printk("xen_init failed\n"); + return -ENODEV; + } + + /* Register ourselves with the kernel bus & device subsystems */ bus_register(&xenbus_frontend.bus); bus_register(&xenbus_backend.bus); device_register(&xenbus_frontend.dev); device_register(&xenbus_backend.dev); - /* - ** Domain0 doesn't have a store_evtchn yet - this will - ** be set up later by xend invoking initDomainStore() - */ - if (!xen_start_info->store_evtchn) - return 0; + if (dom0) { + + unsigned long page; + evtchn_op_t op = { 0 }; + + + /* Allocate page. */ + page = get_zeroed_page(GFP_KERNEL); + if (!page) + return -ENOMEM; + + /* We don't refcnt properly, so set reserved on page. + * (this allocation is permanent) */ + SetPageReserved(virt_to_page(page)); + + xen_start_info->store_mfn = + pfn_to_mfn(virt_to_phys((void *)page) >> + PAGE_SHIFT); + + /* Next allocate a local port which xenstored can bind to */ + op.cmd = EVTCHNOP_alloc_unbound; + op.u.alloc_unbound.dom = DOMID_SELF; + op.u.alloc_unbound.remote_dom = 0; + + BUG_ON(HYPERVISOR_event_channel_op(&op)); + xen_start_info->store_evtchn = op.u.alloc_unbound.port; + + /* And finally publish the above info in /proc/xen */ + if((xsd_mfn_intf = create_xen_proc_entry("xsd_mfn", 0400))) + xsd_mfn_intf->read_proc = xsd_mfn_read; + if((xsd_port_intf = create_xen_proc_entry("xsd_port", 0400))) + xsd_port_intf->read_proc = xsd_port_read; + } + + /* Initialize the interface to xenstore. */ + err = xs_init(); + if (err) { + printk("XENBUS: Error initializing xenstore comms: %i\n", err); + return err; + } + + if (!dom0) { + xenstored_ready = 1; + xenbus_probe(NULL); + } - do_xenbus_probe(NULL); return 0; } diff --git a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h index 1246dbd64b..292ade02b8 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h +++ b/linux-2.6-xen-sparse/include/asm-xen/linux-public/privcmd.h @@ -76,8 +76,6 @@ typedef struct privcmd_blkmsg _IOC(_IOC_NONE, 'P', 3, sizeof(privcmd_mmapbatch_t)) #define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN \ _IOC(_IOC_READ, 'P', 4, sizeof(unsigned long)) -#define IOCTL_PRIVCMD_INITDOMAIN_STORE \ - _IOC(_IOC_READ, 'P', 5, 0) #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */ diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c index ab263689c5..b0987d2a47 100644 --- a/tools/libxc/xc_misc.c +++ b/tools/libxc/xc_misc.c @@ -131,11 +131,6 @@ int xc_msr_write(int xc_handle, int cpu_mask, int msr, unsigned int low, return rc; } -long xc_init_store(int xc_handle, int remote_port) -{ - return ioctl(xc_handle, IOCTL_PRIVCMD_INITDOMAIN_STORE, remote_port); -} - /* * Local variables: * mode: C diff --git a/tools/libxc/xenctrl.h b/tools/libxc/xenctrl.h index 818a29df24..98408f25bf 100644 --- a/tools/libxc/xenctrl.h +++ b/tools/libxc/xenctrl.h @@ -236,12 +236,12 @@ int xc_domain_getinfolist(int xc_handle, xc_domaininfo_t *info); /** - * This function returns information about one domain. This information is - * more detailed than the information from xc_domain_getinfo(). + * This function returns information about the execution context of a + * particular vcpu of a domain. * * @parm xc_handle a handle to an open hypervisor interface * @parm domid the domain to get information from - * @parm info a pointer to an xc_domaininfo_t to store the domain information + * @parm vcpu the vcpu number * @parm ctxt a pointer to a structure to store the execution context of the * domain * @return 0 on success, -1 on failure @@ -489,15 +489,6 @@ int xc_dom0_op(int xc_handle, dom0_op_t *op); int xc_version(int xc_handle, int cmd, void *arg); -/* Initializes the store (for dom0) - remote_port should be the remote end of a bound interdomain channel between - the store and dom0. - - This function returns a shared frame that should be passed to - xs_introduce_domain - */ -long xc_init_store(int xc_handle, int remote_port); - /* * MMU updates. */ diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 4a11ef77c5..927b1ccdc5 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -862,23 +862,6 @@ static PyObject *pyxc_domain_memory_increase_reservation(PyObject *self, return zero; } -static PyObject *pyxc_init_store(PyObject *self, PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - - int remote_port; - - static char *kwd_list[] = { "remote_port", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i", kwd_list, - &remote_port) ) - return NULL; - - return PyInt_FromLong(xc_init_store(xc->xc_handle, remote_port)); -} - - static PyMethodDef pyxc_methods[] = { { "handle", (PyCFunction)pyxc_handle, @@ -1158,13 +1141,6 @@ static PyMethodDef pyxc_methods[] = { " mem_kb [long]: .\n" "Returns: [int] 0 on success; -1 on error.\n" }, - { "init_store", - (PyCFunction)pyxc_init_store, - METH_VARARGS | METH_KEYWORDS, "\n" - "Initialize the store event channel and return the store page mfn.\n" - " remote_port [int]: store event channel port number.\n" - "Returns: [int] mfn on success; <0 on error.\n" }, - { NULL, NULL, 0, NULL } }; diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c index b676419227..b5ce2c357b 100644 --- a/tools/python/xen/lowlevel/xs/xs.c +++ b/tools/python/xen/lowlevel/xs/xs.c @@ -686,7 +686,6 @@ static PyObject *xspy_transaction_end(PyObject *self, PyObject *args, " dom [int] : domain id\n" \ " page [long] : address of domain's xenstore page\n" \ " port [int] : port the domain is using for xenstore\n" \ - " path [string]: path to the domain's data in xenstore\n" \ "\n" \ "Returns None on success.\n" \ "Raises RuntimeError on error.\n" \ @@ -695,12 +694,11 @@ static PyObject *xspy_transaction_end(PyObject *self, PyObject *args, static PyObject *xspy_introduce_domain(PyObject *self, PyObject *args, PyObject *kwds) { - static char *kwd_spec[] = { "dom", "page", "port", "path", NULL }; - static char *arg_spec = "iiis|"; + static char *kwd_spec[] = { "dom", "page", "port", NULL }; + static char *arg_spec = "iii"; domid_t dom = 0; unsigned long page = 0; unsigned int port = 0; - char *path = NULL; struct xs_handle *xh = xshandle(self); PyObject *val = NULL; @@ -709,10 +707,10 @@ static PyObject *xspy_introduce_domain(PyObject *self, PyObject *args, if (!xh) goto exit; if (!PyArg_ParseTupleAndKeywords(args, kwds, arg_spec, kwd_spec, - &dom, &page, &port, &path)) + &dom, &page, &port)) goto exit; Py_BEGIN_ALLOW_THREADS - xsval = xs_introduce_domain(xh, dom, page, port, path); + xsval = xs_introduce_domain(xh, dom, page, port); Py_END_ALLOW_THREADS if (!xsval) { PyErr_SetFromErrno(PyExc_RuntimeError); diff --git a/tools/python/xen/xend/XendCheckpoint.py b/tools/python/xen/xend/XendCheckpoint.py index d8ae85b91e..25c496add0 100644 --- a/tools/python/xen/xend/XendCheckpoint.py +++ b/tools/python/xen/xend/XendCheckpoint.py @@ -143,15 +143,13 @@ def restore(xd, fd): if m: store_mfn = int(m.group(2)) dominfo.setStoreRef(store_mfn) - log.debug("IntroduceDomain %d %d %d %s", + log.debug("IntroduceDomain %d %d %d", dominfo.getDomid(), store_mfn, - dominfo.store_channel, - dominfo.getDomainPath()) + dominfo.store_channel) IntroduceDomain(dominfo.getDomid(), store_mfn, - dominfo.store_channel, - dominfo.getDomainPath()) + dominfo.store_channel) else: m = re.match(r"^(console-mfn) (\d+)$", line) if m: @@ -171,6 +169,7 @@ def forkHelper(cmd, fd, inputHandler, closeToChild): if closeToChild: child.tochild.close() + lasterr = "error unknown" try: fds = [child.fromchild.fileno(), child.childerr.fileno()] diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 6f1ab9b84e..802c53f689 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -21,8 +21,10 @@ Nothing here is persistent (across reboots). Needs to be persistent for one uptime. """ -import os + import logging +import os +import sys import threading import xen.lowlevel.xc @@ -62,8 +64,11 @@ class XendDomain: self.domains_lock.acquire() try: - self.refresh(True) + self._add_domain( + XendDomainInfo.recreate(self.xen_domains()[PRIV_DOMAIN], + True)) self.dom0_setup() + self.refresh(True) finally: self.domains_lock.release() @@ -178,25 +183,23 @@ class XendDomain: 'Cannot recreate information for dying domain %d.' ' Xend will ignore this domain from now on.', doms[d]['dom']) + elif d == PRIV_DOMAIN: + log.fatal( + "No record of privileged domain %d! Terminating.", d) + sys.exit(1) else: try: - dominfo = XendDomainInfo.recreate(doms[d]) - self._add_domain(dominfo) + self._add_domain( + XendDomainInfo.recreate(doms[d], False)) except: - if d == PRIV_DOMAIN: - log.exception( - "Failed to recreate information for domain " - "%d. Doing nothing except crossing my " - "fingers.", d) - else: - log.exception( - "Failed to recreate information for domain " - "%d. Destroying it in the hope of " - "recovery.", d) - try: - xc.domain_destroy(dom = d) - except: - log.exception('Destruction of %d failed.', d) + log.exception( + "Failed to recreate information for domain " + "%d. Destroying it in the hope of " + "recovery.", d) + try: + xc.domain_destroy(dom = d) + except: + log.exception('Destruction of %d failed.', d) ## public: diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 79fdd38a9a..0ad6f5a7dd 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -28,7 +28,6 @@ import logging import string import time import threading -import errno import xen.lowlevel.xc from xen.util import asserts @@ -42,7 +41,7 @@ from xen.xend.XendBootloader import bootloader from xen.xend.XendError import XendError, VmError from xen.xend.XendRoot import get_component -from uuid import getUuid +import uuid from xen.xend.xenstore.xstransact import xstransact from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain @@ -153,7 +152,7 @@ def create(config): log.debug("XendDomainInfo.create(%s)", config) - vm = XendDomainInfo(getUuid(), parseConfig(config)) + vm = XendDomainInfo(uuid.create(), parseConfig(config)) try: vm.construct() vm.initDomain() @@ -169,7 +168,7 @@ def create(config): raise -def recreate(xeninfo): +def recreate(xeninfo, priv): """Create the VM object for an existing domain. The domain must not be dying, as the paths in the store should already have been removed, and asking us to recreate them causes problems.""" @@ -179,39 +178,52 @@ def recreate(xeninfo): assert not xeninfo['dying'] domid = xeninfo['dom'] + dompath = GetDomainPath(domid) + if not dompath: + raise XendError( + 'No domain path in store for existing domain %d' % domid) try: - dompath = GetDomainPath(domid) - if not dompath: - raise XendError( - 'No domain path in store for existing domain %d' % domid) vmpath = xstransact.Read(dompath, "vm") if not vmpath: raise XendError( 'No vm path in store for existing domain %d' % domid) - uuid = xstransact.Read(vmpath, "uuid") - if not uuid: + uuid1_str = xstransact.Read(vmpath, "uuid") + if not uuid1_str: raise XendError( 'No vm/uuid path in store for existing domain %d' % domid) - log.info("Recreating domain %d, UUID %s.", domid, uuid) + uuid1 = uuid.fromString(uuid1_str) - vm = XendDomainInfo(uuid, xeninfo, domid, True) + uuid2 = xeninfo['handle'] + + if uuid1 != uuid2: + raise XendError( + 'Uuid in store does not match uuid for existing domain %d: ' + '%s != %s' % (domid, uuid1_str, uuid.toString(uuid2))) + + log.info("Recreating domain %d, UUID %s.", domid, uuid1_str) + + vm = XendDomainInfo(uuid2, xeninfo, domid, dompath, True) except Exception, exn: log.warn(str(exn)) - uuid = getUuid() + if priv: + new_uuid = [0 for i in range(0, 16)] + else: + new_uuid = uuid.create() - log.info("Recreating domain %d with new UUID %s.", domid, uuid) + log.info("Recreating domain %d with new UUID %s.", domid, + uuid.toString(new_uuid)) - vm = XendDomainInfo(uuid, xeninfo, domid, True) + vm = XendDomainInfo(new_uuid, xeninfo, domid, dompath, True) vm.removeDom() vm.storeVmDetails() vm.storeDomDetails() - vm.create_channel() - if domid == 0: - vm.initStoreConnection() + if domid != 0: + # Setup store and console channels + vm.create_channels() vm.refreshShutdown(xeninfo) return vm @@ -225,12 +237,12 @@ def restore(config): log.debug("XendDomainInfo.restore(%s)", config) - uuid = sxp.child_value(config, 'uuid') - vm = XendDomainInfo(uuid, parseConfig(config)) + vm = XendDomainInfo(uuid.fromString(sxp.child_value(config, 'uuid')), + parseConfig(config)) try: vm.construct() vm.configure() - vm.create_channel() + vm.create_channels() vm.storeVmDetails() vm.storeDomDetails() vm.refreshShutdown() @@ -355,9 +367,10 @@ class XendDomainInfo: MINIMUM_RESTART_TIME = 20 - def __init__(self, uuid, info, domid = None, augment = False): + def __init__(self, uuidbytes, info, domid = None, dompath = None, + augment = False): - self.uuid = uuid + self.uuidbytes = uuidbytes self.info = info if domid is not None: @@ -367,11 +380,8 @@ class XendDomainInfo: else: self.domid = None - self.vmpath = VMROOT + uuid - if self.domid is None: - self.dompath = None - else: - self.dompath = DOMROOT + str(self.domid) + self.vmpath = VMROOT + uuid.toString(uuidbytes) + self.dompath = dompath if augment: self.augmentInfo() @@ -440,6 +450,9 @@ class XendDomainInfo: defaultInfo('cpu', lambda: None) defaultInfo('cpu_weight', lambda: 1.0) defaultInfo('vcpus', lambda: 1) + + self.info['vcpus'] = int(self.info['vcpus']) + defaultInfo('vcpu_avail', lambda: (1 << self.info['vcpus']) - 1) defaultInfo('bootloader', lambda: None) defaultInfo('backend', lambda: []) @@ -576,7 +589,7 @@ class XendDomainInfo: def storeVmDetails(self): to_store = { - 'uuid': self.uuid, + 'uuid': uuid.toString(self.uuidbytes), # XXX 'memory/target': str(self.info['memory_KiB']) @@ -651,9 +664,6 @@ class XendDomainInfo: def getDomainPath(self): return self.dompath - def getUuid(self): - return self.uuid - def getVCpuCount(self): return self.info['vcpus'] @@ -921,7 +931,7 @@ class XendDomainInfo: def sxpr(self): sxpr = ['domain', ['domid', self.domid], - ['uuid', self.uuid], + ['uuid', uuid.toString(self.uuidbytes)], ['memory', self.info['memory_KiB'] / 1024]] for e in ROUNDTRIPPING_CONFIG_ENTRIES: @@ -1038,7 +1048,8 @@ class XendDomainInfo: self.domid, self.info['ssidref']) - self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref']) + self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'], + handle = self.uuidbytes) if self.domid < 0: raise VmError('Creating domain failed: name=%s' % @@ -1089,10 +1100,9 @@ class XendDomainInfo: def construct_image(self): """Construct the boot image for the domain. """ - self.create_channel() + self.create_channels() self.image.createImage() - IntroduceDomain(self.domid, self.store_mfn, - self.store_channel, self.dompath) + IntroduceDomain(self.domid, self.store_mfn, self.store_channel) ## public: @@ -1199,7 +1209,7 @@ class XendDomainInfo: self.storeDom(path, port) return port - def create_channel(self): + def create_channels(self): """Create the channels to the domain. """ self.store_channel = self.eventChannel("store/port") @@ -1312,13 +1322,15 @@ class XendDomainInfo: """ new_name = self.generateUniqueName() - new_uuid = getUuid() + new_uuid = uuid.create() + new_uuid_str = uuid.toString(new_uuid) log.info("Renaming dead domain %s (%d, %s) to %s (%s).", - self.info['name'], self.domid, self.uuid, new_name, new_uuid) + self.info['name'], self.domid, uuid.toString(self.uuidbytes), + new_name, new_uuid_str) self.release_devices() self.info['name'] = new_name - self.uuid = new_uuid - self.vmpath = VMROOT + new_uuid + self.uuidbytes = new_uuid + self.vmpath = VMROOT + new_uuid_str self.storeVmDetails() self.preserve() @@ -1384,20 +1396,6 @@ class XendDomainInfo: self.storeDom("control/sysrq", '%c' % key) - def initStoreConnection(self): - ref = xc.init_store(self.store_channel) - if ref and ref >= 0: - self.setStoreRef(ref) - try: - IntroduceDomain(self.domid, ref, self.store_channel, - self.dompath) - except RuntimeError, ex: - if ex.args[0] == errno.EISCONN: - pass - else: - raise - - def infoIsSet(self, name): return name in self.info and self.info[name] is not None diff --git a/tools/python/xen/xend/uuid.py b/tools/python/xen/xend/uuid.py index b37cb17a39..77517e9fbe 100644 --- a/tools/python/xen/xend/uuid.py +++ b/tools/python/xen/xend/uuid.py @@ -36,23 +36,27 @@ def getUuidUuidgen(random = True): cmd += " -r" else: cmd += " -t" - return commands.getoutput(cmd) + return fromString(commands.getoutput(cmd)) def getUuidRandom(): """Generate a random UUID.""" - bytes = [ random.randint(0, 255) for i in range(0, 16) ] - # Encode the variant. - bytes[6] = (bytes[6] & 0x0f) | 0x40 - bytes[8] = (bytes[8] & 0x3f) | 0x80 - f = "%02x" - return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(bytes) ) + return [ random.randint(0, 255) for i in range(0, 16) ] #uuidFactory = getUuidUuidgen uuidFactory = getUuidRandom -def getUuid(): +def create(): return uuidFactory() + + +def toString(u): + f = "%02x" + return ( "-".join([f*4, f*2, f*2, f*2, f*6]) % tuple(u) ) + +def fromString(s): + s = s.replace('-', '') + return [ int(s[i : i + 2], 16) for i in range(0, 32, 2) ] diff --git a/tools/python/xen/xend/xenstore/xsutil.py b/tools/python/xen/xend/xenstore/xsutil.py index 486a3eeb4d..d2af3c5ac5 100644 --- a/tools/python/xen/xend/xenstore/xsutil.py +++ b/tools/python/xen/xend/xenstore/xsutil.py @@ -19,8 +19,8 @@ def xshandle(): xs_lock.release() return xs_handle -def IntroduceDomain(domid, page, port, path): - return xshandle().introduce_domain(domid, page, port, path) +def IntroduceDomain(domid, page, port): + return xshandle().introduce_domain(domid, page, port) def GetDomainPath(domid): return xshandle().get_domain_path(domid) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index 3fbad0728d..a66f7d8a48 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -51,7 +51,7 @@ #include "xenctrl.h" #include "tdb.h" -int event_fd; +extern int eventchn_fd; /* in xenstored_domain.c */ static bool verbose; LIST_HEAD(connections); @@ -319,9 +319,9 @@ static int initialize_set(fd_set *inset, fd_set *outset, int sock, int ro_sock) FD_SET(ro_sock, inset); if (ro_sock > max) max = ro_sock; - FD_SET(event_fd, inset); - if (event_fd > max) - max = event_fd; + FD_SET(eventchn_fd, inset); + if (eventchn_fd > max) + max = eventchn_fd; list_for_each_entry(i, &connections, list) { if (i->domain) continue; @@ -1416,15 +1416,37 @@ static void daemonize(void) } +static void usage(void) +{ + fprintf(stderr, +"Usage:\n" +"\n" +" xenstored \n" +"\n" +"where options may include:\n" +"\n" +" --no-domain-init to state that xenstored should not initialise dom0,\n" +" --pid-file giving a file for the daemon's pid to be written,\n" +" --help to output this message,\n" +" --no-fork to request that the daemon does not fork,\n" +" --output-pid to request that the pid of the daemon is output,\n" +" --trace-file giving the file for logging, and\n" +" --verbose to request verbose execution.\n"); +} + + static struct option options[] = { { "no-domain-init", 0, NULL, 'D' }, { "pid-file", 1, NULL, 'F' }, + { "help", 0, NULL, 'H' }, { "no-fork", 0, NULL, 'N' }, { "output-pid", 0, NULL, 'P' }, { "trace-file", 1, NULL, 'T' }, { "verbose", 0, NULL, 'V' }, { NULL, 0, NULL, 0 } }; +extern void dump_conn(struct connection *conn); + int main(int argc, char *argv[]) { int opt, *sock, *ro_sock, max; @@ -1435,7 +1457,7 @@ int main(int argc, char *argv[]) bool no_domain_init = false; const char *pidfile = NULL; - while ((opt = getopt_long(argc, argv, "DF:NPT:V", options, + while ((opt = getopt_long(argc, argv, "DF:HNPT:V", options, NULL)) != -1) { switch (opt) { case 'D': @@ -1444,6 +1466,9 @@ int main(int argc, char *argv[]) case 'F': pidfile = optarg; break; + case 'H': + usage(); + return 0; case 'N': dofork = false; break; @@ -1509,12 +1534,12 @@ int main(int argc, char *argv[]) || listen(*ro_sock, 1) != 0) barf_perror("Could not listen on sockets"); - /* If we're the first, create .perms file for root. */ + /* Setup the database */ setup_structure(); /* Listen to hypervisor. */ if (!no_domain_init) - event_fd = domain_init(); + domain_init(); /* Restore existing connections. */ restore_existing_connections(); @@ -1555,7 +1580,7 @@ int main(int argc, char *argv[]) if (FD_ISSET(*ro_sock, &inset)) accept_connection(*ro_sock, false); - if (FD_ISSET(event_fd, &inset)) + if (FD_ISSET(eventchn_fd, &inset)) handle_event(); list_for_each_entry(i, &connections, list) { diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 74558b1ec9..9ddcf4f728 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -40,9 +40,10 @@ #include static int *xc_handle; -static int eventchn_fd; static int virq_port; +int eventchn_fd = -1; + struct domain { struct list_head list; @@ -79,9 +80,11 @@ static LIST_HEAD(domains); #ifndef TESTING static void evtchn_notify(int port) { + int rc; + struct ioctl_evtchn_notify notify; notify.port = port; - (void)ioctl(event_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); + rc = ioctl(eventchn_fd, IOCTL_EVTCHN_NOTIFY, ¬ify); } #else extern void evtchn_notify(int port); @@ -222,14 +225,14 @@ void handle_event(void) { uint16_t port; - if (read(event_fd, &port, sizeof(port)) != sizeof(port)) + if (read(eventchn_fd, &port, sizeof(port)) != sizeof(port)) barf_perror("Failed to read from event fd"); if (port == virq_port) domain_cleanup(); #ifndef TESTING - if (write(event_fd, &port, sizeof(port)) != sizeof(port)) + if (write(eventchn_fd, &port, sizeof(port)) != sizeof(port)) barf_perror("Failed to write to event fd"); #endif } @@ -247,18 +250,18 @@ bool domain_can_write(struct connection *conn) } static struct domain *new_domain(void *context, unsigned int domid, - unsigned long mfn, int port, - const char *path) + unsigned long mfn, int port) { struct domain *domain; struct ioctl_evtchn_bind_interdomain bind; int rc; + domain = talloc(context, struct domain); domain->port = 0; domain->shutdown = 0; domain->domid = domid; - domain->path = talloc_strdup(domain, path); + domain->path = talloc_asprintf(domain, "/local/domain/%d", domid); domain->interface = xc_map_foreign_range( *xc_handle, domain->domid, getpagesize(), PROT_READ|PROT_WRITE, mfn); @@ -269,13 +272,13 @@ static struct domain *new_domain(void *context, unsigned int domid, talloc_set_destructor(domain, destroy_domain); /* Tell kernel we're interested in this event. */ - bind.remote_domain = domid; - bind.remote_port = port; - rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); - if (rc == -1) - return NULL; + bind.remote_domain = domid; + bind.remote_port = port; + rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_INTERDOMAIN, &bind); + if (rc == -1) + return NULL; + domain->port = rc; - domain->port = rc; domain->conn = new_connection(writechn, readchn); domain->conn->domain = domain; @@ -302,11 +305,10 @@ static struct domain *find_domain_by_domid(unsigned int domid) void do_introduce(struct connection *conn, struct buffered_data *in) { struct domain *domain; - char *vec[4]; + char *vec[3]; unsigned int domid; unsigned long mfn; uint16_t port; - const char *path; if (get_strings(in, vec, ARRAY_SIZE(vec)) < ARRAY_SIZE(vec)) { send_error(conn, EINVAL); @@ -321,10 +323,9 @@ void do_introduce(struct connection *conn, struct buffered_data *in) domid = atoi(vec[0]); mfn = atol(vec[1]); port = atoi(vec[2]); - path = vec[3]; /* Sanity check args. */ - if ((port <= 0) || !is_valid_nodename(path)) { + if (port <= 0) { send_error(conn, EINVAL); return; } @@ -333,7 +334,7 @@ void do_introduce(struct connection *conn, struct buffered_data *in) if (domain == NULL) { /* Hang domain off "in" until we're finished. */ - domain = new_domain(in, domid, mfn, port, path); + domain = new_domain(in, domid, mfn, port); if (!domain) { send_error(conn, errno); return; @@ -348,8 +349,7 @@ void do_introduce(struct connection *conn, struct buffered_data *in) /* Check that the given details match the ones we have previously recorded. */ if (port != domain->remote_port || - mfn != domain->mfn || - strcmp(path, domain->path) != 0) { + mfn != domain->mfn) { send_error(conn, EINVAL); return; } @@ -440,10 +440,45 @@ void restore_existing_connections(void) { } +static int dom0_init(void) +{ + int rc, fd, port; + unsigned long mfn; + char str[20]; + struct domain *dom0; + + fd = open("/proc/xen/xsd_mfn", O_RDONLY); + + rc = read(fd, str, sizeof(str)); + str[rc] = '\0'; + mfn = strtoul(str, NULL, 0); + + close(fd); + + fd = open("/proc/xen/xsd_port", O_RDONLY); + + rc = read(fd, str, sizeof(str)); + str[rc] = '\0'; + port = strtoul(str, NULL, 0); + + close(fd); + + + dom0 = new_domain(NULL, 0, mfn, port); + talloc_steal(dom0->conn, dom0); + + evtchn_notify(dom0->port); + + return 0; +} + + + #define EVTCHN_DEV_NAME "/dev/xen/evtchn" #define EVTCHN_DEV_MAJOR 10 #define EVTCHN_DEV_MINOR 201 + /* Returns the event channel handle. */ int domain_init(void) { @@ -484,6 +519,9 @@ int domain_init(void) if (eventchn_fd < 0) barf_perror("Failed to open evtchn device"); + if (dom0_init() != 0) + barf_perror("Failed to initialize dom0 state"); + bind.virq = VIRQ_DOM_EXC; rc = ioctl(eventchn_fd, IOCTL_EVTCHN_BIND_VIRQ, &bind); if (rc == -1) diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c index 18e875e801..22710d5d01 100644 --- a/tools/xenstore/xs.c +++ b/tools/xenstore/xs.c @@ -674,12 +674,12 @@ bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t, */ bool xs_introduce_domain(struct xs_handle *h, unsigned int domid, unsigned long mfn, - unsigned int eventchn, const char *path) + unsigned int eventchn) { char domid_str[MAX_STRLEN(domid)]; char mfn_str[MAX_STRLEN(mfn)]; char eventchn_str[MAX_STRLEN(eventchn)]; - struct iovec iov[4]; + struct iovec iov[3]; sprintf(domid_str, "%u", domid); sprintf(mfn_str, "%lu", mfn); @@ -691,8 +691,6 @@ bool xs_introduce_domain(struct xs_handle *h, iov[1].iov_len = strlen(mfn_str) + 1; iov[2].iov_base = eventchn_str; iov[2].iov_len = strlen(eventchn_str) + 1; - iov[3].iov_base = (char *)path; - iov[3].iov_len = strlen(path) + 1; return xs_bool(xs_talkv(h, NULL, XS_INTRODUCE, iov, ARRAY_SIZE(iov), NULL)); diff --git a/tools/xenstore/xs.h b/tools/xenstore/xs.h index 92007458d3..618e6615a6 100644 --- a/tools/xenstore/xs.h +++ b/tools/xenstore/xs.h @@ -130,9 +130,7 @@ bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t, bool xs_introduce_domain(struct xs_handle *h, unsigned int domid, unsigned long mfn, - unsigned int eventchn, - const char *path); - + unsigned int eventchn); /* Release a domain. * Tells the store domain to release the memory page to the domain. */ From 6f4faa61b2dd326e158952bb16f1bfbe450ccd01 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 17 Oct 2005 16:33:27 +0100 Subject: [PATCH 071/142] More removal of BE_DOMAIN flags. --- tools/python/xen/xend/XendDomainInfo.py | 4 ---- tools/python/xen/xend/image.py | 6 ------ 2 files changed, 10 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 5c0ae8c120..614ae07f87 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -671,10 +671,6 @@ class XendDomainInfo: self.storeDom("store/ring-ref", ref) - def getBackendFlags(self): - return 0 - - def refreshShutdown(self, xeninfo = None): # If set at the end of this method, a restart is required, with the # given reason. This restart has to be done out of the scope of diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 16208786a5..23cc89cfbc 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -66,7 +66,6 @@ class ImageHandler: self.kernel = None self.ramdisk = None self.cmdline = None - self.flags = 0 self.configure(imageConfig, deviceConfig) @@ -118,7 +117,6 @@ class ImageHandler: """Build the domain boot image. """ # Set params and call buildDomain(). - self.flags = self.vm.getBackendFlags() if not os.path.isfile(self.kernel): raise VmError('Kernel image does not exist: %s' % self.kernel) @@ -180,7 +178,6 @@ class LinuxImageHandler(ImageHandler): log.debug("console_evtchn = %d", console_evtchn) log.debug("cmdline = %s", self.cmdline) log.debug("ramdisk = %s", self.ramdisk) - log.debug("flags = %d", self.flags) log.debug("vcpus = %d", self.vm.getVCpuCount()) ret = xc.linux_build(dom = self.vm.getDomid(), @@ -189,7 +186,6 @@ class LinuxImageHandler(ImageHandler): console_evtchn = console_evtchn, cmdline = self.cmdline, ramdisk = self.ramdisk, - flags = self.flags, vcpus = self.vm.getVCpuCount()) if isinstance(ret, dict): self.set_vminfo(ret) @@ -239,7 +235,6 @@ class VmxImageHandler(ImageHandler): log.debug("control_evtchn = %d", self.device_channel) log.debug("store_evtchn = %d", store_evtchn) log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024) - log.debug("flags = %d", self.flags) log.debug("vcpus = %d", self.vm.getVCpuCount()) ret = xc.vmx_build(dom = self.vm.getDomid(), @@ -247,7 +242,6 @@ class VmxImageHandler(ImageHandler): control_evtchn = self.device_channel, store_evtchn = store_evtchn, memsize = self.vm.getMemoryTarget() / 1024, - flags = self.flags, vcpus = self.vm.getVCpuCount()) if isinstance(ret, dict): self.set_vminfo(ret) From fe453929d395355f1bd2a63a350fa8b22212bdec Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 17 Oct 2005 20:34:10 +0100 Subject: [PATCH 072/142] Put back the arg_check calls removed recently -- they aren't as useless as I thought they were. Signed-off-by: Ewan Mellor --- tools/python/xen/xm/main.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index e2545c53cd..7e35899fc0 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -370,6 +370,8 @@ def cpu_make_map(cpulist): return cpumap def xm_vcpu_pin(args): + arg_check(args, 3, "vcpu-pin") + dom = args[0] vcpu = int(args[1]) cpumap = cpu_make_map(args[2]) @@ -378,6 +380,8 @@ def xm_vcpu_pin(args): server.xend_domain_pincpu(dom, vcpu, cpumap) def xm_mem_max(args): + arg_check(args, 2, "mem-max") + dom = args[0] mem = int_unit(args[1], 'm') @@ -385,6 +389,8 @@ def xm_mem_max(args): server.xend_domain_maxmem_set(dom, mem) def xm_mem_set(args): + arg_check(args, 2, "mem-set") + dom = args[0] mem_target = int_unit(args[1], 'm') From 006b46b2d010366415749591af35dd2900e6e6a0 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 02:08:26 +0100 Subject: [PATCH 073/142] Fix transaction EAGAIN handling in xenstore client programs. Redirect all output to a buffer and only print the buffer once the transaction succeeds, discarding output from previous attempts. In particular, fixes failures when the (block) backend driver would not configure because reads from the hotplug script did get double output when a transaction had to be redone. Signed-off-by: Christian Limpach --- tools/xenstore/xenstore_client.c | 52 +++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/tools/xenstore/xenstore_client.c b/tools/xenstore/xenstore_client.c index d18b2de5e1..2d36520653 100644 --- a/tools/xenstore/xenstore_client.c +++ b/tools/xenstore/xenstore_client.c @@ -9,13 +9,45 @@ */ #include +#include #include #include +#include #include #include #include #include -#include + +static char *output_buf = NULL; +static int output_pos = 0; + +#if defined(CLIENT_read) || defined(CLIENT_list) +static int output_size = 0; + +static void +output(const char *fmt, ...) { + va_list ap; + int len; + char buf[1]; + + va_start(ap, fmt); + len = vsnprintf(buf, 1, fmt, ap); + if (len < 0) + err(1, "output"); + va_end(ap); + if (len + 1 + output_pos > output_size) { + output_size += len + 1024; + output_buf = realloc(output_buf, output_size); + if (output_buf == NULL) + err(1, "malloc"); + } + va_start(ap, fmt); + if (vsnprintf(&output_buf[output_pos], len + 1, fmt, ap) != len) + err(1, "output"); + va_end(ap); + output_pos += len; +} +#endif static void usage(const char *progname) @@ -34,7 +66,7 @@ usage(const char *progname) #if defined(CLIENT_rm) static int -do_rm(char * path, struct xs_handle *xsh, struct xs_transaction_handle *xth) +do_rm(char *path, struct xs_handle *xsh, struct xs_transaction_handle *xth) { if (xs_rm(xsh, xth, path)) { return 0; @@ -59,8 +91,8 @@ perform(int optind, int argc, char **argv, struct xs_handle *xsh, return 1; } if (prefix) - printf("%s: ", argv[optind]); - printf("%s\n", val); + output("%s: ", argv[optind]); + output("%s\n", val); free(val); optind++; #elif defined(CLIENT_write) @@ -131,8 +163,8 @@ perform(int optind, int argc, char **argv, struct xs_handle *xsh, } for (i = 0; i < num; i++) { if (prefix) - printf("%s/", argv[optind]); - printf("%s\n", list[i]); + output("%s/", argv[optind]); + output("%s\n", list[i]); } free(list); optind++; @@ -217,9 +249,15 @@ main(int argc, char **argv) ret = perform(optind, argc, argv, xsh, xth, prefix, tidy); if (!xs_transaction_end(xsh, xth, ret)) { - if (ret == 0 && errno == EAGAIN) + if (ret == 0 && errno == EAGAIN) { + output_pos = 0; goto again; + } errx(1, "couldn't end transaction"); } + + if (output_pos) + printf("%s", output_buf); + return ret; } From 7126177413e73356d5e29c519c7d4fbcb0d6f45e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 10:45:29 +0100 Subject: [PATCH 074/142] In the shadow mode, thanks to recent patches, the shadow reference counts (both general counts and type counts) are now correct in all of my testing so far. As a result, we should remove the shadow_tainted_refcnt flag from the domain structure. Leaving this flag in place would create confusion for programmers and would also prevent future debugging of problems in handling general and type reference counts in the shadow mode. In addition, the patch also (1) drops the requirement that shadow_mode_disable() should only be called in the domain destruction sequence (even though it is only used that way so far), and (2) strictly assert that the type reference count must be 0 when we free a page from the dom heap. Signed-off-by: Khoa Huynh --- xen/arch/x86/shadow32.c | 8 -------- xen/arch/x86/shadow_public.c | 8 -------- xen/common/page_alloc.c | 3 +-- xen/include/asm-x86/domain.h | 2 -- xen/include/asm-x86/shadow.h | 2 -- xen/include/xen/shadow.h | 1 - 6 files changed, 1 insertion(+), 23 deletions(-) diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index 0b88448181..18b5dc448f 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -1187,14 +1187,6 @@ void __shadow_mode_disable(struct domain *d) if ( unlikely(!shadow_mode_enabled(d)) ) return; - /* - * Currently this does not fix up page ref counts, so it is valid to call - * only when a domain is being destroyed. - */ - BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags) && - shadow_mode_refcounts(d)); - d->arch.shadow_tainted_refcnts = shadow_mode_refcounts(d); - free_shadow_pages(d); free_writable_pte_predictions(d); diff --git a/xen/arch/x86/shadow_public.c b/xen/arch/x86/shadow_public.c index 36266128df..b27c1086f6 100644 --- a/xen/arch/x86/shadow_public.c +++ b/xen/arch/x86/shadow_public.c @@ -879,14 +879,6 @@ void __shadow_mode_disable(struct domain *d) if ( unlikely(!shadow_mode_enabled(d)) ) return; - /* - * Currently this does not fix up page ref counts, so it is valid to call - * only when a domain is being destroyed. - */ - BUG_ON(!test_bit(_DOMF_dying, &d->domain_flags) && - shadow_mode_refcounts(d)); - d->arch.shadow_tainted_refcnts = shadow_mode_refcounts(d); - free_shadow_pages(d); free_writable_pte_predictions(d); diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index d4ae62ee2e..d2321a747e 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -610,8 +610,7 @@ void free_domheap_pages(struct pfn_info *pg, unsigned int order) for ( i = 0; i < (1 << order); i++ ) { shadow_drop_references(d, &pg[i]); - ASSERT(((pg[i].u.inuse.type_info & PGT_count_mask) == 0) || - shadow_tainted_refcnts(d)); + ASSERT((pg[i].u.inuse.type_info & PGT_count_mask) == 0); pg[i].tlbflush_timestamp = tlbflush_current_time(); pg[i].u.free.cpumask = d->cpumask; list_del(&pg[i].list); diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index aece57a6c3..fb9eff7ee4 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -32,8 +32,6 @@ struct arch_domain struct shadow_ops *ops; unsigned int shadow_mode; /* flags to control shadow table operation */ unsigned int shadow_nest; /* Recursive depth of shadow_lock() nesting */ - /* Shadow mode has tainted page reference counts? */ - unsigned int shadow_tainted_refcnts; /* shadow hashtable */ struct shadow_status *shadow_ht; diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index 3e2f3b9d6a..93bd92aaf7 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -55,8 +55,6 @@ #define shadow_mode_translate(_d) ((_d)->arch.shadow_mode & SHM_translate) #define shadow_mode_external(_d) ((_d)->arch.shadow_mode & SHM_external) -#define shadow_tainted_refcnts(_d) ((_d)->arch.shadow_tainted_refcnts) - #define shadow_linear_pg_table ((l1_pgentry_t *)SH_LINEAR_PT_VIRT_START) #define __shadow_linear_l2_table ((l2_pgentry_t *)(SH_LINEAR_PT_VIRT_START + \ (SH_LINEAR_PT_VIRT_START >> (L2_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))) diff --git a/xen/include/xen/shadow.h b/xen/include/xen/shadow.h index 4248b30f80..a69bd59802 100644 --- a/xen/include/xen/shadow.h +++ b/xen/include/xen/shadow.h @@ -12,7 +12,6 @@ #define shadow_drop_references(_d, _p) ((void)0) #define shadow_sync_and_drop_references(_d, _p) ((void)0) -#define shadow_tainted_refcnts(_d) (0) #endif From 0fd482ecd54ccd8a3d1e0c82a0ae271cdfdc4f7a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 10:53:30 +0100 Subject: [PATCH 075/142] There are only six fields in vcpuinfo. Signed-off-by: Ryan Harper --- tools/python/xen/lowlevel/xc/xc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 927b1ccdc5..f28e5ac157 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -363,7 +363,7 @@ static PyObject *pyxc_vcpu_getinfo(PyObject *self, if ( rc < 0 ) return PyErr_SetFromErrno(xc_error); - info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i,s:i,s:i}", + info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i,s:i}", "online", info.online, "blocked", info.blocked, "running", info.running, From 3a44cc26138189c96b2772781987a9c7d9f43394 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 11:04:48 +0100 Subject: [PATCH 076/142] Allow interdomain channels to bind DOMID_SELF to DOMID_SELF. Signed-off-by: Steve King --- xen/common/event_channel.c | 9 +++++++-- xen/include/public/event_channel.h | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index 8dd52eb49f..f0feb65fd8 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -89,7 +89,8 @@ static long evtchn_alloc_unbound(evtchn_alloc_unbound_t *alloc) chn = evtchn_from_port(d, port); chn->state = ECS_UNBOUND; - chn->u.unbound.remote_domid = alloc->remote_dom; + if ( (chn->u.unbound.remote_domid = alloc->remote_dom) == DOMID_SELF ) + chn->u.unbound.remote_domid = current->domain->domain_id; alloc->port = port; @@ -107,9 +108,13 @@ static long evtchn_bind_interdomain(evtchn_bind_interdomain_t *bind) struct evtchn *lchn, *rchn; struct domain *ld = current->domain, *rd; int lport, rport = bind->remote_port; + domid_t rdom = bind->remote_dom; long rc = 0; - if ( (rd = find_domain_by_id(bind->remote_dom)) == NULL ) + if ( rdom == DOMID_SELF ) + rdom = current->domain->domain_id; + + if ( (rd = find_domain_by_id(rdom)) == NULL ) return -ESRCH; /* Avoid deadlock by first acquiring lock of domain with smaller id. */ diff --git a/xen/include/public/event_channel.h b/xen/include/public/event_channel.h index 18bbd97c86..1de1057512 100644 --- a/xen/include/public/event_channel.h +++ b/xen/include/public/event_channel.h @@ -15,6 +15,7 @@ * is allocated in and returned as . * NOTES: * 1. If the caller is unprivileged then must be DOMID_SELF. + * 2. may be DOMID_SELF, allowing loopback connections. */ #define EVTCHNOP_alloc_unbound 6 typedef struct evtchn_alloc_unbound { @@ -30,6 +31,8 @@ typedef struct evtchn_alloc_unbound { * a port that is unbound and marked as accepting bindings from the calling * domain. A fresh port is allocated in the calling domain and returned as * . + * NOTES: + * 2. may be DOMID_SELF, allowing loopback connections. */ #define EVTCHNOP_bind_interdomain 0 typedef struct evtchn_bind_interdomain { From f2fabb9e4e95326191163347b77702a2a0c3ad0b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 11:07:55 +0100 Subject: [PATCH 077/142] Fix x86_64 smp boot: The local_setup_timer prototype was bad. The call from start secondary() to it was calling with out the CPU parameter. Eventually the CPU parameter received by the local_setup_timer is bogus (big negative number). With such a big cpu number the per_cpu macro was trying to access totally wrong memory location (per cpu data offset for big -ve no cpu) causing the unhandled page fault. Because the dom0 was panicking the error information on the serial console was also not going through, giving just clueless hang. With hyper call based debug statement I could find out what was going wrong in the dom0. Signed-Off-By: Nitin A Kamble --- linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c index b48b559a45..8529c9e5db 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c @@ -445,7 +445,7 @@ void __cpuinit smp_callin(void) } #ifdef CONFIG_XEN -extern void local_setup_timer(void); +extern void local_setup_timer(unsigned int cpu); #endif /* @@ -478,7 +478,7 @@ void __cpuinit start_secondary(void) enable_APIC_timer(); #else - local_setup_timer(); + local_setup_timer(smp_processor_id()); smp_intr_init(); local_irq_enable(); #endif From 422ad78b3c5eec536143deeea7cbd935479d2f1b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 11:09:36 +0100 Subject: [PATCH 078/142] Clean up some VMX IO handler code: 1. Clean up some definitions. 2. change d to v, if it means vcpu. 3. remove some tailing spaces. TODO: split current VMX IO handler list to 2, one for port IO, and the other for MMIO. Signed-off-by: Xin Li --- xen/arch/x86/vmx_intercept.c | 63 ++++++++++++++++------------- xen/arch/x86/vmx_io.c | 3 +- xen/arch/x86/vmx_vmcs.c | 11 ++++- xen/include/asm-x86/vmx_intercept.h | 43 +++++++++++--------- xen/include/asm-x86/vmx_platform.h | 5 +-- xen/include/asm-x86/vmx_virpit.h | 4 +- xen/include/asm-x86/vmx_vmcs.h | 11 ++--- 7 files changed, 79 insertions(+), 61 deletions(-) diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index 865c51ca30..43b48db5da 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -32,31 +32,36 @@ #ifdef CONFIG_VMX -/* Check if the request is handled inside xen - return value: 0 --not handled; 1 --handled */ +/* + * Check if the request is handled inside xen + * return value: 0 --not handled; 1 --handled + */ int vmx_io_intercept(ioreq_t *p, int type) { - struct vcpu *d = current; - struct vmx_handler_t *handler = &(d->domain->arch.vmx_platform.vmx_handler); + struct vcpu *v = current; + struct vmx_io_handler *handler = + &(v->domain->arch.vmx_platform.vmx_io_handler); int i; - unsigned long addr, offset; + unsigned long addr, size; + for (i = 0; i < handler->num_slot; i++) { if( type != handler->hdl_list[i].type) continue; - addr = handler->hdl_list[i].addr; - offset = handler->hdl_list[i].offset; + addr = handler->hdl_list[i].addr; + size = handler->hdl_list[i].size; if (p->addr >= addr && - p->addr < addr + offset) + p->addr < addr + size) return handler->hdl_list[i].action(p); } return 0; } -int register_io_handler(unsigned long addr, unsigned long offset, +int register_io_handler(unsigned long addr, unsigned long size, intercept_action_t action, int type) { - struct vcpu *d = current; - struct vmx_handler_t *handler = &(d->domain->arch.vmx_platform.vmx_handler); + struct vcpu *v = current; + struct vmx_io_handler *handler = + &(v->domain->arch.vmx_platform.vmx_io_handler); int num = handler->num_slot; if (num >= MAX_IO_HANDLER) { @@ -65,15 +70,15 @@ int register_io_handler(unsigned long addr, unsigned long offset, } handler->hdl_list[num].addr = addr; - handler->hdl_list[num].offset = offset; + handler->hdl_list[num].size = size; handler->hdl_list[num].action = action; handler->hdl_list[num].type = type; handler->num_slot++; - return 1; + return 1; } -static void pit_cal_count(struct vmx_virpit_t *vpit) +static void pit_cal_count(struct vmx_virpit *vpit) { u64 nsec_delta = (unsigned int)((NOW() - vpit->inject_point)); if (nsec_delta > vpit->period) @@ -81,7 +86,7 @@ static void pit_cal_count(struct vmx_virpit_t *vpit) vpit->count = vpit->init_val - ((nsec_delta * PIT_FREQ / 1000000000ULL) % vpit->init_val ); } -static void pit_latch_io(struct vmx_virpit_t *vpit) +static void pit_latch_io(struct vmx_virpit *vpit) { pit_cal_count(vpit); @@ -103,11 +108,11 @@ static void pit_latch_io(struct vmx_virpit_t *vpit) vpit->count_MSB_latched=1; break; default: - BUG(); + domain_crash_synchronous(); } } -static int pit_read_io(struct vmx_virpit_t *vpit) +static int pit_read_io(struct vmx_virpit *vpit) { if(vpit->count_LSB_latched) { /* Read Least Significant Byte */ @@ -168,8 +173,8 @@ static void resume_pit_io(ioreq_t *p) /* the intercept action for PIT DM retval:0--not handled; 1--handled */ int intercept_pit_io(ioreq_t *p) { - struct vcpu *d = current; - struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit); + struct vcpu *v = current; + struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); if (p->size != 1 || p->pdata_valid || @@ -197,7 +202,7 @@ int intercept_pit_io(ioreq_t *p) /* hooks function for the PIT initialization response iopacket */ static void pit_timer_fn(void *data) { - struct vmx_virpit_t *vpit = data; + struct vmx_virpit *vpit = data; s_time_t next; int missed_ticks; @@ -221,18 +226,18 @@ static void pit_timer_fn(void *data) /* Only some PIT operations such as load init counter need a hypervisor hook. * leave all other operations in user space DM */ -void vmx_hooks_assist(struct vcpu *d) +void vmx_hooks_assist(struct vcpu *v) { - vcpu_iodata_t * vio = get_vio(d->domain, d->vcpu_id); + vcpu_iodata_t *vio = get_vio(v->domain, v->vcpu_id); ioreq_t *p = &vio->vp_ioreq; - shared_iopage_t *sp = get_sp(d->domain); + shared_iopage_t *sp = get_sp(v->domain); u64 *intr = &(sp->sp_global.pic_intr[0]); - struct vmx_virpit_t *vpit = &(d->domain->arch.vmx_platform.vmx_pit); + struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); int rw_mode, reinit = 0; int oldvec = 0; /* load init count*/ - if (p->state == STATE_IORESP_HOOK) { + if (p->state == STATE_IORESP_HOOK) { /* set up actimer, handle re-init */ if ( active_ac_timer(&(vpit->pit_timer)) ) { VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT: guest reset PIT with channel %lx!\n", (unsigned long) ((p->u.data >> 24) & 0x3) ); @@ -241,12 +246,12 @@ void vmx_hooks_assist(struct vcpu *d) oldvec = vpit->vector; } else - init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, d->processor); + init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, v->processor); /* init count for this channel */ - vpit->init_val = (p->u.data & 0xFFFF) ; + vpit->init_val = (p->u.data & 0xFFFF) ; /* frequency(ns) of pit */ - vpit->period = DIV_ROUND(((vpit->init_val) * 1000000000ULL), PIT_FREQ); + vpit->period = DIV_ROUND(((vpit->init_val) * 1000000000ULL), PIT_FREQ); VMX_DBG_LOG(DBG_LEVEL_1,"VMX_PIT: guest set init pit freq:%u ns, initval:0x%x\n", vpit->period, vpit->init_val); if (vpit->period < 900000) { /* < 0.9 ms */ printk("VMX_PIT: guest programmed too small an init_val: %x\n", @@ -283,7 +288,7 @@ void vmx_hooks_assist(struct vcpu *d) } vpit->intr_bitmap = intr; - vpit->v = d; + vpit->v = v; vpit->scheduled = NOW() + vpit->period; set_ac_timer(&vpit->pit_timer, vpit->scheduled); diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index e6536b31a1..1530e7b533 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -848,7 +848,8 @@ static inline int find_highest_pending_irq(struct vcpu *v, int *type) static inline void interrupt_post_injection(struct vcpu * v, int vector, int type) { - struct vmx_virpit_t *vpit = &(v->domain->arch.vmx_platform.vmx_pit); + struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); + switch(type) { case VLAPIC_DELIV_MODE_EXT: diff --git a/xen/arch/x86/vmx_vmcs.c b/xen/arch/x86/vmx_vmcs.c index 512194d114..bf5fe057c1 100644 --- a/xen/arch/x86/vmx_vmcs.c +++ b/xen/arch/x86/vmx_vmcs.c @@ -142,7 +142,7 @@ struct host_execution_env { #endif }; -static void vmx_setup_platform(struct vcpu *v) +static void get_io_shared_page(struct vcpu *v) { int i; unsigned char e820_map_nr; @@ -151,6 +151,9 @@ static void vmx_setup_platform(struct vcpu *v) unsigned long mpfn; unsigned long gpfn = 0; + if (!(VMX_DOMAIN(v) && (v->vcpu_id == 0))) + return; + local_flush_tlb_pge(); mpfn = get_mfn_from_pfn(E820_MAP_PAGE >> PAGE_SHIFT); @@ -205,6 +208,12 @@ static void vmx_setup_platform(struct vcpu *v) &v->domain->shared_info->evtchn_mask[0]); } +static void vmx_setup_platform(struct vcpu *v) +{ + if (v->vcpu_id == 0) + get_io_shared_page(v); +} + static void vmx_set_host_env(struct vcpu *v) { unsigned int tr, cpu, error = 0; diff --git a/xen/include/asm-x86/vmx_intercept.h b/xen/include/asm-x86/vmx_intercept.h index 9465a7147b..598aab5599 100644 --- a/xen/include/asm-x86/vmx_intercept.h +++ b/xen/include/asm-x86/vmx_intercept.h @@ -8,49 +8,52 @@ #include #include -#define MAX_IO_HANDLER 10 +#define MAX_IO_HANDLER 4 -typedef int (*intercept_action_t)(ioreq_t*); +#define VMX_PORTIO 0 +#define VMX_MMIO 1 -enum {PORTIO, MMIO}; +typedef int (*intercept_action_t)(ioreq_t *); -struct vmx_handler_t { - int num_slot; - struct { - unsigned long addr; - int type; - unsigned long offset; - intercept_action_t action; - } hdl_list[MAX_IO_HANDLER]; +struct io_handler { + int type; + unsigned long addr; + unsigned long size; + intercept_action_t action; +}; + +struct vmx_io_handler { + int num_slot; + struct io_handler hdl_list[MAX_IO_HANDLER]; }; /* global io interception point in HV */ extern int vmx_io_intercept(ioreq_t *p, int type); -extern int register_io_handler(unsigned long addr, unsigned long offset, +extern int register_io_handler(unsigned long addr, unsigned long size, intercept_action_t action, int type); static inline int vmx_portio_intercept(ioreq_t *p) { - return vmx_io_intercept(p, PORTIO); + return vmx_io_intercept(p, VMX_PORTIO); } static inline int vmx_mmio_intercept(ioreq_t *p) { - return vmx_io_intercept(p, MMIO); + return vmx_io_intercept(p, VMX_MMIO); } -static inline int register_portio_handler(unsigned long addr, - unsigned long offset, +static inline int register_portio_handler(unsigned long addr, + unsigned long size, intercept_action_t action) { - return register_io_handler(addr, offset, action, PORTIO); + return register_io_handler(addr, size, action, VMX_PORTIO); } -static inline int register_mmio_handler(unsigned long addr, - unsigned long offset, +static inline int register_mmio_handler(unsigned long addr, + unsigned long size, intercept_action_t action) { - return register_io_handler(addr, offset, action, MMIO); + return register_io_handler(addr, size, action, VMX_MMIO); } #endif /* _VMX_INTERCEPT_H */ diff --git a/xen/include/asm-x86/vmx_platform.h b/xen/include/asm-x86/vmx_platform.h index 1dd3cf7c74..484ec79edd 100644 --- a/xen/include/asm-x86/vmx_platform.h +++ b/xen/include/asm-x86/vmx_platform.h @@ -77,10 +77,9 @@ struct instruction { #define MAX_INST_LEN 32 struct virtual_platform_def { - unsigned long *real_mode_data; /* E820, etc. */ unsigned long shared_page_va; - struct vmx_virpit_t vmx_pit; - struct vmx_handler_t vmx_handler; + struct vmx_virpit vmx_pit; + struct vmx_io_handler vmx_io_handler; }; extern void handle_mmio(unsigned long, unsigned long); diff --git a/xen/include/asm-x86/vmx_virpit.h b/xen/include/asm-x86/vmx_virpit.h index 1f80a83f0e..ba08d0ab8b 100644 --- a/xen/include/asm-x86/vmx_virpit.h +++ b/xen/include/asm-x86/vmx_virpit.h @@ -16,7 +16,7 @@ #define LSByte_multiple 2 #define MSByte_multiple 3 -struct vmx_virpit_t { +struct vmx_virpit { /* for simulation of counter 0 in mode 2*/ int vector; /* the pit irq vector */ unsigned int period; /* the frequency. e.g. 10ms*/ @@ -39,6 +39,6 @@ struct vmx_virpit_t { }; /* to hook the ioreq packet to get the PIT initializaiton info */ -extern void vmx_hooks_assist(struct vcpu *d); +extern void vmx_hooks_assist(struct vcpu *v); #endif /* _VMX_VIRPIT_H_ */ diff --git a/xen/include/asm-x86/vmx_vmcs.h b/xen/include/asm-x86/vmx_vmcs.h index d0240f1a5b..1a8a10effa 100644 --- a/xen/include/asm-x86/vmx_vmcs.h +++ b/xen/include/asm-x86/vmx_vmcs.h @@ -29,7 +29,7 @@ extern void stop_vmx(void); #if defined (__x86_64__) extern void vmx_load_msrs(struct vcpu *n); -void vmx_restore_msrs(struct vcpu *d); +void vmx_restore_msrs(struct vcpu *v); #else #define vmx_load_msrs(_n) ((void)0) #define vmx_restore_msrs(_v) ((void)0) @@ -55,7 +55,7 @@ struct vmcs_struct { extern int vmcs_size; -enum { +enum { VMX_INDEX_MSR_LSTAR = 0, VMX_INDEX_MSR_STAR, VMX_INDEX_MSR_CSTAR, @@ -79,7 +79,7 @@ struct mmio_op { struct cpu_user_regs *inst_decoder_regs; /* current context */ }; -#define PC_DEBUG_PORT 0x80 +#define PC_DEBUG_PORT 0x80 struct arch_vmx_struct { struct vmcs_struct *vmcs; /* VMCS pointer in virtual */ @@ -98,7 +98,7 @@ struct arch_vmx_struct { #define vmx_schedule_tail(next) \ (next)->thread.arch_vmx.arch_vmx_schedule_tail((next)) -#define VMX_DOMAIN(ed) ((ed)->arch.arch_vmx.flags) +#define VMX_DOMAIN(v) ((v)->arch.arch_vmx.flags) #define ARCH_VMX_VMCS_LOADED 0 /* VMCS has been loaded and active */ #define ARCH_VMX_VMCS_LAUNCH 1 /* Needs VMCS launch */ @@ -278,7 +278,8 @@ enum vmcs_field { extern unsigned int opt_vmx_debug_level; #define VMX_DBG_LOG(level, _f, _a...) \ if ((level) & opt_vmx_debug_level) \ - printk("[VMX]" _f "\n", ## _a ) + printk("[VMX:%d.%d] " _f "\n", \ + current->domain->domain_id, current->vcpu_id, ## _a) #else #define VMX_DBG_LOG(level, _f, _a...) #endif From 5cf031e58df9bede3e6751f2905257c3e0ed8642 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 15:40:29 +0100 Subject: [PATCH 079/142] alloc_netif() must return a ERR_PTR() on error, not NULL. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/drivers/xen/netback/interface.c | 4 ++-- linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 12 ------------ 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c index 43f516badf..404eb98831 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c @@ -58,7 +58,7 @@ netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]) dev = alloc_netdev(sizeof(netif_t), name, ether_setup); if (dev == NULL) { DPRINTK("Could not create netif: out of memory\n"); - return NULL; + return ERR_PTR(-ENOMEM); } netif = netdev_priv(dev); @@ -104,7 +104,7 @@ netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]) DPRINTK("Could not register new net device %s: err=%d\n", dev->name, err); free_netdev(dev); - return NULL; + return ERR_PTR(err); } DPRINTK("Successfully created netif\n"); diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c index 905ca8b801..6d81bb7433 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c @@ -28,10 +28,6 @@ struct backend_info netif_t *netif; long int frontend_id; -#if 0 - long int pdev; - long int readonly; -#endif /* watch back end for changes */ struct xenbus_watch backend_watch; @@ -155,14 +151,6 @@ static void backend_changed(struct xenbus_watch *watch, return; } -#if 0 - err = vbd_create(be->netif, handle, be->pdev, be->readonly); - if (err) { - xenbus_dev_error(dev, err, "creating vbd structure"); - return; - } -#endif - kobject_hotplug(&dev->dev.kobj, KOBJ_ONLINE); /* Pass in NULL node to skip exist test. */ From 0a105191a0c5d513fdefa6c204d7ffed83e9c001 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 17:40:31 +0100 Subject: [PATCH 080/142] Merge i386/x86_64 smpboot.c into a simplified common Xen version. Signed-off-by: Keir Fraser --- .../arch/xen/i386/kernel/Makefile | 2 +- .../arch/xen/i386/kernel/head.S | 4 +- .../arch/xen/i386/kernel/i386_ksyms.c | 3 - .../arch/xen/i386/kernel/smpboot.c | 1520 ----------------- linux-2.6-xen-sparse/arch/xen/kernel/Makefile | 2 +- .../arch/xen/kernel/smpboot.c | 381 +++++ .../arch/xen/x86_64/kernel/Makefile | 2 +- .../arch/xen/x86_64/kernel/smpboot.c | 1253 -------------- .../arch/xen/x86_64/kernel/x8664_ksyms.c | 3 - .../asm-xen/asm-i386/mach-xen/smpboot_hooks.h | 55 - .../include/asm-xen/asm-i386/smp.h | 92 + .../asm-x86_64/mach-xen/smpboot_hooks.h | 55 - .../include/asm-xen/asm-x86_64/smp.h | 7 +- 13 files changed, 481 insertions(+), 2898 deletions(-) delete mode 100644 linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c create mode 100644 linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c delete mode 100644 linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c delete mode 100644 linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h create mode 100644 linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h delete mode 100644 linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile index a5bc95512f..8a565b43b2 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/Makefile @@ -27,7 +27,7 @@ c-obj-$(CONFIG_X86_MSR) += msr.o c-obj-$(CONFIG_X86_CPUID) += cpuid.o obj-$(CONFIG_MICROCODE) += microcode.o c-obj-$(CONFIG_APM) += apm.o -obj-$(CONFIG_X86_SMP) += smp.o smpboot.o +obj-$(CONFIG_X86_SMP) += smp.o #obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o obj-$(CONFIG_X86_MPPARSE) += mpparse.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S b/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S index 35c68031fb..64eaa9fe78 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/head.S @@ -40,7 +40,7 @@ ENTRY(startup_32) movl %esi,xen_start_info -#ifdef CONFIG_SMP +#if 0 ENTRY(startup_32_smp) #endif /* CONFIG_SMP */ @@ -78,7 +78,7 @@ checkCPUtype: movl %eax,%gs cld # gcc2 wants the direction flag cleared at all times -#ifdef CONFIG_SMP +#if 0 movb ready, %cl cmpb $1,%cl je 1f # the first CPU calls start_kernel diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c index 30c2357b4e..491820d8cf 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c @@ -136,9 +136,6 @@ EXPORT_SYMBOL(cpu_sibling_map); #endif #ifdef CONFIG_SMP -EXPORT_SYMBOL(cpu_data); -EXPORT_SYMBOL(cpu_online_map); -EXPORT_SYMBOL(cpu_callout_map); EXPORT_SYMBOL(__write_lock_failed); EXPORT_SYMBOL(__read_lock_failed); diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c deleted file mode 100644 index 01e245e3ab..0000000000 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/smpboot.c +++ /dev/null @@ -1,1520 +0,0 @@ -/* - * x86 SMP booting functions - * - * (c) 1995 Alan Cox, Building #3 - * (c) 1998, 1999, 2000 Ingo Molnar - * - * Much of the core SMP work is based on previous work by Thomas Radke, to - * whom a great many thanks are extended. - * - * Thanks to Intel for making available several different Pentium, - * Pentium Pro and Pentium-II/Xeon MP machines. - * Original development of Linux SMP code supported by Caldera. - * - * This code is released under the GNU General Public License version 2 or - * later. - * - * Fixes - * Felix Koop : NR_CPUS used properly - * Jose Renau : Handle single CPU case. - * Alan Cox : By repeated request 8) - Total BogoMIPS report. - * Greg Wright : Fix for kernel stacks panic. - * Erich Boleyn : MP v1.4 and additional changes. - * Matthias Sattler : Changes for 2.1 kernel map. - * Michel Lespinasse : Changes for 2.1 kernel map. - * Michael Chastain : Change trampoline.S to gnu as. - * Alan Cox : Dumb bug: 'B' step PPro's are fine - * Ingo Molnar : Added APIC timers, based on code - * from Jose Renau - * Ingo Molnar : various cleanups and rewrites - * Tigran Aivazian : fixed "0.00 in /proc/uptime on SMP" bug. - * Maciej W. Rozycki : Bits for genuine 82489DX APICs - * Martin J. Bligh : Added support for multi-quad systems - * Dave Jones : Report invalid combinations of Athlon CPUs. -* Rusty Russell : Hacked into shape for new "hotplug" boot process. */ - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#ifndef CONFIG_X86_IO_APIC -#define Dprintk(args...) -#endif -#include -#include - -#include -#include -#include - -static void xen_smp_intr_init(unsigned int cpu); -static void xen_smp_intr_exit(unsigned int cpu); - -/* Set if we find a B stepping CPU */ -static int __initdata smp_b_stepping; - -/* Number of siblings per CPU package */ -int smp_num_siblings = 1; -int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ -EXPORT_SYMBOL(phys_proc_id); -int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ -EXPORT_SYMBOL(cpu_core_id); - -/* bitmap of online cpus */ -cpumask_t cpu_online_map; - -cpumask_t cpu_callin_map; -cpumask_t cpu_callout_map; -static cpumask_t smp_commenced_mask; - -/* Per CPU bogomips and other parameters */ -struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; - -u8 x86_cpu_to_apicid[NR_CPUS] = - { [0 ... NR_CPUS-1] = 0xff }; -EXPORT_SYMBOL(x86_cpu_to_apicid); - -#if 0 -/* - * Trampoline 80x86 program as an array. - */ - -extern unsigned char trampoline_data []; -extern unsigned char trampoline_end []; -static unsigned char *trampoline_base; -static int trampoline_exec; -#endif - -#ifdef CONFIG_HOTPLUG_CPU -/* State of each CPU. */ -DEFINE_PER_CPU(int, cpu_state) = { 0 }; -#endif - -static DEFINE_PER_CPU(int, resched_irq); -static DEFINE_PER_CPU(int, callfunc_irq); -static char resched_name[NR_CPUS][15]; -static char callfunc_name[NR_CPUS][15]; - -#if 0 -/* - * Currently trivial. Write the real->protected mode - * bootstrap into the page concerned. The caller - * has made sure it's suitably aligned. - */ - -static unsigned long __init setup_trampoline(void) -{ - memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data); - return virt_to_phys(trampoline_base); -} -#endif - -static void map_cpu_to_logical_apicid(void); - -/* - * We are called very early to get the low memory for the - * SMP bootup trampoline page. - */ -void __init smp_alloc_memory(void) -{ -#if 0 - trampoline_base = (void *) alloc_bootmem_low_pages(PAGE_SIZE); - /* - * Has to be in very low memory so we can execute - * real-mode AP code. - */ - if (__pa(trampoline_base) >= 0x9F000) - BUG(); - /* - * Make the SMP trampoline executable: - */ - trampoline_exec = set_kernel_exec((unsigned long)trampoline_base, 1); -#endif -} - -/* - * The bootstrap kernel entry code has set these up. Save them for - * a given CPU - */ - -static void __init smp_store_cpu_info(int id) -{ - struct cpuinfo_x86 *c = cpu_data + id; - - *c = boot_cpu_data; - if (id!=0) - identify_cpu(c); - /* - * Mask B, Pentium, but not Pentium MMX - */ - if (c->x86_vendor == X86_VENDOR_INTEL && - c->x86 == 5 && - c->x86_mask >= 1 && c->x86_mask <= 4 && - c->x86_model <= 3) - /* - * Remember we have B step Pentia with bugs - */ - smp_b_stepping = 1; - - /* - * Certain Athlons might work (for various values of 'work') in SMP - * but they are not certified as MP capable. - */ - if ((c->x86_vendor == X86_VENDOR_AMD) && (c->x86 == 6)) { - - /* Athlon 660/661 is valid. */ - if ((c->x86_model==6) && ((c->x86_mask==0) || (c->x86_mask==1))) - goto valid_k7; - - /* Duron 670 is valid */ - if ((c->x86_model==7) && (c->x86_mask==0)) - goto valid_k7; - - /* - * Athlon 662, Duron 671, and Athlon >model 7 have capability bit. - * It's worth noting that the A5 stepping (662) of some Athlon XP's - * have the MP bit set. - * See http://www.heise.de/newsticker/data/jow-18.10.01-000 for more. - */ - if (((c->x86_model==6) && (c->x86_mask>=2)) || - ((c->x86_model==7) && (c->x86_mask>=1)) || - (c->x86_model> 7)) - if (cpu_has_mp) - goto valid_k7; - - /* If we get here, it's not a certified SMP capable AMD system. */ - tainted |= TAINT_UNSAFE_SMP; - } - -valid_k7: - ; -} - -#if 0 -/* - * TSC synchronization. - * - * We first check whether all CPUs have their TSC's synchronized, - * then we print a warning if not, and always resync. - */ - -static atomic_t tsc_start_flag = ATOMIC_INIT(0); -static atomic_t tsc_count_start = ATOMIC_INIT(0); -static atomic_t tsc_count_stop = ATOMIC_INIT(0); -static unsigned long long tsc_values[NR_CPUS]; - -#define NR_LOOPS 5 - -static void __init synchronize_tsc_bp (void) -{ - int i; - unsigned long long t0; - unsigned long long sum, avg; - long long delta; - unsigned long one_usec; - int buggy = 0; - - printk(KERN_INFO "checking TSC synchronization across %u CPUs: ", num_booting_cpus()); - - /* convert from kcyc/sec to cyc/usec */ - one_usec = cpu_khz / 1000; - - atomic_set(&tsc_start_flag, 1); - wmb(); - - /* - * We loop a few times to get a primed instruction cache, - * then the last pass is more or less synchronized and - * the BP and APs set their cycle counters to zero all at - * once. This reduces the chance of having random offsets - * between the processors, and guarantees that the maximum - * delay between the cycle counters is never bigger than - * the latency of information-passing (cachelines) between - * two CPUs. - */ - for (i = 0; i < NR_LOOPS; i++) { - /* - * all APs synchronize but they loop on '== num_cpus' - */ - while (atomic_read(&tsc_count_start) != num_booting_cpus()-1) - mb(); - atomic_set(&tsc_count_stop, 0); - wmb(); - /* - * this lets the APs save their current TSC: - */ - atomic_inc(&tsc_count_start); - - rdtscll(tsc_values[smp_processor_id()]); - /* - * We clear the TSC in the last loop: - */ - if (i == NR_LOOPS-1) - write_tsc(0, 0); - - /* - * Wait for all APs to leave the synchronization point: - */ - while (atomic_read(&tsc_count_stop) != num_booting_cpus()-1) - mb(); - atomic_set(&tsc_count_start, 0); - wmb(); - atomic_inc(&tsc_count_stop); - } - - sum = 0; - for (i = 0; i < NR_CPUS; i++) { - if (cpu_isset(i, cpu_callout_map)) { - t0 = tsc_values[i]; - sum += t0; - } - } - avg = sum; - do_div(avg, num_booting_cpus()); - - sum = 0; - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_isset(i, cpu_callout_map)) - continue; - delta = tsc_values[i] - avg; - if (delta < 0) - delta = -delta; - /* - * We report bigger than 2 microseconds clock differences. - */ - if (delta > 2*one_usec) { - long realdelta; - if (!buggy) { - buggy = 1; - printk("\n"); - } - realdelta = delta; - do_div(realdelta, one_usec); - if (tsc_values[i] < avg) - realdelta = -realdelta; - - printk(KERN_INFO "CPU#%d had %ld usecs TSC skew, fixed it up.\n", i, realdelta); - } - - sum += delta; - } - if (!buggy) - printk("passed.\n"); -} - -static void __init synchronize_tsc_ap (void) -{ - int i; - - /* - * Not every cpu is online at the time - * this gets called, so we first wait for the BP to - * finish SMP initialization: - */ - while (!atomic_read(&tsc_start_flag)) mb(); - - for (i = 0; i < NR_LOOPS; i++) { - atomic_inc(&tsc_count_start); - while (atomic_read(&tsc_count_start) != num_booting_cpus()) - mb(); - - rdtscll(tsc_values[smp_processor_id()]); - if (i == NR_LOOPS-1) - write_tsc(0, 0); - - atomic_inc(&tsc_count_stop); - while (atomic_read(&tsc_count_stop) != num_booting_cpus()) mb(); - } -} -#undef NR_LOOPS -#endif - -extern void calibrate_delay(void); - -static atomic_t init_deasserted; - -static void __init smp_callin(void) -{ - int cpuid, phys_id; -#if 0 - unsigned long timeout; - - /* - * If waken up by an INIT in an 82489DX configuration - * we may get here before an INIT-deassert IPI reaches - * our local APIC. We have to wait for the IPI or we'll - * lock up on an APIC access. - */ - wait_for_init_deassert(&init_deasserted); -#endif - - /* - * (This works even if the APIC is not enabled.) - */ - phys_id = smp_processor_id(); - cpuid = smp_processor_id(); - if (cpu_isset(cpuid, cpu_callin_map)) { - printk("huh, phys CPU#%d, CPU#%d already present??\n", - phys_id, cpuid); - BUG(); - } - Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id); - -#if 0 - /* - * STARTUP IPIs are fragile beasts as they might sometimes - * trigger some glue motherboard logic. Complete APIC bus - * silence for 1 second, this overestimates the time the - * boot CPU is spending to send the up to 2 STARTUP IPIs - * by a factor of two. This should be enough. - */ - - /* - * Waiting 2s total for startup (udelay is not yet working) - */ - timeout = jiffies + 2*HZ; - while (time_before(jiffies, timeout)) { - /* - * Has the boot CPU finished it's STARTUP sequence? - */ - if (cpu_isset(cpuid, cpu_callout_map)) - break; - rep_nop(); - } - - if (!time_before(jiffies, timeout)) { - printk("BUG: CPU%d started up but did not get a callout!\n", - cpuid); - BUG(); - } - - /* - * the boot CPU has finished the init stage and is spinning - * on callin_map until we finish. We are free to set up this - * CPU, first the APIC. (this is probably redundant on most - * boards) - */ - - Dprintk("CALLIN, before setup_local_APIC().\n"); - smp_callin_clear_local_apic(); - setup_local_APIC(); -#endif - map_cpu_to_logical_apicid(); - - /* - * Get our bogomips. - */ - calibrate_delay(); - Dprintk("Stack at about %p\n",&cpuid); - - /* - * Save our processor parameters - */ - smp_store_cpu_info(cpuid); - -#if 0 - disable_APIC_timer(); -#endif - - /* - * Allow the master to continue. - */ - cpu_set(cpuid, cpu_callin_map); - -#if 0 - /* - * Synchronize the TSC with the BP - */ - if (cpu_has_tsc && cpu_khz) - synchronize_tsc_ap(); -#endif -} - -static int cpucount; - -/* - * Activate a secondary processor. - */ -static void __init start_secondary(void *unused) -{ - /* - * Dont put anything before smp_callin(), SMP - * booting is too fragile that we want to limit the - * things done here to the most necessary things. - */ - cpu_init(); - smp_callin(); - while (!cpu_isset(smp_processor_id(), smp_commenced_mask)) - rep_nop(); - local_irq_enable(); - /* - * low-memory mappings have been cleared, flush them from - * the local TLBs too. - */ - local_flush_tlb(); - cpu_set(smp_processor_id(), cpu_online_map); - - /* We can take interrupts now: we're officially "up". */ - local_irq_enable(); - - wmb(); - cpu_idle(); -} - -/* - * Everything has been set up for the secondary - * CPUs - they just need to reload everything - * from the task structure - * This function must not return. - */ -void __init initialize_secondary(void) -{ - /* - * We don't actually need to load the full TSS, - * basically just the stack pointer and the eip. - */ - - asm volatile( - "movl %0,%%esp\n\t" - "jmp *%1" - : - :"r" (current->thread.esp),"r" (current->thread.eip)); -} - -extern struct { - void * esp; - unsigned short ss; -} stack_start; - -#ifdef CONFIG_NUMA - -/* which logical CPUs are on which nodes */ -cpumask_t node_2_cpu_mask[MAX_NUMNODES] = - { [0 ... MAX_NUMNODES-1] = CPU_MASK_NONE }; -/* which node each logical CPU is on */ -int cpu_2_node[NR_CPUS] = { [0 ... NR_CPUS-1] = 0 }; -EXPORT_SYMBOL(cpu_2_node); - -/* set up a mapping between cpu and node. */ -static inline void map_cpu_to_node(int cpu, int node) -{ - printk("Mapping cpu %d to node %d\n", cpu, node); - cpu_set(cpu, node_2_cpu_mask[node]); - cpu_2_node[cpu] = node; -} - -/* undo a mapping between cpu and node. */ -static inline void unmap_cpu_to_node(int cpu) -{ - int node; - - printk("Unmapping cpu %d from all nodes\n", cpu); - for (node = 0; node < MAX_NUMNODES; node ++) - cpu_clear(cpu, node_2_cpu_mask[node]); - cpu_2_node[cpu] = 0; -} -#else /* !CONFIG_NUMA */ - -#define map_cpu_to_node(cpu, node) ({}) -#define unmap_cpu_to_node(cpu) ({}) - -#endif /* CONFIG_NUMA */ - -u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; - -static void map_cpu_to_logical_apicid(void) -{ - int cpu = smp_processor_id(); - int apicid = smp_processor_id(); - - cpu_2_logical_apicid[cpu] = apicid; - map_cpu_to_node(cpu, apicid_to_node(apicid)); -} - -static void unmap_cpu_to_logical_apicid(int cpu) -{ - cpu_2_logical_apicid[cpu] = BAD_APICID; - unmap_cpu_to_node(cpu); -} - -#if APIC_DEBUG -static inline void __inquire_remote_apic(int apicid) -{ - int i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; - char *names[] = { "ID", "VERSION", "SPIV" }; - int timeout, status; - - printk("Inquiring remote APIC #%d...\n", apicid); - - for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) { - printk("... APIC #%d %s: ", apicid, names[i]); - - /* - * Wait for idle. - */ - apic_wait_icr_idle(); - - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); - apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]); - - timeout = 0; - do { - udelay(100); - status = apic_read(APIC_ICR) & APIC_ICR_RR_MASK; - } while (status == APIC_ICR_RR_INPROG && timeout++ < 1000); - - switch (status) { - case APIC_ICR_RR_VALID: - status = apic_read(APIC_RRR); - printk("%08x\n", status); - break; - default: - printk("failed\n"); - } - } -} -#endif - -#if 0 -#ifdef WAKE_SECONDARY_VIA_NMI -/* - * Poke the other CPU in the eye via NMI to wake it up. Remember that the normal - * INIT, INIT, STARTUP sequence will reset the chip hard for us, and this - * won't ... remember to clear down the APIC, etc later. - */ -static int __init -wakeup_secondary_cpu(int logical_apicid, unsigned long start_eip) -{ - unsigned long send_status = 0, accept_status = 0; - int timeout, maxlvt; - - /* Target chip */ - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(logical_apicid)); - - /* Boot on the stack */ - /* Kick the second */ - apic_write_around(APIC_ICR, APIC_DM_NMI | APIC_DEST_LOGICAL); - - Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); - - /* - * Give the other CPU some time to accept the IPI. - */ - udelay(200); - /* - * Due to the Pentium erratum 3AP. - */ - maxlvt = get_maxlvt(); - if (maxlvt > 3) { - apic_read_around(APIC_SPIV); - apic_write(APIC_ESR, 0); - } - accept_status = (apic_read(APIC_ESR) & 0xEF); - Dprintk("NMI sent.\n"); - - if (send_status) - printk("APIC never delivered???\n"); - if (accept_status) - printk("APIC delivery error (%lx).\n", accept_status); - - return (send_status | accept_status); -} -#endif /* WAKE_SECONDARY_VIA_NMI */ - -#ifdef WAKE_SECONDARY_VIA_INIT -static int __init -wakeup_secondary_cpu(int phys_apicid, unsigned long start_eip) -{ - unsigned long send_status = 0, accept_status = 0; - int maxlvt, timeout, num_starts, j; - - /* - * Be paranoid about clearing APIC errors. - */ - if (APIC_INTEGRATED(apic_version[phys_apicid])) { - apic_read_around(APIC_SPIV); - apic_write(APIC_ESR, 0); - apic_read(APIC_ESR); - } - - Dprintk("Asserting INIT.\n"); - - /* - * Turn INIT on target chip - */ - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); - - /* - * Send IPI - */ - apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT - | APIC_DM_INIT); - - Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); - - mdelay(10); - - Dprintk("Deasserting INIT.\n"); - - /* Target chip */ - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); - - /* Send IPI */ - apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); - - Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); - - atomic_set(&init_deasserted, 1); - - /* - * Should we send STARTUP IPIs ? - * - * Determine this based on the APIC version. - * If we don't have an integrated APIC, don't send the STARTUP IPIs. - */ - if (APIC_INTEGRATED(apic_version[phys_apicid])) - num_starts = 2; - else - num_starts = 0; - - /* - * Run STARTUP IPI loop. - */ - Dprintk("#startup loops: %d.\n", num_starts); - - maxlvt = get_maxlvt(); - - for (j = 1; j <= num_starts; j++) { - Dprintk("Sending STARTUP #%d.\n",j); - apic_read_around(APIC_SPIV); - apic_write(APIC_ESR, 0); - apic_read(APIC_ESR); - Dprintk("After apic_write.\n"); - - /* - * STARTUP IPI - */ - - /* Target chip */ - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); - - /* Boot on the stack */ - /* Kick the second */ - apic_write_around(APIC_ICR, APIC_DM_STARTUP - | (start_eip >> 12)); - - /* - * Give the other CPU some time to accept the IPI. - */ - udelay(300); - - Dprintk("Startup point 1.\n"); - - Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); - - /* - * Give the other CPU some time to accept the IPI. - */ - udelay(200); - /* - * Due to the Pentium erratum 3AP. - */ - if (maxlvt > 3) { - apic_read_around(APIC_SPIV); - apic_write(APIC_ESR, 0); - } - accept_status = (apic_read(APIC_ESR) & 0xEF); - if (send_status || accept_status) - break; - } - Dprintk("After Startup.\n"); - - if (send_status) - printk("APIC never delivered???\n"); - if (accept_status) - printk("APIC delivery error (%lx).\n", accept_status); - - return (send_status | accept_status); -} -#endif /* WAKE_SECONDARY_VIA_INIT */ -#endif - -extern cpumask_t cpu_initialized; - -static int __init do_boot_cpu(int apicid) -/* - * NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad - * (ie clustered apic addressing mode), this is a LOGICAL apic ID. - * Returns zero if CPU booted OK, else error code from wakeup_secondary_cpu. - */ -{ - struct task_struct *idle; - unsigned long boot_error; - int timeout, cpu; - unsigned long start_eip; -#if 0 - unsigned short nmi_high = 0, nmi_low = 0; -#endif - vcpu_guest_context_t ctxt; - extern void startup_32_smp(void); - extern void hypervisor_callback(void); - extern void failsafe_callback(void); - extern void smp_trap_init(trap_info_t *); - - cpu = ++cpucount; - /* - * We can't use kernel_thread since we must avoid to - * reschedule the child. - */ - idle = fork_idle(cpu); - if (IS_ERR(idle)) - panic("failed fork for CPU %d", cpu); - idle->thread.eip = (unsigned long) start_secondary; - /* start_eip had better be page-aligned! */ - start_eip = (unsigned long)startup_32_smp; - - /* So we see what's up */ - printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); - /* Stack for startup_32 can be just as for start_secondary onwards */ - stack_start.esp = (void *) idle->thread.esp; - - irq_ctx_init(cpu); - - /* - * This grunge runs the startup process for - * the targeted processor. - */ - - atomic_set(&init_deasserted, 0); - -#if 1 - cpu_gdt_descr[cpu].address = __get_free_page(GFP_KERNEL|__GFP_ZERO); - BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE); - cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size; - memcpy((void *)cpu_gdt_descr[cpu].address, - (void *)cpu_gdt_descr[0].address, cpu_gdt_descr[0].size); - - memset(&ctxt, 0, sizeof(ctxt)); - - ctxt.user_regs.ds = __USER_DS; - ctxt.user_regs.es = __USER_DS; - ctxt.user_regs.fs = 0; - ctxt.user_regs.gs = 0; - ctxt.user_regs.ss = __KERNEL_DS; - ctxt.user_regs.cs = __KERNEL_CS; - ctxt.user_regs.eip = start_eip; - ctxt.user_regs.esp = idle->thread.esp; -#define X86_EFLAGS_IOPL_RING1 0x1000 - ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING1; - - /* FPU is set up to default initial state. */ - memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt)); - - smp_trap_init(ctxt.trap_ctxt); - - /* No LDT. */ - ctxt.ldt_ents = 0; - - { - unsigned long va; - int f; - - for (va = cpu_gdt_descr[cpu].address, f = 0; - va < cpu_gdt_descr[cpu].address + cpu_gdt_descr[cpu].size; - va += PAGE_SIZE, f++) { - ctxt.gdt_frames[f] = virt_to_mfn(va); - make_page_readonly((void *)va); - } - ctxt.gdt_ents = cpu_gdt_descr[cpu].size / 8; - } - - /* Ring 1 stack is the initial stack. */ - ctxt.kernel_ss = __KERNEL_DS; - ctxt.kernel_sp = idle->thread.esp; - - /* Callback handlers. */ - ctxt.event_callback_cs = __KERNEL_CS; - ctxt.event_callback_eip = (unsigned long)hypervisor_callback; - ctxt.failsafe_callback_cs = __KERNEL_CS; - ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback; - - ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT; - - boot_error = HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, &ctxt); - if (boot_error) - printk("boot error: %ld\n", boot_error); - - if (!boot_error) { - HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); - - /* - * allow APs to start initializing. - */ - Dprintk("Before Callout %d.\n", cpu); - cpu_set(cpu, cpu_callout_map); - Dprintk("After Callout %d.\n", cpu); - - /* - * Wait 5s total for a response - */ - for (timeout = 0; timeout < 50000; timeout++) { - if (cpu_isset(cpu, cpu_callin_map)) - break; /* It has booted */ - udelay(100); - } - - if (cpu_isset(cpu, cpu_callin_map)) { - /* number CPUs logically, starting from 1 (BSP is 0) */ - Dprintk("OK.\n"); - printk("CPU%d: ", cpu); - print_cpu_info(&cpu_data[cpu]); - Dprintk("CPU has booted.\n"); - } else { - boot_error= 1; - } - } - x86_cpu_to_apicid[cpu] = apicid; - if (boot_error) { - /* Try to put things back the way they were before ... */ - unmap_cpu_to_logical_apicid(cpu); - cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ - cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ - cpucount--; - } - -#else - Dprintk("Setting warm reset code and vector.\n"); - - store_NMI_vector(&nmi_high, &nmi_low); - - smpboot_setup_warm_reset_vector(start_eip); - - /* - * Starting actual IPI sequence... - */ - boot_error = wakeup_secondary_cpu(apicid, start_eip); - - if (!boot_error) { - /* - * allow APs to start initializing. - */ - Dprintk("Before Callout %d.\n", cpu); - cpu_set(cpu, cpu_callout_map); - Dprintk("After Callout %d.\n", cpu); - - /* - * Wait 5s total for a response - */ - for (timeout = 0; timeout < 50000; timeout++) { - if (cpu_isset(cpu, cpu_callin_map)) - break; /* It has booted */ - udelay(100); - } - - if (cpu_isset(cpu, cpu_callin_map)) { - /* number CPUs logically, starting from 1 (BSP is 0) */ - Dprintk("OK.\n"); - printk("CPU%d: ", cpu); - print_cpu_info(&cpu_data[cpu]); - Dprintk("CPU has booted.\n"); - } else { - boot_error= 1; - if (*((volatile unsigned char *)trampoline_base) - == 0xA5) - /* trampoline started but...? */ - printk("Stuck ??\n"); - else - /* trampoline code not run */ - printk("Not responding.\n"); - inquire_remote_apic(apicid); - } - } - x86_cpu_to_apicid[cpu] = apicid; - if (boot_error) { - /* Try to put things back the way they were before ... */ - unmap_cpu_to_logical_apicid(cpu); - cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ - cpu_clear(cpu, cpu_initialized); /* was set by cpu_init() */ - cpucount--; - } - - /* mark "stuck" area as not stuck */ - *((volatile unsigned long *)trampoline_base) = 0; -#endif - - return boot_error; -} - -static void smp_tune_scheduling (void) -{ - unsigned long cachesize; /* kB */ - unsigned long bandwidth = 350; /* MB/s */ - /* - * Rough estimation for SMP scheduling, this is the number of - * cycles it takes for a fully memory-limited process to flush - * the SMP-local cache. - * - * (For a P5 this pretty much means we will choose another idle - * CPU almost always at wakeup time (this is due to the small - * L1 cache), on PIIs it's around 50-100 usecs, depending on - * the cache size) - */ - - if (!cpu_khz) { - /* - * this basically disables processor-affinity - * scheduling on SMP without a TSC. - */ - return; - } else { - cachesize = boot_cpu_data.x86_cache_size; - if (cachesize == -1) { - cachesize = 16; /* Pentiums, 2x8kB cache */ - bandwidth = 100; - } - } -} - -/* - * Cycle through the processors sending APIC IPIs to boot each. - */ - -#if 0 -static int boot_cpu_logical_apicid; -#endif -/* Where the IO area was mapped on multiquad, always 0 otherwise */ -void *xquad_portio; - -cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; -cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; -EXPORT_SYMBOL(cpu_core_map); - -static void __init smp_boot_cpus(unsigned int max_cpus) -{ - int cpu, kicked; - unsigned long bogosum = 0; -#if 0 - int apicid, bit; -#endif - - /* - * Setup boot CPU information - */ - smp_store_cpu_info(0); /* Final full version of the data */ - printk("CPU%d: ", 0); - print_cpu_info(&cpu_data[0]); - -#if 0 - boot_cpu_physical_apicid = GET_APIC_ID(apic_read(APIC_ID)); - boot_cpu_logical_apicid = logical_smp_processor_id(); - x86_cpu_to_apicid[0] = boot_cpu_physical_apicid; -#else - // boot_cpu_physical_apicid = 0; - // boot_cpu_logical_apicid = 0; - x86_cpu_to_apicid[0] = 0; -#endif - - current_thread_info()->cpu = 0; - smp_tune_scheduling(); - cpus_clear(cpu_sibling_map[0]); - cpu_set(0, cpu_sibling_map[0]); - - cpus_clear(cpu_core_map[0]); - cpu_set(0, cpu_core_map[0]); - -#ifdef CONFIG_X86_IO_APIC - /* - * If we couldn't find an SMP configuration at boot time, - * get out of here now! - */ - if (!smp_found_config && !acpi_lapic) { - printk(KERN_NOTICE "SMP motherboard not detected.\n"); - smpboot_clear_io_apic_irqs(); -#if 0 - phys_cpu_present_map = physid_mask_of_physid(0); -#endif -#ifdef CONFIG_X86_LOCAL_APIC - if (APIC_init_uniprocessor()) - printk(KERN_NOTICE "Local APIC not detected." - " Using dummy APIC emulation.\n"); -#endif - map_cpu_to_logical_apicid(); - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); - return; - } -#endif - -#if 0 - /* - * Should not be necessary because the MP table should list the boot - * CPU too, but we do it for the sake of robustness anyway. - * Makes no sense to do this check in clustered apic mode, so skip it - */ - if (!check_phys_apicid_present(boot_cpu_physical_apicid)) { - printk("weird, boot CPU (#%d) not listed by the BIOS.\n", - boot_cpu_physical_apicid); - physid_set(hard_smp_processor_id(), phys_cpu_present_map); - } - - /* - * If we couldn't find a local APIC, then get out of here now! - */ - if (APIC_INTEGRATED(apic_version[boot_cpu_physical_apicid]) && !cpu_has_apic) { - printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", - boot_cpu_physical_apicid); - printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); - smpboot_clear_io_apic_irqs(); - phys_cpu_present_map = physid_mask_of_physid(0); - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); - return; - } - - verify_local_APIC(); -#endif - - /* - * If SMP should be disabled, then really disable it! - */ - if (!max_cpus) { - xen_start_info->n_vcpu = 1; - printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); - smpboot_clear_io_apic_irqs(); -#if 0 - phys_cpu_present_map = physid_mask_of_physid(0); -#endif - return; - } - - xen_smp_intr_init(0); - -#if 0 - connect_bsp_APIC(); - setup_local_APIC(); -#endif - map_cpu_to_logical_apicid(); -#if 0 - - - setup_portio_remap(); - - /* - * Scan the CPU present map and fire up the other CPUs via do_boot_cpu - * - * In clustered apic mode, phys_cpu_present_map is a constructed thus: - * bits 0-3 are quad0, 4-7 are quad1, etc. A perverse twist on the - * clustered apic ID. - */ - Dprintk("CPU present map: %lx\n", physids_coerce(phys_cpu_present_map)); -#endif - Dprintk("CPU present map: %lx\n", (1UL << xen_start_info->n_vcpu) - 1); - - kicked = 1; - for (cpu = 1; kicked < NR_CPUS && cpu < xen_start_info->n_vcpu; cpu++) { - if (max_cpus <= cpucount+1) - continue; - -#ifdef CONFIG_SMP_ALTERNATIVES - if (kicked == 1) - prepare_for_smp(); -#endif - if (do_boot_cpu(cpu)) - printk("CPU #%d not responding - cannot use it.\n", - cpu); - else - ++kicked; - } - -#if 0 - /* - * Cleanup possible dangling ends... - */ - smpboot_restore_warm_reset_vector(); -#endif - - /* - * Allow the user to impress friends. - */ - Dprintk("Before bogomips.\n"); - for (cpu = 0; cpu < NR_CPUS; cpu++) - if (cpu_isset(cpu, cpu_callout_map)) - bogosum += cpu_data[cpu].loops_per_jiffy; - printk(KERN_INFO - "Total of %d processors activated (%lu.%02lu BogoMIPS).\n", - cpucount+1, - bogosum/(500000/HZ), - (bogosum/(5000/HZ))%100); - - Dprintk("Before bogocount - setting activated=1.\n"); - - if (smp_b_stepping) - printk(KERN_WARNING "WARNING: SMP operation may be unreliable with B stepping processors.\n"); - - /* - * Don't taint if we are running SMP kernel on a single non-MP - * approved Athlon - */ - if (tainted & TAINT_UNSAFE_SMP) { - if (cpucount) - printk (KERN_INFO "WARNING: This combination of AMD processors is not suitable for SMP.\n"); - else - tainted &= ~TAINT_UNSAFE_SMP; - } - - Dprintk("Boot done.\n"); - - /* - * construct cpu_sibling_map[], so that we can tell sibling CPUs - * efficiently. - */ - for (cpu = 0; cpu < NR_CPUS; cpu++) { - cpus_clear(cpu_sibling_map[cpu]); - cpus_clear(cpu_core_map[cpu]); - } - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - struct cpuinfo_x86 *c = cpu_data + cpu; - int siblings = 0; - int i; - if (!cpu_isset(cpu, cpu_callout_map)) - continue; - - if (smp_num_siblings > 1) { - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_isset(i, cpu_callout_map)) - continue; - if (cpu_core_id[cpu] == cpu_core_id[i]) { - siblings++; - cpu_set(i, cpu_sibling_map[cpu]); - } - } - } else { - siblings++; - cpu_set(cpu, cpu_sibling_map[cpu]); - } - - if (siblings != smp_num_siblings) { - printk(KERN_WARNING "WARNING: %d siblings found for CPU%d, should be %d\n", siblings, cpu, smp_num_siblings); - smp_num_siblings = siblings; - } - - if (c->x86_num_cores > 1) { - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_isset(i, cpu_callout_map)) - continue; - if (phys_proc_id[cpu] == phys_proc_id[i]) { - cpu_set(i, cpu_core_map[cpu]); - } - } - } else { - cpu_core_map[cpu] = cpu_sibling_map[cpu]; - } - } - - smpboot_setup_io_apic(); - -#if 0 - setup_boot_APIC_clock(); - - /* - * Synchronize the TSC with the AP - */ - if (cpu_has_tsc && cpucount && cpu_khz) - synchronize_tsc_bp(); -#endif -} - -/* These are wrappers to interface to the new boot process. Someone - who understands all this stuff should rewrite it properly. --RR 15/Jul/02 */ -void __init smp_prepare_cpus(unsigned int max_cpus) -{ - smp_commenced_mask = cpumask_of_cpu(0); - cpu_callin_map = cpumask_of_cpu(0); - mb(); - smp_boot_cpus(max_cpus); -} - -void __devinit smp_prepare_boot_cpu(void) -{ - cpu_set(smp_processor_id(), cpu_online_map); - cpu_set(smp_processor_id(), cpu_callout_map); -} - -#ifdef CONFIG_HOTPLUG_CPU - -static void handle_vcpu_hotplug_event( - struct xenbus_watch *watch, const char **vec, unsigned int len) -{ - int err, cpu; - char dir[32], state[32]; - char *cpustr; - const char *node = vec[XS_WATCH_PATH]; - - if ((cpustr = strstr(node, "cpu/")) == NULL) - return; - - sscanf(cpustr, "cpu/%d", &cpu); - - sprintf(dir, "cpu/%d", cpu); - err = xenbus_scanf(NULL, dir, "availability", "%s", state); - if (err != 1) { - printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); - return; - } - - if (strcmp(state, "online") == 0) - (void)cpu_up(cpu); - else if (strcmp(state, "offline") == 0) - (void)cpu_down(cpu); - else - printk(KERN_ERR "XENBUS: unknown state(%s) on node(%s)\n", - state, node); -} - -static int setup_cpu_watcher(struct notifier_block *notifier, - unsigned long event, void *data) -{ - static struct xenbus_watch cpu_watch = { - .node = "cpu", - .callback = handle_vcpu_hotplug_event }; - (void)register_xenbus_watch(&cpu_watch); - return NOTIFY_DONE; -} - -static int __init setup_vcpu_hotplug_event(void) -{ - static struct notifier_block xsn_cpu = { - .notifier_call = setup_cpu_watcher }; - register_xenstore_notifier(&xsn_cpu); - return 0; -} - -subsys_initcall(setup_vcpu_hotplug_event); - -int __cpu_disable(void) -{ - cpumask_t map = cpu_online_map; - int cpu = smp_processor_id(); - - /* - * Perhaps use cpufreq to drop frequency, but that could go - * into generic code. - * - * We won't take down the boot processor on i386 due to some - * interrupts only being able to be serviced by the BSP. - * Especially so if we're not using an IOAPIC -zwane - */ - if (cpu == 0) - return -EBUSY; - - cpu_clear(cpu, map); - fixup_irqs(map); - - /* It's now safe to remove this processor from the online map */ - cpu_clear(cpu, cpu_online_map); - - return 0; -} - -void __cpu_die(unsigned int cpu) -{ - while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { - current->state = TASK_UNINTERRUPTIBLE; - schedule_timeout(HZ/10); - } - - xen_smp_intr_exit(cpu); - -#ifdef CONFIG_SMP_ALTERNATIVES - if (num_online_cpus() == 1) - unprepare_for_smp(); -#endif -} - -#else /* ... !CONFIG_HOTPLUG_CPU */ -int __cpu_disable(void) -{ - return -ENOSYS; -} - -void __cpu_die(unsigned int cpu) -{ - /* We said "no" in __cpu_disable */ - BUG(); -} -#endif /* CONFIG_HOTPLUG_CPU */ - -int __devinit __cpu_up(unsigned int cpu) -{ - /* In case one didn't come up */ - if (!cpu_isset(cpu, cpu_callin_map)) { - printk(KERN_DEBUG "skipping cpu%d, didn't come online\n", cpu); - local_irq_enable(); - return -EIO; - } - -#ifdef CONFIG_SMP_ALTERNATIVES - if (num_online_cpus() == 1) - prepare_for_smp(); -#endif - - xen_smp_intr_init(cpu); - cpu_set(cpu, smp_commenced_mask); - cpu_set(cpu, cpu_online_map); - HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); - - return 0; -} - -void __init smp_cpus_done(unsigned int max_cpus) -{ -#if 1 -#else -#ifdef CONFIG_X86_IO_APIC - setup_ioapic_dest(); -#endif - zap_low_mappings(); - /* - * Disable executability of the SMP trampoline: - */ - set_kernel_exec((unsigned long)trampoline_base, trampoline_exec); -#endif -} - -extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *); -extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *); - -extern void local_setup_timer(unsigned int cpu); -extern void local_teardown_timer(unsigned int cpu); - -static void xen_smp_intr_init(unsigned int cpu) -{ - per_cpu(resched_irq, cpu) = - bind_ipi_to_irq(RESCHEDULE_VECTOR, cpu); - sprintf(resched_name[cpu], "resched%d", cpu); - BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, - SA_INTERRUPT, resched_name[cpu], NULL)); - - per_cpu(callfunc_irq, cpu) = - bind_ipi_to_irq(CALL_FUNCTION_VECTOR, cpu); - sprintf(callfunc_name[cpu], "callfunc%d", cpu); - BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), - smp_call_function_interrupt, - SA_INTERRUPT, callfunc_name[cpu], NULL)); - - if (cpu != 0) - local_setup_timer(cpu); -} - -static void xen_smp_intr_exit(unsigned int cpu) -{ - if (cpu != 0) - local_teardown_timer(cpu); - - free_irq(per_cpu(resched_irq, cpu), NULL); - unbind_ipi_from_irq(RESCHEDULE_VECTOR, cpu); - - free_irq(per_cpu(callfunc_irq, cpu), NULL); - unbind_ipi_from_irq(CALL_FUNCTION_VECTOR, cpu); -} - -void vcpu_prepare(int vcpu) -{ - extern void hypervisor_callback(void); - extern void failsafe_callback(void); - extern void smp_trap_init(trap_info_t *); - vcpu_guest_context_t ctxt; - struct task_struct *idle = idle_task(vcpu); - - if (vcpu == 0) - return; - - memset(&ctxt, 0, sizeof(ctxt)); - - ctxt.user_regs.ds = __USER_DS; - ctxt.user_regs.es = __USER_DS; - ctxt.user_regs.fs = 0; - ctxt.user_regs.gs = 0; - ctxt.user_regs.ss = __KERNEL_DS; - ctxt.user_regs.cs = __KERNEL_CS; - ctxt.user_regs.eip = (unsigned long)cpu_idle; - ctxt.user_regs.esp = idle->thread.esp; - ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING1; - - memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt)); - - smp_trap_init(ctxt.trap_ctxt); - - ctxt.ldt_ents = 0; - - ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[vcpu].address); - ctxt.gdt_ents = cpu_gdt_descr[vcpu].size / 8; - - ctxt.kernel_ss = __KERNEL_DS; - ctxt.kernel_sp = idle->thread.esp0; - - ctxt.event_callback_cs = __KERNEL_CS; - ctxt.event_callback_eip = (unsigned long)hypervisor_callback; - ctxt.failsafe_callback_cs = __KERNEL_CS; - ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback; - - ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT; - - (void)HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt); -} - -/* - * Local variables: - * c-file-style: "linux" - * indent-tabs-mode: t - * c-indent-level: 8 - * c-basic-offset: 8 - * tab-width: 8 - * End: - */ diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/Makefile b/linux-2.6-xen-sparse/arch/xen/kernel/Makefile index b600a70a35..69b422382e 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/Makefile +++ b/linux-2.6-xen-sparse/arch/xen/kernel/Makefile @@ -15,4 +15,4 @@ obj-y := evtchn.o fixup.o reboot.o gnttab.o devmem.o obj-$(CONFIG_PROC_FS) += xen_proc.o obj-$(CONFIG_NET) += skbuff.o -obj-$(CONFIG_SMP) += smp.o +obj-$(CONFIG_SMP) += smp.o smpboot.o diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c new file mode 100644 index 0000000000..a2e6cab984 --- /dev/null +++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c @@ -0,0 +1,381 @@ +/* + * Xen SMP booting functions + * + * See arch/i386/kernel/smpboot.c for copyright and credits for derived + * portions of this file. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_SMP_ALTERNATIVES +#include +#endif + +extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *); +extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *); + +extern void local_setup_timer(unsigned int cpu); +extern void local_teardown_timer(unsigned int cpu); + +extern void hypervisor_callback(void); +extern void failsafe_callback(void); +extern void system_call(void); +extern void smp_trap_init(trap_info_t *); + +extern cpumask_t cpu_initialized; + +/* Number of siblings per CPU package */ +int smp_num_siblings = 1; +int phys_proc_id[NR_CPUS]; /* Package ID of each logical CPU */ +EXPORT_SYMBOL(phys_proc_id); +int cpu_core_id[NR_CPUS]; /* Core ID of each logical CPU */ +EXPORT_SYMBOL(cpu_core_id); + +cpumask_t cpu_online_map; +EXPORT_SYMBOL(cpu_online_map); +cpumask_t cpu_possible_map; +EXPORT_SYMBOL(cpu_possible_map); + +struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; +EXPORT_SYMBOL(cpu_data); + +#ifdef CONFIG_HOTPLUG_CPU +DEFINE_PER_CPU(int, cpu_state) = { 0 }; +#endif + +static DEFINE_PER_CPU(int, resched_irq); +static DEFINE_PER_CPU(int, callfunc_irq); +static char resched_name[NR_CPUS][15]; +static char callfunc_name[NR_CPUS][15]; + +u8 cpu_2_logical_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; + +void *xquad_portio; + +cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; +cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; +EXPORT_SYMBOL(cpu_core_map); + +#ifdef __i386__ +u8 x86_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = 0xff }; +EXPORT_SYMBOL(x86_cpu_to_apicid); +#else +unsigned int maxcpus = NR_CPUS; +#endif + +void __init smp_alloc_memory(void) +{ +} + +static void xen_smp_intr_init(unsigned int cpu) +{ + per_cpu(resched_irq, cpu) = + bind_ipi_to_irq(RESCHEDULE_VECTOR, cpu); + sprintf(resched_name[cpu], "resched%d", cpu); + BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, + SA_INTERRUPT, resched_name[cpu], NULL)); + + per_cpu(callfunc_irq, cpu) = + bind_ipi_to_irq(CALL_FUNCTION_VECTOR, cpu); + sprintf(callfunc_name[cpu], "callfunc%d", cpu); + BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), + smp_call_function_interrupt, + SA_INTERRUPT, callfunc_name[cpu], NULL)); + + if (cpu != 0) + local_setup_timer(cpu); +} + +#ifdef CONFIG_HOTPLUG_CPU +static void xen_smp_intr_exit(unsigned int cpu) +{ + if (cpu != 0) + local_teardown_timer(cpu); + + free_irq(per_cpu(resched_irq, cpu), NULL); + unbind_ipi_from_irq(RESCHEDULE_VECTOR, cpu); + + free_irq(per_cpu(callfunc_irq, cpu), NULL); + unbind_ipi_from_irq(CALL_FUNCTION_VECTOR, cpu); +} +#endif + +static void cpu_bringup(void) +{ + if (!cpu_isset(smp_processor_id(), cpu_initialized)) + cpu_init(); + local_irq_enable(); + cpu_idle(); +} + +void vcpu_prepare(int vcpu) +{ + vcpu_guest_context_t ctxt; + struct task_struct *idle = idle_task(vcpu); + + if (vcpu == 0) + return; + + memset(&ctxt, 0, sizeof(ctxt)); + + ctxt.flags = VGCF_IN_KERNEL; + ctxt.user_regs.ds = __USER_DS; + ctxt.user_regs.es = __USER_DS; + ctxt.user_regs.fs = 0; + ctxt.user_regs.gs = 0; + ctxt.user_regs.ss = __KERNEL_DS; + ctxt.user_regs.eip = (unsigned long)cpu_bringup; + ctxt.user_regs.eflags = X86_EFLAGS_IF | 0x1000; /* IOPL_RING1 */ + + memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt)); + + smp_trap_init(ctxt.trap_ctxt); + + ctxt.ldt_ents = 0; + + ctxt.gdt_frames[0] = virt_to_mfn(cpu_gdt_descr[vcpu].address); + ctxt.gdt_ents = cpu_gdt_descr[vcpu].size / 8; + +#ifdef __i386__ + ctxt.user_regs.cs = __KERNEL_CS; + ctxt.user_regs.esp = idle->thread.esp; + + ctxt.kernel_ss = __KERNEL_DS; + ctxt.kernel_sp = idle->thread.esp0; + + ctxt.event_callback_cs = __KERNEL_CS; + ctxt.event_callback_eip = (unsigned long)hypervisor_callback; + ctxt.failsafe_callback_cs = __KERNEL_CS; + ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback; + + ctxt.ctrlreg[3] = virt_to_mfn(swapper_pg_dir) << PAGE_SHIFT; +#else + ctxt.user_regs.cs = __KERNEL_CS | 3; + ctxt.user_regs.esp = idle->thread.rsp; + + ctxt.kernel_ss = __KERNEL_DS; + ctxt.kernel_sp = idle->thread.rsp0; + + ctxt.event_callback_eip = (unsigned long)hypervisor_callback; + ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback; + ctxt.syscall_callback_eip = (unsigned long)system_call; + + ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT; +#endif + + BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt)); +} + +void __init smp_prepare_cpus(unsigned int max_cpus) +{ + int cpu; + struct task_struct *idle; + + if (max_cpus == 0) { + xen_start_info->n_vcpu = 1; + return; + } + + if (max_cpus < xen_start_info->n_vcpu) + xen_start_info->n_vcpu = max_cpus; + + xen_smp_intr_init(0); + + for (cpu = 1; cpu < xen_start_info->n_vcpu; cpu++) { + cpu_data[cpu] = boot_cpu_data; + cpu_2_logical_apicid[cpu] = cpu; + x86_cpu_to_apicid[cpu] = cpu; + + idle = fork_idle(cpu); + if (IS_ERR(idle)) + panic("failed fork for CPU %d", cpu); + + irq_ctx_init(cpu); + + cpu_gdt_descr[cpu].address = + __get_free_page(GFP_KERNEL|__GFP_ZERO); + BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE); + cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size; + memcpy((void *)cpu_gdt_descr[cpu].address, + (void *)cpu_gdt_descr[0].address, + cpu_gdt_descr[0].size); + make_page_readonly((void *)cpu_gdt_descr[cpu].address); + + cpu_set(cpu, cpu_possible_map); + + vcpu_prepare(cpu); + } + + /* Currently, Xen gives no dynamic NUMA/HT info. */ + for (cpu = 0; cpu < NR_CPUS; cpu++) { + cpus_clear(cpu_sibling_map[cpu]); + cpus_clear(cpu_core_map[cpu]); + } + +#ifdef CONFIG_X86_IO_APIC + /* + * Here we can be sure that there is an IO-APIC in the system. Let's + * go and set it up: + */ + if (!skip_ioapic_setup && nr_ioapics) + setup_IO_APIC(); +#endif +} + +void __devinit smp_prepare_boot_cpu(void) +{ + cpu_possible_map = cpumask_of_cpu(0); + cpu_online_map = cpumask_of_cpu(0); + + cpu_data[0] = boot_cpu_data; + cpu_2_logical_apicid[0] = 0; + x86_cpu_to_apicid[0] = 0; + + current_thread_info()->cpu = 0; + cpus_clear(cpu_sibling_map[0]); + cpu_set(0, cpu_sibling_map[0]); + + cpus_clear(cpu_core_map[0]); + cpu_set(0, cpu_core_map[0]); +} + +#ifdef CONFIG_HOTPLUG_CPU + +static void handle_vcpu_hotplug_event( + struct xenbus_watch *watch, const char **vec, unsigned int len) +{ + int err, cpu; + char dir[32], state[32]; + char *cpustr; + const char *node = vec[XS_WATCH_PATH]; + + if ((cpustr = strstr(node, "cpu/")) == NULL) + return; + + sscanf(cpustr, "cpu/%d", &cpu); + + sprintf(dir, "cpu/%d", cpu); + err = xenbus_scanf(NULL, dir, "availability", "%s", state); + if (err != 1) { + printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); + return; + } + + if (strcmp(state, "online") == 0) + (void)cpu_up(cpu); + else if (strcmp(state, "offline") == 0) + (void)cpu_down(cpu); + else + printk(KERN_ERR "XENBUS: unknown state(%s) on node(%s)\n", + state, node); +} + +static int setup_cpu_watcher(struct notifier_block *notifier, + unsigned long event, void *data) +{ + static struct xenbus_watch cpu_watch = { + .node = "cpu", + .callback = handle_vcpu_hotplug_event }; + (void)register_xenbus_watch(&cpu_watch); + return NOTIFY_DONE; +} + +static int __init setup_vcpu_hotplug_event(void) +{ + static struct notifier_block xsn_cpu = { + .notifier_call = setup_cpu_watcher }; + register_xenstore_notifier(&xsn_cpu); + return 0; +} + +subsys_initcall(setup_vcpu_hotplug_event); + +int __cpu_disable(void) +{ + cpumask_t map = cpu_online_map; + int cpu = smp_processor_id(); + + if (cpu == 0) + return -EBUSY; + + cpu_clear(cpu, map); + fixup_irqs(map); + cpu_clear(cpu, cpu_online_map); + + return 0; +} + +void __cpu_die(unsigned int cpu) +{ + while (HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL)) { + current->state = TASK_UNINTERRUPTIBLE; + schedule_timeout(HZ/10); + } + + xen_smp_intr_exit(cpu); + +#ifdef CONFIG_SMP_ALTERNATIVES + if (num_online_cpus() == 1) + unprepare_for_smp(); +#endif +} + +#else /* ... !CONFIG_HOTPLUG_CPU */ + +int __cpu_disable(void) +{ + return -ENOSYS; +} + +void __cpu_die(unsigned int cpu) +{ + BUG(); +} + +#endif /* CONFIG_HOTPLUG_CPU */ + +int __devinit __cpu_up(unsigned int cpu) +{ +#ifdef CONFIG_SMP_ALTERNATIVES + if (num_online_cpus() == 1) + prepare_for_smp(); +#endif + + xen_smp_intr_init(cpu); + cpu_set(cpu, cpu_online_map); + HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); + + return 0; +} + +void __init smp_cpus_done(unsigned int max_cpus) +{ +} + +/* + * Local variables: + * c-file-style: "linux" + * indent-tabs-mode: t + * c-indent-level: 8 + * c-basic-offset: 8 + * tab-width: 8 + * End: + */ diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile index 973508d7a4..f45c5751c4 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/Makefile @@ -25,7 +25,7 @@ obj-$(CONFIG_ACPI_BOOT) += acpi/ c-obj-$(CONFIG_X86_MSR) += msr.o obj-$(CONFIG_MICROCODE) += microcode.o obj-$(CONFIG_X86_CPUID) += cpuid.o -obj-$(CONFIG_SMP) += smp.o smpboot.o +obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_X86_LOCAL_APIC) += apic.o c-obj-$(CONFIG_X86_LOCAL_APIC) += nmi.o obj-$(CONFIG_X86_IO_APIC) += io_apic.o mpparse.o diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c deleted file mode 100644 index 8529c9e5db..0000000000 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/smpboot.c +++ /dev/null @@ -1,1253 +0,0 @@ -/* - * x86 SMP booting functions - * - * (c) 1995 Alan Cox, Building #3 - * (c) 1998, 1999, 2000 Ingo Molnar - * Copyright 2001 Andi Kleen, SuSE Labs. - * - * Much of the core SMP work is based on previous work by Thomas Radke, to - * whom a great many thanks are extended. - * - * Thanks to Intel for making available several different Pentium, - * Pentium Pro and Pentium-II/Xeon MP machines. - * Original development of Linux SMP code supported by Caldera. - * - * This code is released under the GNU General Public License version 2 - * - * Fixes - * Felix Koop : NR_CPUS used properly - * Jose Renau : Handle single CPU case. - * Alan Cox : By repeated request 8) - Total BogoMIP report. - * Greg Wright : Fix for kernel stacks panic. - * Erich Boleyn : MP v1.4 and additional changes. - * Matthias Sattler : Changes for 2.1 kernel map. - * Michel Lespinasse : Changes for 2.1 kernel map. - * Michael Chastain : Change trampoline.S to gnu as. - * Alan Cox : Dumb bug: 'B' step PPro's are fine - * Ingo Molnar : Added APIC timers, based on code - * from Jose Renau - * Ingo Molnar : various cleanups and rewrites - * Tigran Aivazian : fixed "0.00 in /proc/uptime on SMP" bug. - * Maciej W. Rozycki : Bits for genuine 82489DX APICs - * Andi Kleen : Changed for SMP boot into long mode. - * Rusty Russell : Hacked into shape for new "hotplug" boot process. - * Andi Kleen : Converted to new state machine. - * Various cleanups. - * Probably mostly hotplug CPU ready now. - */ - - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_XEN -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef CONFIG_XEN -#include -#include -#include -#endif - -/* Change for real CPU hotplug. Note other files need to be fixed - first too. */ -#define __cpuinit __init -#define __cpuinitdata __initdata - -#if defined(CONFIG_XEN) && !defined(CONFIG_XEN_PRIVILEGED_GUEST) - unsigned int maxcpus = NR_CPUS; -#endif - -/* Number of siblings per CPU package */ -int smp_num_siblings = 1; -/* Package ID of each logical CPU */ -u8 phys_proc_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; -u8 cpu_core_id[NR_CPUS] = { [0 ... NR_CPUS-1] = BAD_APICID }; -EXPORT_SYMBOL(phys_proc_id); -EXPORT_SYMBOL(cpu_core_id); - -/* Bitmask of currently online CPUs */ -cpumask_t cpu_online_map; - -EXPORT_SYMBOL(cpu_online_map); - -/* - * Private maps to synchronize booting between AP and BP. - * Probably not needed anymore, but it makes for easier debugging. -AK - */ -cpumask_t cpu_callin_map; -cpumask_t cpu_callout_map; - -cpumask_t cpu_possible_map; -EXPORT_SYMBOL(cpu_possible_map); - -/* Per CPU bogomips and other parameters */ -struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned; - -/* Set when the idlers are all forked */ -int smp_threads_ready; - -cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; -cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; -EXPORT_SYMBOL(cpu_core_map); - -#ifndef CONFIG_XEN -/* - * Trampoline 80x86 program as an array. - */ - -extern unsigned char trampoline_data[]; -extern unsigned char trampoline_end[]; - -/* - * Currently trivial. Write the real->protected mode - * bootstrap into the page concerned. The caller - * has made sure it's suitably aligned. - */ - -static unsigned long __cpuinit setup_trampoline(void) -{ - void *tramp = __va(SMP_TRAMPOLINE_BASE); - memcpy(tramp, trampoline_data, trampoline_end - trampoline_data); - return virt_to_phys(tramp); -} -#endif - -/* - * The bootstrap kernel entry code has set these up. Save them for - * a given CPU - */ - -static void __cpuinit smp_store_cpu_info(int id) -{ - struct cpuinfo_x86 *c = cpu_data + id; - - *c = boot_cpu_data; - identify_cpu(c); - print_cpu_info(c); -} - -#ifndef CONFIG_XEN -/* - * New Funky TSC sync algorithm borrowed from IA64. - * Main advantage is that it doesn't reset the TSCs fully and - * in general looks more robust and it works better than my earlier - * attempts. I believe it was written by David Mosberger. Some minor - * adjustments for x86-64 by me -AK - * - * Original comment reproduced below. - * - * Synchronize TSC of the current (slave) CPU with the TSC of the - * MASTER CPU (normally the time-keeper CPU). We use a closed loop to - * eliminate the possibility of unaccounted-for errors (such as - * getting a machine check in the middle of a calibration step). The - * basic idea is for the slave to ask the master what itc value it has - * and to read its own itc before and after the master responds. Each - * iteration gives us three timestamps: - * - * slave master - * - * t0 ---\ - * ---\ - * ---> - * tm - * /--- - * /--- - * t1 <--- - * - * - * The goal is to adjust the slave's TSC such that tm falls exactly - * half-way between t0 and t1. If we achieve this, the clocks are - * synchronized provided the interconnect between the slave and the - * master is symmetric. Even if the interconnect were asymmetric, we - * would still know that the synchronization error is smaller than the - * roundtrip latency (t0 - t1). - * - * When the interconnect is quiet and symmetric, this lets us - * synchronize the TSC to within one or two cycles. However, we can - * only *guarantee* that the synchronization is accurate to within a - * round-trip time, which is typically in the range of several hundred - * cycles (e.g., ~500 cycles). In practice, this means that the TSCs - * are usually almost perfectly synchronized, but we shouldn't assume - * that the accuracy is much better than half a micro second or so. - * - * [there are other errors like the latency of RDTSC and of the - * WRMSR. These can also account to hundreds of cycles. So it's - * probably worse. It claims 153 cycles error on a dual Opteron, - * but I suspect the numbers are actually somewhat worse -AK] - */ - -#define MASTER 0 -#define SLAVE (SMP_CACHE_BYTES/8) - -/* Intentionally don't use cpu_relax() while TSC synchronization - because we don't want to go into funky power save modi or cause - hypervisors to schedule us away. Going to sleep would likely affect - latency and low latency is the primary objective here. -AK */ -#define no_cpu_relax() barrier() - -static __cpuinitdata DEFINE_SPINLOCK(tsc_sync_lock); -static volatile __cpuinitdata unsigned long go[SLAVE + 1]; -static int notscsync __cpuinitdata; - -#undef DEBUG_TSC_SYNC - -#define NUM_ROUNDS 64 /* magic value */ -#define NUM_ITERS 5 /* likewise */ - -/* Callback on boot CPU */ -static __cpuinit void sync_master(void *arg) -{ - unsigned long flags, i; - - if (smp_processor_id() != boot_cpu_id) - return; - - go[MASTER] = 0; - - local_irq_save(flags); - { - for (i = 0; i < NUM_ROUNDS*NUM_ITERS; ++i) { - while (!go[MASTER]) - no_cpu_relax(); - go[MASTER] = 0; - rdtscll(go[SLAVE]); - } - } - local_irq_restore(flags); -} - -/* - * Return the number of cycles by which our tsc differs from the tsc - * on the master (time-keeper) CPU. A positive number indicates our - * tsc is ahead of the master, negative that it is behind. - */ -static inline long -get_delta(long *rt, long *master) -{ - unsigned long best_t0 = 0, best_t1 = ~0UL, best_tm = 0; - unsigned long tcenter, t0, t1, tm; - int i; - - for (i = 0; i < NUM_ITERS; ++i) { - rdtscll(t0); - go[MASTER] = 1; - while (!(tm = go[SLAVE])) - no_cpu_relax(); - go[SLAVE] = 0; - rdtscll(t1); - - if (t1 - t0 < best_t1 - best_t0) - best_t0 = t0, best_t1 = t1, best_tm = tm; - } - - *rt = best_t1 - best_t0; - *master = best_tm - best_t0; - - /* average best_t0 and best_t1 without overflow: */ - tcenter = (best_t0/2 + best_t1/2); - if (best_t0 % 2 + best_t1 % 2 == 2) - ++tcenter; - return tcenter - best_tm; -} - -static __cpuinit void sync_tsc(void) -{ - int i, done = 0; - long delta, adj, adjust_latency = 0; - unsigned long flags, rt, master_time_stamp, bound; -#if DEBUG_TSC_SYNC - static struct syncdebug { - long rt; /* roundtrip time */ - long master; /* master's timestamp */ - long diff; /* difference between midpoint and master's timestamp */ - long lat; /* estimate of tsc adjustment latency */ - } t[NUM_ROUNDS] __cpuinitdata; -#endif - - go[MASTER] = 1; - - smp_call_function(sync_master, NULL, 1, 0); - - while (go[MASTER]) /* wait for master to be ready */ - no_cpu_relax(); - - spin_lock_irqsave(&tsc_sync_lock, flags); - { - for (i = 0; i < NUM_ROUNDS; ++i) { - delta = get_delta(&rt, &master_time_stamp); - if (delta == 0) { - done = 1; /* let's lock on to this... */ - bound = rt; - } - - if (!done) { - unsigned long t; - if (i > 0) { - adjust_latency += -delta; - adj = -delta + adjust_latency/4; - } else - adj = -delta; - - rdtscll(t); - wrmsrl(MSR_IA32_TSC, t + adj); - } -#if DEBUG_TSC_SYNC - t[i].rt = rt; - t[i].master = master_time_stamp; - t[i].diff = delta; - t[i].lat = adjust_latency/4; -#endif - } - } - spin_unlock_irqrestore(&tsc_sync_lock, flags); - -#if DEBUG_TSC_SYNC - for (i = 0; i < NUM_ROUNDS; ++i) - printk("rt=%5ld master=%5ld diff=%5ld adjlat=%5ld\n", - t[i].rt, t[i].master, t[i].diff, t[i].lat); -#endif - - printk(KERN_INFO - "CPU %d: synchronized TSC with CPU %u (last diff %ld cycles, " - "maxerr %lu cycles)\n", - smp_processor_id(), boot_cpu_id, delta, rt); -} - -static void __cpuinit tsc_sync_wait(void) -{ - if (notscsync || !cpu_has_tsc) - return; - printk(KERN_INFO "CPU %d: Syncing TSC to CPU %u.\n", smp_processor_id(), - boot_cpu_id); - sync_tsc(); -} - -static __init int notscsync_setup(char *s) -{ - notscsync = 1; - return 0; -} -__setup("notscsync", notscsync_setup); -#endif - -static atomic_t init_deasserted __cpuinitdata; - -/* - * Report back to the Boot Processor. - * Running on AP. - */ -void __cpuinit smp_callin(void) -{ - int cpuid, phys_id; - unsigned long timeout; - -#ifndef CONFIG_XEN - /* - * If waken up by an INIT in an 82489DX configuration - * we may get here before an INIT-deassert IPI reaches - * our local APIC. We have to wait for the IPI or we'll - * lock up on an APIC access. - */ - while (!atomic_read(&init_deasserted)) - cpu_relax(); - -#endif - /* - * (This works even if the APIC is not enabled.) - */ -#ifndef CONFIG_XEN - phys_id = GET_APIC_ID(apic_read(APIC_ID)); -#else - phys_id = smp_processor_id(); -#endif - cpuid = smp_processor_id(); - if (cpu_isset(cpuid, cpu_callin_map)) { - panic("smp_callin: phys CPU#%d, CPU#%d already present??\n", - phys_id, cpuid); - } - Dprintk("CPU#%d (phys ID: %d) waiting for CALLOUT\n", cpuid, phys_id); - - /* - * STARTUP IPIs are fragile beasts as they might sometimes - * trigger some glue motherboard logic. Complete APIC bus - * silence for 1 second, this overestimates the time the - * boot CPU is spending to send the up to 2 STARTUP IPIs - * by a factor of two. This should be enough. - */ - - /* - * Waiting 2s total for startup (udelay is not yet working) - */ - timeout = jiffies + 2*HZ; - while (time_before(jiffies, timeout)) { - /* - * Has the boot CPU finished it's STARTUP sequence? - */ - if (cpu_isset(cpuid, cpu_callout_map)) - break; - cpu_relax(); - } - - if (!time_before(jiffies, timeout)) { - panic("smp_callin: CPU%d started up but did not get a callout!\n", - cpuid); - } - -#ifndef CONFIG_XEN - /* - * the boot CPU has finished the init stage and is spinning - * on callin_map until we finish. We are free to set up this - * CPU, first the APIC. (this is probably redundant on most - * boards) - */ - - Dprintk("CALLIN, before setup_local_APIC().\n"); - setup_local_APIC(); -#endif - - /* - * Get our bogomips. - */ - calibrate_delay(); - Dprintk("Stack at about %p\n",&cpuid); - -#ifndef CONFIG_XEN - disable_APIC_timer(); -#endif - - /* - * Save our processor parameters - */ - smp_store_cpu_info(cpuid); - - /* - * Allow the master to continue. - */ - cpu_set(cpuid, cpu_callin_map); -} - -#ifdef CONFIG_XEN -extern void local_setup_timer(unsigned int cpu); -#endif - -/* - * Setup code on secondary processor (after comming out of the trampoline) - */ -void __cpuinit start_secondary(void) -{ - /* - * Dont put anything before smp_callin(), SMP - * booting is too fragile that we want to limit the - * things done here to the most necessary things. - */ - cpu_init(); - smp_callin(); - - /* otherwise gcc will move up the smp_processor_id before the cpu_init */ - barrier(); - -#ifndef CONFIG_XEN - Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); - setup_secondary_APIC_clock(); - - Dprintk("cpu %d: enabling apic timer\n", smp_processor_id()); - - if (nmi_watchdog == NMI_IO_APIC) { - disable_8259A_irq(0); - enable_NMI_through_LVT0(NULL); - enable_8259A_irq(0); - } - - enable_APIC_timer(); -#else - local_setup_timer(smp_processor_id()); - smp_intr_init(); - local_irq_enable(); -#endif - - /* - * Allow the master to continue. - */ - cpu_set(smp_processor_id(), cpu_online_map); - mb(); - -#ifndef CONFIG_XEN - /* Wait for TSC sync to not schedule things before. - We still process interrupts, which could see an inconsistent - time in that window unfortunately. */ - tsc_sync_wait(); -#endif - - cpu_idle(); -} - -extern volatile unsigned long init_rsp; -extern void (*initial_code)(void); - -#ifndef CONFIG_XEN -#if APIC_DEBUG -static void inquire_remote_apic(int apicid) -{ - unsigned i, regs[] = { APIC_ID >> 4, APIC_LVR >> 4, APIC_SPIV >> 4 }; - char *names[] = { "ID", "VERSION", "SPIV" }; - int timeout, status; - - printk(KERN_INFO "Inquiring remote APIC #%d...\n", apicid); - - for (i = 0; i < sizeof(regs) / sizeof(*regs); i++) { - printk("... APIC #%d %s: ", apicid, names[i]); - - /* - * Wait for idle. - */ - apic_wait_icr_idle(); - - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(apicid)); - apic_write_around(APIC_ICR, APIC_DM_REMRD | regs[i]); - - timeout = 0; - do { - udelay(100); - status = apic_read(APIC_ICR) & APIC_ICR_RR_MASK; - } while (status == APIC_ICR_RR_INPROG && timeout++ < 1000); - - switch (status) { - case APIC_ICR_RR_VALID: - status = apic_read(APIC_RRR); - printk("%08x\n", status); - break; - default: - printk("failed\n"); - } - } -} -#endif - -/* - * Kick the secondary to wake up. - */ -static int __cpuinit wakeup_secondary_via_INIT(int phys_apicid, unsigned int start_rip) -{ - unsigned long send_status = 0, accept_status = 0; - int maxlvt, timeout, num_starts, j; - - Dprintk("Asserting INIT.\n"); - - /* - * Turn INIT on target chip - */ - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); - - /* - * Send IPI - */ - apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_INT_ASSERT - | APIC_DM_INIT); - - Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); - - mdelay(10); - - Dprintk("Deasserting INIT.\n"); - - /* Target chip */ - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); - - /* Send IPI */ - apic_write_around(APIC_ICR, APIC_INT_LEVELTRIG | APIC_DM_INIT); - - Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); - - atomic_set(&init_deasserted, 1); - - /* - * Should we send STARTUP IPIs ? - * - * Determine this based on the APIC version. - * If we don't have an integrated APIC, don't send the STARTUP IPIs. - */ - if (APIC_INTEGRATED(apic_version[phys_apicid])) - num_starts = 2; - else - num_starts = 0; - - /* - * Run STARTUP IPI loop. - */ - Dprintk("#startup loops: %d.\n", num_starts); - - maxlvt = get_maxlvt(); - - for (j = 1; j <= num_starts; j++) { - Dprintk("Sending STARTUP #%d.\n",j); - apic_read_around(APIC_SPIV); - apic_write(APIC_ESR, 0); - apic_read(APIC_ESR); - Dprintk("After apic_write.\n"); - - /* - * STARTUP IPI - */ - - /* Target chip */ - apic_write_around(APIC_ICR2, SET_APIC_DEST_FIELD(phys_apicid)); - - /* Boot on the stack */ - /* Kick the second */ - apic_write_around(APIC_ICR, APIC_DM_STARTUP - | (start_rip >> 12)); - - /* - * Give the other CPU some time to accept the IPI. - */ - udelay(300); - - Dprintk("Startup point 1.\n"); - - Dprintk("Waiting for send to finish...\n"); - timeout = 0; - do { - Dprintk("+"); - udelay(100); - send_status = apic_read(APIC_ICR) & APIC_ICR_BUSY; - } while (send_status && (timeout++ < 1000)); - - /* - * Give the other CPU some time to accept the IPI. - */ - udelay(200); - /* - * Due to the Pentium erratum 3AP. - */ - if (maxlvt > 3) { - apic_read_around(APIC_SPIV); - apic_write(APIC_ESR, 0); - } - accept_status = (apic_read(APIC_ESR) & 0xEF); - if (send_status || accept_status) - break; - } - Dprintk("After Startup.\n"); - - if (send_status) - printk(KERN_ERR "APIC never delivered???\n"); - if (accept_status) - printk(KERN_ERR "APIC delivery error (%lx).\n", accept_status); - - return (send_status | accept_status); -} -#endif - -/* - * Boot one CPU. - */ -static int __cpuinit do_boot_cpu(int cpu, int apicid) -{ - struct task_struct *idle; - unsigned long boot_error; - int timeout; - unsigned long start_rip; -#ifdef CONFIG_XEN - vcpu_guest_context_t ctxt; - extern void startup_64_smp(void); - extern void hypervisor_callback(void); - extern void failsafe_callback(void); - extern void smp_trap_init(trap_info_t *); -#endif - /* - * We can't use kernel_thread since we must avoid to - * reschedule the child. - */ - idle = fork_idle(cpu); - if (IS_ERR(idle)) { - printk("failed fork for CPU %d\n", cpu); - return PTR_ERR(idle); - } - - cpu_pda[cpu].pcurrent = idle; - -#ifndef CONFIG_XEN - start_rip = setup_trampoline(); -#else - start_rip = (unsigned long)startup_64_smp; -#endif - - init_rsp = idle->thread.rsp; - per_cpu(init_tss,cpu).rsp0 = init_rsp; - initial_code = start_secondary; - clear_ti_thread_flag(idle->thread_info, TIF_FORK); - - printk(KERN_INFO "Booting processor %d/%d rip %lx rsp %lx\n", cpu, apicid, - start_rip, init_rsp); - - /* - * This grunge runs the startup process for - * the targeted processor. - */ - - atomic_set(&init_deasserted, 0); - -#ifdef CONFIG_XEN - cpu_gdt_descr[cpu].address = __get_free_page(GFP_KERNEL|__GFP_ZERO); - BUG_ON(cpu_gdt_descr[0].size > PAGE_SIZE); - cpu_gdt_descr[cpu].size = cpu_gdt_descr[0].size; - memcpy((void *)cpu_gdt_descr[cpu].address, - (void *)cpu_gdt_descr[0].address, cpu_gdt_descr[0].size); - - memset(&ctxt, 0, sizeof(ctxt)); - - ctxt.flags = VGCF_IN_KERNEL; - ctxt.user_regs.ds = __USER_DS; - ctxt.user_regs.es = __USER_DS; - ctxt.user_regs.fs = 0; - ctxt.user_regs.gs = 0; - ctxt.user_regs.ss = __KERNEL_DS|0x3; - ctxt.user_regs.cs = __KERNEL_CS|0x3; - ctxt.user_regs.rip = start_rip; - ctxt.user_regs.rsp = idle->thread.rsp; -#define X86_EFLAGS_IOPL_RING3 0x3000 - ctxt.user_regs.eflags = X86_EFLAGS_IF | X86_EFLAGS_IOPL_RING3; - - /* FPU is set up to default initial state. */ - memset(&ctxt.fpu_ctxt, 0, sizeof(ctxt.fpu_ctxt)); - - smp_trap_init(ctxt.trap_ctxt); - - /* No LDT. */ - ctxt.ldt_ents = 0; - - { - unsigned long va; - int f; - - for (va = cpu_gdt_descr[cpu].address, f = 0; - va < cpu_gdt_descr[cpu].address + cpu_gdt_descr[cpu].size; - va += PAGE_SIZE, f++) { - ctxt.gdt_frames[f] = virt_to_mfn(va); - make_page_readonly((void *)va); - } - ctxt.gdt_ents = GDT_ENTRIES; - } - - /* Ring 1 stack is the initial stack. */ - ctxt.kernel_ss = __KERNEL_DS; - ctxt.kernel_sp = idle->thread.rsp; - - /* Callback handlers. */ - ctxt.event_callback_eip = (unsigned long)hypervisor_callback; - ctxt.failsafe_callback_eip = (unsigned long)failsafe_callback; - ctxt.syscall_callback_eip = (unsigned long)system_call; - - ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT; - - boot_error = HYPERVISOR_vcpu_op(VCPUOP_initialise, cpu, &ctxt); - if (boot_error) - printk("boot error: %ld\n", boot_error); - - if (!boot_error) { - HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL); - - /* - * allow APs to start initializing. - */ - Dprintk("Before Callout %d.\n", cpu); - cpu_set(cpu, cpu_callout_map); - Dprintk("After Callout %d.\n", cpu); - - /* - * Wait 5s total for a response - */ - for (timeout = 0; timeout < 50000; timeout++) { - if (cpu_isset(cpu, cpu_callin_map)) - break; /* It has booted */ - udelay(100); - } - - if (cpu_isset(cpu, cpu_callin_map)) { - /* number CPUs logically, starting from 1 (BSP is 0) */ - Dprintk("CPU has booted.\n"); - } else { - boot_error= 1; - } - } - x86_cpu_to_apicid[cpu] = apicid; -#else - Dprintk("Setting warm reset code and vector.\n"); - - CMOS_WRITE(0xa, 0xf); - local_flush_tlb(); - Dprintk("1.\n"); - *((volatile unsigned short *) phys_to_virt(0x469)) = start_rip >> 4; - Dprintk("2.\n"); - *((volatile unsigned short *) phys_to_virt(0x467)) = start_rip & 0xf; - Dprintk("3.\n"); - - /* - * Be paranoid about clearing APIC errors. - */ - if (APIC_INTEGRATED(apic_version[apicid])) { - apic_read_around(APIC_SPIV); - apic_write(APIC_ESR, 0); - apic_read(APIC_ESR); - } - - /* - * Status is now clean - */ - boot_error = 0; - - /* - * Starting actual IPI sequence... - */ - boot_error = wakeup_secondary_via_INIT(apicid, start_rip); - - if (!boot_error) { - /* - * allow APs to start initializing. - */ - Dprintk("Before Callout %d.\n", cpu); - cpu_set(cpu, cpu_callout_map); - Dprintk("After Callout %d.\n", cpu); - - /* - * Wait 5s total for a response - */ - for (timeout = 0; timeout < 50000; timeout++) { - if (cpu_isset(cpu, cpu_callin_map)) - break; /* It has booted */ - udelay(100); - } - - if (cpu_isset(cpu, cpu_callin_map)) { - /* number CPUs logically, starting from 1 (BSP is 0) */ - Dprintk("CPU has booted.\n"); - } else { - boot_error = 1; - if (*((volatile unsigned char *)phys_to_virt(SMP_TRAMPOLINE_BASE)) - == 0xA5) - /* trampoline started but...? */ - printk("Stuck ??\n"); - else - /* trampoline code not run */ - printk("Not responding.\n"); -#if APIC_DEBUG - inquire_remote_apic(apicid); -#endif - } - } -#endif - if (boot_error) { - cpu_clear(cpu, cpu_callout_map); /* was set here (do_boot_cpu()) */ - clear_bit(cpu, &cpu_initialized); /* was set by cpu_init() */ - cpu_clear(cpu, cpu_present_map); - cpu_clear(cpu, cpu_possible_map); - x86_cpu_to_apicid[cpu] = BAD_APICID; - x86_cpu_to_log_apicid[cpu] = BAD_APICID; - return -EIO; - } - - return 0; -} - -cycles_t cacheflush_time; -unsigned long cache_decay_ticks; - -/* - * Construct cpu_sibling_map[], so that we can tell the sibling CPU - * on SMT systems efficiently. - */ -static __cpuinit void detect_siblings(void) -{ - int cpu; - - for (cpu = 0; cpu < NR_CPUS; cpu++) { - cpus_clear(cpu_sibling_map[cpu]); - cpus_clear(cpu_core_map[cpu]); - } - - for_each_online_cpu (cpu) { - struct cpuinfo_x86 *c = cpu_data + cpu; - int siblings = 0; - int i; - if (smp_num_siblings > 1) { - for_each_online_cpu (i) { - if (cpu_core_id[cpu] == cpu_core_id[i]) { - siblings++; - cpu_set(i, cpu_sibling_map[cpu]); - } - } - } else { - siblings++; - cpu_set(cpu, cpu_sibling_map[cpu]); - } - - if (siblings != smp_num_siblings) { - printk(KERN_WARNING - "WARNING: %d siblings found for CPU%d, should be %d\n", - siblings, cpu, smp_num_siblings); - smp_num_siblings = siblings; - } - if (c->x86_num_cores > 1) { - for_each_online_cpu(i) { - if (phys_proc_id[cpu] == phys_proc_id[i]) - cpu_set(i, cpu_core_map[cpu]); - } - } else - cpu_core_map[cpu] = cpu_sibling_map[cpu]; - } -} - -#ifndef CONFIG_XEN -/* - * Cleanup possible dangling ends... - */ -static __cpuinit void smp_cleanup_boot(void) -{ - /* - * Paranoid: Set warm reset code and vector here back - * to default values. - */ - CMOS_WRITE(0, 0xf); - - /* - * Reset trampoline flag - */ - *((volatile int *) phys_to_virt(0x467)) = 0; - -#ifndef CONFIG_HOTPLUG_CPU - /* - * Free pages reserved for SMP bootup. - * When you add hotplug CPU support later remove this - * Note there is more work to be done for later CPU bootup. - */ - - free_page((unsigned long) __va(PAGE_SIZE)); - free_page((unsigned long) __va(SMP_TRAMPOLINE_BASE)); -#endif -} -#endif - -/* - * Fall back to non SMP mode after errors. - * - * RED-PEN audit/test this more. I bet there is more state messed up here. - */ -static __cpuinit void disable_smp(void) -{ - cpu_present_map = cpumask_of_cpu(0); - cpu_possible_map = cpumask_of_cpu(0); -#ifndef CONFIG_XEN - if (smp_found_config) - phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id); - else - phys_cpu_present_map = physid_mask_of_physid(0); -#endif - cpu_set(0, cpu_sibling_map[0]); - cpu_set(0, cpu_core_map[0]); -} - -/* - * Handle user cpus=... parameter. - */ -static __cpuinit void enforce_max_cpus(unsigned max_cpus) -{ - int i, k; - k = 0; - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_possible(i)) - continue; - if (++k > max_cpus) { - cpu_clear(i, cpu_possible_map); - cpu_clear(i, cpu_present_map); - } - } -} - -/* - * Various sanity checks. - */ -static int __cpuinit smp_sanity_check(unsigned max_cpus) -{ -#ifndef CONFIG_XEN - if (!physid_isset(hard_smp_processor_id(), phys_cpu_present_map)) { - printk("weird, boot CPU (#%d) not listed by the BIOS.\n", - hard_smp_processor_id()); - physid_set(hard_smp_processor_id(), phys_cpu_present_map); - } - - /* - * If we couldn't find an SMP configuration at boot time, - * get out of here now! - */ - if (!smp_found_config) { - printk(KERN_NOTICE "SMP motherboard not detected.\n"); - disable_smp(); - if (APIC_init_uniprocessor()) - printk(KERN_NOTICE "Local APIC not detected." - " Using dummy APIC emulation.\n"); - return -1; - } - - /* - * Should not be necessary because the MP table should list the boot - * CPU too, but we do it for the sake of robustness anyway. - */ - if (!physid_isset(boot_cpu_id, phys_cpu_present_map)) { - printk(KERN_NOTICE "weird, boot CPU (#%d) not listed by the BIOS.\n", - boot_cpu_id); - physid_set(hard_smp_processor_id(), phys_cpu_present_map); - } - - /* - * If we couldn't find a local APIC, then get out of here now! - */ - if (APIC_INTEGRATED(apic_version[boot_cpu_id]) && !cpu_has_apic) { - printk(KERN_ERR "BIOS bug, local APIC #%d not detected!...\n", - boot_cpu_id); - printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); - nr_ioapics = 0; - return -1; - } -#endif - - /* - * If SMP should be disabled, then really disable it! - */ - if (!max_cpus) { -#ifdef CONFIG_XEN - xen_start_info->n_vcpu = 1; -#endif - printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); -#ifndef CONFIG_XEN - nr_ioapics = 0; -#endif - return -1; - } - - return 0; -} - -/* - * Prepare for SMP bootup. The MP table or ACPI has been read - * earlier. Just do some sanity checking here and enable APIC mode. - */ -void __cpuinit smp_prepare_cpus(unsigned int max_cpus) -{ - int i; - -#if defined(CONFIG_XEN) && !defined(CONFIG_XEN_PRIVILEGED_GUEST) -#else - nmi_watchdog_default(); -#endif - current_cpu_data = boot_cpu_data; - current_thread_info()->cpu = 0; /* needed? */ - - enforce_max_cpus(max_cpus); - - /* - * Fill in cpu_present_mask - */ - for (i = 0; i < NR_CPUS; i++) { -#ifndef CONFIG_XEN - int apicid = cpu_present_to_apicid(i); - if (physid_isset(apicid, phys_cpu_present_map)) { -#else - if (i < xen_start_info->n_vcpu) { -#endif - cpu_set(i, cpu_present_map); - /* possible map would be different if we supported real - CPU hotplug. */ - cpu_set(i, cpu_possible_map); - } - } - - if (smp_sanity_check(max_cpus) < 0) { - printk(KERN_INFO "SMP disabled\n"); - disable_smp(); - return; - } - -#ifdef CONFIG_XEN - smp_intr_init(); -#else - - /* - * Switch from PIC to APIC mode. - */ - connect_bsp_APIC(); - setup_local_APIC(); - - if (GET_APIC_ID(apic_read(APIC_ID)) != boot_cpu_id) { - panic("Boot APIC ID in local APIC unexpected (%d vs %d)", - GET_APIC_ID(apic_read(APIC_ID)), boot_cpu_id); - /* Or can we switch back to PIC here? */ - } -#endif - - /* - * Now start the IO-APICs - */ -#if defined(CONFIG_XEN) && !defined(CONFIG_XEN_PRIVILEGED_GUEST) -#else - if (!skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); - else - nr_ioapics = 0; -#endif - - /* - * Set up local APIC timer on boot CPU. - */ - -#ifndef CONFIG_XEN - setup_boot_APIC_clock(); -#endif -} - -/* - * Early setup to make printk work. - */ -void __init smp_prepare_boot_cpu(void) -{ - int me = smp_processor_id(); - cpu_set(me, cpu_online_map); - cpu_set(me, cpu_callout_map); -} - -/* - * Entry point to boot a CPU. - * - * This is all __cpuinit, not __devinit for now because we don't support - * CPU hotplug (yet). - */ -int __cpuinit __cpu_up(unsigned int cpu) -{ - int err; -#ifndef CONFIG_XEN - int apicid = cpu_present_to_apicid(cpu); -#else - int apicid = cpu; -#endif - - WARN_ON(irqs_disabled()); - - Dprintk("++++++++++++++++++++=_---CPU UP %u\n", cpu); - -#ifndef CONFIG_XEN - if (apicid == BAD_APICID || apicid == boot_cpu_id || - !physid_isset(apicid, phys_cpu_present_map)) { - printk("__cpu_up: bad cpu %d\n", cpu); - return -EINVAL; - } -#endif - - /* Boot it! */ - err = do_boot_cpu(cpu, apicid); - if (err < 0) { - Dprintk("do_boot_cpu failed %d\n", err); - return err; - } - - /* Unleash the CPU! */ - Dprintk("waiting for cpu %d\n", cpu); - - while (!cpu_isset(cpu, cpu_online_map)) - cpu_relax(); - return 0; -} - -/* - * Finish the SMP boot. - */ -void __cpuinit smp_cpus_done(unsigned int max_cpus) -{ -#ifndef CONFIG_XEN - zap_low_mappings(); - smp_cleanup_boot(); - -#ifdef CONFIG_X86_IO_APIC - setup_ioapic_dest(); -#endif -#endif - - detect_siblings(); -#ifndef CONFIG_XEN - time_init_gtod(); - - check_nmi_watchdog(); -#endif -} - -#ifdef CONFIG_XEN -extern irqreturn_t smp_reschedule_interrupt(int, void *, struct pt_regs *); -extern irqreturn_t smp_call_function_interrupt(int, void *, struct pt_regs *); - -static DEFINE_PER_CPU(int, resched_irq); -static DEFINE_PER_CPU(int, callfunc_irq); -static char resched_name[NR_CPUS][15]; -static char callfunc_name[NR_CPUS][15]; - -void smp_intr_init(void) -{ - int cpu = smp_processor_id(); - - per_cpu(resched_irq, cpu) = - bind_ipi_to_irq(RESCHEDULE_VECTOR, cpu); - sprintf(resched_name[cpu], "resched%d", cpu); - BUG_ON(request_irq(per_cpu(resched_irq, cpu), smp_reschedule_interrupt, - SA_INTERRUPT, resched_name[cpu], NULL)); - - per_cpu(callfunc_irq, cpu) = - bind_ipi_to_irq(CALL_FUNCTION_VECTOR, cpu); - sprintf(callfunc_name[cpu], "callfunc%d", cpu); - BUG_ON(request_irq(per_cpu(callfunc_irq, cpu), - smp_call_function_interrupt, - SA_INTERRUPT, callfunc_name[cpu], NULL)); -} - -static void smp_intr_exit(void) -{ - int cpu = smp_processor_id(); - - free_irq(per_cpu(resched_irq, cpu), NULL); - unbind_ipi_from_irq(RESCHEDULE_VECTOR, cpu); - - free_irq(per_cpu(callfunc_irq, cpu), NULL); - unbind_ipi_from_irq(CALL_FUNCTION_VECTOR, cpu); -} - -void vcpu_prepare(int vcpu) -{ -} - -#endif diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c index 442cc247e9..2dd31427c6 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c @@ -113,14 +113,11 @@ EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(cpu_pda); #ifdef CONFIG_SMP -EXPORT_SYMBOL(cpu_data); -EXPORT_SYMBOL(cpu_online_map); EXPORT_SYMBOL(__write_lock_failed); EXPORT_SYMBOL(__read_lock_failed); EXPORT_SYMBOL(synchronize_irq); EXPORT_SYMBOL(smp_call_function); -EXPORT_SYMBOL(cpu_callout_map); #endif #ifdef CONFIG_VT diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h deleted file mode 100644 index fa85aa2cfe..0000000000 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/mach-xen/smpboot_hooks.h +++ /dev/null @@ -1,55 +0,0 @@ -/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws - * which needs to alter them. */ - -static inline void smpboot_clear_io_apic_irqs(void) -{ -#ifdef CONFIG_X86_IO_APIC - io_apic_irqs = 0; -#endif -} - -static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) -{ -#if 1 - printk("smpboot_setup_warm_reset_vector\n"); -#else - CMOS_WRITE(0xa, 0xf); - local_flush_tlb(); - Dprintk("1.\n"); - *((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4; - Dprintk("2.\n"); - *((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf; - Dprintk("3.\n"); -#endif -} - -static inline void smpboot_restore_warm_reset_vector(void) -{ - /* - * Install writable page 0 entry to set BIOS data area. - */ - local_flush_tlb(); - - /* - * Paranoid: Set warm reset code and vector here back - * to default values. - */ - CMOS_WRITE(0, 0xf); - - *((volatile long *) phys_to_virt(0x467)) = 0; -} - -static inline void smpboot_setup_io_apic(void) -{ -#ifdef CONFIG_X86_IO_APIC - /* - * Here we can be sure that there is an IO-APIC in the system. Let's - * go and set it up: - */ - if (!skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); -#endif -} - - -#define smp_found_config (xen_start_info->n_vcpu > 1) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h new file mode 100644 index 0000000000..427f6c8a38 --- /dev/null +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h @@ -0,0 +1,92 @@ +#ifndef __ASM_SMP_H +#define __ASM_SMP_H + +/* + * We need the APIC definitions automatically as part of 'smp.h' + */ +#ifndef __ASSEMBLY__ +#include +#include +#include +#include +#endif + +#ifdef CONFIG_X86_LOCAL_APIC +#ifndef __ASSEMBLY__ +#include +#include +#include +#ifdef CONFIG_X86_IO_APIC +#include +#endif +#include +#endif +#endif + +#define BAD_APICID 0xFFu +#ifdef CONFIG_SMP +#ifndef __ASSEMBLY__ + +/* + * Private routines/data + */ + +extern void smp_alloc_memory(void); +extern int pic_mode; +extern int smp_num_siblings; +extern cpumask_t cpu_sibling_map[]; +extern cpumask_t cpu_core_map[]; + +extern void smp_flush_tlb(void); +extern void smp_message_irq(int cpl, void *dev_id, struct pt_regs *regs); +extern void smp_invalidate_rcv(void); /* Process an NMI */ +extern void (*mtrr_hook) (void); +extern void zap_low_mappings (void); + +#define MAX_APICID 256 +extern u8 x86_cpu_to_apicid[]; + +/* + * This function is needed by all SMP systems. It must _always_ be valid + * from the initial startup. We map APIC_BASE very early in page_setup(), + * so this is correct in the x86 case. + */ +#define __smp_processor_id() (current_thread_info()->cpu) + +extern cpumask_t cpu_possible_map; + +/* We don't mark CPUs online until __cpu_up(), so we need another measure */ +static inline int num_booting_cpus(void) +{ + return cpus_weight(cpu_possible_map); +} + +#ifdef CONFIG_X86_LOCAL_APIC + +#ifdef APIC_DEFINITION +extern int hard_smp_processor_id(void); +#else +#include +static inline int hard_smp_processor_id(void) +{ + /* we don't want to mark this access volatile - bad code generation */ + return GET_APIC_ID(*(unsigned long *)(APIC_BASE+APIC_ID)); +} +#endif + +static __inline int logical_smp_processor_id(void) +{ + /* we don't want to mark this access volatile - bad code generation */ + return GET_APIC_LOGICAL_ID(*(unsigned long *)(APIC_BASE+APIC_LDR)); +} + +#endif + +extern int __cpu_disable(void); +extern void __cpu_die(unsigned int cpu); +#endif /* !__ASSEMBLY__ */ + +#define NO_PROC_ID 0xFF /* No processor magic marker */ + +#endif +#endif diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h deleted file mode 100644 index fa85aa2cfe..0000000000 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/mach-xen/smpboot_hooks.h +++ /dev/null @@ -1,55 +0,0 @@ -/* two abstractions specific to kernel/smpboot.c, mainly to cater to visws - * which needs to alter them. */ - -static inline void smpboot_clear_io_apic_irqs(void) -{ -#ifdef CONFIG_X86_IO_APIC - io_apic_irqs = 0; -#endif -} - -static inline void smpboot_setup_warm_reset_vector(unsigned long start_eip) -{ -#if 1 - printk("smpboot_setup_warm_reset_vector\n"); -#else - CMOS_WRITE(0xa, 0xf); - local_flush_tlb(); - Dprintk("1.\n"); - *((volatile unsigned short *) TRAMPOLINE_HIGH) = start_eip >> 4; - Dprintk("2.\n"); - *((volatile unsigned short *) TRAMPOLINE_LOW) = start_eip & 0xf; - Dprintk("3.\n"); -#endif -} - -static inline void smpboot_restore_warm_reset_vector(void) -{ - /* - * Install writable page 0 entry to set BIOS data area. - */ - local_flush_tlb(); - - /* - * Paranoid: Set warm reset code and vector here back - * to default values. - */ - CMOS_WRITE(0, 0xf); - - *((volatile long *) phys_to_virt(0x467)) = 0; -} - -static inline void smpboot_setup_io_apic(void) -{ -#ifdef CONFIG_X86_IO_APIC - /* - * Here we can be sure that there is an IO-APIC in the system. Let's - * go and set it up: - */ - if (!skip_ioapic_setup && nr_ioapics) - setup_IO_APIC(); -#endif -} - - -#define smp_found_config (xen_start_info->n_vcpu > 1) diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/smp.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/smp.h index fd0e5ea9a2..303af66824 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/smp.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/smp.h @@ -34,7 +34,6 @@ struct pt_regs; extern cpumask_t cpu_present_mask; extern cpumask_t cpu_possible_map; extern cpumask_t cpu_online_map; -extern cpumask_t cpu_callout_map; /* * Private routines/data @@ -52,8 +51,8 @@ extern void zap_low_mappings(void); void smp_stop_cpu(void); extern cpumask_t cpu_sibling_map[NR_CPUS]; extern cpumask_t cpu_core_map[NR_CPUS]; -extern u8 phys_proc_id[NR_CPUS]; -extern u8 cpu_core_id[NR_CPUS]; +extern int phys_proc_id[NR_CPUS]; +extern int cpu_core_id[NR_CPUS]; #define SMP_TRAMPOLINE_BASE 0x6000 @@ -65,7 +64,7 @@ extern u8 cpu_core_id[NR_CPUS]; static inline int num_booting_cpus(void) { - return cpus_weight(cpu_callout_map); + return cpus_weight(cpu_possible_map); } #define __smp_processor_id() read_pda(cpunumber) From 1e6d1e90a21c30eb1f4700cd025f3f75152ac228 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Tue, 18 Oct 2005 17:45:50 +0100 Subject: [PATCH 081/142] Fix call to getVCpuCount for dom0. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomain.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 802c53f689..3046c7eece 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -141,7 +141,7 @@ class XendDomain: # target == 0 means use all processors if target > 0: - self.setVCpuCount(target) + dom0.setVCpuCount(target) def _add_domain(self, info): From ac6e05c769aefa86f38f37e708396d0e3f87f0dc Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Tue, 18 Oct 2005 18:01:14 +0100 Subject: [PATCH 082/142] Added uuid unit test. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/tests/test_uuid.py | 30 ++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tools/python/xen/xend/tests/test_uuid.py diff --git a/tools/python/xen/xend/tests/test_uuid.py b/tools/python/xen/xend/tests/test_uuid.py new file mode 100644 index 0000000000..cc78bd020c --- /dev/null +++ b/tools/python/xen/xend/tests/test_uuid.py @@ -0,0 +1,30 @@ +import unittest + +from xen.xend import uuid + + +class test_uuid(unittest.TestCase): + + def testStringRoundtrip(self): + def t(inp): + self.assertEqual(uuid.fromString(uuid.toString(inp)), inp) + + t(uuid.create()) + t(uuid.create()) + t(uuid.create()) + t(uuid.create()) + t(uuid.create()) + + + def testToFromString(self): + def t(inp, expected): + self.assertEqual(uuid.toString(inp), expected) + self.assertEqual(uuid.fromString(expected), inp) + + t([0 for i in range(0, 16)], "00000000-0000-0000-0000-000000000000") + t([185, 158, 125, 206, 250, 178, 125, 57, 2, 6, 162, 74, 178, 236, + 196, 5], "b99e7dce-fab2-7d39-0206-a24ab2ecc405") + + +def test_suite(): + return unittest.makeSuite(test_uuid) From a1190ad2e6a7b426fcbe8f7ea3f279ce3525ea78 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Tue, 18 Oct 2005 18:07:11 +0100 Subject: [PATCH 083/142] Protect __del__ from failure inside __init__ by setting inTransaction before trying to create a transaction instance. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/xenstore/xstransact.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/python/xen/xend/xenstore/xstransact.py b/tools/python/xen/xend/xenstore/xstransact.py index d33b209e8e..ac8269f2ba 100644 --- a/tools/python/xen/xend/xenstore/xstransact.py +++ b/tools/python/xen/xend/xenstore/xstransact.py @@ -14,6 +14,9 @@ from xen.xend.xenstore.xsutil import xshandle class xstransact: def __init__(self, path): + self.in_transaction = False # Set this temporarily -- if this + # constructor fails, then we need to + # protect __del__. self.path = path.rstrip("/") self.transaction = xshandle().transaction_start() self.in_transaction = True From e85a40dd36921a17aa7658e162738cb5cad25453 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 19:02:14 +0100 Subject: [PATCH 084/142] Remove 'n_vcpu' field from start_info structure. Domain0 simply creates a CPU on every physical CPU. Other domains read the initial VCPU configuration from xenstore. Signed-off-by: Keir Fraser --- .../arch/xen/kernel/smpboot.c | 73 +++++++++++++------ tools/libxc/xc_linux_build.c | 7 +- tools/libxc/xenguest.h | 1 - tools/python/xen/lowlevel/xc/xc.c | 12 ++- tools/python/xen/xend/image.py | 3 +- xen/arch/x86/domain_build.c | 1 - xen/include/public/xen.h | 1 - 7 files changed, 56 insertions(+), 42 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c index a2e6cab984..4b84de07cc 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c @@ -186,20 +186,20 @@ void vcpu_prepare(int vcpu) void __init smp_prepare_cpus(unsigned int max_cpus) { - int cpu; + int cpu, rc; struct task_struct *idle; - if (max_cpus == 0) { - xen_start_info->n_vcpu = 1; + if (max_cpus == 0) return; - } - - if (max_cpus < xen_start_info->n_vcpu) - xen_start_info->n_vcpu = max_cpus; xen_smp_intr_init(0); - for (cpu = 1; cpu < xen_start_info->n_vcpu; cpu++) { + for (cpu = 1; cpu < max_cpus; cpu++) { + rc = HYPERVISOR_vcpu_op(VCPUOP_is_up, cpu, NULL); + if (rc == -ENOENT) + break; + BUG_ON(rc != 0); + cpu_data[cpu] = boot_cpu_data; cpu_2_logical_apicid[cpu] = cpu; x86_cpu_to_apicid[cpu] = cpu; @@ -220,6 +220,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus) make_page_readonly((void *)cpu_gdt_descr[cpu].address); cpu_set(cpu, cpu_possible_map); + if (xen_start_info->flags & SIF_INITDOMAIN) + cpu_set(cpu, cpu_present_map); vcpu_prepare(cpu); } @@ -243,6 +245,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) void __devinit smp_prepare_boot_cpu(void) { cpu_possible_map = cpumask_of_cpu(0); + cpu_present_map = cpumask_of_cpu(0); cpu_online_map = cpumask_of_cpu(0); cpu_data[0] = boot_cpu_data; @@ -257,21 +260,14 @@ void __devinit smp_prepare_boot_cpu(void) cpu_set(0, cpu_core_map[0]); } -#ifdef CONFIG_HOTPLUG_CPU - -static void handle_vcpu_hotplug_event( - struct xenbus_watch *watch, const char **vec, unsigned int len) +static void vcpu_hotplug(unsigned int cpu) { - int err, cpu; + int err; char dir[32], state[32]; - char *cpustr; - const char *node = vec[XS_WATCH_PATH]; - if ((cpustr = strstr(node, "cpu/")) == NULL) + if ((cpu >= NR_CPUS) || !cpu_possible(cpu)) return; - sscanf(cpustr, "cpu/%d", &cpu); - sprintf(dir, "cpu/%d", cpu); err = xenbus_scanf(NULL, dir, "availability", "%s", state); if (err != 1) { @@ -279,22 +275,49 @@ static void handle_vcpu_hotplug_event( return; } - if (strcmp(state, "online") == 0) + if (strcmp(state, "online") == 0) { + cpu_set(cpu, cpu_present_map); (void)cpu_up(cpu); - else if (strcmp(state, "offline") == 0) + } else if (strcmp(state, "offline") == 0) { +#ifdef CONFIG_HOTPLUG_CPU (void)cpu_down(cpu); - else - printk(KERN_ERR "XENBUS: unknown state(%s) on node(%s)\n", - state, node); +#else + printk(KERN_INFO "Ignoring CPU%d hotplug request\n", cpu); +#endif + } else { + printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n", + state, cpu); + } +} + +static void handle_vcpu_hotplug_event( + struct xenbus_watch *watch, const char **vec, unsigned int len) +{ + int cpu; + char *cpustr; + const char *node = vec[XS_WATCH_PATH]; + + if ((cpustr = strstr(node, "cpu/")) != NULL) { + sscanf(cpustr, "cpu/%d", &cpu); + vcpu_hotplug(cpu); + } } static int setup_cpu_watcher(struct notifier_block *notifier, unsigned long event, void *data) { + int i; + static struct xenbus_watch cpu_watch = { .node = "cpu", .callback = handle_vcpu_hotplug_event }; (void)register_xenbus_watch(&cpu_watch); + + for_each_cpu(i) + vcpu_hotplug(i); + + printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus()); + return NOTIFY_DONE; } @@ -308,6 +331,8 @@ static int __init setup_vcpu_hotplug_event(void) subsys_initcall(setup_vcpu_hotplug_event); +#ifdef CONFIG_HOTPLUG_CPU + int __cpu_disable(void) { cpumask_t map = cpu_online_map; @@ -338,7 +363,7 @@ void __cpu_die(unsigned int cpu) #endif } -#else /* ... !CONFIG_HOTPLUG_CPU */ +#else /* !CONFIG_HOTPLUG_CPU */ int __cpu_disable(void) { diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index 1185fc020e..7a3a8737d9 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -289,7 +289,6 @@ static int setup_guest(int xc_handle, const char *cmdline, unsigned long shared_info_frame, unsigned long flags, - unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn) { @@ -376,7 +375,6 @@ static int setup_guest(int xc_handle, const char *cmdline, unsigned long shared_info_frame, unsigned long flags, - unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, unsigned long *console_mfn) { @@ -636,7 +634,6 @@ static int setup_guest(int xc_handle, start_info->store_evtchn = store_evtchn; start_info->console_mfn = *console_mfn; start_info->console_evtchn = console_evtchn; - start_info->n_vcpu = vcpus; if ( initrd_len != 0 ) { start_info->mod_start = vinitrd_start; @@ -682,7 +679,6 @@ int xc_linux_build(int xc_handle, const char *ramdisk_name, const char *cmdline, unsigned long flags, - unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, @@ -756,8 +752,7 @@ int xc_linux_build(int xc_handle, &vstartinfo_start, &vkern_entry, &vstack_start, ctxt, cmdline, op.u.getdomaininfo.shared_info_frame, - flags, vcpus, - store_evtchn, store_mfn, + flags, store_evtchn, store_mfn, console_evtchn, console_mfn) < 0 ) { ERROR("Error constructing guest OS"); diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h index 1a71ec9d6e..b4003d026a 100644 --- a/tools/libxc/xenguest.h +++ b/tools/libxc/xenguest.h @@ -46,7 +46,6 @@ int xc_linux_build(int xc_handle, const char *ramdisk_name, const char *cmdline, unsigned long flags, - unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn, unsigned int console_evtchn, diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index f28e5ac157..17027cdc2a 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -382,7 +382,7 @@ static PyObject *pyxc_linux_build(PyObject *self, uint32_t dom; char *image, *ramdisk = NULL, *cmdline = ""; - int flags = 0, vcpus = 1; + int flags = 0; int store_evtchn, console_evtchn; unsigned long store_mfn = 0; unsigned long console_mfn = 0; @@ -390,19 +390,17 @@ static PyObject *pyxc_linux_build(PyObject *self, static char *kwd_list[] = { "dom", "store_evtchn", "console_evtchn", "image", /* optional */ - "ramdisk", "cmdline", "flags", - "vcpus", NULL }; + "ramdisk", "cmdline", "flags", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssii", kwd_list, + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiis|ssi", kwd_list, &dom, &store_evtchn, &console_evtchn, &image, /* optional */ - &ramdisk, &cmdline, &flags, - &vcpus) ) + &ramdisk, &cmdline, &flags) ) return NULL; if ( xc_linux_build(xc->xc_handle, dom, image, - ramdisk, cmdline, flags, vcpus, + ramdisk, cmdline, flags, store_evtchn, &store_mfn, console_evtchn, &console_mfn) != 0 ) return PyErr_SetFromErrno(xc_error); diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 23cc89cfbc..5453b1089a 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -185,8 +185,7 @@ class LinuxImageHandler(ImageHandler): store_evtchn = store_evtchn, console_evtchn = console_evtchn, cmdline = self.cmdline, - ramdisk = self.ramdisk, - vcpus = self.vm.getVCpuCount()) + ramdisk = self.ramdisk) if isinstance(ret, dict): self.set_vminfo(ret) return 0 diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 38a3cb2c99..c702872206 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -588,7 +588,6 @@ int construct_dom0(struct domain *d, si = (start_info_t *)vstartinfo_start; memset(si, 0, PAGE_SIZE); si->nr_pages = nr_pages; - si->n_vcpu = num_online_cpus(); if ( opt_dom0_translate ) { diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index c88113ab6c..d21a41205d 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -423,7 +423,6 @@ typedef struct start_info { unsigned long mfn_list; /* VIRTUAL address of page-frame list. */ unsigned long mod_start; /* VIRTUAL address of pre-loaded module. */ unsigned long mod_len; /* Size (bytes) of pre-loaded module. */ - uint32_t n_vcpu; int8_t cmd_line[MAX_GUEST_CMDLINE]; } start_info_t; From 1a7490299e65d1471063a3a6651ac9faae9b7a76 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 19:07:03 +0100 Subject: [PATCH 085/142] Domain0 doesn't do initial VCPU hotplug via xenstore. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c index 4b84de07cc..20f96c0da3 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c @@ -313,10 +313,12 @@ static int setup_cpu_watcher(struct notifier_block *notifier, .callback = handle_vcpu_hotplug_event }; (void)register_xenbus_watch(&cpu_watch); - for_each_cpu(i) - vcpu_hotplug(i); - - printk(KERN_INFO "Brought up %ld CPUs\n", (long)num_online_cpus()); + if (!(xen_start_info->flags & SIF_INITDOMAIN)) { + for_each_cpu(i) + vcpu_hotplug(i); + printk(KERN_INFO "Brought up %ld CPUs\n", + (long)num_online_cpus()); + } return NOTIFY_DONE; } From 5e91bc5c8ac6ddb6ff36efe9ab84bcf9047cea5a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 18 Oct 2005 19:28:16 +0100 Subject: [PATCH 086/142] Fix -xen builds. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c | 4 ++-- linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c index 20f96c0da3..a0ec7cff1f 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c @@ -74,10 +74,10 @@ cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; EXPORT_SYMBOL(cpu_core_map); -#ifdef __i386__ +#if defined(__i386__) u8 x86_cpu_to_apicid[NR_CPUS] = { [0 ... NR_CPUS-1] = 0xff }; EXPORT_SYMBOL(x86_cpu_to_apicid); -#else +#elif !defined(CONFIG_X86_IO_APIC) unsigned int maxcpus = NR_CPUS; #endif diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h index 427f6c8a38..cf404f492b 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/smp.h @@ -54,6 +54,7 @@ extern u8 x86_cpu_to_apicid[]; #define __smp_processor_id() (current_thread_info()->cpu) extern cpumask_t cpu_possible_map; +#define cpu_callin_map cpu_possible_map /* We don't mark CPUs online until __cpu_up(), so we need another measure */ static inline int num_booting_cpus(void) From 4bdaa2c588c680afaa862f27afa30fa15a377b2d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 19 Oct 2005 07:43:03 +0100 Subject: [PATCH 087/142] Rename 2.6.12.5 patch so it actually gets applied. Fail the build if 'patch' is missing. Signed-off-by: Keir Fraser --- buildconfigs/Rules.mk | 1 + patches/linux-2.6.12/{patch-2.6.12.5 => 2.6.12.5.patch} | 0 2 files changed, 1 insertion(+) rename patches/linux-2.6.12/{patch-2.6.12.5 => 2.6.12.5.patch} (100%) diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk index 19887c5117..2970945810 100644 --- a/buildconfigs/Rules.mk +++ b/buildconfigs/Rules.mk @@ -82,6 +82,7 @@ clean:: ref-%/.valid-ref: pristine-%/.valid-pristine rm -rf $(@D) cp -al $( Date: Wed, 19 Oct 2005 11:47:51 +0100 Subject: [PATCH 088/142] Take advantage of the new UUID (handle) stored for us in Xen to improve the recreation semantics. Remove the unpause at the end of xc_linux_restore, and move it to XendDomainInfo. This is necessary because xenstored now allocates the domain path when the domain is introduced, which means that the new domain cannot start running until that introduce is performed and the new devices configured. Give restore a separate completion phase in which domain details are stored. This is required because the domain path is no longer available until after the introduceDomain call. TODO: Split the domain introduction into two so that the domain path is available earlier. At the moment, the domain <-> store channel details are passed in to xenstored when the domain is introduced, but in the case of restore it is necessary to wait until the restore is completed before the channel MFN is available. Change the interface between XendDomainInfo and XendCheckpoint/image to not have hideous callbacks through setConsoleRef and setStoreRef. Instead, image.createImage explicitly returns those values, and XendCheckpoint passes them through to completeRestore. Move the purging of the domain path corresponding to a new domain from Xend to xenstored, since xenstored is now in charge of this path. With the domain path creation moved to xenstored, Xend cannot remove the path, because watches may have fired on it already. Fix the printf statement in xenstored in verbose mode that details the messages being written. This statement was printing the buffer using %s, but this buffer has an explicit length field, so we were seeing garbage after the correct details. Signed-off-by: Ewan Mellor --- tools/libxc/xc_linux_restore.c | 10 -- tools/python/xen/xend/XendCheckpoint.py | 57 +++---- tools/python/xen/xend/XendDomain.py | 4 +- tools/python/xen/xend/XendDomainInfo.py | 188 ++++++++++++------------ tools/python/xen/xend/image.py | 76 ++++------ tools/xenstore/xenstored_core.c | 55 ++++--- tools/xenstore/xenstored_core.h | 4 + tools/xenstore/xenstored_domain.c | 2 + 8 files changed, 202 insertions(+), 194 deletions(-) diff --git a/tools/libxc/xc_linux_restore.c b/tools/libxc/xc_linux_restore.c index 2e27db651d..e4eb81b0d6 100644 --- a/tools/libxc/xc_linux_restore.c +++ b/tools/libxc/xc_linux_restore.c @@ -642,16 +642,6 @@ int xc_linux_restore(int xc_handle, int io_fd, uint32_t dom, unsigned long nr_pf goto out; } - DPRINTF("Domain ready to be unpaused\n"); - op.cmd = DOM0_UNPAUSEDOMAIN; - op.u.unpausedomain.domain = (domid_t)dom; - rc = xc_dom0_op(xc_handle, &op); - if (rc == 0) { - /* Success: print the domain id. */ - DPRINTF("DOM=%u\n", dom); - return 0; - } - out: if ( (rc != 0) && (dom != 0) ) xc_domain_destroy(xc_handle, dom); diff --git a/tools/python/xen/xend/XendCheckpoint.py b/tools/python/xen/xend/XendCheckpoint.py index 25c496add0..828fd0f2eb 100644 --- a/tools/python/xen/xend/XendCheckpoint.py +++ b/tools/python/xen/xend/XendCheckpoint.py @@ -118,9 +118,11 @@ def restore(xd, fd): dominfo = xd.restore_(vmconfig) - assert dominfo.store_channel - assert dominfo.console_channel - assert dominfo.getDomainPath() + store_port = dominfo.getStorePort() + console_port = dominfo.getConsolePort() + + assert store_port + assert console_port try: l = read_exact(fd, sizeof_unsigned_long, @@ -130,32 +132,19 @@ def restore(xd, fd): raise XendError( "not a valid guest state file: pfn count out of range") - store_evtchn = dominfo.store_channel - console_evtchn = dominfo.console_channel - - cmd = [xen.util.auxbin.pathTo(XC_RESTORE), str(xc.handle()), str(fd), - str(dominfo.getDomid()), str(nr_pfns), - str(store_evtchn), str(console_evtchn)] + cmd = map(str, [xen.util.auxbin.pathTo(XC_RESTORE), + xc.handle(), fd, dominfo.getDomid(), nr_pfns, + store_port, console_port]) log.debug("[xc_restore]: %s", string.join(cmd)) - def restoreInputHandler(line, _): - m = re.match(r"^(store-mfn) (\d+)$", line) - if m: - store_mfn = int(m.group(2)) - dominfo.setStoreRef(store_mfn) - log.debug("IntroduceDomain %d %d %d", - dominfo.getDomid(), - store_mfn, - dominfo.store_channel) - IntroduceDomain(dominfo.getDomid(), - store_mfn, - dominfo.store_channel) - else: - m = re.match(r"^(console-mfn) (\d+)$", line) - if m: - dominfo.setConsoleRef(int(m.group(2))) + handler = RestoreInputHandler() - forkHelper(cmd, fd, restoreInputHandler, True) + forkHelper(cmd, fd, handler.handler, True) + + if handler.store_mfn is None or handler.console_mfn is None: + raise XendError('Could not read store/console MFN') + + dominfo.completeRestore(handler.store_mfn, handler.console_mfn) return dominfo except: @@ -163,6 +152,22 @@ def restore(xd, fd): raise +class RestoreInputHandler: + def __init__(self): + self.store_mfn = None + self.console_mfn = None + + + def handler(self, line, _): + m = re.match(r"^(store-mfn) (\d+)$", line) + if m: + self.store_mfn = int(m.group(2)) + else: + m = re.match(r"^(console-mfn) (\d+)$", line) + if m: + self.console_mfn = int(m.group(2)) + + def forkHelper(cmd, fd, inputHandler, closeToChild): child = xPopen3(cmd, True, -1, [fd, xc.handle()]) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 3046c7eece..235e39f633 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -347,7 +347,7 @@ class XendDomain: dominfo = self.domain_lookup(domid) log.info("Domain %s (%d) unpaused.", dominfo.getName(), dominfo.getDomid()) - return xc.domain_unpause(dom=dominfo.getDomid()) + return dominfo.unpause() except Exception, ex: raise XendError(str(ex)) @@ -358,7 +358,7 @@ class XendDomain: dominfo = self.domain_lookup(domid) log.info("Domain %s (%d) paused.", dominfo.getName(), dominfo.getDomid()) - return xc.domain_pause(dom=dominfo.getDomid()) + return dominfo.pause() except Exception, ex: raise XendError(str(ex)) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 614ae07f87..59bd0f24a6 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -145,8 +145,6 @@ def create(config): try: vm.construct() vm.initDomain() - vm.construct_image() - vm.configure() vm.storeVmDetails() vm.storeDomDetails() vm.refreshShutdown() @@ -167,6 +165,7 @@ def recreate(xeninfo, priv): assert not xeninfo['dying'] domid = xeninfo['dom'] + uuid1 = xeninfo['handle'] dompath = GetDomainPath(domid) if not dompath: raise XendError( @@ -176,44 +175,34 @@ def recreate(xeninfo, priv): if not vmpath: raise XendError( 'No vm path in store for existing domain %d' % domid) - uuid1_str = xstransact.Read(vmpath, "uuid") - if not uuid1_str: + uuid2_str = xstransact.Read(vmpath, "uuid") + if not uuid2_str: raise XendError( 'No vm/uuid path in store for existing domain %d' % domid) - uuid1 = uuid.fromString(uuid1_str) - - uuid2 = xeninfo['handle'] + uuid2 = uuid.fromString(uuid2_str) if uuid1 != uuid2: raise XendError( 'Uuid in store does not match uuid for existing domain %d: ' - '%s != %s' % (domid, uuid1_str, uuid.toString(uuid2))) + '%s != %s' % (domid, uuid2_str, uuid.toString(uuid1))) - log.info("Recreating domain %d, UUID %s.", domid, uuid1_str) + log.info("Recreating domain %d, UUID %s.", domid, uuid2_str) - vm = XendDomainInfo(uuid2, xeninfo, domid, dompath, True) + vm = XendDomainInfo(uuid1, xeninfo, domid, dompath, True) except Exception, exn: log.warn(str(exn)) - if priv: - new_uuid = [0 for i in range(0, 16)] - else: - new_uuid = uuid.create() + log.info("Recreating domain %d with UUID %s.", domid, + uuid.toString(uuid1)) - log.info("Recreating domain %d with new UUID %s.", domid, - uuid.toString(new_uuid)) - - vm = XendDomainInfo(new_uuid, xeninfo, domid, dompath, True) + vm = XendDomainInfo(uuid1, xeninfo, domid, dompath, True) vm.removeDom() + vm.removeVm() vm.storeVmDetails() vm.storeDomDetails() - if domid != 0: - # Setup store and console channels - vm.create_channels() - vm.refreshShutdown(xeninfo) return vm @@ -230,11 +219,8 @@ def restore(config): parseConfig(config)) try: vm.construct() - vm.configure() - vm.create_channels() vm.storeVmDetails() - vm.storeDomDetails() - vm.refreshShutdown() + vm.createChannels() return vm except: vm.destroy() @@ -379,9 +365,9 @@ class XendDomainInfo: self.image = None - self.store_channel = None + self.store_port = None self.store_mfn = None - self.console_channel = None + self.console_port = None self.console_mfn = None self.state = STATE_DOM_OK @@ -571,6 +557,18 @@ class XendDomainInfo: ## public: + def completeRestore(self, store_mfn, console_mfn): + + self.store_mfn = store_mfn + self.console_mfn = console_mfn + + self.introduceDomain() + self.create_devices() + self.storeDomDetails() + self.unpause() + self.refreshShutdown() + + def storeVmDetails(self): to_store = { 'uuid': uuid.toString(self.uuidbytes), @@ -604,6 +602,15 @@ class XendDomainInfo: if v: to_store[k] = str(v) + def f(n, v): + if v is not None: + to_store[n] = str(v) + + f('console/port', self.console_port) + f('console/ring-ref', self.console_mfn) + f('store/port', self.store_port) + f('store/ring-ref', self.store_mfn) + to_store.update(self.vcpuDomDetails()) log.debug("Storing domain details: %s", to_store) @@ -649,6 +656,16 @@ class XendDomainInfo: return self.dompath + def getStorePort(self): + """For use only by image.py and XendCheckpoint.py.""" + return self.store_port + + + def getConsolePort(self): + """For use only by image.py and XendCheckpoint.py""" + return self.console_port + + def getVCpuCount(self): return self.info['vcpus'] @@ -666,10 +683,6 @@ class XendDomainInfo: """Get this domain's target memory size, in KiB.""" return self.info['memory_KiB'] - def setStoreRef(self, ref): - self.store_mfn = ref - self.storeDom("store/ring-ref", ref) - def refreshShutdown(self, xeninfo = None): # If set at the end of this method, a restart is required, with the @@ -704,6 +717,11 @@ class XendDomainInfo: return elif xeninfo['crashed']: + if self.readDom('xend/shutdown_completed'): + # We've seen this shutdown already, but we are preserving + # the domain for debugging. Leave it alone. + return + log.warn('Domain has crashed: name=%s id=%d.', self.info['name'], self.domid) @@ -735,6 +753,11 @@ class XendDomainInfo: else: self.destroy() + elif self.dompath is None: + # We have yet to manage to call introduceDomain on this + # domain. This can happen if a restore is in progress, or has + # failed. Ignore this domain. + pass else: # Domain is alive. If we are shutting it down, then check # the timeout on that, and destroy it if necessary. @@ -802,11 +825,6 @@ class XendDomainInfo: ## public: - def setConsoleRef(self, ref): - self.console_mfn = ref - self.storeDom("console/ring-ref", ref) - - def setMemoryTarget(self, target): """Set the memory target of this domain. @param target In MiB. @@ -1034,15 +1052,20 @@ class XendDomainInfo: raise VmError('Creating domain failed: name=%s' % self.info['name']) - self.dompath = DOMROOT + str(self.domid) - - # Ensure that the domain entry is clean. This prevents a stale - # shutdown_start_time from killing the domain, for example. - self.removeDom() - # Set maximum number of vcpus in domain xc.domain_max_vcpus(self.domid, int(self.info['vcpus'])) + + def introduceDomain(self): + assert self.domid is not None + assert self.store_mfn is not None + assert self.store_port is not None + + IntroduceDomain(self.domid, self.store_mfn, self.store_port) + self.dompath = GetDomainPath(self.domid) + assert self.dompath + + def initDomain(self): log.debug('XendDomainInfo.initDomain: %s %s %s', self.domid, @@ -1061,28 +1084,28 @@ class XendDomainInfo: xc.domain_setcpuweight(self.domid, self.info['cpu_weight']) - # XXX Merge with configure_maxmem? m = self.image.getDomainMemory(self.info['memory_KiB']) - xc.domain_setmaxmem(self.domid, m) + xc.domain_setmaxmem(self.domid, maxmem_kb = m) xc.domain_memory_increase_reservation(self.domid, m, 0, 0) cpu = self.info['cpu'] if cpu is not None and cpu != -1: xc.domain_pincpu(self.domid, 0, 1 << cpu) + self.createChannels() + + channel_details = self.image.createImage() + + self.store_mfn = channel_details['store_mfn'] + if 'console_mfn' in channel_details: + self.console_mfn = channel_details['console_mfn'] + + self.introduceDomain() + + self.create_devices() + self.info['start_time'] = time.time() - log.debug('init_domain> Created domain=%d name=%s memory=%d', - self.domid, self.info['name'], self.info['memory_KiB']) - - - def construct_image(self): - """Construct the boot image for the domain. - """ - self.create_channels() - self.image.createImage() - IntroduceDomain(self.domid, self.store_mfn, self.store_channel) - ## public: @@ -1166,33 +1189,22 @@ class XendDomainInfo: break - def eventChannel(self, path=None): - """Create an event channel to the domain. - - @param path under which port is stored in db + def createChannels(self): + """Create the channels to the domain. """ - if path: - try: - return int(self.readDom(path)) - except: - # The port is not yet set, i.e. the channel has not yet been - # created. - pass + self.store_port = self.createChannel() + self.console_port = self.createChannel() + + def createChannel(self): + """Create an event channel to the domain. + """ try: - port = xc.evtchn_alloc_unbound(dom=self.domid, remote_dom=0) + return xc.evtchn_alloc_unbound(dom=self.domid, remote_dom=0) except: log.exception("Exception in alloc_unbound(%d)", self.domid) raise - self.storeDom(path, port) - return port - - def create_channels(self): - """Create the channels to the domain. - """ - self.store_channel = self.eventChannel("store/port") - self.console_channel = self.eventChannel("console/port") def create_configured_devices(self): for (n, c) in self.info['device']: @@ -1231,6 +1243,14 @@ class XendDomainInfo: self.reconfigureDevice(deviceClass, devid, dev_config) + def pause(self): + xc.domain_pause(self.domid) + + + def unpause(self): + xc.domain_unpause(self.domid) + + ## private: def restart_check(self): @@ -1280,7 +1300,7 @@ class XendDomainInfo: xd = get_component('xen.xend.XendDomain') new_dom = xd.domain_create(config) try: - xc.domain_unpause(new_dom.getDomid()) + new_dom.unpause() except: new_dom.destroy() raise @@ -1355,20 +1375,6 @@ class XendDomainInfo: self.config = sxp.merge(['vm', ['image', blcfg]], self.config) - def configure(self): - """Configure a vm. - - """ - self.configure_maxmem() - self.create_devices() - - - def configure_maxmem(self): - if self.image: - m = self.image.getDomainMemory(self.info['memory_KiB']) - xc.domain_setmaxmem(self.domid, maxmem_kb = m) - - def send_sysrq(self, key): asserts.isCharConvertible(key) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 5453b1089a..4a9d9fc740 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -111,7 +111,8 @@ class ImageHandler: """Entry point to create domain memory image. Override in subclass if needed. """ - self.createDomain() + return self.createDomain() + def createDomain(self): """Build the domain boot image. @@ -128,10 +129,15 @@ class ImageHandler: log.info("buildDomain os=%s dom=%d vcpus=%d", self.ostype, self.vm.getDomid(), self.vm.getVCpuCount()) - err = self.buildDomain() - if err != 0: - raise VmError('Building domain failed: ostype=%s dom=%d err=%d' - % (self.ostype, self.vm.getDomid(), err)) + + result = self.buildDomain() + + if isinstance(result, dict): + return result + else: + raise VmError('Building domain failed: ostype=%s dom=%d err=%s' + % (self.ostype, self.vm.getDomid(), str(result))) + def getDomainMemory(self, mem): """@return The memory required, in KiB, by the domain to store the @@ -151,26 +157,14 @@ class ImageHandler: """Extra cleanup on domain destroy (define in subclass if needed).""" pass - def set_vminfo(self, d): - if d.has_key('store_mfn'): - self.vm.setStoreRef(d.get('store_mfn')) - if d.has_key('console_mfn'): - self.vm.setConsoleRef(d.get('console_mfn')) - class LinuxImageHandler(ImageHandler): ostype = "linux" def buildDomain(self): - if self.vm.store_channel: - store_evtchn = self.vm.store_channel - else: - store_evtchn = 0 - if self.vm.console_channel: - console_evtchn = self.vm.console_channel - else: - console_evtchn = 0 + store_evtchn = self.vm.getStorePort() + console_evtchn = self.vm.getConsolePort() log.debug("dom = %d", self.vm.getDomid()) log.debug("image = %s", self.kernel) @@ -180,16 +174,12 @@ class LinuxImageHandler(ImageHandler): log.debug("ramdisk = %s", self.ramdisk) log.debug("vcpus = %d", self.vm.getVCpuCount()) - ret = xc.linux_build(dom = self.vm.getDomid(), - image = self.kernel, - store_evtchn = store_evtchn, - console_evtchn = console_evtchn, - cmdline = self.cmdline, - ramdisk = self.ramdisk) - if isinstance(ret, dict): - self.set_vminfo(ret) - return 0 - return ret + return xc.linux_build(dom = self.vm.getDomid(), + image = self.kernel, + store_evtchn = store_evtchn, + console_evtchn = console_evtchn, + cmdline = self.cmdline, + ramdisk = self.ramdisk) class VmxImageHandler(ImageHandler): @@ -214,20 +204,13 @@ class VmxImageHandler(ImageHandler): self.dmargs += self.configVNC(imageConfig) - def createImage(self): - """Create a VM for the VMX environment. - """ - self.createDomain() - def buildDomain(self): # Create an event channel self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(), remote_dom=0) log.info("VMX device model port: %d", self.device_channel) - if self.vm.store_channel: - store_evtchn = self.vm.store_channel - else: - store_evtchn = 0 + + store_evtchn = self.vm.getStorePort() log.debug("dom = %d", self.vm.getDomid()) log.debug("image = %s", self.kernel) @@ -236,16 +219,13 @@ class VmxImageHandler(ImageHandler): log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024) log.debug("vcpus = %d", self.vm.getVCpuCount()) - ret = xc.vmx_build(dom = self.vm.getDomid(), - image = self.kernel, - control_evtchn = self.device_channel, - store_evtchn = store_evtchn, - memsize = self.vm.getMemoryTarget() / 1024, - vcpus = self.vm.getVCpuCount()) - if isinstance(ret, dict): - self.set_vminfo(ret) - return 0 - return ret + return xc.vmx_build(dom = self.vm.getDomid(), + image = self.kernel, + control_evtchn = self.device_channel, + store_evtchn = store_evtchn, + memsize = self.vm.getMemoryTarget() / 1024, + vcpus = self.vm.getVCpuCount()) + # Return a list of cmd line args to the device models based on the # xm config file diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index a66f7d8a48..d9ecefc133 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -246,8 +246,9 @@ static bool write_messages(struct connection *conn) if (out->inhdr) { if (verbose) - xprintf("Writing msg %s (%s) out to %p\n", + xprintf("Writing msg %s (%.*s) out to %p\n", sockmsg_string(out->hdr.msg.type), + out->hdr.msg.len, out->buffer, conn); ret = conn->write(conn, out->hdr.raw + out->used, sizeof(out->hdr) - out->used); @@ -946,9 +947,29 @@ static bool delete_child(struct connection *conn, corrupt(conn, "Can't find child '%s' in %s", childname, node->name); } + +static int _rm(struct connection *conn, struct node *node, const char *name) +{ + /* Delete from parent first, then if something explodes fsck cleans. */ + struct node *parent = read_node(conn, get_parent(name)); + if (!parent) { + send_error(conn, EINVAL); + return 0; + } + + if (!delete_child(conn, parent, basename(name))) { + send_error(conn, EINVAL); + return 0; + } + + delete_node(conn, node); + return 1; +} + + static void do_rm(struct connection *conn, const char *name) { - struct node *node, *parent; + struct node *node; name = canonicalize(conn, name); node = get_node(conn, name, XS_PERM_WRITE); @@ -972,24 +993,24 @@ static void do_rm(struct connection *conn, const char *name) return; } - /* Delete from parent first, then if something explodes fsck cleans. */ - parent = read_node(conn, get_parent(name)); - if (!parent) { - send_error(conn, EINVAL); - return; + if (_rm(conn, node, name)) { + add_change_node(conn->transaction, name, true); + fire_watches(conn, name, true); + send_ack(conn, XS_RM); } - - if (!delete_child(conn, parent, basename(name))) { - send_error(conn, EINVAL); - return; - } - - delete_node(conn, node); - add_change_node(conn->transaction, name, true); - fire_watches(conn, name, true); - send_ack(conn, XS_RM); } + +void internal_rm(const char *name) +{ + struct node *node = read_node(NULL, name); + if (!node) { + return; + } + _rm(NULL, node, name); +} + + static void do_get_perms(struct connection *conn, const char *name) { struct node *node; diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index e8f4a28c65..abcb42c38d 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -154,6 +154,10 @@ void __attribute__((noreturn)) corrupt(struct connection *conn, struct connection *new_connection(connwritefn_t *write, connreadfn_t *read); + +void internal_rm(const char *name); + + /* Is this a valid node name? */ bool is_valid_nodename(const char *node); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 9ddcf4f728..fd2bbdf691 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -271,6 +271,8 @@ static struct domain *new_domain(void *context, unsigned int domid, list_add(&domain->list, &domains); talloc_set_destructor(domain, destroy_domain); + internal_rm(domain->path); + /* Tell kernel we're interested in this event. */ bind.remote_domain = domid; bind.remote_port = port; From 6d55f5160369dc5adec0a3ac8a1725b8fddc2f7c Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 19 Oct 2005 11:51:25 +0100 Subject: [PATCH 089/142] Remove unused shadow_control functionality from the Python layer. This is handled in xc_linux_save, and no-one in the Python layer uses this functionality directly. Signed-off-by: Ewan Mellor --- tools/python/xen/lowlevel/xc/xc.c | 30 ----------------------------- tools/python/xen/xend/XendDomain.py | 9 +-------- 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 17027cdc2a..8e49d8036f 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -787,28 +787,6 @@ static PyObject *pyxc_sedf_domain_get(PyObject *self, "extratime", extratime); } -static PyObject *pyxc_shadow_control(PyObject *self, - PyObject *args, - PyObject *kwds) -{ - XcObject *xc = (XcObject *)self; - - uint32_t dom; - int op=0; - - static char *kwd_list[] = { "dom", "op", NULL }; - - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|i", kwd_list, - &dom, &op) ) - return NULL; - - if ( xc_shadow_control(xc->xc_handle, dom, op, NULL, 0, NULL) < 0 ) - return PyErr_SetFromErrno(xc_error); - - Py_INCREF(zero); - return zero; -} - static PyObject *pyxc_domain_setmaxmem(PyObject *self, PyObject *args, PyObject *kwds) @@ -1115,14 +1093,6 @@ static PyMethodDef pyxc_methods[] = { "Returns [dict]: information about Xen" " [None]: on failure.\n" }, - { "shadow_control", - (PyCFunction)pyxc_shadow_control, - METH_VARARGS | METH_KEYWORDS, "\n" - "Set parameter for shadow pagetable interface\n" - " dom [int]: Identifier of domain.\n" - " op [int, 0]: operation\n\n" - "Returns: [int] 0 on success; -1 on error.\n" }, - { "domain_setmaxmem", (PyCFunction)pyxc_domain_setmaxmem, METH_VARARGS | METH_KEYWORDS, "\n" diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 235e39f633..0b50c83b55 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -473,14 +473,7 @@ class XendDomain: if not dev: raise XendError("invalid vif") return dev.setCreditLimit(credit, period) - - def domain_shadow_control(self, domid, op): - """Shadow page control.""" - dominfo = self.domain_lookup(domid) - try: - return xc.shadow_control(dominfo.getDomid(), op) - except Exception, ex: - raise XendError(str(ex)) + def domain_maxmem_set(self, domid, mem): """Set the memory limit for a domain. From 963785e3ee1eb58f9574170e79714c1329110e55 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 19 Oct 2005 11:53:00 +0100 Subject: [PATCH 090/142] Remove unused parameter from addControllerClass. This became unused when the BE_DOMAIN flags were removed. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomainInfo.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 59bd0f24a6..1e3d482a75 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -1392,7 +1392,7 @@ class XendDomainInfo: implements the device control specific to that device-class.""" controllerClasses = {} -def addControllerClass(device_class, backend_name, cls): +def addControllerClass(device_class, cls): """Register a subclass of DevController to handle the named device-class. """ cls.deviceClass = device_class @@ -1400,8 +1400,8 @@ def addControllerClass(device_class, backend_name, cls): from xen.xend.server import blkif, netif, tpmif, pciif, usbif -addControllerClass('vbd', 'blkif', blkif.BlkifController) -addControllerClass('vif', 'netif', netif.NetifController) -addControllerClass('vtpm', 'tpmif', tpmif.TPMifController) -addControllerClass('pci', 'pciif', pciif.PciController) -addControllerClass('usb', 'usbif', usbif.UsbifController) +addControllerClass('vbd', blkif.BlkifController) +addControllerClass('vif', netif.NetifController) +addControllerClass('vtpm', tpmif.TPMifController) +addControllerClass('pci', pciif.PciController) +addControllerClass('usb', usbif.UsbifController) From db6435aaa83042fa0843b33c0c76f63f6855e5a8 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 19 Oct 2005 13:33:22 +0100 Subject: [PATCH 091/142] Added sedf_get functionality to XendClient interface. From David Isaac Wolinsky . Signed-off-by: Ewan Mellor --- tools/python/xen/lowlevel/xc/xc.c | 13 +++++++------ tools/python/xen/xend/XendClient.py | 4 ++++ tools/python/xen/xend/server/SrvDomain.py | 7 +++++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index 8e49d8036f..b264615b3f 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -739,8 +739,8 @@ static PyObject *pyxc_xeninfo(PyObject *self, static PyObject *pyxc_sedf_domain_set(PyObject *self, - PyObject *args, - PyObject *kwds) + PyObject *args, + PyObject *kwds) { XcObject *xc = (XcObject *)self; uint32_t domid; @@ -762,8 +762,8 @@ static PyObject *pyxc_sedf_domain_set(PyObject *self, } static PyObject *pyxc_sedf_domain_get(PyObject *self, - PyObject *args, - PyObject *kwds) + PyObject *args, + PyObject *kwds) { XcObject *xc = (XcObject *)self; uint32_t domid; @@ -779,12 +779,13 @@ static PyObject *pyxc_sedf_domain_get(PyObject *self, &slice,&latency,&extratime,&weight) ) return PyErr_SetFromErrno(xc_error); - return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i}", + return Py_BuildValue("{s:i,s:L,s:L,s:L,s:i,s:i}", "domain", domid, "period", period, "slice", slice, "latency", latency, - "extratime", extratime); + "extratime", extratime, + "weight", weight); } static PyObject *pyxc_domain_setmaxmem(PyObject *self, diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 22f8fc7571..9fe93bab99 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -269,6 +269,10 @@ class Xend: 'warpl' : warpl, 'warpu' : warpu }) + def xend_domain_cpu_sedf_get(self, id): + return self.xendPost(self.domainurl(id), + {'op' : 'cpu_sedf_get'}) + def xend_domain_cpu_sedf_set(self, id, period, slice, latency, extratime, weight): return self.xendPost(self.domainurl(id), {'op' : 'cpu_sedf_set', diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index 5278506cc4..40ddc81972 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -105,6 +105,13 @@ class SrvDomain(SrvDir): return val + def op_cpu_sedf_get(self, op, req): + fn = FormFn(self.xd.domain_cpu_sedf_get, + [['dom', 'int']]) + val = fn(req.args, {'dom': self.dom.domid}) + return val + + def op_cpu_sedf_set(self, op, req): fn = FormFn(self.xd.domain_cpu_sedf_set, [['dom', 'int'], From c8a1f1c7fce74352f4c2aabcf13803502debacc0 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 19 Oct 2005 13:34:44 +0100 Subject: [PATCH 092/142] Some trivial changes for the tool scripts: - make xen-hotplug-common.sh (un)set locales. - use xen-hotplug-common.sh in vif-bridge. From Gerd Knorr . Signed-off-by: Ewan Mellor --- tools/examples/vif-bridge | 7 ++----- tools/examples/xen-hotplug-common.sh | 4 +++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/tools/examples/vif-bridge b/tools/examples/vif-bridge index 0f692d689f..0174d81116 100755 --- a/tools/examples/vif-bridge +++ b/tools/examples/vif-bridge @@ -31,11 +31,8 @@ # rules for its ip addresses (if any). #============================================================================ -# Exit if anything goes wrong -set -e -export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH - -echo "*vif-bridge $*" >&2 +dir=$(dirname "$0") +. "$dir/xen-hotplug-common.sh" # Operation name. OP=$1 diff --git a/tools/examples/xen-hotplug-common.sh b/tools/examples/xen-hotplug-common.sh index aa0f7fabc8..10c7d4c87b 100644 --- a/tools/examples/xen-hotplug-common.sh +++ b/tools/examples/xen-hotplug-common.sh @@ -1,6 +1,8 @@ set -e -export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH +export PATH="/sbin:/bin:/usr/bin:/usr/sbin:$PATH" +export LANG="POSIX" +unset $(set | grep ^LC_ | cut -d= -f1) log() { local level="$1" From f3adfa9dcb4df8c03fb0fd47e2b9d2bbc028bb1f Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 19 Oct 2005 13:37:16 +0100 Subject: [PATCH 093/142] Set the console limit for DomUs based on a value set in xend-config.sxp. Signed-off-by: Dan Smith Signed-off-by: Ewan Mellor --- tools/examples/xend-config.sxp | 3 +++ tools/python/xen/xend/XendDomainInfo.py | 2 +- tools/python/xen/xend/XendRoot.py | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index 1b6b8c52e1..75152f21db 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -20,6 +20,9 @@ # Specifying the empty string '' allows all connections. (console-address 'localhost') +# The limit (in kilobytes) on the size of the console buffer +(console-limit 1024) + ## Use the following if VIF traffic is routed. # The script used to start/stop networking for xend. #(network-script network-route) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 1e3d482a75..bb3088d500 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -594,7 +594,7 @@ class XendDomainInfo: to_store = { 'domid': str(self.domid), 'vm': self.vmpath, - + 'console/limit': str(xroot.get_console_limit() * 1024), 'memory/target': str(self.info['memory_KiB']) } diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index 85a13286dd..e88e8ff4b3 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -267,6 +267,9 @@ class XendRoot: def get_dom0_vcpus(self): return self.get_config_int('dom0-cpus', self.dom0_vcpus_default) + def get_console_limit(self): + return self.get_config_int('console-limit', 1024) + def instance(): """Get an instance of XendRoot. Use this instead of the constructor. From 3158496ec82f755fea8ea4037aa977c74ac04f89 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 19 Oct 2005 13:39:59 +0100 Subject: [PATCH 094/142] Better fix to detect failed patch application when building guest kernels. Signed-off-by: Muli Ben-Yehuda --- buildconfigs/Rules.mk | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/buildconfigs/Rules.mk b/buildconfigs/Rules.mk index 2970945810..5b70d23508 100644 --- a/buildconfigs/Rules.mk +++ b/buildconfigs/Rules.mk @@ -80,11 +80,12 @@ clean:: rm -f patches/*/.makedep ref-%/.valid-ref: pristine-%/.valid-pristine + set -e rm -rf $(@D) cp -al $( Date: Wed, 19 Oct 2005 13:59:15 +0100 Subject: [PATCH 095/142] Add slack to balloon driver to allow to counteract low-mem address space allocations in backend drivers. Signed-off-by: Keir Fraser --- .../arch/xen/i386/kernel/setup.c | 46 ++++++------------- .../arch/xen/x86_64/kernel/e820.c | 9 ++-- .../arch/xen/x86_64/kernel/setup.c | 26 +++++------ .../drivers/xen/balloon/balloon.c | 5 +- 4 files changed, 33 insertions(+), 53 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c index 17788f3862..958e2af479 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/setup.c @@ -939,6 +939,8 @@ void __init find_max_pfn(void) if ( xen_override_max_pfn < xen_start_info->nr_pages ) xen_override_max_pfn = xen_start_info->nr_pages; max_pfn = xen_override_max_pfn; + /* 8MB slack, to make up for address space allocations in backends. */ + max_pfn += 8 << (20 - PAGE_SHIFT); } #endif /* XEN */ @@ -1638,39 +1640,17 @@ void __init setup_arch(char **cmdline_p) #endif /* Make sure we have a correctly sized P->M table. */ - if (max_pfn != xen_start_info->nr_pages) { - phys_to_machine_mapping = alloc_bootmem_low_pages( - max_pfn * sizeof(unsigned long)); - - if (max_pfn > xen_start_info->nr_pages) { - /* set to INVALID_P2M_ENTRY */ - memset(phys_to_machine_mapping, ~0, - max_pfn * sizeof(unsigned long)); - memcpy(phys_to_machine_mapping, - (unsigned long *)xen_start_info->mfn_list, - xen_start_info->nr_pages * sizeof(unsigned long)); - } else { - struct xen_memory_reservation reservation = { - .extent_start = (unsigned long *)xen_start_info->mfn_list + max_pfn, - .nr_extents = xen_start_info->nr_pages - max_pfn, - .extent_order = 0, - .domid = DOMID_SELF - }; - - memcpy(phys_to_machine_mapping, - (unsigned long *)xen_start_info->mfn_list, - max_pfn * sizeof(unsigned long)); - BUG_ON(HYPERVISOR_memory_op( - XENMEM_decrease_reservation, - &reservation) != - (xen_start_info->nr_pages - max_pfn)); - } - free_bootmem( - __pa(xen_start_info->mfn_list), - PFN_PHYS(PFN_UP(xen_start_info->nr_pages * - sizeof(unsigned long)))); - } - + phys_to_machine_mapping = alloc_bootmem_low_pages( + max_pfn * sizeof(unsigned long)); + memset(phys_to_machine_mapping, ~0, + max_pfn * sizeof(unsigned long)); + memcpy(phys_to_machine_mapping, + (unsigned long *)xen_start_info->mfn_list, + xen_start_info->nr_pages * sizeof(unsigned long)); + free_bootmem( + __pa(xen_start_info->mfn_list), + PFN_PHYS(PFN_UP(xen_start_info->nr_pages * + sizeof(unsigned long)))); /* * Initialise the list of the frames that specify the list of diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c index 32091d2496..6f9ab86b79 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c @@ -528,10 +528,13 @@ unsigned long __init e820_end_of_ram(void) { unsigned long max_end_pfn = xen_start_info->nr_pages; - if ( xen_override_max_pfn < max_end_pfn) + if ( xen_override_max_pfn < max_end_pfn) xen_override_max_pfn = max_end_pfn; - - return xen_override_max_pfn; + + /* 8MB slack, to make up for address space allocations in backends. */ + xen_override_max_pfn += 8 << (20 - PAGE_SHIFT); + + return xen_override_max_pfn; } void __init e820_reserve_resources(void) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c index 2df3585c08..19f5e957a5 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c @@ -429,7 +429,7 @@ static __init void parse_cmdline_early (char ** cmdline_p) static void __init contig_initmem_init(void) { unsigned long bootmap_size = init_bootmem(start_pfn, end_pfn); - free_bootmem(0, end_pfn << PAGE_SHIFT); + free_bootmem(0, xen_start_info->nr_pages << PAGE_SHIFT); reserve_bootmem(HIGH_MEMORY, (PFN_PHYS(start_pfn) + bootmap_size + PAGE_SIZE-1) - HIGH_MEMORY); @@ -734,19 +734,17 @@ void __init setup_arch(char **cmdline_p) { int i, j, k, fpp; /* Make sure we have a large enough P->M table. */ - if (end_pfn > xen_start_info->nr_pages) { - phys_to_machine_mapping = alloc_bootmem( - end_pfn * sizeof(unsigned long)); - memset(phys_to_machine_mapping, ~0, - end_pfn * sizeof(unsigned long)); - memcpy(phys_to_machine_mapping, - (unsigned long *)xen_start_info->mfn_list, - xen_start_info->nr_pages * sizeof(unsigned long)); - free_bootmem( - __pa(xen_start_info->mfn_list), - PFN_PHYS(PFN_UP(xen_start_info->nr_pages * - sizeof(unsigned long)))); - } + phys_to_machine_mapping = alloc_bootmem( + end_pfn * sizeof(unsigned long)); + memset(phys_to_machine_mapping, ~0, + end_pfn * sizeof(unsigned long)); + memcpy(phys_to_machine_mapping, + (unsigned long *)xen_start_info->mfn_list, + xen_start_info->nr_pages * sizeof(unsigned long)); + free_bootmem( + __pa(xen_start_info->mfn_list), + PFN_PHYS(PFN_UP(xen_start_info->nr_pages * + sizeof(unsigned long)))); /* * Initialise the list of the frames that specify the list of diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c index 984e6f9ad9..14a9718326 100644 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c @@ -502,7 +502,7 @@ static int dealloc_pte_fn( .extent_order = 0, .domid = DOMID_SELF }; - set_pte(pte, __pte_ma(0)); + set_pte_at(&init_mm, addr, pte, __pte_ma(0)); phys_to_machine_mapping[__pa(addr) >> PAGE_SHIFT] = INVALID_P2M_ENTRY; BUG_ON(HYPERVISOR_memory_op( @@ -521,10 +521,9 @@ struct page *balloon_alloc_empty_page_range(unsigned long nr_pages) scrub_pages(vstart, 1 << order); + balloon_lock(flags); BUG_ON(generic_page_range( &init_mm, vstart, PAGE_SIZE << order, dealloc_pte_fn, NULL)); - - balloon_lock(flags); current_pages -= 1UL << order; balloon_unlock(flags); From a91b3cb6d76267a2f7d2e120d889ead8b1f1af58 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 19 Oct 2005 13:59:22 +0100 Subject: [PATCH 096/142] Added diagnosis tool for broken domains. Signed-off-by: Ewan Mellor --- tools/python/xen/util/diagnose.py | 148 ++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 tools/python/xen/util/diagnose.py diff --git a/tools/python/xen/util/diagnose.py b/tools/python/xen/util/diagnose.py new file mode 100644 index 0000000000..d8b765e5c7 --- /dev/null +++ b/tools/python/xen/util/diagnose.py @@ -0,0 +1,148 @@ +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Copyright (c) 2005 XenSource Ltd + + +import re +import sys + +from xen.xend import sxp + +from xen.xend.XendClient import server +from xen.xend.XendError import XendError +from xen.xend.xenstore.xstransact import xstransact + +import xen.xend.XendProtocol + + +domain = None +domid = None +deviceClass = None +device = None +frontendPath = None +backendPath = None + + +def diagnose(dom): + global domain + global domid + global dompath + + try: + domain = server.xend_domain(dom) + state = sxp.child_value(domain, 'state') + domid = int(sxp.child_value(domain, 'domid')) + name = sxp.child_value(domain, 'name') + dompath = '/local/domain/%d' % domid + + print "Domain ID is %d." % domid + print "Domain name is %s." % name + + if not state: + raise XendError("Cannot find state") + + if state.find('c') != -1: + print "Domain has crashed." + + diagnose_console() + + diagnose_devices() + except xen.xend.XendProtocol.XendError, exn: + print exn + + +def diagnose_console(): + port = xstransact.Read(dompath + '/console/port') + ringref = xstransact.Read(dompath + '/console/ring-ref') + tty = xstransact.Read(dompath + '/console/tty') + + if not port: + print "Console port is missing; Xend has failed." + if not ringref: + print "Console ring-ref is missing; Xend has failed." + if not tty: + print "Console tty is missing; Xenconsoled has failed." + + +def diagnose_devices(): + global deviceClass + global device + global frontendPath + global backendPath + + device_path = dompath + '/device' + + device_classes = xstransact.List(device_path) + + print "Found %d device classes in use." % len(device_classes) + + for dc in device_classes: + deviceClass = dc + device_class_path = device_path + '/' + deviceClass + + devices = xstransact.List(device_class_path) + + print "Found %d %s devices." % (len(devices), deviceClass) + + for d in devices: + device = d + + print "Found device %s, %s." % (deviceClass, device) + + frontendPath = device_class_path + '/' + device + backendPath = xstransact.Read(frontendPath, 'backend') + + if not backendPath: + print ("Cannot find backend path for device %s, %s." % + (deviceClass, device)) + else: + backend_error = xstransact.Read(backendPath, 'error') + + if backend_error: + diagnose_device_error(backend_error) + + +def diagnose_device_error(err): + if re.search("2 reading .*/ring-ref and event-channel", err): + print ("Backend is stuck waiting for frontend for device %s, %s." % + (deviceClass, device)) + diagnose_stuck_frontend() + else: + print ("Device %s, %s shows error %s." % + (deviceClass, device, err)) + + +def diagnose_stuck_frontend(): + if deviceClass == "vbd": + phy = xstransact.Read(backendPath, 'physical-device') + + if phy: + print ("Device %s, %s hotplugging has completed successfully." % + (deviceClass, device)) + else: + print ("Device %s, %s hotplugging failed." % + (deviceClass, device)) + + +def main(argv = None): + if argv is None: + argv = sys.argv + + diagnose(argv[1]) + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) From 7c2cea666f3ce71b22906ad19b301b63e5138c3d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 19 Oct 2005 15:51:14 +0100 Subject: [PATCH 097/142] Declare ac_timer_init() properly in ac_timer.h --- xen/arch/x86/setup.c | 1 - xen/include/xen/ac_timer.h | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 208142e119..c6653708a1 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -78,7 +78,6 @@ extern void arch_init_memory(void); extern void init_IRQ(void); extern void trap_init(void); extern void early_time_init(void); -extern void ac_timer_init(void); extern void initialize_keytable(void); extern void early_cpu_init(void); diff --git a/xen/include/xen/ac_timer.h b/xen/include/xen/ac_timer.h index baf1014792..bd5131d6e3 100644 --- a/xen/include/xen/ac_timer.h +++ b/xen/include/xen/ac_timer.h @@ -63,6 +63,11 @@ extern void set_ac_timer(struct ac_timer *timer, s_time_t expires); */ extern void rem_ac_timer(struct ac_timer *timer); +/* + * Initialisation. Must be called before any other ac_timer function. + */ +extern void ac_timer_init(void); + #endif /* _AC_TIMER_H_ */ /* From 4308423bdd9722a590c7de096ef3a11124de1e1d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 19 Oct 2005 16:07:11 +0100 Subject: [PATCH 098/142] pygrub's setup.py relies on distutils.UnixCCompiler.has_function(), which does not exist with python2.2, causing the following build error: make[2]: Entering directory `/home/muli/xen/x86.hg/tools/pygrub' CFLAGS=" -m32 -march=i686" python setup.py build Traceback (most recent call last): File "setup.py", line 15, in ? if cc.has_function("ext2fs_open2"): AttributeError: UnixCCompiler instance has no attribute 'has_function' The following patch gets it to build, but is pretty ugly. A proper fix would be to do the check for ext2fs_open2() in a way that is backward compatible with python2.2. Signed-Off-By: Muli Ben-Yehuda --- tools/pygrub/setup.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/pygrub/setup.py b/tools/pygrub/setup.py index 680535d6cb..43e46762a8 100644 --- a/tools/pygrub/setup.py +++ b/tools/pygrub/setup.py @@ -12,11 +12,14 @@ if os.path.exists("/usr/include/ext2fs/ext2_fs.h"): ext2defines = [] cc = new_compiler() cc.add_library("ext2fs") - if cc.has_function("ext2fs_open2"): - ext2defines.append( ("HAVE_EXT2FS_OPEN2", None) ) - else: - sys.stderr.write("WARNING: older version of e2fsprogs installed, not building full\n") - sys.stderr.write(" disk support for ext2.\n") + try: + if cc.has_function("ext2fs_open2"): + ext2defines.append( ("HAVE_EXT2FS_OPEN2", None) ) + else: + sys.stderr.write("WARNING: older version of e2fsprogs installed, not building full\n") + sys.stderr.write(" disk support for ext2.\n") + except AttributeError: + pass ext2 = Extension("grub.fsys.ext2._pyext2", extra_compile_args = extra_compile_args, From a77149f8e43f254cc6a0ac87271fd1a31b2a9474 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 19 Oct 2005 16:24:54 +0100 Subject: [PATCH 099/142] New network-bridge script and associated gubbins. This is Kurt Garloff's reworked network-bridge script: * we got rid of ifconfig * it works for netdev != eth0 * arp on and off are symmetric as are ifdown and ifup * ifup will be passed the ifcfg config file name if needed (the ifup may otherwise figure that the veth0 hardware is NOT the same as the original ${netdev} and not use the same config -- this happens on SUSE. Charles Coffing tracked this one down.) Plus Kurt's avoid-dash patch: the network setup scripts on SUSE have trouble with the bridge name xen-br0; they don't expect the '-'. Arguably this should be fixed. But I assume there's more scripts out there which may not like it, so I suggest the following patch to rename xen-br0 to xenbr0. Plus Charles Duffy's patch to support multiple bridges: The attached patch allows the network-bridge script to be used to generate multiple bridges corresponding to different physical interfaces. It adds a new parameter, "vifnum", used to refer both to the loopback interface to be used and to set defaults regarding the physical interface and bridge name. Thus, if one wishes to start xenbr0 on eth0 and xenbr1 on eth1, one need only call: network-bridge start ## vifnum is 0 by default network-bridge start vifnum=1 ...well, that and set loopback.nloopbacks=2 in the Dom0 kernel parameters. Plus renaming of virtnum to vifnum in Charles' patch, as requested by Ian Pratt. Plus a fix to DevController to allocate vif IDs starting from 0 (i.e. vif2.0 is now domain 2's first vif, as opposed to vif2.1 in the recent past). Plus tidying up inside network-bridge using some helper variables. Signed-off-by: Ewan Mellor --- tools/examples/network-bridge | 201 +++++++++++------- tools/examples/vif-bridge | 2 +- tools/examples/xend-config.sxp | 2 +- tools/examples/xmexample.vmx | 2 +- tools/examples/xmexample1 | 2 +- tools/examples/xmexample2 | 2 +- tools/ioemu/target-i386-dm/qemu-ifup | 2 +- tools/misc/netfix | 4 +- tools/python/xen/xend/XendRoot.py | 2 +- tools/python/xen/xend/server/DevController.py | 2 +- tools/python/xen/xend/server/SrvDaemon.py | 47 +--- tools/vnet/vnet-module/varp.c | 2 +- 12 files changed, 142 insertions(+), 128 deletions(-) mode change 100755 => 100644 tools/examples/network-bridge diff --git a/tools/examples/network-bridge b/tools/examples/network-bridge old mode 100755 new mode 100644 index f0e1e1648d..c6fb1c1f47 --- a/tools/examples/network-bridge +++ b/tools/examples/network-bridge @@ -5,8 +5,8 @@ # The script name to use is defined in /etc/xen/xend-config.sxp # in the network-script field. # -# This script creates a bridge (default xen-br0), adds a device -# (default eth0) to it, copies the IP addresses from the device +# This script creates a bridge (default xenbr${vifnum}), adds a device +# (default eth${vifnum}) to it, copies the IP addresses from the device # to the bridge and adjusts the routes accordingly. # # If all goes well, this should ensure that networking stays up. @@ -20,9 +20,12 @@ # # Vars: # -# bridge The bridge to use (default xen-br0). -# netdev The interface to add to the bridge (default eth0). -# antispoof Whether to use iptables to prevent spoofing (default yes). +# vifnum Virtual device number to use (default 0). Numbers >=1 +# require the netback driver to have nloopbacks set to a +# higher value than its default of 1. +# bridge The bridge to use (default xenbr${vifnum}). +# netdev The interface to add to the bridge (default eth${vifnum}). +# antispoof Whether to use iptables to prevent spoofing (default no). # # start: # Creates the bridge and enslaves netdev to it. @@ -60,11 +63,37 @@ shift # Pull variables in args in to environment. for arg ; do export "${arg}" ; done -bridge=${bridge:-xen-br0} -netdev=${netdev:-eth0} +vifnum=${vifnum:-0} +bridge=${bridge:-xenbr${vifnum}} +netdev=${netdev:-eth${vifnum}} antispoof=${antispoof:-no} -echo "*network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof" >&2 +pdev="p${netdev}" +vdev="veth${vifnum}" +vif0="vif0.${vifnum}" + +echo "*network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof vifnum=$vifnum" >&2 + +legacy_mask_to_prefix() { + mask=$1 + first=${mask%%.*} + second=${mask#*.} + third=${second#*.} + fourth=${third#*.} + second=${second%%.*} + third=${third%%.*} + declare -i INT FULLMASK BIT + INT=$((((($first*256)+$second)*256+$third)*256+$fourth)) + FULLMASK=4294967295 + BIT=1 + for bit in `seq 32 -1 0`; do + if test $FULLMASK -eq $INT; then PREFIX=$bit; return; fi + FULLMASK=$(($FULLMASK-$BIT)) + BIT=$((BIT*2)) + done + echo "ERROR converting netmask $mask to prefix" + exit 1 +} # Usage: transfer_addrs src dst # Copy all IP addresses (including aliases) from device $src to device $dst. @@ -99,6 +128,7 @@ s/inet/ip addr del/ s@\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\)/[0-9]\+@\1@ s/${src}/dev ${src}/ " | sh -e + ip link set dev ${dst} up } # Usage: transfer_routes src dst @@ -131,11 +161,11 @@ create_bridge () { # Don't create the bridge if it already exists. if ! brctl show | grep -q ${bridge} ; then - brctl addbr ${bridge} - brctl stp ${bridge} off - brctl setfd ${bridge} 0 + brctl addbr ${bridge} + brctl stp ${bridge} off + brctl setfd ${bridge} 0 fi - ifconfig ${bridge} up + ip link set ${bridge} up } # Usage: add_to_bridge bridge dev @@ -144,7 +174,7 @@ add_to_bridge () { local dev=$2 # Don't add $dev to $bridge if it's already on a bridge. if ! brctl show | grep -q ${dev} ; then - brctl addif ${bridge} ${dev} + brctl addif ${bridge} ${dev} fi } @@ -166,8 +196,10 @@ show_status () { local bridge=$2 echo '============================================================' - ifconfig ${dev} - ifconfig ${bridge} + ip addr show ${dev} + ip addr show ${bridge} + echo ' ' + brctl show ${bridge} echo ' ' ip route list echo ' ' @@ -177,100 +209,113 @@ show_status () { op_start () { if [ "${bridge}" == "null" ] ; then - return + return fi create_bridge ${bridge} - if ifconfig 2>/dev/null | grep -q veth0 ; then - return + if ! ip link show 2>/dev/null | grep -q "^[0-9]*: ${vdev}"; then + return fi - if ifconfig veth0 2>/dev/null | grep -q veth0 ; then - mac=`ifconfig ${netdev} | grep HWadd | sed -e 's/.*\(..:..:..:..:..:..\).*/\1/'` - if ! ifdown ${netdev} ; then - # if ifup didn't work, see if we have an ip= on cmd line - if egrep 'ip=[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:' /proc/cmdline ; - then - kip=`sed -e 's!.*ip=\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\):.*!\1!' /proc/cmdline` - kmask=`sed -e 's!.*ip=[^:]*:[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline` - kgate=`sed -e 's!.*ip=[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline` - ifconfig ${netdev} 0.0.0.0 down - fi + if ip link show ${vdev} 2>/dev/null >/dev/null; then + mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'` + eval `/sbin/getcfg -d /etc/sysconfig/network/ -f ifcfg- -- ${netdev}` + transfer_addrs ${netdev} ${vdev} + if ! ifdown ${netdev}; then + # if ifup didn't work, see if we have an ip= on cmd line + if egrep 'ip=[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:' /proc/cmdline; then + kip=`sed -e 's!.*ip=\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\):.*!\1!' /proc/cmdline` + kmask=`sed -e 's!.*ip=[^:]*:[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline` + kgate=`sed -e 's!.*ip=[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline` + ip link set ${netdev} down + ip addr flush ${netdev} + fi fi - ip link set ${netdev} name p${netdev} - ip link set veth0 name ${netdev} - ifconfig p${netdev} 0.0.0.0 -arp down - ifconfig p${netdev} hw ether fe:ff:ff:ff:ff:ff - ifconfig ${netdev} hw ether ${mac} - add_to_bridge ${bridge} vif0.0 - add_to_bridge ${bridge} p${netdev} + ip link set ${netdev} name ${pdev} + ip link set ${vdev} name ${netdev} + ip link set ${pdev} down arp off + ip link set ${pdev} addr fe:ff:ff:ff:ff:ff + ip addr flush ${pdev} + ip link set ${netdev} addr ${mac} arp on + add_to_bridge ${bridge} ${vif0} + add_to_bridge ${bridge} ${pdev} ip link set ${bridge} up - ip link set vif0.0 up - ip link set p${netdev} up - if ! ifup ${netdev} ; then - if [ ${kip} ] ; then - # use the addresses we grocked from /proc/cmdline - ifconfig ${netdev} ${kip} - [ ${kmask} ] && ifconfig ${netdev} netmask ${kmask} - ifconfig ${netdev} up - [ ${kgate} ] && ip route add default via ${kgate} + ip link set ${vif0} up + ip link set ${pdev} up + if ! ifup ${HWD_CONFIG_0} ${netdev} ; then + if [ ${kip} ] ; then + # use the addresses we grocked from /proc/cmdline + if [ -z "${kmask}" ]; then + PREFIX=32; + else + legacy_to_prefix ${kmask}; fi - fi + ip addr add ${kip}/${PREFIX} dev ${netdev} + ip link set dev ${netdev} up + [ ${kgate} ] && ip route add default via ${kgate} + fi + fi else - # old style without veth0 - transfer_addrs ${netdev} ${bridge} - transfer_routes ${netdev} ${bridge} + # old style without ${vdev} + transfer_addrs ${netdev} ${bridge} + transfer_routes ${netdev} ${bridge} fi - + if [ ${antispoof} == 'yes' ] ; then - antispoofing ${netdev} ${bridge} + antispoofing ${netdev} ${bridge} fi } op_stop () { - if [ "${bridge}" == "null" ] ; then - return + if [ "${bridge}" == "null" ]; then + return + fi + if ! ip link show ${bridge} >/dev/null 2>&1; then + return fi - if ifconfig peth0 2>/dev/null | grep -q peth0 ; then + if ip link show ${pdev} 2>/dev/null >/dev/null; then + ip link set dev ${vif0} down + mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'` + transfer_addrs ${netdev} ${pdev} + ifdown ${netdev} + ip link set ${netdev} down arp off + ip link set ${netdev} addr fe:ff:ff:ff:ff:ff + ip link set ${pdev} down + ip addr flush ${netdev} + ip link set ${pdev} addr ${mac} arp on - ifconfig vif0.0 down - mac=`ifconfig eth0 | grep HWadd | \ - sed -e 's/.*\(..:..:..:..:..:..\).*/\1/'` - ifconfig ${netdev} 0.0.0.0 down - ifconfig ${netdev} hw ether fe:ff:ff:ff:ff:ff + brctl delif ${bridge} ${pdev} + brctl delif ${bridge} ${vif0} + ip link set ${bridge} down - ifconfig p${netdev} down - ifconfig p${netdev} hw ether ${mac} arp - brctl delif ${bridge} p${netdev} - - ip link set eth0 name veth0 - ip link set peth0 name eth0 - ifconfig ${bridge} down - brctl delbr ${bridge} - ifup eth0 + ip link set ${netdev} name ${vdev} + ip link set ${pdev} name ${netdev} + ifup ${netdev} else - transfer_routes ${bridge} ${netdev} + transfer_routes ${bridge} ${netdev} + ip link set ${bridge} down fi + brctl delbr ${bridge} } case ${OP} in start) - op_start - ;; + op_start + ;; stop) - op_stop - ;; + op_stop + ;; status) - show_status ${netdev} ${bridge} - ;; + show_status ${netdev} ${bridge} + ;; *) - echo 'Unknown command: ' ${OP} >&2 - echo 'Valid commands are: start, stop, status' >&2 - exit 1 + echo 'Unknown command: ' ${OP} >&2 + echo 'Valid commands are: start, stop, status' >&2 + exit 1 esac diff --git a/tools/examples/vif-bridge b/tools/examples/vif-bridge index 0174d81116..4a947397f4 100755 --- a/tools/examples/vif-bridge +++ b/tools/examples/vif-bridge @@ -8,7 +8,7 @@ # # Example invocation: # -# vif-bridge up domain=VM1 vif=vif1.0 bridge=xen-br0 ip="128.232.38.45/28 10.10.10.55/24" +# vif-bridge up domain=VM1 vif=vif1.0 bridge=xenbr0 ip="128.232.38.45/28 10.10.10.55/24" # # # Usage: diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index 75152f21db..881eaacfbc 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -33,7 +33,7 @@ # The script used to start/stop networking for xend. (network-script network-bridge) # The default bridge that virtual interfaces should be connected to. -(vif-bridge xen-br0) +(vif-bridge xenbr0) # The default script used to control virtual interfaces. (vif-script vif-bridge) diff --git a/tools/examples/xmexample.vmx b/tools/examples/xmexample.vmx index a15ad321a9..f9665ce67d 100644 --- a/tools/examples/xmexample.vmx +++ b/tools/examples/xmexample.vmx @@ -35,7 +35,7 @@ vcpus=1 # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. -#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xenbr0' ] #---------------------------------------------------------------------------- # Define the disk devices you want the domain to have access to, and diff --git a/tools/examples/xmexample1 b/tools/examples/xmexample1 index be3af30a95..cd73c7c3fa 100644 --- a/tools/examples/xmexample1 +++ b/tools/examples/xmexample1 @@ -36,7 +36,7 @@ name = "ExampleDomain" # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. -#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xenbr0' ] #---------------------------------------------------------------------------- # Define the disk devices you want the domain to have access to, and diff --git a/tools/examples/xmexample2 b/tools/examples/xmexample2 index 8272e84ab5..ba89eef7eb 100644 --- a/tools/examples/xmexample2 +++ b/tools/examples/xmexample2 @@ -67,7 +67,7 @@ vcpus = 4 # make your domain a 4-way # Optionally define mac and/or bridge for the network interfaces. # Random MACs are assigned if not given. -#vif = [ 'mac=aa:00:00:00:00:11, bridge=xen-br0' ] +#vif = [ 'mac=aa:00:00:00:00:11, bridge=xenbr0' ] #---------------------------------------------------------------------------- # Define the disk devices you want the domain to have access to, and diff --git a/tools/ioemu/target-i386-dm/qemu-ifup b/tools/ioemu/target-i386-dm/qemu-ifup index 87bff3410c..a23f1d2b68 100755 --- a/tools/ioemu/target-i386-dm/qemu-ifup +++ b/tools/ioemu/target-i386-dm/qemu-ifup @@ -7,4 +7,4 @@ echo 'config qemu network with xen bridge for ' echo $* ifconfig $1 0.0.0.0 up -brctl addif xen-br0 $1 +brctl addif xenbr0 $1 diff --git a/tools/misc/netfix b/tools/misc/netfix index e18923f132..669a95497a 100644 --- a/tools/misc/netfix +++ b/tools/misc/netfix @@ -3,7 +3,7 @@ #============================================================================ # Copyright (C) 2004 Mike Wray #============================================================================ -# Move the IP address from eth0 onto the Xen bridge (xen-br0). +# Move the IP address from eth0 onto the Xen bridge (xenbr0). # Only works if the bridge control utils (brctl) have been installed. #============================================================================ @@ -19,7 +19,7 @@ long_options = ['help', 'verbose', 'quiet', 'interface=', 'bridge=', 'create'] defaults['interface'] = 'eth0' -defaults['bridge'] = 'xen-br0' +defaults['bridge'] = 'xenbr0' def usage(): print """Usage: diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index e88e8ff4b3..d5d348d94b 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -253,7 +253,7 @@ class XendRoot: return self.get_config_bool('enable-dump', 'no') def get_vif_bridge(self): - return self.get_config_value('vif-bridge', 'xen-br0') + return self.get_config_value('vif-bridge', 'xenbr0') def get_vif_script(self): return self.get_config_value('vif-script', 'vif-bridge') diff --git a/tools/python/xen/xend/server/DevController.py b/tools/python/xen/xend/server/DevController.py index 8141e890b1..0060a687fd 100644 --- a/tools/python/xen/xend/server/DevController.py +++ b/tools/python/xen/xend/server/DevController.py @@ -160,7 +160,7 @@ class DevController: if result: result = int(result) else: - result = 1 + result = 0 t.write("nextDeviceID", str(result + 1)) if t.commit(): return result diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 543502ad95..2bfcce85a7 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -32,34 +32,6 @@ class Daemon: self.traceindent = 0 self.child = 0 - def daemon_pids(self): - pids = [] - pidex = '(?P\d+)' - pythonex = '(?P\S*python\S*)' - cmdex = '(?P.*)' - procre = re.compile('^\s*' + pidex + '\s*' + pythonex + '\s*' + cmdex + '$') - xendre = re.compile('^\S+/xend\s*(start|restart)\s*.*$') - procs = os.popen('ps -e -o pid,args 2>/dev/null') - for proc in procs: - pm = procre.match(proc) - if not pm: continue - xm = xendre.match(pm.group('cmd')) - if not xm: continue - pids.append(int(pm.group('pid'))) - return pids - - def new_cleanup(self, kill=0): - err = 0 - pids = self.daemon_pids() - if kill: - for pid in pids: - print "Killing daemon pid=%d" % pid - os.kill(pid, signal.SIGHUP) - elif pids: - err = 1 - print "Daemon already running: ", pids - return err - def read_pid(self, pidfile): """Read process id from a file. @@ -115,12 +87,9 @@ class Daemon: os.remove(pidfile) return running - def cleanup_xend(self, kill=False): + def cleanup_xend(self, kill): return self.cleanup_process(XEND_PID_FILE, "xend", kill) - def cleanup(self, kill=False): - self.cleanup_xend(kill=kill) - def status(self): """Returns the status of the xend daemon. The return value is defined by the LSB: @@ -156,16 +125,13 @@ class Daemon: # Detach from TTY. os.setsid() - # Detach from standard file descriptors. - # I do this at the file-descriptor level: the overlying Python file - # objects also use fd's 0, 1 and 2. + # Detach from standard file descriptors, and redirect them to + # /dev/null or the log as appropriate. os.close(0) os.close(1) os.close(2) if XEND_DEBUG: os.open('/dev/null', os.O_RDONLY) - # XXX KAF: Why doesn't this capture output from C extensions that - # fprintf(stdout) or fprintf(stderr) ?? os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT) os.dup(1) else: @@ -180,7 +146,7 @@ class Daemon: 0 Success 4 Insufficient privileges """ - xend_pid = self.cleanup_xend() + xend_pid = self.cleanup_xend(False) if self.set_user(): return 4 @@ -294,7 +260,10 @@ class Daemon: return 1 def stop(self): - return self.cleanup(kill=True) + result = self.cleanup_xend(True) + from xen.xend import Vifctl + Vifctl.network("stop") + return result def run(self, status): try: diff --git a/tools/vnet/vnet-module/varp.c b/tools/vnet/vnet-module/varp.c index 5de3d33254..012e29cea8 100644 --- a/tools/vnet/vnet-module/varp.c +++ b/tools/vnet/vnet-module/varp.c @@ -176,7 +176,7 @@ u32 varp_mcast_addr = 0; /** UDP port (network order). */ u16 varp_port = 0; -char *varp_device = "xen-br0"; +char *varp_device = "xenbr0"; #define VarpTable_read_lock(z, flags) do{ (flags) = 0; down(&(z)->lock); } while(0) #define VarpTable_read_unlock(z, flags) do{ (flags) = 0; up(&(z)->lock); } while(0) From e68e8c51d2eb0a5dcab076bc3a74271c4da3e73f Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Wed, 19 Oct 2005 18:18:30 +0100 Subject: [PATCH 100/142] This patch fixes the problem that VMX guest can not get brought up on current tip (changeset 7425). Signed-off-by: Xin Li --- tools/python/xen/lowlevel/xc/xc.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index b264615b3f..e4855158b6 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -424,11 +424,11 @@ static PyObject *pyxc_vmx_build(PyObject *self, unsigned long store_mfn = 0; static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn", - "memsize", "image", "flags", "vcpus", NULL }; + "memsize", "image", "vcpus", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list, + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisi", kwd_list, &dom, &control_evtchn, &store_evtchn, - &memsize, &image, &flags, &vcpus) ) + &memsize, &image, &vcpus) ) return NULL; if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn, @@ -968,12 +968,10 @@ static PyMethodDef pyxc_methods[] = { { "vmx_build", (PyCFunction)pyxc_vmx_build, METH_VARARGS | METH_KEYWORDS, "\n" - "Build a new Linux guest OS.\n" + "Build a new VMX guest OS.\n" " dom [int]: Identifier of domain to build into.\n" - " image [str]: Name of kernel image file. May be gzipped.\n" - " memmap [str]: Memory map.\n\n" - " ramdisk [str, n/a]: Name of ramdisk file, if any.\n" - " cmdline [str, n/a]: Kernel parameters, if any.\n\n" + " image [str]: Name of VMX loader image file.\n" + " vcpus [int, 1]: Number of Virtual CPUS in domain.\n\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "bvtsched_global_set", From 81e869fdc672d0d2126c0ad2e4338fb971b81b85 Mon Sep 17 00:00:00 2001 From: "tristan.gingold@bull.net" Date: Thu, 20 Oct 2005 06:01:11 -0400 Subject: [PATCH 101/142] Makes smp_call_function a real stmt if CONFIG_SMP is not defined. This avoid a GCC warning. --- xen/include/xen/smp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/include/xen/smp.h b/xen/include/xen/smp.h index 57f7580ade..959657d856 100644 --- a/xen/include/xen/smp.h +++ b/xen/include/xen/smp.h @@ -90,7 +90,7 @@ void smp_prepare_boot_cpu(void); #define smp_processor_id() 0 #endif #define hard_smp_processor_id() 0 -#define smp_call_function(func,info,retry,wait) 0 +#define smp_call_function(func,info,retry,wait) do {} while (0) #define on_each_cpu(func,info,retry,wait) ({ func(info); 0; }) #define num_booting_cpus() 1 #define smp_prepare_boot_cpu() do {} while (0) From 27a9d6d6143f17e2cc2f6426b8a1e2843f7fe705 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 20 Oct 2005 11:25:55 +0100 Subject: [PATCH 102/142] Fix NMI race with context switch. The machine used to auto reboot if an NMI was received in a critical time window when context switching domains. There is a small time window when the GDT may become unmapped (after CR3 is updated and before setting GDTR with the new GDT during a domain context switch. If an NMI is received during this time window a triple fault is triggered causing the machine to auto reboot. Bug found and original patch proposed by Jose Renato Santos . Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 21 ++++++++++++++++----- xen/arch/x86/setup.c | 16 ++++++++++++---- 2 files changed, 28 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 25302d0f5f..7d61eadfab 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -226,11 +226,9 @@ struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) if ( (v->vcpu_id = vcpu_id) != 0 ) { - v->arch.schedule_tail = d->vcpu[0]->arch.schedule_tail; + v->arch.schedule_tail = d->vcpu[0]->arch.schedule_tail; v->arch.perdomain_ptes = d->arch.mm_perdomain_pt + (vcpu_id << PDPT_VCPU_SHIFT); - v->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] = - l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); } return v; @@ -256,6 +254,7 @@ void free_perdomain_pt(struct domain *d) void arch_do_createdomain(struct vcpu *v) { struct domain *d = v->domain; + int vcpuid; if ( is_idle_task(d) ) return; @@ -275,8 +274,20 @@ void arch_do_createdomain(struct vcpu *v) set_pfn_from_mfn(virt_to_phys(d->arch.mm_perdomain_pt) >> PAGE_SHIFT, INVALID_M2P_ENTRY); v->arch.perdomain_ptes = d->arch.mm_perdomain_pt; - v->arch.perdomain_ptes[FIRST_RESERVED_GDT_PAGE] = - l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); + + /* + * Map Xen segments into every VCPU's GDT, irrespective of whether every + * VCPU will actually be used. This avoids an NMI race during context + * switch: if we take an interrupt after switching CR3 but before switching + * GDT, and the old VCPU# is invalid in the new domain, we would otherwise + * try to load CS from an invalid table. + */ + for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ ) + { + d->arch.mm_perdomain_pt[ + (vcpuid << PDPT_VCPU_SHIFT) + FIRST_RESERVED_GDT_PAGE] = + l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); + } v->arch.guest_vtable = __linear_l2_table; v->arch.shadow_vtable = __shadow_linear_l2_table; diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index c6653708a1..388735fb49 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -141,6 +141,7 @@ static void __init do_initcalls(void) static void __init start_of_day(void) { int i; + unsigned long vgdt; early_cpu_init(); @@ -158,10 +159,17 @@ static void __init start_of_day(void) arch_do_createdomain(current); - /* Map default GDT into their final position in the idle page table. */ - map_pages_to_xen( - GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE, - virt_to_phys(gdt_table) >> PAGE_SHIFT, 1, PAGE_HYPERVISOR); + /* + * Map default GDT into its final positions in the idle page table. As + * noted in arch_do_createdomain(), we must map for every possible VCPU#. + */ + vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE; + for ( i = 0; i < MAX_VIRT_CPUS; i++ ) + { + map_pages_to_xen( + vgdt, virt_to_phys(gdt_table) >> PAGE_SHIFT, 1, PAGE_HYPERVISOR); + vgdt += 1 << PDPT_VCPU_VA_SHIFT; + } find_smp_config(); From 96491f3ad56627c73b1838e2b2d6acb39bc26599 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 20 Oct 2005 11:27:51 +0100 Subject: [PATCH 103/142] smp_call_function() must be usable as an expression return an integer. Signed-off-by: Keir Fraser --- xen/include/xen/smp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/include/xen/smp.h b/xen/include/xen/smp.h index 959657d856..a99ea486f6 100644 --- a/xen/include/xen/smp.h +++ b/xen/include/xen/smp.h @@ -90,7 +90,7 @@ void smp_prepare_boot_cpu(void); #define smp_processor_id() 0 #endif #define hard_smp_processor_id() 0 -#define smp_call_function(func,info,retry,wait) do {} while (0) +#define smp_call_function(func,info,retry,wait) ({ do {} while (0); 0; }) #define on_each_cpu(func,info,retry,wait) ({ func(info); 0; }) #define num_booting_cpus() 1 #define smp_prepare_boot_cpu() do {} while (0) From 8169ff8c95e4dcf6b2827fd6e6565a6c553275dd Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 20 Oct 2005 11:52:27 +0100 Subject: [PATCH 104/142] disable bogus touchpad device model, which cause annoying dmesg on 2.6 kernel Signed-off-by: Edwin Zhai --- tools/ioemu/hw/pckbd.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/ioemu/hw/pckbd.c b/tools/ioemu/hw/pckbd.c index 85863b433f..455851d9eb 100644 --- a/tools/ioemu/hw/pckbd.c +++ b/tools/ioemu/hw/pckbd.c @@ -29,6 +29,9 @@ /* debug PC keyboard : only mouse */ //#define DEBUG_MOUSE +/* enable synapatic touchpad device model */ +//#define SYNAPTIC + /* Keyboard Controller Commands */ #define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */ #define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */ @@ -117,10 +120,12 @@ typedef struct { int rptr, wptr, count; } KBDQueue; +#ifdef SYNAPTIC typedef struct { int absolute; int high; } TouchPad; +#endif typedef struct KBDState { KBDQueue queue; @@ -142,7 +147,9 @@ typedef struct KBDState { int mouse_dy; int mouse_dz; uint8_t mouse_buttons; +#ifdef SYNAPTIC TouchPad touchpad; +#endif } KBDState; KBDState kbd_state; @@ -399,6 +406,7 @@ static void kbd_mouse_send_packet(KBDState *s) dx1 = s->mouse_dx; dy1 = s->mouse_dy; dz1 = s->mouse_dz; +#ifdef SYNAPTIC if (s->touchpad.absolute) { int dz2, dleftnright, dg, df; @@ -444,6 +452,7 @@ static void kbd_mouse_send_packet(KBDState *s) kbd_queue(s, dy1 & 0xFF, 1); return; } +#endif /* XXX: increase range to 8 bits ? */ if (dx1 > 127) dx1 = 127; @@ -516,9 +525,11 @@ static void pc_kbd_mouse_event(void *opaque, static void kbd_write_mouse(KBDState *s, int val) { +#ifdef SYNAPTIC /* variables needed to store synaptics command info */ static int rr = 0, ss = 0, tt = 0, uu = 0, res_count = 0, last_com = 0; int spare; +#endif #ifdef DEBUG_MOUSE printf("kbd: write mouse 0x%02x\n", val); #endif @@ -536,7 +547,9 @@ int spare; return; } } +#ifdef SYNAPTIC last_com = val; +#endif switch(val) { case AUX_SET_SCALE11: s->mouse_status &= ~MOUSE_STATUS_SCALE21; @@ -568,6 +581,7 @@ int spare; kbd_queue(s, AUX_ACK, 1); break; case AUX_GET_SCALE: +#ifdef SYNAPTIC if (res_count == 4) { /* time for the special stuff */ @@ -681,6 +695,7 @@ int spare; } } else +#endif { /* not a special command, just do the regular stuff */ kbd_queue(s, AUX_ACK, 1); @@ -705,14 +720,18 @@ int spare; s->mouse_sample_rate = 100; s->mouse_resolution = 2; s->mouse_status = 0; +#ifdef SYNAPTIC s->touchpad.absolute = 0; +#endif kbd_queue(s, AUX_ACK, 1); break; case AUX_RESET: s->mouse_sample_rate = 100; s->mouse_resolution = 2; s->mouse_status = 0; +#ifdef SYNAPTIC s->touchpad.absolute = 0; +#endif kbd_queue(s, AUX_ACK, 1); kbd_queue(s, 0xaa, 1); kbd_queue(s, s->mouse_type, 1); @@ -722,6 +741,7 @@ int spare; } break; case AUX_SET_SAMPLE: +#ifdef SYNAPTIC if (res_count == 4 && val == 0x14) { /* time for the special stuff */ @@ -729,6 +749,7 @@ int spare; val = (rr*64) + (ss*16) + (tt*4) + uu; /* TODO: set the mode byte */ } else +#endif s->mouse_sample_rate = val; #if 0 /* detect IMPS/2 or IMEX */ @@ -762,6 +783,7 @@ int spare; s->mouse_write_cmd = -1; break; case AUX_SET_RES: +#ifdef SYNAPTIC if (last_com != AUX_SET_RES) { /* if its not 4 in a row, its not a command */ @@ -790,6 +812,7 @@ int spare; uu = val; break; } +#endif s->mouse_resolution = val; kbd_queue(s, AUX_ACK, 1); s->mouse_write_cmd = -1; @@ -871,8 +894,10 @@ static void kbd_save(QEMUFile* f, void* opaque) qemu_put_be32s(f, &s->mouse_dy); qemu_put_be32s(f, &s->mouse_dz); qemu_put_8s(f, &s->mouse_buttons); +#ifdef SYNAPTIC qemu_put_be32s(f, &s->touchpad.absolute); qemu_put_be32s(f, &s->touchpad.high); +#endif } static int kbd_load(QEMUFile* f, void* opaque, int version_id) @@ -897,8 +922,10 @@ static int kbd_load(QEMUFile* f, void* opaque, int version_id) qemu_get_be32s(f, &s->mouse_dy); qemu_get_be32s(f, &s->mouse_dz); qemu_get_8s(f, &s->mouse_buttons); +#ifdef SYNAPTIC qemu_get_be32s(f, &s->touchpad.absolute); qemu_get_be32s(f, &s->touchpad.high); +#endif return 0; } From 36e3401c278cd5e774e6afc7c74079f959131836 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 20 Oct 2005 12:10:14 +0100 Subject: [PATCH 105/142] New function direct_kernel_remap_pfn_range(). Like direct_remap_pfn_range but doesn't take a vma and implicitly maps into init_mm. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c | 11 ++++++++++- .../include/asm-xen/asm-i386/pgtable.h | 5 +++++ .../include/asm-xen/asm-x86_64/pgtable.h | 6 ++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c index 7d989863df..08aded5dd9 100644 --- a/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c +++ b/linux-2.6-xen-sparse/arch/xen/i386/mm/ioremap.c @@ -123,9 +123,18 @@ int direct_remap_pfn_range(struct vm_area_struct *vma, return __direct_remap_pfn_range( vma->vm_mm, address, mfn, size, prot, domid); } - EXPORT_SYMBOL(direct_remap_pfn_range); +int direct_kernel_remap_pfn_range(unsigned long address, + unsigned long mfn, + unsigned long size, + pgprot_t prot, + domid_t domid) +{ + return __direct_remap_pfn_range( + &init_mm, address, mfn, size, prot, domid); +} +EXPORT_SYMBOL(direct_kernel_remap_pfn_range); /* FIXME: This is horribly broken on PAE */ static int lookup_pte_fn( diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h index 59cc6f60e0..5d55df00a0 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-i386/pgtable.h @@ -455,6 +455,11 @@ int direct_remap_pfn_range(struct vm_area_struct *vma, unsigned long size, pgprot_t prot, domid_t domid); +int direct_kernel_remap_pfn_range(unsigned long address, + unsigned long mfn, + unsigned long size, + pgprot_t prot, + domid_t domid); int create_lookup_pte_addr(struct mm_struct *mm, unsigned long address, unsigned long *ptep); diff --git a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h index 409c40483c..fe4467a7a1 100644 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-x86_64/pgtable.h @@ -533,6 +533,12 @@ int direct_remap_pfn_range(struct vm_area_struct *vma, pgprot_t prot, domid_t domid); +int direct_kernel_remap_pfn_range(unsigned long address, + unsigned long mfn, + unsigned long size, + pgprot_t prot, + domid_t domid); + int create_lookup_pte_addr(struct mm_struct *mm, unsigned long address, unsigned long *ptep); From dd319571b516900ccc1db056976572837aa55f3c Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Thu, 20 Oct 2005 12:34:50 +0100 Subject: [PATCH 106/142] Fix the recently-introduced failure to preserve uuid across a guest reboot. Store the uuid in string form inside XendDomainInfo, to aid this. Add restart-squelching logic to ensure that runaway domains to restart indefinitely. The logic here could be cleverer, say including a backoff for retrying, in case a network block device has gone away, but for now this will do to stop the pathological behaviour. Fixes bug #275. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomainInfo.py | 97 ++++++++++++------------- 1 file changed, 46 insertions(+), 51 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index bb3088d500..bb34abd099 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -87,6 +87,10 @@ VMROOT = '/vm/' ZOMBIE_PREFIX = 'Zombie-' +"""Minimum time between domain restarts in seconds.""" +MINIMUM_RESTART_TIME = 20 + + xc = xen.lowlevel.xc.new() xroot = XendRoot.instance() @@ -102,6 +106,7 @@ log = logging.getLogger("xend.XendDomainInfo") # file, so those are handled separately. ROUNDTRIPPING_CONFIG_ENTRIES = [ ('name', str), + ('uuid', str), ('ssidref', int), ('vcpus', int), ('vcpu_avail', int), @@ -141,7 +146,7 @@ def create(config): log.debug("XendDomainInfo.create(%s)", config) - vm = XendDomainInfo(uuid.create(), parseConfig(config)) + vm = XendDomainInfo(parseConfig(config)) try: vm.construct() vm.initDomain() @@ -166,10 +171,13 @@ def recreate(xeninfo, priv): domid = xeninfo['dom'] uuid1 = xeninfo['handle'] + xeninfo['uuid'] = uuid.toString(uuid1) dompath = GetDomainPath(domid) if not dompath: raise XendError( 'No domain path in store for existing domain %d' % domid) + + log.info("Recreating domain %d, UUID %s.", domid, xeninfo['uuid']) try: vmpath = xstransact.Read(dompath, "vm") if not vmpath: @@ -185,19 +193,15 @@ def recreate(xeninfo, priv): if uuid1 != uuid2: raise XendError( 'Uuid in store does not match uuid for existing domain %d: ' - '%s != %s' % (domid, uuid2_str, uuid.toString(uuid1))) + '%s != %s' % (domid, uuid2_str, xeninfo['uuid'])) - log.info("Recreating domain %d, UUID %s.", domid, uuid2_str) - - vm = XendDomainInfo(uuid1, xeninfo, domid, dompath, True) + vm = XendDomainInfo(xeninfo, domid, dompath, True) except Exception, exn: - log.warn(str(exn)) + if True: + log.warn(str(exn)) - log.info("Recreating domain %d with UUID %s.", domid, - uuid.toString(uuid1)) - - vm = XendDomainInfo(uuid1, xeninfo, domid, dompath, True) + vm = XendDomainInfo(xeninfo, domid, dompath, True) vm.removeDom() vm.removeVm() vm.storeVmDetails() @@ -215,8 +219,7 @@ def restore(config): log.debug("XendDomainInfo.restore(%s)", config) - vm = XendDomainInfo(uuid.fromString(sxp.child_value(config, 'uuid')), - parseConfig(config)) + vm = XendDomainInfo(parseConfig(config)) try: vm.construct() vm.storeVmDetails() @@ -335,19 +338,15 @@ def dom_get(dom): return None class XendDomainInfo: - """Virtual machine object.""" - - """Minimum time between domain restarts in seconds. - """ - MINIMUM_RESTART_TIME = 20 - def __init__(self, uuidbytes, info, domid = None, dompath = None, - augment = False): + def __init__(self, info, domid = None, dompath = None, augment = False): - self.uuidbytes = uuidbytes self.info = info + if not self.infoIsSet('uuid'): + self.info['uuid'] = uuid.toString(uuid.create()) + if domid is not None: self.domid = domid elif 'dom' in info: @@ -355,7 +354,7 @@ class XendDomainInfo: else: self.domid = None - self.vmpath = VMROOT + uuid.toString(uuidbytes) + self.vmpath = VMROOT + self.info['uuid'] self.dompath = dompath if augment: @@ -571,7 +570,7 @@ class XendDomainInfo: def storeVmDetails(self): to_store = { - 'uuid': uuid.toString(self.uuidbytes), + 'uuid': self.info['uuid'], # XXX 'memory/target': str(self.info['memory_KiB']) @@ -928,7 +927,6 @@ class XendDomainInfo: def sxpr(self): sxpr = ['domain', ['domid', self.domid], - ['uuid', uuid.toString(self.uuidbytes)], ['memory', self.info['memory_KiB'] / 1024]] for e in ROUNDTRIPPING_CONFIG_ENTRIES: @@ -1045,8 +1043,9 @@ class XendDomainInfo: self.domid, self.info['ssidref']) - self.domid = xc.domain_create(dom = 0, ssidref = self.info['ssidref'], - handle = self.uuidbytes) + self.domid = xc.domain_create( + dom = 0, ssidref = self.info['ssidref'], + handle = uuid.fromString(self.info['uuid'])) if self.domid < 0: raise VmError('Creating domain failed: name=%s' % @@ -1253,23 +1252,6 @@ class XendDomainInfo: ## private: - def restart_check(self): - """Check if domain restart is OK. - To prevent restart loops, raise an error if it is - less than MINIMUM_RESTART_TIME seconds since the last restart. - """ - tnow = time.time() - if self.restart_time is not None: - tdelta = tnow - self.restart_time - if tdelta < self.MINIMUM_RESTART_TIME: - self.restart_cancel() - msg = 'VM %s restarting too fast' % self.info['name'] - log.error(msg) - raise VmError(msg) - self.restart_time = tnow - self.restart_count += 1 - - def restart(self, rename = False): """Restart the domain after it has exited. @@ -1277,8 +1259,6 @@ class XendDomainInfo: False if it is to be destroyed. """ - # self.restart_check() - config = self.sxpr() if self.readVm('xend/restart_in_progress'): @@ -1290,11 +1270,27 @@ class XendDomainInfo: self.writeVm('xend/restart_in_progress', 'True') + now = time.time() + rst = self.readVm('xend/previous_restart_time') + log.error(rst) + if rst: + rst = float(rst) + timeout = now - rst + if timeout < MINIMUM_RESTART_TIME: + log.error( + 'VM %s restarting too fast (%f seconds since the last ' + 'restart). Refusing to restart to avoid loops.', + self.info['name'], timeout) + self.destroy() + return + + self.writeVm('xend/previous_restart_time', str(now)) + try: if rename: self.preserveForRestart() else: - self.destroy() + self.destroyDomain() try: xd = get_component('xen.xend.XendDomain') @@ -1321,15 +1317,14 @@ class XendDomainInfo: """ new_name = self.generateUniqueName() - new_uuid = uuid.create() - new_uuid_str = uuid.toString(new_uuid) + new_uuid = uuid.toString(uuid.create()) log.info("Renaming dead domain %s (%d, %s) to %s (%s).", - self.info['name'], self.domid, uuid.toString(self.uuidbytes), - new_name, new_uuid_str) + self.info['name'], self.domid, self.info['uuid'], + new_name, new_uuid) self.release_devices() self.info['name'] = new_name - self.uuidbytes = new_uuid - self.vmpath = VMROOT + new_uuid_str + self.info['uuid'] = new_uuid + self.vmpath = VMROOT + new_uuid self.storeVmDetails() self.preserve() From e08da109cdf2aeccf43dd57c2c543efd4fba0631 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Thu, 20 Oct 2005 14:06:07 +0100 Subject: [PATCH 107/142] Set antispoof default to yes, as this seems safer, and is the current behaviour in VifCtl. Signed-off-by: Ewan Mellor --- tools/examples/network-bridge | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/examples/network-bridge b/tools/examples/network-bridge index c6fb1c1f47..360a6513c6 100644 --- a/tools/examples/network-bridge +++ b/tools/examples/network-bridge @@ -25,7 +25,7 @@ # higher value than its default of 1. # bridge The bridge to use (default xenbr${vifnum}). # netdev The interface to add to the bridge (default eth${vifnum}). -# antispoof Whether to use iptables to prevent spoofing (default no). +# antispoof Whether to use iptables to prevent spoofing (default yes). # # start: # Creates the bridge and enslaves netdev to it. @@ -66,7 +66,7 @@ for arg ; do export "${arg}" ; done vifnum=${vifnum:-0} bridge=${bridge:-xenbr${vifnum}} netdev=${netdev:-eth${vifnum}} -antispoof=${antispoof:-no} +antispoof=${antispoof:-yes} pdev="p${netdev}" vdev="veth${vifnum}" From d52306f795efdf1e340c02254d8aea2c35891405 Mon Sep 17 00:00:00 2001 From: "jrb44@plym.cl.cam.ac.uk" Date: Thu, 20 Oct 2005 19:37:41 +0100 Subject: [PATCH 108/142] Avoid specifying bogus DISPLAY=None when spawning device model. Signed-off-by: James Bulpin --- tools/python/xen/xend/image.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index 4a9d9fc740..ee57bba5da 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -311,7 +311,8 @@ class VmxImageHandler(ImageHandler): "-m", "%s" % (self.vm.getMemoryTarget() / 1024)]) args = args + self.dmargs env = dict(os.environ) - env['DISPLAY'] = self.display + if self.display: + env['DISPLAY'] = self.display log.info("spawning device models: %s %s", self.device_model, args) self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env) log.info("device model pid: %d", self.pid) From cc677c9d4eb35eac6928ed74366ddb1896fe2256 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 20 Oct 2005 21:37:15 +0100 Subject: [PATCH 109/142] This patch to the Xen access control module (ACM) and tools: 1. adapts ACM hooks to the slightly changed event channel structure 2. introduces an ACM_GETDECISION command, which enables authorized domains to retrieve policy decisions regarding the sharing of resources (STE policy) from the Xen hypervisor 3. includes cleanup (warnings I found when applying analysis tools such as beam or flawfinder to the ACM code) The get_decision function is useful to enforce: * the security policy on network traffic in the network backends in domain 0; currently there is no enforcement in Dom0 and all packets flow freely * the security policy in block device backends to control which domains can access which vdisk resources I have added a small test program that shows how to use the get_decision ACM interface call, it is in tools/security/get_decision.c and will be compiled together with the policy tools. As usual, the ACM is unconfigured until you switch on a security policy on in Config.mk. Signed-off: Reiner Sailer --- tools/security/Makefile | 1 + tools/security/get_decision.c | 176 ++++ tools/security/secpol_tool.c | 16 +- xen/acm/acm_chinesewall_hooks.c | 913 +++++++++++--------- xen/acm/acm_core.c | 193 +++-- xen/acm/acm_null_hooks.c | 75 +- xen/acm/acm_policy.c | 342 ++++---- xen/acm/acm_simple_type_enforcement_hooks.c | 835 +++++++++--------- xen/common/acm_ops.c | 200 +++-- xen/common/dom0_ops.c | 2 +- xen/common/sched_sedf.c | 12 +- xen/include/acm/acm_core.h | 93 +- xen/include/acm/acm_endian.h | 33 +- xen/include/acm/acm_hooks.h | 34 +- xen/include/public/acm.h | 9 +- xen/include/public/acm_ops.h | 55 +- 16 files changed, 1741 insertions(+), 1248 deletions(-) create mode 100644 tools/security/get_decision.c diff --git a/tools/security/Makefile b/tools/security/Makefile index 7123edb515..ca77c2c81c 100644 --- a/tools/security/Makefile +++ b/tools/security/Makefile @@ -43,6 +43,7 @@ endif build: mk-symlinks $(MAKE) secpol_tool $(MAKE) secpol_xml2bin + $(MAKE) get_decision chmod 700 ./setlabel.sh chmod 700 ./updategrub.sh chmod 700 ./getlabel.sh diff --git a/tools/security/get_decision.c b/tools/security/get_decision.c new file mode 100644 index 0000000000..888c0e8f6a --- /dev/null +++ b/tools/security/get_decision.c @@ -0,0 +1,176 @@ +/**************************************************************** + * get_decision.c + * + * Copyright (C) 2005 IBM Corporation + * + * Authors: + * Reiner Sailer + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation, version 2 of the + * License. + * + * An example program that shows how to retrieve an access control + * decision from the hypervisor ACM based on the currently active policy. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PERROR(_m, _a...) \ +fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \ + errno, strerror(errno)) + +void usage(char *progname) +{ + printf("Use: %s \n", progname); + printf(" Test program illustrating the retrieval of\n"); + printf(" access control decisions from xen. At this time,\n"); + printf(" only sharing (STE) policy decisions are supported.\n"); + printf(" parameter options:\n"); + printf("\t -i domid -i domid\n"); + printf("\t -i domid -s ssidref\n"); + printf("\t -s ssidref -s ssidref\n\n"); + exit(-1); +} + +static inline int do_policycmd(int xc_handle, unsigned int cmd, + unsigned long data) +{ + return ioctl(xc_handle, cmd, data); +} + +static inline int do_xen_hypercall(int xc_handle, + privcmd_hypercall_t * hypercall) +{ + return do_policycmd(xc_handle, + IOCTL_PRIVCMD_HYPERCALL, + (unsigned long) hypercall); +} + +static inline int do_acm_op(int xc_handle, struct acm_op *op) +{ + int ret = -1; + privcmd_hypercall_t hypercall; + + op->interface_version = ACM_INTERFACE_VERSION; + + hypercall.op = __HYPERVISOR_acm_op; + hypercall.arg[0] = (unsigned long) op; + + if (mlock(op, sizeof(*op)) != 0) { + PERROR("Could not lock memory for Xen policy hypercall"); + goto out1; + } + + if ((ret = do_xen_hypercall(xc_handle, &hypercall)) < 0) { + if (errno == EACCES) + fprintf(stderr, "ACM operation failed -- need to" + " rebuild the user-space tool set?\n"); + goto out2; + } + + out2:(void) munlock(op, sizeof(*op)); + out1:return ret; +} + + +/************************ get decision ******************************/ + +/* this example uses two domain ids and retrieves the decision if these domains + * can share information (useful, i.e., to enforce policy onto network traffic in dom0 + */ +int acm_get_decision(int xc_handle, int argc, char *const argv[]) +{ + struct acm_op op; + int ret; + + op.cmd = ACM_GETDECISION; + op.interface_version = ACM_INTERFACE_VERSION; + op.u.getdecision.get_decision_by1 = UNSET; + op.u.getdecision.get_decision_by2 = UNSET; + op.u.getdecision.hook = SHARING; + + while (1) { + int c = getopt(argc, argv, "i:s:"); + if (c == -1) + break; + + if (c == 'i') { + if (op.u.getdecision.get_decision_by1 == UNSET) { + op.u.getdecision.get_decision_by1 = DOMAINID; + op.u.getdecision.id1.domainid = strtoul(optarg, NULL, 0); + } else if (op.u.getdecision.get_decision_by2 == UNSET) { + op.u.getdecision.get_decision_by2 = DOMAINID; + op.u.getdecision.id2.domainid = strtoul(optarg, NULL, 0); + } else + usage(argv[0]); + } else if (c == 's') { + if (op.u.getdecision.get_decision_by1 == UNSET) { + op.u.getdecision.get_decision_by1 = SSIDREF; + op.u.getdecision.id1.ssidref = strtoul(optarg, NULL, 0); + } else if (op.u.getdecision.get_decision_by2 == UNSET) { + op.u.getdecision.get_decision_by2 = SSIDREF; + op.u.getdecision.id2.ssidref = strtoul(optarg, NULL, 0); + } else + usage(argv[0]); + } else + usage(argv[0]); + } + if ((op.u.getdecision.get_decision_by1 == UNSET) || + (op.u.getdecision.get_decision_by2 == UNSET)) + usage(argv[0]); + + if ((ret = do_acm_op(xc_handle, &op))) { + printf("%s: Error getting decision (%d).\n", __func__, ret); + printf("%s: decision = %s.\n", __func__, + (op.u.getdecision.acm_decision == + ACM_ACCESS_PERMITTED) ? "PERMITTED" : ((op.u.getdecision. + acm_decision == + ACM_ACCESS_DENIED) + ? "DENIED" : + "ERROR")); + return ret; + } + return op.u.getdecision.acm_decision; +} + +/***************************** main **************************************/ + +int main(int argc, char **argv) +{ + + int acm_cmd_fd, ret = 0; + + if (argc < 5) + usage(argv[0]); + + if ((acm_cmd_fd = open("/proc/xen/privcmd", O_RDONLY)) <= 0) { + printf("ERROR: Could not open xen privcmd device!\n"); + exit(-1); + } + + ret = acm_get_decision(acm_cmd_fd, argc, argv); + + printf("Decision: %s (%d)\n", + (ret == ACM_ACCESS_PERMITTED) ? "PERMITTED" : + ((ret == ACM_ACCESS_DENIED) ? "DENIED" : "ERROR"), ret); + + close(acm_cmd_fd); + return ret; +} diff --git a/tools/security/secpol_tool.c b/tools/security/secpol_tool.c index 1fd24cad93..a7d206c84d 100644 --- a/tools/security/secpol_tool.c +++ b/tools/security/secpol_tool.c @@ -67,7 +67,7 @@ static inline int do_xen_hypercall(int xc_handle, (unsigned long) hypercall); } -static inline int do_acm_op(int xc_handle, acm_op_t * op) +static inline int do_acm_op(int xc_handle, struct acm_op * op) { int ret = -1; privcmd_hypercall_t hypercall; @@ -275,10 +275,10 @@ void acm_dump_policy_buffer(void *buf, int buflen) /******************************* get policy ******************************/ #define PULL_CACHE_SIZE 8192 -u8 pull_buffer[PULL_CACHE_SIZE]; +uint8_t pull_buffer[PULL_CACHE_SIZE]; int acm_domain_getpolicy(int xc_handle) { - acm_op_t op; + struct acm_op op; int ret; memset(pull_buffer, 0x00, sizeof(pull_buffer)); @@ -299,7 +299,7 @@ int acm_domain_loadpolicy(int xc_handle, const char *filename) struct stat mystat; int ret, fd; off_t len; - u8 *buffer; + uint8_t *buffer; if ((ret = stat(filename, &mystat))) { @@ -321,7 +321,7 @@ int acm_domain_loadpolicy(int xc_handle, const char *filename) } if (len == read(fd, buffer, len)) { - acm_op_t op; + struct acm_op op; /* dump it and then push it down into xen/acm */ acm_dump_policy_buffer(buffer, len); op.cmd = ACM_SETPOLICY; @@ -368,8 +368,8 @@ void dump_ste_stats(struct acm_ste_stats_buffer *ste_stats) #define PULL_STATS_SIZE 8192 int acm_domain_dumpstats(int xc_handle) { - u8 stats_buffer[PULL_STATS_SIZE]; - acm_op_t op; + uint8_t stats_buffer[PULL_STATS_SIZE]; + struct acm_op op; int ret; struct acm_stats_buffer *stats; @@ -442,7 +442,7 @@ int acm_domain_getssid(int xc_handle, int argc, char * const argv[]) /* this includes header and a set of types */ #define MAX_SSIDBUFFER 2000 int ret, i; - acm_op_t op; + struct acm_op op; struct acm_ssid_buffer *hdr; unsigned char *buf; int nice_print = 1; diff --git a/xen/acm/acm_chinesewall_hooks.c b/xen/acm/acm_chinesewall_hooks.c index f52dd50745..872575f7a6 100644 --- a/xen/acm/acm_chinesewall_hooks.c +++ b/xen/acm/acm_chinesewall_hooks.c @@ -26,7 +26,10 @@ * in which case all types of a new domain must be conflict-free * with all types of already running domains. * + * indent -i4 -kr -nut + * */ + #include #include #include @@ -48,270 +51,333 @@ struct chwall_binary_policy chwall_bin_pol; */ int acm_init_chwall_policy(void) { - /* minimal startup policy; policy write-locked already */ - chwall_bin_pol.max_types = 1; - chwall_bin_pol.max_ssidrefs = 2; - chwall_bin_pol.max_conflictsets = 1; - chwall_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types); - chwall_bin_pol.conflict_sets = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types); - chwall_bin_pol.running_types = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types); - chwall_bin_pol.conflict_aggregate_set = (domaintype_t *)xmalloc_array(domaintype_t, chwall_bin_pol.max_types); - - if ((chwall_bin_pol.conflict_sets == NULL) || (chwall_bin_pol.running_types == NULL) || - (chwall_bin_pol.ssidrefs == NULL) || (chwall_bin_pol.conflict_aggregate_set == NULL)) - return ACM_INIT_SSID_ERROR; + /* minimal startup policy; policy write-locked already */ + chwall_bin_pol.max_types = 1; + chwall_bin_pol.max_ssidrefs = 2; + chwall_bin_pol.max_conflictsets = 1; + chwall_bin_pol.ssidrefs = + (domaintype_t *) xmalloc_array(domaintype_t, + chwall_bin_pol.max_ssidrefs * + chwall_bin_pol.max_types); + chwall_bin_pol.conflict_sets = + (domaintype_t *) xmalloc_array(domaintype_t, + chwall_bin_pol.max_conflictsets * + chwall_bin_pol.max_types); + chwall_bin_pol.running_types = + (domaintype_t *) xmalloc_array(domaintype_t, + chwall_bin_pol.max_types); + chwall_bin_pol.conflict_aggregate_set = + (domaintype_t *) xmalloc_array(domaintype_t, + chwall_bin_pol.max_types); - /* initialize state */ - memset((void *)chwall_bin_pol.ssidrefs, 0, chwall_bin_pol.max_ssidrefs*chwall_bin_pol.max_types*sizeof(domaintype_t)); - memset((void *)chwall_bin_pol.conflict_sets, 0, chwall_bin_pol.max_conflictsets*chwall_bin_pol.max_types*sizeof(domaintype_t)); - memset((void *)chwall_bin_pol.running_types, 0, chwall_bin_pol.max_types*sizeof(domaintype_t)); - memset((void *)chwall_bin_pol.conflict_aggregate_set, 0, chwall_bin_pol.max_types*sizeof(domaintype_t)); - return ACM_OK; + if ((chwall_bin_pol.conflict_sets == NULL) + || (chwall_bin_pol.running_types == NULL) + || (chwall_bin_pol.ssidrefs == NULL) + || (chwall_bin_pol.conflict_aggregate_set == NULL)) + return ACM_INIT_SSID_ERROR; + + /* initialize state */ + memset((void *) chwall_bin_pol.ssidrefs, 0, + chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types * + sizeof(domaintype_t)); + memset((void *) chwall_bin_pol.conflict_sets, 0, + chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types * + sizeof(domaintype_t)); + memset((void *) chwall_bin_pol.running_types, 0, + chwall_bin_pol.max_types * sizeof(domaintype_t)); + memset((void *) chwall_bin_pol.conflict_aggregate_set, 0, + chwall_bin_pol.max_types * sizeof(domaintype_t)); + return ACM_OK; } -static int -chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref) +static int chwall_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref) { - struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid); - traceprintk("%s.\n", __func__); - if (chwall_ssidp == NULL) - return ACM_INIT_SSID_ERROR; - /* - * depending on wheter chwall is primary or secondary, get the respective - * part of the global ssidref (same way we'll get the partial ssid pointer) - */ - chwall_ssidp->chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - if ((chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) || - (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)) { - printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset (0).\n", - __func__, chwall_ssidp->chwall_ssidref); - xfree(chwall_ssidp); - return ACM_INIT_SSID_ERROR; - } - (*chwall_ssid) = chwall_ssidp; - printkd("%s: determined chwall_ssidref to %x.\n", - __func__, chwall_ssidp->chwall_ssidref); - return ACM_OK; + struct chwall_ssid *chwall_ssidp = xmalloc(struct chwall_ssid); + traceprintk("%s.\n", __func__); + if (chwall_ssidp == NULL) + return ACM_INIT_SSID_ERROR; + + chwall_ssidp->chwall_ssidref = + GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); + + if ((chwall_ssidp->chwall_ssidref >= chwall_bin_pol.max_ssidrefs) + || (chwall_ssidp->chwall_ssidref == ACM_DEFAULT_LOCAL_SSID)) + { + printkd("%s: ERROR chwall_ssidref(%x) undefined (>max) or unset (0).\n", + __func__, chwall_ssidp->chwall_ssidref); + xfree(chwall_ssidp); + return ACM_INIT_SSID_ERROR; + } + (*chwall_ssid) = chwall_ssidp; + printkd("%s: determined chwall_ssidref to %x.\n", + __func__, chwall_ssidp->chwall_ssidref); + return ACM_OK; } -static void -chwall_free_domain_ssid(void *chwall_ssid) +static void chwall_free_domain_ssid(void *chwall_ssid) { - traceprintk("%s.\n", __func__); - if (chwall_ssid != NULL) - xfree(chwall_ssid); - return; + traceprintk("%s.\n", __func__); + if (chwall_ssid != NULL) + xfree(chwall_ssid); + return; } /* dump chinese wall cache; policy read-locked already */ -static int -chwall_dump_policy(u8 *buf, u16 buf_size) { - struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf; - int ret = 0; +static int chwall_dump_policy(u8 * buf, u32 buf_size) +{ + struct acm_chwall_policy_buffer *chwall_buf = + (struct acm_chwall_policy_buffer *) buf; + int ret = 0; - chwall_buf->chwall_max_types = htonl(chwall_bin_pol.max_types); - chwall_buf->chwall_max_ssidrefs = htonl(chwall_bin_pol.max_ssidrefs); - chwall_buf->policy_code = htonl(ACM_CHINESE_WALL_POLICY); - chwall_buf->chwall_ssid_offset = htonl(sizeof(struct acm_chwall_policy_buffer)); - chwall_buf->chwall_max_conflictsets = htonl(chwall_bin_pol.max_conflictsets); - chwall_buf->chwall_conflict_sets_offset = - htonl( - ntohl(chwall_buf->chwall_ssid_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs * - chwall_bin_pol.max_types); + if (buf_size < sizeof(struct acm_chwall_policy_buffer)) + return -EINVAL; - chwall_buf->chwall_running_types_offset = - htonl( - ntohl(chwall_buf->chwall_conflict_sets_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets * - chwall_bin_pol.max_types); + chwall_buf->chwall_max_types = htonl(chwall_bin_pol.max_types); + chwall_buf->chwall_max_ssidrefs = htonl(chwall_bin_pol.max_ssidrefs); + chwall_buf->policy_code = htonl(ACM_CHINESE_WALL_POLICY); + chwall_buf->chwall_ssid_offset = + htonl(sizeof(struct acm_chwall_policy_buffer)); + chwall_buf->chwall_max_conflictsets = + htonl(chwall_bin_pol.max_conflictsets); + chwall_buf->chwall_conflict_sets_offset = + htonl(ntohl(chwall_buf->chwall_ssid_offset) + + sizeof(domaintype_t) * chwall_bin_pol.max_ssidrefs * + chwall_bin_pol.max_types); + chwall_buf->chwall_running_types_offset = + htonl(ntohl(chwall_buf->chwall_conflict_sets_offset) + + sizeof(domaintype_t) * chwall_bin_pol.max_conflictsets * + chwall_bin_pol.max_types); + chwall_buf->chwall_conflict_aggregate_offset = + htonl(ntohl(chwall_buf->chwall_running_types_offset) + + sizeof(domaintype_t) * chwall_bin_pol.max_types); - chwall_buf->chwall_conflict_aggregate_offset = - htonl( - ntohl(chwall_buf->chwall_running_types_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_types); + ret = ntohl(chwall_buf->chwall_conflict_aggregate_offset) + + sizeof(domaintype_t) * chwall_bin_pol.max_types; - ret = ntohl(chwall_buf->chwall_conflict_aggregate_offset) + - sizeof(domaintype_t) * chwall_bin_pol.max_types; + if (buf_size < ret) + return -EINVAL; - /* now copy buffers over */ - arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_ssid_offset)), - chwall_bin_pol.ssidrefs, - chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types); + /* now copy buffers over */ + arrcpy16((u16 *) (buf + ntohl(chwall_buf->chwall_ssid_offset)), + chwall_bin_pol.ssidrefs, + chwall_bin_pol.max_ssidrefs * chwall_bin_pol.max_types); - arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_conflict_sets_offset)), - chwall_bin_pol.conflict_sets, - chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types); + arrcpy16((u16 *) (buf + + ntohl(chwall_buf->chwall_conflict_sets_offset)), + chwall_bin_pol.conflict_sets, + chwall_bin_pol.max_conflictsets * chwall_bin_pol.max_types); - arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_running_types_offset)), - chwall_bin_pol.running_types, - chwall_bin_pol.max_types); + arrcpy16((u16 *) (buf + + ntohl(chwall_buf->chwall_running_types_offset)), + chwall_bin_pol.running_types, chwall_bin_pol.max_types); - arrcpy16((u16 *)(buf + ntohl(chwall_buf->chwall_conflict_aggregate_offset)), - chwall_bin_pol.conflict_aggregate_set, - chwall_bin_pol.max_types); - return ret; + arrcpy16((u16 *) (buf + + ntohl(chwall_buf->chwall_conflict_aggregate_offset)), + chwall_bin_pol.conflict_aggregate_set, + chwall_bin_pol.max_types); + return ret; } /* adapt security state (running_types and conflict_aggregate_set) to all running * domains; chwall_init_state is called when a policy is changed to bring the security * information into a consistent state and to detect violations (return != 0). * from a security point of view, we simulate that all running domains are re-started - */ + */ static int -chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf, domaintype_t *ssidrefs, domaintype_t *conflict_sets, - domaintype_t *running_types, domaintype_t *conflict_aggregate_set) +chwall_init_state(struct acm_chwall_policy_buffer *chwall_buf, + domaintype_t * ssidrefs, domaintype_t * conflict_sets, + domaintype_t * running_types, + domaintype_t * conflict_aggregate_set) { - int violation = 0, i, j; - struct chwall_ssid *chwall_ssid; - ssidref_t chwall_ssidref; - struct domain **pd; + int violation = 0, i, j; + struct chwall_ssid *chwall_ssid; + ssidref_t chwall_ssidref; + struct domain **pd; - write_lock(&domlist_lock); - /* go through all domains and adjust policy as if this domain was started now */ - pd = &domain_list; - for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - chwall_ssid = GET_SSIDP(ACM_CHINESE_WALL_POLICY, (struct acm_ssid_domain *)(*pd)->ssid); - chwall_ssidref = chwall_ssid->chwall_ssidref; - traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n", - __func__, (*pd)->domain_id, chwall_ssidref); - /* a) adjust types ref-count for running domains */ - for (i=0; i< chwall_buf->chwall_max_types; i++) - running_types[i] += - ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i]; + write_lock(&domlist_lock); + /* go through all domains and adjust policy as if this domain was started now */ + pd = &domain_list; + for (pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list) + { + chwall_ssid = + GET_SSIDP(ACM_CHINESE_WALL_POLICY, + (struct acm_ssid_domain *) (*pd)->ssid); + chwall_ssidref = chwall_ssid->chwall_ssidref; + traceprintk("%s: validating policy for domain %x (chwall-REF=%x).\n", + __func__, (*pd)->domain_id, chwall_ssidref); + /* a) adjust types ref-count for running domains */ + for (i = 0; i < chwall_buf->chwall_max_types; i++) + running_types[i] += + ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i]; - /* b) check for conflict */ - for (i=0; i< chwall_buf->chwall_max_types; i++) - if (conflict_aggregate_set[i] && - ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + i]) { - printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); - violation = 1; - goto out; - } - /* set violation and break out of the loop */ - /* c) adapt conflict aggregate set for this domain (notice conflicts) */ - for (i=0; ichwall_max_conflictsets; i++) { - int common = 0; - /* check if conflict_set_i and ssidref have common types */ - for (j=0; jchwall_max_types; j++) - if (conflict_sets[i*chwall_buf->chwall_max_types + j] && - ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j]) { - common = 1; - break; - } - if (common == 0) - continue; /* try next conflict set */ - /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ - for (j=0; jchwall_max_types; j++) - if (conflict_sets[i*chwall_buf->chwall_max_types + j] && - !ssidrefs[chwall_ssidref*chwall_buf->chwall_max_types + j]) - conflict_aggregate_set[j]++; - } - } + /* b) check for conflict */ + for (i = 0; i < chwall_buf->chwall_max_types; i++) + if (conflict_aggregate_set[i] && + ssidrefs[chwall_ssidref * chwall_buf->chwall_max_types + i]) + { + printk("%s: CHINESE WALL CONFLICT in type %02x.\n", + __func__, i); + violation = 1; + goto out; + } + /* set violation and break out of the loop */ + /* c) adapt conflict aggregate set for this domain (notice conflicts) */ + for (i = 0; i < chwall_buf->chwall_max_conflictsets; i++) + { + int common = 0; + /* check if conflict_set_i and ssidref have common types */ + for (j = 0; j < chwall_buf->chwall_max_types; j++) + if (conflict_sets[i * chwall_buf->chwall_max_types + j] && + ssidrefs[chwall_ssidref * + chwall_buf->chwall_max_types + j]) + { + common = 1; + break; + } + if (common == 0) + continue; /* try next conflict set */ + /* now add types of the conflict set to conflict_aggregate_set (except types in chwall_ssidref) */ + for (j = 0; j < chwall_buf->chwall_max_types; j++) + if (conflict_sets[i * chwall_buf->chwall_max_types + j] && + !ssidrefs[chwall_ssidref * + chwall_buf->chwall_max_types + j]) + conflict_aggregate_set[j]++; + } + } out: - write_unlock(&domlist_lock); - return violation; - /* returning "violation != 0" means that the currently running set of domains would - * not be possible if the new policy had been enforced before starting them; for chinese - * wall, this means that the new policy includes at least one conflict set of which - * more than one type is currently running */ + write_unlock(&domlist_lock); + return violation; + /* returning "violation != 0" means that the currently running set of domains would + * not be possible if the new policy had been enforced before starting them; for chinese + * wall, this means that the new policy includes at least one conflict set of which + * more than one type is currently running */ } -static int -chwall_set_policy(u8 *buf, u16 buf_size) -{ - /* policy write-locked already */ - struct acm_chwall_policy_buffer *chwall_buf = (struct acm_chwall_policy_buffer *)buf; - void *ssids = NULL, *conflict_sets = NULL, *running_types = NULL, *conflict_aggregate_set = NULL; - - /* rewrite the policy due to endianess */ - chwall_buf->policy_code = ntohl(chwall_buf->policy_code); - chwall_buf->policy_version = ntohl(chwall_buf->policy_version); - chwall_buf->chwall_max_types = ntohl(chwall_buf->chwall_max_types); - chwall_buf->chwall_max_ssidrefs = ntohl(chwall_buf->chwall_max_ssidrefs); - chwall_buf->chwall_max_conflictsets = ntohl(chwall_buf->chwall_max_conflictsets); - chwall_buf->chwall_ssid_offset = ntohl(chwall_buf->chwall_ssid_offset); - chwall_buf->chwall_conflict_sets_offset = ntohl(chwall_buf->chwall_conflict_sets_offset); - chwall_buf->chwall_running_types_offset = ntohl(chwall_buf->chwall_running_types_offset); - chwall_buf->chwall_conflict_aggregate_offset = ntohl(chwall_buf->chwall_conflict_aggregate_offset); - - /* policy type and version checks */ - if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) || - (chwall_buf->policy_version != ACM_CHWALL_VERSION)) - return -EINVAL; - - /* 1. allocate new buffers */ - ssids = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types*chwall_buf->chwall_max_ssidrefs); - conflict_sets = xmalloc_array(domaintype_t, chwall_buf->chwall_max_conflictsets*chwall_buf->chwall_max_types); - running_types = xmalloc_array(domaintype_t,chwall_buf->chwall_max_types); - conflict_aggregate_set = xmalloc_array(domaintype_t, chwall_buf->chwall_max_types); - - if ((ssids == NULL)||(conflict_sets == NULL)||(running_types == NULL)||(conflict_aggregate_set == NULL)) - goto error_free; - - /* 2. set new policy */ - if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) * - chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs > buf_size) - goto error_free; - arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset, - sizeof(domaintype_t), - chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs); - - if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) * - chwall_buf->chwall_max_types * chwall_buf->chwall_max_conflictsets > buf_size) - goto error_free; - - arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset, - sizeof(domaintype_t), - chwall_buf->chwall_max_types * chwall_buf->chwall_max_conflictsets); - - /* we also use new state buffers since max_types can change */ - memset(running_types, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types); - memset(conflict_aggregate_set, 0, sizeof(domaintype_t)*chwall_buf->chwall_max_types); - - /* 3. now re-calculate the state for the new policy based on running domains; - * this can fail if new policy is conflicting with running domains */ - if (chwall_init_state(chwall_buf, ssids, conflict_sets, running_types, conflict_aggregate_set)) { - printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__); - goto error_free; /* new policy conflicts with running domains */ - } - /* 4. free old policy buffers, replace with new ones */ - chwall_bin_pol.max_types = chwall_buf->chwall_max_types; - chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs; - chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets; - if (chwall_bin_pol.ssidrefs != NULL) - xfree(chwall_bin_pol.ssidrefs); - if (chwall_bin_pol.conflict_aggregate_set != NULL) - xfree(chwall_bin_pol.conflict_aggregate_set); - if (chwall_bin_pol.running_types != NULL) - xfree(chwall_bin_pol.running_types); - if (chwall_bin_pol.conflict_sets != NULL) - xfree(chwall_bin_pol.conflict_sets); - chwall_bin_pol.ssidrefs = ssids; - chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set; - chwall_bin_pol.running_types = running_types; - chwall_bin_pol.conflict_sets = conflict_sets; - return ACM_OK; - -error_free: - printk("%s: ERROR setting policy.\n", __func__); - if (ssids != NULL) xfree(ssids); - if (conflict_sets != NULL) xfree(conflict_sets); - if (running_types != NULL) xfree(running_types); - if (conflict_aggregate_set != NULL) xfree(conflict_aggregate_set); - return -EFAULT; -} - -static int -chwall_dump_stats(u8 *buf, u16 len) +static int chwall_set_policy(u8 * buf, u32 buf_size) { - /* no stats for Chinese Wall Policy */ - return 0; + /* policy write-locked already */ + struct acm_chwall_policy_buffer *chwall_buf = + (struct acm_chwall_policy_buffer *) buf; + void *ssids = NULL, *conflict_sets = NULL, *running_types = + NULL, *conflict_aggregate_set = NULL; + + if (buf_size < sizeof(struct acm_chwall_policy_buffer)) + return -EINVAL; + + /* rewrite the policy due to endianess */ + chwall_buf->policy_code = ntohl(chwall_buf->policy_code); + chwall_buf->policy_version = ntohl(chwall_buf->policy_version); + chwall_buf->chwall_max_types = ntohl(chwall_buf->chwall_max_types); + chwall_buf->chwall_max_ssidrefs = + ntohl(chwall_buf->chwall_max_ssidrefs); + chwall_buf->chwall_max_conflictsets = + ntohl(chwall_buf->chwall_max_conflictsets); + chwall_buf->chwall_ssid_offset = ntohl(chwall_buf->chwall_ssid_offset); + chwall_buf->chwall_conflict_sets_offset = + ntohl(chwall_buf->chwall_conflict_sets_offset); + chwall_buf->chwall_running_types_offset = + ntohl(chwall_buf->chwall_running_types_offset); + chwall_buf->chwall_conflict_aggregate_offset = + ntohl(chwall_buf->chwall_conflict_aggregate_offset); + + /* policy type and version checks */ + if ((chwall_buf->policy_code != ACM_CHINESE_WALL_POLICY) || + (chwall_buf->policy_version != ACM_CHWALL_VERSION)) + return -EINVAL; + + /* 1. allocate new buffers */ + ssids = + xmalloc_array(domaintype_t, + chwall_buf->chwall_max_types * + chwall_buf->chwall_max_ssidrefs); + conflict_sets = + xmalloc_array(domaintype_t, + chwall_buf->chwall_max_conflictsets * + chwall_buf->chwall_max_types); + running_types = + xmalloc_array(domaintype_t, chwall_buf->chwall_max_types); + conflict_aggregate_set = + xmalloc_array(domaintype_t, chwall_buf->chwall_max_types); + + if ((ssids == NULL) || (conflict_sets == NULL) + || (running_types == NULL) || (conflict_aggregate_set == NULL)) + goto error_free; + + /* 2. set new policy */ + if (chwall_buf->chwall_ssid_offset + sizeof(domaintype_t) * + chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs > + buf_size) + goto error_free; + + arrcpy(ssids, buf + chwall_buf->chwall_ssid_offset, + sizeof(domaintype_t), + chwall_buf->chwall_max_types * chwall_buf->chwall_max_ssidrefs); + + if (chwall_buf->chwall_conflict_sets_offset + sizeof(domaintype_t) * + chwall_buf->chwall_max_types * + chwall_buf->chwall_max_conflictsets > buf_size) + goto error_free; + + arrcpy(conflict_sets, buf + chwall_buf->chwall_conflict_sets_offset, + sizeof(domaintype_t), + chwall_buf->chwall_max_types * + chwall_buf->chwall_max_conflictsets); + + /* we also use new state buffers since max_types can change */ + memset(running_types, 0, + sizeof(domaintype_t) * chwall_buf->chwall_max_types); + memset(conflict_aggregate_set, 0, + sizeof(domaintype_t) * chwall_buf->chwall_max_types); + + /* 3. now re-calculate the state for the new policy based on running domains; + * this can fail if new policy is conflicting with running domains */ + if (chwall_init_state(chwall_buf, ssids, + conflict_sets, running_types, + conflict_aggregate_set)) + { + printk("%s: New policy conflicts with running domains. Policy load aborted.\n", + __func__); + goto error_free; /* new policy conflicts with running domains */ + } + /* 4. free old policy buffers, replace with new ones */ + chwall_bin_pol.max_types = chwall_buf->chwall_max_types; + chwall_bin_pol.max_ssidrefs = chwall_buf->chwall_max_ssidrefs; + chwall_bin_pol.max_conflictsets = chwall_buf->chwall_max_conflictsets; + if (chwall_bin_pol.ssidrefs != NULL) + xfree(chwall_bin_pol.ssidrefs); + if (chwall_bin_pol.conflict_aggregate_set != NULL) + xfree(chwall_bin_pol.conflict_aggregate_set); + if (chwall_bin_pol.running_types != NULL) + xfree(chwall_bin_pol.running_types); + if (chwall_bin_pol.conflict_sets != NULL) + xfree(chwall_bin_pol.conflict_sets); + chwall_bin_pol.ssidrefs = ssids; + chwall_bin_pol.conflict_aggregate_set = conflict_aggregate_set; + chwall_bin_pol.running_types = running_types; + chwall_bin_pol.conflict_sets = conflict_sets; + return ACM_OK; + + error_free: + printk("%s: ERROR setting policy.\n", __func__); + if (ssids != NULL) + xfree(ssids); + if (conflict_sets != NULL) + xfree(conflict_sets); + if (running_types != NULL) + xfree(running_types); + if (conflict_aggregate_set != NULL) + xfree(conflict_aggregate_set); + return -EFAULT; } -static int -chwall_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) +static int chwall_dump_stats(u8 * buf, u16 len) +{ + /* no stats for Chinese Wall Policy */ + return 0; +} + +static int chwall_dump_ssid_types(ssidref_t ssidref, u8 * buf, u16 len) { int i; @@ -319,12 +385,14 @@ chwall_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) if (chwall_bin_pol.max_types > len) return -EFAULT; - if (ssidref >= chwall_bin_pol.max_ssidrefs) - return -EFAULT; + if (ssidref >= chwall_bin_pol.max_ssidrefs) + return -EFAULT; /* read types for chwall ssidref */ - for(i=0; i< chwall_bin_pol.max_types; i++) { - if (chwall_bin_pol.ssidrefs[ssidref * chwall_bin_pol.max_types + i]) + for (i = 0; i < chwall_bin_pol.max_types; i++) + { + if (chwall_bin_pol. + ssidrefs[ssidref * chwall_bin_pol.max_types + i]) buf[i] = 1; else buf[i] = 0; @@ -336,198 +404,239 @@ chwall_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) * Authorization functions ***************************/ - /* -------- DOMAIN OPERATION HOOKS -----------*/ -static int -chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref) +static int chwall_pre_domain_create(void *subject_ssid, ssidref_t ssidref) { - ssidref_t chwall_ssidref; - int i,j; - traceprintk("%s.\n", __func__); + ssidref_t chwall_ssidref; + int i, j; + traceprintk("%s.\n", __func__); - read_lock(&acm_bin_pol_rwlock); - chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); - if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) { - printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n", __func__); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; /* catching and indicating config error */ - } - if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) { - printk("%s: ERROR chwall_ssidref > max(%x).\n", - __func__, chwall_bin_pol.max_ssidrefs-1); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; - } - /* A: chinese wall check for conflicts */ - for (i=0; i< chwall_bin_pol.max_types; i++) - if (chwall_bin_pol.conflict_aggregate_set[i] && - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]) { - printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; - } + read_lock(&acm_bin_pol_rwlock); + chwall_ssidref = GET_SSIDREF(ACM_CHINESE_WALL_POLICY, ssidref); + if (chwall_ssidref == ACM_DEFAULT_LOCAL_SSID) + { + printk("%s: ERROR CHWALL SSID is NOT SET but policy enforced.\n", + __func__); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; /* catching and indicating config error */ + } + if (chwall_ssidref >= chwall_bin_pol.max_ssidrefs) + { + printk("%s: ERROR chwall_ssidref > max(%x).\n", + __func__, chwall_bin_pol.max_ssidrefs - 1); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; + } + /* A: chinese wall check for conflicts */ + for (i = 0; i < chwall_bin_pol.max_types; i++) + if (chwall_bin_pol.conflict_aggregate_set[i] && + chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + i]) + { + printk("%s: CHINESE WALL CONFLICT in type %02x.\n", __func__, i); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; + } - /* B: chinese wall conflict set adjustment (so that other - * other domains simultaneously created are evaluated against this new set)*/ - for (i=0; ichwall_ssidref; + int i, j; + struct chwall_ssid *chwall_ssidp = GET_SSIDP(ACM_CHINESE_WALL_POLICY, + (struct acm_ssid_domain *) + object_ssid); + ssidref_t chwall_ssidref = chwall_ssidp->chwall_ssidref; - traceprintk("%s.\n", __func__); + traceprintk("%s.\n", __func__); - read_lock(&acm_bin_pol_rwlock); - /* adjust running types set */ - for (i=0; i< chwall_bin_pol.max_types; i++) - chwall_bin_pol.running_types[i] -= - chwall_bin_pol.ssidrefs[chwall_ssidref*chwall_bin_pol.max_types + i]; + read_lock(&acm_bin_pol_rwlock); + /* adjust running types set */ + for (i = 0; i < chwall_bin_pol.max_types; i++) + chwall_bin_pol.running_types[i] -= + chwall_bin_pol.ssidrefs[chwall_ssidref * + chwall_bin_pol.max_types + i]; - /* roll-back: re-adjust conflicting types aggregate */ - for (i=0; imods_count > 1) - *initrdidx = 1; + *initrdidx = 1; /* * Try all modules and see whichever could be the binary policy. @@ -115,14 +115,14 @@ acm_setup(unsigned int *initrdidx, #error Architecture unsupported by sHype #endif _policy_len = mod[i].mod_end - mod[i].mod_start; - if (_policy_len < sizeof(struct acm_policy_buffer)) - continue; /* not a policy */ + if (_policy_len < sizeof(struct acm_policy_buffer)) + continue; /* not a policy */ pol = (struct acm_policy_buffer *)_policy_start; if (ntohl(pol->magic) == ACM_MAGIC) { rc = acm_set_policy((void *)_policy_start, - (u16)_policy_len, + (u32)_policy_len, 0); if (rc == ACM_OK) { @@ -145,7 +145,7 @@ acm_setup(unsigned int *initrdidx, } else { - printk("Invalid policy. %d.th module line.\n", i+1); + printk("Invalid policy. %d.th module line.\n", i+1); } } /* end if a binary policy definition, i.e., (ntohl(pol->magic) == ACM_MAGIC ) */ } @@ -158,10 +158,10 @@ acm_init(unsigned int *initrdidx, const multiboot_info_t *mbi, unsigned long initial_images_start) { - int ret = ACM_OK; + int ret = ACM_OK; acm_set_endian(); - write_lock(&acm_bin_pol_rwlock); + write_lock(&acm_bin_pol_rwlock); acm_init_binary_policy(NULL, NULL); /* set primary policy component */ @@ -170,14 +170,14 @@ acm_init(unsigned int *initrdidx, case ACM_CHINESE_WALL_POLICY: acm_init_chwall_policy(); - acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY; - acm_primary_ops = &acm_chinesewall_ops; + acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY; + acm_primary_ops = &acm_chinesewall_ops; break; case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: acm_init_ste_policy(); - acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; - acm_primary_ops = &acm_simple_type_enforcement_ops; + acm_bin_pol.primary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; + acm_primary_ops = &acm_simple_type_enforcement_ops; break; default: @@ -190,9 +190,9 @@ acm_init(unsigned int *initrdidx, /* secondary policy component part */ switch ((ACM_USE_SECURITY_POLICY) >> 4) { case ACM_NULL_POLICY: - acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; - acm_secondary_ops = &acm_null_ops; - break; + acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY; + acm_secondary_ops = &acm_null_ops; + break; case ACM_CHINESE_WALL_POLICY: if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY) @@ -200,9 +200,9 @@ acm_init(unsigned int *initrdidx, ret = -EINVAL; goto out; } - acm_init_chwall_policy(); + acm_init_chwall_policy(); acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY; - acm_secondary_ops = &acm_chinesewall_ops; + acm_secondary_ops = &acm_chinesewall_ops; break; case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY: @@ -211,9 +211,9 @@ acm_init(unsigned int *initrdidx, ret = -EINVAL; goto out; } - acm_init_ste_policy(); - acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; - acm_secondary_ops = &acm_simple_type_enforcement_ops; + acm_init_ste_policy(); + acm_bin_pol.secondary_policy_code = ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY; + acm_secondary_ops = &acm_simple_type_enforcement_ops; break; default: @@ -222,96 +222,103 @@ acm_init(unsigned int *initrdidx, } out: - write_unlock(&acm_bin_pol_rwlock); + write_unlock(&acm_bin_pol_rwlock); - if (ret != ACM_OK) + if (ret != ACM_OK) { - printk("%s: Error setting policies.\n", __func__); + printk("%s: Error initializing policies.\n", __func__); /* here one could imagine a clean panic */ - return -EINVAL; - } - acm_setup(initrdidx, mbi, initial_images_start); - printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, - ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), + return -EINVAL; + } + if (acm_setup(initrdidx, mbi, initial_images_start) != ACM_OK) + { + printk("%s: Error loading policy at boot time.\n", __func__); + /* ignore, just continue with the minimal hardcoded startup policy */ + } + printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__, + ACM_POLICY_NAME(acm_bin_pol.primary_policy_code), ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code)); - return ret; + return ret; } int acm_init_domain_ssid(domid_t id, ssidref_t ssidref) { - struct acm_ssid_domain *ssid; - struct domain *subj = find_domain_by_id(id); - int ret1, ret2; - - if (subj == NULL) + struct acm_ssid_domain *ssid; + struct domain *subj = find_domain_by_id(id); + int ret1, ret2; + + if (subj == NULL) { - printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id); - return ACM_NULL_POINTER_ERROR; - } - if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL) - return ACM_INIT_SSID_ERROR; + printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id); + return ACM_NULL_POINTER_ERROR; + } + if ((ssid = xmalloc(struct acm_ssid_domain)) == NULL) + return ACM_INIT_SSID_ERROR; - ssid->datatype = DOMAIN; - ssid->subject = subj; - ssid->domainid = subj->domain_id; - ssid->primary_ssid = NULL; - ssid->secondary_ssid = NULL; + ssid->datatype = DOMAIN; + ssid->subject = subj; + ssid->domainid = subj->domain_id; + ssid->primary_ssid = NULL; + ssid->secondary_ssid = NULL; - if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY) - ssid->ssidref = ssidref; - else - ssid->ssidref = ACM_DEFAULT_SSID; + if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY) + ssid->ssidref = ssidref; + else + ssid->ssidref = ACM_DEFAULT_SSID; - subj->ssid = ssid; - /* now fill in primary and secondary parts; we only get here through hooks */ - if (acm_primary_ops->init_domain_ssid != NULL) - ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref); - else - ret1 = ACM_OK; + subj->ssid = ssid; + /* now fill in primary and secondary parts; we only get here through hooks */ + if (acm_primary_ops->init_domain_ssid != NULL) + ret1 = acm_primary_ops->init_domain_ssid(&(ssid->primary_ssid), ssidref); + else + ret1 = ACM_OK; - if (acm_secondary_ops->init_domain_ssid != NULL) - ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref); - else - ret2 = ACM_OK; + if (acm_secondary_ops->init_domain_ssid != NULL) + ret2 = acm_secondary_ops->init_domain_ssid(&(ssid->secondary_ssid), ssidref); + else + ret2 = ACM_OK; - if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) + if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) { - printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n", - __func__, subj->domain_id); - acm_free_domain_ssid(ssid); - put_domain(subj); - return ACM_INIT_SSID_ERROR; - } - printk("%s: assigned domain %x the ssidref=%x.\n", + printk("%s: ERROR instantiating individual ssids for domain 0x%02x.\n", + __func__, subj->domain_id); + acm_free_domain_ssid(ssid); + put_domain(subj); + return ACM_INIT_SSID_ERROR; + } + printk("%s: assigned domain %x the ssidref=%x.\n", __func__, id, ssid->ssidref); - put_domain(subj); - return ACM_OK; + put_domain(subj); + return ACM_OK; } -int +void acm_free_domain_ssid(struct acm_ssid_domain *ssid) { - domid_t id; + /* domain is already gone, just ssid is left */ + if (ssid == NULL) + return; - /* domain is already gone, just ssid is left */ - if (ssid == NULL) - { - printk("%s: ACM_NULL_POINTER ERROR.\n", __func__); - return ACM_NULL_POINTER_ERROR; - } - id = ssid->domainid; - ssid->subject = NULL; - - if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */ - acm_primary_ops->free_domain_ssid(ssid->primary_ssid); - ssid->primary_ssid = NULL; - if (acm_secondary_ops->free_domain_ssid != NULL) - acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid); - ssid->secondary_ssid = NULL; - xfree(ssid); - printkd("%s: Freed individual domain ssid (domain=%02x).\n", + ssid->subject = NULL; + if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */ + acm_primary_ops->free_domain_ssid(ssid->primary_ssid); + ssid->primary_ssid = NULL; + if (acm_secondary_ops->free_domain_ssid != NULL) + acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid); + ssid->secondary_ssid = NULL; + xfree(ssid); + printkd("%s: Freed individual domain ssid (domain=%02x).\n", __func__, id); - return ACM_OK; } + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/acm/acm_null_hooks.c b/xen/acm/acm_null_hooks.c index 600397e9fe..27d949378f 100644 --- a/xen/acm/acm_null_hooks.c +++ b/xen/acm/acm_null_hooks.c @@ -11,37 +11,38 @@ * published by the Free Software Foundation, version 2 of the * License. */ + #include static int null_init_domain_ssid(void **ssid, ssidref_t ssidref) { - return ACM_OK; + return ACM_OK; } static void null_free_domain_ssid(void *ssid) { - return; + return; } static int -null_dump_binary_policy(u8 *buf, u16 buf_size) -{ - return 0; +null_dump_binary_policy(u8 *buf, u32 buf_size) +{ + return 0; } static int -null_set_binary_policy(u8 *buf, u16 buf_size) -{ - return ACM_OK; +null_set_binary_policy(u8 *buf, u32 buf_size) +{ + return ACM_OK; } - + static int null_dump_stats(u8 *buf, u16 buf_size) { - /* no stats for NULL policy */ - return 0; + /* no stats for NULL policy */ + return 0; } static int @@ -54,25 +55,35 @@ null_dump_ssid_types(ssidref_t ssidref, u8 *buffer, u16 buf_size) /* now define the hook structure similarly to LSM */ struct acm_operations acm_null_ops = { - .init_domain_ssid = null_init_domain_ssid, - .free_domain_ssid = null_free_domain_ssid, - .dump_binary_policy = null_dump_binary_policy, - .set_binary_policy = null_set_binary_policy, - .dump_statistics = null_dump_stats, - .dump_ssid_types = null_dump_ssid_types, - /* domain management control hooks */ - .pre_domain_create = NULL, - .post_domain_create = NULL, - .fail_domain_create = NULL, - .post_domain_destroy = NULL, - /* event channel control hooks */ - .pre_eventchannel_unbound = NULL, - .fail_eventchannel_unbound = NULL, - .pre_eventchannel_interdomain = NULL, - .fail_eventchannel_interdomain = NULL, - /* grant table control hooks */ - .pre_grant_map_ref = NULL, - .fail_grant_map_ref = NULL, - .pre_grant_setup = NULL, - .fail_grant_setup = NULL + .init_domain_ssid = null_init_domain_ssid, + .free_domain_ssid = null_free_domain_ssid, + .dump_binary_policy = null_dump_binary_policy, + .set_binary_policy = null_set_binary_policy, + .dump_statistics = null_dump_stats, + .dump_ssid_types = null_dump_ssid_types, + /* domain management control hooks */ + .pre_domain_create = NULL, + .post_domain_create = NULL, + .fail_domain_create = NULL, + .post_domain_destroy = NULL, + /* event channel control hooks */ + .pre_eventchannel_unbound = NULL, + .fail_eventchannel_unbound = NULL, + .pre_eventchannel_interdomain = NULL, + .fail_eventchannel_interdomain = NULL, + /* grant table control hooks */ + .pre_grant_map_ref = NULL, + .fail_grant_map_ref = NULL, + .pre_grant_setup = NULL, + .fail_grant_setup = NULL }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/acm/acm_policy.c b/xen/acm/acm_policy.c index d26a82a35b..e316370993 100644 --- a/xen/acm/acm_policy.c +++ b/xen/acm/acm_policy.c @@ -32,165 +32,166 @@ #include int -acm_set_policy(void *buf, u16 buf_size, int isuserbuffer) +acm_set_policy(void *buf, u32 buf_size, int isuserbuffer) { - u8 *policy_buffer = NULL; - struct acm_policy_buffer *pol; - + u8 *policy_buffer = NULL; + struct acm_policy_buffer *pol; + if (buf_size < sizeof(struct acm_policy_buffer)) - return -EFAULT; + return -EFAULT; - /* 1. copy buffer from domain */ - if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) - return -ENOMEM; + /* 1. copy buffer from domain */ + if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; - if (isuserbuffer) { - if (copy_from_user(policy_buffer, buf, buf_size)) + if (isuserbuffer) { + if (copy_from_user(policy_buffer, buf, buf_size)) { - printk("%s: Error copying!\n",__func__); - goto error_free; - } - } else - memcpy(policy_buffer, buf, buf_size); + printk("%s: Error copying!\n",__func__); + goto error_free; + } + } else + memcpy(policy_buffer, buf, buf_size); - /* 2. some sanity checking */ - pol = (struct acm_policy_buffer *)policy_buffer; + /* 2. some sanity checking */ + pol = (struct acm_policy_buffer *)policy_buffer; - if ((ntohl(pol->magic) != ACM_MAGIC) || - (ntohl(pol->policy_version) != ACM_POLICY_VERSION) || - (ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) || - (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) + if ((ntohl(pol->magic) != ACM_MAGIC) || + (ntohl(pol->policy_version) != ACM_POLICY_VERSION) || + (ntohl(pol->primary_policy_code) != acm_bin_pol.primary_policy_code) || + (ntohl(pol->secondary_policy_code) != acm_bin_pol.secondary_policy_code)) { - printkd("%s: Wrong policy magics or versions!\n", __func__); - goto error_free; - } - if (buf_size != ntohl(pol->len)) + printkd("%s: Wrong policy magics or versions!\n", __func__); + goto error_free; + } + if (buf_size != ntohl(pol->len)) { - printk("%s: ERROR in buf size.\n", __func__); - goto error_free; - } + printk("%s: ERROR in buf size.\n", __func__); + goto error_free; + } - /* get bin_policy lock and rewrite policy (release old one) */ - write_lock(&acm_bin_pol_rwlock); + /* get bin_policy lock and rewrite policy (release old one) */ + write_lock(&acm_bin_pol_rwlock); - /* 3. set primary policy data */ - if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset), - ntohl(pol->secondary_buffer_offset) - - ntohl(pol->primary_buffer_offset))) - goto error_lock_free; + /* 3. set primary policy data */ + if (acm_primary_ops->set_binary_policy(buf + ntohl(pol->primary_buffer_offset), + ntohl(pol->secondary_buffer_offset) - + ntohl(pol->primary_buffer_offset))) + goto error_lock_free; - /* 4. set secondary policy data */ - if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset), - ntohl(pol->len) - - ntohl(pol->secondary_buffer_offset))) - goto error_lock_free; + /* 4. set secondary policy data */ + if (acm_secondary_ops->set_binary_policy(buf + ntohl(pol->secondary_buffer_offset), + ntohl(pol->len) - + ntohl(pol->secondary_buffer_offset))) + goto error_lock_free; - write_unlock(&acm_bin_pol_rwlock); - xfree(policy_buffer); - return ACM_OK; + write_unlock(&acm_bin_pol_rwlock); + xfree(policy_buffer); + return ACM_OK; error_lock_free: - write_unlock(&acm_bin_pol_rwlock); + write_unlock(&acm_bin_pol_rwlock); error_free: - printk("%s: Error setting policy.\n", __func__); + printk("%s: Error setting policy.\n", __func__); xfree(policy_buffer); - return -EFAULT; + return -EFAULT; } int -acm_get_policy(void *buf, u16 buf_size) -{ - u8 *policy_buffer; - int ret; - struct acm_policy_buffer *bin_pol; - +acm_get_policy(void *buf, u32 buf_size) +{ + u8 *policy_buffer; + int ret; + struct acm_policy_buffer *bin_pol; + if (buf_size < sizeof(struct acm_policy_buffer)) - return -EFAULT; + return -EFAULT; - if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) - return -ENOMEM; + if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; - read_lock(&acm_bin_pol_rwlock); + read_lock(&acm_bin_pol_rwlock); - bin_pol = (struct acm_policy_buffer *)policy_buffer; - bin_pol->magic = htonl(ACM_MAGIC); - bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code); - bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code); + bin_pol = (struct acm_policy_buffer *)policy_buffer; + bin_pol->magic = htonl(ACM_MAGIC); + bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code); + bin_pol->secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code); - bin_pol->len = htonl(sizeof(struct acm_policy_buffer)); - bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len)); - bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); + bin_pol->len = htonl(sizeof(struct acm_policy_buffer)); + bin_pol->primary_buffer_offset = htonl(ntohl(bin_pol->len)); + bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); - ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset), - buf_size - ntohl(bin_pol->primary_buffer_offset)); - if (ret < 0) - goto error_free_unlock; + ret = acm_primary_ops->dump_binary_policy (policy_buffer + ntohl(bin_pol->primary_buffer_offset), + buf_size - ntohl(bin_pol->primary_buffer_offset)); + if (ret < 0) + goto error_free_unlock; - bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); + bin_pol->len = htonl(ntohl(bin_pol->len) + ret); + bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len)); - ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohl(bin_pol->secondary_buffer_offset), - buf_size - ntohl(bin_pol->secondary_buffer_offset)); - if (ret < 0) - goto error_free_unlock; + ret = acm_secondary_ops->dump_binary_policy(policy_buffer + ntohl(bin_pol->secondary_buffer_offset), + buf_size - ntohl(bin_pol->secondary_buffer_offset)); + if (ret < 0) + goto error_free_unlock; - bin_pol->len = htonl(ntohl(bin_pol->len) + ret); - if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len))) - goto error_free_unlock; + bin_pol->len = htonl(ntohl(bin_pol->len) + ret); + if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len))) + goto error_free_unlock; - read_unlock(&acm_bin_pol_rwlock); - xfree(policy_buffer); - return ACM_OK; + read_unlock(&acm_bin_pol_rwlock); + xfree(policy_buffer); + return ACM_OK; error_free_unlock: - read_unlock(&acm_bin_pol_rwlock); - printk("%s: Error getting policy.\n", __func__); - xfree(policy_buffer); - return -EFAULT; + read_unlock(&acm_bin_pol_rwlock); + printk("%s: Error getting policy.\n", __func__); + xfree(policy_buffer); + return -EFAULT; } int acm_dump_statistics(void *buf, u16 buf_size) -{ +{ /* send stats to user space */ - u8 *stats_buffer; - int len1, len2; - struct acm_stats_buffer acm_stats; + u8 *stats_buffer; + int len1, len2; + struct acm_stats_buffer acm_stats; - if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL) - return -ENOMEM; + if ((stats_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; - read_lock(&acm_bin_pol_rwlock); + read_lock(&acm_bin_pol_rwlock); - len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer), - buf_size - sizeof(struct acm_stats_buffer)); - if (len1 < 0) - goto error_lock_free; - - len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1, - buf_size - sizeof(struct acm_stats_buffer) - len1); - if (len2 < 0) - goto error_lock_free; + len1 = acm_primary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer), + buf_size - sizeof(struct acm_stats_buffer)); + if (len1 < 0) + goto error_lock_free; + + len2 = acm_secondary_ops->dump_statistics(stats_buffer + sizeof(struct acm_stats_buffer) + len1, + buf_size - sizeof(struct acm_stats_buffer) - len1); + if (len2 < 0) + goto error_lock_free; - acm_stats.magic = htonl(ACM_MAGIC); - acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code); - acm_stats.secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code); - acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer)); - acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) + len1); - acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2); - memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer)); + acm_stats.magic = htonl(ACM_MAGIC); + acm_stats.primary_policy_code = htonl(acm_bin_pol.primary_policy_code); + acm_stats.secondary_policy_code = htonl(acm_bin_pol.secondary_policy_code); + acm_stats.primary_stats_offset = htonl(sizeof(struct acm_stats_buffer)); + acm_stats.secondary_stats_offset = htonl(sizeof(struct acm_stats_buffer) + len1); + acm_stats.len = htonl(sizeof(struct acm_stats_buffer) + len1 + len2); - if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2)) - goto error_lock_free; + memcpy(stats_buffer, &acm_stats, sizeof(struct acm_stats_buffer)); - read_unlock(&acm_bin_pol_rwlock); - xfree(stats_buffer); - return ACM_OK; + if (copy_to_user(buf, stats_buffer, sizeof(struct acm_stats_buffer) + len1 + len2)) + goto error_lock_free; + + read_unlock(&acm_bin_pol_rwlock); + xfree(stats_buffer); + return ACM_OK; error_lock_free: - read_unlock(&acm_bin_pol_rwlock); - xfree(stats_buffer); - return -EFAULT; + read_unlock(&acm_bin_pol_rwlock); + xfree(stats_buffer); + return -EFAULT; } @@ -198,57 +199,88 @@ int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size) { /* send stats to user space */ - u8 *ssid_buffer; - int ret; - struct acm_ssid_buffer *acm_ssid; - if (buf_size < sizeof(struct acm_ssid_buffer)) - return -EFAULT; + u8 *ssid_buffer; + int ret; + struct acm_ssid_buffer *acm_ssid; + if (buf_size < sizeof(struct acm_ssid_buffer)) + return -EFAULT; - if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL) - return -ENOMEM; + if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL) + return -ENOMEM; - read_lock(&acm_bin_pol_rwlock); + read_lock(&acm_bin_pol_rwlock); - acm_ssid = (struct acm_ssid_buffer *)ssid_buffer; - acm_ssid->len = sizeof(struct acm_ssid_buffer); - acm_ssid->ssidref = ssidref; - acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code; - acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code; - acm_ssid->primary_types_offset = acm_ssid->len; + acm_ssid = (struct acm_ssid_buffer *)ssid_buffer; + acm_ssid->len = sizeof(struct acm_ssid_buffer); + acm_ssid->ssidref = ssidref; + acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code; + acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code; + acm_ssid->primary_types_offset = acm_ssid->len; - /* ret >= 0 --> ret == max_types */ - ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref), - ssid_buffer + acm_ssid->primary_types_offset, - buf_size - acm_ssid->primary_types_offset); - if (ret < 0) - goto error_free_unlock; + /* ret >= 0 --> ret == max_types */ + ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref), + ssid_buffer + acm_ssid->primary_types_offset, + buf_size - acm_ssid->primary_types_offset); + if (ret < 0) + goto error_free_unlock; - acm_ssid->len += ret; - acm_ssid->primary_max_types = ret; + acm_ssid->len += ret; + acm_ssid->primary_max_types = ret; + acm_ssid->secondary_types_offset = acm_ssid->len; - acm_ssid->secondary_types_offset = acm_ssid->len; + ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref), + ssid_buffer + acm_ssid->secondary_types_offset, + buf_size - acm_ssid->secondary_types_offset); + if (ret < 0) + goto error_free_unlock; - ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref), - ssid_buffer + acm_ssid->secondary_types_offset, - buf_size - acm_ssid->secondary_types_offset); - if (ret < 0) - goto error_free_unlock; + acm_ssid->len += ret; + acm_ssid->secondary_max_types = ret; - acm_ssid->len += ret; - acm_ssid->secondary_max_types = ret; + if (copy_to_user(buf, ssid_buffer, acm_ssid->len)) + goto error_free_unlock; - if (copy_to_user(buf, ssid_buffer, acm_ssid->len)) - goto error_free_unlock; - - read_unlock(&acm_bin_pol_rwlock); - xfree(ssid_buffer); - return ACM_OK; + read_unlock(&acm_bin_pol_rwlock); + xfree(ssid_buffer); + return ACM_OK; error_free_unlock: - read_unlock(&acm_bin_pol_rwlock); - printk("%s: Error getting ssid.\n", __func__); - xfree(ssid_buffer); - return -ENOMEM; + read_unlock(&acm_bin_pol_rwlock); + printk("%s: Error getting ssid.\n", __func__); + xfree(ssid_buffer); + return -ENOMEM; } -/*eof*/ +int +acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, + enum acm_hook_type hook) +{ + int ret = ACM_ACCESS_DENIED; + switch (hook) { + + case SHARING: + /* SHARING Hook restricts access in STE policy only */ + ret = acm_sharing(ssidref1, ssidref2); + break; + + default: + /* deny */ + break; + } + + printkd("%s: ssid1=%x, ssid2=%x, decision=%s.\n", + __func__, ssidref1, ssidref2, + (ret == ACM_ACCESS_PERMITTED) ? "GRANTED" : "DENIED"); + + return ret; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/acm/acm_simple_type_enforcement_hooks.c b/xen/acm/acm_simple_type_enforcement_hooks.c index 7f40177a4e..de08f46c2a 100644 --- a/xen/acm/acm_simple_type_enforcement_hooks.c +++ b/xen/acm/acm_simple_type_enforcement_hooks.c @@ -24,6 +24,7 @@ * share at least on common type. * */ + #include #include #include @@ -35,34 +36,34 @@ struct ste_binary_policy ste_bin_pol; static inline int have_common_type (ssidref_t ref1, ssidref_t ref2) { - int i; - for(i=0; i< ste_bin_pol.max_types; i++) - if ( ste_bin_pol.ssidrefs[ref1*ste_bin_pol.max_types + i] && - ste_bin_pol.ssidrefs[ref2*ste_bin_pol.max_types + i]) { - printkd("%s: common type #%02x.\n", __func__, i); - return 1; - } - return 0; + int i; + for(i=0; i< ste_bin_pol.max_types; i++) + if ( ste_bin_pol.ssidrefs[ref1*ste_bin_pol.max_types + i] && + ste_bin_pol.ssidrefs[ref2*ste_bin_pol.max_types + i]) { + printkd("%s: common type #%02x.\n", __func__, i); + return 1; + } + return 0; } /* Helper function: return = (subj and obj share a common type) */ static int share_common_type(struct domain *subj, struct domain *obj) { - ssidref_t ref_s, ref_o; - int ret; + ssidref_t ref_s, ref_o; + int ret; - if ((subj == NULL) || (obj == NULL) || (subj->ssid == NULL) || (obj->ssid == NULL)) - return 0; - read_lock(&acm_bin_pol_rwlock); - /* lookup the policy-local ssids */ - ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref; - ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref; - /* check whether subj and obj share a common ste type */ - ret = have_common_type(ref_s, ref_o); - read_unlock(&acm_bin_pol_rwlock); - return ret; + if ((subj == NULL) || (obj == NULL) || (subj->ssid == NULL) || (obj->ssid == NULL)) + return 0; + read_lock(&acm_bin_pol_rwlock); + /* lookup the policy-local ssids */ + ref_s = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)subj->ssid)))->ste_ssidref; + ref_o = ((struct ste_ssid *)(GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)obj->ssid)))->ste_ssidref; + /* check whether subj and obj share a common ste type */ + ret = have_common_type(ref_s, ref_o); + read_unlock(&acm_bin_pol_rwlock); + return ret; } /* @@ -71,26 +72,26 @@ static int share_common_type(struct domain *subj, struct domain *obj) */ int acm_init_ste_policy(void) { - /* minimal startup policy; policy write-locked already */ - ste_bin_pol.max_types = 1; - ste_bin_pol.max_ssidrefs = 2; - ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2); - memset(ste_bin_pol.ssidrefs, 0, 2); + /* minimal startup policy; policy write-locked already */ + ste_bin_pol.max_types = 1; + ste_bin_pol.max_ssidrefs = 2; + ste_bin_pol.ssidrefs = (domaintype_t *)xmalloc_array(domaintype_t, 2); + memset(ste_bin_pol.ssidrefs, 0, 2); - if (ste_bin_pol.ssidrefs == NULL) - return ACM_INIT_SSID_ERROR; + if (ste_bin_pol.ssidrefs == NULL) + return ACM_INIT_SSID_ERROR; - /* initialize state so that dom0 can start up and communicate with itself */ - ste_bin_pol.ssidrefs[1] = 1; + /* initialize state so that dom0 can start up and communicate with itself */ + ste_bin_pol.ssidrefs[1] = 1; - /* init stats */ - atomic_set(&(ste_bin_pol.ec_eval_count), 0); - atomic_set(&(ste_bin_pol.ec_denied_count), 0); - atomic_set(&(ste_bin_pol.ec_cachehit_count), 0); - atomic_set(&(ste_bin_pol.gt_eval_count), 0); - atomic_set(&(ste_bin_pol.gt_denied_count), 0); - atomic_set(&(ste_bin_pol.gt_cachehit_count), 0); - return ACM_OK; + /* init stats */ + atomic_set(&(ste_bin_pol.ec_eval_count), 0); + atomic_set(&(ste_bin_pol.ec_denied_count), 0); + atomic_set(&(ste_bin_pol.ec_cachehit_count), 0); + atomic_set(&(ste_bin_pol.gt_eval_count), 0); + atomic_set(&(ste_bin_pol.gt_denied_count), 0); + atomic_set(&(ste_bin_pol.gt_cachehit_count), 0); + return ACM_OK; } @@ -98,62 +99,68 @@ int acm_init_ste_policy(void) static int ste_init_domain_ssid(void **ste_ssid, ssidref_t ssidref) { - int i; - struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid); - traceprintk("%s.\n", __func__); + int i; + struct ste_ssid *ste_ssidp = xmalloc(struct ste_ssid); + traceprintk("%s.\n", __func__); - if (ste_ssidp == NULL) - return ACM_INIT_SSID_ERROR; + if (ste_ssidp == NULL) + return ACM_INIT_SSID_ERROR; - /* get policy-local ssid reference */ - ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref); - if ((ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) || - (ste_ssidp->ste_ssidref == ACM_DEFAULT_LOCAL_SSID)) { - printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n", - __func__, ste_ssidp->ste_ssidref); - xfree(ste_ssidp); - return ACM_INIT_SSID_ERROR; - } - /* clean ste cache */ - for (i=0; iste_cache[i].valid = FREE; + /* get policy-local ssid reference */ + ste_ssidp->ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref); + if ((ste_ssidp->ste_ssidref >= ste_bin_pol.max_ssidrefs) || + (ste_ssidp->ste_ssidref == ACM_DEFAULT_LOCAL_SSID)) { + printkd("%s: ERROR ste_ssidref (%x) undefined or unset (0).\n", + __func__, ste_ssidp->ste_ssidref); + xfree(ste_ssidp); + return ACM_INIT_SSID_ERROR; + } + /* clean ste cache */ + for (i=0; iste_cache[i].valid = FREE; - (*ste_ssid) = ste_ssidp; - printkd("%s: determined ste_ssidref to %x.\n", - __func__, ste_ssidp->ste_ssidref); - return ACM_OK; + (*ste_ssid) = ste_ssidp; + printkd("%s: determined ste_ssidref to %x.\n", + __func__, ste_ssidp->ste_ssidref); + return ACM_OK; } static void ste_free_domain_ssid(void *ste_ssid) { - traceprintk("%s.\n", __func__); - if (ste_ssid != NULL) - xfree(ste_ssid); - return; + traceprintk("%s.\n", __func__); + if (ste_ssid != NULL) + xfree(ste_ssid); + return; } /* dump type enforcement cache; policy read-locked already */ static int -ste_dump_policy(u8 *buf, u16 buf_size) { - struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; - int ret = 0; +ste_dump_policy(u8 *buf, u32 buf_size) { + struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; + int ret = 0; - ste_buf->ste_max_types = htonl(ste_bin_pol.max_types); - ste_buf->ste_max_ssidrefs = htonl(ste_bin_pol.max_ssidrefs); - ste_buf->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); - ste_buf->ste_ssid_offset = htonl(sizeof(struct acm_ste_policy_buffer)); - ret = ntohl(ste_buf->ste_ssid_offset) + - sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types; + if (buf_size < sizeof(struct acm_ste_policy_buffer)) + return -EINVAL; - /* now copy buffer over */ - arrcpy(buf + ntohl(ste_buf->ste_ssid_offset), - ste_bin_pol.ssidrefs, - sizeof(domaintype_t), - ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types); + ste_buf->ste_max_types = htonl(ste_bin_pol.max_types); + ste_buf->ste_max_ssidrefs = htonl(ste_bin_pol.max_ssidrefs); + ste_buf->policy_code = htonl(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY); + ste_buf->ste_ssid_offset = htonl(sizeof(struct acm_ste_policy_buffer)); + ret = ntohl(ste_buf->ste_ssid_offset) + + sizeof(domaintype_t)*ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types; - return ret; + if (buf_size < ret) + return -EINVAL; + + /* now copy buffer over */ + arrcpy(buf + ntohl(ste_buf->ste_ssid_offset), + ste_bin_pol.ssidrefs, + sizeof(domaintype_t), + ste_bin_pol.max_ssidrefs*ste_bin_pol.max_types); + + return ret; } /* ste_init_state is called when a policy is changed to detect violations (return != 0). @@ -176,83 +183,83 @@ ste_init_state(struct acm_ste_policy_buffer *ste_buf, domaintype_t *ssidrefs) /* go through all domains and adjust policy as if this domain was started now */ pd = &domain_list; for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); - ste_ssidref = ste_ssid->ste_ssidref; - traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n", - __func__, (*pd)->domain_id, ste_ssidref); - /* a) check for event channel conflicts */ - for (port=0; port < NR_EVTCHN_BUCKETS; port++) { - spin_lock(&(*pd)->evtchn_lock); - if ((*pd)->evtchn[port] == NULL) { - spin_unlock(&(*pd)->evtchn_lock); - continue; - } - if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) { - rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom; - rdomid = rdom->domain_id; - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) { - rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid; - if ((rdom = find_domain_by_id(rdomid)) == NULL) { - printk("%s: Error finding domain to id %x!\n", __func__, rdomid); - goto out; - } - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - put_domain(rdom); - } else { - spin_unlock(&(*pd)->evtchn_lock); - continue; /* port unused */ - } - spin_unlock(&(*pd)->evtchn_lock); + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(*pd)->ssid); + ste_ssidref = ste_ssid->ste_ssidref; + traceprintk("%s: validating policy for eventch domain %x (ste-Ref=%x).\n", + __func__, (*pd)->domain_id, ste_ssidref); + /* a) check for event channel conflicts */ + for (port=0; port < NR_EVTCHN_BUCKETS; port++) { + spin_lock(&(*pd)->evtchn_lock); + if ((*pd)->evtchn[port] == NULL) { + spin_unlock(&(*pd)->evtchn_lock); + continue; + } + if ((*pd)->evtchn[port]->state == ECS_INTERDOMAIN) { + rdom = (*pd)->evtchn[port]->u.interdomain.remote_dom; + rdomid = rdom->domain_id; + /* rdom now has remote domain */ + ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(rdom->ssid)); + ste_rssidref = ste_rssid->ste_ssidref; + } else if ((*pd)->evtchn[port]->state == ECS_UNBOUND) { + rdomid = (*pd)->evtchn[port]->u.unbound.remote_domid; + if ((rdom = find_domain_by_id(rdomid)) == NULL) { + printk("%s: Error finding domain to id %x!\n", __func__, rdomid); + goto out; + } + /* rdom now has remote domain */ + ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(rdom->ssid)); + ste_rssidref = ste_rssid->ste_ssidref; + put_domain(rdom); + } else { + spin_unlock(&(*pd)->evtchn_lock); + continue; /* port unused */ + } + spin_unlock(&(*pd)->evtchn_lock); - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n", - __func__, (*pd)->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port); - /* check whether on subj->ssid, obj->ssid share a common type*/ - if (!have_common_type(ste_ssidref, ste_rssidref)) { - printkd("%s: Policy violation in event channel domain %x -> domain %x.\n", - __func__, (*pd)->domain_id, rdomid); - goto out; - } - } - /* b) check for grant table conflicts on shared pages */ - if ((*pd)->grant_table->shared == NULL) { - printkd("%s: Grant ... sharing for domain %x not setup!\n", __func__, (*pd)->domain_id); - continue; - } - for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) { - sha_copy = (*pd)->grant_table->shared[i]; - if ( sha_copy.flags ) { - printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n", - __func__, (*pd)->domain_id, i, sha_copy.flags, sha_copy.domid, - (unsigned long)sha_copy.frame); - rdomid = sha_copy.domid; - if ((rdom = find_domain_by_id(rdomid)) == NULL) { - printkd("%s: domain not found ERROR!\n", __func__); - goto out; - }; - /* rdom now has remote domain */ - ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(rdom->ssid)); - ste_rssidref = ste_rssid->ste_ssidref; - put_domain(rdom); - if (!have_common_type(ste_ssidref, ste_rssidref)) { - printkd("%s: Policy violation in grant table sharing domain %x -> domain %x.\n", - __func__, (*pd)->domain_id, rdomid); - goto out; - } - } - } + /* rdom now has remote domain */ + ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(rdom->ssid)); + ste_rssidref = ste_rssid->ste_ssidref; + traceprintk("%s: eventch: domain %x (ssidref %x) --> domain %x (rssidref %x) used (port %x).\n", + __func__, (*pd)->domain_id, ste_ssidref, rdom->domain_id, ste_rssidref, port); + /* check whether on subj->ssid, obj->ssid share a common type*/ + if (!have_common_type(ste_ssidref, ste_rssidref)) { + printkd("%s: Policy violation in event channel domain %x -> domain %x.\n", + __func__, (*pd)->domain_id, rdomid); + goto out; + } + } + /* b) check for grant table conflicts on shared pages */ + if ((*pd)->grant_table->shared == NULL) { + printkd("%s: Grant ... sharing for domain %x not setup!\n", __func__, (*pd)->domain_id); + continue; + } + for ( i = 0; i < NR_GRANT_ENTRIES; i++ ) { + sha_copy = (*pd)->grant_table->shared[i]; + if ( sha_copy.flags ) { + printkd("%s: grant dom (%hu) SHARED (%d) flags:(%hx) dom:(%hu) frame:(%lx)\n", + __func__, (*pd)->domain_id, i, sha_copy.flags, sha_copy.domid, + (unsigned long)sha_copy.frame); + rdomid = sha_copy.domid; + if ((rdom = find_domain_by_id(rdomid)) == NULL) { + printkd("%s: domain not found ERROR!\n", __func__); + goto out; + }; + /* rdom now has remote domain */ + ste_rssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(rdom->ssid)); + ste_rssidref = ste_rssid->ste_ssidref; + put_domain(rdom); + if (!have_common_type(ste_ssidref, ste_rssidref)) { + printkd("%s: Policy violation in grant table sharing domain %x -> domain %x.\n", + __func__, (*pd)->domain_id, rdomid); + goto out; + } + } + } } violation = 0; out: @@ -267,69 +274,72 @@ ste_init_state(struct acm_ste_policy_buffer *ste_buf, domaintype_t *ssidrefs) /* set new policy; policy write-locked already */ static int -ste_set_policy(u8 *buf, u16 buf_size) +ste_set_policy(u8 *buf, u32 buf_size) { - struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; - void *ssidrefsbuf; - struct ste_ssid *ste_ssid; - struct domain **pd; - int i; + struct acm_ste_policy_buffer *ste_buf = (struct acm_ste_policy_buffer *)buf; + void *ssidrefsbuf; + struct ste_ssid *ste_ssid; + struct domain **pd; + int i; - /* Convert endianess of policy */ - ste_buf->policy_code = ntohl(ste_buf->policy_code); - ste_buf->policy_version = ntohl(ste_buf->policy_version); - ste_buf->ste_max_types = ntohl(ste_buf->ste_max_types); - ste_buf->ste_max_ssidrefs = ntohl(ste_buf->ste_max_ssidrefs); - ste_buf->ste_ssid_offset = ntohl(ste_buf->ste_ssid_offset); + if (buf_size < sizeof(struct acm_ste_policy_buffer)) + return -EINVAL; - /* policy type and version checks */ - if ((ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) || - (ste_buf->policy_version != ACM_STE_VERSION)) - return -EINVAL; + /* Convert endianess of policy */ + ste_buf->policy_code = ntohl(ste_buf->policy_code); + ste_buf->policy_version = ntohl(ste_buf->policy_version); + ste_buf->ste_max_types = ntohl(ste_buf->ste_max_types); + ste_buf->ste_max_ssidrefs = ntohl(ste_buf->ste_max_ssidrefs); + ste_buf->ste_ssid_offset = ntohl(ste_buf->ste_ssid_offset); - /* 1. create and copy-in new ssidrefs buffer */ - ssidrefsbuf = xmalloc_array(u8, sizeof(domaintype_t)*ste_buf->ste_max_types*ste_buf->ste_max_ssidrefs); - if (ssidrefsbuf == NULL) { - return -ENOMEM; - } - if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size) - goto error_free; + /* policy type and version checks */ + if ((ste_buf->policy_code != ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) || + (ste_buf->policy_version != ACM_STE_VERSION)) + return -EINVAL; - arrcpy(ssidrefsbuf, - buf + ste_buf->ste_ssid_offset, - sizeof(domaintype_t), - ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types); + /* 1. create and copy-in new ssidrefs buffer */ + ssidrefsbuf = xmalloc_array(u8, sizeof(domaintype_t)*ste_buf->ste_max_types*ste_buf->ste_max_ssidrefs); + if (ssidrefsbuf == NULL) { + return -ENOMEM; + } + if (ste_buf->ste_ssid_offset + sizeof(domaintype_t) * ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types > buf_size) + goto error_free; - /* 2. now re-calculate sharing decisions based on running domains; - * this can fail if new policy is conflicting with sharing of running domains - * now: reject violating new policy; future: adjust sharing through revoking sharing */ - if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) { - printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__); - goto error_free; /* new policy conflicts with sharing of running domains */ - } - /* 3. replace old policy (activate new policy) */ - ste_bin_pol.max_types = ste_buf->ste_max_types; - ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs; - if (ste_bin_pol.ssidrefs) - xfree(ste_bin_pol.ssidrefs); - ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf; + arrcpy(ssidrefsbuf, + buf + ste_buf->ste_ssid_offset, + sizeof(domaintype_t), + ste_buf->ste_max_ssidrefs*ste_buf->ste_max_types); - /* clear all ste caches */ - read_lock(&domlist_lock); - pd = &domain_list; - for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); - for (i=0; iste_cache[i].valid = FREE; - } - read_unlock(&domlist_lock); - return ACM_OK; + /* 2. now re-calculate sharing decisions based on running domains; + * this can fail if new policy is conflicting with sharing of running domains + * now: reject violating new policy; future: adjust sharing through revoking sharing */ + if (ste_init_state(ste_buf, (domaintype_t *)ssidrefsbuf)) { + printk("%s: New policy conflicts with running domains. Policy load aborted.\n", __func__); + goto error_free; /* new policy conflicts with sharing of running domains */ + } + /* 3. replace old policy (activate new policy) */ + ste_bin_pol.max_types = ste_buf->ste_max_types; + ste_bin_pol.max_ssidrefs = ste_buf->ste_max_ssidrefs; + if (ste_bin_pol.ssidrefs) + xfree(ste_bin_pol.ssidrefs); + ste_bin_pol.ssidrefs = (domaintype_t *)ssidrefsbuf; -error_free: - printk("%s: ERROR setting policy.\n", __func__); - if (ssidrefsbuf != NULL) xfree(ssidrefsbuf); - return -EFAULT; + /* clear all ste caches */ + read_lock(&domlist_lock); + pd = &domain_list; + for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(*pd)->ssid); + for (i=0; iste_cache[i].valid = FREE; + } + read_unlock(&domlist_lock); + return ACM_OK; + + error_free: + printk("%s: ERROR setting policy.\n", __func__); + if (ssidrefsbuf != NULL) xfree(ssidrefsbuf); + return -EFAULT; } static int @@ -337,41 +347,6 @@ ste_dump_stats(u8 *buf, u16 buf_len) { struct acm_ste_stats_buffer stats; -#ifdef ACM_DEBUG - int i; - struct ste_ssid *ste_ssid; - struct domain **pd; - - printk("ste: Decision caches:\n"); - /* go through all domains and adjust policy as if this domain was started now */ - read_lock(&domlist_lock); /* go by domain? or directly by global? event/grant list */ - pd = &domain_list; - for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - printk("ste: Cache Domain %02x.\n", (*pd)->domain_id); - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); - for (i=0; iste_cache[i].valid == VALID) ? - "VALID" : "FREE", - (ste_ssid->ste_cache[i].valid == VALID) ? - ste_ssid->ste_cache[i].id : 0xffffffff); - } - read_unlock(&domlist_lock); - /* init stats */ - printk("STE-Policy Security Hook Statistics:\n"); - printk("ste: event_channel eval_count = %x\n", atomic_read(&(ste_bin_pol.ec_eval_count))); - printk("ste: event_channel denied_count = %x\n", atomic_read(&(ste_bin_pol.ec_denied_count))); - printk("ste: event_channel cache_hit_count = %x\n", atomic_read(&(ste_bin_pol.ec_cachehit_count))); - printk("ste:\n"); - printk("ste: grant_table eval_count = %x\n", atomic_read(&(ste_bin_pol.gt_eval_count))); - printk("ste: grant_table denied_count = %x\n", atomic_read(&(ste_bin_pol.gt_denied_count))); - printk("ste: grant_table cache_hit_count = %x\n", atomic_read(&(ste_bin_pol.gt_cachehit_count))); -#endif - - if (buf_len < sizeof(struct acm_ste_stats_buffer)) - return -ENOMEM; - /* now send the hook counts to user space */ stats.ec_eval_count = htonl(atomic_read(&ste_bin_pol.ec_eval_count)); stats.gt_eval_count = htonl(atomic_read(&ste_bin_pol.gt_eval_count)); @@ -379,6 +354,10 @@ ste_dump_stats(u8 *buf, u16 buf_len) stats.gt_denied_count = htonl(atomic_read(&ste_bin_pol.gt_denied_count)); stats.ec_cachehit_count = htonl(atomic_read(&ste_bin_pol.ec_cachehit_count)); stats.gt_cachehit_count = htonl(atomic_read(&ste_bin_pol.gt_cachehit_count)); + + if (buf_len < sizeof(struct acm_ste_stats_buffer)) + return -ENOMEM; + memcpy(buf, &stats, sizeof(struct acm_ste_stats_buffer)); return sizeof(struct acm_ste_stats_buffer); } @@ -392,12 +371,12 @@ ste_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) if (ste_bin_pol.max_types > len) return -EFAULT; - if (ssidref >= ste_bin_pol.max_ssidrefs) - return -EFAULT; + if (ssidref >= ste_bin_pol.max_ssidrefs) + return -EFAULT; /* read types for chwall ssidref */ for(i=0; i< ste_bin_pol.max_types; i++) { - if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i]) + if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i]) buf[i] = 1; else buf[i] = 0; @@ -409,40 +388,40 @@ ste_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len) * returns 1 == cache hit */ static int inline check_cache(struct domain *dom, domid_t rdom) { - struct ste_ssid *ste_ssid; - int i; + struct ste_ssid *ste_ssid; + int i; - printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom); - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(dom)->ssid); + printkd("checking cache: %x --> %x.\n", dom->domain_id, rdom); + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(dom)->ssid); - for(i=0; i< ACM_TE_CACHE_SIZE; i++) { - if ((ste_ssid->ste_cache[i].valid == VALID) && - (ste_ssid->ste_cache[i].id == rdom)) { - printkd("cache hit (entry %x, id= %x!\n", i, ste_ssid->ste_cache[i].id); - return 1; - } - } - return 0; + for(i=0; i< ACM_TE_CACHE_SIZE; i++) { + if ((ste_ssid->ste_cache[i].valid == VALID) && + (ste_ssid->ste_cache[i].id == rdom)) { + printkd("cache hit (entry %x, id= %x!\n", i, ste_ssid->ste_cache[i].id); + return 1; + } + } + return 0; } /* we only get here if there is NO entry yet; no duplication check! */ static void inline cache_result(struct domain *subj, struct domain *obj) { - struct ste_ssid *ste_ssid; - int i; - printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id); - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(subj)->ssid); - for(i=0; i< ACM_TE_CACHE_SIZE; i++) - if (ste_ssid->ste_cache[i].valid == FREE) - break; - if (i< ACM_TE_CACHE_SIZE) { - ste_ssid->ste_cache[i].valid = VALID; - ste_ssid->ste_cache[i].id = obj->domain_id; - } else - printk ("Cache of dom %x is full!\n", subj->domain_id); + struct ste_ssid *ste_ssid; + int i; + printkd("caching from doms: %x --> %x.\n", subj->domain_id, obj->domain_id); + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(subj)->ssid); + for(i=0; i< ACM_TE_CACHE_SIZE; i++) + if (ste_ssid->ste_cache[i].valid == FREE) + break; + if (i< ACM_TE_CACHE_SIZE) { + ste_ssid->ste_cache[i].valid = VALID; + ste_ssid->ste_cache[i].id = obj->domain_id; + } else + printk ("Cache of dom %x is full!\n", subj->domain_id); } /* deletes entries for domain 'id' from all caches (re-use) */ @@ -458,12 +437,12 @@ clean_id_from_cache(domid_t id) read_lock(&domlist_lock); /* look through caches of all domains */ pd = &domain_list; for ( pd = &domain_list; *pd != NULL; pd = &(*pd)->next_in_list ) { - ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, - (struct acm_ssid_domain *)(*pd)->ssid); - for (i=0; iste_cache[i].valid == VALID) && - (ste_ssid->ste_cache[i].id = id)) - ste_ssid->ste_cache[i].valid = FREE; + ste_ssid = GET_SSIDP(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, + (struct acm_ssid_domain *)(*pd)->ssid); + for (i=0; iste_cache[i].valid == VALID) && + (ste_ssid->ste_cache[i].id = id)) + ste_ssid->ste_cache[i].valid = FREE; } read_unlock(&domlist_lock); } @@ -482,15 +461,15 @@ ste_pre_domain_create(void *subject_ssid, ssidref_t ssidref) read_lock(&acm_bin_pol_rwlock); ste_ssidref = GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref); if (ste_ssidref == ACM_DEFAULT_LOCAL_SSID) { - printk("%s: ERROR STE SSID is NOT SET but policy enforced.\n", __func__); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; /* catching and indicating config error */ + printk("%s: ERROR STE SSID is NOT SET but policy enforced.\n", __func__); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; /* catching and indicating config error */ } if (ste_ssidref >= ste_bin_pol.max_ssidrefs) { - printk("%s: ERROR ste_ssidref > max(%x).\n", - __func__, ste_bin_pol.max_ssidrefs-1); - read_unlock(&acm_bin_pol_rwlock); - return ACM_ACCESS_DENIED; + printk("%s: ERROR ste_ssidref > max(%x).\n", + __func__, ste_bin_pol.max_ssidrefs-1); + read_unlock(&acm_bin_pol_rwlock); + return ACM_ACCESS_DENIED; } read_unlock(&acm_bin_pol_rwlock); return ACM_ACCESS_PERMITTED; @@ -506,163 +485,193 @@ ste_post_domain_destroy(void *subject_ssid, domid_t id) /* -------- EVENTCHANNEL OPERATIONS -----------*/ static int ste_pre_eventchannel_unbound(domid_t id) { - struct domain *subj, *obj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", - __func__, current->domain->domain_id, id); + struct domain *subj, *obj; + int ret; + traceprintk("%s: dom%x-->dom%x.\n", + __func__, current->domain->domain_id, id); - if (check_cache(current->domain, id)) { - atomic_inc(&ste_bin_pol.ec_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.ec_eval_count); - subj = current->domain; - obj = find_domain_by_id(id); + if (check_cache(current->domain, id)) { + atomic_inc(&ste_bin_pol.ec_cachehit_count); + return ACM_ACCESS_PERMITTED; + } + atomic_inc(&ste_bin_pol.ec_eval_count); + subj = current->domain; + obj = find_domain_by_id(id); - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.ec_denied_count); - ret = ACM_ACCESS_DENIED; - } - if (obj != NULL) - put_domain(obj); - return ret; + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.ec_denied_count); + ret = ACM_ACCESS_DENIED; + } + if (obj != NULL) + put_domain(obj); + return ret; } static int ste_pre_eventchannel_interdomain(domid_t id1, domid_t id2) { - struct domain *subj, *obj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - (id1 == DOMID_SELF) ? current->domain->domain_id : id1, - (id2 == DOMID_SELF) ? current->domain->domain_id : id2); + struct domain *subj, *obj; + int ret; + traceprintk("%s: dom%x-->dom%x.\n", __func__, + (id1 == DOMID_SELF) ? current->domain->domain_id : id1, + (id2 == DOMID_SELF) ? current->domain->domain_id : id2); - /* following is a bit longer but ensures that we - * "put" only domains that we where "find"-ing - */ - if (id1 == DOMID_SELF) id1 = current->domain->domain_id; - if (id2 == DOMID_SELF) id2 = current->domain->domain_id; + /* following is a bit longer but ensures that we + * "put" only domains that we where "find"-ing + */ + if (id1 == DOMID_SELF) id1 = current->domain->domain_id; + if (id2 == DOMID_SELF) id2 = current->domain->domain_id; - subj = find_domain_by_id(id1); - obj = find_domain_by_id(id2); - if ((subj == NULL) || (obj == NULL)) { - ret = ACM_ACCESS_DENIED; - goto out; - } - /* cache check late, but evtchn is not on performance critical path */ - if (check_cache(subj, obj->domain_id)) { - atomic_inc(&ste_bin_pol.ec_cachehit_count); - ret = ACM_ACCESS_PERMITTED; - goto out; - } - atomic_inc(&ste_bin_pol.ec_eval_count); + subj = find_domain_by_id(id1); + obj = find_domain_by_id(id2); + if ((subj == NULL) || (obj == NULL)) { + ret = ACM_ACCESS_DENIED; + goto out; + } + /* cache check late, but evtchn is not on performance critical path */ + if (check_cache(subj, obj->domain_id)) { + atomic_inc(&ste_bin_pol.ec_cachehit_count); + ret = ACM_ACCESS_PERMITTED; + goto out; + } + atomic_inc(&ste_bin_pol.ec_eval_count); - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.ec_denied_count); - ret = ACM_ACCESS_DENIED; - } + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.ec_denied_count); + ret = ACM_ACCESS_DENIED; + } out: - if (obj != NULL) - put_domain(obj); - if (subj != NULL) - put_domain(subj); - return ret; + if (obj != NULL) + put_domain(obj); + if (subj != NULL) + put_domain(subj); + return ret; } /* -------- SHARED MEMORY OPERATIONS -----------*/ static int ste_pre_grant_map_ref (domid_t id) { - struct domain *obj, *subj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - current->domain->domain_id, id); + struct domain *obj, *subj; + int ret; + traceprintk("%s: dom%x-->dom%x.\n", __func__, + current->domain->domain_id, id); - if (check_cache(current->domain, id)) { - atomic_inc(&ste_bin_pol.gt_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.gt_eval_count); - subj = current->domain; - obj = find_domain_by_id(id); + if (check_cache(current->domain, id)) { + atomic_inc(&ste_bin_pol.gt_cachehit_count); + return ACM_ACCESS_PERMITTED; + } + atomic_inc(&ste_bin_pol.gt_eval_count); + subj = current->domain; + obj = find_domain_by_id(id); - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.gt_denied_count); - printkd("%s: ACCESS DENIED!\n", __func__); - ret = ACM_ACCESS_DENIED; - } - if (obj != NULL) - put_domain(obj); - return ret; + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.gt_denied_count); + printkd("%s: ACCESS DENIED!\n", __func__); + ret = ACM_ACCESS_DENIED; + } + if (obj != NULL) + put_domain(obj); + return ret; } + /* since setting up grant tables involves some implicit information flow from the creating domain to the domain that is setup, we check types in addition to the general authorization */ static int ste_pre_grant_setup (domid_t id) { - struct domain *obj, *subj; - int ret; - traceprintk("%s: dom%x-->dom%x.\n", __func__, - current->domain->domain_id, id); + struct domain *obj, *subj; + int ret; + traceprintk("%s: dom%x-->dom%x.\n", __func__, + current->domain->domain_id, id); - if (check_cache(current->domain, id)) { - atomic_inc(&ste_bin_pol.gt_cachehit_count); - return ACM_ACCESS_PERMITTED; - } - atomic_inc(&ste_bin_pol.gt_eval_count); - /* a) check authorization (eventually use specific capabilities) */ - if (!IS_PRIV(current->domain)) { - printk("%s: Grant table management authorization denied ERROR!\n", __func__); - return ACM_ACCESS_DENIED; - } - /* b) check types */ - subj = current->domain; - obj = find_domain_by_id(id); + if (check_cache(current->domain, id)) { + atomic_inc(&ste_bin_pol.gt_cachehit_count); + return ACM_ACCESS_PERMITTED; + } + atomic_inc(&ste_bin_pol.gt_eval_count); + /* a) check authorization (eventually use specific capabilities) */ + if (!IS_PRIV(current->domain)) { + printk("%s: Grant table management authorization denied ERROR!\n", __func__); + return ACM_ACCESS_DENIED; + } + /* b) check types */ + subj = current->domain; + obj = find_domain_by_id(id); - if (share_common_type(subj, obj)) { - cache_result(subj, obj); - ret = ACM_ACCESS_PERMITTED; - } else { - atomic_inc(&ste_bin_pol.gt_denied_count); - ret = ACM_ACCESS_DENIED; - } - if (obj != NULL) - put_domain(obj); - return ret; + if (share_common_type(subj, obj)) { + cache_result(subj, obj); + ret = ACM_ACCESS_PERMITTED; + } else { + atomic_inc(&ste_bin_pol.gt_denied_count); + ret = ACM_ACCESS_DENIED; + } + if (obj != NULL) + put_domain(obj); + return ret; } +/* -------- DOMAIN-Requested Decision hooks -----------*/ + +static int +ste_sharing(ssidref_t ssidref1, ssidref_t ssidref2) { + if (have_common_type ( + GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref1), + GET_SSIDREF(ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY, ssidref2) + )) + return ACM_ACCESS_PERMITTED; + else + return ACM_ACCESS_DENIED; +} + + /* now define the hook structure similarly to LSM */ struct acm_operations acm_simple_type_enforcement_ops = { - /* policy management services */ - .init_domain_ssid = ste_init_domain_ssid, - .free_domain_ssid = ste_free_domain_ssid, - .dump_binary_policy = ste_dump_policy, - .set_binary_policy = ste_set_policy, - .dump_statistics = ste_dump_stats, + + /* policy management services */ + .init_domain_ssid = ste_init_domain_ssid, + .free_domain_ssid = ste_free_domain_ssid, + .dump_binary_policy = ste_dump_policy, + .set_binary_policy = ste_set_policy, + .dump_statistics = ste_dump_stats, .dump_ssid_types = ste_dump_ssid_types, - /* domain management control hooks */ - .pre_domain_create = ste_pre_domain_create, - .post_domain_create = NULL, - .fail_domain_create = NULL, - .post_domain_destroy = ste_post_domain_destroy, - /* event channel control hooks */ - .pre_eventchannel_unbound = ste_pre_eventchannel_unbound, - .fail_eventchannel_unbound = NULL, - .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain, - .fail_eventchannel_interdomain = NULL, - /* grant table control hooks */ - .pre_grant_map_ref = ste_pre_grant_map_ref, - .fail_grant_map_ref = NULL, - .pre_grant_setup = ste_pre_grant_setup, - .fail_grant_setup = NULL, + + /* domain management control hooks */ + .pre_domain_create = ste_pre_domain_create, + .post_domain_create = NULL, + .fail_domain_create = NULL, + .post_domain_destroy = ste_post_domain_destroy, + + /* event channel control hooks */ + .pre_eventchannel_unbound = ste_pre_eventchannel_unbound, + .fail_eventchannel_unbound = NULL, + .pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain, + .fail_eventchannel_interdomain = NULL, + + /* grant table control hooks */ + .pre_grant_map_ref = ste_pre_grant_map_ref, + .fail_grant_map_ref = NULL, + .pre_grant_setup = ste_pre_grant_setup, + .fail_grant_setup = NULL, + .sharing = ste_sharing, }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/acm_ops.c b/xen/common/acm_ops.c index b058d058ca..4f0d46c3e5 100644 --- a/xen/common/acm_ops.c +++ b/xen/common/acm_ops.c @@ -31,22 +31,23 @@ #if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) -long do_acm_op(acm_op_t * u_acm_op) +long do_acm_op(struct acm_op * u_acm_op) { return -ENOSYS; } #else -typedef enum acm_operation { +enum acm_operation { POLICY, /* access to policy interface (early drop) */ GETPOLICY, /* dump policy cache */ SETPOLICY, /* set policy cache (controls security) */ DUMPSTATS, /* dump policy statistics */ - GETSSID /* retrieve ssidref for domain id */ -} acm_operation_t; + GETSSID, /* retrieve ssidref for domain id (decide inside authorized domains) */ + GETDECISION /* retrieve ACM decision from authorized domains */ +}; -int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops) +int acm_authorize_acm_ops(struct domain *d, enum acm_operation pops) { /* all policy management functions are restricted to privileged domains, * soon we will introduce finer-grained privileges for policy operations @@ -59,10 +60,10 @@ int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops) return ACM_ACCESS_PERMITTED; } -long do_acm_op(acm_op_t * u_acm_op) +long do_acm_op(struct acm_op * u_acm_op) { long ret = 0; - acm_op_t curop, *op = &curop; + struct acm_op curop, *op = &curop; /* check here policy decision for policy commands */ /* for now allow DOM0 only, later indepedently */ @@ -78,81 +79,148 @@ long do_acm_op(acm_op_t * u_acm_op) switch (op->cmd) { case ACM_SETPOLICY: - { - if (acm_authorize_acm_ops(current->domain, SETPOLICY)) - return -EACCES; - printkd("%s: setting policy.\n", __func__); - ret = acm_set_policy(op->u.setpolicy.pushcache, - op->u.setpolicy.pushcache_size, 1); - if (ret == ACM_OK) - ret = 0; - else - ret = -ESRCH; - } - break; + { + if (acm_authorize_acm_ops(current->domain, SETPOLICY)) + return -EACCES; + printkd("%s: setting policy.\n", __func__); + ret = acm_set_policy(op->u.setpolicy.pushcache, + op->u.setpolicy.pushcache_size, 1); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; case ACM_GETPOLICY: - { - if (acm_authorize_acm_ops(current->domain, GETPOLICY)) - return -EACCES; - printkd("%s: getting policy.\n", __func__); - ret = acm_get_policy(op->u.getpolicy.pullcache, - op->u.getpolicy.pullcache_size); - if (ret == ACM_OK) - ret = 0; - else - ret = -ESRCH; - } - break; + { + if (acm_authorize_acm_ops(current->domain, GETPOLICY)) + return -EACCES; + printkd("%s: getting policy.\n", __func__); + ret = acm_get_policy(op->u.getpolicy.pullcache, + op->u.getpolicy.pullcache_size); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; case ACM_DUMPSTATS: - { - if (acm_authorize_acm_ops(current->domain, DUMPSTATS)) - return -EACCES; - printkd("%s: dumping statistics.\n", __func__); - ret = acm_dump_statistics(op->u.dumpstats.pullcache, - op->u.dumpstats.pullcache_size); - if (ret == ACM_OK) - ret = 0; - else - ret = -ESRCH; - } - break; + { + if (acm_authorize_acm_ops(current->domain, DUMPSTATS)) + return -EACCES; + printkd("%s: dumping statistics.\n", __func__); + ret = acm_dump_statistics(op->u.dumpstats.pullcache, + op->u.dumpstats.pullcache_size); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; case ACM_GETSSID: - { - ssidref_t ssidref; + { + ssidref_t ssidref; - if (acm_authorize_acm_ops(current->domain, GETSSID)) - return -EACCES; + if (acm_authorize_acm_ops(current->domain, GETSSID)) + return -EACCES; + printkd("%s: getting SSID.\n", __func__); + if (op->u.getssid.get_ssid_by == SSIDREF) + ssidref = op->u.getssid.id.ssidref; + else if (op->u.getssid.get_ssid_by == DOMAINID) { + struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid); + if (!subj) + return -ESRCH; /* domain not found */ - if (op->u.getssid.get_ssid_by == SSIDREF) - ssidref = op->u.getssid.id.ssidref; - else if (op->u.getssid.get_ssid_by == DOMAINID) { - struct domain *subj = find_domain_by_id(op->u.getssid.id.domainid); - if (!subj) - return -ESRCH; /* domain not found */ + ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; + put_domain(subj); + } else + return -ESRCH; - ssidref = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; - put_domain(subj); - } else - return -ESRCH; + ret = acm_get_ssid(ssidref, + op->u.getssid.ssidbuf, + op->u.getssid.ssidbuf_size); + if (ret == ACM_OK) + ret = 0; + else + ret = -ESRCH; + } + break; - ret = acm_get_ssid(ssidref, - op->u.getssid.ssidbuf, - op->u.getssid.ssidbuf_size); - if (ret == ACM_OK) - ret = 0; - else - ret = -ESRCH; + case ACM_GETDECISION: + { + ssidref_t ssidref1, ssidref2; + + if (acm_authorize_acm_ops(current->domain, GETDECISION)) { + ret = -EACCES; + goto out; } - break; + printkd("%s: getting access control decision.\n", __func__); + if (op->u.getdecision.get_decision_by1 == SSIDREF) { + ssidref1 = op->u.getdecision.id1.ssidref; + } + else if (op->u.getdecision.get_decision_by1 == DOMAINID) { + struct domain *subj = find_domain_by_id(op->u.getdecision.id1.domainid); + if (!subj) { + ret = -ESRCH; /* domain not found */ + goto out; + } + ssidref1 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; + put_domain(subj); + } else { + ret = -ESRCH; + goto out; + } + if (op->u.getdecision.get_decision_by2 == SSIDREF) { + ssidref2 = op->u.getdecision.id2.ssidref; + } + else if (op->u.getdecision.get_decision_by2 == DOMAINID) { + struct domain *subj = find_domain_by_id(op->u.getdecision.id2.domainid); + if (!subj) { + ret = -ESRCH; /* domain not found */ + goto out; + } + ssidref2 = ((struct acm_ssid_domain *)(subj->ssid))->ssidref; + put_domain(subj); + } else { + ret = -ESRCH; + goto out; + } + ret = acm_get_decision(ssidref1, ssidref2, op->u.getdecision.hook); + } + break; default: ret = -ESRCH; - } + + out: + if (ret == ACM_ACCESS_PERMITTED) { + op->u.getdecision.acm_decision = ACM_ACCESS_PERMITTED; + ret = 0; + } else if (ret == ACM_ACCESS_DENIED) { + op->u.getdecision.acm_decision = ACM_ACCESS_DENIED; + ret = 0; + } else { + op->u.getdecision.acm_decision = ACM_ACCESS_DENIED; + if (ret > 0) + ret = -ret; + } + /* copy decision back to user space */ + copy_to_user(u_acm_op, op, sizeof(*op)); return ret; } #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 76b4a020fa..8ae5f194ad 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -199,7 +199,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) /* * If we're on a HT system, we only use the first HT for dom0, other * domains will all share the second HT of each CPU. Since dom0 is on - * CPU 0, we favour high numbered CPUs in the event of a tie. + * CPU 0, we favour high numbered CPUs in the event of a tie. */ pro = smp_num_siblings - 1; for ( i = pro; i < num_online_cpus(); i += smp_num_siblings ) diff --git a/xen/common/sched_sedf.c b/xen/common/sched_sedf.c index 9fb52e4099..b94143a4a5 100644 --- a/xen/common/sched_sedf.c +++ b/xen/common/sched_sedf.c @@ -1150,7 +1150,7 @@ void sedf_wake(struct vcpu *d) { inf->block_tot++; #endif if (unlikely(now < PERIOD_BEGIN(inf))) { - PRINT(4,"extratime unblock\n"); + PRINT(4,"extratime unblock\n"); /* unblocking in extra-time! */ #if (EXTRA == EXTRA_BLOCK_WEIGHT) if (inf->status & EXTRA_WANT_PEN_Q) { @@ -1459,3 +1459,13 @@ struct scheduler sched_sedf_def = { .wake = sedf_wake, .adjdom = sedf_adjdom, }; + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/acm/acm_core.h b/xen/include/acm/acm_core.h index a2e039933d..eaa46ee3d5 100644 --- a/xen/include/acm/acm_core.h +++ b/xen/include/acm/acm_core.h @@ -15,6 +15,7 @@ * for the access control module and relevant policies * */ + #ifndef _ACM_CORE_H #define _ACM_CORE_H @@ -25,30 +26,30 @@ /* Xen-internal representation of the binary policy */ struct acm_binary_policy { - u16 primary_policy_code; - u16 secondary_policy_code; - void *primary_binary_policy; - void *secondary_binary_policy; - + u16 primary_policy_code; + u16 secondary_policy_code; + void *primary_binary_policy; + void *secondary_binary_policy; + }; struct chwall_binary_policy { - u16 max_types; - u16 max_ssidrefs; - u16 max_conflictsets; - domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ - domaintype_t *conflict_aggregate_set; /* [max_types] */ - domaintype_t *running_types; /* [max_types] */ - domaintype_t *conflict_sets; /* [max_conflictsets][max_types]*/ + u32 max_types; + u32 max_ssidrefs; + u32 max_conflictsets; + domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ + domaintype_t *conflict_aggregate_set; /* [max_types] */ + domaintype_t *running_types; /* [max_types] */ + domaintype_t *conflict_sets; /* [max_conflictsets][max_types]*/ }; struct ste_binary_policy { - u16 max_types; - u16 max_ssidrefs; - domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ - atomic_t ec_eval_count, gt_eval_count; - atomic_t ec_denied_count, gt_denied_count; - atomic_t ec_cachehit_count, gt_cachehit_count; + u32 max_types; + u32 max_ssidrefs; + domaintype_t *ssidrefs; /* [max_ssidrefs][max_types] */ + atomic_t ec_eval_count, gt_eval_count; + atomic_t ec_denied_count, gt_denied_count; + atomic_t ec_cachehit_count, gt_cachehit_count; }; /* global acm policy */ @@ -63,7 +64,7 @@ enum acm_datatype { DOMAIN }; /* defines number of access decisions to other domains can be cached * one entry per domain, TE does not distinguish evtchn or grant_table */ -#define ACM_TE_CACHE_SIZE 8 +#define ACM_TE_CACHE_SIZE 8 enum acm_ste_flag { VALID, FREE }; /* cache line: @@ -72,57 +73,67 @@ enum acm_ste_flag { VALID, FREE }; * on domain cache_line.id */ struct acm_ste_cache_line { - enum acm_ste_flag valid; - domid_t id; + enum acm_ste_flag valid; + domid_t id; }; /* general definition of a subject security id */ struct acm_ssid_domain { - enum acm_datatype datatype; /* type of subject (e.g., partition) */ - ssidref_t ssidref; /* combined security reference */ - void *primary_ssid; /* primary policy ssid part (e.g. chinese wall) */ - void *secondary_ssid; /* secondary policy ssid part (e.g. type enforcement) */ - struct domain *subject; /* backpointer to subject structure */ - domid_t domainid; /* replicate id */ + enum acm_datatype datatype; /* type of subject (e.g., partition) */ + ssidref_t ssidref; /* combined security reference */ + void *primary_ssid; /* primary policy ssid part (e.g. chinese wall) */ + void *secondary_ssid; /* secondary policy ssid part (e.g. type enforcement) */ + struct domain *subject; /* backpointer to subject structure */ + domid_t domainid; /* replicate id */ }; /* chinese wall ssid type */ struct chwall_ssid { - ssidref_t chwall_ssidref; + ssidref_t chwall_ssidref; }; /* simple type enforcement ssid type */ struct ste_ssid { - ssidref_t ste_ssidref; - struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision cache */ + ssidref_t ste_ssidref; + struct acm_ste_cache_line ste_cache[ACM_TE_CACHE_SIZE]; /* decision cache */ }; /* macros to access ssidref for primary / secondary policy - * primary ssidref = lower 16 bit - * secondary ssidref = higher 16 bit + * primary ssidref = lower 16 bit + * secondary ssidref = higher 16 bit */ #define ACM_PRIMARY(ssidref) \ - ((ssidref) & 0xffff) + ((ssidref) & 0xffff) #define ACM_SECONDARY(ssidref) \ - ((ssidref) >> 16) + ((ssidref) >> 16) #define GET_SSIDREF(POLICY, ssidref) \ - ((POLICY) == acm_bin_pol.primary_policy_code) ? \ - ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref) + ((POLICY) == acm_bin_pol.primary_policy_code) ? \ + ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref) /* macros to access ssid pointer for primary / secondary policy */ #define GET_SSIDP(POLICY, ssid) \ - ((POLICY) == acm_bin_pol.primary_policy_code) ? \ - ((ssid)->primary_ssid) : ((ssid)->secondary_ssid) + ((POLICY) == acm_bin_pol.primary_policy_code) ? \ + ((ssid)->primary_ssid) : ((ssid)->secondary_ssid) /* protos */ int acm_init_domain_ssid(domid_t id, ssidref_t ssidref); -int acm_free_domain_ssid(struct acm_ssid_domain *ssid); -int acm_set_policy(void *buf, u16 buf_size, int isuserbuffer); -int acm_get_policy(void *buf, u16 buf_size); +void acm_free_domain_ssid(struct acm_ssid_domain *ssid); +int acm_set_policy(void *buf, u32 buf_size, int isuserbuffer); +int acm_get_policy(void *buf, u32 buf_size); int acm_dump_statistics(void *buf, u16 buf_size); int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size); +int acm_get_decision(ssidref_t ssidref1, ssidref_t ssidref2, enum acm_hook_type hook); #endif +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/acm/acm_endian.h b/xen/include/acm/acm_endian.h index fd7229b846..49d23b5d04 100644 --- a/xen/include/acm/acm_endian.h +++ b/xen/include/acm/acm_endian.h @@ -18,6 +18,7 @@ * big-endian policy interface * */ + #ifndef _ACM_ENDIAN_H #define _ACM_ENDIAN_H @@ -30,10 +31,10 @@ static inline u32 ntohl(u32 x) { if (little_endian) return - ( (((x) >> 24) & 0xff )| - (((x) >> 8) & 0xff00 )| - (((x) << 8) & 0xff0000 )| - (((x) << 24) & 0xff000000) ); + ( (((x) >> 24) & 0xff )| + (((x) >> 8) & 0xff00 )| + (((x) << 8) & 0xff0000 )| + (((x) << 24) & 0xff000000) ); else return x; } @@ -42,10 +43,10 @@ static inline u16 ntohs(u16 x) { if (little_endian) return - ( (((x) >> 8) & 0xff )| - (((x) << 8) & 0xff00 ) ); + ( (((x) >> 8) & 0xff )| + (((x) << 8) & 0xff00 ) ); else - return x; + return x; } #define htonl(x) ntohl(x) @@ -55,8 +56,8 @@ static inline void arrcpy16(u16 *dest, const u16 *src, size_t n) { unsigned int i = 0; while (i < n) { - dest[i] = htons(src[i]); - i++; + dest[i] = htons(src[i]); + i++; } } @@ -64,8 +65,8 @@ static inline void arrcpy32(u32 *dest, const u32 *src, size_t n) { unsigned int i = 0; while (i < n) { - dest[i] = htonl(src[i]); - i++; + dest[i] = htonl(src[i]); + i++; } } @@ -86,3 +87,13 @@ static inline void arrcpy(void *dest, const void *src, unsigned int elsize, size } #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/acm/acm_hooks.h b/xen/include/acm/acm_hooks.h index 49f1e70cc9..a79acf2952 100644 --- a/xen/include/acm/acm_hooks.h +++ b/xen/include/acm/acm_hooks.h @@ -15,6 +15,7 @@ * sHype hooks that are called throughout Xen. * */ + #ifndef _ACM_HOOKS_H #define _ACM_HOOKS_H @@ -89,8 +90,8 @@ struct acm_operations { /* policy management functions (must always be defined!) */ int (*init_domain_ssid) (void **ssid, ssidref_t ssidref); void (*free_domain_ssid) (void *ssid); - int (*dump_binary_policy) (u8 *buffer, u16 buf_size); - int (*set_binary_policy) (u8 *buffer, u16 buf_size); + int (*dump_binary_policy) (u8 *buffer, u32 buf_size); + int (*set_binary_policy) (u8 *buffer, u32 buf_size); int (*dump_statistics) (u8 *buffer, u16 buf_size); int (*dump_ssid_types) (ssidref_t ssidref, u8 *buffer, u16 buf_size); /* domain management control hooks (can be NULL) */ @@ -108,6 +109,8 @@ struct acm_operations { void (*fail_grant_map_ref) (domid_t id); int (*pre_grant_setup) (domid_t id); void (*fail_grant_setup) (domid_t id); + /* generic domain-requested decision hooks (can be NULL) */ + int (*sharing) (ssidref_t ssidref1, ssidref_t ssidref2); }; /* global variables */ @@ -144,6 +147,8 @@ static inline int acm_init(unsigned int *initrdidx, { return 0; } static inline void acm_post_domain0_create(domid_t domid) { return; } +static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2) +{ return 0; } #else @@ -281,7 +286,8 @@ static inline int acm_pre_event_channel(evtchn_op_t *op) break; case EVTCHNOP_bind_interdomain: ret = acm_pre_eventchannel_interdomain( - op->u.bind_interdomain.dom1, op->u.bind_interdomain.dom2); + current->domain->domain_id, + op->u.bind_interdomain.remote_dom); break; default: ret = 0; /* ok */ @@ -341,6 +347,18 @@ static inline void acm_post_domain0_create(domid_t domid) acm_post_domain_create(domid, ACM_DOM0_SSIDREF); } +static inline int acm_sharing(ssidref_t ssidref1, ssidref_t ssidref2) +{ + if ((acm_primary_ops->sharing != NULL) && + acm_primary_ops->sharing(ssidref1, ssidref2)) + return ACM_ACCESS_DENIED; + else if ((acm_secondary_ops->sharing != NULL) && + acm_secondary_ops->sharing(ssidref1, ssidref2)) { + return ACM_ACCESS_DENIED; + } else + return ACM_ACCESS_PERMITTED; +} + extern int acm_init(unsigned int *initrdidx, const multiboot_info_t *mbi, unsigned long start); @@ -348,3 +366,13 @@ extern int acm_init(unsigned int *initrdidx, #endif #endif + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/public/acm.h b/xen/include/public/acm.h index b5820b8d34..a6646c3792 100644 --- a/xen/include/public/acm.h +++ b/xen/include/public/acm.h @@ -52,9 +52,9 @@ #define ACM_ERROR -4 /* External ACCESS DECISIONS */ -#define ACM_ACCESS_PERMITTED 0 -#define ACM_ACCESS_DENIED -111 -#define ACM_NULL_POINTER_ERROR -200 +#define ACM_ACCESS_PERMITTED 0 +#define ACM_ACCESS_DENIED -111 +#define ACM_NULL_POINTER_ERROR -200 /* primary policy in lower 4 bits */ #define ACM_NULL_POLICY 0 @@ -84,6 +84,9 @@ /* defines a ssid reference used by xen */ typedef uint32_t ssidref_t; +/* hooks that are known to domains */ +enum acm_hook_type {NONE=0, SHARING}; + /* -------security policy relevant type definitions-------- */ /* type identifier; compares to "equal" or "not equal" */ diff --git a/xen/include/public/acm_ops.h b/xen/include/public/acm_ops.h index 18165bdff2..3b4fd0750f 100644 --- a/xen/include/public/acm_ops.h +++ b/xen/include/public/acm_ops.h @@ -27,36 +27,36 @@ * This makes sure that old versions of acm tools will stop working in a * well-defined way (rather than crashing the machine, for instance). */ -#define ACM_INTERFACE_VERSION 0xAAAA0004 +#define ACM_INTERFACE_VERSION 0xAAAA0005 /************************************************************************/ #define ACM_SETPOLICY 4 -typedef struct acm_setpolicy { +struct acm_setpolicy { /* OUT variables */ void *pushcache; - uint16_t pushcache_size; -} acm_setpolicy_t; + uint32_t pushcache_size; +}; #define ACM_GETPOLICY 5 -typedef struct acm_getpolicy { +struct acm_getpolicy { /* OUT variables */ void *pullcache; - uint16_t pullcache_size; -} acm_getpolicy_t; + uint32_t pullcache_size; +}; #define ACM_DUMPSTATS 6 -typedef struct acm_dumpstats { +struct acm_dumpstats { void *pullcache; - uint16_t pullcache_size; -} acm_dumpstats_t; + uint32_t pullcache_size; +}; #define ACM_GETSSID 7 -enum get_type {UNSET, SSIDREF, DOMAINID}; -typedef struct acm_getssid { +enum get_type {UNSET=0, SSIDREF, DOMAINID}; +struct acm_getssid { enum get_type get_ssid_by; union { domaintype_t domainid; @@ -64,18 +64,35 @@ typedef struct acm_getssid { } id; void *ssidbuf; uint16_t ssidbuf_size; -} acm_getssid_t; +}; -typedef struct acm_op { +#define ACM_GETDECISION 8 +struct acm_getdecision { + enum get_type get_decision_by1; /* in */ + enum get_type get_decision_by2; + union { + domaintype_t domainid; + ssidref_t ssidref; + } id1; + union { + domaintype_t domainid; + ssidref_t ssidref; + } id2; + enum acm_hook_type hook; + int acm_decision; /* out */ +}; + +struct acm_op { uint32_t cmd; uint32_t interface_version; /* ACM_INTERFACE_VERSION */ union { - acm_setpolicy_t setpolicy; - acm_getpolicy_t getpolicy; - acm_dumpstats_t dumpstats; - acm_getssid_t getssid; + struct acm_setpolicy setpolicy; + struct acm_getpolicy getpolicy; + struct acm_dumpstats dumpstats; + struct acm_getssid getssid; + struct acm_getdecision getdecision; } u; -} acm_op_t; +}; #endif /* __XEN_PUBLIC_ACM_OPS_H__ */ From 5aa6b4306ee87f3589028c48acb644845915ee5e Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 10:17:29 +0100 Subject: [PATCH 110/142] Turn off some debug switches by default These macros cause extra prints in /var/log/xend-debug, and affect the performance. Signed-off-by: Xiaofeng Ling --- tools/ioemu/exec-all.h | 4 ++-- tools/ioemu/hw/i8259.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/ioemu/exec-all.h b/tools/ioemu/exec-all.h index e32207b7c3..ac0533982d 100644 --- a/tools/ioemu/exec-all.h +++ b/tools/ioemu/exec-all.h @@ -573,7 +573,7 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) } #endif -#define DEBUG_UNUSED_IOPORT -#define DEBUG_IOPORT +//#define DEBUG_UNUSED_IOPORT +//#define DEBUG_IOPORT #define TARGET_VMX diff --git a/tools/ioemu/hw/i8259.c b/tools/ioemu/hw/i8259.c index 17dd549c53..8009eea130 100644 --- a/tools/ioemu/hw/i8259.c +++ b/tools/ioemu/hw/i8259.c @@ -29,7 +29,7 @@ //#define DEBUG_PIC //#define DEBUG_IRQ_LATENCY -#define DEBUG_IRQ_COUNT +//#define DEBUG_IRQ_COUNT extern void pit_reset_vmx_vectors(); From 9f202a0633a3447bba3c97ff96e935723a96846a Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 10:20:38 +0100 Subject: [PATCH 111/142] Send special keys that your graphical user interface intercepts at low level, such as ctrl-alt-del in X Window. Adds a command "sendkey" to deal with it in the monitor, you can send keys to the vm. Use - to press several keys simultaneously. Example: sendkey ctrl-alt-f1 Signed-off-by: Dan Xu Signed-off-by: Zhai, Edwin Signed-off-by: Xiaofeng Ling --- tools/ioemu/monitor.c | 157 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 157 insertions(+) diff --git a/tools/ioemu/monitor.c b/tools/ioemu/monitor.c index 43304ea253..643313197d 100644 --- a/tools/ioemu/monitor.c +++ b/tools/ioemu/monitor.c @@ -232,6 +232,161 @@ static void do_quit(void) exit(0); } +typedef struct { + int keycode; + const char *name; +} KeyDef; + +static const KeyDef key_defs[] = { + { 0x2a, "shift" }, + { 0x36, "shift_r" }, + + { 0x38, "alt" }, + { 0xb8, "alt_r" }, + { 0x1d, "ctrl" }, + { 0x9d, "ctrl_r" }, + + { 0xdd, "menu" }, + + { 0x01, "esc" }, + + { 0x02, "1" }, + { 0x03, "2" }, + { 0x04, "3" }, + { 0x05, "4" }, + { 0x06, "5" }, + { 0x07, "6" }, + { 0x08, "7" }, + { 0x09, "8" }, + { 0x0a, "9" }, + { 0x0b, "0" }, + { 0x0e, "backspace" }, + + { 0x0f, "tab" }, + { 0x10, "q" }, + { 0x11, "w" }, + { 0x12, "e" }, + { 0x13, "r" }, + { 0x14, "t" }, + { 0x15, "y" }, + { 0x16, "u" }, + { 0x17, "i" }, + { 0x18, "o" }, + { 0x19, "p" }, + + { 0x1c, "ret" }, + + { 0x1e, "a" }, + { 0x1f, "s" }, + { 0x20, "d" }, + { 0x21, "f" }, + { 0x22, "g" }, + { 0x23, "h" }, + { 0x24, "j" }, + { 0x25, "k" }, + { 0x26, "l" }, + + { 0x2c, "z" }, + { 0x2d, "x" }, + { 0x2e, "c" }, + { 0x2f, "v" }, + { 0x30, "b" }, + { 0x31, "n" }, + { 0x32, "m" }, + + { 0x39, "spc" }, + { 0x3a, "caps_lock" }, + { 0x3b, "f1" }, + { 0x3c, "f2" }, + { 0x3d, "f3" }, + { 0x3e, "f4" }, + { 0x3f, "f5" }, + { 0x40, "f6" }, + { 0x41, "f7" }, + { 0x42, "f8" }, + { 0x43, "f9" }, + { 0x44, "f10" }, + { 0x45, "num_lock" }, + { 0x46, "scroll_lock" }, + + { 0x56, "<" }, + + { 0x57, "f11" }, + { 0x58, "f12" }, + + { 0xb7, "print" }, + + { 0xc7, "home" }, + { 0xc9, "pgup" }, + { 0xd1, "pgdn" }, + { 0xcf, "end" }, + + { 0xcb, "left" }, + { 0xc8, "up" }, + { 0xd0, "down" }, + { 0xcd, "right" }, + + { 0xd2, "insert" }, + { 0xd3, "delete" }, + { 0, NULL }, +}; + +static int get_keycode(const char *key) +{ + const KeyDef *p; + + for(p = key_defs; p->name != NULL; p++) { + if (!strcmp(key, p->name)) + return p->keycode; + } + return -1; +} + +static void do_send_key(const char *string) +{ + char keybuf[16], *q; + uint8_t keycodes[16]; + const char *p; + int nb_keycodes, keycode, i; + + nb_keycodes = 0; + p = string; + while (*p != '\0') { + q = keybuf; + while (*p != '\0' && *p != '-') { + if ((q - keybuf) < sizeof(keybuf) - 1) { + *q++ = *p; + } + p++; + } + *q = '\0'; + keycode = get_keycode(keybuf); + if (keycode < 0) { + term_printf("unknown key: '%s'\n", keybuf); + return; + } + keycodes[nb_keycodes++] = keycode; + if (*p == '\0') + break; + p++; + } + /* key down events */ + for(i = 0; i < nb_keycodes; i++) { + keycode = keycodes[i]; + if (keycode & 0x80) + kbd_put_keycode(0xe0); + kbd_put_keycode(keycode & 0x7f); + } + /* key up events */ + for(i = nb_keycodes - 1; i >= 0; i--) { + keycode = keycodes[i]; + if (keycode & 0x80) + kbd_put_keycode(0xe0); + kbd_put_keycode(keycode | 0x80); + } +} + + static int eject_device(BlockDriverState *bs, int force) { if (bdrv_is_inserted(bs)) { @@ -331,6 +486,8 @@ static term_cmd_t term_cmds[] = { "item1[,...]", "activate logging of the specified items to '/tmp/qemu.log'" }, { "q|quit", "", do_quit, "", "quit the emulator" }, + { "sendkey", "s", do_send_key, + "keys", "send keys to the VM (e.g. 'sendkey ctrl-alt-f1')" }, { NULL, NULL, }, }; From 35658f8da582ecfa7d3fbe511cfe6b1c01d18dd1 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 10:24:35 +0100 Subject: [PATCH 112/142] Update one file from qemu 0.71 for Cirrus Logic VGA device model. Using the older device model running pinball game on windows with full screen can cause guest crash. Signed-off-by: yunhong.jiang@intel.com --- tools/ioemu/hw/cirrus_vga_rop2.h | 51 ++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 15 deletions(-) diff --git a/tools/ioemu/hw/cirrus_vga_rop2.h b/tools/ioemu/hw/cirrus_vga_rop2.h index 5521870c8b..da11d0f5e5 100644 --- a/tools/ioemu/hw/cirrus_vga_rop2.h +++ b/tools/ioemu/hw/cirrus_vga_rop2.h @@ -47,6 +47,11 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) int x, y, pattern_y, pattern_pitch, pattern_x; unsigned int col; const uint8_t *src1; +#if DEPTH == 24 + int skipleft = s->gr[0x2f] & 0x1f; +#else + int skipleft = (s->gr[0x2f] & 0x07) * (DEPTH / 8); +#endif #if DEPTH == 8 pattern_pitch = 8; @@ -56,11 +61,11 @@ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH) pattern_pitch = 32; #endif pattern_y = s->cirrus_blt_srcaddr & 7; - pattern_x = 0; for(y = 0; y < bltheight; y++) { - d = dst; + pattern_x = skipleft; + d = dst + skipleft; src1 = src + pattern_y * pattern_pitch; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) { #if DEPTH == 8 col = src1[pattern_x]; pattern_x = (pattern_x + 1) & 7; @@ -99,7 +104,13 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) unsigned int col; unsigned bitmask; unsigned index; - int srcskipleft = 0; +#if DEPTH == 24 + int dstskipleft = s->gr[0x2f] & 0x1f; + int srcskipleft = dstskipleft / 3; +#else + int srcskipleft = s->gr[0x2f] & 0x07; + int dstskipleft = srcskipleft * (DEPTH / 8); +#endif if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { bits_xor = 0xff; @@ -112,8 +123,8 @@ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH) for(y = 0; y < bltheight; y++) { bitmask = 0x80 >> srcskipleft; bits = *src++ ^ bits_xor; - d = dst; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + d = dst + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { if ((bitmask & 0xff) == 0) { bitmask = 0x80; bits = *src++ ^ bits_xor; @@ -142,15 +153,16 @@ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH) unsigned bits; unsigned int col; unsigned bitmask; - int srcskipleft = 0; + int srcskipleft = s->gr[0x2f] & 0x07; + int dstskipleft = srcskipleft * (DEPTH / 8); colors[0] = s->cirrus_blt_bgcol; colors[1] = s->cirrus_blt_fgcol; for(y = 0; y < bltheight; y++) { bitmask = 0x80 >> srcskipleft; bits = *src++; - d = dst; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + d = dst + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { if ((bitmask & 0xff) == 0) { bitmask = 0x80; bits = *src++; @@ -175,6 +187,13 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) int x, y, bitpos, pattern_y; unsigned int bits, bits_xor; unsigned int col; +#if DEPTH == 24 + int dstskipleft = s->gr[0x2f] & 0x1f; + int srcskipleft = dstskipleft / 3; +#else + int srcskipleft = s->gr[0x2f] & 0x07; + int dstskipleft = srcskipleft * (DEPTH / 8); +#endif if (s->cirrus_blt_modeext & CIRRUS_BLTMODEEXT_COLOREXPINV) { bits_xor = 0xff; @@ -187,9 +206,9 @@ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH) for(y = 0; y < bltheight; y++) { bits = src[pattern_y] ^ bits_xor; - bitpos = 7; - d = dst; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + bitpos = 7 - srcskipleft; + d = dst + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { if ((bits >> bitpos) & 1) { PUTPIXEL(); } @@ -213,6 +232,8 @@ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) int x, y, bitpos, pattern_y; unsigned int bits; unsigned int col; + int srcskipleft = s->gr[0x2f] & 0x07; + int dstskipleft = srcskipleft * (DEPTH / 8); colors[0] = s->cirrus_blt_bgcol; colors[1] = s->cirrus_blt_fgcol; @@ -220,9 +241,9 @@ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH) for(y = 0; y < bltheight; y++) { bits = src[pattern_y]; - bitpos = 7; - d = dst; - for (x = 0; x < bltwidth; x += (DEPTH / 8)) { + bitpos = 7 - srcskipleft; + d = dst + dstskipleft; + for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) { col = colors[(bits >> bitpos) & 1]; PUTPIXEL(); d += (DEPTH / 8); From 1167a3e107cfc1e740352da5c0a63fa5a61de283 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 10:46:30 +0100 Subject: [PATCH 113/142] Upgrade tree to 2.6.12.6. Signed-off-by: Keir Fraser --- .../{2.6.12.5.patch => 2.6.12.6.patch} | 150 ++++++++++++++++-- 1 file changed, 137 insertions(+), 13 deletions(-) rename patches/linux-2.6.12/{2.6.12.5.patch => 2.6.12.6.patch} (92%) diff --git a/patches/linux-2.6.12/2.6.12.5.patch b/patches/linux-2.6.12/2.6.12.6.patch similarity index 92% rename from patches/linux-2.6.12/2.6.12.5.patch rename to patches/linux-2.6.12/2.6.12.6.patch index 5e874eb7b5..f876d022c5 100644 --- a/patches/linux-2.6.12/2.6.12.5.patch +++ b/patches/linux-2.6.12/2.6.12.6.patch @@ -6,7 +6,7 @@ diff --git a/Makefile b/Makefile PATCHLEVEL = 6 SUBLEVEL = 12 -EXTRAVERSION = -+EXTRAVERSION = .5 ++EXTRAVERSION = .6 NAME=Woozy Numbat # *DOCUMENTATION* @@ -1092,6 +1092,61 @@ diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c } EXPORT_SYMBOL_GPL(qla2x00_probe_one); +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -2969,23 +2969,22 @@ static void * dev_seq_start(struct seq_f + { + struct sg_proc_deviter * it = kmalloc(sizeof(*it), GFP_KERNEL); + ++ s->private = it; + if (! it) + return NULL; ++ + if (NULL == sg_dev_arr) +- goto err1; ++ return NULL; + it->index = *pos; + it->max = sg_last_dev(); + if (it->index >= it->max) +- goto err1; ++ return NULL; + return it; +-err1: +- kfree(it); +- return NULL; + } + + static void * dev_seq_next(struct seq_file *s, void *v, loff_t *pos) + { +- struct sg_proc_deviter * it = (struct sg_proc_deviter *) v; ++ struct sg_proc_deviter * it = s->private; + + *pos = ++it->index; + return (it->index < it->max) ? it : NULL; +@@ -2993,7 +2992,9 @@ static void * dev_seq_next(struct seq_fi + + static void dev_seq_stop(struct seq_file *s, void *v) + { +- kfree (v); ++ struct sg_proc_deviter * it = s->private; ++ ++ kfree (it); + } + + static int sg_proc_open_dev(struct inode *inode, struct file *file) +diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c +--- a/drivers/usb/net/usbnet.c ++++ b/drivers/usb/net/usbnet.c +@@ -1922,7 +1922,7 @@ static int genelink_rx_fixup (struct usb + + // copy the packet data to the new skb + memcpy(skb_put(gl_skb, size), packet->packet_data, size); +- skb_return (dev, skb); ++ skb_return (dev, gl_skb); + } + + // advance to the next packet diff --git a/fs/bio.c b/fs/bio.c --- a/fs/bio.c +++ b/fs/bio.c @@ -1337,6 +1392,18 @@ diff --git a/kernel/module.c b/kernel/module.c if (!percpu) { err = -ENOMEM; goto free_mod; +diff --git a/kernel/signal.c b/kernel/signal.c +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -686,7 +686,7 @@ static void handle_stop_signal(int sig, + { + struct task_struct *t; + +- if (p->flags & SIGNAL_GROUP_EXIT) ++ if (p->signal->flags & SIGNAL_GROUP_EXIT) + /* + * The process is in the middle of dying already. + */ diff --git a/lib/inflate.c b/lib/inflate.c --- a/lib/inflate.c +++ b/lib/inflate.c @@ -1377,18 +1444,6 @@ diff --git a/lib/inflate.c b/lib/inflate.c } DEBG1("3 "); z = 1 << j; /* table entries for j-bit table */ -diff --git a/lib/zlib_inflate/inftrees.c b/lib/zlib_inflate/inftrees.c ---- a/lib/zlib_inflate/inftrees.c -+++ b/lib/zlib_inflate/inftrees.c -@@ -141,7 +141,7 @@ static int huft_build( - { - *t = NULL; - *m = 0; -- return Z_OK; -+ return Z_DATA_ERROR; - } - - diff --git a/mm/memory.c b/mm/memory.c --- a/mm/memory.c +++ b/mm/memory.c @@ -1431,6 +1486,28 @@ diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c if ((vlandev->state & VLAN_LINK_STATE_MASK) != flgs) { vlandev->state = (vlandev->state &~ VLAN_LINK_STATE_MASK) | flgs; +diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -349,12 +349,12 @@ static void icmp_push_reply(struct icmp_ + { + struct sk_buff *skb; + +- ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, +- icmp_param->data_len+icmp_param->head_len, +- icmp_param->head_len, +- ipc, rt, MSG_DONTWAIT); +- +- if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { ++ if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, ++ icmp_param->data_len+icmp_param->head_len, ++ icmp_param->head_len, ++ ipc, rt, MSG_DONTWAIT) < 0) ++ ip_flush_pending_frames(icmp_socket->sk); ++ else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { + struct icmphdr *icmph = skb->h.icmph; + unsigned int csum = 0; + struct sk_buff *skb1; diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -1451,6 +1528,19 @@ diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c if (hh) { int hh_alen; +diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c +--- a/net/ipv4/ip_sockglue.c ++++ b/net/ipv4/ip_sockglue.c +@@ -848,6 +848,9 @@ mc_msf_out: + + case IP_IPSEC_POLICY: + case IP_XFRM_POLICY: ++ err = -EPERM; ++ if (!capable(CAP_NET_ADMIN)) ++ break; + err = xfrm_user_policy(sk, optname, optval, optlen); + break; + diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -1507,6 +1597,40 @@ diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_p unsigned int range_size, min, i; if (maniptype == IP_NAT_MANIP_SRC) +diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c +--- a/net/ipv6/ip6_input.c ++++ b/net/ipv6/ip6_input.c +@@ -198,12 +198,13 @@ resubmit: + if (!raw_sk) { + if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { + IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); +- icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff); ++ icmpv6_send(skb, ICMPV6_PARAMPROB, ++ ICMPV6_UNK_NEXTHDR, nhoff, ++ skb->dev); + } +- } else { ++ } else + IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); +- kfree_skb(skb); +- } ++ kfree_skb(skb); + } + rcu_read_unlock(); + return 0; +diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c +--- a/net/ipv6/ipv6_sockglue.c ++++ b/net/ipv6/ipv6_sockglue.c +@@ -503,6 +503,9 @@ done: + break; + case IPV6_IPSEC_POLICY: + case IPV6_XFRM_POLICY: ++ retv = -EPERM; ++ if (!capable(CAP_NET_ADMIN)) ++ break; + retv = xfrm_user_policy(sk, optname, optval, optlen); + break; + diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c From 174e923813011a8d7317726282c585160c46b016 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 21 Oct 2005 11:08:48 +0100 Subject: [PATCH 114/142] Output the Xen changeset in the logs at start of day. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/SrvDaemon.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index 2bfcce85a7..c451071bee 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -14,6 +14,8 @@ import pwd import re import traceback +import xen.lowlevel.xc + from xen.xend.server import SrvServer from xen.xend.XendLogging import log @@ -268,6 +270,10 @@ class Daemon: def run(self, status): try: log.info("Xend Daemon started") + + xinfo = xen.lowlevel.xc.new().xeninfo() + log.info("Xend changeset: %s.", xinfo['xen_changeset']) + event.listenEvent(self) relocate.listenRelocation() servers = SrvServer.create() From aec60dc083330d6d5caee93ea49de2d950ce9e05 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 21 Oct 2005 11:21:05 +0100 Subject: [PATCH 115/142] Remove unused Vifctl.vifctl and Vifctl.set_vif_name. Remove the bridge and antispoof parameters from Vifctl.network -- these are already handled by the script, so it is redundant to have a separate override for these parameters coming from outside. Don't use xen.util.process.runscript, because we don't need to return the output, and therefore can just use os.spawnl. Remove XendRoot.get_vif_antispoof, matching change above. Prefix XendRoot.network_script_dir onto the return value for XendRoot.get_network_script(), removing that burden from callers. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/Vifctl.py | 86 +++---------------------------- tools/python/xen/xend/XendRoot.py | 17 +++--- 2 files changed, 18 insertions(+), 85 deletions(-) diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py index f3f882d389..382cba5c04 100644 --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -19,87 +19,17 @@ """Xend interface to networking control scripts. """ import os -import os.path -import xen.util.process -from xen.xend import XendRoot -xroot = XendRoot.instance() +import XendRoot -"""Where network control scripts live.""" -SCRIPT_DIR = xroot.network_script_dir -def network(op, script=None, bridge=None, antispoof=None): +def network(op): """Call a network control script. - Xend calls this with op 'start' when it starts. - @param op: operation (start, stop, status) - @param script: network script name - @param bridge: xen bridge - @param antispoof: whether to enable IP antispoofing rules + @param op: operation (start, stop) """ - if op not in ['start', 'stop', 'status']: - raise ValueError('Invalid operation:' + op) - if script is None: - script = xroot.get_network_script() - if bridge is None: - bridge = xroot.get_vif_bridge() - if antispoof is None: - antispoof = xroot.get_vif_antispoof() - script = os.path.join(SCRIPT_DIR, script) - args = [op] - args.append("bridge='%s'" % bridge) - if antispoof: - args.append("antispoof=yes") - else: - args.append("antispoof=no") - args = ' '.join(args) - ret = xen.util.process.runscript(script + ' ' + args) - if len(ret): - return ret.splitlines()[0] - -def set_vif_name(vif_old, vif_new): - if vif_old == vif_new: - vif = vif_new - return vif - if os.system("ip link show %s" % vif_old) == 0: - os.system("ip link set %s down" % vif_old) - os.system("ip link set %s name %s" % (vif_old, vif_new)) - os.system("ip link set %s up" % vif_new) - if os.system("ip link show %s" % vif_new) == 0: - vif = vif_new - else: - vif = vif_old - return vif - -def vifctl(op, vif=None, script=None, domain=None, mac=None, bridge=None, ipaddr=None): - """Call a vif control script. - Xend calls this when bringing vifs up or down. - - @param op: vif operation (up, down) - @param vif: vif name - @param script: name of control script - @param domain: name of domain the vif is on - @param mac: vif MAC address - @param bridge: bridge to add the vif to - @param ipaddr: list of ipaddrs the vif may use - """ - if op not in ['up', 'down']: - raise ValueError('Invalid operation:' + op) - if script is None: - script = xroot.get_vif_script() - if bridge is None: - bridge = xroot.get_vif_bridge() - script = os.path.join(SCRIPT_DIR, script) - args = [op] - args.append("vif='%s'" % vif) - args.append("domain='%s'" % domain) - args.append("mac='%s'" % mac) - if bridge: - args.append("bridge='%s'" % bridge) - if ipaddr: - ips = ' '.join(ipaddr) - args.append("ip='%s'" % ips) - args = ' '.join(args) - ret = xen.util.process.runscript(script + ' ' + args) - if len(ret): - return ret.splitlines()[0] + if op not in ['start', 'stop']: + raise ValueError('Invalid operation: ' + op) + script = XendRoot.instance().get_network_script() + if script: + os.spawnl(os.P_WAIT, script, script, op) diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index d5d348d94b..b504c82e0f 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -243,11 +243,17 @@ class XendRoot: """ return self.get_config_value("xend-unix-path", self.xend_unix_path_default) - def get_block_script(self, type): - return self.get_config_value('block-%s' % type, '') - def get_network_script(self): - return self.get_config_value('network-script', '') + """@return the script used to alter the network configuration when + Xend starts and stops, or None if no such script is specified.""" + + s = self.get_config_value('network-script') + + if s: + return os.path.join(self.network_script_dir, s) + else: + return None + def get_enable_dump(self): return self.get_config_bool('enable-dump', 'no') @@ -258,9 +264,6 @@ class XendRoot: def get_vif_script(self): return self.get_config_value('vif-script', 'vif-bridge') - def get_vif_antispoof(self): - return self.get_config_bool('vif-antispoof', 'yes') - def get_dom0_min_mem(self): return self.get_config_int('dom0-min-mem', self.dom0_min_mem_default) From 3a2351fdda41298a04ccae4f27f571971c40ce76 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 21 Oct 2005 11:22:48 +0100 Subject: [PATCH 116/142] Removed xen.util.process, as no-one is using it, and it leaves defunct processes behind. Signed-off-by: Ewan Mellor --- tools/python/xen/util/process.py | 39 -------------------------------- 1 file changed, 39 deletions(-) delete mode 100644 tools/python/xen/util/process.py diff --git a/tools/python/xen/util/process.py b/tools/python/xen/util/process.py deleted file mode 100644 index 9117ef4ded..0000000000 --- a/tools/python/xen/util/process.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2005 Christian Limpach - -# os.system() replacement which outputs through the logger - -import popen2 -import select -import string - -from xen.xend.XendLogging import log - -def runscript(cmd): - # split after first space, then grab last component of path - cmdname = "[%s] " % cmd.split()[0].split('/')[-1] - # run command and grab stdin, stdout and stderr - cout, cin, cerr = popen2.popen3(cmd) - # close stdin to get command to terminate if it waits for input - cin.close() - # wait for output and process - p = select.poll() - p.register(cout) - p.register(cerr) - stdout = "" - while True: - r = p.poll() - for (fd, event) in r: - if event == select.POLLHUP: - cout.close() - cerr.close() - return stdout - if fd == cout.fileno(): - stdout = stdout + cout.readline() - if fd == cerr.fileno(): - l = cerr.readline() - if l[0] == '-': - log.debug(cmdname + l[1:].rstrip()) - elif l[0] == '*': - log.info(cmdname + l[1:].rstrip()) - else: - log.error(cmdname + l.rstrip()) From 608aa777d53e7412da126dd6f9d78455a1915fbd Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 11:29:51 +0100 Subject: [PATCH 117/142] Work around internal error in some versions of x86/64 gcc by manually hoisting gdt address calculation outside loop. Signed-off-by: Keir Fraser --- xen/arch/x86/domain.c | 7 +++---- xen/arch/x86/setup.c | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 7d61eadfab..c52448d2fd 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -254,6 +254,7 @@ void free_perdomain_pt(struct domain *d) void arch_do_createdomain(struct vcpu *v) { struct domain *d = v->domain; + l1_pgentry_t gdt_l1e; int vcpuid; if ( is_idle_task(d) ) @@ -282,12 +283,10 @@ void arch_do_createdomain(struct vcpu *v) * GDT, and the old VCPU# is invalid in the new domain, we would otherwise * try to load CS from an invalid table. */ + gdt_l1e = l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ ) - { d->arch.mm_perdomain_pt[ - (vcpuid << PDPT_VCPU_SHIFT) + FIRST_RESERVED_GDT_PAGE] = - l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); - } + (vcpuid << PDPT_VCPU_SHIFT) + FIRST_RESERVED_GDT_PAGE] = gdt_l1e; v->arch.guest_vtable = __linear_l2_table; v->arch.shadow_vtable = __shadow_linear_l2_table; diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 388735fb49..21e4bb810b 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -141,7 +141,7 @@ static void __init do_initcalls(void) static void __init start_of_day(void) { int i; - unsigned long vgdt; + unsigned long vgdt, gdt_pfn; early_cpu_init(); @@ -164,10 +164,10 @@ static void __init start_of_day(void) * noted in arch_do_createdomain(), we must map for every possible VCPU#. */ vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE; + gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT; for ( i = 0; i < MAX_VIRT_CPUS; i++ ) { - map_pages_to_xen( - vgdt, virt_to_phys(gdt_table) >> PAGE_SHIFT, 1, PAGE_HYPERVISOR); + map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR); vgdt += 1 << PDPT_VCPU_VA_SHIFT; } From fb22028e119ab7422cf19b76ed3e56ee66ba703a Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 21 Oct 2005 12:04:30 +0100 Subject: [PATCH 118/142] Tidy xend-config.sxp, removing entries that haven't been used since the hotplugging stuff was introduced (block-*, console-port-base, console-address) and introducing entries for options that have been present for ages (xend-{http,unix,relocation}-server, xend-unix-path, xend-relocation-address, enable-dump). Remove vif-antispoof, as Vifctl no longer passes this option down. Made the xend-relocation-server default to no, as this is a potential security hole and so must be turned on explicitly. Signed-off-by: Ewan Mellor --- tools/examples/xend-config.sxp | 70 +++++++++++++++++++------------ tools/python/xen/xend/XendRoot.py | 2 +- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/tools/examples/xend-config.sxp b/tools/examples/xend-config.sxp index 881eaacfbc..ba433cd745 100644 --- a/tools/examples/xend-config.sxp +++ b/tools/examples/xend-config.sxp @@ -1,27 +1,52 @@ +# -*- sh -*- + +# # Xend configuration file. +# -# Port xend should use for the HTTP interface. -(xend-port 8000) +# This example configuration is appropriate for an installation that trusts +# only localhost connections, and is otherwise fully functional, with a +# bridged network configuration. -# Port xend should use for the event interface. -(xend-event-port 8001) +# Commented out entries show the default for that entry, unless otherwise +# specified. -# Address xend should listen on for HTTP connections. +#(logfile /var/log/xend.log) +#(loglevel DEBUG) + +#(xend-http-server no) +(xend-http-server yes) +#(xend-unix-server yes) +#(xend-relocation-server no) +(xend-relocation-server yes) + +#(xend-unix-path /var/lib/xend/xend-socket) + +# Port xend should use for the HTTP interface, if xend-http-server is set. +#(xend-port 8000) + +# Port xend should use for the event interface. This interface is deprecated. +#(xend-event-port 8001) + +# Port xend should use for the relocation interface, if xend-relocation-server +# is set. +#(xend-relocation-port 8002) + +# Address xend should listen on for HTTP connections, if xend-http-server is +# set. # Specifying 'localhost' prevents remote connections. -# Specifying the empty string '' allows all connections. -(xend-address 'localhost') +# Specifying the empty string '' (the default) allows all connections. +#(xend-address '') +(xend-address localhost) -# The port xend should start from when allocating a port -# for a domain console. -(console-port-base 9600) - -# Address xend should listen on for console connections. -# Specifying 'localhost' prevents remote connections. -# Specifying the empty string '' allows all connections. -(console-address 'localhost') +# Address xend should listen on for relocation-socket connections, if +# xend-relocation-server is set. +# Meaning and default as for xend-address above. +#(xend-relocation-address '') +(xend-relocation-address localhost) # The limit (in kilobytes) on the size of the console buffer -(console-limit 1024) +#(console-limit 1024) ## Use the following if VIF traffic is routed. # The script used to start/stop networking for xend. @@ -37,16 +62,6 @@ # The default script used to control virtual interfaces. (vif-script vif-bridge) -# Whether iptables should be set up to prevent IP spoofing for -# virtual interfaces. Specify 'yes' or 'no'. -(vif-antispoof no) - -# Setup script for file-backed block devices -(block-file block-file) - -# Setup script for enbd-backed block devices -(block-enbd block-enbd) - # Dom0 will balloon out when needed to free memory for domU. # dom0-min-mem is the lowest memory level (in MB) dom0 will get down to. # If dom0-min-mem=0, dom0 will never balloon out. @@ -55,3 +70,6 @@ # In SMP system, dom0 will use dom0-cpus # of CPUS # If dom0-cpus = 0, dom0 will take all cpus available (dom0-cpus 0) + +# Whether to enable core-dumps when domains crash. +#(enable-dump no) diff --git a/tools/python/xen/xend/XendRoot.py b/tools/python/xen/xend/XendRoot.py index b504c82e0f..b51046a87b 100644 --- a/tools/python/xen/xend/XendRoot.py +++ b/tools/python/xen/xend/XendRoot.py @@ -64,7 +64,7 @@ class XendRoot: xend_address_default = '' """Default for the flag indicating whether xend should run a relocation server.""" - xend_relocation_server_default = 'yes' + xend_relocation_server_default = 'no' """Default interface address the xend relocation server listens at. """ xend_relocation_address_default = '' From e5edf96441c161d4b9593cbfc7e0a7e019e972ce Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 21 Oct 2005 12:06:17 +0100 Subject: [PATCH 119/142] Break common network code in xen-network-common.sh, and common vif hotplugging code into vif-common.sh. Fix the antispoofing in network-bridge to allow forwarding from physical device to bridge, and vif0.0 to eth0. Change the interface between netback driver and vif hotplugging scripts. The mac address and bridge details are read from the store directly by the script, so that the kernel driver does not need to get involved. Remove an awful lot of cruft from vif-bridge. Move the iptables handling into vif-common.sh, and fix it so that the new vif can get past the antispoofing entries. Merge vif-nat and vif-route into this structure too. Use ip instead of ifconfig to get necessary details. Signed-off-by: Ewan Mellor --- .../drivers/xen/netback/xenbus.c | 35 +++----- tools/examples/Makefile | 2 +- tools/examples/network-bridge | 28 ++---- tools/examples/vif-bridge | 86 ++++++------------- tools/examples/vif-common.sh | 74 ++++++++++++++++ tools/examples/vif-nat | 59 +++++-------- tools/examples/vif-route | 70 +++++---------- tools/examples/xen-hotplug-common.sh | 13 +-- tools/examples/xen-network-common.sh | 37 ++++++++ 9 files changed, 209 insertions(+), 195 deletions(-) mode change 100644 => 100755 tools/examples/network-bridge create mode 100644 tools/examples/vif-common.sh create mode 100644 tools/examples/xen-network-common.sh diff --git a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c index 6d81bb7433..f6218fab42 100644 --- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c @@ -161,34 +161,27 @@ static void backend_changed(struct xenbus_watch *watch, static int netback_hotplug(struct xenbus_device *xdev, char **envp, int num_envp, char *buffer, int buffer_size) { - struct backend_info *be; - netif_t *netif; - char **key, *val; + struct backend_info *be = xdev->data; + netif_t *netif = be->netif; int i = 0, length = 0; - static char *env_vars[] = { "script", "domain", "mac", "bridge", "ip", - NULL }; - be = xdev->data; - netif = be->netif; + char *val = xenbus_read(NULL, xdev->nodename, "script", NULL); + if (IS_ERR(val)) { + int err = PTR_ERR(val); + xenbus_dev_error(xdev, err, "reading script"); + return err; + } + else { + add_hotplug_env_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "script=%s", val); + kfree(val); + } add_hotplug_env_var(envp, num_envp, &i, buffer, buffer_size, &length, "vif=%s", netif->dev->name); - key = env_vars; - while (*key != NULL) { - val = xenbus_read(NULL, xdev->nodename, *key, NULL); - if (!IS_ERR(val)) { - char buf[strlen(*key) + 4]; - sprintf(buf, "%s=%%s", *key); - add_hotplug_env_var(envp, num_envp, &i, - buffer, buffer_size, &length, - buf, val); - kfree(val); - } - key++; - } - envp[i] = NULL; return 0; diff --git a/tools/examples/Makefile b/tools/examples/Makefile index f94a222466..f58f75e092 100644 --- a/tools/examples/Makefile +++ b/tools/examples/Makefile @@ -24,7 +24,7 @@ XEN_SCRIPTS += network-route vif-route XEN_SCRIPTS += network-nat vif-nat XEN_SCRIPTS += block XEN_SCRIPTS += block-enbd -XEN_SCRIPTS += xen-hotplug-common.sh +XEN_SCRIPTS += xen-hotplug-common.sh xen-network-common.sh vif-common.sh XEN_HOTPLUG_DIR = /etc/hotplug XEN_HOTPLUG_SCRIPTS = xen-backend.agent diff --git a/tools/examples/network-bridge b/tools/examples/network-bridge old mode 100644 new mode 100755 index 360a6513c6..c9d00b8e81 --- a/tools/examples/network-bridge +++ b/tools/examples/network-bridge @@ -25,7 +25,7 @@ # higher value than its default of 1. # bridge The bridge to use (default xenbr${vifnum}). # netdev The interface to add to the bridge (default eth${vifnum}). -# antispoof Whether to use iptables to prevent spoofing (default yes). +# antispoof Whether to use iptables to prevent spoofing (default no). # # start: # Creates the bridge and enslaves netdev to it. @@ -42,16 +42,8 @@ # #============================================================================ -# Gentoo doesn't have ifup/ifdown: define appropriate alternatives -which ifup >& /dev/null -if [ "$?" != 0 -a -e /etc/conf.d/net ]; then - ifup() { - /etc/init.d/net.$1 start - } - ifdown() { - /etc/init.d/net.$1 stop - } -fi +dir=$(dirname "$0") +. "$dir/xen-network-common.sh" # Exit if anything goes wrong. set -e @@ -66,14 +58,12 @@ for arg ; do export "${arg}" ; done vifnum=${vifnum:-0} bridge=${bridge:-xenbr${vifnum}} netdev=${netdev:-eth${vifnum}} -antispoof=${antispoof:-yes} +antispoof=${antispoof:-no} pdev="p${netdev}" vdev="veth${vifnum}" vif0="vif0.${vifnum}" -echo "*network $OP bridge=$bridge netdev=$netdev antispoof=$antispoof vifnum=$vifnum" >&2 - legacy_mask_to_prefix() { mask=$1 first=${mask%%.*} @@ -178,15 +168,13 @@ add_to_bridge () { fi } -# Usage: antispoofing dev bridge # Set the default forwarding policy for $dev to drop. # Allow forwarding to the bridge. antispoofing () { - local dev=$1 - local bridge=$2 - iptables -P FORWARD DROP - iptables -A FORWARD -m physdev --physdev-in ${dev} -j ACCEPT + iptables -F FORWARD + iptables -A FORWARD -m physdev --physdev-in ${pdev} -j ACCEPT + iptables -A FORWARD -m physdev --physdev-in ${vif0} -j ACCEPT } # Usage: show_status dev bridge @@ -263,7 +251,7 @@ op_start () { fi if [ ${antispoof} == 'yes' ] ; then - antispoofing ${netdev} ${bridge} + antispoofing fi } diff --git a/tools/examples/vif-bridge b/tools/examples/vif-bridge index 4a947397f4..619762fe30 100755 --- a/tools/examples/vif-bridge +++ b/tools/examples/vif-bridge @@ -3,22 +3,19 @@ # /etc/xen/vif-bridge # # Script for configuring a vif in bridged mode. -# Xend calls a vif script when bringing a vif up or down. -# This script is the default - but it can be configured for each vif. -# -# Example invocation: -# -# vif-bridge up domain=VM1 vif=vif1.0 bridge=xenbr0 ip="128.232.38.45/28 10.10.10.55/24" -# +# The hotplugging system will call this script if it is specified either in +# the device configuration given to Xend, or the default Xend configuration +# in /etc/xen/xend-config.sxp. If the script is specified in neither of those +# places, then this script is the default. # # Usage: -# vif-bridge (up|down) {VAR=VAL}* +# vif-bridge (up|down) # -# Vars: +# Environment vars: +# vif vif interface name (required). +# XENBUS_PATH path to this device's details in the XenStore (required). # -# domain name of the domain the interface is on (required). -# vif vif interface name (required). -# mac vif MAC address (required). +# Read from the store: # bridge bridge to add the vif to (required). # ip list of IP networks for the vif, space-separated (optional). # @@ -32,60 +29,29 @@ #============================================================================ dir=$(dirname "$0") -. "$dir/xen-hotplug-common.sh" +. "$dir/vif-common.sh" -# Operation name. -OP=$1 -shift +bridge=$(xenstore_read "$XENBUS_PATH/bridge") -# Pull variables in args into environment -for arg ; do export "${arg}" ; done - -# Required parameters. Fail if not set. -domain=${domain:?} -vif=${vif:?} -mac=${mac:?} -bridge=${bridge:?} - -# Optional parameters. Set defaults. -ip=${ip:-''} # default to null (do nothing) - -# Are we going up or down? -case $OP in +case "$command" in up) - brcmd='addif' - iptcmd='-A' + if brctl show "$bridge" | grep "$vif" >&/dev/null + then + log debug "$vif already attached to $bridge" + exit 0 + fi + + brctl addif "$bridge" "$vif" || + fatal "brctl addif $bridge $vif failed" + + ifconfig "$vif" up || fatal "ifconfig $vif up failed" ;; down) - brcmd='delif' - iptcmd='-D' - ;; - *) - echo 'Invalid command: ' $OP >&2 - echo 'Valid commands are: up, down' >&2 - exit 1 + # vifs are auto-removed from bridge. + ifconfig "$vif" down || fatal "ifconfig $vif down failed" ;; esac -# Don't do anything if the bridge is "null". -if [ "${bridge}" == "null" ] ; then - exit -fi - -# Add vif to bridge. vifs are auto-removed from bridge. -if [ "${brcmd}" == "addif" ] ; then - brctl ${brcmd} ${bridge} ${vif} -fi -ifconfig ${vif} $OP - -if [ "${ip}" ] ; then - - # If we've been given a list of IP networks, allow pkts with these src addrs. - for addr in ${ip} ; do - iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -s ${addr} -j ACCEPT - done - - # Always allow us to talk to a DHCP server anyhow. - iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -p udp --sport 68 --dport 67 -j ACCEPT -fi +handle_iptable +log debug "vif-bridge operation for $vif successful." diff --git a/tools/examples/vif-common.sh b/tools/examples/vif-common.sh new file mode 100644 index 0000000000..48e3cf9bc7 --- /dev/null +++ b/tools/examples/vif-common.sh @@ -0,0 +1,74 @@ +# +# Copyright (c) 2005 XenSource Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + + +dir=$(dirname "$0") +. "$dir/xen-hotplug-common.sh" +. "$dir/xen-network-common.sh" + +command="$1" + +if [ "$command" != "up" ] && [ "$command" != "down" ] +then + log err "Invalid command: $command" + exit 1 +fi + + +XENBUS_PATH="${XENBUS_PATH:?}" +vif="${vif:?}" + +ip=$(xenstore-read "$XENBUS_PATH/ip" >&/dev/null || true) + + +function frob_iptable() +{ + if [ "$command" == "up" ] + then + local c="-A" + else + local c="-D" + fi + + iptables "$c" FORWARD -m physdev --physdev-in "$vif" "$@" -j ACCEPT +} + + +## +# Add or remove the appropriate entries in the iptables. With antispoofing +# turned on, we have to explicitly allow packets to the interface, regardless +# of the ip setting. If ip is set, then we additionally restrict the packets +# to those coming from the specified networks, though we allow DHCP requests +# as well. +# +function handle_iptable() +{ + if [ "$ip" != "" ] + then + local addr + for addr in "$ip" + do + frob_iptable -s "$addr" + done + + # Always allow the domain to talk to a DHCP server. + frob_iptable -p udp --sport 68 --dport 67 + else + # No IP addresses have been specified, so allow anything. + frob_iptable + fi +} diff --git a/tools/examples/vif-nat b/tools/examples/vif-nat index a86bd91dd9..bf9f40a7b9 100644 --- a/tools/examples/vif-nat +++ b/tools/examples/vif-nat @@ -3,40 +3,30 @@ # /etc/xen/vif-nat # # Script for configuring a vif in routed-nat mode. -# Xend calls a vif script when bringing a vif up or down. -# This script is the default - but it can be configured for each vif. -# -# Example invocation: -# -# vif-nat up domain=VM1 vif=vif1.0 ip="192.168.0.10/31" +# The hotplugging system will call this script if it is specified either in +# the device configuration given to Xend, or the default Xend configuration +# in /etc/xen/xend-config.sxp. If the script is specified in neither of those +# places, then vif-bridge is the default. # # Usage: -# vif-nat (up|down) {VAR=VAL}* +# vif-nat (up|down) # -# Vars: +# Environment vars: +# vif vif interface name (required). +# XENBUS_PATH path to this device's details in the XenStore (required). # -# domain name of the domain the interface is on (required). -# vif vif interface name (required). -# ip list of IP networks for the vif, space-separated (required). +# Read from the store: +# ip list of IP networks for the vif, space-separated (default given in +# this script). #============================================================================ -# Exit if anything goes wrong -set -e -export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH +dir=$(dirname "$0") +. "$dir/vif-common.sh" -# Operation name. -OP=$1 -shift - -# Pull variables in args into environment -for arg ; do export "${arg}" ; done - -# Required parameters. Fail if not set. -domain=${domain:?} -vif=${vif:?} -ip=${ip:-'169.254.1.1/24'} #if not defined, give a default address - -echo "*vif-nat $OP domain=$domain vif=$vif ip=$ip" >&2 +if [ "$ip" == "" ] +then + ip='169.254.1.1/24' +fi #determine ip address and netmask vif_ip=`echo ${ip} | awk -F/ '{print $1}'` @@ -47,27 +37,20 @@ netmask=$netmask.$(( (($intmask & 0x00FF0000)) >> 16 )) netmask=$netmask.$(( (($intmask & 0x0000FF00)) >> 8 )) netmask=$netmask.$(( $intmask & 0x000000FF )) -main_ip=`ifconfig eth0 | grep "inet addr:" | sed -e 's/.*inet addr:\(\w\w*\.\w\w*\.\w\w*\.\w\w*\).*/\1/'` +main_ip=$(ip addr show eth0 | sed -e '/inet /!d;s/^.*inet \([^\s*]\)\s.*$/\1/') -# Are we going up or down? -case $OP in +case "$command" in up) ifconfig ${vif} ${vif_ip} netmask ${netmask} up echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp - iptcmd='-A' ipcmd='a' ;; down) ifconfig ${vif} down - iptcmd='-D' ipcmd='d' ;; - *) - echo 'Invalid command: ' $OP >&2 - echo 'Valid commands are: up, down' >&2 - exit 1 - ;; esac ip r ${ipcmd} ${ip} dev ${vif} src ${main_ip} -# iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -p udp --sport 68 --dport 67 -j ACCEPT + +handle_iptable() diff --git a/tools/examples/vif-route b/tools/examples/vif-route index efb83881d2..beb8e43ef2 100755 --- a/tools/examples/vif-route +++ b/tools/examples/vif-route @@ -3,74 +3,46 @@ # /etc/xen/vif-route # # Script for configuring a vif in routed mode. -# Xend calls a vif script when bringing a vif up or down. -# This script is the default - but it can be configured for each vif. -# -# Example invocation: -# -# vif-route up domain=VM1 vif=vif1.0 ip="128.232.38.45/28 10.10.10.55/24" +# The hotplugging system will call this script if it is specified either in +# the device configuration given to Xend, or the default Xend configuration +# in /etc/xen/xend-config.sxp. If the script is specified in neither of those +# places, then vif-bridge is the default. # # Usage: -# vif-route (up|down) {VAR=VAL}* +# vif-route (up|down) # -# Vars: +# Environment vars: +# vif vif interface name (required). +# XENBUS_PATH path to this device's details in the XenStore (required). # -# domain name of the domain the interface is on (required). -# vif vif interface name (required). -# mac vif MAC address (required). -# ip list of IP networks for the vif, space-separated (optional). +# Read from the store: +# ip list of IP networks for the vif, space-separated (default given in +# this script). #============================================================================ -# Exit if anything goes wrong -set -e -export PATH=/sbin:/bin:/usr/bin:/usr/sbin:$PATH -echo "*vif-route $*" >&2 +dir=$(dirname "$0") +. "$dir/vif-common.sh" -# Operation name. -OP=$1 -shift +main_ip=$(ip addr show eth0 | sed -e '/inet /!d;s/^.*inet \([^\s*]\)\s.*$/\1/') -# Pull variables in args into environment -for arg ; do export "${arg}" ; done - -# Required parameters. Fail if not set. -domain=${domain:?} -vif=${vif:?} -mac=${mac:?} - -# Optional parameters. Set defaults. -ip=${ip:-''} # default to null (do nothing) - -main_ip=`ifconfig eth0 | grep "inet addr:" | sed -e 's/.*inet addr:\(\w\w*\.\w\w*\.\w\w*\.\w\w*\).*/\1/'` - -# Are we going up or down? -case $OP in +case "$command" in up) - ifconfig ${vif} 169.254.1.0 netmask 255.255.255.255 up + ifconfig ${vif} ${main_ip} netmask 255.255.255.255 up echo 1 >/proc/sys/net/ipv4/conf/${vif}/proxy_arp - iptcmd='-A' ipcmd='a' ;; down) - ifconfig ${vif} down - iptcmd='-D' + ifdown ${vif} ipcmd='d' ;; - *) - echo 'Invalid command: ' $OP >&2 - echo 'Valid commands are: up, down' >&2 - exit 1 - ;; esac if [ "${ip}" ] ; then - - # If we've been given a list of IP networks, allow pkts with these src addrs. + # If we've been given a list of IP addresses, then add routes from dom0 to + # the guest using those addresses. for addr in ${ip} ; do ip r ${ipcmd} ${addr} dev ${vif} src ${main_ip} -# iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -s ${addr} -j ACCEPT done - - # Always allow us to talk to a DHCP server anyhow. -# iptables ${iptcmd} FORWARD -m physdev --physdev-in ${vif} -p udp --sport 68 --dport 67 -j ACCEPT fi + +handle_iptable() diff --git a/tools/examples/xen-hotplug-common.sh b/tools/examples/xen-hotplug-common.sh index 10c7d4c87b..c25f493551 100644 --- a/tools/examples/xen-hotplug-common.sh +++ b/tools/examples/xen-hotplug-common.sh @@ -10,19 +10,20 @@ log() { logger -p "daemon.$level" -- "$0:" "$@" || echo "$0 $@" >&2 } +fatal() { + log err "$@" + exit 1 +} + xenstore_read() { local v=$(xenstore-read "$@" || true) - if [ "$v" == "" ] - then - log error "xenstore-read $@ failed." - exit 1 - fi + [ "$v" != "" ] || fatal "xenstore-read $@ failed." echo "$v" } xenstore_write() { log debug "Writing $@ to xenstore." - xenstore-write "$@" || log error "Writing $@ to xenstore failed." + xenstore-write "$@" || log err "Writing $@ to xenstore failed." } log debug "$@" "XENBUS_PATH=$XENBUS_PATH" diff --git a/tools/examples/xen-network-common.sh b/tools/examples/xen-network-common.sh new file mode 100644 index 0000000000..d4af3990ca --- /dev/null +++ b/tools/examples/xen-network-common.sh @@ -0,0 +1,37 @@ +# +# Copyright (c) 2005 XenSource Ltd. +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of version 2.1 of the GNU Lesser General Public +# License as published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + + +# Gentoo doesn't have ifup/ifdown: define appropriate alternatives +if ! which ifup >&/dev/null +then + if [ -e /etc/conf.d/net ] + then + ifup() + { + /etc/init.d/net.$1 start + } + ifdown() + { + /etc/init.d/net.$1 stop + } + else + logger -p "daemon.crit" -- \ + "You don't have ifup and don't seem to be running Gentoo either!" + exit 1 + fi +fi From a04a1a1dc78ddbaceee558d0811f1fe9787b8c3d Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 21 Oct 2005 13:30:31 +0100 Subject: [PATCH 120/142] Break proc paths out into separate include file, rather than inlining them. Signed-off-by: Ewan Mellor --- tools/xenstore/xenstored_domain.c | 5 +++-- tools/xenstore/xenstored_proc.h | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 tools/xenstore/xenstored_proc.h diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index fd2bbdf691..69e429ccfa 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -33,6 +33,7 @@ #include "talloc.h" #include "xenstored_core.h" #include "xenstored_domain.h" +#include "xenstored_proc.h" #include "xenstored_watch.h" #include "xenstored_test.h" @@ -449,7 +450,7 @@ static int dom0_init(void) char str[20]; struct domain *dom0; - fd = open("/proc/xen/xsd_mfn", O_RDONLY); + fd = open(XENSTORED_PROC_MFN, O_RDONLY); rc = read(fd, str, sizeof(str)); str[rc] = '\0'; @@ -457,7 +458,7 @@ static int dom0_init(void) close(fd); - fd = open("/proc/xen/xsd_port", O_RDONLY); + fd = open(XENSTORED_PROC_PORT, O_RDONLY); rc = read(fd, str, sizeof(str)); str[rc] = '\0'; diff --git a/tools/xenstore/xenstored_proc.h b/tools/xenstore/xenstored_proc.h new file mode 100644 index 0000000000..d065b05894 --- /dev/null +++ b/tools/xenstore/xenstored_proc.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2005 XenSource Ltd + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#ifndef _XENSTORED_PROC_H +#define _XENSTORED_PROC_H + +#define XENSTORED_PROC_MFN "/proc/xen/xsd_mfn" +#define XENSTORED_PROC_PORT "/proc/xen/xsd_port" + + +#endif /* _XENSTORED_PROC_H */ From 4e1cf7ae5f8cc7d59f3b5433d3b34a349687d01d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 14:33:46 +0100 Subject: [PATCH 121/142] Fix early bootstrap of secondary VCPUs on x86/64. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c index a0ec7cff1f..f1f733df5a 100644 --- a/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c +++ b/linux-2.6-xen-sparse/arch/xen/kernel/smpboot.c @@ -179,6 +179,8 @@ void vcpu_prepare(int vcpu) ctxt.syscall_callback_eip = (unsigned long)system_call; ctxt.ctrlreg[3] = virt_to_mfn(init_level4_pgt) << PAGE_SHIFT; + + ctxt.gs_base_kernel = (unsigned long)(cpu_pda + vcpu); #endif BUG_ON(HYPERVISOR_vcpu_op(VCPUOP_initialise, vcpu, &ctxt)); @@ -208,6 +210,13 @@ void __init smp_prepare_cpus(unsigned int max_cpus) if (IS_ERR(idle)) panic("failed fork for CPU %d", cpu); +#ifdef __x86_64__ + cpu_pda[cpu].pcurrent = idle; + cpu_pda[cpu].cpunumber = cpu; + per_cpu(init_tss,cpu).rsp0 = idle->thread.rsp; + clear_ti_thread_flag(idle->thread_info, TIF_FORK); +#endif + irq_ctx_init(cpu); cpu_gdt_descr[cpu].address = From 3896d075f802698f5ec8cb3f81366f85c2a401a4 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 21 Oct 2005 15:31:51 +0100 Subject: [PATCH 122/142] Explicitly delete xc instance, which will hopefully solve the intermittent failure to start up. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/server/SrvDaemon.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index c451071bee..80e2d0eb8b 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -271,8 +271,10 @@ class Daemon: try: log.info("Xend Daemon started") - xinfo = xen.lowlevel.xc.new().xeninfo() + xc = xen.lowlevel.xc.new() + xinfo = xc.xeninfo() log.info("Xend changeset: %s.", xinfo['xen_changeset']) + del xc event.listenEvent(self) relocate.listenRelocation() From 64b6e234d2401ea5cf78eb7fd9ff49f0acad2be3 Mon Sep 17 00:00:00 2001 From: "jrb44@plym.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 15:42:26 +0100 Subject: [PATCH 123/142] Add biossums dependency to Makefile to avoid parallel build breakage. Signed-off-by: James Bulpin --- tools/firmware/vgabios/Makefile | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/firmware/vgabios/Makefile b/tools/firmware/vgabios/Makefile index 929d882e72..b1568c248b 100644 --- a/tools/firmware/vgabios/Makefile +++ b/tools/firmware/vgabios/Makefile @@ -33,7 +33,7 @@ release: cp VGABIOS-lgpl-latest.cirrus.debug.bin ../$(RELEASE).cirrus.debug.bin tar czvf ../$(RELEASE).tgz --exclude CVS -C .. $(RELEASE)/ -vgabios.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h +vgabios.bin: biossums vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h $(GCC) -E -P vgabios.c $(VGABIOS_VERS) $(VGABIOS_DATE) > _vgabios_.c $(BCC) -o vgabios.s -C-c -D__i86__ -S -0 _vgabios_.c sed -e 's/^\.text//' -e 's/^\.data//' vgabios.s > _vgabios_.s @@ -43,7 +43,7 @@ vgabios.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h ./biossums VGABIOS-lgpl-latest.bin ls -l VGABIOS-lgpl-latest.bin -vgabios.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h +vgabios.debug.bin: biossums vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetables.h $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DDEBUG $(VGABIOS_DATE) > _vgabios-debug_.c $(BCC) -o vgabios-debug.s -C-c -D__i86__ -S -0 _vgabios-debug_.c sed -e 's/^\.text//' -e 's/^\.data//' vgabios-debug.s > _vgabios-debug_.s @@ -53,7 +53,7 @@ vgabios.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h vbe.h vbe.c vbetab ./biossums VGABIOS-lgpl-latest.debug.bin ls -l VGABIOS-lgpl-latest.debug.bin -vgabios-cirrus.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c +vgabios-cirrus.bin: biossums vgabios.c vgabios.h vgafonts.h vgatables.h clext.c $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DCIRRUS $(VGABIOS_DATE) > _vgabios-cirrus_.c $(BCC) -o vgabios-cirrus.s -C-c -D__i86__ -S -0 _vgabios-cirrus_.c sed -e 's/^\.text//' -e 's/^\.data//' vgabios-cirrus.s > _vgabios-cirrus_.s @@ -63,7 +63,7 @@ vgabios-cirrus.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c ./biossums VGABIOS-lgpl-latest.cirrus.bin ls -l VGABIOS-lgpl-latest.cirrus.bin -vgabios-cirrus.debug.bin: vgabios.c vgabios.h vgafonts.h vgatables.h clext.c +vgabios-cirrus.debug.bin: biossums vgabios.c vgabios.h vgafonts.h vgatables.h clext.c $(GCC) -E -P vgabios.c $(VGABIOS_VERS) -DCIRRUS -DCIRRUS_DEBUG $(VGABIOS_DATE) > _vgabios-cirrus-debug_.c $(BCC) -o vgabios-cirrus-debug.s -C-c -D__i86__ -S -0 _vgabios-cirrus-debug_.c sed -e 's/^\.text//' -e 's/^\.data//' vgabios-cirrus-debug.s > _vgabios-cirrus-debug_.s From 73e4aa4e2b844b0b53802348c0d26a7e7bda36c4 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 16:22:09 +0100 Subject: [PATCH 124/142] Fix allocation of phys_to_machine_mapping array during x86/64 linux boot. The original builder-provided array must be made read-only in the initial mapping. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c | 2 +- linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c index 6f9ab86b79..c4f0999d32 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/e820.c @@ -519,7 +519,7 @@ void __init setup_memory_region(void) e820_print_map(who); } -#else /* CONFIX_XEN */ +#else /* CONFIG_XEN */ extern unsigned long xen_override_max_pfn; extern union xen_start_info_union xen_start_info_union; diff --git a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c index 19f5e957a5..9c51a4f270 100644 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/setup.c @@ -733,6 +733,7 @@ void __init setup_arch(char **cmdline_p) #ifdef CONFIG_XEN { int i, j, k, fpp; + /* Make sure we have a large enough P->M table. */ phys_to_machine_mapping = alloc_bootmem( end_pfn * sizeof(unsigned long)); @@ -745,6 +746,9 @@ void __init setup_arch(char **cmdline_p) __pa(xen_start_info->mfn_list), PFN_PHYS(PFN_UP(xen_start_info->nr_pages * sizeof(unsigned long)))); + make_pages_readonly((void *)xen_start_info->mfn_list, + PFN_UP(xen_start_info->nr_pages * + sizeof(unsigned long))); /* * Initialise the list of the frames that specify the list of From 7ebcb094f9f19f8230ac0d72c4b9c53d55ebb51b Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 18:19:38 +0100 Subject: [PATCH 125/142] Tweak to pygrub build config detection. Signed-off-by: Jeremy Katz --- tools/pygrub/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/pygrub/setup.py b/tools/pygrub/setup.py index 43e46762a8..5e0937bbad 100644 --- a/tools/pygrub/setup.py +++ b/tools/pygrub/setup.py @@ -13,7 +13,7 @@ if os.path.exists("/usr/include/ext2fs/ext2_fs.h"): cc = new_compiler() cc.add_library("ext2fs") try: - if cc.has_function("ext2fs_open2"): + if hasattr(cc, "has_function") and cc.has_function("ext2fs_open2"): ext2defines.append( ("HAVE_EXT2FS_OPEN2", None) ) else: sys.stderr.write("WARNING: older version of e2fsprogs installed, not building full\n") From 3f450621b643420c39eb267d207b4bb0ccd61b91 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 18:29:26 +0100 Subject: [PATCH 126/142] This is a follow up of PIC device model by Xiaofeng and me to move to hypervisor using virtual weired interrupt line. With this patch the performance of CPU2K improves 7%, kernel kuild improves 14% and cyclesoak improves 12%. It is quite amazing! Signed-off-by: Xiaofeng Ling Signed-off-by: Eddie Dong --- tools/ioemu/hw/i8254.c | 4 +- tools/ioemu/hw/i8259_stub.c | 96 +++++ tools/ioemu/target-i386-dm/Makefile | 2 +- tools/ioemu/target-i386-dm/helper2.c | 20 -- xen/arch/x86/Makefile | 2 + xen/arch/x86/dm/i8259.c | 520 +++++++++++++++++++++++++++ xen/arch/x86/domain.c | 1 - xen/arch/x86/vmx.c | 4 +- xen/arch/x86/vmx_intercept.c | 18 +- xen/arch/x86/vmx_io.c | 131 +++---- xen/arch/x86/vmx_vmcs.c | 11 +- xen/include/asm-x86/vmx.h | 1 + xen/include/asm-x86/vmx_intercept.h | 2 +- xen/include/asm-x86/vmx_platform.h | 3 + xen/include/asm-x86/vmx_virpit.h | 6 +- xen/include/public/io/ioreq.h | 6 +- xen/include/public/io/vmx_vpic.h | 84 +++++ 17 files changed, 789 insertions(+), 122 deletions(-) create mode 100644 tools/ioemu/hw/i8259_stub.c create mode 100644 xen/arch/x86/dm/i8259.c create mode 100644 xen/include/public/io/vmx_vpic.h diff --git a/tools/ioemu/hw/i8254.c b/tools/ioemu/hw/i8254.c index b506acc695..111a6c6144 100644 --- a/tools/ioemu/hw/i8254.c +++ b/tools/ioemu/hw/i8254.c @@ -222,9 +222,7 @@ void pit_reset_vmx_vectors() int irq, i; PITChannelState *s; - /* Assumes PIT is wired to IRQ0 and -1 is uninitialized irq base */ - if ((irq = pic_irq2vec(0)) == -1) - return; + irq = 0; for(i = 0; i < 3; i++) { if (pit_state.channels[i].vmx_channel) diff --git a/tools/ioemu/hw/i8259_stub.c b/tools/ioemu/hw/i8259_stub.c new file mode 100644 index 0000000000..2315184e9e --- /dev/null +++ b/tools/ioemu/hw/i8259_stub.c @@ -0,0 +1,96 @@ +/* Xen 8259 stub for interrupt controller emulation + * + * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2005 Intel corperation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "xenctrl.h" +#include +#include +#include "cpu.h" +#include "cpu-all.h" + +static __inline__ void atomic_set_bit(long nr, volatile void *addr) +{ + __asm__ __volatile__( + "lock ; bts %1,%0" + :"=m" (*(volatile long *)addr) + :"dIr" (nr)); +} +static __inline__ void atomic_clear_bit(long nr, volatile void *addr) +{ + __asm__ __volatile__( + "lock ; btr %1,%0" + :"=m" (*(volatile long *)addr) + :"dIr" (nr)); +} + +#include +extern shared_iopage_t *shared_page; +extern CPUState *global_env; +void pic_set_irq(int irq, int level) +{ + global_iodata_t *gio; + int mask; + + gio = &shared_page->sp_global; + mask = 1 << irq; + if ( gio->pic_elcr & mask ) { + /* level */ + if ( level ) { + atomic_set_bit(irq, &gio->pic_irr); + atomic_clear_bit(irq, &gio->pic_clear_irr); + global_env->send_event = 1; + } + else { + atomic_set_bit(irq, &gio->pic_clear_irr); + atomic_clear_bit(irq, &gio->pic_irr); + global_env->send_event = 1; + } + } + else { + /* edge */ + if ( level ) { + if ( (mask & gio->pic_last_irr) == 0 ) { + atomic_set_bit(irq, &gio->pic_irr); + atomic_set_bit(irq, &gio->pic_last_irr); + global_env->send_event = 1; + } + } + else { + atomic_clear_bit(irq, &gio->pic_last_irr); + } + } +} + +void irq_info(void) +{ + term_printf("irq statistic code not compiled.\n"); +} + +void pic_info(void) +{ + term_printf("pic_infoi code not compiled.\n"); +} + +void pic_init(void) +{ +} + diff --git a/tools/ioemu/target-i386-dm/Makefile b/tools/ioemu/target-i386-dm/Makefile index ec0c7a513a..465d0c1a02 100644 --- a/tools/ioemu/target-i386-dm/Makefile +++ b/tools/ioemu/target-i386-dm/Makefile @@ -271,7 +271,7 @@ endif # Hardware support VL_OBJS+= ide.o ne2000.o pckbd.o vga.o dma.o -VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pc.o port-e9.o +VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259_stub.o i8254.o pc.o port-e9.o VL_OBJS+= cirrus_vga.o pcnet.o ifeq ($(TARGET_ARCH), ppc) diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c index 0acb6fe29e..acc82ebacb 100644 --- a/tools/ioemu/target-i386-dm/helper2.c +++ b/tools/ioemu/target-i386-dm/helper2.c @@ -403,20 +403,6 @@ static __inline__ void atomic_set_bit(long nr, volatile void *addr) :"dIr" (nr)); } -void -do_interrupt(CPUState *env, int vector) -{ - unsigned long *intr; - - // Send a message on the event channel. Add the vector to the shared mem - // page. - intr = (unsigned long *) &(shared_page->sp_global.pic_intr[0]); - atomic_set_bit(vector, intr); - if (loglevel & CPU_LOG_INT) - fprintf(logfile, "injecting vector: %x\n", vector); - env->send_event = 1; -} - void destroy_vmx_domain(void) { @@ -429,7 +415,6 @@ destroy_vmx_domain(void) int main_loop(void) { - int vector; fd_set rfds; struct timeval tv; extern CPUState *global_env; @@ -476,11 +461,6 @@ int main_loop(void) ioapic_update_EOI(); #endif cpu_timer_handler(env); - if (env->interrupt_request & CPU_INTERRUPT_HARD) { - env->interrupt_request &= ~CPU_INTERRUPT_HARD; - vector = cpu_get_pic_interrupt(env); - do_interrupt(env, vector); - } #ifdef APIC_SUPPORT if (ioapic_has_intr()) do_ioapic(); diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile index 5a8549ea44..ecd0b64e68 100644 --- a/xen/arch/x86/Makefile +++ b/xen/arch/x86/Makefile @@ -4,6 +4,7 @@ include $(BASEDIR)/Rules.mk OBJS += $(patsubst %.S,%.o,$(wildcard $(TARGET_SUBARCH)/*.S)) OBJS += $(patsubst %.c,%.o,$(wildcard $(TARGET_SUBARCH)/*.c)) OBJS += $(patsubst %.c,%.o,$(wildcard acpi/*.c)) +OBJS += $(patsubst %.c,%.o,$(wildcard dm/*.c)) OBJS += $(patsubst %.c,%.o,$(wildcard mtrr/*.c)) OBJS += $(patsubst %.c,%.o,$(wildcard genapic/*.c)) OBJS += $(patsubst %.c,%.o,$(wildcard cpu/*.c)) @@ -66,6 +67,7 @@ clean: rm -f x86_64/*.o x86_64/*~ x86_64/core rm -f mtrr/*.o mtrr/*~ mtrr/core rm -f acpi/*.o acpi/*~ acpi/core + rm -f dm/*.o dm/*~ dm/core rm -f genapic/*.o genapic/*~ genapic/core rm -f cpu/*.o cpu/*~ cpu/core diff --git a/xen/arch/x86/dm/i8259.c b/xen/arch/x86/dm/i8259.c new file mode 100644 index 0000000000..557d2f27b7 --- /dev/null +++ b/xen/arch/x86/dm/i8259.c @@ -0,0 +1,520 @@ +/* + * QEMU 8259 interrupt controller emulation + * + * Copyright (c) 2003-2004 Fabrice Bellard + * Copyright (c) 2005 Intel Corperation + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* set irq level. If an edge is detected, then the IRR is set to 1 */ +static inline void pic_set_irq1(PicState *s, int irq, int level) +{ + int mask; + mask = 1 << irq; + if (s->elcr & mask) { + /* level triggered */ + if (level) { + s->irr |= mask; + s->last_irr |= mask; + } else { + s->irr &= ~mask; + s->last_irr &= ~mask; + } + } else { + /* edge triggered */ + if (level) { + if ((s->last_irr & mask) == 0) { + s->irr |= mask; + } + s->last_irr |= mask; + } else { + s->last_irr &= ~mask; + } + } +} + +/* return the highest priority found in mask (highest = smallest + number). Return 8 if no irq */ +static inline int get_priority(PicState *s, int mask) +{ + int priority; + if (mask == 0) + return 8; + priority = 0; + while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) + priority++; + return priority; +} + +/* return the pic wanted interrupt. return -1 if none */ +static int pic_get_irq(PicState *s) +{ + int mask, cur_priority, priority; + + mask = s->irr & ~s->imr; + priority = get_priority(s, mask); + if (priority == 8) + return -1; + /* compute current priority. If special fully nested mode on the + master, the IRQ coming from the slave is not taken into account + for the priority computation. */ + mask = s->isr; + if (s->special_fully_nested_mode && s == &s->pics_state->pics[0]) + mask &= ~(1 << 2); + cur_priority = get_priority(s, mask); + if (priority < cur_priority) { + /* higher priority found: an irq should be generated */ + return (priority + s->priority_add) & 7; + } else { + return -1; + } +} + +/* raise irq to CPU if necessary. must be called every time the active + irq may change */ +/* XXX: should not export it, but it is needed for an APIC kludge */ +void pic_update_irq(struct vmx_virpic *s) +{ + int irq2, irq; + + /* first look at slave pic */ + irq2 = pic_get_irq(&s->pics[1]); + if (irq2 >= 0) { + /* if irq request by slave pic, signal master PIC */ + pic_set_irq1(&s->pics[0], 2, 1); + pic_set_irq1(&s->pics[0], 2, 0); + } + /* look at requested irq */ + irq = pic_get_irq(&s->pics[0]); + if (irq >= 0) { + s->irq_request(s->irq_request_opaque, 1); + } +} + +void pic_set_irq_new(void *opaque, int irq, int level) +{ + struct vmx_virpic *s = opaque; + + pic_set_irq1(&s->pics[irq >> 3], irq & 7, level); + /* used for IOAPIC irqs */ + if (s->alt_irq_func) + s->alt_irq_func(s->alt_irq_opaque, irq, level); + pic_update_irq(s); +} + +void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs) +{ + s->pics[1].irr |= (uint8_t)(irqs >> 8); + s->pics[0].irr |= (uint8_t) irqs; + /* TODO for alt_irq_func */ + pic_update_irq(s); +} + +void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs) +{ + s->pics[1].irr &= ~(uint8_t)(irqs >> 8); + s->pics[0].irr &= ~(uint8_t) irqs; + pic_update_irq(s); +} + +/* obsolete function */ +void pic_set_irq(struct vmx_virpic *isa_pic, int irq, int level) +{ + pic_set_irq_new(isa_pic, irq, level); +} + +/* acknowledge interrupt 'irq' */ +static inline void pic_intack(PicState *s, int irq) +{ + if (s->auto_eoi) { + if (s->rotate_on_auto_eoi) + s->priority_add = (irq + 1) & 7; + } else { + s->isr |= (1 << irq); + } + /* We don't clear a level sensitive interrupt here */ + if (!(s->elcr & (1 << irq))) + s->irr &= ~(1 << irq); +} + +int pic_read_irq(struct vmx_virpic *s) +{ + int irq, irq2, intno; + + irq = pic_get_irq(&s->pics[0]); + if (irq >= 0) { + pic_intack(&s->pics[0], irq); + if (irq == 2) { + irq2 = pic_get_irq(&s->pics[1]); + if (irq2 >= 0) { + pic_intack(&s->pics[1], irq2); + } else { + /* spurious IRQ on slave controller */ + irq2 = 7; + } + intno = s->pics[1].irq_base + irq2; + irq = irq2 + 8; + } else { + intno = s->pics[0].irq_base + irq; + } + } else { + /* spurious IRQ on host controller */ + printk("spurious IRQ irq got=%d\n",irq); + irq = 7; + intno = s->pics[0].irq_base + irq; + } + pic_update_irq(s); + + return intno; +} + +static void update_shared_irr(struct vmx_virpic *s, PicState *c) +{ + uint8_t *pl, *pe; + + get_sp(current->domain)->sp_global.pic_elcr = + s->pics[0].elcr | ((u16)s->pics[1].elcr << 8); + pl =(uint8_t*)&get_sp(current->domain)->sp_global.pic_last_irr; + pe =(uint8_t*)&get_sp(current->domain)->sp_global.pic_elcr; + if ( c == &s->pics[0] ) { + *pl = c->last_irr; + *pe = c->elcr; + } + else { + *(pl+1) = c->last_irr; + *(pe+1) = c->elcr; + } +} + +static void pic_reset(void *opaque) +{ + PicState *s = opaque; + + s->last_irr = 0; + s->irr = 0; + s->imr = 0; + s->isr = 0; + s->priority_add = 0; + s->irq_base = 0; + s->read_reg_select = 0; + s->poll = 0; + s->special_mask = 0; + s->init_state = 0; + s->auto_eoi = 0; + s->rotate_on_auto_eoi = 0; + s->special_fully_nested_mode = 0; + s->init4 = 0; + s->elcr = 0; +} + +static void pic_ioport_write(void *opaque, uint32_t addr, uint32_t val) +{ + PicState *s = opaque; + int priority, cmd, irq; + + addr &= 1; + if (addr == 0) { + if (val & 0x10) { + /* init */ + pic_reset(s); + update_shared_irr(s->pics_state, s); + /* deassert a pending interrupt */ + s->pics_state->irq_request(s->pics_state->irq_request_opaque, 0); + s->init_state = 1; + s->init4 = val & 1; + if (val & 0x02) + hw_error("single mode not supported"); + if (val & 0x08) + hw_error("level sensitive irq not supported"); + } else if (val & 0x08) { + if (val & 0x04) + s->poll = 1; + if (val & 0x02) + s->read_reg_select = val & 1; + if (val & 0x40) + s->special_mask = (val >> 5) & 1; + } else { + cmd = val >> 5; + switch(cmd) { + case 0: + case 4: + s->rotate_on_auto_eoi = cmd >> 2; + break; + case 1: /* end of interrupt */ + case 5: + priority = get_priority(s, s->isr); + if (priority != 8) { + irq = (priority + s->priority_add) & 7; + s->isr &= ~(1 << irq); + if (cmd == 5) + s->priority_add = (irq + 1) & 7; + pic_update_irq(s->pics_state); + } + break; + case 3: + irq = val & 7; + s->isr &= ~(1 << irq); + pic_update_irq(s->pics_state); + break; + case 6: + s->priority_add = (val + 1) & 7; + pic_update_irq(s->pics_state); + break; + case 7: + irq = val & 7; + s->isr &= ~(1 << irq); + s->priority_add = (irq + 1) & 7; + pic_update_irq(s->pics_state); + break; + default: + /* no operation */ + break; + } + } + } else { + switch(s->init_state) { + case 0: + /* normal mode */ + s->imr = val; + pic_update_irq(s->pics_state); + break; + case 1: + s->irq_base = val & 0xf8; + s->init_state = 2; + break; + case 2: + if (s->init4) { + s->init_state = 3; + } else { + s->init_state = 0; + } + break; + case 3: + s->special_fully_nested_mode = (val >> 4) & 1; + s->auto_eoi = (val >> 1) & 1; + s->init_state = 0; + break; + } + } +} + +static uint32_t pic_poll_read (PicState *s, uint32_t addr1) +{ + int ret; + + ret = pic_get_irq(s); + if (ret >= 0) { + if (addr1 >> 7) { + s->pics_state->pics[0].isr &= ~(1 << 2); + s->pics_state->pics[0].irr &= ~(1 << 2); + } + s->irr &= ~(1 << ret); + s->isr &= ~(1 << ret); + if (addr1 >> 7 || ret != 2) + pic_update_irq(s->pics_state); + } else { + ret = 0x07; + pic_update_irq(s->pics_state); + } + + return ret; +} + +static uint32_t pic_ioport_read(void *opaque, uint32_t addr1) +{ + PicState *s = opaque; + unsigned int addr; + int ret; + + addr = addr1; + addr &= 1; + if (s->poll) { + ret = pic_poll_read(s, addr1); + s->poll = 0; + } else { + if (addr == 0) { + if (s->read_reg_select) + ret = s->isr; + else + ret = s->irr; + } else { + ret = s->imr; + } + } + return ret; +} + +/* memory mapped interrupt status */ +/* XXX: may be the same than pic_read_irq() */ +uint32_t pic_intack_read(struct vmx_virpic *s) +{ + int ret; + + ret = pic_poll_read(&s->pics[0], 0x00); + if (ret == 2) + ret = pic_poll_read(&s->pics[1], 0x80) + 8; + /* Prepare for ISR read */ + s->pics[0].read_reg_select = 1; + + return ret; +} + +static void elcr_ioport_write(void *opaque, uint32_t addr, uint32_t val) +{ + PicState *s = opaque; + s->elcr = val & s->elcr_mask; +} + +static uint32_t elcr_ioport_read(void *opaque, uint32_t addr1) +{ + PicState *s = opaque; + return s->elcr; +} + +/* XXX: add generic master/slave system */ +static void pic_init1(int io_addr, int elcr_addr, PicState *s) +{ + pic_reset(s); +} + +void pic_init(struct vmx_virpic *s, void (*irq_request)(), + void *irq_request_opaque) +{ + memset(s, 0, sizeof(*s)); + pic_init1(0x20, 0x4d0, &s->pics[0]); + pic_init1(0xa0, 0x4d1, &s->pics[1]); + s->pics[0].elcr_mask = 0xf8; + s->pics[1].elcr_mask = 0xde; + s->irq_request = irq_request; + s->irq_request_opaque = irq_request_opaque; + s->pics[0].pics_state = s; + s->pics[1].pics_state = s; + return; +} + +void pic_set_alt_irq_func(struct vmx_virpic *s, void (*alt_irq_func)(), + void *alt_irq_opaque) +{ + s->alt_irq_func = alt_irq_func; + s->alt_irq_opaque = alt_irq_opaque; +} + +static int intercept_pic_io(ioreq_t *p) +{ + struct vmx_virpic *pic; + struct vcpu *v = current; + uint32_t data; + + if ( p->size != 1 || p->count != 1) { + printk("PIC_IO wrong access size %d!\n", (int)p->size); + return 1; + } + pic = &v->domain->arch.vmx_platform.vmx_pic; + if ( p->dir == 0 ) { + if(p->pdata_valid) + vmx_copy(&data, (unsigned long)p->u.pdata, p->size, VMX_COPY_IN); + else + data = p->u.data; + pic_ioport_write((void*)&pic->pics[p->addr>>7], + (uint32_t) p->addr, (uint32_t) (data & 0xff)); + } + else { + data = pic_ioport_read( + (void*)&pic->pics[p->addr>>7], (uint32_t) p->addr); + if(p->pdata_valid) + vmx_copy(&data, (unsigned long)p->u.pdata, p->size, VMX_COPY_OUT); + else + p->u.data = (u64)data; + } + return 1; +} + +static int intercept_elcr_io(ioreq_t *p) +{ + struct vmx_virpic *s; + struct vcpu *v = current; + uint32_t data; + + if ( p->size != 1 || p->count != 1 ) { + printk("PIC_IO wrong access size %d!\n", (int)p->size); + return 1; + } + + s = &v->domain->arch.vmx_platform.vmx_pic; + if ( p->dir == 0 ) { + if(p->pdata_valid) + vmx_copy(&data, (unsigned long)p->u.pdata, p->size, VMX_COPY_IN); + else + data = p->u.data; + elcr_ioport_write((void*)&s->pics[p->addr&1], + (uint32_t) p->addr, (uint32_t)( data & 0xff)); + get_sp(current->domain)->sp_global.pic_elcr = + s->pics[0].elcr | ((u16)s->pics[1].elcr << 8); + } + else { + data = (u64) elcr_ioport_read( + (void*)&s->pics[p->addr&1], (uint32_t) p->addr); + if(p->pdata_valid) + vmx_copy(&data, (unsigned long)p->u.pdata, p->size, VMX_COPY_OUT); + else + p->u.data = (u64)data; + + } + return 1; +} +void register_pic_io_hook (void) +{ + register_portio_handler(0x20, 2, intercept_pic_io); + register_portio_handler(0x4d0, 1, intercept_elcr_io); + register_portio_handler(0xa0, 2, intercept_pic_io); + register_portio_handler(0x4d1, 1, intercept_elcr_io); +} + + +/* IRQ handling */ +int cpu_get_pic_interrupt(struct vcpu *v, int *type) +{ + int intno; + struct vmx_virpic *s = &v->domain->arch.vmx_platform.vmx_pic; + + /* read the irq from the PIC */ + intno = pic_read_irq(s); + *type = VLAPIC_DELIV_MODE_EXT; + return intno; +} + +int is_pit_irq(struct vcpu *v, int irq) +{ + int pit_vec = v->domain->arch.vmx_platform.vmx_pic.pics[0].irq_base; + + return (irq == pit_vec); +} diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index c52448d2fd..cbb1863e95 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -39,7 +39,6 @@ #include #include #include -#include #include /* opt_noreboot: If true, machine will need manual reset on error. */ diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index c403002bef..e77370c9ec 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -647,8 +647,8 @@ void send_pio_req(struct cpu_user_regs *regs, unsigned long port, p->u.data = value; if (vmx_portio_intercept(p)) { - /* no blocking & no evtchn notification */ - clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags); + p->state = STATE_IORESP_READY; + vmx_io_assist(v); return; } diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index 43b48db5da..4e9a1fe86d 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -209,8 +209,7 @@ static void pit_timer_fn(void *data) missed_ticks = (NOW() - vpit->scheduled)/(s_time_t) vpit->period; /* Set the pending intr bit, and send evtchn notification to myself. */ - if (test_and_set_bit(vpit->vector, vpit->intr_bitmap)) - vpit->pending_intr_nr++; /* already set, then count the pending intr */ + vpit->pending_intr_nr++; /* already set, then count the pending intr */ evtchn_set_pending(vpit->v, iopacket_port(vpit->v->domain)); /* pick up missed timer tick */ @@ -230,11 +229,8 @@ void vmx_hooks_assist(struct vcpu *v) { vcpu_iodata_t *vio = get_vio(v->domain, v->vcpu_id); ioreq_t *p = &vio->vp_ioreq; - shared_iopage_t *sp = get_sp(v->domain); - u64 *intr = &(sp->sp_global.pic_intr[0]); struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); int rw_mode, reinit = 0; - int oldvec = 0; /* load init count*/ if (p->state == STATE_IORESP_HOOK) { @@ -243,7 +239,7 @@ void vmx_hooks_assist(struct vcpu *v) VMX_DBG_LOG(DBG_LEVEL_1, "VMX_PIT: guest reset PIT with channel %lx!\n", (unsigned long) ((p->u.data >> 24) & 0x3) ); rem_ac_timer(&(vpit->pit_timer)); reinit = 1; - oldvec = vpit->vector; + } else init_ac_timer(&vpit->pit_timer, pit_timer_fn, vpit, v->processor); @@ -258,12 +254,6 @@ void vmx_hooks_assist(struct vcpu *v) vpit->init_val); vpit->period = 1000000; } - vpit->vector = ((p->u.data >> 16) & 0xFF); - - if( reinit && oldvec != vpit->vector){ - clear_bit(oldvec, intr); - vpit->pending_intr_nr = 0; - } vpit->channel = ((p->u.data >> 24) & 0x3); vpit->first_injected = 0; @@ -287,7 +277,6 @@ void vmx_hooks_assist(struct vcpu *v) break; } - vpit->intr_bitmap = intr; vpit->v = v; vpit->scheduled = NOW() + vpit->period; @@ -297,8 +286,9 @@ void vmx_hooks_assist(struct vcpu *v) p->state = STATE_IORESP_READY; /* register handler to intercept the PIT io when vm_exit */ - if (!reinit) + if (!reinit) { register_portio_handler(0x40, 4, intercept_pit_io); + } } } #endif /* CONFIG_VMX */ diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 1530e7b533..31e6f17e78 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -37,6 +37,7 @@ #include #include +#include #include #ifdef CONFIG_VMX @@ -794,57 +795,6 @@ static __inline__ int find_highest_irq(u32 *pintr) } #define BSP_CPU(v) (!(v->vcpu_id)) -static inline void clear_extint(struct vcpu *v) -{ - global_iodata_t *spg; - int i; - spg = &get_sp(v->domain)->sp_global; - - for(i = 0; i < INTR_LEN; i++) - spg->pic_intr[i] = 0; -} - -static inline void clear_highest_bit(struct vcpu *v, int vector) -{ - global_iodata_t *spg; - - spg = &get_sp(v->domain)->sp_global; - - clear_bit(vector, &spg->pic_intr[0]); -} - -static inline int find_highest_pic_irq(struct vcpu *v) -{ - u64 intr[INTR_LEN]; - global_iodata_t *spg; - int i; - - if(!BSP_CPU(v)) - return -1; - - spg = &get_sp(v->domain)->sp_global; - - for(i = 0; i < INTR_LEN; i++){ - intr[i] = spg->pic_intr[i] & ~spg->pic_mask[i]; - } - - return find_highest_irq((u32 *)&intr[0]); -} - -/* - * Return 0-255 for pending irq. - * -1 when no pending. - */ -static inline int find_highest_pending_irq(struct vcpu *v, int *type) -{ - int result = -1; - if ((result = find_highest_pic_irq(v)) != -1){ - *type = VLAPIC_DELIV_MODE_EXT; - return result; - } - return result; -} - static inline void interrupt_post_injection(struct vcpu * v, int vector, int type) { @@ -853,17 +803,17 @@ interrupt_post_injection(struct vcpu * v, int vector, int type) switch(type) { case VLAPIC_DELIV_MODE_EXT: - if (vpit->pending_intr_nr && vector == vpit->vector) - vpit->pending_intr_nr--; - else - clear_highest_bit(v, vector); - - if (vector == vpit->vector && !vpit->first_injected){ - vpit->first_injected = 1; - vpit->pending_intr_nr = 0; - } - if (vector == vpit->vector) + if ( is_pit_irq(v, vector) ) { + if ( !vpit->first_injected ) { + vpit->first_injected = 1; + vpit->pending_intr_nr = 0; + } + else { + vpit->pending_intr_nr--; + } vpit->inject_point = NOW(); + + } break; default: @@ -895,17 +845,56 @@ static inline int irq_masked(unsigned long eflags) return ((eflags & X86_EFLAGS_IF) == 0); } +void pic_irq_request(int *interrupt_request, int level) +{ + if (level) + *interrupt_request = 1; + else + *interrupt_request = 0; +} + +void vmx_pic_assist(struct vcpu *v) +{ + global_iodata_t *spg; + u16 *virq_line, irqs; + struct vmx_virpic *pic = &v->domain->arch.vmx_platform.vmx_pic; + + spg = &get_sp(v->domain)->sp_global; + virq_line = &spg->pic_clear_irr; + if ( *virq_line ) { + do { + irqs = *(volatile u16*)virq_line; + } while ( (u16)cmpxchg(virq_line,irqs, 0) != irqs ); + do_pic_irqs_clear(pic, irqs); + } + virq_line = &spg->pic_irr; + if ( *virq_line ) { + do { + irqs = *(volatile u16*)virq_line; + } while ( (u16)cmpxchg(virq_line,irqs, 0) != irqs ); + do_pic_irqs(pic, irqs); + } + +} + asmlinkage void vmx_intr_assist(void) { int intr_type = 0; int highest_vector; unsigned long intr_fields, eflags, interruptibility, cpu_exec_control; struct vcpu *v = current; + struct virtual_platform_def *plat=&v->domain->arch.vmx_platform; + struct vmx_virpit *vpit = &plat->vmx_pit; + struct vmx_virpic *pic= &plat->vmx_pic; - highest_vector = find_highest_pending_irq(v, &intr_type); + vmx_pic_assist(v); __vmread_vcpu(v, CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control); + if ( vpit->pending_intr_nr ) { + pic_set_irq(pic, 0, 0); + pic_set_irq(pic, 0, 1); + } - if (highest_vector == -1) { + if ( !plat->interrupt_request ) { disable_irq_window(cpu_exec_control); return; } @@ -922,22 +911,20 @@ asmlinkage void vmx_intr_assist(void) if (interruptibility) { enable_irq_window(cpu_exec_control); - VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, interruptibility: %lx", - highest_vector, interruptibility); + VMX_DBG_LOG(DBG_LEVEL_1, "interruptibility: %lx",interruptibility); return; } __vmread(GUEST_RFLAGS, &eflags); + if (irq_masked(eflags)) { + enable_irq_window(cpu_exec_control); + return; + } + plat->interrupt_request = 0; + highest_vector = cpu_get_pic_interrupt(v, &intr_type); switch (intr_type) { case VLAPIC_DELIV_MODE_EXT: - if (irq_masked(eflags)) { - enable_irq_window(cpu_exec_control); - VMX_DBG_LOG(DBG_LEVEL_1, "guesting pending: %x, eflags: %lx", - highest_vector, eflags); - return; - } - vmx_inject_extint(v, highest_vector, VMX_INVALID_ERROR_CODE); TRACE_3D(TRC_VMX_INT, v->domain->domain_id, highest_vector, 0); break; diff --git a/xen/arch/x86/vmx_vmcs.c b/xen/arch/x86/vmx_vmcs.c index bf5fe057c1..92150eafb6 100644 --- a/xen/arch/x86/vmx_vmcs.c +++ b/xen/arch/x86/vmx_vmcs.c @@ -210,8 +210,14 @@ static void get_io_shared_page(struct vcpu *v) static void vmx_setup_platform(struct vcpu *v) { - if (v->vcpu_id == 0) + struct virtual_platform_def *platform; + if (v->vcpu_id == 0) { get_io_shared_page(v); + platform = &v->domain->arch.vmx_platform; + pic_init(&platform->vmx_pic, pic_irq_request, + &platform->interrupt_request); + register_pic_io_hook(); + } } static void vmx_set_host_env(struct vcpu *v) @@ -275,7 +281,8 @@ static void vmx_do_launch(struct vcpu *v) page = (struct pfn_info *) alloc_domheap_page(NULL); pfn = (unsigned long) (page - frame_table); - vmx_setup_platform(v); + if ( v == v->domain->vcpu[0] ) + vmx_setup_platform(v); vmx_set_host_env(v); diff --git a/xen/include/asm-x86/vmx.h b/xen/include/asm-x86/vmx.h index c1ba8fd436..fefb109f41 100644 --- a/xen/include/asm-x86/vmx.h +++ b/xen/include/asm-x86/vmx.h @@ -34,6 +34,7 @@ extern void vmx_asm_vmexit_handler(struct cpu_user_regs); extern void vmx_asm_do_resume(void); extern void vmx_asm_do_launch(void); extern void vmx_intr_assist(void); +extern void pic_irq_request(int *interrupt_request, int level); extern void arch_vmx_do_launch(struct vcpu *); extern void arch_vmx_do_resume(struct vcpu *); diff --git a/xen/include/asm-x86/vmx_intercept.h b/xen/include/asm-x86/vmx_intercept.h index 598aab5599..80ab22e723 100644 --- a/xen/include/asm-x86/vmx_intercept.h +++ b/xen/include/asm-x86/vmx_intercept.h @@ -8,7 +8,7 @@ #include #include -#define MAX_IO_HANDLER 4 +#define MAX_IO_HANDLER 8 #define VMX_PORTIO 0 #define VMX_MMIO 1 diff --git a/xen/include/asm-x86/vmx_platform.h b/xen/include/asm-x86/vmx_platform.h index 484ec79edd..a7c2a79d18 100644 --- a/xen/include/asm-x86/vmx_platform.h +++ b/xen/include/asm-x86/vmx_platform.h @@ -24,6 +24,7 @@ #include #include #include +#include #define MAX_OPERAND_NUM 2 @@ -80,6 +81,8 @@ struct virtual_platform_def { unsigned long shared_page_va; struct vmx_virpit vmx_pit; struct vmx_io_handler vmx_io_handler; + struct vmx_virpic vmx_pic; + int interrupt_request; }; extern void handle_mmio(unsigned long, unsigned long); diff --git a/xen/include/asm-x86/vmx_virpit.h b/xen/include/asm-x86/vmx_virpit.h index ba08d0ab8b..d0c758dd37 100644 --- a/xen/include/asm-x86/vmx_virpit.h +++ b/xen/include/asm-x86/vmx_virpit.h @@ -18,13 +18,11 @@ struct vmx_virpit { /* for simulation of counter 0 in mode 2*/ - int vector; /* the pit irq vector */ - unsigned int period; /* the frequency. e.g. 10ms*/ + u32 period; /* pit frequency in ns */ s_time_t scheduled; /* scheduled timer interrupt */ unsigned int channel; /* the pit channel, counter 0~2 */ - u64 *intr_bitmap; unsigned int pending_intr_nr; /* the couner for pending timer interrupts */ - unsigned long long inject_point; /* the time inject virt intr */ + u64 inject_point; /* the time inject virt intr */ struct ac_timer pit_timer; /* periodic timer for mode 2*/ int first_injected; /* flag to prevent shadow window */ diff --git a/xen/include/public/io/ioreq.h b/xen/include/public/io/ioreq.h index d502171bbf..86c5d8d741 100644 --- a/xen/include/public/io/ioreq.h +++ b/xen/include/public/io/ioreq.h @@ -60,8 +60,10 @@ typedef struct { #define INTR_LEN (MAX_VECTOR/(BITS_PER_BYTE * sizeof(uint64_t))) typedef struct { - uint64_t pic_intr[INTR_LEN]; - uint64_t pic_mask[INTR_LEN]; + uint16_t pic_elcr; + uint16_t pic_irr; + uint16_t pic_last_irr; + uint16_t pic_clear_irr; int eport; /* Event channel port */ } global_iodata_t; diff --git a/xen/include/public/io/vmx_vpic.h b/xen/include/public/io/vmx_vpic.h new file mode 100644 index 0000000000..ba68a3a9f7 --- /dev/null +++ b/xen/include/public/io/vmx_vpic.h @@ -0,0 +1,84 @@ +/* + * QEMU System Emulator header + * + * Copyright (c) 2003 Fabrice Bellard + * Copyright (c) 2005 Intel Corp + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef _VMX_VPIC_H +#define _VMX_VPIC_H + +#define hw_error(x) do {} while (0); + + +/* i8259.c */ +typedef struct IOAPICState IOAPICState; +typedef struct PicState { + uint8_t last_irr; /* edge detection */ + uint8_t irr; /* interrupt request register */ + uint8_t imr; /* interrupt mask register */ + uint8_t isr; /* interrupt service register */ + uint8_t priority_add; /* highest irq priority */ + uint8_t irq_base; + uint8_t read_reg_select; + uint8_t poll; + uint8_t special_mask; + uint8_t init_state; + uint8_t auto_eoi; + uint8_t rotate_on_auto_eoi; + uint8_t special_fully_nested_mode; + uint8_t init4; /* true if 4 byte init */ + uint8_t elcr; /* PIIX edge/trigger selection*/ + uint8_t elcr_mask; + struct vmx_virpic *pics_state; +} PicState; + +struct vmx_virpic { + /* 0 is master pic, 1 is slave pic */ + /* XXX: better separation between the two pics */ + PicState pics[2]; + void (*irq_request)(int *opaque, int level); + void *irq_request_opaque; + /* IOAPIC callback support */ + void (*alt_irq_func)(void *opaque, int irq_num, int level); + void *alt_irq_opaque; +}; + + +void pic_set_irq(struct vmx_virpic *s, int irq, int level); +void pic_set_irq_new(void *opaque, int irq, int level); +void pic_init(struct vmx_virpic *s, + void (*irq_request)(), + void *irq_request_opaque); +void pic_set_alt_irq_func(struct vmx_virpic *s, + void(*alt_irq_func)(), + void *alt_irq_opaque); +int pic_read_irq(struct vmx_virpic *s); +void pic_update_irq(struct vmx_virpic *s); +uint32_t pic_intack_read(struct vmx_virpic *s); +void register_pic_io_hook (void); +int cpu_get_pic_interrupt(struct vcpu *v, int *type); +int is_pit_irq(struct vcpu *v, int irq); +void do_pic_irqs (struct vmx_virpic *s, uint16_t irqs); +void do_pic_irqs_clear (struct vmx_virpic *s, uint16_t irqs); + +/* APIC */ +#endif /* _VMX_VPIC_H */ From 1bd54c9db6b0207c27142bb513495508a60ed803 Mon Sep 17 00:00:00 2001 From: "jrb44@plym.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 18:51:42 +0100 Subject: [PATCH 127/142] Temporary workaround to xend start problem. Signed-off-by: James Bulpin --- tools/python/xen/util/process.py | 39 ++++++++++++++++++++++++++++++++ tools/python/xen/xend/Vifctl.py | 6 +++-- 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 tools/python/xen/util/process.py diff --git a/tools/python/xen/util/process.py b/tools/python/xen/util/process.py new file mode 100644 index 0000000000..9117ef4ded --- /dev/null +++ b/tools/python/xen/util/process.py @@ -0,0 +1,39 @@ +# Copyright (C) 2005 Christian Limpach + +# os.system() replacement which outputs through the logger + +import popen2 +import select +import string + +from xen.xend.XendLogging import log + +def runscript(cmd): + # split after first space, then grab last component of path + cmdname = "[%s] " % cmd.split()[0].split('/')[-1] + # run command and grab stdin, stdout and stderr + cout, cin, cerr = popen2.popen3(cmd) + # close stdin to get command to terminate if it waits for input + cin.close() + # wait for output and process + p = select.poll() + p.register(cout) + p.register(cerr) + stdout = "" + while True: + r = p.poll() + for (fd, event) in r: + if event == select.POLLHUP: + cout.close() + cerr.close() + return stdout + if fd == cout.fileno(): + stdout = stdout + cout.readline() + if fd == cerr.fileno(): + l = cerr.readline() + if l[0] == '-': + log.debug(cmdname + l[1:].rstrip()) + elif l[0] == '*': + log.info(cmdname + l[1:].rstrip()) + else: + log.error(cmdname + l.rstrip()) diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py index 382cba5c04..fe37dfc506 100644 --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -20,9 +20,9 @@ """ import os +import xen.util.process import XendRoot - def network(op): """Call a network control script. @@ -32,4 +32,6 @@ def network(op): raise ValueError('Invalid operation: ' + op) script = XendRoot.instance().get_network_script() if script: - os.spawnl(os.P_WAIT, script, script, op) + xen.util.process.runscript(script + " " + op) + #os.spawnl(os.P_WAIT, script, script, op) + From 3eeb70411201ae16b2920ccaa3a9a5df81fb6627 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 21 Oct 2005 20:07:54 +0100 Subject: [PATCH 128/142] Disable Xen verbosity by default. At this point I think it is best to disable 'scary' warning messages by default, even though this will also quieten down genuine error paths. The ideal solution would be to introduce DPRINTK levels (e.g., info, warning, error) and allow these to be selected at compile and/or boot time. We could then enable error messages until things have stabilised some more. Signed-off-by: Keir Fraser --- xen/Rules.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/Rules.mk b/xen/Rules.mk index d57ca65e51..f65564240a 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -2,7 +2,7 @@ # If you change any of these configuration options then you must # 'make clean' before rebuilding. # -verbose ?= y +verbose ?= n debug ?= n perfc ?= n perfc_arrays?= n From 44d95809c515f3207960665b9ba1b640168446f7 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 22 Oct 2005 07:35:36 +0100 Subject: [PATCH 129/142] Two patches were applied to pygrub's setup.py to work around python2.2 limitations and only one is needed. Revert one of them. Signed-Off-By: Muli Ben-Yehuda --- tools/pygrub/setup.py | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tools/pygrub/setup.py b/tools/pygrub/setup.py index 5e0937bbad..88a06d6de1 100644 --- a/tools/pygrub/setup.py +++ b/tools/pygrub/setup.py @@ -12,14 +12,11 @@ if os.path.exists("/usr/include/ext2fs/ext2_fs.h"): ext2defines = [] cc = new_compiler() cc.add_library("ext2fs") - try: - if hasattr(cc, "has_function") and cc.has_function("ext2fs_open2"): - ext2defines.append( ("HAVE_EXT2FS_OPEN2", None) ) - else: - sys.stderr.write("WARNING: older version of e2fsprogs installed, not building full\n") - sys.stderr.write(" disk support for ext2.\n") - except AttributeError: - pass + if hasattr(cc, "has_function") and cc.has_function("ext2fs_open2"): + ext2defines.append( ("HAVE_EXT2FS_OPEN2", None) ) + else: + sys.stderr.write("WARNING: older version of e2fsprogs installed, not building full\n") + sys.stderr.write(" disk support for ext2.\n") ext2 = Extension("grub.fsys.ext2._pyext2", extra_compile_args = extra_compile_args, From db65a8e335a5ed2a9f4eca87d8015686c526ebea Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 22 Oct 2005 07:37:15 +0100 Subject: [PATCH 130/142] This patch is to make xentop able to print vcpu usage for out of order enabled vcpus in a domain. This really isn't an issue anymore with the changes made to dom0 ops and xm/xend. But, I provide it because: - Josh noticed my previous patch called getvcpuinfo twice for each vpcu, which was completely silly. - this patch would be useful in the remote chance that domain vpcus are enabled out of order. Signed-off-by: Daniel Stekloff --- tools/xenstat/libxenstat/src/xen-interface.c | 10 ++++--- tools/xenstat/libxenstat/src/xen-interface.h | 5 ++-- tools/xenstat/libxenstat/src/xenstat.c | 29 +++++++++++++------- tools/xenstat/libxenstat/src/xenstat.h | 1 + tools/xenstat/xentop/xentop.c | 11 +++++--- 5 files changed, 36 insertions(+), 20 deletions(-) diff --git a/tools/xenstat/libxenstat/src/xen-interface.c b/tools/xenstat/libxenstat/src/xen-interface.c index e0f9de7c07..8c06449db3 100644 --- a/tools/xenstat/libxenstat/src/xen-interface.c +++ b/tools/xenstat/libxenstat/src/xen-interface.c @@ -173,9 +173,9 @@ int xi_get_domaininfolist(xi_handle *handle, dom0_getdomaininfo_t *info, return op.u.getdomaininfolist.num_domains; } -/* Returns cpu usage data from dom0 */ -long long xi_get_vcpu_usage(xi_handle *handle, unsigned int domain, - unsigned int vcpu) +/* Get vcpu info from a domain */ +int xi_get_domain_vcpu_info(xi_handle *handle, unsigned int domain, + unsigned int vcpu, dom0_getvcpuinfo_t *info) { dom0_op_t op; op.u.getvcpuinfo.domain = domain; @@ -186,7 +186,9 @@ long long xi_get_vcpu_usage(xi_handle *handle, unsigned int domain, return -1; } - return op.u.getvcpuinfo.cpu_time; + memcpy(info, &op.u.getvcpuinfo, sizeof(dom0_getvcpuinfo_t)); + + return 0; } /* gets xen version information from hypervisor */ diff --git a/tools/xenstat/libxenstat/src/xen-interface.h b/tools/xenstat/libxenstat/src/xen-interface.h index 2cda13583e..c1e74edcd6 100644 --- a/tools/xenstat/libxenstat/src/xen-interface.h +++ b/tools/xenstat/libxenstat/src/xen-interface.h @@ -41,5 +41,6 @@ int xi_get_physinfo(xi_handle *, dom0_physinfo_t *); int xi_get_domaininfolist(xi_handle *, dom0_getdomaininfo_t *, unsigned int, unsigned int); -/* Returns cpu usage data from dom0 */ -long long xi_get_vcpu_usage(xi_handle *, unsigned int, unsigned int); +/* Get vcpu info from a domain */ +int xi_get_domain_vcpu_info(xi_handle *, unsigned int, unsigned int, + dom0_getvcpuinfo_t *); diff --git a/tools/xenstat/libxenstat/src/xenstat.c b/tools/xenstat/libxenstat/src/xenstat.c index d9b18dbcd0..85da72b168 100644 --- a/tools/xenstat/libxenstat/src/xenstat.c +++ b/tools/xenstat/libxenstat/src/xenstat.c @@ -51,7 +51,7 @@ struct xenstat_domain { unsigned int id; unsigned int state; unsigned long long cpu_ns; - unsigned int num_vcpus; + unsigned int num_vcpus; /* No. vcpus configured for domain */ xenstat_vcpu *vcpus; /* Array of length num_vcpus */ unsigned long long cur_mem; /* Current memory reservation */ unsigned long long max_mem; /* Total memory allowed */ @@ -61,6 +61,7 @@ struct xenstat_domain { }; struct xenstat_vcpu { + unsigned int online; unsigned long long ns; }; @@ -229,7 +230,7 @@ xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags) domain->id = domaininfo[i].domain; domain->state = domaininfo[i].flags; domain->cpu_ns = domaininfo[i].cpu_time; - domain->num_vcpus = domaininfo[i].nr_online_vcpus; + domain->num_vcpus = (domaininfo[i].max_vcpu_id+1); domain->vcpus = NULL; domain->cur_mem = ((unsigned long long)domaininfo[i].tot_pages) @@ -344,7 +345,7 @@ unsigned long long xenstat_domain_cpu_ns(xenstat_domain * domain) return domain->cpu_ns; } -/* Find the number of VCPUs allocated to a domain */ +/* Find the number of VCPUs for a domain */ unsigned int xenstat_domain_num_vcpus(xenstat_domain * domain) { return domain->num_vcpus; @@ -432,22 +433,24 @@ xenstat_network *xenstat_domain_network(xenstat_domain * domain, static int xenstat_collect_vcpus(xenstat_node * node) { unsigned int i, vcpu; + /* Fill in VCPU information */ for (i = 0; i < node->num_domains; i++) { node->domains[i].vcpus = malloc(node->domains[i].num_vcpus * sizeof(xenstat_vcpu)); if (node->domains[i].vcpus == NULL) return 0; - + for (vcpu = 0; vcpu < node->domains[i].num_vcpus; vcpu++) { /* FIXME: need to be using a more efficient mechanism*/ - long long vcpu_time; - vcpu_time = xi_get_vcpu_usage(node->handle->xihandle, - node->domains[i].id, - vcpu); - if (vcpu_time < 0) + dom0_getvcpuinfo_t info; + + if (xi_get_domain_vcpu_info(node->handle->xihandle, + node->domains[i].id, vcpu, &info) != 0) return 0; - node->domains[i].vcpus[vcpu].ns = vcpu_time; + + node->domains[i].vcpus[vcpu].online = info.online; + node->domains[i].vcpus[vcpu].ns = info.cpu_time; } } return 1; @@ -466,6 +469,12 @@ static void xenstat_uninit_vcpus(xenstat_handle * handle) { } +/* Get VCPU online status */ +unsigned int xenstat_vcpu_online(xenstat_vcpu * vcpu) +{ + return vcpu->online; +} + /* Get VCPU usage */ unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu) { diff --git a/tools/xenstat/libxenstat/src/xenstat.h b/tools/xenstat/libxenstat/src/xenstat.h index c9bbf61958..286fa035bf 100644 --- a/tools/xenstat/libxenstat/src/xenstat.h +++ b/tools/xenstat/libxenstat/src/xenstat.h @@ -119,6 +119,7 @@ xenstat_network *xenstat_domain_network(xenstat_domain * domain, */ /* Get VCPU usage */ +unsigned int xenstat_vcpu_online(xenstat_vcpu * vcpu); unsigned long long xenstat_vcpu_ns(xenstat_vcpu * vcpu); diff --git a/tools/xenstat/xentop/xentop.c b/tools/xenstat/xentop/xentop.c index 386e9326e9..1cb5e36829 100644 --- a/tools/xenstat/xentop/xentop.c +++ b/tools/xenstat/xentop/xentop.c @@ -713,13 +713,16 @@ void do_vcpu(xenstat_domain *domain) num_vcpus = xenstat_domain_num_vcpus(domain); - /* for all vcpus dump out values */ + /* for all online vcpus dump out values */ for (i=0; i< num_vcpus; i++) { vcpu = xenstat_domain_vcpu(domain,i); - if (i != 0 && (i%5)==0) - print("\n "); - print(" %2u: %10llus", i, xenstat_vcpu_ns(vcpu)/1000000000); + if (xenstat_vcpu_online(vcpu) > 0) { + if (i != 0 && (i%5)==0) + print("\n "); + print(" %2u: %10llus", i, + xenstat_vcpu_ns(vcpu)/1000000000); + } } print("\n"); } From c6d83ccc90166d5d0285ac80a7c8cb30e2f1fa35 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 22 Oct 2005 07:43:56 +0100 Subject: [PATCH 131/142] Fix assertions in bitops.c. Signed-off-by: Aravindh Puthiyaparambil --- xen/arch/x86/bitops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/bitops.c b/xen/arch/x86/bitops.c index 695a609a23..639d82d830 100644 --- a/xen/arch/x86/bitops.c +++ b/xen/arch/x86/bitops.c @@ -29,7 +29,7 @@ unsigned int __find_next_bit( const unsigned long *p = addr + (offset / BITS_PER_LONG); unsigned int set, bit = offset & (BITS_PER_LONG - 1); - ASSERT(offset < size); + ASSERT(offset <= size); if ( bit != 0 ) { @@ -78,7 +78,7 @@ unsigned int __find_next_zero_bit( const unsigned long *p = addr + (offset / BITS_PER_LONG); unsigned int set, bit = offset & (BITS_PER_LONG - 1); - ASSERT(offset < size); + ASSERT(offset <= size); if ( bit != 0 ) { From 900a11e8ed5635cf98d5dbad7d8a5d12fba9479c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sat, 22 Oct 2005 08:35:03 +0100 Subject: [PATCH 132/142] cpumap cleanups -- Python now deals with lists of cpus rather than cpu bitmaps. Signed-off-by: Ryan Harper Signed-off-by: Keir Fraser --- tools/python/xen/lowlevel/xc/xc.c | 36 +++++++++---- tools/python/xen/xend/XendClient.py | 2 +- tools/python/xen/xend/XendDomain.py | 5 +- tools/python/xen/xend/XendDomainInfo.py | 6 ++- tools/python/xen/xend/server/SrvDomain.py | 2 +- tools/python/xen/xm/main.py | 66 ++++++++++++++++++++--- 6 files changed, 97 insertions(+), 20 deletions(-) diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index e4855158b6..e3c2dbcb36 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -204,15 +204,23 @@ static PyObject *pyxc_domain_pincpu(PyObject *self, XcObject *xc = (XcObject *)self; uint32_t dom; - int vcpu = 0; + int vcpu = 0, i; cpumap_t cpumap = ~0ULL; + PyObject *cpulist = NULL; static char *kwd_list[] = { "dom", "vcpu", "cpumap", NULL }; - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|ii", kwd_list, - &dom, &vcpu, &cpumap) ) + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "i|iO", kwd_list, + &dom, &vcpu, &cpulist) ) return NULL; + if ( (cpulist != NULL) && PyList_Check(cpulist) ) + { + cpumap = 0ULL; + for ( i = 0; i < PyList_Size(cpulist); i++ ) + cpumap |= (cpumap_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i)); + } + if ( xc_domain_pincpu(xc->xc_handle, dom, vcpu, cpumap) != 0 ) return PyErr_SetFromErrno(xc_error); @@ -347,11 +355,12 @@ static PyObject *pyxc_vcpu_getinfo(PyObject *self, PyObject *kwds) { XcObject *xc = (XcObject *)self; - PyObject *info_dict; + PyObject *info_dict, *cpulist; uint32_t dom, vcpu = 0; xc_vcpuinfo_t info; - int rc; + int rc, i; + cpumap_t cpumap; static char *kwd_list[] = { "dom", "vcpu", NULL }; @@ -363,13 +372,22 @@ static PyObject *pyxc_vcpu_getinfo(PyObject *self, if ( rc < 0 ) return PyErr_SetFromErrno(xc_error); - info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i,s:i}", + info_dict = Py_BuildValue("{s:i,s:i,s:i,s:L,s:i}", "online", info.online, "blocked", info.blocked, "running", info.running, "cpu_time", info.cpu_time, - "cpu", info.cpu, - "cpumap", info.cpumap); + "cpu", info.cpu); + + cpumap = info.cpumap; + cpulist = PyList_New(0); + for ( i = 0; cpumap != 0; i++ ) + { + if ( cpumap & 1 ) + PyList_Append(cpulist, PyInt_FromLong(i)); + cpumap >>= 1; + } + PyDict_SetItemString(info_dict, "cpumap", cpulist); return info_dict; } @@ -896,7 +914,7 @@ static PyMethodDef pyxc_methods[] = { "Pin a VCPU to a specified set CPUs.\n" " dom [int]: Identifier of domain to which VCPU belongs.\n" " vcpu [int, 0]: VCPU being pinned.\n" - " cpumap [int, -1]: Bitmap of usable CPUs.\n\n" + " cpumap [list, []]: list of usable CPUs.\n\n" "Returns: [int] 0 on success; -1 on error.\n" }, { "domain_setcpuweight", diff --git a/tools/python/xen/xend/XendClient.py b/tools/python/xen/xend/XendClient.py index 9fe93bab99..9cbef2401b 100644 --- a/tools/python/xen/xend/XendClient.py +++ b/tools/python/xen/xend/XendClient.py @@ -258,7 +258,7 @@ class Xend: return self.xendPost(self.domainurl(id), {'op' : 'pincpu', 'vcpu' : vcpu, - 'cpumap' : cpumap }) + 'cpumap' : str(cpumap) }) def xend_domain_cpu_bvt_set(self, id, mcuadv, warpback, warpvalue, warpl, warpu): return self.xendPost(self.domainurl(id), diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 0b50c83b55..3c0532645c 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -412,9 +412,12 @@ class XendDomain: def domain_pincpu(self, domid, vcpu, cpumap): """Set which cpus vcpu can use - @param cpumap: bitmap of usable cpus + @param cpumap: string repr of list of usable cpus """ dominfo = self.domain_lookup(domid) + # convert cpumap string into a list of ints + cpumap = map(lambda x: int(x), + cpumap.replace("[", "").replace("]", "").split(",")) try: return xc.domain_pincpu(dominfo.getDomid(), vcpu, cpumap) except Exception, ex: diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index bb34abd099..061e7863d5 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -980,6 +980,9 @@ class XendDomainInfo: def getVCPUInfo(self): try: + def filter_cpumap(map, max): + return filter(lambda x: x >= 0, map[0:max]) + # We include the domain name and ID, to help xm. sxpr = ['domain', ['domid', self.domid], @@ -996,7 +999,8 @@ class XendDomainInfo: ['running', info['running']], ['cpu_time', info['cpu_time'] / 1e9], ['cpu', info['cpu']], - ['cpumap', info['cpumap']]]) + ['cpumap', filter_cpumap(info['cpumap'], + self.info['vcpus'])]]) return sxpr diff --git a/tools/python/xen/xend/server/SrvDomain.py b/tools/python/xen/xend/server/SrvDomain.py index 40ddc81972..676c5f37ca 100644 --- a/tools/python/xen/xend/server/SrvDomain.py +++ b/tools/python/xen/xend/server/SrvDomain.py @@ -89,7 +89,7 @@ class SrvDomain(SrvDir): fn = FormFn(self.xd.domain_pincpu, [['dom', 'int'], ['vcpu', 'int'], - ['cpumap', 'int']]) + ['cpumap', 'str']]) val = fn(req.args, {'dom': self.dom.domid}) return val diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 7e35899fc0..f9771f6c0a 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -289,6 +289,62 @@ def xm_vcpu_list(args): def get_info(n): return sxp.child_value(dom, n) + # + # convert a list of integers into a list of pairs indicating + # continuous sequences in the list: + # + # [0,1,2,3] -> [(0,3)] + # [1,2,4,5] -> [(1,2),(4,5)] + # [0] -> [(0,0)] + # [0,1,4,6,7] -> [(0,1),(4,4),(6,7)] + # + def list_to_rangepairs(cmap): + cmap.sort() + pairs = [] + x = y = 0 + for i in range(0,len(cmap)): + try: + if ((cmap[y+1] - cmap[i]) > 1): + pairs.append((cmap[x],cmap[y])) + x = y = i+1 + else: + y = y + 1 + # if we go off the end, then just add x to y + except IndexError: + pairs.append((cmap[x],cmap[y])) + + return pairs + + # + # Convert pairs to range string, e.g: [(1,2),(3,3),(5,7)] -> 1-2,3,5-7 + # + def format_pairs(pairs): + out = "" + for f,s in pairs: + if (f==s): + out += '%d'%f + else: + out += '%d-%d'%(f,s) + out += ',' + # trim trailing ',' + return out[:-1] + + def format_cpumap(cpumap): + def uniq(x): + return [ u for u in x if u not in locals()['_[1]'] ] + + from xen.xend.XendClient import server + for x in server.xend_node()[1:]: + if len(x) > 1 and x[0] == 'nr_cpus': + nr_cpus = int(x[1]) + break + + return format_pairs( + list_to_rangepairs( + map(lambda x: x % nr_cpus, + uniq(map(lambda x: int(x), cpumap)) ))) + + name = get_info('name') domid = int(get_info('domid')) @@ -299,7 +355,7 @@ def xm_vcpu_list(args): number = vinfo('number', int) cpu = vinfo('cpu', int) - cpumap = vinfo('cpumap', int) + cpumap = format_cpumap(vinfo('cpumap', list)) online = vinfo('online', int) cpu_time = vinfo('cpu_time', float) running = vinfo('running', int) @@ -321,7 +377,7 @@ def xm_vcpu_list(args): s = "--p" print ( - "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f 0x%(cpumap)x" % + "%(name)-32s %(domid)3d %(number)4d %(c)3s %(s)-3s %(cpu_time)7.1f %(cpumap)s" % locals()) @@ -355,7 +411,6 @@ def xm_subcommand(command, args): def cpu_make_map(cpulist): cpus = [] - cpumap = 0 for c in cpulist.split(','): if c.find('-') != -1: (x,y) = c.split('-') @@ -364,10 +419,7 @@ def cpu_make_map(cpulist): else: cpus.append(int(c)) cpus.sort() - for c in cpus: - cpumap = cpumap | 1< Date: Sat, 22 Oct 2005 10:33:26 +0100 Subject: [PATCH 133/142] Fix 'xm vcpu-list'. List cpumap as 'CPU Affinity'. Use special descriptive strings for empty and full cpu maps. Signed-off-by: Keir Fraser --- tools/python/xen/xm/main.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index f9771f6c0a..2949ff157c 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -274,7 +274,7 @@ def xm_brief_list(doms): def xm_vcpu_list(args): - print 'Name ID VCPU CPU State Time(s) CPU Map' + print 'Name ID VCPU CPU State Time(s) CPU Affinity' from xen.xend.XendClient import server if args: @@ -319,6 +319,8 @@ def xm_vcpu_list(args): # Convert pairs to range string, e.g: [(1,2),(3,3),(5,7)] -> 1-2,3,5-7 # def format_pairs(pairs): + if not pairs: + return "no cpus" out = "" for f,s in pairs: if (f==s): @@ -330,25 +332,23 @@ def xm_vcpu_list(args): return out[:-1] def format_cpumap(cpumap): - def uniq(x): - return [ u for u in x if u not in locals()['_[1]'] ] + cpumap = map(lambda x: int(x), cpumap) + cpumap.sort() from xen.xend.XendClient import server for x in server.xend_node()[1:]: if len(x) > 1 and x[0] == 'nr_cpus': nr_cpus = int(x[1]) + cpumap = filter(lambda x: x < nr_cpus, cpumap) + if len(cpumap) == nr_cpus: + return "any cpu" break - return format_pairs( - list_to_rangepairs( - map(lambda x: x % nr_cpus, - uniq(map(lambda x: int(x), cpumap)) ))) - + return format_pairs(list_to_rangepairs(cpumap)) name = get_info('name') domid = int(get_info('domid')) - for vcpu in sxp.children(dom, 'vcpu'): def vinfo(n, t): return t(sxp.child_value(vcpu, n)) From bacb111591d30c5928a545068ccba49ef5482850 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Sat, 22 Oct 2005 11:04:45 +0100 Subject: [PATCH 134/142] Reintroduce the changes made by changeset 7455:021324804fbd, which were disabled by workaround 7468:17a9f111fa93. We additionally need to set the FD_CLOEXEC flag on the status fd given to SrvServer when spawning the network script, as at least on some platforms this causes xend to fail to start properly. Signed-off-by: Ewan Mellor --- tools/python/xen/util/process.py | 39 ----------------------- tools/python/xen/xend/Vifctl.py | 6 ++-- tools/python/xen/xend/server/SrvServer.py | 6 ++++ 3 files changed, 8 insertions(+), 43 deletions(-) delete mode 100644 tools/python/xen/util/process.py diff --git a/tools/python/xen/util/process.py b/tools/python/xen/util/process.py deleted file mode 100644 index 9117ef4ded..0000000000 --- a/tools/python/xen/util/process.py +++ /dev/null @@ -1,39 +0,0 @@ -# Copyright (C) 2005 Christian Limpach - -# os.system() replacement which outputs through the logger - -import popen2 -import select -import string - -from xen.xend.XendLogging import log - -def runscript(cmd): - # split after first space, then grab last component of path - cmdname = "[%s] " % cmd.split()[0].split('/')[-1] - # run command and grab stdin, stdout and stderr - cout, cin, cerr = popen2.popen3(cmd) - # close stdin to get command to terminate if it waits for input - cin.close() - # wait for output and process - p = select.poll() - p.register(cout) - p.register(cerr) - stdout = "" - while True: - r = p.poll() - for (fd, event) in r: - if event == select.POLLHUP: - cout.close() - cerr.close() - return stdout - if fd == cout.fileno(): - stdout = stdout + cout.readline() - if fd == cerr.fileno(): - l = cerr.readline() - if l[0] == '-': - log.debug(cmdname + l[1:].rstrip()) - elif l[0] == '*': - log.info(cmdname + l[1:].rstrip()) - else: - log.error(cmdname + l.rstrip()) diff --git a/tools/python/xen/xend/Vifctl.py b/tools/python/xen/xend/Vifctl.py index fe37dfc506..382cba5c04 100644 --- a/tools/python/xen/xend/Vifctl.py +++ b/tools/python/xen/xend/Vifctl.py @@ -20,9 +20,9 @@ """ import os -import xen.util.process import XendRoot + def network(op): """Call a network control script. @@ -32,6 +32,4 @@ def network(op): raise ValueError('Invalid operation: ' + op) script = XendRoot.instance().get_network_script() if script: - xen.util.process.runscript(script + " " + op) - #os.spawnl(os.P_WAIT, script, script, op) - + os.spawnl(os.P_WAIT, script, script, op) diff --git a/tools/python/xen/xend/server/SrvServer.py b/tools/python/xen/xend/server/SrvServer.py index 4a4f9f4946..576de6be16 100644 --- a/tools/python/xen/xend/server/SrvServer.py +++ b/tools/python/xen/xend/server/SrvServer.py @@ -39,6 +39,7 @@ # todo Support security settings etc. in the config file. # todo Support command-line args. +import fcntl from threading import Thread from xen.web.httpserver import HttpServer, UnixHttpServer @@ -64,6 +65,11 @@ class XendServers: self.servers.append(server) def start(self, status): + # Running the network script will spawn another process, which takes + # the status fd with it unless we set FD_CLOEXEC. Failing to do this + # causes the read in SrvDaemon to hang even when we have written here. + fcntl.fcntl(status, fcntl.F_SETFD, fcntl.FD_CLOEXEC) + Vifctl.network('start') threads = [] for server in self.servers: From 74df472110b38b1d28398feca7c805e2c234f2fe Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 23 Oct 2005 11:51:15 +0100 Subject: [PATCH 135/142] some fixes to VMX: 1) enable ACPI in VMXAssist by default. 2) do nothing when emulating wbinvd instruction in VMXAssist. 3) use MACRO in cpu number setting/getting code. 4) remove useless parameter flags from xc_vmx_build. 5) remove usage of dsi.v_start in xc_vmx_build when not handling vmxloader elf. 6) unmap shared_page_va when destroy VMX domain. 7) change virtual_platform_def to vmx_platform. 8) remove useless code in vmx_setup_platform. 9) change parameter of vmx_setup_platform from vcpu to domain. 10) in xen HV, vmx domain get domain processor number from the reserved E820 area. 11) in domain.c, don't define some functions when on i386 platform or no CONFIG_VMX. Also removed some ugly tailing space. Signed-off-by: Xin Li --- tools/firmware/vmxassist/Makefile | 2 +- tools/firmware/vmxassist/acpi_madt.c | 16 ++--- tools/firmware/vmxassist/vm86.c | 1 - tools/libxc/xc_ia64_stubs.c | 1 - tools/libxc/xc_vmx_build.c | 82 ++++++++++++------------- tools/libxc/xenguest.h | 2 - tools/python/xen/lowlevel/xc/xc.c | 12 ++-- xen/arch/x86/domain.c | 90 ++++++---------------------- xen/arch/x86/vmx.c | 44 ++++++++++++++ xen/arch/x86/vmx_io.c | 2 +- xen/arch/x86/vmx_vmcs.c | 77 ++++++++++++++++-------- xen/include/asm-x86/domain.h | 4 +- xen/include/asm-x86/vmx.h | 5 ++ xen/include/asm-x86/vmx_platform.h | 4 +- xen/include/asm-x86/vmx_vmcs.h | 3 + 15 files changed, 187 insertions(+), 158 deletions(-) diff --git a/tools/firmware/vmxassist/Makefile b/tools/firmware/vmxassist/Makefile index e64473716b..616f64d4e7 100644 --- a/tools/firmware/vmxassist/Makefile +++ b/tools/firmware/vmxassist/Makefile @@ -24,7 +24,7 @@ include $(XEN_ROOT)/tools/Rules.mk # The emulator code lives in ROM space TEXTADDR=0x000D0000 -DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR) +DEFINES=-DDEBUG -D_ACPI_ -DTEXTADDR=$(TEXTADDR) XENINC=-I$(XEN_ROOT)/tools/libxc LD = ld diff --git a/tools/firmware/vmxassist/acpi_madt.c b/tools/firmware/vmxassist/acpi_madt.c index aaa6025c4e..1efbaa4b5d 100644 --- a/tools/firmware/vmxassist/acpi_madt.c +++ b/tools/firmware/vmxassist/acpi_madt.c @@ -24,17 +24,19 @@ extern int puts(const char *s); -#define VCPU_MAGIC 0x76637075 /* "vcpu" */ +#define VCPU_NR_PAGE 0x0009F000 +#define VCPU_NR_OFFSET 0x00000800 +#define VCPU_MAGIC 0x76637075 /* "vcpu" */ /* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */ -static int -get_vcpus(void) +static int +get_vcpu_nr(void) { - unsigned long *vcpus; + unsigned int *vcpus; - vcpus = (unsigned long *)0x9F800; + vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET); if (vcpus[0] != VCPU_MAGIC) { - puts("Bad vcpus magic, set vcpu number=1\n"); + puts("Bad vcpus magic, set vcpu number to 1 by default.\n"); return 1; } @@ -123,7 +125,7 @@ int acpi_madt_update(unsigned char *acpi_start) if (!madt) return -1; - rc = acpi_madt_set_local_apics(get_vcpus(), madt); + rc = acpi_madt_set_local_apics(get_vcpu_nr(), madt); if (rc != 0) return rc; diff --git a/tools/firmware/vmxassist/vm86.c b/tools/firmware/vmxassist/vm86.c index 48fb6159fa..c9a5311405 100644 --- a/tools/firmware/vmxassist/vm86.c +++ b/tools/firmware/vmxassist/vm86.c @@ -784,7 +784,6 @@ opcode(struct regs *regs) } break; case 0x09: /* wbinvd */ - asm volatile ( "wbinvd" ); return OPC_EMULATED; case 0x20: /* mov Rd, Cd (1h) */ case 0x22: diff --git a/tools/libxc/xc_ia64_stubs.c b/tools/libxc/xc_ia64_stubs.c index f1e8a46a0b..b171ea37ef 100644 --- a/tools/libxc/xc_ia64_stubs.c +++ b/tools/libxc/xc_ia64_stubs.c @@ -24,7 +24,6 @@ int xc_vmx_build(int xc_handle, const char *ramdisk_name, const char *cmdline, unsigned int control_evtchn, - unsigned long flags, unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn) diff --git a/tools/libxc/xc_vmx_build.c b/tools/libxc/xc_vmx_build.c index 2f8a5ec72d..168acaf0d7 100644 --- a/tools/libxc/xc_vmx_build.c +++ b/tools/libxc/xc_vmx_build.c @@ -29,9 +29,12 @@ #define E820_SHARED_PAGE 17 #define E820_XENSTORE 18 -#define E820_MAP_PAGE 0x00090000 -#define E820_MAP_NR_OFFSET 0x000001E8 -#define E820_MAP_OFFSET 0x000002D0 +#define E820_MAP_PAGE 0x00090000 +#define E820_MAP_NR_OFFSET 0x000001E8 +#define E820_MAP_OFFSET 0x000002D0 + +#define VCPU_NR_PAGE 0x0009F000 +#define VCPU_NR_OFFSET 0x00000800 struct e820entry { uint64_t addr; @@ -120,23 +123,22 @@ static unsigned char build_e820map(void *e820_page, unsigned long mem_size) * Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader * vmxloader will use it to config ACPI MADT table */ -#define VCPU_MAGIC 0x76637075 /* "vcpu" */ -static int -set_nr_vcpus(int xc_handle, uint32_t dom, unsigned long *pfn_list, - struct domain_setup_info *dsi, unsigned long vcpus) +#define VCPU_MAGIC 0x76637075 /* "vcpu" */ +static int set_vcpu_nr(int xc_handle, uint32_t dom, + unsigned long *pfn_list, unsigned int vcpus) { - char *va_map; - unsigned long *va_vcpus; + char *va_map; + unsigned int *va_vcpus; - va_map = xc_map_foreign_range( - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, - pfn_list[(0x9F000 - dsi->v_start) >> PAGE_SHIFT]); + va_map = xc_map_foreign_range(xc_handle, dom, + PAGE_SIZE, PROT_READ|PROT_WRITE, + pfn_list[VCPU_NR_PAGE >> PAGE_SHIFT]); if ( va_map == NULL ) return -1; - va_vcpus = (unsigned long *)(va_map + 0x800); - *va_vcpus++ = VCPU_MAGIC; - *va_vcpus++ = vcpus; + va_vcpus = (unsigned int *)(va_map + VCPU_NR_OFFSET); + va_vcpus[0] = VCPU_MAGIC; + va_vcpus[1] = vcpus; munmap(va_map, PAGE_SIZE); @@ -277,7 +279,6 @@ static int setup_guest(int xc_handle, vcpu_guest_context_t *ctxt, unsigned long shared_info_frame, unsigned int control_evtchn, - unsigned long flags, unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn) @@ -366,7 +367,7 @@ static int setup_guest(int xc_handle, goto error_out; /* First allocate page for page dir or pdpt */ - ppt_alloc = (vpt_start - dsi.v_start) >> PAGE_SHIFT; + ppt_alloc = vpt_start >> PAGE_SHIFT; if ( page_array[ppt_alloc] > 0xfffff ) { unsigned long nmfn; @@ -388,8 +389,8 @@ static int setup_guest(int xc_handle, l2tab >> PAGE_SHIFT)) == NULL ) goto error_out; memset(vl2tab, 0, PAGE_SIZE); - vl2e = &vl2tab[l2_table_offset(dsi.v_start)]; - for ( count = 0; count < ((v_end-dsi.v_start)>>PAGE_SHIFT); count++ ) + vl2e = &vl2tab[l2_table_offset(0)]; + for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ ) { if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) { @@ -404,7 +405,7 @@ static int setup_guest(int xc_handle, goto error_out; } memset(vl1tab, 0, PAGE_SIZE); - vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<>PAGE_SHIFT); count++ ) + vl3e = &vl3tab[l3_table_offset(0)]; + for ( count = 0; count < (v_end >> PAGE_SHIFT); count++ ) { if (!(count & (1 << (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)))){ l2tab = vl3tab[count >> (L3_PAGETABLE_SHIFT - L1_PAGETABLE_SHIFT)] @@ -452,7 +452,7 @@ static int setup_guest(int xc_handle, l2tab >> PAGE_SHIFT)) == NULL ) goto error_out; - vl2e = &vl2tab[l2_table_offset(dsi.v_start + (count << PAGE_SHIFT))]; + vl2e = &vl2tab[l2_table_offset(count << PAGE_SHIFT)]; } if ( ((unsigned long)vl1e & (PAGE_SIZE-1)) == 0 ) { @@ -467,7 +467,7 @@ static int setup_guest(int xc_handle, goto error_out; } memset(vl1tab, 0, PAGE_SIZE); - vl1e = &vl1tab[l1_table_offset(dsi.v_start + (count<> PAGE_SHIFT]; shared_page_frame = (v_end - PAGE_SIZE) >> PAGE_SHIFT; @@ -566,28 +569,26 @@ static int setup_guest(int xc_handle, return -1; } - #define VMX_FEATURE_FLAG 0x20 static int vmx_identify(void) { int eax, ecx; -#ifdef __i386__ - __asm__ __volatile__ ("pushl %%ebx; cpuid; popl %%ebx" - : "=a" (eax), "=c" (ecx) - : "0" (1) - : "dx"); -#elif defined __x86_64__ - __asm__ __volatile__ ("pushq %%rbx; cpuid; popq %%rbx" - : "=a" (eax), "=c" (ecx) - : "0" (1) - : "dx"); + __asm__ __volatile__ ( +#if defined(__i386__) + "push %%ebx; cpuid; pop %%ebx" +#elif defined(__x86_64__) + "push %%rbx; cpuid; pop %%rbx" #endif + : "=a" (eax), "=c" (ecx) + : "0" (1) + : "dx"); if (!(ecx & VMX_FEATURE_FLAG)) { return -1; } + return 0; } @@ -596,7 +597,6 @@ int xc_vmx_build(int xc_handle, int memsize, const char *image_name, unsigned int control_evtchn, - unsigned long flags, unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn) @@ -651,9 +651,9 @@ int xc_vmx_build(int xc_handle, goto error_out; } - if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages, - ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn, - flags, vcpus, store_evtchn, store_mfn) < 0) + if ( setup_guest(xc_handle, domid, memsize, image, image_size, + nr_pages, ctxt, op.u.getdomaininfo.shared_info_frame, + control_evtchn, vcpus, store_evtchn, store_mfn) < 0) { ERROR("Error constructing guest OS"); goto error_out; diff --git a/tools/libxc/xenguest.h b/tools/libxc/xenguest.h index b4003d026a..70d23af826 100644 --- a/tools/libxc/xenguest.h +++ b/tools/libxc/xenguest.h @@ -51,13 +51,11 @@ int xc_linux_build(int xc_handle, unsigned int console_evtchn, unsigned long *console_mfn); -struct mem_map; int xc_vmx_build(int xc_handle, uint32_t domid, int memsize, const char *image_name, unsigned int control_evtchn, - unsigned long flags, unsigned int vcpus, unsigned int store_evtchn, unsigned long *store_mfn); diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index e3c2dbcb36..8b72e0ec57 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -429,15 +429,15 @@ static PyObject *pyxc_linux_build(PyObject *self, } static PyObject *pyxc_vmx_build(PyObject *self, - PyObject *args, - PyObject *kwds) + PyObject *args, + PyObject *kwds) { XcObject *xc = (XcObject *)self; - uint32_t dom; + uint32_t dom; char *image; - int control_evtchn, store_evtchn; - int flags = 0, vcpus = 1; + int control_evtchn, store_evtchn; + int vcpus = 1; int memsize; unsigned long store_mfn = 0; @@ -450,7 +450,7 @@ static PyObject *pyxc_vmx_build(PyObject *self, return NULL; if ( xc_vmx_build(xc->xc_handle, dom, memsize, image, control_evtchn, - flags, vcpus, store_evtchn, &store_mfn) != 0 ) + vcpus, store_evtchn, &store_mfn) != 0 ) return PyErr_SetFromErrno(xc_error); return Py_BuildValue("{s:i}", "store_mfn", store_mfn); diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index cbb1863e95..be471bd475 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1,6 +1,6 @@ /****************************************************************************** * arch/x86/domain.c - * + * * x86-specific domain handling (e.g., register setup and context switching). */ @@ -144,9 +144,7 @@ void machine_restart(char * __unused) smp_send_stop(); disable_IO_APIC(); -#ifdef CONFIG_VMX stop_vmx(); -#endif /* Rebooting needs to touch the page at absolute address 0. */ *((unsigned short *)__va(0x472)) = reboot_mode; @@ -204,7 +202,6 @@ void dump_pageframe_info(struct domain *d) page->u.inuse.type_info); } - page = virt_to_page(d->shared_info); printk("Shared_info@%p: caf=%08x, taf=%" PRtype_info "\n", _p(page_to_phys(page)), page->count_info, @@ -260,7 +257,7 @@ void arch_do_createdomain(struct vcpu *v) return; v->arch.schedule_tail = continue_nonidle_task; - + d->shared_info = alloc_xenheap_page(); memset(d->shared_info, 0, PAGE_SIZE); v->vcpu_info = &d->shared_info->vcpu_data[v->vcpu_id]; @@ -268,7 +265,7 @@ void arch_do_createdomain(struct vcpu *v) SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d); set_pfn_from_mfn(virt_to_phys(d->shared_info) >> PAGE_SHIFT, INVALID_M2P_ENTRY); - + d->arch.mm_perdomain_pt = alloc_xenheap_page(); memset(d->arch.mm_perdomain_pt, 0, PAGE_SIZE); set_pfn_from_mfn(virt_to_phys(d->arch.mm_perdomain_pt) >> PAGE_SHIFT, @@ -293,22 +290,22 @@ void arch_do_createdomain(struct vcpu *v) #ifdef __x86_64__ v->arch.guest_vl3table = __linear_l3_table; v->arch.guest_vl4table = __linear_l4_table; - + d->arch.mm_perdomain_l2 = alloc_xenheap_page(); memset(d->arch.mm_perdomain_l2, 0, PAGE_SIZE); - d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)] = + d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)] = l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt), __PAGE_HYPERVISOR); d->arch.mm_perdomain_l3 = alloc_xenheap_page(); memset(d->arch.mm_perdomain_l3, 0, PAGE_SIZE); - d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] = + d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] = l3e_from_page(virt_to_page(d->arch.mm_perdomain_l2), __PAGE_HYPERVISOR); #endif - + (void)ptwr_init(d); - - shadow_lock_init(d); + + shadow_lock_init(d); INIT_LIST_HEAD(&d->arch.free_shadow_frames); } @@ -327,34 +324,6 @@ void vcpu_migrate_cpu(struct vcpu *v, int newcpu) } } -#ifdef CONFIG_VMX -static int vmx_switch_on; - -static void vmx_final_setup_guest(struct vcpu *v) -{ - v->arch.schedule_tail = arch_vmx_do_launch; - - if (v == v->domain->vcpu[0]) { - /* - * Required to do this once per domain - * XXX todo: add a seperate function to do these. - */ - memset(&v->domain->shared_info->evtchn_mask[0], 0xff, - sizeof(v->domain->shared_info->evtchn_mask)); - - /* Put the domain in shadow mode even though we're going to be using - * the shared 1:1 page table initially. It shouldn't hurt */ - shadow_mode_enable(v->domain, - SHM_enable|SHM_refcounts| - SHM_translate|SHM_external); - } - - if (!vmx_switch_on) - vmx_switch_on = 1; -} -#endif - - /* This is called by arch_final_setup_guest and do_boot_vcpu */ int arch_set_info_guest( struct vcpu *v, struct vcpu_guest_context *c) @@ -422,7 +391,7 @@ int arch_set_info_guest( } else if ( !(c->flags & VGCF_VMX_GUEST) ) { - if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d, + if ( !get_page_and_type(&frame_table[phys_basetab>>PAGE_SHIFT], d, PGT_base_page_table) ) return -EINVAL; } @@ -507,12 +476,6 @@ void toggle_guest_mode(struct vcpu *v) : "=r" (__r) : "r" (value), "0" (__r) );\ __r; }) -#if CONFIG_VMX -#define load_msrs(n) if (vmx_switch_on) vmx_load_msrs(n) -#else -#define load_msrs(n) ((void)0) -#endif - /* * save_segments() writes a mask of segments which are dirty (non-zero), * allowing load_segments() to avoid some expensive segment loads and @@ -590,7 +553,7 @@ static void load_segments(struct vcpu *n) struct cpu_user_regs *regs = guest_cpu_user_regs(); unsigned long *rsp = (n->arch.flags & TF_kernel_mode) ? - (unsigned long *)regs->rsp : + (unsigned long *)regs->rsp : (unsigned long *)nctxt->kernel_sp; if ( !(n->arch.flags & TF_kernel_mode) ) @@ -690,9 +653,9 @@ long do_switch_to_user(void) regs->r11 = stu.r11; regs->rcx = stu.rcx; } - + /* Saved %rax gets written back to regs->rax in entry.S. */ - return stu.rax; + return stu.rax; } #define switch_kernel_stack(_n,_c) ((void)0) @@ -700,7 +663,6 @@ long do_switch_to_user(void) #elif defined(__i386__) #define load_segments(n) ((void)0) -#define load_msrs(n) ((void)0) #define save_segments(p) ((void)0) static inline void switch_kernel_stack(struct vcpu *n, unsigned int cpu) @@ -725,7 +687,7 @@ static void __context_switch(void) if ( !is_idle_task(p->domain) ) { memcpy(&p->arch.guest_context.user_regs, - stack_regs, + stack_regs, CTXT_SWITCH_STACK_BYTES); unlazy_fpu(p); save_segments(p); @@ -811,7 +773,7 @@ void context_switch_finalise(struct vcpu *next) { load_LDT(next); load_segments(next); - load_msrs(next); + vmx_load_msrs(next); } } @@ -883,7 +845,7 @@ unsigned long __hypercall_create_continuation( #if defined(__i386__) regs->eax = op; regs->eip -= 2; /* re-execute 'int 0x82' */ - + for ( i = 0; i < nr_args; i++ ) { switch ( i ) @@ -899,7 +861,7 @@ unsigned long __hypercall_create_continuation( #elif defined(__x86_64__) regs->rax = op; regs->rip -= 2; /* re-execute 'syscall' */ - + for ( i = 0; i < nr_args; i++ ) { switch ( i ) @@ -920,20 +882,6 @@ unsigned long __hypercall_create_continuation( return op; } -#ifdef CONFIG_VMX -static void vmx_relinquish_resources(struct vcpu *v) -{ - if ( !VMX_DOMAIN(v) ) - return; - - destroy_vmcs(&v->arch.arch_vmx); - free_monitor_pagetable(v); - rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer); -} -#else -#define vmx_relinquish_resources(_v) ((void)0) -#endif - static void relinquish_memory(struct domain *d, struct list_head *list) { struct list_head *ent; @@ -972,7 +920,7 @@ static void relinquish_memory(struct domain *d, struct list_head *list) for ( ; ; ) { x = y; - if ( likely((x & (PGT_type_mask|PGT_validated)) != + if ( likely((x & (PGT_type_mask|PGT_validated)) != (PGT_base_page_table|PGT_validated)) ) break; @@ -1033,7 +981,7 @@ void domain_relinquish_resources(struct domain *d) shadow_mode_disable(d); /* - * Relinquish GDT mappings. No need for explicit unmapping of the LDT as + * Relinquish GDT mappings. No need for explicit unmapping of the LDT as * it automatically gets squashed when the guest's mappings go away. */ for_each_vcpu(d, v) diff --git a/xen/arch/x86/vmx.c b/xen/arch/x86/vmx.c index e77370c9ec..6f3efae9e2 100644 --- a/xen/arch/x86/vmx.c +++ b/xen/arch/x86/vmx.c @@ -57,6 +57,47 @@ static unsigned long trace_values[NR_CPUS][4]; #define TRACE_VMEXIT(index,value) ((void)0) #endif +static int vmx_switch_on; + +void vmx_final_setup_guest(struct vcpu *v) +{ + v->arch.schedule_tail = arch_vmx_do_launch; + + if ( v == v->domain->vcpu[0] ) + { + /* + * Required to do this once per domain + * XXX todo: add a seperate function to do these. + */ + memset(&v->domain->shared_info->evtchn_mask[0], 0xff, + sizeof(v->domain->shared_info->evtchn_mask)); + + /* Put the domain in shadow mode even though we're going to be using + * the shared 1:1 page table initially. It shouldn't hurt */ + shadow_mode_enable(v->domain, + SHM_enable|SHM_refcounts| + SHM_translate|SHM_external); + } + + vmx_switch_on = 1; +} + +void vmx_relinquish_resources(struct vcpu *v) +{ + if ( !VMX_DOMAIN(v) ) + return; + + if (v->vcpu_id == 0) { + /* unmap IO shared page */ + struct domain *d = v->domain; + unmap_domain_page((void *)d->arch.vmx_platform.shared_page_va); + } + + destroy_vmcs(&v->arch.arch_vmx); + free_monitor_pagetable(v); + rem_ac_timer(&v->domain->arch.vmx_platform.vmx_pit.pit_timer); +} + #ifdef __x86_64__ static struct msr_state percpu_msr[NR_CPUS]; @@ -77,6 +118,9 @@ void vmx_load_msrs(struct vcpu *n) struct msr_state *host_state; host_state = &percpu_msr[smp_processor_id()]; + if ( !vmx_switch_on ) + return; + while (host_state->flags){ int i; diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 31e6f17e78..434d302209 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -883,7 +883,7 @@ asmlinkage void vmx_intr_assist(void) int highest_vector; unsigned long intr_fields, eflags, interruptibility, cpu_exec_control; struct vcpu *v = current; - struct virtual_platform_def *plat=&v->domain->arch.vmx_platform; + struct vmx_platform *plat=&v->domain->arch.vmx_platform; struct vmx_virpit *vpit = &plat->vmx_pit; struct vmx_virpic *pic= &plat->vmx_pic; diff --git a/xen/arch/x86/vmx_vmcs.c b/xen/arch/x86/vmx_vmcs.c index 92150eafb6..eb99f9525b 100644 --- a/xen/arch/x86/vmx_vmcs.c +++ b/xen/arch/x86/vmx_vmcs.c @@ -142,7 +142,7 @@ struct host_execution_env { #endif }; -static void get_io_shared_page(struct vcpu *v) +static void vmx_map_io_shared_page(struct domain *d) { int i; unsigned char e820_map_nr; @@ -151,9 +151,6 @@ static void get_io_shared_page(struct vcpu *v) unsigned long mpfn; unsigned long gpfn = 0; - if (!(VMX_DOMAIN(v) && (v->vcpu_id == 0))) - return; - local_flush_tlb_pge(); mpfn = get_mfn_from_pfn(E820_MAP_PAGE >> PAGE_SHIFT); @@ -200,24 +197,61 @@ static void get_io_shared_page(struct vcpu *v) printk("Can not map io request shared page for VMX domain.\n"); domain_crash(); } - v->domain->arch.vmx_platform.shared_page_va = (unsigned long)p; + d->arch.vmx_platform.shared_page_va = (unsigned long)p; - VMX_DBG_LOG(DBG_LEVEL_1, "eport: %x\n", iopacket_port(v->domain)); + VMX_DBG_LOG(DBG_LEVEL_1, "eport: %x\n", iopacket_port(d)); - clear_bit(iopacket_port(v->domain), - &v->domain->shared_info->evtchn_mask[0]); + clear_bit(iopacket_port(d), + &d->shared_info->evtchn_mask[0]); } -static void vmx_setup_platform(struct vcpu *v) +#define VCPU_NR_PAGE 0x0009F000 +#define VCPU_NR_OFFSET 0x00000800 +#define VCPU_MAGIC 0x76637075 /* "vcpu" */ + +static void vmx_set_vcpu_nr(struct domain *d) { - struct virtual_platform_def *platform; - if (v->vcpu_id == 0) { - get_io_shared_page(v); - platform = &v->domain->arch.vmx_platform; - pic_init(&platform->vmx_pic, pic_irq_request, - &platform->interrupt_request); - register_pic_io_hook(); + unsigned char *p; + unsigned long mpfn; + unsigned int *vcpus; + + mpfn = get_mfn_from_pfn(VCPU_NR_PAGE >> PAGE_SHIFT); + if (mpfn == INVALID_MFN) { + printk("Can not get vcpu number page mfn for VMX domain.\n"); + domain_crash_synchronous(); } + + p = map_domain_page(mpfn); + if (p == NULL) { + printk("Can not map vcpu number page for VMX domain.\n"); + domain_crash_synchronous(); + } + + vcpus = (unsigned int *)(p + VCPU_NR_OFFSET); + if (vcpus[0] != VCPU_MAGIC) { + printk("Bad vcpus magic, set vcpu number to 1 by default.\n"); + d->arch.vmx_platform.nr_vcpu = 1; + } + + d->arch.vmx_platform.nr_vcpu = vcpus[1]; + + unmap_domain_page(p); +} + +static void vmx_setup_platform(struct domain* d) +{ + struct vmx_platform *platform; + + if (!(VMX_DOMAIN(current) && (current->vcpu_id == 0))) + return; + + vmx_map_io_shared_page(d); + vmx_set_vcpu_nr(d); + + platform = &d->arch.vmx_platform; + pic_init(&platform->vmx_pic, pic_irq_request, + &platform->interrupt_request); + register_pic_io_hook(); } static void vmx_set_host_env(struct vcpu *v) @@ -249,9 +283,10 @@ static void vmx_do_launch(struct vcpu *v) { /* Update CR3, GDT, LDT, TR */ unsigned int error = 0; - unsigned long pfn = 0; unsigned long cr0, cr4; - struct pfn_info *page; + + if (v->vcpu_id == 0) + vmx_setup_platform(v->domain); __asm__ __volatile__ ("mov %%cr0,%0" : "=r" (cr0) : ); @@ -278,12 +313,6 @@ static void vmx_do_launch(struct vcpu *v) vmx_stts(); - page = (struct pfn_info *) alloc_domheap_page(NULL); - pfn = (unsigned long) (page - frame_table); - - if ( v == v->domain->vcpu[0] ) - vmx_setup_platform(v); - vmx_set_host_env(v); error |= __vmwrite(GUEST_LDTR_SELECTOR, 0); diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index fb9eff7ee4..36aa222bd2 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -61,8 +61,8 @@ struct arch_domain struct list_head free_shadow_frames; - pagetable_t phys_table; /* guest 1:1 pagetable */ - struct virtual_platform_def vmx_platform; + pagetable_t phys_table; /* guest 1:1 pagetable */ + struct vmx_platform vmx_platform; } __cacheline_aligned; struct arch_vcpu diff --git a/xen/include/asm-x86/vmx.h b/xen/include/asm-x86/vmx.h index fefb109f41..d16080cb1a 100644 --- a/xen/include/asm-x86/vmx.h +++ b/xen/include/asm-x86/vmx.h @@ -503,6 +503,11 @@ static inline int vmx_reflect_exception(struct vcpu *v) return 0; } +static inline unsigned int vmx_get_vcpu_nr(struct domain *d) +{ + return d->arch.vmx_platform.nr_vcpu; +} + static inline shared_iopage_t *get_sp(struct domain *d) { return (shared_iopage_t *) d->arch.vmx_platform.shared_page_va; diff --git a/xen/include/asm-x86/vmx_platform.h b/xen/include/asm-x86/vmx_platform.h index a7c2a79d18..83b0f102b5 100644 --- a/xen/include/asm-x86/vmx_platform.h +++ b/xen/include/asm-x86/vmx_platform.h @@ -77,8 +77,10 @@ struct instruction { #define MAX_INST_LEN 32 -struct virtual_platform_def { +struct vmx_platform { unsigned long shared_page_va; + unsigned int nr_vcpu; + struct vmx_virpit vmx_pit; struct vmx_io_handler vmx_io_handler; struct vmx_virpic vmx_pic; diff --git a/xen/include/asm-x86/vmx_vmcs.h b/xen/include/asm-x86/vmx_vmcs.h index 1a8a10effa..f47daf8e09 100644 --- a/xen/include/asm-x86/vmx_vmcs.h +++ b/xen/include/asm-x86/vmx_vmcs.h @@ -35,6 +35,9 @@ void vmx_restore_msrs(struct vcpu *v); #define vmx_restore_msrs(_v) ((void)0) #endif +void vmx_final_setup_guest(struct vcpu *v); +void vmx_relinquish_resources(struct vcpu *v); + void vmx_enter_scheduler(void); enum { From 9329e6405d0936b900bf095cba6dbc74fb8c07c8 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 23 Oct 2005 16:51:47 +0100 Subject: [PATCH 136/142] Fix an issue for passing arguement from control panel to deivce model for some arguemnt like 'localtime', 'isa', device model need an argument "-localtime", instead of "-localtime 1" Signed-off-by: Xiaofeng Ling --- tools/python/xen/xend/image.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index ee57bba5da..6cd9f540f3 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -243,11 +243,12 @@ class VmxImageHandler(ImageHandler): # Handle booleans gracefully if a in ['localtime', 'std-vga', 'isa', 'nic-ne2000']: if v != None: v = int(v) - + if v: ret.append("-%s" % a) + else: + if v: + ret.append("-%s" % a) + ret.append("%s" % v) log.debug("args: %s, val: %s" % (a,v)) - if v: - ret.append("-%s" % a) - ret.append("%s" % v) # Handle disk/network related options for (name, info) in deviceConfig: From dab3d2969db5dca7011c185af76b188b21e08e44 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 23 Oct 2005 16:54:51 +0100 Subject: [PATCH 137/142] Enable TSC-offsetting capability to ensure that VMX guest's TSC remains in sync with virtual-PIT interrupts. This avoids the following message from full-virt Linux: "Losing too many ticks! TSC cannot be used as a timesource. =20 Possible reasons for this are: You're running with Speedstep, ......" Signed-off-by: Eddie Dong Signed-off-by: Edwin Zhai --- xen/arch/x86/vmx_intercept.c | 2 ++ xen/arch/x86/vmx_io.c | 8 ++++++++ xen/include/asm-x86/vmx.h | 1 + xen/include/asm-x86/vmx_virpit.h | 1 + xen/include/asm-x86/vmx_vmcs.h | 1 + 5 files changed, 13 insertions(+) diff --git a/xen/arch/x86/vmx_intercept.c b/xen/arch/x86/vmx_intercept.c index 4e9a1fe86d..0a3c168107 100644 --- a/xen/arch/x86/vmx_intercept.c +++ b/xen/arch/x86/vmx_intercept.c @@ -254,6 +254,8 @@ void vmx_hooks_assist(struct vcpu *v) vpit->init_val); vpit->period = 1000000; } + vpit->period_cycles = (u64)vpit->period * cpu_khz / 1000000L; + printk("VMX_PIT: guest freq in cycles=%lld\n",(long long)vpit->period_cycles); vpit->channel = ((p->u.data >> 24) & 0x3); vpit->first_injected = 0; diff --git a/xen/arch/x86/vmx_io.c b/xen/arch/x86/vmx_io.c index 434d302209..4ede995d8c 100644 --- a/xen/arch/x86/vmx_io.c +++ b/xen/arch/x86/vmx_io.c @@ -799,6 +799,7 @@ static inline void interrupt_post_injection(struct vcpu * v, int vector, int type) { struct vmx_virpit *vpit = &(v->domain->arch.vmx_platform.vmx_pit); + u64 drift; switch(type) { @@ -812,6 +813,13 @@ interrupt_post_injection(struct vcpu * v, int vector, int type) vpit->pending_intr_nr--; } vpit->inject_point = NOW(); + drift = vpit->period_cycles * vpit->pending_intr_nr; + drift = v->arch.arch_vmx.tsc_offset - drift; + __vmwrite(TSC_OFFSET, drift); + +#if defined (__i386__) + __vmwrite(TSC_OFFSET_HIGH, (drift >> 32)); +#endif } break; diff --git a/xen/include/asm-x86/vmx.h b/xen/include/asm-x86/vmx.h index d16080cb1a..445c24bb59 100644 --- a/xen/include/asm-x86/vmx.h +++ b/xen/include/asm-x86/vmx.h @@ -65,6 +65,7 @@ extern unsigned int cpu_rev; CPU_BASED_MWAIT_EXITING | \ CPU_BASED_MOV_DR_EXITING | \ CPU_BASED_ACTIVATE_IO_BITMAP | \ + CPU_BASED_USE_TSC_OFFSETING | \ CPU_BASED_UNCOND_IO_EXITING \ ) diff --git a/xen/include/asm-x86/vmx_virpit.h b/xen/include/asm-x86/vmx_virpit.h index d0c758dd37..9539682d94 100644 --- a/xen/include/asm-x86/vmx_virpit.h +++ b/xen/include/asm-x86/vmx_virpit.h @@ -19,6 +19,7 @@ struct vmx_virpit { /* for simulation of counter 0 in mode 2*/ u32 period; /* pit frequency in ns */ + u64 period_cycles; /* pit frequency in cpu cycles */ s_time_t scheduled; /* scheduled timer interrupt */ unsigned int channel; /* the pit channel, counter 0~2 */ unsigned int pending_intr_nr; /* the couner for pending timer interrupts */ diff --git a/xen/include/asm-x86/vmx_vmcs.h b/xen/include/asm-x86/vmx_vmcs.h index f47daf8e09..207289a59d 100644 --- a/xen/include/asm-x86/vmx_vmcs.h +++ b/xen/include/asm-x86/vmx_vmcs.h @@ -96,6 +96,7 @@ struct arch_vmx_struct { struct msr_state msr_content; struct mmio_op mmio_op; /* MMIO */ void *io_bitmap_a, *io_bitmap_b; + u64 tsc_offset; }; #define vmx_schedule_tail(next) \ From 4384b3fc7028be8e027d984e4f7e38a0d488211d Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Sun, 23 Oct 2005 22:34:13 +0100 Subject: [PATCH 138/142] Instead of writing errors to /local/domain/0/backend////error, write them instead to /local/domain/0/error/backend/. This is not the best place for them perhaps, but it moves them out of the backend directory, on which the drivers have a watch. This fixes the problem whereby writing an error will trigger a watch, causing the error message to be written again, and repeat. Fixes bug #286. Signed-off-by: Ewan Mellor --- .../drivers/xen/xenbus/xenbus_xs.c | 60 ++++++++++++++++--- tools/examples/xen-backend.agent | 4 ++ tools/python/xen/util/diagnose.py | 4 +- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c index efaffe2393..c8d1204fc2 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_xs.c @@ -516,17 +516,38 @@ int xenbus_printf(struct xenbus_transaction *t, } EXPORT_SYMBOL(xenbus_printf); +/** + * Return the path to the error node for the given device, or NULL on failure. + * If the value returned is non-NULL, then it is the caller's to kfree. + */ +static char *error_path(struct xenbus_device *dev) +{ + char *path_buffer = kmalloc(strlen("error/") + strlen(dev->nodename) + + 1, GFP_KERNEL); + if (path_buffer == NULL) { + return NULL; + } + + strcpy(path_buffer, "error/"); + strcpy(path_buffer + strlen("error/"), dev->nodename); + + return path_buffer; +} + /* Report a (negative) errno into the store, with explanation. */ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...) { va_list ap; int ret; unsigned int len; - char *printf_buffer; + char *printf_buffer = NULL, *path_buffer = NULL; printf_buffer = kmalloc(PRINTF_BUFFER_SIZE, GFP_KERNEL); - if (printf_buffer == NULL) + if (printf_buffer == NULL) { + printk("xenbus: failed to write error node for %s (%d): %d\n", + dev->nodename, err, errno); goto fail; + } len = sprintf(printf_buffer, "%i ", -err); va_start(ap, fmt); @@ -535,15 +556,26 @@ void xenbus_dev_error(struct xenbus_device *dev, int err, const char *fmt, ...) BUG_ON(len + ret > PRINTF_BUFFER_SIZE-1); dev->has_error = 1; - if (xenbus_write(NULL, dev->nodename, "error", printf_buffer) != 0) + + path_buffer = error_path(dev); + + if (path_buffer == NULL) { + printk("xenbus: failed to write error node for %s (%s): %d\n", + dev->nodename, printf_buffer, errno); goto fail; + } - kfree(printf_buffer); - return; + if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) { + printk("xenbus: failed to write error node for %s (%s)\n", + dev->nodename, printf_buffer); + goto fail; + } - fail: - printk("xenbus: failed to write error node for %s (%s)\n", - dev->nodename, printf_buffer); +fail: + if (printf_buffer) + kfree(printf_buffer); + if (path_buffer) + kfree(path_buffer); } EXPORT_SYMBOL(xenbus_dev_error); @@ -551,11 +583,21 @@ EXPORT_SYMBOL(xenbus_dev_error); void xenbus_dev_ok(struct xenbus_device *dev) { if (dev->has_error) { - if (xenbus_rm(NULL, dev->nodename, "error") != 0) + char *path_buffer = error_path(dev); + + if (path_buffer == NULL) { + printk("xenbus: failed to clear error node for %s: " + "%d\n", dev->nodename, errno); + return; + } + + if (xenbus_rm(NULL, path_buffer, "error") != 0) printk("xenbus: failed to clear error node for %s\n", dev->nodename); else dev->has_error = 0; + + kfree(path_buffer); } } EXPORT_SYMBOL(xenbus_dev_ok); diff --git a/tools/examples/xen-backend.agent b/tools/examples/xen-backend.agent index 105572102b..35eb79601a 100755 --- a/tools/examples/xen-backend.agent +++ b/tools/examples/xen-backend.agent @@ -15,9 +15,13 @@ case "$ACTION" in vbd) /etc/xen/scripts/block unbind ;; + vif) + [ -n "$script" ] && $script down + ;; esac # remove device backend store entries xenstore-rm -t "$XENBUS_PATH" + xenstore-rm -t "error/$XENBUS_PATH" ;; online) case "$XENBUS_TYPE" in diff --git a/tools/python/xen/util/diagnose.py b/tools/python/xen/util/diagnose.py index d8b765e5c7..201c88120c 100644 --- a/tools/python/xen/util/diagnose.py +++ b/tools/python/xen/util/diagnose.py @@ -107,7 +107,9 @@ def diagnose_devices(): print ("Cannot find backend path for device %s, %s." % (deviceClass, device)) else: - backend_error = xstransact.Read(backendPath, 'error') + backend_error = xstransact.Read( + backendPath.replace('backend/', 'error/backend/'), + 'error') if backend_error: diagnose_device_error(backend_error) From fea77823212ce8b48b1897cb73dd0590896809eb Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Sun, 23 Oct 2005 22:45:15 +0100 Subject: [PATCH 139/142] Change the semantics of GetDomainPath so that it always succeeds, regardless of whether a domain has been introduced to the store. Added a separate message XS_IS_DOMAIN_INTRODUCED and API for that (xs_is_domain_introduced) to determine whether the domain has really been introduced. This change means that the tools can determine the correct domain path earlier in the domain creation process, which is particularly a factor with live migration, as it allows us to create the devices earlier in the process, and unpause the new domain before performing the introduce. Until recently we already had these features, but the simplification of the interface between xend and xenstored caused breakage. No longer clear out the domain path when a domain is introduced -- this was a hack to work around the recent problematic semantics of GetDomainPath. Do not write the contents of the info block to the store. All the configuration info is written to the /vm path, and anything else in the info block is either dealt with explicitly or is ephemeral and has no place in the store. Signed-off-by: Ewan Mellor --- tools/console/daemon/io.c | 3 -- tools/python/xen/lowlevel/xs/xs.c | 3 +- tools/python/xen/xend/XendCheckpoint.py | 2 ++ tools/python/xen/xend/XendDomainInfo.py | 36 +++++++++++------------ tools/xenstore/xenstored_core.c | 15 ++++------ tools/xenstore/xenstored_core.h | 3 -- tools/xenstore/xenstored_domain.c | 39 +++++++++++++++++-------- tools/xenstore/xenstored_domain.h | 3 ++ tools/xenstore/xs.c | 17 +++++++++-- tools/xenstore/xs.h | 4 +++ xen/include/public/io/xs_wire.h | 1 + 11 files changed, 75 insertions(+), 51 deletions(-) diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index 9039a96525..60e89267fc 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -301,10 +301,7 @@ static struct domain *create_domain(int domid) } dom->domid = domid; - dom->conspath = xs_get_domain_path(xs, dom->domid); - if (dom->conspath == NULL) - goto out; s = realloc(dom->conspath, strlen(dom->conspath) + strlen("/console") + 1); if (s == NULL) diff --git a/tools/python/xen/lowlevel/xs/xs.c b/tools/python/xen/lowlevel/xs/xs.c index b5ce2c357b..1f0dd5fac2 100644 --- a/tools/python/xen/lowlevel/xs/xs.c +++ b/tools/python/xen/lowlevel/xs/xs.c @@ -795,11 +795,10 @@ static PyObject *xspy_close(PyObject *self, PyObject *args, PyObject *kwds) } #define xspy_get_domain_path_doc "\n" \ - "Return store path of domain.\n" \ + "Return store path of domain, whether or not the domain exists.\n" \ " domid [int]: domain id\n" \ "\n" \ "Returns: [string] domain store path.\n" \ - " None if domid doesn't exist.\n" \ "Raises RuntimeError on error.\n" \ "\n" diff --git a/tools/python/xen/xend/XendCheckpoint.py b/tools/python/xen/xend/XendCheckpoint.py index 828fd0f2eb..4455734952 100644 --- a/tools/python/xen/xend/XendCheckpoint.py +++ b/tools/python/xen/xend/XendCheckpoint.py @@ -144,6 +144,8 @@ def restore(xd, fd): if handler.store_mfn is None or handler.console_mfn is None: raise XendError('Could not read store/console MFN') + dominfo.unpause() + dominfo.completeRestore(handler.store_mfn, handler.console_mfn) return dominfo diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 061e7863d5..11256f8916 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -198,7 +198,7 @@ def recreate(xeninfo, priv): vm = XendDomainInfo(xeninfo, domid, dompath, True) except Exception, exn: - if True: + if priv: log.warn(str(exn)) vm = XendDomainInfo(xeninfo, domid, dompath, True) @@ -223,7 +223,9 @@ def restore(config): try: vm.construct() vm.storeVmDetails() + vm.createDevices() vm.createChannels() + vm.storeDomDetails() return vm except: vm.destroy() @@ -337,8 +339,8 @@ def dom_get(dom): log.debug("domain_getinfo(%d) failed, ignoring: %s", dom, str(err)) return None -class XendDomainInfo: +class XendDomainInfo: def __init__(self, info, domid = None, dompath = None, augment = False): @@ -558,13 +560,13 @@ class XendDomainInfo: def completeRestore(self, store_mfn, console_mfn): + log.debug("XendDomainInfo.completeRestore") + self.store_mfn = store_mfn self.console_mfn = console_mfn self.introduceDomain() - self.create_devices() self.storeDomDetails() - self.unpause() self.refreshShutdown() @@ -597,10 +599,6 @@ class XendDomainInfo: 'memory/target': str(self.info['memory_KiB']) } - for (k, v) in self.info.items(): - if v: - to_store[k] = str(v) - def f(n, v): if v is not None: to_store[n] = str(v) @@ -1055,6 +1053,10 @@ class XendDomainInfo: raise VmError('Creating domain failed: name=%s' % self.info['name']) + self.dompath = GetDomainPath(self.domid) + + self.removeDom() + # Set maximum number of vcpus in domain xc.domain_max_vcpus(self.domid, int(self.info['vcpus'])) @@ -1065,8 +1067,6 @@ class XendDomainInfo: assert self.store_port is not None IntroduceDomain(self.domid, self.store_mfn, self.store_port) - self.dompath = GetDomainPath(self.domid) - assert self.dompath def initDomain(self): @@ -1105,7 +1105,7 @@ class XendDomainInfo: self.introduceDomain() - self.create_devices() + self.createDevices() self.info['start_time'] = time.time() @@ -1209,23 +1209,21 @@ class XendDomainInfo: raise - def create_configured_devices(self): - for (n, c) in self.info['device']: - self.createDevice(n, c) + ## public: - - def create_devices(self): + def createDevices(self): """Create the devices for a vm. @raise: VmError for invalid devices """ - self.create_configured_devices() + + for (n, c) in self.info['device']: + self.createDevice(n, c) + if self.image: self.image.createDeviceModel() - ## public: - def device_create(self, dev_config): """Create a new device. diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index d9ecefc133..f5b1b014e3 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -166,6 +166,7 @@ static char *sockmsg_string(enum xsd_sockmsg_type type) case XS_SET_PERMS: return "SET_PERMS"; case XS_WATCH_EVENT: return "WATCH_EVENT"; case XS_ERROR: return "ERROR"; + case XS_IS_DOMAIN_INTRODUCED: return "XS_IS_DOMAIN_INTRODUCED"; default: return "**UNKNOWN**"; } @@ -1001,16 +1002,6 @@ static void do_rm(struct connection *conn, const char *name) } -void internal_rm(const char *name) -{ - struct node *node = read_node(NULL, name); - if (!node) { - return; - } - _rm(NULL, node, name); -} - - static void do_get_perms(struct connection *conn, const char *name) { struct node *node; @@ -1153,6 +1144,10 @@ static void process_message(struct connection *conn, struct buffered_data *in) do_introduce(conn, in); break; + case XS_IS_DOMAIN_INTRODUCED: + do_is_domain_introduced(conn, onearg(in)); + break; + case XS_RELEASE: do_release(conn, onearg(in)); break; diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h index abcb42c38d..da98a9211d 100644 --- a/tools/xenstore/xenstored_core.h +++ b/tools/xenstore/xenstored_core.h @@ -155,9 +155,6 @@ void __attribute__((noreturn)) corrupt(struct connection *conn, struct connection *new_connection(connwritefn_t *write, connreadfn_t *read); -void internal_rm(const char *name); - - /* Is this a valid node name? */ bool is_valid_nodename(const char *node); diff --git a/tools/xenstore/xenstored_domain.c b/tools/xenstore/xenstored_domain.c index 69e429ccfa..d252469617 100644 --- a/tools/xenstore/xenstored_domain.c +++ b/tools/xenstore/xenstored_domain.c @@ -250,6 +250,11 @@ bool domain_can_write(struct connection *conn) return ((intf->rsp_prod - intf->rsp_cons) != XENSTORE_RING_SIZE); } +static char *talloc_domain_path(void *context, unsigned int domid) +{ + return talloc_asprintf(context, "/local/domain/%u", domid); +} + static struct domain *new_domain(void *context, unsigned int domid, unsigned long mfn, int port) { @@ -262,7 +267,7 @@ static struct domain *new_domain(void *context, unsigned int domid, domain->port = 0; domain->shutdown = 0; domain->domid = domid; - domain->path = talloc_asprintf(domain, "/local/domain/%d", domid); + domain->path = talloc_domain_path(domain, domid); domain->interface = xc_map_foreign_range( *xc_handle, domain->domid, getpagesize(), PROT_READ|PROT_WRITE, mfn); @@ -272,8 +277,6 @@ static struct domain *new_domain(void *context, unsigned int domid, list_add(&domain->list, &domains); talloc_set_destructor(domain, destroy_domain); - internal_rm(domain->path); - /* Tell kernel we're interested in this event. */ bind.remote_domain = domid; bind.remote_port = port; @@ -403,25 +406,37 @@ void do_release(struct connection *conn, const char *domid_str) void do_get_domain_path(struct connection *conn, const char *domid_str) { - struct domain *domain; - unsigned int domid; + char *path; if (!domid_str) { send_error(conn, EINVAL); return; } + path = talloc_domain_path(conn, atoi(domid_str)); + + send_reply(conn, XS_GET_DOMAIN_PATH, path, strlen(path) + 1); + + talloc_free(path); +} + +void do_is_domain_introduced(struct connection *conn, const char *domid_str) +{ + int result; + unsigned int domid; + + if (!domid_str) { + send_error(conn, EINVAL); + return; + } + domid = atoi(domid_str); if (domid == DOMID_SELF) - domain = conn->domain; + result = 1; else - domain = find_domain_by_domid(domid); + result = (find_domain_by_domid(domid) != NULL); - if (!domain) - send_error(conn, ENOENT); - else - send_reply(conn, XS_GET_DOMAIN_PATH, domain->path, - strlen(domain->path) + 1); + send_reply(conn, XS_IS_DOMAIN_INTRODUCED, result ? "T" : "F", 2); } static int close_xc_handle(void *_handle) diff --git a/tools/xenstore/xenstored_domain.h b/tools/xenstore/xenstored_domain.h index e8d5ec8c88..b8d839d624 100644 --- a/tools/xenstore/xenstored_domain.h +++ b/tools/xenstore/xenstored_domain.h @@ -25,6 +25,9 @@ void handle_event(void); /* domid, mfn, eventchn, path */ void do_introduce(struct connection *conn, struct buffered_data *in); +/* domid */ +void do_is_domain_introduced(struct connection *conn, const char *domid_str); + /* domid */ void do_release(struct connection *conn, const char *domid_str); diff --git a/tools/xenstore/xs.c b/tools/xenstore/xs.c index 22710d5d01..a817a88077 100644 --- a/tools/xenstore/xs.c +++ b/tools/xenstore/xs.c @@ -696,13 +696,20 @@ bool xs_introduce_domain(struct xs_handle *h, ARRAY_SIZE(iov), NULL)); } -bool xs_release_domain(struct xs_handle *h, unsigned int domid) +static void * single_with_domid(struct xs_handle *h, + enum xsd_sockmsg_type type, + unsigned int domid) { char domid_str[MAX_STRLEN(domid)]; sprintf(domid_str, "%u", domid); - return xs_bool(xs_single(h, NULL, XS_RELEASE, domid_str, NULL)); + return xs_single(h, NULL, type, domid_str, NULL); +} + +bool xs_release_domain(struct xs_handle *h, unsigned int domid) +{ + return xs_bool(single_with_domid(h, XS_RELEASE, domid)); } char *xs_get_domain_path(struct xs_handle *h, unsigned int domid) @@ -714,6 +721,12 @@ char *xs_get_domain_path(struct xs_handle *h, unsigned int domid) return xs_single(h, NULL, XS_GET_DOMAIN_PATH, domid_str, NULL); } +bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid) +{ + return strcmp("F", + single_with_domid(h, XS_IS_DOMAIN_INTRODUCED, domid)); +} + /* Only useful for DEBUG versions */ char *xs_debug_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len) diff --git a/tools/xenstore/xs.h b/tools/xenstore/xs.h index 618e6615a6..f59b1e76f9 100644 --- a/tools/xenstore/xs.h +++ b/tools/xenstore/xs.h @@ -140,6 +140,10 @@ bool xs_release_domain(struct xs_handle *h, unsigned int domid); */ char *xs_get_domain_path(struct xs_handle *h, unsigned int domid); +/* Return whether the domain specified has been introduced to xenstored. + */ +bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid); + /* Only useful for DEBUG versions */ char *xs_debug_command(struct xs_handle *h, const char *cmd, void *data, unsigned int len); diff --git a/xen/include/public/io/xs_wire.h b/xen/include/public/io/xs_wire.h index 88d6b1f212..7d96dc813a 100644 --- a/xen/include/public/io/xs_wire.h +++ b/xen/include/public/io/xs_wire.h @@ -47,6 +47,7 @@ enum xsd_sockmsg_type XS_SET_PERMS, XS_WATCH_EVENT, XS_ERROR, + XS_IS_DOMAIN_INTRODUCED }; #define XS_WRITE_NONE "NONE" From 7ce0fde009344d9b18f47d722f998e0d6a110271 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 24 Oct 2005 08:04:38 +0100 Subject: [PATCH 140/142] Attached patch avoids "Bad L1 flags 80" for VMX domains. Thanks Ian for the suggestions. Signed-off-by: Jun Nakajima --- xen/arch/x86/shadow.c | 27 +++++++++++++++++++++++++-- xen/arch/x86/shadow32.c | 27 +++++++++++++++++++++++++-- xen/include/asm-x86/shadow.h | 14 +++++++++++--- 3 files changed, 61 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index dfea7b4f43..fdd0c5aaf0 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -871,6 +871,7 @@ mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn, perfc_incrc(shadow_mark_mfn_out_of_sync_calls); + entry->v = v; entry->gpfn = gpfn; entry->gmfn = mfn; entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn); @@ -937,6 +938,7 @@ static void shadow_mark_va_out_of_sync( entry->writable_pl1e = l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * l1_table_offset(va)); ASSERT( !(entry->writable_pl1e & (sizeof(l1_pgentry_t)-1)) ); + entry->va = va; // Increment shadow's page count to represent the reference // inherent in entry->writable_pl1e @@ -1340,6 +1342,7 @@ static int resync_all(struct domain *d, u32 stype) guest_l1_pgentry_t *guest1 = guest; l1_pgentry_t *shadow1 = shadow; guest_l1_pgentry_t *snapshot1 = snapshot; + int unshadow_l1 = 0; ASSERT(VM_ASSIST(d, VMASST_TYPE_writable_pagetables) || shadow_mode_write_all(d)); @@ -1358,8 +1361,15 @@ static int resync_all(struct domain *d, u32 stype) if ( (i < min_snapshot) || (i > max_snapshot) || guest_l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) ) { - need_flush |= validate_pte_change(d, guest1[i], &shadow1[i]); - set_guest_back_ptr(d, shadow1[i], smfn, i); + int error; + + error = validate_pte_change(d, guest1[i], &shadow1[i]); + if ( error == -1 ) + unshadow_l1 = 1; + else { + need_flush |= error; + set_guest_back_ptr(d, shadow1[i], smfn, i); + } // can't update snapshots of linear page tables -- they // are used multiple times... // @@ -1371,6 +1381,19 @@ static int resync_all(struct domain *d, u32 stype) perfc_incrc(resync_l1); perfc_incr_histo(wpt_updates, changed, PT_UPDATES); perfc_incr_histo(l1_entries_checked, max_shadow - min_shadow + 1, PT_UPDATES); + if (unshadow_l1) { + pgentry_64_t l2e; + + __shadow_get_l2e(entry->v, entry->va, &l2e); + if (entry_get_flags(l2e) & _PAGE_PRESENT) { + entry_remove_flags(l2e, _PAGE_PRESENT); + __shadow_set_l2e(entry->v, entry->va, &l2e); + + if (entry->v == current) + need_flush = 1; + } + } + break; } #if defined (__i386__) diff --git a/xen/arch/x86/shadow32.c b/xen/arch/x86/shadow32.c index 18b5dc448f..5293e11843 100644 --- a/xen/arch/x86/shadow32.c +++ b/xen/arch/x86/shadow32.c @@ -1829,6 +1829,7 @@ shadow_mark_mfn_out_of_sync(struct vcpu *v, unsigned long gpfn, perfc_incrc(shadow_mark_mfn_out_of_sync_calls); + entry->v = v; entry->gpfn = gpfn; entry->gmfn = mfn; entry->snapshot_mfn = shadow_make_snapshot(d, gpfn, mfn); @@ -1875,6 +1876,7 @@ void shadow_mark_va_out_of_sync( entry->writable_pl1e = l2e_get_paddr(sl2e) | (sizeof(l1_pgentry_t) * l1_table_offset(va)); ASSERT( !(entry->writable_pl1e & (sizeof(l1_pgentry_t)-1)) ); + entry->va = va; // Increment shadow's page count to represent the reference // inherent in entry->writable_pl1e @@ -2320,6 +2322,7 @@ static int resync_all(struct domain *d, u32 stype) l1_pgentry_t *guest1 = guest; l1_pgentry_t *shadow1 = shadow; l1_pgentry_t *snapshot1 = snapshot; + int unshadow_l1 = 0; ASSERT(VM_ASSIST(d, VMASST_TYPE_writable_pagetables) || shadow_mode_write_all(d)); @@ -2346,8 +2349,15 @@ static int resync_all(struct domain *d, u32 stype) if ( (i < min_snapshot) || (i > max_snapshot) || l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) ) { - need_flush |= validate_pte_change(d, guest1[i], &shadow1[i]); - set_guest_back_ptr(d, shadow1[i], smfn, i); + int error; + + error = validate_pte_change(d, guest1[i], &shadow1[i]); + if ( error == -1 ) + unshadow_l1 = 1; + else { + need_flush |= error; + set_guest_back_ptr(d, shadow1[i], smfn, i); + } // can't update snapshots of linear page tables -- they // are used multiple times... @@ -2359,6 +2369,19 @@ static int resync_all(struct domain *d, u32 stype) perfc_incrc(resync_l1); perfc_incr_histo(wpt_updates, changed, PT_UPDATES); perfc_incr_histo(l1_entries_checked, max_shadow - min_shadow + 1, PT_UPDATES); + if (unshadow_l1) { + l2_pgentry_t l2e; + + __shadow_get_l2e(entry->v, entry->va, &l2e); + if (l2e_get_flags(l2e) & _PAGE_PRESENT) { + l2e_remove_flags(l2e, _PAGE_PRESENT); + __shadow_set_l2e(entry->v, entry->va, l2e); + + if (entry->v == current) + need_flush = 1; + } + } + break; } case PGT_l2_shadow: diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index 93bd92aaf7..0a8112c3d3 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -302,10 +302,12 @@ struct shadow_status { struct out_of_sync_entry { struct out_of_sync_entry *next; + struct vcpu *v; unsigned long gpfn; /* why is this here? */ unsigned long gmfn; unsigned long snapshot_mfn; unsigned long writable_pl1e; /* NB: this is a machine address */ + unsigned long va; }; #define out_of_sync_extra_size 127 @@ -384,6 +386,10 @@ shadow_get_page_from_l1e(l1_pgentry_t l1e, struct domain *d) nl1e = l1e; l1e_remove_flags(nl1e, _PAGE_GLOBAL); + + if ( unlikely(l1e_get_flags(l1e) & L1_DISALLOW_MASK) ) + return 0; + res = get_page_from_l1e(nl1e, d); if ( unlikely(!res) && IS_PRIV(d) && !shadow_mode_translate(d) && @@ -959,14 +965,16 @@ validate_pte_change( // perfc_incrc(validate_pte_changes3); - if ( (l1e_get_flags(new_spte) & _PAGE_PRESENT) && - !shadow_get_page_from_l1e(new_spte, d) ) - new_spte = l1e_empty(); if ( l1e_get_flags(old_spte) & _PAGE_PRESENT ) { shadow_put_page_from_l1e(old_spte, d); need_flush = 1; } + if ( (l1e_get_flags(new_spte) & _PAGE_PRESENT) && + !shadow_get_page_from_l1e(new_spte, d) ) { + new_spte = l1e_empty(); + need_flush = -1; /* need to unshadow the page */ + } } else { From 493b98bf232159bef0a0f8d5955c04562c2c4108 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 24 Oct 2005 14:11:07 +0100 Subject: [PATCH 141/142] Do not create the console tty until domain_create_ring has succeeded. This means that any reads attempted on that tty will not cause handle_tty_read to segfault looking for an interface that does not exist. Move the writing of the tty node so that it happens after console/limit has been read, as it is cleaner if the writing is the last thing that happens. Signed-off-by: Ewan Mellor --- tools/console/daemon/io.c | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/tools/console/daemon/io.c b/tools/console/daemon/io.c index 60e89267fc..0b55607d50 100644 --- a/tools/console/daemon/io.c +++ b/tools/console/daemon/io.c @@ -163,14 +163,6 @@ static int domain_create_tty(struct domain *dom) tcsetattr(master, TCSAFLUSH, &term); } - success = asprintf(&path, "%s/tty", dom->conspath) != -1; - if (!success) - goto out; - success = xs_write(xs, NULL, path, slave, strlen(slave)); - free(path); - if (!success) - goto out; - success = asprintf(&path, "%s/limit", dom->conspath) != -1; if (!success) goto out; @@ -180,6 +172,14 @@ static int domain_create_tty(struct domain *dom) free(data); } free(path); + + success = asprintf(&path, "%s/tty", dom->conspath) != -1; + if (!success) + goto out; + success = xs_write(xs, NULL, path, slave, strlen(slave)); + free(path); + if (!success) + goto out; } return master; @@ -269,6 +269,18 @@ static int domain_create_ring(struct domain *dom) } dom->local_port = rc; + if (dom->tty_fd == -1) { + dom->tty_fd = domain_create_tty(dom); + + if (dom->tty_fd == -1) { + err = errno; + close(dom->evtchn_fd); + dom->evtchn_fd = -1; + dom->local_port = -1; + goto out; + } + } + out: return err; } @@ -309,7 +321,7 @@ static struct domain *create_domain(int domid) dom->conspath = s; strcat(dom->conspath, "/console"); - dom->tty_fd = domain_create_tty(dom); + dom->tty_fd = -1; dom->is_dead = false; dom->buffer.data = 0; dom->buffer.size = 0; From 8b6e8053b8a755c7953f00799dafa3de531ed596 Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Mon, 24 Oct 2005 14:12:42 +0100 Subject: [PATCH 142/142] Added a timestamp to the logging output by trace_io. Signed-off-by: Ewan Mellor --- tools/xenstore/xenstored_core.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c index f5b1b014e3..00c64719de 100644 --- a/tools/xenstore/xenstored_core.c +++ b/tools/xenstore/xenstored_core.c @@ -178,12 +178,18 @@ static void trace_io(const struct connection *conn, { char string[64]; unsigned int i; + time_t now; + struct tm *tm; if (tracefd < 0) return; + now = time(NULL); + tm = localtime(&now); + write(tracefd, prefix, strlen(prefix)); - sprintf(string, " %p ", conn); + sprintf(string, " %p %0d:%0d:%0d ", conn, tm->tm_hour, tm->tm_min, + tm->tm_sec); write(tracefd, string, strlen(string)); write(tracefd, sockmsg_string(data->hdr.msg.type), strlen(sockmsg_string(data->hdr.msg.type)));