mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
merge with xen-unstable.hg
This commit is contained in:
commit
fc81946a2c
21 files changed
+339
-193
No files matched your search
+4
-3
@@ -432,7 +432,6 @@ bug report.
|
||||
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>
|
||||
|
||||
|
||||
+44
-12
@@ -1654,26 +1654,58 @@ Now unmount (this is important!):
|
||||
|
||||
In the configuration file set:
|
||||
\begin{quote}
|
||||
\verb_disk = ['file:/full/path/to/vm1disk,sda1,w']_
|
||||
\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.
|
||||
|
||||
{\bf Note that file-backed VBDs may not be appropriate for backing
|
||||
I/O-intensive domains.} File-backed VBDs are known to experience
|
||||
{\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}
|
||||
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}).
|
||||
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).
|
||||
|
||||
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.
|
||||
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}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -110,24 +110,26 @@ static irqreturn_t handle_input(int irq, void *unused, struct pt_regs *regs)
|
||||
|
||||
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();
|
||||
|
||||
@@ -427,6 +427,14 @@ static int connect_rings(struct backend_info *be)
|
||||
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) {
|
||||
|
||||
@@ -237,6 +237,25 @@ static uint32_t gen_cksum(char *ptr, int len)
|
||||
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)
|
||||
{
|
||||
struct tdqcow_state *s = (struct tdqcow_state *)bs->private;
|
||||
@@ -1204,12 +1223,14 @@ int qcow_create(const char *filename, uint64_t total_size,
|
||||
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",
|
||||
|
||||
@@ -127,18 +127,15 @@ void sig_handler(int sig)
|
||||
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_state *s)
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -48,6 +48,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
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
@@ -49,6 +49,7 @@ from xen.xend.xenstore.xstransact import xstransact, complete
|
||||
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()
|
||||
|
||||
@@ -1485,6 +1504,19 @@ class XendDomainInfo:
|
||||
|
||||
## 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
|
||||
@raise: XendError for a device that cannot be migrated
|
||||
|
||||
@@ -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(HVMImageHandler):
|
||||
|
||||
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(HVMImageHandler):
|
||||
|
||||
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": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 *
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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_AUTHOR("ssmith@xensource.com");
|
||||
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 long len)
|
||||
/* 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.\n", pages);
|
||||
|
||||
printk(KERN_INFO "Hypercall area is %u pages (order %u allocation)\n",
|
||||
pages, order);
|
||||
|
||||
hypercall_stubs = (void *)__get_free_pages(GFP_KERNEL, order);
|
||||
/* 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;
|
||||
}
|
||||
|
||||
@@ -1792,8 +1792,10 @@ void sh_install_xen_entries_in_l2h(struct vcpu *v,
|
||||
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);
|
||||
}
|
||||
|
||||
+71
-75
@@ -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 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);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
new_scombo = scombo;
|
||||
new_scombo.shorts.flags |= GTF_transfer_committed;
|
||||
|
||||
tmp_scombo = scombo;
|
||||
tmp_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 ( readonly )
|
||||
{
|
||||
act->pin -= GNTPIN_hstr_inc;
|
||||
}
|
||||
else
|
||||
{
|
||||
act->pin -= GNTPIN_hstw_inc;
|
||||
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)) )
|
||||
(!readonly && !(act->pin & (GNTPIN_devw_mask|GNTPIN_hstw_mask))) )
|
||||
{
|
||||
sflags = sha->flags;
|
||||
sdom = sha->domid;
|
||||
scombo.word = *(u32 *)&sha->flags;
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
union grant_combo scombo, prev_scombo, new_scombo;
|
||||
/* 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);
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
|
||||
@@ -7,20 +7,19 @@
|
||||
|
||||
#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 ; "
|
||||
#else
|
||||
#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, volatile void * addr)
|
||||
{
|
||||
__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, volatile void * addr)
|
||||
{
|
||||
__asm__(
|
||||
"btsl %1,%0"
|
||||
:"=m" (ADDR)
|
||||
:"dIr" (nr));
|
||||
:"+m" (ADDR)
|
||||
:"dIr" (nr) : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -72,8 +71,8 @@ static __inline__ void clear_bit(int nr, volatile void * addr)
|
||||
{
|
||||
__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 nr, volatile void * addr)
|
||||
{
|
||||
__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 nr, volatile void * addr)
|
||||
{
|
||||
__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, volatile void * addr)
|
||||
{
|
||||
__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(int nr, volatile void * addr)
|
||||
|
||||
__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(int nr, volatile void * addr)
|
||||
|
||||
__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(int nr, volatile void * addr)
|
||||
|
||||
__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_bit(int nr, volatile void * addr)
|
||||
|
||||
__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_bit(int nr, volatile void * addr)
|
||||
|
||||
__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_bit(int nr, volatile void * addr)
|
||||
|
||||
__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_bit(int nr, volatile void * addr)
|
||||
|
||||
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)
|
||||
|
||||