# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 3bed37b2c599c74ba3ca9f90f5e948f13b3b2891
# Parent 5791030e6473138d37ce346a84859d1921b47a86
# Parent 7acaba46e15edc6a07613c833097f662da351552
merge with xen-unstable.hg
---
docs/man/xm.pod.1 | 7
docs/src/user.tex | 64 ++++--
linux-2.6-xen-sparse/drivers/xen/console/console.c | 20 +-
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c | 18 +
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c | 8
tools/blktap/drivers/block-qcow.c | 29 ++
tools/blktap/drivers/tapdisk.c | 23 --
tools/console/client/main.c | 3
tools/examples/vtpm-common.sh | 5
tools/examples/vtpm-impl | 3
tools/python/xen/xend/XendDomain.py | 4
tools/python/xen/xend/XendDomainInfo.py | 60 ++++--
tools/python/xen/xend/image.py | 45 +++-
tools/python/xen/xend/server/pciquirk.py | 2
tools/python/xen/xm/create.py | 3
tools/python/xen/xm/tests/test_create.py | 4
tools/xenmon/xenmon.py | 3
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 32 +--
xen/arch/x86/mm/shadow/multi.c | 6
xen/common/grant_table.c | 148 +++++++--------
xen/include/asm-x86/bitops.h | 57 ++---
21 files changed, 345 insertions(+), 199 deletions(-)
diff -r 5791030e6473 -r 3bed37b2c599 docs/man/xm.pod.1
--- a/docs/man/xm.pod.1 Sun Sep 10 14:31:54 2006 -0600
+++ b/docs/man/xm.pod.1 Sun Sep 10 14:52:57 2006 -0600
@@ -432,7 +432,6 @@ Sample xen domain info looks as follows
Sample xen domain info looks as follows (lines wrapped manually to
make the man page more readable):
- system : Linux
host : talon
release : 2.6.12.6-xen0
version : #1 Mon Nov 14 14:26:26 EST 2005
@@ -444,13 +443,14 @@ make the man page more readable):
threads_per_core : 1
cpu_mhz : 696
hw_caps : 0383fbff:00000000:00000000:00000040
- memory : 767
+ total_memory : 767
free_memory : 37
xen_major : 3
xen_minor : 0
xen_extra : -devel
xen_caps : xen-3.0-x86_32
- xen_params : virt_start=0xfc000000
+ xen_pagesize : 4096
+ platform_params : virt_start=0xfc000000
xen_changeset : Mon Nov 14 18:13:38 2005 +0100
7793:090e44133d40
cc_compiler : gcc version 3.4.3 (Mandrakelinux
@@ -458,6 +458,7 @@ make the man page more readable):
cc_compile_by : sdague
cc_compile_domain : (none)
cc_compile_date : Mon Nov 14 14:16:48 EST 2005
+ xend_config_format : 2
B<FIELDS>
diff -r 5791030e6473 -r 3bed37b2c599 docs/src/user.tex
--- a/docs/src/user.tex Sun Sep 10 14:31:54 2006 -0600
+++ b/docs/src/user.tex Sun Sep 10 14:52:57 2006 -0600
@@ -1654,26 +1654,58 @@ Now unmount (this is important!):
In the configuration file set:
\begin{quote}
+ \verb_disk = ['tap:aio:/full/path/to/vm1disk,sda1,w']_
+\end{quote}
+
+As the virtual machine writes to its `disk', the sparse file will be
+filled in and consume more space up to the original 2GB.
+
+{\em{Note:}} Users that have worked with file-backed VBDs on Xen in previous
+versions will be interested to know that this support is now provided through
+the blktap driver instead of the loopback driver. This change results in
+file-based block devices that are higher-performance, more scalable, and which
+provide better safety properties for VBD data. All that is required to update
+your existing file-backed VM configurations is to change VBD configuration
+lines from:
+\begin{quote}
\verb_disk = ['file:/full/path/to/vm1disk,sda1,w']_
\end{quote}
-
-As the virtual machine writes to its `disk', the sparse file will be
-filled in and consume more space up to the original 2GB.
-
-{\bf Note that file-backed VBDs may not be appropriate for backing
- I/O-intensive domains.} File-backed VBDs are known to experience
+to:
+\begin{quote}
+ \verb_disk = ['tap:aio:/full/path/to/vm1disk,sda1,w']_
+\end{quote}
+
+
+\subsection{Loopback-mounted file-backed VBDs (deprecated)}
+
+{\em{{\bf{Note:}} Loopback mounted VBDs have now been replaced with
+ blktap-based support for raw image files, as described above. This
+ section remains to detail a configuration that was used by older Xen
+ versions.}}
+
+Raw image file-backed VBDs amy also be attached to VMs using the
+Linux loopback driver. The only required change to the raw file
+instructions above are to specify the configuration entry as:
+\begin{quote}
+ \verb_disk = ['file:/full/path/to/vm1disk,sda1,w']_
+\end{quote}
+
+{\bf Note that loopback file-backed VBDs may not be appropriate for backing
+ I/O-intensive domains.} This approach is known to experience
substantial slowdowns under heavy I/O workloads, due to the I/O
handling by the loopback block device used to support file-backed VBDs
-in dom0. Better I/O performance can be achieved by using either
-LVM-backed VBDs (Section~\ref{s:using-lvm-backed-vbds}) or physical
-devices as VBDs (Section~\ref{s:exporting-physical-devices-as-vbds}).
-
-Linux supports a maximum of eight file-backed VBDs across all domains
-by default. This limit can be statically increased by using the
-\emph{max\_loop} module parameter if CONFIG\_BLK\_DEV\_LOOP is
-compiled as a module in the dom0 kernel, or by using the
-\emph{max\_loop=n} boot option if CONFIG\_BLK\_DEV\_LOOP is compiled
-directly into the dom0 kernel.
+in dom0. Loopbach support remains for old Xen installations, and users
+are strongly encouraged to use the blktap-based file support (using
+``{\tt{tap:aio}}'' as described above).
+
+Additionally, Linux supports a maximum of eight loopback file-backed
+VBDs across all domains by default. This limit can be statically
+increased by using the \emph{max\_loop} module parameter if
+CONFIG\_BLK\_DEV\_LOOP is compiled as a module in the dom0 kernel, or
+by using the \emph{max\_loop=n} boot option if CONFIG\_BLK\_DEV\_LOOP
+is compiled directly into the dom0 kernel. Again, users are encouraged
+to use the blktap-based file support described above which scales to much
+larger number of active VBDs.
\section{Using LVM-backed VBDs}
diff -r 5791030e6473 -r 3bed37b2c599
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Sun Sep 10
14:31:54 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Sun Sep 10
14:52:57 2006 -0600
@@ -182,17 +182,18 @@ static struct console kcons_info = {
.index = -1,
};
-#define __RETCODE 0
static int __init xen_console_init(void)
{
if (!is_running_on_xen())
- return __RETCODE;
+ goto out;
if (is_initial_xendomain()) {
if (xc_mode == XC_DEFAULT)
xc_mode = XC_SERIAL;
kcons_info.write = kcons_write_dom0;
} else {
+ if (!xen_start_info->console.domU.evtchn)
+ goto out;
if (xc_mode == XC_DEFAULT)
xc_mode = XC_TTY;
kcons_info.write = kcons_write;
@@ -212,14 +213,15 @@ static int __init xen_console_init(void)
break;
default:
- return __RETCODE;
+ goto out;
}
wbuf = alloc_bootmem(wbuf_size);
register_console(&kcons_info);
- return __RETCODE;
+ out:
+ return 0;
}
console_initcall(xen_console_init);
@@ -247,7 +249,9 @@ void xencons_force_flush(void)
int sz;
/* Emergency console is synchronous, so there's nothing to flush. */
- if (is_initial_xendomain())
+ if (!is_running_on_xen() ||
+ is_initial_xendomain() ||
+ !xen_start_info->console.domU.evtchn)
return;
/* Spin until console data is flushed through to the daemon. */
@@ -582,7 +586,11 @@ static int __init xencons_init(void)
if (xc_mode == XC_OFF)
return 0;
- xencons_ring_init();
+ if (!is_initial_xendomain()) {
+ rc = xencons_ring_init();
+ if (rc)
+ return rc;
+ }
xencons_driver = alloc_tty_driver((xc_mode == XC_SERIAL) ?
1 : MAX_NR_CONSOLES);
diff -r 5791030e6473 -r 3bed37b2c599
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Sun Sep 10
14:31:54 2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Sun Sep 10
14:52:57 2006 -0600
@@ -110,24 +110,26 @@ static irqreturn_t handle_input(int irq,
int xencons_ring_init(void)
{
- int err;
+ int irq;
if (xencons_irq)
unbind_from_irqhandler(xencons_irq, NULL);
xencons_irq = 0;
- if (!xen_start_info->console.domU.evtchn)
- return 0;
+ if (!is_running_on_xen() ||
+ is_initial_xendomain() ||
+ !xen_start_info->console.domU.evtchn)
+ return -ENODEV;
- err = bind_evtchn_to_irqhandler(
+ irq = bind_evtchn_to_irqhandler(
xen_start_info->console.domU.evtchn,
handle_input, 0, "xencons", NULL);
- if (err <= 0) {
- printk(KERN_ERR "XEN console request irq failed %i\n", err);
- return err;
+ if (irq < 0) {
+ printk(KERN_ERR "XEN console request irq failed %i\n", irq);
+ return irq;
}
- xencons_irq = err;
+ xencons_irq = irq;
/* In case we have in-flight data after save/restore... */
notify_daemon();
diff -r 5791030e6473 -r 3bed37b2c599
linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Sun Sep 10 14:31:54
2006 -0600
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/xenbus.c Sun Sep 10 14:52:57
2006 -0600
@@ -427,6 +427,14 @@ static int connect_rings(struct backend_
be->netif->dev->features |= NETIF_F_TSO;
}
+ if (xenbus_scanf(XBT_NIL, dev->otherend, "feature-no-csum-offload",
+ "%d", &val) < 0)
+ val = 0;
+ if (val) {
+ be->netif->features &= ~NETIF_F_IP_CSUM;
+ be->netif->dev->features &= ~NETIF_F_IP_CSUM;
+ }
+
/* Map the shared frame, irq etc. */
err = netif_map(be->netif, tx_ring_ref, rx_ring_ref, evtchn);
if (err) {
diff -r 5791030e6473 -r 3bed37b2c599 tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/blktap/drivers/block-qcow.c Sun Sep 10 14:52:57 2006 -0600
@@ -235,6 +235,25 @@ static uint32_t gen_cksum(char *ptr, int
memcpy(&ret, md, sizeof(uint32_t));
free(md);
return ret;
+}
+
+static int get_filesize(char *filename, uint64_t *size, struct stat *st)
+{
+ int blockfd;
+
+ /*Set to the backing file size*/
+ if(S_ISBLK(st->st_mode)) {
+ blockfd = open(filename, O_RDONLY);
+ if (blockfd < 0)
+ return -1;
+ if (ioctl(blockfd,BLKGETSIZE,size)!=0) {
+ printf("Unable to get Block device size\n");
+ close(blockfd);
+ return -1;
+ }
+ close(blockfd);
+ } else *size = (st->st_size >> SECTOR_SHIFT);
+ return 0;
}
static int qcow_set_key(struct td_state *bs, const char *key)
@@ -1204,12 +1223,14 @@ int qcow_create(const char *filename, ui
header_size += backing_filename_len;
/*Set to the backing file size*/
- size = (st.st_size >> SECTOR_SHIFT);
+ if(get_filesize(backing_filename, &size, &st)) {
+ return -1;
+ }
DPRINTF("Backing file size detected: %lld sectors"
"(total %lld [%lld MB])\n",
- (long long)total_size,
- (long long)(total_size << SECTOR_SHIFT),
- (long long)(total_size >> 11));
+ (long long)size,
+ (long long)(size << SECTOR_SHIFT),
+ (long long)(size >> 11));
} else {
backing_file = NULL;
DPRINTF("Setting file size: %lld (total %lld)\n",
diff -r 5791030e6473 -r 3bed37b2c599 tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/blktap/drivers/tapdisk.c Sun Sep 10 14:52:57 2006 -0600
@@ -127,18 +127,15 @@ static inline int LOCAL_FD_SET(fd_set *r
static inline int LOCAL_FD_SET(fd_set *readfds)
{
fd_list_entry_t *ptr;
- int i;
ptr = fd_start;
while (ptr != NULL) {
if (ptr->tap_fd) {
FD_SET(ptr->tap_fd, readfds);
- for (i = 0; i < MAX_IOFD; i++) {
- if (ptr->io_fd[i])
- FD_SET(ptr->io_fd[i], readfds);
- maxfds = (ptr->io_fd[i] > maxfds ?
- ptr->io_fd[i]: maxfds);
- }
+ if (ptr->io_fd[READ])
+ FD_SET(ptr->io_fd[READ], readfds);
+ maxfds = (ptr->io_fd[READ] > maxfds ?
+ ptr->io_fd[READ]: maxfds);
maxfds = (ptr->tap_fd > maxfds ? ptr->tap_fd: maxfds);
}
ptr = ptr->next;
@@ -580,7 +577,7 @@ static void get_io_request(struct td_sta
int main(int argc, char *argv[])
{
- int len, msglen, ret, i;
+ int len, msglen, ret;
char *p, *buf;
fd_set readfds, writefds;
struct timeval timeout;
@@ -633,16 +630,14 @@ int main(int argc, char *argv[])
(fd_set *) 0, &timeout);
if (ret > 0)
- {
+ {
ptr = fd_start;
while (ptr != NULL) {
if (FD_ISSET(ptr->tap_fd, &readfds))
get_io_request(ptr->s);
- for (i = 0; i < MAX_IOFD; i++) {
- if (ptr->io_fd[i] &&
- FD_ISSET(ptr->io_fd[i], &readfds))
- io_done(ptr->s, i);
- }
+ if (ptr->io_fd[READ] &&
+ FD_ISSET(ptr->io_fd[READ],
&readfds))
+ io_done(ptr->s, READ);
ptr = ptr->next;
}
diff -r 5791030e6473 -r 3bed37b2c599 tools/console/client/main.c
--- a/tools/console/client/main.c Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/console/client/main.c Sun Sep 10 14:52:57 2006 -0600
@@ -220,7 +220,8 @@ int main(int argc, char **argv)
user friendly, we'll bail out here since no data will ever show
up on domain-0. */
if (domid == 0) {
- err(errno, "Could not read tty from store");
+ fprintf(stderr, "Can't specify Domain-0\n");
+ exit(EINVAL);
}
/* Wait a little bit for tty to appear. There is a race
diff -r 5791030e6473 -r 3bed37b2c599 tools/examples/vtpm-common.sh
--- a/tools/examples/vtpm-common.sh Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/examples/vtpm-common.sh Sun Sep 10 14:52:57 2006 -0600
@@ -47,6 +47,9 @@ else
}
function vtpm_migrate() {
echo "Error: vTPM migration accross machines not implemented."
+ }
+ function vtpm_migrate_local() {
+ echo "Error: local vTPM migration not supported"
}
function vtpm_migrate_recover() {
true
@@ -353,6 +356,8 @@ function vtpm_migration_step() {
local res=$(vtpm_isLocalAddress $1)
if [ "$res" == "0" ]; then
vtpm_migrate $1 $2 $3
+ else
+ vtpm_migrate_local
fi
}
diff -r 5791030e6473 -r 3bed37b2c599 tools/examples/vtpm-impl
--- a/tools/examples/vtpm-impl Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/examples/vtpm-impl Sun Sep 10 14:52:57 2006 -0600
@@ -184,3 +184,6 @@ function vtpm_migrate_recover() {
echo "Error: Recovery not supported yet"
}
+function vtpm_migrate_local() {
+ echo "Error: local vTPM migration not supported"
+}
diff -r 5791030e6473 -r 3bed37b2c599 tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/python/xen/xend/XendDomain.py Sun Sep 10 14:52:57 2006 -0600
@@ -420,6 +420,10 @@ class XendDomain:
""" The following call may raise a XendError exception """
dominfo.testMigrateDevices(True, dst)
+ if live:
+ """ Make sure there's memory free for enabling shadow mode """
+ dominfo.checkLiveMigrateMemory()
+
if port == 0:
port = xroot.get_xend_relocation_port()
try:
diff -r 5791030e6473 -r 3bed37b2c599 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/python/xen/xend/XendDomainInfo.py Sun Sep 10 14:52:57 2006 -0600
@@ -49,6 +49,7 @@ from xen.xend.xenstore.xsutil import Get
from xen.xend.xenstore.xsutil import GetDomainPath, IntroduceDomain
from xen.xend.xenstore.xswatch import xswatch
+from xen.xend import arch
"""Shutdown code for poweroff."""
DOMAIN_POWEROFF = 0
@@ -1087,6 +1088,15 @@ class XendDomainInfo:
## public:
def destroyDevice(self, deviceClass, devid):
+ if type(devid) is str:
+ devicePath = '%s/device/%s' % (self.dompath, deviceClass)
+ for entry in xstransact.List(devicePath):
+ backend = xstransact.Read('%s/%s' % (devicePath, entry),
"backend")
+ devName = xstransact.Read(backend, "dev")
+ if devName == devid:
+ # We found the integer matching our devid, use it instead
+ devid = entry
+ break
return self.getDeviceController(deviceClass).destroyDevice(devid)
@@ -1285,28 +1295,37 @@ class XendDomainInfo:
for v in range(0, self.info['max_vcpu_id']+1):
xc.vcpu_setaffinity(self.domid, v, self.info['cpus'])
+ # Use architecture- and image-specific calculations to determine
+ # the various headrooms necessary, given the raw configured
+ # values.
+ # reservation, maxmem, memory, and shadow are all in KiB.
+ reservation = self.image.getRequiredInitialReservation(
+ self.info['memory'] * 1024)
+ maxmem = self.image.getRequiredAvailableMemory(
+ self.info['maxmem'] * 1024)
+ memory = self.image.getRequiredAvailableMemory(
+ self.info['memory'] * 1024)
+ shadow = self.image.getRequiredShadowMemory(
+ self.info['shadow_memory'] * 1024,
+ self.info['maxmem'] * 1024)
+
+ # Round shadow up to a multiple of a MiB, as shadow_mem_control
+ # takes MiB and we must not round down and end up under-providing.
+ shadow = ((shadow + 1023) / 1024) * 1024
+
# set memory limit
- maxmem = self.image.getRequiredMemory(self.info['maxmem'] * 1024)
xc.domain_setmaxmem(self.domid, maxmem)
- mem_kb = self.image.getRequiredMemory(self.info['memory'] * 1024)
-
- # get the domain's shadow memory requirement
- shadow_kb = self.image.getRequiredShadowMemory(mem_kb)
- shadow_kb_req = self.info['shadow_memory'] * 1024
- if shadow_kb_req > shadow_kb:
- shadow_kb = shadow_kb_req
- shadow_mb = (shadow_kb + 1023) / 1024
-
# Make sure there's enough RAM available for the domain
- balloon.free(mem_kb + shadow_mb * 1024)
+ balloon.free(memory + shadow)
# Set up the shadow memory
- shadow_cur = xc.shadow_mem_control(self.domid, shadow_mb)
+ shadow_cur = xc.shadow_mem_control(self.domid, shadow / 1024)
self.info['shadow_memory'] = shadow_cur
- # initial memory allocation
- xc.domain_memory_increase_reservation(self.domid, mem_kb, 0, 0)
+ # initial memory reservation
+ xc.domain_memory_increase_reservation(self.domid, reservation, 0,
+ 0)
self.createChannels()
@@ -1484,6 +1503,19 @@ class XendDomainInfo:
self.image.createDeviceModel()
## public:
+
+ def checkLiveMigrateMemory(self):
+ """ Make sure there's enough memory to migrate this domain """
+ overhead_kb = 0
+ if arch.type == "x86":
+ # 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than
+ # the minimum that Xen would allocate if no value were given.
+ overhead_kb = self.info['vcpus'] * 1024 + self.info['maxmem'] * 4
+ overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
+ # The domain might already have some shadow memory
+ overhead_kb -= xc.shadow_mem_control(self.domid) * 1024
+ if overhead_kb > 0:
+ balloon.free(overhead_kb)
def testMigrateDevices(self, network, dst):
""" Notify all device about intention of migration
diff -r 5791030e6473 -r 3bed37b2c599 tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/python/xen/xend/image.py Sun Sep 10 14:52:57 2006 -0600
@@ -143,12 +143,27 @@ class ImageHandler:
raise VmError('Building domain failed: ostype=%s dom=%d err=%s'
% (self.ostype, self.vm.getDomid(), str(result)))
- def getRequiredMemory(self, mem_kb):
+ def getRequiredAvailableMemory(self, mem_kb):
+ """@param mem_kb The configured maxmem or memory, in KiB.
+ @return The corresponding required amount of memory for the domain,
+ also in KiB. This is normally the given mem_kb, but architecture- or
+ image-specific code may override this to add headroom where
+ necessary."""
return mem_kb
- def getRequiredShadowMemory(self, mem_kb):
- """@return The minimum shadow memory required, in KiB, for a domain
- with mem_kb KiB of RAM."""
+ def getRequiredInitialReservation(self, mem_kb):
+ """@param mem_kb The configured memory, in KiB.
+ @return The corresponding required amount of memory to be free, also
+ in KiB. This is normally the same as getRequiredAvailableMemory, but
+ architecture- or image-specific code may override this to
+ add headroom where necessary."""
+ return self.getRequiredAvailableMemory(mem_kb)
+
+ def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+ """@param shadow_mem_kb The configured shadow memory, in KiB.
+ @param maxmem_kb The configured maxmem, in KiB.
+ @return The corresponding required amount of shadow memory, also in
+ KiB."""
# PV domains don't need any shadow memory
return 0
@@ -418,7 +433,7 @@ class IA64_HVM_ImageHandler(HVMImageHand
ostype = "hvm"
- def getRequiredMemory(self, mem_kb):
+ def getRequiredAvailableMemory(self, mem_kb):
page_kb = 16
# ROM size for guest firmware, ioreq page and xenstore page
extra_pages = 1024 + 2
@@ -432,19 +447,29 @@ class X86_HVM_ImageHandler(HVMImageHandl
ostype = "hvm"
- def getRequiredMemory(self, mem_kb):
+ def getRequiredAvailableMemory(self, mem_kb):
+ # Add 8 MiB overhead for QEMU's video RAM.
+ return self.getRequiredInitialReservation(mem_kb) + 8192
+
+ def getRequiredInitialReservation(self, mem_kb):
page_kb = 4
# This was derived emperically:
- # 2.4 MB overhead per 1024 MB RAM + 8 MB constant
+ # 2.4 MB overhead per 1024 MB RAM
# + 4 to avoid low-memory condition
- extra_mb = (2.4/1024) * (mem_kb/1024.0) + 12;
+ extra_mb = (2.4/1024) * (mem_kb/1024.0) + 4;
extra_pages = int( math.ceil( extra_mb*1024 / page_kb ))
return mem_kb + extra_pages * page_kb
- def getRequiredShadowMemory(self, mem_kb):
+ def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb):
+ # The given value is the configured value -- we need to include the
+ # overhead due to getRequiredInitialReservation.
+ maxmem_kb = self.getRequiredInitialReservation(maxmem_kb)
+
# 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than
# the minimum that Xen would allocate if no value were given.
- return 1024 * self.vm.getVCpuCount() + mem_kb / 256
+ return max(1024 * self.vm.getVCpuCount() + maxmem_kb / 256,
+ shadow_mem_kb)
+
_handlers = {
"powerpc": {
diff -r 5791030e6473 -r 3bed37b2c599 tools/python/xen/xend/server/pciquirk.py
--- a/tools/python/xen/xend/server/pciquirk.py Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/python/xen/xend/server/pciquirk.py Sun Sep 10 14:52:57 2006 -0600
@@ -1,5 +1,5 @@ from xen.xend.XendLogging import log
from xen.xend.XendLogging import log
-from xen.xend.XendError import XendError
+from xen.xend.XendError import XendError, VmError
import sys
import os.path
from xen.xend.sxp import *
diff -r 5791030e6473 -r 3bed37b2c599 tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/python/xen/xm/create.py Sun Sep 10 14:52:57 2006 -0600
@@ -1169,6 +1169,9 @@ def main(argv):
if not opts:
return
+ if type(config) == str:
+ config = sxp.parse(file(config))[0]
+
if opts.vals.dryrun:
PrettyPrint.prettyprint(config)
else:
diff -r 5791030e6473 -r 3bed37b2c599 tools/python/xen/xm/tests/test_create.py
--- a/tools/python/xen/xm/tests/test_create.py Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/python/xen/xm/tests/test_create.py Sun Sep 10 14:52:57 2006 -0600
@@ -51,6 +51,7 @@ class test_create(unittest.TestCase):
'path' : '.:/etc/xen',
'builder' : 'linux',
'nics' : -1,
+ 'vncunused' : 1,
'xauthority': xen.xm.create.get_xauthority(),
})
@@ -101,6 +102,7 @@ on_crash = 'destroy'
'path' : '.:/etc/xen',
'builder' : 'linux',
+ 'vncunused' : 1,
'xauthority' : xen.xm.create.get_xauthority(),
})
@@ -140,6 +142,7 @@ cpu_weight = 0.75
'builder' : 'linux',
'nics' : -1,
+ 'vncunused' : 1,
'xauthority' : xen.xm.create.get_xauthority(),
})
@@ -182,6 +185,7 @@ ne2000=0
xen.xm.create.VNC_BASE_PORT +
xen.xm.create.choose_vnc_display())),
'vnc' : 1,
+ 'vncunused' : 1,
'vncviewer' : 1,
'xm_file' : fname,
diff -r 5791030e6473 -r 3bed37b2c599 tools/xenmon/xenmon.py
--- a/tools/xenmon/xenmon.py Sun Sep 10 14:31:54 2006 -0600
+++ b/tools/xenmon/xenmon.py Sun Sep 10 14:52:57 2006 -0600
@@ -672,6 +672,9 @@ def main():
parser = setup_cmdline_parser()
(options, args) = parser.parse_args()
+ if options.mspersample < 0:
+ parser.error("option --ms_per_sample: invalid negative value: '%d'" %
+ options.mspersample)
start_xenbaked()
if options.live:
diff -r 5791030e6473 -r 3bed37b2c599
unmodified_drivers/linux-2.6/platform-pci/platform-pci.c
--- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Sun Sep 10
14:31:54 2006 -0600
+++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c Sun Sep 10
14:52:57 2006 -0600
@@ -17,6 +17,7 @@
* Place - Suite 330, Boston, MA 02111-1307 USA.
*
*/
+
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -25,6 +26,8 @@
#include <linux/init.h>
#include <linux/version.h>
#include <linux/interrupt.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -47,7 +50,6 @@ MODULE_DESCRIPTION("Xen platform PCI dev
MODULE_DESCRIPTION("Xen platform PCI device");
MODULE_LICENSE("GPL");
-
unsigned long *phys_to_machine_mapping;
EXPORT_SYMBOL(phys_to_machine_mapping);
@@ -118,7 +120,7 @@ unsigned long alloc_xen_mmio(unsigned lo
/* Lifted from hvmloader.c */
static int get_hypercall_stubs(void)
{
- uint32_t eax, ebx, ecx, edx, pages, msr, order, i;
+ uint32_t eax, ebx, ecx, edx, pages, msr, i;
char signature[13];
cpuid(0x40000000, &eax, &ebx, &ecx, &edx);
@@ -141,22 +143,22 @@ static int get_hypercall_stubs(void)
cpuid(0x40000002, &pages, &msr, &ecx, &edx);
- i = pages - 1;
- for (order = 0; i != 0; order++)
- i >>= 1;
-
- printk(KERN_INFO "Hypercall area is %u pages (order %u allocation)\n",
- pages, order);
-
- hypercall_stubs = (void *)__get_free_pages(GFP_KERNEL, order);
+ printk(KERN_INFO "Hypercall area is %u pages.\n", pages);
+
+ /* Use __vmalloc() because vmalloc_exec() is not an exported symbol. */
+ /* PAGE_KERNEL_EXEC also is not exported, hence we use PAGE_KERNEL. */
+ /* hypercall_stubs = vmalloc_exec(pages * PAGE_SIZE); */
+ hypercall_stubs = __vmalloc(pages * PAGE_SIZE,
+ GFP_KERNEL | __GFP_HIGHMEM,
+ __pgprot(__PAGE_KERNEL & ~_PAGE_NX));
if (hypercall_stubs == NULL)
return -ENOMEM;
- for (i = 0; i < pages; i++)
- wrmsrl(ebx,
- virt_to_phys(hypercall_stubs) + /* base address */
- (i << PAGE_SHIFT) + /* offset of page @i */
- i); /* request page @i */
+ for (i = 0; i < pages; i++) {
+ unsigned long pfn;
+ pfn = vmalloc_to_pfn((char *)hypercall_stubs + i*PAGE_SIZE);
+ wrmsrl(msr, ((u64)pfn << PAGE_SHIFT) + i);
+ }
return 0;
}
diff -r 5791030e6473 -r 3bed37b2c599 xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c Sun Sep 10 14:31:54 2006 -0600
+++ b/xen/arch/x86/mm/shadow/multi.c Sun Sep 10 14:52:57 2006 -0600
@@ -1792,8 +1792,10 @@ void sh_install_xen_entries_in_l2h(struc
for ( i = 0; i < MACHPHYS_MBYTES>>1; i++ )
{
sl2e[shadow_l2_table_offset(RO_MPT_VIRT_START) + i] =
- shadow_l2e_from_mfn(_mfn(l3e_get_pfn(p2m[i])),
- __PAGE_HYPERVISOR);
+ (l3e_get_flags(p2m[i]) & _PAGE_PRESENT)
+ ? shadow_l2e_from_mfn(_mfn(l3e_get_pfn(p2m[i])),
+ __PAGE_HYPERVISOR)
+ : shadow_l2e_empty();
}
sh_unmap_domain_page(p2m);
}
diff -r 5791030e6473 -r 3bed37b2c599 xen/common/grant_table.c
--- a/xen/common/grant_table.c Sun Sep 10 14:31:54 2006 -0600
+++ b/xen/common/grant_table.c Sun Sep 10 14:52:57 2006 -0600
@@ -90,11 +90,8 @@ __gnttab_map_grant_ref(
unsigned long frame = 0;
int rc = GNTST_okay;
struct active_grant_entry *act;
-
- /* Entry details from @rd's shared grant table. */
grant_entry_t *sha;
- domid_t sdom;
- u16 sflags;
+ union grant_combo scombo, prev_scombo, new_scombo;
/*
* We bound the number of times we retry CMPXCHG on memory locations that
@@ -159,7 +156,10 @@ __gnttab_map_grant_ref(
memcpy(new_mt, lgt->maptrack, PAGE_SIZE << lgt->maptrack_order);
for ( i = lgt->maptrack_limit; i < (lgt->maptrack_limit << 1); i++ )
+ {
new_mt[i].ref = i+1;
+ new_mt[i].flags = 0;
+ }
free_xenheap_pages(lgt->maptrack, lgt->maptrack_order);
lgt->maptrack = new_mt;
@@ -175,12 +175,19 @@ __gnttab_map_grant_ref(
spin_lock(&rd->grant_table->lock);
+ /* If already pinned, check the active domid and avoid refcnt overflow. */
+ if ( act->pin &&
+ ((act->domid != ld->domain_id) ||
+ (act->pin & 0x80808080U) != 0) )
+ PIN_FAIL(unlock_out, GNTST_general_error,
+ "Bad domain (%d != %d), or risk of counter overflow %08x\n",
+ act->domid, ld->domain_id, act->pin);
+
if ( !act->pin ||
(!(op->flags & GNTMAP_readonly) &&
!(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask))) )
{
- sflags = sha->flags;
- sdom = sha->domid;
+ scombo.word = *(u32 *)&sha->flags;
/*
* This loop attempts to set the access (reading/writing) flags
@@ -190,33 +197,29 @@ __gnttab_map_grant_ref(
*/
for ( ; ; )
{
- union grant_combo scombo, prev_scombo, new_scombo;
-
- if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access) ||
- unlikely(sdom != led->domain->domain_id) )
- PIN_FAIL(unlock_out, GNTST_general_error,
- "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
- sflags, sdom, led->domain->domain_id);
-
- /* Merge two 16-bit values into a 32-bit combined update. */
- scombo.shorts.flags = sflags;
- scombo.shorts.domid = sdom;
-
+ /* If not already pinned, check the grant domid and type. */
+ if ( !act->pin &&
+ (((scombo.shorts.flags & GTF_type_mask) !=
+ GTF_permit_access) ||
+ (scombo.shorts.domid != ld->domain_id)) )
+ PIN_FAIL(unlock_out, GNTST_general_error,
+ "Bad flags (%x) or dom (%d). (expected dom %d)\n",
+ scombo.shorts.flags, scombo.shorts.domid,
+ ld->domain_id);
+
new_scombo = scombo;
new_scombo.shorts.flags |= GTF_reading;
if ( !(op->flags & GNTMAP_readonly) )
{
new_scombo.shorts.flags |= GTF_writing;
- if ( unlikely(sflags & GTF_readonly) )
+ if ( unlikely(scombo.shorts.flags & GTF_readonly) )
PIN_FAIL(unlock_out, GNTST_general_error,
"Attempt to write-pin a r/o grant entry.\n");
}
prev_scombo.word = cmpxchg((u32 *)&sha->flags,
scombo.word, new_scombo.word);
-
- /* Did the combined update work (did we see what we expected?). */
if ( likely(prev_scombo.word == scombo.word) )
break;
@@ -224,20 +227,15 @@ __gnttab_map_grant_ref(
PIN_FAIL(unlock_out, GNTST_general_error,
"Shared grant entry is unstable.\n");
- /* Didn't see what we expected. Split out the seen flags & dom. */
- sflags = prev_scombo.shorts.flags;
- sdom = prev_scombo.shorts.domid;
+ scombo = prev_scombo;
}
if ( !act->pin )
{
- act->domid = sdom;
+ act->domid = scombo.shorts.domid;
act->frame = gmfn_to_mfn(rd, sha->frame);
}
}
- else if ( (act->pin & 0x80808080U) != 0 )
- PIN_FAIL(unlock_out, ENOSPC,
- "Risk of counter overflow %08x\n", act->pin);
if ( op->flags & GNTMAP_device_map )
act->pin += (op->flags & GNTMAP_readonly) ?
@@ -545,9 +543,7 @@ gnttab_prepare_for_transfer(
{
struct grant_table *rgt;
struct grant_entry *sha;
- domid_t sdom;
- u16 sflags;
- union grant_combo scombo, prev_scombo, tmp_scombo;
+ union grant_combo scombo, prev_scombo, new_scombo;
int retries = 0;
if ( unlikely((rgt = rd->grant_table) == NULL) ||
@@ -562,29 +558,24 @@ gnttab_prepare_for_transfer(
sha = &rgt->shared[ref];
- sflags = sha->flags;
- sdom = sha->domid;
+ scombo.word = *(u32 *)&sha->flags;
for ( ; ; )
{
- if ( unlikely(sflags != GTF_accept_transfer) ||
- unlikely(sdom != ld->domain_id) )
+ if ( unlikely(scombo.shorts.flags != GTF_accept_transfer) ||
+ unlikely(scombo.shorts.domid != ld->domain_id) )
{
DPRINTK("Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
- sflags, sdom, ld->domain_id);
+ scombo.shorts.flags, scombo.shorts.domid,
+ ld->domain_id);
goto fail;
}
- /* Merge two 16-bit values into a 32-bit combined update. */
- scombo.shorts.flags = sflags;
- scombo.shorts.domid = sdom;
-
- tmp_scombo = scombo;
- tmp_scombo.shorts.flags |= GTF_transfer_committed;
+ new_scombo = scombo;
+ new_scombo.shorts.flags |= GTF_transfer_committed;
+
prev_scombo.word = cmpxchg((u32 *)&sha->flags,
- scombo.word, tmp_scombo.word);
-
- /* Did the combined update work (did we see what we expected?). */
+ scombo.word, new_scombo.word);
if ( likely(prev_scombo.word == scombo.word) )
break;
@@ -594,9 +585,7 @@ gnttab_prepare_for_transfer(
goto fail;
}
- /* Didn't see what we expected. Split out the seen flags & dom. */
- sflags = prev_scombo.shorts.flags;
- sdom = prev_scombo.shorts.domid;
+ scombo = prev_scombo;
}
spin_unlock(&rgt->lock);
@@ -734,16 +723,21 @@ __release_grant_for_copy(
gnttab_mark_dirty(rd, r_frame);
spin_lock(&rd->grant_table->lock);
+
if ( readonly )
+ {
act->pin -= GNTPIN_hstr_inc;
+ }
else
+ {
act->pin -= GNTPIN_hstw_inc;
-
- if ( !(act->pin & GNTPIN_hstw_mask) && !readonly )
- gnttab_clear_flag(_GTF_writing, &sha->flags);
+ if ( !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask)) )
+ gnttab_clear_flag(_GTF_writing, &sha->flags);
+ }
if ( !act->pin )
gnttab_clear_flag(_GTF_reading, &sha->flags);
+
spin_unlock(&rd->grant_table->lock);
}
@@ -759,8 +753,7 @@ __acquire_grant_for_copy(
struct active_grant_entry *act;
s16 rc = GNTST_okay;
int retries = 0;
- u16 sflags;
- domid_t sdom;
+ union grant_combo scombo, prev_scombo, new_scombo;
if ( unlikely(gref >= NR_GRANT_ENTRIES) )
PIN_FAIL(error_out, GNTST_bad_gntref,
@@ -771,36 +764,42 @@ __acquire_grant_for_copy(
spin_lock(&rd->grant_table->lock);
+ /* If already pinned, check the active domid and avoid refcnt overflow. */
+ if ( act->pin &&
+ ((act->domid != current->domain->domain_id) ||
+ (act->pin & 0x80808080U) != 0) )
+ PIN_FAIL(unlock_out, GNTST_general_error,
+ "Bad domain (%d != %d), or risk of counter overflow %08x\n",
+ act->domid, current->domain->domain_id, act->pin);
+
if ( !act->pin ||
- (!readonly && !(act->pin & GNTPIN_hstw_mask)) )
- {
- sflags = sha->flags;
- sdom = sha->domid;
+ (!readonly && !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) )
+ {
+ scombo.word = *(u32 *)&sha->flags;
for ( ; ; )
{
- union grant_combo scombo, prev_scombo, new_scombo;
-
- if ( unlikely((sflags & GTF_type_mask) != GTF_permit_access ||
- sdom != current->domain->domain_id ) )
- PIN_FAIL(unlock_out, GNTST_general_error,
- "Bad flags (%x) or dom (%d). (NB. expected dom %d)\n",
- sflags, sdom, current->domain->domain_id);
-
- /* Merge two 16-bit values into a 32-bit combined update. */
- scombo.shorts.flags = sflags;
- scombo.shorts.domid = sdom;
-
+ /* If not already pinned, check the grant domid and type. */
+ if ( !act->pin &&
+ (((scombo.shorts.flags & GTF_type_mask) !=
+ GTF_permit_access) ||
+ (scombo.shorts.domid != current->domain->domain_id)) )
+ PIN_FAIL(unlock_out, GNTST_general_error,
+ "Bad flags (%x) or dom (%d). (expected dom %d)\n",
+ scombo.shorts.flags, scombo.shorts.domid,
+ current->domain->domain_id);
+
new_scombo = scombo;
new_scombo.shorts.flags |= GTF_reading;
if ( !readonly )
{
new_scombo.shorts.flags |= GTF_writing;
- if ( unlikely(sflags & GTF_readonly) )
+ if ( unlikely(scombo.shorts.flags & GTF_readonly) )
PIN_FAIL(unlock_out, GNTST_general_error,
"Attempt to write-pin a r/o grant entry.\n");
}
+
prev_scombo.word = cmpxchg((u32 *)&sha->flags,
scombo.word, new_scombo.word);
if ( likely(prev_scombo.word == scombo.word) )
@@ -809,19 +808,16 @@ __acquire_grant_for_copy(
if ( retries++ == 4 )
PIN_FAIL(unlock_out, GNTST_general_error,
"Shared grant entry is unstable.\n");
- sflags = prev_scombo.shorts.flags;
- sdom = prev_scombo.shorts.flags;
+
+ scombo = prev_scombo;
}
if ( !act->pin )
{
- act->domid = sdom;
+ act->domid = scombo.shorts.domid;
act->frame = gmfn_to_mfn(rd, sha->frame);
}
}
- else if ( (act->pin & 0x80808080U) != 0 )
- PIN_FAIL(unlock_out, ENOSPC,
- "Risk of counter overflow %08x\n", act->pin);
act->pin += readonly ? GNTPIN_hstr_inc : GNTPIN_hstw_inc;
diff -r 5791030e6473 -r 3bed37b2c599 xen/include/asm-x86/bitops.h
--- a/xen/include/asm-x86/bitops.h Sun Sep 10 14:31:54 2006 -0600
+++ b/xen/include/asm-x86/bitops.h Sun Sep 10 14:52:57 2006 -0600
@@ -6,14 +6,6 @@
*/
#include <xen/config.h>
-
-/*
- * These have to be done with inline assembly: that way the bit-setting
- * is guaranteed to be atomic. All bit operations return 0 if the bit
- * was cleared before the operation and != 0 if it was not.
- *
- * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
- */
#ifdef CONFIG_SMP
#define LOCK_PREFIX "lock ; "
@@ -21,6 +13,13 @@
#define LOCK_PREFIX ""
#endif
+/*
+ * We use the "+m" constraint because the memory operand is both read from
+ * and written to. Since the operand is in fact a word array, we also
+ * specify "memory" in the clobbers list to indicate that words other than
+ * the one directly addressed by the memory operand may be modified.
+ */
+
#define ADDR (*(volatile long *) addr)
/**
@@ -37,8 +36,8 @@ static __inline__ void set_bit(int nr, v
{
__asm__ __volatile__( LOCK_PREFIX
"btsl %1,%0"
- :"=m" (ADDR)
- :"dIr" (nr));
+ :"+m" (ADDR)
+ :"dIr" (nr) : "memory");
}
/**
@@ -54,8 +53,8 @@ static __inline__ void __set_bit(int nr,
{
__asm__(
"btsl %1,%0"
- :"=m" (ADDR)
- :"dIr" (nr));
+ :"+m" (ADDR)
+ :"dIr" (nr) : "memory");
}
/**
@@ -72,8 +71,8 @@ static __inline__ void clear_bit(int nr,
{
__asm__ __volatile__( LOCK_PREFIX
"btrl %1,%0"
- :"=m" (ADDR)
- :"dIr" (nr));
+ :"+m" (ADDR)
+ :"dIr" (nr) : "memory");
}
/**
@@ -89,8 +88,8 @@ static __inline__ void __clear_bit(int n
{
__asm__(
"btrl %1,%0"
- :"=m" (ADDR)
- :"dIr" (nr));
+ :"+m" (ADDR)
+ :"dIr" (nr) : "memory");
}
#define smp_mb__before_clear_bit() barrier()
@@ -109,8 +108,8 @@ static __inline__ void __change_bit(int
{
__asm__ __volatile__(
"btcl %1,%0"
- :"=m" (ADDR)
- :"dIr" (nr));
+ :"+m" (ADDR)
+ :"dIr" (nr) : "memory");
}
/**
@@ -126,8 +125,8 @@ static __inline__ void change_bit(int nr
{
__asm__ __volatile__( LOCK_PREFIX
"btcl %1,%0"
- :"=m" (ADDR)
- :"dIr" (nr));
+ :"+m" (ADDR)
+ :"dIr" (nr) : "memory");
}
/**
@@ -144,7 +143,7 @@ static __inline__ int test_and_set_bit(i
__asm__ __volatile__( LOCK_PREFIX
"btsl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
+ :"=r" (oldbit),"+m" (ADDR)
:"dIr" (nr) : "memory");
return oldbit;
}
@@ -164,8 +163,8 @@ static __inline__ int __test_and_set_bit
__asm__(
"btsl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr));
+ :"=r" (oldbit),"+m" (ADDR)
+ :"dIr" (nr) : "memory");
return oldbit;
}
@@ -183,7 +182,7 @@ static __inline__ int test_and_clear_bit
__asm__ __volatile__( LOCK_PREFIX
"btrl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
+ :"=r" (oldbit),"+m" (ADDR)
:"dIr" (nr) : "memory");
return oldbit;
}
@@ -203,8 +202,8 @@ static __inline__ int __test_and_clear_b
__asm__(
"btrl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
- :"dIr" (nr));
+ :"=r" (oldbit),"+m" (ADDR)
+ :"dIr" (nr) : "memory");
return oldbit;
}
@@ -215,7 +214,7 @@ static __inline__ int __test_and_change_
__asm__ __volatile__(
"btcl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
+ :"=r" (oldbit),"+m" (ADDR)
:"dIr" (nr) : "memory");
return oldbit;
}
@@ -234,7 +233,7 @@ static __inline__ int test_and_change_bi
__asm__ __volatile__( LOCK_PREFIX
"btcl %2,%1\n\tsbbl %0,%0"
- :"=r" (oldbit),"=m" (ADDR)
+ :"=r" (oldbit),"+m" (ADDR)
:"dIr" (nr) : "memory");
return oldbit;
}
@@ -242,7 +241,7 @@ static __inline__ int test_and_change_bi
static __inline__ int constant_test_bit(int nr, const volatile void * addr)
{
- return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr
>> 5])) != 0;
+ return ((1U << (nr & 31)) & (((const volatile unsigned int *) addr)[nr
>> 5])) != 0;
}
static __inline__ int variable_test_bit(int nr, volatile void * addr)
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|