# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID d603aed5ad6dfc3c318ef2b8bac2f7a427163cb9
# Parent 6fdbf173142d6b4da68d2019f594f9a81fa70d28
# Parent 275a8f9a07109375cd55a2bf90f111ffa09db06d
merge with xen-unstable.hg
---
xen/arch/x86/hvm/vmx/io.c
| 202 -
.hgignore
| 2
Config.mk
| 2
buildconfigs/linux-defconfig_xen0_x86_32
| 1
buildconfigs/linux-defconfig_xen0_x86_64
| 1
buildconfigs/linux-defconfig_xen_x86_32
| 2
buildconfigs/linux-defconfig_xen_x86_64
| 1
docs/xen-api/presentation.tex
| 5
docs/xen-api/todo.tex
| 2
docs/xen-api/wire-protocol.tex
| 66
docs/xen-api/xenapi-datamodel-graph.dot
| 3
docs/xen-api/xenapi-datamodel.tex
| 320 ++
extras/mini-os/events.c
| 27
extras/mini-os/include/events.h
| 1
linux-2.6-xen-sparse/arch/i386/Kconfig
| 2
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
| 27
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
| 10
linux-2.6-xen-sparse/arch/x86_64/Kconfig
| 2
linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c
| 6
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
| 23
linux-2.6-xen-sparse/drivers/xen/Kconfig
| 23
linux-2.6-xen-sparse/drivers/xen/Makefile
| 2
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
| 3
linux-2.6-xen-sparse/drivers/xen/char/mem.c
| 4
linux-2.6-xen-sparse/drivers/xen/console/console.c
| 28
linux-2.6-xen-sparse/drivers/xen/core/Makefile
| 1
linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c
| 184 +
linux-2.6-xen-sparse/drivers/xen/fbfront/Makefile
| 2
linux-2.6-xen-sparse/drivers/xen/fbfront/xenfb.c
| 682 +++++
linux-2.6-xen-sparse/drivers/xen/fbfront/xenkbd.c
| 300 ++
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
| 8
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/agp.h
| 35
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
| 7
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h
| 2
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/xenoprof.h
| 1
linux-2.6-xen-sparse/include/xen/xencons.h
| 2
linux-2.6-xen-sparse/mm/memory.c
| 1
patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
| 50
patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
| 75
patches/linux-2.6.16.33/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch
| 197 +
patches/linux-2.6.16.33/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch
| 156 +
patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch
| 44
patches/linux-2.6.16.33/kexec-generic.patch
| 167 +
patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch
| 114
patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch
| 114
patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-xen-i386.patch
| 49
patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-xen-x86_64.patch
| 88
patches/linux-2.6.16.33/series
| 10
tools/Makefile
| 1
tools/blktap/drivers/block-aio.c
| 8
tools/blktap/drivers/block-qcow.c
| 9
tools/blktap/drivers/tapdisk.c
| 3
tools/check/Makefile
| 6
tools/check/check_libvncserver
| 27
tools/check/check_sdl
| 27
tools/firmware/vmxassist/setup.c
| 22
tools/firmware/vmxassist/trap.S
| 16
tools/firmware/vmxassist/util.c
| 6
tools/firmware/vmxassist/vm86.c
| 21
tools/firmware/vmxassist/vm86.h
| 2
tools/ioemu/hw/pci.c
| 24
tools/ioemu/hw/usb-uhci.c
| 2
tools/ioemu/vl.h
| 7
tools/ioemu/vnc.c
| 20
tools/libxc/xc_linux.c
| 9
tools/libxc/xc_solaris.c
| 9
tools/libxc/xenctrl.h
| 16
tools/libxen/Makefile
| 4
tools/libxen/README
| 5
tools/libxen/include/xen_console.h
| 207 +
tools/libxen/include/xen_console_decl.h
| 30
tools/libxen/include/xen_console_protocol.h
| 82
tools/libxen/include/xen_console_protocol_internal.h
| 37
tools/libxen/include/xen_vm.h
| 9
tools/libxen/src/xen_console.c
| 207 +
tools/libxen/src/xen_console_protocol.c
| 82
tools/libxen/src/xen_vm.c
| 22
tools/python/scripts/xapi.domcfg.py
| 2
tools/python/scripts/xapi.py
| 46
tools/python/xen/lowlevel/xc/xc.c
| 4
tools/python/xen/util/bugtool.py
| 5
tools/python/xen/util/mkdir.py
| 44
tools/python/xen/util/xmlrpclib2.py
| 13
tools/python/xen/web/unix.py
| 12
tools/python/xen/xend/XendAPI.py
| 620 ++--
tools/python/xen/xend/XendCheckpoint.py
| 4
tools/python/xen/xend/XendConfig.py
| 1356 +++++-----
tools/python/xen/xend/XendConstants.py
| 2
tools/python/xen/xend/XendDevices.py
| 4
tools/python/xen/xend/XendDomain.py
| 54
tools/python/xen/xend/XendDomainInfo.py
| 415 +--
tools/python/xen/xend/XendLogging.py
| 5
tools/python/xen/xend/XendStorageRepository.py
| 9
tools/python/xen/xend/image.py
| 218 -
tools/python/xen/xend/server/DevController.py
| 7
tools/python/xen/xend/server/SrvDaemon.py
| 4
tools/python/xen/xend/server/SrvServer.py
| 2
tools/python/xen/xend/server/blkif.py
| 21
tools/python/xen/xend/server/iopif.py
| 4
tools/python/xen/xend/server/irqif.py
| 2
tools/python/xen/xend/server/netif.py
| 24
tools/python/xen/xend/server/pciif.py
| 69
tools/python/xen/xend/server/pciquirk.py
| 43
tools/python/xen/xend/server/tests/test_controllers.py
| 6
tools/python/xen/xend/server/tpmif.py
| 12
tools/python/xen/xend/server/vfbif.py
| 74
tools/python/xen/xm/create.py
| 34
tools/python/xen/xm/main.py
| 4
tools/tests/test_x86_emulator.c
| 108
tools/xenfb/Makefile
| 35
tools/xenfb/sdlfb.c
| 342 ++
tools/xenfb/vncfb.c
| 401 ++
tools/xenfb/xenfb.c
| 711 +++++
tools/xenfb/xenfb.h
| 35
tools/xm-test/grouptest/xapi
| 1
tools/xm-test/lib/XmTestLib/XenManagedDomain.py
| 176 +
tools/xm-test/lib/XmTestLib/xapi.py
| 66
tools/xm-test/tests/vtpm/09_vtpm-xapi.py
| 76
tools/xm-test/tests/vtpm/Makefile.am
| 3
xen/arch/ia64/xen/Makefile
| 2
xen/arch/ia64/xen/crash.c
| 19
xen/arch/ia64/xen/machine_kexec.c
| 34
xen/arch/powerpc/Makefile
| 2
xen/arch/powerpc/crash.c
| 19
xen/arch/powerpc/machine_kexec.c
| 34
xen/arch/x86/Makefile
| 2
xen/arch/x86/crash.c
| 128
xen/arch/x86/hvm/platform.c
| 18
xen/arch/x86/hvm/svm/emulate.c
| 15
xen/arch/x86/hvm/svm/svm.c
| 232 +
xen/arch/x86/hvm/svm/vmcb.c
| 22
xen/arch/x86/hvm/vlapic.c
| 11
xen/arch/x86/hvm/vmx/Makefile
| 2
xen/arch/x86/hvm/vmx/intr.c
| 196 +
xen/arch/x86/hvm/vmx/vmx.c
| 318 +-
xen/arch/x86/machine_kexec.c
| 105
xen/arch/x86/mm.c
| 98
xen/arch/x86/mm/shadow/common.c
| 313 +-
xen/arch/x86/mm/shadow/multi.c
| 83
xen/arch/x86/mm/shadow/private.h
| 19
xen/arch/x86/oprofile/op_model_athlon.c
| 9
xen/arch/x86/setup.c
| 74
xen/arch/x86/traps.c
| 2
xen/arch/x86/x86_32/entry.S
| 2
xen/arch/x86/x86_64/entry.S
| 2
xen/arch/x86/x86_emulate.c
| 558 +---
xen/common/Makefile
| 1
xen/common/domain.c
| 4
xen/common/kexec.c
| 350 ++
xen/common/page_alloc.c
| 37
xen/drivers/char/console.c
| 3
xen/include/asm-ia64/elf.h
| 30
xen/include/asm-ia64/kexec.h
| 25
xen/include/asm-ia64/softirq.h
| 6
xen/include/asm-powerpc/elf.h
| 30
xen/include/asm-powerpc/kexec.h
| 25
xen/include/asm-powerpc/softirq.h
| 6
xen/include/asm-x86/domain.h
| 2
xen/include/asm-x86/elf.h
| 24
xen/include/asm-x86/fixmap.h
| 4
xen/include/asm-x86/hvm/hvm.h
| 71
xen/include/asm-x86/hvm/svm/vmcb.h
| 50
xen/include/asm-x86/hvm/vlapic.h
| 1
xen/include/asm-x86/hvm/vmx/vmx.h
| 7
xen/include/asm-x86/hypercall.h
| 5
xen/include/asm-x86/kexec.h
| 20
xen/include/asm-x86/shadow.h
| 8
xen/include/asm-x86/softirq.h
| 6
xen/include/asm-x86/x86_32/elf.h
| 72
xen/include/asm-x86/x86_32/kexec.h
| 40
xen/include/asm-x86/x86_32/page.h
| 2
xen/include/asm-x86/x86_64/elf.h
| 92
xen/include/asm-x86/x86_64/kexec.h
| 39
xen/include/asm-x86/x86_64/page.h
| 2
xen/include/asm-x86/x86_emulate.h
| 139 -
xen/include/public/elfnote.h
| 19
xen/include/public/io/fbif.h
| 116
xen/include/public/io/kbdif.h
| 108
xen/include/public/kexec.h
| 138 +
xen/include/xen/elf.h
| 20
xen/include/xen/elfcore.h
| 140 +
xen/include/xen/hypercall.h
| 6
xen/include/xen/kexec.h
| 45
xen/include/xen/mm.h
| 1
xen/include/xen/softirq.h
| 13
185 files changed, 10427 insertions(+), 2646 deletions(-)
diff -r 6fdbf173142d -r d603aed5ad6d .hgignore
--- a/.hgignore Sat Dec 02 15:19:50 2006 -0700
+++ b/.hgignore Mon Dec 04 08:24:41 2006 -0700
@@ -158,6 +158,8 @@
^tools/xcutils/xc_restore$
^tools/xcutils/xc_save$
^tools/xcutils/readnotes$
+^tools/xenfb/sdlfb$
+^tools/xenfb/vncfb$
^tools/xenmon/xentrace_setmask$
^tools/xenmon/xenbaked$
^tools/xenstat/xentop/xentop$
diff -r 6fdbf173142d -r d603aed5ad6d Config.mk
--- a/Config.mk Sat Dec 02 15:19:50 2006 -0700
+++ b/Config.mk Mon Dec 04 08:24:41 2006 -0700
@@ -69,8 +69,8 @@ ACM_DEFAULT_SECURITY_POLICY ?= ACM_NULL_
# Optional components
XENSTAT_XENTOP ?= y
-
VTPM_TOOLS ?= n
LIBXENAPI_BINDINGS ?= n
+XENFB_TOOLS ?= n
-include $(XEN_ROOT)/.config
diff -r 6fdbf173142d -r d603aed5ad6d buildconfigs/linux-defconfig_xen0_x86_32
--- a/buildconfigs/linux-defconfig_xen0_x86_32 Sat Dec 02 15:19:50 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen0_x86_32 Mon Dec 04 08:24:41 2006 -0700
@@ -179,6 +179,7 @@ CONFIG_HZ_100=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
+CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x100000
diff -r 6fdbf173142d -r d603aed5ad6d buildconfigs/linux-defconfig_xen0_x86_64
--- a/buildconfigs/linux-defconfig_xen0_x86_64 Sat Dec 02 15:19:50 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen0_x86_64 Mon Dec 04 08:24:41 2006 -0700
@@ -126,6 +126,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
# CONFIG_SPARSEMEM_STATIC is not set
CONFIG_SPLIT_PTLOCK_CPUS=4096
CONFIG_SWIOTLB=y
+CONFIG_KEXEC=y
# CONFIG_CRASH_DUMP is not set
CONFIG_PHYSICAL_START=0x100000
CONFIG_SECCOMP=y
diff -r 6fdbf173142d -r d603aed5ad6d buildconfigs/linux-defconfig_xen_x86_32
--- a/buildconfigs/linux-defconfig_xen_x86_32 Sat Dec 02 15:19:50 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen_x86_32 Mon Dec 04 08:24:41 2006 -0700
@@ -184,6 +184,7 @@ CONFIG_REGPARM=y
CONFIG_REGPARM=y
CONFIG_SECCOMP=y
CONFIG_HZ_100=y
+CONFIG_KEXEC=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
@@ -2776,6 +2777,7 @@ CONFIG_NTFS_FS=m
#
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
+# CONFIG_PROC_VMCORE is not set
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_HUGETLB_PAGE is not set
diff -r 6fdbf173142d -r d603aed5ad6d buildconfigs/linux-defconfig_xen_x86_64
--- a/buildconfigs/linux-defconfig_xen_x86_64 Sat Dec 02 15:19:50 2006 -0700
+++ b/buildconfigs/linux-defconfig_xen_x86_64 Mon Dec 04 08:24:41 2006 -0700
@@ -139,6 +139,7 @@ CONFIG_PHYSICAL_START=0x100000
CONFIG_PHYSICAL_START=0x100000
CONFIG_SECCOMP=y
CONFIG_HZ_100=y
+CONFIG_KEXEC=y
# CONFIG_HZ_250 is not set
# CONFIG_HZ_1000 is not set
CONFIG_HZ=100
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/presentation.tex
--- a/docs/xen-api/presentation.tex Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/presentation.tex Mon Dec 04 08:24:41 2006 -0700
@@ -131,9 +131,6 @@ of that class that has the specified {\t
``{\tt get\_by\_name\_label(name)}'' RPC that returns a set of objects of that
class that have the specified {\tt label}.
-\item Each class has a ``{\tt to\_XML()}'' RPC that serialises the
-state of all fields as an XML string.
-
\item Each class has a ``{\tt destroy(Ref x)}'' RPC that explicitly deletes
the persistent object specified by {\tt x} from the system. This is a
non-cascading delete -- if the object being removed is referenced by another
@@ -144,6 +141,6 @@ object then the {\tt destroy} call will
\subsection{Additional RPCs}
As well as the RPCs enumerated above, some classes have additional RPCs
-associated with them. For example, the {\tt VM} class have RPCs for cloning,
+associated with them. For example, the {\tt VM} class has RPCs for cloning,
suspending, starting etc. Such additional RPCs are described explicitly
in the API reference.
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/todo.tex
--- a/docs/xen-api/todo.tex Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/todo.tex Mon Dec 04 08:24:41 2006 -0700
@@ -34,6 +34,8 @@ code, potential error description, but o
\item Clarify behaviour of progress field on asyncrhonous request polling when
that request fails.
+
+\item Clarify which calls have asynchronous counterparts by marking them as
such in the reference. (Individual getters and setters are too small and quick
to justify having async versions)
\end{itemize}
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/wire-protocol.tex
--- a/docs/xen-api/wire-protocol.tex Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/wire-protocol.tex Mon Dec 04 08:24:41 2006 -0700
@@ -21,9 +21,9 @@ In our API Reference we specify the sign
In our API Reference we specify the signatures of API functions in the
following
style:
\begin{verbatim}
- (ref_vm Set) Host.ListAllVMs()
-\end{verbatim}
-This specifies that the function with name {\tt Host.ListAllVMs} takes
+ (ref_vm Set) VM.get_all()
+\end{verbatim}
+This specifies that the function with name {\tt VM.get\_all} takes
no parameters and returns a Set of {\tt ref\_vm}s.
These types are mapped onto XML-RPC types in a straight-forward manner:
\begin{itemize}
@@ -105,8 +105,8 @@ the struct contains a second element nam
the struct contains a second element named {\tt ErrorDescription}:
\begin{itemize}
\item The element of the struct named {\tt ErrorDescription} contains
-an array of string values. The first element of the array represents an error
code;
-the remainder of the array represents error parameters relating to that code.
+an array of string values. The first element of the array is an XML-RPC 32-bit
{\tt i4} and represents an error code;
+the remainder of the array are strings representing error parameters relating
to that code.
\end{itemize}
For example, an XML-RPC return value from the {\tt Host.ListAllVMs} function
above
@@ -161,19 +161,19 @@ A session can be terminated with the {\t
\subsection{Synchronous and Asynchronous invocation}
-Each method call (apart from those on ``Session'' and ``Task'' objects)
+Each method call (apart from methods on ``Session'' and ``Task'' objects
+and ``getters'' and ``setters'' derived from fields)
can be made either synchronously or asynchronously.
A synchronous RPC call blocks until the
return value is received; the return value of a synchronous RPC call is
exactly as specified in Section~\ref{synchronous-result}.
-Each of the methods specified in the API Reference is synchronous.
-However, although not listed explicitly in this document, each
-method call has an asynchronous analogue in the {\tt Async}
-namespace. For example, synchronous call {\tt VM.Install(...)}
+Only synchronous API calls are listed explicitly in this document.
+All asynchronous versions are in the special {\tt Async} namespace.
+For example, synchronous call {\tt VM.clone(...)}
(described in Chapter~\ref{api-reference})
has an asynchronous counterpart, {\tt
-Async.VM.Install(...)}, that is non-blocking.
+Async.VM.clone(...)}, that is non-blocking.
Instead of returning its result directly, an asynchronous RPC call
returns a {\tt task-id}; this identifier is subsequently used
@@ -186,39 +186,14 @@ The {\tt task-id} is provided in the {\t
The {\tt task-id} is provided in the {\tt Value} field if {\tt Status} is set
to
{\tt Success}.
-Two special RPC calls are provided to poll the status of
-asynchronous calls:
-\begin{verbatim}
- Array<task_id> Async.Task.GetAllTasks (session_id s)
- task_status Async.Task.GetStatus (session_id s, task_id t)
-\end{verbatim}
-
-{\tt Async.Task.GetAllTasks} returns a set of the currently
-executing asynchronous tasks belong to the current user\footnote{
-%
-The current user is determined by the username that was provided
-to {\tt Session.Login}.
-%
-}.
-
-{\tt Async.Task.GetStatus} returns a {\tt task\_status} result.
-This is an XML-RPC struct with three elements:
-\begin{itemize}
- \item The first element is named {\tt Progress} and contains
-an {\tt Integer} between 0 and 100 representing the estimated percentage of
-the task currently completed.
- \item The second element is named {\tt ETA} and contains a {\tt DateTime}
-representing the estimated time the task will be complete.
- \item The third element is named {\tt Result}. If {\tt Progress}
-is not 100 then {\tt Result} contains the empty string. If {\tt Progress}
-{\em is\/} set to 100, then {\tt Result} contains the function's return
-result (as specified in Section~\ref{synchronous-result})\footnote{
-%
-Recall that this itself is a struct potentially containing status, errorcode,
-value fields etc.
-%
-}.
-\end{itemize}
+The RPC call
+\begin{verbatim}
+ (ref_task Set) Task.get_all(session_id s)
+\end{verbatim}
+returns a set of all task IDs known to the system. The status (including any
+returned result and error codes) of these tasks
+can then be queried by accessing the fields of the Task object in the usual
way.
+Note that, in order to get a consistent snapshot of a task's state, it is
advisable to call the ``get\_record'' function.
\section{Example interactive session}
@@ -267,7 +242,8 @@ Next, the user may acquire a list of all
\begin{verbatim}
>>> all_vms = xen.VM.do_list(session)['Value']
>>> all_vms
-['b7b92d9e-d442-4710-92a5-ab039fd7d89b',
'23e1e837-abbf-4675-b077-d4007989b0cc', '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2',
'3202ae18-a046-4c32-9fda-e32e9631866e']
+['b7b92d9e-d442-4710-92a5-ab039fd7d89b',
'23e1e837-abbf-4675-b077-d4007989b0cc',
+ '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2',
'3202ae18-a046-4c32-9fda-e32e9631866e']
\end{verbatim}
Note the VM references are internally UUIDs. Once a reference to a VM has been
acquired a lifecycle operation may be invoked:
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/xenapi-datamodel-graph.dot
--- a/docs/xen-api/xenapi-datamodel-graph.dot Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/xenapi-datamodel-graph.dot Mon Dec 04 08:24:41 2006 -0700
@@ -1,5 +1,5 @@ digraph g{
digraph g{
-node [ shape=box ]; session [ URL="session.html" ] task [ URL="task.html" ] VM
[ URL="VM.html" ] host [ URL="host.html" ] host_cpu [ URL="host_cpu.html" ]
network [ URL="network.html" ] VIF [ URL="VIF.html" ] PIF [ URL="PIF.html" ] SR
[ URL="SR.html" ] VDI [ URL="VDI.html" ] VBD [ URL="VBD.html" ] VTPM [
URL="VTPM.html" ] user [ URL="user.html" ] debug [ URL="debug.html" ];
+node [ shape=box ]; session [ URL="session.html" ] task [ URL="task.html" ] VM
[ URL="VM.html" ] host [ URL="host.html" ] host_cpu [ URL="host_cpu.html" ]
network [ URL="network.html" ] VIF [ URL="VIF.html" ] PIF [ URL="PIF.html" ] SR
[ URL="SR.html" ] VDI [ URL="VDI.html" ] VBD [ URL="VBD.html" ] VTPM [
URL="VTPM.html" ] console [ URL="console.html" ] user [ URL="user.html" ] debug
[ URL="debug.html" ];
session -> host [ label="this_host(1)" ]
session -> user [ label="this_user(1)" ]
host -> VM [ color="blue", arrowhead="crow", arrowtail="none" ]
@@ -14,4 +14,5 @@ VBD -> VM [ color="blue", arrowhead="non
VBD -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
VTPM -> VM [ label="backend(1)" ]
VTPM -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
+console -> VM [ color="blue", arrowhead="none", arrowtail="crow" ]
}
diff -r 6fdbf173142d -r d603aed5ad6d docs/xen-api/xenapi-datamodel.tex
--- a/docs/xen-api/xenapi-datamodel.tex Sat Dec 02 15:19:50 2006 -0700
+++ b/docs/xen-api/xenapi-datamodel.tex Mon Dec 04 08:24:41 2006 -0700
@@ -34,6 +34,7 @@ Name & Description \\
{\tt VDI} & A virtual disk image \\
{\tt VBD} & A virtual block device \\
{\tt VTPM} & A virtual TPM device \\
+{\tt console} & A console \\
{\tt user} & A user of the system \\
{\tt debug} & A basic class for testing \\
\hline
@@ -54,6 +55,7 @@ PIF.network & network.PIFs & one-to-many
PIF.network & network.PIFs & one-to-many\\
SR.VDIs & VDI.SR & many-to-one\\
VTPM.VM & VM.VTPMs & one-to-many\\
+console.VM & VM.consoles & one-to-many\\
host.resident\_VMs & VM.resident\_on & many-to-one\\
host.host\_CPUs & host\_cpu.host & many-to-one\\
\hline
@@ -96,6 +98,16 @@ Map (a $\rightarrow$ b) & a table mappin
\end{tabular}\end{center}
\subsection{Enumeration types}
The following enumeration types are used:
+
+\begin{longtable}{|ll|}
+\hline
+{\tt enum console\_protocol} & \\
+\hline
+\hspace{0.5cm}{\tt vt100} & VT100 terminal \\
+\hspace{0.5cm}{\tt rfb} & Remote FrameBuffer protocol (as used in VNC) \\
+\hspace{0.5cm}{\tt rdp} & Remote Desktop Protocol \\
+\hline
+\end{longtable}
\begin{longtable}{|ll|}
\hline
@@ -947,6 +959,7 @@ Quals & Field & Type & Description \\
$\mathit{RW}$ & {\tt actions/after\_reboot} & on\_normal\_exit & action to
take after the guest has rebooted itself \\
$\mathit{RW}$ & {\tt actions/after\_suspend} & on\_normal\_exit & action to
take after the guest has suspended itself \\
$\mathit{RW}$ & {\tt actions/after\_crash} & on\_crash\_behaviour & action to
take if the guest crashes \\
+$\mathit{RO}_\mathit{run}$ & {\tt consoles} & (console ref) Set & virtual
console devices \\
$\mathit{RO}_\mathit{run}$ & {\tt VIFs} & (VIF ref) Set & virtual network
interfaces \\
$\mathit{RO}_\mathit{run}$ & {\tt VBDs} & (VBD ref) Set & virtual block
devices \\
$\mathit{RO}_\mathit{run}$ & {\tt VTPMs} & (VTPM ref) Set & virtual TPMs \\
@@ -2628,6 +2641,38 @@ void
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_consoles}
+
+{\bf Overview:}
+Get the consoles field of the given VM.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} ((console ref) Set) get_consoles (session_id s, VM ref
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt VM ref } & self & object instance \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+(console ref) Set
+}
+
+
+value of the field
\vspace{0.3cm}
\vspace{0.3cm}
\vspace{0.3cm}
@@ -9187,6 +9232,281 @@ all fields from the object
\vspace{1cm}
\newpage
+\section{Class: console}
+\subsection{Fields for class: console}
+\begin{longtable}{|lllp{0.38\textwidth}|}
+\hline
+\multicolumn{1}{|l}{Name} & \multicolumn{3}{l|}{\bf console} \\
+\multicolumn{1}{|l}{Description} & \multicolumn{3}{l|}{\parbox{11cm}{\em A
console}} \\
+\hline
+Quals & Field & Type & Description \\
+\hline
+$\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object
reference \\
+$\mathit{RO}_\mathit{run}$ & {\tt protocol} & console\_protocol & the
protocol used by this console \\
+$\mathit{RO}_\mathit{run}$ & {\tt uri} & string & URI for the console service
\\
+$\mathit{RO}_\mathit{run}$ & {\tt VM} & VM ref & VM to which this console is
attached \\
+\hline
+\end{longtable}
+\subsection{Additional RPCs associated with class: console}
+\subsubsection{RPC name:~get\_record}
+
+{\bf Overview:}
+Get the current state of the given console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (console record) get_record (session_id s, console ref
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & reference to the object \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+console record
+}
+
+
+all fields from the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_by\_uuid}
+
+{\bf Overview:}
+Get a reference to the object with the specified UUID.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (console ref) get_by_uuid (session_id s, string
uuid)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt string } & uuid & UUID of object to return \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+console ref
+}
+
+
+reference to the object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~create}
+
+{\bf Overview:}
+Create a new console instance, and return its handle.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (console ref) create (session_id s, console record
args)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console record } & args & All constructor arguments \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+console ref
+}
+
+
+reference to the newly created object
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~destroy}
+
+{\bf Overview:}
+Destroy the specified console instance.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} void destroy (session_id s, console ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+void
+}
+
+
+
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_uuid}
+
+{\bf Overview:}
+Get the uuid field of the given console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_uuid (session_id s, console ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+string
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_protocol}
+
+{\bf Overview:}
+Get the protocol field of the given console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (console_protocol) get_protocol (session_id s, console ref
self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+console\_protocol
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_uri}
+
+{\bf Overview:}
+Get the uri field of the given console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} string get_uri (session_id s, console ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+string
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+\subsubsection{RPC name:~get\_VM}
+
+{\bf Overview:}
+Get the VM field of the given console.
+
+ \noindent {\bf Signature:}
+\begin{verbatim} (VM ref) get_VM (session_id s, console ref self)\end{verbatim}
+
+
+\noindent{\bf Arguments:}
+
+
+\vspace{0.3cm}
+\begin{tabular}{|c|c|p{7cm}|}
+ \hline
+{\bf type} & {\bf name} & {\bf description} \\ \hline
+{\tt console ref } & self & object instance \\ \hline
+
+\end{tabular}
+
+\vspace{0.3cm}
+
+ \noindent {\bf Return Type:}
+{\tt
+VM ref
+}
+
+
+value of the field
+\vspace{0.3cm}
+\vspace{0.3cm}
+\vspace{0.3cm}
+
+\vspace{1cm}
+\newpage
\section{Class: user}
\subsection{Fields for class: user}
\begin{longtable}{|lllp{0.38\textwidth}|}
diff -r 6fdbf173142d -r d603aed5ad6d extras/mini-os/events.c
--- a/extras/mini-os/events.c Sat Dec 02 15:19:50 2006 -0700
+++ b/extras/mini-os/events.c Mon Dec 04 08:24:41 2006 -0700
@@ -31,26 +31,27 @@ typedef struct _ev_action_t {
u32 count;
} ev_action_t;
-
static ev_action_t ev_actions[NR_EVS];
void default_handler(evtchn_port_t port, struct pt_regs *regs, void *data);
+
+static unsigned long bound_ports[NR_EVS/(8*sizeof(unsigned long))];
void unbind_all_ports(void)
{
int i;
- for(i=0;i<NR_EVS;i++)
- {
- if(ev_actions[i].handler != default_handler)
- {
- struct evtchn_close close;
- mask_evtchn(i);
- close.port = i;
- HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
- }
- }
+ for (i = 0; i < NR_EVS; i++)
+ {
+ if (test_and_clear_bit(i, bound_ports))
+ {
+ struct evtchn_close close;
+ mask_evtchn(i);
+ close.port = i;
+ HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+ }
+ }
}
-
+
/*
* Demux events to different handlers.
*/
@@ -114,6 +115,7 @@ int bind_virq(uint32_t virq, evtchn_hand
printk("Failed to bind virtual IRQ %d\n", virq);
return 1;
}
+ set_bit(op.port,bound_ports);
bind_evtchn(op.port, handler, data);
return 0;
}
@@ -188,6 +190,7 @@ int evtchn_bind_interdomain(domid_t pal,
int err = HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &op);
if (err)
return err;
+ set_bit(op.local_port,bound_ports);
evtchn_port_t port = op.local_port;
clear_evtchn(port); /* Without, handler gets invoked now! */
*local_port = bind_evtchn(port, handler, data);
diff -r 6fdbf173142d -r d603aed5ad6d extras/mini-os/include/events.h
--- a/extras/mini-os/include/events.h Sat Dec 02 15:19:50 2006 -0700
+++ b/extras/mini-os/include/events.h Mon Dec 04 08:24:41 2006 -0700
@@ -36,6 +36,7 @@ int evtchn_bind_interdomain(domid_t pal,
int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
evtchn_handler_t
handler, void *data,
evtchn_port_t
*local_port);
+void unbind_all_ports(void);
static inline int notify_remote_via_evtchn(evtchn_port_t port)
{
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/arch/i386/Kconfig
--- a/linux-2.6-xen-sparse/arch/i386/Kconfig Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/Kconfig Mon Dec 04 08:24:41 2006 -0700
@@ -726,7 +726,7 @@ source kernel/Kconfig.hz
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
- depends on EXPERIMENTAL && !X86_XEN
+ depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Sat Dec 02 15:19:50
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c Mon Dec 04 08:24:41
2006 -0700
@@ -68,6 +68,10 @@
#include <xen/xencons.h>
#include "setup_arch_pre.h"
#include <bios_ebda.h>
+
+#ifdef CONFIG_XEN
+#include <xen/interface/kexec.h>
+#endif
/* Forward Declaration. */
void __init find_max_pfn(void);
@@ -943,6 +947,7 @@ static void __init parse_cmdline_early (
* after a kernel panic.
*/
else if (!memcmp(from, "crashkernel=", 12)) {
+#ifndef CONFIG_XEN
unsigned long size, base;
size = memparse(from+12, &from);
if (*from == '@') {
@@ -953,6 +958,10 @@ static void __init parse_cmdline_early (
crashk_res.start = base;
crashk_res.end = base + size - 1;
}
+#else
+ printk("Ignoring crashkernel command line, "
+ "parameter will be supplied by xen\n");
+#endif
}
#endif
#ifdef CONFIG_PROC_VMCORE
@@ -1322,9 +1331,13 @@ void __init setup_bootmem_allocator(void
}
#endif
#ifdef CONFIG_KEXEC
+#ifdef CONFIG_XEN
+ xen_machine_kexec_setup_resources();
+#else
if (crashk_res.start != crashk_res.end)
reserve_bootmem(crashk_res.start,
crashk_res.end - crashk_res.start + 1);
+#endif
#endif
if (!xen_feature(XENFEAT_auto_translated_physmap))
@@ -1389,7 +1402,11 @@ legacy_init_iomem_resources(struct e820e
request_resource(res, data_resource);
#endif
#ifdef CONFIG_KEXEC
- request_resource(res, &crashk_res);
+ if (crashk_res.start != crashk_res.end)
+ request_resource(res, &crashk_res);
+#ifdef CONFIG_XEN
+ xen_machine_kexec_register_resources(res);
+#endif
#endif
}
}
@@ -1850,9 +1867,11 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif
} else {
- extern int console_use_vt;
- console_use_vt = 0;
- }
+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+ }
+ xencons_early_setup();
}
static int
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/arch/ia64/kernel/setup.c
--- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Sat Dec 02 15:19:50
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c Mon Dec 04 08:24:41
2006 -0700
@@ -550,13 +550,15 @@ setup_arch (char **cmdline_p)
xen_start_info->nr_pages, xen_start_info->flags);
if (!is_initial_xendomain()) {
- extern int console_use_vt;
+#if !defined(CONFIG_VT) || !defined(CONFIG_DUMMY_CONSOLE)
conswitchp = NULL;
- console_use_vt = 0;
+#endif
}
}
-#endif
-#endif
+ xencons_early_setup();
+#endif
+#endif
+
/* enable IA-64 Machine Check Abort Handling unless disabled */
if (!strstr(saved_command_line, "nomca"))
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/arch/x86_64/Kconfig
--- a/linux-2.6-xen-sparse/arch/x86_64/Kconfig Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/Kconfig Mon Dec 04 08:24:41 2006 -0700
@@ -435,7 +435,7 @@ config X86_MCE_AMD
config KEXEC
bool "kexec system call (EXPERIMENTAL)"
- depends on EXPERIMENTAL && !X86_64_XEN
+ depends on EXPERIMENTAL && !XEN_UNPRIVILEGED_GUEST
help
kexec is a system call that implements the ability to shutdown your
current kernel, and to start another kernel. It is like a reboot
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Sat Dec 02
15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/e820-xen.c Mon Dec 04
08:24:41 2006 -0700
@@ -260,7 +260,11 @@ void __init e820_reserve_resources(struc
request_resource(res, &data_resource);
#endif
#ifdef CONFIG_KEXEC
- request_resource(res, &crashk_res);
+ if (crashk_res.start != crashk_res.end)
+ request_resource(res, &crashk_res);
+#ifdef CONFIG_XEN
+ xen_machine_kexec_register_resources(res);
+#endif
#endif
}
}
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Sat Dec 02
15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/setup-xen.c Mon Dec 04
08:24:41 2006 -0700
@@ -80,6 +80,10 @@
#include <asm/mach-xen/setup_arch_post.h>
#include <xen/interface/memory.h>
+#ifdef CONFIG_XEN
+#include <xen/interface/kexec.h>
+#endif
+
extern unsigned long start_pfn;
extern struct edid_info edid_info;
@@ -450,6 +454,7 @@ static __init void parse_cmdline_early (
* after a kernel panic.
*/
else if (!memcmp(from, "crashkernel=", 12)) {
+#ifndef CONFIG_XEN
unsigned long size, base;
size = memparse(from+12, &from);
if (*from == '@') {
@@ -460,6 +465,10 @@ static __init void parse_cmdline_early (
crashk_res.start = base;
crashk_res.end = base + size - 1;
}
+#else
+ printk("Ignoring crashkernel command line, "
+ "parameter will be supplied by xen\n");
+#endif
}
#endif
@@ -812,10 +821,14 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif /* !CONFIG_XEN */
#ifdef CONFIG_KEXEC
+#ifdef CONFIG_XEN
+ xen_machine_kexec_setup_resources();
+#else
if (crashk_res.start != crashk_res.end) {
reserve_bootmem(crashk_res.start,
crashk_res.end - crashk_res.start + 1);
}
+#endif
#endif
paging_init();
@@ -970,10 +983,12 @@ void __init setup_arch(char **cmdline_p)
#endif
#endif
} else {
- extern int console_use_vt;
- console_use_vt = 0;
- }
- }
+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+ }
+ }
+ xencons_early_setup();
#else /* CONFIG_XEN */
#ifdef CONFIG_VT
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/drivers/xen/Kconfig
--- a/linux-2.6-xen-sparse/drivers/xen/Kconfig Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/Kconfig Mon Dec 04 08:24:41 2006 -0700
@@ -172,6 +172,29 @@ config XEN_NETDEV_FRONTEND
dedicated device-driver domain, or your master control domain
(domain 0), then you almost certainly want to say Y here.
+config XEN_FRAMEBUFFER
+ tristate "Framebuffer-device frontend driver"
+ depends on XEN && FB
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ default y
+ help
+ The framebuffer-device frontend drivers allows the kernel to create a
+ virtual framebuffer. This framebuffer can be viewed in another
+ domain. Unless this domain has access to a real video card, you
+ probably want to say Y here.
+
+config XEN_KEYBOARD
+ tristate "Keyboard-device frontend driver"
+ depends on XEN && XEN_FRAMEBUFFER && INPUT
+ default y
+ help
+ The keyboard-device frontend driver allows the kernel to create a
+ virtual keyboard. This keyboard can then be driven by another
+ domain. If you've said Y to CONFIG_XEN_FRAMEBUFFER, you probably
+ want to say Y here.
+
config XEN_SCRUB_PAGES
bool "Scrub memory before freeing it to Xen"
default y
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/drivers/xen/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -15,3 +15,5 @@ obj-$(CONFIG_XEN_NETDEV_FRONTEND) += net
obj-$(CONFIG_XEN_NETDEV_FRONTEND) += netfront/
obj-$(CONFIG_XEN_PCIDEV_BACKEND) += pciback/
obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += pcifront/
+obj-$(CONFIG_XEN_FRAMEBUFFER) += fbfront/
+obj-$(CONFIG_XEN_KEYBOARD) += fbfront/
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Sat Dec 02
15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Dec 04
08:24:41 2006 -0700
@@ -359,7 +359,7 @@ static void blkfront_closing(struct xenb
DPRINTK("blkfront_closing: %s removed\n", dev->nodename);
if (info->rq == NULL)
- return;
+ goto out;
spin_lock_irqsave(&blkif_io_lock, flags);
/* No more blkif_request(). */
@@ -373,6 +373,7 @@ static void blkfront_closing(struct xenb
xlvbd_del(info);
+ out:
xenbus_frontend_closed(dev);
}
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/drivers/xen/char/mem.c
--- a/linux-2.6-xen-sparse/drivers/xen/char/mem.c Sat Dec 02 15:19:50
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/char/mem.c Mon Dec 04 08:24:41
2006 -0700
@@ -147,7 +147,7 @@ static inline int uncached_access(struct
return 0;
}
-static int mmap_mem(struct file * file, struct vm_area_struct * vma)
+static int xen_mmap_mem(struct file * file, struct vm_area_struct * vma)
{
size_t size = vma->vm_end - vma->vm_start;
@@ -200,6 +200,6 @@ struct file_operations mem_fops = {
.llseek = memory_lseek,
.read = read_mem,
.write = write_mem,
- .mmap = mmap_mem,
+ .mmap = xen_mmap_mem,
.open = open_mem,
};
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/drivers/xen/console/console.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Sat Dec 02
15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Mon Dec 04
08:24:41 2006 -0700
@@ -57,6 +57,7 @@
#include <xen/interface/event_channel.h>
#include <asm/hypervisor.h>
#include <xen/evtchn.h>
+#include <xen/xenbus.h>
#include <xen/xencons.h>
/*
@@ -65,14 +66,14 @@
* 'xencons=tty' [XC_TTY]: Console attached to '/dev/tty[0-9]+'.
* 'xencons=ttyS' [XC_SERIAL]: Console attached to '/dev/ttyS[0-9]+'.
* 'xencons=xvc' [XC_XVC]: Console attached to '/dev/xvc0'.
- * [XC_DEFAULT]: DOM0 -> XC_SERIAL ; all others -> XC_TTY.
+ * default: DOM0 -> XC_SERIAL ; all others -> XC_TTY.
*
* NB. In mode XC_TTY, we create dummy consoles for tty2-63. This suppresses
* warnings from standard distro startup scripts.
*/
static enum {
- XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL, XC_XVC
-} xc_mode = XC_DEFAULT;
+ XC_OFF, XC_TTY, XC_SERIAL, XC_XVC
+} xc_mode;
static int xc_num = -1;
/* /dev/xvc0 device number allocated by lanana.org. */
@@ -84,17 +85,32 @@ extern int sysrq_enabled;
extern int sysrq_enabled;
#endif
+void xencons_early_setup(void)
+{
+ extern int console_use_vt;
+
+ if (is_initial_xendomain()) {
+ xc_mode = XC_SERIAL;
+ } else {
+ xc_mode = XC_TTY;
+ console_use_vt = 0;
+ }
+}
+
static int __init xencons_setup(char *str)
{
char *q;
int n;
-
+ extern int console_use_vt;
+
+ console_use_vt = 1;
if (!strncmp(str, "ttyS", 4)) {
xc_mode = XC_SERIAL;
str += 4;
} else if (!strncmp(str, "tty", 3)) {
xc_mode = XC_TTY;
str += 3;
+ console_use_vt = 0;
} else if (!strncmp(str, "xvc", 3)) {
xc_mode = XC_XVC;
str += 3;
@@ -192,14 +208,10 @@ static int __init xen_console_init(void)
goto out;
if (is_initial_xendomain()) {
- if (xc_mode == XC_DEFAULT)
- xc_mode = XC_SERIAL;
kcons_info.write = kcons_write_dom0;
} else {
if (!xen_start_info->console.domU.evtchn)
goto out;
- if (xc_mode == XC_DEFAULT)
- xc_mode = XC_TTY;
kcons_info.write = kcons_write;
}
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/drivers/xen/core/Makefile
--- a/linux-2.6-xen-sparse/drivers/xen/core/Makefile Sat Dec 02 15:19:50
2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/core/Makefile Mon Dec 04 08:24:41
2006 -0700
@@ -11,3 +11,4 @@ obj-$(CONFIG_XEN_SKBUFF) += skbuff.o
obj-$(CONFIG_XEN_SKBUFF) += skbuff.o
obj-$(CONFIG_XEN_REBOOT) += reboot.o machine_reboot.o
obj-$(CONFIG_XEN_SMPBOOT) += smpboot.o
+obj-$(CONFIG_KEXEC) += machine_kexec.o
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Sat Dec
02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypercall.h Mon Dec
04 08:24:41 2006 -0700
@@ -395,5 +395,13 @@ HYPERVISOR_xenoprof_op(
return _hypercall2(int, xenoprof_op, op, arg);
}
+static inline int
+HYPERVISOR_kexec_op(
+ unsigned long op, void *args)
+{
+ return _hypercall2(int, kexec_op, op, args);
+}
+
+
#endif /* __HYPERCALL_H__ */
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Sat Dec
02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/hypercall.h Mon Dec
04 08:24:41 2006 -0700
@@ -396,4 +396,11 @@ HYPERVISOR_xenoprof_op(
return _hypercall2(int, xenoprof_op, op, arg);
}
+static inline int
+HYPERVISOR_kexec_op(
+ unsigned long op, void *args)
+{
+ return _hypercall2(int, kexec_op, op, args);
+}
+
#endif /* __HYPERCALL_H__ */
diff -r 6fdbf173142d -r d603aed5ad6d
linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h
--- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h Sat Dec
02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/ptrace.h Mon Dec
04 08:24:41 2006 -0700
@@ -90,6 +90,8 @@ extern unsigned long profile_pc(struct p
#define profile_pc(regs) instruction_pointer(regs)
#endif
+#include <linux/compiler.h>
+
void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
struct task_struct;
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/include/xen/xencons.h
--- a/linux-2.6-xen-sparse/include/xen/xencons.h Sat Dec 02 15:19:50
2006 -0700
+++ b/linux-2.6-xen-sparse/include/xen/xencons.h Mon Dec 04 08:24:41
2006 -0700
@@ -14,4 +14,6 @@ int xencons_ring_init(void);
int xencons_ring_init(void);
int xencons_ring_send(const char *data, unsigned len);
+void xencons_early_setup(void);
+
#endif /* __ASM_XENCONS_H__ */
diff -r 6fdbf173142d -r d603aed5ad6d linux-2.6-xen-sparse/mm/memory.c
--- a/linux-2.6-xen-sparse/mm/memory.c Sat Dec 02 15:19:50 2006 -0700
+++ b/linux-2.6-xen-sparse/mm/memory.c Mon Dec 04 08:24:41 2006 -0700
@@ -882,6 +882,7 @@ unsigned long zap_page_range(struct vm_a
tlb_finish_mmu(tlb, address, end);
return end;
}
+EXPORT_SYMBOL(zap_page_range);
/*
* Do a quick page-table lookup for a single page.
diff -r 6fdbf173142d -r d603aed5ad6d patches/linux-2.6.16.33/series
--- a/patches/linux-2.6.16.33/series Sat Dec 02 15:19:50 2006 -0700
+++ b/patches/linux-2.6.16.33/series Mon Dec 04 08:24:41 2006 -0700
@@ -1,3 +1,12 @@ blktap-aio-16_03_06.patch
+kexec-generic.patch
+git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch
+git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch
+git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch
+linux-2.6.19-rc1-kexec-move_segment_code-i386.patch
+linux-2.6.19-rc1-kexec-xen-i386.patch
+git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch
+linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch
+linux-2.6.19-rc1-kexec-xen-x86_64.patch
blktap-aio-16_03_06.patch
device_bind.patch
fix-hz-suspend.patch
@@ -22,6 +31,7 @@ xenoprof-generic.patch
xenoprof-generic.patch
x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch
+git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch
x86-elfnote-as-preprocessor-macro.patch
vsnprintf.patch
kasprintf.patch
diff -r 6fdbf173142d -r d603aed5ad6d tools/Makefile
--- a/tools/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -19,6 +19,7 @@ SUBDIRS-y += libaio
SUBDIRS-y += libaio
SUBDIRS-y += blktap
SUBDIRS-y += libfsimage
+SUBDIRS-$(XENFB_TOOLS) += xenfb
SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen
# These don't cross-compile
diff -r 6fdbf173142d -r d603aed5ad6d tools/blktap/drivers/block-aio.c
--- a/tools/blktap/drivers/block-aio.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/blktap/drivers/block-aio.c Mon Dec 04 08:24:41 2006 -0700
@@ -311,12 +311,8 @@ int tdaio_do_callbacks(struct td_state *
struct pending_aio *pio;
pio = &prv->pending_aio[(long)io->data];
-
- if (ep->res != io->u.c.nbytes) {
- /* TODO: handle this case better. */
- DPRINTF("AIO did less than I asked it to. \n");
- }
- rsp += pio->cb(s, ep->res2, pio->id, pio->private);
+ rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0 : 1,
+ pio->id, pio->private);
prv->iocb_free[prv->iocb_free_count++] = io;
}
diff -r 6fdbf173142d -r d603aed5ad6d tools/blktap/drivers/block-qcow.c
--- a/tools/blktap/drivers/block-qcow.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/blktap/drivers/block-qcow.c Mon Dec 04 08:24:41 2006 -0700
@@ -1145,13 +1145,6 @@ int tdqcow_do_callbacks(struct td_state
pio = &prv->pending_aio[(long)io->data];
- if (ep->res != io->u.c.nbytes) {
- /* TODO: handle this case better. */
- ptr = (int *)&ep->res;
- DPRINTF("AIO did less than I asked it to "
- "[%lu,%lu,%d]\n",
- ep->res, io->u.c.nbytes, *ptr);
- }
aio_unlock(prv, pio->sector);
if (pio->id >= 0) {
if (prv->crypt_method)
@@ -1162,7 +1155,7 @@ int tdqcow_do_callbacks(struct td_state
&prv->aes_decrypt_key);
prv->nr_reqs[pio->qcow_idx]--;
if (prv->nr_reqs[pio->qcow_idx] == 0)
- rsp += pio->cb(s, ep->res2, pio->id,
+ rsp += pio->cb(s, ep->res == io->u.c.nbytes ? 0
: 1, pio->id,
pio->private);
} else if (pio->id == -2) free(pio->buf);
diff -r 6fdbf173142d -r d603aed5ad6d tools/blktap/drivers/tapdisk.c
--- a/tools/blktap/drivers/tapdisk.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/blktap/drivers/tapdisk.c Mon Dec 04 08:24:41 2006 -0700
@@ -424,8 +424,7 @@ int send_responses(struct td_state *s, i
}
if (res != 0) {
- DPRINTF("*** request error %d! \n", res);
- return 0;
+ blkif->pending_list[idx].status = BLKIF_RSP_ERROR;
}
blkif->pending_list[idx].count--;
diff -r 6fdbf173142d -r d603aed5ad6d tools/check/Makefile
--- a/tools/check/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/check/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -1,3 +1,5 @@
+XEN_ROOT = ../..
+include $(XEN_ROOT)/tools/Rules.mk
.PHONY: all
all: build
@@ -5,7 +7,7 @@ all: build
# Check this machine is OK for building on.
.PHONY: build
build:
- ./chk build
+ XENFB_TOOLS=$(XENFB_TOOLS) ./chk build
# Check this machine is OK for installing on.
# DO NOT use this check from 'make install' in the parent
@@ -13,7 +15,7 @@ build:
# copy rather than actually installing.
.PHONY: install
install:
- ./chk install
+ XENFB_TOOLS=$(XENFB_TOOLS) ./chk install
.PHONY: clean
clean:
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/setup.c Mon Dec 04 08:24:41 2006 -0700
@@ -66,7 +66,7 @@ unsigned long memory_size;
unsigned long memory_size;
int initialize_real_mode;
-extern char stack[], stack_top[];
+extern char stack_top[];
extern unsigned trap_handlers[];
void
@@ -201,7 +201,7 @@ enter_real_mode(struct regs *regs)
enter_real_mode(struct regs *regs)
{
/* mask off TSS busy bit */
- gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
+ gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
/* start 8086 emulation of BIOS */
if (initialize_real_mode) {
@@ -219,8 +219,10 @@ enter_real_mode(struct regs *regs)
regs->cs = booting_vector << 8; /* AP entry point */
regs->eip = 0;
}
- regs->uesp = 0;
- regs->uss = 0;
+
+ regs->uesp = regs->uss = 0;
+ regs->eax = regs->ecx = regs->edx = regs->ebx = 0;
+ regs->esp = regs->ebp = regs->esi = regs->edi = 0;
/* intercept accesses to the PIC */
setiomap(PIC_MASTER+PIC_CMD);
@@ -236,14 +238,12 @@ enter_real_mode(struct regs *regs)
/* this should get us into 16-bit mode */
return;
- } else {
- /* go from protected to real mode */
- regs->eflags |= EFLAGS_VM;
-
- set_mode(regs, VM86_PROTECTED_TO_REAL);
-
- emulate(regs);
}
+
+ /* go from protected to real mode */
+ regs->eflags |= EFLAGS_VM;
+ set_mode(regs, VM86_PROTECTED_TO_REAL);
+ emulate(regs);
}
/*
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/trap.S
--- a/tools/firmware/vmxassist/trap.S Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/trap.S Mon Dec 04 08:24:41 2006 -0700
@@ -100,10 +100,6 @@ trap_handlers:
.code32
.align 16
common_trap: /* common trap handler */
- pushl %gs
- pushl %fs
- pushl %ds
- pushl %es
pushal
movl $(DATA_SELECTOR), %eax /* make sure these are sane */
@@ -114,17 +110,13 @@ common_trap: /* common trap
handler *
movl %esp, %ebp
pushl %ebp
- pushl 52(%ebp)
- pushl 48(%ebp)
+ pushl 36(%ebp)
+ pushl 32(%ebp)
call trap /* trap(trapno, errno, regs) */
addl $12, %esp
trap_return:
popal
- popl %es
- popl %ds
- popl %fs
- popl %gs
addl $8, %esp /* skip trapno, errno */
iret
/* NOT REACHED */
@@ -152,10 +144,6 @@ switch_to_real_mode:
pushl oldctx+VMX_ASSIST_CTX_EIP
pushl $-1 /* trapno, errno */
pushl $-1
- pushl %gs
- pushl %fs
- pushl %ds
- pushl %es
pushal
movl %esp, %ebp
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/util.c
--- a/tools/firmware/vmxassist/util.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/util.c Mon Dec 04 08:24:41 2006 -0700
@@ -62,17 +62,15 @@ dump_regs(struct regs *regs)
regs->eax, regs->ecx, regs->edx, regs->ebx);
printf("esp %8x ebp %8x esi %8x edi %8x\n",
regs->esp, regs->ebp, regs->esi, regs->edi);
- printf("es %8x ds %8x fs %8x gs %8x\n",
- regs->es, regs->ds, regs->fs, regs->gs);
printf("trapno %8x errno %8x\n", regs->trapno, regs->errno);
printf("eip %8x cs %8x eflags %8x\n",
regs->eip, regs->cs, regs->eflags);
- printf("uesp %8x uss %8x \n",
+ printf("uesp %8x uss %8x\n",
regs->uesp, regs->uss);
printf("ves %8x vds %8x vfs %8x vgs %8x\n",
regs->ves, regs->vds, regs->vfs, regs->vgs);
- printf("cr0 %8lx cr2 %8x cr3 %8lx cr4 %8lx\n",
+ printf("cr0 %8lx cr2 %8x cr3 %8lx cr4 %8lx\n\n",
(long)oldctx.cr0, get_cr2(),
(long)oldctx.cr3, (long)oldctx.cr4);
}
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/vm86.c Mon Dec 04 08:24:41 2006 -0700
@@ -376,9 +376,9 @@ segment(unsigned prefix, struct regs *re
if (prefix & SEG_SS)
seg = regs->uss;
if (prefix & SEG_FS)
- seg = regs->fs;
+ seg = regs->vfs;
if (prefix & SEG_GS)
- seg = regs->gs;
+ seg = regs->vgs;
return seg;
}
@@ -934,6 +934,8 @@ static void
static void
protected_mode(struct regs *regs)
{
+ extern char stack_top[];
+
regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM);
oldctx.eip = regs->eip;
@@ -958,12 +960,10 @@ protected_mode(struct regs *regs)
&oldctx.gs_limit, &oldctx.gs_arbytes);
/* initialize jump environment to warp back to protected mode */
+ regs->uss = DATA_SELECTOR;
+ regs->uesp = stack_top;
regs->cs = CODE_SELECTOR;
- regs->ds = DATA_SELECTOR;
- regs->es = DATA_SELECTOR;
- regs->fs = DATA_SELECTOR;
- regs->gs = DATA_SELECTOR;
- regs->eip = (unsigned) &switch_to_protected_mode;
+ regs->eip = (unsigned) switch_to_protected_mode;
/* this should get us into 32-bit mode */
}
@@ -975,10 +975,6 @@ real_mode(struct regs *regs)
real_mode(struct regs *regs)
{
regs->eflags |= EFLAGS_VM | 0x02;
- regs->ds = DATA_SELECTOR;
- regs->es = DATA_SELECTOR;
- regs->fs = DATA_SELECTOR;
- regs->gs = DATA_SELECTOR;
/*
* When we transition from protected to real-mode and we
@@ -1070,9 +1066,6 @@ set_mode(struct regs *regs, enum vm86_mo
case VM86_PROTECTED:
if (mode == VM86_REAL_TO_PROTECTED) {
protected_mode(regs);
-// printf("<VM86_PROTECTED>\n");
- mode = newmode;
- return;
} else
panic("unexpected protected mode transition");
break;
diff -r 6fdbf173142d -r d603aed5ad6d tools/firmware/vmxassist/vm86.h
--- a/tools/firmware/vmxassist/vm86.h Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/firmware/vmxassist/vm86.h Mon Dec 04 08:24:41 2006 -0700
@@ -34,7 +34,6 @@
struct regs {
unsigned edi, esi, ebp, esp, ebx, edx, ecx, eax;
- unsigned es, ds, fs, gs;
unsigned trapno, errno;
unsigned eip, cs, eflags, uesp, uss;
unsigned ves, vds, vfs, vgs;
@@ -55,7 +54,6 @@ enum vm86_mode {
extern enum vm86_mode prevmode, mode;
extern struct vmx_assist_context oldctx;
-extern struct vmx_assist_context newctx;
extern void emulate(struct regs *);
extern void dump_regs(struct regs *);
diff -r 6fdbf173142d -r d603aed5ad6d tools/ioemu/hw/pci.c
--- a/tools/ioemu/hw/pci.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/ioemu/hw/pci.c Mon Dec 04 08:24:41 2006 -0700
@@ -221,23 +221,16 @@ uint32_t pci_default_read_config(PCIDevi
uint32_t address, int len)
{
uint32_t val;
-
switch(len) {
+ case 1:
+ val = d->config[address];
+ break;
+ case 2:
+ val = le16_to_cpu(*(uint16_t *)(d->config + address));
+ break;
default:
case 4:
- if (address <= 0xfc) {
- val = le32_to_cpu(*(uint32_t *)(d->config + address));
- break;
- }
- /* fall through */
- case 2:
- if (address <= 0xfe) {
- val = le16_to_cpu(*(uint16_t *)(d->config + address));
- break;
- }
- /* fall through */
- case 1:
- val = d->config[address];
+ val = le32_to_cpu(*(uint32_t *)(d->config + address));
break;
}
return val;
@@ -340,8 +333,7 @@ void pci_default_write_config(PCIDevice
d->config[addr] = val;
}
- if (++addr > 0xff)
- break;
+ addr++;
val >>= 8;
}
diff -r 6fdbf173142d -r d603aed5ad6d tools/ioemu/hw/usb-uhci.c
--- a/tools/ioemu/hw/usb-uhci.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/ioemu/hw/usb-uhci.c Mon Dec 04 08:24:41 2006 -0700
@@ -421,7 +421,7 @@ static int uhci_handle_td(UHCIState *s,
static int uhci_handle_td(UHCIState *s, UHCI_TD *td, int *int_mask)
{
uint8_t pid;
- uint8_t buf[1280];
+ uint8_t buf[2048];
int len, max_len, err, ret;
if (td->ctrl & TD_CTRL_IOC) {
diff -r 6fdbf173142d -r d603aed5ad6d tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/ioemu/vl.h Mon Dec 04 08:24:41 2006 -0700
@@ -650,8 +650,11 @@ typedef struct PCIIORegion {
#define PCI_MAX_LAT 0x3f /* 8 bits */
struct PCIDevice {
- /* PCI config space */
- uint8_t config[256];
+ /*
+ * PCI config space. The 4 extra bytes are a safety buffer for guest
+ * word/dword writes that can extend past byte 0xff.
+ */
+ uint8_t config[256+4];
/* the following fields are read only */
PCIBus *bus;
diff -r 6fdbf173142d -r d603aed5ad6d tools/ioemu/vnc.c
--- a/tools/ioemu/vnc.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/ioemu/vnc.c Mon Dec 04 08:24:41 2006 -0700
@@ -114,6 +114,7 @@ struct VncState
int visible_h;
int ctl_keys; /* Ctrl+Alt starts calibration */
+ int shift_keys; /* Shift / CapsLock keys */
};
#define DIRTY_PIXEL_BITS 64
@@ -870,9 +871,12 @@ static void do_key_event(VncState *vs, i
} else if (down) {
int qemu_keysym = 0;
- if (sym <= 128) /* normal ascii */
+ if (sym <= 128) { /* normal ascii */
+ int shifted = vs->shift_keys == 1 || vs->shift_keys == 2;
qemu_keysym = sym;
- else {
+ if (sym >= 'a' && sym <= 'z' && shifted)
+ qemu_keysym -= 'a' - 'A';
+ } else {
switch (sym) {
case XK_Up: qemu_keysym = QEMU_KEY_UP; break;
case XK_Down: qemu_keysym = QEMU_KEY_DOWN; break;
@@ -903,6 +907,10 @@ static void do_key_event(VncState *vs, i
vs->ctl_keys |= 2;
break;
+ case XK_Shift_L:
+ vs->shift_keys |= 1;
+ break;
+
default:
break;
}
@@ -914,6 +922,14 @@ static void do_key_event(VncState *vs, i
case XK_Alt_L:
vs->ctl_keys &= ~2;
+ break;
+
+ case XK_Shift_L:
+ vs->shift_keys &= ~1;
+ break;
+
+ case XK_Caps_Lock:
+ vs->shift_keys ^= 2;
break;
case XK_1 ... XK_9:
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxc/xc_linux.c
--- a/tools/libxc/xc_linux.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxc/xc_linux.c Mon Dec 04 08:24:41 2006 -0700
@@ -250,6 +250,15 @@ int xc_evtchn_notify(int xce_handle, evt
return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, ¬ify);
}
+evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
+{
+ struct ioctl_evtchn_bind_unbound_port bind;
+
+ bind.remote_domain = domid;
+
+ return ioctl(xce_handle, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
+}
+
evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
evtchn_port_t remote_port)
{
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxc/xc_solaris.c
--- a/tools/libxc/xc_solaris.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxc/xc_solaris.c Mon Dec 04 08:24:41 2006 -0700
@@ -165,6 +165,15 @@ int xc_evtchn_notify(int xce_handle, evt
return ioctl(xce_handle, IOCTL_EVTCHN_NOTIFY, ¬ify);
}
+evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid)
+{
+ struct ioctl_evtchn_bind_unbound_port bind;
+
+ bind.remote_domain = domid;
+
+ return ioctl(xce_handle, IOCTL_EVTCHN_BIND_UNBOUND_PORT, &bind);
+}
+
evtchn_port_t xc_evtchn_bind_interdomain(int xce_handle, int domid,
evtchn_port_t remote_port)
{
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxc/xenctrl.h Mon Dec 04 08:24:41 2006 -0700
@@ -382,6 +382,10 @@ int xc_sched_credit_domain_get(int xc_ha
* This function allocates an unbound port. Ports are named endpoints used for
* interdomain communication. This function is most useful in opening a
* well-known port within a domain to receive events on.
+ *
+ * NOTE: If you are allocating a *local* unbound port, you probably want to
+ * use xc_evtchn_bind_unbound_port(). This function is intended for allocating
+ * ports *only* during domain creation.
*
* @parm xc_handle a handle to an open hypervisor interface
* @parm dom the ID of the local domain (the 'allocatee')
@@ -630,6 +634,12 @@ int xc_evtchn_notify(int xce_handle, evt
int xc_evtchn_notify(int xce_handle, evtchn_port_t port);
/*
+ * Returns a new event port awaiting interdomain connection from the given
+ * domain ID, or -1 on failure, in which case errno will be set appropriately.
+ */
+evtchn_port_t xc_evtchn_bind_unbound_port(int xce_handle, int domid);
+
+/*
* Returns a new event port bound to the remote port for the given domain ID,
* or -1 on failure, in which case errno will be set appropriately.
*/
@@ -661,15 +671,15 @@ int xc_evtchn_unmask(int xce_handle, evt
int xc_evtchn_unmask(int xce_handle, evtchn_port_t port);
int xc_hvm_set_pci_intx_level(
- int xce_handle, domid_t dom,
+ int xc_handle, domid_t dom,
uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
unsigned int level);
int xc_hvm_set_isa_irq_level(
- int xce_handle, domid_t dom,
+ int xc_handle, domid_t dom,
uint8_t isa_irq,
unsigned int level);
int xc_hvm_set_pci_link_route(
- int xce_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
+ int xc_handle, domid_t dom, uint8_t link, uint8_t isa_irq);
#endif
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxen/Makefile
--- a/tools/libxen/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxen/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -48,8 +48,8 @@ libxenapi.a: $(LIBXENAPI_OBJS)
libxenapi.a: $(LIBXENAPI_OBJS)
$(AR) rcs libxenapi.a $^
-test/test_bindings: test/test_bindings.o src/libxen.so
- $(CC) $(LDFLAGS) -o $@ $< -L src -lxen
+test/test_bindings: test/test_bindings.o libxenapi.so
+ $(CC) $(LDFLAGS) -o $@ $< -L . -lxenapi
.PHONY: install
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxen/README
--- a/tools/libxen/README Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxen/README Mon Dec 04 08:24:41 2006 -0700
@@ -44,11 +44,12 @@ test program depends upon libcurl3 also.
test program depends upon libcurl3 also. On Debian, you need the packages
libxml2-dev and libcurl3-dev.
-To compile, type make.
+To compile, type make. To compile the test also, type make
+test/test_bindings, remembering the additional dependency.
To run the test, do
-LD_LIBRARY_PATH=src ./test/test_bindings <url> <username> <password>
+LD_LIBRARY_PATH=. ./test/test_bindings <url> <username> <password>
where <url> is the fragment of the server URL that follows the http://, for
example "localhost:8005/RPC2".
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxen/include/xen_vm.h
--- a/tools/libxen/include/xen_vm.h Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxen/include/xen_vm.h Mon Dec 04 08:24:41 2006 -0700
@@ -21,6 +21,7 @@
#include "xen_boot_type.h"
#include "xen_common.h"
+#include "xen_console_decl.h"
#include "xen_cpu_feature.h"
#include "xen_host_decl.h"
#include "xen_int_float_map.h"
@@ -96,6 +97,7 @@ typedef struct xen_vm_record
enum xen_on_normal_exit actions_after_reboot;
enum xen_on_normal_exit actions_after_suspend;
enum xen_on_crash_behaviour actions_after_crash;
+ struct xen_console_record_opt_set *consoles;
struct xen_vif_record_opt_set *vifs;
struct xen_vbd_record_opt_set *vbds;
struct xen_vtpm_record_opt_set *vtpms;
@@ -401,6 +403,13 @@ xen_vm_get_actions_after_crash(xen_sessi
/**
+ * Get the consoles field of the given VM.
+ */
+extern bool
+xen_vm_get_consoles(xen_session *session, struct xen_console_set **result,
xen_vm vm);
+
+
+/**
* Get the VIFs field of the given VM.
*/
extern bool
diff -r 6fdbf173142d -r d603aed5ad6d tools/libxen/src/xen_vm.c
--- a/tools/libxen/src/xen_vm.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/libxen/src/xen_vm.c Mon Dec 04 08:24:41 2006 -0700
@@ -22,6 +22,7 @@
#include "xen_boot_type_internal.h"
#include "xen_common.h"
+#include "xen_console.h"
#include "xen_cpu_feature.h"
#include "xen_cpu_feature_internal.h"
#include "xen_host.h"
@@ -120,6 +121,9 @@ static const struct_member xen_vm_record
{ .key = "actions_after_crash",
.type = &xen_on_crash_behaviour_abstract_type_,
.offset = offsetof(xen_vm_record, actions_after_crash) },
+ { .key = "consoles",
+ .type = &abstract_type_ref_set,
+ .offset = offsetof(xen_vm_record, consoles) },
{ .key = "VIFs",
.type = &abstract_type_ref_set,
.offset = offsetof(xen_vm_record, vifs) },
@@ -205,6 +209,7 @@ xen_vm_record_free(xen_vm_record *record
xen_cpu_feature_set_free(record->vcpus_features_can_use);
xen_cpu_feature_set_free(record->vcpus_features_force_on);
xen_cpu_feature_set_free(record->vcpus_features_force_off);
+ xen_console_record_opt_set_free(record->consoles);
xen_vif_record_opt_set_free(record->vifs);
xen_vbd_record_opt_set_free(record->vbds);
xen_vtpm_record_opt_set_free(record->vtpms);
@@ -694,6 +699,23 @@ xen_vm_get_actions_after_crash(xen_sessi
bool
+xen_vm_get_consoles(xen_session *session, struct xen_console_set **result,
xen_vm vm)
+{
+ abstract_value param_values[] =
+ {
+ { .type = &abstract_type_string,
+ .u.string_val = vm }
+ };
+
+ abstract_type result_type = abstract_type_string_set;
+
+ *result = NULL;
+ XEN_CALL_("VM.get_consoles");
+ return session->ok;
+}
+
+
+bool
xen_vm_get_vifs(xen_session *session, struct xen_vif_set **result, xen_vm vm)
{
abstract_value param_values[] =
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/scripts/xapi.domcfg.py
--- a/tools/python/scripts/xapi.domcfg.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/scripts/xapi.domcfg.py Mon Dec 04 08:24:41 2006 -0700
@@ -26,7 +26,7 @@ platform_localtime = False
platform_localtime = False
platform_clock_offset = False
platform_enable_audio = False
-builder = ''
+builder = 'linux'
boot_method = '' # this will remove the kernel/initrd ??
kernel_kernel = '/boot/vmlinuz-2.6.16.29-xen'
kernel_initrd = '/root/initrd-2.6.16.29-xen.img'
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/scripts/xapi.py
--- a/tools/python/scripts/xapi.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/scripts/xapi.py Mon Dec 04 08:24:41 2006 -0700
@@ -29,17 +29,20 @@ MB = 1024 * 1024
MB = 1024 * 1024
HOST_INFO_FORMAT = '%-20s: %-50s'
-VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(vcpus_number)-5s'\
+VM_LIST_FORMAT = '%(name_label)-18s %(memory_actual)-5s %(VCPUs_number)-5s'\
' %(power_state)-10s %(uuid)-36s'
SR_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(physical_size)-10s' \
'%(type)-10s'
VDI_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(virtual_size)-8s '\
'%(sector_size)-8s'
+VBD_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(VDI)-8s '\
+ '%(image)-8s'
COMMANDS = {
'host-info': ('', 'Get Xen Host Info'),
'host-set-name': ('', 'Set host name'),
'sr-list': ('', 'List all SRs'),
+ 'vbd-list': ('', 'List all VBDs'),
'vbd-create': ('<domname> <pycfg> [opts]',
'Create VBD attached to domname'),
'vdi-create': ('<pycfg> [opts]', 'Create a VDI'),
@@ -165,6 +168,13 @@ def resolve_vm(server, session, vm_name)
else:
return vm_uuid[0]
+def resolve_vdi(server, session, vdi_name):
+ vdi_uuid = execute(server.VDI.get_by_name_label, session, vdi_name)
+ if not vdi_uuid:
+ return None
+ else:
+ return vdi_uuid[0]
+
#
# Actual commands
#
@@ -216,16 +226,16 @@ def xapi_vm_list(*args):
if not is_long:
print VM_LIST_FORMAT % {'name_label':'Name',
'memory_actual':'Mem',
- 'vcpus_number': 'VCPUs',
+ 'VCPUs_number': 'VCPUs',
'power_state': 'State',
'uuid': 'UUID'}
for uuid in vm_uuids:
vm_info = execute(server.VM.get_record, session, uuid)
if is_long:
- vbds = vm_info['vbds']
- vifs = vm_info['vifs']
- vtpms = vm_info['vtpms']
+ vbds = vm_info['VBDs']
+ vifs = vm_info['VIFs']
+ vtpms = vm_info['VTPMs']
vif_infos = []
vbd_infos = []
vtpm_infos = []
@@ -238,9 +248,9 @@ def xapi_vm_list(*args):
for vtpm in vtpms:
vtpm_info = execute(server.VTPM.get_record, session, vtpm)
vtpm_infos.append(vtpm_info)
- vm_info['vbds'] = vbd_infos
- vm_info['vifs'] = vif_infos
- vm_info['vtpms'] = vtpm_infos
+ vm_info['VBDs'] = vbd_infos
+ vm_info['VIFs'] = vif_infos
+ vm_info['VTPMs'] = vtpm_infos
pprint(vm_info)
else:
print VM_LIST_FORMAT % _stringify(vm_info)
@@ -276,7 +286,7 @@ def xapi_vm_start(*args):
server, session = _connect()
vm_uuid = resolve_vm(server, session, args[0])
print 'Starting VM %s (%s)' % (args[0], vm_uuid)
- success = execute(server.VM.start, session, vm_uuid)
+ success = execute(server.VM.start, session, vm_uuid, False)
print 'Done.'
def xapi_vm_shutdown(*args):
@@ -333,6 +343,22 @@ def xapi_vif_create(*args):
cfg['VM'] = vm_uuid
vif_uuid = execute(server.VIF.create, session, cfg)
print 'Done. (%s)' % vif_uuid
+
+def xapi_vbd_list(*args):
+ server, session = _connect()
+ domname = args[0]
+
+ dom_uuid = resolve_vm(server, session, domname)
+ vbds = execute(server.VM.get_VBDs, session, dom_uuid)
+
+ print VBD_LIST_FORMAT % {'name_label': 'VDI Label',
+ 'uuid' : 'UUID',
+ 'VDI': 'VDI',
+ 'image': 'Image'}
+
+ for vbd in vbds:
+ vbd_struct = execute(server.VBD.get_record, session, vbd)
+ print VBD_LIST_FORMAT % vbd_struct
def xapi_vdi_list(*args):
server, session = _connect()
@@ -420,8 +446,6 @@ def xapi_vtpm_create(*args):
print "Has driver type '%s'" % driver
vtpm_rec = execute(server.VTPM.get_record, session, vtpm_uuid)
print "Has vtpm record '%s'" % vtpm_rec
- vm = execute(server.VTPM.get_VM, session, vtpm_uuid)
- print "Has VM '%s'" % vm
#
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Dec 04 08:24:41 2006 -0700
@@ -392,7 +392,7 @@ static PyObject *pyxc_hvm_build(XcObject
return PyErr_SetFromErrno(xc_error);
/* Set up the HVM info table. */
- va_map = xc_map_foreign_range(self->xc_handle, dom, PAGE_SIZE,
+ va_map = xc_map_foreign_range(self->xc_handle, dom, XC_PAGE_SIZE,
PROT_READ | PROT_WRITE,
HVM_INFO_PFN);
if ( va_map == NULL )
@@ -407,7 +407,7 @@ static PyObject *pyxc_hvm_build(XcObject
for ( i = 0, sum = 0; i < va_hvm->length; i++ )
sum += ((uint8_t *)va_hvm)[i];
va_hvm->checksum = -sum;
- munmap(va_map, PAGE_SIZE);
+ munmap(va_map, XC_PAGE_SIZE);
xc_get_hvm_param(self->xc_handle, dom, HVM_PARAM_STORE_PFN, &store_mfn);
xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_PAE_ENABLED, pae);
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/util/bugtool.py
--- a/tools/python/xen/util/bugtool.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/util/bugtool.py Mon Dec 04 08:24:41 2006 -0700
@@ -43,8 +43,9 @@ TITLE_RE = re.compile(r'<title>(.*)</tit
FILES_TO_SEND = [ '/var/log/' + x for x in
[ 'syslog', 'messages', 'debug',
- 'xen/xend.log', 'xen/xend-debug.log',
'xen/xenstored-trace.log',
- 'xen/xen-hotplug.log' ] ]
+ 'xen/xend-debug.log', 'xen/xenstored-trace.log',
+ 'xen/xen-hotplug.log', 'xen/xend.log' ] +
+ [ 'xen/xend.log.%d' % z for z in range(1,6) ] ]
#FILES_TO_SEND = [ ]
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/util/xmlrpclib2.py
--- a/tools/python/xen/util/xmlrpclib2.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/util/xmlrpclib2.py Mon Dec 04 08:24:41 2006 -0700
@@ -29,6 +29,8 @@ from SimpleXMLRPCServer import SimpleXML
from SimpleXMLRPCServer import SimpleXMLRPCServer, SimpleXMLRPCRequestHandler
import SocketServer
import xmlrpclib, socket, os, stat
+
+import mkdir
from xen.web import connection
from xen.xend.XendLogging import log
@@ -234,14 +236,9 @@ class UnixXMLRPCServer(TCPXMLRPCServer):
address_family = socket.AF_UNIX
def __init__(self, addr, allowed, logRequests = 1):
- parent = os.path.dirname(addr)
- if os.path.exists(parent):
- os.chown(parent, os.geteuid(), os.getegid())
- os.chmod(parent, stat.S_IRWXU)
- if self.allow_reuse_address and os.path.exists(addr):
- os.unlink(addr)
- else:
- os.makedirs(parent, stat.S_IRWXU)
+ mkdir.parents(os.path.dirname(addr), stat.S_IRWXU, True)
+ if self.allow_reuse_address and os.path.exists(addr):
+ os.unlink(addr)
TCPXMLRPCServer.__init__(self, addr, allowed,
UnixXMLRPCRequestHandler, logRequests)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/web/unix.py
--- a/tools/python/xen/web/unix.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/web/unix.py Mon Dec 04 08:24:41 2006 -0700
@@ -22,6 +22,8 @@ import socket
import socket
import stat
+from xen.util import mkdir
+
import connection
@@ -30,13 +32,9 @@ created such that only the current user
created such that only the current user may access it."""
parent = os.path.dirname(path)
- if os.path.exists(parent):
- os.chown(parent, os.geteuid(), os.getegid())
- os.chmod(parent, stat.S_IRWXU)
- if os.path.exists(path):
- os.unlink(path)
- else:
- os.makedirs(parent, stat.S_IRWXU)
+ mkdir.parents(parent, stat.S_IRWXU, True)
+ if os.path.exists(path):
+ os.unlink(path)
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.bind(path)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendAPI.py Mon Dec 04 08:24:41 2006 -0700
@@ -303,8 +303,8 @@ class XendAPI:
# all get_by_uuid() methods.
for cls in classes.keys():
- get_by_uuid = '%s_get_by_uuid' % cls.lower()
- get_uuid = '%s_get_uuid' % cls.lower()
+ get_by_uuid = '%s_get_by_uuid' % cls
+ get_uuid = '%s_get_uuid' % cls
setattr(XendAPI, get_by_uuid,
lambda s, sess, obj_ref: xen_api_success(obj_ref))
setattr(XendAPI, get_uuid,
@@ -327,7 +327,7 @@ class XendAPI:
# wrap validators around readable class attributes
for attr_name in ro_attrs + rw_attrs + self.Base_attr_ro:
- getter_name = '%s_get_%s' % (cls.lower(), attr_name)
+ getter_name = '%s_get_%s' % (cls, attr_name)
try:
getter = getattr(XendAPI, getter_name)
for validator in validators:
@@ -340,7 +340,7 @@ class XendAPI:
# wrap validators around writable class attrributes
for attr_name in rw_attrs + self.Base_attr_rw:
- setter_name = '%s_set_%s' % (cls.lower(), attr_name)
+ setter_name = '%s_set_%s' % (cls, attr_name)
try:
setter = getattr(XendAPI, setter_name)
for validator in validators:
@@ -353,7 +353,8 @@ class XendAPI:
# wrap validators around methods
for method_name in methods + self.Base_methods:
- method_full_name = '%s_%s' % (cls.lower(), method_name)
+ method_full_name = '%s_%s' % (cls, method_name)
+
try:
method = getattr(XendAPI, method_full_name)
for validator in validators:
@@ -366,7 +367,7 @@ class XendAPI:
# wrap validators around class functions
for func_name in funcs + self.Base_funcs:
- func_full_name = '%s_%s' % (cls.lower(), func_name)
+ func_full_name = '%s_%s' % (cls, func_name)
try:
method = getattr(XendAPI, func_full_name)
method = session_required(method)
@@ -379,7 +380,7 @@ class XendAPI:
Base_attr_ro = ['uuid']
Base_attr_rw = []
- Base_methods = ['destroy', 'to_XML', 'get_record']
+ Base_methods = ['destroy', 'get_record']
Base_funcs = ['create', 'get_by_uuid', 'get_all']
# Xen API: Class Session
@@ -411,8 +412,6 @@ class XendAPI:
record = {'this_host': XendNode.instance().uuid,
'this_user': auth_manager().get_user(session)}
return xen_api_success(record)
- def session_to_XML(self, session):
- return xen_api_todo()
# attributes (ro)
def session_get_this_host(self, session):
@@ -536,8 +535,6 @@ class XendAPI:
'features': node.get_host_cpu_features(host_cpu_ref),
'utilisation': node.get_host_cpu_load(host_cpu_ref)}
return xen_api_success(record)
- def host_cpu_to_XML(self, session, host_cpu_ref):
- return xen_api_todo()
# class methods
def host_cpu_get_all(self, session):
@@ -656,304 +653,301 @@ class XendAPI:
'otherConfig']
# attributes (ro)
- def vm_get_power_state(self, session, vm_ref):
+ def VM_get_power_state(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.state)
- def vm_get_resident_on(self, session, vm_ref):
+ def VM_get_resident_on(self, session, vm_ref):
return xen_api_success(XendNode.instance().uuid)
- def vm_get_memory_actual(self, session, vm_ref):
+ def VM_get_memory_actual(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo() # unsupported by xc
- def vm_get_memory_static_max(self, session, vm_ref):
+ def VM_get_memory_static_max(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_memory_static_max())
- def vm_get_memory_static_min(self, session, vm_ref):
+ def VM_get_memory_static_min(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_memory_static_min())
- def vm_get_VCPUs_number(self, session, vm_ref):
+ def VM_get_VCPUs_number(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.getVCpuCount())
- def vm_get_VCPUs_utilisation(self, session, vm_ref):
+ def VM_get_VCPUs_utilisation(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vcpus_util())
- def vm_get_VCPUs_features_required(self, session, vm_ref):
+ def VM_get_VCPUs_features_required(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo() # unsupported by xc
- def vm_get_VCPUs_can_use(self, session, vm_ref):
+ def VM_get_VCPUs_can_use(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo() # unsupported by xc
- def vm_get_VIFs(self, session, vm_ref):
+ def VM_get_VIFs(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vifs())
- def vm_get_VBDs(self, session, vm_ref):
+ def VM_get_VBDs(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vbds())
- def vm_get_VTPMs(self, session, vm_ref):
+ def VM_get_VTPMs(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_vtpms())
- def vm_get_PCI_bus(self, session, vm_ref):
+ def VM_get_PCI_bus(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo() # unsupported by xc
- def vm_get_tools_version(self, session, vm_ref):
+ def VM_get_tools_version(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo()
# attributes (rw)
- def vm_get_name_label(self, session, vm_ref):
+ def VM_get_name_label(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.getName())
- def vm_get_name_description(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_user_version(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_is_a_template(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_memory_dynamic_max(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_memory_dynamic_min(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_VCPUs_policy(self, session, vm_ref):
+ def VM_get_name_description(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_user_version(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_is_a_template(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_memory_dynamic_max(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success(dom.get_memory_dynamic_max())
+
+ def VM_get_memory_dynamic_min(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success(dom.get_memory_dynamic_min())
+
+ def VM_get_VCPUs_policy(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo() # need to access scheduler
- def vm_get_VCPUs_params(self, session, vm_ref):
+ def VM_get_VCPUs_params(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_todo() # need access to scheduler
- def vm_get_VCPUs_features_force_on(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_VCPUs_features_force_off(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_actions_after_shutdown(self, session, vm_ref):
+ def VM_get_VCPUs_features_force_on(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_VCPUs_features_force_off(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_actions_after_shutdown(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_on_shutdown())
- def vm_get_actions_after_reboot(self, session, vm_ref):
+ def VM_get_actions_after_reboot(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_on_reboot())
- def vm_get_actions_after_suspend(self, session, vm_ref):
+ def VM_get_actions_after_suspend(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_on_suspend())
- def vm_get_actions_after_crash(self, session, vm_ref):
+ def VM_get_actions_after_crash(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_on_crash())
- def vm_get_bios_boot(self, session, vm_ref):
+ def VM_get_bios_boot(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success(dom.get_bios_boot())
- def vm_get_platform_std_VGA(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_platform_serial(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_platform_localtime(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_platform_clock_offset(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_platform_enable_audio(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_platform_keymap(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_builder(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_get_boot_method(self, session, vm_ref):
+ def VM_get_platform_std_VGA(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_platform_serial(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_platform_localtime(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_platform_clock_offset(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_platform_enable_audio(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_platform_keymap(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_get_builder(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success(dom.get_builder())
+
+ def VM_get_boot_method(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success(dom.get_boot_method())
+
+ def VM_get_kernel_kernel(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success('')
- def vm_get_kernel_kernel(self, session, vm_ref):
+ def VM_get_kernel_initrd(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success('')
- def vm_get_kernel_initrd(self, session, vm_ref):
+ def VM_get_kernel_args(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success('')
- def vm_get_kernel_args(self, session, vm_ref):
+ def VM_get_grub_cmdline(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success('')
- def vm_get_grub_cmdline(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success('')
-
- def vm_get_otherConfig(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_todo()
-
- def vm_set_name_label(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_name_description(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_user_version(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_is_a_template(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_memory_dynamic_max(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_memory_dynamic_min(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_VCPUs_policy(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_VCPUs_params(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_VCPUs_features_force_on(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_VCPUs_features_force_off(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_actions_after_shutdown(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_actions_after_reboot(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_actions_after_suspend(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_actions_after_crash(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_bios_boot(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_platform_std_VGA(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_platform_serial(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_platform_localtime(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_platform_clock_offset(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_platform_enable_audio(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_builder(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_boot_method(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_kernel_kernel(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_kernel_initrd(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_kernel_args(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_grub_cmdline(self, session, vm_ref):
- dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
- return xen_api_success_void()
-
- def vm_set_otherConfig(self, session, vm_ref):
+ def VM_get_otherConfig(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_todo()
+
+ def VM_set_name_label(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_name_description(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_user_version(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_is_a_template(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_memory_dynamic_max(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_memory_dynamic_min(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_VCPUs_policy(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_VCPUs_params(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_VCPUs_features_force_on(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_VCPUs_features_force_off(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_actions_after_shutdown(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_actions_after_reboot(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_actions_after_suspend(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_actions_after_crash(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_bios_boot(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_platform_std_VGA(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_platform_serial(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_platform_localtime(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_platform_clock_offset(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_platform_enable_audio(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_builder(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_boot_method(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_kernel_kernel(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_kernel_initrd(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_kernel_args(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_grub_cmdline(self, session, vm_ref):
+ dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
+ return xen_api_success_void()
+
+ def VM_set_otherConfig(self, session, vm_ref):
dom = XendDomain.instance().get_vm_by_uuid(vm_ref)
return xen_api_success_void()
# class methods
- def vm_get_all(self, session):
- refs = [d.get_uuid() for d in XendDomain.instance().list()]
+ def VM_get_all(self, session):
+ refs = [d.get_uuid() for d in XendDomain.instance().list('all')]
return xen_api_success(refs)
- def vm_get_by_name_label(self, session, label):
+ def VM_get_by_name_label(self, session, label):
xendom = XendDomain.instance()
dom = xendom.domain_lookup_nr(label)
if dom:
return xen_api_success([dom.get_uuid()])
return xen_api_error(XEND_ERROR_VM_INVALID)
- def vm_create(self, session, vm_struct):
+ def VM_create(self, session, vm_struct):
xendom = XendDomain.instance()
domuuid = xendom.create_domain(vm_struct)
return xen_api_success(domuuid)
# object methods
- def vm_to_XML(self, session, vm_ref):
- return xen_api_todo()
-
- def vm_get_record(self, session, vm_ref):
+ def VM_get_record(self, session, vm_ref):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
if not xeninfo:
@@ -969,17 +963,17 @@ class XendAPI:
'resident_on': XendNode.instance().uuid,
'memory_static_min': xeninfo.get_memory_static_min(),
'memory_static_max': xeninfo.get_memory_static_max(),
- 'memory_dynamic_min': xeninfo.get_memory_static_min(),
- 'memory_dynamic_max': xeninfo.get_memory_static_max(),
+ 'memory_dynamic_min': xeninfo.get_memory_dynamic_min(),
+ 'memory_dynamic_max': xeninfo.get_memory_dynamic_max(),
'memory_actual': xeninfo.get_memory_static_min(),
- 'vcpus_policy': xeninfo.get_vcpus_policy(),
- 'vcpus_params': xeninfo.get_vcpus_params(),
- 'vcpus_number': xeninfo.getVCpuCount(),
- 'vcpus_utilisation': xeninfo.get_vcpus_util(),
- 'vcpus_features_required': [],
- 'vcpus_features_can_use': [],
- 'vcpus_features_force_on': [],
- 'vcpus_features_force_off': [],
+ 'VCPUs_policy': xeninfo.get_vcpus_policy(),
+ 'VCPUs_params': xeninfo.get_vcpus_params(),
+ 'VCPUs_number': xeninfo.getVCpuCount(),
+ 'VCPUs_utilisation': xeninfo.get_vcpus_util(),
+ 'VCPUs_features_required': [],
+ 'VCPUs_features_can_use': [],
+ 'VCPUs_features_force_on': [],
+ 'VCPUs_features_force_off': [],
'actions_after_shutdown': xeninfo.get_on_shutdown(),
'actions_after_reboot': xeninfo.get_on_reboot(),
'actions_after_suspend': xeninfo.get_on_suspend(),
@@ -1006,41 +1000,39 @@ class XendAPI:
}
return xen_api_success(record)
- def vm_clean_reboot(self, session, vm_ref):
+ def VM_clean_reboot(self, session, vm_ref):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
xeninfo.shutdown("reboot")
return xen_api_success_void()
- def vm_clean_shutdown(self, session, vm_ref):
+ def VM_clean_shutdown(self, session, vm_ref):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
xeninfo.shutdown("poweroff")
return xen_api_success_void()
- def vm_clone(self, session, vm_ref):
+ def VM_clone(self, session, vm_ref):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
- def vm_destroy(self, session, vm_ref):
+ def VM_destroy(self, session, vm_ref):
return do_vm_func("domain_delete", vm_ref)
- def vm_hard_reboot(self, session, vm_ref):
+ def VM_hard_reboot(self, session, vm_ref):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
- def vm_hard_shutdown(self, session, vm_ref):
+ def VM_hard_shutdown(self, session, vm_ref):
return do_vm_func("domain_destroy", vm_ref)
- def vm_pause(self, session, vm_ref):
+ def VM_pause(self, session, vm_ref):
return do_vm_func("domain_pause", vm_ref)
- def vm_resume(self, session, vm_ref, start_paused):
+ def VM_resume(self, session, vm_ref, start_paused):
return do_vm_func("domain_resume", vm_ref, start_paused =
start_paused)
- def vm_start(self, session, vm_ref, start_paused):
+ def VM_start(self, session, vm_ref, start_paused):
return do_vm_func("domain_start", vm_ref, start_paused = start_paused)
- def vm_suspend(self, session, vm_ref):
+ def VM_suspend(self, session, vm_ref):
return do_vm_func("domain_suspend", vm_ref)
- def vm_unpause(self, session, vm_ref):
+ def VM_unpause(self, session, vm_ref):
return do_vm_func("domain_unpause", vm_ref)
-
- # Xen API: Class VDI
- # ----------------------------------------------------------------
- # TODO: NOT IMPLEMENTED.
# Xen API: Class VBD
# ----------------------------------------------------------------
+ # Note: accepts a non-API standard 'image' attribute to emulate
+ # regular xm created VBDs
VBD_attr_ro = ['image',
'IO_bandwidth_incoming_kbs',
@@ -1053,8 +1045,10 @@ class XendAPI:
VBD_attr_inst = VBD_attr_rw + ['image']
+ VBD_methods = ['media_change']
+
# object methods
- def vbd_get_record(self, session, vbd_ref):
+ def VBD_get_record(self, session, vbd_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vbd', vbd_ref)
if not vm:
@@ -1063,9 +1057,12 @@ class XendAPI:
if not cfg:
return xen_api_error(XEND_ERROR_VBD_INVALID)
return xen_api_success(cfg)
-
+
+ def VBD_media_change(self, session, vbd_ref, vdi_ref):
+ return xen_api_error(XEND_ERROR_UNSUPPORTED)
+
# class methods
- def vbd_create(self, session, vbd_struct):
+ def VBD_create(self, session, vbd_struct):
xendom = XendDomain.instance()
if not xendom.is_valid_vm(vbd_struct['VM']):
return xen_api_error(XEND_ERROR_DOMAIN_INVALID)
@@ -1092,22 +1089,22 @@ class XendAPI:
return xen_api_success(vbd_ref)
# attributes (rw)
- def vbd_get_VM(self, session, vbd_ref):
+ def VBD_get_VM(self, session, vbd_ref):
xendom = XendDomain.instance()
return xen_api_success(xendom.get_dev_property('vbd', vbd_ref, 'VM'))
- def vbd_get_VDI(self, session, vbd_ref):
- return xen_api_todo()
-
- def vbd_get_device(self, session, vbd_ref):
+ def VBD_get_VDI(self, session, vbd_ref):
+ return xen_api_todo()
+
+ def VBD_get_device(self, session, vbd_ref):
xendom = XendDomain.instance()
return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
'device'))
- def vbd_get_mode(self, session, vbd_ref):
+ def VBD_get_mode(self, session, vbd_ref):
xendom = XendDomain.instance()
return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
'mode'))
- def vbd_get_driver(self, session, vbd_ref):
+ def VBD_get_driver(self, session, vbd_ref):
xendom = XendDomain.instance()
return xen_api_success(xendom.get_dev_property('vbd', vbd_ref,
'driver'))
@@ -1130,7 +1127,7 @@ class XendAPI:
VIF_attr_inst = VIF_attr_rw
# object methods
- def vif_get_record(self, session, vif_ref):
+ def VIF_get_record(self, session, vif_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vif', vif_ref)
if not vm:
@@ -1147,7 +1144,7 @@ class XendAPI:
return xen_api_success(cfg)
# class methods
- def vif_create(self, session, vif_struct):
+ def VIF_create(self, session, vif_struct):
xendom = XendDomain.instance()
if xendom.is_valid_vm(vif_struct['VM']):
dom = xendom.get_vm_by_uuid(vif_struct['VM'])
@@ -1180,99 +1177,96 @@ class XendAPI:
VDI_methods = ['snapshot']
VDI_funcs = ['get_by_name_label']
- def vdi_get_VBDs(self, session, vdi_ref):
- return xen_api_todo()
-
- def vdi_get_physical_utilisation(self, session, vdi_ref):
+ def VDI_get_VBDs(self, session, vdi_ref):
+ return xen_api_todo()
+
+ def VDI_get_physical_utilisation(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.get_physical_utilisation())
- def vdi_get_sector_size(self, session, vdi_ref):
+ def VDI_get_sector_size(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.sector_size)
- def vdi_get_type(self, session, vdi_ref):
+ def VDI_get_type(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.type)
- def vdi_get_parent(self, session, vdi_ref):
+ def VDI_get_parent(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.parent)
- def vdi_get_children(self, session, vdi_ref):
+ def VDI_get_children(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.children)
- def vdi_get_name_label(self, session, vdi_ref):
+ def VDI_get_name_label(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.name_label)
- def vdi_get_name_description(self, session, vdi_ref):
+ def VDI_get_name_description(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.name_description)
- def vdi_get_SR(self, session, vdi_ref):
+ def VDI_get_SR(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
return xen_api_success(sr.uuid)
- def vdi_get_virtual_size(self, session, vdi_ref):
+ def VDI_get_virtual_size(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.virtual_size)
- def vdi_get_sharable(self, session, vdi_ref):
+ def VDI_get_sharable(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.sharable)
- def vdi_get_read_only(self, session, vdi_ref):
+ def VDI_get_read_only(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
return xen_api_success(image.sharable)
- def vdi_set_name_label(self, session, vdi_ref, value):
+ def VDI_set_name_label(self, session, vdi_ref, value):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
image.name_label = value
return xen_api_success_void()
- def vdi_set_name_description(self, session, vdi_ref, value):
+ def VDI_set_name_description(self, session, vdi_ref, value):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
image.name_description = value
return xen_api_success_void()
- def vdi_set_SR(self, session, vdi_ref, value):
+ def VDI_set_SR(self, session, vdi_ref, value):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
- def vdi_set_virtual_size(self, session, vdi_ref, value):
+ def VDI_set_virtual_size(self, session, vdi_ref, value):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
- def vdi_set_sharable(self, session, vdi_ref, value):
- return xen_api_todo()
- def vdi_set_read_only(self, session, vdi_ref, value):
+ def VDI_set_sharable(self, session, vdi_ref, value):
+ return xen_api_todo()
+ def VDI_set_read_only(self, session, vdi_ref, value):
return xen_api_todo()
# Object Methods
- def vdi_snapshot(self, session, vdi_ref):
- return xen_api_todo()
-
- def vdi_destroy(self, session, vdi_ref):
+ def VDI_snapshot(self, session, vdi_ref):
+ return xen_api_todo()
+
+ def VDI_destroy(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
sr.destroy_image(vdi_ref)
return xen_api_success_void()
- def vdi_to_XML(self, session, vdi_ref):
- return xen_api_todo()
-
- def vdi_get_record(self, session, vdi_ref):
+ def VDI_get_record(self, session, vdi_ref):
sr = XendNode.instance().get_sr()
image = sr.xen_api_get_by_uuid(vdi_ref)
if image:
@@ -1295,7 +1289,7 @@ class XendAPI:
return xen_api_error(XEND_ERROR_VDI_INVALID)
# Class Functions
- def vdi_create(self, session, vdi_struct):
+ def VDI_create(self, session, vdi_struct):
sr = XendNode.instance().get_sr()
sr_ref = vdi_struct['SR']
if sr.uuid != sr_ref:
@@ -1304,11 +1298,11 @@ class XendAPI:
vdi_uuid = sr.create_image(vdi_struct)
return xen_api_success(vdi_uuid)
- def vdi_get_all(self, session):
+ def VDI_get_all(self, session):
sr = XendNode.instance().get_sr()
return xen_api_success(sr.list_images())
- def vdi_get_by_name_label(self, session, name):
+ def VDI_get_by_name_label(self, session, name):
sr = XendNode.instance().get_sr()
image_uuid = sr.xen_api_get_by_name_label(name)
if image_uuid:
@@ -1329,7 +1323,7 @@ class XendAPI:
VTPM_attr_inst = VTPM_attr_rw
# object methods
- def vtpm_get_record(self, session, vtpm_ref):
+ def VTPM_get_record(self, session, vtpm_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
if not vm:
@@ -1346,7 +1340,7 @@ class XendAPI:
return xen_api_success(cfg)
# Class Functions
- def vtpm_get_instance(self, session, vtpm_ref):
+ def VTPM_get_instance(self, session, vtpm_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
if not vm:
@@ -1360,7 +1354,7 @@ class XendAPI:
instance = -1
return xen_api_success(instance)
- def vtpm_get_driver(self, session, vtpm_ref):
+ def VTPM_get_driver(self, session, vtpm_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
if not vm:
@@ -1374,7 +1368,7 @@ class XendAPI:
driver = "Unknown"
return xen_api_success(driver)
- def vtpm_get_backend(self, session, vtpm_ref):
+ def VTPM_get_backend(self, session, vtpm_ref):
xendom = XendDomain.instance()
vm = xendom.get_vm_with_dev_uuid('vtpm', vtpm_ref)
if not vm:
@@ -1388,12 +1382,12 @@ class XendAPI:
backend = "Domain-0"
return xen_api_success(backend)
- def vtpm_get_VM(self, session, vtpm_ref):
+ def VTPM_get_VM(self, session, vtpm_ref):
xendom = XendDomain.instance()
return xen_api_success(xendom.get_dev_property('vtpm', vtpm_ref, 'VM'))
# class methods
- def vtpm_create(self, session, vtpm_struct):
+ def VTPM_create(self, session, vtpm_struct):
xendom = XendDomain.instance()
if xendom.is_valid_vm(vtpm_struct['VM']):
dom = xendom.get_vm_by_uuid(vtpm_struct['VM'])
@@ -1429,32 +1423,30 @@ class XendAPI:
SR_funcs = ['get_by_name_label']
# Class Functions
- def sr_get_all(self, session):
+ def SR_get_all(self, session):
sr = XendNode.instance().get_sr()
return xen_api_success([sr.uuid])
- def sr_get_by_name_label(self, session, label):
+ def SR_get_by_name_label(self, session, label):
sr = XendNode.instance().get_sr()
if sr.name_label != label:
return xen_api_error(XEND_ERROR_SR_INVALID)
return xen_api_success([sr.uuid])
- def sr_create(self, session):
+ def SR_create(self, session):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
- def sr_get_by_uuid(self, session):
+ def SR_get_by_uuid(self, session):
return xen_api_success(XendNode.instance().get_sr().uuid)
# Class Methods
- def sr_clone(self, session, sr_ref):
+ def SR_clone(self, session, sr_ref):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
- def sr_destroy(self, session, sr_ref):
+
+ def SR_destroy(self, session, sr_ref):
return xen_api_error(XEND_ERROR_UNSUPPORTED)
- def sr_to_XML(self, session, sr_ref):
- return xen_api_todo()
-
- def sr_get_record(self, session, sr_ref):
+ def SR_get_record(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return xen_api_success({
'uuid': sr.uuid,
@@ -1469,44 +1461,44 @@ class XendAPI:
})
# Attribute acceess
- def sr_get_VDIs(self, session, sr_ref):
+ def SR_get_VDIs(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return xen_api_success(sr.list_images())
- def sr_get_virtual_allocation(self, session, sr_ref):
+ def SR_get_virtual_allocation(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return sr.used_space_bytes()
- def sr_get_physical_utilisation(self, session, sr_ref):
+ def SR_get_physical_utilisation(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return sr.used_space_bytes()
- def sr_get_physical_size(self, session, sr_ref):
+ def SR_get_physical_size(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return sr.total_space_bytes()
- def sr_get_type(self, session, sr_ref):
+ def SR_get_type(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return xen_api_success(sr.type)
- def sr_get_location(self, session, sr_ref):
+ def SR_get_location(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return xen_api_success(sr.location)
- def sr_get_name_label(self, session, sr_ref):
+ def SR_get_name_label(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return xen_api_success(sr.name_label)
- def sr_get_name_description(self, session, sr_ref):
+ def SR_get_name_description(self, session, sr_ref):
sr = XendNode.instance().get_sr()
return xen_api_success(sr.name_description)
- def sr_set_name_label(self, session, sr_ref, value):
+ def SR_set_name_label(self, session, sr_ref, value):
sr = XendNode.instance().get_sr()
sr.name_label = value
return xen_api_success_void()
- def sr_set_name_description(self, session, sr_ref, value):
+ def SR_set_name_description(self, session, sr_ref, value):
sr = XendNode.instance().get_sr()
sr.name_description = value
return xen_api_success_void()
@@ -1525,24 +1517,24 @@ if __name__ == "__main__":
methods = getattr(XendAPI, '%s_methods' % cls, [])
funcs = getattr(XendAPI, '%s_funcs' % cls, [])
- ref = '%s_ref' % cls.lower()
+ ref = '%s_ref' % cls
for attr_name in ro_attrs + rw_attrs + XendAPI.Base_attr_ro:
- getter_name = '%s_get_%s' % (cls.lower(), attr_name.lower())
+ getter_name = '%s_get_%s' % (cls, attr_name)
output('def %s(self, session, %s):' % (getter_name, ref))
output(' return xen_api_todo()')
for attr_name in rw_attrs + XendAPI.Base_attr_rw:
- setter_name = '%s_set_%s' % (cls.lower(), attr_name.lower())
+ setter_name = '%s_set_%s' % (cls, attr_name)
output('def %s(self, session, %s, value):' % (setter_name, ref))
output(' return xen_api_todo()')
for method_name in methods + XendAPI.Base_methods:
- method_full_name = '%s_%s' % (cls.lower(),method_name.lower())
+ method_full_name = '%s_%s' % (cls,method_name)
output('def %s(self, session, %s):' % (method_full_name, ref))
output(' return xen_api_todo()')
for func_name in funcs + XendAPI.Base_funcs:
- func_full_name = '%s_%s' % (cls.lower(), func_name.lower())
+ func_full_name = '%s_%s' % (cls, func_name)
output('def %s(self, session):' % func_full_name)
output(' return xen_api_todo()')
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendCheckpoint.py
--- a/tools/python/xen/xend/XendCheckpoint.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendCheckpoint.py Mon Dec 04 08:24:41 2006 -0700
@@ -18,8 +18,8 @@ from xen.xend import balloon, sxp
from xen.xend import balloon, sxp
from xen.xend.XendError import XendError, VmError
from xen.xend.XendLogging import log
+from xen.xend.XendConfig import XendConfig
from xen.xend.XendConstants import *
-from xen.xend.XendConfig import XendConfig
SIGNATURE = "LinuxGuestRecord"
XC_SAVE = "xc_save"
@@ -137,7 +137,7 @@ def restore(xd, fd, dominfo = None, paus
vmconfig = p.get_val()
if dominfo:
- dominfo.update(XendConfig(sxp = vmconfig), refresh = False)
+ dominfo.update(XendConfig(sxp_obj = vmconfig), refresh = False)
dominfo.resume()
else:
dominfo = xd.restore_(vmconfig)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendConfig.py
--- a/tools/python/xen/xend/XendConfig.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendConfig.py Mon Dec 04 08:24:41 2006 -0700
@@ -31,143 +31,197 @@ XendConfig API
XendConfig API
XendConfig will try to mirror as closely the Xen API VM Struct
- providing a backwards compatibility mode for SXP dumping, loading.
+ with extra parameters for those options that are not supported.
"""
-
-LEGACY_CFG_TO_XENAPI_CFG = {
+def reverse_dict(adict):
+ """Return the reverse mapping of a dictionary."""
+ return dict([(v, k) for k, v in adict.items()])
+
+def bool0(v):
+ return v != '0' and bool(v)
+
+# Mapping from XendConfig configuration keys to the old
+# legacy configuration keys that map directly.
+
+XENAPI_CFG_TO_LEGACY_CFG = {
'uuid': 'uuid',
- 'vcpus': 'vcpus_number',
- 'maxmem': 'memory_static_max',
- 'memory': 'memory_static_min',
- 'name': 'name_label',
- 'on_poweroff': 'actions_after_shutdown',
- 'on_reboot': 'actions_after_reboot',
- 'on_crash': 'actions_after_crash',
- 'bootloader': 'boot_method',
- 'kernel_kernel': 'kernel_kernel',
- 'kernel_initrd': 'kernel_initrd',
- 'kernel_args': 'kernel_args',
- }
-
-XENAPI_CFG_CUSTOM_TRANSLATE = [
- 'vifs',
- 'vbds',
- ]
-
+ 'vcpus_number': 'vcpus',
+ 'memory_static_min': 'memory',
+ 'memory_static_max': 'maxmem',
+ 'name_label': 'name',
+ 'actions_after_shutdown': 'on_poweroff',
+ 'actions_after_reboot': 'on_reboot',
+ 'actions_after_crash': 'on_crash',
+ 'platform_localtime': 'localtime',
+}
+
+LEGACY_CFG_TO_XENAPI_CFG = reverse_dict(XENAPI_CFG_TO_LEGACY_CFG)
+
+# Mapping from XendConfig configuration keys to the old
+# legacy configuration keys that are found in the 'image'
+# SXP object.
XENAPI_HVM_CFG = {
- 'platform_std_vga': 'std-vga',
+ 'platform_std_vga': 'stdvga',
'platform_serial' : 'serial',
'platform_localtime': 'localtime',
'platform_enable_audio': 'soundhw',
'platform_keymap' : 'keymap',
}
-XENAPI_UNSUPPORTED_IN_LEGACY_CFG = [
- 'name_description',
- 'user_version',
- 'is_a_template',
- 'memory_dynamic_min',
- 'memory_dynamic_max',
- 'memory_actual',
- 'vcpus_policy',
- 'vcpus_params',
- 'vcpus_features_required',
- 'vcpus_features_can_use',
- 'vcpus_features_force_on',
- 'vcpus_features_force_off',
- 'actions_after_suspend',
- 'bios_boot',
- 'platform_std_vga',
- 'platform_serial',
- 'platform_localtime',
- 'platform_clock_offset',
- 'platform_enable_audio',
- 'platform_keymap',
- 'builder',
- 'grub_cmdline',
- 'pci_bus',
- 'otherconfig'
- ]
-
-
-# configuration params that need to be converted to ints
-# since the XMLRPC transport for Xen API does not use
-# 32 bit ints but string representation of 64 bit ints.
-XENAPI_INT_CFG = [
- 'user_version',
- 'vcpus_number',
- 'memory_static_min',
- 'memory_static_max',
- 'memory_dynamic_min',
- 'memory_dynamic_max',
- 'tpm_instance',
- 'tpm_backend',
-]
-
-##
-## Xend Configuration Parameters
-##
-
-
-# All parameters of VMs that may be configured on-the-fly, or at start-up.
-VM_CONFIG_ENTRIES = [
- ('name', str),
- ('on_crash', str),
- ('on_poweroff', str),
- ('on_reboot', str),
- ('on_xend_start', str),
- ('on_xend_stop', str),
+# List of XendConfig configuration keys that have no equivalent
+# in the old world.
+
+XENAPI_CFG_TYPES = {
+ 'uuid': str,
+ 'power_state': str,
+ 'name_label': str,
+ 'name_description': str,
+ 'user_version': str,
+ 'is_a_template': bool0,
+ 'resident_on': str,
+ 'memory_static_min': int,
+ 'memory_static_max': int,
+ 'memory_dynamic_min': int,
+ 'memory_dynamic_max': int,
+ 'memory_actual': int,
+ 'vcpus_policy': str,
+ 'vcpus_params': str,
+ 'vcpus_number': int,
+ 'vcpus_features_required': list,
+ 'vcpus_features_can_use': list,
+ 'vcpus_features_force_on': list,
+ 'vcpus_features_force_off': list,
+ 'actions_after_shutdown': str,
+ 'actions_after_reboot': str,
+ 'actions_after_suspend': str,
+ 'actions_after_crash': str,
+ 'tpm_instance': int,
+ 'tpm_backend': int,
+ 'bios_boot': str,
+ 'platform_std_vga': bool0,
+ 'platform_serial': str,
+ 'platform_localtime': bool0,
+ 'platform_clock_offset': bool0,
+ 'platform_enable_audio': bool0,
+ 'platform_keymap': str,
+ 'boot_method': str,
+ 'builder': str,
+ 'kernel_kernel': str,
+ 'kernel_initrd': str,
+ 'kernel_args': str,
+ 'grub_cmdline': str,
+ 'pci_bus': str,
+ 'tools_version': dict,
+ 'otherconfig': dict,
+}
+
+# List of legacy configuration keys that have no equivalent in the
+# Xen API, but are still stored in XendConfig.
+
+LEGACY_UNSUPPORTED_BY_XENAPI_CFG = [
+ # roundtripped (dynamic, unmodified)
+ 'shadow_memory',
+ 'security',
+ 'vcpu_avail',
+ 'cpu_weight',
+ 'cpu_cap',
+ 'bootloader',
+ 'bootloader_args',
+ 'features',
+ # read/write
+ 'on_xend_start',
+ 'on_xend_stop',
+ # read-only
+ 'domid',
+ 'start_time',
+ 'cpu_time',
+ 'online_vcpus',
+ # write-once
+ 'cpu',
+ 'cpus',
]
-# All entries written to the store. This is VM_CONFIG_ENTRIES, plus those
-# entries written to the store that cannot be reconfigured on-the-fly.
-VM_STORE_ENTRIES = [
- ('uuid', str),
- ('vcpus', int),
- ('vcpu_avail', int),
- ('memory', int),
- ('maxmem', int),
- ('start_time', float),
+LEGACY_CFG_TYPES = {
+ 'uuid': str,
+ 'name': str,
+ 'vcpus': int,
+ 'vcpu_avail': int,
+ 'memory': int,
+ 'shadow_memory': int,
+ 'maxmem': int,
+ 'start_time': float,
+ 'cpu_cap': int,
+ 'cpu_weight': int,
+ 'cpu_time': float,
+ 'bootloader': str,
+ 'bootloader_args': str,
+ 'features': str,
+ 'localtime': int,
+ 'name': str,
+ 'on_poweroff': str,
+ 'on_reboot': str,
+ 'on_crash': str,
+ 'on_xend_stop': str,
+ 'on_xend_start': str,
+ 'online_vcpus': int,
+}
+
+# Values that should be stored in xenstore's /vm/<uuid> that is used
+# by Xend. Used in XendDomainInfo to restore running VM state from
+# xenstore.
+LEGACY_XENSTORE_VM_PARAMS = [
+ 'uuid',
+ 'name',
+ 'vcpus',
+ 'vcpu_avail',
+ 'memory',
+ 'shadow_memory',
+ 'maxmem',
+ 'start_time',
+ 'name',
+ 'on_poweroff',
+ 'on_crash',
+ 'on_reboot',
+ 'on_xend_start',
+ 'on_xend_stop',
]
-VM_STORED_ENTRIES = VM_CONFIG_ENTRIES + VM_STORE_ENTRIES
-
-# Configuration entries that we expect to round-trip -- be read from the
-# config file or xc, written to save-files (i.e. through sxpr), and reused as
-# config on restart or restore, all without munging. Some configuration
-# entries are munged for backwards compatibility reasons, or because they
-# don't come out of xc in the same form as they are specified in the config
-# file, so those are handled separately.
-
-ROUNDTRIPPING_CONFIG_ENTRIES = [
- ('uuid', str),
- ('vcpus', int),
- ('vcpu_avail', int),
- ('cpu_cap', int),
- ('cpu_weight', int),
- ('memory', int),
- ('shadow_memory', int),
- ('maxmem', int),
- ('bootloader', str),
- ('bootloader_args', str),
- ('features', str),
- ('localtime', int),
+LEGACY_IMAGE_CFG = [
+ ('root', str),
+ ('ip', str),
+ ('nographic', int),
+ ('vnc', int),
+ ('sdl', int),
+ ('vncdisplay', int),
+ ('vncunused', int),
+ ('vncpasswd', str),
]
-ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_ENTRIES
-
-## Static Configuration
-
-STATIC_CONFIG_ENTRIES = [
- ('cpu', int),
- ('cpus', str),
- ('image', list),
- ('security', list), # TODO: what if null?
+
+LEGACY_IMAGE_HVM_CFG = [
+ ('device_model', str),
+ ('display', str),
+ ('xauthority', str),
+ ('vncconsole', int),
+ ('pae', int),
+ ('apic', int),
]
-DEPRECATED_ENTRIES = [
- ('restart', str),
+LEGACY_IMAGE_HVM_DEVICES_CFG = [
+ ('acpi', int),
+ ('boot', str),
+ ('fda', str),
+ ('fdb', str),
+ ('isa', str),
+ ('keymap', str),
+ ('localtime', str),
+ ('serial', str),
+ ('stdvga', int),
+ ('soundhw', str),
+ ('usb', str),
+ ('usbdevice', str),
+ ('vcpus', int),
]
##
@@ -178,245 +232,172 @@ CONFIG_OLD_DOM_STATES = ('running', 'blo
CONFIG_OLD_DOM_STATES = ('running', 'blocked', 'paused', 'shutdown',
'crashed', 'dying')
-##
-## Defaults
-##
-
-def DEFAULT_VCPUS(info):
- if 'max_vcpu_id' in info: return int(info['max_vcpu_id']) + 1
- else: return 1
-
-DEFAULT_CONFIGURATION = (
- ('uuid', lambda info: uuid.createString()),
- ('name', lambda info: 'Domain-' + info['uuid']),
-
- ('on_poweroff', lambda info: 'destroy'),
- ('on_reboot', lambda info: 'restart'),
- ('on_crash', lambda info: 'restart'),
- ('features', lambda info: ''),
-
-
- ('memory', lambda info: 0),
- ('shadow_memory',lambda info: 0),
- ('maxmem', lambda info: 0),
- ('bootloader', lambda info: None),
- ('bootloader_args', lambda info: None),
- ('backend', lambda info: []),
- ('device', lambda info: {}),
- ('image', lambda info: None),
- ('security', lambda info: []),
- ('on_xend_start', lambda info: 'ignore'),
- ('on_xend_stop', lambda info: 'ignore'),
-
- ('cpus', lambda info: []),
- ('cpu_cap', lambda info: 0),
- ('cpu_weight', lambda info: 256),
- ('vcpus', lambda info: DEFAULT_VCPUS(info)),
- ('online_vcpus', lambda info: info['vcpus']),
- ('max_vcpu_id', lambda info: info['vcpus']-1),
- ('vcpu_avail', lambda info: (1<<info['vcpus'])-1),
-
- # New for Xen API
- ('kernel_kernel', lambda info: ''),
- ('kernel_initrd', lambda info: ''),
- ('kernel_args', lambda info: ''),
-
-)
-
class XendConfigError(VmError):
def __str__(self):
return 'Invalid Configuration: %s' % str(self.value)
##
-## XendConfig SXP Config Compat
-##
-
-class XendSXPConfig:
- def get_domid(self):
- pass
- def get_handle(self):
- return self['uuid']
-
-
-##
## XendConfig Class (an extended dictionary)
##
class XendConfig(dict):
- """ Generic Configuration Parser accepting SXP, Python or XML.
- This is a dictionary-like object that is populated.
-
- @ivar legacy: dictionary holding legacy xen domain info
- @ivar xenapi: dictionary holding xen api config info
+ """ The new Xend VM Configuration.
+
+ Stores the configuration in xenapi compatible format but retains
+ import and export functions for SXP.
"""
-
- def __init__(self, filename = None, fd = None,
- sxp = None, xml = None, pycfg = None, xenapi_vm = None,
- cfg = {}):
- """Constructor. Provide either the filename, fd or sxp.
-
- @keyword filename: filename of an SXP file
- @keyword fd: file descriptor of an SXP file
- @keyword sxp: a list of list of a parsed SXP
- @keyword xml: an XML tree object
- @keyword xenapi_vm: a struct passed from an XMLRPC call (Xen API)
- @keyword cfg: a dictionary of configuration (eg. from xc)
- """
- format = 'unknown'
-
- self.xenapi = {}
-
- if filename and not fd:
- fd = open(filename, 'r')
-
- if fd:
- format = self._detect_format(fd)
-
- if fd:
- if format == 'sxp':
- sxp = self._read_sxp(fd)
- elif format == 'python' and filename != None:
- pycfg = self._read_python(filename)
- elif format == 'python' and filename == None:
- raise XendConfigError("Python files must be passed as a "
- "filename rather than file descriptor.")
- elif format == 'xml':
- xml = self._read_xml(fd)
- else:
- raise XendConfigError("Unable to determine format of file")
-
- if sxp:
- cfg = self._populate_from_sxp(sxp)
- if xml:
- cfg = self._populate_from_xml(xml)
- if pycfg:
- cfg = self._populate_from_python_config(pycfg)
- if xenapi_vm:
- cfg = self._populate_from_xenapi_vm(xenapi_vm)
+ def __init__(self, filename = None, sxp_obj = None,
+ xapi = None, dominfo = None):
+
+ dict.__init__(self)
+ self.update(self._defaults())
+
+ if filename:
+ try:
+ sxp_obj = sxp.parse(open(filename,'r'))
+ sxp_obj = sxp_obj[0]
+ except IOError, e:
+ raise XendConfigError("Unable to read file: %s" % filename)
+
+ if sxp_obj:
+ self._sxp_to_xapi(sxp_obj)
+ self._sxp_to_xapi_unsupported(sxp_obj)
+ elif xapi:
+ self.update_with_xenapi_config(xapi)
+ self._add_xapi_unsupported()
+ elif dominfo:
+ # output from xc.domain_getinfo
+ self._dominfo_to_xapi(dominfo)
+
+ log.debug('XendConfig.init: %s' % self)
+
+ # validators go here
+ self.validate()
+
+ """ In time, we should enable this type checking addition. It is great
+ also for tracking bugs and unintended writes to XendDomainInfo.info
+ def __setitem__(self, key, value):
+ type_conv = XENAPI_CFG_TYPES.get(key)
+ if callable(type_conv):
+ try:
+ dict.__setitem__(self, key, type_conv(value))
+ except (ValueError, TypeError):
+ raise XendConfigError("Wrong type for configuration value " +
+ "%s. Expected %s" %
+ (key, type_conv.__name__))
+ else:
+ dict.__setitem__(self, key, value)
+ """
+
+ def _defaults(self):
+ defaults = {
+ 'uuid': uuid.createString(),
+ 'name_label': 'Domain-Unnamed',
+ 'actions_after_shutdown': 'destroy',
+ 'actions_after_reboot': 'restart',
+ 'actions_after_crash': 'restart',
+ 'actions_after_suspend': '',
+ 'features': '',
+ 'builder': 'linux',
+ 'memory_static_min': 0,
+ 'memory_dynamic_min': 0,
+ 'shadow_memory': 0,
+ 'memory_static_max': 0,
+ 'memory_dynamic_max': 0,
+ 'memory_actual': 0,
+ 'boot_method': None,
+ 'bootloader': None,
+ 'bootloader_args': None,
+ 'devices': {},
+ 'image': {},
+ 'security': None,
+ 'on_xend_start': 'ignore',
+ 'on_xend_stop': 'ignore',
+ 'cpus': [],
+ 'cpu_weight': 256,
+ 'cpu_cap': 0,
+ 'vcpus_number': 1,
+ 'online_vcpus': 1,
+ 'max_vcpu_id': 0,
+ 'vcpu_avail': 1,
+ 'vif_refs': [],
+ 'vbd_refs': [],
+ 'vtpm_refs': [],
+ }
+
+ defaults['name_label'] = 'Domain-' + defaults['uuid']
+ return defaults
+
+ def _memory_sanity_check(self):
+ if self['memory_static_min'] == 0:
+ self['memory_static_min'] = self['memory_dynamic_min']
+
+ # If the static max is not set, let's set it to dynamic max.
+ # If the static max is smaller than static min, then fix it!
+ self['memory_static_max'] = max(self['memory_static_max'],
+ self['memory_dynamic_max'],
+ self['memory_static_min'])
+
+ for mem_type in ('memory_static_min', 'memory_static_max'):
+ if self[mem_type] <= 0:
+ raise XendConfigError('Memory value too low for %s: %d' %
+ (mem_type, self[mem_type]))
+
+ def _actions_sanity_check(self):
+ for event in ['shutdown', 'reboot', 'crash']:
+ if self['actions_after_' + event] not in CONFIG_RESTART_MODES:
+ raise XendConfigError('Invalid event handling mode: ' +
+ event)
+
+ def _builder_sanity_check(self):
+ if self['builder'] not in ('hvm', 'linux'):
+ raise XendConfigError('Invalid builder configuration')
+
+ def validate(self):
+ self._memory_sanity_check()
+ self._actions_sanity_check()
+ self._builder_sanity_check()
+
+ def _dominfo_to_xapi(self, dominfo):
+ self['domid'] = dominfo['domid']
+ self['online_vcpus'] = dominfo['online_vcpus']
+ self['max_vcpu_id'] = dominfo['max_vcpu_id']
+ self['memory_dynamic_min'] = (dominfo['mem_kb'] + 1023)/1024
+ self['memory_dynamic_max'] = (dominfo['maxmem_kb'] + 1023)/1024
+ self['cpu_time'] = dominfo['cpu_time']/1e9
+ # TODO: i don't know what the security stuff expects here
+ if dominfo.get('ssidref'):
+ self['security'] = [['ssidref', dominfo['ssidref']]]
+ self['shutdown_reason'] = dominfo['shutdown_reason']
+
+ # parse state into Xen API states
+ self['running'] = dominfo['running']
+ self['crashed'] = dominfo['crashed']
+ self['dying'] = dominfo['dying']
+ self['shutdown'] = dominfo['shutdown']
+ self['paused'] = dominfo['paused']
+ self['blocked'] = dominfo['blocked']
+
+ if 'name' in dominfo:
+ self['name_label'] = dominfo['name']
+
+ if 'handle' in dominfo:
+ self['uuid'] = uuid.toString(dominfo['handle'])
- if cfg:
- self.update(cfg)
-
- if xenapi_vm:
- self.xenapi.update(xenapi_vm)
-
- log.debug('XendConfig: %s' % str(self))
- self.validate()
-
- #
- # Xen API Attribute Access
- #
-
- def __getattr__(self, name):
- try:
- return dict.__getattr__(self, name)
- except AttributeError:
- try:
- return self.__dict__['xenapi'][name]
- except KeyError:
- raise AttributeError("XendConfig Xen API has no attribute "
- "'%s'" % name)
-
-
- def __setattr__(self, name, value):
- try:
- return dict.__setattr__(self, name, value)
- except AttributeError:
- self.xenapi[name] = value
- #self.set_legacy_api_with_xen_api_value(name, value)
-
- def __delattr__(self, name):
- try:
- dict.__delattr__(self, name)
- except AttributeError:
- del self.xenapi[name]
- #self.del_legacy_api_with_xen_api_key(name)
-
-
- """
- #
- # Legacy API Attribute Access
- #
-
- def __getitem__(self, key):
- try:
- return self.legacy[key]
- except KeyError:
- raise AttributeError, "XendConfig Legacy has no attribute '%s'"\
- % key
-
- def __setitem__(self, key, value):
- self.legacy[key] = value
- self.set_xen_api_with_legacy_api_value(key, value)
-
- def __delitem__(self, key):
- del self.legacy[key]
- self.del_xen_api_with_legacy_api_key(key)
- """
-
-
- def _detect_format(self, fd):
- """Detect the format of the configuration passed.
-
- @param fd: file descriptor of contents to detect
- @rtype: string, 'sxp', 'xml', 'python' or 'unknown'
- """
- format = 'unknown'
-
- fd.seek(0)
- for line in fd:
- stripped = line.strip()
- if stripped:
- if re.search(r'^\(', stripped):
- format = 'sxp'
- elif re.search(r'^\<?xml', stripped):
- format = 'xml'
- else:
- format = 'python'
- break
-
- fd.seek(0)
- return format
-
- def _read_sxp(self, fd):
- """ Read and parse SXP (from SXP to list of lists)
-
- @rtype: list of lists.
- """
- try:
- parsed = sxp.parse(fd)[0]
- return parsed
- except:
- raise
- return None
-
- def _read_xml(self, fd):
- """TODO: Read and parse XML (from XML to dict)
-
- @rtype: dict
- """
- raise NotImplementedError
-
- def _read_python(self, filename):
- """Read and parse python module that represents the config.
-
- @rtype: dict
- """
- cfg_globals = {}
- execfile(filename, cfg_globals, {})
- return cfg_globals
-
- def _populate_from_sxp(self, parsed):
+ def _parse_sxp(self, sxp_cfg):
""" Populate this XendConfig using the parsed SXP.
+ @param sxp_cfg: Parsed SXP Configuration
+ @type sxp_cfg: list of lists
@rtype: dictionary
+ @return: A dictionary containing the parsed options of the SXP.
"""
cfg = {}
# First step is to convert deprecated options to
# current equivalents.
- restart = sxp.child_value(parsed, 'restart')
+ restart = sxp.child_value(sxp_cfg, 'restart')
if restart:
if restart == 'onreboot':
cfg['on_poweroff'] = 'destroy'
@@ -433,23 +414,19 @@ class XendConfig(dict):
'restart = \'%s\'', restart)
# Only extract options we know about.
- all_params = VM_CONFIG_ENTRIES + ROUNDTRIPPING_CONFIG_ENTRIES + \
- STATIC_CONFIG_ENTRIES
-
- for key, typeconv in all_params:
- val = sxp.child_value(parsed, key)
- if val:
+ extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG
+ extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values()
+
+ for key in extract_keys:
+ val = sxp.child_value(sxp_cfg, key)
+ if val != None:
try:
- cfg[key] = typeconv(val)
- except ValueError:
- pass
-
- # Manually extract other complex configuration
- # options.
-
- cfg['backend'] = []
- for c in sxp.children(parsed, 'backend'):
- cfg['backend'].append(sxp.name(sxp.child0(c)))
+ cfg[key] = LEGACY_CFG_TYPES[key](val)
+ except KeyError:
+ cfg[key] = val
+ except (TypeError, ValueError), e:
+ log.warn("Unable to parse key %s: %s: %s" %
+ (key, str(val), e))
# Parsing the device SXP's. In most cases, the SXP looks
# like this:
@@ -472,65 +449,52 @@ class XendConfig(dict):
# Hence we deal with pci device configurations outside of
# the regular device parsing.
- cfg['device'] = {}
- for dev in sxp.children(parsed, 'device'):
+ cfg['devices'] = {}
+ for dev in sxp.children(sxp_cfg, 'device'):
config = sxp.child0(dev)
dev_type = sxp.name(config)
dev_info = {}
if dev_type == 'pci':
- continue
-
- for opt, val in config[1:]:
- dev_info[opt] = val
- log.debug("XendConfig: reading device: %s" % dev_info)
- # create uuid if it doesn't
- dev_uuid = dev_info.get('uuid', uuid.createString())
- dev_info['uuid'] = dev_uuid
- cfg['device'][dev_uuid] = (dev_type, dev_info)
-
- # deal with PCI device configurations if they exist
- for dev in sxp.children(parsed, 'device'):
- config = sxp.child0(dev)
- dev_type = sxp.name(config)
-
- if dev_type != 'pci':
- continue
-
- dev_attr = sxp.child_value(config, 'dev')
- if isinstance(dev_attr, (types.ListType, types.TupleType)):
+ pci_devs_uuid = sxp.child_value(config, 'uuid',
+ uuid.createString())
+ pci_devs = []
for pci_dev in sxp.children(config, 'dev'):
- dev_info = {}
+ pci_dev_info = {}
for opt, val in pci_dev[1:]:
- dev_info[opt] = val
- log.debug("XendConfig: reading device: %s" % dev_info)
- dev_uuid = dev_info.get('uuid', uuid.createString())
- dev_info['uuid'] = dev_uuid
- cfg['device'][dev_uuid] = (dev_type, dev_info)
-
- else: # Xen 2.0 PCI device configuration
+ pci_dev_info[opt] = val
+ pci_devs.append(pci_dev_info)
+
+ cfg['devices'][pci_devs_uuid] = (dev_type,
+ {'devs': pci_devs,
+ 'uuid': pci_devs_uuid})
+
+ log.debug("XendConfig: reading device: %s" % pci_devs)
+ else:
for opt, val in config[1:]:
dev_info[opt] = val
log.debug("XendConfig: reading device: %s" % dev_info)
# create uuid if it doesn't
dev_uuid = dev_info.get('uuid', uuid.createString())
dev_info['uuid'] = dev_uuid
- cfg['device'][dev_uuid] = (dev_type, dev_info)
+ cfg['devices'][dev_uuid] = (dev_type, dev_info)
+
# Extract missing data from configuration entries
- if 'image' in cfg:
- image_vcpus = sxp.child_value(cfg['image'], 'vcpus')
- if image_vcpus is not None:
+ image_sxp = sxp.child_value(sxp_cfg, 'image', [])
+ if image_sxp:
+ image_vcpus = sxp.child_value(image_sxp, 'vcpus')
+ if image_vcpus != None:
try:
- if 'vcpus' not in cfg:
- cfg['vcpus'] = int(image_vcpus)
- elif cfg['vcpus'] != int(image_vcpus):
- cfg['vcpus'] = int(image_vcpus)
+ if 'vcpus_number' not in cfg:
+ cfg['vcpus_number'] = int(image_vcpus)
+ elif cfg['vcpus_number'] != int(image_vcpus):
+ cfg['vcpus_number'] = int(image_vcpus)
log.warn('Overriding vcpus from %d to %d using image'
- 'vcpus value.', cfg['vcpus'])
+ 'vcpus value.', cfg['vcpus_number'])
except ValueError, e:
raise XendConfigError('integer expeceted: %s: %s' %
- str(cfg['image']), e)
+ image_sxp, e)
# Deprecated cpu configuration
if 'cpu' in cfg:
@@ -564,101 +528,188 @@ class XendConfig(dict):
except ValueError, e:
raise XendConfigError('cpus = %s: %s' % (cfg['cpus'], e))
- # Parse image SXP outside of image.py
- # - used to be only done in image.py
- if 'image' in cfg:
- cfg['kernel_kernel'] = sxp.child_value(cfg['image'], 'kernel','')
- cfg['kernel_initrd'] = sxp.child_value(cfg['image'], 'ramdisk','')
- kernel_args = sxp.child_value(cfg['image'], 'args', '')
-
- # attempt to extract extra arguments from SXP config
- arg_ip = sxp.child_value(cfg['image'], 'ip')
- if arg_ip: kernel_args += ' ip=%s' % arg_ip
- arg_root = sxp.child_value(cfg['image'], 'root')
- if arg_root: kernel_args += ' root=%s' % arg_root
-
- cfg['kernel_args'] = kernel_args
+ if 'security' in cfg and isinstance(cfg['security'], str):
+ cfg['security'] = sxp.from_string(cfg['security'])
# TODO: get states
- old_state = sxp.child_value(parsed, 'state')
+ old_state = sxp.child_value(sxp_cfg, 'state')
if old_state:
for i in range(len(CONFIG_OLD_DOM_STATES)):
cfg[CONFIG_OLD_DOM_STATES[i]] = int(old_state[i] != '-')
- # Xen API extra cfgs
- # ------------------
- cfg['vif_refs'] = []
- cfg['vbd_refs'] = []
- cfg['vtpm_refs'] = []
- for dev_uuid, (dev_type, dev_info) in cfg['device'].items():
- if dev_type == 'vif':
- cfg['vif_refs'].append(dev_uuid)
- elif dev_type in ('vbd','tap'):
- cfg['vbd_refs'].append(dev_uuid)
- elif dev_type == 'vtpm':
- cfg['vtpm_refs'].append(dev_uuid)
-
return cfg
-
-
- def _populate_from_xenapi_vm(self, xenapi_vm):
- cfg = {}
-
- for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
+
+
+ def _sxp_to_xapi(self, sxp_cfg):
+ """Read in an SXP Configuration object and
+ populate at much of the Xen API with valid values.
+ """
+ cfg = self._parse_sxp(sxp_cfg)
+
+ # Convert parameters that can be directly mapped from
+ # the Legacy Config to Xen API Config
+
+ for apikey, cfgkey in XENAPI_CFG_TO_LEGACY_CFG.items():
try:
- if apikey in XENAPI_INT_CFG:
- cfg[cfgkey] = int(xenapi_vm[apikey])
+ type_conv = XENAPI_CFG_TYPES.get(apikey)
+ if callable(type_conv):
+ self[apikey] = type_conv(cfg[cfgkey])
else:
- cfg[cfgkey] = xenapi_vm[apikey]
+ log.warn("Unconverted key: " + apikey)
+ self[apikey] = cfg[cfgkey]
except KeyError:
pass
- # Reconstruct image SXP
- # TODO: get rid of SXP altogether from here
- sxp_image = ['linux']
- if xenapi_vm['kernel_kernel']:
- sxp_image.append(['kernel', xenapi_vm['kernel_kernel']])
- if xenapi_vm['kernel_initrd']:
- sxp_image.append(['ramdisk', xenapi_vm['kernel_initrd']])
- if xenapi_vm['kernel_args']:
- sxp_image.append(['args', xenapi_vm['kernel_args']])
-
- cfg['image'] = prettyprintstring(sxp_image)
-
- # make sure device structures are there.
- if 'device' not in cfg:
- cfg['device'] = {}
- if 'vif_refs' not in cfg:
- cfg['vif_refs'] = []
- if 'vbd_refs' not in cfg:
- cfg['vbd_refs'] = []
- if 'vtpm_refs' not in cfg:
- cfg['vtpm_refs'] = []
-
- return cfg
-
-
- def _sync_xen_api_from_legacy_api(self):
- """ Sync all the attributes that is supported by the Xen API
- from the legacy API configuration.
+ # Convert Legacy "image" config to Xen API kernel_*
+ # configuration
+ image_sxp = sxp.child_value(sxp_cfg, 'image', [])
+ if image_sxp:
+ self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
+ self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
+ kernel_args = sxp.child_value(image_sxp, 'args', '')
+
+ # attempt to extract extra arguments from SXP config
+ arg_ip = sxp.child_value(image_sxp, 'ip')
+ if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
+ kernel_args += ' ip=%s' % arg_ip
+ arg_root = sxp.child_value(image_sxp, 'root')
+ if arg_root and not re.search(r'root=[^ ]+', kernel_args):
+ kernel_args += ' root=%s' % arg_root
+
+ self['kernel_args'] = kernel_args
+
+ # Convert Legacy HVM parameters to Xen API configuration
+ self['platform_std_vga'] = bool0(cfg.get('stdvga', 0))
+ self['platform_serial'] = str(cfg.get('serial', ''))
+ self['platform_localtime'] = bool0(cfg.get('localtime', 0))
+ self['platform_enable_audio'] = bool0(cfg.get('soundhw', 0))
+
+ # Convert path to bootloader to boot_method
+ if not cfg.get('bootloader'):
+ if self.get('kernel_kernel','').endswith('hvmloader'):
+ self['boot_method'] = 'bios'
+ else:
+ self['boot_method'] = 'kernel_external'
+ else:
+ self['boot_method'] = 'grub'
+
+ # make sure a sane maximum is set
+ if self['memory_static_max'] <= 0:
+ self['memory_static_max'] = self['memory_static_min']
+
+ self['memory_dynamic_max'] = self['memory_static_max']
+ self['memory_dynamic_min'] = self['memory_static_min']
+
+ # set device references in the configuration
+ self['devices'] = cfg.get('devices', {})
+
+ self['vif_refs'] = []
+ self['vbd_refs'] = []
+ self['vtpm_refs'] = []
+ for dev_uuid, (dev_type, dev_info) in self['devices'].items():
+ if dev_type == 'vif':
+ self['vif_refs'].append(dev_uuid)
+ elif dev_type in ('vbd','tap'):
+ self['vbd_refs'].append(dev_uuid)
+ elif dev_type in ('vtpm',):
+ self['vtpm_refs'].append(dev_uuid)
+
+
+ def _sxp_to_xapi_unsupported(self, sxp_cfg):
+ """Read in an SXP configuration object and populate
+ values are that not related directly supported in
+ the Xen API.
"""
- for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
- if cfgkey in self:
- self.xenapi[apikey] = self[cfgkey]
-
- def _sync_legacy_api_from_xen_api(self):
- for cfgkey, apikey in LEGACY_CFG_TO_XENAPI_CFG.items():
- if apikey in self.xenapi:
- self[cfgkey] = self.xenapi[apikey]
-
-
- def _populate_from_xml(self, parsed_xml):
- raise NotImplementedError
-
- def _populate_from_python_config(self, parsed_py):
- raise NotImplementedError
+
+ # Parse and convert parameters used to configure
+ # the image (as well as HVM images)
+ image_sxp = sxp.child_value(sxp_cfg, 'image', [])
+ if image_sxp:
+ image = {}
+ image['type'] = sxp.name(image_sxp)
+ for arg, conv in LEGACY_IMAGE_CFG:
+ val = sxp.child_value(image_sxp, arg, None)
+ if val != None:
+ image[arg] = conv(val)
+
+ image_hvm = {}
+ for arg, conv in LEGACY_IMAGE_HVM_CFG:
+ val = sxp.child_value(image_sxp, arg, None)
+ if val != None:
+ image_hvm[arg] = conv(val)
+
+ image_hvm_devices = {}
+ for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
+ val = sxp.child_value(image_sxp, arg, None)
+ if val != None:
+ image_hvm_devices[arg] = conv(val)
+
+ if image_hvm or image_hvm_devices:
+ image['hvm'] = image_hvm
+ image['hvm']['devices'] = image_hvm_devices
+
+ self['image'] = image
+
+ for apikey, imgkey in XENAPI_HVM_CFG.items():
+ val = sxp.child_value(image_sxp, imgkey, None)
+ if val != None:
+ self[apikey] = val
+
+ # extract backend value
+
+ backend = []
+ for c in sxp.children(sxp_cfg, 'backend'):
+ backend.append(sxp.name(sxp.child0(c)))
+ if backend:
+ self['backend'] = backend
+
+ if self['image'].has_key('hvm'):
+ self['builder'] = 'hvm'
+
+ # Parse and convert other Non Xen API parameters.
+ def _set_cfg_if_exists(sxp_arg):
+ val = sxp.child_value(sxp_cfg, sxp_arg)
+ if val != None:
+ if LEGACY_CFG_TYPES.get(sxp_arg):
+ self[sxp_arg] = LEGACY_CFG_TYPES[sxp_arg](val)
+ else:
+ self[sxp_arg] = val
+
+ _set_cfg_if_exists('shadow_memory')
+ _set_cfg_if_exists('security')
+ _set_cfg_if_exists('features')
+ _set_cfg_if_exists('on_xend_stop')
+ _set_cfg_if_exists('on_xend_start')
+ _set_cfg_if_exists('vcpu_avail')
+ _set_cfg_if_exists('max_vcpu_id') # TODO, deprecated?
+
+ # Parse and store runtime configuration
+ _set_cfg_if_exists('start_time')
+ _set_cfg_if_exists('online_vcpus')
+ _set_cfg_if_exists('cpu_time')
+ _set_cfg_if_exists('shutdown_reason')
+ _set_cfg_if_exists('up_time')
+ _set_cfg_if_exists('status') # TODO, deprecated
+
+ def _add_xapi_unsupported(self):
+ """Updates the configuration object with entries that are not
+ officially supported by the Xen API but is required for
+ the rest of Xend to function.
+ """
+
+ # populate image
+ self['image']['type'] = self['builder']
+ if self['builder'] == 'hvm':
+ self['image']['hvm'] = {}
+ for xapi, cfgapi in XENAPI_HVM_CFG.items():
+ self['image']['hvm'][cfgapi] = self[xapi]
+
def _get_old_state_string(self):
+ """Returns the old xm state string.
+ @rtype: string
+ @return: old state string
+ """
state_string = ''
for state_name in CONFIG_OLD_DOM_STATES:
on_off = self.get(state_name, 0)
@@ -669,8 +720,40 @@ class XendConfig(dict):
return state_string
- def get_sxp(self, domain = None, ignore_devices = False, ignore = []):
+
+ def update_config(self, dominfo):
+ """Update configuration with the output from xc.domain_getinfo().
+
+ @param dominfo: Domain information via xc.domain_getinfo()
+ @type dominfo: dict
+ """
+ self._dominfo_to_xapi(dominfo)
+ self.validate()
+
+ def update_with_xenapi_config(self, xapi):
+ """Update configuration with a Xen API VM struct
+
+ @param xapi: Xen API VM Struct
+ @type xapi: dict
+ """
+ for key, val in xapi.items():
+ key = key.lower()
+ type_conv = XENAPI_CFG_TYPES.get(key)
+ if callable(type_conv):
+ self[key] = type_conv(val)
+ else:
+ self[key] = val
+
+ self.validate()
+
+ def to_xml(self):
+ """Return an XML string representing the configuration."""
+ pass
+
+ def to_sxp(self, domain = None, ignore_devices = False, ignore = []):
""" Get SXP representation of this config object.
+
+ Incompat: removed store_mfn, console_mfn
@keyword domain: (optional) XendDomainInfo to get extra information
from such as domid and running devices.
@@ -688,44 +771,36 @@ class XendConfig(dict):
if domain.getDomid() is not None:
sxpr.append(['domid', domain.getDomid()])
- for cfg, typefunc in ROUNDTRIPPING_CONFIG_ENTRIES:
- if cfg in self:
- if self[cfg] is not None:
- sxpr.append([cfg, self[cfg]])
-
- if 'image' in self and self['image'] is not None:
- sxpr.append(['image', self['image']])
- if 'security' in self and self['security']:
- sxpr.append(['security', self['security']])
- if 'shutdown_reason' in self:
- sxpr.append(['shutdown_reason', self['shutdown_reason']])
- if 'cpu_time' in self:
- sxpr.append(['cpu_time', self['cpu_time']/1e9])
-
- sxpr.append(['online_vcpus', self['online_vcpus']])
-
- if 'start_time' in self:
- uptime = time.time() - self['start_time']
- sxpr.append(['up_time', str(uptime)])
- sxpr.append(['start_time', str(self['start_time'])])
-
- if domain:
- sxpr.append(['status', str(domain.state)])
- else:
- sxpr.append(['status', str(DOM_STATE_HALTED)])
+ for xenapi, legacy in XENAPI_CFG_TO_LEGACY_CFG.items():
+ if self.has_key(xenapi) and self[xenapi] not in (None, []):
+ if type(self[xenapi]) == bool:
+ # convert booleans to ints before making an sxp item
+ sxpr.append([legacy, int(self[xenapi])])
+ else:
+ sxpr.append([legacy, self[xenapi]])
+
+ for legacy in LEGACY_UNSUPPORTED_BY_XENAPI_CFG:
+ if legacy in ('domid', 'uuid'): # skip these
+ continue
+ if self.has_key(legacy) and self[legacy] not in (None, []):
+ sxpr.append([legacy, self[legacy]])
+
+ if 'image' in self and self['image']:
+ sxpr.append(['image', self.image_sxpr()])
+
+ sxpr.append(['status', domain.state])
+ sxpr.append(['memory_dynamic_min', self.get('memory_dynamic_min')])
+ sxpr.append(['memory_dynamic_max', self.get('memory_dynamic_max')])
if domain.getDomid() is not None:
sxpr.append(['state', self._get_old_state_string()])
- sxpr.append(['memory_dynamic_max', self.get('memory_dynamic_max',
- self['memory'])])
-
- # For save/restore migration
if domain:
if domain.store_mfn:
sxpr.append(['store_mfn', domain.store_mfn])
if domain.console_mfn:
sxpr.append(['console_mfn', domain.console_mfn])
+
# Marshall devices (running or from configuration)
if not ignore_devices:
@@ -743,7 +818,7 @@ class XendConfig(dict):
except:
log.exception("dumping sxp from device controllers")
pass
-
+
# if we didn't find that device, check the existing config
# for a device in the same class
if not found:
@@ -751,58 +826,28 @@ class XendConfig(dict):
if dev_type == cls:
sxpr.append(['device', dev_info])
- return sxpr
-
- def validate(self):
- """ Validate the configuration and fill in missing configuration
- with defaults.
+ return sxpr
+
+ def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
+ """Add a device configuration in SXP format or XenAPI struct format.
+
+ For SXP, it could be either:
+
+ [device, [vbd, [uname ...]]
+
+ or:
+
+ [vbd, [uname ..]]
+
+ @type cfg_sxp: list of lists (parsed sxp object)
+ @param cfg_sxp: SXP configuration object
+ @type cfg_xenapi: dict
+ @param cfg_xenapi: A device configuration from Xen API (eg. vbd,vif)
+ @rtype: string
+ @return: Assigned UUID of the device.
"""
-
- # Fill in default values
- for key, default_func in DEFAULT_CONFIGURATION:
- if key not in self or self[key] == None:
- self[key] = default_func(self)
-
- # Basic sanity checks
- if 'image' in self and isinstance(self['image'], str):
- self['image'] = sxp.from_string(self['image'])
- if 'security' in self and isinstance(self['security'], str):
- self['security'] = sxp.from_string(self['security'])
- if self['memory'] == 0 and 'mem_kb' in self:
- self['memory'] = (self['mem_kb'] + 1023)/1024
- if self['memory'] <= 0:
- raise XendConfigError('Invalid memory size: %s' %
- str(self['memory']))
-
- self['maxmem'] = max(self['memory'], self['maxmem'])
-
- # convert mem_kb from domain_getinfo to something more descriptive
- if 'mem_kb' in self:
- self['memory_dynamic_max'] = (self['mem_kb'] + 1023)/1024
-
- # Verify devices
- for d_uuid, (d_type, d_info) in self['device'].items():
- if d_type not in XendDevices.valid_devices() and \
- d_type not in XendDevices.pseudo_devices():
- raise XendConfigError('Invalid device (%s)' % d_type)
-
- # Verify restart modes
- for event in ('on_poweroff', 'on_reboot', 'on_crash'):
- if self[event] not in CONFIG_RESTART_MODES:
- raise XendConfigError('Invalid restart event: %s = %s' % \
- (event, str(self[event])))
-
- # Verify that {vif,vbd}_refs are here too
- if 'vif_refs' not in self:
- self['vif_refs'] = []
- if 'vbd_refs' not in self:
- self['vbd_refs'] = []
- if 'vtpm_refs' not in self:
- self['vtpm_refs'] = []
-
- def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None):
if dev_type not in XendDevices.valid_devices() and \
- dev_type not in XendDevices.pseudo_devices():
+ dev_type not in XendDevices.pseudo_devices():
raise XendConfigError("XendConfig: %s not a valid device type" %
dev_type)
@@ -816,22 +861,48 @@ class XendConfig(dict):
log.debug("XendConfig.device_add: %s" % str(cfg_xenapi))
if cfg_sxp:
+ if sxp.child0(cfg_sxp) == 'device':
+ config = sxp.child0(cfg_sxp)
+ else:
+ config = cfg_sxp
+
+ dev_type = sxp.name(config)
dev_info = {}
try:
- for opt, val in cfg_sxp[1:]:
+ for opt, val in config[1:]:
dev_info[opt] = val
except ValueError:
pass # SXP has no options for this device
+
+ def _get_config_ipaddr(config):
+ val = []
+ for ipaddr in sxp.children(config, elt='ip'):
+ val.append(sxp.child0(ipaddr))
+ return val
+
+ if dev_type == 'vif' and 'ip' in dev_info:
+ dev_info['ip'] = _get_config_ipaddr(config)
+
+ if dev_type == 'vbd':
+ if dev_info.get('dev', '').startswith('ioemu:'):
+ dev_info['driver'] = 'ioemu'
+ else:
+ dev_info['driver'] = 'paravirtualised'
+
+
# create uuid if it doesn't exist
dev_uuid = dev_info.get('uuid', uuid.createString())
dev_info['uuid'] = dev_uuid
- self['device'][dev_uuid] = (dev_type, dev_info)
- if dev_type in ('vif', 'vbd'):
+
+ # store dev references by uuid for certain device types
+ self['devices'][dev_uuid] = (dev_type, dev_info)
+ if dev_type in ('vif', 'vbd', 'vtpm'):
self['%s_refs' % dev_type].append(dev_uuid)
elif dev_type in ('tap',):
self['vbd_refs'].append(dev_uuid)
+
return dev_uuid
if cfg_xenapi:
@@ -849,13 +920,21 @@ class XendConfig(dict):
dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
dev_info['uuid'] = dev_uuid
- self['device'][dev_uuid] = (dev_type, dev_info)
+ self['devices'][dev_uuid] = (dev_type, dev_info)
self['vif_refs'].append(dev_uuid)
return dev_uuid
- elif dev_type == 'vbd':
- dev_info['uname'] = cfg_xenapi.get('image', None)
- dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
+ elif dev_type in ('vbd', 'tap'):
+ if dev_type == 'vbd':
+ dev_info['uname'] = cfg_xenapi.get('image', '')
+ dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
+ elif dev_type == 'tap':
+ dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
+ dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
+
+ dev_info['driver'] = cfg_xenapi.get('driver')
+ dev_info['VDI'] = cfg_xenapi.get('VDI', '')
+
if cfg_xenapi.get('mode') == 'RW':
dev_info['mode'] = 'w'
else:
@@ -863,35 +942,43 @@ class XendConfig(dict):
dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
dev_info['uuid'] = dev_uuid
- self['device'][dev_uuid] = (dev_type, dev_info)
+ self['devices'][dev_uuid] = (dev_type, dev_info)
self['vbd_refs'].append(dev_uuid)
return dev_uuid
- elif dev_type == 'vtpm':
+ elif dev_type in ('vtpm'):
if cfg_xenapi.get('type'):
dev_info['type'] = cfg_xenapi.get('type')
+
dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
dev_info['uuid'] = dev_uuid
- self['device'][dev_uuid] = (dev_type, dev_info)
+ self['devices'][dev_uuid] = (dev_type, dev_info)
self['vtpm_refs'].append(dev_uuid)
return dev_uuid
- elif dev_type == 'tap':
- dev_info['uname'] = 'tap:qcow:%s' % cfg_xenapi.get('image')
- dev_info['dev'] = '%s:disk' % cfg_xenapi.get('device')
-
- if cfg_xenapi.get('mode') == 'RW':
- dev_info['mode'] = 'w'
- else:
- dev_info['mode'] = 'r'
-
- dev_uuid = cfg_xenapi.get('uuid', uuid.createString())
- dev_info['uuid'] = dev_uuid
- self['device'][dev_uuid] = (dev_type, dev_info)
- self['vbd_refs'].append(dev_uuid)
- return dev_uuid
-
return ''
+
+ def device_update(self, dev_uuid, cfg_sxp):
+ """Update an existing device with the new configuration.
+
+ @rtype: boolean
+ @return: Returns True if succesfully found and updated a device conf
+ """
+ if dev_uuid in self['devices']:
+ config = sxp.child0(cfg_sxp)
+ dev_type = sxp.name(config)
+ dev_info = {}
+
+ try:
+ for opt, val in config[1:]:
+ self['devices'][opt] = val
+ except ValueError:
+ pass # SXP has no options for this device
+
+ return True
+
+ return False
+
def device_sxpr(self, dev_uuid = None, dev_type = None, dev_info = None):
"""Get Device SXPR by either giving the device UUID or (type, config).
@@ -900,8 +987,8 @@ class XendConfig(dict):
@return: device config sxpr
"""
sxpr = []
- if dev_uuid != None and dev_uuid in self['device']:
- dev_type, dev_info = self['device'][dev_uuid]
+ if dev_uuid != None and dev_uuid in self['devices']:
+ dev_type, dev_info = self['devices'][dev_uuid]
if dev_type == None or dev_info == None:
raise XendConfigError("Required either UUID or device type and "
@@ -917,27 +1004,106 @@ class XendConfig(dict):
"""Returns the SXPR for all devices in the current configuration."""
sxprs = []
pci_devs = []
- for dev_type, dev_info in self['device'].values():
+
+ if 'devices' not in self:
+ return sxprs
+
+ for dev_type, dev_info in self['devices'].values():
if dev_type == 'pci': # special case for pci devices
- pci_devs.append(dev_info)
+ sxpr = [['uuid', dev_info['uuid']]]
+ for pci_dev_info in dev_info['devs']:
+ pci_dev_sxpr = ['dev']
+ for opt, val in pci_dev_info.items():
+ pci_dev_sxpr.append([opt, val])
+ sxpr.append(pci_dev_sxpr)
+ sxprs.append((dev_type, sxpr))
else:
sxpr = self.device_sxpr(dev_type = dev_type,
dev_info = dev_info)
sxprs.append((dev_type, sxpr))
- # if we have any pci_devs, we parse them differently into
- # one single pci SXP entry.
- if pci_devs:
- sxpr = ['pci',]
- for dev_info in pci_devs:
- dev_sxpr = self.device_sxpr(dev_type = 'dev',
- dev_info = dev_info)
- sxpr.append(dev_sxpr)
- sxprs.append(('pci', sxpr))
-
return sxprs
-
+ def image_sxpr(self):
+ """Returns a backwards compatible image SXP expression that is
+ used in xenstore's /vm/<uuid>/image value and xm list."""
+ image = [self['image'].get('type', 'linux')]
+ if self.has_key('kernel_kernel'):
+ image.append(['kernel', self['kernel_kernel']])
+ if self.has_key('kernel_initrd') and self['kernel_initrd']:
+ image.append(['ramdisk', self['kernel_initrd']])
+ if self.has_key('kernel_args') and self['kernel_args']:
+ image.append(['args', self['kernel_args']])
+
+ for arg, conv in LEGACY_IMAGE_CFG:
+ if self['image'].has_key(arg):
+ image.append([arg, self['image'][arg]])
+
+ if 'hvm' in self['image']:
+ for arg, conv in LEGACY_IMAGE_HVM_CFG:
+ if self['image']['hvm'].get(arg):
+ image.append([arg, self['image']['hvm'][arg]])
+
+ if 'hvm' in self['image'] and 'devices' in self['image']['hvm']:
+ for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
+ if self['image']['hvm']['devices'].get(arg):
+ image.append([arg,
+ self['image']['hvm']['devices'][arg]])
+
+ return image
+
+ def update_with_image_sxp(self, image_sxp):
+ # Convert Legacy "image" config to Xen API kernel_*
+ # configuration
+ self['kernel_kernel'] = sxp.child_value(image_sxp, 'kernel','')
+ self['kernel_initrd'] = sxp.child_value(image_sxp, 'ramdisk','')
+ kernel_args = sxp.child_value(image_sxp, 'args', '')
+
+ # attempt to extract extra arguments from SXP config
+ arg_ip = sxp.child_value(image_sxp, 'ip')
+ if arg_ip and not re.search(r'ip=[^ ]+', kernel_args):
+ kernel_args += ' ip=%s' % arg_ip
+ arg_root = sxp.child_value(image_sxp, 'root')
+ if arg_root and not re.search(r'root=', kernel_args):
+ kernel_args += ' root=%s' % arg_root
+ self['kernel_args'] = kernel_args
+
+ # Store image SXP in python dictionary format
+ image = {}
+ image['type'] = sxp.name(image_sxp)
+ for arg, conv in LEGACY_IMAGE_CFG:
+ val = sxp.child_value(image_sxp, arg, None)
+ if val != None:
+ image[arg] = conv(val)
+
+ image_hvm = {}
+ for arg, conv in LEGACY_IMAGE_HVM_CFG:
+ val = sxp.child_value(image_sxp, arg, None)
+ if val != None:
+ image_hvm[arg] = conv(val)
+
+ image_hvm_devices = {}
+ for arg, conv in LEGACY_IMAGE_HVM_DEVICES_CFG:
+ val = sxp.child_value(image_sxp, arg, None)
+ if val != None:
+ image_hvm_devices[arg] = conv(val)
+
+ if image_hvm or image_hvm_devices:
+ image['hvm'] = image_hvm
+ image['hvm']['devices'] = image_hvm_devices
+
+ self['image'] = image
+
+ for apikey, imgkey in XENAPI_HVM_CFG.items():
+ val = sxp.child_value(image_sxp, imgkey, None)
+ if val != None:
+ type_conv = XENAPI_CFG_TYPES[apikey]
+ if callable(conv):
+ self[apikey] = type_conv(val)
+ else:
+ self[apikey] = val
+
+
#
# debugging
#
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendConstants.py
--- a/tools/python/xen/xend/XendConstants.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendConstants.py Mon Dec 04 08:24:41 2006 -0700
@@ -34,6 +34,8 @@ DOMAIN_SHUTDOWN_REASONS = {
DOMAIN_CRASH : "crash",
DOMAIN_HALT : "halt"
}
+REVERSE_DOMAIN_SHUTDOWN_REASONS = \
+ dict([(y, x) for x, y in DOMAIN_SHUTDOWN_REASONS.items()])
restart_modes = [
"restart",
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendDevices.py
--- a/tools/python/xen/xend/XendDevices.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendDevices.py Mon Dec 04 08:24:41 2006 -0700
@@ -19,7 +19,7 @@
# A collection of DevControllers
#
-from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif
+from xen.xend.server import blkif, netif, tpmif, pciif, iopif, irqif, usbif,
vfbif
from xen.xend.server.BlktapController import BlktapController
class XendDevices:
@@ -41,6 +41,8 @@ class XendDevices:
'irq': irqif.IRQController,
'usb': usbif.UsbifController,
'tap': BlktapController,
+ 'vfb': vfbif.VfbifController,
+ 'vkbd': vfbif.VkbdifController,
}
#@classmethod
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendDomain.py Mon Dec 04 08:24:41 2006 -0700
@@ -23,6 +23,7 @@
"""
import os
+import stat
import shutil
import socket
import threading
@@ -44,7 +45,7 @@ from xen.xend.XendDevices import XendDev
from xen.xend.xenstore.xstransact import xstransact
from xen.xend.xenstore.xswatch import xswatch
-from xen.util import security
+from xen.util import mkdir, security
from xen.xend import uuid
xc = xen.lowlevel.xc.xc()
@@ -99,11 +100,7 @@ class XendDomain:
"""Singleton initialisation function."""
dom_path = self._managed_path()
- try:
- os.stat(dom_path)
- except OSError:
- log.info("Making %s", dom_path)
- os.makedirs(dom_path, 0755)
+ mkdir.parents(dom_path, stat.S_IRWXU)
xstransact.Mkdir(XS_VMROOT)
xstransact.SetPermissions(XS_VMROOT, {'dom': DOM0_ID})
@@ -184,7 +181,7 @@ class XendDomain:
if not dom_uuid:
continue
- dom_name = dom.get('name', 'Domain-%s' % dom_uuid)
+ dom_name = dom.get('name_label', 'Domain-%s' % dom_uuid)
try:
running_dom = self.domain_lookup_nr(dom_name)
if not running_dom:
@@ -271,25 +268,17 @@ class XendDomain:
domains_dir = self._managed_path()
dom_uuid = dominfo.get_uuid()
domain_config_dir = self._managed_path(dom_uuid)
-
- # make sure the domain dir exists
- if not os.path.exists(domains_dir):
- os.makedirs(domains_dir, 0755)
- elif not os.path.isdir(domains_dir):
- log.error("xend_domain_dir is not a directory.")
- raise XendError("Unable to save managed configuration "
- "because %s is not a directory." %
- domains_dir)
-
- if not os.path.exists(domain_config_dir):
+
+ def make_or_raise(path):
try:
- os.makedirs(domain_config_dir, 0755)
- except IOError:
- log.exception("Failed to create directory: %s" %
- domain_config_dir)
- raise XendError("Failed to create directory: %s" %
- domain_config_dir)
-
+ mkdir.parents(path, stat.S_IRWXU)
+ except:
+ log.exception("%s could not be created." % path)
+ raise XendError("%s could not be created." % path)
+
+ make_or_raise(domains_dir)
+ make_or_raise(domain_config_dir)
+
try:
sxp_cache_file = open(self._managed_config_path(dom_uuid),'w')
prettyprint(dominfo.sxpr(), sxp_cache_file, width = 78)
@@ -423,7 +412,6 @@ class XendDomain:
self._remove_domain(dom, domid)
-
def _add_domain(self, info):
"""Add a domain to the list of running domains
@@ -433,6 +421,11 @@ class XendDomain:
"""
log.debug("Adding Domain: %s" % info.getDomid())
self.domains[info.getDomid()] = info
+
+ # update the managed domains with a new XendDomainInfo object
+ # if we are keeping track of it.
+ if info.get_uuid() in self.managed_domains:
+ self._managed_domain_register(info)
def _remove_domain(self, info, domid = None):
"""Remove the domain from the list of running domains
@@ -669,7 +662,7 @@ class XendDomain:
self.domains_lock.acquire()
try:
try:
- xeninfo = XendConfig(xenapi_vm = xenapi_vm)
+ xeninfo = XendConfig(xapi = xenapi_vm)
dominfo = XendDomainInfo.createDormant(xeninfo)
log.debug("Creating new managed domain: %s: %s" %
(dominfo.getName(), dominfo.get_uuid()))
@@ -873,8 +866,8 @@ class XendDomain:
self.domains_lock.acquire()
try:
try:
- xeninfo = XendConfig(sxp = config)
- dominfo = XendDomainInfo.createDormant(xeninfo)
+ domconfig = XendConfig(sxp_obj = config)
+ dominfo = XendDomainInfo.createDormant(domconfig)
log.debug("Creating new managed domain: %s" %
dominfo.getName())
self._managed_domain_register(dominfo)
@@ -935,6 +928,9 @@ class XendDomain:
if dominfo.state != DOM_STATE_HALTED:
raise XendError("Domain is still running")
+
+ log.info("Domain %s (%s) deleted." %
+ (dominfo.getName(), dominfo.info.get('uuid')))
self._managed_domain_unregister(dominfo)
self._remove_domain(dominfo)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon Dec 04 08:24:41 2006 -0700
@@ -38,10 +38,9 @@ from xen.util import security
from xen.util import security
from xen.xend import balloon, sxp, uuid, image, arch
-from xen.xend import XendRoot, XendNode
+from xen.xend import XendRoot, XendNode, XendConfig
from xen.xend.XendBootloader import bootloader
-from xen.xend.XendConfig import XendConfig
from xen.xend.XendError import XendError, VmError
from xen.xend.XendDevices import XendDevices
from xen.xend.xenstore.xstransact import xstransact, complete
@@ -57,6 +56,11 @@ xroot = XendRoot.instance()
log = logging.getLogger("xend.XendDomainInfo")
#log.setLevel(logging.TRACE)
+
+
+def bool0(v):
+ return v != "0" and bool(v)
+
##
# All parameters of VMs that may be configured on-the-fly, or at start-up.
@@ -88,7 +92,7 @@ ROUNDTRIPPING_CONFIG_ENTRIES = [
('bootloader', str),
('bootloader_args', str),
('features', str),
- ('localtime', int),
+ ('localtime', bool0),
]
ROUNDTRIPPING_CONFIG_ENTRIES += VM_CONFIG_PARAMS
@@ -145,7 +149,7 @@ def create(config):
"""
log.debug("XendDomainInfo.create(%s)", config)
- vm = XendDomainInfo(XendConfig(sxp = config))
+ vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config))
try:
vm.start()
except:
@@ -175,10 +179,9 @@ def recreate(info, priv):
assert not info['dying']
- xeninfo = XendConfig(cfg = info)
+ xeninfo = XendConfig.XendConfig(dominfo = info)
domid = xeninfo['domid']
- uuid1 = xeninfo['handle']
- xeninfo['uuid'] = uuid.toString(uuid1)
+ uuid1 = uuid.fromString(xeninfo['uuid'])
needs_reinitialising = False
dompath = GetDomainPath(domid)
@@ -228,6 +231,15 @@ def recreate(info, priv):
vm._storeVmDetails()
vm._storeDomDetails()
+ if vm.info['image']: # Only dom0 should be without an image entry when
+ # recreating, but we cope with missing ones
+ # elsewhere just in case.
+ vm.image = image.create(vm,
+ vm.info,
+ vm.info['image'],
+ vm.info['devices'])
+ vm.image.recreate()
+
vm._registerWatches()
vm.refreshShutdown(xeninfo)
return vm
@@ -236,7 +248,7 @@ def restore(config):
def restore(config):
"""Create a domain and a VM object to do a restore.
- @param config: Domain configuration object
+ @param config: Domain SXP configuration
@type config: list of lists. (see C{create})
@rtype: XendDomainInfo
@@ -246,7 +258,8 @@ def restore(config):
"""
log.debug("XendDomainInfo.restore(%s)", config)
- vm = XendDomainInfo(XendConfig(sxp = config), resume = True)
+ vm = XendDomainInfo(XendConfig.XendConfig(sxp_obj = config),
+ resume = True)
try:
vm.resume()
return vm
@@ -254,24 +267,24 @@ def restore(config):
vm.destroy()
raise
-def createDormant(xeninfo):
+def createDormant(domconfig):
"""Create a dormant/inactive XenDomainInfo without creating VM.
This is for creating instances of persistent domains that are not
yet start.
- @param xeninfo: Parsed configuration
- @type xeninfo: dictionary
+ @param domconfig: Parsed configuration
+ @type domconfig: XendConfig object
@rtype: XendDomainInfo
@return: A up and running XendDomainInfo instance
@raise XendError: Errors with configuration.
"""
- log.debug("XendDomainInfo.createDormant(%s)", xeninfo)
+ log.debug("XendDomainInfo.createDormant(%s)", domconfig)
# domid does not make sense for non-running domains.
- xeninfo.pop('domid', None)
- vm = XendDomainInfo(XendConfig(cfg = xeninfo))
+ domconfig.pop('domid', None)
+ vm = XendDomainInfo(domconfig)
return vm
def domain_by_name(name):
@@ -383,14 +396,6 @@ class XendDomainInfo:
#if not self._infoIsSet('uuid'):
# self.info['uuid'] = uuid.toString(uuid.create())
- #REMOVE: domid logic can be shortened
- #if domid is not None:
- # self.domid = domid
- #elif info.has_key('dom'):
- # self.domid = int(info['dom'])
- #else:
- # self.domid = None
-
self.vmpath = XS_VMROOT + self.info['uuid']
self.dompath = dompath
@@ -403,6 +408,7 @@ class XendDomainInfo:
self.vmWatch = None
self.shutdownWatch = None
self.shutdownStartTime = None
+ self._resume = resume
self.state = DOM_STATE_HALTED
self.state_updated = threading.Condition()
@@ -416,8 +422,7 @@ class XendDomainInfo:
if augment:
self._augmentInfo(priv)
- self._checkName(self.info['name'])
- self.setResume(resume)
+ self._checkName(self.info['name_label'])
#
@@ -477,10 +482,11 @@ class XendDomainInfo:
if self.domid == 0:
raise XendError('Domain 0 cannot be shutdown')
- if not reason in DOMAIN_SHUTDOWN_REASONS.values():
+ if reason not in DOMAIN_SHUTDOWN_REASONS.values():
raise XendError('Invalid reason: %s' % reason)
- self._storeDom("control/shutdown", reason)
-
+ self._removeVm('xend/previous_restart_time')
+ self.storeDom("control/shutdown", reason)
+
def pause(self):
"""Pause domain
@@ -506,18 +512,20 @@ class XendDomainInfo:
def send_sysrq(self, key):
""" Send a Sysrq equivalent key via xenstored."""
asserts.isCharConvertible(key)
- self._storeDom("control/sysrq", '%c' % key)
+ self.storeDom("control/sysrq", '%c' % key)
def device_create(self, dev_config):
"""Create a new device.
@param dev_config: device configuration
- @type dev_config: dictionary (parsed config)
+ @type dev_config: SXP object (parsed config)
"""
log.debug("XendDomainInfo.device_create: %s" % dev_config)
dev_type = sxp.name(dev_config)
- devid = self._createDevice(dev_type, dev_config)
- self.info.device_add(dev_type, cfg_sxp = dev_config)
+ dev_uuid = self.info.device_add(dev_type, cfg_sxp = dev_config)
+ dev_config_dict = self.info['devices'][dev_uuid][1]
+ log.debug("XendDomainInfo.device_create: %s" % dev_config_dict)
+ devid = self._createDevice(dev_type, dev_config_dict)
self._waitForDevice(dev_type, devid)
return self.getDeviceController(dev_type).sxpr(devid)
@@ -525,12 +533,26 @@ class XendDomainInfo:
"""Configure an existing device.
@param dev_config: device configuration
- @type dev_config: dictionary (parsed config)
+ @type dev_config: SXP object (parsed config)
@param devid: device id
@type devid: int
+ @return: Returns True if successfully updated device
+ @rtype: boolean
"""
deviceClass = sxp.name(dev_config)
- self._reconfigureDevice(deviceClass, devid, dev_config)
+
+ # look up uuid of the device
+ dev_control = self.getDeviceController(deviceClass)
+ dev_sxpr = dev_control.sxpr(devid)
+ dev_uuid = sxp.child_value(sxpr, 'uuid')
+ if not dev_uuid:
+ return False
+
+ self.info.device_update(dev_uuid, dev_config)
+ dev_config_dict = self.info['devices'].get(dev_uuid)
+ if dev_config_dict:
+ dev_control.reconfigureDevice(devid, dev_config_dict[1])
+ return True
def waitForDevices(self):
"""Wait for this domain's configured devices to connect.
@@ -558,8 +580,18 @@ class XendDomainInfo:
return self.getDeviceController(deviceClass).destroyDevice(devid)
+
def getDeviceSxprs(self, deviceClass):
- return self.getDeviceController(deviceClass).sxprs()
+ if self.state == DOM_STATE_RUNNING:
+ return self.getDeviceController(deviceClass).sxprs()
+ else:
+ sxprs = []
+ dev_num = 0
+ for dev_type, dev_info in self.info.all_devices_sxpr():
+ if dev_type == deviceClass:
+ sxprs.append([dev_num, dev_info])
+ dev_num += 1
+ return sxprs
def setMemoryTarget(self, target):
@@ -567,22 +599,22 @@ class XendDomainInfo:
@param target: In MiB.
"""
log.debug("Setting memory target of domain %s (%d) to %d MiB.",
- self.info['name'], self.domid, target)
+ self.info['name_label'], self.domid, target)
if target <= 0:
raise XendError('Invalid memory size')
- self.info['memory'] = target
+ self.info['memory_static_min'] = target
self.storeVm("memory", target)
- self._storeDom("memory/target", target << 10)
+ self.storeDom("memory/target", target << 10)
def getVCPUInfo(self):
try:
# We include the domain name and ID, to help xm.
sxpr = ['domain',
['domid', self.domid],
- ['name', self.info['name']],
- ['vcpu_count', self.info['online_vcpus']]]
+ ['name', self.info['name_label']],
+ ['vcpu_count', self.info['vcpus_number']]]
for i in range(0, self.info['max_vcpu_id']+1):
info = xc.vcpu_getinfo(self.domid, i)
@@ -610,30 +642,40 @@ class XendDomainInfo:
values taken from the store. This recovers those values known
to xend but not to the hypervisor.
"""
- def useIfNeeded(name, val):
- if not self._infoIsSet(name) and val is not None:
- self.info[name] = val
-
+ augment_entries = XendConfig.LEGACY_XENSTORE_VM_PARAMS[:]
if priv:
- entries = VM_STORE_ENTRIES[:]
- entries.remove(('memory', int))
- entries.remove(('maxmem', int))
- else:
- entries = VM_STORE_ENTRIES
- entries.append(('image', str))
- entries.append(('security', str))
-
- map(lambda x, y: useIfNeeded(x[0], y), entries,
- self._readVMDetails(entries))
-
+ augment_entries.remove('memory')
+ augment_entries.remove('maxmem')
+
+ vm_config = self._readVMDetails([(k, XendConfig.LEGACY_CFG_TYPES[k])
+ for k in augment_entries])
+
+ # make returned lists into a dictionary
+ vm_config = dict(zip(augment_entries, vm_config))
+
+ for arg in augment_entries:
+ xapicfg = arg
+ val = vm_config[arg]
+ if val != None:
+ if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
+ xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
+ self.info[xapiarg] = val
+ else:
+ self.info[arg] = val
+
+ # read image value
+ image_sxp = self._readVm('image')
+ if image_sxp:
+ self.info.update_with_image_sxp(sxp.from_string(image_sxp))
+
+ # read devices
devices = []
-
for devclass in XendDevices.valid_devices():
devconfig = self.getDeviceController(devclass).configurations()
if devconfig:
- devices.extend(map(lambda conf: (devclass, conf), devconfig))
-
- if not self.info['device'] and devices is not None:
+ devices.extend(devconfig)
+
+ if not self.info['devices'] and devices is not None:
for device in devices:
self.info.device_add(device[0], cfg_sxp = device)
@@ -660,8 +702,11 @@ class XendDomainInfo:
# Function to update xenstore /dom/*
#
- def _readDom(self, *args):
+ def readDom(self, *args):
return xstransact.Read(self.dompath, *args)
+
+ def gatherDom(self, *args):
+ return xstransact.Gather(self.dompath, *args)
def _writeDom(self, *args):
return xstransact.Write(self.dompath, *args)
@@ -669,7 +714,7 @@ class XendDomainInfo:
def _removeDom(self, *args):
return xstransact.Remove(self.dompath, *args)
- def _storeDom(self, *args):
+ def storeDom(self, *args):
return xstransact.Store(self.dompath, *args)
def _recreateDom(self):
@@ -678,16 +723,16 @@ class XendDomainInfo:
def _recreateDomFunc(self, t):
t.remove()
t.mkdir()
- t.set_permissions({ 'dom' : self.domid })
+ t.set_permissions({'dom' : self.domid})
t.write('vm', self.vmpath)
def _storeDomDetails(self):
to_store = {
'domid': str(self.domid),
'vm': self.vmpath,
- 'name': self.info['name'],
+ 'name': self.info['name_label'],
'console/limit': str(xroot.get_console_limit() * 1024),
- 'memory/target': str(self.info['memory'] * 1024)
+ 'memory/target': str(self.info['memory_static_min'] * 1024)
}
def f(n, v):
@@ -713,7 +758,7 @@ class XendDomainInfo:
return 'offline'
result = {}
- for v in range(0, self.info['vcpus']):
+ for v in range(0, self.info['vcpus_number']):
result["cpu/%d/availability" % v] = availability(v)
return result
@@ -735,19 +780,29 @@ class XendDomainInfo:
log.trace("XendDomainInfo.storeChanged");
changed = False
-
- def f(x, y):
- if y is not None and self.info[x[0]] != y:
- self.info[x[0]] = y
- changed = True
-
- map(f, VM_CONFIG_PARAMS, self._readVMDetails(VM_CONFIG_PARAMS))
-
- im = self._readVm('image')
- current_im = self.info['image']
- if (im is not None and
- (current_im is None or sxp.to_string(current_im) != im)):
- self.info['image'] = sxp.from_string(im)
+
+ # Check whether values in the configuration have
+ # changed in Xenstore.
+
+ cfg_vm = ['name', 'on_poweroff', 'on_reboot', 'on_crash']
+
+ vm_details = self._readVMDetails([(k,XendConfig.LEGACY_CFG_TYPES[k])
+ for k in cfg_vm])
+
+ # convert two lists into a python dictionary
+ vm_details = dict(zip(cfg_vm, vm_details))
+
+ for arg, val in vm_details.items():
+ if arg in XendConfig.LEGACY_CFG_TO_XENAPI_CFG:
+ xapiarg = XendConfig.LEGACY_CFG_TO_XENAPI_CFG[arg]
+ if val != None and val != self.info[xapiarg]:
+ self.info[xapiarg] = val
+ changed= True
+
+ # Check whether image definition has been updated
+ image_sxp = self._readVm('image')
+ if image_sxp and image_sxp != self.info.image_sxpr():
+ self.info.update_with_image_sxp(sxp.from_string(image_sxp))
changed = True
if changed:
@@ -760,17 +815,17 @@ class XendDomainInfo:
def _handleShutdownWatch(self, _):
log.debug('XendDomainInfo.handleShutdownWatch')
- reason = self._readDom('control/shutdown')
+ reason = self.readDom('control/shutdown')
if reason and reason != 'suspend':
- sst = self._readDom('xend/shutdown_start_time')
+ sst = self.readDom('xend/shutdown_start_time')
now = time.time()
if sst:
self.shutdownStartTime = float(sst)
timeout = float(sst) + SHUTDOWN_TIMEOUT - now
else:
self.shutdownStartTime = now
- self._storeDom('xend/shutdown_start_time', now)
+ self.storeDom('xend/shutdown_start_time', now)
timeout = SHUTDOWN_TIMEOUT
log.trace(
@@ -791,17 +846,17 @@ class XendDomainInfo:
def setName(self, name):
self._checkName(name)
- self.info['name'] = name
+ self.info['name_label'] = name
self.storeVm("name", name)
def getName(self):
- return self.info['name']
+ return self.info['name_label']
def getDomainPath(self):
return self.dompath
def getShutdownReason(self):
- return self._readDom('control/shutdown')
+ return self.readDom('control/shutdown')
def getStorePort(self):
"""For use only by image.py and XendCheckpoint.py."""
@@ -816,11 +871,13 @@ class XendDomainInfo:
return self.info['features']
def getVCpuCount(self):
- return self.info['vcpus']
+ return self.info['vcpus_number']
def setVCpuCount(self, vcpus):
self.info['vcpu_avail'] = (1 << vcpus) - 1
+ self.info['vcpus_number'] = vcpus
self.storeVm('vcpu_avail', self.info['vcpu_avail'])
+ self.storeVm('vcpus', self.info['vcpus_number'])
self._writeDom(self._vcpuDomDetails())
def getLabel(self):
@@ -828,19 +885,19 @@ class XendDomainInfo:
def getMemoryTarget(self):
"""Get this domain's target memory size, in KB."""
- return self.info['memory'] * 1024
+ return self.info['memory_static_min'] * 1024
def getResume(self):
- return "%s" % self.info['resume']
+ return str(self._resume)
def getCap(self):
- return self.info['cpu_cap']
+ return self.info.get('cpu_cap', 0)
def getWeight(self):
return self.info['cpu_weight']
def setResume(self, state):
- self.info['resume'] = state
+ self._resume = state
def getRestartCount(self):
return self._readVm('xend/restart_count')
@@ -885,13 +942,13 @@ class XendDomainInfo:
return
elif xeninfo['crashed']:
- if self._readDom('xend/shutdown_completed'):
+ if self.readDom('xend/shutdown_completed'):
# We've seen this shutdown already, but we are preserving
# the domain for debugging. Leave it alone.
return
log.warn('Domain has crashed: name=%s id=%d.',
- self.info['name'], self.domid)
+ self.info['name_label'], self.domid)
if xroot.get_enable_dump():
self.dumpCore()
@@ -901,7 +958,7 @@ class XendDomainInfo:
elif xeninfo['shutdown']:
self._stateSet(DOM_STATE_SHUTDOWN)
- if self._readDom('xend/shutdown_completed'):
+ if self.readDom('xend/shutdown_completed'):
# We've seen this shutdown already, but we are preserving
# the domain for debugging. Leave it alone.
return
@@ -910,7 +967,7 @@ class XendDomainInfo:
reason = shutdown_reason(xeninfo['shutdown_reason'])
log.info('Domain has shutdown: name=%s id=%d reason=%s.',
- self.info['name'], self.domid, reason)
+ self.info['name_label'], self.domid, reason)
self._clearRestart()
@@ -945,7 +1002,7 @@ class XendDomainInfo:
if timeout < 0:
log.info(
"Domain shutdown timeout expired: name=%s id=%s",
- self.info['name'], self.domid)
+ self.info['name_label'], self.domid)
self.destroy()
finally:
self.refresh_shutdown_lock.release()
@@ -965,11 +1022,23 @@ class XendDomainInfo:
def _maybeRestart(self, reason):
# Dispatch to the correct method based upon the configured on_{reason}
# behaviour.
- {"destroy" : self.destroy,
- "restart" : self._restart,
- "preserve" : self._preserve,
- "rename-restart" : self._renameRestart}[self.info['on_' + reason]]()
-
+ actions = {"destroy" : self.destroy,
+ "restart" : self._restart,
+ "preserve" : self._preserve,
+ "rename-restart" : self._renameRestart}
+
+ action_conf = {
+ 'poweroff': 'actions_after_shutdown',
+ 'reboot': 'actions_after_reboot',
+ 'crash': 'actions_after_crash',
+ }
+
+ action_target = self.info.get(action_conf.get(reason))
+ func = actions.get(action_target, None)
+ if func and callable(func):
+ func()
+ else:
+ self.destroy() # default to destroy
def _renameRestart(self):
self._restart(True)
@@ -1008,7 +1077,7 @@ class XendDomainInfo:
log.error(
'VM %s restarting too fast (%f seconds since the last '
'restart). Refusing to restart to avoid loops.',
- self.info['name'], timeout)
+ self.info['name_label'], timeout)
self.destroy()
return
@@ -1055,11 +1124,11 @@ class XendDomainInfo:
new_uuid = uuid.createString()
new_name = 'Domain-%s' % new_uuid
log.info("Renaming dead domain %s (%d, %s) to %s (%s).",
- self.info['name'], self.domid, self.info['uuid'],
+ self.info['name_label'], self.domid, self.info['uuid'],
new_name, new_uuid)
self._unwatchVm()
self._releaseDevices()
- self.info['name'] = new_name
+ self.info['name_label'] = new_name
self.info['uuid'] = new_uuid
self.vmpath = XS_VMROOT + new_uuid
self._storeVmDetails()
@@ -1067,10 +1136,10 @@ class XendDomainInfo:
def _preserve(self):
- log.info("Preserving dead domain %s (%d).", self.info['name'],
+ log.info("Preserving dead domain %s (%d).", self.info['name_label'],
self.domid)
self._unwatchVm()
- self._storeDom('xend/shutdown_completed', 'True')
+ self.storeDom('xend/shutdown_completed', 'True')
self._stateSet(DOM_STATE_HALTED)
#
@@ -1084,7 +1153,7 @@ class XendDomainInfo:
if not corefile:
this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime())
corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time,
- self.info['name'], self.domid)
+ self.info['name_label'], self.domid)
if os.path.isdir(corefile):
raise XendError("Cannot dump core in a directory: %s" %
@@ -1095,7 +1164,7 @@ class XendDomainInfo:
corefile_incomp = corefile+'-incomplete'
os.rename(corefile, corefile_incomp)
log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s",
- self.domid, self.info['name'])
+ self.domid, self.info['name_label'])
raise XendError("Failed to dump core: %s" % str(ex))
#
@@ -1117,8 +1186,8 @@ class XendDomainInfo:
@raise: VmError for invalid devices
"""
- for (devclass, config) in self.info.all_devices_sxpr():
- if devclass in XendDevices.valid_devices():
+ for (devclass, config) in self.info.get('devices', {}).values():
+ if devclass in XendDevices.valid_devices():
log.info("createDevice: %s : %s" % (devclass, config))
self._createDevice(devclass, config)
@@ -1139,7 +1208,7 @@ class XendDomainInfo:
# there's nothing more we can do.
log.exception(
"Device release failed: %s; %s; %s",
- self.info['name'], devclass, dev)
+ self.info['name_label'], devclass, dev)
if t.commit():
break
@@ -1211,11 +1280,12 @@ class XendDomainInfo:
log.debug('XendDomainInfo.constructDomain')
- hvm = (self._infoIsSet('image') and
- sxp.name(self.info['image']) == "hvm")
+ image_cfg = self.info.get('image', {})
+ hvm = image_cfg.has_key('hvm')
+
if hvm:
info = xc.xeninfo()
- if not 'hvm' in info['xen_caps']:
+ if 'hvm' not in info['xen_caps']:
raise VmError("HVM guest support is unavailable: is VT/AMD-V "
"supported by your CPU and enabled in your "
"BIOS?")
@@ -1228,14 +1298,14 @@ class XendDomainInfo:
if self.domid < 0:
raise VmError('Creating domain failed: name=%s' %
- self.info['name'])
+ self.info['name_label'])
self.dompath = GetDomainPath(self.domid)
self._recreateDom()
# Set maximum number of vcpus in domain
- xc.domain_max_vcpus(self.domid, int(self.info['vcpus']))
+ xc.domain_max_vcpus(self.domid, int(self.info['vcpus_number']))
def _introduceDomain(self):
@@ -1256,7 +1326,7 @@ class XendDomainInfo:
# if we have a boot loader but no image, then we need to set things
# up by running the boot loader non-interactively
- if self._infoIsSet('bootloader') and not self._infoIsSet('image'):
+ if self.info.get('bootloader') and self.info.get('image'):
self._configureBootloader()
if not self._infoIsSet('image'):
@@ -1264,11 +1334,12 @@ class XendDomainInfo:
try:
self.image = image.create(self,
+ self.info,
self.info['image'],
- self.info.all_devices_sxpr())
-
- localtime = self.info.get('localtime', 0)
- if localtime is not None and localtime == 1:
+ self.info['devices'])
+
+ localtime = self.info.get('localtime', False)
+ if localtime:
xc.domain_set_time_offset(self.domid)
xc.domain_setcpuweight(self.domid, self.info['cpu_weight'])
@@ -1284,12 +1355,12 @@ class XendDomainInfo:
# the various headrooms necessary, given the raw configured
# values. maxmem, memory, and shadow are all in KiB.
maxmem = self.image.getRequiredAvailableMemory(
- self.info['maxmem'] * 1024)
+ self.info['memory_static_min'] * 1024)
memory = self.image.getRequiredAvailableMemory(
- self.info['memory'] * 1024)
+ self.info['memory_static_max'] * 1024)
shadow = self.image.getRequiredShadowMemory(
self.info['shadow_memory'] * 1024,
- self.info['maxmem'] * 1024)
+ self.info['memory_static_max'] * 1024)
# Round shadow up to a multiple of a MiB, as shadow_mem_control
# takes MiB and we must not round down and end up under-providing.
@@ -1317,7 +1388,7 @@ class XendDomainInfo:
self._createDevices()
- if self.info['bootloader'] not in [None, 'kernel_external']:
+ if self.info['bootloader']:
self.image.cleanupBootloading()
self.info['start_time'] = time.time()
@@ -1325,7 +1396,7 @@ class XendDomainInfo:
self._stateSet(DOM_STATE_RUNNING)
except RuntimeError, exn:
log.exception("XendDomainInfo.initDomain: exception occurred")
- if self.info['bootloader'] not in [None, 'kernel_external'] \
+ if self.info['bootloader'] not in (None, 'kernel_external') \
and self.image is not None:
self.image.cleanupBootloading()
raise VmError(str(exn))
@@ -1338,7 +1409,6 @@ class XendDomainInfo:
self.refresh_shutdown_lock.acquire()
try:
self.unwatchShutdown()
-
self._releaseDevices()
if self.image:
@@ -1459,14 +1529,14 @@ class XendDomainInfo:
def _configureBootloader(self):
"""Run the bootloader if we're configured to do so."""
- if not self.info['bootloader']:
+ if not self.info.get('bootloader'):
return
blcfg = None
# FIXME: this assumes that we want to use the first disk device
- for (n, c) in self.info.all_devices_sxpr():
- if not n or not c or not(n in ["vbd", "tap"]):
+ for devuuid, (devtype, devinfo) in self.info.all_devices_sxpr():
+ if not devtype or not devinfo or devtype not in ('vbd', 'tap'):
continue
- disk = sxp.child_value(c, "uname")
+ disk = devinfo.get('uname')
if disk is None:
continue
fn = blkdev_uname_to_file(disk)
@@ -1478,7 +1548,8 @@ class XendDomainInfo:
msg = "Had a bootloader specified, but can't find disk"
log.error(msg)
raise VmError(msg)
- self.info['image'] = blcfg
+
+ self.info.update_with_image_sxp(blcfg)
#
# VM Functions
@@ -1516,7 +1587,8 @@ class XendDomainInfo:
if arch.type == "x86":
# 1MB per vcpu plus 4Kib/Mib of RAM. This is higher than
# the minimum that Xen would allocate if no value were given.
- overhead_kb = self.info['vcpus'] * 1024 + self.info['maxmem'] * 4
+ overhead_kb = self.info['vcpus_number'] * 1024 + \
+ self.info['memory_static_max'] * 4
overhead_kb = ((overhead_kb + 1023) / 1024) * 1024
# The domain might already have some shadow memory
overhead_kb -= xc.shadow_mem_control(self.domid) * 1024
@@ -1558,12 +1630,15 @@ class XendDomainInfo:
def _storeVmDetails(self):
to_store = {}
- for k in VM_STORE_ENTRIES:
- if self._infoIsSet(k[0]):
- to_store[k[0]] = str(self.info[k[0]])
-
- if self._infoIsSet('image'):
- to_store['image'] = sxp.to_string(self.info['image'])
+ for key in XendConfig.LEGACY_XENSTORE_VM_PARAMS:
+ info_key = XendConfig.LEGACY_CFG_TO_XENAPI_CFG.get(key, key)
+ if self._infoIsSet(info_key):
+ to_store[key] = str(self.info[info_key])
+
+ if self.info.get('image'):
+ image_sxpr = self.info.image_sxpr()
+ if image_sxpr:
+ to_store['image'] = sxp.to_string(image_sxpr)
if self._infoIsSet('security'):
secinfo = self.info['security']
@@ -1633,8 +1708,9 @@ class XendDomainInfo:
raise VmError('Invalid VM Name')
dom = XendDomain.instance().domain_lookup_nr(name)
- if dom and dom != self and not dom.info['dying']:
- raise VmError("VM name '%s' already exists" % name)
+ if dom and dom.info['uuid'] != self.info['uuid']:
+ raise VmError("VM name '%s' already exists as domain %s" %
+ (name, str(dom.domid)))
def update(self, info = None, refresh = True):
@@ -1656,6 +1732,7 @@ class XendDomainInfo:
#create new security element
self.info.update({'security':
[['ssidref', str(info['ssidref'])]]})
+
#ssidref field not used any longer
if 'ssidref' in info:
info.pop('ssidref')
@@ -1663,8 +1740,7 @@ class XendDomainInfo:
# make sure state is reset for info
# TODO: we should eventually get rid of old_dom_states
- self.info.update(info)
- self.info.validate()
+ self.info.update_config(info)
if refresh:
self.refreshShutdown(info)
@@ -1673,11 +1749,11 @@ class XendDomainInfo:
str(self.domid), self.info)
def sxpr(self, ignore_store = False):
- result = self.info.get_sxp(domain = self,
+ result = self.info.to_sxp(domain = self,
ignore_devices = ignore_store)
if not ignore_store and self.dompath:
- vnc_port = self._readDom('console/vnc-port')
+ vnc_port = self.readDom('console/vnc-port')
if vnc_port is not None:
result.append(['device',
['console', ['vnc-port', str(vnc_port)]]])
@@ -1695,9 +1771,15 @@ class XendDomainInfo:
return dom_uuid
def get_memory_static_max(self):
- return self.info['maxmem']
+ return self.info.get('memory_static_max')
def get_memory_static_min(self):
- return self.info['memory']
+ return self.info.get('memory_static_min')
+ def get_memory_dynamic_max(self):
+ return self.info.get('memory_dynamic_min')
+ def get_memory_dynamic_min(self):
+ return self.info.get('memory_dynamic_max')
+
+
def get_vcpus_policy(self):
sched_id = xc.sched_id_get()
if sched_id == xen.lowlevel.xc.XEN_SCHEDULER_SEDF:
@@ -1713,31 +1795,29 @@ class XendDomainInfo:
def get_bios_boot(self):
return '' # TODO
def get_platform_std_vga(self):
- return False
+ return self.info.get('platform_std_vga', False)
def get_platform_keymap(self):
return ''
def get_platform_serial(self):
- return '' # TODO
+ return self.info.get('platform_serial', '')
def get_platform_localtime(self):
- return False # TODO
+ return self.info.get('platform_localtime', False)
def get_platform_clock_offset(self):
- return False # TODO
+ return self.info.get('platform_clock_offset', False)
def get_platform_enable_audio(self):
- return False # TODO
+ return self.info.get('platform_enable_audio', False)
+ def get_platform_keymap(self):
+ return self.info.get('platform_keymap', '')
def get_builder(self):
- return 'Linux' # TODO
+ return self.info.get('builder', 0)
def get_boot_method(self):
- bootloader = self.info['bootloader']
- if not bootloader or bootloader not in XEN_API_BOOT_TYPE:
- return 'kernel_external'
- return bootloader
-
+ return self.info.get('boot_method', '')
def get_kernel_image(self):
- return self.info['kernel_kernel']
+ return self.info.get('kernel_kernel', '')
def get_kernel_initrd(self):
- return self.info['kernel_initrd']
+ return self.info.get('kernel_initrd', '')
def get_kernel_args(self):
- return self.info['kernel_args']
+ return self.info.get('kernel_args', '')
def get_grub_cmdline(self):
return '' # TODO
def get_pci_bus(self):
@@ -1748,25 +1828,26 @@ class XendDomainInfo:
return {} # TODO
def get_on_shutdown(self):
- after_shutdown = self.info.get('on_poweroff')
+ after_shutdown = self.info.get('action_after_shutdown')
if not after_shutdown or after_shutdown not in XEN_API_ON_NORMAL_EXIT:
return XEN_API_ON_NORMAL_EXIT[-1]
return after_shutdown
def get_on_reboot(self):
- after_reboot = self.info.get('on_reboot')
+ after_reboot = self.info.get('action_after_reboot')
if not after_reboot or after_reboot not in XEN_API_ON_NORMAL_EXIT:
return XEN_API_ON_NORMAL_EXIT[-1]
return after_reboot
def get_on_suspend(self):
- after_suspend = self.info.get('on_suspend') # TODO: not supported
+ # TODO: not supported
+ after_suspend = self.info.get('action_after_suspend')
if not after_suspend or after_suspend not in XEN_API_ON_NORMAL_EXIT:
return XEN_API_ON_NORMAL_EXIT[-1]
return after_suspend
def get_on_crash(self):
- after_crash = self.info.get('on_crash')
+ after_crash = self.info.get('action_after_crash')
if not after_crash or after_crash not in XEN_API_ON_CRASH_BEHAVIOUR:
return XEN_API_ON_CRASH_BEHAVIOUR[0]
return after_crash
@@ -1780,7 +1861,7 @@ class XendDomainInfo:
@rtype: dictionary
"""
- dev_type_config = self.info['device'].get(dev_uuid)
+ dev_type_config = self.info['devices'].get(dev_uuid)
# shortcut if the domain isn't started because
# the devcontrollers will have no better information
@@ -1840,7 +1921,7 @@ class XendDomainInfo:
config['IO_bandwidth_incoming_kbs'] = 0.0
config['IO_bandwidth_outgoing_kbs'] = 0.0
- if dev_class =='vbd':
+ if dev_class == 'vbd':
config['VDI'] = '' # TODO
config['device'] = config.get('dev', '')
config['driver'] = 'paravirtualised' # TODO
@@ -1984,8 +2065,8 @@ class XendDomainInfo:
def __str__(self):
return '<domain id=%s name=%s memory=%s state=%s>' % \
- (str(self.domid), self.info['name'],
- str(self.info['memory']), DOM_STATES[self.state])
+ (str(self.domid), self.info['name_label'],
+ str(self.info['memory_static_min']), DOM_STATES[self.state])
__repr__ = __str__
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/XendLogging.py
--- a/tools/python/xen/xend/XendLogging.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/XendLogging.py Mon Dec 04 08:24:41 2006 -0700
@@ -16,13 +16,15 @@
# Copyright (C) 2005, 2006 XenSource Ltd.
#============================================================================
-
+import os
+import stat
import tempfile
import types
import logging
import logging.handlers
import fcntl
+from xen.util import mkdir
from xen.xend.server import params
@@ -80,6 +82,7 @@ def init(filename, level):
global logfilename
def openFileHandler(fname):
+ mkdir.parents(os.path.dirname(fname), stat.S_IRWXU)
return XendRotatingFileHandler(fname, mode = 'a',
maxBytes = MAX_BYTES,
backupCount = BACKUP_COUNT)
diff -r 6fdbf173142d -r d603aed5ad6d
tools/python/xen/xend/XendStorageRepository.py
--- a/tools/python/xen/xend/XendStorageRepository.py Sat Dec 02 15:19:50
2006 -0700
+++ b/tools/python/xen/xend/XendStorageRepository.py Mon Dec 04 08:24:41
2006 -0700
@@ -19,10 +19,12 @@
# The default QCOW Xen API Storage Repository
#
+import commands
import os
-import commands
+import stat
import threading
+from xen.util import mkdir
from xen.xend import uuid
from xen.xend.XendError import XendError
from xen.xend.XendVDI import *
@@ -98,10 +100,7 @@ class XendStorageRepository:
"""
self.lock.acquire()
try:
- # create directory if /var/lib/xend/storage does not exist
- if not os.path.exists(XEND_STORAGE_DIR):
- os.makedirs(XEND_STORAGE_DIR)
- os.chmod(XEND_STORAGE_DIR, 0700)
+ mkdir.parents(XEND_STORAGE_DIR, stat.S_IRWXU)
# scan the directory and populate self.images
total_used = 0
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/image.py
--- a/tools/python/xen/xend/image.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/image.py Mon Dec 04 08:24:41 2006 -0700
@@ -23,7 +23,7 @@ import signal
import signal
import xen.lowlevel.xc
-from xen.xend import sxp
+from xen.xend.XendConstants import REVERSE_DOMAIN_SHUTDOWN_REASONS
from xen.xend.XendError import VmError, XendError
from xen.xend.XendLogging import log
from xen.xend.server.netif import randomMAC
@@ -31,19 +31,18 @@ from xen.xend import arch
from xen.xend import arch
from xen.xend import FlatDeviceTree
-
xc = xen.lowlevel.xc.xc()
-
MAX_GUEST_CMDLINE = 1024
-def create(vm, imageConfig, deviceConfig):
+def create(vm, vmConfig, imageConfig, deviceConfig):
"""Create an image handler for a vm.
@return ImageHandler instance
"""
- return findImageHandlerClass(imageConfig)(vm, imageConfig, deviceConfig)
+ return findImageHandlerClass(imageConfig)(vm, vmConfig, imageConfig,
+ deviceConfig)
class ImageHandler:
@@ -66,34 +65,20 @@ class ImageHandler:
ostype = None
- def __init__(self, vm, imageConfig, deviceConfig):
+ def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
self.vm = vm
self.kernel = None
self.ramdisk = None
self.cmdline = None
- self.configure(imageConfig, deviceConfig)
-
- def configure(self, imageConfig, _):
+ self.configure(vmConfig, imageConfig, deviceConfig)
+
+ def configure(self, vmConfig, imageConfig, _):
"""Config actions common to all unix-like domains."""
-
- def get_cfg(name, default = None):
- return sxp.child_value(imageConfig, name, default)
-
- self.kernel = get_cfg("kernel")
- self.cmdline = ""
- ip = get_cfg("ip")
- if ip:
- self.cmdline += " ip=" + ip
- root = get_cfg("root")
- if root:
- self.cmdline += " root=" + root
- args = get_cfg("args")
- if args:
- self.cmdline += " " + args
- self.ramdisk = get_cfg("ramdisk", '')
-
+ self.kernel = vmConfig['kernel_kernel']
+ self.cmdline = vmConfig['kernel_args']
+ self.ramdisk = vmConfig['kernel_initrd']
self.vm.storeVm(("image/ostype", self.ostype),
("image/kernel", self.kernel),
("image/cmdline", self.cmdline),
@@ -181,6 +166,10 @@ class ImageHandler:
pass
+ def recreate(self):
+ pass
+
+
class LinuxImageHandler(ImageHandler):
ostype = "linux"
@@ -214,8 +203,8 @@ class PPC_LinuxImageHandler(LinuxImageHa
ostype = "linux"
- def configure(self, imageConfig, deviceConfig):
- LinuxImageHandler.configure(self, imageConfig, deviceConfig)
+ def configure(self, vmConfig, imageConfig, deviceConfig):
+ LinuxImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
self.imageConfig = imageConfig
def buildDomain(self):
@@ -248,37 +237,42 @@ class PPC_LinuxImageHandler(LinuxImageHa
class HVMImageHandler(ImageHandler):
- def __init__(self, vm, imageConfig, deviceConfig):
- ImageHandler.__init__(self, vm, imageConfig, deviceConfig)
+ ostype = "hvm"
+
+ def __init__(self, vm, vmConfig, imageConfig, deviceConfig):
+ ImageHandler.__init__(self, vm, vmConfig, imageConfig, deviceConfig)
self.shutdownWatch = None
-
- def configure(self, imageConfig, deviceConfig):
- ImageHandler.configure(self, imageConfig, deviceConfig)
+ self.rebootFeatureWatch = None
+
+ def configure(self, vmConfig, imageConfig, deviceConfig):
+ ImageHandler.configure(self, vmConfig, imageConfig, deviceConfig)
info = xc.xeninfo()
- if not 'hvm' in info['xen_caps']:
+ if 'hvm' not in info['xen_caps']:
raise VmError("HVM guest support is unavailable: is VT/AMD-V "
"supported by your CPU and enabled in your BIOS?")
self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
- self.device_model = sxp.child_value(imageConfig, 'device_model')
+ self.device_model = imageConfig['hvm'].get('device_model')
if not self.device_model:
raise VmError("hvm: missing device model")
- self.display = sxp.child_value(imageConfig, 'display')
- self.xauthority = sxp.child_value(imageConfig, 'xauthority')
- self.vncconsole = sxp.child_value(imageConfig, 'vncconsole')
+
+ self.display = imageConfig['hvm'].get('display')
+ self.xauthority = imageConfig['hvm'].get('xauthority')
+ self.vncconsole = imageConfig['hvm'].get('vncconsole')
self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
("image/device-model", self.device_model),
("image/display", self.display))
- self.pid = 0
+ self.pid = None
self.dmargs += self.configVNC(imageConfig)
- self.pae = int(sxp.child_value(imageConfig, 'pae', 1))
- self.acpi = int(sxp.child_value(imageConfig, 'acpi', 1))
- self.apic = int(sxp.child_value(imageConfig, 'apic', 1))
+ self.pae = imageConfig['hvm'].get('pae', 0)
+ self.apic = imageConfig['hvm'].get('apic', 0)
+ self.acpi = imageConfig['hvm']['devices'].get('acpi', 0)
+
def buildDomain(self):
store_evtchn = self.vm.getStorePort()
@@ -295,6 +289,7 @@ class HVMImageHandler(ImageHandler):
log.debug("apic = %d", self.apic)
self.register_shutdown_watch()
+ self.register_reboot_feature_watch()
return xc.hvm_build(domid = self.vm.getDomid(),
image = self.kernel,
@@ -312,8 +307,10 @@ class HVMImageHandler(ImageHandler):
'localtime', 'serial', 'stdvga', 'isa', 'vcpus',
'acpi', 'usb', 'usbdevice', 'keymap' ]
ret = []
+ hvmDeviceConfig = imageConfig['hvm']['devices']
+
for a in dmargs:
- v = sxp.child_value(imageConfig, a)
+ v = hvmDeviceConfig.get(a)
# python doesn't allow '-' in variable names
if a == 'stdvga': a = 'std-vga'
@@ -328,7 +325,7 @@ class HVMImageHandler(ImageHandler):
ret.append("-%s" % a)
ret.append("%s" % v)
- if a in ['fda', 'fdb' ]:
+ if a in ['fda', 'fdb']:
if v:
if not os.path.isabs(v):
raise VmError("Floppy file %s does not exist." % v)
@@ -336,26 +333,27 @@ class HVMImageHandler(ImageHandler):
# Handle disk/network related options
mac = None
- ret = ret + ["-domain-name", "%s" % self.vm.info['name']]
+ ret = ret + ["-domain-name", str(self.vm.info['name_label'])]
nics = 0
- for (name, info) in deviceConfig:
- if name == 'vbd':
- uname = sxp.child_value(info, 'uname')
+
+ for devuuid, (devtype, devinfo) in deviceConfig.items():
+ if devtype == 'vbd':
+ uname = devinfo['uname']
if uname is not None and 'file:' in uname:
(_, vbdparam) = string.split(uname, ':', 1)
if not os.path.isfile(vbdparam):
raise VmError('Disk image does not exist: %s' %
vbdparam)
- if name == 'vif':
- type = sxp.child_value(info, 'type')
- if type != 'ioemu':
+ if devtype == 'vif':
+ dtype = devinfo.get('type', 'ioemu')
+ if dtype != 'ioemu':
continue
nics += 1
- mac = sxp.child_value(info, 'mac')
+ mac = devinfo.get('mac')
if mac == None:
mac = randomMAC()
- bridge = sxp.child_value(info, 'bridge', 'xenbr0')
- model = sxp.child_value(info, 'model', 'rtl8139')
+ bridge = devinfo.get('bridge', 'xenbr0')
+ model = devinfo.get('model', 'rtl8139')
ret.append("-net")
ret.append("nic,vlan=%d,macaddr=%s,model=%s" %
(nics, mac, model))
@@ -363,31 +361,32 @@ class HVMImageHandler(ImageHandler):
ret.append("tap,vlan=%d,bridge=%s" % (nics, bridge))
return ret
- def configVNC(self, config):
+ def configVNC(self, imageConfig):
# Handle graphics library related options
- vnc = sxp.child_value(config, 'vnc')
- sdl = sxp.child_value(config, 'sdl')
+ vnc = imageConfig.get('vnc')
+ sdl = imageConfig.get('sdl')
ret = []
- nographic = sxp.child_value(config, 'nographic')
+ nographic = imageConfig.get('nographic')
# get password from VM config (if password omitted, None)
- vncpasswd_vmconfig = sxp.child_value(config, 'vncpasswd')
+ vncpasswd_vmconfig = imageConfig.get('vncpasswd')
if nographic:
ret.append('-nographic')
return ret
if vnc:
- vncdisplay = int(sxp.child_value(config, 'vncdisplay',
- self.vm.getDomid()))
-
- vncunused = sxp.child_value(config, 'vncunused')
+ vncdisplay = imageConfig.get('vncdisplay',
+ int(self.vm.getDomid()))
+ vncunused = imageConfig.get('vncunused')
+
if vncunused:
ret += ['-vncunused']
else:
ret += ['-vnc', '%d' % vncdisplay]
- vnclisten = sxp.child_value(config, 'vnclisten')
+ vnclisten = imageConfig.get('vnclisten')
+
if not(vnclisten):
vnclisten = (xen.xend.XendRoot.instance().
get_vnclisten_address())
@@ -423,21 +422,37 @@ class HVMImageHandler(ImageHandler):
if self.vncconsole:
args = args + ([ "-vncviewer" ])
log.info("spawning device models: %s %s", self.device_model, args)
+ # keep track of pid and spawned options to kill it later
self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
+ self.vm.storeDom("image/device-model-pid", self.pid)
log.info("device model pid: %d", self.pid)
+ def recreate(self):
+ self.register_shutdown_watch()
+ self.register_reboot_feature_watch()
+ self.pid = self.vm.gatherDom(('image/device-model-pid', int))
+
def destroy(self):
- self.unregister_shutdown_watch();
- if not self.pid:
- return
- os.kill(self.pid, signal.SIGKILL)
- os.waitpid(self.pid, 0)
- self.pid = 0
+ self.unregister_shutdown_watch()
+ self.unregister_reboot_feature_watch();
+ if self.pid:
+ try:
+ os.kill(self.pid, signal.SIGKILL)
+ except OSError, exn:
+ log.exception(exn)
+ try:
+ os.waitpid(self.pid, 0)
+ except OSError, exn:
+ # This is expected if Xend has been restarted within the
+ # life of this domain. In this case, we can kill the process,
+ # but we can't wait for it because it's not our child.
+ pass
+ self.pid = None
def register_shutdown_watch(self):
""" add xen store watch on control/shutdown """
- self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown", \
- self.hvm_shutdown)
+ self.shutdownWatch = xswatch(self.vm.dompath + "/control/shutdown",
+ self.hvm_shutdown)
log.debug("hvm shutdown watch registered")
def unregister_shutdown_watch(self):
@@ -456,27 +471,54 @@ class HVMImageHandler(ImageHandler):
""" watch call back on node control/shutdown,
if node changed, this function will be called
"""
- from xen.xend.XendConstants import DOMAIN_SHUTDOWN_REASONS
xd = xen.xend.XendDomain.instance()
try:
vm = xd.domain_lookup( self.vm.getDomid() )
except XendError:
# domain isn't registered, no need to clean it up.
- return
+ return False
reason = vm.getShutdownReason()
log.debug("hvm_shutdown fired, shutdown reason=%s", reason)
- for x in DOMAIN_SHUTDOWN_REASONS.keys():
- if DOMAIN_SHUTDOWN_REASONS[x] == reason:
- vm.info['shutdown'] = 1
- vm.info['shutdown_reason'] = x
- vm.refreshShutdown(vm.info)
-
- return 1 # Keep watching
+ if reason in REVERSE_DOMAIN_SHUTDOWN_REASONS:
+ vm.info['shutdown'] = 1
+ vm.info['shutdown_reason'] = \
+ REVERSE_DOMAIN_SHUTDOWN_REASONS[reason]
+ vm.refreshShutdown(vm.info)
+
+ return True # Keep watching
+
+ def register_reboot_feature_watch(self):
+ """ add xen store watch on control/feature-reboot """
+ self.rebootFeatureWatch = xswatch(self.vm.dompath +
"/control/feature-reboot", \
+ self.hvm_reboot_feature)
+ log.debug("hvm reboot feature watch registered")
+
+ def unregister_reboot_feature_watch(self):
+ """Remove the watch on the control/feature-reboot, if any. Nothrow
+ guarantee."""
+
+ try:
+ if self.rebootFeatureWatch:
+ self.rebootFeatureWatch.unwatch()
+ except:
+ log.exception("Unwatching hvm reboot feature watch failed.")
+ self.rebootFeatureWatch = None
+ log.debug("hvm reboot feature watch unregistered")
+
+ def hvm_reboot_feature(self, _):
+ """ watch call back on node control/feature-reboot,
+ if node changed, this function will be called
+ """
+ status = self.vm.readDom('control/feature-reboot')
+ log.debug("hvm_reboot_feature fired, module status=%s", status)
+ if status == '1':
+ self.unregister_shutdown_watch()
+
+ return True # Keep watching
+
class IA64_HVM_ImageHandler(HVMImageHandler):
-
- ostype = "hvm"
def getRequiredAvailableMemory(self, mem_kb):
page_kb = 16
@@ -489,8 +531,6 @@ class IA64_HVM_ImageHandler(HVMImageHand
return 0
class X86_HVM_ImageHandler(HVMImageHandler):
-
- ostype = "hvm"
def getRequiredAvailableMemory(self, mem_kb):
# Add 8 MiB overhead for QEMU's video RAM.
@@ -529,10 +569,10 @@ def findImageHandlerClass(image):
@param image config
@return ImageHandler subclass or None
"""
- type = sxp.name(image)
- if type is None:
+ image_type = image['type']
+ if image_type is None:
raise VmError('missing image type')
try:
- return _handlers[arch.type][type]
+ return _handlers[arch.type][image_type]
except KeyError:
- raise VmError('unknown image type: ' + type)
+ raise VmError('unknown image type: ' + image_type)
diff -r 6fdbf173142d -r d603aed5ad6d
tools/python/xen/xend/server/DevController.py
--- a/tools/python/xen/xend/server/DevController.py Sat Dec 02 15:19:50
2006 -0700
+++ b/tools/python/xen/xend/server/DevController.py Mon Dec 04 08:24:41
2006 -0700
@@ -17,6 +17,7 @@
#============================================================================
from threading import Event
+import types
from xen.xend import sxp
from xen.xend.XendError import VmError
@@ -86,7 +87,7 @@ class DevController:
import xen.xend.XendDomain
xd = xen.xend.XendDomain.instance()
- backdom_name = sxp.child_value(config, 'backend')
+ backdom_name = config.get('backend')
if backdom_name is None:
backdom = xen.xend.XendDomain.DOM0_ID
else:
@@ -223,7 +224,7 @@ class DevController:
configDict = self.getDeviceConfiguration(devid)
sxpr = [self.deviceClass]
for key, val in configDict.items():
- if type(val) == type(list()):
+ if isinstance(val, (types.ListType, types.TupleType)):
for v in val:
sxpr.append([key, v])
else:
@@ -405,7 +406,7 @@ class DevController:
import xen.xend.XendDomain
xd = xen.xend.XendDomain.instance()
- backdom_name = sxp.child_value(config, 'backend')
+ backdom_name = config.get('backend')
if backdom_name:
backdom = xd.domain_lookup_nr(backdom_name)
else:
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/SrvDaemon.py
--- a/tools/python/xen/xend/server/SrvDaemon.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/SrvDaemon.py Mon Dec 04 08:24:41 2006 -0700
@@ -21,6 +21,7 @@ import xen.lowlevel.xc
from xen.xend.XendLogging import log
from xen.xend import osdep
+from xen.util import mkdir
import relocate
import SrvServer
@@ -108,8 +109,7 @@ class Daemon:
# so _before_ we close stderr.
try:
parent = os.path.dirname(XEND_DEBUG_LOG)
- if not os.path.exists(parent):
- os.makedirs(parent, stat.S_IRWXU)
+ mkdir.parents(parent, stat.S_IRWXU)
fd = os.open(XEND_DEBUG_LOG, os.O_WRONLY|os.O_CREAT|os.O_APPEND)
except Exception, exn:
print >>sys.stderr, exn
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/SrvServer.py
--- a/tools/python/xen/xend/server/SrvServer.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/SrvServer.py Mon Dec 04 08:24:41 2006 -0700
@@ -154,7 +154,7 @@ def create():
if api_cfg:
try:
addrs = [(str(x[0]).split(':'),
- len(x) > 1 and x[1] or XendAPI.AUTH_NONE,
+ len(x) > 1 and x[1] or XendAPI.AUTH_PAM,
len(x) > 2 and x[2] and map(re.compile, x[2].split(" "))
or None)
for x in api_cfg]
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/blkif.py
--- a/tools/python/xen/xend/server/blkif.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/blkif.py Mon Dec 04 08:24:41 2006 -0700
@@ -21,7 +21,6 @@ import string
from xen.util import blkif
from xen.util import security
-from xen.xend import sxp
from xen.xend.XendError import VmError
from xen.xend.server.DevController import DevController
@@ -37,9 +36,9 @@ class BlkifController(DevController):
def getDeviceDetails(self, config):
"""@see DevController.getDeviceDetails"""
- uname = sxp.child_value(config, 'uname', '')
- dev = sxp.child_value(config, 'dev', '')
-
+ uname = config.get('uname', '')
+ dev = config.get('dev', '')
+
if 'ioemu:' in dev:
(_, dev) = string.split(dev, ':', 1)
try:
@@ -59,17 +58,17 @@ class BlkifController(DevController):
except ValueError:
(typ, params) = ("", "")
- mode = sxp.child_value(config, 'mode', 'r')
+ mode = config.get('mode', 'r')
if mode not in ('r', 'w', 'w!'):
raise VmError('Invalid mode')
- back = { 'dev' : dev,
- 'type' : typ,
- 'params' : params,
- 'mode' : mode
- }
+ back = {'dev' : dev,
+ 'type' : typ,
+ 'params' : params,
+ 'mode' : mode,
+ }
- uuid = sxp.child_value(config, 'uuid')
+ uuid = config.get('uuid')
if uuid:
back['uuid'] = uuid
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/iopif.py
--- a/tools/python/xen/xend/server/iopif.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/iopif.py Mon Dec 04 08:24:41 2006 -0700
@@ -22,7 +22,6 @@ import types
import xen.lowlevel.xc
-from xen.xend import sxp
from xen.xend.XendError import VmError
from xen.xend.server.DevController import DevController
@@ -49,13 +48,12 @@ class IOPortsController(DevController):
def __init__(self, vm):
DevController.__init__(self, vm)
-
def getDeviceDetails(self, config):
"""@see DevController.getDeviceDetails"""
def get_param(field):
try:
- val = sxp.child_value(config, field)
+ val = config.get(field)
if not val:
raise VmError('ioports: Missing %s config setting' % field)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/irqif.py
--- a/tools/python/xen/xend/server/irqif.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/irqif.py Mon Dec 04 08:24:41 2006 -0700
@@ -45,7 +45,7 @@ class IRQController(DevController):
def get_param(field):
try:
- val = sxp.child_value(config, field)
+ val = config.get(field)
if not val:
raise VmError('irq: Missing %s config setting' % field)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/netif.py
--- a/tools/python/xen/xend/server/netif.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/netif.py Mon Dec 04 08:24:41 2006 -0700
@@ -24,7 +24,6 @@ import random
import random
import re
-from xen.xend import sxp
from xen.xend import XendRoot
from xen.xend.server.DevController import DevController
@@ -139,22 +138,15 @@ class NetifController(DevController):
def getDeviceDetails(self, config):
"""@see DevController.getDeviceDetails"""
- def _get_config_ipaddr(config):
- val = []
- for ipaddr in sxp.children(config, elt='ip'):
- val.append(sxp.child0(ipaddr))
- return val
-
script = os.path.join(xroot.network_script_dir,
- sxp.child_value(config, 'script',
- xroot.get_vif_script()))
- typ = sxp.child_value(config, 'type')
- bridge = sxp.child_value(config, 'bridge')
- mac = sxp.child_value(config, 'mac')
- vifname = sxp.child_value(config, 'vifname')
- rate = sxp.child_value(config, 'rate')
- uuid = sxp.child_value(config, 'uuid')
- ipaddr = _get_config_ipaddr(config)
+ config.get('script', xroot.get_vif_script()))
+ typ = config.get('type')
+ bridge = config.get('bridge')
+ mac = config.get('mac')
+ vifname = config.get('vifname')
+ rate = config.get('rate')
+ uuid = config.get('uuid')
+ ipaddr = config.get('ip')
devid = self.allocateDeviceID()
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/pciif.py Mon Dec 04 08:24:41 2006 -0700
@@ -53,60 +53,29 @@ class PciController(DevController):
def getDeviceDetails(self, config):
"""@see DevController.getDeviceDetails"""
- #log.debug('pci config='+sxp.to_string(config))
-
- def get_param(config, field, default=None):
+ def parse_hex(val):
try:
- val = sxp.child_value(config, field)
-
- if not val:
- if default==None:
- raise VmError('pci: Missing %s config setting' % field)
- else:
- return default
-
if isinstance(val, types.StringTypes):
return int(val, 16)
else:
return val
- except:
- if default==None:
- raise VmError('pci: Invalid config setting %s: %s' %
- (field, val))
- else:
- return default
-
+ except ValueError:
+ return None
+
back = {}
+ pcidevid = 0
+ for pci_config in config.get('devs', []):
+ domain = parse_hex(pci_config.get('domain', 0))
+ bus = parse_hex(pci_config.get('bus', 0))
+ slot = parse_hex(pci_config.get('slot', 0))
+ func = parse_hex(pci_config.get('func', 0))
+ self.setupDevice(domain, bus, slot, func)
+ back['dev-%i' % pcidevid] = "%04x:%02x:%02x.%02x" % \
+ (domain, bus, slot, func)
+ pcidevid += 1
- val = sxp.child_value(config, 'dev')
- if isinstance(val, (types.ListType, types.TupleType)):
- pcidevid = 0
- for dev_config in sxp.children(config, 'dev'):
- domain = get_param(dev_config, 'domain', 0)
- bus = get_param(dev_config,'bus')
- slot = get_param(dev_config,'slot')
- func = get_param(dev_config,'func')
-
- self.setupDevice(domain, bus, slot, func)
-
- back['dev-%i' % pcidevid]="%04x:%02x:%02x.%02x"% \
- (domain, bus, slot, func)
- pcidevid+=1
-
- back['num_devs']=str(pcidevid)
-
- else:
- # Xen 2.0 configuration compatibility
- domain = get_param(config, 'domain', 0)
- bus = get_param(config, 'bus')
- slot = get_param(config, 'dev')
- func = get_param(config, 'func')
-
- self.setupDevice(domain, bus, slot, func)
-
- back['dev-0']="%04x:%02x:%02x.%02x"%(domain, bus, slot, func)
- back['num_devs']=str(1)
-
+ back['num_devs']=str(pcidevid)
+ back['uuid'] = config.get('uuid','')
return (0, back, {})
def getDeviceConfiguration(self, devid):
@@ -129,7 +98,8 @@ class PciController(DevController):
'slot': '0x%(slot)s' % pci_dev_info,
'func': '0x%(func)s' % pci_dev_info})
- result['dev'] = pci_devs
+ result['devs'] = pci_devs
+ result['uuid'] = self.readBackend(devid, 'uuid')
return result
def configuration(self, devid):
@@ -142,7 +112,8 @@ class PciController(DevController):
sxpr = [self.deviceClass]
# remove devs
- devs = configDict.pop('dev', [])
+ devs = configDict.pop('devs', [])
+
for dev in devs:
dev_sxpr = ['dev']
for dev_item in dev.items():
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/pciquirk.py
--- a/tools/python/xen/xend/server/pciquirk.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/pciquirk.py Mon Dec 04 08:24:41 2006 -0700
@@ -15,25 +15,24 @@ class PCIQuirk:
self.device = device
self.subvendor = subvendor
self.subdevice = subdevice
- self.domain = domain
- self.bus = bus
- self.slot = slot
- self.func = func
+ self.domain = domain
+ self.bus = bus
+ self.slot = slot
+ self.func = func
self.devid = "%04x:%04x:%04x:%04x" % (vendor, device, subvendor,
subdevice)
- self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
+ self.pciid = "%04x:%02x:%02x.%01x" % (domain, bus, slot, func)
+ self.quirks = self.__getQuirksByID()
- self.quirks = self.__getQuirksByID( )
-
- self.__sendQuirks( )
- self.__sendPermDevs( )
+ self.__sendQuirks()
+ self.__sendPermDevs()
def __matchPCIdev( self, list ):
ret = False
if list == None:
return False
for id in list:
- if id.startswith( self.devid[:9] ): # id's vendor and device ID
match
+ if id.startswith(self.devid[:9]): # id's vendor and device ID match
skey = id.split(':')
size = len(skey)
if (size == 2): # subvendor/subdevice not
suplied
@@ -41,13 +40,13 @@ class PCIQuirk:
break
elif (size == 4): # check subvendor/subdevice
# check subvendor
- subven = '%04x' % self.subvendor
+ subven = '%04x' % self.subvendor
if ((skey[2] != 'FFFF') and
(skey[2] != 'ffff') and
(skey[2] != subven)):
continue
# check subdevice
- subdev = '%04x' % self.subdevice
+ subdev = '%04x' % self.subdevice
if ((skey[3] != 'FFFF') and
(skey[3] != 'ffff') and
(skey[3] != subdev)):
@@ -101,8 +100,8 @@ class PCIQuirk:
self.slot, self.func, quirk) )
f.close()
except Exception, e:
- raise VmError("pci: failed to open/write/close quirks sysfs "
+ \
- "node - " + str(e))
+ raise VmError("pci: failed to open/write/close quirks " +
+ "sysfs node - " + str(e))
def __devIsUnconstrained( self ):
if os.path.exists(PERMISSIVE_CONFIG_FILE):
@@ -126,20 +125,22 @@ class PCIQuirk:
devices = child_at(child(pci_perm_dev_config,
'unconstrained_dev_ids'),0)
if self.__matchPCIdev( devices ):
- log.debug("Permissive mode enabled for PCI device [%s]" %
self.devid)
+ log.debug("Permissive mode enabled for PCI device [%s]" %
+ self.devid)
return True
- log.debug("Permissive mode NOT enabled for PCI device [%s]" %
self.devid)
+ log.debug("Permissive mode NOT enabled for PCI device [%s]" %
+ self.devid)
return False
def __sendPermDevs(self):
if self.__devIsUnconstrained( ):
- log.debug("Unconstrained device: %04x:%02x:%02x.%1x" %
(self.domain,
- self.bus, self.slot, self.func))
+ log.debug("Unconstrained device: %04x:%02x:%02x.%1x" %
+ (self.domain, self.bus, self.slot, self.func))
try:
f = file(PERMISSIVE_SYSFS_NODE ,"w")
f.write( "%04x:%02x:%02x.%1x" % (self.domain, self.bus,
- self.slot, self.func) )
+ self.slot, self.func))
f.close()
except Exception, e:
- raise VmError("pci: failed to open/write/close permissive " + \
- "sysfs node: " + str(e))
+ raise VmError("pci: failed to open/write/close permissive " +
+ "sysfs node: " + str(e))
diff -r 6fdbf173142d -r d603aed5ad6d
tools/python/xen/xend/server/tests/test_controllers.py
--- a/tools/python/xen/xend/server/tests/test_controllers.py Sat Dec 02
15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/tests/test_controllers.py Mon Dec 04
08:24:41 2006 -0700
@@ -21,11 +21,11 @@ class test_controllers(unittest.TestCase
def testNetif(self):
controller = self.controllerInstance(netif.NetifController)
- self.assertNetif(controller.getDeviceDetails(['vif']), None)
+ self.assertNetif(controller.getDeviceDetails({}), None)
self.assertNetif(
- controller.getDeviceDetails(
- ['vif', ['mac', 'aa:bb:cc:dd:ee:ff']]),
+ controller.getDeviceDetails({'mac': 'aa:bb:cc:dd:ee:ff'}),
'aa:bb:cc:dd:ee:ff')
+
def assertNetif(self, results, expectedMac):
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xend/server/tpmif.py
--- a/tools/python/xen/xend/server/tpmif.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xend/server/tpmif.py Mon Dec 04 08:24:41 2006 -0700
@@ -18,10 +18,8 @@
# Copyright (C) 2005 XenSource Ltd
#============================================================================
-"""Support for virtual TPM interfaces.
-"""
+"""Support for virtual TPM interfaces."""
-from xen.xend import sxp
from xen.xend import XendRoot
from xen.xend.XendLogging import log
from xen.xend.XendError import XendError
@@ -49,12 +47,12 @@ class TPMifController(DevController):
"""@see DevController.getDeviceDetails"""
devid = self.allocateDeviceID()
- inst = int(sxp.child_value(config, 'pref_instance', '-1'))
+ inst = int(config.get('pref_instance', -1))
if inst == -1:
- inst = int(sxp.child_value(config, 'instance' , '0'))
+ inst = int(config.get('instance', 0))
- typ = sxp.child_value(config, 'type')
- uuid = sxp.child_value(config, 'uuid')
+ typ = config.get('type')
+ uuid = config.get('uuid')
log.info("The domain has a TPM with pref. instance %d and devid %d.",
inst, devid)
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xm/create.py
--- a/tools/python/xen/xm/create.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xm/create.py Mon Dec 04 08:24:41 2006 -0700
@@ -284,6 +284,18 @@ gopts.var('usbport', val='PATH',
use="""Add a physical USB port to a domain, as specified by the path
to that port. This option may be repeated to add more than one
port.""")
+gopts.var('vfb',
val="type={vnc,sdl},vncunused=1,vncdisplay=N,vnclisten=ADDR,display=DISPLAY,xauthority=XAUTHORITY",
+ fn=append_value, default=[],
+ use="""Make the domain a framebuffer backend.
+ The backend type should be either sdl or vnc.
+ For type=vnc, connect an external vncviewer. The server will listen
+ on ADDR (default 127.0.0.1) on port N+5900. N defaults to the
+ domain id. If vncunused=1, the server will try to find an arbitrary
+ unused port above 5900.
+ For type=sdl, a viewer will be started automatically using the
+ given DISPLAY and XAUTHORITY, which default to the current user's
+ ones.""")
+
gopts.var('vif',
val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT,backend=DOM,vifname=NAME",
fn=append_value, default=[],
use="""Add a network interface with the given MAC address and bridge.
@@ -512,8 +524,8 @@ def configure_image(vals):
config_image.append(['args', vals.extra])
if vals.builder == 'hvm':
- configure_hvm(config_image, vals)
-
+ configure_hvm(config_image, vals)
+
return config_image
def configure_disks(config_devs, vals):
@@ -564,6 +576,23 @@ def configure_usb(config_devs, vals):
config_usb = ['usbport', ['path', path]]
config_devs.append(['device', config_usb])
+def configure_vfbs(config_devs, vals):
+ for f in vals.vfb:
+ d = comma_sep_kv_to_dict(f)
+ config = ['vfb']
+ if not d.has_key("type"):
+ d['type'] = 'sdl'
+ for (k,v) in d.iteritems():
+ if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display',
+ 'xauthority', 'type' ]:
+ err("configuration option %s unknown to vfbs" % k)
+ config.append([k,v])
+ if not d.has_key("display") and os.environ.has_key("DISPLAY"):
+ config.append(["display", os.environ['DISPLAY']])
+ if not d.has_key("xauthority"):
+ config.append(["xauthority", get_xauthority()])
+ config_devs.append(['device', ['vkbd']])
+ config_devs.append(['device', config])
def configure_security(config, vals):
"""Create the config for ACM security labels.
@@ -742,6 +771,7 @@ def make_config(vals):
configure_vifs(config_devs, vals)
configure_usb(config_devs, vals)
configure_vtpm(config_devs, vals)
+ configure_vfbs(config_devs, vals)
configure_security(config, vals)
config += config_devs
diff -r 6fdbf173142d -r d603aed5ad6d tools/python/xen/xm/main.py
--- a/tools/python/xen/xm/main.py Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/python/xen/xm/main.py Mon Dec 04 08:24:41 2006 -0700
@@ -581,8 +581,8 @@ def parse_doms_info(info):
return {
'domid' : get_info('domid', str, ''),
'name' : get_info('name', str, '??'),
- 'mem' : get_info('memory_dynamic_max', int, 0),
- 'vcpus' : get_info('online_vcpus', int, 0),
+ 'mem' : get_info('memory_dynamic_min', int, 0),
+ 'vcpus' : get_info('vcpus', int, 0),
'state' : get_info('state', str, ''),
'cpu_time' : get_info('cpu_time', float, 0),
'up_time' : get_info('up_time', float, -1),
diff -r 6fdbf173142d -r d603aed5ad6d tools/tests/test_x86_emulator.c
--- a/tools/tests/test_x86_emulator.c Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/tests/test_x86_emulator.c Mon Dec 04 08:24:41 2006 -0700
@@ -17,12 +17,14 @@ typedef int64_t s64;
#define PFEC_write_access (1U<<1)
-static int read_any(
- unsigned long addr,
+static int read(
+ unsigned int seg,
+ unsigned long offset,
unsigned long *val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
+ unsigned long addr = offset;
switch ( bytes )
{
case 1: *val = *(u8 *)addr; break;
@@ -33,12 +35,14 @@ static int read_any(
return X86EMUL_CONTINUE;
}
-static int write_any(
- unsigned long addr,
+static int write(
+ unsigned int seg,
+ unsigned long offset,
unsigned long val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
+ unsigned long addr = offset;
switch ( bytes )
{
case 1: *(u8 *)addr = (u8)val; break;
@@ -49,13 +53,15 @@ static int write_any(
return X86EMUL_CONTINUE;
}
-static int cmpxchg_any(
- unsigned long addr,
+static int cmpxchg(
+ unsigned int seg,
+ unsigned long offset,
unsigned long old,
unsigned long new,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
+ unsigned long addr = offset;
switch ( bytes )
{
case 1: *(u8 *)addr = (u8)new; break;
@@ -66,21 +72,27 @@ static int cmpxchg_any(
return X86EMUL_CONTINUE;
}
-static int cmpxchg8b_any(
- unsigned long addr,
+static int cmpxchg8b(
+ unsigned int seg,
+ unsigned long offset,
unsigned long old_lo,
unsigned long old_hi,
unsigned long new_lo,
unsigned long new_hi,
struct x86_emulate_ctxt *ctxt)
{
+ unsigned long addr = offset;
((unsigned long *)addr)[0] = new_lo;
((unsigned long *)addr)[1] = new_hi;
return X86EMUL_CONTINUE;
}
static struct x86_emulate_ops emulops = {
- read_any, write_any, read_any, write_any, cmpxchg_any, cmpxchg8b_any
+ .read = read,
+ .insn_fetch = read,
+ .write = write,
+ .cmpxchg = cmpxchg,
+ .cmpxchg8b = cmpxchg8b
};
int main(int argc, char **argv)
@@ -108,7 +120,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
regs.error_code = PFEC_write_access;
- ctxt.cr2 = (unsigned long)res;
+ regs.eax = (unsigned long)res;
*res = 0x7FFFFFFF;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -127,7 +139,7 @@ int main(int argc, char **argv)
#else
regs.ecx = 0x12345678UL;
#endif
- ctxt.cr2 = (unsigned long)res;
+ regs.eax = (unsigned long)res;
regs.error_code = 0;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -142,7 +154,7 @@ int main(int argc, char **argv)
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.ecx = ~0UL;
- ctxt.cr2 = (unsigned long)res;
+ regs.eax = (unsigned long)res;
regs.error_code = 0;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -152,13 +164,13 @@ int main(int argc, char **argv)
goto fail;
printf("okay\n");
- printf("%-40s", "Testing lock cmpxchgb %%cl,(%%eax)...");
- instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x08;
+ printf("%-40s", "Testing lock cmpxchgb %%cl,(%%ebx)...");
+ instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x0b;
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.eax = 0x92345677UL;
regs.ecx = 0xAA;
- ctxt.cr2 = (unsigned long)res;
+ regs.ebx = (unsigned long)res;
regs.error_code = PFEC_write_access;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -169,13 +181,13 @@ int main(int argc, char **argv)
goto fail;
printf("okay\n");
- printf("%-40s", "Testing lock cmpxchgb %%cl,(%%eax)...");
- instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x08;
+ printf("%-40s", "Testing lock cmpxchgb %%cl,(%%ebx)...");
+ instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb0; instr[3] = 0x0b;
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.eax = 0xAABBCC77UL;
regs.ecx = 0xFF;
- ctxt.cr2 = (unsigned long)res;
+ regs.ebx = (unsigned long)res;
regs.error_code = PFEC_write_access;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -192,7 +204,7 @@ int main(int argc, char **argv)
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
- ctxt.cr2 = (unsigned long)res;
+ regs.eax = (unsigned long)res;
regs.error_code = PFEC_write_access;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -203,14 +215,14 @@ int main(int argc, char **argv)
goto fail;
printf("okay\n");
- printf("%-40s", "Testing lock cmpxchgl %%ecx,(%%eax)...");
- instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb1; instr[3] = 0x08;
+ printf("%-40s", "Testing lock cmpxchgl %%ecx,(%%ebx)...");
+ instr[0] = 0xf0; instr[1] = 0x0f; instr[2] = 0xb1; instr[3] = 0x0b;
regs.eflags = 0x200;
*res = 0x923456AA;
regs.eip = (unsigned long)&instr[0];
regs.eax = 0x923456AAUL;
regs.ecx = 0xDDEEFF00L;
- ctxt.cr2 = (unsigned long)res;
+ regs.ebx = (unsigned long)res;
regs.error_code = PFEC_write_access;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -230,7 +242,6 @@ int main(int argc, char **argv)
regs.esi = (unsigned long)res + 0;
regs.edi = (unsigned long)res + 2;
regs.error_code = 0; /* read fault */
- ctxt.cr2 = regs.esi;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(*res != 0x44554455) ||
@@ -248,13 +259,28 @@ int main(int argc, char **argv)
regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)res;
- ctxt.cr2 = regs.edi;
regs.error_code = PFEC_write_access;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
(*res != 0x2233445D) ||
((regs.eflags&0x201) != 0x201) ||
(regs.eip != (unsigned long)&instr[4]) )
+ goto fail;
+ printf("okay\n");
+
+ printf("%-40s", "Testing btrl %eax,(%edi)...");
+ instr[0] = 0x0f; instr[1] = 0xb3; instr[2] = 0x07;
+ *res = 0x2233445F;
+ regs.eflags = 0x200;
+ regs.eip = (unsigned long)&instr[0];
+ regs.eax = -32;
+ regs.edi = (unsigned long)(res+1);
+ regs.error_code = PFEC_write_access;
+ rc = x86_emulate_memop(&ctxt, &emulops);
+ if ( (rc != 0) ||
+ (*res != 0x2233445E) ||
+ ((regs.eflags&0x201) != 0x201) ||
+ (regs.eip != (unsigned long)&instr[3]) )
goto fail;
printf("okay\n");
@@ -270,7 +296,6 @@ int main(int argc, char **argv)
regs.ecx = 0xCCCCFFFF;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)res;
- ctxt.cr2 = regs.edi;
regs.error_code = PFEC_write_access;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -283,9 +308,9 @@ int main(int argc, char **argv)
printf("%-40s", "Testing cmpxchg8b (%edi) [failing]...");
instr[0] = 0x0f; instr[1] = 0xc7; instr[2] = 0x0f;
+ regs.eflags = 0x200;
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)res;
- ctxt.cr2 = regs.edi;
regs.error_code = PFEC_write_access;
rc = x86_emulate_memop(&ctxt, &emulops);
if ( (rc != 0) ||
@@ -300,9 +325,10 @@ int main(int argc, char **argv)
printf("%-40s", "Testing movsxbd (%%eax),%%ecx...");
instr[0] = 0x0f; instr[1] = 0xbe; instr[2] = 0x08;
- regs.eip = (unsigned long)&instr[0];
- regs.ecx = 0x12345678;
- ctxt.cr2 = (unsigned long)res;
+ regs.eflags = 0x200;
+ regs.eip = (unsigned long)&instr[0];
+ regs.ecx = 0x12345678;
+ regs.eax = (unsigned long)res;
*res = 0x82;
regs.error_code = 0;
rc = x86_emulate_memop(&ctxt, &emulops);
@@ -316,9 +342,10 @@ int main(int argc, char **argv)
printf("%-40s", "Testing movzxwd (%%eax),%%ecx...");
instr[0] = 0x0f; instr[1] = 0xb7; instr[2] = 0x08;
- regs.eip = (unsigned long)&instr[0];
- regs.ecx = 0x12345678;
- ctxt.cr2 = (unsigned long)res;
+ regs.eflags = 0x200;
+ regs.eip = (unsigned long)&instr[0];
+ regs.ecx = 0x12345678;
+ regs.eax = (unsigned long)res;
*res = 0x1234aa82;
regs.error_code = 0;
rc = x86_emulate_memop(&ctxt, &emulops);
@@ -330,6 +357,23 @@ int main(int argc, char **argv)
goto fail;
printf("okay\n");
+ printf("%-40s", "Testing xadd %%ax,(%%ecx)...");
+ instr[0] = 0x66; instr[1] = 0x0f; instr[2] = 0xc1; instr[3] = 0x01;
+ regs.eflags = 0x200;
+ regs.eip = (unsigned long)&instr[0];
+ regs.ecx = (unsigned long)res;
+ regs.eax = 0x12345678;
+ *res = 0x11111111;
+ regs.error_code = 0;
+ rc = x86_emulate_memop(&ctxt, &emulops);
+ if ( (rc != 0) ||
+ (*res != 0x11116789) ||
+ (regs.eax != 0x12341111) ||
+ ((regs.eflags&0x240) != 0x200) ||
+ (regs.eip != (unsigned long)&instr[4]) )
+ goto fail;
+ printf("okay\n");
+
return 0;
fail:
diff -r 6fdbf173142d -r d603aed5ad6d tools/xm-test/tests/vtpm/Makefile.am
--- a/tools/xm-test/tests/vtpm/Makefile.am Sat Dec 02 15:19:50 2006 -0700
+++ b/tools/xm-test/tests/vtpm/Makefile.am Mon Dec 04 08:24:41 2006 -0700
@@ -7,7 +7,8 @@ TESTS = 01_vtpm-list_pos.test \
05_vtpm-loc_migr.test \
06_vtpm-susp_res_pcrs.test \
07_vtpm-mig_pcrs.test \
- 08_vtpm-mig_pcrs.test
+ 08_vtpm-mig_pcrs.test \
+ 09_vtpm-xapi.test
XFAIL_TESTS =
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/ia64/xen/Makefile
--- a/xen/arch/ia64/xen/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/ia64/xen/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -1,5 +1,7 @@ subdir-y += oprofile
subdir-y += oprofile
+obj-y += machine_kexec.o
+obj-y += crash.o
obj-y += acpi.o
obj-y += dom0_ops.o
obj-y += domain.o
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/powerpc/Makefile
--- a/xen/arch/powerpc/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/powerpc/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -40,6 +40,8 @@ obj-y += sysctl.o
obj-y += sysctl.o
obj-y += time.o
obj-y += usercopy.o
+obj-y += machine_kexec.o
+obj-y += crash.o
obj-$(debug) += 0opt.o
obj-$(crash_debug) += gdbstub.o
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -43,6 +43,8 @@ obj-y += traps.o
obj-y += traps.o
obj-y += usercopy.o
obj-y += x86_emulate.o
+obj-y += machine_kexec.o
+obj-y += crash.o
obj-$(crash_debug) += gdbstub.o
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/platform.c Mon Dec 04 08:24:41 2006 -0700
@@ -920,7 +920,7 @@ void handle_mmio(unsigned long gpa)
df = regs->eflags & X86_EFLAGS_DF ? 1 : 0;
mode = hvm_guest_x86_mode(v);
- inst_addr = hvm_get_segment_base(v, seg_cs) + regs->eip;
+ inst_addr = hvm_get_segment_base(v, x86_seg_cs) + regs->eip;
inst_len = hvm_instruction_length(inst_addr, mode);
if ( inst_len <= 0 )
{
@@ -964,10 +964,10 @@ void handle_mmio(unsigned long gpa)
addr = regs->edi;
if ( ad_size == WORD )
addr &= 0xFFFF;
- addr += hvm_get_segment_base(v, seg_es);
+ addr += hvm_get_segment_base(v, x86_seg_es);
if ( addr == gpa )
{
- enum segment seg;
+ enum x86_segment seg;
dir = IOREQ_WRITE;
addr = regs->esi;
@@ -975,13 +975,13 @@ void handle_mmio(unsigned long gpa)
addr &= 0xFFFF;
switch ( seg_sel )
{
- case 0x26: seg = seg_es; break;
- case 0x2e: seg = seg_cs; break;
- case 0x36: seg = seg_ss; break;
+ case 0x26: seg = x86_seg_es; break;
+ case 0x2e: seg = x86_seg_cs; break;
+ case 0x36: seg = x86_seg_ss; break;
case 0:
- case 0x3e: seg = seg_ds; break;
- case 0x64: seg = seg_fs; break;
- case 0x65: seg = seg_gs; break;
+ case 0x3e: seg = x86_seg_ds; break;
+ case 0x64: seg = x86_seg_fs; break;
+ case 0x65: seg = x86_seg_gs; break;
default: domain_crash_synchronous();
}
addr += hvm_get_segment_base(v, seg);
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/svm/emulate.c
--- a/xen/arch/x86/hvm/svm/emulate.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/svm/emulate.c Mon Dec 04 08:24:41 2006 -0700
@@ -128,17 +128,6 @@ static inline unsigned long DECODE_GPR_V
return (unsigned long) -1; \
}
-#if 0
-/*
- * hv_is_canonical - checks if the given address is canonical
- */
-static inline u64 hv_is_canonical(u64 addr)
-{
- u64 bits = addr & (u64)0xffff800000000000;
- return (u64)((bits == (u64)0xffff800000000000) || (bits == (u64)0x0));
-}
-#endif
-
#define modrm operand [0]
#define sib operand [1]
@@ -209,7 +198,7 @@ unsigned long get_effective_addr_modrm64
#if __x86_64__
/* 64-bit mode */
- if (vmcb->cs.attributes.fields.l && (vmcb->efer & EFER_LMA))
+ if (vmcb->cs.attr.fields.l && (vmcb->efer & EFER_LMA))
return vmcb->rip + inst_len + *size + disp;
#endif
return disp;
@@ -334,7 +323,7 @@ unsigned long svm_rip2pointer(struct vmc
* no matter what kind of addressing is used.
*/
unsigned long p = vmcb->cs.base + vmcb->rip;
- if (!(vmcb->cs.attributes.fields.l && vmcb->efer & EFER_LMA))
+ if (!(vmcb->cs.attr.fields.l && vmcb->efer & EFER_LMA))
return (u32)p; /* mask to 32 bits */
/* NB. Should mask to 16 bits if in real mode or 16-bit protected mode. */
return p;
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/svm/svm.c Mon Dec 04 08:24:41 2006 -0700
@@ -269,13 +269,11 @@ static int svm_long_mode_enabled(struct
return test_bit(SVM_CPU_STATE_LMA_ENABLED, &v->arch.hvm_svm.cpu_state);
}
-#define IS_CANO_ADDRESS(add) 1
-
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
{
u64 msr_content = 0;
- struct vcpu *vc = current;
- struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
+ struct vcpu *v = current;
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
switch ((u32)regs->ecx)
{
@@ -284,17 +282,25 @@ static inline int long_mode_do_msr_read(
msr_content &= ~EFER_SVME;
break;
+#ifdef __x86_64__
case MSR_FS_BASE:
msr_content = vmcb->fs.base;
- break;
+ goto check_long_mode;
case MSR_GS_BASE:
msr_content = vmcb->gs.base;
- break;
+ goto check_long_mode;
case MSR_SHADOW_GS_BASE:
msr_content = vmcb->kerngsbase;
- break;
+ check_long_mode:
+ if ( !svm_long_mode_enabled(v) )
+ {
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+ return 0;
+ }
+ break;
+#endif
case MSR_STAR:
msr_content = vmcb->star;
@@ -326,25 +332,25 @@ static inline int long_mode_do_msr_write
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
+ u32 ecx = regs->ecx;
struct vcpu *v = current;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
HVM_DBG_LOG(DBG_LEVEL_1, "msr %x msr_content %"PRIx64"\n",
- (u32)regs->ecx, msr_content);
-
- switch ( (u32)regs->ecx )
+ ecx, msr_content);
+
+ switch ( ecx )
{
case MSR_EFER:
-#ifdef __x86_64__
/* offending reserved bit will cause #GP */
if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
{
- printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
- msr_content);
- svm_inject_exception(v, TRAP_gp_fault, 1, 0);
- return 0;
- }
-
+ gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
+ "EFER: %"PRIx64"\n", msr_content);
+ goto gp_fault;
+ }
+
+#ifdef __x86_64__
/* LME: 0 -> 1 */
if ( msr_content & EFER_LME &&
!test_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state))
@@ -353,10 +359,9 @@ static inline int long_mode_do_msr_write
!test_bit(SVM_CPU_STATE_PAE_ENABLED,
&v->arch.hvm_svm.cpu_state) )
{
- printk("Trying to set LME bit when "
- "in paging mode or PAE bit is not set\n");
- svm_inject_exception(v, TRAP_gp_fault, 1, 0);
- return 0;
+ gdprintk(XENLOG_WARNING, "Trying to set LME bit when "
+ "in paging mode or PAE bit is not set\n");
+ goto gp_fault;
}
set_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state);
}
@@ -371,37 +376,38 @@ static inline int long_mode_do_msr_write
vmcb->efer = msr_content | EFER_SVME;
break;
+#ifdef __x86_64__
case MSR_FS_BASE:
case MSR_GS_BASE:
+ case MSR_SHADOW_GS_BASE:
if ( !svm_long_mode_enabled(v) )
- goto exit_and_crash;
-
- if (!IS_CANO_ADDRESS(msr_content))
- {
- HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
- svm_inject_exception(v, TRAP_gp_fault, 1, 0);
- }
-
- if (regs->ecx == MSR_FS_BASE)
+ goto gp_fault;
+
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+
+ if ( ecx == MSR_FS_BASE )
vmcb->fs.base = msr_content;
- else
+ else if ( ecx == MSR_GS_BASE )
vmcb->gs.base = msr_content;
- break;
-
- case MSR_SHADOW_GS_BASE:
- vmcb->kerngsbase = msr_content;
- break;
+ else
+ vmcb->kerngsbase = msr_content;
+ break;
+#endif
case MSR_STAR:
vmcb->star = msr_content;
break;
case MSR_LSTAR:
- vmcb->lstar = msr_content;
- break;
-
case MSR_CSTAR:
- vmcb->cstar = msr_content;
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+
+ if ( ecx == MSR_LSTAR )
+ vmcb->lstar = msr_content;
+ else
+ vmcb->cstar = msr_content;
break;
case MSR_SYSCALL_MASK:
@@ -414,10 +420,11 @@ static inline int long_mode_do_msr_write
return 1;
- exit_and_crash:
- gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
- domain_crash(v->domain);
- return 1; /* handled */
+ uncanonical_address:
+ HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write %x\n", ecx);
+ gp_fault:
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+ return 0;
}
@@ -476,13 +483,13 @@ static int svm_guest_x86_mode(struct vcp
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
if ( vmcb->efer & EFER_LMA )
- return (vmcb->cs.attributes.fields.l ?
+ return (vmcb->cs.attr.fields.l ?
X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32);
if ( svm_realmode(v) )
return X86EMUL_MODE_REAL;
- return (vmcb->cs.attributes.fields.db ?
+ return (vmcb->cs.attr.fields.db ?
X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16);
}
@@ -509,29 +516,49 @@ unsigned long svm_get_ctrl_reg(struct vc
return 0; /* dummy */
}
-static unsigned long svm_get_segment_base(struct vcpu *v, enum segment seg)
+static unsigned long svm_get_segment_base(struct vcpu *v, enum x86_segment seg)
{
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
int long_mode = 0;
#ifdef __x86_64__
- long_mode = vmcb->cs.attributes.fields.l && (vmcb->efer & EFER_LMA);
+ long_mode = vmcb->cs.attr.fields.l && (vmcb->efer & EFER_LMA);
#endif
switch ( seg )
{
- case seg_cs: return long_mode ? 0 : vmcb->cs.base;
- case seg_ds: return long_mode ? 0 : vmcb->ds.base;
- case seg_es: return long_mode ? 0 : vmcb->es.base;
- case seg_fs: return vmcb->fs.base;
- case seg_gs: return vmcb->gs.base;
- case seg_ss: return long_mode ? 0 : vmcb->ss.base;
- case seg_tr: return vmcb->tr.base;
- case seg_gdtr: return vmcb->gdtr.base;
- case seg_idtr: return vmcb->idtr.base;
- case seg_ldtr: return vmcb->ldtr.base;
+ case x86_seg_cs: return long_mode ? 0 : vmcb->cs.base;
+ case x86_seg_ds: return long_mode ? 0 : vmcb->ds.base;
+ case x86_seg_es: return long_mode ? 0 : vmcb->es.base;
+ case x86_seg_fs: return vmcb->fs.base;
+ case x86_seg_gs: return vmcb->gs.base;
+ case x86_seg_ss: return long_mode ? 0 : vmcb->ss.base;
+ case x86_seg_tr: return vmcb->tr.base;
+ case x86_seg_gdtr: return vmcb->gdtr.base;
+ case x86_seg_idtr: return vmcb->idtr.base;
+ case x86_seg_ldtr: return vmcb->ldtr.base;
}
BUG();
return 0;
+}
+
+static void svm_get_segment_register(struct vcpu *v, enum x86_segment seg,
+ struct segment_register *reg)
+{
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
+ switch ( seg )
+ {
+ case x86_seg_cs: memcpy(reg, &vmcb->cs, sizeof(*reg)); break;
+ case x86_seg_ds: memcpy(reg, &vmcb->ds, sizeof(*reg)); break;
+ case x86_seg_es: memcpy(reg, &vmcb->es, sizeof(*reg)); break;
+ case x86_seg_fs: memcpy(reg, &vmcb->fs, sizeof(*reg)); break;
+ case x86_seg_gs: memcpy(reg, &vmcb->gs, sizeof(*reg)); break;
+ case x86_seg_ss: memcpy(reg, &vmcb->ss, sizeof(*reg)); break;
+ case x86_seg_tr: memcpy(reg, &vmcb->tr, sizeof(*reg)); break;
+ case x86_seg_gdtr: memcpy(reg, &vmcb->gdtr, sizeof(*reg)); break;
+ case x86_seg_idtr: memcpy(reg, &vmcb->idtr, sizeof(*reg)); break;
+ case x86_seg_ldtr: memcpy(reg, &vmcb->ldtr, sizeof(*reg)); break;
+ default: BUG();
+ }
}
/* Make sure that xen intercepts any FP accesses from current */
@@ -785,6 +812,15 @@ static void svm_vcpu_destroy(struct vcpu
svm_destroy_vmcb(v);
}
+static void svm_hvm_inject_exception(
+ unsigned int trapnr, int errcode, unsigned long cr2)
+{
+ struct vcpu *v = current;
+ svm_inject_exception(v, trapnr, (errcode != -1), errcode);
+ if ( trapnr == TRAP_page_fault )
+ v->arch.hvm_svm.vmcb->cr2 = v->arch.hvm_svm.cpu_cr2 = cr2;
+}
+
int start_svm(void)
{
u32 eax, ecx, edx;
@@ -844,11 +880,14 @@ int start_svm(void)
hvm_funcs.guest_x86_mode = svm_guest_x86_mode;
hvm_funcs.get_guest_ctrl_reg = svm_get_ctrl_reg;
hvm_funcs.get_segment_base = svm_get_segment_base;
+ hvm_funcs.get_segment_register = svm_get_segment_register;
hvm_funcs.update_host_cr3 = svm_update_host_cr3;
hvm_funcs.stts = svm_stts;
hvm_funcs.set_tsc_offset = svm_set_tsc_offset;
+
+ hvm_funcs.inject_exception = svm_hvm_inject_exception;
hvm_funcs.init_ap_context = svm_init_ap_context;
hvm_funcs.init_hypercall_page = svm_init_hypercall_page;
@@ -1154,7 +1193,7 @@ static void svm_dr_access(struct vcpu *v
static void svm_get_prefix_info(
struct vmcb_struct *vmcb,
- unsigned int dir, segment_selector_t **seg, unsigned int *asize)
+ unsigned int dir, svm_segment_register_t **seg, unsigned int *asize)
{
unsigned char inst[MAX_INST_LEN];
int i;
@@ -1235,18 +1274,18 @@ static inline int svm_get_io_address(
unsigned long reg;
unsigned int asize, isize;
int long_mode = 0;
- segment_selector_t *seg = NULL;
+ svm_segment_register_t *seg = NULL;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
#ifdef __x86_64__
/* If we're in long mode, we shouldn't check the segment presence & limit
*/
- long_mode = vmcb->cs.attributes.fields.l && vmcb->efer & EFER_LMA;
+ long_mode = vmcb->cs.attr.fields.l && vmcb->efer & EFER_LMA;
#endif
- /* d field of cs.attributes is 1 for 32-bit, 0 for 16 or 64 bit.
- * l field combined with EFER_LMA -> longmode says whether it's 16 or 64
bit.
+ /* d field of cs.attr is 1 for 32-bit, 0 for 16 or 64 bit.
+ * l field combined with EFER_LMA says whether it's 16 or 64 bit.
*/
- asize = (long_mode)?64:((vmcb->cs.attributes.fields.db)?32:16);
+ asize = (long_mode)?64:((vmcb->cs.attr.fields.db)?32:16);
/* The ins/outs instructions are single byte, so if we have got more
@@ -1266,7 +1305,7 @@ static inline int svm_get_io_address(
reg = regs->esi;
if (!seg) /* If no prefix, used DS. */
seg = &vmcb->ds;
- if (!long_mode && (seg->attributes.fields.type & 0xa) == 0x8) {
+ if (!long_mode && (seg->attr.fields.type & 0xa) == 0x8) {
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}
@@ -1275,14 +1314,14 @@ static inline int svm_get_io_address(
{
reg = regs->edi;
seg = &vmcb->es; /* Note: This is ALWAYS ES. */
- if (!long_mode && (seg->attributes.fields.type & 0xa) != 0x2) {
+ if (!long_mode && (seg->attr.fields.type & 0xa) != 0x2) {
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}
}
/* If the segment isn't present, give GP fault! */
- if (!long_mode && !seg->attributes.fields.p)
+ if (!long_mode && !seg->attr.fields.p)
{
svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
@@ -1305,7 +1344,7 @@ static inline int svm_get_io_address(
{
ASSERT(*addr == (u32)*addr);
if ((u32)(*addr + size - 1) < (u32)*addr ||
- (seg->attributes.fields.type & 0xc) != 0x4 ?
+ (seg->attr.fields.type & 0xc) != 0x4 ?
*addr + size - 1 > seg->limit :
*addr <= seg->limit)
{
@@ -1318,9 +1357,9 @@ static inline int svm_get_io_address(
occur. Note that the checking is not necessary for page granular
segments as transfers crossing page boundaries will be broken up
anyway. */
- if (!seg->attributes.fields.g && *count > 1)
- {
- if ((seg->attributes.fields.type & 0xc) != 0x4)
+ if (!seg->attr.fields.g && *count > 1)
+ {
+ if ((seg->attr.fields.type & 0xc) != 0x4)
{
/* expand-up */
if (!(regs->eflags & EF_DF))
@@ -1355,8 +1394,35 @@ static inline int svm_get_io_address(
*addr += seg->base;
}
- else if (seg == &vmcb->fs || seg == &vmcb->gs)
- *addr += seg->base;
+#ifdef __x86_64__
+ else
+ {
+ if (seg == &vmcb->fs || seg == &vmcb->gs)
+ *addr += seg->base;
+
+ if (!is_canonical_address(*addr) ||
+ !is_canonical_address(*addr + size - 1))
+ {
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
+ return 0;
+ }
+ if (*count > (1UL << 48) / size)
+ *count = (1UL << 48) / size;
+ if (!(regs->eflags & EF_DF))
+ {
+ if (*addr + *count * size - 1 < *addr ||
+ !is_canonical_address(*addr + *count * size - 1))
+ *count = (*addr & ~((1UL << 48) - 1)) / size;
+ }
+ else
+ {
+ if ((*count - 1) * size > *addr ||
+ !is_canonical_address(*addr + (*count - 1) * size))
+ *count = (*addr & ~((1UL << 48) - 1)) / size + 1;
+ }
+ ASSERT(*count);
+ }
+#endif
return 1;
}
@@ -2154,52 +2220,52 @@ static int svm_do_vmmcall_reset_to_realm
/* setup the segment registers and all their hidden states */
vmcb->cs.sel = 0xF000;
- vmcb->cs.attributes.bytes = 0x089b;
+ vmcb->cs.attr.bytes = 0x089b;
vmcb->cs.limit = 0xffff;
vmcb->cs.base = 0x000F0000;
vmcb->ss.sel = 0x00;
- vmcb->ss.attributes.bytes = 0x0893;
+ vmcb->ss.attr.bytes = 0x0893;
vmcb->ss.limit = 0xffff;
vmcb->ss.base = 0x00;
vmcb->ds.sel = 0x00;
- vmcb->ds.attributes.bytes = 0x0893;
+ vmcb->ds.attr.bytes = 0x0893;
vmcb->ds.limit = 0xffff;
vmcb->ds.base = 0x00;
vmcb->es.sel = 0x00;
- vmcb->es.attributes.bytes = 0x0893;
+ vmcb->es.attr.bytes = 0x0893;
vmcb->es.limit = 0xffff;
vmcb->es.base = 0x00;
vmcb->fs.sel = 0x00;
- vmcb->fs.attributes.bytes = 0x0893;
+ vmcb->fs.attr.bytes = 0x0893;
vmcb->fs.limit = 0xffff;
vmcb->fs.base = 0x00;
vmcb->gs.sel = 0x00;
- vmcb->gs.attributes.bytes = 0x0893;
+ vmcb->gs.attr.bytes = 0x0893;
vmcb->gs.limit = 0xffff;
vmcb->gs.base = 0x00;
vmcb->ldtr.sel = 0x00;
- vmcb->ldtr.attributes.bytes = 0x0000;
+ vmcb->ldtr.attr.bytes = 0x0000;
vmcb->ldtr.limit = 0x0;
vmcb->ldtr.base = 0x00;
vmcb->gdtr.sel = 0x00;
- vmcb->gdtr.attributes.bytes = 0x0000;
+ vmcb->gdtr.attr.bytes = 0x0000;
vmcb->gdtr.limit = 0x0;
vmcb->gdtr.base = 0x00;
vmcb->tr.sel = 0;
- vmcb->tr.attributes.bytes = 0;
+ vmcb->tr.attr.bytes = 0;
vmcb->tr.limit = 0x0;
vmcb->tr.base = 0;
vmcb->idtr.sel = 0x00;
- vmcb->idtr.attributes.bytes = 0x0000;
+ vmcb->idtr.attr.bytes = 0x0000;
vmcb->idtr.limit = 0x3ff;
vmcb->idtr.base = 0x00;
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/svm/vmcb.c
--- a/xen/arch/x86/hvm/svm/vmcb.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/svm/vmcb.c Mon Dec 04 08:24:41 2006 -0700
@@ -90,7 +90,7 @@ static int construct_vmcb(struct vcpu *v
{
struct arch_svm_struct *arch_svm = &v->arch.hvm_svm;
struct vmcb_struct *vmcb = arch_svm->vmcb;
- segment_attributes_t attrib;
+ svm_segment_attributes_t attrib;
/* Always flush the TLB on VMRUN. */
vmcb->tlb_control = 1;
@@ -166,13 +166,13 @@ static int construct_vmcb(struct vcpu *v
attrib.fields.p = 1; /* segment present */
attrib.fields.db = 1; /* 32-bit */
attrib.fields.g = 1; /* 4K pages in limit */
- vmcb->es.attributes = attrib;
- vmcb->ss.attributes = attrib;
- vmcb->ds.attributes = attrib;
- vmcb->fs.attributes = attrib;
- vmcb->gs.attributes = attrib;
+ vmcb->es.attr = attrib;
+ vmcb->ss.attr = attrib;
+ vmcb->ds.attr = attrib;
+ vmcb->fs.attr = attrib;
+ vmcb->gs.attr = attrib;
attrib.fields.type = 0xb; /* type=0xb -> executable/readable, accessed */
- vmcb->cs.attributes = attrib;
+ vmcb->cs.attr = attrib;
/* Guest IDT. */
vmcb->idtr.base = 0;
@@ -186,11 +186,11 @@ static int construct_vmcb(struct vcpu *v
vmcb->ldtr.sel = 0;
vmcb->ldtr.base = 0;
vmcb->ldtr.limit = 0;
- vmcb->ldtr.attributes.bytes = 0;
+ vmcb->ldtr.attr.bytes = 0;
/* Guest TSS. */
attrib.fields.type = 0xb; /* 32-bit TSS (busy) */
- vmcb->tr.attributes = attrib;
+ vmcb->tr.attr = attrib;
vmcb->tr.base = 0;
vmcb->tr.limit = 0xff;
@@ -278,10 +278,10 @@ void svm_do_launch(struct vcpu *v)
v->arch.schedule_tail = arch_svm_do_resume;
}
-static void svm_dump_sel(char *name, segment_selector_t *s)
+static void svm_dump_sel(char *name, svm_segment_register_t *s)
{
printk("%s: sel=0x%04x, attr=0x%04x, limit=0x%08x, base=0x%016llx\n",
- name, s->sel, s->attributes.bytes, s->limit,
+ name, s->sel, s->attr.bytes, s->limit,
(unsigned long long)s->base);
}
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/vlapic.c Mon Dec 04 08:24:41 2006 -0700
@@ -119,19 +119,16 @@ static int vlapic_find_highest_vector(u3
static int vlapic_test_and_set_irr(int vector, struct vlapic *vlapic)
{
- vlapic->flush_tpr_threshold = 1;
return vlapic_test_and_set_vector(vector, vlapic->regs + APIC_IRR);
}
static void vlapic_set_irr(int vector, struct vlapic *vlapic)
{
- vlapic->flush_tpr_threshold = 1;
vlapic_set_vector(vector, vlapic->regs + APIC_IRR);
}
static void vlapic_clear_irr(int vector, struct vlapic *vlapic)
{
- vlapic->flush_tpr_threshold = 1;
vlapic_clear_vector(vector, vlapic->regs + APIC_IRR);
}
@@ -634,7 +631,6 @@ static void vlapic_write(struct vcpu *v,
{
case APIC_TASKPRI:
vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
- vlapic->flush_tpr_threshold = 1;
break;
case APIC_EOI:
@@ -667,10 +663,7 @@ static void vlapic_write(struct vcpu *v,
}
}
else
- {
vlapic->disabled &= ~VLAPIC_SW_DISABLED;
- vlapic->flush_tpr_threshold = 1;
- }
break;
case APIC_ESR:
@@ -730,7 +723,7 @@ static void vlapic_write(struct vcpu *v,
break;
default:
- gdprintk(XENLOG_WARNING,
+ gdprintk(XENLOG_DEBUG,
"Local APIC Write to read-only register 0x%x\n", offset);
break;
}
@@ -925,8 +918,6 @@ static int vlapic_reset(struct vlapic *v
vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
vlapic->disabled |= VLAPIC_SW_DISABLED;
- vlapic->flush_tpr_threshold = 1;
-
return 1;
}
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/vmx/Makefile
--- a/xen/arch/x86/hvm/vmx/Makefile Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/Makefile Mon Dec 04 08:24:41 2006 -0700
@@ -1,6 +1,6 @@ subdir-$(x86_32) += x86_32
subdir-$(x86_32) += x86_32
subdir-$(x86_64) += x86_64
-obj-y += io.o
+obj-y += intr.o
obj-y += vmcs.o
obj-y += vmx.o
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Dec 04 08:24:41 2006 -0700
@@ -95,13 +95,7 @@ static void vmx_save_host_msrs(void)
rdmsrl(msr_index[i], host_msr_state->msrs[i]);
}
-#define CASE_READ_MSR(address) \
- case MSR_ ## address: \
- msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_ ## address]; \
- break
-
-#define CASE_WRITE_MSR(address) \
- case MSR_ ## address: \
+#define WRITE_MSR(address) \
guest_msr_state->msrs[VMX_INDEX_MSR_ ## address] = msr_content; \
if ( !test_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags) )\
set_bit(VMX_INDEX_MSR_ ## address, &guest_msr_state->flags); \
@@ -109,7 +103,6 @@ static void vmx_save_host_msrs(void)
set_bit(VMX_INDEX_MSR_ ## address, &host_msr_state->flags); \
break
-#define IS_CANO_ADDRESS(add) 1
static inline int long_mode_do_msr_read(struct cpu_user_regs *regs)
{
u64 msr_content = 0;
@@ -123,27 +116,38 @@ static inline int long_mode_do_msr_read(
break;
case MSR_FS_BASE:
- if ( !(vmx_long_mode_enabled(v)) )
- goto exit_and_crash;
-
msr_content = __vmread(GUEST_FS_BASE);
- break;
+ goto check_long_mode;
case MSR_GS_BASE:
- if ( !(vmx_long_mode_enabled(v)) )
- goto exit_and_crash;
-
msr_content = __vmread(GUEST_GS_BASE);
- break;
+ goto check_long_mode;
case MSR_SHADOW_GS_BASE:
msr_content = guest_msr_state->shadow_gs;
- break;
-
- CASE_READ_MSR(STAR);
- CASE_READ_MSR(LSTAR);
- CASE_READ_MSR(CSTAR);
- CASE_READ_MSR(SYSCALL_MASK);
+ check_long_mode:
+ if ( !(vmx_long_mode_enabled(v)) )
+ {
+ vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
+ return 0;
+ }
+ break;
+
+ case MSR_STAR:
+ msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_STAR];
+ break;
+
+ case MSR_LSTAR:
+ msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_LSTAR];
+ break;
+
+ case MSR_CSTAR:
+ msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_CSTAR];
+ break;
+
+ case MSR_SYSCALL_MASK:
+ msr_content = guest_msr_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
+ break;
default:
return 0;
@@ -155,32 +159,28 @@ static inline int long_mode_do_msr_read(
regs->edx = (u32)(msr_content >> 32);
return 1;
-
- exit_and_crash:
- gdprintk(XENLOG_ERR, "Fatal error reading MSR %lx\n", (long)regs->ecx);
- domain_crash(v->domain);
- return 1; /* handled */
}
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
+ u32 ecx = regs->ecx;
struct vcpu *v = current;
struct vmx_msr_state *guest_msr_state = &v->arch.hvm_vmx.msr_state;
struct vmx_msr_state *host_msr_state = &this_cpu(host_msr_state);
HVM_DBG_LOG(DBG_LEVEL_1, "msr 0x%x msr_content 0x%"PRIx64"\n",
- (u32)regs->ecx, msr_content);
-
- switch ( (u32)regs->ecx ) {
+ ecx, msr_content);
+
+ switch ( ecx )
+ {
case MSR_EFER:
/* offending reserved bit will cause #GP */
if ( msr_content & ~(EFER_LME | EFER_LMA | EFER_NX | EFER_SCE) )
{
- printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
- msr_content);
- vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
- return 0;
+ gdprintk(XENLOG_WARNING, "Trying to set reserved bit in "
+ "EFER: %"PRIx64"\n", msr_content);
+ goto gp_fault;
}
if ( (msr_content & EFER_LME)
@@ -188,9 +188,9 @@ static inline int long_mode_do_msr_write
{
if ( unlikely(vmx_paging_enabled(v)) )
{
- printk("Trying to set EFER.LME with paging enabled\n");
- vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
- return 0;
+ gdprintk(XENLOG_WARNING,
+ "Trying to set EFER.LME with paging enabled\n");
+ goto gp_fault;
}
}
else if ( !(msr_content & EFER_LME)
@@ -198,9 +198,9 @@ static inline int long_mode_do_msr_write
{
if ( unlikely(vmx_paging_enabled(v)) )
{
- printk("Trying to clear EFER.LME with paging enabled\n");
- vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
- return 0;
+ gdprintk(XENLOG_WARNING,
+ "Trying to clear EFER.LME with paging enabled\n");
+ goto gp_fault;
}
}
@@ -209,35 +209,40 @@ static inline int long_mode_do_msr_write
case MSR_FS_BASE:
case MSR_GS_BASE:
+ case MSR_SHADOW_GS_BASE:
if ( !vmx_long_mode_enabled(v) )
- goto exit_and_crash;
-
- if ( !IS_CANO_ADDRESS(msr_content) )
- {
- HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
- vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
- return 0;
- }
-
- if ( regs->ecx == MSR_FS_BASE )
+ goto gp_fault;
+
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+
+ if ( ecx == MSR_FS_BASE )
__vmwrite(GUEST_FS_BASE, msr_content);
+ else if ( ecx == MSR_GS_BASE )
+ __vmwrite(GUEST_GS_BASE, msr_content);
else
- __vmwrite(GUEST_GS_BASE, msr_content);
-
- break;
-
- case MSR_SHADOW_GS_BASE:
- if ( !(vmx_long_mode_enabled(v)) )
- goto exit_and_crash;
-
- v->arch.hvm_vmx.msr_state.shadow_gs = msr_content;
- wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
- break;
-
- CASE_WRITE_MSR(STAR);
- CASE_WRITE_MSR(LSTAR);
- CASE_WRITE_MSR(CSTAR);
- CASE_WRITE_MSR(SYSCALL_MASK);
+ {
+ v->arch.hvm_vmx.msr_state.shadow_gs = msr_content;
+ wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
+ }
+
+ break;
+
+ case MSR_STAR:
+ WRITE_MSR(STAR);
+
+ case MSR_LSTAR:
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+ WRITE_MSR(LSTAR);
+
+ case MSR_CSTAR:
+ if ( !is_canonical_address(msr_content) )
+ goto uncanonical_address;
+ WRITE_MSR(CSTAR);
+
+ case MSR_SYSCALL_MASK:
+ WRITE_MSR(SYSCALL_MASK);
default:
return 0;
@@ -245,10 +250,11 @@ static inline int long_mode_do_msr_write
return 1;
- exit_and_crash:
- gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
- domain_crash(v->domain);
- return 1; /* handled */
+ uncanonical_address:
+ HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write %x\n", ecx);
+ gp_fault:
+ vmx_inject_hw_exception(v, TRAP_gp_fault, 0);
+ return 0;
}
/*
@@ -501,7 +507,7 @@ static unsigned long vmx_get_ctrl_reg(st
return 0; /* dummy */
}
-static unsigned long vmx_get_segment_base(struct vcpu *v, enum segment seg)
+static unsigned long vmx_get_segment_base(struct vcpu *v, enum x86_segment seg)
{
unsigned long base = 0;
int long_mode = 0;
@@ -516,20 +522,92 @@ static unsigned long vmx_get_segment_bas
switch ( seg )
{
- case seg_cs: if ( !long_mode ) base = __vmread(GUEST_CS_BASE); break;
- case seg_ds: if ( !long_mode ) base = __vmread(GUEST_DS_BASE); break;
- case seg_es: if ( !long_mode ) base = __vmread(GUEST_ES_BASE); break;
- case seg_fs: base = __vmread(GUEST_FS_BASE); break;
- case seg_gs: base = __vmread(GUEST_GS_BASE); break;
- case seg_ss: if ( !long_mode ) base = __vmread(GUEST_SS_BASE); break;
- case seg_tr: base = __vmread(GUEST_TR_BASE); break;
- case seg_gdtr: base = __vmread(GUEST_GDTR_BASE); break;
- case seg_idtr: base = __vmread(GUEST_IDTR_BASE); break;
- case seg_ldtr: base = __vmread(GUEST_LDTR_BASE); break;
+ case x86_seg_cs: if ( !long_mode ) base = __vmread(GUEST_CS_BASE); break;
+ case x86_seg_ds: if ( !long_mode ) base = __vmread(GUEST_DS_BASE); break;
+ case x86_seg_es: if ( !long_mode ) base = __vmread(GUEST_ES_BASE); break;
+ case x86_seg_fs: base = __vmread(GUEST_FS_BASE); break;
+ case x86_seg_gs: base = __vmread(GUEST_GS_BASE); break;
+ case x86_seg_ss: if ( !long_mode ) base = __vmread(GUEST_SS_BASE); break;
+ case x86_seg_tr: base = __vmread(GUEST_TR_BASE); break;
+ case x86_seg_gdtr: base = __vmread(GUEST_GDTR_BASE); break;
+ case x86_seg_idtr: base = __vmread(GUEST_IDTR_BASE); break;
+ case x86_seg_ldtr: base = __vmread(GUEST_LDTR_BASE); break;
default: BUG(); break;
}
return base;
+}
+
+static void vmx_get_segment_register(struct vcpu *v, enum x86_segment seg,
+ struct segment_register *reg)
+{
+ u16 attr = 0;
+
+ ASSERT(v == current);
+
+ switch ( seg )
+ {
+ case x86_seg_cs:
+ reg->sel = __vmread(GUEST_CS_SELECTOR);
+ reg->limit = __vmread(GUEST_CS_LIMIT);
+ reg->base = __vmread(GUEST_CS_BASE);
+ attr = __vmread(GUEST_CS_AR_BYTES);
+ break;
+ case x86_seg_ds:
+ reg->sel = __vmread(GUEST_DS_SELECTOR);
+ reg->limit = __vmread(GUEST_DS_LIMIT);
+ reg->base = __vmread(GUEST_DS_BASE);
+ attr = __vmread(GUEST_DS_AR_BYTES);
+ break;
+ case x86_seg_es:
+ reg->sel = __vmread(GUEST_ES_SELECTOR);
+ reg->limit = __vmread(GUEST_ES_LIMIT);
+ reg->base = __vmread(GUEST_ES_BASE);
+ attr = __vmread(GUEST_ES_AR_BYTES);
+ break;
+ case x86_seg_fs:
+ reg->sel = __vmread(GUEST_FS_SELECTOR);
+ reg->limit = __vmread(GUEST_FS_LIMIT);
+ reg->base = __vmread(GUEST_FS_BASE);
+ attr = __vmread(GUEST_FS_AR_BYTES);
+ break;
+ case x86_seg_gs:
+ reg->sel = __vmread(GUEST_GS_SELECTOR);
+ reg->limit = __vmread(GUEST_GS_LIMIT);
+ reg->base = __vmread(GUEST_GS_BASE);
+ attr = __vmread(GUEST_GS_AR_BYTES);
+ break;
+ case x86_seg_ss:
+ reg->sel = __vmread(GUEST_SS_SELECTOR);
+ reg->limit = __vmread(GUEST_SS_LIMIT);
+ reg->base = __vmread(GUEST_SS_BASE);
+ attr = __vmread(GUEST_SS_AR_BYTES);
+ break;
+ case x86_seg_tr:
+ reg->sel = __vmread(GUEST_TR_SELECTOR);
+ reg->limit = __vmread(GUEST_TR_LIMIT);
+ reg->base = __vmread(GUEST_TR_BASE);
+ attr = __vmread(GUEST_TR_AR_BYTES);
+ break;
+ case x86_seg_gdtr:
+ reg->limit = __vmread(GUEST_GDTR_LIMIT);
+ reg->base = __vmread(GUEST_GDTR_BASE);
+ break;
+ case x86_seg_idtr:
+ reg->limit = __vmread(GUEST_IDTR_LIMIT);
+ reg->base = __vmread(GUEST_IDTR_BASE);
+ break;
+ case x86_seg_ldtr:
+ reg->sel = __vmread(GUEST_LDTR_SELECTOR);
+ reg->limit = __vmread(GUEST_LDTR_LIMIT);
+ reg->base = __vmread(GUEST_LDTR_BASE);
+ attr = __vmread(GUEST_LDTR_AR_BYTES);
+ break;
+ default:
+ BUG();
+ }
+
+ reg->attr.bytes = (attr & 0xff) | ((attr >> 4) & 0xf00);
}
/* Make sure that xen intercepts any FP accesses from current */
@@ -630,6 +708,22 @@ static int vmx_pae_enabled(struct vcpu *
return (vmx_paging_enabled(v) && (cr4 & X86_CR4_PAE));
}
+/* Works only for vcpu == current */
+static void vmx_update_host_cr3(struct vcpu *v)
+{
+ ASSERT(v == current);
+ __vmwrite(HOST_CR3, v->arch.cr3);
+}
+
+static void vmx_inject_exception(
+ unsigned int trapnr, int errcode, unsigned long cr2)
+{
+ struct vcpu *v = current;
+ vmx_inject_hw_exception(v, trapnr, errcode);
+ if ( trapnr == TRAP_page_fault )
+ v->arch.hvm_vmx.cpu_cr2 = cr2;
+}
+
/* Setup HVM interfaces */
static void vmx_setup_hvm_funcs(void)
{
@@ -650,11 +744,14 @@ static void vmx_setup_hvm_funcs(void)
hvm_funcs.guest_x86_mode = vmx_guest_x86_mode;
hvm_funcs.get_guest_ctrl_reg = vmx_get_ctrl_reg;
hvm_funcs.get_segment_base = vmx_get_segment_base;
+ hvm_funcs.get_segment_register = vmx_get_segment_register;
hvm_funcs.update_host_cr3 = vmx_update_host_cr3;
hvm_funcs.stts = vmx_stts;
hvm_funcs.set_tsc_offset = vmx_set_tsc_offset;
+
+ hvm_funcs.inject_exception = vmx_inject_exception;
hvm_funcs.init_ap_context = vmx_init_ap_context;
@@ -962,14 +1059,14 @@ static void vmx_do_invlpg(unsigned long
static int vmx_check_descriptor(int long_mode, unsigned long eip, int inst_len,
- enum segment seg, unsigned long *base,
+ enum x86_segment seg, unsigned long *base,
u32 *limit, u32 *ar_bytes)
{
enum vmcs_field ar_field, base_field, limit_field;
*base = 0;
*limit = 0;
- if ( seg != seg_es )
+ if ( seg != x86_seg_es )
{
unsigned char inst[MAX_INST_LEN];
int i;
@@ -999,22 +1096,22 @@ static int vmx_check_descriptor(int long
#endif
continue;
case 0x2e: /* CS */
- seg = seg_cs;
+ seg = x86_seg_cs;
continue;
case 0x36: /* SS */
- seg = seg_ss;
+ seg = x86_seg_ss;
continue;
case 0x26: /* ES */
- seg = seg_es;
+ seg = x86_seg_es;
continue;
case 0x64: /* FS */
- seg = seg_fs;
+ seg = x86_seg_fs;
continue;
case 0x65: /* GS */
- seg = seg_gs;
+ seg = x86_seg_gs;
continue;
case 0x3e: /* DS */
- seg = seg_ds;
+ seg = x86_seg_ds;
continue;
}
}
@@ -1022,32 +1119,32 @@ static int vmx_check_descriptor(int long
switch ( seg )
{
- case seg_cs:
+ case x86_seg_cs:
ar_field = GUEST_CS_AR_BYTES;
base_field = GUEST_CS_BASE;
limit_field = GUEST_CS_LIMIT;
break;
- case seg_ds:
+ case x86_seg_ds:
ar_field = GUEST_DS_AR_BYTES;
base_field = GUEST_DS_BASE;
limit_field = GUEST_DS_LIMIT;
break;
- case seg_es:
+ case x86_seg_es:
ar_field = GUEST_ES_AR_BYTES;
base_field = GUEST_ES_BASE;
limit_field = GUEST_ES_LIMIT;
break;
- case seg_fs:
+ case x86_seg_fs:
ar_field = GUEST_FS_AR_BYTES;
base_field = GUEST_FS_BASE;
limit_field = GUEST_FS_LIMIT;
break;
- case seg_gs:
+ case x86_seg_gs:
ar_field = GUEST_FS_AR_BYTES;
base_field = GUEST_FS_BASE;
limit_field = GUEST_FS_LIMIT;
break;
- case seg_ss:
+ case x86_seg_ss:
ar_field = GUEST_GS_AR_BYTES;
base_field = GUEST_GS_BASE;
limit_field = GUEST_GS_LIMIT;
@@ -1057,7 +1154,7 @@ static int vmx_check_descriptor(int long
return 0;
}
- if ( !long_mode || seg == seg_fs || seg == seg_gs )
+ if ( !long_mode || seg == x86_seg_fs || seg == x86_seg_gs )
{
*base = __vmread(base_field);
*limit = __vmread(limit_field);
@@ -1127,7 +1224,7 @@ static void vmx_io_instruction(unsigned
* selector is null.
*/
if ( !vmx_check_descriptor(long_mode, regs->eip, inst_len,
- dir == IOREQ_WRITE ? seg_ds : seg_es,
+ dir==IOREQ_WRITE ? x86_seg_ds : x86_seg_es,
&base, &limit, &ar_bytes) ) {
if ( !long_mode ) {
vmx_inject_hw_exception(current, TRAP_gp_fault, 0);
@@ -1196,6 +1293,32 @@ static void vmx_io_instruction(unsigned
ASSERT(count);
}
}
+#ifdef __x86_64__
+ else
+ {
+ if ( !is_canonical_address(addr) ||
+ !is_canonical_address(addr + size - 1) )
+ {
+ vmx_inject_hw_exception(current, TRAP_gp_fault, 0);
+ return;
+ }
+ if ( count > (1UL << 48) / size )
+ count = (1UL << 48) / size;
+ if ( !(regs->eflags & EF_DF) )
+ {
+ if ( addr + count * size - 1 < addr ||
+ !is_canonical_address(addr + count * size - 1) )
+ count = (addr & ~((1UL << 48) - 1)) / size;
+ }
+ else
+ {
+ if ( (count - 1) * size > addr ||
+ !is_canonical_address(addr + (count - 1) * size) )
+ count = (addr & ~((1UL << 48) - 1)) / size + 1;
+ }
+ ASSERT(count);
+ }
+#endif
/*
* Handle string pio instructions that cross pages or that
@@ -2413,7 +2536,6 @@ asmlinkage void vmx_vmexit_handler(struc
break;
case EXIT_REASON_TPR_BELOW_THRESHOLD:
- vcpu_vlapic(v)->flush_tpr_threshold = 1;
break;
default:
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/mm.c Mon Dec 04 08:24:41 2006 -0700
@@ -3033,12 +3033,39 @@ long arch_memory_op(int op, XEN_GUEST_HA
* Writable Pagetables
*/
+struct ptwr_emulate_ctxt {
+ struct x86_emulate_ctxt ctxt;
+ unsigned long cr2;
+ l1_pgentry_t pte;
+};
+
+static int ptwr_emulated_read(
+ enum x86_segment seg,
+ unsigned long offset,
+ unsigned long *val,
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
+{
+ unsigned int rc;
+ unsigned long addr = offset;
+
+ *val = 0;
+ if ( (rc = copy_from_user((void *)val, (void *)addr, bytes)) != 0 )
+ {
+ propagate_page_fault(addr + bytes - rc, 0); /* read fault */
+ return X86EMUL_PROPAGATE_FAULT;
+ }
+
+ return X86EMUL_CONTINUE;
+}
+
static int ptwr_emulated_update(
unsigned long addr,
paddr_t old,
paddr_t val,
unsigned int bytes,
- unsigned int do_cmpxchg)
+ unsigned int do_cmpxchg,
+ struct ptwr_emulate_ctxt *ptwr_ctxt)
{
unsigned long gmfn, mfn;
struct page_info *page;
@@ -3046,11 +3073,11 @@ static int ptwr_emulated_update(
struct vcpu *v = current;
struct domain *d = v->domain;
- /* Aligned access only, thank you. */
- if ( !access_ok(addr, bytes) || ((addr & (bytes-1)) != 0) )
- {
- MEM_LOG("ptwr_emulate: Unaligned or bad size ptwr access (%d, %lx)",
- bytes, addr);
+ /* Only allow naturally-aligned stores within the original %cr2 page. */
+ if ( unlikely(((addr^ptwr_ctxt->cr2) & PAGE_MASK) || (addr & (bytes-1))) )
+ {
+ MEM_LOG("Bad ptwr access (cr2=%lx, addr=%lx, bytes=%u)",
+ ptwr_ctxt->cr2, addr, bytes);
return X86EMUL_UNHANDLEABLE;
}
@@ -3079,17 +3106,9 @@ static int ptwr_emulated_update(
old |= full;
}
- /* Read the PTE that maps the page being updated. */
- guest_get_eff_l1e(v, addr, &pte);
- if ( unlikely(!(l1e_get_flags(pte) & _PAGE_PRESENT)) )
- {
- MEM_LOG("%s: Cannot get L1 PTE for guest address %lx",
- __func__, addr);
- return X86EMUL_UNHANDLEABLE;
- }
-
- gmfn = l1e_get_pfn(pte);
- mfn = gmfn_to_mfn(d, gmfn);
+ pte = ptwr_ctxt->pte;
+ gmfn = l1e_get_pfn(pte);
+ mfn = gmfn_to_mfn(d, gmfn);
page = mfn_to_page(mfn);
/* We are looking only for read-only mappings of p.t. pages. */
@@ -3164,26 +3183,33 @@ static int ptwr_emulated_update(
}
static int ptwr_emulated_write(
- unsigned long addr,
+ enum x86_segment seg,
+ unsigned long offset,
unsigned long val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
- return ptwr_emulated_update(addr, 0, val, bytes, 0);
+ return ptwr_emulated_update(
+ offset, 0, val, bytes, 0,
+ container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
}
static int ptwr_emulated_cmpxchg(
- unsigned long addr,
+ enum x86_segment seg,
+ unsigned long offset,
unsigned long old,
unsigned long new,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
- return ptwr_emulated_update(addr, old, new, bytes, 1);
+ return ptwr_emulated_update(
+ offset, old, new, bytes, 1,
+ container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
}
static int ptwr_emulated_cmpxchg8b(
- unsigned long addr,
+ enum x86_segment seg,
+ unsigned long offset,
unsigned long old,
unsigned long old_hi,
unsigned long new,
@@ -3192,18 +3218,17 @@ static int ptwr_emulated_cmpxchg8b(
{
if ( CONFIG_PAGING_LEVELS == 2 )
return X86EMUL_UNHANDLEABLE;
- else
- return ptwr_emulated_update(
- addr, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1);
+ return ptwr_emulated_update(
+ offset, ((u64)old_hi << 32) | old, ((u64)new_hi << 32) | new, 8, 1,
+ container_of(ctxt, struct ptwr_emulate_ctxt, ctxt));
}
static struct x86_emulate_ops ptwr_emulate_ops = {
- .read_std = x86_emulate_read_std,
- .write_std = x86_emulate_write_std,
- .read_emulated = x86_emulate_read_std,
- .write_emulated = ptwr_emulated_write,
- .cmpxchg_emulated = ptwr_emulated_cmpxchg,
- .cmpxchg8b_emulated = ptwr_emulated_cmpxchg8b
+ .read = ptwr_emulated_read,
+ .insn_fetch = ptwr_emulated_read,
+ .write = ptwr_emulated_write,
+ .cmpxchg = ptwr_emulated_cmpxchg,
+ .cmpxchg8b = ptwr_emulated_cmpxchg8b
};
/* Write page fault handler: check if guest is trying to modify a PTE. */
@@ -3214,7 +3239,7 @@ int ptwr_do_page_fault(struct vcpu *v, u
unsigned long pfn;
struct page_info *page;
l1_pgentry_t pte;
- struct x86_emulate_ctxt emul_ctxt;
+ struct ptwr_emulate_ctxt ptwr_ctxt;
LOCK_BIGLOCK(d);
@@ -3235,10 +3260,11 @@ int ptwr_do_page_fault(struct vcpu *v, u
(page_get_owner(page) != d) )
goto bail;
- emul_ctxt.regs = guest_cpu_user_regs();
- emul_ctxt.cr2 = addr;
- emul_ctxt.mode = X86EMUL_MODE_HOST;
- if ( x86_emulate_memop(&emul_ctxt, &ptwr_emulate_ops) )
+ ptwr_ctxt.ctxt.regs = guest_cpu_user_regs();
+ ptwr_ctxt.ctxt.mode = X86EMUL_MODE_HOST;
+ ptwr_ctxt.cr2 = addr;
+ ptwr_ctxt.pte = pte;
+ if ( x86_emulate_memop(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) )
goto bail;
UNLOCK_BIGLOCK(d);
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/mm/shadow/common.c Mon Dec 04 08:24:41 2006 -0700
@@ -69,18 +69,122 @@ int _shadow_mode_refcounts(struct domain
/* x86 emulator support for the shadow code
*/
+struct segment_register *hvm_get_seg_reg(
+ enum x86_segment seg, struct sh_emulate_ctxt *sh_ctxt)
+{
+ struct segment_register *seg_reg = &sh_ctxt->seg_reg[seg];
+ if ( !__test_and_set_bit(seg, &sh_ctxt->valid_seg_regs) )
+ hvm_get_segment_register(current, seg, seg_reg);
+ return seg_reg;
+}
+
+enum hvm_access_type {
+ hvm_access_insn_fetch, hvm_access_read, hvm_access_write
+};
+
+static int hvm_translate_linear_addr(
+ enum x86_segment seg,
+ unsigned long offset,
+ unsigned int bytes,
+ enum hvm_access_type access_type,
+ struct sh_emulate_ctxt *sh_ctxt,
+ unsigned long *paddr)
+{
+ struct segment_register *reg = hvm_get_seg_reg(seg, sh_ctxt);
+ unsigned long limit, addr = offset;
+ uint32_t last_byte;
+
+ if ( sh_ctxt->ctxt.mode != X86EMUL_MODE_PROT64 )
+ {
+ /*
+ * COMPATIBILITY MODE: Apply segment checks and add base.
+ */
+
+ switch ( access_type )
+ {
+ case hvm_access_read:
+ if ( (reg->attr.fields.type & 0xa) == 0x8 )
+ goto gpf; /* execute-only code segment */
+ break;
+ case hvm_access_write:
+ if ( (reg->attr.fields.type & 0xa) != 0x2 )
+ goto gpf; /* not a writable data segment */
+ break;
+ default:
+ break;
+ }
+
+ /* Calculate the segment limit, including granularity flag. */
+ limit = reg->limit;
+ if ( reg->attr.fields.g )
+ limit = (limit << 12) | 0xfff;
+
+ last_byte = offset + bytes - 1;
+
+ /* Is this a grows-down data segment? Special limit check if so. */
+ if ( (reg->attr.fields.type & 0xc) == 0x4 )
+ {
+ /* Is upper limit 0xFFFF or 0xFFFFFFFF? */
+ if ( !reg->attr.fields.db )
+ last_byte = (uint16_t)last_byte;
+
+ /* Check first byte and last byte against respective bounds. */
+ if ( (offset <= limit) || (last_byte < offset) )
+ goto gpf;
+ }
+ else if ( (last_byte > limit) || (last_byte < offset) )
+ goto gpf; /* last byte is beyond limit or wraps 0xFFFFFFFF */
+
+ /*
+ * Hardware truncates to 32 bits in compatibility mode.
+ * It does not truncate to 16 bits in 16-bit address-size mode.
+ */
+ addr = (uint32_t)(addr + reg->base);
+ }
+ else
+ {
+ /*
+ * LONG MODE: FS and GS add segment base. Addresses must be canonical.
+ */
+
+ if ( (seg == x86_seg_fs) || (seg == x86_seg_gs) )
+ addr += reg->base;
+
+ if ( !is_canonical_address(addr) )
+ goto gpf;
+ }
+
+ *paddr = addr;
+ return 0;
+
+ gpf:
+ /* Inject #GP(0). */
+ hvm_inject_exception(TRAP_gp_fault, 0, 0);
+ return X86EMUL_PROPAGATE_FAULT;
+}
+
static int
-sh_x86_emulate_read_std(unsigned long addr,
- unsigned long *val,
- unsigned int bytes,
- struct x86_emulate_ctxt *ctxt)
-{
+hvm_read(enum x86_segment seg,
+ unsigned long offset,
+ unsigned long *val,
+ unsigned int bytes,
+ enum hvm_access_type access_type,
+ struct sh_emulate_ctxt *sh_ctxt)
+{
+ unsigned long addr;
+ int rc, errcode;
+
+ rc = hvm_translate_linear_addr(
+ seg, offset, bytes, access_type, sh_ctxt, &addr);
+ if ( rc )
+ return rc;
+
*val = 0;
// XXX -- this is WRONG.
// It entirely ignores the permissions in the page tables.
// In this case, that is only a user vs supervisor access check.
//
- if ( hvm_copy_from_guest_virt(val, addr, bytes) == 0 )
+ if ( (rc = hvm_copy_from_guest_virt(val, addr, bytes)) == 0 )
{
#if 0
struct vcpu *v = current;
@@ -95,93 +199,168 @@ sh_x86_emulate_read_std(unsigned long ad
* was mapped here. This should never happen: we're here because
* of a write fault at the end of the instruction we're emulating. */
SHADOW_PRINTK("read failed to va %#lx\n", addr);
+ errcode = ring_3(sh_ctxt->ctxt.regs) ? PFEC_user_mode : 0;
+ if ( access_type == hvm_access_insn_fetch )
+ errcode |= PFEC_insn_fetch;
+ hvm_inject_exception(TRAP_page_fault, errcode, addr + bytes - rc);
return X86EMUL_PROPAGATE_FAULT;
}
+void shadow_init_emulation(struct sh_emulate_ctxt *sh_ctxt,
+ struct cpu_user_regs *regs)
+{
+ struct segment_register *creg;
+ struct vcpu *v = current;
+ unsigned long addr;
+
+ sh_ctxt->ctxt.regs = regs;
+
+ /* Segment cache initialisation. Primed with CS. */
+ sh_ctxt->valid_seg_regs = 0;
+ creg = hvm_get_seg_reg(x86_seg_cs, sh_ctxt);
+
+ /* Work out the emulation mode. */
+ if ( hvm_long_mode_enabled(v) )
+ sh_ctxt->ctxt.mode = creg->attr.fields.l ?
+ X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32;
+ else if ( regs->eflags & X86_EFLAGS_VM )
+ sh_ctxt->ctxt.mode = X86EMUL_MODE_REAL;
+ else
+ sh_ctxt->ctxt.mode = creg->attr.fields.db ?
+ X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16;
+
+ /* Attempt to prefetch whole instruction. */
+ sh_ctxt->insn_buf_bytes =
+ (!hvm_translate_linear_addr(
+ x86_seg_cs, regs->eip, sizeof(sh_ctxt->insn_buf),
+ hvm_access_insn_fetch, sh_ctxt, &addr) &&
+ !hvm_copy_from_guest_virt(
+ sh_ctxt->insn_buf, addr, sizeof(sh_ctxt->insn_buf)))
+ ? sizeof(sh_ctxt->insn_buf) : 0;
+}
+
static int
-sh_x86_emulate_write_std(unsigned long addr,
- unsigned long val,
+sh_x86_emulate_read(enum x86_segment seg,
+ unsigned long offset,
+ unsigned long *val,
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
+{
+ return hvm_read(seg, offset, val, bytes, hvm_access_read,
+ container_of(ctxt, struct sh_emulate_ctxt, ctxt));
+}
+
+static int
+sh_x86_emulate_insn_fetch(enum x86_segment seg,
+ unsigned long offset,
+ unsigned long *val,
unsigned int bytes,
struct x86_emulate_ctxt *ctxt)
{
-#if 0
+ struct sh_emulate_ctxt *sh_ctxt =
+ container_of(ctxt, struct sh_emulate_ctxt, ctxt);
+ unsigned int insn_off = offset - ctxt->regs->eip;
+
+ /* Fall back if requested bytes are not in the prefetch cache. */
+ if ( unlikely((insn_off + bytes) > sh_ctxt->insn_buf_bytes) )
+ return hvm_read(seg, offset, val, bytes,
+ hvm_access_insn_fetch, sh_ctxt);
+
+ /* Hit the cache. Simple memcpy. */
+ *val = 0;
+ memcpy(val, &sh_ctxt->insn_buf[insn_off], bytes);
+ return X86EMUL_CONTINUE;
+}
+
+static int
+sh_x86_emulate_write(enum x86_segment seg,
+ unsigned long offset,
+ unsigned long val,
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
+{
+ struct sh_emulate_ctxt *sh_ctxt =
+ container_of(ctxt, struct sh_emulate_ctxt, ctxt);
struct vcpu *v = current;
- SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
- v->domain->domain_id, v->vcpu_id, addr, val, bytes);
-#endif
-
- // XXX -- this is WRONG.
- // It entirely ignores the permissions in the page tables.
- // In this case, that includes user vs supervisor, and
- // write access.
- //
- if ( hvm_copy_to_guest_virt(addr, &val, bytes) == 0 )
- return X86EMUL_CONTINUE;
-
- /* If we got here, there was nothing mapped here, or a bad GFN
- * was mapped here. This should never happen: we're here because
- * of a write fault at the end of the instruction we're emulating,
- * which should be handled by sh_x86_emulate_write_emulated. */
- SHADOW_PRINTK("write failed to va %#lx\n", addr);
- return X86EMUL_PROPAGATE_FAULT;
-}
-
-static int
-sh_x86_emulate_write_emulated(unsigned long addr,
- unsigned long val,
- unsigned int bytes,
- struct x86_emulate_ctxt *ctxt)
-{
- struct vcpu *v = current;
+ unsigned long addr;
+ int rc;
+
+ rc = hvm_translate_linear_addr(
+ seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
+ if ( rc )
+ return rc;
+
#if 0
SHADOW_PRINTK("d=%u v=%u a=%#lx v=%#lx bytes=%u\n",
v->domain->domain_id, v->vcpu_id, addr, val, bytes);
#endif
- return v->arch.shadow.mode->x86_emulate_write(v, addr, &val, bytes, ctxt);
+ return v->arch.shadow.mode->x86_emulate_write(
+ v, addr, &val, bytes, sh_ctxt);
}
static int
-sh_x86_emulate_cmpxchg_emulated(unsigned long addr,
- unsigned long old,
- unsigned long new,
- unsigned int bytes,
- struct x86_emulate_ctxt *ctxt)
-{
+sh_x86_emulate_cmpxchg(enum x86_segment seg,
+ unsigned long offset,
+ unsigned long old,
+ unsigned long new,
+ unsigned int bytes,
+ struct x86_emulate_ctxt *ctxt)
+{
+ struct sh_emulate_ctxt *sh_ctxt =
+ container_of(ctxt, struct sh_emulate_ctxt, ctxt);
struct vcpu *v = current;
+ unsigned long addr;
+ int rc;
+
+ rc = hvm_translate_linear_addr(
+ seg, offset, bytes, hvm_access_write, sh_ctxt, &addr);
+ if ( rc )
+ return rc;
+
#if 0
SHADOW_PRINTK("d=%u v=%u a=%#lx o?=%#lx n:=%#lx bytes=%u\n",
v->domain->domain_id, v->vcpu_id, addr, old, new, bytes);
#endif
- return v->arch.shadow.mode->x86_emulate_cmpxchg(v, addr, old, new,
- bytes, ctxt);
+ return v->arch.shadow.mode->x86_emulate_cmpxchg(
+ v, addr, old, new, bytes, sh_ctxt);
}
static int
-sh_x86_emulate_cmpxchg8b_emulated(unsigned long addr,
- unsigned long old_lo,
- unsigned long old_hi,
- unsigned long new_lo,
- unsigned long new_hi,
- struct x86_emulate_ctxt *ctxt)
-{
+sh_x86_emulate_cmpxchg8b(enum x86_segment seg,
+ unsigned long offset,
+ unsigned long old_lo,
+ unsigned long old_hi,
+ unsigned long new_lo,
+ unsigned long new_hi,
+ struct x86_emulate_ctxt *ctxt)
+{
+ struct sh_emulate_ctxt *sh_ctxt =
+ container_of(ctxt, struct sh_emulate_ctxt, ctxt);
struct vcpu *v = current;
+ unsigned long addr;
+ int rc;
+
+ rc = hvm_translate_linear_addr(
+ seg, offset, 8, hvm_access_write, sh_ctxt, &addr);
+ if ( rc )
+ return rc;
+
#if 0
SHADOW_PRINTK("d=%u v=%u a=%#lx o?=%#lx:%lx n:=%#lx:%lx\n",
v->domain->domain_id, v->vcpu_id, addr, old_hi, old_lo,
new_hi, new_lo, ctxt);
#endif
- return v->arch.shadow.mode->x86_emulate_cmpxchg8b(v, addr, old_lo, old_hi,
- new_lo, new_hi, ctxt);
+ return v->arch.shadow.mode->x86_emulate_cmpxchg8b(
+ v, addr, old_lo, old_hi, new_lo, new_hi, sh_ctxt);
}
struct x86_emulate_ops shadow_emulator_ops = {
- .read_std = sh_x86_emulate_read_std,
- .write_std = sh_x86_emulate_write_std,
- .read_emulated = sh_x86_emulate_read_std,
- .write_emulated = sh_x86_emulate_write_emulated,
- .cmpxchg_emulated = sh_x86_emulate_cmpxchg_emulated,
- .cmpxchg8b_emulated = sh_x86_emulate_cmpxchg8b_emulated,
+ .read = sh_x86_emulate_read,
+ .insn_fetch = sh_x86_emulate_insn_fetch,
+ .write = sh_x86_emulate_write,
+ .cmpxchg = sh_x86_emulate_cmpxchg,
+ .cmpxchg8b = sh_x86_emulate_cmpxchg8b,
};
/**************************************************************************/
@@ -938,12 +1117,13 @@ shadow_set_p2m_entry(struct domain *d, u
void *table = sh_map_domain_page(table_mfn);
unsigned long gfn_remainder = gfn;
l1_pgentry_t *p2m_entry;
+ int rv=0;
#if CONFIG_PAGING_LEVELS >= 4
if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
L4_PAGETABLE_SHIFT - PAGE_SHIFT,
L4_PAGETABLE_ENTRIES, PGT_l3_page_table) )
- return 0;
+ goto out;
#endif
#if CONFIG_PAGING_LEVELS >= 3
// When using PAE Xen, we only allow 33 bits of pseudo-physical
@@ -957,12 +1137,12 @@ shadow_set_p2m_entry(struct domain *d, u
? 8
: L3_PAGETABLE_ENTRIES),
PGT_l2_page_table) )
- return 0;
+ goto out;
#endif
if ( !p2m_next_level(d, &table_mfn, &table, &gfn_remainder, gfn,
L2_PAGETABLE_SHIFT - PAGE_SHIFT,
L2_PAGETABLE_ENTRIES, PGT_l1_page_table) )
- return 0;
+ goto out;
p2m_entry = p2m_find_entry(table, &gfn_remainder, gfn,
0, L1_PAGETABLE_ENTRIES);
@@ -981,9 +1161,12 @@ shadow_set_p2m_entry(struct domain *d, u
(void)__shadow_validate_guest_entry(
d->vcpu[0], table_mfn, p2m_entry, sizeof(*p2m_entry));
+ /* Success */
+ rv = 1;
+
+ out:
sh_unmap_domain_page(table);
-
- return 1;
+ return rv;
}
// Allocate a new p2m table for a domain.
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/mm/shadow/multi.c
--- a/xen/arch/x86/mm/shadow/multi.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/mm/shadow/multi.c Mon Dec 04 08:24:41 2006 -0700
@@ -581,7 +581,7 @@ guest_index(void *ptr)
return (u32)((unsigned long)ptr & ~PAGE_MASK) / sizeof(guest_l1e_t);
}
-static inline u32
+static u32
shadow_l1_index(mfn_t *smfn, u32 guest_index)
{
#if (GUEST_PAGING_LEVELS == 2) && (SHADOW_PAGING_LEVELS != 2)
@@ -593,7 +593,7 @@ shadow_l1_index(mfn_t *smfn, u32 guest_i
#endif
}
-static inline u32
+static u32
shadow_l2_index(mfn_t *smfn, u32 guest_index)
{
#if (GUEST_PAGING_LEVELS == 2) && (SHADOW_PAGING_LEVELS != 2)
@@ -613,13 +613,13 @@ shadow_l2_index(mfn_t *smfn, u32 guest_i
#if GUEST_PAGING_LEVELS >= 4
-static inline u32
+static u32
shadow_l3_index(mfn_t *smfn, u32 guest_index)
{
return guest_index;
}
-static inline u32
+static u32
shadow_l4_index(mfn_t *smfn, u32 guest_index)
{
return guest_index;
@@ -2582,7 +2582,7 @@ static int sh_page_fault(struct vcpu *v,
mfn_t gmfn, sl1mfn=_mfn(0);
shadow_l1e_t sl1e, *ptr_sl1e;
paddr_t gpa;
- struct x86_emulate_ctxt emul_ctxt;
+ struct sh_emulate_ctxt emul_ctxt;
int r, mmio;
fetch_type_t ft = 0;
@@ -2808,26 +2808,21 @@ static int sh_page_fault(struct vcpu *v,
return EXCRET_fault_fixed;
emulate:
- /* Take the register set we were called with */
- if ( is_hvm_domain(d) )
- hvm_store_cpu_guest_regs(v, regs, NULL);
- emul_ctxt.regs = regs;
- emul_ctxt.cr2 = va;
- emul_ctxt.mode = (is_hvm_domain(d) ?
- hvm_guest_x86_mode(v) : X86EMUL_MODE_HOST);
-
+ if ( !is_hvm_domain(d) || !guest_mode(regs) )
+ goto not_a_shadow_fault;
+
+ hvm_store_cpu_guest_regs(v, regs, NULL);
SHADOW_PRINTK("emulate: eip=%#lx\n", regs->eip);
- v->arch.shadow.propagate_fault = 0;
+ shadow_init_emulation(&emul_ctxt, regs);
/*
* We do not emulate user writes. Instead we use them as a hint that the
* page is no longer a page table. This behaviour differs from native, but
* it seems very unlikely that any OS grants user access to page tables.
- * We also disallow guest PTE updates from within Xen.
*/
- if ( (regs->error_code & PFEC_user_mode) || !guest_mode(regs) ||
- x86_emulate_memop(&emul_ctxt, &shadow_emulator_ops) )
+ if ( (regs->error_code & PFEC_user_mode) ||
+ x86_emulate_memop(&emul_ctxt.ctxt, &shadow_emulator_ops) )
{
SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n",
mfn_x(gmfn));
@@ -2836,19 +2831,10 @@ static int sh_page_fault(struct vcpu *v,
* to support more operations in the emulator. More likely,
* though, this is a hint that this page should not be shadowed. */
shadow_remove_all_shadows(v, gmfn);
- /* This means that actual missing operations will cause the
- * guest to loop on the same page fault. */
- goto done;
- }
-
- /* Emulation triggered another page fault? */
- if ( v->arch.shadow.propagate_fault )
- goto not_a_shadow_fault;
+ }
/* Emulator has changed the user registers: write back */
- if ( is_hvm_domain(d) )
- hvm_load_cpu_guest_regs(v, regs);
-
+ hvm_load_cpu_guest_regs(v, regs);
goto done;
mmio:
@@ -3787,11 +3773,11 @@ int sh_remove_l3_shadow(struct vcpu *v,
* or NULL for error. */
static inline void * emulate_map_dest(struct vcpu *v,
unsigned long vaddr,
- struct x86_emulate_ctxt *ctxt,
+ struct sh_emulate_ctxt *sh_ctxt,
mfn_t *mfnp)
{
walk_t gw;
- u32 flags;
+ u32 flags, errcode;
gfn_t gfn;
mfn_t mfn;
@@ -3802,13 +3788,17 @@ static inline void * emulate_map_dest(st
sh_audit_gw(v, &gw);
unmap_walk(v, &gw);
- if ( !(flags & _PAGE_PRESENT)
- || !(flags & _PAGE_RW)
- || (!(flags & _PAGE_USER) && ring_3(ctxt->regs)) )
- {
- /* This write would have faulted even on bare metal */
- v->arch.shadow.propagate_fault = 1;
- return NULL;
+ if ( !(flags & _PAGE_PRESENT) )
+ {
+ errcode = 0;
+ goto page_fault;
+ }
+
+ if ( !(flags & _PAGE_RW) ||
+ (!(flags & _PAGE_USER) && ring_3(sh_ctxt->ctxt.regs)) )
+ {
+ errcode = PFEC_page_present;
+ goto page_fault;
}
/* Attempted a write to a bad gfn? This should never happen:
@@ -3818,11 +3808,18 @@ static inline void * emulate_map_dest(st
ASSERT(sh_mfn_is_a_page_table(mfn));
*mfnp = mfn;
return sh_map_domain_page(mfn) + (vaddr & ~PAGE_MASK);
+
+ page_fault:
+ errcode |= PFEC_write_access;
+ if ( ring_3(sh_ctxt->ctxt.regs) )
+ errcode |= PFEC_user_mode;
+ hvm_inject_exception(TRAP_page_fault, errcode, vaddr);
+ return NULL;
}
int
sh_x86_emulate_write(struct vcpu *v, unsigned long vaddr, void *src,
- u32 bytes, struct x86_emulate_ctxt *ctxt)
+ u32 bytes, struct sh_emulate_ctxt *sh_ctxt)
{
mfn_t mfn;
void *addr;
@@ -3833,7 +3830,7 @@ sh_x86_emulate_write(struct vcpu *v, uns
ASSERT(shadow_lock_is_acquired(v->domain));
ASSERT(((vaddr & ~PAGE_MASK) + bytes) <= PAGE_SIZE);
- if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
+ if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
return X86EMUL_PROPAGATE_FAULT;
memcpy(addr, src, bytes);
@@ -3851,7 +3848,7 @@ int
int
sh_x86_emulate_cmpxchg(struct vcpu *v, unsigned long vaddr,
unsigned long old, unsigned long new,
- unsigned int bytes, struct x86_emulate_ctxt *ctxt)
+ unsigned int bytes, struct sh_emulate_ctxt *sh_ctxt)
{
mfn_t mfn;
void *addr;
@@ -3864,7 +3861,7 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u
if ( vaddr & (bytes-1) )
return X86EMUL_UNHANDLEABLE;
- if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
+ if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
return X86EMUL_PROPAGATE_FAULT;
switch ( bytes )
@@ -3900,7 +3897,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
sh_x86_emulate_cmpxchg8b(struct vcpu *v, unsigned long vaddr,
unsigned long old_lo, unsigned long old_hi,
unsigned long new_lo, unsigned long new_hi,
- struct x86_emulate_ctxt *ctxt)
+ struct sh_emulate_ctxt *sh_ctxt)
{
mfn_t mfn;
void *addr;
@@ -3912,7 +3909,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v,
if ( vaddr & 7 )
return X86EMUL_UNHANDLEABLE;
- if ( (addr = emulate_map_dest(v, vaddr, ctxt, &mfn)) == NULL )
+ if ( (addr = emulate_map_dest(v, vaddr, sh_ctxt, &mfn)) == NULL )
return X86EMUL_PROPAGATE_FAULT;
old = (((u64) old_hi) << 32) | (u64) old_lo;
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/mm/shadow/private.h
--- a/xen/arch/x86/mm/shadow/private.h Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/mm/shadow/private.h Mon Dec 04 08:24:41 2006 -0700
@@ -506,6 +506,25 @@ static inline void sh_unpin(struct vcpu
}
}
+
+/**************************************************************************/
+/* PTE-write emulation. */
+
+struct sh_emulate_ctxt {
+ struct x86_emulate_ctxt ctxt;
+
+ /* Cache of up to 15 bytes of instruction. */
+ uint8_t insn_buf[15];
+ uint8_t insn_buf_bytes;
+
+ /* Cache of segment registers already gathered for this emulation. */
+ unsigned int valid_seg_regs;
+ struct segment_register seg_reg[6];
+};
+
+void shadow_init_emulation(struct sh_emulate_ctxt *sh_ctxt,
+ struct cpu_user_regs *regs);
+
#endif /* _XEN_SHADOW_PRIVATE_H */
/*
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/oprofile/op_model_athlon.c
--- a/xen/arch/x86/oprofile/op_model_athlon.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/oprofile/op_model_athlon.c Mon Dec 04 08:24:41 2006 -0700
@@ -113,14 +113,15 @@ static int athlon_check_ctrs(unsigned in
unsigned long eip = regs->eip;
int mode = 0;
struct vcpu *v = current;
- struct cpu_user_regs tmp_regs;
+ struct cpu_user_regs *guest_regs = guest_cpu_user_regs();
if (!guest_mode(regs) &&
(regs->eip == (unsigned long)svm_stgi_label)) {
/* SVM guest was running when NMI occurred */
- hvm_store_cpu_guest_regs(v, &tmp_regs, NULL);
- eip = tmp_regs.eip;
- mode = xenoprofile_get_mode(v, &tmp_regs);
+ ASSERT(is_hvm_vcpu(v));
+ hvm_store_cpu_guest_regs(v, guest_regs, NULL);
+ eip = guest_regs->eip;
+ mode = xenoprofile_get_mode(v, guest_regs);
} else {
eip = regs->eip;
mode = xenoprofile_get_mode(v, regs);
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/setup.c Mon Dec 04 08:24:41 2006 -0700
@@ -27,6 +27,7 @@
#include <asm/shadow.h>
#include <asm/e820.h>
#include <acm/acm_hooks.h>
+#include <xen/kexec.h>
extern void dmi_scan_machine(void);
extern void generic_apic_probe(void);
@@ -273,6 +274,20 @@ static void srat_detect_node(int cpu)
printk(KERN_INFO "CPU %d APIC %d -> Node %d\n", cpu, apicid, node);
}
+void __init move_memory(unsigned long dst,
+ unsigned long src_start, unsigned long src_end)
+{
+#if defined(CONFIG_X86_32)
+ memmove((void *)dst, /* use low mapping */
+ (void *)src_start, /* use low mapping */
+ src_end - src_start);
+#elif defined(CONFIG_X86_64)
+ memmove(__va(dst),
+ __va(src_start),
+ src_end - src_start);
+#endif
+}
+
void __init __start_xen(multiboot_info_t *mbi)
{
char __cmdline[] = "", *cmdline = __cmdline;
@@ -415,15 +430,8 @@ void __init __start_xen(multiboot_info_t
initial_images_start = xenheap_phys_end;
initial_images_end = initial_images_start + modules_length;
-#if defined(CONFIG_X86_32)
- memmove((void *)initial_images_start, /* use low mapping */
- (void *)mod[0].mod_start, /* use low mapping */
- mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
-#elif defined(CONFIG_X86_64)
- memmove(__va(initial_images_start),
- __va(mod[0].mod_start),
- mod[mbi->mods_count-1].mod_end - mod[0].mod_start);
-#endif
+ move_memory(initial_images_start,
+ mod[0].mod_start, mod[mbi->mods_count-1].mod_end);
/* Initialise boot-time allocator with all RAM situated after modules. */
xenheap_phys_start = init_boot_allocator(__pa(&_end));
@@ -471,10 +479,56 @@ void __init __start_xen(multiboot_info_t
#endif
}
+ if ( kexec_crash_area.size > 0 )
+ {
+ unsigned long kdump_start, kdump_size, k;
+
+ /* Mark images pages as free for now. */
+
+ init_boot_pages(initial_images_start, initial_images_end);
+
+ kdump_start = kexec_crash_area.start;
+ kdump_size = kexec_crash_area.size;
+
+ printk("Kdump: %luMB (%lukB) at 0x%lx\n",
+ kdump_size >> 20,
+ kdump_size >> 10,
+ kdump_start);
+
+ if ( (kdump_start & ~PAGE_MASK) || (kdump_size & ~PAGE_MASK) )
+ panic("Kdump parameters not page aligned\n");
+
+ kdump_start >>= PAGE_SHIFT;
+ kdump_size >>= PAGE_SHIFT;
+
+ /* allocate pages for Kdump memory area */
+
+ k = alloc_boot_pages_at(kdump_size, kdump_start);
+
+ if ( k != kdump_start )
+ panic("Unable to reserve Kdump memory\n");
+
+ /* allocate pages for relocated initial images */
+
+ k = ((initial_images_end - initial_images_start) & ~PAGE_MASK) ? 1 : 0;
+ k += (initial_images_end - initial_images_start) >> PAGE_SHIFT;
+
+ k = alloc_boot_pages(k, 1);
+
+ if ( !k )
+ panic("Unable to allocate initial images memory\n");
+
+ move_memory(k << PAGE_SHIFT, initial_images_start, initial_images_end);
+
+ initial_images_end -= initial_images_start;
+ initial_images_start = k << PAGE_SHIFT;
+ initial_images_end += initial_images_start;
+ }
+
memguard_init();
percpu_guard_areas();
- printk("System RAM: %luMB (%lukB)\n",
+ printk("System RAM: %luMB (%lukB)\n",
nr_pages >> (20 - PAGE_SHIFT),
nr_pages << (PAGE_SHIFT - 10));
total_pages = nr_pages;
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/traps.c Mon Dec 04 08:24:41 2006 -0700
@@ -45,6 +45,7 @@
#include <xen/iocap.h>
#include <xen/nmi.h>
#include <xen/version.h>
+#include <xen/kexec.h>
#include <asm/shadow.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -1633,6 +1634,7 @@ static void unknown_nmi_error(unsigned c
printk("Uhhuh. NMI received for unknown reason %02x.\n", reason);
printk("Dazed and confused, but trying to continue\n");
printk("Do you have a strange power saving mode enabled?\n");
+ machine_crash_kexec();
}
}
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/x86_32/entry.S
--- a/xen/arch/x86/x86_32/entry.S Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/x86_32/entry.S Mon Dec 04 08:24:41 2006 -0700
@@ -659,6 +659,7 @@ ENTRY(hypercall_table)
.long do_hvm_op
.long do_sysctl /* 35 */
.long do_domctl
+ .long do_kexec_op
.rept NR_hypercalls-((.-hypercall_table)/4)
.long do_ni_hypercall
.endr
@@ -701,6 +702,7 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_hvm_op */
.byte 1 /* do_sysctl */ /* 35 */
.byte 1 /* do_domctl */
+ .byte 2 /* do_kexec_op */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/x86_64/entry.S Mon Dec 04 08:24:41 2006 -0700
@@ -559,6 +559,7 @@ ENTRY(hypercall_table)
.quad do_hvm_op
.quad do_sysctl /* 35 */
.quad do_domctl
+ .quad do_kexec_op
.rept NR_hypercalls-((.-hypercall_table)/8)
.quad do_ni_hypercall
.endr
@@ -601,6 +602,7 @@ ENTRY(hypercall_args_table)
.byte 2 /* do_hvm_op */
.byte 1 /* do_sysctl */ /* 35 */
.byte 1 /* do_domctl */
+ .byte 2 /* do_kexec */
.rept NR_hypercalls-(.-hypercall_args_table)
.byte 0 /* do_ni_hypercall */
.endr
diff -r 6fdbf173142d -r d603aed5ad6d xen/arch/x86/x86_emulate.c
--- a/xen/arch/x86/x86_emulate.c Sat Dec 02 15:19:50 2006 -0700
+++ b/xen/arch/x86/x86_emulate.c Mon Dec 04 08:24:41 2006 -0700
@@ -7,24 +7,17 @@
*/
#ifndef __XEN__
-#include <stdio.h>
+#include <stddef.h>
#include <stdint.h>
#include <public/xen.h>
-#define dprintf(_f, _a...) printf( _f , ## _a )
#else
#include <xen/config.h>
#include <xen/types.h>
#include <xen/lib.h>
-#include <xen/mm.h>
#include <asm/regs.h>
-#define dprintf(_f, _a...) gdprintk(XENLOG_WARNING, _f , ## _a )
+#undef cmpxchg
#endif
#include <asm-x86/x86_emulate.h>
-
-#ifndef PFEC_write_access
-#define PFEC_write_access (1U<<1)
-#define PFEC_insn_fetch (1U<<4)
-#endif
/*
* Opcode effective-address decode tables.
@@ -38,6 +31,7 @@
/* Operand sizes: 8-bit operands or specified/overridden size. */
#define ByteOp (1<<0) /* 8-bit operands. */
/* Destination operand type. */
+#define DstBitBase (0<<1) /* Memory operand, bit string. */
#define ImplicitOps (1<<1) /* Implicit in opcode. No generic decode. */
#define DstReg (2<<1) /* Register operand. */
#define DstMem (3<<1) /* Memory operand. */
@@ -111,8 +105,8 @@ static uint8_t opcode_table[256] = {
/* 0x90 - 0x9F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0xA0 - 0xA7 */
- ByteOp|DstReg|SrcMem|Mov, DstReg|SrcMem|Mov,
- ByteOp|DstMem|SrcReg|Mov, DstMem|SrcReg|Mov,
+ ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
+ ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0,
/* 0xA8 - 0xAF */
0, 0, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov,
@@ -170,17 +164,21 @@ static uint8_t twobyte_table[256] = {
/* 0x90 - 0x9F */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0xA0 - 0xA7 */
- 0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
+ 0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0,
/* 0xA8 - 0xAF */
- 0, 0, 0, DstMem|SrcReg|ModRM, 0, 0, 0, 0,
+ 0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0,
/* 0xB0 - 0xB7 */
- ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, DstMem|SrcReg|ModRM,
+ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM,
+ 0, DstBitBase|SrcReg|ModRM,
0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
/* 0xB8 - 0xBF */
- 0, 0, DstMem|SrcImmByte|ModRM, DstMem|SrcReg|ModRM,
+ 0, 0, DstBitBase|SrcImmByte|ModRM, DstBitBase|SrcReg|ModRM,
0, 0, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem16|ModRM|Mov,
- /* 0xC0 - 0xCF */
- 0, 0, 0, 0, 0, 0, 0, ImplicitOps|ModRM, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 0xC0 - 0xC7 */
+ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0,
+ 0, 0, 0, ImplicitOps|ModRM,
+ /* 0xC8 - 0xCF */
+ 0, 0, 0, 0, 0, 0, 0, 0,
/* 0xD0 - 0xDF */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
/* 0xE0 - 0xEF */
@@ -193,7 +191,12 @@ struct operand {
struct operand {
enum { OP_REG, OP_MEM, OP_IMM } type;
unsigned int bytes;
- unsigned long val, orig_val, *ptr;
+ unsigned long val, orig_val;
+ /* OP_REG: Pointer to register field. */
+ unsigned long *reg;
+ /* OP_MEM: Segment and offset. */
+ enum x86_segment mem_seg;
+ unsigned long mem_off;
};
/* EFLAGS bit definitions. */
@@ -366,24 +369,23 @@ do{ __asm__ __volatile__ (
#endif /* __i386__ */
/* Fetch next part of the instruction being emulated. */
-#define _insn_fetch(_size) \
-({ unsigned long _x, _ptr = _regs.eip; \
- if ( mode == X86EMUL_MODE_REAL ) _ptr += _regs.cs << 4; \
- rc = ops->read_std(_ptr, &_x, (_size), ctxt); \
+#define insn_fetch_bytes(_size) \
+({ unsigned long _x; \
+ rc = ops->insn_fetch(x86_seg_cs, _regs.eip, &_x, (_size), ctxt); \
if ( rc != 0 ) \
goto done; \
_regs.eip += (_size); \
_x; \
})
-#define insn_fetch(_type) ((_type)_insn_fetch(sizeof(_type)))
-
-/* Access/update address held in a register, based on addressing mode. */
-#define register_address(sel, reg) \
-({ unsigned long __reg = (reg); \
- (((mode == X86EMUL_MODE_REAL) ? ((unsigned long)(sel) << 4) : 0) + \
- ((ad_bytes == sizeof(unsigned long)) ? __reg : \
- (__reg & ((1UL << (ad_bytes << 3)) - 1)))); \
+#define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type)))
+
+#define truncate_ea(ea) \
+({ unsigned long __ea = (ea); \
+ ((ad_bytes == sizeof(unsigned long)) ? __ea : \
+ (__ea & ((1UL << (ad_bytes << 3)) - 1))); \
})
+
+/* Update address held in a register, based on addressing mode. */
#define register_address_increment(reg, inc) \
do { \
int _inc = (inc); /* signed type ensures sign extension to long */ \
@@ -393,17 +395,6 @@ do {
(reg) = ((reg) & ~((1UL << (ad_bytes << 3)) - 1)) | \
(((reg) + _inc) & ((1UL << (ad_bytes << 3)) - 1)); \
} while (0)
-
-/*
- * We cannot handle a page fault on a data access that straddles two pages
- * and faults on the second page. This is because CR2 is not equal to the
- * memory operand's effective address in this case. Rather than fix up the
- * effective address it is okay for us to fail the emulation.
- */
-#define page_boundary_test() do { \
- if ( ((cr2 & (PAGE_SIZE-1)) == 0) && ((ea & 7) != 0) ) \
- goto bad_ea; \
-} while ( 0 )
void *
decode_register(
@@ -445,31 +436,6 @@ decode_register(
return p;
}
-static void
-dump_instr(
- struct x86_emulate_ctxt *ctxt,
- struct x86_emulate_ops *ops)
-{
-#ifdef __XEN__
- int i;
- unsigned long x, pc;
-
- pc = ctxt->regs->eip;
- if ( ctxt->mode == X86EMUL_MODE_REAL )
- pc += ctxt->regs->cs << 4;
-
- dprintf("Instr:");
- for ( i = 0; i < 16; i++, pc++ )
- {
- if ( ops->read_std(pc, &x, 1, ctxt) != 0 )
- printk(" ??");
- else
- printk(" %02x", (uint8_t)x);
- }
- printk("\n");
-#endif
-}
-
int
x86_emulate_memop(
struct x86_emulate_ctxt *ctxt,
@@ -480,19 +446,13 @@ x86_emulate_memop(
uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0;
uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0;
- uint16_t *seg = &_regs.ds; /* override segment */
unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i;
int rc = 0;
struct operand src, dst;
- unsigned long ea = 0, cr2 = ctxt->cr2;
int mode = ctxt->mode;
- /*
- * We do not emulate faults on instruction fetch. We assume that the
- * guest never executes out of a special memory area.
- */
- if ( _regs.error_code & PFEC_insn_fetch )
- return -1;
+ enum x86_segment ea_seg = x86_seg_ds;
+ unsigned long ea_off = 0;
switch ( mode )
{
@@ -516,7 +476,7 @@ x86_emulate_memop(
/* Legacy prefixes. */
for ( i = 0; i < 8; i++ )
{
- switch ( b = insn_fetch(uint8_t) )
+ switch ( b = insn_fetch_type(uint8_t) )
{
case 0x66: /* operand-size override */
op_bytes ^= 6; /* switch between 2/4 bytes */
@@ -528,22 +488,22 @@ x86_emulate_memop(
ad_bytes ^= 6; /* switch between 2/4 bytes */
break;
case 0x2e: /* CS override */
- seg = &_regs.cs;
+ ea_seg = x86_seg_cs;
break;
case 0x3e: /* DS override */
- seg = &_regs.ds;
+ ea_seg = x86_seg_ds;
break;
case 0x26: /* ES override */
- seg = &_regs.es;
+ ea_seg = x86_seg_es;
break;
case 0x64: /* FS override */
- seg = &_regs.fs;
+ ea_seg = x86_seg_fs;
break;
case 0x65: /* GS override */
- seg = &_regs.gs;
+ ea_seg = x86_seg_gs;
break;
case 0x36: /* SS override */
- seg = &_regs.ss;
+ ea_seg = x86_seg_ss;
break;
case 0xf0: /* LOCK */
lock_prefix = 1;
@@ -565,7 +525,7 @@ x86_emulate_memop(
rex_prefix = b;
if ( b & 8 ) /* REX.W */
op_bytes = 8;
- b = insn_fetch(uint8_t);
+ b = insn_fetch_type(uint8_t);
}
/* Opcode byte(s). */
@@ -576,7 +536,7 @@ x86_emulate_memop(
if ( b == 0x0f )
{
twobyte = 1;
- b = insn_fetch(uint8_t);
+ b = insn_fetch_type(uint8_t);
d = twobyte_table[b];
}
@@ -588,36 +548,40 @@ x86_emulate_memop(
/* ModRM and SIB bytes. */
if ( d & ModRM )
{
- modrm = insn_fetch(uint8_t);
+ modrm = insn_fetch_type(uint8_t);
modrm_mod = (modrm & 0xc0) >> 6;
modrm_reg = ((rex_prefix & 4) << 1) | ((modrm & 0x38) >> 3);
modrm_rm = modrm & 0x07;
if ( modrm_mod == 3 )
- {
- dprintf("Cannot parse ModRM.mod == 3.\n");
goto cannot_emulate;
- }
if ( ad_bytes == 2 )
{
/* 16-bit ModR/M decode. */
switch ( modrm_rm )
{
- case 0: ea = _regs.ebx + _regs.esi; break;
- case 1: ea = _regs.ebx + _regs.edi; break;
- case 2: ea = _regs.ebp + _regs.esi; break;
- case 3: ea = _regs.ebp + _regs.edi; break;
- case 4: ea = _regs.esi; break;
- case 5: ea = _regs.edi; break;
- case 6: ea = _regs.ebp; break;
- case 7: ea = _regs.ebx; break;
+ case 0: ea_off = _regs.ebx + _regs.esi; break;
+ case 1: ea_off = _regs.ebx + _regs.edi; break;
+ case 2: ea_off = _regs.ebp + _regs.esi; break;
+ case 3: ea_off = _regs.ebp + _regs.edi; break;
+ case 4: ea_off = _regs.esi; break;
+ case 5: ea_off = _regs.edi; break;
+ case 6: ea_off = _regs.ebp; break;
+ case 7: ea_off = _regs.ebx; break;
}
switch ( modrm_mod )
{
- case 0: if ( modrm_rm == 6 ) ea = insn_fetch(int16_t); break;
- case 1: ea += insn_fetch(int8_t); break;
- case 2: ea += insn_fetch(int16_t); break;
+ case 0:
+ if ( modrm_rm == 6 )
+ ea_off = insn_fetch_type(int16_t);
+ break;
+ case 1:
+ ea_off += insn_fetch_type(int8_t);
+ break;
+ case 2:
+ ea_off += insn_fetch_type(int16_t);
+ break;
}
}
else
@@ -625,87 +589,58 @@ x86_emulate_memop(
/* 32/64-bit ModR/M decode. */
if ( modrm_rm == 4 )
{
- sib = insn_fetch(uint8_t);
- sib_index = ((sib >> 3) & 7) | ((modrm << 2) & 8);
- sib_base = (sib & 7) | ((modrm << 3) & 8);
+ sib = insn_fetch_type(uint8_t);
+ sib_index = ((sib >> 3) & 7) | ((rex_prefix << 2) & 8);
+ sib_base = (sib & 7) | ((rex_prefix << 3) & 8);
if ( sib_index != 4 )
- ea = *(long *)decode_register(sib_index, &_regs, 0);
- ea <<= (sib >> 6) & 3;
+ ea_off = *(long *)decode_register(sib_index, &_regs, 0);
+ ea_off <<= (sib >> 6) & 3;
if ( (modrm_mod == 0) && ((sib_base & 7) == 5) )
- ea += insn_fetch(int32_t);
+ ea_off += insn_fetch_type(int32_t);
else
- ea += *(long *)decode_register(sib_base, &_regs, 0);
+ ea_off += *(long *)decode_register(sib_base, &_regs, 0);
}
else
{
modrm_rm |= (rex_prefix & 1) << 3;
- ea = *(long *)decode_register(modrm_rm, &_regs, 0);
+ ea_off = *(long *)decode_register(modrm_rm, &_regs, 0);
}
switch ( modrm_mod )
{
case 0:
if ( (modrm_rm & 7) != 5 )
break;
- ea = insn_fetch(int32_t);
+ ea_off = insn_fetch_type(int32_t);
if ( mode != X86EMUL_MODE_PROT64 )
break;
/* Relative to RIP of next instruction. Argh! */
- ea += _regs.eip;
+ ea_off += _regs.eip;
if ( (d & SrcMask) == SrcImm )
- ea += (d & ByteOp) ? 1 : ((op_bytes == 8) ? 4 : op_bytes);
+ ea_off += (d & ByteOp) ? 1 :
+ ((op_bytes == 8) ? 4 : op_bytes);
else if ( (d & SrcMask) == SrcImmByte )
- ea += 1;
+ ea_off += 1;
else if ( ((b == 0xf6) || (b == 0xf7)) &&
((modrm_reg & 7) <= 1) )
/* Special case in Grp3: test has immediate operand. */
- ea += (d & ByteOp) ? 1
+ ea_off += (d & ByteOp) ? 1
: ((op_bytes == 8) ? 4 : op_bytes);
break;
- case 1: ea += insn_fetch(int8_t); break;
- case 2: ea += insn_fetch(int32_t); break;
+ case 1:
+ ea_off += insn_fetch_type(int8_t);
+ break;
+ case 2:
+ ea_off += insn_fetch_type(int32_t);
+ break;
}
}
- ea = register_address(*seg, ea);
- page_boundary_test();
- }
-
- /* Decode and fetch the destination operand: register or memory. */
- switch ( d & DstMask )
- {
- case ImplicitOps:
- /* Special instructions do their own operand decoding. */
+ ea_off = truncate_ea(ea_off);
+ }
+
+ /* Special instructions do their own operand decoding. */
+ if ( (d & DstMask) == ImplicitOps )
goto special_insn;
- case DstReg:
- dst.type = OP_REG;
- if ( d & ByteOp )
- {
- dst.ptr = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
- dst.val = *(uint8_t *)dst.ptr;
- dst.bytes = 1;
- }
- else
- {
- dst.ptr = decode_register(modrm_reg, &_regs, 0);
- switch ( (dst.bytes = op_bytes) )
- {
- case 2: dst.val = *(uint16_t *)dst.ptr; break;
- case 4: dst.val = *(uint32_t *)dst.ptr; break;
- case 8: dst.val = *(uint64_t *)dst.ptr; break;
- }
- }
- break;
- case DstMem:
- dst.type = OP_MEM;
- dst.ptr = (unsigned long *)cr2;
- dst.bytes = (d & ByteOp) ? 1 : op_bytes;
- if ( !(d & Mov) && /* optimisation - avoid slow emulated read */
- ((rc = ops->read_emulated((unsigned long)dst.ptr,
- &dst.val, dst.bytes, ctxt)) != 0) )
- goto done;
- break;
- }
- dst.orig_val = dst.val;
/* Decode and fetch the source operand: register, memory or immediate. */
switch ( d & SrcMask )
@@ -716,18 +651,18 @@ x86_emulate_memop(
src.type = OP_REG;
if ( d & ByteOp )
{
- src.ptr = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
- src.val = src.orig_val = *(uint8_t *)src.ptr;
+ src.reg = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
+ src.val = src.orig_val = *(uint8_t *)src.reg;
src.bytes = 1;
}
else
{
- src.ptr = decode_register(modrm_reg, &_regs, 0);
+ src.reg = decode_register(modrm_reg, &_regs, 0);
switch ( (src.bytes = op_bytes) )
{
- case 2: src.val = src.orig_val = *(uint16_t *)src.ptr; break;
- case 4: src.val = src.orig_val = *(uint32_t *)src.ptr; break;
- case 8: src.val = src.orig_val = *(uint64_t *)src.ptr; break;
+ case 2: src.val = src.orig_val = *(uint16_t *)src.reg; break;
+ case 4: src.val = src.orig_val = *(uint32_t *)src.reg; break;
+ case 8: src.val = src.orig_val = *(uint64_t *)src.reg; break;
}
}
break;
@@ -741,32 +676,101 @@ x86_emulate_memop(
src.bytes = (d & ByteOp) ? 1 : op_bytes;
srcmem_common:
src.type = OP_MEM;
- src.ptr = (unsigned long *)cr2;
- if ( (rc = ops->read_emulated((unsigned long)src.ptr,
- &src.val, src.bytes, ctxt)) != 0 )
+ src.mem_seg = ea_seg;
+ src.mem_off = ea_off;
+ if ( (rc = ops->read(src.mem_seg, src.mem_off,
+ &src.val, src.bytes, ctxt)) != 0 )
goto done;
src.orig_val = src.val;
break;
case SrcImm:
src.type = OP_IMM;
- src.ptr = (unsigned long *)_regs.eip;
src.bytes = (d & ByteOp) ? 1 : op_bytes;
if ( src.bytes == 8 ) src.bytes = 4;
/* NB. Immediates are sign-extended as necessary. */
switch ( src.bytes )
{
- case 1: src.val = insn_fetch(int8_t); break;
- case 2: src.val = insn_fetch(int16_t); break;
- case 4: src.val = insn_fetch(int32_t); break;
+ case 1: src.val = insn_fetch_type(int8_t); break;
+ case 2: src.val = insn_fetch_type(int16_t); break;
+ case 4: src.val = insn_fetch_type(int32_t); break;
}
break;
case SrcImmByte:
src.type = OP_IMM;
- src.ptr = (unsigned long *)_regs.eip;
src.bytes = 1;
- src.val = insn_fetch(int8_t);
- break;
- }
+ src.val = insn_fetch_type(int8_t);
+ break;
+ }
+
+ /* Decode and fetch the destination operand: register or memory. */
+ switch ( d & DstMask )
+ {
+ case DstReg:
+ dst.type = OP_REG;
+ if ( d & ByteOp )
+ {
+ dst.reg = decode_register(modrm_reg, &_regs, (rex_prefix == 0));
+ dst.val = *(uint8_t *)dst.reg;
+ dst.bytes = 1;
+ }
+ else
+ {
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|