merge with xen-unstable.hg

This commit is contained in:
awilliam@xenbuild.aw committed 2006-04-11 18:54:18 -06:00
commit b4fa7c40e9
327 files changed
+7773 -4486

No files matched your search

+1
View File
@@ -14,3 +14,4 @@ fb875591fd72e15c31879c0e9034d99b80225595 RELEASE-2.0.4
3d330e41f41ce1bc118c02346e18949ad5d67f6b split-1.1
c8fdb0caa77b429cf47f9707926e83947778cb48 RELEASE-3.0.0
af0573e9e5258db0a9d28aa954dd302ddd2c2d23 3.0.2-rc
d0d3fef37685be264a7f52201f8ef44c030daad3 3.0.2-branched
+1
View File
@@ -24,6 +24,7 @@ OBJCOPY = $(CROSS_COMPILE)objcopy
OBJDUMP = $(CROSS_COMPILE)objdump
DISTDIR ?= $(XEN_ROOT)/dist
DESTDIR ?= /
INSTALL = install
INSTALL_DIR = $(INSTALL) -d -m0755
+35 -25
View File
@@ -14,6 +14,7 @@ export XEN_TARGET_ARCH SUBARCH XEN_SYSTYPE
endif
# Default target must appear before any include lines
.PHONY: all
all: dist
XEN_ROOT=$(CURDIR)
@@ -24,12 +25,11 @@ ifeq ($(XEN_TARGET_X86_PAE),y)
export pae=y
endif
.PHONY: all dist install xen kernels tools dev-docs docs world clean
.PHONY: mkpatches mrproper kbuild kdelete kclean
# build and install everything into the standard system directories
.PHONY: install
install: install-xen install-kernels install-tools install-docs
.PHONY: build
build: kernels
$(MAKE) -C xen build
$(MAKE) -C tools build
@@ -38,10 +38,12 @@ build: kernels
# The test target is for unit tests that can run without an installation. Of
# course, many tests require a machine running Xen itself, and these are
# handled elsewhere.
.PHONY: test
test:
$(MAKE) -C tools/python test
# build and install everything into local dist directory
.PHONY: dist
dist: DESTDIR=$(DISTDIR)/install
dist: dist-xen dist-kernels dist-tools dist-docs
$(INSTALL_DIR) $(DISTDIR)/check
@@ -54,79 +56,83 @@ dist-%: install-%
@: # do nothing
# Legacy dist targets
.PHONY: xen tools kernels docs
xen: dist-xen
tools: dist-tools
kernels: dist-kernels
docs: dist-docs
.PHONY: prep-kernels
prep-kernels:
for i in $(XKERNELS) ; do $(MAKE) $$i-prep || exit 1; done
.PHONY: install-xen
install-xen:
$(MAKE) -C xen install
.PHONY: install-tools
install-tools:
$(MAKE) -C tools install
.PHONY: install-kernels
install-kernels:
for i in $(XKERNELS) ; do $(MAKE) $$i-install || exit 1; done
.PHONY: install-docs
install-docs:
sh ./docs/check_pkgs && $(MAKE) -C docs install || true
.PHONY: dev-docs
dev-docs:
$(MAKE) -C docs dev-docs
# Build all the various kernels and modules
.PHONY: kbuild
kbuild: kernels
# Delete the kernel build trees entirely
.PHONY: kdelete
kdelete:
for i in $(XKERNELS) ; do $(MAKE) $$i-delete ; done
# Clean the kernel build trees
.PHONY: kclean
kclean:
for i in $(XKERNELS) ; do $(MAKE) $$i-clean ; done
# Make patches from kernel sparse trees
.PHONY: mkpatches
mkpatches:
for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-xen.patch; done
# build xen, the tools, and a domain 0 plus unprivileged linux-xen images,
# and place them in the install directory. 'make install' should then
# copy them to the normal system directories
.PHONY: world
world:
$(MAKE) clean
$(MAKE) kdelete
$(MAKE) dist
# clean doesn't do a kclean
.PHONY: clean
clean::
$(MAKE) -C xen clean
$(MAKE) -C tools clean
$(MAKE) -C docs clean
# clean, but blow away kernel build tree plus tarballs
.PHONY: distclean
distclean: clean
rm -rf dist patches/tmp
for i in $(ALLKERNELS) ; do $(MAKE) $$i-delete ; done
for i in $(ALLSPARSETREES) ; do $(MAKE) $$i-mrproper ; done
# Linux name for GNU distclean
.PHONY: mrproper
mrproper: distclean
install-logging: LOGGING=logging-0.4.9.2
install-logging:
[ -f $(LOGGING).tar.gz ] || wget http://www.red-dove.com/$(LOGGING).tar.gz
tar -zxf $(LOGGING).tar.gz
cd $(LOGGING) && python setup.py install
# handy target to upgrade iptables (use rpm or apt-get in preference)
install-iptables:
wget http://www.netfilter.org/files/iptables-1.2.11.tar.bz2
tar -jxf iptables-1.2.11.tar.bz2
$(MAKE) -C iptables-1.2.11 PREFIX= KERNEL_DIR=../linux-$(LINUX_VER)-xen0 install
.PHONY: help
help:
@echo 'Installation targets:'
@echo ' install - build and install everything'
@@ -147,25 +153,28 @@ help:
@echo ' dev-docs - build developer-only documentation'
@echo ''
@echo 'Cleaning targets:'
@echo ' clean - clean the Xen, tools and docs (but not'
@echo ' guest kernel) trees'
@echo ' distclean - clean plus delete kernel tarballs and kernel'
@echo ' build trees'
@echo ' clean - clean the Xen, tools and docs (but not guest kernel trees)'
@echo ' distclean - clean plus delete kernel build trees and'
@echo ' local downloaded files'
@echo ' kdelete - delete guest kernel build trees'
@echo ' kclean - clean guest kernel build trees'
@echo ''
@echo 'Dependency installation targets:'
@echo ' install-logging - install the Python Logging package'
@echo ' install-iptables - install iptables tools'
@echo ''
@echo 'Miscellaneous targets:'
@echo ' prep-kernels - prepares kernel directories, does not build'
@echo ' mkpatches - make patches against vanilla kernels from'
@echo ' sparse trees'
@echo ' uninstall - attempt to remove installed Xen tools (use'
@echo ' with extreme care!)'
@echo ' uninstall - attempt to remove installed Xen tools'
@echo ' (use with extreme care!)'
@echo
@echo 'Environment:'
@echo ' XEN_PYTHON_NATIVE_INSTALL=y'
@echo ' - native python install or dist'
@echo ' install into prefix/lib/python<VERSION>'
@echo ' instead of <PREFIX>/lib/python'
@echo ' true if set to non-empty value, false otherwise'
# Use this target with extreme care!
.PHONY: uninstall
uninstall: D=$(DESTDIR)
uninstall:
[ -d $(D)/etc/xen ] && mv -f $(D)/etc/xen $(D)/etc/xen.old-`date +%s` || true
@@ -199,5 +208,6 @@ uninstall:
rm -rf $(D)/usr/share/man/man8/xen*
# Legacy targets for compatibility
.PHONY: linux26
linux26:
$(MAKE) 'KERNELS=linux-2.6*' kernels
+176 -158
View File
@@ -1,158 +1,176 @@
################################
__ __ _____ ___
\ \/ /___ _ __ |___ / / _ \
\ // _ \ '_ \ |_ \| | | |
/ \ __/ | | | ___) | |_| |
/_/\_\___|_| |_| |____(_)___/
################################
http://www.xensource.com/xen/about.html
What is Xen?
============
Xen is a Virtual Machine Monitor (VMM) originally developed by the
Systems Research Group of the University of Cambridge Computer
Laboratory, as part of the UK-EPSRC funded XenoServers project. Xen
is freely-distributable Open Source software, released under the GNU
GPL. Since its initial public release, Xen has grown a large
development community, spearheaded by XenSource Inc, a company created
by the original Xen development team to build enterprise products
around Xen.
The 3.0 release offers excellent performance, hardware support and
enterprise-grade features such as x86_32-PAE, x86_64, SMP guests and
live relocation of VMs. This install tree contains source for a Linux
2.6 guest; ports to Linux 2.4, NetBSD, FreeBSD and Solaris will follow
later (and are already available for previous Xen releases).
This file contains some quick-start instructions to install Xen on
your system. For full documentation, see the Xen User Manual. If this
is a pre-built release then you can find the manual at:
dist/install/usr/share/doc/xen/pdf/user.pdf
If you have a source release, then 'make -C docs' will build the
manual at docs/pdf/user.pdf.
Quick-Start Guide - Pre-Built Binary Release
============================================
[NB. Unless noted otherwise, all the following steps should be
performed with root privileges.]
1. Install the binary distribution onto your filesystem:
# sh ./install.sh
Among other things, this will install Xen and Xen-ready Linux
kernel files in /boot, kernel modules and Python packages in /lib,
and various control tools in standard 'bin' directories.
2. Configure your bootloader to boot Xen and an initial Linux virtual
machine. Note that Xen currently only works with GRUB and pxelinux
derived boot loaders: less common alternatives such as LILO are
*not* supported. You can most likely find your GRUB menu file at
/boot/grub/menu.lst: edit this file to include an entry like the
following:
title Xen 3.0 / XenLinux 2.6
kernel /boot/xen-3.0.gz console=vga
module /boot/vmlinuz-2.6-xen root=<root-dev> ro console=tty0
module /boot/initrd-2.6-xen.img
NB: Not all kernel configs need an initial ram disk (initrd), but
if you do specify one you'll need to use the 'module' grub directive
rather than 'initrd'.
The linux command line takes all the usual options, such as
root=<root-dev> to specify your usual root partition (e.g.,
/dev/hda1).
The Xen command line takes a number of optional arguments described
in the manual. The most common is 'dom0_mem=xxxM' which sets the
amount of memory to allocate for use by your initial virtual
machine (known as domain 0). Note that Xen itself reserves about
32MB memory for internal use, which is not available for allocation
to virtual machines.
3. Reboot your system and select the "Xen 3.0 / XenLinux 2.6" menu
option. After booting Xen, Linux will start and your initialisation
scripts should execute in the usual way.
Quick-Start Guide - Source Release
==================================
First, there are a number of prerequisites for building a Xen source
release. Make sure you have all the following installed, either by
visiting the project webpage or installing a pre-built package
provided by your Linux distributor:
* GCC (preferably v3.2.x or v3.3.x; older versions are unsupported)
* GNU Make
* GNU Binutils
* Development install of zlib (e.g., zlib-dev)
* Development install of Python v2.3 or later (e.g., python-dev)
* bridge-utils package (/sbin/brctl)
* iproute package (/sbin/ip)
* hotplug or udev
[NB. Unless noted otherwise, all the following steps should be
performed with root privileges.]
1. Download and untar the source tarball file. This will be a
file named xen-unstable-src.tgz, or xen-$version-src.tgz.
You can also pull the current version from the SCMS
that is being used (Bitkeeper, scheduled to change shortly).
# tar xzf xen-unstable-src.tgz
Assuming you are using the unstable tree, this will
untar into xen-unstable. The rest of the instructions
use the unstable tree as an example, substitute the
version for unstable.
2. cd to xen-unstable (or whatever you sensibly rename it to).
The Linux, netbsd and freebsd kernel source trees are in
the $os-$version-xen-sparse directories.
On Linux:
3. For the very first build, or if you want to destroy existing
.configs and build trees, perform the following steps:
# make KERNELS=linux-2.6-xen world
# make install
It will create and install into the dist/ directory which is the
default install location. It will build the xen binary (xen.gz),
and a linux kernel and modules that can be used in both dom0 and an
unprivileged guest kernel (vmlinuz-2.6.x-xen), the tools and the
documentation.
If you don't specify KERNELS= on the make command line it will
default to building two kernels, vmlinuz-2.6.x-xen0 and
vmlinuz-2.6.x-xenU. These are smaller builds with just selected
modules, intended primarilly for developers that don't like to wait
for a -xen kernel to build. The -xenU kernel is particularly small
as it does not contain any physical device drivers, and hence is
only useful for guest domains.
If you want to build an x86_32 PAE capable xen and kernel to work
on machines with >= 4GB of memory, use XEN_TARGET_X86_PAE=y on the
make command line.
4. To rebuild an existing tree without modifying the config:
# make dist
This will build and install xen, kernels, tools, and
docs into the local dist/ directory.
5. To rebuild a kernel with a modified config:
# make linux-2.6-xen-config CONFIGMODE=menuconfig (or xconfig)
# make linux-2.6-xen-build
# make linux-2.6-xen-install
Depending on your config, you may need to use 'mkinitrd' to create
an initial ram disk, just like a native system e.g.
# depmod 2.6.12.6-xen
# mkinitrd -v -f --with=aacraid --with=sd_mod --with=scsi_mod initrd-2.6.12.6-xen.img 2.6.12.6-xen
################################
__ __ _____ ___
\ \/ /___ _ __ |___ / / _ \
\ // _ \ '_ \ |_ \| | | |
/ \ __/ | | | ___) | |_| |
/_/\_\___|_| |_| |____(_)___/
################################
http://www.xensource.com/xen/about.html
What is Xen?
============
Xen is a Virtual Machine Monitor (VMM) originally developed by the
Systems Research Group of the University of Cambridge Computer
Laboratory, as part of the UK-EPSRC funded XenoServers project. Xen
is freely-distributable Open Source software, released under the GNU
GPL. Since its initial public release, Xen has grown a large
development community, spearheaded by XenSource Inc, a company created
by the original Xen development team to build enterprise products
around Xen.
The 3.0 release offers excellent performance, hardware support and
enterprise-grade features such as x86_32-PAE, x86_64, SMP guests and
live relocation of VMs. This install tree contains source for a Linux
2.6 guest; ports to Linux 2.4, NetBSD, FreeBSD and Solaris will follow
later (and are already available for previous Xen releases).
This file contains some quick-start instructions to install Xen on
your system. For full documentation, see the Xen User Manual. If this
is a pre-built release then you can find the manual at:
dist/install/usr/share/doc/xen/pdf/user.pdf
If you have a source release, then 'make -C docs' will build the
manual at docs/pdf/user.pdf.
Quick-Start Guide - Pre-Built Binary Release
============================================
[NB. Unless noted otherwise, all the following steps should be
performed with root privileges.]
1. Install the binary distribution onto your filesystem:
# sh ./install.sh
Among other things, this will install Xen and Xen-ready Linux
kernel files in /boot, kernel modules and Python packages in /lib,
and various control tools in standard 'bin' directories.
2. Configure your bootloader to boot Xen and an initial Linux virtual
machine. Note that Xen currently only works with GRUB and pxelinux
derived boot loaders: less common alternatives such as LILO are
*not* supported. You can most likely find your GRUB menu file at
/boot/grub/menu.lst: edit this file to include an entry like the
following:
title Xen 3.0 / XenLinux 2.6
kernel /boot/xen-3.0.gz console=vga
module /boot/vmlinuz-2.6-xen root=<root-dev> ro console=tty0
module /boot/initrd-2.6-xen.img
NB: Not all kernel configs need an initial ram disk (initrd), but
if you do specify one you'll need to use the 'module' grub directive
rather than 'initrd'.
The linux command line takes all the usual options, such as
root=<root-dev> to specify your usual root partition (e.g.,
/dev/hda1).
The Xen command line takes a number of optional arguments described
in the manual. The most common is 'dom0_mem=xxxM' which sets the
amount of memory to allocate for use by your initial virtual
machine (known as domain 0). Note that Xen itself reserves about
32MB memory for internal use, which is not available for allocation
to virtual machines.
3. Reboot your system and select the "Xen 3.0 / XenLinux 2.6" menu
option. After booting Xen, Linux will start and your initialisation
scripts should execute in the usual way.
Quick-Start Guide - Source Release
==================================
First, there are a number of prerequisites for building a Xen source
release. Make sure you have all the following installed, either by
visiting the project webpage or installing a pre-built package
provided by your Linux distributor:
* GCC (preferably v3.2.x or v3.3.x; older versions are unsupported)
* GNU Make
* GNU Binutils
* Development install of zlib (e.g., zlib-dev)
* Development install of Python v2.3 or later (e.g., python-dev)
* bridge-utils package (/sbin/brctl)
* iproute package (/sbin/ip)
* hotplug or udev
[NB. Unless noted otherwise, all the following steps should be
performed with root privileges.]
1. Download and untar the source tarball file. This will be a
file named xen-unstable-src.tgz, or xen-$version-src.tgz.
You can also pull the current version from the SCMS
that is being used (Bitkeeper, scheduled to change shortly).
# tar xzf xen-unstable-src.tgz
Assuming you are using the unstable tree, this will
untar into xen-unstable. The rest of the instructions
use the unstable tree as an example, substitute the
version for unstable.
2. cd to xen-unstable (or whatever you sensibly rename it to).
The Linux, netbsd and freebsd kernel source trees are in
the $os-$version-xen-sparse directories.
On Linux:
3. For the very first build, or if you want to destroy existing
.configs and build trees, perform the following steps:
# make world
# make install
This will create and install onto the local machine. It will build
the xen binary (xen.gz), and a linux kernel and modules that can be
used in both dom0 and an unprivileged guest kernel (vmlinuz-2.6.x-xen),
the tools and the documentation.
You can override the destination for make install by setting DESTDIR
to some value.
The make command line defaults to building the kernel vmlinuz-2.6.x-xen.
You can override this default by specifying KERNELS=kernelname. For
example, you can make two kernels - linux-2.6-xen0
and linux-2.6-xenU - which are smaller builds containing only selected
modules, intended primarily for developers that don't like to wait
for a full -xen kernel to build. The -xenU kernel is particularly small,
as it does not contain any physical device drivers, and hence is
only useful for guest domains.
To make these two kernels, simply specify
KERNELS="linux-2.6-xen0 linux-2.6-xenU"
in the make command line.
If you want to build an x86_32 PAE capable xen and kernel to work
on machines with >= 4GB of memory, use XEN_TARGET_X86_PAE=y on the
make command line.
4. To rebuild an existing tree without modifying the config:
# make dist
This will build and install xen, kernels, tools, and
docs into the local dist/ directory.
You can override the destination for make install by setting DISTDIR
to some value.
make install and make dist differ in that make install does the
right things for your local machine (installing the appropriate
version of hotplug or udev scripts, for example), but make dist
includes all versions of those scripts, so that you can copy the dist
directory to another machine and install from that distribution.
5. To rebuild a kernel with a modified config:
# make linux-2.6-xen-config CONFIGMODE=menuconfig (or xconfig)
# make linux-2.6-xen-build
# make linux-2.6-xen-install
Depending on your config, you may need to use 'mkinitrd' to create
an initial ram disk, just like a native system e.g.
# depmod 2.6.16-xen
# mkinitrd -v -f --with=aacraid --with=sd_mod --with=scsi_mod initrd-2.6.16-xen.img 2.6.16-xen
+5 -35
View File
@@ -6,8 +6,6 @@ export DESTDIR
ALLKERNELS = $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.*))
ALLSPARSETREES = $(patsubst %-xen-sparse,%,$(wildcard *-xen-sparse))
.PHONY: mkpatches mrproper
# Setup pristine search path
PRISTINE_SRC_PATH ?= .:..
vpath pristine-% $(PRISTINE_SRC_PATH)
@@ -40,29 +38,6 @@ patch-%.bz2:
@echo "Cannot find $(@F) in path $(LINUX_SRC_PATH)"
wget $(KERNEL_REPO)/pub/linux/kernel/v$(_LINUX_VDIR)/$(_LINUX_XDIR)/$(@F) -O./$@
# Expand NetBSD release to NetBSD version
NETBSD_RELEASE ?= 2.0
NETBSD_VER ?= $(patsubst netbsd-%-xen-sparse,%,$(wildcard netbsd-$(NETBSD_RELEASE)*-xen-sparse))
NETBSD_CVSSNAP ?= 20050309
# Setup NetBSD search path
NETBSD_SRC_PATH ?= .:..
vpath netbsd-%.tar.bz2 $(NETBSD_SRC_PATH)
# download a pristine NetBSD tarball if there isn't one in NETBSD_SRC_PATH
netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2:
@echo "Cannot find $@ in path $(NETBSD_SRC_PATH)"
wget http://www.cl.cam.ac.uk/Research/SRG/netos/xen/downloads/$@ -O./$@
netbsd-%.tar.bz2: netbsd-%-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2
ln -fs $< $@
ifeq ($(OS),linux)
OS_VER = $(LINUX_VER)
else
OS_VER = $(NETBSD_VER)
endif
pristine-%: pristine-%/.valid-pristine
@true
@@ -84,6 +59,7 @@ ifneq ($(PATCHDIRS),)
$(patsubst patches/%,patches/%/.makedep,$(PATCHDIRS)): patches/%/.makedep:
@echo 'ref-$*/.valid-ref: $$(wildcard patches/$*/*.patch)' >$@
.PHONY: clean
clean::
rm -f patches/*/.makedep
@@ -124,27 +100,21 @@ linux-2.6-xen.patch: ref-linux-$(LINUX_VER)/.valid-ref
rm -rf tmp-$@
cp -al $(<D) tmp-$@
( cd linux-2.6-xen-sparse && ./mkbuildtree ../tmp-$@ )
diff -Nurp $(<D) tmp-$@ > $@ || true
diff -Nurp $(patsubst ref%,pristine%,$(<D)) tmp-$@ > $@ || true
rm -rf tmp-$@
%-xen.patch: ref-%/.valid-ref
rm -rf tmp-$@
cp -al $(<D) tmp-$@
( cd $*-xen-sparse && ./mkbuildtree ../tmp-$@ )
diff -Nurp $(<D) tmp-$@ > $@ || true
diff -Nurp $(patsubst ref%,pristine%,$(<D)) tmp-$@ > $@ || true
rm -rf tmp-$@
%-mrproper: %-mrproper-extra
%-mrproper:
rm -rf pristine-$(*)* ref-$(*)* $*.tar.bz2
rm -rf $*-xen.patch
netbsd-%-mrproper-extra:
rm -rf netbsd-$*-tools netbsd-$*-tools.tar.bz2
rm -f netbsd-$*-xen-kernel-$(NETBSD_CVSSNAP).tar.bz2
%-mrproper-extra:
@: # do nothing
.PHONY: config-update-pae
config-update-pae:
ifeq ($(XEN_TARGET_X86_PAE),y)
sed -e 's!^CONFIG_HIGHMEM4G=y$$!\# CONFIG_HIGHMEM4G is not set!;s!^\# CONFIG_HIGHMEM64G is not set$$!CONFIG_HIGHMEM64G=y!' $(CONFIG_FILE) > $(CONFIG_FILE)- && mv $(CONFIG_FILE)- $(CONFIG_FILE)
+1
View File
@@ -95,6 +95,7 @@ CONFIG_ARCH_XEN=y
CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_XEN_SYSFS=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+18 -10
View File
@@ -1,7 +1,7 @@
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.16-rc3-xen0
# Thu Feb 16 22:52:42 2006
# Linux kernel version: 2.6.16-xen0
# Sat Apr 8 11:34:07 2006
#
CONFIG_X86_32=y
CONFIG_SEMAPHORE_SLEEPERS=y
@@ -208,7 +208,6 @@ CONFIG_ACPI_BLACKLIST_YEAR=0
CONFIG_ACPI_EC=y
CONFIG_ACPI_POWER=y
CONFIG_ACPI_SYSTEM=y
# CONFIG_X86_PM_TIMER is not set
# CONFIG_ACPI_CONTAINER is not set
#
@@ -392,7 +391,13 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Plug and Play support
#
# CONFIG_PNP is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG=y
#
# Protocols
#
CONFIG_PNPACPI=y
#
# Block devices
@@ -440,6 +445,7 @@ CONFIG_BLK_DEV_IDECD=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -623,6 +629,7 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=y
# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
@@ -1064,11 +1071,7 @@ CONFIG_USB_MON=y
# CONFIG_INFINIBAND is not set
#
# SN Devices
#
#
# EDAC - error detection and reporting (RAS)
# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
#
# CONFIG_EDAC is not set
@@ -1231,6 +1234,7 @@ CONFIG_NLS_ISO8859_1=y
#
# Instrumentation Support
#
# CONFIG_PROFILING is not set
# CONFIG_KPROBES is not set
#
@@ -1305,13 +1309,14 @@ CONFIG_CRYPTO_CRC32C=m
#
# CONFIG_CRYPTO_DEV_PADLOCK is not set
CONFIG_XEN=y
CONFIG_NO_IDLE_HZ=y
CONFIG_XEN_INTERFACE_VERSION=0x00030101
#
# XEN
#
CONFIG_XEN_PRIVILEGED_GUEST=y
# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
CONFIG_XEN_BACKEND=y
CONFIG_XEN_PCIDEV_BACKEND=y
# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
CONFIG_XEN_PCIDEV_BACKEND_PASS=y
@@ -1331,6 +1336,7 @@ CONFIG_XEN_DISABLE_SERIAL=y
CONFIG_XEN_SYSFS=y
CONFIG_HAVE_ARCH_ALLOC_SKB=y
CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y
CONFIG_NO_IDLE_HZ=y
#
# Library routines
@@ -1343,4 +1349,6 @@ CONFIG_ZLIB_INFLATE=y
CONFIG_GENERIC_HARDIRQS=y
CONFIG_GENERIC_IRQ_PROBE=y
CONFIG_X86_BIOS_REBOOT=y
CONFIG_X86_NO_TSS=y
CONFIG_X86_NO_IDT=y
CONFIG_KTIME_SCALAR=y
+11 -1
View File
@@ -327,7 +327,13 @@ CONFIG_STANDALONE=y
#
# Plug and Play support
#
# CONFIG_PNP is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG=y
#
# Protocols
#
CONFIG_PNPACPI=y
#
# Block devices
@@ -375,6 +381,7 @@ CONFIG_BLK_DEV_IDECD=y
#
CONFIG_IDE_GENERIC=y
# CONFIG_BLK_DEV_CMD640 is not set
# CONFIG_BLK_DEV_IDEPNP is not set
CONFIG_BLK_DEV_IDEPCI=y
# CONFIG_IDEPCI_SHARE_IRQ is not set
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -559,6 +566,7 @@ CONFIG_NETDEVICES=y
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
CONFIG_TUN=y
# CONFIG_NET_SB1000 is not set
#
# ARCnet devices
@@ -1183,6 +1191,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
CONFIG_FRAME_POINTER=y
@@ -1237,6 +1246,7 @@ CONFIG_NO_IDLE_HZ=y
#
CONFIG_XEN_PRIVILEGED_GUEST=y
# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
CONFIG_XEN_BACKEND=y
CONFIG_XEN_PCIDEV_BACKEND=y
# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
CONFIG_XEN_PCIDEV_BACKEND_PASS=y
+1
View File
@@ -92,6 +92,7 @@ CONFIG_ARCH_XEN=y
CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_XEN_SYSFS=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+2 -5
View File
@@ -779,6 +779,7 @@ CONFIG_NLS_ISO8859_1=y
#
# Instrumentation Support
#
# CONFIG_PROFILING is not set
# CONFIG_KPROBES is not set
#
@@ -858,13 +859,9 @@ CONFIG_NO_IDLE_HZ=y
#
# CONFIG_XEN_PRIVILEGED_GUEST is not set
CONFIG_XEN_UNPRIVILEGED_GUEST=y
# CONFIG_XEN_PCIDEV_BACKEND is not set
# CONFIG_XEN_BLKDEV_BACKEND is not set
# CONFIG_XEN_NETDEV_BACKEND is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
# CONFIG_XEN_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_TPMDEV_FRONTEND is not set
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DISABLE_SERIAL=y
+2 -5
View File
@@ -1080,6 +1080,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
CONFIG_FRAME_POINTER=y
@@ -1134,13 +1135,9 @@ CONFIG_NO_IDLE_HZ=y
#
# CONFIG_XEN_PRIVILEGED_GUEST is not set
CONFIG_XEN_UNPRIVILEGED_GUEST=y
# CONFIG_XEN_PCIDEV_BACKEND is not set
# CONFIG_XEN_BLKDEV_BACKEND is not set
# CONFIG_XEN_NETDEV_BACKEND is not set
# CONFIG_XEN_TPMDEV_BACKEND is not set
# CONFIG_XEN_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_TPMDEV_FRONTEND is not set
CONFIG_XEN_SCRUB_PAGES=y
CONFIG_XEN_DISABLE_SERIAL=y
+1
View File
@@ -95,6 +95,7 @@ CONFIG_ARCH_XEN=y
CONFIG_XEN_PRIVILEGED_GUEST=y
CONFIG_XEN_BLKDEV_GRANT=y
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_BACKEND=y
CONFIG_XEN_BLKDEV_BACKEND=y
CONFIG_XEN_SYSFS=y
CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+7 -5
View File
@@ -292,11 +292,11 @@ CONFIG_NET=y
# Networking options
#
# CONFIG_NETDEBUG is not set
CONFIG_PACKET=m
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=m
CONFIG_UNIX=y
CONFIG_XFRM=y
CONFIG_XFRM_USER=m
CONFIG_XFRM_USER=y
CONFIG_NET_KEY=m
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
@@ -912,12 +912,12 @@ CONFIG_PARPORT_1284=y
# Plug and Play support
#
CONFIG_PNP=y
# CONFIG_PNP_DEBUG is not set
CONFIG_PNP_DEBUG=y
#
# Protocols
#
# CONFIG_PNPACPI is not set
CONFIG_PNPACPI=y
#
# Block devices
@@ -2892,6 +2892,7 @@ CONFIG_NLS_UTF8=m
#
# Instrumentation Support
#
# CONFIG_PROFILING is not set
# CONFIG_KPROBES is not set
#
@@ -2978,6 +2979,7 @@ CONFIG_NO_IDLE_HZ=y
#
CONFIG_XEN_PRIVILEGED_GUEST=y
# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
CONFIG_XEN_BACKEND=y
CONFIG_XEN_PCIDEV_BACKEND=y
# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
CONFIG_XEN_PCIDEV_BACKEND_PASS=y
+11 -1
View File
@@ -776,7 +776,13 @@ CONFIG_PARPORT_1284=y
#
# Plug and Play support
#
# CONFIG_PNP is not set
CONFIG_PNP=y
CONFIG_PNP_DEBUG=y
#
# Protocols
#
CONFIG_PNPACPI=y
#
# Block devices
@@ -857,6 +863,7 @@ CONFIG_BLK_DEV_IDESCSI=m
CONFIG_IDE_GENERIC=y
CONFIG_BLK_DEV_CMD640=y
CONFIG_BLK_DEV_CMD640_ENHANCED=y
CONFIG_BLK_DEV_IDEPNP=y
CONFIG_BLK_DEV_IDEPCI=y
CONFIG_IDEPCI_SHARE_IRQ=y
# CONFIG_BLK_DEV_OFFBOARD is not set
@@ -1088,6 +1095,7 @@ CONFIG_DUMMY=m
CONFIG_BONDING=m
CONFIG_EQUALIZER=m
CONFIG_TUN=m
CONFIG_NET_SB1000=m
#
# ARCnet devices
@@ -2587,6 +2595,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_FRAME_POINTER is not set
@@ -2647,6 +2656,7 @@ CONFIG_NO_IDLE_HZ=y
#
CONFIG_XEN_PRIVILEGED_GUEST=y
# CONFIG_XEN_UNPRIVILEGED_GUEST is not set
CONFIG_XEN_BACKEND=y
CONFIG_XEN_PCIDEV_BACKEND=y
# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set
CONFIG_XEN_PCIDEV_BACKEND_PASS=y
+8 -8
View File
@@ -1,19 +1,15 @@
OS = linux
LINUX_SERIES = 2.6
LINUX_VER = 2.6.16
LINUX_SRCS = linux-2.6.16.tar.bz2
EXTRAVERSION ?= xen
LINUX_DIR = $(OS)-$(LINUX_VER)-$(EXTRAVERSION)
LINUX_DIR = linux-$(LINUX_VER)-$(EXTRAVERSION)
include buildconfigs/Rules.mk
.PHONY: build clean delete
# The real action starts here!
.PHONY: build
build: $(LINUX_DIR)/include/linux/autoconf.h
if grep "^CONFIG_MODULES=" $(LINUX_DIR)/.config ; then \
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) modules ; \
@@ -22,7 +18,7 @@ build: $(LINUX_DIR)/include/linux/autoconf.h
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) vmlinuz
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(DESTDIR) install
$(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
$(LINUX_DIR)/include/linux/autoconf.h: ref-linux-$(LINUX_VER)/.valid-ref
rm -rf $(LINUX_DIR)
cp -al $(<D) $(LINUX_DIR)
# Apply arch-xen patches
@@ -42,14 +38,18 @@ $(LINUX_DIR)/include/linux/autoconf.h: ref-$(OS)-$(LINUX_VER)/.valid-ref
rm -f Makefile ; mv Mk.tmp Makefile )
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) oldconfig
.PHONY: prep
prep: $(LINUX_DIR)/include/linux/autoconf.h
.PHONY: config
config: CONFIGMODE = menuconfig
config: $(LINUX_DIR)/include/linux/autoconf.h
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) $(CONFIGMODE)
.PHONY: clean
clean::
$(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) clean
.PHONY: delete
delete:
rm -rf tmp-$(OS)-$(LINUX_VER) $(LINUX_DIR)
rm -rf tmp-linux-$(LINUX_VER) $(LINUX_DIR)
+11 -2
View File
@@ -26,22 +26,28 @@ DOC_HTML := $(patsubst src/%.tex,html/%/index.html,$(DOC_TEX))
GFX = $(patsubst %.fig, %.eps, $(wildcard figs/*.fig))
.PHONY: all build dev-docs python-dev-docs ps pdf html clean install
.PHONY: all
all: build
.PHONY: build
build: ps pdf html man-pages
rm -f *.aux *.dvi *.bbl *.blg *.glo *.idx *.ilg *.log *.ind *.toc
.PHONY: dev-docs
dev-docs: python-dev-docs
.PHONY: ps
ps: $(DOC_PS)
.PHONY: pdf
pdf: $(DOC_PDF)
.PHONY: html
html:
@if which $(LATEX2HTML) 1>/dev/null 2>/dev/null; then \
$(MAKE) $(DOC_HTML); fi
.PHONY: python-dev-docs
python-dev-docs:
@mkdir -v -p api/tools/python
@if which $(DOXYGEN) 1>/dev/null 2>/dev/null; then \
@@ -50,6 +56,7 @@ python-dev-docs:
$(MAKE) -C api/tools/python/latex ; else \
echo "Doxygen not installed; skipping python-dev-docs."; fi
.PHONY: man-pages
man-pages:
@if which $(POD2MAN) 1>/dev/null 2>/dev/null; then \
$(MAKE) $(DOC_MAN1) $(DOC_MAN5); fi
@@ -64,6 +71,7 @@ man5/%.5: man/%.pod.5 Makefile
$(POD2MAN) --release=$(VERSION) --name=`echo $@ | sed 's/^man5.//'| \
sed 's/.5//'` -s 5 -c "Xen" $< $@
.PHONY: clean
clean:
rm -rf .word_count *.aux *.dvi *.bbl *.blg *.glo *.idx *~
rm -rf *.ilg *.log *.ind *.toc *.bak core
@@ -72,6 +80,7 @@ clean:
rm -rf man5
rm -rf man1
.PHONY: install
install: all
rm -rf $(DESTDIR)$(pkgdocdir)
$(INSTALL_DIR) $(DESTDIR)$(pkgdocdir)
+3 -3
View File
@@ -360,7 +360,7 @@ your Linux Kernel sources.
Moves a domain out of the paused state. This will allow a previously
paused domain to now be eligible for scheduling by the Xen hypervisor.
=item B<set-vcpus> I<domain-id> I<vcpu-count>
=item B<vcpu-set> I<domain-id> I<vcpu-count>
Enables the I<vcpu-count> virtual CPUs for the domain in question.
Like mem-set, this command can only allocate up to the maximum virtual
@@ -370,8 +370,8 @@ If the I<vcpu-count> is smaller than the current number of active
VCPUs, the highest number VCPUs will be hotplug removed. This may be
important for pinning purposes.
Attempting to set-vcpus to a number larger than the initially
configured VCPU count is an error. Trying to set-vcpus to < 1 will be
Attempting to set the VCPUs to a number larger than the initially
configured VCPU count is an error. Trying to set VCPUs to < 1 will be
quietly ignored.
=item B<vcpu-list> I<[domain-id]>
+27 -1
View File
@@ -2052,7 +2052,7 @@ dev86 & The dev86 package provides an assembler and linker for real mode 80x86 i
If the dev86 package is not available on the x86\_64 distribution, you can install the i386 version of it. The dev86 rpm package for various distributions can be found at {\scriptsize {\tt http://www.rpmfind.net/linux/rpm2html/search.php?query=dev86\&submit=Search}} \\
LibVNCServer & The unmodified guest's VGA display, keyboard, and mouse are virtualized using the vncserver library provided by this package. You can get the sources of libvncserver from {\small {\tt http://sourceforge.net/projects/libvncserver}}. Build and install the sources on the build system to get the libvncserver library. The 0.8pre version of libvncserver is currently working well with Xen.\\
LibVNCServer & The unmodified guest's VGA display, keyboard, and mouse can be virtualized by the vncserver library. You can get the sources of libvncserver from {\small {\tt http://sourceforge.net/projects/libvncserver}}. Build and install the sources on the build system to get the libvncserver library. There is a significant performance degradation in 0.8 version. The current sources in the CVS tree have fixed this degradation. So it is highly recommended to download the latest CVS sources and install them.\\
SDL-devel, SDL & Simple DirectMedia Layer (SDL) is another way of virtualizing the unmodified guest console. It provides an X window for the guest console.
@@ -2077,6 +2077,8 @@ acpi & Enable VMX guest ACPI, default=0 (disabled)\\
apic & Enable VMX guest APIC, default=0 (disabled)\\
pae & Enable VMX guest PAE, default=0 (disabled)\\
vif & Optionally defines MAC address and/or bridge for the network interfaces. Random MACs are assigned if not given. {\small {\tt type=ioemu}} means ioemu is used to virtualize the VMX NIC. If no type is specified, vbd is used, as with paravirtualized guests.\\
disk & Defines the disk devices you want the domain to have access to, and what you want them accessible as. If using a physical device as the VMX guest's disk, each disk entry is of the form
@@ -2229,6 +2231,30 @@ Simply follow the usual method of creating the guest, using the -f parameter and
In the default configuration, VNC is on and SDL is off. Therefore VNC windows will open when VMX guests are created. If you want to use SDL to create VMX guests, set {\small {\tt sdl=1}} in your VMX configuration file. You can also turn off VNC by setting {\small {\tt vnc=0}}.
\subsection{Use mouse in VNC window}
The default PS/2 mouse will not work properly in VMX by a VNC window. Summagraphics mouse emulation does work in this environment. A Summagraphics mouse can be enabled by reconfiguring 2 services:
{\small {\tt 1. General Purpose Mouse (GPM). The GPM daemon is configured in different ways in different Linux distributions. On a Redhat distribution, this is accomplished by changing the file `/etc/sysconfig/mouse' to have the following:\\
MOUSETYPE="summa"\\
XMOUSETYPE="SUMMA"\\
DEVICE=/dev/ttyS0\\
\\
2. X11. For all Linux distributions, change the Mouse0 stanza in `/etc/X11/xorg.conf' to:\\
Section "InputDevice"\\
Identifier "Mouse0"\\
Driver "summa"\\
Option "Device" "/dev/ttyS0"\\
Option "InputFashion" "Tablet"\\
Option "Mode" "Absolute"\\
Option "Name" "EasyPen"\\
Option "Compatible" "True"\\
Option "Protocol" "Auto"\\
Option "SendCoreEvents" "on"\\
Option "Vendor" "GENIUS"\\
EndSection}}
If the Summagraphics mouse isn't the default mouse, you can manually kill 'gpm' and restart it with the command "gpm -m /dev/ttyS0 -t summa". Note that Summagraphics mouse makes no sense in an SDL window and is therefore not available in this environment.
\subsection{Destroy VMX guests}
VMX guests can be destroyed in the same way as can paravirtualized guests. We recommend that you type the command
+3
View File
@@ -37,8 +37,10 @@ OBJS += $(patsubst %.c,%.o,$(wildcard console/*.c))
HDRS := $(wildcard include/*.h)
HDRS += $(wildcard include/xen/*.h)
.PHONY: default
default: $(TARGET)
.PHONY: links
links:
[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
@@ -46,6 +48,7 @@ $(TARGET): links $(OBJS)
$(LD) -N -T minios-$(TARGET_ARCH).lds $(OBJS) -o $@.elf
gzip -f -9 -c $@.elf >$@.gz
.PHONY: clean
clean:
find . -type f -name '*.o' | xargs rm -f
rm -f *.o *~ core $(TARGET).elf $(TARGET).raw $(TARGET) $(TARGET).gz
+25 -28
View File
@@ -4,6 +4,7 @@
#include <hypervisor.h>
#include <mm.h>
#include <lib.h>
#include <sched.h>
/*
* These are assembler stubs in entry.S.
@@ -31,6 +32,8 @@ void machine_check(void);
void dump_regs(struct pt_regs *regs)
{
printk("Thread: %s\n", current->name);
#ifdef __i386__
printk("EIP: %x, EFLAGS %x.\n", regs->eip, regs->eflags);
printk("EBX: %08x ECX: %08x EDX: %08x\n",
regs->ebx, regs->ecx, regs->edx);
@@ -40,9 +43,22 @@ void dump_regs(struct pt_regs *regs)
regs->xds, regs->xes, regs->orig_eax, regs->eip);
printk("CS: %04x EFLAGS: %08x esp: %08x ss: %04x\n",
regs->xcs, regs->eflags, regs->esp, regs->xss);
}
#else
printk("RIP: %04lx:[<%016lx>] ", regs->cs & 0xffff, regs->rip);
printk("\nRSP: %04lx:%016lx EFLAGS: %08lx\n",
regs->ss, regs->rsp, regs->eflags);
printk("RAX: %016lx RBX: %016lx RCX: %016lx\n",
regs->rax, regs->rbx, regs->rcx);
printk("RDX: %016lx RSI: %016lx RDI: %016lx\n",
regs->rdx, regs->rsi, regs->rdi);
printk("RBP: %016lx R08: %016lx R09: %016lx\n",
regs->rbp, regs->r8, regs->r9);
printk("R10: %016lx R11: %016lx R12: %016lx\n",
regs->r10, regs->r11, regs->r12);
printk("R13: %016lx R14: %016lx R15: %016lx\n",
regs->r13, regs->r14, regs->r15);
#endif
}
static void do_trap(int trapnr, char *str, struct pt_regs * regs, unsigned long error_code)
{
@@ -110,36 +126,17 @@ void do_page_fault(struct pt_regs *regs, unsigned long error_code)
printk("Page fault at linear address %p, regs %p, code %lx\n", addr, regs,
error_code);
dump_regs(regs);
#ifdef __x86_64__
/* FIXME: _PAGE_PSE */
{
unsigned long *tab = (unsigned long *)start_info.pt_base;
unsigned long page;
printk("Pagetable walk from %p:\n", tab);
page = tab[l4_table_offset(addr)];
tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
printk(" L4 = %p (%p)\n", page, tab);
page = tab[l3_table_offset(addr)];
tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
printk(" L3 = %p (%p)\n", page, tab);
page = tab[l2_table_offset(addr)];
tab = to_virt(mfn_to_pfn(pte_to_mfn(page)) << PAGE_SHIFT);
printk(" L2 = %p (%p)\n", page, tab);
page = tab[l1_table_offset(addr)];
printk(" L1 = %p\n", page);
}
#endif
page_walk(addr);
do_exit();
}
void do_general_protection(struct pt_regs *regs, long error_code)
{
printk("GPF %p, error_code=%lx\n", regs, error_code);
#ifdef __i386__
printk("GPF eip: %p, error_code=%lx\n", regs->eip, error_code);
#else
printk("GPF rip: %p, error_code=%lx\n", regs->rip, error_code);
#endif
dump_regs(regs);
do_exit();
}
-2
View File
@@ -1116,9 +1116,7 @@ source "fs/Kconfig"
menu "Instrumentation Support"
depends on EXPERIMENTAL
if !X86_XEN
source "arch/i386/oprofile/Kconfig"
endif
config KPROBES
bool "Kprobes (EXPERIMENTAL)"
+7 -1
View File
@@ -45,6 +45,11 @@ CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-op
CFLAGS += $(cflags-y)
cppflags-$(CONFIG_XEN) += \
-D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION)
CPPFLAGS += $(cppflags-y)
# Default subarch .c files
mcore-y := mach-default
@@ -107,7 +112,7 @@ boot := arch/i386/boot
zdisk bzdisk fdimage fdimage144 fdimage288 install
ifdef CONFIG_XEN
CPPFLAGS := -D__KERNEL__ -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(LINUXINCLUDE)
CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS)
head-y := arch/i386/kernel/head-xen.o arch/i386/kernel/init_task-xen.o
boot := arch/i386/boot-xen
.PHONY: vmlinuz
@@ -157,3 +162,4 @@ define archhelp
endef
CLEAN_FILES += arch/$(ARCH)/boot/fdimage arch/$(ARCH)/boot/mtools.conf
CLEAN_FILES += vmlinuz vmlinux-stripped
@@ -65,7 +65,6 @@ ES = 0x20
ORIG_EAX = 0x24
EIP = 0x28
CS = 0x2C
EVENT_MASK = 0x2E
EFLAGS = 0x30
OLDESP = 0x34
OLDSS = 0x38
@@ -290,14 +289,14 @@ restore_all:
restore_nocheck:
#else
restore_nocheck:
testl $(VM_MASK|NMI_MASK), EFLAGS(%esp)
movl EFLAGS(%esp), %eax
testl $(VM_MASK|NMI_MASK), %eax
jnz hypervisor_iret
movb EVENT_MASK(%esp), %al
notb %al # %al == ~saved_mask
shr $9, %eax # EAX[0] == IRET_EFLAGS.IF
GET_VCPU_INFO
andb evtchn_upcall_mask(%esi),%al
andb $1,%al # %al == mask & ~saved_mask
jnz restore_all_enable_events # != 0 => reenable event delivery
andb $1,%al # EAX[0] == IRET_EFLAGS.IF & event_mask
jnz restore_all_enable_events # != 0 => enable event delivery
#endif
RESTORE_REGS
addl $4, %esp
@@ -462,7 +461,7 @@ vector=0
ENTRY(irq_entries_start)
.rept NR_IRQS
ALIGN
1: pushl 0x80000000+$vector
1: pushl $~(vector)
jmp common_interrupt
.data
.long 1b
@@ -479,7 +478,7 @@ common_interrupt:
#define BUILD_INTERRUPT(name, nr) \
ENTRY(name) \
pushl 0x80000000+$nr; \
pushl $~(nr); \
SAVE_ALL \
movl %esp,%eax; \
call smp_/**/name; \
@@ -555,14 +554,9 @@ scrit: /**** START OF CRITICAL REGION ****/
RESTORE_REGS
addl $4, %esp
1: iret
.section .fixup,"ax"
2: pushl $0
pushl $do_iret_error
jmp error_code
.previous
.section __ex_table,"a"
.align 4
.long 1b,2b
.long 1b,iret_exc
.previous
14: __DISABLE_INTERRUPTS
jmp 11b
@@ -614,30 +608,51 @@ critical_fixup_table:
.byte 0x00,0x00 # jmp 11b
# Hypervisor uses this for application faults while it executes.
# We get here for two reasons:
# 1. Fault while reloading DS, ES, FS or GS
# 2. Fault while executing IRET
# Category 1 we fix up by reattempting the load, and zeroing the segment
# register if the load fails.
# Category 2 we fix up by jumping to do_iret_error. We cannot use the
# normal Linux return path in this case because if we use the IRET hypercall
# to pop the stack frame we end up in an infinite loop of failsafe callbacks.
# We distinguish between categories by maintaining a status value in EAX.
ENTRY(failsafe_callback)
1: popl %ds
2: popl %es
3: popl %fs
4: popl %gs
subl $4,%esp
pushl %eax
movl $1,%eax
1: mov 4(%esp),%ds
2: mov 8(%esp),%es
3: mov 12(%esp),%fs
4: mov 16(%esp),%gs
testl %eax,%eax
popl %eax
jz 5f
addl $16,%esp # EAX != 0 => Category 2 (Bad IRET)
jmp iret_exc
5: addl $16,%esp # EAX == 0 => Category 1 (Bad segment)
pushl $0
SAVE_ALL
jmp ret_from_exception
.section .fixup,"ax"; \
6: movl $0,(%esp); \
jmp 1b; \
7: movl $0,(%esp); \
jmp 2b; \
8: movl $0,(%esp); \
jmp 3b; \
9: movl $0,(%esp); \
jmp 4b; \
.previous; \
.section __ex_table,"a";\
.align 4; \
.long 1b,6b; \
.long 2b,7b; \
.long 3b,8b; \
.long 4b,9b; \
jmp ret_from_exception
.section .fixup,"ax"; \
6: xorl %eax,%eax; \
movl %eax,4(%esp); \
jmp 1b; \
7: xorl %eax,%eax; \
movl %eax,8(%esp); \
jmp 2b; \
8: xorl %eax,%eax; \
movl %eax,12(%esp); \
jmp 3b; \
9: xorl %eax,%eax; \
movl %eax,16(%esp); \
jmp 4b; \
.previous; \
.section __ex_table,"a"; \
.align 4; \
.long 1b,6b; \
.long 2b,7b; \
.long 3b,8b; \
.long 4b,9b; \
.previous
#endif
@@ -54,7 +54,7 @@ static union irq_ctx *softirq_ctx[NR_CPUS];
fastcall unsigned int do_IRQ(struct pt_regs *regs)
{
/* high bit used in ret_from_ code */
int irq = regs->orig_eax & __IRQ_MASK(BITS_PER_LONG - 1);
int irq = ~regs->orig_eax;
#ifdef CONFIG_4KSTACKS
union irq_ctx *curctx, *irqctx;
u32 *isp;
@@ -69,7 +69,7 @@ dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents,
} else {
for (i = 0; i < nents; i++ ) {
sg[i].dma_address =
page_to_phys(sg[i].page) + sg[i].offset;
page_to_bus(sg[i].page) + sg[i].offset;
sg[i].dma_length = sg[i].length;
BUG_ON(!sg[i].page);
IOMMU_BUG_ON(address_needs_mapping(
@@ -105,7 +105,7 @@ dma_map_page(struct device *dev, struct page *page, unsigned long offset,
dma_addr = swiotlb_map_page(
dev, page, offset, size, direction);
} else {
dma_addr = page_to_phys(page) + offset;
dma_addr = page_to_bus(page) + offset;
IOMMU_BUG_ON(address_needs_mapping(dev, dma_addr));
}
@@ -114,7 +114,7 @@ void xen_idle(void)
smp_mb__after_clear_bit();
stop_hz_timer();
/* Blocking includes an implicit local_irq_enable(). */
HYPERVISOR_sched_op(SCHEDOP_block, 0);
HYPERVISOR_block();
start_hz_timer();
set_thread_flag(TIF_POLLING_NRFLAG);
}
@@ -5,7 +5,7 @@
#include <linux/pci.h>
#include <linux/irq.h>
#if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI)
#if defined(CONFIG_X86_IO_APIC) && (defined(CONFIG_SMP) || defined(CONFIG_XEN)) && defined(CONFIG_PCI)
static void __devinit quirk_intel_irqbalance(struct pci_dev *dev)
{
@@ -1317,6 +1317,11 @@ void __init setup_bootmem_allocator(void)
}
}
#endif
#ifdef CONFIG_KEXEC
if (crashk_res.start != crashk_res.end)
reserve_bootmem(crashk_res.start,
crashk_res.end - crashk_res.start + 1);
#endif
if (!xen_feature(XENFEAT_auto_translated_physmap))
phys_to_machine_mapping =
@@ -1436,11 +1441,6 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat
}
}
#endif
#ifdef CONFIG_KEXEC
if (crashk_res.start != crashk_res.end)
reserve_bootmem(crashk_res.start,
crashk_res.end - crashk_res.start + 1);
#endif
}
/*
@@ -1633,9 +1633,9 @@ void __init setup_arch(char **cmdline_p)
physdev_op_t op;
unsigned long max_low_pfn;
/* Force a quick death if the kernel panics. */
/* Force a quick death if the kernel panics (not domain 0). */
extern int panic_timeout;
if (panic_timeout == 0)
if (!panic_timeout && !(xen_start_info->flags & SIF_INITDOMAIN))
panic_timeout = 1;
/* Register a call for panic conditions. */
@@ -1848,10 +1848,6 @@ void __init setup_arch(char **cmdline_p)
get_smp_config();
#endif
/* XXX Disable irqdebug until we have a way to avoid interrupt
* conflicts. */
noirqdebug_setup("");
register_memory();
if (xen_start_info->flags & SIF_INITDOMAIN) {
@@ -1877,7 +1873,7 @@ void __init setup_arch(char **cmdline_p)
static int
xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
{
HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash);
HYPERVISOR_shutdown(SHUTDOWN_crash);
/* we're never actually going to get here... */
return NOTIFY_DONE;
}
@@ -32,7 +32,7 @@ EXPORT_SYMBOL(swiotlb);
#define OFFSET(val,align) ((unsigned long)((val) & ( (align) - 1)))
#define SG_ENT_PHYS_ADDRESS(sg) (page_to_phys((sg)->page) + (sg)->offset)
#define SG_ENT_PHYS_ADDRESS(sg) (page_to_bus((sg)->page) + (sg)->offset)
/*
* Maximum allowable number of contiguous slabs to map,
@@ -607,7 +607,7 @@ swiotlb_map_page(struct device *hwdev, struct page *page,
dma_addr_t dev_addr;
char *map;
dev_addr = page_to_phys(page) + offset;
dev_addr = page_to_bus(page) + offset;
if (address_needs_mapping(hwdev, dev_addr)) {
buffer.page = page;
buffer.offset = offset;
@@ -177,6 +177,32 @@ int touch_pte_range(struct mm_struct *mm,
EXPORT_SYMBOL(touch_pte_range);
void *vm_map_xen_pages (unsigned long maddr, int vm_size, pgprot_t prot)
{
int error;
struct vm_struct *vma;
vma = get_vm_area (vm_size, VM_IOREMAP);
if (vma == NULL) {
printk ("ioremap.c,vm_map_xen_pages(): "
"Failed to get VMA area\n");
return NULL;
}
error = direct_kernel_remap_pfn_range((unsigned long) vma->addr,
maddr >> PAGE_SHIFT, vm_size,
prot, DOMID_SELF );
if (error == 0) {
return vma->addr;
} else {
printk ("ioremap.c,vm_map_xen_pages(): "
"Failed to map xen shared pages into kernel space\n");
return NULL;
}
}
EXPORT_SYMBOL(vm_map_xen_pages);
/*
* Does @address reside within a non-highmem page that is local to this virtual
* machine (i.e., not an I/O page, nor a memory page belonging to another VM).
@@ -0,0 +1,16 @@
obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o \
timer_int.o )
ifdef CONFIG_XEN
oprofile-y := $(DRIVER_OBJS) xenoprof.o
else
oprofile-y := $(DRIVER_OBJS) init.o backtrace.o
oprofile-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o \
op_model_ppro.o op_model_p4.o
oprofile-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o
endif
@@ -0,0 +1,395 @@
/**
* @file xenoprof.c
*
* @remark Copyright 2002 OProfile authors
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
*
* Modified by Aravind Menon and Jose Renato Santos for Xen
* These modifications are:
* Copyright (C) 2005 Hewlett-Packard Co.
*/
#include <linux/init.h>
#include <linux/notifier.h>
#include <linux/smp.h>
#include <linux/oprofile.h>
#include <linux/sysdev.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/vmalloc.h>
#include <asm/nmi.h>
#include <asm/msr.h>
#include <asm/apic.h>
#include <asm/pgtable.h>
#include <xen/evtchn.h>
#include "op_counter.h"
#include <xen/interface/xen.h>
#include <xen/interface/xenoprof.h>
static int xenoprof_start(void);
static void xenoprof_stop(void);
void * vm_map_xen_pages(unsigned long maddr, int vm_size, pgprot_t prot);
static int xenoprof_enabled = 0;
static int num_events = 0;
static int is_primary = 0;
/* sample buffers shared with Xen */
xenoprof_buf_t * xenoprof_buf[MAX_VIRT_CPUS];
/* Shared buffer area */
char * shared_buffer;
/* Number of buffers in shared area (one per VCPU) */
int nbuf;
/* Mappings of VIRQ_XENOPROF to irq number (per cpu) */
int ovf_irq[NR_CPUS];
/* cpu model type string - copied from Xen memory space on XENOPROF_init command */
char cpu_type[XENOPROF_CPU_TYPE_SIZE];
#ifdef CONFIG_PM
static int xenoprof_suspend(struct sys_device * dev, pm_message_t state)
{
if (xenoprof_enabled == 1)
xenoprof_stop();
return 0;
}
static int xenoprof_resume(struct sys_device * dev)
{
if (xenoprof_enabled == 1)
xenoprof_start();
return 0;
}
static struct sysdev_class oprofile_sysclass = {
set_kset_name("oprofile"),
.resume = xenoprof_resume,
.suspend = xenoprof_suspend
};
static struct sys_device device_oprofile = {
.id = 0,
.cls = &oprofile_sysclass,
};
static int __init init_driverfs(void)
{
int error;
if (!(error = sysdev_class_register(&oprofile_sysclass)))
error = sysdev_register(&device_oprofile);
return error;
}
static void __exit exit_driverfs(void)
{
sysdev_unregister(&device_oprofile);
sysdev_class_unregister(&oprofile_sysclass);
}
#else
#define init_driverfs() do { } while (0)
#define exit_driverfs() do { } while (0)
#endif /* CONFIG_PM */
unsigned long long oprofile_samples = 0;
static irqreturn_t
xenoprof_ovf_interrupt(int irq, void * dev_id, struct pt_regs * regs)
{
int head, tail, size;
xenoprof_buf_t * buf;
int cpu;
cpu = smp_processor_id();
buf = xenoprof_buf[cpu];
head = buf->event_head;
tail = buf->event_tail;
size = buf->event_size;
if (tail > head) {
while (tail < size) {
oprofile_add_pc(buf->event_log[tail].eip,
buf->event_log[tail].mode,
buf->event_log[tail].event);
oprofile_samples++;
tail++;
}
tail = 0;
}
while (tail < head) {
oprofile_add_pc(buf->event_log[tail].eip,
buf->event_log[tail].mode,
buf->event_log[tail].event);
oprofile_samples++;
tail++;
}
buf->event_tail = tail;
return IRQ_HANDLED;
}
static void unbind_virq_cpu(void * info)
{
int cpu = smp_processor_id();
if (ovf_irq[cpu] >= 0) {
unbind_from_irqhandler(ovf_irq[cpu], NULL);
ovf_irq[cpu] = -1;
}
}
static void unbind_virq(void)
{
on_each_cpu(unbind_virq_cpu, NULL, 0, 1);
}
int bind_virq_error;
static void bind_virq_cpu(void * info)
{
int result;
int cpu = smp_processor_id();
result = bind_virq_to_irqhandler(VIRQ_XENOPROF,
cpu,
xenoprof_ovf_interrupt,
SA_INTERRUPT,
"xenoprof",
NULL);
if (result<0) {
bind_virq_error = result;
printk("xenoprof.c: binding VIRQ_XENOPROF to IRQ failed on CPU "
"%d\n", cpu);
} else {
ovf_irq[cpu] = result;
}
}
static int bind_virq(void)
{
bind_virq_error = 0;
on_each_cpu(bind_virq_cpu, NULL, 0, 1);
if (bind_virq_error) {
unbind_virq();
return bind_virq_error;
} else {
return 0;
}
}
static int xenoprof_setup(void)
{
int ret;
ret = bind_virq();
if (ret)
return ret;
if (is_primary) {
ret = HYPERVISOR_xenoprof_op(XENOPROF_reserve_counters,
(unsigned long)NULL,
(unsigned long)NULL);
if (ret)
goto err;
ret = HYPERVISOR_xenoprof_op(XENOPROF_setup_events,
(unsigned long)&counter_config,
(unsigned long)num_events);
if (ret)
goto err;
}
ret = HYPERVISOR_xenoprof_op(XENOPROF_enable_virq,
(unsigned long)NULL,
(unsigned long)NULL);
if (ret)
goto err;
xenoprof_enabled = 1;
return 0;
err:
unbind_virq();
return ret;
}
static void xenoprof_shutdown(void)
{
xenoprof_enabled = 0;
HYPERVISOR_xenoprof_op(XENOPROF_disable_virq,
(unsigned long)NULL,
(unsigned long)NULL);
if (is_primary) {
HYPERVISOR_xenoprof_op(XENOPROF_release_counters,
(unsigned long)NULL,
(unsigned long)NULL);
}
unbind_virq();
}
static int xenoprof_start(void)
{
int ret = 0;
if (is_primary)
ret = HYPERVISOR_xenoprof_op(XENOPROF_start,
(unsigned long)NULL,
(unsigned long)NULL);
return ret;
}
static void xenoprof_stop(void)
{
if (is_primary)
HYPERVISOR_xenoprof_op(XENOPROF_stop,
(unsigned long)NULL,
(unsigned long)NULL);
}
static int xenoprof_set_active(int * active_domains,
unsigned int adomains)
{
int ret = 0;
if (is_primary)
ret = HYPERVISOR_xenoprof_op(XENOPROF_set_active,
(unsigned long)active_domains,
(unsigned long)adomains);
return ret;
}
struct op_counter_config counter_config[OP_MAX_COUNTER];
static int xenoprof_create_files(struct super_block * sb, struct dentry * root)
{
unsigned int i;
for (i = 0; i < num_events; ++i) {
struct dentry * dir;
char buf[2];
snprintf(buf, 2, "%d", i);
dir = oprofilefs_mkdir(sb, root, buf);
oprofilefs_create_ulong(sb, dir, "enabled",
&counter_config[i].enabled);
oprofilefs_create_ulong(sb, dir, "event",
&counter_config[i].event);
oprofilefs_create_ulong(sb, dir, "count",
&counter_config[i].count);
oprofilefs_create_ulong(sb, dir, "unit_mask",
&counter_config[i].unit_mask);
oprofilefs_create_ulong(sb, dir, "kernel",
&counter_config[i].kernel);
oprofilefs_create_ulong(sb, dir, "user",
&counter_config[i].user);
}
return 0;
}
struct oprofile_operations xenoprof_ops = {
.create_files = xenoprof_create_files,
.set_active = xenoprof_set_active,
.setup = xenoprof_setup,
.shutdown = xenoprof_shutdown,
.start = xenoprof_start,
.stop = xenoprof_stop
};
/* in order to get driverfs right */
static int using_xenoprof;
int __init oprofile_arch_init(struct oprofile_operations * ops)
{
xenoprof_init_result_t result;
xenoprof_buf_t * buf;
int max_samples = 16;
int vm_size;
int npages;
int i;
int ret = HYPERVISOR_xenoprof_op(XENOPROF_init,
(unsigned long)max_samples,
(unsigned long)&result);
if (!ret) {
pgprot_t prot = __pgprot(_KERNPG_TABLE);
num_events = result.num_events;
is_primary = result.is_primary;
nbuf = result.nbuf;
npages = (result.bufsize * nbuf - 1) / PAGE_SIZE + 1;
vm_size = npages * PAGE_SIZE;
shared_buffer = (char *) vm_map_xen_pages(result.buf_maddr,
vm_size, prot);
if (!shared_buffer) {
ret = -ENOMEM;
goto out;
}
for (i=0; i< nbuf; i++) {
buf = (xenoprof_buf_t*)
&shared_buffer[i * result.bufsize];
BUG_ON(buf->vcpu_id >= MAX_VIRT_CPUS);
xenoprof_buf[buf->vcpu_id] = buf;
}
/* cpu_type is detected by Xen */
cpu_type[XENOPROF_CPU_TYPE_SIZE-1] = 0;
strncpy(cpu_type, result.cpu_type, XENOPROF_CPU_TYPE_SIZE - 1);
xenoprof_ops.cpu_type = cpu_type;
init_driverfs();
using_xenoprof = 1;
*ops = xenoprof_ops;
for (i=0; i<NR_CPUS; i++)
ovf_irq[i] = -1;
}
out:
printk(KERN_INFO "oprofile_arch_init: ret %d, events %d, "
"is_primary %d\n", ret, num_events, is_primary);
return ret;
}
void __exit oprofile_arch_exit(void)
{
if (using_xenoprof)
exit_driverfs();
if (shared_buffer) {
vunmap(shared_buffer);
shared_buffer = NULL;
}
if (is_primary)
HYPERVISOR_xenoprof_op(XENOPROF_shutdown,
(unsigned long)NULL,
(unsigned long)NULL);
}
+11 -1
View File
@@ -79,11 +79,16 @@ config XEN_BLKDEV_FRONTEND
bool
default y
config XEN_BLKDEV_BACKEND
config XEN_BACKEND
depends on XEN
bool
default y
config XEN_BLKDEV_BACKEND
depends on XEN && XEN_BACKEND
bool
default y
config XEN_SYSFS
bool "Export Xen attributes in sysfs"
depends on XEN && SYSFS
@@ -91,6 +96,11 @@ config XEN_SYSFS
help
Xen hypervisor attributes will show up under /sys/hypervisor/.
config XEN_INTERFACE_VERSION
hex
depends on XEN
default 0x00030101
config SCHED_NO_NO_OMIT_FRAME_POINTER
bool
default y
+6
View File
@@ -42,6 +42,12 @@ ifeq ($(call cc-version),0304)
endif
CFLAGS += $(cflags-y)
cppflags-$(CONFIG_XEN) += \
-D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION)
CPPFLAGS += $(cppflags-y)
head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
libs-y += arch/ia64/lib/
@@ -10,7 +10,7 @@ $(obj)/vmlinux.lds.S:
@ln -fsn $(srctree)/arch/$(XENARCH)/kernel/vmlinux.lds.S $@
obj-y := gnttab.o
obj-y := gnttab.o features.o
obj-$(CONFIG_PROC_FS) += xen_proc.o
ifeq ($(ARCH),ia64)
+5 -1
View File
@@ -31,6 +31,10 @@ cflags-$(CONFIG_MK8) += $(call cc-option,-march=k8)
cflags-$(CONFIG_MPSC) += $(call cc-option,-march=nocona)
CFLAGS += $(cflags-y)
cppflags-$(CONFIG_XEN) += \
-D__XEN_INTERFACE_VERSION__=$(CONFIG_XEN_INTERFACE_VERSION)
CPPFLAGS += $(cppflags-y)
CFLAGS += -m64
CFLAGS += -mno-red-zone
CFLAGS += -mcmodel=kernel
@@ -71,7 +75,7 @@ boot := arch/x86_64/boot
fdimage fdimage144 fdimage288 archclean
ifdef CONFIG_XEN
CPPFLAGS := -D__KERNEL__ -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(LINUXINCLUDE)
CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS)
head-y := arch/x86_64/kernel/head-xen.o arch/x86_64/kernel/head64-xen.o arch/x86_64/kernel/init_task.o
LDFLAGS_vmlinux := -e _start
boot := arch/i386/boot-xen
@@ -520,13 +520,13 @@ retint_check:
CFI_REMEMBER_STATE
jnz retint_careful
retint_restore_args:
movb EVENT_MASK-REST_SKIP(%rsp), %al
notb %al # %al == ~saved_mask
XEN_GET_VCPU_INFO(%rsi)
andb evtchn_upcall_mask(%rsi),%al
andb $1,%al # %al == mask & ~saved_mask
jnz restore_all_enable_events # != 0 => reenable event delivery
XEN_PUT_VCPU_INFO(%rsi)
movl EFLAGS-REST_SKIP(%rsp), %eax
shr $9, %eax # EAX[0] == IRET_EFLAGS.IF
XEN_GET_VCPU_INFO(%rsi)
andb evtchn_upcall_mask(%rsi),%al
andb $1,%al # EAX[0] == IRET_EFLAGS.IF & event_mask
jnz restore_all_enable_events # != 0 => enable event delivery
XEN_PUT_VCPU_INFO(%rsi)
RESTORE_ARGS 0,8,0
HYPERVISOR_IRET 0
@@ -584,7 +584,7 @@ retint_kernel:
*/
.macro apicinterrupt num,func
INTR_FRAME
pushq 0x8000000000000000+$\num
pushq $~(\num)
CFI_ADJUST_CFA_OFFSET 8
interrupt \func
jmp error_entry
@@ -803,12 +803,11 @@ ENTRY(hypervisor_callback)
# So, on entry to the handler we detect whether we interrupted an
# existing activation in its critical region -- if so, we pop the current
# activation and restart the handler using the previous one.
ENTRY(do_hypervisor_callback) # do_hyperviosr_callback(struct *pt_regs)
ENTRY(do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
# Since we don't modify %rdi, evtchn_do_upall(struct *pt_regs) will
# see the correct pointer to the pt_regs
movq %rdi, %rsp # we don't return, adjust the stack frame
11: movb $0, EVENT_MASK(%rdi)
movq %gs:pda_irqstackptr,%rax
11: movq %gs:pda_irqstackptr,%rax
incl %gs:pda_irqcount
cmovzq %rax,%rsp
pushq %rdi
@@ -853,15 +852,44 @@ ecrit: /**** END OF CRITICAL REGION ****/
# When the kernel is interrupted in the critical section, the kernel
# will do IRET in that case, and everything will be restored at that point,
# i.e. it just resumes from the next instruction interrupted with the same context.
# Hypervisor uses this for application faults while it executes.
# Unlike i386 there is no need to reload the saved segment selectors:
# Xen already reloaded all valid ones and zeroed the others.
# We get here for two reasons:
# 1. Fault while reloading DS, ES, FS or GS
# 2. Fault while executing IRET
# Category 1 we do not need to fix up as Xen has already reloaded all segment
# registers that could be reloaded and zeroed the others.
# Category 2 we fix up by killing the current process. We cannot use the
# normal Linux return path in this case because if we use the IRET hypercall
# to pop the stack frame we end up in an infinite loop of failsafe callbacks.
# We distinguish between categories by comparing each saved segment register
# with its current contents: any discrepancy means we in category 1.
ENTRY(failsafe_callback)
addq $0x30,%rsp /* skip %rcx,%r11,%ds,%es,%fs,%gs */
movw %ds,%cx
cmpw %cx,0x10(%rsp)
jne 1f
movw %es,%cx
cmpw %cx,0x18(%rsp)
jne 1f
movw %fs,%cx
cmpw %cx,0x20(%rsp)
jne 1f
movw %gs,%cx
cmpw %cx,0x28(%rsp)
jne 1f
/* All segments match their saved values => Category 2 (Bad IRET). */
movq (%rsp),%rcx
movq 8(%rsp),%r11
addq $0x30,%rsp
movq $-9999,%rdi /* better code? */
jmp do_exit
1: /* Segment mismatch => Category 1 (Bad segment). Retry the IRET. */
movq (%rsp),%rcx
movq 8(%rsp),%r11
addq $0x30,%rsp
pushq $0
SAVE_ALL
jmp error_exit
jmp error_exit
#if 0
.section __ex_table,"a"
.align 8
@@ -97,7 +97,7 @@ skip:
asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
{
/* high bit used in ret_from_ code */
int irq = regs->orig_rax & __IRQ_MASK(BITS_PER_LONG - 1);
unsigned irq = ~regs->orig_rax;
exit_idle();
irq_enter();
@@ -131,7 +131,7 @@ void xen_idle(void)
smp_mb__after_clear_bit();
stop_hz_timer();
/* Blocking includes an implicit local_irq_enable(). */
HYPERVISOR_sched_op(SCHEDOP_block, 0);
HYPERVISOR_block();
start_hz_timer();
set_thread_flag(TIF_POLLING_NRFLAG);
}
@@ -999,7 +999,7 @@ void __init setup_arch(char **cmdline_p)
static int
xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
{
HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_crash);
HYPERVISOR_shutdown(SHUTDOWN_crash);
/* we're never actually going to get here... */
return NOTIFY_DONE;
}
@@ -2,7 +2,7 @@
* Copied from arch/xen/i386/kernel/entry.S
*/
/* Offsets into shared_info_t. */
#define evtchn_upcall_pending 0
#define evtchn_upcall_pending /* 0 */
#define evtchn_upcall_mask 1
#define sizeof_vcpu_shift 6
@@ -35,7 +35,6 @@
XEN_PUT_VCPU_INFO(reg)
#define XEN_TEST_PENDING(reg) testb $0xFF,evtchn_upcall_pending(reg)
EVENT_MASK = (CS+4)
VGCF_IN_SYSCALL = (1<<8)
@@ -0,0 +1,22 @@
#
# oprofile for x86-64.
# Just reuse the one from i386.
#
obj-$(CONFIG_OPROFILE) += oprofile.o
DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprof.o cpu_buffer.o buffer_sync.o \
event_buffer.o oprofile_files.o \
oprofilefs.o oprofile_stats.o \
timer_int.o )
ifdef CONFIG_XEN
OPROFILE-y := xenoprof.o
else
OPROFILE-y := init.o backtrace.o
OPROFILE-$(CONFIG_X86_LOCAL_APIC) += nmi_int.o op_model_athlon.o op_model_p4.o \
op_model_ppro.o
OPROFILE-$(CONFIG_X86_IO_APIC) += nmi_timer_int.o
endif
oprofile-y = $(DRIVER_OBJS) $(addprefix ../../i386/oprofile/, $(OPROFILE-y))
+20 -7
View File
@@ -10,12 +10,11 @@ config XEN
help
This is the Linux Xen port.
config NO_IDLE_HZ
bool
depends on XEN
default y
if XEN
config XEN_INTERFACE_VERSION
hex
default 0x00030101
menu "XEN"
config XEN_PRIVILEGED_GUEST
@@ -29,9 +28,16 @@ config XEN_UNPRIVILEGED_GUEST
bool
default !XEN_PRIVILEGED_GUEST
config XEN_BACKEND
tristate "Backend driver support"
default y
help
Support for backend device drivers that provide I/O services
to other virtual machines.
config XEN_PCIDEV_BACKEND
tristate "PCI device backend driver"
depends PCI
depends on PCI && XEN_BACKEND
default XEN_PRIVILEGED_GUEST
help
The PCI device backend driver allows the kernel to export arbitrary
@@ -71,6 +77,7 @@ config XEN_PCIDEV_BE_DEBUG
config XEN_BLKDEV_BACKEND
tristate "Block-device backend driver"
depends on XEN_BACKEND
default y
help
The block-device backend driver allows the kernel to export its
@@ -92,6 +99,7 @@ config XEN_BLKDEV_TAP_BE
config XEN_NETDEV_BACKEND
tristate "Network-device backend driver"
depends on XEN_BACKEND
default y
help
The network-device backend driver allows the kernel to export its
@@ -121,6 +129,7 @@ config XEN_NETDEV_LOOPBACK
config XEN_TPMDEV_BACKEND
tristate "TPM-device backend driver"
depends on XEN_BACKEND
default n
help
The TPM-device backend driver
@@ -156,6 +165,7 @@ config XEN_NETDEV_FRONTEND
config XEN_BLKDEV_TAP
tristate "Block device tap driver"
depends on XEN_BACKEND
default n
help
This driver allows a VM to interact on block device channels
@@ -191,7 +201,6 @@ config XEN_DISABLE_SERIAL
config XEN_SYSFS
tristate "Export Xen attributes in sysfs"
depends on XEN
depends on SYSFS
default y
help
@@ -207,4 +216,8 @@ config HAVE_ARCH_DEV_ALLOC_SKB
bool
default y
config NO_IDLE_HZ
bool
default y
endif
@@ -215,52 +215,26 @@ static void print_stats(blkif_t *blkif)
int blkif_schedule(void *arg)
{
blkif_t *blkif = arg;
blkif_t *blkif = arg;
blkif_get(blkif);
if (debug_lvl)
printk(KERN_DEBUG "%s: started\n", current->comm);
for (;;) {
if (kthread_should_stop()) {
/* asked to quit? */
if (!atomic_read(&blkif->io_pending))
break;
if (debug_lvl)
printk(KERN_DEBUG "%s: I/O pending, "
"delaying exit\n", current->comm);
}
if (!atomic_read(&blkif->io_pending)) {
/* Wait for work to do. */
wait_event_interruptible(
blkif->wq,
(atomic_read(&blkif->io_pending) ||
kthread_should_stop()));
} else if (list_empty(&pending_free)) {
/* Wait for pending_req becoming available. */
wait_event_interruptible(
pending_free_wq,
!list_empty(&pending_free));
}
while (!kthread_should_stop()) {
wait_event_interruptible(
blkif->wq,
blkif->waiting_reqs || kthread_should_stop());
wait_event_interruptible(
pending_free_wq,
!list_empty(&pending_free) || kthread_should_stop());
if (blkif->status != CONNECTED) {
/* make sure we are connected */
if (debug_lvl)
printk(KERN_DEBUG "%s: not connected "
"(%d pending)\n",
current->comm,
atomic_read(&blkif->io_pending));
wait_event_interruptible(
blkif->wq,
(blkif->status == CONNECTED ||
kthread_should_stop()));
continue;
}
blkif->waiting_reqs = 0;
smp_mb(); /* clear flag *before* checking for work */
/* Schedule I/O */
atomic_set(&blkif->io_pending, 0);
if (do_block_io_op(blkif))
atomic_inc(&blkif->io_pending);
blkif->waiting_reqs = 1;
unplug_queue(blkif);
if (log_stats && time_after(jiffies, blkif->st_print))
@@ -271,8 +245,10 @@ int blkif_schedule(void *arg)
print_stats(blkif);
if (debug_lvl)
printk(KERN_DEBUG "%s: exiting\n", current->comm);
blkif->xenblkd = NULL;
blkif_put(blkif);
return 0;
}
@@ -311,12 +287,15 @@ static int end_block_io_op(struct bio *bio, unsigned int done, int error)
* NOTIFICATION FROM GUEST OS.
*/
static void blkif_notify_work(blkif_t *blkif)
{
blkif->waiting_reqs = 1;
wake_up(&blkif->wq);
}
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs)
{
blkif_t *blkif = dev_id;
atomic_inc(&blkif->io_pending);
wake_up(&blkif->wq);
blkif_notify_work(dev_id);
return IRQ_HANDLED;
}
@@ -536,10 +515,8 @@ static void make_response(blkif_t *blkif, unsigned long id,
}
spin_unlock_irqrestore(&blkif->blk_ring_lock, flags);
if (more_to_do) {
atomic_inc(&blkif->io_pending);
wake_up(&blkif->wq);
}
if (more_to_do)
blkif_notify_work(blkif);
if (notify)
notify_remote_via_irq(blkif->irq);
}
@@ -72,7 +72,6 @@ typedef struct blkif_st {
/* Back pointer to the backend_info. */
struct backend_info *be;
/* Private fields. */
enum { DISCONNECTED, CONNECTED } status;
#ifdef CONFIG_XEN_BLKDEV_TAP_BE
/* Is this a blktap frontend */
unsigned int is_blktap;
@@ -82,7 +81,7 @@ typedef struct blkif_st {
wait_queue_head_t wq;
struct task_struct *xenblkd;
atomic_t io_pending;
unsigned int waiting_reqs;
request_queue_t *plug;
/* statistics */
@@ -133,8 +132,6 @@ void blkif_xenbus_init(void);
irqreturn_t blkif_be_int(int irq, void *dev_id, struct pt_regs *regs);
int blkif_schedule(void *arg);
void update_blkif_status(blkif_t *blkif);
#endif /* __BLKIF__BACKEND__COMMON_H__ */
/*
@@ -45,7 +45,6 @@ blkif_t *alloc_blkif(domid_t domid)
memset(blkif, 0, sizeof(*blkif));
blkif->domid = domid;
blkif->status = DISCONNECTED;
spin_lock_init(&blkif->blk_ring_lock);
atomic_set(&blkif->refcnt, 1);
init_waitqueue_head(&blkif->wq);
@@ -138,9 +137,6 @@ int blkif_map(blkif_t *blkif, unsigned long shared_page, unsigned int evtchn)
blkif->irq = bind_evtchn_to_irqhandler(
blkif->evtchn, blkif_be_int, 0, "blkif-backend", blkif);
/* We're potentially connected now */
update_blkif_status(blkif);
return 0;
}
@@ -17,7 +17,6 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdarg.h>
#include <linux/module.h>
#include <linux/kthread.h>
@@ -25,36 +24,52 @@
#include "common.h"
#undef DPRINTK
#define DPRINTK(fmt, args...) \
pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", __FUNCTION__, __LINE__, ##args)
#define DPRINTK(fmt, args...) \
pr_debug("blkback/xenbus (%s:%d) " fmt ".\n", \
__FUNCTION__, __LINE__, ##args)
struct backend_info
{
struct xenbus_device *dev;
blkif_t *blkif;
struct xenbus_watch backend_watch;
unsigned major;
unsigned minor;
char *mode;
};
static void maybe_connect(struct backend_info *);
static void connect(struct backend_info *);
static int connect_ring(struct backend_info *);
static void backend_changed(struct xenbus_watch *, const char **,
unsigned int);
void update_blkif_status(blkif_t *blkif)
static void update_blkif_status(blkif_t *blkif)
{
if(blkif->irq && blkif->vbd.bdev) {
blkif->status = CONNECTED;
(void)blkif_be_int(0, blkif, NULL);
int err;
/* Not ready to connect? */
if (!blkif->irq || !blkif->vbd.bdev)
return;
/* Already connected? */
if (blkif->be->dev->state == XenbusStateConnected)
return;
/* Attempt to connect: exit if we fail to. */
connect(blkif->be);
if (blkif->be->dev->state != XenbusStateConnected)
return;
blkif->xenblkd = kthread_run(blkif_schedule, blkif,
"xvd %d %02x:%02x",
blkif->domid,
blkif->be->major, blkif->be->minor);
if (IS_ERR(blkif->xenblkd)) {
err = PTR_ERR(blkif->xenblkd);
blkif->xenblkd = NULL;
xenbus_dev_error(blkif->be->dev, err, "start xenblkd");
}
maybe_connect(blkif->be);
}
@@ -91,7 +106,6 @@ static int blkback_remove(struct xenbus_device *dev)
be->backend_watch.node = NULL;
}
if (be->blkif) {
be->blkif->status = DISCONNECTED;
if (be->blkif->xenblkd)
kthread_stop(be->blkif->xenblkd);
blkif_put(be->blkif);
@@ -142,7 +156,7 @@ static int blkback_probe(struct xenbus_device *dev,
if (err)
goto fail;
err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
err = xenbus_switch_state(dev, XenbusStateInitWait);
if (err)
goto fail;
@@ -185,8 +199,8 @@ static void backend_changed(struct xenbus_watch *watch,
return;
}
if (be->major && be->minor &&
(be->major != major || be->minor != minor)) {
if ((be->major || be->minor) &&
((be->major != major) || (be->minor != minor))) {
printk(KERN_WARNING
"blkback: changing physical device (from %x:%x to "
"%x:%x) not supported.\n", be->major, be->minor,
@@ -220,17 +234,6 @@ static void backend_changed(struct xenbus_watch *watch,
return;
}
be->blkif->xenblkd = kthread_run(blkif_schedule, be->blkif,
"xvd %d %02x:%02x",
be->blkif->domid,
be->major, be->minor);
if (IS_ERR(be->blkif->xenblkd)) {
err = PTR_ERR(be->blkif->xenblkd);
be->blkif->xenblkd = NULL;
xenbus_dev_error(dev, err, "start xenblkd");
return;
}
device_create_file(&dev->dev, &dev_attr_physical_device);
device_create_file(&dev->dev, &dev_attr_mode);
@@ -253,19 +256,24 @@ static void frontend_changed(struct xenbus_device *dev,
switch (frontend_state) {
case XenbusStateInitialising:
case XenbusStateConnected:
break;
case XenbusStateInitialised:
case XenbusStateConnected:
/* Ensure we connect even when two watches fire in
close successsion and we miss the intermediate value
of frontend_state. */
if (dev->state == XenbusStateConnected)
break;
err = connect_ring(be);
if (err) {
return;
}
update_blkif_status(be->blkif);
if (err)
break;
update_blkif_status(be->blkif);
break;
case XenbusStateClosing:
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
xenbus_switch_state(dev, XenbusStateClosing);
break;
case XenbusStateClosed:
@@ -285,14 +293,6 @@ static void frontend_changed(struct xenbus_device *dev,
/* ** Connection ** */
static void maybe_connect(struct backend_info *be)
{
if ((be->major != 0 || be->minor != 0) &&
be->blkif->status == CONNECTED)
connect(be);
}
/**
* Write the physical details regarding the block device to the store, and
* switch to Connected state.
@@ -338,15 +338,17 @@ again:
goto abort;
}
err = xenbus_switch_state(dev, xbt, XenbusStateConnected);
if (err)
goto abort;
err = xenbus_transaction_end(xbt, 0);
if (err == -EAGAIN)
goto again;
if (err)
xenbus_dev_fatal(dev, err, "ending transaction");
err = xenbus_switch_state(dev, XenbusStateConnected);
if (err)
xenbus_dev_fatal(dev, err, "switching to Connected state",
dev->nodename);
return;
abort:
xenbus_transaction_end(xbt, 1);
@@ -176,10 +176,6 @@ again:
goto abort_transaction;
}
err = xenbus_switch_state(dev, xbt, XenbusStateInitialised);
if (err)
goto abort_transaction;
err = xenbus_transaction_end(xbt, 0);
if (err) {
if (err == -EAGAIN)
@@ -188,6 +184,8 @@ again:
goto destroy_blkring;
}
xenbus_switch_state(dev, XenbusStateInitialised);
return 0;
abort_transaction:
@@ -324,7 +322,7 @@ static void connect(struct blkfront_info *info)
return;
}
(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
(void)xenbus_switch_state(info->xbdev, XenbusStateConnected);
/* Kick pending requests. */
spin_lock_irq(&blkif_io_lock);
@@ -349,7 +347,7 @@ static void blkfront_closing(struct xenbus_device *dev)
xlvbd_del(info);
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
xenbus_switch_state(dev, XenbusStateClosed);
}
@@ -755,7 +753,7 @@ static void blkif_recover(struct blkfront_info *info)
kfree(copy);
(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
(void)xenbus_switch_state(info->xbdev, XenbusStateConnected);
/* Now safe for us to use the shared ring */
spin_lock_irq(&blkif_io_lock);
@@ -170,9 +170,9 @@ static inline void exit_idle(void) {}
#include <asm/idle.h>
#define IRQ_REG orig_rax
#endif
#define do_IRQ(irq, regs) do { \
(regs)->IRQ_REG = (irq) | (1UL << (BITS_PER_LONG - 1)); \
do_IRQ((regs)); \
#define do_IRQ(irq, regs) do { \
(regs)->IRQ_REG = ~(irq); \
do_IRQ((regs)); \
} while (0)
#endif
@@ -395,6 +395,9 @@ gnttab_resume(void)
setup.frame_list = frames;
rc = HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
if (rc == -ENOSYS)
return -ENOSYS;
BUG_ON(rc || setup.status);
#ifndef __ia64__
@@ -436,7 +439,8 @@ gnttab_init(void)
if (xen_init() < 0)
return -ENODEV;
BUG_ON(gnttab_resume());
if (gnttab_resume() < 0)
return -ENODEV;
for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
gnttab_list[i] = i + 1;
+45 -89
View File
@@ -15,6 +15,7 @@
#include <xen/xenbus.h>
#include <linux/cpu.h>
#include <linux/kthread.h>
#include <xen/gnttab.h>
#include <xen/xencons.h>
#if defined(__i386__) || defined(__x86_64__)
@@ -41,7 +42,7 @@ void machine_emergency_restart(void)
{
/* We really want to get pending console data out before we die. */
xencons_force_flush();
HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_reboot);
HYPERVISOR_shutdown(SHUTDOWN_reboot);
}
void machine_restart(char * __unused)
@@ -58,7 +59,11 @@ void machine_power_off(void)
{
/* We really want to get pending console data out before we die. */
xencons_force_flush();
HYPERVISOR_sched_op(SCHEDOP_shutdown, SHUTDOWN_poweroff);
#if defined(__i386__) || defined(__x86_64__)
if (pm_power_off)
pm_power_off();
#endif
HYPERVISOR_shutdown(SHUTDOWN_poweroff);
}
int reboot_thru_bios = 0; /* for dmi_scan.c */
@@ -76,31 +81,41 @@ 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)
#define cpu_up(x) (-EOPNOTSUPP)
#ifdef CONFIG_SMP
int smp_suspend(void);
void smp_resume(void);
#else
#define smp_suspend() (0)
#define smp_resume() ((void)0)
#endif
/* Ensure we run on the idle task page tables so that we will
switch page tables before running user space. This is needed
on architectures with separate kernel and user page tables
because the user page table pointer is not saved/restored. */
static void switch_idle_mm(void)
{
struct mm_struct *mm = current->active_mm;
if (mm == &init_mm)
return;
atomic_inc(&init_mm.mm_count);
switch_mm(mm, &init_mm, current);
current->active_mm = &init_mm;
mmdrop(mm);
}
static int __do_suspend(void *ignore)
{
int i, j, k, fpp;
int i, j, k, fpp, err;
extern unsigned long max_pfn;
extern unsigned long *pfn_to_mfn_frame_list_list;
extern unsigned long *pfn_to_mfn_frame_list[];
extern int gnttab_suspend(void);
extern int gnttab_resume(void);
extern void time_resume(void);
#ifdef CONFIG_SMP
cpumask_t prev_online_cpus;
int vcpu_prepare(int vcpu);
#endif
int err = 0;
BUG_ON(smp_processor_id() != 0);
BUG_ON(in_interrupt());
@@ -110,50 +125,21 @@ static int __do_suspend(void *ignore)
return -EOPNOTSUPP;
}
#if defined(CONFIG_SMP) && !defined(CONFIG_HOTPLUG_CPU)
if (num_online_cpus() > 1) {
printk(KERN_WARNING "Can't suspend SMP guests "
"without CONFIG_HOTPLUG_CPU\n");
return -EOPNOTSUPP;
}
#endif
err = smp_suspend();
if (err)
return err;
xenbus_suspend();
lock_cpu_hotplug();
#ifdef CONFIG_SMP
/*
* Take all other CPUs offline. We hold the hotplug mutex to
* avoid other processes bringing up CPUs under our feet.
*/
cpus_clear(prev_online_cpus);
while (num_online_cpus() > 1) {
for_each_online_cpu(i) {
if (i == 0)
continue;
unlock_cpu_hotplug();
err = cpu_down(i);
lock_cpu_hotplug();
if (err != 0) {
printk(KERN_CRIT "Failed to take all CPUs "
"down: %d.\n", err);
goto out_reenable_cpus;
}
cpu_set(i, prev_online_cpus);
}
}
#endif
preempt_disable();
#ifdef __i386__
kmem_cache_shrink(pgd_cache);
mm_pin_all();
#endif
mm_pin_all();
__cli();
preempt_enable();
unlock_cpu_hotplug();
gnttab_suspend();
@@ -199,34 +185,15 @@ static int __do_suspend(void *ignore)
time_resume();
switch_idle_mm();
__sti();
xencons_resume();
#ifdef CONFIG_SMP
for_each_cpu(i)
vcpu_prepare(i);
#endif
/*
* Only resume xenbus /after/ we've prepared our VCPUs; otherwise
* the VCPU hotplug callback can race with our vcpu_prepare
*/
xenbus_resume();
#ifdef CONFIG_SMP
out_reenable_cpus:
for_each_cpu_mask(i, prev_online_cpus) {
j = cpu_up(i);
if ((j != 0) && !cpu_online(i)) {
printk(KERN_CRIT "Failed to bring cpu "
"%d back up (%d).\n",
i, j);
err = j;
}
}
#endif
smp_resume();
return err;
}
@@ -334,7 +301,6 @@ static void shutdown_handler(struct xenbus_watch *watch,
kfree(str);
}
#ifdef CONFIG_MAGIC_SYSRQ
static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
unsigned int len)
{
@@ -360,45 +326,35 @@ static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
if (err == -EAGAIN)
goto again;
if (sysrq_key != '\0') {
#ifdef CONFIG_MAGIC_SYSRQ
if (sysrq_key != '\0')
handle_sysrq(sysrq_key, NULL, NULL);
}
}
#endif
}
static struct xenbus_watch shutdown_watch = {
.node = "control/shutdown",
.callback = shutdown_handler
};
#ifdef CONFIG_MAGIC_SYSRQ
static struct xenbus_watch sysrq_watch = {
.node ="control/sysrq",
.callback = sysrq_handler
};
#endif
static int setup_shutdown_watcher(struct notifier_block *notifier,
unsigned long event,
void *data)
{
int err1 = 0;
#ifdef CONFIG_MAGIC_SYSRQ
int err2 = 0;
#endif
int err;
err1 = register_xenbus_watch(&shutdown_watch);
#ifdef CONFIG_MAGIC_SYSRQ
err2 = register_xenbus_watch(&sysrq_watch);
#endif
if (err1)
err = register_xenbus_watch(&shutdown_watch);
if (err)
printk(KERN_ERR "Failed to set shutdown watcher\n");
#ifdef CONFIG_MAGIC_SYSRQ
if (err2)
err = register_xenbus_watch(&sysrq_watch);
if (err)
printk(KERN_ERR "Failed to set sysrq watcher\n");
#endif
return NOTIFY_DONE;
}
+120 -3
View File
@@ -79,6 +79,15 @@ EXPORT_SYMBOL(x86_cpu_to_apicid);
unsigned int maxcpus = NR_CPUS;
#endif
/*
* Set of CPUs that remote admin software will allow us to bring online.
* Notified to us via xenbus.
*/
static cpumask_t xenbus_allowed_cpumask;
/* Set of CPUs that local admin will allow us to bring online. */
static cpumask_t local_allowed_cpumask = CPU_MASK_ALL;
void __init prefill_possible_map(void)
{
int i, rc;
@@ -146,7 +155,7 @@ static void cpu_bringup(void)
cpu_idle();
}
void vcpu_prepare(int vcpu)
static void vcpu_prepare(int vcpu)
{
vcpu_guest_context_t ctxt;
struct task_struct *idle = idle_task(vcpu);
@@ -278,6 +287,8 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
vcpu_prepare(cpu);
}
xenbus_allowed_cpumask = cpu_present_map;
/* Currently, Xen gives no dynamic NUMA/HT info. */
for (cpu = 1; cpu < NR_CPUS; cpu++) {
cpu_sibling_map[cpu] = cpumask_of_cpu(cpu);
@@ -301,6 +312,15 @@ void __devinit smp_prepare_boot_cpu(void)
cpu_online_map = cpumask_of_cpu(0);
}
static int local_cpu_hotplug_request(void)
{
/*
* We assume a CPU hotplug request comes from local admin if it is made
* via a userspace process (i.e., one with a real mm_struct).
*/
return (current->mm != NULL);
}
#ifdef CONFIG_HOTPLUG_CPU
/*
@@ -331,8 +351,10 @@ static void vcpu_hotplug(unsigned int cpu)
}
if (strcmp(state, "online") == 0) {
cpu_set(cpu, xenbus_allowed_cpumask);
(void)cpu_up(cpu);
} else if (strcmp(state, "offline") == 0) {
cpu_clear(cpu, xenbus_allowed_cpumask);
(void)cpu_down(cpu);
} else {
printk(KERN_ERR "XENBUS: unknown state(%s) on CPU%d\n",
@@ -353,6 +375,22 @@ static void handle_vcpu_hotplug_event(
}
}
static int smpboot_cpu_notify(struct notifier_block *notifier,
unsigned long action, void *hcpu)
{
int cpu = (long)hcpu;
/*
* We do this in a callback notifier rather than __cpu_disable()
* because local_cpu_hotplug_request() does not work in the latter
* as it's always executed from within a stopmachine kthread.
*/
if ((action == CPU_DOWN_PREPARE) && local_cpu_hotplug_request())
cpu_clear(cpu, local_allowed_cpumask);
return NOTIFY_OK;
}
static int setup_cpu_watcher(struct notifier_block *notifier,
unsigned long event, void *data)
{
@@ -360,7 +398,8 @@ static int setup_cpu_watcher(struct notifier_block *notifier,
static struct xenbus_watch cpu_watch = {
.node = "cpu",
.callback = handle_vcpu_hotplug_event };
.callback = handle_vcpu_hotplug_event,
.flags = XBWF_new_thread };
(void)register_xenbus_watch(&cpu_watch);
if (!(xen_start_info->flags & SIF_INITDOMAIN)) {
@@ -375,14 +414,62 @@ static int setup_cpu_watcher(struct notifier_block *notifier,
static int __init setup_vcpu_hotplug_event(void)
{
static struct notifier_block hotplug_cpu = {
.notifier_call = smpboot_cpu_notify };
static struct notifier_block xsn_cpu = {
.notifier_call = setup_cpu_watcher };
register_cpu_notifier(&hotplug_cpu);
register_xenstore_notifier(&xsn_cpu);
return 0;
}
arch_initcall(setup_vcpu_hotplug_event);
int smp_suspend(void)
{
int i, err;
lock_cpu_hotplug();
/*
* Take all other CPUs offline. We hold the hotplug mutex to
* avoid other processes bringing up CPUs under our feet.
*/
while (num_online_cpus() > 1) {
unlock_cpu_hotplug();
for_each_online_cpu(i) {
if (i == 0)
continue;
err = cpu_down(i);
if (err) {
printk(KERN_CRIT "Failed to take all CPUs "
"down: %d.\n", err);
for_each_cpu(i)
vcpu_hotplug(i);
return err;
}
}
lock_cpu_hotplug();
}
return 0;
}
void smp_resume(void)
{
int i;
for_each_cpu(i)
vcpu_prepare(i);
unlock_cpu_hotplug();
for_each_cpu(i)
vcpu_hotplug(i);
}
int __cpu_disable(void)
{
cpumask_t map = cpu_online_map;
@@ -415,6 +502,20 @@ void __cpu_die(unsigned int cpu)
#else /* !CONFIG_HOTPLUG_CPU */
int smp_suspend(void)
{
if (num_online_cpus() > 1) {
printk(KERN_WARNING "Can't suspend SMP guests "
"without CONFIG_HOTPLUG_CPU\n");
return -EOPNOTSUPP;
}
return 0;
}
void smp_resume(void)
{
}
int __cpu_disable(void)
{
return -ENOSYS;
@@ -429,6 +530,20 @@ void __cpu_die(unsigned int cpu)
int __devinit __cpu_up(unsigned int cpu)
{
int rc;
if (local_cpu_hotplug_request()) {
cpu_set(cpu, local_allowed_cpumask);
if (!cpu_isset(cpu, xenbus_allowed_cpumask)) {
printk("%s: attempt to bring up CPU %u disallowed by "
"remote admin.\n", __FUNCTION__, cpu);
return -EBUSY;
}
} else if (!cpu_isset(cpu, local_allowed_cpumask) ||
!cpu_isset(cpu, xenbus_allowed_cpumask)) {
return -EBUSY;
}
#ifdef CONFIG_SMP_ALTERNATIVES
if (num_online_cpus() == 1)
prepare_for_smp();
@@ -436,7 +551,9 @@ int __devinit __cpu_up(unsigned int cpu)
xen_smp_intr_init(cpu);
cpu_set(cpu, cpu_online_map);
if (HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL) != 0)
rc = HYPERVISOR_vcpu_op(VCPUOP_up, cpu, NULL);
if (rc != 0)
BUG();
return 0;
@@ -97,7 +97,6 @@ typedef struct netif_st {
#define NET_TX_RING_SIZE __RING_SIZE((netif_tx_sring_t *)0, PAGE_SIZE)
#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
void netif_creditlimit(netif_t *netif);
void netif_disconnect(netif_t *netif);
netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
@@ -31,6 +31,7 @@
*/
#include "common.h"
#include <linux/ethtool.h>
#include <linux/rtnetlink.h>
static void __netif_up(netif_t *netif)
@@ -71,6 +72,12 @@ static int net_close(struct net_device *dev)
return 0;
}
static struct ethtool_ops network_ethtool_ops =
{
.get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum,
};
netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
{
int err = 0, i;
@@ -101,7 +108,9 @@ netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN])
dev->get_stats = netif_be_get_stats;
dev->open = net_open;
dev->stop = net_close;
dev->features = NETIF_F_NO_CSUM;
dev->features = NETIF_F_IP_CSUM;
SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
/* Disable queuing. */
dev->tx_queue_len = 0;
@@ -293,25 +302,6 @@ void free_netif(netif_t *netif)
schedule_work(&netif->free_work);
}
void netif_creditlimit(netif_t *netif)
{
#if 0
/* Set the credit limit (reset remaining credit to new limit). */
netif->credit_bytes = creditlimit->credit_bytes;
netif->remaining_credit = creditlimit->credit_bytes;
netif->credit_usec = creditlimit->period_usec;
if (netif->status == CONNECTED) {
/*
* Schedule work so that any packets waiting under previous
* credit limit are dealt with (acts as a replenishment point).
*/
netif->credit_timeout.expires = jiffies;
netif_schedule_work(netif);
}
#endif
}
void netif_disconnect(netif_t *netif)
{
switch (netif->status) {
@@ -100,10 +100,10 @@ static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Defer checksum calculation. */
skb->proto_csum_blank = 1;
/* Must be a local packet: assert its integrity. */
skb->proto_csum_valid = 1;
skb->proto_data_valid = 1;
}
skb->ip_summed = skb->proto_csum_valid ?
skb->ip_summed = skb->proto_data_valid ?
CHECKSUM_UNNECESSARY : CHECKSUM_NONE;
skb->pkt_type = PACKET_HOST; /* overridden by eth_type_trans() */
@@ -121,6 +121,12 @@ static struct net_device_stats *loopback_get_stats(struct net_device *dev)
return &np->stats;
}
static struct ethtool_ops network_ethtool_ops =
{
.get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum,
};
static void loopback_construct(struct net_device *dev, struct net_device *lo)
{
struct net_private *np = netdev_priv(dev);
@@ -134,7 +140,11 @@ static void loopback_construct(struct net_device *dev, struct net_device *lo)
dev->tx_queue_len = 0;
dev->features = NETIF_F_HIGHDMA | NETIF_F_LLTX;
dev->features = (NETIF_F_HIGHDMA |
NETIF_F_LLTX |
NETIF_F_IP_CSUM);
SET_ETHTOOL_OPS(dev, &network_ethtool_ops);
/*
* We do not set a jumbo MTU on the interface. Otherwise the network
@@ -147,12 +157,6 @@ static void loopback_construct(struct net_device *dev, struct net_device *lo)
/*dev->mtu = 16*1024;*/
}
static struct ethtool_ops network_ethtool_ops =
{
.get_tx_csum = ethtool_op_get_tx_csum,
.set_tx_csum = ethtool_op_set_tx_csum,
};
static int __init make_loopback(int i)
{
struct net_device *dev1, *dev2;
@@ -172,11 +176,6 @@ static int __init make_loopback(int i)
loopback_construct(dev1, dev2);
loopback_construct(dev2, dev1);
dev1->features |= NETIF_F_NO_CSUM;
dev2->features |= NETIF_F_IP_CSUM;
SET_ETHTOOL_OPS(dev2, &network_ethtool_ops);
/*
* Initialise a dummy MAC address for the 'dummy backend' interface. We
* choose the numerically largest non-broadcast address to prevent the
@@ -171,7 +171,7 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev)
skb->len + hlen);
BUG_ON(ret);
nskb->dev = skb->dev;
nskb->proto_csum_valid = skb->proto_csum_valid;
nskb->proto_data_valid = skb->proto_data_valid;
dev_kfree_skb(skb);
skb = nskb;
}
@@ -213,7 +213,7 @@ static void net_rx_action(unsigned long unused)
{
netif_t *netif = NULL;
s8 status;
u16 size, id, irq;
u16 size, id, irq, flags;
multicall_entry_t *mcl;
mmu_update_t *mmu;
gnttab_transfer_t *gop;
@@ -301,9 +301,6 @@ static void net_rx_action(unsigned long unused)
netif = netdev_priv(skb->dev);
size = skb->tail - skb->data;
/* Rederive the machine addresses. */
new_mfn = mcl->args[1] >> PAGE_SHIFT;
old_mfn = gop->mfn;
atomic_set(&(skb_shinfo(skb)->dataref), 1);
skb_shinfo(skb)->nr_frags = 0;
skb_shinfo(skb)->frag_list = NULL;
@@ -328,10 +325,14 @@ static void net_rx_action(unsigned long unused)
}
irq = netif->irq;
id = RING_GET_REQUEST(&netif->rx, netif->rx.rsp_prod_pvt)->id;
flags = 0;
if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
flags |= NETRXF_csum_blank | NETRXF_data_validated;
else if (skb->proto_data_valid) /* remote but checksummed? */
flags |= NETRXF_data_validated;
if (make_rx_response(netif, id, status,
(unsigned long)skb->data & ~PAGE_MASK,
size, skb->proto_csum_valid ?
NETRXF_data_validated : 0) &&
size, flags) &&
(rx_notify[irq] == 0)) {
rx_notify[irq] = 1;
notify_list[notify_nr++] = irq;
@@ -655,11 +656,16 @@ static void net_tx_action(unsigned long unused)
skb->protocol = eth_type_trans(skb, skb->dev);
/*
* No checking needed on localhost, but remember the field is
* blank.
*/
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->proto_csum_valid = 1;
* Old frontends do not assert data_validated but we
* can infer it from csum_blank so test both flags.
*/
if (txreq.flags & (NETTXF_data_validated|NETTXF_csum_blank)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->proto_data_valid = 1;
} else {
skb->ip_summed = CHECKSUM_NONE;
skb->proto_data_valid = 0;
}
skb->proto_csum_blank = !!(txreq.flags & NETTXF_csum_blank);
netif->stats.rx_bytes += txreq.size;
@@ -92,7 +92,7 @@ static int netback_probe(struct xenbus_device *dev,
if (err)
goto fail;
err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
err = xenbus_switch_state(dev, XenbusStateInitWait);
if (err) {
goto fail;
}
@@ -209,7 +209,7 @@ static void frontend_changed(struct xenbus_device *dev,
break;
case XenbusStateClosing:
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
xenbus_switch_state(dev, XenbusStateClosing);
break;
case XenbusStateClosed:
@@ -233,9 +233,44 @@ static void frontend_changed(struct xenbus_device *dev,
static void maybe_connect(struct backend_info *be)
{
if (be->netif != NULL && be->frontend_state == XenbusStateConnected) {
if (be->netif && (be->frontend_state == XenbusStateConnected))
connect(be);
}
}
static void xen_net_read_rate(struct xenbus_device *dev,
unsigned long *bytes, unsigned long *usec)
{
char *s, *e;
unsigned long b, u;
char *ratestr;
/* Default to unlimited bandwidth. */
*bytes = ~0UL;
*usec = 0;
ratestr = xenbus_read(XBT_NULL, dev->nodename, "rate", NULL);
if (IS_ERR(ratestr))
return;
s = ratestr;
b = simple_strtoul(s, &e, 10);
if ((s == e) || (*e != ','))
goto fail;
s = e + 1;
u = simple_strtoul(s, &e, 10);
if ((s == e) || (*e != '\0'))
goto fail;
*bytes = b;
*usec = u;
kfree(ratestr);
return;
fail:
WPRINTK("Failed to parse network rate limit. Traffic unlimited.\n");
kfree(ratestr);
}
@@ -254,7 +289,11 @@ static void connect(struct backend_info *be)
return;
}
xenbus_switch_state(dev, XBT_NULL, XenbusStateConnected);
xen_net_read_rate(dev, &be->netif->credit_bytes,
&be->netif->credit_usec);
be->netif->remaining_credit = be->netif->credit_bytes;
xenbus_switch_state(dev, XenbusStateConnected);
}
@@ -300,13 +300,6 @@ again:
goto abort_transaction;
}
err = xenbus_printf(xbt, dev->nodename,
"state", "%d", XenbusStateConnected);
if (err) {
message = "writing frontend XenbusStateConnected";
goto abort_transaction;
}
err = xenbus_transaction_end(xbt, 0);
if (err) {
if (err == -EAGAIN)
@@ -315,6 +308,8 @@ again:
goto destroy_ring;
}
xenbus_switch_state(dev, XenbusStateConnected);
return 0;
abort_transaction:
@@ -696,7 +691,12 @@ static int network_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx->gref = np->grant_tx_ref[id] = ref;
tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
tx->size = skb->len;
tx->flags = (skb->ip_summed == CHECKSUM_HW) ? NETTXF_csum_blank : 0;
tx->flags = 0;
if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
if (skb->proto_data_valid) /* remote but checksummed? */
tx->flags |= NETTXF_data_validated;
np->tx.req_prod_pvt = i + 1;
RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&np->tx, notify);
@@ -811,8 +811,18 @@ static int netif_poll(struct net_device *dev, int *pbudget)
skb->len = rx->status;
skb->tail = skb->data + skb->len;
if (rx->flags & NETRXF_data_validated)
/*
* Old backends do not assert data_validated but we
* can infer it from csum_blank so test both flags.
*/
if (rx->flags & (NETRXF_data_validated|NETRXF_csum_blank)) {
skb->ip_summed = CHECKSUM_UNNECESSARY;
skb->proto_data_valid = 1;
} else {
skb->ip_summed = CHECKSUM_NONE;
skb->proto_data_valid = 0;
}
skb->proto_csum_blank = !!(rx->flags & NETRXF_csum_blank);
np->stats.rx_packets++;
np->stats.rx_bytes += rx->status;
@@ -978,8 +988,8 @@ static void network_connect(struct net_device *dev)
* the RX ring because some of our pages are currently flipped out
* so we can't just free the RX skbs.
* NB2. Freelist index entries are always going to be less than
* __PAGE_OFFSET, whereas pointers to skbs will always be equal or
* greater than __PAGE_OFFSET: we use this property to distinguish
* PAGE_OFFSET, whereas pointers to skbs will always be equal or
* greater than PAGE_OFFSET: we use this property to distinguish
* them.
*/
@@ -990,7 +1000,7 @@ static void network_connect(struct net_device *dev)
* interface has been down.
*/
for (requeue_idx = 0, i = 1; i <= NET_TX_RING_SIZE; i++) {
if ((unsigned long)np->tx_skbs[i] < __PAGE_OFFSET)
if ((unsigned long)np->tx_skbs[i] < PAGE_OFFSET)
continue;
skb = np->tx_skbs[i];
@@ -1006,8 +1016,11 @@ static void network_connect(struct net_device *dev)
tx->gref = np->grant_tx_ref[i];
tx->offset = (unsigned long)skb->data & ~PAGE_MASK;
tx->size = skb->len;
tx->flags = (skb->ip_summed == CHECKSUM_HW) ?
NETTXF_csum_blank : 0;
tx->flags = 0;
if (skb->ip_summed == CHECKSUM_HW) /* local packet? */
tx->flags |= NETTXF_csum_blank | NETTXF_data_validated;
if (skb->proto_data_valid) /* remote but checksummed? */
tx->flags |= NETTXF_data_validated;
np->stats.tx_bytes += skb->len;
np->stats.tx_packets++;
@@ -1018,7 +1031,7 @@ static void network_connect(struct net_device *dev)
/* Rebuild the RX buffer freelist and the RX ring itself. */
for (requeue_idx = 0, i = 1; i <= NET_RX_RING_SIZE; i++) {
if ((unsigned long)np->rx_skbs[i] < __PAGE_OFFSET)
if ((unsigned long)np->rx_skbs[i] < PAGE_OFFSET)
continue;
gnttab_grant_foreign_transfer_ref(
np->grant_rx_ref[i], np->xbdev->otherend_id,
@@ -1216,7 +1229,7 @@ static void netfront_closing(struct xenbus_device *dev)
close_netdev(info);
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
xenbus_switch_state(dev, XenbusStateClosed);
}
@@ -106,7 +106,7 @@ static inline int valid_request(int offset, int size)
}
static inline u32 merge_value(u32 val, u32 new_val, u32 new_val_mask,
u32 offset)
int offset)
{
if (offset >= 0) {
new_val_mask <<= (offset * 8);
@@ -180,7 +180,8 @@ int pciback_config_read(struct pci_dev *dev, int offset, int size,
if ((req_start >= field_start && req_start < field_end)
|| (req_end > field_start && req_end <= field_end)) {
err = conf_space_read(dev, cfg_entry, offset, &tmp_val);
err = conf_space_read(dev, cfg_entry, field_start,
&tmp_val);
if (err)
goto out;
@@ -228,14 +229,16 @@ int pciback_config_write(struct pci_dev *dev, int offset, int size, u32 value)
|| (req_end > field_start && req_end <= field_end)) {
tmp_val = 0;
err = pciback_config_read(dev, offset, size, &tmp_val);
err = pciback_config_read(dev, field_start,
field->size, &tmp_val);
if (err)
break;
tmp_val = merge_value(tmp_val, value, get_mask(size),
field_start - req_start);
req_start - field_start);
err = conf_space_write(dev, cfg_entry, offset, tmp_val);
err = conf_space_write(dev, cfg_entry, field_start,
tmp_val);
handled = 1;
}
}
@@ -16,7 +16,7 @@ static struct pciback_device *alloc_pdev(struct xenbus_device *xdev)
{
struct pciback_device *pdev;
pdev = kmalloc(sizeof(struct pciback_device), GFP_KERNEL);
pdev = kzalloc(sizeof(struct pciback_device), GFP_KERNEL);
if (pdev == NULL)
goto out;
dev_dbg(&xdev->dev, "allocated pdev @ 0x%p\n", pdev);
@@ -137,7 +137,7 @@ static int pciback_attach(struct pciback_device *pdev)
dev_dbg(&pdev->xdev->dev, "Connecting...\n");
err = xenbus_switch_state(pdev->xdev, XBT_NULL, XenbusStateConnected);
err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);
if (err)
xenbus_dev_fatal(pdev->xdev, err,
"Error switching to connected state!");
@@ -165,7 +165,7 @@ static void pciback_frontend_changed(struct xenbus_device *xdev,
break;
case XenbusStateClosing:
xenbus_switch_state(xdev, XBT_NULL, XenbusStateClosing);
xenbus_switch_state(xdev, XenbusStateClosing);
break;
case XenbusStateClosed:
@@ -341,7 +341,7 @@ static int pciback_setup_backend(struct pciback_device *pdev)
goto out;
}
err = xenbus_switch_state(pdev->xdev, XBT_NULL, XenbusStateInitialised);
err = xenbus_switch_state(pdev->xdev, XenbusStateInitialised);
if (err)
xenbus_dev_fatal(pdev->xdev, err,
"Error switching to initialised state!");
@@ -386,7 +386,7 @@ static int pciback_xenbus_probe(struct xenbus_device *dev,
}
/* wait for xend to configure us */
err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
err = xenbus_switch_state(dev, XenbusStateInitWait);
if (err)
goto out;
@@ -96,10 +96,6 @@ static int pcifront_publish_info(struct pcifront_device *pdev)
if (!err)
err = xenbus_printf(trans, pdev->xdev->nodename,
"magic", XEN_PCI_MAGIC);
if (!err)
err =
xenbus_switch_state(pdev->xdev, trans,
XenbusStateInitialised);
if (err) {
xenbus_transaction_end(trans, 1);
@@ -118,6 +114,8 @@ static int pcifront_publish_info(struct pcifront_device *pdev)
}
}
xenbus_switch_state(pdev->xdev, XenbusStateInitialised);
dev_dbg(&pdev->xdev->dev, "publishing successful!\n");
out:
@@ -186,7 +184,7 @@ static int pcifront_try_connect(struct pcifront_device *pdev)
}
}
err = xenbus_switch_state(pdev->xdev, XBT_NULL, XenbusStateConnected);
err = xenbus_switch_state(pdev->xdev, XenbusStateConnected);
if (err)
goto out;
@@ -205,8 +203,7 @@ static int pcifront_try_disconnect(struct pcifront_device *pdev)
prev_state = xenbus_read_driver_state(pdev->xdev->nodename);
if (prev_state < XenbusStateClosing)
err = xenbus_switch_state(pdev->xdev, XBT_NULL,
XenbusStateClosing);
err = xenbus_switch_state(pdev->xdev, XenbusStateClosing);
if (!err && prev_state == XenbusStateConnected)
pcifront_disconnect(pdev);
@@ -277,6 +277,7 @@ static int __init privcmd_init(void)
set_bit(__HYPERVISOR_mmu_update, hypercall_permission_map);
set_bit(__HYPERVISOR_mmuext_op, hypercall_permission_map);
set_bit(__HYPERVISOR_xen_version, hypercall_permission_map);
set_bit(__HYPERVISOR_sched_op, hypercall_permission_map);
privcmd_intf = create_xen_proc_entry("privcmd", 0400);
if (privcmd_intf != NULL)
@@ -55,6 +55,7 @@ static int tpmback_remove(struct xenbus_device *dev)
be->backend_watch.node = NULL;
}
if (be->tpmif) {
vtpm_release_packets(be->tpmif, 0);
tpmif_put(be->tpmif);
be->tpmif = NULL;
}
@@ -87,7 +88,7 @@ static int tpmback_probe(struct xenbus_device *dev,
goto fail;
}
err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
err = xenbus_switch_state(dev, XenbusStateInitWait);
if (err) {
goto fail;
}
@@ -175,7 +176,7 @@ static void frontend_changed(struct xenbus_device *dev,
break;
case XenbusStateClosing:
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
xenbus_switch_state(dev, XenbusStateClosing);
break;
case XenbusStateClosed:
@@ -247,18 +248,15 @@ again:
goto abort;
}
err = xenbus_switch_state(dev, xbt, XenbusStateConnected);
if (err)
goto abort;
be->tpmif->status = CONNECTED;
err = xenbus_transaction_end(xbt, 0);
if (err == -EAGAIN)
goto again;
if (err) {
if (err)
xenbus_dev_fatal(be->dev, err, "end of transaction");
}
err = xenbus_switch_state(dev, XenbusStateConnected);
if (!err)
be->tpmif->status = CONNECTED;
return;
abort:
xenbus_transaction_end(xbt, 1);
@@ -65,14 +65,18 @@ static irqreturn_t tpmif_int(int irq,
void *tpm_priv,
struct pt_regs *ptregs);
static void tpmif_rx_action(unsigned long unused);
static void tpmif_connect(struct tpm_private *tp, domid_t domid);
static int tpmif_connect(struct xenbus_device *dev,
struct tpm_private *tp,
domid_t domid);
static DECLARE_TASKLET(tpmif_rx_tasklet, tpmif_rx_action, 0);
static int tpm_allocate_buffers(struct tpm_private *tp);
static int tpmif_allocate_tx_buffers(struct tpm_private *tp);
static void tpmif_free_tx_buffers(struct tpm_private *tp);
static void tpmif_set_connected_state(struct tpm_private *tp,
u8 newstate);
static int tpm_xmit(struct tpm_private *tp,
const u8 * buf, size_t count, int userbuffer,
void *remember);
static void destroy_tpmring(struct tpm_private *tp);
#define DPRINTK(fmt, args...) \
pr_debug("xen_tpm_fr (%s:%d) " fmt, __FUNCTION__, __LINE__, ##args)
@@ -81,6 +85,8 @@ static int tpm_xmit(struct tpm_private *tp,
#define WPRINTK(fmt, args...) \
printk(KERN_WARNING "xen_tpm_fr: " fmt, ##args)
#define GRANT_INVALID_REF 0
static inline int
tx_buffer_copy(struct tx_buffer *txb, const u8 * src, int len,
@@ -119,6 +125,14 @@ static inline struct tx_buffer *tx_buffer_alloc(void)
}
static inline void tx_buffer_free(struct tx_buffer *txb)
{
if (txb) {
free_page((long)txb->data);
kfree(txb);
}
}
/**************************************************************
Utility function for the tpm_private structure
**************************************************************/
@@ -128,23 +142,29 @@ static inline void tpm_private_init(struct tpm_private *tp)
init_waitqueue_head(&tp->wait_q);
}
static inline void tpm_private_free(void)
{
tpmif_free_tx_buffers(my_priv);
kfree(my_priv);
my_priv = NULL;
}
static struct tpm_private *tpm_private_get(void)
{
int err;
if (!my_priv) {
my_priv = kzalloc(sizeof(struct tpm_private), GFP_KERNEL);
if (my_priv) {
tpm_private_init(my_priv);
err = tpmif_allocate_tx_buffers(my_priv);
if (err < 0) {
tpm_private_free();
}
}
}
return my_priv;
}
static inline void tpm_private_free(void)
{
kfree(my_priv);
my_priv = NULL;
}
/**************************************************************
The interface to let the tpm plugin register its callback
@@ -233,6 +253,8 @@ static int setup_tpmring(struct xenbus_device *dev,
tpmif_tx_interface_t *sring;
int err;
tp->ring_ref = GRANT_INVALID_REF;
sring = (void *)__get_free_page(GFP_KERNEL);
if (!sring) {
xenbus_dev_fatal(dev, -ENOMEM, "allocating shared ring");
@@ -240,8 +262,6 @@ static int setup_tpmring(struct xenbus_device *dev,
}
tp->tx = sring;
tpm_allocate_buffers(tp);
err = xenbus_grant_ring(dev, virt_to_mfn(tp->tx));
if (err < 0) {
free_page((unsigned long)sring);
@@ -251,14 +271,13 @@ static int setup_tpmring(struct xenbus_device *dev,
}
tp->ring_ref = err;
err = xenbus_alloc_evtchn(dev, &tp->evtchn);
err = tpmif_connect(dev, tp, dev->otherend_id);
if (err)
goto fail;
tpmif_connect(tp, dev->otherend_id);
return 0;
fail:
destroy_tpmring(tp);
return err;
}
@@ -266,14 +285,17 @@ fail:
static void destroy_tpmring(struct tpm_private *tp)
{
tpmif_set_connected_state(tp, 0);
if (tp->tx != NULL) {
if (tp->ring_ref != GRANT_INVALID_REF) {
gnttab_end_foreign_access(tp->ring_ref, 0,
(unsigned long)tp->tx);
tp->ring_ref = GRANT_INVALID_REF;
tp->tx = NULL;
}
if (tp->irq)
unbind_from_irqhandler(tp->irq, NULL);
unbind_from_irqhandler(tp->irq, tp);
tp->evtchn = tp->irq = 0;
}
@@ -377,6 +399,9 @@ static int tpmfront_probe(struct xenbus_device *dev,
int handle;
struct tpm_private *tp = tpm_private_get();
if (!tp)
return -ENOMEM;
err = xenbus_scanf(XBT_NULL, dev->nodename,
"handle", "%i", &handle);
if (XENBUS_EXIST_ERR(err))
@@ -402,15 +427,14 @@ static int tpmfront_probe(struct xenbus_device *dev,
static int tpmfront_remove(struct xenbus_device *dev)
{
struct tpm_private *tp = dev->data;
struct tpm_private *tp = (struct tpm_private *)dev->data;
destroy_tpmring(tp);
return 0;
}
static int
tpmfront_suspend(struct xenbus_device *dev)
static int tpmfront_suspend(struct xenbus_device *dev)
{
struct tpm_private *tp = dev->data;
struct tpm_private *tp = (struct tpm_private *)dev->data;
u32 ctr;
/* lock, so no app can send */
@@ -437,29 +461,35 @@ tpmfront_suspend(struct xenbus_device *dev)
return 0;
}
static int
tpmfront_resume(struct xenbus_device *dev)
static int tpmfront_resume(struct xenbus_device *dev)
{
struct tpm_private *tp = dev->data;
struct tpm_private *tp = (struct tpm_private *)dev->data;
destroy_tpmring(tp);
return talk_to_backend(dev, tp);
}
static void
tpmif_connect(struct tpm_private *tp, domid_t domid)
static int tpmif_connect(struct xenbus_device *dev,
struct tpm_private *tp,
domid_t domid)
{
int err;
tp->backend_id = domid;
err = xenbus_alloc_evtchn(dev, &tp->evtchn);
if (err)
return err;
err = bind_evtchn_to_irqhandler(tp->evtchn,
tpmif_int, SA_SAMPLE_RANDOM, "tpmif",
tp);
if (err <= 0) {
WPRINTK("bind_evtchn_to_irqhandler failed (err=%d)\n", err);
return;
return err;
}
tp->irq = err;
return 0;
}
static struct xenbus_device_id tpmfront_ids[] = {
@@ -488,19 +518,30 @@ static void __exit exit_tpm_xenbus(void)
xenbus_unregister_driver(&tpmfront);
}
static int
tpm_allocate_buffers(struct tpm_private *tp)
static int tpmif_allocate_tx_buffers(struct tpm_private *tp)
{
unsigned int i;
for (i = 0; i < TPMIF_TX_RING_SIZE; i++)
for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
tp->tx_buffers[i] = tx_buffer_alloc();
return 1;
if (!tp->tx_buffers[i]) {
tpmif_free_tx_buffers(tp);
return -ENOMEM;
}
}
return 0;
}
static void
tpmif_rx_action(unsigned long priv)
static void tpmif_free_tx_buffers(struct tpm_private *tp)
{
unsigned int i;
for (i = 0; i < TPMIF_TX_RING_SIZE; i++) {
tx_buffer_free(tp->tx_buffers[i]);
}
}
static void tpmif_rx_action(unsigned long priv)
{
struct tpm_private *tp = (struct tpm_private *)priv;
@@ -545,8 +586,7 @@ exit:
}
static irqreturn_t
tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
static irqreturn_t tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
{
struct tpm_private *tp = tpm_priv;
unsigned long flags;
@@ -560,10 +600,9 @@ tpmif_int(int irq, void *tpm_priv, struct pt_regs *ptregs)
}
static int
tpm_xmit(struct tpm_private *tp,
const u8 * buf, size_t count, int isuserbuffer,
void *remember)
static int tpm_xmit(struct tpm_private *tp,
const u8 * buf, size_t count, int isuserbuffer,
void *remember)
{
tpmif_tx_request_t *tx;
TPMIF_RING_IDX i;
@@ -693,8 +732,7 @@ static void tpmif_set_connected_state(struct tpm_private *tp, u8 is_connected)
* =================================================================
*/
static int __init
tpmif_init(void)
static int __init tpmif_init(void)
{
IPRINTK("Initialising the vTPM driver.\n");
if ( gnttab_alloc_grant_references ( TPMIF_TX_RING_SIZE,
@@ -709,8 +747,7 @@ tpmif_init(void)
module_init(tpmif_init);
static void __exit
tpmif_exit(void)
static void __exit tpmif_exit(void)
{
exit_tpm_xenbus();
gnttab_free_grant_references(gref_head);
@@ -1,4 +1,8 @@
obj-y += xenbus.o
obj-$(CONFIG_XEN_BACKEND) += xenbus_be.o
xenbus_be-objs =
xenbus_be-objs += xenbus_backend_client.o
xenbus-objs =
xenbus-objs += xenbus_client.o
@@ -0,0 +1,173 @@
/******************************************************************************
* Backend-client-facing interface for the Xenbus driver. In other words, the
* interface between the Xenbus and the device-specific code in the backend
* driver.
*
* Copyright (C) 2005-2006 XenSource Ltd
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
* as published by the Free Software Foundation; or, when distributed
* separately from the Linux kernel or incorporated into other
* software packages, subject to the following license:
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this source file (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 <xen/gnttab.h>
#include <xen/xenbus.h>
#include <xen/driver_util.h>
/* Based on Rusty Russell's skeleton driver's map_page */
int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
{
struct gnttab_map_grant_ref op = {
.flags = GNTMAP_host_map,
.ref = gnt_ref,
.dom = dev->otherend_id,
};
struct vm_struct *area;
*vaddr = NULL;
area = alloc_vm_area(PAGE_SIZE);
if (!area)
return -ENOMEM;
op.host_addr = (unsigned long)area->addr;
lock_vm_area(area);
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
unlock_vm_area(area);
if (op.status != GNTST_okay) {
free_vm_area(area);
xenbus_dev_fatal(dev, op.status,
"mapping in shared page %d from domain %d",
gnt_ref, dev->otherend_id);
return op.status;
}
/* Stuff the handle in an unused field */
area->phys_addr = (unsigned long)op.handle;
*vaddr = area->addr;
return 0;
}
EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
grant_handle_t *handle, void *vaddr)
{
struct gnttab_map_grant_ref op = {
.host_addr = (unsigned long)vaddr,
.flags = GNTMAP_host_map,
.ref = gnt_ref,
.dom = dev->otherend_id,
};
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
if (op.status != GNTST_okay) {
xenbus_dev_fatal(dev, op.status,
"mapping in shared page %d from domain %d",
gnt_ref, dev->otherend_id);
} else
*handle = op.handle;
return op.status;
}
EXPORT_SYMBOL_GPL(xenbus_map_ring);
/* Based on Rusty Russell's skeleton driver's unmap_page */
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
{
struct vm_struct *area;
struct gnttab_unmap_grant_ref op = {
.host_addr = (unsigned long)vaddr,
};
/* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
* method so that we don't have to muck with vmalloc internals here.
* We could force the user to hang on to their struct vm_struct from
* xenbus_map_ring_valloc, but these 6 lines considerably simplify
* this API.
*/
read_lock(&vmlist_lock);
for (area = vmlist; area != NULL; area = area->next) {
if (area->addr == vaddr)
break;
}
read_unlock(&vmlist_lock);
if (!area) {
xenbus_dev_error(dev, -ENOENT,
"can't find mapped virtual address %p", vaddr);
return GNTST_bad_virt_addr;
}
op.handle = (grant_handle_t)area->phys_addr;
lock_vm_area(area);
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
unlock_vm_area(area);
if (op.status == GNTST_okay)
free_vm_area(area);
else
xenbus_dev_error(dev, op.status,
"unmapping page at handle %d error %d",
(int16_t)area->phys_addr, op.status);
return op.status;
}
EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
int xenbus_unmap_ring(struct xenbus_device *dev,
grant_handle_t handle, void *vaddr)
{
struct gnttab_unmap_grant_ref op = {
.host_addr = (unsigned long)vaddr,
.handle = handle,
};
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
if (op.status != GNTST_okay)
xenbus_dev_error(dev, op.status,
"unmapping page at handle %d error %d",
handle, op.status);
return op.status;
}
EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
/*
* Local variables:
* c-file-style: "linux"
* indent-tabs-mode: t
* c-indent-level: 8
* c-basic-offset: 8
* tab-width: 8
* End:
*/
@@ -84,9 +84,7 @@ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
EXPORT_SYMBOL_GPL(xenbus_watch_path2);
int xenbus_switch_state(struct xenbus_device *dev,
xenbus_transaction_t xbt,
XenbusState state)
int xenbus_switch_state(struct xenbus_device *dev, XenbusState state)
{
/* We check whether the state is currently set to the given value, and
if not, then the state is set. We don't want to unconditionally
@@ -94,6 +92,12 @@ int xenbus_switch_state(struct xenbus_device *dev,
unnecessarily. Furthermore, if the node has gone, we don't write
to it, as the device will be tearing down, and we don't want to
resurrect that directory.
Note that, because of this cached value of our state, this function
will not work inside a Xenstore transaction (something it was
trying to in the past) because dev->state would not get reset if
the transaction was aborted.
*/
int current_state;
@@ -102,12 +106,12 @@ int xenbus_switch_state(struct xenbus_device *dev,
if (state == dev->state)
return 0;
err = xenbus_scanf(xbt, dev->nodename, "state", "%d",
&current_state);
err = xenbus_scanf(XBT_NULL, dev->nodename, "state", "%d",
&current_state);
if (err != 1)
return 0;
err = xenbus_printf(xbt, dev->nodename, "state", "%d", state);
err = xenbus_printf(XBT_NULL, dev->nodename, "state", "%d", state);
if (err) {
if (state != XenbusStateClosing) /* Avoid looping */
xenbus_dev_fatal(dev, err, "writing new state");
@@ -193,7 +197,7 @@ void xenbus_dev_fatal(struct xenbus_device *dev, int err, const char *fmt,
_dev_error(dev, err, fmt, ap);
va_end(ap);
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
xenbus_switch_state(dev, XenbusStateClosing);
}
EXPORT_SYMBOL_GPL(xenbus_dev_fatal);
@@ -257,134 +261,6 @@ int xenbus_free_evtchn(struct xenbus_device *dev, int port)
}
/* Based on Rusty Russell's skeleton driver's map_page */
int xenbus_map_ring_valloc(struct xenbus_device *dev, int gnt_ref, void **vaddr)
{
struct gnttab_map_grant_ref op = {
.flags = GNTMAP_host_map,
.ref = gnt_ref,
.dom = dev->otherend_id,
};
struct vm_struct *area;
*vaddr = NULL;
area = alloc_vm_area(PAGE_SIZE);
if (!area)
return -ENOMEM;
op.host_addr = (unsigned long)area->addr;
lock_vm_area(area);
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
unlock_vm_area(area);
if (op.status != GNTST_okay) {
free_vm_area(area);
xenbus_dev_fatal(dev, op.status,
"mapping in shared page %d from domain %d",
gnt_ref, dev->otherend_id);
return op.status;
}
/* Stuff the handle in an unused field */
area->phys_addr = (unsigned long)op.handle;
*vaddr = area->addr;
return 0;
}
EXPORT_SYMBOL_GPL(xenbus_map_ring_valloc);
int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
grant_handle_t *handle, void *vaddr)
{
struct gnttab_map_grant_ref op = {
.host_addr = (unsigned long)vaddr,
.flags = GNTMAP_host_map,
.ref = gnt_ref,
.dom = dev->otherend_id,
};
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1));
if (op.status != GNTST_okay) {
xenbus_dev_fatal(dev, op.status,
"mapping in shared page %d from domain %d",
gnt_ref, dev->otherend_id);
} else
*handle = op.handle;
return op.status;
}
EXPORT_SYMBOL_GPL(xenbus_map_ring);
/* Based on Rusty Russell's skeleton driver's unmap_page */
int xenbus_unmap_ring_vfree(struct xenbus_device *dev, void *vaddr)
{
struct vm_struct *area;
struct gnttab_unmap_grant_ref op = {
.host_addr = (unsigned long)vaddr,
};
/* It'd be nice if linux/vmalloc.h provided a find_vm_area(void *addr)
* method so that we don't have to muck with vmalloc internals here.
* We could force the user to hang on to their struct vm_struct from
* xenbus_map_ring_valloc, but these 6 lines considerably simplify
* this API.
*/
read_lock(&vmlist_lock);
for (area = vmlist; area != NULL; area = area->next) {
if (area->addr == vaddr)
break;
}
read_unlock(&vmlist_lock);
if (!area) {
xenbus_dev_error(dev, -ENOENT,
"can't find mapped virtual address %p", vaddr);
return GNTST_bad_virt_addr;
}
op.handle = (grant_handle_t)area->phys_addr;
lock_vm_area(area);
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
unlock_vm_area(area);
if (op.status == GNTST_okay)
free_vm_area(area);
else
xenbus_dev_error(dev, op.status,
"unmapping page at handle %d error %d",
(int16_t)area->phys_addr, op.status);
return op.status;
}
EXPORT_SYMBOL_GPL(xenbus_unmap_ring_vfree);
int xenbus_unmap_ring(struct xenbus_device *dev,
grant_handle_t handle, void *vaddr)
{
struct gnttab_unmap_grant_ref op = {
.host_addr = (unsigned long)vaddr,
.handle = handle,
};
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
if (op.status != GNTST_okay)
xenbus_dev_error(dev, op.status,
"unmapping page at handle %d error %d",
handle, op.status);
return op.status;
}
EXPORT_SYMBOL_GPL(xenbus_unmap_ring);
XenbusState xenbus_read_driver_state(const char *path)
{
XenbusState result;
@@ -3,7 +3,7 @@
*
* Copyright (C) 2005 Rusty Russell, IBM Corporation
* Copyright (C) 2005 Mike Wray, Hewlett-Packard
* Copyright (C) 2005 XenSource Ltd
* Copyright (C) 2005, 2006 XenSource Ltd
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License version 2
@@ -49,6 +49,7 @@
#include <xen/xenbus.h>
#include <xen/xen_proc.h>
#include <xen/evtchn.h>
#include <xen/features.h>
#include "xenbus_comms.h"
@@ -364,7 +365,7 @@ static int xenbus_dev_probe(struct device *_dev)
return 0;
fail:
xenbus_dev_error(dev, err, "xenbus_dev_probe on %s", dev->nodename);
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
xenbus_switch_state(dev, XenbusStateClosed);
return -ENODEV;
}
@@ -381,7 +382,7 @@ static int xenbus_dev_remove(struct device *_dev)
if (drv->remove)
drv->remove(dev);
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
xenbus_switch_state(dev, XenbusStateClosed);
return 0;
}
@@ -882,7 +883,7 @@ static int all_devices_ready_(struct device *dev, void *data)
int *result = data;
if (xendev->state != XenbusStateConnected) {
result = 0;
*result = 0;
return 1;
}
@@ -901,8 +902,6 @@ static int all_devices_ready(void)
void xenbus_probe(void *unused)
{
int i;
BUG_ON((xenstored_ready <= 0));
/* Enumerate devices in xenstore. */
@@ -915,28 +914,6 @@ void xenbus_probe(void *unused)
/* Notify others that xenstore is up */
notifier_call_chain(&xenstore_chain, 0, NULL);
/* On a 10 second timeout, waiting for all devices currently
configured. We need to do this to guarantee that the filesystems
and / or network devices needed for boot are available, before we
can allow the boot to proceed.
A possible improvement here would be to have the tools add a
per-device flag to the store entry, indicating whether it is needed
at boot time. This would allow people who knew what they were
doing to accelerate their boot slightly, but of course needs tools
or manual intervention to set up those flags correctly.
*/
for (i = 0; i < 10 * HZ; i++) {
if (all_devices_ready())
return;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
}
printk(KERN_WARNING
"XENBUS: Timeout connecting to devices!\n");
}
@@ -983,6 +960,7 @@ static int xsd_port_read(char *page, char **start, off_t off,
static int __init xenbus_probe_init(void)
{
int err = 0, dom0;
unsigned long page = 0;
DPRINTK("");
@@ -991,11 +969,9 @@ static int __init xenbus_probe_init(void)
return -ENODEV;
}
/* Register ourselves with the kernel bus & device subsystems */
/* Register ourselves with the kernel bus subsystem */
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 or store_mfn yet.
@@ -1003,11 +979,7 @@ static int __init xenbus_probe_init(void)
dom0 = (xen_start_info->store_evtchn == 0);
if (dom0) {
unsigned long page;
evtchn_op_t op = { 0 };
int ret;
/* Allocate page. */
page = get_zeroed_page(GFP_KERNEL);
@@ -1023,8 +995,10 @@ static int __init xenbus_probe_init(void)
op.u.alloc_unbound.dom = DOMID_SELF;
op.u.alloc_unbound.remote_dom = 0;
ret = HYPERVISOR_event_channel_op(&op);
BUG_ON(ret);
err = HYPERVISOR_event_channel_op(&op);
if (err == -ENOSYS)
goto err;
BUG_ON(err);
xen_start_info->store_evtchn = op.u.alloc_unbound.port;
/* And finally publish the above info in /proc/xen */
@@ -1047,17 +1021,65 @@ static int __init xenbus_probe_init(void)
if (err) {
printk(KERN_WARNING
"XENBUS: Error initializing xenstore comms: %i\n", err);
return err;
goto err;
}
/* Register ourselves with the kernel device subsystem */
device_register(&xenbus_frontend.dev);
device_register(&xenbus_backend.dev);
if (!dom0)
xenbus_probe(NULL);
return 0;
err:
if (page)
free_page(page);
/*
* Do not unregister the xenbus front/backend buses here. The
* buses must exist because front/backend drivers will use
* them when they are registered.
*/
return err;
}
postcore_initcall(xenbus_probe_init);
/*
* On a 10 second timeout, wait for all devices currently configured. We need
* to do this to guarantee that the filesystems and / or network devices
* needed for boot are available, before we can allow the boot to proceed.
*
* This needs to be on a late_initcall, to happen after the frontend device
* drivers have been initialised, but before the root fs is mounted.
*
* A possible improvement here would be to have the tools add a per-device
* flag to the store entry, indicating whether it is needed at boot time.
* This would allow people who knew what they were doing to accelerate their
* boot slightly, but of course needs tools or manual intervention to set up
* those flags correctly.
*/
static int __init wait_for_devices(void)
{
unsigned long timeout = jiffies + 10*HZ;
while (time_before(jiffies, timeout)) {
if (all_devices_ready())
return 0;
schedule_timeout_interruptible(HZ/10);
}
printk(KERN_WARNING "XENBUS: Timeout connecting to devices!\n");
return 0;
}
late_initcall(wait_for_devices);
/*
* Local variables:
* c-file-style: "linux"
@@ -685,6 +685,24 @@ void xs_resume(void)
up_write(&xs_state.suspend_mutex);
}
static int xenwatch_handle_callback(void *data)
{
struct xs_stored_msg *msg = data;
msg->u.watch.handle->callback(msg->u.watch.handle,
(const char **)msg->u.watch.vec,
msg->u.watch.vec_size);
kfree(msg->u.watch.vec);
kfree(msg);
/* Kill this kthread if we were spawned just for this callback. */
if (current->pid != xenwatch_pid)
do_exit(0);
return 0;
}
static int xenwatch_thread(void *unused)
{
struct list_head *ent;
@@ -707,12 +725,11 @@ static int xenwatch_thread(void *unused)
if (ent != &watch_events) {
msg = list_entry(ent, struct xs_stored_msg, list);
msg->u.watch.handle->callback(
msg->u.watch.handle,
(const char **)msg->u.watch.vec,
msg->u.watch.vec_size);
kfree(msg->u.watch.vec);
kfree(msg);
if (msg->u.watch.handle->flags & XBWF_new_thread)
kthread_run(xenwatch_handle_callback,
msg, "xenwatch_cb");
else
xenwatch_handle_callback(msg);
}
mutex_unlock(&xenwatch_mutex);
@@ -33,10 +33,9 @@
#ifndef __HYPERCALL_H__
#define __HYPERCALL_H__
#include <xen/interface/xen.h>
#include <xen/interface/sched.h>
#include <xen/interface/nmi.h>
#include <linux/errno.h>
#ifndef __HYPERVISOR_H__
# error "please don't include this file directly"
#endif
#define __STR(x) #x
#define STR(x) __STR(x)
@@ -167,35 +166,17 @@ HYPERVISOR_fpu_taskswitch(
}
static inline int
HYPERVISOR_sched_op(
HYPERVISOR_sched_op_compat(
int cmd, unsigned long arg)
{
return _hypercall2(int, sched_op, cmd, arg);
return _hypercall2(int, sched_op_compat, cmd, arg);
}
static inline int
HYPERVISOR_sched_op_new(
HYPERVISOR_sched_op(
int cmd, void *arg)
{
return _hypercall2(int, sched_op_new, cmd, arg);
}
static inline int
HYPERVISOR_poll(
evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
{
struct sched_poll sched_poll = {
.ports = ports,
.nr_ports = nr_ports,
.timeout = jiffies_to_st(timeout)
};
int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0);
return rc;
return _hypercall2(int, sched_op, cmd, arg);
}
static inline long
@@ -327,8 +308,18 @@ static inline int
HYPERVISOR_suspend(
unsigned long srec)
{
return _hypercall3(int, sched_op, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
struct sched_shutdown sched_shutdown = {
.reason = SHUTDOWN_suspend
};
int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
&sched_shutdown, srec);
if (rc == -ENOSYS)
rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
return rc;
}
static inline int
@@ -338,6 +329,21 @@ HYPERVISOR_nmi_op(
return _hypercall2(int, nmi_op, op, arg);
}
static inline int
HYPERVISOR_callback_op(
int cmd, void *arg)
{
return _hypercall2(int, callback_op, cmd, arg);
}
static inline int
HYPERVISOR_xenoprof_op(
int op, unsigned long arg1, unsigned long arg2)
{
return _hypercall3(int, xenoprof_op, op, arg1, arg2);
}
#endif /* __HYPERCALL_H__ */
/*
@@ -37,8 +37,11 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>
#include <xen/interface/xen.h>
#include <xen/interface/dom0_ops.h>
#include <xen/interface/sched.h>
#include <xen/interface/nmi.h>
#include <asm/ptrace.h>
#include <asm/page.h>
#if defined(__i386__)
@@ -115,6 +118,64 @@ u64 jiffies_to_st(unsigned long jiffies);
#define xen_init() (0)
static inline int
HYPERVISOR_yield(
void)
{
int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
return rc;
}
static inline int
HYPERVISOR_block(
void)
{
int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
return rc;
}
static inline int
HYPERVISOR_shutdown(
unsigned int reason)
{
struct sched_shutdown sched_shutdown = {
.reason = reason
};
int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
return rc;
}
static inline int
HYPERVISOR_poll(
evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
{
struct sched_poll sched_poll = {
.ports = ports,
.nr_ports = nr_ports,
.timeout = jiffies_to_st(timeout)
};
int rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
return rc;
}
static inline void
MULTI_update_va_mapping(
multicall_entry_t *mcl, unsigned long va,
@@ -102,6 +102,7 @@ static inline void * phys_to_virt(unsigned long address)
*/
#define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
#define page_to_phys(page) (phys_to_machine(page_to_pseudophys(page)))
#define page_to_bus(page) (phys_to_machine(page_to_pseudophys(page)))
#define bio_to_pseudophys(bio) (page_to_pseudophys(bio_page((bio))) + \
(unsigned long) bio_offset((bio)))
@@ -6,6 +6,8 @@
* use of all of the static functions.
**/
#include <xen/interface/callback.h>
static char * __init machine_specific_memory_setup(void)
{
unsigned long max_pfn = xen_start_info->nr_pages;
@@ -23,6 +25,14 @@ extern void nmi(void);
static void __init machine_specific_arch_setup(void)
{
struct xen_platform_parameters pp;
struct callback_register event = {
.type = CALLBACKTYPE_event,
.address = { __KERNEL_CS, (unsigned long)hypervisor_callback },
};
struct callback_register failsafe = {
.type = CALLBACKTYPE_failsafe,
.address = { __KERNEL_CS, (unsigned long)failsafe_callback },
};
struct xennmi_callback cb;
if (xen_feature(XENFEAT_auto_translated_physmap) &&
@@ -32,9 +42,8 @@ static void __init machine_specific_arch_setup(void)
memset(empty_zero_page, 0, sizeof(empty_zero_page));
}
HYPERVISOR_set_callbacks(
__KERNEL_CS, (unsigned long)hypervisor_callback,
__KERNEL_CS, (unsigned long)failsafe_callback);
HYPERVISOR_callback_op(CALLBACKOP_register, &event);
HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
cb.handler_address = (unsigned long)&nmi;
HYPERVISOR_nmi_op(XENNMI_register_callback, &cb);
@@ -33,11 +33,9 @@
#ifndef __HYPERCALL_H__
#define __HYPERCALL_H__
#include <xen/interface/xen.h>
#include <xen/interface/sched.h>
#include <xen/interface/dom0_ops.h>
#include <linux/errno.h>
#include <asm/hypervisor.h> // for jiffies_to_st()
#ifndef __HYPERVISOR_H__
# error "please don't include this file directly"
#endif
/* FIXME: temp place to hold these page related macros */
#include <asm/page.h>
@@ -165,35 +163,17 @@
})
static inline int
HYPERVISOR_sched_op(
HYPERVISOR_sched_op_compat(
int cmd, unsigned long arg)
{
return _hypercall2(int, sched_op, cmd, arg);
return _hypercall2(int, sched_op_compat, cmd, arg);
}
static inline int
HYPERVISOR_sched_op_new(
HYPERVISOR_sched_op(
int cmd, void *arg)
{
return _hypercall2(int, sched_op_new, cmd, arg);
}
static inline int
HYPERVISOR_poll(
evtchn_port_t *ports, unsigned int nr_ports, unsigned long timeout)
{
struct sched_poll sched_poll = {
.ports = ports,
.nr_ports = nr_ports,
.timeout = jiffies_to_st(timeout)
};
int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0);
return rc;
return _hypercall2(int, sched_op, cmd, arg);
}
static inline long
@@ -273,8 +253,18 @@ static inline int
HYPERVISOR_suspend(
unsigned long srec)
{
return _hypercall3(int, sched_op, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
struct sched_shutdown sched_shutdown = {
.reason = SHUTDOWN_suspend
};
int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
&sched_shutdown, srec);
if (rc == -ENOSYS)
rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
return rc;
}
extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
@@ -37,8 +37,10 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>
#include <xen/interface/xen.h>
#include <xen/interface/dom0_ops.h>
#include <xen/interface/sched.h>
#include <asm/ptrace.h>
#include <asm/page.h>
#include <asm/xen/privop.h> // for running_on_xen
@@ -55,6 +57,64 @@ int xen_init(void);
#include <asm/hypercall.h>
static inline int
HYPERVISOR_yield(
void)
{
int rc = HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
return rc;
}
static inline int
HYPERVISOR_block(
void)
{
int rc = HYPERVISOR_sched_op(SCHEDOP_block, NULL);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_block, 0);
return rc;
}
static inline int
HYPERVISOR_shutdown(
unsigned int reason)
{
struct sched_shutdown sched_shutdown = {
.reason = reason
};
int rc = HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_shutdown, reason);
return rc;
}
static inline int
HYPERVISOR_poll(
evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
{
struct sched_poll sched_poll = {
.ports = ports,
.nr_ports = nr_ports,
.timeout = jiffies_to_st(timeout)
};
int rc = HYPERVISOR_sched_op(SCHEDOP_poll, &sched_poll);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op_compat(SCHEDOP_yield, 0);
return rc;
}
// for drivers/xen/privcmd/privcmd.c
#define direct_remap_pfn_range(a,b,c,d,e,f) remap_pfn_range(a,b,c,d,e)
#define pfn_to_mfn(x) (x)
@@ -37,10 +37,9 @@
#ifndef __HYPERCALL_H__
#define __HYPERCALL_H__
#include <xen/interface/xen.h>
#include <xen/interface/sched.h>
#include <xen/interface/nmi.h>
#include <linux/errno.h>
#ifndef __HYPERVISOR_H__
# error "please don't include this file directly"
#endif
#define __STR(x) #x
#define STR(x) __STR(x)
@@ -172,35 +171,17 @@ HYPERVISOR_fpu_taskswitch(
}
static inline int
HYPERVISOR_sched_op(
HYPERVISOR_sched_op_compat(
int cmd, unsigned long arg)
{
return _hypercall2(int, sched_op, cmd, arg);
return _hypercall2(int, sched_op_compat, cmd, arg);
}
static inline int
HYPERVISOR_sched_op_new(
HYPERVISOR_sched_op(
int cmd, void *arg)
{
return _hypercall2(int, sched_op_new, cmd, arg);
}
static inline int
HYPERVISOR_poll(
evtchn_port_t *ports, unsigned int nr_ports, u64 timeout)
{
struct sched_poll sched_poll = {
.ports = ports,
.nr_ports = nr_ports,
.timeout = jiffies_to_st(timeout)
};
int rc = HYPERVISOR_sched_op_new(SCHEDOP_poll, &sched_poll);
if (rc == -ENOSYS)
rc = HYPERVISOR_sched_op(SCHEDOP_yield, 0);
return rc;
return _hypercall2(int, sched_op, cmd, arg);
}
static inline long
@@ -328,8 +309,18 @@ static inline int
HYPERVISOR_suspend(
unsigned long srec)
{
return _hypercall3(int, sched_op, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
struct sched_shutdown sched_shutdown = {
.reason = SHUTDOWN_suspend
};
int rc = _hypercall3(int, sched_op, SCHEDOP_shutdown,
&sched_shutdown, srec);
if (rc == -ENOSYS)
rc = _hypercall3(int, sched_op_compat, SCHEDOP_shutdown,
SHUTDOWN_suspend, srec);
return rc;
}
static inline int
@@ -339,6 +330,20 @@ HYPERVISOR_nmi_op(
return _hypercall2(int, nmi_op, op, arg);
}
static inline int
HYPERVISOR_callback_op(
int cmd, void *arg)
{
return _hypercall2(int, callback_op, cmd, arg);
}
static inline int
HYPERVISOR_xenoprof_op(
int op, unsigned long arg1, unsigned long arg2)
{
return _hypercall3(int, xenoprof_op, op, arg1, arg2);
}
#endif /* __HYPERCALL_H__ */
/*
@@ -130,6 +130,7 @@ static inline void * phys_to_virt(unsigned long address)
*/
#define page_to_pseudophys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
#define page_to_phys(page) (phys_to_machine(page_to_pseudophys(page)))
#define page_to_bus(page) (phys_to_machine(page_to_pseudophys(page)))
#define bio_to_pseudophys(bio) (page_to_pseudophys(bio_page((bio))) + \
(unsigned long) bio_offset((bio)))
@@ -6,20 +6,33 @@
* use of all of the static functions.
**/
#include <xen/interface/callback.h>
extern void hypervisor_callback(void);
extern void failsafe_callback(void);
extern void nmi(void);
static void __init machine_specific_arch_setup(void)
{
struct callback_register event = {
.type = CALLBACKTYPE_event,
.address = (unsigned long) hypervisor_callback,
};
struct callback_register failsafe = {
.type = CALLBACKTYPE_failsafe,
.address = (unsigned long)failsafe_callback,
};
struct callback_register syscall = {
.type = CALLBACKTYPE_syscall,
.address = (unsigned long)system_call,
};
#ifdef CONFIG_X86_LOCAL_APIC
struct xennmi_callback cb;
#endif
HYPERVISOR_set_callbacks(
(unsigned long) hypervisor_callback,
(unsigned long) failsafe_callback,
(unsigned long) system_call);
HYPERVISOR_callback_op(CALLBACKOP_register, &event);
HYPERVISOR_callback_op(CALLBACKOP_register, &failsafe);
HYPERVISOR_callback_op(CALLBACKOP_register, &syscall);
#ifdef CONFIG_X86_LOCAL_APIC
cb.handler_address = (unsigned long)&nmi;
-244
View File
@@ -1,244 +0,0 @@
#ifndef __irq_h
#define __irq_h
/*
* Please do not include this file in generic code. There is currently
* no requirement for any architecture to implement anything held
* within this file.
*
* Thanks. --rmk
*/
#include <linux/config.h>
#include <linux/smp.h>
#if !defined(CONFIG_S390)
#include <linux/linkage.h>
#include <linux/cache.h>
#include <linux/spinlock.h>
#include <linux/cpumask.h>
#include <asm/irq.h>
#include <asm/ptrace.h>
/*
* IRQ line status.
*/
#define IRQ_INPROGRESS 1 /* IRQ handler active - do not enter! */
#define IRQ_DISABLED 2 /* IRQ disabled - do not enter! */
#define IRQ_PENDING 4 /* IRQ pending - replay on enable */
#define IRQ_REPLAY 8 /* IRQ has been replayed but not acked yet */
#define IRQ_AUTODETECT 16 /* IRQ is being autodetected */
#define IRQ_WAITING 32 /* IRQ not yet seen - for autodetection */
#define IRQ_LEVEL 64 /* IRQ level triggered */
#define IRQ_MASKED 128 /* IRQ masked - shouldn't be seen again */
#if defined(ARCH_HAS_IRQ_PER_CPU)
# define IRQ_PER_CPU 256 /* IRQ is per CPU */
# define CHECK_IRQ_PER_CPU(var) ((var) & IRQ_PER_CPU)
#else
# define CHECK_IRQ_PER_CPU(var) 0
#endif
/*
* Interrupt controller descriptor. This is all we need
* to describe about the low-level hardware.
*/
struct hw_interrupt_type {
const char * typename;
unsigned int (*startup)(unsigned int irq);
void (*shutdown)(unsigned int irq);
void (*enable)(unsigned int irq);
void (*disable)(unsigned int irq);
void (*ack)(unsigned int irq);
void (*end)(unsigned int irq);
void (*set_affinity)(unsigned int irq, cpumask_t dest);
/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
void (*release)(unsigned int irq, void *dev_id);
#endif
};
typedef struct hw_interrupt_type hw_irq_controller;
/*
* This is the "IRQ descriptor", which contains various information
* about the irq, including what kind of hardware handling it has,
* whether it is disabled etc etc.
*
* Pad this out to 32 bytes for cache and indexing reasons.
*/
typedef struct irq_desc {
hw_irq_controller *handler;
void *handler_data;
struct irqaction *action; /* IRQ action list */
unsigned int status; /* IRQ status */
unsigned int depth; /* nested irq disables */
unsigned int irq_count; /* For detecting broken interrupts */
unsigned int irqs_unhandled;
spinlock_t lock;
#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
unsigned int move_irq; /* Flag need to re-target intr dest*/
#endif
} ____cacheline_aligned irq_desc_t;
extern irq_desc_t irq_desc [NR_IRQS];
/* Return a pointer to the irq descriptor for IRQ. */
static inline irq_desc_t *
irq_descp (int irq)
{
return irq_desc + irq;
}
#include <asm/hw_irq.h> /* the arch dependent stuff */
extern int setup_irq(unsigned int irq, struct irqaction * new);
#ifdef CONFIG_XEN
extern int teardown_irq(unsigned int irq, struct irqaction * old);
#endif
#ifdef CONFIG_GENERIC_HARDIRQS
extern cpumask_t irq_affinity[NR_IRQS];
#ifdef CONFIG_SMP
static inline void set_native_irq_info(int irq, cpumask_t mask)
{
irq_affinity[irq] = mask;
}
#else
static inline void set_native_irq_info(int irq, cpumask_t mask)
{
}
#endif
#ifdef CONFIG_SMP
#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
extern cpumask_t pending_irq_cpumask[NR_IRQS];
static inline void set_pending_irq(unsigned int irq, cpumask_t mask)
{
irq_desc_t *desc = irq_desc + irq;
unsigned long flags;
spin_lock_irqsave(&desc->lock, flags);
desc->move_irq = 1;
pending_irq_cpumask[irq] = mask;
spin_unlock_irqrestore(&desc->lock, flags);
}
static inline void
move_native_irq(int irq)
{
cpumask_t tmp;
irq_desc_t *desc = irq_descp(irq);
if (likely (!desc->move_irq))
return;
desc->move_irq = 0;
if (likely(cpus_empty(pending_irq_cpumask[irq])))
return;
if (!desc->handler->set_affinity)
return;
/* note - we hold the desc->lock */
cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map);
/*
* If there was a valid mask to work with, please
* do the disable, re-program, enable sequence.
* This is *not* particularly important for level triggered
* but in a edge trigger case, we might be setting rte
* when an active trigger is comming in. This could
* cause some ioapics to mal-function.
* Being paranoid i guess!
*/
if (unlikely(!cpus_empty(tmp))) {
desc->handler->disable(irq);
desc->handler->set_affinity(irq,tmp);
desc->handler->enable(irq);
}
cpus_clear(pending_irq_cpumask[irq]);
}
#ifdef CONFIG_PCI_MSI
/*
* Wonder why these are dummies?
* For e.g the set_ioapic_affinity_vector() calls the set_ioapic_affinity_irq()
* counter part after translating the vector to irq info. We need to perform
* this operation on the real irq, when we dont use vector, i.e when
* pci_use_vector() is false.
*/
static inline void move_irq(int irq)
{
}
static inline void set_irq_info(int irq, cpumask_t mask)
{
}
#else // CONFIG_PCI_MSI
static inline void move_irq(int irq)
{
move_native_irq(irq);
}
static inline void set_irq_info(int irq, cpumask_t mask)
{
set_native_irq_info(irq, mask);
}
#endif // CONFIG_PCI_MSI
#else // CONFIG_GENERIC_PENDING_IRQ || CONFIG_IRQBALANCE
#define move_irq(x)
#define move_native_irq(x)
#define set_pending_irq(x,y)
static inline void set_irq_info(int irq, cpumask_t mask)
{
set_native_irq_info(irq, mask);
}
#endif // CONFIG_GENERIC_PENDING_IRQ
#else // CONFIG_SMP
#define move_irq(x)
#define move_native_irq(x)
#endif // CONFIG_SMP
extern int no_irq_affinity;
extern int noirqdebug_setup(char *str);
extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs,
struct irqaction *action);
extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs);
extern void note_interrupt(unsigned int irq, irq_desc_t *desc,
int action_ret, struct pt_regs *regs);
extern int can_request_irq(unsigned int irq, unsigned long irqflags);
extern void init_irq_proc(void);
#ifdef CONFIG_AUTO_IRQ_AFFINITY
extern int select_smp_affinity(unsigned int irq);
#else
static inline int
select_smp_affinity(unsigned int irq)
{
return 1;
}
#endif
#endif
extern hw_irq_controller no_irq_type; /* needed in every arch ? */
#endif
#endif /* __irq_h */
+2 -2
View File
@@ -189,7 +189,7 @@ enum {
* @local_df: allow local fragmentation
* @cloned: Head may be cloned (check refcnt to be sure)
* @nohdr: Payload reference only, must not modify header
* @proto_csum_valid: Protocol csum validated since arriving at localhost
* @proto_data_valid: Protocol data validated since arriving at localhost
* @proto_csum_blank: Protocol csum must be added before leaving localhost
* @pkt_type: Packet class
* @fclone: skbuff clone status
@@ -271,7 +271,7 @@ struct sk_buff {
ipvs_property:1;
#else
ipvs_property:1,
proto_csum_valid:1,
proto_data_valid:1,
proto_csum_blank:1;
#endif
__be16 protocol;
@@ -110,6 +110,9 @@ void gnttab_grant_foreign_transfer_ref(grant_ref_t, domid_t domid,
#define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
#endif
int gnttab_suspend(void);
int gnttab_resume(void);
#endif /* __ASM_GNTTAB_H__ */
/*
+12 -7
View File
@@ -55,8 +55,17 @@ struct xenbus_watch
/* Callback (executed in a process context with no locks held). */
void (*callback)(struct xenbus_watch *,
const char **vec, unsigned int len);
/* See XBWF_ definitions below. */
unsigned long flags;
};
/*
* Execute callback in its own kthread. Useful if the callback is long
* running or heavily serialised, to avoid taking out the main xenwatch thread
* for a long period of time (or even unwittingly causing a deadlock).
*/
#define XBWF_new_thread 1
/* A xenbus device. */
struct xenbus_device {
@@ -195,14 +204,10 @@ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
/**
* Advertise in the store a change of the given driver to the given new_state.
* Perform the change inside the given transaction xbt. xbt may be NULL, in
* which case this is performed inside its own transaction. Return 0 on
* success, or -errno on error. On error, the device will switch to
* XenbusStateClosing, and the error will be saved in the store.
* Return 0 on success, or -errno on error. On error, the device will switch
* to XenbusStateClosing, and the error will be saved in the store.
*/
int xenbus_switch_state(struct xenbus_device *dev,
xenbus_transaction_t xbt,
XenbusState new_state);
int xenbus_switch_state(struct xenbus_device *dev, XenbusState new_state);
/**
-425
View File
@@ -1,425 +0,0 @@
/*
* linux/kernel/irq/manage.c
*
* Copyright (C) 1992, 1998-2004 Linus Torvalds, Ingo Molnar
*
* This file contains driver APIs to the irq subsystem.
*/
#include <linux/config.h>
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/random.h>
#include <linux/interrupt.h>
#include "internals.h"
#ifdef CONFIG_SMP
cpumask_t irq_affinity[NR_IRQS] = { [0 ... NR_IRQS-1] = CPU_MASK_ALL };
#if defined (CONFIG_GENERIC_PENDING_IRQ) || defined (CONFIG_IRQBALANCE)
cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS];
#endif
/**
* synchronize_irq - wait for pending IRQ handlers (on other CPUs)
* @irq: interrupt number to wait for
*
* This function waits for any pending IRQ handlers for this interrupt
* to complete before returning. If you use this function while
* holding a resource the IRQ handler may need you will deadlock.
*
* This function may be called - with care - from IRQ context.
*/
void synchronize_irq(unsigned int irq)
{
struct irq_desc *desc = irq_desc + irq;
if (irq >= NR_IRQS)
return;
while (desc->status & IRQ_INPROGRESS)
cpu_relax();
}
EXPORT_SYMBOL(synchronize_irq);
#endif
/**
* disable_irq_nosync - disable an irq without waiting
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Disables and Enables are
* nested.
* Unlike disable_irq(), this function does not ensure existing
* instances of the IRQ handler have completed before returning.
*
* This function may be called from IRQ context.
*/
void disable_irq_nosync(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
unsigned long flags;
if (irq >= NR_IRQS)
return;
spin_lock_irqsave(&desc->lock, flags);
if (!desc->depth++) {
desc->status |= IRQ_DISABLED;
desc->handler->disable(irq);
}
spin_unlock_irqrestore(&desc->lock, flags);
}
EXPORT_SYMBOL(disable_irq_nosync);
/**
* disable_irq - disable an irq and wait for completion
* @irq: Interrupt to disable
*
* Disable the selected interrupt line. Enables and Disables are
* nested.
* This function waits for any pending IRQ handlers for this interrupt
* to complete before returning. If you use this function while
* holding a resource the IRQ handler may need you will deadlock.
*
* This function may be called - with care - from IRQ context.
*/
void disable_irq(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
if (irq >= NR_IRQS)
return;
disable_irq_nosync(irq);
if (desc->action)
synchronize_irq(irq);
}
EXPORT_SYMBOL(disable_irq);
/**
* enable_irq - enable handling of an irq
* @irq: Interrupt to enable
*
* Undoes the effect of one call to disable_irq(). If this
* matches the last disable, processing of interrupts on this
* IRQ line is re-enabled.
*
* This function may be called from IRQ context.
*/
void enable_irq(unsigned int irq)
{
irq_desc_t *desc = irq_desc + irq;
unsigned long flags;
if (irq >= NR_IRQS)
return;
spin_lock_irqsave(&desc->lock, flags);
switch (desc->depth) {
case 0:
WARN_ON(1);
break;
case 1: {
unsigned int status = desc->status & ~IRQ_DISABLED;
desc->status = status;
if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
desc->status = status | IRQ_REPLAY;
hw_resend_irq(desc->handler,irq);
}
desc->handler->enable(irq);
/* fall-through */
}
default:
desc->depth--;
}
spin_unlock_irqrestore(&desc->lock, flags);
}
EXPORT_SYMBOL(enable_irq);
/*
* Internal function that tells the architecture code whether a
* particular irq has been exclusively allocated or is available
* for driver use.
*/
int can_request_irq(unsigned int irq, unsigned long irqflags)
{
struct irqaction *action;
if (irq >= NR_IRQS)
return 0;
action = irq_desc[irq].action;
if (action)
if (irqflags & action->flags & SA_SHIRQ)
action = NULL;
return !action;
}
/**
* setup_irq - register an irqaction structure
* @irq: Interrupt to register
* @irqaction: The irqaction structure to be registered
*
* Normally called by request_irq, this function can be used
* directly to allocate special interrupts that are part of the
* architecture.
*/
int setup_irq(unsigned int irq, struct irqaction * new)
{
struct irq_desc *desc = irq_desc + irq;
struct irqaction *old, **p;
unsigned long flags;
int shared = 0;
if (irq >= NR_IRQS)
return -EINVAL;
if (desc->handler == &no_irq_type)
return -ENOSYS;
/*
* Some drivers like serial.c use request_irq() heavily,
* so we have to be careful not to interfere with a
* running system.
*/
if (new->flags & SA_SAMPLE_RANDOM) {
/*
* This function might sleep, we want to call it first,
* outside of the atomic block.
* Yes, this might clear the entropy pool if the wrong
* driver is attempted to be loaded, without actually
* installing a new handler, but is this really a problem,
* only the sysadmin is able to do this.
*/
rand_initialize_irq(irq);
}
/*
* The following block of code has to be executed atomically
*/
spin_lock_irqsave(&desc->lock,flags);
p = &desc->action;
if ((old = *p) != NULL) {
/* Can't share interrupts unless both agree to */
if (!(old->flags & new->flags & SA_SHIRQ)) {
spin_unlock_irqrestore(&desc->lock,flags);
return -EBUSY;
}
/* add new interrupt at end of irq queue */
do {
p = &old->next;
old = *p;
} while (old);
shared = 1;
}
*p = new;
if (!shared) {
desc->depth = 0;
desc->status &= ~(IRQ_DISABLED | IRQ_AUTODETECT |
IRQ_WAITING | IRQ_INPROGRESS);
if (desc->handler->startup)
desc->handler->startup(irq);
else
desc->handler->enable(irq);
}
spin_unlock_irqrestore(&desc->lock,flags);
new->irq = irq;
register_irq_proc(irq);
new->dir = NULL;
register_handler_proc(irq, new);
return 0;
}
/*
* teardown_irq - unregister an irqaction
* @irq: Interrupt line being freed
* @old: Pointer to the irqaction that is to be unregistered
*
* This function is called by free_irq and does the actual
* business of unregistering the handler. It exists as a
* seperate function to enable handlers to be unregistered
* for irqactions that have been allocated statically at
* boot time.
*
* This function must not be called from interrupt context.
*/
#ifndef CONFIG_XEN
static
#endif
int teardown_irq(unsigned int irq, struct irqaction * old)
{
struct irq_desc *desc;
struct irqaction **p;
unsigned long flags;
if (irq >= NR_IRQS)
return -ENOENT;
desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock,flags);
p = &desc->action;
for (;;) {
struct irqaction * action = *p;
if (action) {
struct irqaction **pp = p;
p = &action->next;
if (action != old)
continue;
/* Found it - now remove it from the list of entries */
*pp = action->next;
/* Currently used only by UML, might disappear one day.*/
#ifdef CONFIG_IRQ_RELEASE_METHOD
if (desc->handler->release)
desc->handler->release(irq, dev_id);
#endif
if (!desc->action) {
desc->status |= IRQ_DISABLED;
if (desc->handler->shutdown)
desc->handler->shutdown(irq);
else
desc->handler->disable(irq);
}
spin_unlock_irqrestore(&desc->lock,flags);
unregister_handler_proc(irq, action);
/* Make sure it's not being used on another CPU */
synchronize_irq(irq);
return 0;
}
printk(KERN_ERR "Trying to teardown free IRQ%d\n",irq);
spin_unlock_irqrestore(&desc->lock,flags);
return -ENOENT;
}
}
/**
* free_irq - free an interrupt
* @irq: Interrupt line to free
* @dev_id: Device identity to free
*
* Remove an interrupt handler. The handler is removed and if the
* interrupt line is no longer in use by any driver it is disabled.
* On a shared IRQ the caller must ensure the interrupt is disabled
* on the card it drives before calling this function. The function
* does not return until any executing interrupts for this IRQ
* have completed.
*
* This function must not be called from interrupt context.
*/
void free_irq(unsigned int irq, void *dev_id)
{
struct irq_desc *desc;
struct irqaction *action;
unsigned long flags;
if (irq >= NR_IRQS)
return;
desc = irq_desc + irq;
spin_lock_irqsave(&desc->lock,flags);
for (action = desc->action; action != NULL; action = action->next) {
if (action->dev_id != dev_id)
continue;
spin_unlock_irqrestore(&desc->lock,flags);
if (teardown_irq(irq, action) == 0)
kfree(action);
return;
}
printk(KERN_ERR "Trying to free free IRQ%d\n",irq);
spin_unlock_irqrestore(&desc->lock,flags);
return;
}
EXPORT_SYMBOL(free_irq);
/**
* request_irq - allocate an interrupt line
* @irq: Interrupt line to allocate
* @handler: Function to be called when the IRQ occurs
* @irqflags: Interrupt type flags
* @devname: An ascii name for the claiming device
* @dev_id: A cookie passed back to the handler function
*
* This call allocates interrupt resources and enables the
* interrupt line and IRQ handling. From the point this
* call is made your handler function may be invoked. Since
* your handler function must clear any interrupt the board
* raises, you must take care both to initialise your hardware
* and to set up the interrupt handler in the right order.
*
* Dev_id must be globally unique. Normally the address of the
* device data structure is used as the cookie. Since the handler
* receives this value it makes sense to use it.
*
* If your interrupt is shared you must pass a non NULL dev_id
* as this is required when freeing the interrupt.
*
* Flags:
*
* SA_SHIRQ Interrupt is shared
* SA_INTERRUPT Disable local interrupts while processing
* SA_SAMPLE_RANDOM The interrupt can be used for entropy
*
*/
int request_irq(unsigned int irq,
irqreturn_t (*handler)(int, void *, struct pt_regs *),
unsigned long irqflags, const char * devname, void *dev_id)
{
struct irqaction * action;
int retval;
/*
* Sanity-check: shared interrupts must pass in a real dev-ID,
* otherwise we'll have trouble later trying to figure out
* which interrupt is which (messes up the interrupt freeing
* logic etc).
*/
if ((irqflags & SA_SHIRQ) && !dev_id)
return -EINVAL;
if (irq >= NR_IRQS)
return -EINVAL;
if (!handler)
return -EINVAL;
action = kmalloc(sizeof(struct irqaction), GFP_ATOMIC);
if (!action)
return -ENOMEM;
action->handler = handler;
action->flags = irqflags;
cpus_clear(action->mask);
action->name = devname;
action->next = NULL;
action->dev_id = dev_id;
select_smp_affinity(irq);
retval = setup_irq(irq, action);
if (retval)
kfree(action);
return retval;
}
EXPORT_SYMBOL(request_irq);
-224
View File
@@ -1,224 +0,0 @@
config PRINTK_TIME
bool "Show timing information on printks"
help
Selecting this option causes timing information to be
included in printk output. This allows you to measure
the interval between kernel operations, including bootup
operations. This is useful for identifying long delays
in kernel startup.
config MAGIC_SYSRQ
bool "Magic SysRq key"
depends on !UML
help
If you say Y here, you will have some control over the system even
if the system crashes for example during kernel debugging (e.g., you
will be able to flush the buffer cache to disk, reboot the system
immediately or dump some status information). This is accomplished
by pressing various keys while holding SysRq (Alt+PrintScreen). It
also works on a serial console (on PC hardware at least), if you
send a BREAK and then within 5 seconds a command keypress. The
keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
unless you really know what this hack does.
config DEBUG_KERNEL
bool "Kernel debugging"
help
Say Y here if you are developing drivers or trying to debug and
identify kernel problems.
config LOG_BUF_SHIFT
int "Kernel log buffer size (16 => 64KB, 17 => 128KB)" if DEBUG_KERNEL
range 12 21
default 17 if S390
default 16 if X86_NUMAQ || IA64
default 15 if SMP
default 14
help
Select kernel log buffer size as a power of 2.
Defaults and Examples:
17 => 128 KB for S/390
16 => 64 KB for x86 NUMAQ or IA-64
15 => 32 KB for SMP
14 => 16 KB for uniprocessor
13 => 8 KB
12 => 4 KB
config DETECT_SOFTLOCKUP
bool "Detect Soft Lockups"
depends on DEBUG_KERNEL
default y
help
Say Y here to enable the kernel to detect "soft lockups",
which are bugs that cause the kernel to loop in kernel
mode for more than 10 seconds, without giving other tasks a
chance to run.
When a soft-lockup is detected, the kernel will print the
current stack trace (which you should report), but the
system will stay locked up. This feature has negligible
overhead.
(Note that "hard lockups" are separate type of bugs that
can be detected via the NMI-watchdog, on platforms that
support it.)
config SCHEDSTATS
bool "Collect scheduler statistics"
depends on DEBUG_KERNEL && PROC_FS
help
If you say Y here, additional code will be inserted into the
scheduler and related routines to collect statistics about
scheduler behavior and provide them in /proc/schedstat. These
stats may be useful for both tuning and debugging the scheduler
If you aren't debugging the scheduler or trying to tune a specific
application, you can say N to avoid the very slight overhead
this adds.
config DEBUG_SLAB
bool "Debug memory allocations"
depends on DEBUG_KERNEL && SLAB
help
Say Y here to have the kernel do limited verification on memory
allocation as well as poisoning memory on free to catch use of freed
memory. This can make kmalloc/kfree-intensive workloads much slower.
config DEBUG_PREEMPT
bool "Debug preemptible kernel"
depends on DEBUG_KERNEL && PREEMPT
default y
help
If you say Y here then the kernel will use a debug variant of the
commonly used smp_processor_id() function and will print warnings
if kernel code uses it in a preemption-unsafe way. Also, the kernel
will detect preemption count underflows.
config DEBUG_MUTEXES
bool "Mutex debugging, deadlock detection"
default y
depends on DEBUG_KERNEL
help
This allows mutex semantics violations and mutex related deadlocks
(lockups) to be detected and reported automatically.
config DEBUG_SPINLOCK
bool "Spinlock debugging"
depends on DEBUG_KERNEL
help
Say Y here and build SMP to catch missing spinlock initialization
and certain other kinds of spinlock errors commonly made. This is
best used in conjunction with the NMI watchdog so that spinlock
deadlocks are also debuggable.
config DEBUG_SPINLOCK_SLEEP
bool "Sleep-inside-spinlock checking"
depends on DEBUG_KERNEL
help
If you say Y here, various routines which may sleep will become very
noisy if they are called with a spinlock held.
config DEBUG_KOBJECT
bool "kobject debugging"
depends on DEBUG_KERNEL
help
If you say Y here, some extra kobject debugging messages will be sent
to the syslog.
config DEBUG_HIGHMEM
bool "Highmem debugging"
depends on DEBUG_KERNEL && HIGHMEM
help
This options enables addition error checking for high memory systems.
Disable for production systems.
config DEBUG_BUGVERBOSE
bool "Verbose BUG() reporting (adds 70K)" if DEBUG_KERNEL && EMBEDDED
depends on BUG
depends on ARM || ARM26 || M32R || M68K || SPARC32 || SPARC64 || X86_32 || FRV
default !EMBEDDED
help
Say Y here to make BUG() panics output the file name and line number
of the BUG call as well as the EIP and oops trace. This aids
debugging but costs about 70-100K of memory.
config DEBUG_INFO
bool "Compile the kernel with debug info"
depends on DEBUG_KERNEL && !X86_64_XEN
help
If you say Y here the resulting kernel image will include
debugging info resulting in a larger kernel image.
Say Y here only if you plan to debug the kernel.
If unsure, say N.
config DEBUG_IOREMAP
bool "Enable ioremap() debugging"
depends on DEBUG_KERNEL && PARISC
help
Enabling this option will cause the kernel to distinguish between
ioremapped and physical addresses. It will print a backtrace (at
most one every 10 seconds), hopefully allowing you to see which
drivers need work. Fixing all these problems is a prerequisite
for turning on USE_HPPA_IOREMAP. The warnings are harmless;
the kernel has enough information to fix the broken drivers
automatically, but we'd like to make it more efficient by not
having to do that.
config DEBUG_FS
bool "Debug Filesystem"
depends on DEBUG_KERNEL && SYSFS
help
debugfs is a virtual file system that kernel developers use to put
debugging files into. Enable this option to be able to read and
write to these files.
If unsure, say N.
config DEBUG_VM
bool "Debug VM"
depends on DEBUG_KERNEL
help
Enable this to turn on extended checks in the virtual-memory system
that may impact performance.
If unsure, say N.
config FRAME_POINTER
bool "Compile the kernel with frame pointers"
depends on DEBUG_KERNEL && (X86 || CRIS || M68K || M68KNOMMU || FRV || UML)
default y if DEBUG_INFO && UML
help
If you say Y here the resulting kernel image will be slightly larger
and slower, but it might give very useful debugging information on
some architectures or if you use external debuggers.
If you don't debug the kernel, you can say N.
config FORCED_INLINING
bool "Force gcc to inline functions marked 'inline'"
depends on DEBUG_KERNEL
default y
help
This option determines if the kernel forces gcc to inline the functions
developers have marked 'inline'. Doing so takes away freedom from gcc to
do what it thinks is best, which is desirable for the gcc 3.x series of
compilers. The gcc 4.x series have a rewritten inlining algorithm and
disabling this option will generate a smaller kernel there. Hopefully
this algorithm is so good that allowing gcc4 to make the decision can
become the default in the future, until then this option is there to
test gcc for this.
config RCU_TORTURE_TEST
tristate "torture tests for RCU"
depends on DEBUG_KERNEL
default n
help
This option provides a kernel module that runs torture tests
on the RCU infrastructure. The kernel module may be built
after the fact on the running kernel to be tested, if desired.
Say Y here if you want RCU torture tests to start automatically
at boot time (you probably don't).
Say M if you want the RCU torture tests to build as a module.
Say N if you are unsure.
+2 -2
View File
@@ -1649,12 +1649,12 @@ int netif_receive_skb(struct sk_buff *skb)
#ifdef CONFIG_XEN
switch (skb->ip_summed) {
case CHECKSUM_UNNECESSARY:
skb->proto_csum_valid = 1;
skb->proto_data_valid = 1;
break;
case CHECKSUM_HW:
/* XXX Implement me. */
default:
skb->proto_csum_valid = 0;
skb->proto_data_valid = 0;
break;
}
#endif
+1 -1
View File
@@ -428,7 +428,7 @@ struct sk_buff *skb_clone(struct sk_buff *skb, gfp_t gfp_mask)
n->cloned = 1;
n->nohdr = 0;
#ifdef CONFIG_XEN
C(proto_csum_valid);
C(proto_data_valid);
C(proto_csum_blank);
#endif
C(pkt_type);
@@ -0,0 +1,107 @@
Subject: Increase x86 interrupt vector range
Remove the limit of 256 interrupt vectors by changing the value
stored in orig_{e,r}ax to be the negated interrupt vector.
The orig_{e,r}ax needs to be < 0 to allow the signal code to
distinguish between return from interrupt and return from syscall.
With this change applied, NR_IRQS can be > 256.
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
---
arch/i386/kernel/entry.S | 4 ++--
arch/i386/kernel/irq.c | 4 ++--
arch/x86_64/kernel/entry.S | 2 +-
arch/x86_64/kernel/irq.c | 4 ++--
arch/x86_64/kernel/smp.c | 4 ++--
include/asm-x86_64/hw_irq.h | 2 +-
6 files changed, 10 insertions(+), 10 deletions(-)
diff -r 7d239c83edea arch/i386/kernel/entry.S
--- a/arch/i386/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000
+++ b/arch/i386/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100
@@ -406,7 +406,7 @@ ENTRY(irq_entries_start)
ENTRY(irq_entries_start)
.rept NR_IRQS
ALIGN
-1: pushl $vector-256
+1: pushl $~(vector)
jmp common_interrupt
.data
.long 1b
@@ -423,7 +423,7 @@ common_interrupt:
#define BUILD_INTERRUPT(name, nr) \
ENTRY(name) \
- pushl $nr-256; \
+ pushl $~(nr); \
SAVE_ALL \
movl %esp,%eax; \
call smp_/**/name; \
diff -r 7d239c83edea arch/i386/kernel/irq.c
--- a/arch/i386/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000
+++ b/arch/i386/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100
@@ -53,8 +53,8 @@ static union irq_ctx *softirq_ctx[NR_CPU
*/
fastcall unsigned int do_IRQ(struct pt_regs *regs)
{
- /* high bits used in ret_from_ code */
- int irq = regs->orig_eax & 0xff;
+ /* high bit used in ret_from_ code */
+ int irq = ~regs->orig_eax;
#ifdef CONFIG_4KSTACKS
union irq_ctx *curctx, *irqctx;
u32 *isp;
diff -r 7d239c83edea arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S Mon Mar 20 06:00:20 2006 +0000
+++ b/arch/x86_64/kernel/entry.S Fri Mar 31 17:01:35 2006 +0100
@@ -609,7 +609,7 @@ retint_kernel:
*/
.macro apicinterrupt num,func
INTR_FRAME
- pushq $\num-256
+ pushq $~(\num)
CFI_ADJUST_CFA_OFFSET 8
interrupt \func
jmp ret_from_intr
diff -r 7d239c83edea arch/x86_64/kernel/irq.c
--- a/arch/x86_64/kernel/irq.c Mon Mar 20 06:00:20 2006 +0000
+++ b/arch/x86_64/kernel/irq.c Fri Mar 31 17:01:35 2006 +0100
@@ -96,8 +96,8 @@ skip:
*/
asmlinkage unsigned int do_IRQ(struct pt_regs *regs)
{
- /* high bits used in ret_from_ code */
- unsigned irq = regs->orig_rax & 0xff;
+ /* high bit used in ret_from_ code */
+ unsigned irq = ~regs->orig_rax;
exit_idle();
irq_enter();
diff -r 7d239c83edea arch/x86_64/kernel/smp.c
--- a/arch/x86_64/kernel/smp.c Mon Mar 20 06:00:20 2006 +0000
+++ b/arch/x86_64/kernel/smp.c Fri Mar 31 17:01:35 2006 +0100
@@ -135,10 +135,10 @@ asmlinkage void smp_invalidate_interrupt
cpu = smp_processor_id();
/*
- * orig_rax contains the interrupt vector - 256.
+ * orig_rax contains the negated interrupt vector.
* Use that to determine where the sender put the data.
*/
- sender = regs->orig_rax + 256 - INVALIDATE_TLB_VECTOR_START;
+ sender = ~regs->orig_rax - INVALIDATE_TLB_VECTOR_START;
f = &per_cpu(flush_state, sender);
if (!cpu_isset(cpu, f->flush_cpumask))
diff -r 7d239c83edea include/asm-x86_64/hw_irq.h
--- a/include/asm-x86_64/hw_irq.h Mon Mar 20 06:00:20 2006 +0000
+++ b/include/asm-x86_64/hw_irq.h Fri Mar 31 17:01:35 2006 +0100
@@ -127,7 +127,7 @@ __asm__( \
__asm__( \
"\n.p2align\n" \
"IRQ" #nr "_interrupt:\n\t" \
- "push $" #nr "-256 ; " \
+ "push $~(" #nr ") ; " \
"jmp common_interrupt");
#if defined(CONFIG_X86_IO_APIC)
+384
View File
@@ -0,0 +1,384 @@
diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/buffer_sync.c ./drivers/oprofile/buffer_sync.c
--- ../pristine-linux-2.6.16/drivers/oprofile/buffer_sync.c 2006-03-20 05:53:29.000000000 +0000
+++ ./drivers/oprofile/buffer_sync.c 2006-04-03 15:53:05.000000000 +0100
@@ -6,6 +6,10 @@
*
* @author John Levon <levon@movementarian.org>
*
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
+ *
* This is the core of the buffer management. Each
* CPU buffer is processed and entered into the
* global event buffer. Such processing is necessary
@@ -275,15 +279,24 @@ static void add_cpu_switch(int i)
last_cookie = INVALID_COOKIE;
}
-static void add_kernel_ctx_switch(unsigned int in_kernel)
+static void add_cpu_mode_switch(unsigned int cpu_mode)
{
add_event_entry(ESCAPE_CODE);
- if (in_kernel)
- add_event_entry(KERNEL_ENTER_SWITCH_CODE);
- else
- add_event_entry(KERNEL_EXIT_SWITCH_CODE);
+ switch (cpu_mode) {
+ case CPU_MODE_USER:
+ add_event_entry(USER_ENTER_SWITCH_CODE);
+ break;
+ case CPU_MODE_KERNEL:
+ add_event_entry(KERNEL_ENTER_SWITCH_CODE);
+ break;
+ case CPU_MODE_XEN:
+ add_event_entry(XEN_ENTER_SWITCH_CODE);
+ break;
+ default:
+ break;
+ }
}
-
+
static void
add_user_ctx_switch(struct task_struct const * task, unsigned long cookie)
{
@@ -348,9 +361,9 @@ static int add_us_sample(struct mm_struc
* for later lookup from userspace.
*/
static int
-add_sample(struct mm_struct * mm, struct op_sample * s, int in_kernel)
+add_sample(struct mm_struct * mm, struct op_sample * s, int cpu_mode)
{
- if (in_kernel) {
+ if (cpu_mode >= CPU_MODE_KERNEL) {
add_sample_entry(s->eip, s->event);
return 1;
} else if (mm) {
@@ -496,7 +509,7 @@ void sync_buffer(int cpu)
struct mm_struct *mm = NULL;
struct task_struct * new;
unsigned long cookie = 0;
- int in_kernel = 1;
+ int cpu_mode = 1;
unsigned int i;
sync_buffer_state state = sb_buffer_start;
unsigned long available;
@@ -513,12 +526,12 @@ void sync_buffer(int cpu)
struct op_sample * s = &cpu_buf->buffer[cpu_buf->tail_pos];
if (is_code(s->eip)) {
- if (s->event <= CPU_IS_KERNEL) {
+ if (s->event <= CPU_MODE_XEN) {
/* kernel/userspace switch */
- in_kernel = s->event;
+ cpu_mode = s->event;
if (state == sb_buffer_start)
state = sb_sample_start;
- add_kernel_ctx_switch(s->event);
+ add_cpu_mode_switch(s->event);
} else if (s->event == CPU_TRACE_BEGIN) {
state = sb_bt_start;
add_trace_begin();
@@ -536,7 +549,7 @@ void sync_buffer(int cpu)
}
} else {
if (state >= sb_bt_start &&
- !add_sample(mm, s, in_kernel)) {
+ !add_sample(mm, s, cpu_mode)) {
if (state == sb_bt_start) {
state = sb_bt_ignore;
atomic_inc(&oprofile_stats.bt_lost_no_mapping);
diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.c ./drivers/oprofile/cpu_buffer.c
--- ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.c 2006-03-20 05:53:29.000000000 +0000
+++ ./drivers/oprofile/cpu_buffer.c 2006-04-03 15:53:05.000000000 +0100
@@ -6,6 +6,10 @@
*
* @author John Levon <levon@movementarian.org>
*
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
+ *
* Each CPU has a local buffer that stores PC value/event
* pairs. We also log context switches when we notice them.
* Eventually each CPU's buffer is processed into the global
@@ -58,7 +62,7 @@ int alloc_cpu_buffers(void)
goto fail;
b->last_task = NULL;
- b->last_is_kernel = -1;
+ b->last_cpu_mode = -1;
b->tracing = 0;
b->buffer_size = buffer_size;
b->tail_pos = 0;
@@ -114,7 +118,7 @@ void cpu_buffer_reset(struct oprofile_cp
* collected will populate the buffer with proper
* values to initialize the buffer
*/
- cpu_buf->last_is_kernel = -1;
+ cpu_buf->last_cpu_mode = -1;
cpu_buf->last_task = NULL;
}
@@ -164,13 +168,13 @@ add_code(struct oprofile_cpu_buffer * bu
* because of the head/tail separation of the writer and reader
* of the CPU buffer.
*
- * is_kernel is needed because on some architectures you cannot
+ * cpu_mode is needed because on some architectures you cannot
* tell if you are in kernel or user space simply by looking at
- * pc. We tag this in the buffer by generating kernel enter/exit
- * events whenever is_kernel changes
+ * pc. We tag this in the buffer by generating kernel/user (and xen)
+ * enter events whenever cpu_mode changes
*/
static int log_sample(struct oprofile_cpu_buffer * cpu_buf, unsigned long pc,
- int is_kernel, unsigned long event)
+ int cpu_mode, unsigned long event)
{
struct task_struct * task;
@@ -181,16 +185,16 @@ static int log_sample(struct oprofile_cp
return 0;
}
- is_kernel = !!is_kernel;
+ WARN_ON(cpu_mode > CPU_MODE_XEN);
task = current;
/* notice a switch from user->kernel or vice versa */
- if (cpu_buf->last_is_kernel != is_kernel) {
- cpu_buf->last_is_kernel = is_kernel;
- add_code(cpu_buf, is_kernel);
+ if (cpu_buf->last_cpu_mode != cpu_mode) {
+ cpu_buf->last_cpu_mode = cpu_mode;
+ add_code(cpu_buf, cpu_mode);
}
-
+
/* notice a task switch */
if (cpu_buf->last_task != task) {
cpu_buf->last_task = task;
diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.h ./drivers/oprofile/cpu_buffer.h
--- ../pristine-linux-2.6.16/drivers/oprofile/cpu_buffer.h 2006-03-20 05:53:29.000000000 +0000
+++ ./drivers/oprofile/cpu_buffer.h 2006-04-03 15:53:05.000000000 +0100
@@ -36,7 +36,7 @@ struct oprofile_cpu_buffer {
volatile unsigned long tail_pos;
unsigned long buffer_size;
struct task_struct * last_task;
- int last_is_kernel;
+ int last_cpu_mode;
int tracing;
struct op_sample * buffer;
unsigned long sample_received;
@@ -51,7 +51,9 @@ extern struct oprofile_cpu_buffer cpu_bu
void cpu_buffer_reset(struct oprofile_cpu_buffer * cpu_buf);
/* transient events for the CPU buffer -> event buffer */
-#define CPU_IS_KERNEL 1
-#define CPU_TRACE_BEGIN 2
+#define CPU_MODE_USER 0
+#define CPU_MODE_KERNEL 1
+#define CPU_MODE_XEN 2
+#define CPU_TRACE_BEGIN 3
#endif /* OPROFILE_CPU_BUFFER_H */
diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/event_buffer.h ./drivers/oprofile/event_buffer.h
--- ../pristine-linux-2.6.16/drivers/oprofile/event_buffer.h 2006-03-20 05:53:29.000000000 +0000
+++ ./drivers/oprofile/event_buffer.h 2006-04-03 15:53:05.000000000 +0100
@@ -29,11 +29,12 @@ void wake_up_buffer_waiter(void);
#define CPU_SWITCH_CODE 2
#define COOKIE_SWITCH_CODE 3
#define KERNEL_ENTER_SWITCH_CODE 4
-#define KERNEL_EXIT_SWITCH_CODE 5
+#define USER_ENTER_SWITCH_CODE 5
#define MODULE_LOADED_CODE 6
#define CTX_TGID_CODE 7
#define TRACE_BEGIN_CODE 8
#define TRACE_END_CODE 9
+#define XEN_ENTER_SWITCH_CODE 10
#define INVALID_COOKIE ~0UL
#define NO_COOKIE 0UL
diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprof.c ./drivers/oprofile/oprof.c
--- ../pristine-linux-2.6.16/drivers/oprofile/oprof.c 2006-03-20 05:53:29.000000000 +0000
+++ ./drivers/oprofile/oprof.c 2006-04-03 15:53:05.000000000 +0100
@@ -5,6 +5,10 @@
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*/
#include <linux/kernel.h>
@@ -19,7 +23,7 @@
#include "cpu_buffer.h"
#include "buffer_sync.h"
#include "oprofile_stats.h"
-
+
struct oprofile_operations oprofile_ops;
unsigned long oprofile_started;
@@ -33,6 +37,17 @@ static DECLARE_MUTEX(start_sem);
*/
static int timer = 0;
+extern unsigned int adomains;
+extern int active_domains[MAX_OPROF_DOMAINS];
+
+int oprofile_set_active(void)
+{
+ if (oprofile_ops.set_active)
+ return oprofile_ops.set_active(active_domains, adomains);
+
+ return -EINVAL;
+}
+
int oprofile_setup(void)
{
int err;
diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprof.h ./drivers/oprofile/oprof.h
--- ../pristine-linux-2.6.16/drivers/oprofile/oprof.h 2006-03-20 05:53:29.000000000 +0000
+++ ./drivers/oprofile/oprof.h 2006-04-03 15:53:05.000000000 +0100
@@ -35,5 +35,7 @@ void oprofile_create_files(struct super_
void oprofile_timer_init(struct oprofile_operations * ops);
int oprofile_set_backtrace(unsigned long depth);
+
+int oprofile_set_active(void);
#endif /* OPROF_H */
diff -pruN ../pristine-linux-2.6.16/drivers/oprofile/oprofile_files.c ./drivers/oprofile/oprofile_files.c
--- ../pristine-linux-2.6.16/drivers/oprofile/oprofile_files.c 2006-03-20 05:53:29.000000000 +0000
+++ ./drivers/oprofile/oprofile_files.c 2006-04-03 15:53:05.000000000 +0100
@@ -5,15 +5,21 @@
* @remark Read the file COPYING
*
* @author John Levon <levon@movementarian.org>
+ *
+ * Modified by Aravind Menon for Xen
+ * These modifications are:
+ * Copyright (C) 2005 Hewlett-Packard Co.
*/
#include <linux/fs.h>
#include <linux/oprofile.h>
+#include <asm/uaccess.h>
+#include <linux/ctype.h>
#include "event_buffer.h"
#include "oprofile_stats.h"
#include "oprof.h"
-
+
unsigned long fs_buffer_size = 131072;
unsigned long fs_cpu_buffer_size = 8192;
unsigned long fs_buffer_watershed = 32768; /* FIXME: tune */
@@ -117,11 +123,79 @@ static ssize_t dump_write(struct file *
static struct file_operations dump_fops = {
.write = dump_write,
};
-
+
+#define TMPBUFSIZE 512
+
+unsigned int adomains = 0;
+long active_domains[MAX_OPROF_DOMAINS];
+
+static ssize_t adomain_write(struct file * file, char const __user * buf,
+ size_t count, loff_t * offset)
+{
+ char tmpbuf[TMPBUFSIZE];
+ char * startp = tmpbuf;
+ char * endp = tmpbuf;
+ int i;
+ unsigned long val;
+
+ if (*offset)
+ return -EINVAL;
+ if (!count)
+ return 0;
+ if (count > TMPBUFSIZE - 1)
+ return -EINVAL;
+
+ memset(tmpbuf, 0x0, TMPBUFSIZE);
+
+ if (copy_from_user(tmpbuf, buf, count))
+ return -EFAULT;
+
+ for (i = 0; i < MAX_OPROF_DOMAINS; i++)
+ active_domains[i] = -1;
+ adomains = 0;
+
+ while (1) {
+ val = simple_strtol(startp, &endp, 0);
+ if (endp == startp)
+ break;
+ while (ispunct(*endp))
+ endp++;
+ active_domains[adomains++] = val;
+ if (adomains >= MAX_OPROF_DOMAINS)
+ break;
+ startp = endp;
+ }
+ if (oprofile_set_active())
+ return -EINVAL;
+ return count;
+}
+
+static ssize_t adomain_read(struct file * file, char __user * buf,
+ size_t count, loff_t * offset)
+{
+ char tmpbuf[TMPBUFSIZE];
+ size_t len = 0;
+ int i;
+ /* This is all screwed up if we run out of space */
+ for (i = 0; i < adomains; i++)
+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len,
+ "%u ", (unsigned int)active_domains[i]);
+ len += snprintf(tmpbuf + len, TMPBUFSIZE - len, "\n");
+ return simple_read_from_buffer((void __user *)buf, count,
+ offset, tmpbuf, len);
+}
+
+
+static struct file_operations active_domain_ops = {
+ .read = adomain_read,
+ .write = adomain_write,
+};
+
void oprofile_create_files(struct super_block * sb, struct dentry * root)
{
oprofilefs_create_file(sb, root, "enable", &enable_fops);
oprofilefs_create_file_perm(sb, root, "dump", &dump_fops, 0666);
+ oprofilefs_create_file(sb, root, "active_domains", &active_domain_ops);
oprofilefs_create_file(sb, root, "buffer", &event_buffer_fops);
oprofilefs_create_ulong(sb, root, "buffer_size", &fs_buffer_size);
oprofilefs_create_ulong(sb, root, "buffer_watershed", &fs_buffer_watershed);
diff -pruN ../pristine-linux-2.6.16/include/linux/oprofile.h ./include/linux/oprofile.h
--- ../pristine-linux-2.6.16/include/linux/oprofile.h 2006-03-20 05:53:29.000000000 +0000
+++ ./include/linux/oprofile.h 2006-04-03 15:53:05.000000000 +0100
@@ -16,6 +16,8 @@
#include <linux/types.h>
#include <linux/spinlock.h>
#include <asm/atomic.h>
+
+#include <xen/interface/xenoprof.h>
struct super_block;
struct dentry;
@@ -27,6 +29,8 @@ struct oprofile_operations {
/* create any necessary configuration files in the oprofile fs.
* Optional. */
int (*create_files)(struct super_block * sb, struct dentry * root);
+ /* setup active domains with Xen */
+ int (*set_active)(int *active_domains, unsigned int adomains);
/* Do any necessary interrupt setup. Optional. */
int (*setup)(void);
/* Do any necessary interrupt shutdown. Optional. */
+6 -2
View File
@@ -24,14 +24,14 @@ SUBDIRS += python
SUBDIRS += pygrub
endif
.PHONY: all install clean check check_clean ioemu eioemuinstall ioemuclean
.PHONY: all
all: check
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
done
$(MAKE) ioemu
.PHONY: install
install: check
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
@@ -39,18 +39,22 @@ install: check
$(MAKE) ioemuinstall
$(INSTALL_DIR) -p $(DESTDIR)/var/xen/dump
.PHONY: clean
clean: check_clean
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
done
$(MAKE) ioemuclean
.PHONY: check
check:
$(MAKE) -C check
.PHONY: check_clean
check_clean:
$(MAKE) -C check clean
.PHONY: ioemu ioemuinstall ioemuclean
ifndef XEN_NO_IOEMU
ioemu ioemuinstall ioemuclean:
[ -f ioemu/config-host.h ] || \
+3
View File
@@ -12,6 +12,8 @@ XEN_LIBXENSTAT = $(XEN_ROOT)/tools/xenstat/libxenstat/src
X11_LDPATH = -L/usr/X11R6/$(LIBDIR)
CFLAGS += -D__XEN_INTERFACE_VERSION__=0x00030101
%.opic: %.c
$(CC) $(CPPFLAGS) -DPIC $(CFLAGS) -fPIC -c -o $@ $<
@@ -21,6 +23,7 @@ X11_LDPATH = -L/usr/X11R6/$(LIBDIR)
%.o: %.cc
$(CC) $(CPPFLAGS) $(CXXFLAGS) -c -o $@ $<
.PHONY: mk-symlinks
mk-symlinks: LINUX_ROOT=$(XEN_ROOT)/linux-2.6-xen-sparse
mk-symlinks:
mkdir -p xen
+5
View File
@@ -39,11 +39,13 @@ IBINS :=
LIB = libblktap.so libblktap.so.$(MAJOR) libblktap.so.$(MAJOR).$(MINOR)
.PHONY: all
all: mk-symlinks libblktap.so #blkdump
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
done
.PHONY: install
install: all
$(INSTALL_DIR) -p $(DESTDIR)/usr/$(LIBDIR)
$(INSTALL_DIR) -p $(DESTDIR)/usr/include
@@ -54,12 +56,14 @@ install: all
$(MAKE) -C $$subdir $@; \
done
.PHONY: clean
clean:
rm -rf *.a *.so *.o *.rpm $(LIB) *~ $(DEPS) xen TAGS blkdump
@set -e; for subdir in $(SUBDIRS); do \
$(MAKE) -C $$subdir $@; \
done
.PHONY: rpm
rpm: all
rm -rf staging
mkdir staging
@@ -82,6 +86,7 @@ blkdump: libblktap.so
.PHONY: TAGS clean install mk-symlinks rpm
.PHONY: TAGS
TAGS:
etags -t $(SRCS) *.h
+3 -1
View File
@@ -43,11 +43,14 @@ DEPS = .*.d
OBJS = $(patsubst %.c,%.o,$(SRCS))
IBINS = parallax $(VDI_TOOLS)
.PHONY: all
all: $(VDI_TOOLS) parallax blockstored
.PHONY: install
install: all
$(INSTALL_PROG) $(IBINS) $(DESTDIR)$(PARALLAX_INSTALL_DIR)
.PHONY: clean
clean:
rm -rf *.o *~ $(DEPS) xen TAGS $(VDI_TOOLS) parallax vdi_unittest
@@ -57,5 +60,4 @@ parallax: $(PLX_SRCS)
${VDI_TOOLS}: %: %.c $(VDI_SRCS)
$(CC) $(CFLAGS) -o $@ $@.c $(LDFLAGS) $(VDI_SRCS)
.PHONY: TAGS clean install rpm
-include $(DEPS)
+4 -2
View File
@@ -21,12 +21,16 @@ DEPS = .*.d
OBJS = $(patsubst %.c,%.o,$(SRCS))
.PHONY: all
all: $(IBIN)
LINUX_ROOT := $(wildcard $(XEN_ROOT)/linux-2.6.*-xen-sparse)
.PHONY: install
install:
$(INSTALL_PROG) $(IBIN) $(DESTDIR)$(INSTALL_DIR)
.PHONY: clean
clean:
rm -rf *.o*~ $(DEPS) xen TAGS $(IBIN)
@@ -34,6 +38,4 @@ ublkback:
$(CC) $(CFLAGS) -o ublkback -L$(XEN_LIBXC) -L. -L.. \
-lblktap -laio ublkback.c ublkbacklib.c -pg
.PHONY: clean install
-include $(DEPS)
+5 -1
View File
@@ -1,7 +1,9 @@
.PHONY: all
all: build
# Check this machine is OK for building on.
.PHONY: build
build:
./chk build
@@ -9,8 +11,10 @@ build:
# DO NOT use this check from 'make install' in the parent
# directory, as that target can be used to make an installable
# copy rather than actually installing.
.PHONY: install
install:
./chk install
.PHONY: clean
clean:
./chk clean
./chk clean
+3
View File
@@ -16,8 +16,10 @@ CFLAGS += -I $(XEN_XENSTORE)
BIN = xenconsoled xenconsole
.PHONY: all
all: $(BIN)
.PHONY: clean
clean:
$(RM) *.a *.so *.o *.rpm $(BIN)
$(RM) client/*.o daemon/*.o
@@ -30,6 +32,7 @@ xenconsole: $(patsubst %.c,%.o,$(wildcard client/*.c))
$(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_XENSTORE) \
-lxenctrl -lxenstore
.PHONY: install
install: $(BIN)
$(INSTALL_DIR) -p $(DESTDIR)/$(DAEMON_INSTALL_DIR)
$(INSTALL_PROG) xenconsoled $(DESTDIR)/$(DAEMON_INSTALL_DIR)
+2 -9
View File
@@ -36,7 +36,6 @@
#include <errno.h>
#include <pty.h>
#include "xenctrl.h"
#include "xs.h"
#define ESCAPE_CHARACTER 0x1d
@@ -92,7 +91,7 @@ static void restore_term(int fd, struct termios *old)
tcsetattr(fd, TCSAFLUSH, old);
}
static int console_loop(int xc_handle, domid_t domid, int fd)
static int console_loop(int fd)
{
int ret;
@@ -161,7 +160,6 @@ int main(int argc, char **argv)
{
struct termios attr;
int domid;
int xc_handle;
char *sopt = "h";
int ch;
int opt_ind=0;
@@ -206,11 +204,6 @@ int main(int argc, char **argv)
err(errno, "Could not contact XenStore");
}
xc_handle = xc_interface_open();
if (xc_handle == -1) {
err(errno, "xc_interface_open()");
}
signal(SIGTERM, sighandler);
path = xs_get_domain_path(xs, domid);
@@ -260,7 +253,7 @@ int main(int argc, char **argv)
free(path);
init_term(STDIN_FILENO, &attr);
console_loop(xc_handle, domid, spty);
console_loop(spty);
restore_term(STDIN_FILENO, &attr);
return 0;
+25 -13
View File
@@ -434,26 +434,37 @@ void enum_domains(void)
}
}
static int ring_free_bytes(struct domain *dom)
{
struct xencons_interface *intf = dom->interface;
XENCONS_RING_IDX cons, prod, space;
cons = intf->in_cons;
prod = intf->in_prod;
mb();
space = prod - cons;
if (space > sizeof(intf->in))
return 0; /* ring is screwed: ignore it */
return (sizeof(intf->in) - space);
}
static void handle_tty_read(struct domain *dom)
{
ssize_t len = 0;
char msg[80];
int i;
struct xencons_interface *intf = dom->interface;
XENCONS_RING_IDX cons, prod;
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);
XENCONS_RING_IDX prod;
len = ring_free_bytes(dom);
if (len == 0)
return;
if (len > sizeof(msg))
len = sizeof(msg);
len = read(dom->tty_fd, msg, len);
if (len < 1) {
close(dom->tty_fd);
@@ -465,6 +476,7 @@ static void handle_tty_read(struct domain *dom)
shutdown_domain(dom);
}
} else if (domain_is_valid(dom->domid)) {
prod = intf->in_prod;
for (i = 0; i < len; i++) {
intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
msg[i];
@@ -514,7 +526,7 @@ static void handle_ring_read(struct domain *dom)
(void)write_sync(dom->evtchn_fd, &v, sizeof(v));
}
static void handle_xs(int fd)
static void handle_xs(void)
{
char **vec;
int domid;
@@ -560,7 +572,7 @@ void handle_io(void)
}
if (d->tty_fd != -1) {
if (!d->is_dead)
if (!d->is_dead && ring_free_bytes(d))
FD_SET(d->tty_fd, &readfds);
if (!buffer_empty(&d->buffer))
@@ -572,7 +584,7 @@ void handle_io(void)
ret = select(max_fd + 1, &readfds, &writefds, 0, NULL);
if (FD_ISSET(xs_fileno(xs), &readfds))
handle_xs(xs_fileno(xs));
handle_xs();
for (d = dom_head; d; d = n) {
n = d->next;
+2
View File
@@ -3,10 +3,12 @@ include $(XEN_ROOT)/tools/Rules.mk
LDFLAGS=-static
.PHONY: all
all: console-dom0 console-domU procpipe
console-dom0: console-dom0.o
console-domU: console-domU.o
procpipe: procpipe.o
.PHONY: clean
clean:; $(RM) *.o console-domU console-dom0 procpipe
+4 -3
View File
@@ -1,16 +1,17 @@
DomU GDB server for 32-bit (PAE and non-PAE) systems
DomU & HVM GDB server for 32-bit (PAE and non-PAE) and x86_64 systems
----------------------------------------------------
Lines marked below with [*] are optional, if you want full
source-level debugging of your kernel image.
To build the GDB server:
0. Build rest of the Xen first from the base directory
1. Run ./gdbbuild from within this directory.
2. Copy ./gdb-6.2.1-linux-i386-xen/gdb/gdbserver/gdbserver-xen
to your test machine.
To build a debuggable guest kernel image:
To build a debuggable guest domU kernel image:
1. cd linux-2.6.xx-xenU
2. make menuconfig
3. From within the configurator, enable the following options:
@@ -28,7 +29,7 @@ To debug a running guest:
# bt
# disass
To debug a crashed guest:
To debug a crashed domU guest:
1. Add '(enable-dump yes)' to /etc/xen/xend-config.sxp before
starting xend.
2. When the domain crashes, a core file is written to
@@ -286,6 +286,21 @@ handle_v_requests (char *own_buf, char *status, unsigned char *signal)
return;
}
void
handle_breakpoint_requests (char *own_buf, char *status, unsigned char *signal)
{
/* Currently we only support software breakpoints */
switch (own_buf[1]) {
case '0': /* software breakpoint, int3 based */
own_buf[0] = '\0';
break;
case '1': /* hardware breakpoint */
default:
write_enn (own_buf);
break;
}
}
void
myresume (int step, int sig)
{
@@ -322,6 +337,18 @@ gdbserver_usage (void)
"HOST:PORT to listen for a TCP connection.\n");
}
extern control_c_pressed_flag;
#include <signal.h>
void ctrl_c_handler(int signo)
{
printf("Ctrl-C pressed: Quit from the attached gdb first\n");
control_c_pressed_flag = 1;
}
struct sigaction ctrl_c_sigaction = { .sa_handler = ctrl_c_handler };
struct sigaction old_sigaction;
int
main (int argc, char *argv[])
{
@@ -396,9 +423,11 @@ main (int argc, char *argv[])
}
}
while (1)
{
remote_open (argv[1]);
sigaction(SIGINT, &ctrl_c_sigaction, &old_sigaction);
restart:
setjmp (toplevel);
@@ -587,6 +616,9 @@ main (int argc, char *argv[])
/* Extended (long) request. */
handle_v_requests (own_buf, &status, &signal);
break;
case 'Z':
handle_breakpoint_requests (own_buf, &status, &signal);
break;
default:
/* It is a request we don't understand. Respond with an
empty packet so that gdb knows that we don't support this
@@ -643,5 +675,6 @@ main (int argc, char *argv[])
"GDBserver will reopen the connection.\n");
remote_close ();
}
sigaction(SIGINT, &old_sigaction, NULL);
}
}
Loaded 100 of 327 files, more files were not shown because too many files have changed in this diff. Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.