mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
Merge
This commit is contained in:
commit
0070cb1f3a
204 files changed
+3832
-2189
No files matched your search
@@ -1885,6 +1885,220 @@ mailing lists and subscription information can be found at \begin{quote}
|
||||
|
||||
\appendix
|
||||
|
||||
\chapter{Unmodified (VMX) guest domains in Xen with Intel\textregistered Virtualization Technology (VT)}
|
||||
|
||||
Xen supports guest domains running unmodified Guest operating systems using Virtualization Technology (VT) available on recent Intel Processors. More information about the Intel Virtualization Technology implementing Virtual Machine Extensions (VMX) in the processor is available on the Intel website at \\
|
||||
{\small {\tt http://www.intel.com/technology/computing/vptech}}
|
||||
|
||||
\section{Building Xen with VT support}
|
||||
|
||||
The following packages need to be installed in order to build Xen with VT support. Some Linux distributions do not provide these packages by default.
|
||||
|
||||
\begin{tabular}{lp{11.0cm}}
|
||||
{\bfseries Package} & {\bfseries Description} \\
|
||||
|
||||
dev86 & The dev86 package provides an assembler and linker for real mode 80x86 instructions. You need to have this package installed in order to build the BIOS code which runs in (virtual) real mode.
|
||||
|
||||
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.\\
|
||||
|
||||
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.
|
||||
|
||||
If the SDL and SDL-devel packages are not installed by default on the build system, they can be obtained from {\scriptsize {\tt http://www.rpmfind.net/linux/rpm2html/search.php?query=SDL\&submit=Search}}
|
||||
, {\scriptsize {\tt http://www.rpmfind.net/linux/rpm2html/search.php?query=SDL-devel\&submit=Search}} \\
|
||||
|
||||
\end{tabular}
|
||||
|
||||
\section{Configuration file for unmodified VMX guests}
|
||||
|
||||
The Xen installation includes a sample configuration file, {\small {\tt /etc/xen/xmexample.vmx}}. There are comments describing all the options. In addition to the common options that are the same as those for paravirtualized guest configurations, VMX guest configurations have the following settings:
|
||||
|
||||
\begin{tabular}{lp{11.0cm}}
|
||||
|
||||
{\bfseries Parameter} & {\bfseries Description} \\
|
||||
|
||||
kernel & The VMX firmware loader, {\small {\tt /usr/lib/xen/boot/vmxloader}}\\
|
||||
|
||||
builder & The domain build function. The VMX domain uses the vmx builder.\\
|
||||
|
||||
acpi & Enable VMX guest ACPI, default=0 (disabled)\\
|
||||
|
||||
apic & Enable VMX guest APIC, 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
|
||||
|
||||
{\small {\tt phy:UNAME,ioemu:DEV,MODE,}}
|
||||
|
||||
where UNAME is the device, DEV is the device name the domain will see, and MODE is r for read-only, w for read-write. ioemu means the disk will use ioemu to virtualize the VMX disk. If not adding ioemu, it uses vbd like paravirtualized guests.
|
||||
|
||||
If using disk image file, its form should be like
|
||||
|
||||
{\small {\tt file:FILEPATH,ioemu:DEV,MODE}}
|
||||
|
||||
If using more than one disk, there should be a comma between each disk entry. For example:
|
||||
|
||||
{\scriptsize {\tt disk = ['file:/var/images/image1.img,ioemu:hda,w', 'file:/var/images/image2.img,ioemu:hdb,w']}}\\
|
||||
|
||||
cdrom & Disk image for CD-ROM. The default is {\small {\tt /dev/cdrom}} for Domain0. Inside the VMX domain, the CD-ROM will available as device {\small {\tt /dev/hdc}}. The entry can also point to an ISO file.\\
|
||||
|
||||
boot & Boot from floppy (a), hard disk (c) or CD-ROM (d). For example, to boot from CD-ROM, the entry should be:
|
||||
|
||||
boot='d'\\
|
||||
|
||||
device\_model & The device emulation tool for VMX guests. This parameter should not be changed.\\
|
||||
|
||||
sdl & Enable SDL library for graphics, default = 0 (disabled)\\
|
||||
|
||||
vnc & Enable VNC library for graphics, default = 1 (enabled)\\
|
||||
|
||||
vncviewer & Enable spawning of the vncviewer (only valid when vnc=1), default = 1 (enabled)
|
||||
|
||||
If vnc=1 and vncviewer=0, user can use vncviewer to manually connect VMX from remote. For example:
|
||||
|
||||
{\small {\tt vncviewer domain0\_IP\_address:VMX\_domain\_id}} \\
|
||||
|
||||
ne2000 & Enable ne2000, default = 0 (disabled; use pcnet)\\
|
||||
|
||||
serial & Enable redirection of VMX serial output to pty device\\
|
||||
|
||||
localtime & Set the real time clock to local time [default=0, that is, set to UTC].\\
|
||||
|
||||
enable-audio & Enable audio support. This is under development.\\
|
||||
|
||||
full-screen & Start in full screen. This is under development.\\
|
||||
|
||||
nographic & Another way to redirect serial output. If enabled, no 'sdl' or 'vnc' can work. Not recommended.\\
|
||||
|
||||
\end{tabular}
|
||||
|
||||
|
||||
\section{Creating virtual disks from scratch}
|
||||
\subsection{Using physical disks}
|
||||
If you are using a physical disk or physical disk partition, you need to install a Linux OS on the disk first. Then the boot loader should be installed in the correct place. For example {\small {\tt dev/sda}} for booting from the whole disk, or {\small {\tt /dev/sda1}} for booting from partition 1.
|
||||
|
||||
\subsection{Using disk image files}
|
||||
You need to create a large empty disk image file first; then, you need to install a Linux OS onto it. There are two methods you can choose. One is directly installing it using a VMX guest while booting from the OS installation CD-ROM. The other is copying an installed OS into it. The boot loader will also need to be installed.
|
||||
|
||||
\subsubsection*{To create the image file:}
|
||||
The image size should be big enough to accommodate the entire OS. This example assumes the size is 1G (which is probably too small for most OSes).
|
||||
|
||||
{\small {\tt \# dd if=/dev/zero of=hd.img bs=1M count=1 seek=1023}}
|
||||
|
||||
\subsubsection*{To directly install Linux OS into an image file using a VMX guest:}
|
||||
|
||||
Install Xen and create VMX with the original image file with booting from CD-ROM. Then it is just like a normal Linux OS installation. The VMX configuration file should have these two entries before creating:
|
||||
|
||||
{\small {\tt cdrom='/dev/cdrom'
|
||||
boot='d'}}
|
||||
|
||||
If this method does not succeed, you can choose the following method of copying an installed Linux OS into an image file.
|
||||
|
||||
\subsubsection*{To copy a installed OS into an image file:}
|
||||
Directly installing is an easier way to make partitions and install an OS in a disk image file. But if you want to create a specific OS in your disk image, then you will most likely want to use this method.
|
||||
|
||||
\begin{enumerate}
|
||||
\item {\bfseries Install a normal Linux OS on the host machine}\\
|
||||
You can choose any way to install Linux, such as using yum to install Red Hat Linux or YAST to install Novell SuSE Linux. The rest of this example assumes the Linux OS is installed in {\small {\tt /var/guestos/}}.
|
||||
|
||||
\item {\bfseries Make the partition table}\\
|
||||
The image file will be treated as hard disk, so you should make the partition table in the image file. For example:
|
||||
|
||||
{\scriptsize {\tt \# losetup /dev/loop0 hd.img\\
|
||||
\# fdisk -b 512 -C 4096 -H 16 -S 32 /dev/loop0\\
|
||||
press 'n' to add new partition\\
|
||||
press 'p' to choose primary partition\\
|
||||
press '1' to set partition number\\
|
||||
press "Enter" keys to choose default value of "First Cylinder" parameter.\\
|
||||
press "Enter" keys to choose default value of "Last Cylinder" parameter.\\
|
||||
press 'w' to write partition table and exit\\
|
||||
\# losetup -d /dev/loop0}}
|
||||
|
||||
\item {\bfseries Make the file system and install grub}\\
|
||||
{\scriptsize {\tt \# ln -s /dev/loop0 /dev/loop\\
|
||||
\# losetup /dev/loop0 hd.img\\
|
||||
\# losetup -o 16384 /dev/loop1 hd.img\\
|
||||
\# mkfs.ext3 /dev/loop1\\
|
||||
\# mount /dev/loop1 /mnt\\
|
||||
\# mkdir -p /mnt/boot/grub\\
|
||||
\# cp /boot/grub/stage* /boot/grub/e2fs\_stage1\_5 /mnt/boot/grub\\
|
||||
\# umount /mnt\\
|
||||
\# grub\\
|
||||
grub> device (hd0) /dev/loop\\
|
||||
grub> root (hd0,0)\\
|
||||
grub> setup (hd0)\\
|
||||
grub> quit\\
|
||||
\# rm /dev/loop\\
|
||||
\# losetup -d /dev/loop0\\
|
||||
\# losetup -d /dev/loop1}}
|
||||
|
||||
The {\small {\tt losetup}} option {\small {\tt -o 16384}} skips the partition table in the image file. It is the number of sectors times 512. We need {\small {\tt /dev/loop}} because grub is expecting a disk device \emph{name}, where \emph{name} represents the entire disk and \emph{name1} represents the first partition.
|
||||
|
||||
\item {\bfseries Copy the OS files to the image}\\
|
||||
If you have Xen installed, you can easily use {\small {\tt lomount}} instead of {\small {\tt losetup}} and {\small {\tt mount}} when coping files to some partitions. {\small {\tt lomount}} just needs the partition information.
|
||||
|
||||
{\scriptsize {\tt \# lomount -t ext3 -diskimage hd.img -partition 1 /mnt/guest\\
|
||||
\# cp -ax /var/guestos/\{root,dev,var,etc,usr,bin,sbin,lib\} /mnt/guest\\
|
||||
\# mkdir /mnt/guest/\{proc,sys,home,tmp\}}}
|
||||
|
||||
\item {\bfseries Edit the {\small {\tt /etc/fstab}} of the guest image}\\
|
||||
The fstab should look like this:
|
||||
|
||||
{\scriptsize {\tt \# vim /mnt/guest/etc/fstab\\
|
||||
/dev/hda1 / ext3 defaults 1 1\\
|
||||
none /dev/pts devpts gid=5,mode=620 0 0\\
|
||||
none /dev/shm tmpfs defaults 0 0\\
|
||||
none /proc proc defaults 0 0\\
|
||||
none /sys sysfs efaults 0 0}}
|
||||
|
||||
\item {\bfseries umount the image file}\\
|
||||
{\small {\tt \# umount /mnt/guest}}
|
||||
\end{enumerate}
|
||||
|
||||
Now, the guest OS image {\small {\tt hd.img}} is ready. You can also reference {\small {\tt http://free.oszoo.org}} for quickstart images. But make sure to install the boot loader.
|
||||
|
||||
\subsection{Install Windows into an Image File using a VMX guest}
|
||||
In order to install a Windows OS, you should keep {\small {\tt acpi=0}} in your VMX configuration file.
|
||||
|
||||
\section{VMX Guests}
|
||||
\subsection{Editing the Xen VMX config file}
|
||||
Make a copy of the example VMX configuration file {\small {\tt /etc/xen/xmeaxmple.vmx}} and edit the line that reads
|
||||
|
||||
{\small {\tt disk = [ 'file:/var/images/\emph{guest.img},ioemu:hda,w' ]}}
|
||||
|
||||
replacing \emph{guest.img} with the name of the guest OS image file you just made.
|
||||
|
||||
\subsection{Creating VMX guests}
|
||||
Simply follow the usual method of creating the guest, using the -f parameter and providing the filename of your VMX configuration file:\\
|
||||
|
||||
{\small {\tt \# xend start\\
|
||||
\# xm create /etc/xen/vmxguest.vmx}}
|
||||
|
||||
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{Destroy VMX guests}
|
||||
VMX guests can be destroyed in the same way as can paravirtualized guests. We recommend that you type the command
|
||||
|
||||
{\small {\tt poweroff}}
|
||||
|
||||
in the VMX guest's console first to prevent data loss. Then execute the command
|
||||
|
||||
{\small {\tt xm destroy \emph{vmx\_guest\_id} }}
|
||||
|
||||
at the Domain0 console.
|
||||
|
||||
\subsection{VMX window (X or VNC) Hot Key}
|
||||
If you are running in the X environment after creating a VMX guest, an X window is created. There are several hot keys for control of the VMX guest that can be used in the window.
|
||||
|
||||
{\bfseries Ctrl+Alt+2} switches from guest VGA window to the control window. Typing {\small {\tt help }} shows the control commands help. For example, 'q' is the command to destroy the VMX guest.\\
|
||||
{\bfseries Ctrl+Alt+1} switches back to VMX guest's VGA.\\
|
||||
{\bfseries Ctrl+Alt+3} switches to serial port output. It captures serial output from the VMX guest. It works only if the VMX guest was configured to use the serial port. \\
|
||||
|
||||
\subsection{Save/Restore and Migration}
|
||||
VMX guests currently cannot be saved and restored, nor migrated. These features are currently under active development.
|
||||
|
||||
%% Chapter Glossary of Terms moved to glossary.tex
|
||||
\chapter{Glossary of Terms}
|
||||
|
||||
|
||||
@@ -77,8 +77,6 @@ install kernel_install:
|
||||
install -m0664 .config $(INSTALL_PATH)/boot/config-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
|
||||
install -m0664 System.map $(INSTALL_PATH)/boot/System.map-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
|
||||
ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
|
||||
mkdir -p $(INSTALL_PATH)/usr/include/xen/linux
|
||||
install -m0644 $(srctree)/include/asm-xen/linux-public/*.h $(INSTALL_PATH)/usr/include/xen/linux
|
||||
|
||||
archclean:
|
||||
@if [ -e arch/xen/arch ]; then $(MAKE) $(clean)=arch/xen/arch; fi;
|
||||
|
||||
@@ -40,8 +40,6 @@
|
||||
#include <asm/fixmap.h>
|
||||
#endif
|
||||
|
||||
void (*pm_power_off)(void) = NULL;
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
|
||||
static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) { }
|
||||
|
||||
@@ -67,8 +67,11 @@ int mtrr_add_page(unsigned long base, unsigned long size,
|
||||
op.u.add_memtype.pfn = base;
|
||||
op.u.add_memtype.nr_pfns = size;
|
||||
op.u.add_memtype.type = type;
|
||||
if ((error = HYPERVISOR_dom0_op(&op)))
|
||||
error = HYPERVISOR_dom0_op(&op);
|
||||
if (error) {
|
||||
BUG_ON(error > 0);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (increment)
|
||||
++usage_table[op.u.add_memtype.reg];
|
||||
@@ -121,8 +124,12 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
|
||||
if (--usage_table[reg] < 1) {
|
||||
op.cmd = DOM0_DEL_MEMTYPE;
|
||||
op.u.del_memtype.handle = 0;
|
||||
op.u.add_memtype.reg = reg;
|
||||
(void)HYPERVISOR_dom0_op(&op);
|
||||
op.u.del_memtype.reg = reg;
|
||||
error = HYPERVISOR_dom0_op(&op);
|
||||
if (error) {
|
||||
BUG_ON(error > 0);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
error = reg;
|
||||
out:
|
||||
|
||||
@@ -76,7 +76,9 @@ IF_MASK = 0x00000200
|
||||
DF_MASK = 0x00000400
|
||||
NT_MASK = 0x00004000
|
||||
VM_MASK = 0x00020000
|
||||
|
||||
/* Pseudo-eflags. */
|
||||
NMI_MASK = 0x80000000
|
||||
|
||||
/* Offsets into shared_info_t. */
|
||||
#define evtchn_upcall_pending /* 0 */
|
||||
#define evtchn_upcall_mask 1
|
||||
@@ -305,8 +307,8 @@ restore_all:
|
||||
je ldt_ss # returning to user-space with LDT SS
|
||||
#endif /* XEN */
|
||||
restore_nocheck:
|
||||
testl $VM_MASK, EFLAGS(%esp)
|
||||
jnz resume_vm86
|
||||
testl $(VM_MASK|NMI_MASK), EFLAGS(%esp)
|
||||
jnz hypervisor_iret
|
||||
movb EVENT_MASK(%esp), %al
|
||||
notb %al # %al == ~saved_mask
|
||||
XEN_GET_VCPU_INFO(%esi)
|
||||
@@ -328,11 +330,11 @@ iret_exc:
|
||||
.long 1b,iret_exc
|
||||
.previous
|
||||
|
||||
resume_vm86:
|
||||
XEN_UNBLOCK_EVENTS(%esi)
|
||||
hypervisor_iret:
|
||||
andl $~NMI_MASK, EFLAGS(%esp)
|
||||
RESTORE_REGS
|
||||
movl %eax,(%esp)
|
||||
movl $__HYPERVISOR_switch_vm86,%eax
|
||||
movl $__HYPERVISOR_iret,%eax
|
||||
int $0x82
|
||||
ud2
|
||||
|
||||
@@ -691,6 +693,15 @@ debug_stack_correct:
|
||||
call do_debug
|
||||
jmp ret_from_exception
|
||||
|
||||
ENTRY(nmi)
|
||||
pushl %eax
|
||||
SAVE_ALL
|
||||
xorl %edx,%edx # zero error code
|
||||
movl %esp,%eax # pt_regs pointer
|
||||
call do_nmi
|
||||
orl $NMI_MASK, EFLAGS(%esp)
|
||||
jmp restore_all
|
||||
|
||||
#if 0 /* XEN */
|
||||
/*
|
||||
* NMI is doubly nasty. It can happen _while_ we're handling
|
||||
|
||||
@@ -76,9 +76,7 @@ EXPORT_SYMBOL(ioremap_nocache);
|
||||
EXPORT_SYMBOL(iounmap);
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
EXPORT_SYMBOL(pm_idle);
|
||||
#ifdef CONFIG_ACPI_BOOT
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
#endif
|
||||
EXPORT_SYMBOL(get_cmos_time);
|
||||
EXPORT_SYMBOL(cpu_khz);
|
||||
EXPORT_SYMBOL(apm_info);
|
||||
|
||||
@@ -622,9 +622,11 @@ static int balanced_irq(void *unused)
|
||||
try_to_freeze(PF_FREEZE);
|
||||
if (time_after(jiffies,
|
||||
prev_balance_time+balanced_irq_interval)) {
|
||||
preempt_disable();
|
||||
do_irq_balance();
|
||||
prev_balance_time = jiffies;
|
||||
time_remaining = balanced_irq_interval;
|
||||
preempt_enable();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -506,18 +506,11 @@ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
|
||||
|
||||
static void io_check_error(unsigned char reason, struct pt_regs * regs)
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
printk("NMI: IOCK error (debug interrupt?)\n");
|
||||
show_registers(regs);
|
||||
|
||||
/* Re-enable the IOCK line, wait for a few seconds */
|
||||
reason = (reason & 0xf) | 8;
|
||||
outb(reason, 0x61);
|
||||
i = 2000;
|
||||
while (--i) udelay(1000);
|
||||
reason &= ~8;
|
||||
outb(reason, 0x61);
|
||||
clear_io_check_error(reason);
|
||||
}
|
||||
|
||||
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
|
||||
@@ -648,12 +641,6 @@ fastcall void do_int3(struct pt_regs *regs, long error_code)
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline void conditional_sti(struct pt_regs *regs)
|
||||
{
|
||||
if (regs->eflags & (X86_EFLAGS_IF|VM_MASK))
|
||||
local_irq_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Our handling of the processor debug registers is non-trivial.
|
||||
* We do not clear them on entry and exit from the kernel. Therefore
|
||||
@@ -686,9 +673,9 @@ fastcall void do_debug(struct pt_regs * regs, long error_code)
|
||||
if (notify_die(DIE_DEBUG, "debug", regs, condition, error_code,
|
||||
SIGTRAP) == NOTIFY_STOP)
|
||||
return;
|
||||
|
||||
/* It's safe to allow irq's after DR6 has been saved */
|
||||
conditional_sti(regs);
|
||||
if (regs->eflags & X86_EFLAGS_IF)
|
||||
local_irq_enable();
|
||||
|
||||
/* Mask out spurious debug traps due to lazy DR7 setting */
|
||||
if (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) {
|
||||
|
||||
@@ -65,7 +65,7 @@ static pmd_t * __init one_md_table_init(pgd_t *pgd)
|
||||
{
|
||||
pud_t *pud;
|
||||
pmd_t *pmd_table;
|
||||
|
||||
|
||||
#ifdef CONFIG_X86_PAE
|
||||
pmd_table = (pmd_t *) alloc_bootmem_low_pages(PAGE_SIZE);
|
||||
make_lowmem_page_readonly(pmd_table);
|
||||
|
||||
@@ -17,6 +17,13 @@
|
||||
#include <linux/kthread.h>
|
||||
#include <asm-xen/xencons.h>
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
/*
|
||||
* Power off function, if any
|
||||
*/
|
||||
void (*pm_power_off)(void);
|
||||
#endif
|
||||
|
||||
#define SHUTDOWN_INVALID -1
|
||||
#define SHUTDOWN_POWEROFF 0
|
||||
#define SHUTDOWN_REBOOT 1
|
||||
@@ -283,15 +290,15 @@ static void shutdown_handler(struct xenbus_watch *watch,
|
||||
const char **vec, unsigned int len)
|
||||
{
|
||||
char *str;
|
||||
struct xenbus_transaction *xbt;
|
||||
xenbus_transaction_t xbt;
|
||||
int err;
|
||||
|
||||
if (shutting_down != SHUTDOWN_INVALID)
|
||||
return;
|
||||
|
||||
again:
|
||||
xbt = xenbus_transaction_start();
|
||||
if (IS_ERR(xbt))
|
||||
err = xenbus_transaction_start(&xbt);
|
||||
if (err)
|
||||
return;
|
||||
str = (char *)xenbus_read(xbt, "control", "shutdown", NULL);
|
||||
/* Ignore read errors and empty reads. */
|
||||
@@ -332,12 +339,12 @@ static void sysrq_handler(struct xenbus_watch *watch, const char **vec,
|
||||
unsigned int len)
|
||||
{
|
||||
char sysrq_key = '\0';
|
||||
struct xenbus_transaction *xbt;
|
||||
xenbus_transaction_t xbt;
|
||||
int err;
|
||||
|
||||
again:
|
||||
xbt = xenbus_transaction_start();
|
||||
if (IS_ERR(xbt))
|
||||
err = xenbus_transaction_start(&xbt);
|
||||
if (err)
|
||||
return;
|
||||
if (!xenbus_scanf(xbt, "control", "sysrq", "%c", &sysrq_key)) {
|
||||
printk(KERN_ERR "Unable to read sysrq code in "
|
||||
|
||||
@@ -298,7 +298,7 @@ static void vcpu_hotplug(unsigned int cpu)
|
||||
return;
|
||||
|
||||
sprintf(dir, "cpu/%d", cpu);
|
||||
err = xenbus_scanf(NULL, dir, "availability", "%s", state);
|
||||
err = xenbus_scanf(XBT_NULL, dir, "availability", "%s", state);
|
||||
if (err != 1) {
|
||||
printk(KERN_ERR "XENBUS: Unable to read cpu state\n");
|
||||
return;
|
||||
|
||||
@@ -526,7 +526,7 @@ extern union xen_start_info_union xen_start_info_union;
|
||||
|
||||
unsigned long __init e820_end_of_ram(void)
|
||||
{
|
||||
unsigned long max_end_pfn;
|
||||
unsigned long max_end_pfn;
|
||||
|
||||
if (xen_override_max_pfn == 0) {
|
||||
max_end_pfn = xen_start_info->nr_pages;
|
||||
@@ -612,7 +612,7 @@ void __init parse_memopt(char *p, char **from)
|
||||
{
|
||||
end_user_pfn = memparse(p, from);
|
||||
end_user_pfn >>= PAGE_SHIFT;
|
||||
xen_override_max_pfn = (unsigned long) end_user_pfn;
|
||||
xen_override_max_pfn = (unsigned long) end_user_pfn;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
#ifndef CONFIG_PREEMPT
|
||||
#define retint_kernel retint_restore_args
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* C code is not supposed to know about undefined top of stack. Every time
|
||||
* a C function with an pt_regs argument is called from the SYSCALL based
|
||||
@@ -65,7 +65,7 @@
|
||||
* RESTORE_TOP_OF_STACK syncs the syscall state after any possible ptregs
|
||||
* manipulation.
|
||||
*/
|
||||
|
||||
|
||||
/* %rsp:at FRAMEEND */
|
||||
.macro FIXUP_TOP_OF_STACK tmp
|
||||
movq $__USER_CS,CS(%rsp)
|
||||
@@ -121,19 +121,19 @@
|
||||
.endm
|
||||
|
||||
/*
|
||||
* Must be consistent with the definition in arch_x86_64.h:
|
||||
* struct switch_to_user {
|
||||
* Must be consistent with the definition in arch-x86_64.h:
|
||||
* struct iret_context {
|
||||
* u64 rax, r11, rcx, flags, rip, cs, rflags, rsp, ss;
|
||||
* };
|
||||
* #define VGCF_IN_SYSCALL (1<<8)
|
||||
*/
|
||||
.macro SWITCH_TO_USER flag
|
||||
.macro HYPERVISOR_IRET flag
|
||||
subq $8*4,%rsp # reuse rip, cs, rflags, rsp, ss in the stack
|
||||
movq %rax,(%rsp)
|
||||
movq %r11,1*8(%rsp)
|
||||
movq %rcx,2*8(%rsp) # we saved %rcx upon exceptions
|
||||
movq $\flag,3*8(%rsp)
|
||||
movq $__HYPERVISOR_switch_to_user,%rax
|
||||
movq $__HYPERVISOR_iret,%rax
|
||||
syscall
|
||||
.endm
|
||||
|
||||
@@ -225,7 +225,7 @@ sysret_check:
|
||||
jnz sysret_careful
|
||||
XEN_UNBLOCK_EVENTS(%rsi)
|
||||
RESTORE_ARGS 0,8,0
|
||||
SWITCH_TO_USER VGCF_IN_SYSCALL
|
||||
HYPERVISOR_IRET VGCF_IN_SYSCALL
|
||||
|
||||
/* Handle reschedules */
|
||||
/* edx: work, edi: workmask */
|
||||
@@ -418,7 +418,6 @@ ENTRY(stub_rt_sigreturn)
|
||||
jmp int_ret_from_sys_call
|
||||
CFI_ENDPROC
|
||||
|
||||
|
||||
/*
|
||||
* Interrupt entry/exit.
|
||||
*
|
||||
@@ -479,7 +478,7 @@ kernel_mode:
|
||||
orb $3,1*8(%rsp)
|
||||
iretq
|
||||
user_mode:
|
||||
SWITCH_TO_USER 0
|
||||
HYPERVISOR_IRET 0
|
||||
|
||||
/* edi: workmask, edx: work */
|
||||
retint_careful:
|
||||
@@ -720,6 +719,18 @@ ENTRY(do_hypervisor_callback) # do_hyperviosr_callback(struct *pt_regs)
|
||||
call evtchn_do_upcall
|
||||
jmp error_exit
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
ENTRY(nmi)
|
||||
zeroentry do_nmi_callback
|
||||
ENTRY(do_nmi_callback)
|
||||
addq $8, %rsp
|
||||
call do_nmi
|
||||
RESTORE_REST
|
||||
XEN_BLOCK_EVENTS(%rsi)
|
||||
GET_THREAD_INFO(%rcx)
|
||||
jmp retint_restore_args
|
||||
#endif
|
||||
|
||||
ALIGN
|
||||
restore_all_enable_events:
|
||||
XEN_UNBLOCK_EVENTS(%rsi) # %rsi is already set up...
|
||||
@@ -734,7 +745,7 @@ scrit: /**** START OF CRITICAL REGION ****/
|
||||
orb $3,1*8(%rsp)
|
||||
iretq
|
||||
crit_user_mode:
|
||||
SWITCH_TO_USER 0
|
||||
HYPERVISOR_IRET 0
|
||||
|
||||
14: XEN_LOCKED_BLOCK_EVENTS(%rsi)
|
||||
XEN_PUT_VCPU_INFO(%rsi)
|
||||
|
||||
@@ -68,13 +68,13 @@ static void __init copy_bootdata(char *real_mode_data)
|
||||
|
||||
static void __init setup_boot_cpu_data(void)
|
||||
{
|
||||
int dummy, eax;
|
||||
unsigned int dummy, eax;
|
||||
|
||||
/* get vendor info */
|
||||
cpuid(0, &boot_cpu_data.cpuid_level,
|
||||
(int *)&boot_cpu_data.x86_vendor_id[0],
|
||||
(int *)&boot_cpu_data.x86_vendor_id[8],
|
||||
(int *)&boot_cpu_data.x86_vendor_id[4]);
|
||||
cpuid(0, (unsigned int *)&boot_cpu_data.cpuid_level,
|
||||
(unsigned int *)&boot_cpu_data.x86_vendor_id[0],
|
||||
(unsigned int *)&boot_cpu_data.x86_vendor_id[8],
|
||||
(unsigned int *)&boot_cpu_data.x86_vendor_id[4]);
|
||||
|
||||
/* get cpu type */
|
||||
cpuid(1, &eax, &dummy, &dummy,
|
||||
@@ -109,7 +109,6 @@ void __init x86_64_start_kernel(char * real_mode_data)
|
||||
if (s != NULL)
|
||||
setup_early_printk(s);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DISCONTIGMEM
|
||||
s = strstr(saved_command_line, "numa=");
|
||||
if (s != NULL)
|
||||
|
||||
@@ -255,11 +255,9 @@ static int __init enable_ioapic_setup(char *str)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
__setup("noapic", disable_ioapic_setup);
|
||||
__setup("apic", enable_ioapic_setup);
|
||||
|
||||
|
||||
#include <asm/pci-direct.h>
|
||||
#include <linux/pci_ids.h>
|
||||
#include <linux/pci.h>
|
||||
@@ -1146,6 +1144,7 @@ void __apicdebuginit print_PIC(void)
|
||||
v = inb(0x4d1) << 8 | inb(0x4d0);
|
||||
printk(KERN_DEBUG "... PIC ELCR: %04x\n", v);
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
#else
|
||||
@@ -1191,6 +1190,7 @@ void disable_IO_APIC(void)
|
||||
* Clear the IO-APIC before rebooting:
|
||||
*/
|
||||
clear_IO_APIC();
|
||||
|
||||
#ifndef CONFIG_XEN
|
||||
disconnect_bsp_APIC();
|
||||
#endif
|
||||
@@ -1202,6 +1202,7 @@ void disable_IO_APIC(void)
|
||||
*
|
||||
* by Matt Domsch <Matt_Domsch@dell.com> Tue Dec 21 12:25:05 CST 1999
|
||||
*/
|
||||
|
||||
#ifndef CONFIG_XEN
|
||||
static void __init setup_ioapic_ids_from_mpc (void)
|
||||
{
|
||||
|
||||
@@ -9,18 +9,15 @@
|
||||
* x86_64-specific irq controller code. (e.g. i8259.c and
|
||||
* io_apic.c.)
|
||||
*/
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel_stat.h>
|
||||
|
||||
/*
|
||||
* Interrupt statistics:
|
||||
*/
|
||||
#include <linux/kernel_stat.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/module.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/io_apic.h>
|
||||
|
||||
atomic_t irq_err_count;
|
||||
|
||||
#ifdef CONFIG_X86_IO_APIC
|
||||
#ifdef APIC_MISMATCH_DEBUG
|
||||
atomic_t irq_mis_count;
|
||||
|
||||
@@ -62,6 +62,7 @@ static int alloc_ldt(mm_context_t *pc, unsigned mincount, int reload)
|
||||
if (reload) {
|
||||
#ifdef CONFIG_SMP
|
||||
cpumask_t mask;
|
||||
|
||||
preempt_disable();
|
||||
#endif
|
||||
make_pages_readonly(pc->ldt, (pc->size * LDT_ENTRY_SIZE) /
|
||||
@@ -201,6 +202,7 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int oldmode)
|
||||
struct user_desc ldt_info;
|
||||
|
||||
error = -EINVAL;
|
||||
|
||||
if (bytecount != sizeof(ldt_info))
|
||||
goto out;
|
||||
error = -EFAULT;
|
||||
|
||||
@@ -62,6 +62,7 @@
|
||||
#include <asm-xen/xen-public/physdev.h>
|
||||
#include "setup_arch_pre.h"
|
||||
#include <asm/hypervisor.h>
|
||||
#include <asm-xen/xen-public/nmi.h>
|
||||
#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
|
||||
#define PFN_PHYS(x) ((x) << PAGE_SHIFT)
|
||||
#define end_pfn_map end_pfn
|
||||
@@ -304,7 +305,6 @@ static void __init probe_roms(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static __init void parse_cmdline_early (char ** cmdline_p)
|
||||
{
|
||||
char c = ' ', *to = command_line, *from = COMMAND_LINE;
|
||||
@@ -379,6 +379,7 @@ static __init void parse_cmdline_early (char ** cmdline_p)
|
||||
acpi_skip_timer_override = 1;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_XEN
|
||||
if (!memcmp(from, "nolapic", 7) ||
|
||||
!memcmp(from, "disableapic", 11))
|
||||
@@ -391,7 +392,8 @@ static __init void parse_cmdline_early (char ** cmdline_p)
|
||||
skip_ioapic_setup = 0;
|
||||
ioapic_force = 1;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (!memcmp(from, "mem=", 4))
|
||||
parse_memopt(from+4, &from);
|
||||
|
||||
@@ -588,7 +590,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
HYPERVISOR_vm_assist(VMASST_CMD_enable,
|
||||
VMASST_TYPE_writable_pagetables);
|
||||
|
||||
ARCH_SETUP
|
||||
ARCH_SETUP
|
||||
#else
|
||||
ROOT_DEV = old_decode_dev(ORIG_ROOT_DEV);
|
||||
drive_info = DRIVE_INFO;
|
||||
@@ -612,7 +614,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
init_mm.end_code = (unsigned long) &_etext;
|
||||
init_mm.end_data = (unsigned long) &_edata;
|
||||
#ifdef CONFIG_XEN
|
||||
init_mm.brk = start_pfn << PAGE_SHIFT;
|
||||
init_mm.brk = start_pfn << PAGE_SHIFT;
|
||||
#else
|
||||
init_mm.brk = (unsigned long) &_end;
|
||||
|
||||
@@ -668,7 +670,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
reserve_ebda_region();
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* But first pinch a few for the stack/trampoline stuff
|
||||
@@ -790,8 +791,6 @@ void __init setup_arch(char **cmdline_p)
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ( ! (xen_start_info->flags & SIF_INITDOMAIN))
|
||||
{
|
||||
acpi_disabled = 1;
|
||||
@@ -835,7 +834,7 @@ void __init setup_arch(char **cmdline_p)
|
||||
* and also for regions reported as reserved by the e820.
|
||||
*/
|
||||
probe_roms();
|
||||
e820_reserve_resources();
|
||||
e820_reserve_resources();
|
||||
#endif
|
||||
|
||||
request_resource(&iomem_resource, &video_ram_resource);
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#ifdef CONFIG_XEN
|
||||
#include <asm/hypervisor.h>
|
||||
#endif
|
||||
|
||||
char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
|
||||
|
||||
cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;
|
||||
@@ -165,7 +166,6 @@ void __init cpu_gdt_init(struct desc_ptr *gdt_descr)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void pda_init(int cpu)
|
||||
{
|
||||
struct x8664_pda *pda = &cpu_pda[cpu];
|
||||
@@ -175,9 +175,10 @@ void pda_init(int cpu)
|
||||
#ifndef CONFIG_XEN
|
||||
wrmsrl(MSR_GS_BASE, cpu_pda + cpu);
|
||||
#else
|
||||
HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL,
|
||||
(unsigned long)(cpu_pda + cpu));
|
||||
HYPERVISOR_set_segment_base(SEGBASE_GS_KERNEL,
|
||||
(unsigned long)(cpu_pda + cpu));
|
||||
#endif
|
||||
|
||||
pda->me = pda;
|
||||
pda->cpunumber = cpu;
|
||||
pda->irqcount = -1;
|
||||
@@ -201,6 +202,7 @@ void pda_init(int cpu)
|
||||
}
|
||||
|
||||
switch_pt();
|
||||
|
||||
pda->irqstackptr += IRQSTACKSIZE-64;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,8 +30,9 @@
|
||||
#include <asm/apicdef.h>
|
||||
#ifdef CONFIG_XEN
|
||||
#include <asm-xen/evtchn.h>
|
||||
#endif
|
||||
|
||||
#else
|
||||
#ifndef CONFIG_XEN
|
||||
/*
|
||||
* Smarter SMP flushing macros.
|
||||
* c/o Linus Torvalds.
|
||||
|
||||
@@ -559,9 +559,11 @@ static void mem_parity_error(unsigned char reason, struct pt_regs * regs)
|
||||
printk("Uhhuh. NMI received. Dazed and confused, but trying to continue\n");
|
||||
printk("You probably have a hardware problem with your RAM chips\n");
|
||||
|
||||
#if 0 /* XEN */
|
||||
/* Clear and disable the memory parity error line. */
|
||||
reason = (reason & 0xf) | 4;
|
||||
outb(reason, 0x61);
|
||||
#endif /* XEN */
|
||||
}
|
||||
|
||||
static void io_check_error(unsigned char reason, struct pt_regs * regs)
|
||||
@@ -569,12 +571,14 @@ static void io_check_error(unsigned char reason, struct pt_regs * regs)
|
||||
printk("NMI: IOCK error (debug interrupt?)\n");
|
||||
show_registers(regs);
|
||||
|
||||
#if 0 /* XEN */
|
||||
/* Re-enable the IOCK line, wait for a few seconds */
|
||||
reason = (reason & 0xf) | 8;
|
||||
outb(reason, 0x61);
|
||||
mdelay(2000);
|
||||
reason &= ~8;
|
||||
outb(reason, 0x61);
|
||||
#endif /* XEN */
|
||||
}
|
||||
|
||||
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
|
||||
@@ -890,7 +894,6 @@ asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void)
|
||||
asmlinkage void math_state_restore(void)
|
||||
{
|
||||
struct task_struct *me = current;
|
||||
|
||||
/* clts(); */ /* 'clts' is done for us by Xen during virtual trap. */
|
||||
|
||||
if (!used_math())
|
||||
|
||||
@@ -59,9 +59,7 @@ EXPORT_SYMBOL(disable_irq_nosync);
|
||||
EXPORT_SYMBOL(probe_irq_mask);
|
||||
EXPORT_SYMBOL(kernel_thread);
|
||||
EXPORT_SYMBOL(pm_idle);
|
||||
#ifdef CONFIG_ACPI_BOOT
|
||||
EXPORT_SYMBOL(pm_power_off);
|
||||
#endif
|
||||
EXPORT_SYMBOL(get_cmos_time);
|
||||
|
||||
EXPORT_SYMBOL(__down_failed);
|
||||
|
||||
@@ -153,7 +153,6 @@ void dump_pagetable(unsigned long address)
|
||||
pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
|
||||
preempt_enable();
|
||||
pgd += pgd_index(address);
|
||||
|
||||
printk("PGD %lx ", pgd_val(*pgd));
|
||||
if (bad_address(pgd)) goto bad;
|
||||
if (!pgd_present(*pgd)) goto ret;
|
||||
@@ -258,7 +257,6 @@ static int vmalloc_fault(unsigned long address)
|
||||
pgd = (pgd_t *)per_cpu(cur_pgd, smp_processor_id());
|
||||
preempt_enable();
|
||||
pgd += pgd_index(address);
|
||||
|
||||
pgd_ref = pgd_offset_k(address);
|
||||
if (pgd_none(*pgd_ref))
|
||||
return -1;
|
||||
|
||||
@@ -40,16 +40,16 @@
|
||||
#include <asm/proto.h>
|
||||
#include <asm/smp.h>
|
||||
|
||||
#ifndef Dprintk
|
||||
#define Dprintk(x...)
|
||||
#endif
|
||||
|
||||
extern unsigned long *contiguous_bitmap;
|
||||
|
||||
#if defined(CONFIG_SWIOTLB)
|
||||
extern void swiotlb_init(void);
|
||||
#endif
|
||||
|
||||
#ifndef Dprintk
|
||||
#define Dprintk(x...)
|
||||
#endif
|
||||
|
||||
extern char _stext[];
|
||||
|
||||
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
|
||||
@@ -200,9 +200,9 @@ static void *spp_getpage(void)
|
||||
|
||||
static inline pud_t *pud_offset_u(unsigned long address)
|
||||
{
|
||||
pud_t *pud = level3_user_pgt;
|
||||
pud_t *pud = level3_user_pgt;
|
||||
|
||||
return pud + pud_index(address);
|
||||
return pud + pud_index(address);
|
||||
}
|
||||
|
||||
static void set_pte_phys(unsigned long vaddr,
|
||||
@@ -215,34 +215,27 @@ static void set_pte_phys(unsigned long vaddr,
|
||||
|
||||
Dprintk("set_pte_phys %lx to %lx\n", vaddr, phys);
|
||||
|
||||
pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
|
||||
|
||||
pgd = (user_mode ? pgd_offset_u(vaddr) : pgd_offset_k(vaddr));
|
||||
if (pgd_none(*pgd)) {
|
||||
printk("PGD FIXMAP MISSING, it should be setup in head.S!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
|
||||
|
||||
pud = (user_mode ? pud_offset_u(vaddr) : pud_offset(pgd, vaddr));
|
||||
if (pud_none(*pud)) {
|
||||
pmd = (pmd_t *) spp_getpage();
|
||||
|
||||
make_page_readonly(pmd);
|
||||
xen_pmd_pin(__pa(pmd));
|
||||
make_page_readonly(pmd);
|
||||
xen_pmd_pin(__pa(pmd));
|
||||
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
|
||||
if (pmd != pmd_offset(pud, 0)) {
|
||||
printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
pmd = pmd_offset(pud, vaddr);
|
||||
|
||||
if (pmd_none(*pmd)) {
|
||||
pte = (pte_t *) spp_getpage();
|
||||
make_page_readonly(pte);
|
||||
|
||||
xen_pte_pin(__pa(pte));
|
||||
make_page_readonly(pte);
|
||||
xen_pte_pin(__pa(pte));
|
||||
set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
|
||||
if (pte != pte_offset_kernel(pmd, 0)) {
|
||||
printk("PAGETABLE BUG #02!\n");
|
||||
@@ -252,11 +245,10 @@ static void set_pte_phys(unsigned long vaddr,
|
||||
new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
|
||||
|
||||
pte = pte_offset_kernel(pmd, vaddr);
|
||||
|
||||
if (!pte_none(*pte) &&
|
||||
pte_val(*pte) != (pte_val(new_pte) & __supported_pte_mask))
|
||||
pte_ERROR(*pte);
|
||||
set_pte(pte, new_pte);
|
||||
set_pte(pte, new_pte);
|
||||
|
||||
/*
|
||||
* It's enough to flush this one mapping.
|
||||
@@ -284,11 +276,11 @@ static void set_pte_phys_ma(unsigned long vaddr,
|
||||
if (pud_none(*pud)) {
|
||||
|
||||
pmd = (pmd_t *) spp_getpage();
|
||||
make_page_readonly(pmd);
|
||||
xen_pmd_pin(__pa(pmd));
|
||||
make_page_readonly(pmd);
|
||||
xen_pmd_pin(__pa(pmd));
|
||||
|
||||
set_pud(pud, __pud(__pa(pmd) | _KERNPG_TABLE | _PAGE_USER));
|
||||
|
||||
|
||||
if (pmd != pmd_offset(pud, 0)) {
|
||||
printk("PAGETABLE BUG #01! %p <-> %p\n", pmd, pmd_offset(pud,0));
|
||||
return;
|
||||
@@ -298,8 +290,8 @@ static void set_pte_phys_ma(unsigned long vaddr,
|
||||
|
||||
if (pmd_none(*pmd)) {
|
||||
pte = (pte_t *) spp_getpage();
|
||||
make_page_readonly(pte);
|
||||
xen_pte_pin(__pa(pte));
|
||||
make_page_readonly(pte);
|
||||
xen_pte_pin(__pa(pte));
|
||||
|
||||
set_pmd(pmd, __pmd(__pa(pte) | _KERNPG_TABLE | _PAGE_USER));
|
||||
if (pte != pte_offset_kernel(pmd, 0)) {
|
||||
@@ -311,12 +303,12 @@ static void set_pte_phys_ma(unsigned long vaddr,
|
||||
new_pte = pfn_pte_ma(phys >> PAGE_SHIFT, prot);
|
||||
pte = pte_offset_kernel(pmd, vaddr);
|
||||
|
||||
/*
|
||||
* Note that the pte page is already RO, thus we want to use
|
||||
* xen_l1_entry_update(), not set_pte().
|
||||
*/
|
||||
xen_l1_entry_update(pte,
|
||||
pfn_pte_ma(phys >> PAGE_SHIFT, prot));
|
||||
/*
|
||||
* Note that the pte page is already RO, thus we want to use
|
||||
* xen_l1_entry_update(), not set_pte().
|
||||
*/
|
||||
xen_l1_entry_update(pte,
|
||||
pfn_pte_ma(phys >> PAGE_SHIFT, prot));
|
||||
|
||||
/*
|
||||
* It's enough to flush this one mapping.
|
||||
@@ -347,7 +339,6 @@ void __set_fixmap (enum fixed_addresses idx, unsigned long phys, pgprot_t prot)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* At this point it only supports vsyscall area.
|
||||
*/
|
||||
@@ -360,18 +351,18 @@ void __set_fixmap_user (enum fixed_addresses idx, unsigned long phys, pgprot_t p
|
||||
return;
|
||||
}
|
||||
|
||||
set_pte_phys(address, phys, prot, SET_FIXMAP_USER);
|
||||
set_pte_phys(address, phys, prot, SET_FIXMAP_USER);
|
||||
}
|
||||
|
||||
unsigned long __initdata table_start, tables_space;
|
||||
|
||||
unsigned long get_machine_pfn(unsigned long addr)
|
||||
{
|
||||
pud_t* pud = pud_offset_k(addr);
|
||||
pmd_t* pmd = pmd_offset(pud, addr);
|
||||
pte_t *pte = pte_offset_kernel(pmd, addr);
|
||||
|
||||
return pte_mfn(*pte);
|
||||
pud_t* pud = pud_offset_k(addr);
|
||||
pmd_t* pmd = pmd_offset(pud, addr);
|
||||
pte_t *pte = pte_offset_kernel(pmd, addr);
|
||||
|
||||
return pte_mfn(*pte);
|
||||
}
|
||||
|
||||
static __init void *alloc_static_page(unsigned long *phys)
|
||||
@@ -411,12 +402,11 @@ static inline int make_readonly(unsigned long paddr)
|
||||
|
||||
static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned long end)
|
||||
{
|
||||
long i, j, k;
|
||||
unsigned long paddr;
|
||||
long i, j, k;
|
||||
unsigned long paddr;
|
||||
|
||||
i = pud_index(address);
|
||||
pud = pud + i;
|
||||
|
||||
for (; i < PTRS_PER_PUD; pud++, i++) {
|
||||
unsigned long pmd_phys;
|
||||
pmd_t *pmd;
|
||||
@@ -429,38 +419,37 @@ static void __init phys_pud_init(pud_t *pud, unsigned long address, unsigned lon
|
||||
}
|
||||
|
||||
pmd = alloc_static_page(&pmd_phys);
|
||||
early_make_page_readonly(pmd);
|
||||
xen_pmd_pin(pmd_phys);
|
||||
early_make_page_readonly(pmd);
|
||||
xen_pmd_pin(pmd_phys);
|
||||
set_pud(pud, __pud(pmd_phys | _KERNPG_TABLE));
|
||||
|
||||
for (j = 0; j < PTRS_PER_PMD; pmd++, j++) {
|
||||
unsigned long pte_phys;
|
||||
pte_t *pte, *pte_save;
|
||||
unsigned long pte_phys;
|
||||
pte_t *pte, *pte_save;
|
||||
|
||||
if (paddr >= end) {
|
||||
for (; j < PTRS_PER_PMD; j++, pmd++)
|
||||
set_pmd(pmd, __pmd(0));
|
||||
break;
|
||||
}
|
||||
pte = alloc_static_page(&pte_phys);
|
||||
pte_save = pte;
|
||||
for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += PTE_SIZE) {
|
||||
if ((paddr >= end) ||
|
||||
((paddr >> PAGE_SHIFT) >=
|
||||
xen_start_info->nr_pages)) {
|
||||
__set_pte(pte, __pte(0));
|
||||
continue;
|
||||
}
|
||||
if (make_readonly(paddr)) {
|
||||
__set_pte(pte,
|
||||
__pte(paddr | (_KERNPG_TABLE & ~_PAGE_RW)));
|
||||
continue;
|
||||
}
|
||||
__set_pte(pte, __pte(paddr | _KERNPG_TABLE));
|
||||
}
|
||||
pte = pte_save;
|
||||
early_make_page_readonly(pte);
|
||||
xen_pte_pin(pte_phys);
|
||||
pte = alloc_static_page(&pte_phys);
|
||||
pte_save = pte;
|
||||
for (k = 0; k < PTRS_PER_PTE; pte++, k++, paddr += PTE_SIZE) {
|
||||
if ((paddr >= end) ||
|
||||
((paddr >> PAGE_SHIFT) >=
|
||||
xen_start_info->nr_pages)) {
|
||||
__set_pte(pte, __pte(0));
|
||||
continue;
|
||||
}
|
||||
if (make_readonly(paddr)) {
|
||||
__set_pte(pte,
|
||||
__pte(paddr | (_KERNPG_TABLE & ~_PAGE_RW)));
|
||||
continue;
|
||||
}
|
||||
__set_pte(pte, __pte(paddr | _KERNPG_TABLE));
|
||||
}
|
||||
pte = pte_save;
|
||||
early_make_page_readonly(pte);
|
||||
xen_pte_pin(pte_phys);
|
||||
set_pmd(pmd, __pmd(pte_phys | _KERNPG_TABLE));
|
||||
}
|
||||
}
|
||||
@@ -506,7 +495,7 @@ void __init xen_init_pt(void)
|
||||
level3_kernel_pgt[pud_index(__START_KERNEL_map)] =
|
||||
__pud(__pa_symbol(level2_kernel_pgt) |
|
||||
_KERNPG_TABLE | _PAGE_USER);
|
||||
memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
|
||||
memcpy((void *)level2_kernel_pgt, page, PAGE_SIZE);
|
||||
|
||||
early_make_page_readonly(init_level4_pgt);
|
||||
early_make_page_readonly(init_level4_user_pgt);
|
||||
@@ -618,7 +607,7 @@ extern struct x8664_pda cpu_pda[NR_CPUS];
|
||||
|
||||
void zap_low_mappings(void)
|
||||
{
|
||||
/* this is not required for Xen */
|
||||
/* this is not required for Xen */
|
||||
#if 0
|
||||
swap_low_mappings();
|
||||
#endif
|
||||
@@ -629,11 +618,11 @@ void __init paging_init(void)
|
||||
{
|
||||
{
|
||||
unsigned long zones_size[MAX_NR_ZONES] = {0, 0, 0};
|
||||
/* unsigned int max_dma; */
|
||||
/* max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; */
|
||||
/* if (end_pfn < max_dma) */
|
||||
/* unsigned int max_dma; */
|
||||
/* max_dma = virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT; */
|
||||
/* if (end_pfn < max_dma) */
|
||||
zones_size[ZONE_DMA] = end_pfn;
|
||||
#if 0
|
||||
#if 0
|
||||
else {
|
||||
zones_size[ZONE_DMA] = max_dma;
|
||||
zones_size[ZONE_NORMAL] = end_pfn - max_dma;
|
||||
@@ -642,16 +631,16 @@ void __init paging_init(void)
|
||||
free_area_init(zones_size);
|
||||
}
|
||||
|
||||
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
|
||||
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
|
||||
set_fixmap(FIX_SHARED_INFO, xen_start_info->shared_info);
|
||||
HYPERVISOR_shared_info = (shared_info_t *)fix_to_virt(FIX_SHARED_INFO);
|
||||
|
||||
memset(empty_zero_page, 0, sizeof(empty_zero_page));
|
||||
memset(empty_zero_page, 0, sizeof(empty_zero_page));
|
||||
init_mm.context.pinned = 1;
|
||||
|
||||
#ifdef CONFIG_XEN_PHYSDEV_ACCESS
|
||||
{
|
||||
int i;
|
||||
/* Setup mapping of lower 1st MB */
|
||||
/* Setup mapping of lower 1st MB */
|
||||
for (i = 0; i < NR_FIX_ISAMAPS; i++)
|
||||
if (xen_start_info->flags & SIF_PRIVILEGED)
|
||||
set_fixmap(FIX_ISAMAP_BEGIN - i, i * PAGE_SIZE);
|
||||
@@ -701,7 +690,7 @@ void __init clear_kernel_mapping(unsigned long address, unsigned long size)
|
||||
|
||||
static inline int page_is_ram (unsigned long pagenr)
|
||||
{
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct kcore_list kcore_mem, kcore_vmalloc, kcore_kernel, kcore_modules,
|
||||
@@ -790,10 +779,10 @@ extern char __initdata_begin[], __initdata_end[];
|
||||
void free_initmem(void)
|
||||
{
|
||||
#ifdef __DO_LATER__
|
||||
/*
|
||||
* Some pages can be pinned, but some are not. Unpinning such pages
|
||||
* triggers BUG().
|
||||
*/
|
||||
/*
|
||||
* Some pages can be pinned, but some are not. Unpinning such pages
|
||||
* triggers BUG().
|
||||
*/
|
||||
unsigned long addr;
|
||||
|
||||
addr = (unsigned long)(&__init_begin);
|
||||
@@ -801,12 +790,12 @@ void free_initmem(void)
|
||||
ClearPageReserved(virt_to_page(addr));
|
||||
set_page_count(virt_to_page(addr), 1);
|
||||
memset((void *)(addr & ~(PAGE_SIZE-1)), 0xcc, PAGE_SIZE);
|
||||
xen_pte_unpin(__pa(addr));
|
||||
make_page_writable(__va(__pa(addr)));
|
||||
/*
|
||||
* Make pages from __PAGE_OFFSET address as well
|
||||
*/
|
||||
make_page_writable((void *)addr);
|
||||
xen_pte_unpin(__pa(addr));
|
||||
make_page_writable(__va(__pa(addr)));
|
||||
/*
|
||||
* Make pages from __PAGE_OFFSET address as well
|
||||
*/
|
||||
make_page_writable((void *)addr);
|
||||
free_page(addr);
|
||||
totalram_pages++;
|
||||
}
|
||||
@@ -856,7 +845,7 @@ int kern_addr_valid(unsigned long addr)
|
||||
if (pgd_none(*pgd))
|
||||
return 0;
|
||||
|
||||
pud = pud_offset_k(addr);
|
||||
pud = pud_offset_k(addr);
|
||||
if (pud_none(*pud))
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ static void watch_target(struct xenbus_watch *watch,
|
||||
unsigned long long new_target;
|
||||
int err;
|
||||
|
||||
err = xenbus_scanf(NULL, "memory", "target", "%llu", &new_target);
|
||||
err = xenbus_scanf(XBT_NULL, "memory", "target", "%llu", &new_target);
|
||||
if (err != 1) {
|
||||
/* This is ok (for domain0 at least) - so just return */
|
||||
return;
|
||||
|
||||
@@ -540,6 +540,9 @@ static int __init blkif_init(void)
|
||||
pending_vaddrs = kmalloc(sizeof(pending_vaddrs[0]) *
|
||||
mmap_pages, GFP_KERNEL);
|
||||
if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) {
|
||||
kfree(pending_reqs);
|
||||
kfree(pending_grant_handles);
|
||||
kfree(pending_vaddrs);
|
||||
printk("%s: out of memory\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ static int blkback_probe(struct xenbus_device *dev,
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
|
||||
err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
@@ -175,7 +175,7 @@ static void backend_changed(struct xenbus_watch *watch,
|
||||
|
||||
DPRINTK("");
|
||||
|
||||
err = xenbus_scanf(NULL, dev->nodename, "physical-device", "%x:%x",
|
||||
err = xenbus_scanf(XBT_NULL, dev->nodename, "physical-device", "%x:%x",
|
||||
&major, &minor);
|
||||
if (XENBUS_EXIST_ERR(err)) {
|
||||
/* Since this watch will fire once immediately after it is
|
||||
@@ -197,7 +197,7 @@ static void backend_changed(struct xenbus_watch *watch,
|
||||
return;
|
||||
}
|
||||
|
||||
be->mode = xenbus_read(NULL, dev->nodename, "mode", NULL);
|
||||
be->mode = xenbus_read(XBT_NULL, dev->nodename, "mode", NULL);
|
||||
if (IS_ERR(be->mode)) {
|
||||
err = PTR_ERR(be->mode);
|
||||
be->mode = NULL;
|
||||
@@ -268,7 +268,7 @@ static void frontend_changed(struct xenbus_device *dev,
|
||||
break;
|
||||
|
||||
case XenbusStateClosing:
|
||||
xenbus_switch_state(dev, NULL, XenbusStateClosing);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
|
||||
break;
|
||||
|
||||
case XenbusStateClosed:
|
||||
@@ -302,7 +302,7 @@ static void maybe_connect(struct backend_info *be)
|
||||
*/
|
||||
static void connect(struct backend_info *be)
|
||||
{
|
||||
struct xenbus_transaction *xbt;
|
||||
xenbus_transaction_t xbt;
|
||||
int err;
|
||||
struct xenbus_device *dev = be->dev;
|
||||
|
||||
@@ -310,10 +310,9 @@ static void connect(struct backend_info *be)
|
||||
|
||||
/* Supply the information about the device the frontend needs */
|
||||
again:
|
||||
xbt = xenbus_transaction_start();
|
||||
err = xenbus_transaction_start(&xbt);
|
||||
|
||||
if (IS_ERR(xbt)) {
|
||||
err = PTR_ERR(xbt);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(dev, err, "starting transaction");
|
||||
return;
|
||||
}
|
||||
@@ -366,7 +365,7 @@ static int connect_ring(struct backend_info *be)
|
||||
|
||||
DPRINTK("%s", dev->otherend);
|
||||
|
||||
err = xenbus_gather(NULL, dev->otherend, "ring-ref", "%lu", &ring_ref,
|
||||
err = xenbus_gather(XBT_NULL, dev->otherend, "ring-ref", "%lu", &ring_ref,
|
||||
"event-channel", "%u", &evtchn, NULL);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(dev, err,
|
||||
|
||||
@@ -91,7 +91,7 @@ static int blkfront_probe(struct xenbus_device *dev,
|
||||
struct blkfront_info *info;
|
||||
|
||||
/* FIXME: Use dynamic device id if this is not set. */
|
||||
err = xenbus_scanf(NULL, dev->nodename,
|
||||
err = xenbus_scanf(XBT_NULL, dev->nodename,
|
||||
"virtual-device", "%i", &vdevice);
|
||||
if (err != 1) {
|
||||
xenbus_dev_fatal(dev, err, "reading virtual-device");
|
||||
@@ -161,7 +161,7 @@ static int talk_to_backend(struct xenbus_device *dev,
|
||||
struct blkfront_info *info)
|
||||
{
|
||||
const char *message = NULL;
|
||||
struct xenbus_transaction *xbt;
|
||||
xenbus_transaction_t xbt;
|
||||
int err;
|
||||
|
||||
/* Create shared ring, alloc event channel. */
|
||||
@@ -170,8 +170,8 @@ static int talk_to_backend(struct xenbus_device *dev,
|
||||
goto out;
|
||||
|
||||
again:
|
||||
xbt = xenbus_transaction_start();
|
||||
if (IS_ERR(xbt)) {
|
||||
err = xenbus_transaction_start(&xbt);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(dev, err, "starting transaction");
|
||||
goto destroy_blkring;
|
||||
}
|
||||
@@ -319,7 +319,7 @@ static void connect(struct blkfront_info *info)
|
||||
|
||||
DPRINTK("blkfront.c:connect:%s.\n", info->xbdev->otherend);
|
||||
|
||||
err = xenbus_gather(NULL, info->xbdev->otherend,
|
||||
err = xenbus_gather(XBT_NULL, info->xbdev->otherend,
|
||||
"sectors", "%lu", §ors,
|
||||
"info", "%u", &binfo,
|
||||
"sector-size", "%lu", §or_size,
|
||||
@@ -338,7 +338,7 @@ static void connect(struct blkfront_info *info)
|
||||
return;
|
||||
}
|
||||
|
||||
(void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected);
|
||||
(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
|
||||
|
||||
/* Kick pending requests. */
|
||||
spin_lock_irq(&blkif_io_lock);
|
||||
@@ -367,7 +367,7 @@ static void blkfront_closing(struct xenbus_device *dev)
|
||||
info->mi = NULL;
|
||||
}
|
||||
|
||||
xenbus_switch_state(dev, NULL, XenbusStateClosed);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
|
||||
}
|
||||
|
||||
|
||||
@@ -775,7 +775,7 @@ static void blkif_recover(struct blkfront_info *info)
|
||||
|
||||
kfree(copy);
|
||||
|
||||
(void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected);
|
||||
(void)xenbus_switch_state(info->xbdev, XBT_NULL, XenbusStateConnected);
|
||||
|
||||
/* Now safe for us to use the shared ring */
|
||||
spin_lock_irq(&blkif_io_lock);
|
||||
|
||||
@@ -208,7 +208,7 @@ static struct page *blktap_nopage(struct vm_area_struct *vma,
|
||||
}
|
||||
|
||||
struct vm_operations_struct blktap_vm_ops = {
|
||||
nopage: blktap_nopage,
|
||||
.nopage = blktap_nopage,
|
||||
};
|
||||
|
||||
/******************************************************************
|
||||
@@ -225,7 +225,7 @@ static int blktap_open(struct inode *inode, struct file *filp)
|
||||
/* Allocate the fe ring. */
|
||||
sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
|
||||
if (sring == NULL)
|
||||
goto fail_nomem;
|
||||
return -ENOMEM;
|
||||
|
||||
SetPageReserved(virt_to_page(sring));
|
||||
|
||||
@@ -233,9 +233,6 @@ static int blktap_open(struct inode *inode, struct file *filp)
|
||||
FRONT_RING_INIT(&blktap_ufe_ring, sring, PAGE_SIZE);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_nomem:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int blktap_release(struct inode *inode, struct file *filp)
|
||||
@@ -391,12 +388,12 @@ void blktap_kick_user(void)
|
||||
}
|
||||
|
||||
static struct file_operations blktap_fops = {
|
||||
owner: THIS_MODULE,
|
||||
poll: blktap_poll,
|
||||
ioctl: blktap_ioctl,
|
||||
open: blktap_open,
|
||||
release: blktap_release,
|
||||
mmap: blktap_mmap,
|
||||
.owner = THIS_MODULE,
|
||||
.poll = blktap_poll,
|
||||
.ioctl = blktap_ioctl,
|
||||
.open = blktap_open,
|
||||
.release = blktap_release,
|
||||
.mmap = blktap_mmap,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -314,39 +314,31 @@ static void __xencons_tx_flush(void)
|
||||
{
|
||||
int sent, sz, work_done = 0;
|
||||
|
||||
if (xen_start_info->flags & SIF_INITDOMAIN) {
|
||||
if (x_char) {
|
||||
if (x_char) {
|
||||
if (xen_start_info->flags & SIF_INITDOMAIN)
|
||||
kcons_write_dom0(NULL, &x_char, 1);
|
||||
x_char = 0;
|
||||
work_done = 1;
|
||||
}
|
||||
else
|
||||
while (x_char)
|
||||
if (xencons_ring_send(&x_char, 1) == 1)
|
||||
break;
|
||||
x_char = 0;
|
||||
work_done = 1;
|
||||
}
|
||||
|
||||
while (wc != wp) {
|
||||
sz = wp - wc;
|
||||
if (sz > (wbuf_size - WBUF_MASK(wc)))
|
||||
sz = wbuf_size - WBUF_MASK(wc);
|
||||
while (wc != wp) {
|
||||
sz = wp - wc;
|
||||
if (sz > (wbuf_size - WBUF_MASK(wc)))
|
||||
sz = wbuf_size - WBUF_MASK(wc);
|
||||
if (xen_start_info->flags & SIF_INITDOMAIN) {
|
||||
kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz);
|
||||
wc += sz;
|
||||
work_done = 1;
|
||||
}
|
||||
} else {
|
||||
while (x_char) {
|
||||
if (xencons_ring_send(&x_char, 1) == 1) {
|
||||
x_char = 0;
|
||||
work_done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
while (wc != wp) {
|
||||
sz = wp - wc;
|
||||
if (sz > (wbuf_size - WBUF_MASK(wc)))
|
||||
sz = wbuf_size - WBUF_MASK(wc);
|
||||
} else {
|
||||
sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
|
||||
if (sent == 0)
|
||||
break;
|
||||
wc += sent;
|
||||
work_done = 1;
|
||||
}
|
||||
work_done = 1;
|
||||
}
|
||||
|
||||
if (work_done && (xencons_tty != NULL)) {
|
||||
|
||||
@@ -38,7 +38,7 @@ int xen_net_read_mac(struct xenbus_device *dev, u8 mac[])
|
||||
char *s;
|
||||
int i;
|
||||
char *e;
|
||||
char *macstr = xenbus_read(NULL, dev->nodename, "mac", NULL);
|
||||
char *macstr = xenbus_read(XBT_NULL, dev->nodename, "mac", NULL);
|
||||
if (IS_ERR(macstr)) {
|
||||
return PTR_ERR(macstr);
|
||||
}
|
||||
|
||||
@@ -183,7 +183,7 @@ static void unmap_frontend_pages(netif_t *netif)
|
||||
int netif_map(netif_t *netif, unsigned long tx_ring_ref,
|
||||
unsigned long rx_ring_ref, unsigned int evtchn)
|
||||
{
|
||||
int err;
|
||||
int err = -ENOMEM;
|
||||
netif_tx_sring_t *txs;
|
||||
netif_rx_sring_t *rxs;
|
||||
evtchn_op_t op = {
|
||||
@@ -199,25 +199,16 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
|
||||
if (netif->tx_comms_area == NULL)
|
||||
return -ENOMEM;
|
||||
netif->rx_comms_area = alloc_vm_area(PAGE_SIZE);
|
||||
if (netif->rx_comms_area == NULL) {
|
||||
free_vm_area(netif->tx_comms_area);
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (netif->rx_comms_area == NULL)
|
||||
goto err_rx;
|
||||
|
||||
err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref);
|
||||
if (err) {
|
||||
free_vm_area(netif->tx_comms_area);
|
||||
free_vm_area(netif->rx_comms_area);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto err_map;
|
||||
|
||||
err = HYPERVISOR_event_channel_op(&op);
|
||||
if (err) {
|
||||
unmap_frontend_pages(netif);
|
||||
free_vm_area(netif->tx_comms_area);
|
||||
free_vm_area(netif->rx_comms_area);
|
||||
return err;
|
||||
}
|
||||
if (err)
|
||||
goto err_hypervisor;
|
||||
|
||||
netif->evtchn = op.u.bind_interdomain.local_port;
|
||||
|
||||
@@ -245,6 +236,13 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
err_hypervisor:
|
||||
unmap_frontend_pages(netif);
|
||||
err_map:
|
||||
free_vm_area(netif->rx_comms_area);
|
||||
err_rx:
|
||||
free_vm_area(netif->tx_comms_area);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void free_netif_callback(void *arg)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <asm-xen/balloon.h>
|
||||
#include <asm-xen/xen-public/memory.h>
|
||||
|
||||
/*#define NETBE_DEBUG_INTERRUPT*/
|
||||
|
||||
static void netif_idx_release(u16 pending_idx);
|
||||
static void netif_page_release(struct page *page);
|
||||
@@ -727,6 +728,7 @@ static int make_rx_response(netif_t *netif,
|
||||
return notify;
|
||||
}
|
||||
|
||||
#ifdef NETBE_DEBUG_INTERRUPT
|
||||
static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
struct list_head *ent;
|
||||
@@ -758,6 +760,7 @@ static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
|
||||
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init netback_init(void)
|
||||
{
|
||||
@@ -794,6 +797,7 @@ static int __init netback_init(void)
|
||||
|
||||
netif_xenbus_init();
|
||||
|
||||
#ifdef NETBE_DEBUG_INTERRUPT
|
||||
(void)bind_virq_to_irqhandler(
|
||||
VIRQ_DEBUG,
|
||||
0,
|
||||
@@ -801,6 +805,7 @@ static int __init netback_init(void)
|
||||
SA_SHIRQ,
|
||||
"net-be-dbg",
|
||||
&netif_be_dbg);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ static int netback_probe(struct xenbus_device *dev,
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
|
||||
err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
|
||||
if (err) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -122,7 +122,7 @@ static int netback_hotplug(struct xenbus_device *xdev, char **envp,
|
||||
|
||||
DPRINTK("netback_hotplug");
|
||||
|
||||
val = xenbus_read(NULL, xdev->nodename, "script", NULL);
|
||||
val = xenbus_read(XBT_NULL, xdev->nodename, "script", NULL);
|
||||
if (IS_ERR(val)) {
|
||||
int err = PTR_ERR(val);
|
||||
xenbus_dev_fatal(xdev, err, "reading script");
|
||||
@@ -160,7 +160,7 @@ static void backend_changed(struct xenbus_watch *watch,
|
||||
|
||||
DPRINTK("");
|
||||
|
||||
err = xenbus_scanf(NULL, dev->nodename, "handle", "%li", &handle);
|
||||
err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%li", &handle);
|
||||
if (XENBUS_EXIST_ERR(err)) {
|
||||
/* Since this watch will fire once immediately after it is
|
||||
registered, we expect this. Ignore it, and wait for the
|
||||
@@ -212,7 +212,7 @@ static void frontend_changed(struct xenbus_device *dev,
|
||||
break;
|
||||
|
||||
case XenbusStateClosing:
|
||||
xenbus_switch_state(dev, NULL, XenbusStateClosing);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
|
||||
break;
|
||||
|
||||
case XenbusStateClosed:
|
||||
@@ -256,7 +256,7 @@ static void connect(struct backend_info *be)
|
||||
return;
|
||||
}
|
||||
|
||||
xenbus_switch_state(dev, NULL, XenbusStateConnected);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateConnected);
|
||||
}
|
||||
|
||||
|
||||
@@ -269,7 +269,7 @@ static int connect_rings(struct backend_info *be)
|
||||
|
||||
DPRINTK("");
|
||||
|
||||
err = xenbus_gather(NULL, dev->otherend,
|
||||
err = xenbus_gather(XBT_NULL, dev->otherend,
|
||||
"tx-ring-ref", "%lu", &tx_ring_ref,
|
||||
"rx-ring-ref", "%lu", &rx_ring_ref,
|
||||
"event-channel", "%u", &evtchn, NULL);
|
||||
|
||||
@@ -212,7 +212,7 @@ static int netfront_probe(struct xenbus_device *dev,
|
||||
struct netfront_info *info;
|
||||
unsigned int handle;
|
||||
|
||||
err = xenbus_scanf(NULL, dev->nodename, "handle", "%u", &handle);
|
||||
err = xenbus_scanf(XBT_NULL, dev->nodename, "handle", "%u", &handle);
|
||||
if (err != 1) {
|
||||
xenbus_dev_fatal(dev, err, "reading handle");
|
||||
return err;
|
||||
@@ -260,7 +260,7 @@ static int talk_to_backend(struct xenbus_device *dev,
|
||||
struct netfront_info *info)
|
||||
{
|
||||
const char *message;
|
||||
struct xenbus_transaction *xbt;
|
||||
xenbus_transaction_t xbt;
|
||||
int err;
|
||||
|
||||
err = xen_net_read_mac(dev, info->mac);
|
||||
@@ -275,8 +275,8 @@ static int talk_to_backend(struct xenbus_device *dev,
|
||||
goto out;
|
||||
|
||||
again:
|
||||
xbt = xenbus_transaction_start();
|
||||
if (IS_ERR(xbt)) {
|
||||
err = xenbus_transaction_start(&xbt);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(dev, err, "starting transaction");
|
||||
goto destroy_ring;
|
||||
}
|
||||
@@ -1199,7 +1199,7 @@ static void netfront_closing(struct xenbus_device *dev)
|
||||
|
||||
close_netdev(info);
|
||||
|
||||
xenbus_switch_state(dev, NULL, XenbusStateClosed);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
|
||||
}
|
||||
|
||||
|
||||
@@ -1218,22 +1218,14 @@ static int netfront_remove(struct xenbus_device *dev)
|
||||
|
||||
static void close_netdev(struct netfront_info *info)
|
||||
{
|
||||
/* Stop old i/f to prevent errors whilst we rebuild the state. */
|
||||
spin_lock_irq(&info->tx_lock);
|
||||
spin_lock(&info->rx_lock);
|
||||
spin_lock_irq(&info->netdev->xmit_lock);
|
||||
netif_stop_queue(info->netdev);
|
||||
/* info->backend_state = BEST_DISCONNECTED; */
|
||||
spin_unlock(&info->rx_lock);
|
||||
spin_unlock_irq(&info->tx_lock);
|
||||
spin_unlock_irq(&info->netdev->xmit_lock);
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
xennet_proc_delif(info->netdev);
|
||||
#endif
|
||||
|
||||
if (info->irq)
|
||||
unbind_from_irqhandler(info->irq, info->netdev);
|
||||
info->evtchn = info->irq = 0;
|
||||
|
||||
del_timer_sync(&info->rx_refill_timer);
|
||||
|
||||
unregister_netdev(info->netdev);
|
||||
@@ -1242,6 +1234,17 @@ static void close_netdev(struct netfront_info *info)
|
||||
|
||||
static void netif_disconnect_backend(struct netfront_info *info)
|
||||
{
|
||||
/* Stop old i/f to prevent errors whilst we rebuild the state. */
|
||||
spin_lock_irq(&info->tx_lock);
|
||||
spin_lock(&info->rx_lock);
|
||||
info->backend_state = BEST_DISCONNECTED;
|
||||
spin_unlock(&info->rx_lock);
|
||||
spin_unlock_irq(&info->tx_lock);
|
||||
|
||||
if (info->irq)
|
||||
unbind_from_irqhandler(info->irq, info->netdev);
|
||||
info->evtchn = info->irq = 0;
|
||||
|
||||
end_access(info->tx_ring_ref, info->tx.sring);
|
||||
end_access(info->rx_ring_ref, info->rx.sring);
|
||||
info->tx_ring_ref = GRANT_INVALID_REF;
|
||||
|
||||
@@ -89,7 +89,7 @@ static int tpmback_probe(struct xenbus_device *dev,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
err = xenbus_switch_state(dev, NULL, XenbusStateInitWait);
|
||||
err = xenbus_switch_state(dev, XBT_NULL, XenbusStateInitWait);
|
||||
if (err) {
|
||||
goto fail;
|
||||
}
|
||||
@@ -109,7 +109,7 @@ static void backend_changed(struct xenbus_watch *watch,
|
||||
= container_of(watch, struct backend_info, backend_watch);
|
||||
struct xenbus_device *dev = be->dev;
|
||||
|
||||
err = xenbus_scanf(NULL, dev->nodename,
|
||||
err = xenbus_scanf(XBT_NULL, dev->nodename,
|
||||
"instance","%li", &instance);
|
||||
if (XENBUS_EXIST_ERR(err)) {
|
||||
return;
|
||||
@@ -177,7 +177,7 @@ static void frontend_changed(struct xenbus_device *dev,
|
||||
break;
|
||||
|
||||
case XenbusStateClosing:
|
||||
xenbus_switch_state(dev, NULL, XenbusStateClosing);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
|
||||
break;
|
||||
|
||||
case XenbusStateClosed:
|
||||
@@ -230,15 +230,14 @@ static void maybe_connect(struct backend_info *be)
|
||||
|
||||
static void connect(struct backend_info *be)
|
||||
{
|
||||
struct xenbus_transaction *xbt;
|
||||
xenbus_transaction_t xbt;
|
||||
int err;
|
||||
struct xenbus_device *dev = be->dev;
|
||||
unsigned long ready = 1;
|
||||
|
||||
again:
|
||||
xbt = xenbus_transaction_start();
|
||||
if (IS_ERR(xbt)) {
|
||||
err = PTR_ERR(xbt);
|
||||
err = xenbus_transaction_start(&xbt);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(be->dev, err, "starting transaction");
|
||||
return;
|
||||
}
|
||||
@@ -275,7 +274,7 @@ static int connect_ring(struct backend_info *be)
|
||||
unsigned int evtchn;
|
||||
int err;
|
||||
|
||||
err = xenbus_gather(NULL, dev->otherend,
|
||||
err = xenbus_gather(XBT_NULL, dev->otherend,
|
||||
"ring-ref", "%lu", &ring_ref,
|
||||
"event-channel", "%u", &evtchn, NULL);
|
||||
if (err) {
|
||||
|
||||
@@ -271,7 +271,7 @@ static int talk_to_backend(struct xenbus_device *dev,
|
||||
{
|
||||
const char *message = NULL;
|
||||
int err;
|
||||
struct xenbus_transaction *xbt;
|
||||
xenbus_transaction_t xbt;
|
||||
|
||||
err = setup_tpmring(dev, info);
|
||||
if (err) {
|
||||
@@ -280,8 +280,8 @@ static int talk_to_backend(struct xenbus_device *dev,
|
||||
}
|
||||
|
||||
again:
|
||||
xbt = xenbus_transaction_start();
|
||||
if (IS_ERR(xbt)) {
|
||||
err = xenbus_transaction_start(&xbt);
|
||||
if (err) {
|
||||
xenbus_dev_fatal(dev, err, "starting transaction");
|
||||
goto destroy_tpmring;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ EXPORT_SYMBOL(xenbus_watch_path2);
|
||||
|
||||
|
||||
int xenbus_switch_state(struct xenbus_device *dev,
|
||||
struct xenbus_transaction *xbt,
|
||||
xenbus_transaction_t xbt,
|
||||
XenbusState state)
|
||||
{
|
||||
/* We check whether the state is currently set to the given value, and
|
||||
@@ -152,7 +152,7 @@ void _dev_error(struct xenbus_device *dev, int err, const char *fmt,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (xenbus_write(NULL, path_buffer, "error", printf_buffer) != 0) {
|
||||
if (xenbus_write(XBT_NULL, path_buffer, "error", printf_buffer) != 0) {
|
||||
printk("xenbus: failed to write error node for %s (%s)\n",
|
||||
dev->nodename, printf_buffer);
|
||||
goto fail;
|
||||
@@ -187,7 +187,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, NULL, XenbusStateClosing);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosing);
|
||||
}
|
||||
EXPORT_SYMBOL(xenbus_dev_fatal);
|
||||
|
||||
@@ -223,7 +223,7 @@ XenbusState xenbus_read_driver_state(const char *path)
|
||||
{
|
||||
XenbusState result;
|
||||
|
||||
int err = xenbus_gather(NULL, path, "state", "%d", &result, NULL);
|
||||
int err = xenbus_gather(XBT_NULL, path, "state", "%d", &result, NULL);
|
||||
if (err)
|
||||
result = XenbusStateClosed;
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
|
||||
struct xenbus_dev_transaction {
|
||||
struct list_head list;
|
||||
struct xenbus_transaction *handle;
|
||||
xenbus_transaction_t handle;
|
||||
};
|
||||
|
||||
struct xenbus_dev_data {
|
||||
@@ -109,9 +109,8 @@ static ssize_t xenbus_dev_write(struct file *filp,
|
||||
size_t len, loff_t *ppos)
|
||||
{
|
||||
struct xenbus_dev_data *u = filp->private_data;
|
||||
struct xenbus_dev_transaction *trans;
|
||||
struct xenbus_dev_transaction *trans = NULL;
|
||||
void *reply;
|
||||
int err = 0;
|
||||
|
||||
if ((len + u->len) > sizeof(u->u.buffer))
|
||||
return -EINVAL;
|
||||
@@ -135,42 +134,40 @@ static ssize_t xenbus_dev_write(struct file *filp,
|
||||
case XS_MKDIR:
|
||||
case XS_RM:
|
||||
case XS_SET_PERMS:
|
||||
if (u->u.msg.type == XS_TRANSACTION_START) {
|
||||
trans = kmalloc(sizeof(*trans), GFP_KERNEL);
|
||||
if (!trans)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
reply = xenbus_dev_request_and_reply(&u->u.msg);
|
||||
if (IS_ERR(reply)) {
|
||||
err = PTR_ERR(reply);
|
||||
} else {
|
||||
if (u->u.msg.type == XS_TRANSACTION_START) {
|
||||
trans = kmalloc(sizeof(*trans), GFP_KERNEL);
|
||||
trans->handle = (struct xenbus_transaction *)
|
||||
simple_strtoul(reply, NULL, 0);
|
||||
list_add(&trans->list, &u->transactions);
|
||||
} else if (u->u.msg.type == XS_TRANSACTION_END) {
|
||||
list_for_each_entry(trans, &u->transactions,
|
||||
list)
|
||||
if ((unsigned long)trans->handle ==
|
||||
(unsigned long)u->u.msg.tx_id)
|
||||
break;
|
||||
BUG_ON(&trans->list == &u->transactions);
|
||||
list_del(&trans->list);
|
||||
kfree(trans);
|
||||
}
|
||||
queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
|
||||
queue_reply(u, (char *)reply, u->u.msg.len);
|
||||
kfree(reply);
|
||||
kfree(trans);
|
||||
return PTR_ERR(reply);
|
||||
}
|
||||
|
||||
if (u->u.msg.type == XS_TRANSACTION_START) {
|
||||
trans->handle = simple_strtoul(reply, NULL, 0);
|
||||
list_add(&trans->list, &u->transactions);
|
||||
} else if (u->u.msg.type == XS_TRANSACTION_END) {
|
||||
list_for_each_entry(trans, &u->transactions, list)
|
||||
if (trans->handle == u->u.msg.tx_id)
|
||||
break;
|
||||
BUG_ON(&trans->list == &u->transactions);
|
||||
list_del(&trans->list);
|
||||
kfree(trans);
|
||||
}
|
||||
queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
|
||||
queue_reply(u, (char *)reply, u->u.msg.len);
|
||||
kfree(reply);
|
||||
break;
|
||||
|
||||
default:
|
||||
err = -EINVAL;
|
||||
break;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (err == 0) {
|
||||
u->len = 0;
|
||||
err = len;
|
||||
}
|
||||
|
||||
return err;
|
||||
u->len = 0;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int xenbus_dev_open(struct inode *inode, struct file *filp)
|
||||
|
||||
@@ -115,7 +115,7 @@ static int frontend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
|
||||
static int read_otherend_details(struct xenbus_device *xendev,
|
||||
char *id_node, char *path_node)
|
||||
{
|
||||
int err = xenbus_gather(NULL, xendev->nodename,
|
||||
int err = xenbus_gather(XBT_NULL, xendev->nodename,
|
||||
id_node, "%i", &xendev->otherend_id,
|
||||
path_node, NULL, &xendev->otherend,
|
||||
NULL);
|
||||
@@ -126,7 +126,7 @@ static int read_otherend_details(struct xenbus_device *xendev,
|
||||
return err;
|
||||
}
|
||||
if (strlen(xendev->otherend) == 0 ||
|
||||
!xenbus_exists(NULL, xendev->otherend, "")) {
|
||||
!xenbus_exists(XBT_NULL, xendev->otherend, "")) {
|
||||
xenbus_dev_fatal(xendev, -ENOENT, "missing other end from %s",
|
||||
xendev->nodename);
|
||||
kfree(xendev->otherend);
|
||||
@@ -200,14 +200,14 @@ static int backend_bus_id(char bus_id[BUS_ID_SIZE], const char *nodename)
|
||||
|
||||
devid = strrchr(nodename, '/') + 1;
|
||||
|
||||
err = xenbus_gather(NULL, nodename, "frontend-id", "%i", &domid,
|
||||
err = xenbus_gather(XBT_NULL, nodename, "frontend-id", "%i", &domid,
|
||||
"frontend", NULL, &frontend,
|
||||
NULL);
|
||||
if (err)
|
||||
return err;
|
||||
if (strlen(frontend) == 0)
|
||||
err = -ERANGE;
|
||||
if (!err && !xenbus_exists(NULL, frontend, ""))
|
||||
if (!err && !xenbus_exists(XBT_NULL, frontend, ""))
|
||||
err = -ENOENT;
|
||||
|
||||
kfree(frontend);
|
||||
@@ -373,7 +373,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, NULL, XenbusStateClosed);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
|
||||
return -ENODEV;
|
||||
|
||||
}
|
||||
@@ -391,7 +391,7 @@ static int xenbus_dev_remove(struct device *_dev)
|
||||
if (drv->remove)
|
||||
drv->remove(dev);
|
||||
|
||||
xenbus_switch_state(dev, NULL, XenbusStateClosed);
|
||||
xenbus_switch_state(dev, XBT_NULL, XenbusStateClosed);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -470,12 +470,17 @@ static int cleanup_dev(struct device *dev, void *data)
|
||||
|
||||
DPRINTK("%s", info->nodename);
|
||||
|
||||
if (!strncmp(xendev->nodename, info->nodename, len)) {
|
||||
info->dev = xendev;
|
||||
get_device(dev);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
/* Match the info->nodename path, or any subdirectory of that path. */
|
||||
if (strncmp(xendev->nodename, info->nodename, len))
|
||||
return 0;
|
||||
|
||||
/* If the node name is longer, ensure it really is a subdirectory. */
|
||||
if ((strlen(xendev->nodename) > len) && (xendev->nodename[len] != '/'))
|
||||
return 0;
|
||||
|
||||
info->dev = xendev;
|
||||
get_device(dev);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void xenbus_cleanup_devices(const char *path, struct bus_type *bus)
|
||||
@@ -542,14 +547,6 @@ static int xenbus_probe_node(struct xen_bus_type *bus,
|
||||
const char *type,
|
||||
const char *nodename)
|
||||
{
|
||||
#define CHECK_FAIL \
|
||||
do { \
|
||||
if (err) \
|
||||
goto fail; \
|
||||
} \
|
||||
while (0) \
|
||||
|
||||
|
||||
int err;
|
||||
struct xenbus_device *xendev;
|
||||
size_t stringlen;
|
||||
@@ -584,19 +581,18 @@ static int xenbus_probe_node(struct xen_bus_type *bus,
|
||||
xendev->dev.release = xenbus_dev_release;
|
||||
|
||||
err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
|
||||
CHECK_FAIL;
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
/* Register with generic device framework. */
|
||||
err = device_register(&xendev->dev);
|
||||
CHECK_FAIL;
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
device_create_file(&xendev->dev, &dev_attr_nodename);
|
||||
device_create_file(&xendev->dev, &dev_attr_devtype);
|
||||
|
||||
return 0;
|
||||
|
||||
#undef CHECK_FAIL
|
||||
|
||||
fail:
|
||||
xenbus_dev_free(xendev);
|
||||
return err;
|
||||
@@ -652,7 +648,7 @@ static int xenbus_probe_backend(const char *type, const char *domid)
|
||||
if (!nodename)
|
||||
return -ENOMEM;
|
||||
|
||||
dir = xenbus_directory(NULL, nodename, "", &dir_n);
|
||||
dir = xenbus_directory(XBT_NULL, nodename, "", &dir_n);
|
||||
if (IS_ERR(dir)) {
|
||||
kfree(nodename);
|
||||
return PTR_ERR(dir);
|
||||
@@ -675,7 +671,7 @@ static int xenbus_probe_device_type(struct xen_bus_type *bus, const char *type)
|
||||
unsigned int dir_n = 0;
|
||||
int i;
|
||||
|
||||
dir = xenbus_directory(NULL, bus->root, type, &dir_n);
|
||||
dir = xenbus_directory(XBT_NULL, bus->root, type, &dir_n);
|
||||
if (IS_ERR(dir))
|
||||
return PTR_ERR(dir);
|
||||
|
||||
@@ -694,7 +690,7 @@ static int xenbus_probe_devices(struct xen_bus_type *bus)
|
||||
char **dir;
|
||||
unsigned int i, dir_n;
|
||||
|
||||
dir = xenbus_directory(NULL, bus->root, "", &dir_n);
|
||||
dir = xenbus_directory(XBT_NULL, bus->root, "", &dir_n);
|
||||
if (IS_ERR(dir))
|
||||
return PTR_ERR(dir);
|
||||
|
||||
@@ -740,7 +736,7 @@ static void dev_changed(const char *node, struct xen_bus_type *bus)
|
||||
if (char_count(node, '/') < 2)
|
||||
return;
|
||||
|
||||
exists = xenbus_exists(NULL, node, "");
|
||||
exists = xenbus_exists(XBT_NULL, node, "");
|
||||
if (!exists) {
|
||||
xenbus_cleanup_devices(node, &bus->bus);
|
||||
return;
|
||||
|
||||
@@ -190,7 +190,7 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
|
||||
}
|
||||
|
||||
/* Send message to xs, get kmalloc'ed reply. ERR_PTR() on error. */
|
||||
static void *xs_talkv(struct xenbus_transaction *t,
|
||||
static void *xs_talkv(xenbus_transaction_t t,
|
||||
enum xsd_sockmsg_type type,
|
||||
const struct kvec *iovec,
|
||||
unsigned int num_vecs,
|
||||
@@ -201,7 +201,7 @@ static void *xs_talkv(struct xenbus_transaction *t,
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
msg.tx_id = (u32)(unsigned long)t;
|
||||
msg.tx_id = t;
|
||||
msg.req_id = 0;
|
||||
msg.type = type;
|
||||
msg.len = 0;
|
||||
@@ -242,7 +242,7 @@ static void *xs_talkv(struct xenbus_transaction *t,
|
||||
}
|
||||
|
||||
/* Simplified version of xs_talkv: single message. */
|
||||
static void *xs_single(struct xenbus_transaction *t,
|
||||
static void *xs_single(xenbus_transaction_t t,
|
||||
enum xsd_sockmsg_type type,
|
||||
const char *string,
|
||||
unsigned int *len)
|
||||
@@ -309,7 +309,7 @@ static char **split(char *strings, unsigned int len, unsigned int *num)
|
||||
return ret;
|
||||
}
|
||||
|
||||
char **xenbus_directory(struct xenbus_transaction *t,
|
||||
char **xenbus_directory(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, unsigned int *num)
|
||||
{
|
||||
char *strings, *path;
|
||||
@@ -329,7 +329,7 @@ char **xenbus_directory(struct xenbus_transaction *t,
|
||||
EXPORT_SYMBOL(xenbus_directory);
|
||||
|
||||
/* Check if a path exists. Return 1 if it does. */
|
||||
int xenbus_exists(struct xenbus_transaction *t,
|
||||
int xenbus_exists(xenbus_transaction_t t,
|
||||
const char *dir, const char *node)
|
||||
{
|
||||
char **d;
|
||||
@@ -347,7 +347,7 @@ EXPORT_SYMBOL(xenbus_exists);
|
||||
* Returns a kmalloced value: call free() on it after use.
|
||||
* len indicates length in bytes.
|
||||
*/
|
||||
void *xenbus_read(struct xenbus_transaction *t,
|
||||
void *xenbus_read(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, unsigned int *len)
|
||||
{
|
||||
char *path;
|
||||
@@ -366,7 +366,7 @@ EXPORT_SYMBOL(xenbus_read);
|
||||
/* Write the value of a single file.
|
||||
* Returns -err on failure.
|
||||
*/
|
||||
int xenbus_write(struct xenbus_transaction *t,
|
||||
int xenbus_write(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, const char *string)
|
||||
{
|
||||
const char *path;
|
||||
@@ -389,7 +389,7 @@ int xenbus_write(struct xenbus_transaction *t,
|
||||
EXPORT_SYMBOL(xenbus_write);
|
||||
|
||||
/* Create a new directory. */
|
||||
int xenbus_mkdir(struct xenbus_transaction *t,
|
||||
int xenbus_mkdir(xenbus_transaction_t t,
|
||||
const char *dir, const char *node)
|
||||
{
|
||||
char *path;
|
||||
@@ -406,7 +406,7 @@ int xenbus_mkdir(struct xenbus_transaction *t,
|
||||
EXPORT_SYMBOL(xenbus_mkdir);
|
||||
|
||||
/* Destroy a file or directory (directories must be empty). */
|
||||
int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node)
|
||||
int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node)
|
||||
{
|
||||
char *path;
|
||||
int ret;
|
||||
@@ -424,30 +424,28 @@ EXPORT_SYMBOL(xenbus_rm);
|
||||
/* Start a transaction: changes by others will not be seen during this
|
||||
* transaction, and changes will not be visible to others until end.
|
||||
*/
|
||||
struct xenbus_transaction *xenbus_transaction_start(void)
|
||||
int xenbus_transaction_start(xenbus_transaction_t *t)
|
||||
{
|
||||
char *id_str;
|
||||
unsigned long id;
|
||||
|
||||
down_read(&xs_state.suspend_mutex);
|
||||
|
||||
id_str = xs_single(NULL, XS_TRANSACTION_START, "", NULL);
|
||||
id_str = xs_single(XBT_NULL, XS_TRANSACTION_START, "", NULL);
|
||||
if (IS_ERR(id_str)) {
|
||||
up_read(&xs_state.suspend_mutex);
|
||||
return (struct xenbus_transaction *)id_str;
|
||||
return PTR_ERR(id_str);
|
||||
}
|
||||
|
||||
id = simple_strtoul(id_str, NULL, 0);
|
||||
*t = simple_strtoul(id_str, NULL, 0);
|
||||
kfree(id_str);
|
||||
|
||||
return (struct xenbus_transaction *)id;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(xenbus_transaction_start);
|
||||
|
||||
/* End a transaction.
|
||||
* If abandon is true, transaction is discarded instead of committed.
|
||||
*/
|
||||
int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
|
||||
int xenbus_transaction_end(xenbus_transaction_t t, int abort)
|
||||
{
|
||||
char abortstr[2];
|
||||
int err;
|
||||
@@ -466,7 +464,7 @@ int xenbus_transaction_end(struct xenbus_transaction *t, int abort)
|
||||
EXPORT_SYMBOL(xenbus_transaction_end);
|
||||
|
||||
/* Single read and scanf: returns -errno or num scanned. */
|
||||
int xenbus_scanf(struct xenbus_transaction *t,
|
||||
int xenbus_scanf(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@@ -489,7 +487,7 @@ int xenbus_scanf(struct xenbus_transaction *t,
|
||||
EXPORT_SYMBOL(xenbus_scanf);
|
||||
|
||||
/* Single printf and write: returns -errno or 0. */
|
||||
int xenbus_printf(struct xenbus_transaction *t,
|
||||
int xenbus_printf(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
@@ -515,7 +513,7 @@ int xenbus_printf(struct xenbus_transaction *t,
|
||||
EXPORT_SYMBOL(xenbus_printf);
|
||||
|
||||
/* Takes tuples of names, scanf-style args, and void **, NULL terminated. */
|
||||
int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...)
|
||||
int xenbus_gather(xenbus_transaction_t t, const char *dir, ...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *name;
|
||||
@@ -553,7 +551,7 @@ static int xs_watch(const char *path, const char *token)
|
||||
iov[1].iov_base = (void *)token;
|
||||
iov[1].iov_len = strlen(token) + 1;
|
||||
|
||||
return xs_error(xs_talkv(NULL, XS_WATCH, iov,
|
||||
return xs_error(xs_talkv(XBT_NULL, XS_WATCH, iov,
|
||||
ARRAY_SIZE(iov), NULL));
|
||||
}
|
||||
|
||||
@@ -566,7 +564,7 @@ static int xs_unwatch(const char *path, const char *token)
|
||||
iov[1].iov_base = (char *)token;
|
||||
iov[1].iov_len = strlen(token) + 1;
|
||||
|
||||
return xs_error(xs_talkv(NULL, XS_UNWATCH, iov,
|
||||
return xs_error(xs_talkv(XBT_NULL, XS_UNWATCH, iov,
|
||||
ARRAY_SIZE(iov), NULL));
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include <asm-xen/xen-public/xen.h>
|
||||
#include <asm-xen/xen-public/sched.h>
|
||||
#include <asm-xen/xen-public/nmi.h>
|
||||
|
||||
#define _hypercall0(type, name) \
|
||||
({ \
|
||||
@@ -300,6 +301,14 @@ HYPERVISOR_suspend(
|
||||
SHUTDOWN_suspend, srec);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_nmi_op(
|
||||
unsigned long op,
|
||||
unsigned long arg)
|
||||
{
|
||||
return _hypercall2(int, nmi_op, op, arg);
|
||||
}
|
||||
|
||||
#endif /* __HYPERCALL_H__ */
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* include/asm-xen/asm-i386/mach-xen/mach_traps.h
|
||||
*
|
||||
* Machine specific NMI handling for Xen
|
||||
*/
|
||||
#ifndef _MACH_TRAPS_H
|
||||
#define _MACH_TRAPS_H
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <asm-xen/xen-public/nmi.h>
|
||||
|
||||
static inline void clear_mem_error(unsigned char reason) {}
|
||||
static inline void clear_io_check_error(unsigned char reason) {}
|
||||
|
||||
static inline unsigned char get_nmi_reason(void)
|
||||
{
|
||||
shared_info_t *s = HYPERVISOR_shared_info;
|
||||
unsigned char reason = 0;
|
||||
|
||||
/* construct a value which looks like it came from
|
||||
* port 0x61.
|
||||
*/
|
||||
if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
|
||||
reason |= 0x40;
|
||||
if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
|
||||
reason |= 0x80;
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
||||
static inline void reassert_nmi(void) {}
|
||||
|
||||
#endif /* !_MACH_TRAPS_H */
|
||||
@@ -29,6 +29,7 @@ void __init machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
|
||||
|
||||
extern void hypervisor_callback(void);
|
||||
extern void failsafe_callback(void);
|
||||
extern void nmi(void);
|
||||
|
||||
static void __init machine_specific_arch_setup(void)
|
||||
{
|
||||
@@ -36,5 +37,7 @@ static void __init machine_specific_arch_setup(void)
|
||||
__KERNEL_CS, (unsigned long)hypervisor_callback,
|
||||
__KERNEL_CS, (unsigned long)failsafe_callback);
|
||||
|
||||
HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
|
||||
|
||||
machine_specific_modify_cpu_capabilities(&boot_cpu_data);
|
||||
}
|
||||
@@ -287,9 +287,9 @@ HYPERVISOR_vcpu_op(
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_switch_to_user(void)
|
||||
HYPERVISOR_iret(void)
|
||||
{
|
||||
return _hypercall0(int, switch_to_user);
|
||||
return _hypercall0(int, iret);
|
||||
}
|
||||
|
||||
static inline int
|
||||
@@ -307,6 +307,14 @@ HYPERVISOR_suspend(
|
||||
SHUTDOWN_suspend, srec);
|
||||
}
|
||||
|
||||
static inline int
|
||||
HYPERVISOR_nmi_op(
|
||||
unsigned long op,
|
||||
unsigned long arg)
|
||||
{
|
||||
return _hypercall2(int, nmi_op, op, arg);
|
||||
}
|
||||
|
||||
#endif /* __HYPERCALL_H__ */
|
||||
|
||||
/*
|
||||
|
||||
@@ -35,6 +35,7 @@ void __init machine_specific_modify_cpu_capabilities(struct cpuinfo_x86 *c)
|
||||
|
||||
extern void hypervisor_callback(void);
|
||||
extern void failsafe_callback(void);
|
||||
extern void nmi(void);
|
||||
|
||||
static void __init machine_specific_arch_setup(void)
|
||||
{
|
||||
@@ -43,5 +44,9 @@ static void __init machine_specific_arch_setup(void)
|
||||
(unsigned long) failsafe_callback,
|
||||
(unsigned long) system_call);
|
||||
|
||||
#ifdef CONFIG_X86_LOCAL_APIC
|
||||
HYPERVISOR_nmi_op(XENNMI_register_callback, (unsigned long)&nmi);
|
||||
#endif
|
||||
|
||||
machine_specific_modify_cpu_capabilities(&boot_cpu_data);
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* linux/include/asm-i386/nmi.h
|
||||
*/
|
||||
#ifndef ASM_NMI_H
|
||||
#define ASM_NMI_H
|
||||
|
||||
#include <linux/pm.h>
|
||||
|
||||
#include <asm-xen/xen-public/nmi.h>
|
||||
|
||||
struct pt_regs;
|
||||
|
||||
typedef int (*nmi_callback_t)(struct pt_regs * regs, int cpu);
|
||||
|
||||
/**
|
||||
* set_nmi_callback
|
||||
*
|
||||
* Set a handler for an NMI. Only one handler may be
|
||||
* set. Return 1 if the NMI was handled.
|
||||
*/
|
||||
void set_nmi_callback(nmi_callback_t callback);
|
||||
|
||||
/**
|
||||
* unset_nmi_callback
|
||||
*
|
||||
* Remove the handler previously set.
|
||||
*/
|
||||
void unset_nmi_callback(void);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
/** Replace the PM callback routine for NMI. */
|
||||
struct pm_dev * set_nmi_pm_callback(pm_callback callback);
|
||||
|
||||
/** Unset the PM callback routine back to the default. */
|
||||
void unset_nmi_pm_callback(struct pm_dev * dev);
|
||||
|
||||
#else
|
||||
|
||||
static inline struct pm_dev * set_nmi_pm_callback(pm_callback callback)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void unset_nmi_pm_callback(struct pm_dev * dev)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PM */
|
||||
|
||||
extern void default_do_nmi(struct pt_regs *);
|
||||
extern void die_nmi(char *str, struct pt_regs *regs);
|
||||
|
||||
static inline unsigned char get_nmi_reason(void)
|
||||
{
|
||||
shared_info_t *s = HYPERVISOR_shared_info;
|
||||
unsigned char reason = 0;
|
||||
|
||||
/* construct a value which looks like it came from
|
||||
* port 0x61.
|
||||
*/
|
||||
if (test_bit(_XEN_NMIREASON_io_error, &s->arch.nmi_reason))
|
||||
reason |= 0x40;
|
||||
if (test_bit(_XEN_NMIREASON_parity_error, &s->arch.nmi_reason))
|
||||
reason |= 0x80;
|
||||
|
||||
return reason;
|
||||
}
|
||||
|
||||
extern int panic_on_timeout;
|
||||
extern int unknown_nmi_panic;
|
||||
|
||||
extern int check_nmi_watchdog(void);
|
||||
|
||||
#endif /* ASM_NMI_H */
|
||||
@@ -37,6 +37,8 @@
|
||||
#include <asm-xen/xen-public/io/xenbus.h>
|
||||
#include <asm-xen/xen-public/io/xs_wire.h>
|
||||
|
||||
#define XBT_NULL 0
|
||||
|
||||
/* Register callback to watch this node. */
|
||||
struct xenbus_watch
|
||||
{
|
||||
@@ -100,35 +102,35 @@ int xenbus_register_frontend(struct xenbus_driver *drv);
|
||||
int xenbus_register_backend(struct xenbus_driver *drv);
|
||||
void xenbus_unregister_driver(struct xenbus_driver *drv);
|
||||
|
||||
struct xenbus_transaction;
|
||||
typedef u32 xenbus_transaction_t;
|
||||
|
||||
char **xenbus_directory(struct xenbus_transaction *t,
|
||||
char **xenbus_directory(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, unsigned int *num);
|
||||
void *xenbus_read(struct xenbus_transaction *t,
|
||||
void *xenbus_read(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, unsigned int *len);
|
||||
int xenbus_write(struct xenbus_transaction *t,
|
||||
int xenbus_write(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, const char *string);
|
||||
int xenbus_mkdir(struct xenbus_transaction *t,
|
||||
int xenbus_mkdir(xenbus_transaction_t t,
|
||||
const char *dir, const char *node);
|
||||
int xenbus_exists(struct xenbus_transaction *t,
|
||||
int xenbus_exists(xenbus_transaction_t t,
|
||||
const char *dir, const char *node);
|
||||
int xenbus_rm(struct xenbus_transaction *t, const char *dir, const char *node);
|
||||
struct xenbus_transaction *xenbus_transaction_start(void);
|
||||
int xenbus_transaction_end(struct xenbus_transaction *t, int abort);
|
||||
int xenbus_rm(xenbus_transaction_t t, const char *dir, const char *node);
|
||||
int xenbus_transaction_start(xenbus_transaction_t *t);
|
||||
int xenbus_transaction_end(xenbus_transaction_t t, int abort);
|
||||
|
||||
/* Single read and scanf: returns -errno or num scanned if > 0. */
|
||||
int xenbus_scanf(struct xenbus_transaction *t,
|
||||
int xenbus_scanf(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, const char *fmt, ...)
|
||||
__attribute__((format(scanf, 4, 5)));
|
||||
|
||||
/* Single printf and write: returns -errno or 0. */
|
||||
int xenbus_printf(struct xenbus_transaction *t,
|
||||
int xenbus_printf(xenbus_transaction_t t,
|
||||
const char *dir, const char *node, const char *fmt, ...)
|
||||
__attribute__((format(printf, 4, 5)));
|
||||
|
||||
/* Generic read function: NULL-terminated triples of name,
|
||||
* sprintf-style type string, and pointer. Returns 0 or errno.*/
|
||||
int xenbus_gather(struct xenbus_transaction *t, const char *dir, ...);
|
||||
int xenbus_gather(xenbus_transaction_t t, const char *dir, ...);
|
||||
|
||||
/* notifer routines for when the xenstore comes up */
|
||||
int register_xenstore_notifier(struct notifier_block *nb);
|
||||
@@ -194,7 +196,7 @@ int xenbus_watch_path2(struct xenbus_device *dev, const char *path,
|
||||
* XenbusStateClosing, and the error will be saved in the store.
|
||||
*/
|
||||
int xenbus_switch_state(struct xenbus_device *dev,
|
||||
struct xenbus_transaction *xbt,
|
||||
xenbus_transaction_t xbt,
|
||||
XenbusState new_state);
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
--- ref-linux-2.6.12/arch/i386/kernel/traps.c 2005-12-19 09:23:44.000000000 +0000
|
||||
+++ linux-2.6.12-xen0/arch/i386/kernel/traps.c 2006-01-05 15:51:52.000000000 +0000
|
||||
@@ -521,18 +521,11 @@
|
||||
|
||||
static void io_check_error(unsigned char reason, struct pt_regs * regs)
|
||||
{
|
||||
- unsigned long i;
|
||||
-
|
||||
printk("NMI: IOCK error (debug interrupt?)\n");
|
||||
show_registers(regs);
|
||||
|
||||
/* Re-enable the IOCK line, wait for a few seconds */
|
||||
- reason = (reason & 0xf) | 8;
|
||||
- outb(reason, 0x61);
|
||||
- i = 2000;
|
||||
- while (--i) udelay(1000);
|
||||
- reason &= ~8;
|
||||
- outb(reason, 0x61);
|
||||
+ clear_io_check_error(reason);
|
||||
}
|
||||
|
||||
static void unknown_nmi_error(unsigned char reason, struct pt_regs * regs)
|
||||
--- ref-linux-2.6.12/include/asm-i386/mach-default/mach_traps.h 2005-06-17 20:48:29.000000000 +0100
|
||||
+++ linux-2.6.12-xen0/include/asm-i386/mach-default/mach_traps.h 2006-01-05 15:52:33.000000000 +0000
|
||||
@@ -15,6 +15,18 @@
|
||||
outb(reason, 0x61);
|
||||
}
|
||||
|
||||
+static inline void clear_io_check_error(unsigned char reason)
|
||||
+{
|
||||
+ unsigned long i;
|
||||
+
|
||||
+ reason = (reason & 0xf) | 8;
|
||||
+ outb(reason, 0x61);
|
||||
+ i = 2000;
|
||||
+ while (--i) udelay(1000);
|
||||
+ reason &= ~8;
|
||||
+ outb(reason, 0x61);
|
||||
+}
|
||||
+
|
||||
static inline unsigned char get_nmi_reason(void)
|
||||
{
|
||||
return inb(0x61);
|
||||
@@ -12,6 +12,7 @@ SUBDIRS += firmware
|
||||
SUBDIRS += security
|
||||
SUBDIRS += console
|
||||
SUBDIRS += xenmon
|
||||
SUBDIRS += guest-headers
|
||||
ifeq ($(VTPM_TOOLS),y)
|
||||
SUBDIRS += vtpm_manager
|
||||
SUBDIRS += vtpm
|
||||
|
||||
@@ -35,6 +35,8 @@ mk-symlinks: LINUX_ROOT=$(XEN_ROOT)/linux-2.6-xen-sparse
|
||||
mk-symlinks:
|
||||
mkdir -p xen
|
||||
( cd xen && ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
|
||||
mkdir -p xen/hvm
|
||||
( cd xen/hvm && ln -sf ../../$(XEN_ROOT)/xen/include/public/hvm/*.h . )
|
||||
mkdir -p xen/io
|
||||
( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
|
||||
mkdir -p xen/linux
|
||||
|
||||
@@ -220,7 +220,7 @@ int main(int argc, char **argv)
|
||||
if (path == NULL)
|
||||
err(ENOMEM, "realloc");
|
||||
strcat(path, "/console/tty");
|
||||
str_pty = xs_read(xs, NULL, path, &len);
|
||||
str_pty = xs_read(xs, XBT_NULL, path, &len);
|
||||
|
||||
/* FIXME consoled currently does not assume domain-0 doesn't have a
|
||||
console which is good when we break domain-0 up. To keep us
|
||||
@@ -245,7 +245,7 @@ int main(int argc, char **argv)
|
||||
struct timeval tv = { 0, 500 };
|
||||
select(0, NULL, NULL, NULL, &tv); /* pause briefly */
|
||||
|
||||
str_pty = xs_read(xs, NULL, path, &len);
|
||||
str_pty = xs_read(xs, XBT_NULL, path, &len);
|
||||
}
|
||||
|
||||
if (str_pty == NULL) {
|
||||
|
||||
@@ -174,7 +174,7 @@ static int domain_create_tty(struct domain *dom)
|
||||
success = asprintf(&path, "%s/limit", dom->conspath) != -1;
|
||||
if (!success)
|
||||
goto out;
|
||||
data = xs_read(xs, NULL, path, &len);
|
||||
data = xs_read(xs, XBT_NULL, path, &len);
|
||||
if (data) {
|
||||
dom->buffer.max_capacity = strtoul(data, 0, 0);
|
||||
free(data);
|
||||
@@ -184,7 +184,7 @@ static int domain_create_tty(struct domain *dom)
|
||||
success = asprintf(&path, "%s/tty", dom->conspath) != -1;
|
||||
if (!success)
|
||||
goto out;
|
||||
success = xs_write(xs, NULL, path, slave, strlen(slave));
|
||||
success = xs_write(xs, XBT_NULL, path, slave, strlen(slave));
|
||||
free(path);
|
||||
if (!success)
|
||||
goto out;
|
||||
@@ -214,7 +214,7 @@ int xs_gather(struct xs_handle *xs, const char *dir, ...)
|
||||
char *p;
|
||||
|
||||
asprintf(&path, "%s/%s", dir, name);
|
||||
p = xs_read(xs, NULL, path, NULL);
|
||||
p = xs_read(xs, XBT_NULL, path, NULL);
|
||||
free(path);
|
||||
if (p == NULL) {
|
||||
ret = ENOENT;
|
||||
|
||||
@@ -119,8 +119,8 @@ xendebug_get_context (int xc_handle, uint32_t domid, uint32_t vcpu)
|
||||
|
||||
if ( !ctxt->valid[vcpu] )
|
||||
{
|
||||
if ( (rc = xc_domain_get_vcpu_context(xc_handle, domid, vcpu,
|
||||
&ctxt->context[vcpu])) )
|
||||
if ( (rc = xc_vcpu_getcontext(xc_handle, domid, vcpu,
|
||||
&ctxt->context[vcpu])) )
|
||||
return NULL;
|
||||
|
||||
ctxt->valid[vcpu] = true;
|
||||
@@ -139,10 +139,10 @@ xendebug_set_context (int xc_handle, domain_context_p ctxt, uint32_t vcpu)
|
||||
return -EINVAL;
|
||||
|
||||
op.interface_version = DOM0_INTERFACE_VERSION;
|
||||
op.cmd = DOM0_SETDOMAININFO;
|
||||
op.u.setdomaininfo.domain = ctxt->domid;
|
||||
op.u.setdomaininfo.vcpu = vcpu;
|
||||
op.u.setdomaininfo.ctxt = &ctxt->context[vcpu];
|
||||
op.cmd = DOM0_SETVCPUCONTEXT;
|
||||
op.u.setvcpucontext.domain = ctxt->domid;
|
||||
op.u.setvcpucontext.vcpu = vcpu;
|
||||
op.u.setvcpucontext.ctxt = &ctxt->context[vcpu];
|
||||
|
||||
if ( (rc = mlock(&ctxt->context[vcpu], sizeof(vcpu_guest_context_t))) )
|
||||
return rc;
|
||||
|
||||
@@ -68,48 +68,19 @@ pdev="p${netdev}"
|
||||
vdev="veth${vifnum}"
|
||||
vif0="vif0.${vifnum}"
|
||||
|
||||
legacy_mask_to_prefix() {
|
||||
mask=$1
|
||||
first=${mask%%.*}
|
||||
second=${mask#*.}
|
||||
third=${second#*.}
|
||||
fourth=${third#*.}
|
||||
second=${second%%.*}
|
||||
third=${third%%.*}
|
||||
declare -i INT FULLMASK BIT
|
||||
INT=$((((($first*256)+$second)*256+$third)*256+$fourth))
|
||||
FULLMASK=4294967295
|
||||
BIT=1
|
||||
for bit in `seq 32 -1 0`; do
|
||||
if test $FULLMASK -eq $INT; then PREFIX=$bit; return; fi
|
||||
FULLMASK=$(($FULLMASK-$BIT))
|
||||
BIT=$((BIT*2))
|
||||
done
|
||||
echo "ERROR converting netmask $mask to prefix"
|
||||
exit 1
|
||||
get_ip_info() {
|
||||
addr_pfx=`ip addr show dev $1 | egrep '^ *inet' | sed -e 's/ *inet //' -e 's/ .*//'`
|
||||
gateway=`ip route show dev $1 | fgrep default | sed 's/default via //'`
|
||||
}
|
||||
|
||||
parse_kernel_ip() {
|
||||
if egrep 'ip=[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+:' /proc/cmdline; then
|
||||
kip=`sed -e 's!.*ip=\([0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+\):.*!\1!' /proc/cmdline`
|
||||
kmask=`sed -e 's!.*ip=[^:]*:[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline`
|
||||
kgate=`sed -e 's!.*ip=[^:]*:[^:]*:\([^:]*\):.*!\1!' /proc/cmdline`
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
do_ifup() {
|
||||
if ! ifup $1 ; then
|
||||
if [ ${kip} ] ; then
|
||||
# use the addresses we grocked from /proc/cmdline
|
||||
if [ -z "${kmask}" ]; then
|
||||
PREFIX=32
|
||||
else
|
||||
legacy_mask_to_prefix ${kmask}
|
||||
fi
|
||||
if [ ${addr_pfx} ] ; then
|
||||
# use the info from get_ip_info()
|
||||
ip addr flush $1
|
||||
ip addr add ${kip}/${PREFIX} dev $1
|
||||
ip addr add ${addr_pfx} dev $1
|
||||
ip link set dev $1 up
|
||||
[ ${kgate} ] && ip route add default via ${kgate}
|
||||
[ ${gateway} ] && ip route add default via ${gateway}
|
||||
fi
|
||||
fi
|
||||
}
|
||||
@@ -171,7 +142,7 @@ transfer_routes () {
|
||||
#
|
||||
link_exists()
|
||||
{
|
||||
if ip link show "$1" >&/dev/null
|
||||
if ip link show "$1" >/dev/null 2>/dev/null
|
||||
then
|
||||
return 0
|
||||
else
|
||||
@@ -231,7 +202,7 @@ show_status () {
|
||||
}
|
||||
|
||||
op_start () {
|
||||
if [ "${bridge}" == "null" ] ; then
|
||||
if [ "${bridge}" = "null" ] ; then
|
||||
return
|
||||
fi
|
||||
|
||||
@@ -259,9 +230,8 @@ using loopback.nloopbacks=<N> on the domain 0 kernel command line.
|
||||
preiftransfer ${netdev}
|
||||
transfer_addrs ${netdev} ${vdev}
|
||||
if ! ifdown ${netdev}; then
|
||||
# If ifdown fails, take the IP details from the kernel command
|
||||
# line.
|
||||
parse_kernel_ip
|
||||
# If ifdown fails, remember the IP details.
|
||||
get_ip_info ${netdev}
|
||||
ip link set ${netdev} down
|
||||
ip addr flush ${netdev}
|
||||
fi
|
||||
@@ -283,13 +253,13 @@ using loopback.nloopbacks=<N> on the domain 0 kernel command line.
|
||||
transfer_routes ${netdev} ${bridge}
|
||||
fi
|
||||
|
||||
if [ ${antispoof} == 'yes' ] ; then
|
||||
if [ ${antispoof} = 'yes' ] ; then
|
||||
antispoofing
|
||||
fi
|
||||
}
|
||||
|
||||
op_stop () {
|
||||
if [ "${bridge}" == "null" ]; then
|
||||
if [ "${bridge}" = "null" ]; then
|
||||
return
|
||||
fi
|
||||
if ! link_exists "$bridge"; then
|
||||
@@ -301,7 +271,7 @@ op_stop () {
|
||||
mac=`ip link show ${netdev} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'`
|
||||
transfer_addrs ${netdev} ${pdev}
|
||||
if ! ifdown ${netdev}; then
|
||||
parse_kernel_ip
|
||||
get_ip_info ${netdev}
|
||||
fi
|
||||
ip link set ${netdev} down arp off
|
||||
ip link set ${netdev} addr fe:ff:ff:ff:ff:ff
|
||||
|
||||
@@ -42,7 +42,7 @@ then
|
||||
{
|
||||
/sbin/ifup ${HWD_CONFIG_0} $1
|
||||
}
|
||||
elif ! which ifup >&/dev/null
|
||||
elif ! which ifup >/dev/null 2>/dev/null
|
||||
then
|
||||
if [ -e /etc/conf.d/net ]
|
||||
then
|
||||
@@ -59,9 +59,18 @@ then
|
||||
/etc/init.d/net.$1 stop
|
||||
}
|
||||
else
|
||||
logger -p "daemon.crit" -- \
|
||||
"You don't have ifup and don't seem to be running Gentoo either!"
|
||||
exit 1
|
||||
preiftransfer()
|
||||
{
|
||||
true
|
||||
}
|
||||
ifup()
|
||||
{
|
||||
false
|
||||
}
|
||||
ifdown()
|
||||
{
|
||||
false
|
||||
}
|
||||
fi
|
||||
else
|
||||
preiftransfer()
|
||||
|
||||
@@ -28,11 +28,14 @@ name = "ExampleVMXDomain"
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# the number of cpus guest platform has, default=1
|
||||
vcpus=1
|
||||
#vcpus=1
|
||||
|
||||
# enable/disalbe vmx guest ACPI, default=0 (disabled)
|
||||
#acpi=0
|
||||
|
||||
# enable/disalbe vmx guest APIC, default=0 (disabled)
|
||||
#apic=0
|
||||
|
||||
# List of which CPUS this domain is allowed to use, default Xen picks
|
||||
#cpus = "" # leave to Xen to pick
|
||||
#cpus = "0" # all vcpus run on CPU0
|
||||
|
||||
@@ -17,34 +17,34 @@
|
||||
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
* Place - Suite 330, Boston, MA 02111-1307 USA.
|
||||
*/
|
||||
|
||||
#include "../acpi/acpi2_0.h"
|
||||
#include "../acpi/acpi_madt.h"
|
||||
|
||||
#include <xen/hvm/hvm_info_table.h>
|
||||
|
||||
#define NULL ((void*)0)
|
||||
|
||||
extern int puts(const char *s);
|
||||
|
||||
#define HVM_INFO_PAGE 0x0009F000
|
||||
#define HVM_INFO_OFFSET 0x00000800
|
||||
|
||||
struct hvm_info_table {
|
||||
char signature[8]; /* "HVM INFO" */
|
||||
uint32_t length;
|
||||
uint8_t checksum;
|
||||
uint8_t acpi_enabled;
|
||||
uint8_t pad[2];
|
||||
uint32_t nr_vcpus;
|
||||
};
|
||||
|
||||
static struct hvm_info_table *table = NULL;
|
||||
|
||||
static int
|
||||
checksum_valid(uint8_t *ptr, int len)
|
||||
static int validate_hvm_info(struct hvm_info_table *t)
|
||||
{
|
||||
uint8_t sum=0;
|
||||
char signature[] = "HVM INFO";
|
||||
uint8_t *ptr = (uint8_t *)t;
|
||||
uint8_t sum = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
/* strncmp(t->signature, "HVM INFO", 8) */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (signature[i] != t->signature[i]) {
|
||||
puts("Bad hvm info signature\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < t->length; i++)
|
||||
sum += ptr[i];
|
||||
|
||||
return (sum == 0);
|
||||
@@ -55,24 +55,15 @@ static struct hvm_info_table *
|
||||
get_hvm_info_table(void)
|
||||
{
|
||||
struct hvm_info_table *t;
|
||||
char signature[] = "HVM INFO";
|
||||
int i;
|
||||
|
||||
if (table != NULL)
|
||||
return table;
|
||||
|
||||
t = (struct hvm_info_table *)(HVM_INFO_PAGE + HVM_INFO_OFFSET);
|
||||
t = (struct hvm_info_table *)HVM_INFO_PADDR;
|
||||
|
||||
/* strncmp(t->signature, "HVM INFO", 8) */
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (signature[i] != t->signature[i]) {
|
||||
puts("Bad hvm info signature\n");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!checksum_valid((uint8_t *)t, t->length)) {
|
||||
puts("Bad hvm info checksum\n");
|
||||
if (!validate_hvm_info(t)) {
|
||||
puts("Bad hvm info table\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -126,10 +117,10 @@ acpi_madt_get_madt(unsigned char *acpi_start)
|
||||
return madt;
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
set_checksum(void *start, int checksum_offset, int len)
|
||||
{
|
||||
unsigned char sum = 0;
|
||||
unsigned char sum = 0;
|
||||
unsigned char *ptr;
|
||||
|
||||
ptr = start;
|
||||
@@ -141,9 +132,9 @@ set_checksum(void *start, int checksum_offset, int len)
|
||||
ptr[checksum_offset] = -sum;
|
||||
}
|
||||
|
||||
static int
|
||||
static int
|
||||
acpi_madt_set_local_apics(
|
||||
int nr_vcpu,
|
||||
int nr_vcpu,
|
||||
ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
|
||||
{
|
||||
int i;
|
||||
@@ -156,14 +147,14 @@ acpi_madt_set_local_apics(
|
||||
madt->LocalApic[i].Length = sizeof (ACPI_LOCAL_APIC_STRUCTURE);
|
||||
madt->LocalApic[i].AcpiProcessorId = i;
|
||||
madt->LocalApic[i].ApicId = i;
|
||||
madt->LocalApic[i].Flags = 1;
|
||||
madt->LocalApic[i].Flags = 1;
|
||||
}
|
||||
|
||||
madt->Header.Header.Length =
|
||||
sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
|
||||
sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
|
||||
(MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
|
||||
@@ -185,7 +176,7 @@ int acpi_madt_update(unsigned char *acpi_start)
|
||||
madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
|
||||
madt->Header.Header.Length);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
#include <xen/vmx_assist.h>
|
||||
#include <xen/hvm/vmx_assist.h>
|
||||
|
||||
#define NR_EXCEPTION_HANDLER 32
|
||||
#define NR_INTERRUPT_HANDLERS 16
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
|
||||
XEN_ROOT=../..
|
||||
linuxsparsetree = $(XEN_ROOT)/linux-2.6-xen-sparse
|
||||
|
||||
all:
|
||||
|
||||
check:
|
||||
|
||||
install:
|
||||
mkdir -p $(DESTDIR)/usr/include/xen/linux
|
||||
install -m0644 $(linuxsparsetree)/include/asm-xen/linux-public/*.h $(DESTDIR)/usr/include/xen/linux
|
||||
|
||||
clean:
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
#include "vl.h"
|
||||
#include <xenctrl.h>
|
||||
#include <xen/io/ioreq.h>
|
||||
#include <xen/hvm/ioreq.h>
|
||||
|
||||
//#define DEBUG_PIT
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
#include "vl.h"
|
||||
#include <xenctrl.h>
|
||||
#include <xen/io/ioreq.h>
|
||||
#include <xen/hvm/ioreq.h>
|
||||
|
||||
/* debug PIC */
|
||||
//#define DEBUG_PIC
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
#include "xenctrl.h"
|
||||
#include <xen/io/ioreq.h>
|
||||
#include <xen/hvm/ioreq.h>
|
||||
#include <stdio.h>
|
||||
#include "cpu.h"
|
||||
#include "cpu-all.h"
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <xenctrl.h>
|
||||
#include <xen/io/ioreq.h>
|
||||
#include <xen/hvm/ioreq.h>
|
||||
#include <xen/linux/evtchn.h>
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
@@ -55,7 +55,7 @@ xc_domain_dumpcore(int xc_handle,
|
||||
}
|
||||
|
||||
for (i = 0; i < info.max_vcpu_id; i++)
|
||||
if (xc_domain_get_vcpu_context(xc_handle, domid,
|
||||
if (xc_vcpu_getcontext(xc_handle, domid,
|
||||
i, &ctxt[nr_vcpus]) == 0)
|
||||
nr_vcpus++;
|
||||
|
||||
|
||||
+21
-21
@@ -58,16 +58,16 @@ int xc_domain_destroy(int xc_handle,
|
||||
return do_dom0_op(xc_handle, &op);
|
||||
}
|
||||
|
||||
int xc_domain_pincpu(int xc_handle,
|
||||
uint32_t domid,
|
||||
int vcpu,
|
||||
cpumap_t cpumap)
|
||||
int xc_vcpu_setaffinity(int xc_handle,
|
||||
uint32_t domid,
|
||||
int vcpu,
|
||||
cpumap_t cpumap)
|
||||
{
|
||||
DECLARE_DOM0_OP;
|
||||
op.cmd = DOM0_PINCPUDOMAIN;
|
||||
op.u.pincpudomain.domain = (domid_t)domid;
|
||||
op.u.pincpudomain.vcpu = vcpu;
|
||||
op.u.pincpudomain.cpumap = cpumap;
|
||||
op.cmd = DOM0_SETVCPUAFFINITY;
|
||||
op.u.setvcpuaffinity.domain = (domid_t)domid;
|
||||
op.u.setvcpuaffinity.vcpu = vcpu;
|
||||
op.u.setvcpuaffinity.cpumap = cpumap;
|
||||
return do_dom0_op(xc_handle, &op);
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ int xc_domain_getinfolist(int xc_handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
int xc_domain_get_vcpu_context(int xc_handle,
|
||||
int xc_vcpu_getcontext(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
vcpu_guest_context_t *ctxt)
|
||||
@@ -345,10 +345,10 @@ int xc_domain_sethandle(int xc_handle, uint32_t domid,
|
||||
return do_dom0_op(xc_handle, &op);
|
||||
}
|
||||
|
||||
int xc_domain_get_vcpu_info(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
xc_vcpuinfo_t *info)
|
||||
int xc_vcpu_getinfo(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
xc_vcpuinfo_t *info)
|
||||
{
|
||||
int rc;
|
||||
DECLARE_DOM0_OP;
|
||||
@@ -380,18 +380,18 @@ int xc_domain_ioport_permission(int xc_handle,
|
||||
return do_dom0_op(xc_handle, &op);
|
||||
}
|
||||
|
||||
int xc_domain_setinfo(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
vcpu_guest_context_t *ctxt)
|
||||
int xc_vcpu_setcontext(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
vcpu_guest_context_t *ctxt)
|
||||
{
|
||||
dom0_op_t op;
|
||||
int rc;
|
||||
|
||||
op.cmd = DOM0_SETDOMAININFO;
|
||||
op.u.setdomaininfo.domain = domid;
|
||||
op.u.setdomaininfo.vcpu = vcpu;
|
||||
op.u.setdomaininfo.ctxt = ctxt;
|
||||
op.cmd = DOM0_SETVCPUCONTEXT;
|
||||
op.u.setvcpucontext.domain = domid;
|
||||
op.u.setvcpucontext.vcpu = vcpu;
|
||||
op.u.setvcpucontext.ctxt = ctxt;
|
||||
|
||||
if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
|
||||
return rc;
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <zlib.h>
|
||||
#include "xen/arch-ia64.h"
|
||||
#include <xen/io/ioreq.h>
|
||||
#include <xen/hvm/ioreq.h>
|
||||
|
||||
/* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is
|
||||
* mysteriously declared in two places: /usr/include/asm/fpu.h and
|
||||
@@ -23,7 +23,8 @@ unsigned long xc_ia64_fpsr_default(void)
|
||||
}
|
||||
|
||||
int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
uint32_t max_factor, uint32_t flags)
|
||||
uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
|
||||
int (*suspend)(int domid))
|
||||
{
|
||||
PERROR("xc_linux_save not implemented\n");
|
||||
return -1;
|
||||
@@ -664,7 +665,7 @@ int xc_vmx_build(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ){
|
||||
if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) ){
|
||||
PERROR("Could not get vcpu context");
|
||||
goto error_out;
|
||||
}
|
||||
@@ -688,11 +689,11 @@ int xc_vmx_build(int xc_handle,
|
||||
|
||||
memset( &launch_op, 0, sizeof(launch_op) );
|
||||
|
||||
launch_op.u.setdomaininfo.domain = (domid_t)domid;
|
||||
launch_op.u.setdomaininfo.vcpu = 0;
|
||||
launch_op.u.setdomaininfo.ctxt = ctxt;
|
||||
launch_op.u.setvcpucontext.domain = (domid_t)domid;
|
||||
launch_op.u.setvcpucontext.vcpu = 0;
|
||||
launch_op.u.setvcpucontext.ctxt = ctxt;
|
||||
|
||||
launch_op.cmd = DOM0_SETDOMAININFO;
|
||||
launch_op.cmd = DOM0_SETVCPUCONTEXT;
|
||||
rc = do_dom0_op(xc_handle, &launch_op);
|
||||
return rc;
|
||||
|
||||
|
||||
@@ -402,8 +402,11 @@ static int setup_guest(int xc_handle,
|
||||
ctxt->initrd.start = 0;
|
||||
ctxt->initrd.size = 0;
|
||||
}
|
||||
strncpy((char *)ctxt->cmdline, cmdline, IA64_COMMAND_LINE_SIZE);
|
||||
ctxt->cmdline[IA64_COMMAND_LINE_SIZE-1] = '\0';
|
||||
if ( cmdline != NULL )
|
||||
{
|
||||
strncpy((char *)ctxt->cmdline, cmdline, IA64_COMMAND_LINE_SIZE);
|
||||
ctxt->cmdline[IA64_COMMAND_LINE_SIZE-1] = '\0';
|
||||
}
|
||||
munmap(start_info, PAGE_SIZE);
|
||||
|
||||
free(page_array);
|
||||
@@ -693,8 +696,11 @@ static int setup_guest(int xc_handle,
|
||||
start_info->mod_start = vinitrd_start;
|
||||
start_info->mod_len = initrd_len;
|
||||
}
|
||||
strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
|
||||
start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0';
|
||||
if ( cmdline != NULL )
|
||||
{
|
||||
strncpy((char *)start_info->cmd_line, cmdline, MAX_GUEST_CMDLINE);
|
||||
start_info->cmd_line[MAX_GUEST_CMDLINE-1] = '\0';
|
||||
}
|
||||
munmap(start_info, PAGE_SIZE);
|
||||
|
||||
/* shared_info page starts its life empty. */
|
||||
@@ -794,7 +800,7 @@ int xc_linux_build(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
|
||||
if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
|
||||
{
|
||||
PERROR("Could not get vcpu context");
|
||||
goto error_out;
|
||||
@@ -897,11 +903,11 @@ int xc_linux_build(int xc_handle,
|
||||
|
||||
memset( &launch_op, 0, sizeof(launch_op) );
|
||||
|
||||
launch_op.u.setdomaininfo.domain = (domid_t)domid;
|
||||
launch_op.u.setdomaininfo.vcpu = 0;
|
||||
launch_op.u.setdomaininfo.ctxt = ctxt;
|
||||
launch_op.u.setvcpucontext.domain = (domid_t)domid;
|
||||
launch_op.u.setvcpucontext.vcpu = 0;
|
||||
launch_op.u.setvcpucontext.ctxt = ctxt;
|
||||
|
||||
launch_op.cmd = DOM0_SETDOMAININFO;
|
||||
launch_op.cmd = DOM0_SETVCPUCONTEXT;
|
||||
rc = xc_dom0_op(xc_handle, &launch_op);
|
||||
|
||||
return rc;
|
||||
|
||||
@@ -171,7 +171,7 @@ int xc_linux_restore(int xc_handle, int io_fd,
|
||||
|
||||
|
||||
/* Only have to worry about vcpu 0 even for SMP */
|
||||
if (xc_domain_get_vcpu_context( xc_handle, dom, 0, &ctxt)) {
|
||||
if (xc_vcpu_getcontext( xc_handle, dom, 0, &ctxt)) {
|
||||
ERR("Could not get vcpu context");
|
||||
goto out;
|
||||
}
|
||||
@@ -735,10 +735,10 @@ int xc_linux_restore(int xc_handle, int io_fd,
|
||||
|
||||
DPRINTF("Domain ready to be built.\n");
|
||||
|
||||
op.cmd = DOM0_SETDOMAININFO;
|
||||
op.u.setdomaininfo.domain = (domid_t)dom;
|
||||
op.u.setdomaininfo.vcpu = 0;
|
||||
op.u.setdomaininfo.ctxt = &ctxt;
|
||||
op.cmd = DOM0_SETVCPUCONTEXT;
|
||||
op.u.setvcpucontext.domain = (domid_t)dom;
|
||||
op.u.setvcpucontext.vcpu = 0;
|
||||
op.u.setvcpucontext.ctxt = &ctxt;
|
||||
rc = xc_dom0_op(xc_handle, &op);
|
||||
|
||||
if (rc != 0) {
|
||||
|
||||
+13
-16
@@ -357,21 +357,14 @@ static int analysis_phase(int xc_handle, uint32_t domid, int max_pfn,
|
||||
}
|
||||
|
||||
|
||||
static int suspend_and_state(int xc_handle, int io_fd, int dom,
|
||||
xc_dominfo_t *info,
|
||||
static int suspend_and_state(int (*suspend)(int), int xc_handle, int io_fd,
|
||||
int dom, xc_dominfo_t *info,
|
||||
vcpu_guest_context_t *ctxt)
|
||||
{
|
||||
int i = 0;
|
||||
char ans[30];
|
||||
|
||||
printf("suspend\n");
|
||||
fflush(stdout);
|
||||
if (fgets(ans, sizeof(ans), stdin) == NULL) {
|
||||
ERR("failed reading suspend reply");
|
||||
return -1;
|
||||
}
|
||||
if (strncmp(ans, "done\n", 5)) {
|
||||
ERR("suspend reply incorrect: %s", ans);
|
||||
if (!(*suspend)(dom)) {
|
||||
ERR("Suspend request failed");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -382,7 +375,7 @@ static int suspend_and_state(int xc_handle, int io_fd, int dom,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( xc_domain_get_vcpu_context(xc_handle, dom, 0 /* XXX */, ctxt))
|
||||
if ( xc_vcpu_getcontext(xc_handle, dom, 0 /* XXX */, ctxt))
|
||||
ERR("Could not get vcpu context");
|
||||
|
||||
|
||||
@@ -568,7 +561,7 @@ static unsigned long *xc_map_m2p(int xc_handle,
|
||||
|
||||
|
||||
int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
uint32_t max_factor, uint32_t flags)
|
||||
uint32_t max_factor, uint32_t flags, int (*suspend)(int))
|
||||
{
|
||||
xc_dominfo_t info;
|
||||
|
||||
@@ -643,7 +636,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
}
|
||||
|
||||
/* Only have to worry about vcpu 0 even for SMP */
|
||||
if (xc_domain_get_vcpu_context(xc_handle, dom, 0, &ctxt)) {
|
||||
if (xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt)) {
|
||||
ERR("Could not get vcpu context");
|
||||
goto out;
|
||||
}
|
||||
@@ -748,7 +741,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
|
||||
last_iter = 1;
|
||||
|
||||
if (suspend_and_state( xc_handle, io_fd, dom, &info, &ctxt)) {
|
||||
if (suspend_and_state(suspend, xc_handle, io_fd, dom, &info, &ctxt)) {
|
||||
ERR("Domain appears not to have suspended");
|
||||
goto out;
|
||||
}
|
||||
@@ -1054,7 +1047,8 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
DPRINTF("Start last iteration\n");
|
||||
last_iter = 1;
|
||||
|
||||
if (suspend_and_state(xc_handle, io_fd, dom, &info, &ctxt)) {
|
||||
if (suspend_and_state(suspend, xc_handle, io_fd, dom, &info,
|
||||
&ctxt)) {
|
||||
ERR("Domain appears not to have suspended");
|
||||
goto out;
|
||||
}
|
||||
@@ -1164,6 +1158,9 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
if (live_shinfo)
|
||||
munmap(live_shinfo, PAGE_SIZE);
|
||||
|
||||
if (live_p2m_frame_list_list)
|
||||
munmap(live_p2m_frame_list_list, PAGE_SIZE);
|
||||
|
||||
if (live_p2m_frame_list)
|
||||
munmap(live_p2m_frame_list, P2M_FLL_ENTRIES * PAGE_SIZE);
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
|
||||
#define pt_levels 4
|
||||
#endif
|
||||
|
||||
if (xc_domain_get_vcpu_context(xc_handle, dom, vcpu, &ctx) != 0) {
|
||||
if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0) {
|
||||
fprintf(stderr, "failed to retreive vcpu context\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ fetch_regs(int xc_handle, int cpu, int *online)
|
||||
if (online)
|
||||
*online = 0;
|
||||
if ( !(regs_valid & (1 << cpu)) ) {
|
||||
retval = xc_domain_get_vcpu_context(xc_handle, current_domid,
|
||||
retval = xc_vcpu_getcontext(xc_handle, current_domid,
|
||||
cpu, &ctxt[cpu]);
|
||||
if ( retval )
|
||||
goto done;
|
||||
@@ -43,8 +43,7 @@ fetch_regs(int xc_handle, int cpu, int *online)
|
||||
if ( online == NULL )
|
||||
goto done;
|
||||
|
||||
retval = xc_domain_get_vcpu_info(xc_handle, current_domid,
|
||||
cpu, &info);
|
||||
retval = xc_vcpu_getinfo(xc_handle, current_domid, cpu, &info);
|
||||
*online = info.online;
|
||||
|
||||
done:
|
||||
@@ -395,7 +394,7 @@ xc_ptrace(
|
||||
|
||||
case PTRACE_SETREGS:
|
||||
SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
|
||||
retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
|
||||
retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]);
|
||||
if (retval)
|
||||
goto error_out;
|
||||
break;
|
||||
@@ -405,7 +404,7 @@ xc_ptrace(
|
||||
* during single-stepping - but that just seems retarded
|
||||
*/
|
||||
ctxt[cpu].user_regs.eflags |= PSL_T;
|
||||
retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
|
||||
retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]);
|
||||
if ( retval )
|
||||
{
|
||||
perror("dom0 op failed");
|
||||
@@ -423,8 +422,8 @@ xc_ptrace(
|
||||
/* Clear trace flag */
|
||||
if ( ctxt[cpu].user_regs.eflags & PSL_T ) {
|
||||
ctxt[cpu].user_regs.eflags &= ~PSL_T;
|
||||
retval = xc_domain_setinfo(xc_handle, current_domid,
|
||||
cpu, &ctxt[cpu]);
|
||||
retval = xc_vcpu_setcontext(xc_handle, current_domid,
|
||||
cpu, &ctxt[cpu]);
|
||||
if ( retval ) {
|
||||
perror("dom0 op failed");
|
||||
goto error_out;
|
||||
|
||||
+37
-45
@@ -9,7 +9,8 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <zlib.h>
|
||||
#include <xen/io/ioreq.h>
|
||||
#include <xen/hvm/hvm_info_table.h>
|
||||
#include <xen/hvm/ioreq.h>
|
||||
|
||||
#define VMX_LOADER_ENTR_ADDR 0x00100000
|
||||
|
||||
@@ -33,18 +34,6 @@
|
||||
#define E820_MAP_NR_OFFSET 0x000001E8
|
||||
#define E820_MAP_OFFSET 0x000002D0
|
||||
|
||||
#define HVM_INFO_PAGE 0x0009F000
|
||||
#define HVM_INFO_OFFSET 0x00000800
|
||||
|
||||
struct hvm_info_table {
|
||||
char signature[8]; /* "HVM INFO" */
|
||||
uint32_t length;
|
||||
uint8_t checksum;
|
||||
uint8_t acpi_enabled;
|
||||
uint8_t pad[2];
|
||||
uint32_t nr_vcpus;
|
||||
};
|
||||
|
||||
struct e820entry {
|
||||
uint64_t addr;
|
||||
uint64_t size;
|
||||
@@ -128,7 +117,7 @@ static unsigned char build_e820map(void *e820_page, unsigned long mem_size)
|
||||
return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
set_hvm_info_checksum(struct hvm_info_table *t)
|
||||
{
|
||||
uint8_t *ptr = (uint8_t *)t, sum = 0;
|
||||
@@ -148,14 +137,18 @@ set_hvm_info_checksum(struct hvm_info_table *t)
|
||||
*/
|
||||
static int set_hvm_info(int xc_handle, uint32_t dom,
|
||||
unsigned long *pfn_list, unsigned int vcpus,
|
||||
unsigned int acpi)
|
||||
unsigned int acpi, unsigned int apic)
|
||||
{
|
||||
char *va_map;
|
||||
struct hvm_info_table *va_hvm;
|
||||
|
||||
va_map = xc_map_foreign_range(xc_handle, dom,
|
||||
PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
pfn_list[HVM_INFO_PAGE >> PAGE_SHIFT]);
|
||||
va_map = xc_map_foreign_range(
|
||||
xc_handle,
|
||||
dom,
|
||||
PAGE_SIZE,
|
||||
PROT_READ|PROT_WRITE,
|
||||
pfn_list[HVM_INFO_PFN]);
|
||||
|
||||
if ( va_map == NULL )
|
||||
return -1;
|
||||
|
||||
@@ -164,8 +157,9 @@ static int set_hvm_info(int xc_handle, uint32_t dom,
|
||||
strncpy(va_hvm->signature, "HVM INFO", 8);
|
||||
va_hvm->length = sizeof(struct hvm_info_table);
|
||||
va_hvm->acpi_enabled = acpi;
|
||||
va_hvm->apic_enabled = apic;
|
||||
va_hvm->nr_vcpus = vcpus;
|
||||
|
||||
|
||||
set_hvm_info_checksum(va_hvm);
|
||||
|
||||
munmap(va_map, PAGE_SIZE);
|
||||
@@ -307,9 +301,9 @@ static int setup_guest(int xc_handle,
|
||||
vcpu_guest_context_t *ctxt,
|
||||
unsigned long shared_info_frame,
|
||||
unsigned int control_evtchn,
|
||||
unsigned int lapic,
|
||||
unsigned int vcpus,
|
||||
unsigned int acpi,
|
||||
unsigned int apic,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn)
|
||||
{
|
||||
@@ -519,20 +513,14 @@ static int setup_guest(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if (set_hvm_info(xc_handle, dom, page_array, vcpus, acpi)) {
|
||||
if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi, apic) ) {
|
||||
fprintf(stderr, "Couldn't set hvm info for VMX guest.\n");
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
*store_mfn = page_array[(v_end-2) >> PAGE_SHIFT];
|
||||
if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
|
||||
goto error_out;
|
||||
|
||||
shared_page_frame = (v_end - PAGE_SIZE) >> PAGE_SHIFT;
|
||||
|
||||
if ((e820_page = xc_map_foreign_range(
|
||||
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0)
|
||||
if ( (e820_page = xc_map_foreign_range(
|
||||
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0 )
|
||||
goto error_out;
|
||||
memset(e820_page, 0, PAGE_SIZE);
|
||||
e820_map_nr = build_e820map(e820_page, v_end);
|
||||
@@ -547,26 +535,30 @@ static int setup_guest(int xc_handle,
|
||||
munmap(e820_page, PAGE_SIZE);
|
||||
|
||||
/* shared_info page starts its life empty. */
|
||||
if ((shared_info = xc_map_foreign_range(
|
||||
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
shared_info_frame)) == 0)
|
||||
if ( (shared_info = xc_map_foreign_range(
|
||||
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
shared_info_frame)) == 0 )
|
||||
goto error_out;
|
||||
memset(shared_info, 0, sizeof(shared_info_t));
|
||||
/* Mask all upcalls... */
|
||||
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
|
||||
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
|
||||
|
||||
munmap(shared_info, PAGE_SIZE);
|
||||
|
||||
/* Populate the event channel port in the shared page */
|
||||
if ((sp = (shared_iopage_t *) xc_map_foreign_range(
|
||||
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
page_array[shared_page_frame])) == 0)
|
||||
shared_page_frame = page_array[(v_end >> PAGE_SHIFT) - 1];
|
||||
if ( (sp = (shared_iopage_t *) xc_map_foreign_range(
|
||||
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
|
||||
shared_page_frame)) == 0 )
|
||||
goto error_out;
|
||||
memset(sp, 0, PAGE_SIZE);
|
||||
sp->sp_global.eport = control_evtchn;
|
||||
munmap(sp, PAGE_SIZE);
|
||||
|
||||
*store_mfn = page_array[(v_end >> PAGE_SHIFT) - 2];
|
||||
if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
|
||||
goto error_out;
|
||||
|
||||
/* Send the page update requests down to the hypervisor. */
|
||||
if ( xc_finish_mmu_updates(xc_handle, mmu) )
|
||||
goto error_out;
|
||||
@@ -588,7 +580,7 @@ static int setup_guest(int xc_handle,
|
||||
ctxt->user_regs.eax = 0;
|
||||
ctxt->user_regs.esp = 0;
|
||||
ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */
|
||||
ctxt->user_regs.ecx = lapic;
|
||||
ctxt->user_regs.ecx = 0;
|
||||
ctxt->user_regs.esi = 0;
|
||||
ctxt->user_regs.edi = 0;
|
||||
ctxt->user_regs.ebp = 0;
|
||||
@@ -608,9 +600,9 @@ int xc_vmx_build(int xc_handle,
|
||||
int memsize,
|
||||
const char *image_name,
|
||||
unsigned int control_evtchn,
|
||||
unsigned int lapic,
|
||||
unsigned int vcpus,
|
||||
unsigned int acpi,
|
||||
unsigned int apic,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn)
|
||||
{
|
||||
@@ -659,7 +651,7 @@ int xc_vmx_build(int xc_handle,
|
||||
goto error_out;
|
||||
}
|
||||
|
||||
if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
|
||||
if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
|
||||
{
|
||||
PERROR("Could not get vcpu context");
|
||||
goto error_out;
|
||||
@@ -674,7 +666,7 @@ int xc_vmx_build(int xc_handle,
|
||||
|
||||
if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
|
||||
ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
|
||||
lapic, vcpus, acpi, store_evtchn, store_mfn) < 0)
|
||||
vcpus, acpi, apic, store_evtchn, store_mfn) < 0)
|
||||
{
|
||||
ERROR("Error constructing guest OS");
|
||||
goto error_out;
|
||||
@@ -716,11 +708,11 @@ int xc_vmx_build(int xc_handle,
|
||||
|
||||
memset( &launch_op, 0, sizeof(launch_op) );
|
||||
|
||||
launch_op.u.setdomaininfo.domain = (domid_t)domid;
|
||||
launch_op.u.setdomaininfo.vcpu = 0;
|
||||
launch_op.u.setdomaininfo.ctxt = ctxt;
|
||||
launch_op.u.setvcpucontext.domain = (domid_t)domid;
|
||||
launch_op.u.setvcpucontext.vcpu = 0;
|
||||
launch_op.u.setvcpucontext.ctxt = ctxt;
|
||||
|
||||
launch_op.cmd = DOM0_SETDOMAININFO;
|
||||
launch_op.cmd = DOM0_SETVCPUCONTEXT;
|
||||
rc = xc_dom0_op(xc_handle, &launch_op);
|
||||
|
||||
return rc;
|
||||
|
||||
+15
-15
@@ -181,10 +181,11 @@ int xc_domain_unpause(int xc_handle,
|
||||
*/
|
||||
int xc_domain_destroy(int xc_handle,
|
||||
uint32_t domid);
|
||||
int xc_domain_pincpu(int xc_handle,
|
||||
uint32_t domid,
|
||||
int vcpu,
|
||||
cpumap_t cpumap);
|
||||
|
||||
int xc_vcpu_setaffinity(int xc_handle,
|
||||
uint32_t domid,
|
||||
int vcpu,
|
||||
cpumap_t cpumap);
|
||||
|
||||
/**
|
||||
* This function will return information about one or more domains. It is
|
||||
@@ -208,7 +209,7 @@ int xc_domain_getinfo(int xc_handle,
|
||||
|
||||
|
||||
/**
|
||||
* This function will set the vcpu context for the specified domain.
|
||||
* This function will set the execution context for the specified vcpu.
|
||||
*
|
||||
* @parm xc_handle a handle to an open hypervisor interface
|
||||
* @parm domid the domain to set the vcpu context for
|
||||
@@ -216,10 +217,10 @@ int xc_domain_getinfo(int xc_handle,
|
||||
* @parm ctxt pointer to the the cpu context with the values to set
|
||||
* @return the number of domains enumerated or -1 on error
|
||||
*/
|
||||
int xc_domain_setinfo(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
vcpu_guest_context_t *ctxt);
|
||||
int xc_vcpu_setcontext(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
vcpu_guest_context_t *ctxt);
|
||||
/**
|
||||
* This function will return information about one or more domains, using a
|
||||
* single hypercall. The domain information will be stored into the supplied
|
||||
@@ -249,17 +250,16 @@ int xc_domain_getinfolist(int xc_handle,
|
||||
* domain
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int xc_domain_get_vcpu_context(int xc_handle,
|
||||
int xc_vcpu_getcontext(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
vcpu_guest_context_t *ctxt);
|
||||
|
||||
typedef dom0_getvcpuinfo_t xc_vcpuinfo_t;
|
||||
int xc_domain_get_vcpu_info(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
xc_vcpuinfo_t *info);
|
||||
|
||||
int xc_vcpu_getinfo(int xc_handle,
|
||||
uint32_t domid,
|
||||
uint32_t vcpu,
|
||||
xc_vcpuinfo_t *info);
|
||||
|
||||
int xc_domain_setcpuweight(int xc_handle,
|
||||
uint32_t domid,
|
||||
|
||||
@@ -21,8 +21,10 @@
|
||||
* @parm dom the id of the domain
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int xc_linux_save(int xc_handle, int fd, uint32_t dom, uint32_t max_iters,
|
||||
uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */);
|
||||
int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
|
||||
uint32_t max_factor, uint32_t flags /* XCFLAGS_xxx */,
|
||||
int (*suspend)(int domid));
|
||||
|
||||
|
||||
/**
|
||||
* This function will restore a saved domain running Linux.
|
||||
@@ -56,9 +58,9 @@ int xc_vmx_build(int xc_handle,
|
||||
int memsize,
|
||||
const char *image_name,
|
||||
unsigned int control_evtchn,
|
||||
unsigned int lapic,
|
||||
unsigned int vcpus,
|
||||
unsigned int acpi,
|
||||
unsigned int apic,
|
||||
unsigned int store_evtchn,
|
||||
unsigned long *store_mfn);
|
||||
|
||||
|
||||
@@ -17,6 +17,9 @@ char *xc_read_kernel_image(const char *filename, unsigned long *size)
|
||||
char *image = NULL;
|
||||
unsigned int bytes;
|
||||
|
||||
if ( filename == NULL )
|
||||
goto out;
|
||||
|
||||
if ( (kernel_fd = open(filename, O_RDONLY)) < 0 )
|
||||
{
|
||||
PERROR("Could not open kernel image");
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "xc_private.h"
|
||||
#include "xenctrl.h"
|
||||
|
||||
/* Needed for Python versions earlier than 2.3. */
|
||||
#ifndef PyMODINIT_FUNC
|
||||
@@ -135,9 +135,9 @@ static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
|
||||
}
|
||||
|
||||
|
||||
static PyObject *pyxc_domain_pincpu(XcObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
|
||||
PyObject *args,
|
||||
PyObject *kwds)
|
||||
{
|
||||
uint32_t dom;
|
||||
int vcpu = 0, i;
|
||||
@@ -157,7 +157,7 @@ static PyObject *pyxc_domain_pincpu(XcObject *self,
|
||||
cpumap |= (cpumap_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
|
||||
}
|
||||
|
||||
if ( xc_domain_pincpu(self->xc_handle, dom, vcpu, cpumap) != 0 )
|
||||
if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
Py_INCREF(zero);
|
||||
@@ -297,7 +297,7 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self,
|
||||
&dom, &vcpu) )
|
||||
return NULL;
|
||||
|
||||
rc = xc_domain_get_vcpu_info(self->xc_handle, dom, vcpu, &info);
|
||||
rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
|
||||
if ( rc < 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
@@ -362,22 +362,23 @@ static PyObject *pyxc_vmx_build(XcObject *self,
|
||||
uint32_t dom;
|
||||
char *image;
|
||||
int control_evtchn, store_evtchn;
|
||||
int vcpus = 1;
|
||||
int lapic = 0;
|
||||
int acpi = 0;
|
||||
int memsize;
|
||||
int vcpus = 1;
|
||||
int acpi = 0;
|
||||
int apic = 0;
|
||||
unsigned long store_mfn = 0;
|
||||
|
||||
static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
|
||||
"memsize", "image", "lapic", "vcpus", "acpi",NULL };
|
||||
"memsize", "image", "vcpus", "acpi", "apic",
|
||||
NULL };
|
||||
|
||||
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list,
|
||||
&dom, &control_evtchn, &store_evtchn,
|
||||
&memsize, &image, &lapic, &vcpus,&acpi) )
|
||||
&memsize, &image, &vcpus, &acpi, &apic) )
|
||||
return NULL;
|
||||
|
||||
if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn,
|
||||
lapic, vcpus, acpi, store_evtchn, &store_mfn) != 0 )
|
||||
vcpus, acpi, apic, store_evtchn, &store_mfn) != 0 )
|
||||
return PyErr_SetFromErrno(xc_error);
|
||||
|
||||
return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
|
||||
@@ -889,8 +890,8 @@ static PyMethodDef pyxc_methods[] = {
|
||||
" dom [int]: Identifier of domain to be destroyed.\n\n"
|
||||
"Returns: [int] 0 on success; -1 on error.\n" },
|
||||
|
||||
{ "domain_pincpu",
|
||||
(PyCFunction)pyxc_domain_pincpu,
|
||||
{ "vcpu_setaffinity",
|
||||
(PyCFunction)pyxc_vcpu_setaffinity,
|
||||
METH_VARARGS | METH_KEYWORDS, "\n"
|
||||
"Pin a VCPU to a specified set CPUs.\n"
|
||||
" dom [int]: Identifier of domain to which VCPU belongs.\n"
|
||||
|
||||
@@ -66,7 +66,7 @@ static PyObject *none(bool result);
|
||||
|
||||
static int parse_transaction_path(XsHandle *self, PyObject *args,
|
||||
struct xs_handle **xh,
|
||||
struct xs_transaction_handle **th,
|
||||
xs_transaction_t *th,
|
||||
char **path);
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ static int parse_transaction_path(XsHandle *self, PyObject *args,
|
||||
static PyObject *xspy_read(XsHandle *self, PyObject *args)
|
||||
{
|
||||
struct xs_handle *xh;
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char *path;
|
||||
|
||||
char *xsval;
|
||||
@@ -120,7 +120,7 @@ static PyObject *xspy_write(XsHandle *self, PyObject *args)
|
||||
{
|
||||
static char *arg_spec = "sss#";
|
||||
struct xs_handle *xh = xshandle(self);
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char *thstr;
|
||||
char *path;
|
||||
char *data;
|
||||
@@ -132,7 +132,7 @@ static PyObject *xspy_write(XsHandle *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path, &data, &data_n))
|
||||
return NULL;
|
||||
|
||||
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
|
||||
th = strtoul(thstr, NULL, 16);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
result = xs_write(xh, th, path, data, data_n);
|
||||
@@ -155,7 +155,7 @@ static PyObject *xspy_write(XsHandle *self, PyObject *args)
|
||||
static PyObject *xspy_ls(XsHandle *self, PyObject *args)
|
||||
{
|
||||
struct xs_handle *xh;
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char *path;
|
||||
|
||||
char **xsval;
|
||||
@@ -193,7 +193,7 @@ static PyObject *xspy_ls(XsHandle *self, PyObject *args)
|
||||
static PyObject *xspy_mkdir(XsHandle *self, PyObject *args)
|
||||
{
|
||||
struct xs_handle *xh;
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char *path;
|
||||
|
||||
bool result;
|
||||
@@ -221,7 +221,7 @@ static PyObject *xspy_mkdir(XsHandle *self, PyObject *args)
|
||||
static PyObject *xspy_rm(XsHandle *self, PyObject *args)
|
||||
{
|
||||
struct xs_handle *xh;
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char *path;
|
||||
|
||||
bool result;
|
||||
@@ -256,7 +256,7 @@ static PyObject *xspy_get_permissions(XsHandle *self, PyObject *args)
|
||||
unsigned int perms_n = 0;
|
||||
int i;
|
||||
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char *thstr;
|
||||
|
||||
if (!xh)
|
||||
@@ -264,7 +264,7 @@ static PyObject *xspy_get_permissions(XsHandle *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, arg_spec, &thstr, &path))
|
||||
return NULL;
|
||||
|
||||
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
|
||||
th = strtoul(thstr, NULL, 16);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
perms = xs_get_permissions(xh, th, path, &perms_n);
|
||||
@@ -312,7 +312,7 @@ static PyObject *xspy_set_permissions(XsHandle *self, PyObject *args)
|
||||
int xsperms_n;
|
||||
PyObject *tuple0 = NULL;
|
||||
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char *thstr;
|
||||
|
||||
if (!xh)
|
||||
@@ -320,7 +320,7 @@ static PyObject *xspy_set_permissions(XsHandle *self, PyObject *args)
|
||||
if (!PyArg_ParseTuple(args, "ssO", &thstr, &path, &perms))
|
||||
goto exit;
|
||||
|
||||
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
|
||||
th = strtoul(thstr, NULL, 16);
|
||||
|
||||
if (!PyList_Check(perms)) {
|
||||
PyErr_SetString(PyExc_RuntimeError, "perms must be a list");
|
||||
@@ -509,7 +509,7 @@ static PyObject *xspy_unwatch(XsHandle *self, PyObject *args)
|
||||
static PyObject *xspy_transaction_start(XsHandle *self)
|
||||
{
|
||||
struct xs_handle *xh = xshandle(self);
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char thstr[MAX_STRLEN(unsigned long) + 1];
|
||||
|
||||
if (!xh)
|
||||
@@ -519,7 +519,7 @@ static PyObject *xspy_transaction_start(XsHandle *self)
|
||||
th = xs_transaction_start(xh);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
if (th == NULL) {
|
||||
if (th == XBT_NULL) {
|
||||
PyErr_SetFromErrno(PyExc_RuntimeError);
|
||||
return NULL;
|
||||
}
|
||||
@@ -547,7 +547,7 @@ static PyObject *xspy_transaction_end(XsHandle *self, PyObject *args,
|
||||
struct xs_handle *xh = xshandle(self);
|
||||
bool result;
|
||||
|
||||
struct xs_transaction_handle *th;
|
||||
xs_transaction_t th;
|
||||
char *thstr;
|
||||
|
||||
if (!xh)
|
||||
@@ -556,7 +556,7 @@ static PyObject *xspy_transaction_end(XsHandle *self, PyObject *args,
|
||||
&thstr, &abort))
|
||||
return NULL;
|
||||
|
||||
th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
|
||||
th = strtoul(thstr, NULL, 16);
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
result = xs_transaction_end(xh, th, abort);
|
||||
@@ -727,7 +727,7 @@ static void remove_watch(XsHandle *self, PyObject *token)
|
||||
*/
|
||||
static int parse_transaction_path(XsHandle *self, PyObject *args,
|
||||
struct xs_handle **xh,
|
||||
struct xs_transaction_handle **th,
|
||||
xs_transaction_t *th,
|
||||
char **path)
|
||||
{
|
||||
char *thstr;
|
||||
@@ -740,7 +740,7 @@ static int parse_transaction_path(XsHandle *self, PyObject *args,
|
||||
if (!PyArg_ParseTuple(args, "ss", &thstr, path))
|
||||
return 0;
|
||||
|
||||
*th = (struct xs_transaction_handle *)strtoul(thstr, NULL, 16);
|
||||
*th = strtoul(thstr, NULL, 16);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -443,7 +443,7 @@ class XendDomain:
|
||||
cpumap = map(lambda x: int(x),
|
||||
cpumap.replace("[", "").replace("]", "").split(","))
|
||||
try:
|
||||
return xc.domain_pincpu(dominfo.getDomid(), vcpu, cpumap)
|
||||
return xc.vcpu_setaffinity(dominfo.getDomid(), vcpu, cpumap)
|
||||
except Exception, ex:
|
||||
raise XendError(str(ex))
|
||||
|
||||
|
||||
@@ -1179,7 +1179,7 @@ class XendDomainInfo:
|
||||
for v in range(0, self.info['max_vcpu_id']+1):
|
||||
# pincpu takes a list of ints
|
||||
cpu = [ int( cpus[v % len(cpus)] ) ]
|
||||
xc.domain_pincpu(self.domid, v, cpu)
|
||||
xc.vcpu_setaffinity(self.domid, v, cpu)
|
||||
|
||||
m = self.image.getDomainMemory(self.info['memory'] * 1024)
|
||||
balloon.free(m)
|
||||
|
||||
@@ -209,13 +209,9 @@ class VmxImageHandler(ImageHandler):
|
||||
|
||||
self.dmargs += self.configVNC(imageConfig)
|
||||
|
||||
self.lapic = 0
|
||||
lapic = sxp.child_value(imageConfig, 'lapic')
|
||||
if not lapic is None:
|
||||
self.lapic = int(lapic)
|
||||
|
||||
self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
|
||||
|
||||
self.apic = int(sxp.child_value(imageConfig, 'apic', 0))
|
||||
|
||||
def buildDomain(self):
|
||||
# Create an event channel
|
||||
self.device_channel = xc.evtchn_alloc_unbound(dom=self.vm.getDomid(),
|
||||
@@ -229,18 +225,18 @@ class VmxImageHandler(ImageHandler):
|
||||
log.debug("control_evtchn = %d", self.device_channel)
|
||||
log.debug("store_evtchn = %d", store_evtchn)
|
||||
log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024)
|
||||
log.debug("lapic = %d", self.lapic)
|
||||
log.debug("vcpus = %d", self.vm.getVCpuCount())
|
||||
log.debug("acpi = %d", self.acpi)
|
||||
log.debug("apic = %d", self.apic)
|
||||
|
||||
return xc.vmx_build(dom = self.vm.getDomid(),
|
||||
image = self.kernel,
|
||||
control_evtchn = self.device_channel,
|
||||
store_evtchn = store_evtchn,
|
||||
memsize = self.vm.getMemoryTarget() / 1024,
|
||||
lapic = self.lapic,
|
||||
vcpus = self.vm.getVCpuCount(),
|
||||
acpi = self.acpi,
|
||||
vcpus = self.vm.getVCpuCount())
|
||||
apic = self.apic)
|
||||
|
||||
# Return a list of cmd line args to the device models based on the
|
||||
# xm config file
|
||||
|
||||
@@ -32,11 +32,10 @@ HOTPLUG_STATUS_ERROR = "error"
|
||||
HOTPLUG_STATUS_BUSY = "busy"
|
||||
|
||||
Connected = 1
|
||||
Died = 2
|
||||
Error = 3
|
||||
Missing = 4
|
||||
Timeout = 5
|
||||
Busy = 6
|
||||
Error = 2
|
||||
Missing = 3
|
||||
Timeout = 4
|
||||
Busy = 5
|
||||
|
||||
xenbusState = {
|
||||
'Unknown' : 0,
|
||||
@@ -157,11 +156,6 @@ class DevController:
|
||||
raise VmError("Device %s (%s) could not be connected. "
|
||||
"Device not found." % (devid, self.deviceClass))
|
||||
|
||||
elif status == Died:
|
||||
self.destroyDevice(devid)
|
||||
raise VmError("Device %s (%s) could not be connected. "
|
||||
"Device has died." % (devid, self.deviceClass))
|
||||
|
||||
elif status == Busy:
|
||||
err = None
|
||||
frontpath = self.frontendPath(devid)
|
||||
@@ -408,20 +402,17 @@ class DevController:
|
||||
def hotplugStatusCallback(statusPath, ev, result):
|
||||
log.debug("hotplugStatusCallback %s.", statusPath)
|
||||
|
||||
try:
|
||||
status = xstransact.Read(statusPath)
|
||||
status = xstransact.Read(statusPath)
|
||||
|
||||
if status is not None:
|
||||
if status == HOTPLUG_STATUS_ERROR:
|
||||
result['status'] = Error
|
||||
elif status == HOTPLUG_STATUS_BUSY:
|
||||
result['status'] = Busy
|
||||
else:
|
||||
result['status'] = Connected
|
||||
if status is not None:
|
||||
if status == HOTPLUG_STATUS_ERROR:
|
||||
result['status'] = Error
|
||||
elif status == HOTPLUG_STATUS_BUSY:
|
||||
result['status'] = Busy
|
||||
else:
|
||||
return 1
|
||||
except VmError:
|
||||
result['status'] = Died
|
||||
result['status'] = Connected
|
||||
else:
|
||||
return 1
|
||||
|
||||
log.debug("hotplugStatusCallback %d.", result['status'])
|
||||
|
||||
|
||||
@@ -160,14 +160,14 @@ gopts.var('cpus', val='CPUS',
|
||||
fn=set_int, default=None,
|
||||
use="CPUS to run the domain on.")
|
||||
|
||||
gopts.var('lapic', val='LAPIC',
|
||||
fn=set_int, default=0,
|
||||
use="Disable or enable local APIC of VMX domain.")
|
||||
|
||||
gopts.var('acpi', val='ACPI',
|
||||
fn=set_int, default=0,
|
||||
use="Disable or enable ACPI of VMX domain.")
|
||||
|
||||
gopts.var('apic', val='APIC',
|
||||
fn=set_int, default=0,
|
||||
use="Disable or enable APIC of VMX domain.")
|
||||
|
||||
gopts.var('vcpus', val='VCPUS',
|
||||
fn=set_int, default=1,
|
||||
use="# of Virtual CPUS in domain.")
|
||||
@@ -534,8 +534,8 @@ def configure_vmx(config_image, vals):
|
||||
"""
|
||||
args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
|
||||
'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
|
||||
'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic',
|
||||
'xauthority', 'acpi' ]
|
||||
'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'acpi', 'apic',
|
||||
'xauthority' ]
|
||||
for a in args:
|
||||
if (vals.__dict__[a]):
|
||||
config_image.append([a, vals.__dict__[a]])
|
||||
|
||||
@@ -390,7 +390,6 @@ def xm_brief_list(doms):
|
||||
|
||||
|
||||
def xm_vcpu_list(args):
|
||||
print 'Name ID VCPU CPU State Time(s) CPU Affinity'
|
||||
|
||||
from xen.xend.XendClient import server
|
||||
if args:
|
||||
@@ -401,6 +400,8 @@ def xm_vcpu_list(args):
|
||||
lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')),
|
||||
doms)
|
||||
|
||||
print 'Name ID VCPU CPU State Time(s) CPU Affinity'
|
||||
|
||||
for dom in dominfo:
|
||||
def get_info(n):
|
||||
return sxp.child_value(dom, n)
|
||||
@@ -625,6 +626,8 @@ def xm_sched_sedf(args):
|
||||
server.xend_domain_cpu_sedf_set(dom, *v)
|
||||
|
||||
def xm_info(args):
|
||||
arg_check(args, "info", 0)
|
||||
|
||||
from xen.xend.XendClient import server
|
||||
info = server.xend_node()
|
||||
|
||||
@@ -645,9 +648,12 @@ def xm_console(args):
|
||||
|
||||
|
||||
def xm_top(args):
|
||||
arg_check(args, "top", 0)
|
||||
|
||||
os.execvp('xentop', ['xentop'])
|
||||
|
||||
def xm_dmesg(args):
|
||||
arg_check(args, "dmesg", 0)
|
||||
|
||||
gopts = Opts(use="""[-c|--clear]
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ int main(int argc, char **argv)
|
||||
regs.ecx = 0x12345678;
|
||||
cr2 = (unsigned long)&res;
|
||||
res = 0x7FFFFFFF;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x92345677) ||
|
||||
(regs.eflags != 0xa94) ||
|
||||
@@ -110,7 +110,7 @@ int main(int argc, char **argv)
|
||||
regs.ecx = 0x12345678UL;
|
||||
#endif
|
||||
cr2 = (unsigned long)&res;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x92345677) ||
|
||||
(regs.ecx != 0x8000000FUL) ||
|
||||
@@ -125,7 +125,7 @@ int main(int argc, char **argv)
|
||||
regs.eax = 0x92345677UL;
|
||||
regs.ecx = 0xAA;
|
||||
cr2 = (unsigned long)&res;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x923456AA) ||
|
||||
(regs.eflags != 0x244) ||
|
||||
@@ -141,7 +141,7 @@ int main(int argc, char **argv)
|
||||
regs.eax = 0xAABBCC77UL;
|
||||
regs.ecx = 0xFF;
|
||||
cr2 = (unsigned long)&res;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x923456AA) ||
|
||||
((regs.eflags&0x240) != 0x200) ||
|
||||
@@ -157,7 +157,7 @@ int main(int argc, char **argv)
|
||||
regs.eip = (unsigned long)&instr[0];
|
||||
regs.ecx = 0x12345678;
|
||||
cr2 = (unsigned long)&res;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x12345678) ||
|
||||
(regs.eflags != 0x200) ||
|
||||
@@ -174,7 +174,7 @@ int main(int argc, char **argv)
|
||||
regs.eax = 0x923456AAUL;
|
||||
regs.ecx = 0xDDEEFF00L;
|
||||
cr2 = (unsigned long)&res;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0xDDEEFF00) ||
|
||||
(regs.eflags != 0x244) ||
|
||||
@@ -193,7 +193,7 @@ int main(int argc, char **argv)
|
||||
regs.edi = (unsigned long)&res + 2;
|
||||
regs.error_code = 0; /* read fault */
|
||||
cr2 = regs.esi;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x44554455) ||
|
||||
(regs.eflags != 0x200) ||
|
||||
@@ -211,7 +211,7 @@ int main(int argc, char **argv)
|
||||
regs.eip = (unsigned long)&instr[0];
|
||||
regs.edi = (unsigned long)&res;
|
||||
cr2 = regs.edi;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x2233445D) ||
|
||||
((regs.eflags&0x201) != 0x201) ||
|
||||
@@ -229,7 +229,7 @@ int main(int argc, char **argv)
|
||||
regs.eip = (unsigned long)&instr[0];
|
||||
regs.edi = (unsigned long)cmpxchg8b_res;
|
||||
cr2 = regs.edi;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(cmpxchg8b_res[0] != 0x9999AAAA) ||
|
||||
(cmpxchg8b_res[1] != 0xCCCCFFFF) ||
|
||||
@@ -243,7 +243,7 @@ int main(int argc, char **argv)
|
||||
regs.eip = (unsigned long)&instr[0];
|
||||
regs.edi = (unsigned long)cmpxchg8b_res;
|
||||
cr2 = regs.edi;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(cmpxchg8b_res[0] != 0x9999AAAA) ||
|
||||
(cmpxchg8b_res[1] != 0xCCCCFFFF) ||
|
||||
@@ -260,7 +260,7 @@ int main(int argc, char **argv)
|
||||
regs.ecx = 0x12345678;
|
||||
cr2 = (unsigned long)&res;
|
||||
res = 0x82;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x82) ||
|
||||
(regs.ecx != 0xFFFFFF82) ||
|
||||
@@ -275,7 +275,7 @@ int main(int argc, char **argv)
|
||||
regs.ecx = 0x12345678;
|
||||
cr2 = (unsigned long)&res;
|
||||
res = 0x1234aa82;
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, 4);
|
||||
rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32);
|
||||
if ( (rc != 0) ||
|
||||
(res != 0x1234aa82) ||
|
||||
(regs.ecx != 0xaa82) ||
|
||||
|
||||
+11
-2
@@ -11,6 +11,8 @@ VTPM_DIR = vtpm
|
||||
# Emulator tarball name
|
||||
TPM_EMULATOR_TARFILE = tpm_emulator-0.2b.tar.gz
|
||||
|
||||
GMP_HEADER = /usr/include/gmp.h
|
||||
|
||||
all: build
|
||||
|
||||
build: $(TPM_EMULATOR_DIR) $(VTPM_DIR) build_sub
|
||||
@@ -55,5 +57,12 @@ $(VTPM_DIR): $(TPM_EMULATOR_TARFILE)
|
||||
patch -p1 <../vtpm.patch
|
||||
|
||||
build_sub:
|
||||
$(MAKE) -C $(TPM_EMULATOR_DIR)
|
||||
$(MAKE) -C $(VTPM_DIR)
|
||||
if [ -e $(GMP_HEADER) ]; then \
|
||||
$(MAKE) -C $(VTPM_DIR); \
|
||||
if [ "$(BUILD_EMULATOR)" = "y" ]; then \
|
||||
$(MAKE) -C $(TPM_EMULATOR_DIR); \
|
||||
fi \
|
||||
else \
|
||||
echo "*** Unable to build VTPMs. libgmp could not be found."; \
|
||||
fi
|
||||
|
||||
@@ -33,5 +33,7 @@ $(OBJS): $(SRCS)
|
||||
|
||||
-include $(DEP_FILES)
|
||||
|
||||
BUILD_EMULATOR = n
|
||||
|
||||
# Make sure these are just rules
|
||||
.PHONY : all build install clean
|
||||
@@ -4,13 +4,18 @@ XEN_ROOT = ../..
|
||||
include $(XEN_ROOT)/tools/vtpm_manager/Rules.mk
|
||||
|
||||
SUBDIRS = crypto tcs util manager
|
||||
OPENSSL_HEADER = /usr/include/openssl/crypto.h
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
@set -e; for subdir in $(SUBDIRS); do \
|
||||
$(MAKE) -C $$subdir $@; \
|
||||
done
|
||||
if [ -e $(OPENSSL_HEADER) ]; then \
|
||||
@set -e; for subdir in $(SUBDIRS); do \
|
||||
$(MAKE) -C $$subdir $@; \
|
||||
done; \
|
||||
else \
|
||||
echo "*** Cannot build vtpm_manager: OpenSSL developement files missing."; \
|
||||
fi
|
||||
|
||||
install: build
|
||||
@set -e; for subdir in $(SUBDIRS); do \
|
||||
|
||||
@@ -144,7 +144,10 @@ TPM_RESULT VerifyAuth( /*[IN]*/ const BYTE *outParamDigestText,
|
||||
if (memcmp (&hm, &(auth->HMAC), sizeof(TPM_DIGEST)) == 0) // 0 indicates equality
|
||||
return (TPM_SUCCESS);
|
||||
else {
|
||||
VTSP_OIAP( hContext, auth);
|
||||
// If specified, reconnect the OIAP session.
|
||||
// NOTE: This only works for TCS's that never have a 0 context.
|
||||
if (hContext)
|
||||
VTSP_OIAP( hContext, auth);
|
||||
return (TPM_AUTHFAIL);
|
||||
}
|
||||
}
|
||||
@@ -157,6 +160,10 @@ TPM_RESULT VTSP_OIAP(const TCS_CONTEXT_HANDLE hContext,
|
||||
TPMTRYRETURN( TCSP_OIAP(hContext,
|
||||
&auth->AuthHandle,
|
||||
&auth->NonceEven) );
|
||||
|
||||
memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
|
||||
auth->fContinueAuthSession = FALSE;
|
||||
|
||||
goto egress;
|
||||
|
||||
abort_egress:
|
||||
@@ -195,6 +202,9 @@ TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_HANDLE hContext,
|
||||
BSG_TPM_NONCE, &nonceOddOSAP);
|
||||
|
||||
Crypto_HMAC(sharedSecretText, sizeof(sharedSecretText), (BYTE *) usageAuth, TPM_DIGEST_SIZE, (BYTE *) sharedSecret);
|
||||
|
||||
memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
|
||||
auth->fContinueAuthSession = FALSE;
|
||||
|
||||
goto egress;
|
||||
|
||||
@@ -288,9 +298,6 @@ TPM_RESULT VTSP_TakeOwnership( const TCS_CONTEXT_HANDLE hContext,
|
||||
|
||||
struct pack_buf_t srkText;
|
||||
|
||||
// GenerateAuth new nonceOdd
|
||||
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
|
||||
|
||||
//These values are accurate for an enc(AuthData).
|
||||
struct pack_buf_t encOwnerAuth, encSrkAuth;
|
||||
|
||||
@@ -383,9 +390,6 @@ TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE hContext,
|
||||
BYTE *paramText; // Digest to make Auth.
|
||||
UINT32 paramTextSize;
|
||||
|
||||
// Generate HMAC
|
||||
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
|
||||
|
||||
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
|
||||
|
||||
paramTextSize = BSG_PackList(paramText, 1,
|
||||
@@ -504,9 +508,6 @@ TPM_RESULT VTSP_CreateWrapKey( const TCS_CONTEXT_HANDLE hContext,
|
||||
newKeyText.data = flatKey;
|
||||
newKeyText.size = flatKeySize;
|
||||
|
||||
// GenerateAuth new nonceOdd
|
||||
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
|
||||
|
||||
// Generate HMAC
|
||||
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
|
||||
|
||||
@@ -587,9 +588,6 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE hContext,
|
||||
// Generate Extra TCS Parameters
|
||||
TPM_HANDLE phKeyHMAC;
|
||||
|
||||
// Generate HMAC
|
||||
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
|
||||
|
||||
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
|
||||
|
||||
paramTextSize = BSG_PackList(paramText, 1,
|
||||
@@ -676,9 +674,6 @@ TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE hContext,
|
||||
BYTE *clear_data_text;
|
||||
UINT32 clear_data_size;
|
||||
|
||||
// Generate HMAC
|
||||
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
|
||||
|
||||
struct pack_buf_t bound_data32 = {bound_data->size, bound_data->bytes};
|
||||
|
||||
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
|
||||
@@ -787,6 +782,196 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo,
|
||||
return TPM_SUCCESS;
|
||||
}
|
||||
|
||||
TPM_RESULT VTSP_Seal(const TCS_CONTEXT_HANDLE hContext,
|
||||
const TPM_KEY_HANDLE keyHandle,
|
||||
const TPM_AUTHDATA *sealDataAuth,
|
||||
const TPM_PCR_COMPOSITE *pcrComp,
|
||||
const buffer_t *inData,
|
||||
TPM_STORED_DATA *sealedData,
|
||||
const TPM_SECRET *osapSharedSecret,
|
||||
TCS_AUTH *auth) {
|
||||
|
||||
TPM_RESULT status = TPM_SUCCESS;
|
||||
TPM_COMMAND_CODE command = TPM_ORD_Seal;
|
||||
|
||||
BYTE *paramText; // Digest to make Auth.
|
||||
UINT32 paramTextSize;
|
||||
|
||||
// Generate PCR_Info Struct from Comp
|
||||
TPM_PCR_INFO pcrInfo;
|
||||
UINT32 pcrInfoSize, flatpcrSize;
|
||||
BYTE flatpcr[3 + // PCR_Select = 3 1 byte banks
|
||||
sizeof(UINT16) + // 2 byte UINT16
|
||||
sizeof(UINT32) + // PCR_Comp = 4 byte UINT32
|
||||
24 * sizeof(TPM_PCRVALUE) ]; // up to 24 PCRs
|
||||
|
||||
if (pcrComp != NULL) {
|
||||
//printf("\n\tBinding to PCRs: ");
|
||||
//for(int i = 0 ; i < pcrComp->select.sizeOfSelect ; i++)
|
||||
//printf("%2.2x", pcrComp->select.pcrSelect[i]);
|
||||
|
||||
memcpy(&pcrInfo.pcrSelection, &pcrComp->select, sizeof(TPM_PCR_SELECTION));
|
||||
|
||||
flatpcrSize = BSG_Pack(BSG_TPM_PCR_COMPOSITE, (BYTE *) pcrComp, flatpcr);
|
||||
Crypto_SHA1Full((BYTE *) flatpcr, flatpcrSize, (BYTE *) &(pcrInfo.digestAtRelease));
|
||||
memset(&(pcrInfo.digestAtCreation), 0, sizeof(TPM_DIGEST));
|
||||
pcrInfoSize = BSG_Pack(BSG_TPM_PCR_INFO, (BYTE *) &pcrInfo, flatpcr);
|
||||
} else {
|
||||
//printf("\n\tBinding to no PCRS.");
|
||||
pcrInfoSize = 0;
|
||||
}
|
||||
|
||||
// Calculate encUsageAuth
|
||||
BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)];
|
||||
UINT32 XORbufferSize = sizeof(XORbuffer);
|
||||
TPM_DIGEST XORKey;
|
||||
TPM_ENCAUTH encAuth;
|
||||
|
||||
BSG_PackList( XORbuffer, 2,
|
||||
BSG_TPM_SECRET, osapSharedSecret,
|
||||
BSG_TPM_NONCE, &auth->NonceEven );
|
||||
|
||||
Crypto_SHA1Full(XORbuffer, XORbufferSize, (BYTE *) &XORKey);
|
||||
|
||||
int i;
|
||||
for (i=0; i < TPM_DIGEST_SIZE; i++)
|
||||
((BYTE *) &encAuth)[i] = ((BYTE *) &XORKey)[i] ^ ((BYTE *) sealDataAuth)[i];
|
||||
|
||||
// Generate Extra TCS Parameters
|
||||
UINT32 inDataSize = buffer_len(inData);
|
||||
struct pack_buf_t inData_pack = {inDataSize, inData->bytes};
|
||||
struct pack_buf_t pcrInfo_pack = {pcrInfoSize, flatpcr};
|
||||
|
||||
UINT32 sealedDataSize;
|
||||
BYTE *flatSealedData=NULL;
|
||||
|
||||
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
|
||||
|
||||
paramTextSize = BSG_PackList(paramText, 4,
|
||||
BSG_TPM_COMMAND_CODE, &command,
|
||||
BSG_TPM_ENCAUTH, &encAuth,
|
||||
BSG_TPM_SIZE32_DATA, &pcrInfo_pack,
|
||||
BSG_TPM_SIZE32_DATA, &inData_pack);
|
||||
|
||||
TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
|
||||
osapSharedSecret, auth) );
|
||||
|
||||
// Call TCS
|
||||
TPMTRYRETURN( TCSP_Seal( hContext,
|
||||
keyHandle,
|
||||
encAuth,
|
||||
pcrInfoSize,
|
||||
flatpcr,
|
||||
inDataSize,
|
||||
inData->bytes,
|
||||
auth,
|
||||
&sealedDataSize,
|
||||
&flatSealedData) );
|
||||
|
||||
// Unpack/return key structure
|
||||
BSG_Unpack( BSG_TPM_STORED_DATA, flatSealedData, sealedData );
|
||||
|
||||
paramTextSize = BSG_PackList(paramText, 3,
|
||||
BSG_TPM_RESULT, &status,
|
||||
BSG_TPM_COMMAND_CODE, &command,
|
||||
BSG_TPM_STORED_DATA, sealedData);
|
||||
|
||||
TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
|
||||
osapSharedSecret, auth,
|
||||
0) );
|
||||
|
||||
|
||||
goto egress;
|
||||
|
||||
abort_egress:
|
||||
egress:
|
||||
|
||||
if (flatSealedData)
|
||||
TCS_FreeMemory( hContext, flatSealedData);
|
||||
|
||||
free(paramText);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
TPM_RESULT VTSP_Unseal(const TCS_CONTEXT_HANDLE hContext,
|
||||
const TPM_KEY_HANDLE keyHandle,
|
||||
const TPM_STORED_DATA *sealedData,
|
||||
const TPM_AUTHDATA *key_usage_auth,
|
||||
const TPM_AUTHDATA *data_usage_auth,
|
||||
buffer_t *outData,
|
||||
TCS_AUTH *auth,
|
||||
TCS_AUTH *dataAuth) {
|
||||
|
||||
TPM_RESULT status = TPM_SUCCESS;
|
||||
TPM_COMMAND_CODE command = TPM_ORD_Unseal;
|
||||
|
||||
BYTE *paramText; // Digest to make Auth.
|
||||
UINT32 paramTextSize;
|
||||
|
||||
// Generate Extra TCS Parameters
|
||||
UINT32 sealDataSize, clearDataSize;
|
||||
BYTE *flatSealedData= (BYTE *) malloc(sizeof(TPM_VERSION) +
|
||||
2 * sizeof(UINT32) +
|
||||
sealedData->sealInfoSize +
|
||||
sealedData->encDataSize),
|
||||
*clearData=NULL;
|
||||
|
||||
sealDataSize = BSG_Pack(BSG_TPM_STORED_DATA, sealedData, flatSealedData );
|
||||
|
||||
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
|
||||
|
||||
paramTextSize = BSG_PackList(paramText, 2,
|
||||
BSG_TPM_COMMAND_CODE, &command,
|
||||
BSG_TPM_STORED_DATA, sealedData);
|
||||
|
||||
TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
|
||||
key_usage_auth, auth) );
|
||||
|
||||
TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
|
||||
data_usage_auth, dataAuth) );
|
||||
// Call TCS
|
||||
TPMTRYRETURN( TCSP_Unseal( hContext,
|
||||
keyHandle,
|
||||
sealDataSize,
|
||||
flatSealedData,
|
||||
auth,
|
||||
dataAuth,
|
||||
&clearDataSize,
|
||||
&clearData) );
|
||||
|
||||
// Verify Auth
|
||||
struct pack_buf_t clearData_pack = {clearDataSize, clearData};
|
||||
|
||||
paramTextSize = BSG_PackList(paramText, 3,
|
||||
BSG_TPM_RESULT, &status,
|
||||
BSG_TPM_COMMAND_CODE, &command,
|
||||
BSG_TPM_SIZE32_DATA, &clearData_pack);
|
||||
|
||||
TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
|
||||
key_usage_auth, auth,
|
||||
hContext) );
|
||||
|
||||
TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
|
||||
data_usage_auth, dataAuth,
|
||||
hContext) );
|
||||
|
||||
// Unpack/return key structure
|
||||
TPMTRYRETURN( buffer_init(outData, clearDataSize, clearData) );
|
||||
|
||||
goto egress;
|
||||
|
||||
abort_egress:
|
||||
egress:
|
||||
|
||||
if (flatSealedData)
|
||||
TCS_FreeMemory( hContext, clearData);
|
||||
|
||||
free(paramText);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
// Function Reaches into unsupported TCS command, beware.
|
||||
TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE hContext,
|
||||
const buffer_t *inbuf,
|
||||
|
||||
@@ -100,4 +100,22 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo,
|
||||
const buffer_t *inData,
|
||||
buffer_t *outData);
|
||||
|
||||
TPM_RESULT VTSP_Seal(const TCS_CONTEXT_HANDLE hContext,
|
||||
const TPM_KEY_HANDLE keyHandle,
|
||||
const TPM_AUTHDATA *sealDataAuth,
|
||||
const TPM_PCR_COMPOSITE *pcrComp,
|
||||
const buffer_t *inData,
|
||||
TPM_STORED_DATA *sealedData,
|
||||
const TPM_SECRET *osapSharedSecret,
|
||||
TCS_AUTH *auth);
|
||||
|
||||
TPM_RESULT VTSP_Unseal(const TCS_CONTEXT_HANDLE hContext,
|
||||
const TPM_KEY_HANDLE keyHandle,
|
||||
const TPM_STORED_DATA *sealedData,
|
||||
const TPM_AUTHDATA *key_usage_auth,
|
||||
const TPM_AUTHDATA *data_usage_auth,
|
||||
buffer_t *outData,
|
||||
TCS_AUTH *auth,
|
||||
TCS_AUTH *dataAuth);
|
||||
|
||||
#endif //_VTSP_H_
|
||||
@@ -636,7 +636,7 @@ TPM_RESULT TCSP_Seal( TCS_CONTEXT_HANDLE hContext, // in
|
||||
TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH;
|
||||
|
||||
// check input params
|
||||
if (inData == NULL || pubAuth == NULL || SealedDataSize == NULL || *SealedData == NULL)
|
||||
if (inData == NULL || pubAuth == NULL || SealedDataSize == NULL || SealedData == NULL)
|
||||
return TPM_BAD_PARAMETER;
|
||||
|
||||
// Convert Byte Input parameter in the input byte stream InBuf
|
||||
|
||||
+19
-1
@@ -10,10 +10,28 @@
|
||||
#include <err.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <xenguest.h>
|
||||
|
||||
|
||||
/**
|
||||
* Issue a suspend request through stdout, and receive the acknowledgement
|
||||
* from stdin. This is handled by XendCheckpoint in the Python layer.
|
||||
*/
|
||||
static int suspend(int domid)
|
||||
{
|
||||
char ans[30];
|
||||
|
||||
printf("suspend\n");
|
||||
fflush(stdout);
|
||||
|
||||
return (fgets(ans, sizeof(ans), stdin) != NULL &&
|
||||
!strncmp(ans, "done\n", 5));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
@@ -29,5 +47,5 @@ main(int argc, char **argv)
|
||||
max_f = atoi(argv[5]);
|
||||
flags = atoi(argv[6]);
|
||||
|
||||
return xc_linux_save(xc_fd, io_fd, domid, maxit, max_f, flags);
|
||||
return xc_linux_save(xc_fd, io_fd, domid, maxit, max_f, flags, &suspend);
|
||||
}
|
||||
@@ -13,12 +13,9 @@
|
||||
INSTALL = install
|
||||
INSTALL_PROG = $(INSTALL) -m0755
|
||||
INSTALL_DIR = $(INSTALL) -d -m0755
|
||||
INSTALL_DATA = $(INSTALL) -m064
|
||||
INSTALL_DATA = $(INSTALL) -m0644
|
||||
|
||||
prefix=/usr/local
|
||||
mandir=$(prefix)/share/man
|
||||
man1dir=$(mandir)/man1
|
||||
sbindir=$(prefix)/sbin
|
||||
sbindir=/usr/sbin
|
||||
|
||||
XEN_ROOT=../..
|
||||
include $(XEN_ROOT)/tools/Rules.mk
|
||||
|
||||
@@ -705,7 +705,7 @@ static char *xenstat_get_domain_name(xenstat_handle *handle, unsigned int domain
|
||||
|
||||
snprintf(path, sizeof(path),"/local/domain/%i/name", domain_id);
|
||||
|
||||
name = xs_read(handle->xshandle, NULL, path, NULL);
|
||||
name = xs_read(handle->xshandle, XBT_NULL, path, NULL);
|
||||
if (name == NULL)
|
||||
name = strdup(" ");
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ usage(const char *progname)
|
||||
|
||||
#if defined(CLIENT_rm)
|
||||
static int
|
||||
do_rm(char *path, struct xs_handle *xsh, struct xs_transaction_handle *xth)
|
||||
do_rm(char *path, struct xs_handle *xsh, xs_transaction_t xth)
|
||||
{
|
||||
if (xs_rm(xsh, xth, path)) {
|
||||
return 0;
|
||||
@@ -81,7 +81,7 @@ do_rm(char *path, struct xs_handle *xsh, struct xs_transaction_handle *xth)
|
||||
|
||||
static int
|
||||
perform(int optind, int argc, char **argv, struct xs_handle *xsh,
|
||||
struct xs_transaction_handle *xth, int prefix, int tidy)
|
||||
xs_transaction_t xth, int prefix, int tidy)
|
||||
{
|
||||
while (optind < argc) {
|
||||
#if defined(CLIENT_read)
|
||||
@@ -179,7 +179,7 @@ int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct xs_handle *xsh;
|
||||
struct xs_transaction_handle *xth;
|
||||
xs_transaction_t xth;
|
||||
int ret = 0, socket = 0;
|
||||
int prefix = 0;
|
||||
int tidy = 0;
|
||||
@@ -243,7 +243,7 @@ main(int argc, char **argv)
|
||||
|
||||
again:
|
||||
xth = xs_transaction_start(xsh);
|
||||
if (xth == NULL)
|
||||
if (xth == XBT_NULL)
|
||||
errx(1, "couldn't start transaction");
|
||||
|
||||
ret = perform(optind, argc, argv, xsh, xth, prefix, tidy);
|
||||
|
||||
+23
-23
@@ -292,7 +292,7 @@ static void *read_reply(
|
||||
}
|
||||
|
||||
/* Send message to xs, get malloc'ed reply. NULL and set errno on error. */
|
||||
static void *xs_talkv(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
static void *xs_talkv(struct xs_handle *h, xs_transaction_t t,
|
||||
enum xsd_sockmsg_type type,
|
||||
const struct iovec *iovec,
|
||||
unsigned int num_vecs,
|
||||
@@ -304,7 +304,7 @@ static void *xs_talkv(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
unsigned int i;
|
||||
struct sigaction ignorepipe, oldact;
|
||||
|
||||
msg.tx_id = (uint32_t)(unsigned long)t;
|
||||
msg.tx_id = t;
|
||||
msg.req_id = 0;
|
||||
msg.type = type;
|
||||
msg.len = 0;
|
||||
@@ -368,7 +368,7 @@ static void free_no_errno(void *p)
|
||||
}
|
||||
|
||||
/* Simplified version of xs_talkv: single message. */
|
||||
static void *xs_single(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
static void *xs_single(struct xs_handle *h, xs_transaction_t t,
|
||||
enum xsd_sockmsg_type type,
|
||||
const char *string,
|
||||
unsigned int *len)
|
||||
@@ -388,7 +388,7 @@ static bool xs_bool(char *reply)
|
||||
return true;
|
||||
}
|
||||
|
||||
char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
char **xs_directory(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path, unsigned int *num)
|
||||
{
|
||||
char *strings, *p, **ret;
|
||||
@@ -420,7 +420,7 @@ char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
* Returns a malloced value: call free() on it after use.
|
||||
* len indicates length in bytes, not including the nul.
|
||||
*/
|
||||
void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
void *xs_read(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path, unsigned int *len)
|
||||
{
|
||||
return xs_single(h, t, XS_READ, path, len);
|
||||
@@ -429,7 +429,7 @@ void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
/* Write the value of a single file.
|
||||
* Returns false on failure.
|
||||
*/
|
||||
bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_write(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path, const void *data, unsigned int len)
|
||||
{
|
||||
struct iovec iovec[2];
|
||||
@@ -446,7 +446,7 @@ bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
/* Create a new directory.
|
||||
* Returns false on failure, or success if it already exists.
|
||||
*/
|
||||
bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path)
|
||||
{
|
||||
return xs_bool(xs_single(h, t, XS_MKDIR, path, NULL));
|
||||
@@ -455,7 +455,7 @@ bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
/* Destroy a file or directory (directories must be empty).
|
||||
* Returns false on failure, or success if it doesn't exist.
|
||||
*/
|
||||
bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_rm(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path)
|
||||
{
|
||||
return xs_bool(xs_single(h, t, XS_RM, path, NULL));
|
||||
@@ -465,7 +465,7 @@ bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
* Returns malloced array, or NULL: call free() after use.
|
||||
*/
|
||||
struct xs_permissions *xs_get_permissions(struct xs_handle *h,
|
||||
struct xs_transaction_handle *t,
|
||||
xs_transaction_t t,
|
||||
const char *path, unsigned int *num)
|
||||
{
|
||||
char *strings;
|
||||
@@ -499,7 +499,7 @@ struct xs_permissions *xs_get_permissions(struct xs_handle *h,
|
||||
* Returns false on failure.
|
||||
*/
|
||||
bool xs_set_permissions(struct xs_handle *h,
|
||||
struct xs_transaction_handle *t,
|
||||
xs_transaction_t t,
|
||||
const char *path,
|
||||
struct xs_permissions *perms,
|
||||
unsigned int num_perms)
|
||||
@@ -560,7 +560,7 @@ bool xs_watch(struct xs_handle *h, const char *path, const char *token)
|
||||
iov[1].iov_base = (void *)token;
|
||||
iov[1].iov_len = strlen(token) + 1;
|
||||
|
||||
return xs_bool(xs_talkv(h, NULL, XS_WATCH, iov,
|
||||
return xs_bool(xs_talkv(h, XBT_NULL, XS_WATCH, iov,
|
||||
ARRAY_SIZE(iov), NULL));
|
||||
}
|
||||
|
||||
@@ -627,28 +627,28 @@ bool xs_unwatch(struct xs_handle *h, const char *path, const char *token)
|
||||
iov[1].iov_base = (char *)token;
|
||||
iov[1].iov_len = strlen(token) + 1;
|
||||
|
||||
return xs_bool(xs_talkv(h, NULL, XS_UNWATCH, iov,
|
||||
return xs_bool(xs_talkv(h, XBT_NULL, XS_UNWATCH, iov,
|
||||
ARRAY_SIZE(iov), NULL));
|
||||
}
|
||||
|
||||
/* Start a transaction: changes by others will not be seen during this
|
||||
* transaction, and changes will not be visible to others until end.
|
||||
* You can only have one transaction at any time.
|
||||
* Returns NULL on failure.
|
||||
* Returns XBT_NULL on failure.
|
||||
*/
|
||||
struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h)
|
||||
xs_transaction_t xs_transaction_start(struct xs_handle *h)
|
||||
{
|
||||
char *id_str;
|
||||
unsigned long id;
|
||||
xs_transaction_t id;
|
||||
|
||||
id_str = xs_single(h, NULL, XS_TRANSACTION_START, "", NULL);
|
||||
id_str = xs_single(h, XBT_NULL, XS_TRANSACTION_START, "", NULL);
|
||||
if (id_str == NULL)
|
||||
return NULL;
|
||||
return XBT_NULL;
|
||||
|
||||
id = strtoul(id_str, NULL, 0);
|
||||
free(id_str);
|
||||
|
||||
return (struct xs_transaction_handle *)id;
|
||||
return id;
|
||||
}
|
||||
|
||||
/* End a transaction.
|
||||
@@ -656,7 +656,7 @@ struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h)
|
||||
* Returns false on failure, which indicates an error: transactions will
|
||||
* not fail spuriously.
|
||||
*/
|
||||
bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
|
||||
bool abort)
|
||||
{
|
||||
char abortstr[2];
|
||||
@@ -693,7 +693,7 @@ bool xs_introduce_domain(struct xs_handle *h,
|
||||
iov[2].iov_base = eventchn_str;
|
||||
iov[2].iov_len = strlen(eventchn_str) + 1;
|
||||
|
||||
return xs_bool(xs_talkv(h, NULL, XS_INTRODUCE, iov,
|
||||
return xs_bool(xs_talkv(h, XBT_NULL, XS_INTRODUCE, iov,
|
||||
ARRAY_SIZE(iov), NULL));
|
||||
}
|
||||
|
||||
@@ -705,7 +705,7 @@ static void * single_with_domid(struct xs_handle *h,
|
||||
|
||||
sprintf(domid_str, "%u", domid);
|
||||
|
||||
return xs_single(h, NULL, type, domid_str, NULL);
|
||||
return xs_single(h, XBT_NULL, type, domid_str, NULL);
|
||||
}
|
||||
|
||||
bool xs_release_domain(struct xs_handle *h, unsigned int domid)
|
||||
@@ -719,7 +719,7 @@ char *xs_get_domain_path(struct xs_handle *h, unsigned int domid)
|
||||
|
||||
sprintf(domid_str, "%u", domid);
|
||||
|
||||
return xs_single(h, NULL, XS_GET_DOMAIN_PATH, domid_str, NULL);
|
||||
return xs_single(h, XBT_NULL, XS_GET_DOMAIN_PATH, domid_str, NULL);
|
||||
}
|
||||
|
||||
bool xs_is_domain_introduced(struct xs_handle *h, unsigned int domid)
|
||||
@@ -739,7 +739,7 @@ char *xs_debug_command(struct xs_handle *h, const char *cmd,
|
||||
iov[1].iov_base = data;
|
||||
iov[1].iov_len = len;
|
||||
|
||||
return xs_talkv(h, NULL, XS_DEBUG, iov,
|
||||
return xs_talkv(h, XBT_NULL, XS_DEBUG, iov,
|
||||
ARRAY_SIZE(iov), NULL);
|
||||
}
|
||||
|
||||
|
||||
+13
-11
@@ -22,8 +22,10 @@
|
||||
|
||||
#include <xs_lib.h>
|
||||
|
||||
#define XBT_NULL 0
|
||||
|
||||
struct xs_handle;
|
||||
struct xs_transaction_handle;
|
||||
typedef uint32_t xs_transaction_t;
|
||||
|
||||
/* On failure, these routines set errno. */
|
||||
|
||||
@@ -45,45 +47,45 @@ void xs_daemon_close(struct xs_handle *);
|
||||
* Returns a malloced array: call free() on it after use.
|
||||
* Num indicates size.
|
||||
*/
|
||||
char **xs_directory(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
char **xs_directory(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path, unsigned int *num);
|
||||
|
||||
/* Get the value of a single file, nul terminated.
|
||||
* Returns a malloced value: call free() on it after use.
|
||||
* len indicates length in bytes, not including terminator.
|
||||
*/
|
||||
void *xs_read(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
void *xs_read(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path, unsigned int *len);
|
||||
|
||||
/* Write the value of a single file.
|
||||
* Returns false on failure.
|
||||
*/
|
||||
bool xs_write(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_write(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path, const void *data, unsigned int len);
|
||||
|
||||
/* Create a new directory.
|
||||
* Returns false on failure, or success if it already exists.
|
||||
*/
|
||||
bool xs_mkdir(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_mkdir(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path);
|
||||
|
||||
/* Destroy a file or directory (and children).
|
||||
* Returns false on failure, or success if it doesn't exist.
|
||||
* Returns false on failure, or if it doesn't exist.
|
||||
*/
|
||||
bool xs_rm(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_rm(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path);
|
||||
|
||||
/* Get permissions of node (first element is owner, first perms is "other").
|
||||
* Returns malloced array, or NULL: call free() after use.
|
||||
*/
|
||||
struct xs_permissions *xs_get_permissions(struct xs_handle *h,
|
||||
struct xs_transaction_handle *t,
|
||||
xs_transaction_t t,
|
||||
const char *path, unsigned int *num);
|
||||
|
||||
/* Set permissions of node (must be owner).
|
||||
* Returns false on failure.
|
||||
*/
|
||||
bool xs_set_permissions(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_set_permissions(struct xs_handle *h, xs_transaction_t t,
|
||||
const char *path, struct xs_permissions *perms,
|
||||
unsigned int num_perms);
|
||||
|
||||
@@ -113,14 +115,14 @@ bool xs_unwatch(struct xs_handle *h, const char *path, const char *token);
|
||||
* You can only have one transaction at any time.
|
||||
* Returns NULL on failure.
|
||||
*/
|
||||
struct xs_transaction_handle *xs_transaction_start(struct xs_handle *h);
|
||||
xs_transaction_t xs_transaction_start(struct xs_handle *h);
|
||||
|
||||
/* End a transaction.
|
||||
* If abandon is true, transaction is discarded instead of committed.
|
||||
* Returns false on failure: if errno == EAGAIN, you have to restart
|
||||
* transaction.
|
||||
*/
|
||||
bool xs_transaction_end(struct xs_handle *h, struct xs_transaction_handle *t,
|
||||
bool xs_transaction_end(struct xs_handle *h, xs_transaction_t t,
|
||||
bool abort);
|
||||
|
||||
/* Introduce a new domain.
|
||||
|
||||
@@ -37,12 +37,13 @@
|
||||
#include <sys/time.h>
|
||||
#include "utils.h"
|
||||
#include "xs_lib.h"
|
||||
#include "xs.h"
|
||||
#include "list.h"
|
||||
|
||||
#define XSTEST
|
||||
|
||||
static struct xs_handle *handles[10] = { NULL };
|
||||
static struct xs_transaction_handle *txh[10] = { NULL };
|
||||
static xs_transaction_t txh[10] = { XBT_NULL };
|
||||
|
||||
static unsigned int timeout_ms = 500;
|
||||
static bool timeout_suppressed = true;
|
||||
@@ -492,7 +493,7 @@ static void do_unwatch(unsigned int handle, const char *node, const char *token)
|
||||
static void do_start(unsigned int handle)
|
||||
{
|
||||
txh[handle] = xs_transaction_start(handles[handle]);
|
||||
if (txh[handle] == NULL)
|
||||
if (txh[handle] == XBT_NULL)
|
||||
failed(handle);
|
||||
}
|
||||
|
||||
@@ -500,7 +501,7 @@ static void do_end(unsigned int handle, bool abort)
|
||||
{
|
||||
if (!xs_transaction_end(handles[handle], txh[handle], abort))
|
||||
failed(handle);
|
||||
txh[handle] = NULL;
|
||||
txh[handle] = XBT_NULL;
|
||||
}
|
||||
|
||||
static void do_introduce(unsigned int handle,
|
||||
@@ -534,7 +535,7 @@ static void do_introduce(unsigned int handle,
|
||||
*(uint16_t *)((void *)interface + 36) = atoi(eventchn);
|
||||
|
||||
if (!xs_introduce_domain(handles[handle], atoi(domid),
|
||||
atol(mfn), atoi(eventchn), path)) {
|
||||
atol(mfn), atoi(eventchn))) {
|
||||
failed(handle);
|
||||
munmap(interface, getpagesize());
|
||||
return;
|
||||
@@ -718,7 +719,7 @@ static void do_command(unsigned int default_handle, char *line)
|
||||
else if (streq(command, "close")) {
|
||||
xs_daemon_close(handles[handle]);
|
||||
handles[handle] = NULL;
|
||||
txh[handle] = NULL;
|
||||
txh[handle] = XBT_NULL;
|
||||
} else if (streq(command, "start"))
|
||||
do_start(handle);
|
||||
else if (streq(command, "commit"))
|
||||
|
||||
@@ -11,7 +11,7 @@ void print_dir(struct xs_handle *h, char *path, int cur_depth)
|
||||
int i;
|
||||
unsigned int num, len;
|
||||
|
||||
e = xs_directory(h, NULL, path, &num);
|
||||
e = xs_directory(h, XBT_NULL, path, &num);
|
||||
if (e == NULL)
|
||||
err(1, "xs_directory (%s)", path);
|
||||
|
||||
@@ -22,7 +22,7 @@ void print_dir(struct xs_handle *h, char *path, int cur_depth)
|
||||
sprintf(newpath, "%s%s%s", path,
|
||||
path[strlen(path)-1] == '/' ? "" : "/",
|
||||
e[i]);
|
||||
val = xs_read(h, NULL, newpath, &len);
|
||||
val = xs_read(h, XBT_NULL, newpath, &len);
|
||||
if (val == NULL)
|
||||
printf(":\n");
|
||||
else if ((unsigned)len > (151 - strlen(e[i])))
|
||||
|
||||
@@ -380,10 +380,10 @@ void dump_ctx(int vcpu)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
ret = xc_domain_get_vcpu_context(xc_handle, domid, vcpu, &ctx);
|
||||
ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx);
|
||||
if (ret < 0) {
|
||||
xc_domain_unpause(xc_handle, domid);
|
||||
perror("xc_domain_get_vcpu_context");
|
||||
perror("xc_vcpu_getcontext");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 204 files, more files were not shown because too many files have changed in this diff.
Show more