# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1212374139 -32400
# Node ID f1508348ffabedf2eab0b666a5b8e2c9515e52d7
# Parent d2a239224cb23f5a7a8059e4167c50bd3abeb9df
# Parent 85fa199b4b7bd1e7511ce7fc2361bae808c27ba6
merge with xen-unstable.hg
---
extras/mini-os/main-caml.c | 42 --
tools/examples/xend-config-xenapi.sxp | 196 ---------
tools/examples/xm-config-xenapi.xml | 41 --
extras/mini-os/Config.mk | 13
extras/mini-os/Makefile | 35 -
extras/mini-os/arch/ia64/minios-ia64.lds | 17
extras/mini-os/arch/ia64/mm.c | 8
extras/mini-os/arch/x86/minios-x86_32.lds | 18
extras/mini-os/arch/x86/minios-x86_64.lds | 18
extras/mini-os/arch/x86/mm.c | 17
extras/mini-os/hypervisor.c | 4
extras/mini-os/include/lib.h | 1
extras/mini-os/include/mm.h | 3
extras/mini-os/include/posix/pthread.h | 52 ++
extras/mini-os/include/x86/arch_mm.h | 5
extras/mini-os/lib/sys.c | 67 +--
extras/mini-os/lib/xmalloc.c | 2
extras/mini-os/main.c | 12
extras/mini-os/mm.c | 38 -
extras/mini-os/sched.c | 2
stubdom/Makefile | 33 -
stubdom/c/Makefile | 7
stubdom/c/main.c | 2
stubdom/caml/Makefile | 10
stubdom/caml/main-caml.c | 42 ++
tools/examples/Makefile | 2
tools/examples/xend-config.sxp | 16
tools/firmware/hvmloader/util.c | 12
tools/firmware/rombios/rombios.c | 26 -
tools/ioemu/Makefile.target | 7
tools/ioemu/hw/cirrus_vga.c | 2
tools/ioemu/vl.c | 5
tools/ioemu/vl.h | 2
tools/ioemu/xenstore.c | 2
tools/libxc/Makefile | 8
tools/libxc/xc_core.c | 18
tools/libxc/xc_domain.c | 31 +
tools/libxc/xc_minios.c | 17
tools/libxc/xenctrl.h | 7
tools/libxc/xg_private.c | 16
tools/python/xen/lowlevel/xc/xc.c | 230 +++++++++--
tools/python/xen/xend/XendAPI.py | 6
tools/python/xen/xend/XendDomain.py | 31 -
tools/python/xen/xend/XendDomainInfo.py | 22 -
tools/python/xen/xend/XendOptions.py | 27 +
tools/python/xen/xend/server/SrvDomain.py | 13
tools/python/xen/xend/server/pciif.py | 52 ++
tools/python/xen/xend/server/relocate.py | 24 -
tools/python/xen/xm/migrate.py | 10
tools/xenstat/libxenstat/src/xenstat.c | 18
unmodified_drivers/linux-2.6/platform-pci/evtchn.c | 2
xen/arch/x86/acpi/cpu_idle.c | 2
xen/arch/x86/acpi/power.c | 14
xen/arch/x86/cpu/amd.c | 8
xen/arch/x86/crash.c | 1
xen/arch/x86/domain.c | 30 -
xen/arch/x86/domctl.c | 63 ++-
xen/arch/x86/hvm/hpet.c | 18
xen/arch/x86/hvm/hvm.c | 158 ++++---
xen/arch/x86/hvm/i8254.c | 26 -
xen/arch/x86/hvm/pmtimer.c | 2
xen/arch/x86/hvm/svm/svm.c | 4
xen/arch/x86/hvm/vlapic.c | 24 -
xen/arch/x86/hvm/vmx/vmx.c | 4
xen/arch/x86/hvm/vpt.c | 35 +
xen/arch/x86/mm.c | 14
xen/arch/x86/mm/hap/p2m-ept.c | 6
xen/arch/x86/mm/p2m.c | 21 -
xen/arch/x86/mm/shadow/common.c | 119 +++---
xen/arch/x86/msi.c | 7
xen/arch/x86/setup.c | 8
xen/arch/x86/smpboot.c | 5
xen/arch/x86/tboot.c | 12
xen/arch/x86/x86_emulate/x86_emulate.c | 8
xen/common/domain.c | 4
xen/common/grant_table.c | 57 ++
xen/common/libelf/libelf-private.h | 2
xen/common/memory.c | 17
xen/drivers/passthrough/amd/pci_amd_iommu.c | 11
xen/drivers/passthrough/iommu.c | 108 +++++
xen/drivers/passthrough/vtd/dmar.c | 33 -
xen/drivers/passthrough/vtd/dmar.h | 1
xen/drivers/passthrough/vtd/extern.h | 3
xen/drivers/passthrough/vtd/intremap.c | 318 ++++++++++++----
xen/drivers/passthrough/vtd/iommu.c | 416 ++++++++++-----------
xen/drivers/passthrough/vtd/iommu.h | 1
xen/drivers/passthrough/vtd/utils.c | 178 ++++----
xen/drivers/passthrough/vtd/vtd.h | 22 +
xen/drivers/passthrough/vtd/x86/vtd.c | 184 ---------
xen/include/asm-x86/hvm/hvm.h | 6
xen/include/asm-x86/hvm/vcpu.h | 3
xen/include/asm-x86/hvm/vmx/vmx.h | 1
xen/include/asm-x86/hvm/vpt.h | 7
xen/include/asm-x86/tboot.h | 15
xen/include/public/domctl.h | 11
xen/include/xen/elfcore.h | 1
xen/include/xen/hvm/iommu.h | 4
xen/include/xen/iommu.h | 14
xen/include/xen/sched.h | 3
xen/include/xen/time.h | 1
100 files changed, 1874 insertions(+), 1427 deletions(-)
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/Config.mk
--- a/extras/mini-os/Config.mk Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/Config.mk Mon Jun 02 11:35:39 2008 +0900
@@ -41,10 +41,7 @@ extra_incl := $(foreach dir,$(EXTRA_INC)
extra_incl := $(foreach dir,$(EXTRA_INC),-I$(MINI-OS_ROOT)/include/$(dir))
DEF_CPPFLAGS += -I$(MINI-OS_ROOT)/include
-
-ifeq ($(stubdom),y)
-DEF_CPPFLAGS += -DCONFIG_STUBDOM
-endif
+DEF_CPPFLAGS += -D__MINIOS__
ifeq ($(libc),y)
DEF_CPPFLAGS += -DHAVE_LIBC
@@ -58,11 +55,3 @@ DEF_CPPFLAGS += -I$(LWIPDIR)/src/include
DEF_CPPFLAGS += -I$(LWIPDIR)/src/include
DEF_CPPFLAGS += -I$(LWIPDIR)/src/include/ipv4
endif
-
-ifneq ($(QEMUDIR),)
-qemu=y
-endif
-
-ifneq ($(CAMLDIR),)
-caml=y
-endif
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/Makefile
--- a/extras/mini-os/Makefile Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/Makefile Mon Jun 02 11:35:39 2008 +0900
@@ -73,44 +73,25 @@ OBJS += lwip.a
OBJS += lwip.a
endif
-OBJS := $(filter-out lwip%.o $(LWO), $(OBJS))
-
-ifeq ($(caml),y)
-CAMLLIB = $(shell ocamlc -where)
-APP_OBJS += main-caml.o
-APP_OBJS += $(CAMLDIR)/caml.o
-APP_OBJS += $(CAMLLIB)/libasmrun.a
-CFLAGS += -I$(CAMLLIB)
-APP_LDLIBS += -lm
-endif
-OBJS := $(filter-out main-caml.o, $(OBJS))
-
-ifeq ($(qemu),y)
-APP_OBJS += $(QEMUDIR)/i386-dm-stubdom/qemu.a
$(QEMUDIR)/i386-dm-stubdom/libqemu.a
-CFLAGS += -DCONFIG_QEMU
-endif
-
-ifneq ($(CDIR),)
-APP_OBJS += $(CDIR)/main.a
-APP_LDLIBS +=
-endif
+OBJS := $(filter-out main.o lwip%.o $(LWO), $(OBJS))
ifeq ($(libc),y)
-LDLIBS += -L$(XEN_ROOT)/stubdom/libxc -lxenctrl -lxenguest
+APP_LDLIBS += -L$(XEN_ROOT)/stubdom/libxc -whole-archive -lxenguest -lxenctrl
-no-whole-archive
APP_LDLIBS += -lpci
APP_LDLIBS += -lz
+APP_LDLIBS += -lm
LDLIBS += -lc
endif
-ifneq ($(caml)-$(qemu)-$(CDIR)-$(lwip),---y)
+ifneq ($(APP_OBJS)-$(lwip),-y)
OBJS := $(filter-out daytime.o, $(OBJS))
endif
-app.o: $(APP_OBJS) app.lds
- $(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined main -o $@
+$(TARGET)_app.o: $(APP_OBJS) app.lds
+ $(LD) -r -d $(LDFLAGS) $^ $(APP_LDLIBS) --undefined app_main -o $@
-$(TARGET): links $(OBJS) app.o arch_lib
- $(LD) -r $(LDFLAGS) $(HEAD_OBJ) app.o $(OBJS) $(LDARCHLIB) $(LDLIBS) -o
$@.o
+$(TARGET): links $(OBJS) $(TARGET)_app.o arch_lib
+ $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(TARGET)_app.o $(OBJS) $(LDARCHLIB)
$(LDLIBS) -o $@.o
$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
gzip -f -9 -c $@ >$@.gz
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/arch/ia64/minios-ia64.lds
--- a/extras/mini-os/arch/ia64/minios-ia64.lds Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/arch/ia64/minios-ia64.lds Mon Jun 02 11:35:39 2008 +0900
@@ -52,6 +52,23 @@ SECTIONS
.fini_array : { *(.fini_array) }
PROVIDE (__fini_array_end = .);
+ .ctors : {
+ __CTOR_LIST__ = .;
+ QUAD((__CTOR_END__ - __CTOR_LIST__) / 8 - 2)
+ *(SORT_BY_NAME(.ctors))
+ SORT_BY_NAME(CONSTRUCTORS)
+ QUAD(0)
+ __CTOR_END__ = .;
+ }
+
+ .dtors : {
+ __DTOR_LIST__ = .;
+ QUAD((__DTOR_END__ - __DTOR_LIST__) / 8 - 2)
+ *(SORT_BY_NAME(.dtors))
+ QUAD(0)
+ __DTOR_END__ = .;
+ }
+
.IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - (((5<<(61))+0x100000000)
- (1 << 20)))
{ *(.IA_64.unwind_info) }
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/arch/ia64/mm.c
--- a/extras/mini-os/arch/ia64/mm.c Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/arch/ia64/mm.c Mon Jun 02 11:35:39 2008 +0900
@@ -131,6 +131,14 @@ arch_init_demand_mapping_area(unsigned l
}
/* Helper function used in gnttab.c. */
+void do_map_frames(unsigned long addr,
+ unsigned long *f, unsigned long n, unsigned long stride,
+ unsigned long increment, domid_t id, int may_fail, unsigned long prot)
+{
+ /* TODO */
+ ASSERT(0);
+}
+
void*
map_frames_ex(unsigned long* frames, unsigned long n, unsigned long stride,
unsigned long increment, unsigned long alignment, domid_t id,
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/arch/x86/minios-x86_32.lds
--- a/extras/mini-os/arch/x86/minios-x86_32.lds Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/arch/x86/minios-x86_32.lds Mon Jun 02 11:35:39 2008 +0900
@@ -28,9 +28,25 @@ SECTIONS
.fini_array : { *(.fini_array) }
PROVIDE (__fini_array_end = .);
+ .ctors : {
+ __CTOR_LIST__ = .;
+ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
+ *(SORT_BY_NAME(.ctors))
+ SORT_BY_NAME(CONSTRUCTORS)
+ LONG(0)
+ __CTOR_END__ = .;
+ }
+
+ .dtors : {
+ __DTOR_LIST__ = .;
+ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
+ *(SORT_BY_NAME(.dtors))
+ LONG(0)
+ __DTOR_END__ = .;
+ }
+
.data : { /* Data */
*(.data)
- CONSTRUCTORS
}
_edata = .; /* End of data section */
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/arch/x86/minios-x86_64.lds
--- a/extras/mini-os/arch/x86/minios-x86_64.lds Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/arch/x86/minios-x86_64.lds Mon Jun 02 11:35:39 2008 +0900
@@ -28,9 +28,25 @@ SECTIONS
.fini_array : { *(.fini_array) }
PROVIDE (__fini_array_end = .);
+ .ctors : {
+ __CTOR_LIST__ = .;
+ QUAD((__CTOR_END__ - __CTOR_LIST__) / 8 - 2)
+ *(SORT_BY_NAME(.ctors))
+ SORT_BY_NAME(CONSTRUCTORS)
+ QUAD(0)
+ __CTOR_END__ = .;
+ }
+
+ .dtors : {
+ __DTOR_LIST__ = .;
+ QUAD((__DTOR_END__ - __DTOR_LIST__) / 8 - 2)
+ *(SORT_BY_NAME(.dtors))
+ QUAD(0)
+ __DTOR_END__ = .;
+ }
+
.data : { /* Data */
*(.data)
- CONSTRUCTORS
}
_edata = .; /* End of data section */
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/arch/x86/mm.c
--- a/extras/mini-os/arch/x86/mm.c Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/arch/x86/mm.c Mon Jun 02 11:35:39 2008 +0900
@@ -59,11 +59,10 @@ void new_pt_frame(unsigned long *pt_pfn,
{
pgentry_t *tab = (pgentry_t *)start_info.pt_base;
unsigned long pt_page = (unsigned long)pfn_to_virt(*pt_pfn);
- unsigned long prot_e, prot_t, pincmd;
+ unsigned long prot_e, prot_t;
mmu_update_t mmu_updates[1];
- struct mmuext_op pin_request;
- prot_e = prot_t = pincmd = 0;
+ prot_e = prot_t = 0;
DEBUG("Allocating new L%d pt frame for pt_pfn=%lx, "
"prev_l_mfn=%lx, offset=%lx",
level, *pt_pfn, prev_l_mfn, offset);
@@ -77,18 +76,15 @@ void new_pt_frame(unsigned long *pt_pfn,
case L1_FRAME:
prot_e = L1_PROT;
prot_t = L2_PROT;
- pincmd = MMUEXT_PIN_L1_TABLE;
break;
case L2_FRAME:
prot_e = L2_PROT;
prot_t = L3_PROT;
- pincmd = MMUEXT_PIN_L2_TABLE;
break;
#if defined(__x86_64__)
case L3_FRAME:
prot_e = L3_PROT;
prot_t = L4_PROT;
- pincmd = MMUEXT_PIN_L3_TABLE;
break;
#endif
default:
@@ -113,15 +109,6 @@ void new_pt_frame(unsigned long *pt_pfn,
do_exit();
}
- /* Pin the page to provide correct protection */
- pin_request.cmd = pincmd;
- pin_request.arg1.mfn = pfn_to_mfn(*pt_pfn);
- if(HYPERVISOR_mmuext_op(&pin_request, 1, NULL, DOMID_SELF) < 0)
- {
- printk("ERROR: pinning failed\n");
- do_exit();
- }
-
/* Now fill the new page table page with entries.
Update the page directory as well. */
mmu_updates[0].ptr = ((pgentry_t)prev_l_mfn << PAGE_SHIFT) +
sizeof(pgentry_t) * offset;
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/hypervisor.c
--- a/extras/mini-os/hypervisor.c Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/hypervisor.c Mon Jun 02 11:35:39 2008 +0900
@@ -55,12 +55,12 @@ void do_hypervisor_callback(struct pt_re
while ( l1 != 0 )
{
l1i = __ffs(l1);
- l1 &= ~(1 << l1i);
+ l1 &= ~(1UL << l1i);
while ( (l2 = active_evtchns(cpu, s, l1i)) != 0 )
{
l2i = __ffs(l2);
- l2 &= ~(1 << l2i);
+ l2 &= ~(1UL << l2i);
port = (l1i * (sizeof(unsigned long) * 8)) + l2i;
do_event(port, regs);
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/include/lib.h
--- a/extras/mini-os/include/lib.h Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/include/lib.h Mon Jun 02 11:35:39 2008 +0900
@@ -136,6 +136,7 @@ enum fd_type {
FTYPE_CONSOLE,
FTYPE_FILE,
FTYPE_XENBUS,
+ FTYPE_XC,
FTYPE_EVTCHN,
FTYPE_SOCKET,
FTYPE_TAP,
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/include/mm.h
--- a/extras/mini-os/include/mm.h Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/include/mm.h Mon Jun 02 11:35:39 2008 +0900
@@ -67,6 +67,9 @@ void *map_frames_ex(unsigned long *f, un
void *map_frames_ex(unsigned long *f, unsigned long n, unsigned long stride,
unsigned long increment, unsigned long alignment, domid_t id,
int may_fail, unsigned long prot);
+void do_map_frames(unsigned long addr,
+ unsigned long *f, unsigned long n, unsigned long stride,
+ unsigned long increment, domid_t id, int may_fail, unsigned long prot);
#ifdef HAVE_LIBC
extern unsigned long heap, brk, heap_mapped, heap_end;
#endif
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/include/posix/pthread.h
--- a/extras/mini-os/include/posix/pthread.h Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/include/posix/pthread.h Mon Jun 02 11:35:39 2008 +0900
@@ -1,18 +1,56 @@
#ifndef _POSIX_PTHREAD_H
#define _POSIX_PTHREAD_H
+#include <stdlib.h>
+
/* Let's be single-threaded for now. */
-typedef void *pthread_key_t;
-typedef struct {} pthread_mutex_t, pthread_once_t;
+typedef struct {
+ void *ptr;
+} *pthread_key_t;
+static inline int pthread_key_create(pthread_key_t *key, void
(*destr_function)(void*))
+{
+ *key = malloc(sizeof(**key));
+ (*key)->ptr = NULL;
+ return 0;
+}
+static inline int pthread_setspecific(pthread_key_t key, const void *pointer)
+{
+ key->ptr = (void*) pointer;
+ return 0;
+}
+static inline void *pthread_getspecific(pthread_key_t key)
+{
+ return key->ptr;
+}
+static inline int pthread_key_delete(pthread_key_t key)
+{
+ free(key);
+ return 0;
+}
+
+
+
+typedef struct {} pthread_mutex_t;
#define PTHREAD_MUTEX_INITIALIZER {}
-#define PTHREAD_ONCE_INIT {}
static inline int pthread_mutex_lock(pthread_mutex_t *mutex) { return 0; }
static inline int pthread_mutex_unlock(pthread_mutex_t *mutex) { return 0; }
-static inline int pthread_key_create(pthread_key_t *key, void
(*destr_function)(void*)) { *key = NULL; return 0; }
-static inline int pthread_setspecific(pthread_key_t *key, const void *pointer)
{ *key = (void*) pointer; return 0; }
-static inline void *pthread_getspecific(pthread_key_t *key) { return *key; }
-static inline int pthread_once(pthread_once_t *once_control, void
(*init_routine)(void)) { init_routine(); return 0; }
+
+
+
+typedef struct {
+ int done;
+} pthread_once_t;
+#define PTHREAD_ONCE_INIT { 0 }
+
+static inline int pthread_once(pthread_once_t *once_control, void
(*init_routine)(void))
+{
+ if (!once_control->done) {
+ once_control->done = 1;
+ init_routine();
+ }
+ return 0;
+}
#define __thread
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/include/x86/arch_mm.h
--- a/extras/mini-os/include/x86/arch_mm.h Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/include/x86/arch_mm.h Mon Jun 02 11:35:39 2008 +0900
@@ -219,11 +219,6 @@ static __inline__ paddr_t machine_to_phy
#define map_frames(f, n) map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, 0, L1_PROT)
#define map_zero(n, a) map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF, 0,
L1_PROT_RO)
-#ifndef __ASSEMBLY__
-void do_map_frames(unsigned long addr,
- unsigned long *f, unsigned long n, unsigned long stride,
- unsigned long increment, domid_t id, int may_fail, unsigned long prot);
-#endif
#define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0,
DOMID_SELF, 0, L1_PROT_RO)
#endif /* _ARCH_MM_H_ */
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/lib/sys.c
--- a/extras/mini-os/lib/sys.c Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/lib/sys.c Mon Jun 02 11:35:39 2008 +0900
@@ -81,6 +81,7 @@
#define NOFILE 32
extern int xc_evtchn_close(int fd);
+extern int xc_interface_close(int fd);
pthread_mutex_t fd_lock = PTHREAD_MUTEX_INITIALIZER;
struct file files[NOFILE] = {
@@ -259,10 +260,7 @@ int read(int fd, void *buf, size_t nbyte
}
return ret * sizeof(union xenfb_in_event);
}
- case FTYPE_NONE:
- case FTYPE_XENBUS:
- case FTYPE_EVTCHN:
- case FTYPE_BLK:
+ default:
break;
}
printk("read(%d): Bad descriptor\n", fd);
@@ -295,12 +293,7 @@ int write(int fd, const void *buf, size_
case FTYPE_TAP:
netfront_xmit(files[fd].tap.dev, (void*) buf, nbytes);
return nbytes;
- case FTYPE_NONE:
- case FTYPE_XENBUS:
- case FTYPE_EVTCHN:
- case FTYPE_BLK:
- case FTYPE_KBD:
- case FTYPE_FB:
+ default:
break;
}
printk("write(%d): Bad descriptor\n", fd);
@@ -351,15 +344,7 @@ int fsync(int fd) {
}
return 0;
}
- case FTYPE_NONE:
- case FTYPE_CONSOLE:
- case FTYPE_SOCKET:
- case FTYPE_XENBUS:
- case FTYPE_EVTCHN:
- case FTYPE_TAP:
- case FTYPE_BLK:
- case FTYPE_KBD:
- case FTYPE_FB:
+ default:
break;
}
printk("fsync(%d): Bad descriptor\n", fd);
@@ -391,6 +376,9 @@ int close(int fd)
files[fd].type = FTYPE_NONE;
return res;
}
+ case FTYPE_XC:
+ xc_interface_close(fd);
+ return 0;
case FTYPE_EVTCHN:
xc_evtchn_close(fd);
return 0;
@@ -495,13 +483,7 @@ int fstat(int fd, struct stat *buf)
stat_from_fs(buf, &stat);
return 0;
}
- case FTYPE_NONE:
- case FTYPE_XENBUS:
- case FTYPE_EVTCHN:
- case FTYPE_TAP:
- case FTYPE_BLK:
- case FTYPE_KBD:
- case FTYPE_FB:
+ default:
break;
}
@@ -522,15 +504,7 @@ int ftruncate(int fd, off_t length)
}
return 0;
}
- case FTYPE_NONE:
- case FTYPE_CONSOLE:
- case FTYPE_SOCKET:
- case FTYPE_XENBUS:
- case FTYPE_EVTCHN:
- case FTYPE_TAP:
- case FTYPE_BLK:
- case FTYPE_KBD:
- case FTYPE_FB:
+ default:
break;
}
@@ -636,9 +610,10 @@ static const char file_types[] = {
[FTYPE_NONE] = 'N',
[FTYPE_CONSOLE] = 'C',
[FTYPE_FILE] = 'F',
- [FTYPE_XENBUS] = 'X',
+ [FTYPE_XENBUS] = 'S',
+ [FTYPE_XC] = 'X',
[FTYPE_EVTCHN] = 'E',
- [FTYPE_SOCKET] = 'S',
+ [FTYPE_SOCKET] = 's',
[FTYPE_TAP] = 'T',
[FTYPE_BLK] = 'B',
[FTYPE_KBD] = 'K',
@@ -722,7 +697,7 @@ static int select_poll(int nfds, fd_set
/* Then see others as well. */
for (i = 0; i < nfds; i++) {
switch(files[i].type) {
- case FTYPE_NONE:
+ default:
if (FD_ISSET(i, readfds) || FD_ISSET(i, writefds) || FD_ISSET(i,
exceptfds))
printk("bogus fd %d in select\n", i);
/* Fallthrough. */
@@ -1083,14 +1058,20 @@ int clock_gettime(clockid_t clk_id, stru
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t
offset)
{
+ unsigned long n = (length + PAGE_SIZE - 1) / PAGE_SIZE;
+
ASSERT(!start);
- length = (length + PAGE_SIZE - 1) & PAGE_MASK;
ASSERT(prot == (PROT_READ|PROT_WRITE));
- ASSERT(flags == (MAP_SHARED|MAP_ANON) || flags == (MAP_PRIVATE|MAP_ANON));
- ASSERT(fd == -1);
+ ASSERT((fd == -1 && (flags == (MAP_SHARED|MAP_ANON) || flags ==
(MAP_PRIVATE|MAP_ANON)))
+ || (fd != -1 && flags == MAP_SHARED));
ASSERT(offset == 0);
- return map_zero(length / PAGE_SIZE, 1);
+ if (fd == -1)
+ return map_zero(n, 1);
+ else if (files[fd].type == FTYPE_XC) {
+ unsigned long zero = 0;
+ return map_frames_ex(&zero, n, 0, 0, 1, DOMID_SELF, 0, 0);
+ } else ASSERT(0);
}
#if defined(__x86_64__) || defined(__ia64__)
__typeof__(mmap) mmap64 __attribute__((__alias__("mmap")));
@@ -1110,7 +1091,7 @@ int munmap(void *start, size_t length)
call[i].args[0] = (unsigned long) &data[i];
call[i].args[1] = 0;
call[i].args[2] = 0;
- call[i].args[3] = UVMF_INVLPG | UVMF_ALL;
+ call[i].args[3] = UVMF_INVLPG;
}
ret = HYPERVISOR_multicall(call, n);
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/lib/xmalloc.c
--- a/extras/mini-os/lib/xmalloc.c Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/lib/xmalloc.c Mon Jun 02 11:35:39 2008 +0900
@@ -127,7 +127,7 @@ static void *xmalloc_whole_pages(size_t
if ( hdr == NULL )
return NULL;
- hdr->size = (1 << (pageorder + PAGE_SHIFT));
+ hdr->size = (1UL << (pageorder + PAGE_SHIFT));
/* Debugging aid. */
hdr->freelist.next = hdr->freelist.prev = NULL;
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/main-caml.c
--- a/extras/mini-os/main-caml.c Mon Jun 02 11:35:02 2008 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,42 +0,0 @@
-/*
- * Caml bootstrap
- *
- * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, January 2008
- */
-
-#include <stdio.h>
-#include <errno.h>
-
-#include <caml/mlvalues.h>
-#include <caml/callback.h>
-#include <unistd.h>
-
-/* Ugly binary compatibility with Linux */
-FILE *_stderr asm("stderr");
-int *__errno_location;
-/* Will probably break everything, probably need to fetch from glibc */
-void *__ctype_b_loc;
-
-int main(int argc, char *argv[], char *envp[])
-{
- value *val;
-
- /* Get current thread's value */
- _stderr = stderr;
- __errno_location = &errno;
-
- printf("starting caml\n");
-
- /* Wait before things might hang up */
- sleep(1);
-
- caml_startup(argv);
- val = caml_named_value("main");
- if (!val) {
- printf("Couldn't find Caml main");
- return 1;
- }
- caml_callback(*val, Val_int(0));
- printf("callback returned\n");
- return 0;
-}
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/main.c
--- a/extras/mini-os/main.c Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/main.c Mon Jun 02 11:35:39 2008 +0900
@@ -4,7 +4,6 @@
* Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, October 2007
*/
-#ifdef HAVE_LIBC
#include <os.h>
#include <sched.h>
#include <console.h>
@@ -19,8 +18,8 @@ extern int main(int argc, char *argv[],
extern int main(int argc, char *argv[], char *envp[]);
extern void __libc_init_array(void);
extern void __libc_fini_array(void);
-
-struct thread *main_thread;
+extern unsigned long __CTOR_LIST__[];
+extern unsigned long __DTOR_LIST__[];
#if 0
#include <stdio.h>
@@ -147,6 +146,8 @@ static void call_main(void *p)
__libc_init_array();
environ = envp;
+ for (i = 1; i <= __CTOR_LIST__[0]; i++)
+ ((void((*)(void)))__CTOR_LIST__[i]) ();
tzset();
exit(main(argc, argv, envp));
@@ -154,6 +155,10 @@ static void call_main(void *p)
void _exit(int ret)
{
+ int i;
+
+ for (i = 1; i <= __DTOR_LIST__[0]; i++)
+ ((void((*)(void)))__DTOR_LIST__[i]) ();
close_all_files();
__libc_fini_array();
printk("main returned %d\n", ret);
@@ -172,4 +177,3 @@ int app_main(start_info_t *si)
main_thread = create_thread("main", call_main, si);
return 0;
}
-#endif
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/mm.c
--- a/extras/mini-os/mm.c Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/mm.c Mon Jun 02 11:35:39 2008 +0900
@@ -58,7 +58,7 @@ static unsigned long *alloc_bitmap;
#define PAGES_PER_MAPWORD (sizeof(unsigned long) * 8)
#define allocated_in_map(_pn) \
-(alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & (1<<((_pn)&(PAGES_PER_MAPWORD-1))))
+(alloc_bitmap[(_pn)/PAGES_PER_MAPWORD] & (1UL<<((_pn)&(PAGES_PER_MAPWORD-1))))
/*
* Hint regarding bitwise arithmetic in map_{alloc,free}:
@@ -80,13 +80,13 @@ static void map_alloc(unsigned long firs
if ( curr_idx == end_idx )
{
- alloc_bitmap[curr_idx] |= ((1<<end_off)-1) & -(1<<start_off);
+ alloc_bitmap[curr_idx] |= ((1UL<<end_off)-1) & -(1UL<<start_off);
}
else
{
- alloc_bitmap[curr_idx] |= -(1<<start_off);
- while ( ++curr_idx < end_idx ) alloc_bitmap[curr_idx] = ~0L;
- alloc_bitmap[curr_idx] |= (1<<end_off)-1;
+ alloc_bitmap[curr_idx] |= -(1UL<<start_off);
+ while ( ++curr_idx < end_idx ) alloc_bitmap[curr_idx] = ~0UL;
+ alloc_bitmap[curr_idx] |= (1UL<<end_off)-1;
}
}
@@ -102,13 +102,13 @@ static void map_free(unsigned long first
if ( curr_idx == end_idx )
{
- alloc_bitmap[curr_idx] &= -(1<<end_off) | ((1<<start_off)-1);
+ alloc_bitmap[curr_idx] &= -(1UL<<end_off) | ((1UL<<start_off)-1);
}
else
{
- alloc_bitmap[curr_idx] &= (1<<start_off)-1;
+ alloc_bitmap[curr_idx] &= (1UL<<start_off)-1;
while ( ++curr_idx != end_idx ) alloc_bitmap[curr_idx] = 0;
- alloc_bitmap[curr_idx] &= -(1<<end_off);
+ alloc_bitmap[curr_idx] &= -(1UL<<end_off);
}
}
@@ -178,7 +178,7 @@ USED static void print_chunks(void *star
head = free_head[order];
while(!FREELIST_EMPTY(head))
{
- for(count = 0; count < 1<< head->level; count++)
+ for(count = 0; count < 1UL<< head->level; count++)
{
if(count + virt_to_pfn(head) - pfn_start < 1000)
chunks[count + virt_to_pfn(head) - pfn_start] = current;
@@ -235,13 +235,13 @@ static void init_page_allocator(unsigned
* Next chunk is limited by alignment of min, but also
* must not be bigger than remaining range.
*/
- for ( i = PAGE_SHIFT; (1<<(i+1)) <= range; i++ )
- if ( min & (1<<i) ) break;
+ for ( i = PAGE_SHIFT; (1UL<<(i+1)) <= range; i++ )
+ if ( min & (1UL<<i) ) break;
ch = (chunk_head_t *)min;
- min += (1<<i);
- range -= (1<<i);
+ min += (1UL<<i);
+ range -= (1UL<<i);
ct = (chunk_tail_t *)min-1;
i -= PAGE_SHIFT;
ch->level = i;
@@ -280,8 +280,8 @@ unsigned long alloc_pages(int order)
{
/* Split into two equal parts. */
i--;
- spare_ch = (chunk_head_t *)((char *)alloc_ch + (1<<(i+PAGE_SHIFT)));
- spare_ct = (chunk_tail_t *)((char *)spare_ch + (1<<(i+PAGE_SHIFT)))-1;
+ spare_ch = (chunk_head_t *)((char *)alloc_ch + (1UL<<(i+PAGE_SHIFT)));
+ spare_ct = (chunk_tail_t *)((char *)spare_ch +
(1UL<<(i+PAGE_SHIFT)))-1;
/* Create new header for spare chunk. */
spare_ch->level = i;
@@ -294,7 +294,7 @@ unsigned long alloc_pages(int order)
free_head[i] = spare_ch;
}
- map_alloc(PHYS_PFN(to_phys(alloc_ch)), 1<<order);
+ map_alloc(PHYS_PFN(to_phys(alloc_ch)), 1UL<<order);
return((unsigned long)alloc_ch);
@@ -312,16 +312,16 @@ void free_pages(void *pointer, int order
unsigned long mask;
/* First free the chunk */
- map_free(virt_to_pfn(pointer), 1 << order);
+ map_free(virt_to_pfn(pointer), 1UL << order);
/* Create free chunk */
freed_ch = (chunk_head_t *)pointer;
- freed_ct = (chunk_tail_t *)((char *)pointer + (1<<(order + PAGE_SHIFT)))-1;
+ freed_ct = (chunk_tail_t *)((char *)pointer + (1UL<<(order +
PAGE_SHIFT)))-1;
/* Now, possibly we can conseal chunks together */
while(order < FREELIST_SIZE)
{
- mask = 1 << (order + PAGE_SHIFT);
+ mask = 1UL << (order + PAGE_SHIFT);
if((unsigned long)freed_ch & mask)
{
to_merge_ch = (chunk_head_t *)((char *)freed_ch - mask);
diff -r d2a239224cb2 -r f1508348ffab extras/mini-os/sched.c
--- a/extras/mini-os/sched.c Mon Jun 02 11:35:02 2008 +0900
+++ b/extras/mini-os/sched.c Mon Jun 02 11:35:39 2008 +0900
@@ -57,6 +57,8 @@ struct thread *idle_thread = NULL;
struct thread *idle_thread = NULL;
LIST_HEAD(exited_threads);
static int threads_started;
+
+struct thread *main_thread;
void inline print_runqueue(void)
{
diff -r d2a239224cb2 -r f1508348ffab stubdom/Makefile
--- a/stubdom/Makefile Mon Jun 02 11:35:02 2008 +0900
+++ b/stubdom/Makefile Mon Jun 02 11:35:39 2008 +0900
@@ -37,7 +37,7 @@ export PATH:=$(CROSS_PREFIX)/bin:$(PATH)
export PATH:=$(CROSS_PREFIX)/bin:$(PATH)
.PHONY: all
-all: qemu-stubdom
+all: ioemu-stubdom c-stubdom
################
# Cross-binutils
@@ -174,6 +174,7 @@ mk-symlinks:
([ ! -h config-host.h ] || rm -f config-host.h) && \
([ ! -h config-host.mak ] || rm -f config-host.mak) )
[ -h mini-os ] || ln -sf ../extras/mini-os .
+ [ -h mini-os/include/xen ] || ln -sf ../../../xen/include/public
mini-os/include/xen
#######
# libxc
@@ -198,40 +199,41 @@ ioemu: cross-zlib cross-libpci mk-symlin
######
.PHONY: caml
-caml:
- $(MAKE) -C $@
+caml: mk-symlinks
+ $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs
###
# C
###
.PHONY: c
-c:
- $(MAKE) -C $@
+c: mk-symlinks
+ $(MAKE) -C $@ LWIPDIR=$(CURDIR)/lwip-cvs
########
# minios
########
-.PHONY: qemu-stubdom
-qemu-stubdom: mk-symlinks lwip-cvs libxc ioemu
- $(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs QEMUDIR=$(CURDIR)/ioemu
-
+.PHONY: ioemu-stubdom
+ioemu-stubdom: lwip-cvs libxc ioemu
+ $(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs
APP_OBJS="$(CURDIR)/ioemu/i386-dm-stubdom/qemu.a
$(CURDIR)/ioemu/i386-dm-stubdom/libqemu.a"
+
+CAMLLIB = $(shell ocamlc -where)
.PHONY: caml-stubdom
-caml-stubdom: mk-symlinks lwip-cvs libxc cross-libpci caml
- $(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs CAMLDIR=$(CURDIR)/caml
+caml-stubdom: lwip-cvs libxc caml
+ $(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs
APP_OBJS="$(CURDIR)/caml/main-c.o $(CURDIR)/caml/main-caml.o
$(CURDIR)/caml/caml.o $(CAMLLIB)/libasmrun.a"
.PHONY: c-stubdom
-c-stubdom: mk-symlinks lwip-cvs libxc cross-libpci c
- $(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs CDIR=$(CURDIR)/c
+c-stubdom: lwip-cvs libxc c
+ $(MAKE) -C mini-os TARGET=$@ LWIPDIR=$(CURDIR)/lwip-cvs
APP_OBJS=$(CURDIR)/c/main.a
#########
# install
#########
-install: mini-os/mini-os.gz
+install: mini-os/ioemu-stubdom.gz
$(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin"
- $(INSTALL_PROG) mini-os/mini-os.gz
"$(DESTDIR)/usr/lib/xen/boot/stubdom.gz"
+ $(INSTALL_PROG) $< "$(DESTDIR)/usr/lib/xen/boot/stubdom.gz"
#######
# clean
@@ -242,6 +244,7 @@ clean:
clean:
-$(MAKE) -C mini-os LWIPDIR=$(CURDIR)/lwip-cvs clean
$(MAKE) -C caml clean
+ $(MAKE) -C c clean
rm -fr libxc ioemu mini-os include
# clean the cross-compilation result
diff -r d2a239224cb2 -r f1508348ffab stubdom/c/Makefile
--- a/stubdom/c/Makefile Mon Jun 02 11:35:02 2008 +0900
+++ b/stubdom/c/Makefile Mon Jun 02 11:35:39 2008 +0900
@@ -2,7 +2,12 @@ XEN_ROOT = ../..
include $(XEN_ROOT)/Config.mk
-main.a: main.o
+all: main.a
+
+main-c.c:
+ ln -sf $(XEN_ROOT)/extras/mini-os/main.c $@
+
+main.a: main-c.o main.o
$(AR) cr $@ $^
clean:
diff -r d2a239224cb2 -r f1508348ffab stubdom/c/main.c
--- a/stubdom/c/main.c Mon Jun 02 11:35:02 2008 +0900
+++ b/stubdom/c/main.c Mon Jun 02 11:35:39 2008 +0900
@@ -1,4 +1,6 @@
#include <stdio.h>
+#include <unistd.h>
+
int main(void) {
sleep(2);
printf("Hello, world!\n");
diff -r d2a239224cb2 -r f1508348ffab stubdom/caml/Makefile
--- a/stubdom/caml/Makefile Mon Jun 02 11:35:02 2008 +0900
+++ b/stubdom/caml/Makefile Mon Jun 02 11:35:39 2008 +0900
@@ -1,12 +1,20 @@ XEN_ROOT = ../..
XEN_ROOT = ../..
include $(XEN_ROOT)/Config.mk
+
+CAMLLIB = $(shell ocamlc -where)
+DEF_CPPFLAGS += -I$(CAMLLIB)
OCAMLFIND=ocamlfind
OCAMLOPT=ocamlopt
OBJS := hello.cmx
LIBS :=
+
+all: main-c.o main-caml.o caml.o
+
+main-c.c:
+ ln -sf $(XEN_ROOT)/extras/mini-os/main.c $@
%.cmx: %.ml
$(OCAMLFIND) $(OCAMLOPT) -c $< -o $@
@@ -15,4 +23,4 @@ caml.o: $(OBJS)
$(OCAMLFIND) $(OCAMLOPT) $(LIBS) $^ -output-obj -o $@
clean:
- rm -f *.o *.cmx *.cmi
+ rm -f *.a *.o *.cmx *.cmi
diff -r d2a239224cb2 -r f1508348ffab stubdom/caml/main-caml.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stubdom/caml/main-caml.c Mon Jun 02 11:35:39 2008 +0900
@@ -0,0 +1,42 @@
+/*
+ * Caml bootstrap
+ *
+ * Samuel Thibault <Samuel.Thibault@xxxxxxxxxxxxx>, January 2008
+ */
+
+#include <stdio.h>
+#include <errno.h>
+
+#include <caml/mlvalues.h>
+#include <caml/callback.h>
+#include <unistd.h>
+
+/* Ugly binary compatibility with Linux */
+FILE *_stderr asm("stderr");
+int *__errno_location;
+/* Will probably break everything, probably need to fetch from glibc */
+void *__ctype_b_loc;
+
+int main(int argc, char *argv[], char *envp[])
+{
+ value *val;
+
+ /* Get current thread's value */
+ _stderr = stderr;
+ __errno_location = &errno;
+
+ printf("starting caml\n");
+
+ /* Wait before things might hang up */
+ sleep(1);
+
+ caml_startup(argv);
+ val = caml_named_value("main");
+ if (!val) {
+ printf("Couldn't find Caml main");
+ return 1;
+ }
+ caml_callback(*val, Val_int(0));
+ printf("callback returned\n");
+ return 0;
+}
diff -r d2a239224cb2 -r f1508348ffab tools/examples/Makefile
--- a/tools/examples/Makefile Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/examples/Makefile Mon Jun 02 11:35:39 2008 +0900
@@ -9,9 +9,7 @@ XENDOMAINS_SYSCONFIG = init.d/sysconfig.
# Xen configuration dir and configs to go there.
XEN_CONFIG_DIR = /etc/xen
XEN_CONFIGS = xend-config.sxp
-XEN_CONFIGS += xend-config-xenapi.sxp
XEN_CONFIGS += xm-config.xml
-XEN_CONFIGS += xm-config-xenapi.xml
XEN_CONFIGS += xmexample1
XEN_CONFIGS += xmexample2
XEN_CONFIGS += xmexample.hvm
diff -r d2a239224cb2 -r f1508348ffab tools/examples/xend-config-xenapi.sxp
--- a/tools/examples/xend-config-xenapi.sxp Mon Jun 02 11:35:02 2008 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +0,0 @@
-# -*- sh -*-
-
-#
-# Xend configuration file.
-#
-
-# This example configuration is appropriate for an installation that
-# utilizes a bridged network configuration. Access to xend via http
-# is disabled.
-
-# Commented out entries show the default for that entry, unless otherwise
-# specified.
-
-#(logfile /var/log/xen/xend.log)
-#(loglevel DEBUG)
-
-
-# The Xen-API server configuration. (Please note that this server is
-# available as an UNSUPPORTED PREVIEW in Xen 3.0.4, and should not be relied
-# upon).
-#
-# This value configures the ports, interfaces, and access controls for the
-# Xen-API server. Each entry in the list starts with either unix, a port
-# number, or an address:port pair. If this is "unix", then a UDP socket is
-# opened, and this entry applies to that. If it is a port, then Xend will
-# listen on all interfaces on that TCP port, and if it is an address:port
-# pair, then Xend will listen on the specified port, using the interface with
-# the specified address.
-#
-# The subsequent string configures the user-based access control for the
-# listener in question. This can be one of "none" or "pam", indicating either
-# that users should be allowed access unconditionally, or that the local
-# Pluggable Authentication Modules configuration should be used. If this
-# string is missing or empty, then "pam" is used.
-#
-# The final string gives the host-based access control for that listener. If
-# this is missing or empty, then all connections are accepted. Otherwise,
-# this should be a space-separated sequence of regular expressions; any host
-# with a fully-qualified domain name or an IP address that matches one of
-# these regular expressions will be accepted.
-#
-# Example: listen on TCP port 9363 on all interfaces, accepting connections
-# only from machines in example.com or localhost, and allow access through
-# the unix domain socket unconditionally:
-#
- (xen-api-server ((9363 none)))
-# (unix none)))
-#
-# Optionally, the TCP Xen-API server can use SSL by specifying the private
-# key and certificate location:
-#
-# (9367 pam '' /etc/xen/xen-api.key /etc/xen/xen-api.crt)
-#
-# Default:
-# (xen-api-server ((unix)))
-
-
-#(xend-http-server no)
-#(xend-unix-server no)
-#(xend-tcp-xmlrpc-server no)
-#(xend-unix-xmlrpc-server yes)
-#(xend-relocation-server no)
-(xend-relocation-server yes)
-
-#(xend-unix-path /var/lib/xend/xend-socket)
-
-
-# Address and port xend should use for the legacy TCP XMLRPC interface,
-# if xend-tcp-xmlrpc-server is set.
-#(xend-tcp-xmlrpc-server-address 'localhost')
-#(xend-tcp-xmlrpc-server-port 8006)
-
-# SSL key and certificate to use for the legacy TCP XMLRPC interface.
-# Setting these will mean that this port serves only SSL connections as
-# opposed to plaintext ones.
-#(xend-tcp-xmlrpc-server-ssl-key-file /etc/xen/xmlrpc.key)
-#(xend-tcp-xmlrpc-server-ssl-cert-file /etc/xen/xmlrpc.crt)
-
-
-# Port xend should use for the HTTP interface, if xend-http-server is set.
-#(xend-port 8000)
-
-# Port xend should use for the relocation interface, if xend-relocation-server
-# is set.
-#(xend-relocation-port 8002)
-
-# Address xend should listen on for HTTP connections, if xend-http-server is
-# set.
-# Specifying 'localhost' prevents remote connections.
-# Specifying the empty string '' (the default) allows all connections.
-#(xend-address '')
-#(xend-address localhost)
-
-# Address xend should listen on for relocation-socket connections, if
-# xend-relocation-server is set.
-# Meaning and default as for xend-address above.
-#(xend-relocation-address '')
-
-# The hosts allowed to talk to the relocation port. If this is empty (the
-# default), then all connections are allowed (assuming that the connection
-# arrives on a port and interface on which we are listening; see
-# xend-relocation-port and xend-relocation-address above). Otherwise, this
-# should be a space-separated sequence of regular expressions. Any host with
-# a fully-qualified domain name or an IP address that matches one of these
-# regular expressions will be accepted.
-#
-# For example:
-# (xend-relocation-hosts-allow '^localhost$ ^.*\\.example\\.org$')
-#
-#(xend-relocation-hosts-allow '')
-(xend-relocation-hosts-allow '^localhost$ ^localhost\\.localdomain$')
-
-# The limit (in kilobytes) on the size of the console buffer
-#(console-limit 1024)
-
-##
-# To bridge network traffic, like this:
-#
-# dom0: ----------------- bridge -> real eth0 -> the network
-# |
-# domU: fake eth0 -> vifN.0 -+
-#
-# use
-#
-# (network-script network-bridge)
-#
-# Your default ethernet device is used as the outgoing interface, by default.
-# To use a different one (e.g. eth1) use
-#
-# (network-script 'network-bridge netdev=eth1')
-#
-# The bridge is named xenbr0, by default. To rename the bridge, use
-#
-# (network-script 'network-bridge bridge=<name>')
-#
-# It is possible to use the network-bridge script in more complicated
-# scenarios, such as having two outgoing interfaces, with two bridges, and
-# two fake interfaces per guest domain. To do things like this, write
-# yourself a wrapper script, and call network-bridge from it, as appropriate.
-#
-(network-script network-bridge)
-
-# The script used to control virtual interfaces. This can be overridden on a
-# per-vif basis when creating a domain or a configuring a new vif. The
-# vif-bridge script is designed for use with the network-bridge script, or
-# similar configurations.
-#
-# If you have overridden the bridge name using
-# (network-script 'network-bridge bridge=<name>') then you may wish to do the
-# same here. The bridge name can also be set when creating a domain or
-# configuring a new vif, but a value specified here would act as a default.
-#
-# If you are using only one bridge, the vif-bridge script will discover that,
-# so there is no need to specify it explicitly.
-#
-(vif-script vif-bridge)
-
-
-## Use the following if network traffic is routed, as an alternative to the
-# settings for bridged networking given above.
-#(network-script network-route)
-#(vif-script vif-route)
-
-
-## Use the following if network traffic is routed with NAT, as an alternative
-# to the settings for bridged networking given above.
-#(network-script network-nat)
-#(vif-script vif-nat)
-
-# dom0-min-mem is the lowest permissible memory level (in MB) for dom0.
-# This is a minimum both for auto-ballooning (as enabled by
-# enable-dom0-ballooning below) and for xm mem-set when applied to dom0.
-(dom0-min-mem 196)
-
-# Whether to enable auto-ballooning of dom0 to allow domUs to be created.
-# If enable-dom0-ballooning = no, dom0 will never balloon out.
-(enable-dom0-ballooning yes)
-
-# In SMP system, dom0 will use dom0-cpus # of CPUS
-# If dom0-cpus = 0, dom0 will take all cpus available
-(dom0-cpus 0)
-
-# Whether to enable core-dumps when domains crash.
-#(enable-dump no)
-
-# The tool used for initiating virtual TPM migration
-#(external-migration-tool '')
-
-# The interface for VNC servers to listen on. Defaults
-# to 127.0.0.1 To restore old 'listen everywhere' behaviour
-# set this to 0.0.0.0
-#(vnc-listen '127.0.0.1')
-
-# The default password for VNC console on HVM domain.
-# Empty string is no authentication.
-(vncpasswd '')
diff -r d2a239224cb2 -r f1508348ffab tools/examples/xend-config.sxp
--- a/tools/examples/xend-config.sxp Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/examples/xend-config.sxp Mon Jun 02 11:35:39 2008 +0900
@@ -59,6 +59,7 @@
#(xend-unix-xmlrpc-server yes)
#(xend-relocation-server no)
(xend-relocation-server yes)
+#(xend-relocation-ssl-server no)
#(xend-unix-path /var/lib/xend/xend-socket)
@@ -82,14 +83,17 @@
# is set.
#(xend-relocation-port 8002)
-# Whether to use tls when relocating.
-#(xend-relocation-tls no)
-
-# SSL key and certificate to use for the relocation interface.
-# Setting these will mean that this port serves only SSL connections as
-# opposed to plaintext ones.
+# Port xend should use for the ssl relocation interface, if
+# xend-relocation-ssl-server is set.
+#(xend-relocation-ssl-port 8003)
+
+# SSL key and certificate to use for the ssl relocation interface, if
+# xend-relocation-ssl-server is set.
#(xend-relocation-server-ssl-key-file /etc/xen/xmlrpc.key)
#(xend-relocation-server-ssl-cert-file /etc/xen/xmlrpc.crt)
+
+# Whether to use ssl as default when relocating.
+#(xend-relocation-ssl no)
# Address xend should listen on for HTTP connections, if xend-http-server is
# set.
diff -r d2a239224cb2 -r f1508348ffab tools/examples/xm-config-xenapi.xml
--- a/tools/examples/xm-config-xenapi.xml Mon Jun 02 11:35:02 2008 +0900
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +0,0 @@
-<!--
-
-Copyright (C) 2006 XenSource Inc.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of version 2.1 of the GNU Lesser General Public
-License as published by the Free Software Foundation.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
--->
-
-<!--
-
-This is a configuration file for xm; it should be placed in
-/etc/xen/xm-config.xml. If this file is missing, then xm will fall back to
-the normal behaviour that's in Xen 3.0.4 and below. The settings here are
-most useful for experimenting with the Xen-API preview in Xen 3.0.4.
-
--->
-
-<xm>
- <!-- The server element describes how to talk to Xend. The type may be
- Xen-API or LegacyXMLRPC (the default). The URI is that of the
- server; you might try http://server:9363/ or
- httpu:///var/run/xend/xen-api.sock for the Xen-API, or
- httpu:///var/run/xend/xmlrpc.sock for the legacy server.
-
- The username and password attributes will be used to log in if Xen-API
- is being used.
- -->
- <server type='Xen-API'
- uri='http://localhost:9363/'
- username='me'
- password='mypassword' />
-</xm>
diff -r d2a239224cb2 -r f1508348ffab tools/firmware/hvmloader/util.c
--- a/tools/firmware/hvmloader/util.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/firmware/hvmloader/util.c Mon Jun 02 11:35:39 2008 +0900
@@ -609,7 +609,7 @@ uint16_t get_cpu_mhz(void)
uint16_t get_cpu_mhz(void)
{
struct xen_add_to_physmap xatp;
- struct shared_info *shared_info = (struct shared_info *)0xa0000;
+ struct shared_info *shared_info = (struct shared_info *)0xfffff000;
struct vcpu_time_info *info = &shared_info->vcpu_info[0].time;
uint64_t cpu_khz;
uint32_t tsc_to_nsec_mul, version;
@@ -619,7 +619,7 @@ uint16_t get_cpu_mhz(void)
if ( cpu_mhz != 0 )
return cpu_mhz;
- /* Map shared-info page to 0xa0000 (i.e., overlap VGA hole). */
+ /* Map shared-info page. */
xatp.domid = DOMID_SELF;
xatp.space = XENMAPSPACE_shared_info;
xatp.idx = 0;
@@ -643,14 +643,6 @@ uint16_t get_cpu_mhz(void)
cpu_khz = cpu_khz << -tsc_shift;
else
cpu_khz = cpu_khz >> tsc_shift;
-
- /* Get the VGA MMIO hole back by remapping shared info to scratch. */
- xatp.domid = DOMID_SELF;
- xatp.space = XENMAPSPACE_shared_info;
- xatp.idx = 0;
- xatp.gpfn = 0xfffff; /* scratch pfn */
- if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
- BUG();
cpu_mhz = (uint16_t)(((uint32_t)cpu_khz + 500) / 1000);
return cpu_mhz;
diff -r d2a239224cb2 -r f1508348ffab tools/firmware/rombios/rombios.c
--- a/tools/firmware/rombios/rombios.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/firmware/rombios/rombios.c Mon Jun 02 11:35:39 2008 +0900
@@ -2225,26 +2225,12 @@ void interactive_bootkey()
Bit16u i;
Bit8u scan = 0;
- bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\nPress F10 to
select boot device.\n");
- for (i = 3; i > 0; i--)
- {
- scan = wait(WAIT_HZ, 0);
- switch (scan) {
- case 0x3D:
- case 0x3E:
- case 0x3F:
- case 0x58:
- break;
- case 0x44:
- scan = bootmenu(inb_cmos(0x3d) & 0x0f);
- break;
- default:
- scan = 0;
- break;
- }
- if (scan != 0)
- break;
- }
+ bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO,
+ "\n\nPress F10 to select boot device.\n");
+
+ scan = wait(1, 0);
+ if (scan == 0x44)
+ scan = bootmenu(inb_cmos(0x3d) & 0x0f);
/* set the default based on the keypress or menu */
switch(scan) {
diff -r d2a239224cb2 -r f1508348ffab tools/ioemu/Makefile.target
--- a/tools/ioemu/Makefile.target Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/ioemu/Makefile.target Mon Jun 02 11:35:39 2008 +0900
@@ -358,6 +358,13 @@ endif
endif
ifdef CONFIG_STUBDOM
+VL_OBJS+=main-qemu.o
+CFLAGS += -DCONFIG_QEMU
+main-qemu.c:
+ ln -s $(XEN_ROOT)/extras/mini-os/main.c $@
+endif
+
+ifdef CONFIG_STUBDOM
#CONFIG_PASSTHROUGH=1
else
ifeq (,$(wildcard /usr/include/pci))
diff -r d2a239224cb2 -r f1508348ffab tools/ioemu/hw/cirrus_vga.c
--- a/tools/ioemu/hw/cirrus_vga.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/ioemu/hw/cirrus_vga.c Mon Jun 02 11:35:39 2008 +0900
@@ -281,8 +281,6 @@ typedef struct PCICirrusVGAState {
static uint8_t rop_to_index[256];
-void *shared_vram;
-
/***************************************
*
* prototypes.
diff -r d2a239224cb2 -r f1508348ffab tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/ioemu/vl.c Mon Jun 02 11:35:39 2008 +0900
@@ -7807,8 +7807,9 @@ int main(int argc, char **argv)
bdrv_set_type_hint(fd_table[i], BDRV_TYPE_FLOPPY);
}
if (fd_filename[i] != '\0') {
- if (bdrv_open(fd_table[i], fd_filename[i],
- snapshot ? BDRV_O_SNAPSHOT : 0) < 0) {
+ if (bdrv_open2(fd_table[i], fd_filename[i],
+ snapshot ? BDRV_O_SNAPSHOT : 0,
+ &bdrv_raw) < 0) {
fprintf(stderr, "qemu: could not open floppy disk image
'%s'\n",
fd_filename[i]);
exit(1);
diff -r d2a239224cb2 -r f1508348ffab tools/ioemu/vl.h
--- a/tools/ioemu/vl.h Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/ioemu/vl.h Mon Jun 02 11:35:39 2008 +0900
@@ -153,8 +153,6 @@ int unset_mm_mapping(int xc_handle, uint
unsigned int address_bits, unsigned long *extent_start);
int set_mm_mapping(int xc_handle, uint32_t domid, unsigned long nr_pages,
unsigned int address_bits, unsigned long *extent_start);
-
-extern void *shared_vram;
extern FILE *logfile;
diff -r d2a239224cb2 -r f1508348ffab tools/ioemu/xenstore.c
--- a/tools/ioemu/xenstore.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/ioemu/xenstore.c Mon Jun 02 11:35:39 2008 +0900
@@ -112,7 +112,7 @@ void xenstore_parse_domain_config(int hv
e = xs_directory(xsh, XBT_NULL, buf, &num);
if (e == NULL)
- goto out;
+ num = 0;
for (i = 0; i < num; i++) {
/* read the backend path */
diff -r d2a239224cb2 -r f1508348ffab tools/libxc/Makefile
--- a/tools/libxc/Makefile Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/libxc/Makefile Mon Jun 02 11:35:39 2008 +0900
@@ -5,11 +5,9 @@ MINOR = 0
MINOR = 0
CTRL_SRCS-y :=
-ifneq ($(stubdom),y)
CTRL_SRCS-y += xc_core.c
CTRL_SRCS-$(CONFIG_X86) += xc_core_x86.c
CTRL_SRCS-$(CONFIG_IA64) += xc_core_ia64.c
-endif
CTRL_SRCS-y += xc_domain.c
CTRL_SRCS-y += xc_evtchn.c
CTRL_SRCS-y += xc_misc.c
@@ -21,9 +19,7 @@ CTRL_SRCS-y += xc_csched.c
CTRL_SRCS-y += xc_csched.c
CTRL_SRCS-y += xc_tbuf.c
CTRL_SRCS-y += xc_pm.c
-ifneq ($(stubdom),y)
CTRL_SRCS-y += xc_resume.c
-endif
CTRL_SRCS-$(CONFIG_X86) += xc_pagetab.c
CTRL_SRCS-$(CONFIG_Linux) += xc_linux.c
CTRL_SRCS-$(CONFIG_SunOS) += xc_solaris.c
@@ -33,15 +29,12 @@ CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.
GUEST_SRCS-y :=
GUEST_SRCS-y += xg_private.c
-ifneq ($(stubdom),y)
GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c
GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c
-endif
VPATH = ../../xen/common/libelf
CFLAGS += -I../../xen/common/libelf
-ifneq ($(stubdom),y)
GUEST_SRCS-y += libelf-tools.c libelf-loader.c
GUEST_SRCS-y += libelf-dominfo.c libelf-relocate.c
@@ -55,7 +48,6 @@ GUEST_SRCS-$(CONFIG_X86) += xc_dom_x
GUEST_SRCS-$(CONFIG_X86) += xc_dom_x86.c
GUEST_SRCS-$(CONFIG_X86) += xc_cpuid_x86.c
GUEST_SRCS-$(CONFIG_IA64) += xc_dom_ia64.c
-endif
-include $(XEN_TARGET_ARCH)/Makefile
diff -r d2a239224cb2 -r f1508348ffab tools/libxc/xc_core.c
--- a/tools/libxc/xc_core.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/libxc/xc_core.c Mon Jun 02 11:35:39 2008 +0900
@@ -64,7 +64,7 @@
/* string table */
struct xc_core_strtab {
char *strings;
- uint16_t current;
+ uint16_t length;
uint16_t max;
};
@@ -89,7 +89,7 @@ xc_core_strtab_init(void)
/* index 0 represents none */
strtab->strings[0] = '\0';
- strtab->current = 1;
+ strtab->length = 1;
return strtab;
}
@@ -107,14 +107,14 @@ xc_core_strtab_get(struct xc_core_strtab
uint16_t ret = 0;
uint16_t len = strlen(name) + 1;
- if ( strtab->current > UINT16_MAX - len )
+ if ( strtab->length > UINT16_MAX - len )
{
PERROR("too long string table");
errno = E2BIG;
return ret;
}
- if ( strtab->current + len > strtab->max )
+ if ( strtab->length + len > strtab->max )
{
char *tmp;
if ( strtab->max > UINT16_MAX / 2 )
@@ -135,9 +135,9 @@ xc_core_strtab_get(struct xc_core_strtab
strtab->max *= 2;
}
- ret = strtab->current;
- strcpy(strtab->strings + strtab->current, name);
- strtab->current += len;
+ ret = strtab->length;
+ strcpy(strtab->strings + strtab->length, name);
+ strtab->length += len;
return ret;
}
@@ -669,7 +669,7 @@ xc_domain_dumpcore_via_callback(int xc_h
offset += filesz;
/* fixing up section header string table section header */
- filesz = strtab->current;
+ filesz = strtab->length;
sheaders->shdrs[strtab_idx].sh_offset = offset;
sheaders->shdrs[strtab_idx].sh_size = filesz;
@@ -829,7 +829,7 @@ copy_done:
goto out;
/* elf section header string table: .shstrtab */
- sts = dump_rtn(args, strtab->strings, strtab->current);
+ sts = dump_rtn(args, strtab->strings, strtab->length);
if ( sts != 0 )
goto out;
diff -r d2a239224cb2 -r f1508348ffab tools/libxc/xc_domain.c
--- a/tools/libxc/xc_domain.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/libxc/xc_domain.c Mon Jun 02 11:35:39 2008 +0900
@@ -767,6 +767,37 @@ int xc_assign_device(
return do_domctl(xc_handle, &domctl);
}
+int xc_get_device_group(
+ int xc_handle,
+ uint32_t domid,
+ uint32_t machine_bdf,
+ uint32_t max_sdevs,
+ uint32_t *num_sdevs,
+ uint32_t *sdev_array)
+{
+ int rc;
+ DECLARE_DOMCTL;
+
+ domctl.cmd = XEN_DOMCTL_get_device_group;
+ domctl.domain = (domid_t)domid;
+
+ domctl.u.get_device_group.machine_bdf = machine_bdf;
+ domctl.u.get_device_group.max_sdevs = max_sdevs;
+
+ set_xen_guest_handle(domctl.u.get_device_group.sdev_array, sdev_array);
+
+ if ( lock_pages(sdev_array, max_sdevs * sizeof(*sdev_array)) != 0 )
+ {
+ PERROR("Could not lock memory for xc_get_device_group\n");
+ return -ENOMEM;
+ }
+ rc = do_domctl(xc_handle, &domctl);
+ unlock_pages(sdev_array, max_sdevs * sizeof(*sdev_array));
+
+ *num_sdevs = domctl.u.get_device_group.num_sdevs;
+ return rc;
+}
+
int xc_test_assign_device(
int xc_handle,
uint32_t domid,
diff -r d2a239224cb2 -r f1508348ffab tools/libxc/xc_minios.c
--- a/tools/libxc/xc_minios.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/libxc/xc_minios.c Mon Jun 02 11:35:39 2008 +0900
@@ -35,11 +35,12 @@ extern struct wait_queue_head event_queu
int xc_interface_open(void)
{
- return 0;
+ return alloc_fd(FTYPE_XC);
}
int xc_interface_close(int xc_handle)
{
+ files[xc_handle].type = FTYPE_NONE;
return 0;
}
@@ -79,8 +80,12 @@ int xc_map_foreign_ranges(int xc_handle,
int xc_map_foreign_ranges(int xc_handle, uint32_t dom,
privcmd_mmap_entry_t *entries, int nr)
{
- printf("xc_map_foreign_ranges, TODO\n");
- do_exit();
+ int i;
+ for (i = 0; i < nr; i++) {
+ unsigned long mfn = entries[i].mfn;
+ do_map_frames(entries[i].va, &mfn, entries[i].npages, 0, 1, dom, 0,
L1_PROT);
+ }
+ return 0;
}
int do_xen_hypercall(int xc_handle, privcmd_hypercall_t *hypercall)
@@ -294,6 +299,12 @@ int xc_evtchn_unmask(int xce_handle, evt
return 0;
}
+/* Optionally flush file to disk and discard page cache */
+void discard_file_cache(int fd, int flush)
+{
+ if (flush)
+ fsync(fd);
+}
/*
* Local variables:
* mode: C
diff -r d2a239224cb2 -r f1508348ffab tools/libxc/xenctrl.h
--- a/tools/libxc/xenctrl.h Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/libxc/xenctrl.h Mon Jun 02 11:35:39 2008 +0900
@@ -955,6 +955,13 @@ int xc_assign_device(int xc_handle,
uint32_t domid,
uint32_t machine_bdf);
+int xc_get_device_group(int xc_handle,
+ uint32_t domid,
+ uint32_t machine_bdf,
+ uint32_t max_sdevs,
+ uint32_t *num_sdevs,
+ uint32_t *sdev_array);
+
int xc_test_assign_device(int xc_handle,
uint32_t domid,
uint32_t machine_bdf);
diff -r d2a239224cb2 -r f1508348ffab tools/libxc/xg_private.c
--- a/tools/libxc/xg_private.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/libxc/xg_private.c Mon Jun 02 11:35:39 2008 +0900
@@ -11,22 +11,6 @@
#include <malloc.h>
#include "xg_private.h"
-
-int lock_pages(void *addr, size_t len)
-{
- int e = 0;
-#ifndef __sun__
- e = mlock(addr, len);
-#endif
- return (e);
-}
-
-void unlock_pages(void *addr, size_t len)
-{
-#ifndef __sun__
- safe_munlock(addr, len);
-#endif
-}
char *xc_read_image(const char *filename, unsigned long *size)
{
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/lowlevel/xc/xc.c
--- a/tools/python/xen/lowlevel/xc/xc.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/lowlevel/xc/xc.c Mon Jun 02 11:35:39 2008 +0900
@@ -106,7 +106,7 @@ static PyObject *pyxc_domain_create(XcOb
static char *kwd_list[] = { "domid", "ssidref", "handle", "flags",
"target", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "|iiOii", kwd_list,
- &dom, &ssidref, &pyhandle, &flags,
&target))
+ &dom, &ssidref, &pyhandle, &flags,
&target))
return NULL;
if ( pyhandle != NULL )
{
@@ -434,44 +434,44 @@ static PyObject *pyxc_linux_build(XcObje
dom->vhpt_size_log2 = vhpt;
if ( xc_dom_linux_build(self->xc_handle, dom, domid, mem_mb, image,
- ramdisk, flags, store_evtchn, &store_mfn,
- console_evtchn, &console_mfn) != 0 ) {
- goto out;
+ ramdisk, flags, store_evtchn, &store_mfn,
+ console_evtchn, &console_mfn) != 0 ) {
+ goto out;
}
if ( !(elfnote_dict = PyDict_New()) )
- goto out;
+ goto out;
for ( i = 0; i < ARRAY_SIZE(dom->parms.elf_notes); i++ )
{
- switch ( dom->parms.elf_notes[i].type )
+ switch ( dom->parms.elf_notes[i].type )
{
- case XEN_ENT_NONE:
- continue;
- case XEN_ENT_LONG:
- elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
- break;
- case XEN_ENT_STR:
- elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
- break;
- }
- PyDict_SetItemString(elfnote_dict,
- dom->parms.elf_notes[i].name,
- elfnote);
- Py_DECREF(elfnote);
+ case XEN_ENT_NONE:
+ continue;
+ case XEN_ENT_LONG:
+ elfnote = Py_BuildValue("k", dom->parms.elf_notes[i].data.num);
+ break;
+ case XEN_ENT_STR:
+ elfnote = Py_BuildValue("s", dom->parms.elf_notes[i].data.str);
+ break;
+ }
+ PyDict_SetItemString(elfnote_dict,
+ dom->parms.elf_notes[i].name,
+ elfnote);
+ Py_DECREF(elfnote);
}
ret = Py_BuildValue("{s:i,s:i,s:N}",
- "store_mfn", store_mfn,
- "console_mfn", console_mfn,
- "notes", elfnote_dict);
+ "store_mfn", store_mfn,
+ "console_mfn", console_mfn,
+ "notes", elfnote_dict);
if ( dom->arch_hooks->native_protocol )
{
- PyObject *native_protocol =
- Py_BuildValue("s", dom->arch_hooks->native_protocol);
- PyDict_SetItemString(ret, "native_protocol", native_protocol);
- Py_DECREF(native_protocol);
+ PyObject *native_protocol =
+ Py_BuildValue("s", dom->arch_hooks->native_protocol);
+ PyDict_SetItemString(ret, "native_protocol", native_protocol);
+ Py_DECREF(native_protocol);
}
xc_dom_release(dom);
@@ -556,7 +556,7 @@ static PyObject *pyxc_test_assign_device
{
uint32_t dom;
char *pci_str;
- uint32_t bdf = 0;
+ int32_t bdf = 0;
int seg, bus, dev, func;
static char *kwd_list[] = { "domid", "pci", NULL };
@@ -571,12 +571,141 @@ static PyObject *pyxc_test_assign_device
bdf |= (func & 0x7) << 8;
if ( xc_test_assign_device(self->xc_handle, dom, bdf) != 0 )
+ {
+ if (errno == ENOSYS)
+ bdf = -1;
break;
-
+ }
bdf = 0;
}
return Py_BuildValue("i", bdf);
+}
+
+static PyObject *pyxc_assign_device(XcObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ uint32_t dom;
+ char *pci_str;
+ int32_t bdf = 0;
+ int seg, bus, dev, func;
+
+ static char *kwd_list[] = { "domid", "pci", NULL };
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
+ &dom, &pci_str) )
+ return NULL;
+
+ while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
+ {
+ bdf |= (bus & 0xff) << 16;
+ bdf |= (dev & 0x1f) << 11;
+ bdf |= (func & 0x7) << 8;
+
+ if ( xc_assign_device(self->xc_handle, dom, bdf) != 0 )
+ {
+ if (errno == ENOSYS)
+ bdf = -1;
+ break;
+ }
+ bdf = 0;
+ }
+
+ return Py_BuildValue("i", bdf);
+}
+
+static PyObject *pyxc_deassign_device(XcObject *self,
+ PyObject *args,
+ PyObject *kwds)
+{
+ uint32_t dom;
+ char *pci_str;
+ int32_t bdf = 0;
+ int seg, bus, dev, func;
+
+ static char *kwd_list[] = { "domid", "pci", NULL };
+ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "is", kwd_list,
+ &dom, &pci_str) )
+ return NULL;
+
+ while ( next_bdf(&pci_str, &seg, &bus, &dev, &func) )
+ {
+ bdf |= (bus & 0xff) << 16;
+ bdf |= (dev & 0x1f) << 11;
+ bdf |= (func & 0x7) << 8;
+
+ if ( xc_deassign_device(self->xc_handle, dom, bdf) != 0 )
+ {
+ if (errno == ENOSYS)
+ bdf = -1;
+ break;
+ }
+ bdf = 0;
+ }
+
+ return Py_BuildValue("i", bdf);
+}
+
+static PyObject *pyxc_get_device_group(XcObject *self,
+ PyObject *args)
+{
+ domid_t domid;
+ uint32_t bdf = 0;
+ uint32_t max_sdevs, num_sdevs;
+ int seg, bus, dev, func, rc, i;
+ PyObject *Pystr;
+ char *group_str;
+ char dev_str[9];
+ uint32_t *sdev_array;
+
+ if ( !PyArg_ParseTuple(args, "iiiii", &domid, &seg, &bus, &dev, &func) )
+ return NULL;
+
+ /* Maximum allowed siblings device number per group */
+ max_sdevs = 1024;
+
+ if ( (sdev_array = malloc(max_sdevs * sizeof(*sdev_array))) == NULL )
+ return PyErr_NoMemory();
+ memset(sdev_array, 0, max_sdevs * sizeof(*sdev_array));
+
+ bdf |= (bus & 0xff) << 16;
+ bdf |= (dev & 0x1f) << 11;
+ bdf |= (func & 0x7) << 8;
+
+ rc = xc_get_device_group(self->xc_handle,
+ domid, bdf, max_sdevs, &num_sdevs, sdev_array);
+
+ if ( rc < 0 )
+ {
+ free(sdev_array);
+ return pyxc_error_to_exception();
+ }
+
+ if ( !num_sdevs )
+ {
+ free(sdev_array);
+ return Py_BuildValue("s", "");
+ }
+
+ if ( (group_str = malloc(num_sdevs * sizeof(dev_str))) == NULL )
+ return PyErr_NoMemory();
+ memset(group_str, '\0', num_sdevs * sizeof(dev_str));
+
+ for ( i = 0; i < num_sdevs; i++ )
+ {
+ bus = (sdev_array[i] >> 16) & 0xff;
+ dev = (sdev_array[i] >> 11) & 0x1f;
+ func = (sdev_array[i] >> 8) & 0x7;
+ sprintf(dev_str, "%02x:%02x.%x,", bus, dev, func);
+ strcat(group_str, dev_str);
+ }
+
+ Pystr = Py_BuildValue("s", group_str);
+
+ free(sdev_array);
+ free(group_str);
+
+ return Pystr;
}
#ifdef __ia64__
@@ -729,8 +858,8 @@ static PyObject *pyxc_hvm_build(XcObject
int memsize, vcpus = 1, acpi = 0, apic = 1;
static char *kwd_list[] = { "domid",
- "memsize", "image", "vcpus", "acpi",
- "apic", NULL };
+ "memsize", "image", "vcpus", "acpi",
+ "apic", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iii", kwd_list,
&dom, &memsize,
&image, &vcpus, &acpi, &apic) )
@@ -782,8 +911,8 @@ static PyObject *pyxc_evtchn_alloc_unbou
}
static PyObject *pyxc_evtchn_reset(XcObject *self,
- PyObject *args,
- PyObject *kwds)
+ PyObject *args,
+ PyObject *kwds)
{
uint32_t dom;
@@ -947,11 +1076,11 @@ static PyObject *pyxc_physinfo(XcObject
for ( i = 0; i < info.nr_nodes; i++ )
{
- xc_availheap(self->xc_handle, 0, 0, i, &free_heap);
- PyList_Append(node_to_memory_obj,
- PyInt_FromLong(free_heap / 1024));
- }
-
+ xc_availheap(self->xc_handle, 0, 0, i, &free_heap);
+ PyList_Append(node_to_memory_obj,
+ PyInt_FromLong(free_heap / 1024));
+ }
+
PyDict_SetItemString(ret_obj, "node_to_cpu", node_to_cpu_obj);
PyDict_SetItemString(ret_obj, "node_to_memory", node_to_memory_obj);
@@ -1517,6 +1646,17 @@ static PyMethodDef pyxc_methods[] = {
" value [long]: Value of param.\n"
"Returns: [int] 0 on success.\n" },
+ { "get_device_group",
+ (PyCFunction)pyxc_get_device_group,
+ METH_VARARGS, "\n"
+ "get sibling devices infomation.\n"
+ " dom [int]: Domain to assign device to.\n"
+ " seg [int]: PCI segment.\n"
+ " bus [int]: PCI bus.\n"
+ " dev [int]: PCI dev.\n"
+ " func [int]: PCI func.\n"
+ "Returns: [string]: Sibling devices \n" },
+
{ "test_assign_device",
(PyCFunction)pyxc_test_assign_device,
METH_VARARGS | METH_KEYWORDS, "\n"
@@ -1524,6 +1664,22 @@ static PyMethodDef pyxc_methods[] = {
" dom [int]: Identifier of domain to build into.\n"
" pci_str [str]: PCI devices.\n"
"Returns: [int] 0 on success, or device bdf that can't be assigned.\n"
},
+
+ { "assign_device",
+ (PyCFunction)pyxc_assign_device,
+ METH_VARARGS | METH_KEYWORDS, "\n"
+ "Assign device to IOMMU domain.\n"
+ " dom [int]: Domain to assign device to.\n"
+ " pci_str [str]: PCI devices.\n"
+ "Returns: [int] 0 on success, or device bdf that can't be assigned.\n"
},
+
+ { "deassign_device",
+ (PyCFunction)pyxc_deassign_device,
+ METH_VARARGS | METH_KEYWORDS, "\n"
+ "Deassign device from IOMMU domain.\n"
+ " dom [int]: Domain to deassign device from.\n"
+ " pci_str [str]: PCI devices.\n"
+ "Returns: [int] 0 on success, or device bdf that can't be
deassigned.\n" },
{ "sched_id_get",
(PyCFunction)pyxc_sched_id_get,
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/xend/XendAPI.py
--- a/tools/python/xen/xend/XendAPI.py Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/xend/XendAPI.py Mon Jun 02 11:35:39 2008 +0900
@@ -1759,12 +1759,12 @@ class XendAPI(object):
xendom = XendDomain.instance()
xeninfo = xendom.get_vm_by_uuid(vm_ref)
- resource = other_config.get("resource", 0)
port = other_config.get("port", 0)
- node = other_config.get("node", 0)
+ node = other_config.get("node", -1)
+ ssl = other_config.get("ssl", None)
xendom.domain_migrate(xeninfo.getDomid(), destination_url,
- bool(live), resource, port, node)
+ bool(live), port, node, ssl)
return xen_api_success_void()
def VM_save(self, _, vm_ref, dest, checkpoint):
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/xend/XendDomain.py
--- a/tools/python/xen/xend/XendDomain.py Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/xend/XendDomain.py Mon Jun 02 11:35:39 2008 +0900
@@ -43,8 +43,8 @@ from xen.xend.XendConstants import DOM_S
from xen.xend.XendConstants import DOM_STATE_HALTED, DOM_STATE_PAUSED
from xen.xend.XendConstants import DOM_STATE_RUNNING, DOM_STATE_SUSPENDED
from xen.xend.XendConstants import DOM_STATE_SHUTDOWN, DOM_STATE_UNKNOWN
-from xen.xend.XendConstants import DOM_STATE_CRASHED
-from xen.xend.XendConstants import TRIGGER_TYPE
+from xen.xend.XendConstants import DOM_STATE_CRASHED, HVM_PARAM_ACPI_S_STATE
+from xen.xend.XendConstants import TRIGGER_TYPE, TRIGGER_S3RESUME
from xen.xend.XendDevices import XendDevices
from xen.xend.XendAPIConstants import *
@@ -1258,22 +1258,24 @@ class XendDomain:
return val
- def domain_migrate(self, domid, dst, live=False, port=0, node=-1):
+ def domain_migrate(self, domid, dst, live=False, port=0, node=-1,
ssl=None):
"""Start domain migration.
@param domid: Domain ID or Name
@type domid: int or string.
@param dst: Destination IP address
@type dst: string
- @keyword port: relocation port on destination
- @type port: int
@keyword live: Live migration
@type live: bool
+ @keyword port: relocation port on destination
+ @type port: int
+ @keyword node: use node number for target
+ @type node: int
+ @keyword ssl: use ssl connection
+ @type ssl: bool
@rtype: None
- @keyword node: use node number for target
- @rtype: int
@raise XendError: Failed to migrate
- @raise XendInvalidDomain: Domain is not valid
+ @raise XendInvalidDomain: Domain is not valid
"""
dominfo = self.domain_lookup_nr(domid)
@@ -1294,13 +1296,14 @@ class XendDomain:
""" Make sure there's memory free for enabling shadow mode """
dominfo.checkLiveMigrateMemory()
- if port == 0:
- port = xoptions.get_xend_relocation_port()
-
- tls = xoptions.get_xend_relocation_tls()
- if tls:
+ if ssl is None:
+ ssl = xoptions.get_xend_relocation_ssl()
+
+ if ssl:
from OpenSSL import SSL
from xen.web import connection
+ if port == 0:
+ port = xoptions.get_xend_relocation_ssl_port()
try:
ctx = SSL.Context(SSL.SSLv23_METHOD)
sock = SSL.Connection(ctx,
@@ -1328,6 +1331,8 @@ class XendDomain:
os.close(p2cread)
os.close(p2cwrite)
else:
+ if port == 0:
+ port = xoptions.get_xend_relocation_port()
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# When connecting to our ssl enabled relocation server using a
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/xend/XendDomainInfo.py Mon Jun 02 11:35:39 2008 +0900
@@ -2091,28 +2091,28 @@ class XendDomainInfo:
xc.vcpu_setaffinity(self.domid, v,
self.info['cpus'][v])
else:
def find_relaxed_node(node_list):
- import sys
+ import sys
+ nr_nodes = info['nr_nodes']
if node_list is None:
- node_list = range(0, info['nr_nodes'])
+ node_list = range(0, nr_nodes)
nodeload = [0]
- nodeload = nodeload * info['nr_nodes']
+ nodeload = nodeload * nr_nodes
from xen.xend import XendDomain
doms = XendDomain.instance().list('all')
- for dom in doms:
+ for dom in filter (lambda d: d.domid != self.domid, doms):
cpuinfo = dom.getVCPUInfo()
for vcpu in sxp.children(cpuinfo, 'vcpu'):
- def vinfo(n, t):
- return t(sxp.child_value(vcpu, n))
- cpumap = vinfo('cpumap', list)
- for i in node_list:
+ if sxp.child_value(vcpu, 'online') == 0: continue
+ cpumap = list(sxp.child_value(vcpu,'cpumap'))
+ for i in range(0, nr_nodes):
node_cpumask = info['node_to_cpu'][i]
for j in node_cpumask:
if j in cpumap:
nodeload[i] += 1
break
- for i in node_list:
- if len(info['node_to_cpu'][i]) > 0:
- nodeload[i] = int(nodeload[i] /
len(info['node_to_cpu'][i]))
+ for i in range(0, nr_nodes):
+ if len(info['node_to_cpu'][i]) > 0 and i in node_list:
+ nodeload[i] = int(nodeload[i] * 16 /
len(info['node_to_cpu'][i]))
else:
nodeload[i] = sys.maxint
index = nodeload.index( min(nodeload) )
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/xend/XendOptions.py
--- a/tools/python/xen/xend/XendOptions.py Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/xend/XendOptions.py Mon Jun 02 11:35:39 2008 +0900
@@ -72,6 +72,9 @@ class XendOptions:
"""Default for the flag indicating whether xend should run a relocation
server."""
xend_relocation_server_default = 'no'
+ """Default for the flag indicating whether xend should run a ssl
relocation server."""
+ xend_relocation_ssl_server_default = 'no'
+
"""Default interface address the xend relocation server listens at. """
xend_relocation_address_default = ''
@@ -80,6 +83,9 @@ class XendOptions:
"""Default port xend serves relocation at. """
xend_relocation_port_default = 8002
+
+ """Default port xend serves ssl relocation at. """
+ xend_relocation_ssl_port_default = 8003
xend_relocation_hosts_allow_default = ''
@@ -192,6 +198,12 @@ class XendOptions:
return self.get_config_bool("xend-relocation-server",
self.xend_relocation_server_default)
+ def get_xend_relocation_ssl_server(self):
+ """Get the flag indicating whether xend should run a ssl relocation
server.
+ """
+ return self.get_config_bool("xend-relocation-ssl-server",
+ self.xend_relocation_ssl_server_default)
+
def get_xend_relocation_server_ssl_key_file(self):
return self.get_config_string("xend-relocation-server-ssl-key-file")
@@ -209,10 +221,17 @@ class XendOptions:
return self.get_config_int('xend-relocation-port',
self.xend_relocation_port_default)
- def get_xend_relocation_tls(self):
- """Whether to use tls when relocating.
- """
- return self.get_config_bool('xend-relocation-tls', 'no')
+ def get_xend_relocation_ssl_port(self):
+ """Get the port xend listens at for ssl connection to its relocation
+ server.
+ """
+ return self.get_config_int('xend-relocation-ssl-port',
+ self.xend_relocation_ssl_port_default)
+
+ def get_xend_relocation_ssl(self):
+ """Whether to use ssl when relocating.
+ """
+ return self.get_config_bool('xend-relocation-ssl', 'no')
def get_xend_relocation_hosts_allow(self):
return self.get_config_string("xend-relocation-hosts-allow",
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/xend/server/SrvDomain.py
--- a/tools/python/xen/xend/server/SrvDomain.py Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/xend/server/SrvDomain.py Mon Jun 02 11:35:39 2008 +0900
@@ -115,7 +115,9 @@ class SrvDomain(SrvDir):
[['dom', 'int'],
['destination', 'str'],
['live', 'int'],
- ['port', 'int']])
+ ['port', 'int'],
+ ['node', 'int'],
+ ['ssl', 'int']])
return fn(req.args, {'dom': self.dom.domid})
def op_pincpu(self, _, req):
@@ -215,6 +217,11 @@ class SrvDomain(SrvDir):
def op_vcpuinfo(self, _1, req):
return self.call(self.dom.getVCPUInfo, [], req)
+
+
+ def op_reset(self, _, req):
+ self.acceptCommand(req)
+ return self.xd.domain_reset(self.dom.getName())
def render_POST(self, req):
@@ -257,6 +264,10 @@ class SrvDomain(SrvDir):
req.write('</form>')
req.write('<form method="post" action="%s">' % url)
+ req.write('<input type="submit" name="op" value="reset">')
+ req.write('</form>')
+
+ req.write('<form method="post" action="%s">' % url)
req.write('<input type="submit" name="op" value="shutdown">')
req.write('<input type="radio" name="reason" value="poweroff"
checked>Poweroff')
req.write('<input type="radio" name="reason" value="halt">Halt')
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/xend/server/pciif.py
--- a/tools/python/xen/xend/server/pciif.py Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/xend/server/pciif.py Mon Jun 02 11:35:39 2008 +0900
@@ -226,6 +226,39 @@ class PciController(DevController):
return sxpr
+ def CheckSiblingDevices(self, domid, dev):
+ """ Check if all sibling devices of dev are owned by pciback
+ """
+ if not self.vm.info.is_hvm():
+ return
+
+ group_str = xc.get_device_group(domid, dev.domain, dev.bus, dev.slot,
dev.func)
+ if group_str == "":
+ return
+
+ #group string format xx:xx.x,xx:xx.x,
+ devstr_len = group_str.find(',')
+ for i in range(0, len(group_str), devstr_len + 1):
+ (bus, slotfunc) = group_str[i:i + devstr_len].split(':')
+ (slot, func) = slotfunc.split('.')
+ b = parse_hex(bus)
+ d = parse_hex(slot)
+ f = parse_hex(func)
+ try:
+ sdev = PciDevice(dev.domain, b, d, f)
+ except Exception, e:
+ #no dom0 drivers bound to sdev
+ continue
+
+ if sdev.driver!='pciback':
+ raise VmError(("pci: PCI Backend does not own\n "+ \
+ "sibling device %s of device %s\n"+ \
+ "See the pciback.hide kernel "+ \
+ "command-line parameter or\n"+ \
+ "bind your slot/device to the PCI backend using sysfs" \
+ )%(sdev.name, dev.name))
+ return
+
def setupOneDevice(self, domain, bus, slot, func):
""" Attach I/O resources for device to frontend domain
"""
@@ -245,8 +278,19 @@ class PciController(DevController):
"bind your slot/device to the PCI backend using sysfs" \
)%(dev.name))
+ self.CheckSiblingDevices(fe_domid, dev)
+
PCIQuirk(dev.vendor, dev.device, dev.subvendor, dev.subdevice, domain,
bus, slot, func)
+
+ if not self.vm.info.is_hvm():
+ # Setup IOMMU device assignment
+ pci_str = "0x%x, 0x%x, 0x%x, 0x%x" % (domain, bus, slot, func)
+ bdf = xc.assign_device(fe_domid, pci_str)
+ if bdf > 0:
+ raise VmError("Failed to assign device to IOMMU (%x:%x.%x)"
+ % (bus, slot, func))
+ log.debug("pci: assign device %x:%x.%x" % (bus, slot, func))
for (start, size) in dev.ioports:
log.debug('pci: enabling ioport 0x%x/0x%x'%(start,size))
@@ -329,6 +373,14 @@ class PciController(DevController):
"command-line parameter or\n"+ \
"bind your slot/device to the PCI backend using sysfs" \
)%(dev.name))
+
+ if not self.vm.info.is_hvm():
+ pci_str = "0x%x, 0x%x, 0x%x, 0x%x" % (domain, bus, slot, func)
+ bdf = xc.deassign_device(fe_domid, pci_str)
+ if bdf > 0:
+ raise VmError("Failed to deassign device from IOMMU (%x:%x.%x)"
+ % (bus, slot, func))
+ log.debug("pci: deassign device %x:%x.%x" % (bus, slot, func))
for (start, size) in dev.ioports:
log.debug('pci: disabling ioport 0x%x/0x%x'%(start,size))
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/xend/server/relocate.py
--- a/tools/python/xen/xend/server/relocate.py Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/xend/server/relocate.py Mon Jun 02 11:35:39 2008 +0900
@@ -142,16 +142,22 @@ def listenRelocation():
if xoptions.get_xend_unix_server():
path = '/var/lib/xend/relocation-socket'
unix.UnixListener(path, RelocationProtocol)
+
+ interface = xoptions.get_xend_relocation_address()
+
+ hosts_allow = xoptions.get_xend_relocation_hosts_allow()
+ if hosts_allow == '':
+ hosts_allow = None
+ else:
+ hosts_allow = map(re.compile, hosts_allow.split(" "))
+
if xoptions.get_xend_relocation_server():
port = xoptions.get_xend_relocation_port()
- interface = xoptions.get_xend_relocation_address()
+ tcp.TCPListener(RelocationProtocol, port, interface = interface,
+ hosts_allow = hosts_allow)
- hosts_allow = xoptions.get_xend_relocation_hosts_allow()
- if hosts_allow == '':
- hosts_allow = None
- else:
- hosts_allow = map(re.compile, hosts_allow.split(" "))
-
+ if xoptions.get_xend_relocation_ssl_server():
+ port = xoptions.get_xend_relocation_ssl_port()
ssl_key_file = xoptions.get_xend_relocation_server_ssl_key_file()
ssl_cert_file = xoptions.get_xend_relocation_server_ssl_cert_file()
@@ -161,5 +167,5 @@ def listenRelocation():
ssl_key_file = ssl_key_file,
ssl_cert_file = ssl_cert_file)
else:
- tcp.TCPListener(RelocationProtocol, port, interface = interface,
- hosts_allow = hosts_allow)
+ raise XendError("ssl_key_file or ssl_cert_file for ssl relocation
server is missing.")
+
diff -r d2a239224cb2 -r f1508348ffab tools/python/xen/xm/migrate.py
--- a/tools/python/xen/xm/migrate.py Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/python/xen/xm/migrate.py Mon Jun 02 11:35:39 2008 +0900
@@ -47,6 +47,10 @@ gopts.opt('node', short='n', val='nodenu
fn=set_int, default=-1,
use="Use specified NUMA node on target.")
+gopts.opt('ssl', short='s',
+ fn=set_true, default=None,
+ use="Use ssl connection for migration.")
+
def help():
return str(gopts)
@@ -65,11 +69,13 @@ def main(argv):
vm_ref = get_single_vm(dom)
other_config = {
"port": opts.vals.port,
- "node": opts.vals.node
+ "node": opts.vals.node,
+ "ssl": opts.vals.ssl
}
server.xenapi.VM.migrate(vm_ref, dst, bool(opts.vals.live),
other_config)
else:
server.xend.domain.migrate(dom, dst, opts.vals.live,
opts.vals.port,
- opts.vals.node)
+ opts.vals.node,
+ opts.vals.ssl)
diff -r d2a239224cb2 -r f1508348ffab tools/xenstat/libxenstat/src/xenstat.c
--- a/tools/xenstat/libxenstat/src/xenstat.c Mon Jun 02 11:35:02 2008 +0900
+++ b/tools/xenstat/libxenstat/src/xenstat.c Mon Jun 02 11:35:39 2008 +0900
@@ -655,12 +655,20 @@ unsigned long long xenstat_vbd_wr_reqs(x
static char *xenstat_get_domain_name(xenstat_handle *handle, unsigned int
domain_id)
{
- char path[80];
-
- snprintf(path, sizeof(path),"/local/domain/%i/name", domain_id);
-
+ char path[80], *vmpath;
+
+ snprintf(path, sizeof(path),"/local/domain/%i/vm", domain_id);
+
+ vmpath = xs_read(handle->xshandle, XBT_NULL, path, NULL);
+
+ if (vmpath == NULL)
+ return NULL;
+
+ snprintf(path, sizeof(path),"%s/name", vmpath);
+ free(vmpath);
+
return xs_read(handle->xshandle, XBT_NULL, path, NULL);
-}
+}
/* Remove specified entry from list of domains */
static void xenstat_prune_domain(xenstat_node *node, unsigned int entry)
diff -r d2a239224cb2 -r f1508348ffab
unmodified_drivers/linux-2.6/platform-pci/evtchn.c
--- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Mon Jun 02
11:35:02 2008 +0900
+++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c Mon Jun 02
11:35:39 2008 +0900
@@ -284,7 +284,7 @@ static irqreturn_t evtchn_interrupt(int
#ifndef CONFIG_X86 /* No need for a barrier -- XCHG is a barrier on x86. */
/* Clear master flag /before/ clearing selector flag. */
- rmb();
+ wmb();
#endif
l1 = xchg(&v->evtchn_pending_sel, 0);
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/acpi/cpu_idle.c
--- a/xen/arch/x86/acpi/cpu_idle.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/acpi/cpu_idle.c Mon Jun 02 11:35:39 2008 +0900
@@ -173,6 +173,8 @@ static inline u32 ticks_elapsed(u32 t1,
{
if ( t2 >= t1 )
return (t2 - t1);
+ else if ( !(acpi_gbl_FADT.flags & ACPI_FADT_32BIT_TIMER) )
+ return (((0x00FFFFFF - t1) + t2) & 0x00FFFFFF);
else
return ((0xFFFFFFFF - t1) + t2);
}
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/acpi/power.c
--- a/xen/arch/x86/acpi/power.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/acpi/power.c Mon Jun 02 11:35:39 2008 +0900
@@ -238,9 +238,17 @@ static void tboot_sleep(u8 sleep_state)
static void tboot_sleep(u8 sleep_state)
{
uint32_t shutdown_type;
-
- *((struct acpi_sleep_info *)(unsigned long)g_tboot_shared->acpi_sinfo) =
- acpi_sinfo;
+
+ g_tboot_shared->acpi_sinfo.pm1a_cnt =
+ (uint16_t)acpi_sinfo.pm1a_cnt_blk.address;
+ g_tboot_shared->acpi_sinfo.pm1b_cnt =
+ (uint16_t)acpi_sinfo.pm1b_cnt_blk.address;
+ g_tboot_shared->acpi_sinfo.pm1a_evt =
+ (uint16_t)acpi_sinfo.pm1a_evt_blk.address;
+ g_tboot_shared->acpi_sinfo.pm1b_evt =
+ (uint16_t)acpi_sinfo.pm1b_evt_blk.address;
+ g_tboot_shared->acpi_sinfo.pm1a_cnt_val = acpi_sinfo.pm1a_cnt_val;
+ g_tboot_shared->acpi_sinfo.pm1b_cnt_val = acpi_sinfo.pm1b_cnt_val;
switch ( sleep_state )
{
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/cpu/amd.c
--- a/xen/arch/x86/cpu/amd.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/cpu/amd.c Mon Jun 02 11:35:39 2008 +0900
@@ -74,9 +74,11 @@ static void disable_c1_ramping(void)
static void disable_c1_ramping(void)
{
u8 pmm7;
- int node;
-
- for (node=0; node < NR_CPUS; node++) {
+ int node, nr_nodes;
+
+ /* Read the number of nodes from the first Northbridge. */
+ nr_nodes = ((pci_conf_read32(0, 0x18, 0x0, 0x60)>>4)&0x07)+1;
+ for (node = 0; node < nr_nodes; node++) {
/* PMM7: bus=0, dev=0x18+node, function=0x3, register=0x87. */
pmm7 = pci_conf_read8(0, 0x18+node, 0x3, 0x87);
/* Invalid read means we've updated every Northbridge. */
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/crash.c
--- a/xen/arch/x86/crash.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/crash.c Mon Jun 02 11:35:39 2008 +0900
@@ -102,6 +102,7 @@ void machine_crash_shutdown(void)
hvm_cpu_down();
info = kexec_crash_save_info();
+ info->xen_phys_start = xen_phys_start;
info->dom0_pfn_to_mfn_frame_list_list =
arch_get_pfn_to_mfn_frame_list_list(dom0);
}
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/domain.c Mon Jun 02 11:35:39 2008 +0900
@@ -59,8 +59,6 @@ static void default_idle(void);
static void default_idle(void);
void (*pm_idle) (void) = default_idle;
-static void unmap_vcpu_info(struct vcpu *v);
-
static void paravirt_ctxt_switch_from(struct vcpu *v);
static void paravirt_ctxt_switch_to(struct vcpu *v);
@@ -432,8 +430,6 @@ void vcpu_destroy(struct vcpu *v)
{
if ( is_pv_32on64_vcpu(v) )
release_compat_l4(v);
-
- unmap_vcpu_info(v);
if ( is_hvm_vcpu(v) )
hvm_vcpu_destroy(v);
@@ -825,8 +821,15 @@ int arch_set_info_guest(
void arch_vcpu_reset(struct vcpu *v)
{
- destroy_gdt(v);
- vcpu_destroy_pagetables(v);
+ if ( !is_hvm_vcpu(v) )
+ {
+ destroy_gdt(v);
+ vcpu_destroy_pagetables(v);
+ }
+ else
+ {
+ vcpu_end_shutdown_deferral(v);
+ }
}
/*
@@ -1857,16 +1860,19 @@ int domain_relinquish_resources(struct d
/* Tear down paging-assistance stuff. */
paging_teardown(d);
- /* Drop the in-use references to page-table bases. */
for_each_vcpu ( d, v )
+ {
+ /* Drop the in-use references to page-table bases. */
vcpu_destroy_pagetables(v);
- /*
- * Relinquish GDT mappings. No need for explicit unmapping of the LDT
- * as it automatically gets squashed when the guest's mappings go away.
- */
- for_each_vcpu(d, v)
+ /*
+ * Relinquish GDT mappings. No need for explicit unmapping of the
+ * LDT as it automatically gets squashed with the guest mappings.
+ */
destroy_gdt(v);
+
+ unmap_vcpu_info(v);
+ }
d->arch.relmem = RELMEM_xen_l4;
/* fallthrough */
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/domctl.c
--- a/xen/arch/x86/domctl.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/domctl.c Mon Jun 02 11:35:39 2008 +0900
@@ -526,14 +526,54 @@ long arch_do_domctl(
}
break;
+ case XEN_DOMCTL_get_device_group:
+ {
+ struct domain *d;
+ u32 max_sdevs;
+ u8 bus, devfn;
+ XEN_GUEST_HANDLE_64(uint32) sdevs;
+ int num_sdevs;
+
+ ret = -ENOSYS;
+ if ( !iommu_enabled )
+ break;
+
+ ret = -EINVAL;
+ if ( (d = rcu_lock_domain_by_id(domctl->domain)) == NULL )
+ break;
+
+ bus = (domctl->u.get_device_group.machine_bdf >> 16) & 0xff;
+ devfn = (domctl->u.get_device_group.machine_bdf >> 8) & 0xff;
+ max_sdevs = domctl->u.get_device_group.max_sdevs;
+ sdevs = domctl->u.get_device_group.sdev_array;
+
+ num_sdevs = iommu_get_device_group(d, bus, devfn, sdevs, max_sdevs);
+ if ( num_sdevs < 0 )
+ {
+ dprintk(XENLOG_ERR, "iommu_get_device_group() failed!\n");
+ ret = -EFAULT;
+ domctl->u.get_device_group.num_sdevs = 0;
+ }
+ else
+ {
+ ret = 0;
+ domctl->u.get_device_group.num_sdevs = num_sdevs;
+ }
+ if ( copy_to_guest(u_domctl, domctl, 1) )
+ ret = -EFAULT;
+ rcu_unlock_domain(d);
+ }
+ break;
+
case XEN_DOMCTL_test_assign_device:
{
u8 bus, devfn;
- ret = -EINVAL;
+ ret = -ENOSYS;
if ( !iommu_enabled )
break;
+ ret = -EINVAL;
bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
@@ -553,10 +593,11 @@ long arch_do_domctl(
struct domain *d;
u8 bus, devfn;
- ret = -EINVAL;
+ ret = -ENOSYS;
if ( !iommu_enabled )
break;
+ ret = -EINVAL;
if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) )
{
gdprintk(XENLOG_ERR,
@@ -565,6 +606,12 @@ long arch_do_domctl(
}
bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
+
+ if ( !iommu_pv_enabled && !is_hvm_domain(d) )
+ {
+ ret = -ENOSYS;
+ break;
+ }
if ( device_assigned(bus, devfn) )
{
@@ -576,7 +623,7 @@ long arch_do_domctl(
ret = assign_device(d, bus, devfn);
gdprintk(XENLOG_INFO, "XEN_DOMCTL_assign_device: bdf = %x:%x:%x\n",
- bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
+ bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
put_domain(d);
}
break;
@@ -586,10 +633,11 @@ long arch_do_domctl(
struct domain *d;
u8 bus, devfn;
- ret = -EINVAL;
+ ret = -ENOSYS;
if ( !iommu_enabled )
break;
+ ret = -EINVAL;
if ( unlikely((d = get_domain_by_id(domctl->domain)) == NULL) )
{
gdprintk(XENLOG_ERR,
@@ -599,9 +647,16 @@ long arch_do_domctl(
bus = (domctl->u.assign_device.machine_bdf >> 16) & 0xff;
devfn = (domctl->u.assign_device.machine_bdf >> 8) & 0xff;
+ if ( !iommu_pv_enabled && !is_hvm_domain(d) )
+ {
+ ret = -ENOSYS;
+ break;
+ }
+
if ( !device_assigned(bus, devfn) )
break;
+ ret = 0;
deassign_device(d, bus, devfn);
gdprintk(XENLOG_INFO, "XEN_DOMCTL_deassign_device: bdf = %x:%x:%x\n",
bus, PCI_SLOT(devfn), PCI_FUNC(devfn));
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/hvm/hpet.c
--- a/xen/arch/x86/hvm/hpet.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/hvm/hpet.c Mon Jun 02 11:35:39 2008 +0900
@@ -29,9 +29,9 @@
#define S_TO_NS 1000000000ULL /* 1s = 10^9 ns */
#define S_TO_FS 1000000000000000ULL /* 1s = 10^15 fs */
-/* Frequency_of_TSC / frequency_of_HPET = 32 */
-#define TSC_PER_HPET_TICK 32
-#define guest_time_hpet(v) (hvm_get_guest_time(v) / TSC_PER_HPET_TICK)
+/* Frequency_of_Xen_systeme_time / frequency_of_HPET = 16 */
+#define STIME_PER_HPET_TICK 16
+#define guest_time_hpet(v) (hvm_get_guest_time(v) / STIME_PER_HPET_TICK)
#define HPET_ID 0x000
#define HPET_PERIOD 0x004
@@ -192,7 +192,7 @@ static void hpet_stop_timer(HPETState *h
/* the number of HPET tick that stands for
* 1/(2^10) second, namely, 0.9765625 milliseconds */
-#define HPET_TINY_TIME_SPAN ((h->tsc_freq >> 10) / TSC_PER_HPET_TICK)
+#define HPET_TINY_TIME_SPAN ((h->stime_freq >> 10) / STIME_PER_HPET_TICK)
static void hpet_set_timer(HPETState *h, unsigned int tn)
{
@@ -558,17 +558,17 @@ void hpet_init(struct vcpu *v)
spin_lock_init(&h->lock);
h->vcpu = v;
- h->tsc_freq = ticks_per_sec(v);
-
- h->hpet_to_ns_scale = ((S_TO_NS * TSC_PER_HPET_TICK) << 10) / h->tsc_freq;
+ h->stime_freq = S_TO_NS;
+
+ h->hpet_to_ns_scale = ((S_TO_NS * STIME_PER_HPET_TICK) << 10) /
h->stime_freq;
h->hpet_to_ns_limit = ~0ULL / h->hpet_to_ns_scale;
/* 64-bit main counter; 3 timers supported; LegacyReplacementRoute. */
h->hpet.capability = 0x8086A201ULL;
/* This is the number of femptoseconds per HPET tick. */
- /* Here we define HPET's frequency to be 1/32 of the TSC's */
- h->hpet.capability |= ((S_TO_FS*TSC_PER_HPET_TICK/h->tsc_freq) << 32);
+ /* Here we define HPET's frequency to be 1/16 of Xen system time */
+ h->hpet.capability |= ((S_TO_FS*STIME_PER_HPET_TICK/h->stime_freq) << 32);
for ( i = 0; i < HPET_TIMER_NUM; i++ )
{
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/hvm/hvm.c Mon Jun 02 11:35:39 2008 +0900
@@ -296,6 +296,8 @@ int hvm_domain_initialise(struct domain
spin_lock_init(&d->arch.hvm_domain.irq_lock);
spin_lock_init(&d->arch.hvm_domain.uc_lock);
+ hvm_init_guest_time(d);
+
d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1;
hvm_init_cacheattr_region_list(d);
@@ -661,7 +663,7 @@ int hvm_vcpu_initialise(struct vcpu *v)
hpet_init(v);
/* Init guest TSC to start from zero. */
- hvm_set_guest_time(v, 0);
+ hvm_set_guest_tsc(v, 0);
/* Can start up without SIPI-SIPI or setvcpucontext domctl. */
v->is_initialised = 1;
@@ -1098,16 +1100,17 @@ int hvm_virtual_to_linear_addr(
return 0;
}
-static void *hvm_map(unsigned long va, int size)
+static void *hvm_map_entry(unsigned long va)
{
unsigned long gfn, mfn;
p2m_type_t p2mt;
uint32_t pfec;
- if ( ((va & ~PAGE_MASK) + size) > PAGE_SIZE )
- {
- hvm_inject_exception(TRAP_page_fault, PFEC_write_access,
- (va + PAGE_SIZE - 1) & PAGE_MASK);
+ if ( ((va & ~PAGE_MASK) + 8) > PAGE_SIZE )
+ {
+ gdprintk(XENLOG_ERR, "Descriptor table entry "
+ "straddles page boundary\n");
+ domain_crash(current->domain);
return NULL;
}
@@ -1119,7 +1122,8 @@ static void *hvm_map(unsigned long va, i
mfn = mfn_x(gfn_to_mfn_current(gfn, &p2mt));
if ( !p2m_is_ram(p2mt) )
{
- hvm_inject_exception(TRAP_page_fault, pfec, va);
+ gdprintk(XENLOG_ERR, "Failed to look up descriptor table entry\n");
+ domain_crash(current->domain);
return NULL;
}
@@ -1130,7 +1134,7 @@ static void *hvm_map(unsigned long va, i
return (char *)map_domain_page(mfn) + (va & ~PAGE_MASK);
}
-static void hvm_unmap(void *p)
+static void hvm_unmap_entry(void *p)
{
if ( p )
unmap_domain_page(p);
@@ -1166,7 +1170,7 @@ static int hvm_load_segment_selector(
if ( ((sel & 0xfff8) + 7) > desctab.limit )
goto fail;
- pdesc = hvm_map(desctab.base + (sel & 0xfff8), 8);
+ pdesc = hvm_map_entry(desctab.base + (sel & 0xfff8));
if ( pdesc == NULL )
goto hvm_map_fail;
@@ -1226,7 +1230,7 @@ static int hvm_load_segment_selector(
desc.b |= 0x100;
skip_accessed_flag:
- hvm_unmap(pdesc);
+ hvm_unmap_entry(pdesc);
segr.base = (((desc.b << 0) & 0xff000000u) |
((desc.b << 16) & 0x00ff0000u) |
@@ -1242,7 +1246,7 @@ static int hvm_load_segment_selector(
return 0;
unmap_and_fail:
- hvm_unmap(pdesc);
+ hvm_unmap_entry(pdesc);
fail:
hvm_inject_exception(fault_type, sel & 0xfffc, 0);
hvm_map_fail:
@@ -1258,7 +1262,7 @@ void hvm_task_switch(
struct segment_register gdt, tr, prev_tr, segr;
struct desc_struct *optss_desc = NULL, *nptss_desc = NULL, tss_desc;
unsigned long eflags;
- int exn_raised;
+ int exn_raised, rc;
struct {
u16 back_link,__blh;
u32 esp0;
@@ -1270,7 +1274,7 @@ void hvm_task_switch(
u32 cr3, eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi;
u16 es, _3, cs, _4, ss, _5, ds, _6, fs, _7, gs, _8, ldt, _9;
u16 trace, iomap;
- } *ptss, tss;
+ } tss = { 0 };
hvm_get_segment_register(v, x86_seg_gdtr, &gdt);
hvm_get_segment_register(v, x86_seg_tr, &prev_tr);
@@ -1283,11 +1287,11 @@ void hvm_task_switch(
goto out;
}
- optss_desc = hvm_map(gdt.base + (prev_tr.sel & 0xfff8), 8);
+ optss_desc = hvm_map_entry(gdt.base + (prev_tr.sel & 0xfff8));
if ( optss_desc == NULL )
goto out;
- nptss_desc = hvm_map(gdt.base + (tss_sel & 0xfff8), 8);
+ nptss_desc = hvm_map_entry(gdt.base + (tss_sel & 0xfff8));
if ( nptss_desc == NULL )
goto out;
@@ -1322,84 +1326,89 @@ void hvm_task_switch(
goto out;
}
- ptss = hvm_map(prev_tr.base, sizeof(tss));
- if ( ptss == NULL )
+ rc = hvm_copy_from_guest_virt(
+ &tss, prev_tr.base, sizeof(tss), PFEC_page_present);
+ if ( rc == HVMCOPY_bad_gva_to_gfn )
goto out;
eflags = regs->eflags;
if ( taskswitch_reason == TSW_iret )
eflags &= ~X86_EFLAGS_NT;
- ptss->cr3 = v->arch.hvm_vcpu.guest_cr[3];
- ptss->eip = regs->eip;
- ptss->eflags = eflags;
- ptss->eax = regs->eax;
- ptss->ecx = regs->ecx;
- ptss->edx = regs->edx;
- ptss->ebx = regs->ebx;
- ptss->esp = regs->esp;
- ptss->ebp = regs->ebp;
- ptss->esi = regs->esi;
- ptss->edi = regs->edi;
+ tss.cr3 = v->arch.hvm_vcpu.guest_cr[3];
+ tss.eip = regs->eip;
+ tss.eflags = eflags;
+ tss.eax = regs->eax;
+ tss.ecx = regs->ecx;
+ tss.edx = regs->edx;
+ tss.ebx = regs->ebx;
+ tss.esp = regs->esp;
+ tss.ebp = regs->ebp;
+ tss.esi = regs->esi;
+ tss.edi = regs->edi;
hvm_get_segment_register(v, x86_seg_es, &segr);
- ptss->es = segr.sel;
+ tss.es = segr.sel;
hvm_get_segment_register(v, x86_seg_cs, &segr);
- ptss->cs = segr.sel;
+ tss.cs = segr.sel;
hvm_get_segment_register(v, x86_seg_ss, &segr);
- ptss->ss = segr.sel;
+ tss.ss = segr.sel;
hvm_get_segment_register(v, x86_seg_ds, &segr);
- ptss->ds = segr.sel;
+ tss.ds = segr.sel;
hvm_get_segment_register(v, x86_seg_fs, &segr);
- ptss->fs = segr.sel;
+ tss.fs = segr.sel;
hvm_get_segment_register(v, x86_seg_gs, &segr);
- ptss->gs = segr.sel;
+ tss.gs = segr.sel;
hvm_get_segment_register(v, x86_seg_ldtr, &segr);
- ptss->ldt = segr.sel;
-
- hvm_unmap(ptss);
-
- ptss = hvm_map(tr.base, sizeof(tss));
- if ( ptss == NULL )
+ tss.ldt = segr.sel;
+
+ rc = hvm_copy_to_guest_virt(
+ prev_tr.base, &tss, sizeof(tss), PFEC_page_present);
+ if ( rc == HVMCOPY_bad_gva_to_gfn )
goto out;
- if ( hvm_set_cr3(ptss->cr3) )
- {
- hvm_unmap(ptss);
+ rc = hvm_copy_from_guest_virt(
+ &tss, tr.base, sizeof(tss), PFEC_page_present);
+ if ( rc == HVMCOPY_bad_gva_to_gfn )
goto out;
- }
-
- regs->eip = ptss->eip;
- regs->eflags = ptss->eflags | 2;
- regs->eax = ptss->eax;
- regs->ecx = ptss->ecx;
- regs->edx = ptss->edx;
- regs->ebx = ptss->ebx;
- regs->esp = ptss->esp;
- regs->ebp = ptss->ebp;
- regs->esi = ptss->esi;
- regs->edi = ptss->edi;
+
+ if ( hvm_set_cr3(tss.cr3) )
+ goto out;
+
+ regs->eip = tss.eip;
+ regs->eflags = tss.eflags | 2;
+ regs->eax = tss.eax;
+ regs->ecx = tss.ecx;
+ regs->edx = tss.edx;
+ regs->ebx = tss.ebx;
+ regs->esp = tss.esp;
+ regs->ebp = tss.ebp;
+ regs->esi = tss.esi;
+ regs->edi = tss.edi;
if ( (taskswitch_reason == TSW_call_or_int) )
{
regs->eflags |= X86_EFLAGS_NT;
- ptss->back_link = prev_tr.sel;
+ tss.back_link = prev_tr.sel;
}
exn_raised = 0;
- if ( hvm_load_segment_selector(v, x86_seg_es, ptss->es) ||
- hvm_load_segment_selector(v, x86_seg_cs, ptss->cs) ||
- hvm_load_segment_selector(v, x86_seg_ss, ptss->ss) ||
- hvm_load_segment_selector(v, x86_seg_ds, ptss->ds) ||
- hvm_load_segment_selector(v, x86_seg_fs, ptss->fs) ||
- hvm_load_segment_selector(v, x86_seg_gs, ptss->gs) ||
- hvm_load_segment_selector(v, x86_seg_ldtr, ptss->ldt) )
+ if ( hvm_load_segment_selector(v, x86_seg_es, tss.es) ||
+ hvm_load_segment_selector(v, x86_seg_cs, tss.cs) ||
+ hvm_load_segment_selector(v, x86_seg_ss, tss.ss) ||
+ hvm_load_segment_selector(v, x86_seg_ds, tss.ds) ||
+ hvm_load_segment_selector(v, x86_seg_fs, tss.fs) ||
+ hvm_load_segment_selector(v, x86_seg_gs, tss.gs) ||
+ hvm_load_segment_selector(v, x86_seg_ldtr, tss.ldt) )
exn_raised = 1;
- if ( (ptss->trace & 1) && !exn_raised )
+ rc = hvm_copy_to_guest_virt(
+ tr.base, &tss, sizeof(tss), PFEC_page_present);
+ if ( rc == HVMCOPY_bad_gva_to_gfn )
+ exn_raised = 1;
+
+ if ( (tss.trace & 1) && !exn_raised )
hvm_inject_exception(TRAP_debug, tss_sel & 0xfff8, 0);
-
- hvm_unmap(ptss);
tr.attr.fields.type = 0xb; /* busy 32-bit tss */
hvm_set_segment_register(v, x86_seg_tr, &tr);
@@ -1428,8 +1437,8 @@ void hvm_task_switch(
}
out:
- hvm_unmap(optss_desc);
- hvm_unmap(nptss_desc);
+ hvm_unmap_entry(optss_desc);
+ hvm_unmap_entry(nptss_desc);
}
#define HVMCOPY_from_guest (0u<<0)
@@ -1632,7 +1641,7 @@ int hvm_msr_read_intercept(struct cpu_us
switch ( ecx )
{
case MSR_IA32_TSC:
- msr_content = hvm_get_guest_time(v);
+ msr_content = hvm_get_guest_tsc(v);
break;
case MSR_IA32_APICBASE:
@@ -1725,7 +1734,7 @@ int hvm_msr_write_intercept(struct cpu_u
switch ( ecx )
{
case MSR_IA32_TSC:
- hvm_set_guest_time(v, msr_content);
+ hvm_set_guest_tsc(v, msr_content);
pt_reset(v);
break;
@@ -2071,6 +2080,13 @@ void hvm_vcpu_reset_state(struct vcpu *v
if ( v->is_initialised )
goto out;
+ if ( !paging_mode_hap(d) )
+ {
+ if ( v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PG )
+ put_page(pagetable_get_page(v->arch.guest_table));
+ v->arch.guest_table = pagetable_null();
+ }
+
ctxt = &v->arch.guest_context;
memset(ctxt, 0, sizeof(*ctxt));
ctxt->flags = VGCF_online;
@@ -2122,6 +2138,8 @@ void hvm_vcpu_reset_state(struct vcpu *v
v->arch.hvm_vcpu.cache_tsc_offset =
v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
hvm_funcs.set_tsc_offset(v, v->arch.hvm_vcpu.cache_tsc_offset);
+
+ paging_update_paging_modes(v);
v->arch.flags |= TF_kernel_mode;
v->is_initialised = 1;
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/hvm/i8254.c
--- a/xen/arch/x86/hvm/i8254.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/hvm/i8254.c Mon Jun 02 11:35:39 2008 +0900
@@ -31,6 +31,7 @@
#include <xen/lib.h>
#include <xen/errno.h>
#include <xen/sched.h>
+#include <asm/time.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/io.h>
#include <asm/hvm/support.h>
@@ -52,6 +53,9 @@ static int handle_pit_io(
int dir, uint32_t port, uint32_t bytes, uint32_t *val);
static int handle_speaker_io(
int dir, uint32_t port, uint32_t bytes, uint32_t *val);
+
+#define get_guest_time(v) \
+ (is_hvm_vcpu(v) ? hvm_get_guest_time(v) : (u64)get_s_time())
/* Compute with 96 bit intermediate result: (a*b)/c */
static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
@@ -86,8 +90,8 @@ static int pit_get_count(PITState *pit,
ASSERT(spin_is_locked(&pit->lock));
- d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel],
- PIT_FREQ, ticks_per_sec(v));
+ d = muldiv64(get_guest_time(v) - pit->count_load_time[channel],
+ PIT_FREQ, SYSTEM_TIME_HZ);
switch ( c->mode )
{
@@ -117,8 +121,8 @@ static int pit_get_out(PITState *pit, in
ASSERT(spin_is_locked(&pit->lock));
- d = muldiv64(hvm_get_guest_time(v) - pit->count_load_time[channel],
- PIT_FREQ, ticks_per_sec(v));
+ d = muldiv64(get_guest_time(v) - pit->count_load_time[channel],
+ PIT_FREQ, SYSTEM_TIME_HZ);
switch ( s->mode )
{
@@ -164,7 +168,7 @@ static void pit_set_gate(PITState *pit,
case 3:
/* Restart counting on rising edge. */
if ( s->gate < val )
- pit->count_load_time[channel] = hvm_get_guest_time(v);
+ pit->count_load_time[channel] = get_guest_time(v);
break;
}
@@ -180,7 +184,7 @@ static void pit_time_fired(struct vcpu *
static void pit_time_fired(struct vcpu *v, void *priv)
{
uint64_t *count_load_time = priv;
- *count_load_time = hvm_get_guest_time(v);
+ *count_load_time = get_guest_time(v);
}
static void pit_load_count(PITState *pit, int channel, int val)
@@ -195,11 +199,11 @@ static void pit_load_count(PITState *pit
val = 0x10000;
if ( v == NULL )
- rdtscll(pit->count_load_time[channel]);
- else
- pit->count_load_time[channel] = hvm_get_guest_time(v);
+ pit->count_load_time[channel] = 0;
+ else
+ pit->count_load_time[channel] = get_guest_time(v);
s->count = val;
- period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ);
+ period = DIV_ROUND(val * SYSTEM_TIME_HZ, PIT_FREQ);
if ( (v == NULL) || !is_hvm_vcpu(v) || (channel != 0) )
return;
@@ -435,7 +439,7 @@ static int pit_load(struct domain *d, hv
* time jitter here, but the wall-clock will have jumped massively, so
* we hope the guest can handle it.
*/
- pit->pt0.last_plt_gtime = hvm_get_guest_time(d->vcpu[0]);
+ pit->pt0.last_plt_gtime = get_guest_time(d->vcpu[0]);
for ( i = 0; i < 3; i++ )
pit_load_count(pit, i, pit->hw.channels[i].count);
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/hvm/pmtimer.c
--- a/xen/arch/x86/hvm/pmtimer.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/hvm/pmtimer.c Mon Jun 02 11:35:39 2008 +0900
@@ -257,7 +257,7 @@ void pmtimer_init(struct vcpu *v)
spin_lock_init(&s->lock);
- s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / ticks_per_sec(v);
+ s->scale = ((uint64_t)FREQUENCE_PMTIMER << 32) / SYSTEM_TIME_HZ;
s->vcpu = v;
/* Intercept port I/O (need two handlers because PM1a_CNT is between
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/hvm/svm/svm.c Mon Jun 02 11:35:39 2008 +0900
@@ -299,7 +299,7 @@ static void svm_save_cpu_state(struct vc
data->msr_efer = v->arch.hvm_vcpu.guest_efer;
data->msr_flags = -1ULL;
- data->tsc = hvm_get_guest_time(v);
+ data->tsc = hvm_get_guest_tsc(v);
}
@@ -315,7 +315,7 @@ static void svm_load_cpu_state(struct vc
v->arch.hvm_vcpu.guest_efer = data->msr_efer;
svm_update_guest_efer(v);
- hvm_set_guest_time(v, data->tsc);
+ hvm_set_guest_tsc(v, data->tsc);
}
static void svm_save_vmcb_ctxt(struct vcpu *v, struct hvm_hw_cpu *ctxt)
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/hvm/vlapic.c Mon Jun 02 11:35:39 2008 +0900
@@ -22,18 +22,19 @@
#include <xen/types.h>
#include <xen/mm.h>
#include <xen/xmalloc.h>
+#include <xen/domain.h>
#include <xen/domain_page.h>
-#include <asm/page.h>
#include <xen/event.h>
#include <xen/trace.h>
+#include <xen/lib.h>
+#include <xen/sched.h>
+#include <xen/numa.h>
+#include <asm/current.h>
+#include <asm/page.h>
#include <asm/hvm/hvm.h>
#include <asm/hvm/io.h>
#include <asm/hvm/support.h>
-#include <xen/lib.h>
-#include <xen/sched.h>
-#include <asm/current.h>
#include <asm/hvm/vmx/vmx.h>
-#include <xen/numa.h>
#include <public/hvm/ioreq.h>
#include <public/hvm/params.h>
@@ -259,6 +260,7 @@ static void vlapic_init_action(unsigned
{
struct vcpu *v = (struct vcpu *)_vcpu;
struct domain *d = v->domain;
+ bool_t fpu_initialised;
/* If the VCPU is not on its way down we have nothing to do. */
if ( !test_bit(_VPF_down, &v->pause_flags) )
@@ -270,15 +272,12 @@ static void vlapic_init_action(unsigned
return;
}
+ /* Reset necessary VCPU state. This does not include FPU state. */
domain_lock(d);
-
- /* Paranoia makes us re-assert VPF_down under the domain lock. */
- set_bit(_VPF_down, &v->pause_flags);
- v->is_initialised = 0;
- clear_bit(_VPF_blocked, &v->pause_flags);
-
+ fpu_initialised = v->fpu_initialised;
+ vcpu_reset(v);
+ v->fpu_initialised = fpu_initialised;
vlapic_reset(vcpu_vlapic(v));
-
domain_unlock(d);
vcpu_unpause(v);
@@ -474,7 +473,6 @@ static uint32_t vlapic_get_tmcct(struct
uint64_t counter_passed;
counter_passed = ((hvm_get_guest_time(v) - vlapic->timer_last_update)
- * 1000000000ULL / ticks_per_sec(v)
/ APIC_BUS_CYCLE_NS / vlapic->hw.timer_divisor);
tmcct = tmict - counter_passed;
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Jun 02 11:35:39 2008 +0900
@@ -607,7 +607,7 @@ static void vmx_save_cpu_state(struct vc
data->msr_syscall_mask = guest_state->msrs[VMX_INDEX_MSR_SYSCALL_MASK];
#endif
- data->tsc = hvm_get_guest_time(v);
+ data->tsc = hvm_get_guest_tsc(v);
}
static void vmx_load_cpu_state(struct vcpu *v, struct hvm_hw_cpu *data)
@@ -625,7 +625,7 @@ static void vmx_load_cpu_state(struct vc
v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
#endif
- hvm_set_guest_time(v, data->tsc);
+ hvm_set_guest_tsc(v, data->tsc);
}
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/hvm/vpt.c
--- a/xen/arch/x86/hvm/vpt.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/hvm/vpt.c Mon Jun 02 11:35:39 2008 +0900
@@ -25,6 +25,39 @@
#define mode_is(d, name) \
((d)->arch.hvm_domain.params[HVM_PARAM_TIMER_MODE] == HVMPTM_##name)
+void hvm_init_guest_time(struct domain *d)
+{
+ struct pl_time *pl = &d->arch.hvm_domain.pl_time;
+
+ spin_lock_init(&pl->pl_time_lock);
+ pl->stime_offset = -(u64)get_s_time();
+ pl->last_guest_time = 0;
+}
+
+u64 hvm_get_guest_time(struct vcpu *v)
+{
+ struct pl_time *pl = &v->domain->arch.hvm_domain.pl_time;
+ u64 now;
+
+ /* Called from device models shared with PV guests. Be careful. */
+ ASSERT(is_hvm_vcpu(v));
+
+ spin_lock(&pl->pl_time_lock);
+ now = get_s_time() + pl->stime_offset;
+ if ( (int64_t)(now - pl->last_guest_time) >= 0 )
+ pl->last_guest_time = now;
+ else
+ now = pl->last_guest_time;
+ spin_unlock(&pl->pl_time_lock);
+
+ return now + v->arch.hvm_vcpu.stime_offset;
+}
+
+void hvm_set_guest_time(struct vcpu *v, u64 guest_time)
+{
+ v->arch.hvm_vcpu.stime_offset += guest_time - hvm_get_guest_time(v);
+}
+
static int pt_irq_vector(struct periodic_time *pt, enum hvm_intsrc src)
{
struct vcpu *v = pt->vcpu;
@@ -348,7 +381,7 @@ void create_periodic_time(
pt->vcpu = v;
pt->last_plt_gtime = hvm_get_guest_time(pt->vcpu);
pt->irq = irq;
- pt->period_cycles = (u64)period * cpu_khz / 1000000L;
+ pt->period_cycles = (u64)period;
pt->one_shot = one_shot;
pt->scheduled = NOW() + period;
/*
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/mm.c Mon Jun 02 11:35:39 2008 +0900
@@ -1939,6 +1939,20 @@ int get_page_type(struct page_info *page
}
while ( unlikely((y = cmpxchg(&page->u.inuse.type_info, x, nx)) != x) );
+ if ( unlikely((x & PGT_type_mask) != type) )
+ {
+ /* Special pages should not be accessible from devices. */
+ struct domain *d = page_get_owner(page);
+ if ( d && unlikely(need_iommu(d)) )
+ {
+ if ( (x & PGT_type_mask) == PGT_writable_page )
+ iommu_unmap_page(d, mfn_to_gmfn(d, page_to_mfn(page)));
+ else if ( type == PGT_writable_page )
+ iommu_map_page(d, mfn_to_gmfn(d, page_to_mfn(page)),
+ page_to_mfn(page));
+ }
+ }
+
if ( unlikely(!(nx & PGT_validated)) )
{
/* Try to validate page type; drop the new reference on failure. */
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/mm/hap/p2m-ept.c
--- a/xen/arch/x86/mm/hap/p2m-ept.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/mm/hap/p2m-ept.c Mon Jun 02 11:35:39 2008 +0900
@@ -266,12 +266,6 @@ out:
iommu_unmap_page(d, gfn);
}
}
-
-#ifdef P2M_SHARE_WITH_VTD_PAGE_TABLE
- /* If p2m table is shared with vtd page-table. */
- if ( iommu_enabled && is_hvm_domain(d) && (p2mt == p2m_mmio_direct) )
- iommu_flush(d, gfn, (u64*)ept_entry);
-#endif
return rv;
}
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/mm/p2m.c
--- a/xen/arch/x86/mm/p2m.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/mm/p2m.c Mon Jun 02 11:35:39 2008 +0900
@@ -325,7 +325,7 @@ p2m_set_entry(struct domain *d, unsigned
if ( mfn_valid(mfn) && (gfn > d->arch.p2m->max_mapped_pfn) )
d->arch.p2m->max_mapped_pfn = gfn;
- if ( iommu_enabled && is_hvm_domain(d) )
+ if ( iommu_enabled && (is_hvm_domain(d) || need_iommu(d)) )
{
if ( p2mt == p2m_ram_rw )
for ( i = 0; i < (1UL << page_order); i++ )
@@ -868,7 +868,12 @@ p2m_remove_page(struct domain *d, unsign
unsigned long i;
if ( !paging_mode_translate(d) )
+ {
+ if ( need_iommu(d) )
+ for ( i = 0; i < (1 << page_order); i++ )
+ iommu_unmap_page(d, mfn + i);
return;
+ }
P2M_DEBUG("removing gfn=%#lx mfn=%#lx\n", gfn, mfn);
@@ -899,7 +904,19 @@ guest_physmap_add_entry(struct domain *d
int rc = 0;
if ( !paging_mode_translate(d) )
- return -EINVAL;
+ {
+ if ( need_iommu(d) && t == p2m_ram_rw )
+ {
+ for ( i = 0; i < (1 << page_order); i++ )
+ if ( (rc = iommu_map_page(d, mfn + i, mfn + i)) != 0 )
+ {
+ while ( i-- > 0 )
+ iommu_unmap_page(d, mfn + i);
+ return rc;
+ }
+ }
+ return 0;
+ }
#if CONFIG_PAGING_LEVELS == 3
/*
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/mm/shadow/common.c
--- a/xen/arch/x86/mm/shadow/common.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/mm/shadow/common.c Mon Jun 02 11:35:39 2008 +0900
@@ -2799,8 +2799,11 @@ int shadow_track_dirty_vram(struct domai
if ( !d->dirty_vram )
{
/* Just recount from start. */
- for ( i = begin_pfn; i < end_pfn; i++ )
- flush_tlb |= sh_remove_all_mappings(d->vcpu[0], gfn_to_mfn(d, i,
&t));
+ for ( i = begin_pfn; i < end_pfn; i++ ) {
+ mfn_t mfn = gfn_to_mfn(d, i, &t);
+ if (mfn_x(mfn) != INVALID_MFN)
+ flush_tlb |= sh_remove_all_mappings(d->vcpu[0], mfn);
+ }
gdprintk(XENLOG_INFO, "tracking VRAM %lx - %lx\n", begin_pfn, end_pfn);
@@ -2840,61 +2843,70 @@ int shadow_track_dirty_vram(struct domai
/* Iterate over VRAM to track dirty bits. */
for ( i = 0; i < nr; i++ ) {
mfn_t mfn = gfn_to_mfn(d, begin_pfn + i, &t);
- struct page_info *page = mfn_to_page(mfn);
- u32 count_info = page->u.inuse.type_info & PGT_count_mask;
+ struct page_info *page;
+ u32 count_info;
int dirty = 0;
paddr_t sl1ma = d->dirty_vram->sl1ma[i];
- switch (count_info)
+ if (mfn_x(mfn) == INVALID_MFN)
{
- case 0:
- /* No guest reference, nothing to track. */
- break;
- case 1:
- /* One guest reference. */
- if ( sl1ma == INVALID_PADDR )
+ dirty = 1;
+ }
+ else
+ {
+ page = mfn_to_page(mfn);
+ count_info = page->u.inuse.type_info & PGT_count_mask;
+ switch (count_info)
{
- /* We don't know which sl1e points to this, too bad. */
+ case 0:
+ /* No guest reference, nothing to track. */
+ break;
+ case 1:
+ /* One guest reference. */
+ if ( sl1ma == INVALID_PADDR )
+ {
+ /* We don't know which sl1e points to this, too bad. */
+ dirty = 1;
+ /* TODO: Heuristics for finding the single mapping of
+ * this gmfn */
+ flush_tlb |= sh_remove_all_mappings(d->vcpu[0], mfn);
+ }
+ else
+ {
+ /* Hopefully the most common case: only one mapping,
+ * whose dirty bit we can use. */
+ l1_pgentry_t *sl1e;
+#ifdef __i386__
+ void *sl1p = map_sl1p;
+ unsigned long sl1mfn = paddr_to_pfn(sl1ma);
+
+ if ( sl1mfn != map_mfn ) {
+ if ( map_sl1p )
+ sh_unmap_domain_page(map_sl1p);
+ map_sl1p = sl1p = sh_map_domain_page(_mfn(sl1mfn));
+ map_mfn = sl1mfn;
+ }
+ sl1e = sl1p + (sl1ma & ~PAGE_MASK);
+#else
+ sl1e = maddr_to_virt(sl1ma);
+#endif
+
+ if ( l1e_get_flags(*sl1e) & _PAGE_DIRTY )
+ {
+ dirty = 1;
+ /* Note: this is atomic, so we may clear a
+ * _PAGE_ACCESSED set by another processor. */
+ l1e_remove_flags(*sl1e, _PAGE_DIRTY);
+ flush_tlb = 1;
+ }
+ }
+ break;
+ default:
+ /* More than one guest reference,
+ * we don't afford tracking that. */
dirty = 1;
- /* TODO: Heuristics for finding the single mapping of
- * this gmfn */
- flush_tlb |= sh_remove_all_mappings(d->vcpu[0],
gfn_to_mfn(d, begin_pfn + i, &t));
+ break;
}
- else
- {
- /* Hopefully the most common case: only one mapping,
- * whose dirty bit we can use. */
- l1_pgentry_t *sl1e;
-#ifdef __i386__
- void *sl1p = map_sl1p;
- unsigned long sl1mfn = paddr_to_pfn(sl1ma);
-
- if ( sl1mfn != map_mfn ) {
- if ( map_sl1p )
- sh_unmap_domain_page(map_sl1p);
- map_sl1p = sl1p = sh_map_domain_page(_mfn(sl1mfn));
- map_mfn = sl1mfn;
- }
- sl1e = sl1p + (sl1ma & ~PAGE_MASK);
-#else
- sl1e = maddr_to_virt(sl1ma);
-#endif
-
- if ( l1e_get_flags(*sl1e) & _PAGE_DIRTY )
- {
- dirty = 1;
- /* Note: this is atomic, so we may clear a
- * _PAGE_ACCESSED set by another processor. */
- l1e_remove_flags(*sl1e, _PAGE_DIRTY);
- flush_tlb = 1;
- }
- }
- break;
- default:
- /* More than one guest reference,
- * we don't afford tracking that. */
- dirty = 1;
- break;
}
if ( dirty )
@@ -2916,8 +2928,11 @@ int shadow_track_dirty_vram(struct domai
{
/* was clean for more than two seconds, try to disable guest
* write access */
- for ( i = begin_pfn; i < end_pfn; i++ )
- flush_tlb |= sh_remove_write_access(d->vcpu[0],
gfn_to_mfn(d, i, &t), 1, 0);
+ for ( i = begin_pfn; i < end_pfn; i++ ) {
+ mfn_t mfn = gfn_to_mfn(d, i, &t);
+ if (mfn_x(mfn) != INVALID_MFN)
+ flush_tlb |= sh_remove_write_access(d->vcpu[0], mfn,
1, 0);
+ }
d->dirty_vram->last_dirty = -1;
}
rc = 0;
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/msi.c
--- a/xen/arch/x86/msi.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/msi.c Mon Jun 02 11:35:39 2008 +0900
@@ -25,6 +25,7 @@
#include <mach_apic.h>
#include <io_ports.h>
#include <public/physdev.h>
+#include <xen/iommu.h>
extern int msi_irq_enable;
@@ -156,6 +157,9 @@ void read_msi_msg(unsigned int irq, stru
default:
BUG();
}
+
+ if ( vtd_enabled )
+ msi_msg_read_remap_rte(entry, msg);
}
static int set_vector_msi(struct msi_desc *entry)
@@ -201,6 +205,9 @@ void write_msi_msg(unsigned int irq, str
void write_msi_msg(unsigned int irq, struct msi_msg *msg)
{
struct msi_desc *entry = irq_desc[irq].msi_desc;
+
+ if ( vtd_enabled )
+ msi_msg_write_remap_rte(entry, msg);
switch ( entry->msi_attrib.type )
{
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/setup.c Mon Jun 02 11:35:39 2008 +0900
@@ -1100,6 +1100,14 @@ void arch_get_xen_caps(xen_capabilities_
#endif
}
+int xen_in_range(paddr_t start, paddr_t end)
+{
+ start = max_t(paddr_t, start, xenheap_phys_start);
+ end = min_t(paddr_t, end, xenheap_phys_end);
+
+ return start < end;
+}
+
/*
* Local variables:
* mode: C
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/smpboot.c
--- a/xen/arch/x86/smpboot.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/smpboot.c Mon Jun 02 11:35:39 2008 +0900
@@ -1391,6 +1391,11 @@ void enable_nonboot_cpus(void)
panic("Not enough cpus");
}
cpus_clear(frozen_cpus);
+
+ /*
+ * Cleanup possible dangling ends after sleep...
+ */
+ smpboot_restore_warm_reset_vector();
}
#else /* ... !CONFIG_HOTPLUG_CPU */
int __cpu_disable(void)
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/tboot.c
--- a/xen/arch/x86/tboot.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/tboot.c Mon Jun 02 11:35:39 2008 +0900
@@ -96,6 +96,18 @@ int tboot_in_measured_env(void)
return (g_tboot_shared != NULL);
}
+int tboot_in_range(paddr_t start, paddr_t end)
+{
+ if ( g_tboot_shared == NULL || g_tboot_shared->version < 0x02 )
+ return 0;
+
+ start = max_t(paddr_t, start, g_tboot_shared->tboot_base);
+ end = min_t(paddr_t, end,
+ g_tboot_shared->tboot_base + g_tboot_shared->tboot_size);
+
+ return start < end;
+}
+
/*
* Local variables:
* mode: C
diff -r d2a239224cb2 -r f1508348ffab xen/arch/x86/x86_emulate/x86_emulate.c
--- a/xen/arch/x86/x86_emulate/x86_emulate.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c Mon Jun 02 11:35:39 2008 +0900
@@ -2105,12 +2105,14 @@ x86_emulate(
break;
}
+ /* Inject #DB if single-step tracing was enabled at instruction start. */
+ if ( (ctxt->regs->eflags & EFLG_TF) && (rc == X86EMUL_OKAY) &&
+ (ops->inject_hw_exception != NULL) )
+ rc = ops->inject_hw_exception(EXC_DB, -1, ctxt) ? : X86EMUL_EXCEPTION;
+
/* Commit shadow register state. */
_regs.eflags &= ~EFLG_RF;
*ctxt->regs = _regs;
- if ( (_regs.eflags & EFLG_TF) && (rc == X86EMUL_OKAY) &&
- (ops->inject_hw_exception != NULL) )
- rc = ops->inject_hw_exception(EXC_DB, -1, ctxt) ? : X86EMUL_EXCEPTION;
done:
return rc;
diff -r d2a239224cb2 -r f1508348ffab xen/common/domain.c
--- a/xen/common/domain.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/common/domain.c Mon Jun 02 11:35:39 2008 +0900
@@ -637,7 +637,7 @@ void vcpu_reset(struct vcpu *v)
{
struct domain *d = v->domain;
- domain_pause(d);
+ vcpu_pause(v);
domain_lock(d);
arch_vcpu_reset(v);
@@ -653,7 +653,7 @@ void vcpu_reset(struct vcpu *v)
clear_bit(_VPF_blocked, &v->pause_flags);
domain_unlock(v->domain);
- domain_unpause(d);
+ vcpu_unpause(v);
}
diff -r d2a239224cb2 -r f1508348ffab xen/common/grant_table.c
--- a/xen/common/grant_table.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/common/grant_table.c Mon Jun 02 11:35:39 2008 +0900
@@ -32,6 +32,8 @@
#include <xen/trace.h>
#include <xen/guest_access.h>
#include <xen/domain_page.h>
+#include <xen/iommu.h>
+#include <xen/paging.h>
#include <xsm/xsm.h>
#ifndef max_nr_grant_frames
@@ -196,8 +198,9 @@ __gnttab_map_grant_ref(
struct domain *ld, *rd;
struct vcpu *led;
int handle;
- unsigned long frame = 0;
+ unsigned long frame = 0, nr_gets = 0;
int rc = GNTST_okay;
+ u32 old_pin;
unsigned int cache_flags;
struct active_grant_entry *act;
struct grant_mapping *mt;
@@ -318,6 +321,7 @@ __gnttab_map_grant_ref(
}
}
+ old_pin = act->pin;
if ( op->flags & GNTMAP_device_map )
act->pin += (op->flags & GNTMAP_readonly) ?
GNTPIN_devr_inc : GNTPIN_devw_inc;
@@ -361,20 +365,17 @@ __gnttab_map_grant_ref(
rc = GNTST_general_error;
goto undo_out;
}
-
+
+ nr_gets++;
if ( op->flags & GNTMAP_host_map )
{
rc = create_grant_host_mapping(op->host_addr, frame, op->flags, 0);
if ( rc != GNTST_okay )
- {
- if ( gnttab_host_mapping_get_page_type(op, ld, rd) )
- put_page_type(mfn_to_page(frame));
- put_page(mfn_to_page(frame));
goto undo_out;
- }
if ( op->flags & GNTMAP_device_map )
{
+ nr_gets++;
(void)get_page(mfn_to_page(frame), rd);
if ( !(op->flags & GNTMAP_readonly) )
get_page_type(mfn_to_page(frame), PGT_writable_page);
@@ -382,6 +383,17 @@ __gnttab_map_grant_ref(
}
}
+ if ( need_iommu(ld) &&
+ !(old_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) &&
+ (act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
+ {
+ if ( iommu_map_page(ld, mfn_to_gmfn(ld, frame), frame) )
+ {
+ rc = GNTST_general_error;
+ goto undo_out;
+ }
+ }
+
TRACE_1D(TRC_MEM_PAGE_GRANT_MAP, op->dom);
mt = &maptrack_entry(ld->grant_table, handle);
@@ -397,6 +409,19 @@ __gnttab_map_grant_ref(
return;
undo_out:
+ if ( nr_gets > 1 )
+ {
+ if ( !(op->flags & GNTMAP_readonly) )
+ put_page_type(mfn_to_page(frame));
+ put_page(mfn_to_page(frame));
+ }
+ if ( nr_gets > 0 )
+ {
+ if ( gnttab_host_mapping_get_page_type(op, ld, rd) )
+ put_page_type(mfn_to_page(frame));
+ put_page(mfn_to_page(frame));
+ }
+
spin_lock(&rd->grant_table->lock);
act = &active_entry(rd->grant_table, op->ref);
@@ -451,6 +476,7 @@ __gnttab_unmap_common(
struct active_grant_entry *act;
grant_entry_t *sha;
s16 rc = 0;
+ u32 old_pin;
ld = current->domain;
@@ -497,6 +523,7 @@ __gnttab_unmap_common(
act = &active_entry(rd->grant_table, op->map->ref);
sha = &shared_entry(rd->grant_table, op->map->ref);
+ old_pin = act->pin;
if ( op->frame == 0 )
{
@@ -532,6 +559,17 @@ __gnttab_unmap_common(
act->pin -= GNTPIN_hstr_inc;
else
act->pin -= GNTPIN_hstw_inc;
+ }
+
+ if ( need_iommu(ld) &&
+ (old_pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) &&
+ !(act->pin & (GNTPIN_hstw_mask|GNTPIN_devw_mask)) )
+ {
+ if ( iommu_unmap_page(ld, mfn_to_gmfn(ld, op->frame)) )
+ {
+ rc = GNTST_general_error;
+ goto unmap_out;
+ }
}
/* If just unmapped a writable mapping, mark as dirtied */
@@ -1073,6 +1111,11 @@ gnttab_transfer(
gop.status = GNTST_bad_page;
goto copyback;
}
+
+#ifndef __ia64__ /* IA64 implicitly replaces the old page in steal_page(). */
+ guest_physmap_remove_page(d, gop.mfn, mfn, 0);
+#endif
+ flush_tlb_mask(d->domain_dirty_cpumask);
/* Find the target domain. */
if ( unlikely((e = rcu_lock_domain_by_id(gop.domid)) == NULL) )
diff -r d2a239224cb2 -r f1508348ffab xen/common/libelf/libelf-private.h
--- a/xen/common/libelf/libelf-private.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/common/libelf/libelf-private.h Mon Jun 02 11:35:39 2008 +0900
@@ -43,7 +43,7 @@
#define bswap_16(x) swap16(x)
#define bswap_32(x) swap32(x)
#define bswap_64(x) swap64(x)
-#elif defined(__linux__) || defined(__Linux__)
+#elif defined(__linux__) || defined(__Linux__) || defined(__MINIOS__)
#include <byteswap.h>
#else
#error Unsupported OS
diff -r d2a239224cb2 -r f1508348ffab xen/common/memory.c
--- a/xen/common/memory.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/common/memory.c Mon Jun 02 11:35:39 2008 +0900
@@ -124,12 +124,9 @@ static void populate_physmap(struct memo
}
mfn = page_to_mfn(page);
-
- if ( unlikely(paging_mode_translate(d)) )
- {
- guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
- }
- else
+ guest_physmap_add_page(d, gpfn, mfn, a->extent_order);
+
+ if ( !paging_mode_translate(d) )
{
for ( j = 0; j < (1 << a->extent_order); j++ )
set_gpfn_from_mfn(mfn + j, gpfn + j);
@@ -436,11 +433,9 @@ static long memory_exchange(XEN_GUEST_HA
&gpfn, exch.out.extent_start, (i<<out_chunk_order)+j, 1);
mfn = page_to_mfn(page);
- if ( unlikely(paging_mode_translate(d)) )
- {
- guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
- }
- else
+ guest_physmap_add_page(d, gpfn, mfn, exch.out.extent_order);
+
+ if ( !paging_mode_translate(d) )
{
for ( k = 0; k < (1UL << exch.out.extent_order); k++ )
set_gpfn_from_mfn(mfn + k, gpfn + k);
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/amd/pci_amd_iommu.c
--- a/xen/drivers/passthrough/amd/pci_amd_iommu.c Mon Jun 02 11:35:02
2008 +0900
+++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c Mon Jun 02 11:35:39
2008 +0900
@@ -635,6 +635,16 @@ static void amd_iommu_return_device(
reassign_device(s, t, bus, devfn);
}
+static int amd_iommu_group_id(u8 bus, u8 devfn)
+{
+ int rt;
+ int bdf = (bus << 8) | devfn;
+ rt = ( bdf < ivrs_bdf_entries ) ?
+ ivrs_mappings[bdf].dte_requestor_id :
+ bdf;
+ return rt;
+}
+
struct iommu_ops amd_iommu_ops = {
.init = amd_iommu_domain_init,
.assign_device = amd_iommu_assign_device,
@@ -642,4 +652,5 @@ struct iommu_ops amd_iommu_ops = {
.map_page = amd_iommu_map_page,
.unmap_page = amd_iommu_unmap_page,
.reassign_device = amd_iommu_return_device,
+ .get_device_group_id = amd_iommu_group_id,
};
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/iommu.c
--- a/xen/drivers/passthrough/iommu.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/iommu.c Mon Jun 02 11:35:39 2008 +0900
@@ -15,14 +15,20 @@
#include <xen/sched.h>
#include <xen/iommu.h>
+#include <xen/paging.h>
+#include <xen/guest_access.h>
extern struct iommu_ops intel_iommu_ops;
extern struct iommu_ops amd_iommu_ops;
+static int iommu_populate_page_table(struct domain *d);
int intel_vtd_setup(void);
int amd_iov_detect(void);
int iommu_enabled = 1;
boolean_param("iommu", iommu_enabled);
+
+int iommu_pv_enabled = 0;
+boolean_param("iommu_pv", iommu_pv_enabled);
int iommu_domain_init(struct domain *domain)
{
@@ -54,11 +60,46 @@ int assign_device(struct domain *d, u8 b
int assign_device(struct domain *d, u8 bus, u8 devfn)
{
struct hvm_iommu *hd = domain_hvm_iommu(d);
-
- if ( !iommu_enabled || !hd->platform_ops )
- return 0;
-
- return hd->platform_ops->assign_device(d, bus, devfn);
+ int rc;
+
+ if ( !iommu_enabled || !hd->platform_ops )
+ return 0;
+
+ if ( (rc = hd->platform_ops->assign_device(d, bus, devfn)) )
+ return rc;
+
+ if ( has_iommu_pdevs(d) && !need_iommu(d) )
+ {
+ d->need_iommu = 1;
+ return iommu_populate_page_table(d);
+ }
+ return 0;
+}
+
+static int iommu_populate_page_table(struct domain *d)
+{
+ struct hvm_iommu *hd = domain_hvm_iommu(d);
+ struct page_info *page;
+ int rc;
+
+ spin_lock(&d->page_alloc_lock);
+
+ list_for_each_entry ( page, &d->page_list, list )
+ {
+ if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page )
+ {
+ rc = hd->platform_ops->map_page(
+ d, mfn_to_gmfn(d, page_to_mfn(page)), page_to_mfn(page));
+ if (rc)
+ {
+ spin_unlock(&d->page_alloc_lock);
+ hd->platform_ops->teardown(d);
+ return rc;
+ }
+ }
+ }
+ spin_unlock(&d->page_alloc_lock);
+ return 0;
}
void iommu_domain_destroy(struct domain *d)
@@ -137,7 +178,13 @@ void deassign_device(struct domain *d, u
if ( !iommu_enabled || !hd->platform_ops )
return;
- return hd->platform_ops->reassign_device(d, dom0, bus, devfn);
+ hd->platform_ops->reassign_device(d, dom0, bus, devfn);
+
+ if ( !has_iommu_pdevs(d) && need_iommu(d) )
+ {
+ d->need_iommu = 0;
+ hd->platform_ops->teardown(d);
+ }
}
static int iommu_setup(void)
@@ -160,7 +207,56 @@ static int iommu_setup(void)
iommu_enabled = (rc == 0);
out:
+ if ( !iommu_enabled || !vtd_enabled )
+ iommu_pv_enabled = 0;
printk("I/O virtualisation %sabled\n", iommu_enabled ? "en" : "dis");
+ if (iommu_enabled)
+ printk("I/O virtualisation for PV guests %sabled\n",
+ iommu_pv_enabled ? "en" : "dis");
return rc;
}
__initcall(iommu_setup);
+
+int iommu_get_device_group(struct domain *d, u8 bus, u8 devfn,
+ XEN_GUEST_HANDLE_64(uint32) buf, int max_sdevs)
+{
+ struct hvm_iommu *hd = domain_hvm_iommu(d);
+ struct pci_dev *pdev;
+ int group_id, sdev_id;
+ u32 bdf;
+ int i = 0;
+ struct iommu_ops *ops = hd->platform_ops;
+
+ if ( !iommu_enabled || !ops || !ops->get_device_group_id )
+ return 0;
+
+ group_id = ops->get_device_group_id(bus, devfn);
+
+ list_for_each_entry(pdev,
+ &(dom0->arch.hvm_domain.hvm_iommu.pdev_list), list)
+ {
+ if ( (pdev->bus == bus) && (pdev->devfn == devfn) )
+ continue;
+
+ sdev_id = ops->get_device_group_id(pdev->bus, pdev->devfn);
+ if ( (sdev_id == group_id) && (i < max_sdevs) )
+ {
+ bdf = 0;
+ bdf |= (pdev->bus & 0xff) << 16;
+ bdf |= (pdev->devfn & 0xff) << 8;
+ if ( unlikely(copy_to_guest_offset(buf, i, &bdf, 1)) )
+ return -1;
+ i++;
+ }
+ }
+
+ return i;
+}
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/dmar.c Mon Jun 02 11:35:39 2008 +0900
@@ -147,39 +147,6 @@ struct acpi_drhd_unit * acpi_find_matche
return NULL;
}
-struct acpi_rmrr_unit * acpi_find_matched_rmrr_unit(struct pci_dev *dev)
-{
- struct acpi_rmrr_unit *rmrr;
-
- list_for_each_entry ( rmrr, &acpi_rmrr_units, list )
- if ( acpi_pci_device_match(rmrr->devices,
- rmrr->devices_cnt, dev) )
- return rmrr;
-
- return NULL;
-}
-
-struct acpi_atsr_unit * acpi_find_matched_atsr_unit(struct pci_dev *dev)
-{
- struct acpi_atsr_unit *atsru;
- struct acpi_atsr_unit *all_ports_atsru;
-
- all_ports_atsru = NULL;
- list_for_each_entry ( atsru, &acpi_atsr_units, list )
- {
- if ( atsru->all_ports )
- all_ports_atsru = atsru;
- if ( acpi_pci_device_match(atsru->devices,
- atsru->devices_cnt, dev) )
- return atsru;
- }
-
- if ( all_ports_atsru )
- return all_ports_atsru;;
-
- return NULL;
-}
-
static int scope_device_count(void *start, void *end)
{
struct acpi_dev_scope *scope;
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/dmar.h
--- a/xen/drivers/passthrough/vtd/dmar.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/dmar.h Mon Jun 02 11:35:39 2008 +0900
@@ -86,7 +86,6 @@ struct acpi_atsr_unit {
}
struct acpi_drhd_unit * acpi_find_matched_drhd_unit(struct pci_dev *dev);
-struct acpi_rmrr_unit * acpi_find_matched_rmrr_unit(struct pci_dev *dev);
#define DMAR_TYPE 1
#define RMRR_TYPE 2
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/extern.h
--- a/xen/drivers/passthrough/vtd/extern.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/extern.h Mon Jun 02 11:35:39 2008 +0900
@@ -27,8 +27,7 @@ extern struct ir_ctrl *ir_ctrl;
extern struct ir_ctrl *ir_ctrl;
void print_iommu_regs(struct acpi_drhd_unit *drhd);
-void print_vtd_entries(struct domain *d, struct iommu *iommu,
- int bus, int devfn, unsigned long gmfn);
+void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn);
void pdev_flr(u8 bus, u8 devfn);
int qinval_setup(struct iommu *iommu);
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/intremap.c Mon Jun 02 11:35:39 2008 +0900
@@ -48,14 +48,14 @@ static void remap_entry_to_ioapic_rte(
{
struct iremap_entry *iremap_entry = NULL, *iremap_entries;
struct IO_APIC_route_remap_entry *remap_rte;
- unsigned int index;
+ int index = 0;
unsigned long flags;
struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
- if ( ir_ctrl == NULL )
+ if ( ir_ctrl == NULL || ir_ctrl->iremap_index < 0 )
{
dprintk(XENLOG_ERR VTDPREFIX,
- "remap_entry_to_ioapic_rte: ir_ctl == NULL");
+ "remap_entry_to_ioapic_rte: ir_ctl is not ready\n");
return;
}
@@ -63,11 +63,8 @@ static void remap_entry_to_ioapic_rte(
index = (remap_rte->index_15 << 15) + remap_rte->index_0_14;
if ( index > ir_ctrl->iremap_index )
- {
- dprintk(XENLOG_ERR VTDPREFIX,
- "Index is larger than remap table entry size. Error!\n");
- return;
- }
+ panic("%s: index (%d) is larger than remap table entry size (%d)!\n",
+ __func__, index, ir_ctrl->iremap_index);
spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
@@ -81,79 +78,90 @@ static void remap_entry_to_ioapic_rte(
old_rte->trigger = iremap_entry->lo.tm;
old_rte->__reserved_2 = 0;
old_rte->dest.logical.__reserved_1 = 0;
- old_rte->dest.logical.logical_dest = iremap_entry->lo.dst;
+ old_rte->dest.logical.logical_dest = iremap_entry->lo.dst >> 8;
unmap_vtd_domain_page(iremap_entries);
spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
}
static void ioapic_rte_to_remap_entry(struct iommu *iommu,
- int apic_id, struct IO_APIC_route_entry *old_rte)
+ int apic_id, struct IO_APIC_route_entry *old_rte,
+ unsigned int rte_upper, unsigned int value)
{
struct iremap_entry *iremap_entry = NULL, *iremap_entries;
+ struct iremap_entry new_ire;
struct IO_APIC_route_remap_entry *remap_rte;
- unsigned int index;
+ struct IO_APIC_route_entry new_rte;
+ int index;
unsigned long flags;
- int ret = 0;
struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
remap_rte = (struct IO_APIC_route_remap_entry *) old_rte;
spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
- index = ir_ctrl->iremap_index;
+
+ if ( remap_rte->format == 0 )
+ {
+ ir_ctrl->iremap_index++;
+ index = ir_ctrl->iremap_index;
+ }
+ else
+ index = (remap_rte->index_15 << 15) | remap_rte->index_0_14;
+
if ( index > IREMAP_ENTRY_NR - 1 )
- {
- dprintk(XENLOG_ERR VTDPREFIX,
- "The interrupt number is more than 256!\n");
- goto out;
- }
+ panic("ioapic_rte_to_remap_entry: intremap index is more than 256!\n");
iremap_entries =
(struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
iremap_entry = &iremap_entries[index];
- if ( *(u64 *)iremap_entry != 0 )
- dprintk(XENLOG_WARNING VTDPREFIX,
- "Interrupt remapping entry is in use already!\n");
- iremap_entry->lo.fpd = 0;
- iremap_entry->lo.dm = old_rte->dest_mode;
- iremap_entry->lo.rh = 0;
- iremap_entry->lo.tm = old_rte->trigger;
- iremap_entry->lo.dlm = old_rte->delivery_mode;
- iremap_entry->lo.avail = 0;
- iremap_entry->lo.res_1 = 0;
- iremap_entry->lo.vector = old_rte->vector;
- iremap_entry->lo.res_2 = 0;
- iremap_entry->lo.dst = (old_rte->dest.logical.logical_dest << 8);
- iremap_entry->hi.sid = apicid_to_bdf(apic_id);
- iremap_entry->hi.sq = 0; /* comparing all 16-bit of SID */
- iremap_entry->hi.svt = 1; /* turn on requestor ID verification SID/SQ */
- iremap_entry->hi.res_1 = 0;
- iremap_entry->lo.p = 1; /* finally, set present bit */
- ir_ctrl->iremap_index++;
+ memcpy(&new_ire, iremap_entry, sizeof(struct iremap_entry));
+
+ if ( rte_upper )
+ new_ire.lo.dst = (value >> 24) << 8;
+ else
+ {
+ *(((u32 *)&new_rte) + 0) = value;
+ new_ire.lo.fpd = 0;
+ new_ire.lo.dm = new_rte.dest_mode;
+ new_ire.lo.rh = 0;
+ new_ire.lo.tm = new_rte.trigger;
+ new_ire.lo.dlm = new_rte.delivery_mode;
+ new_ire.lo.avail = 0;
+ new_ire.lo.res_1 = 0;
+ new_ire.lo.vector = new_rte.vector;
+ new_ire.lo.res_2 = 0;
+ new_ire.hi.sid = apicid_to_bdf(apic_id);
+
+ new_ire.hi.sq = 0; /* comparing all 16-bit of SID */
+ new_ire.hi.svt = 1; /* requestor ID verification SID/SQ */
+ new_ire.hi.res_1 = 0;
+ new_ire.lo.p = 1; /* finally, set present bit */
+
+ /* now construct new ioapic rte entry */
+ remap_rte->vector = new_rte.vector;
+ remap_rte->delivery_mode = 0; /* has to be 0 for remap format */
+ remap_rte->index_15 = index & 0x8000;
+ remap_rte->index_0_14 = index & 0x7fff;
+
+ remap_rte->delivery_status = new_rte.delivery_status;
+ remap_rte->polarity = new_rte.polarity;
+ remap_rte->irr = new_rte.irr;
+ remap_rte->trigger = new_rte.trigger;
+ remap_rte->mask = new_rte.mask;
+ remap_rte->reserved = 0;
+ remap_rte->format = 1; /* indicate remap format */
+ }
+
+ memcpy(iremap_entry, &new_ire, sizeof(struct iremap_entry));
+ iommu_flush_iec_index(iommu, 0, index);
+ invalidate_sync(iommu);
unmap_vtd_domain_page(iremap_entries);
- iommu_flush_iec_index(iommu, 0, index);
- ret = invalidate_sync(iommu);
-
- /* now construct new ioapic rte entry */
- remap_rte->vector = old_rte->vector;
- remap_rte->delivery_mode = 0; /* has to be 0 for remap format */
- remap_rte->index_15 = index & 0x8000;
- remap_rte->index_0_14 = index & 0x7fff;
- remap_rte->delivery_status = old_rte->delivery_status;
- remap_rte->polarity = old_rte->polarity;
- remap_rte->irr = old_rte->irr;
- remap_rte->trigger = old_rte->trigger;
- remap_rte->mask = 1;
- remap_rte->reserved = 0;
- remap_rte->format = 1; /* indicate remap format */
-out:
spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
return;
}
-unsigned int
-io_apic_read_remap_rte(
+unsigned int io_apic_read_remap_rte(
unsigned int apic, unsigned int reg)
{
struct IO_APIC_route_entry old_rte = { 0 };
@@ -198,15 +206,15 @@ io_apic_read_remap_rte(
}
}
-void
-io_apic_write_remap_rte(
+void io_apic_write_remap_rte(
unsigned int apic, unsigned int reg, unsigned int value)
{
struct IO_APIC_route_entry old_rte = { 0 };
struct IO_APIC_route_remap_entry *remap_rte;
- int rte_upper = (reg & 1) ? 1 : 0;
+ unsigned int rte_upper = (reg & 1) ? 1 : 0;
struct iommu *iommu = ioapic_to_iommu(mp_ioapics[apic].mpc_apicid);
struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
+ int saved_mask;
if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 )
{
@@ -225,21 +233,192 @@ io_apic_write_remap_rte(
*(((u32 *)&old_rte) + 1) = *(IO_APIC_BASE(apic)+4);
remap_rte = (struct IO_APIC_route_remap_entry *) &old_rte;
- if ( remap_rte->mask || (remap_rte->format == 0) )
- {
- *IO_APIC_BASE(apic) = rte_upper ? ++reg : reg;
- *(IO_APIC_BASE(apic)+4) = value;
- return;
- }
-
- *(((u32 *)&old_rte) + rte_upper) = value;
- ioapic_rte_to_remap_entry(iommu, mp_ioapics[apic].mpc_apicid, &old_rte);
+
+ /* mask the interrupt while we change the intremap table */
+ saved_mask = remap_rte->mask;
+ remap_rte->mask = 1;
+ *IO_APIC_BASE(apic) = reg;
+ *(IO_APIC_BASE(apic)+4) = *(((int *)&old_rte)+0);
+ remap_rte->mask = saved_mask;
+
+ ioapic_rte_to_remap_entry(iommu, mp_ioapics[apic].mpc_apicid,
+ &old_rte, rte_upper, value);
/* write new entry to ioapic */
*IO_APIC_BASE(apic) = reg;
- *(IO_APIC_BASE(apic)+4) = *(((int *)&old_rte)+0);
+ *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+0);
*IO_APIC_BASE(apic) = reg + 1;
- *(IO_APIC_BASE(apic)+4) = *(((int *)&old_rte)+1);
+ *(IO_APIC_BASE(apic)+4) = *(((u32 *)&old_rte)+1);
+}
+
+static void remap_entry_to_msi_msg(
+ struct iommu *iommu, struct msi_msg *msg)
+{
+ struct iremap_entry *iremap_entry = NULL, *iremap_entries;
+ struct msi_msg_remap_entry *remap_rte;
+ int index;
+ unsigned long flags;
+ struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
+
+ if ( ir_ctrl == NULL )
+ {
+ dprintk(XENLOG_ERR VTDPREFIX,
+ "remap_entry_to_msi_msg: ir_ctl == NULL");
+ return;
+ }
+
+ remap_rte = (struct msi_msg_remap_entry *) msg;
+ index = (remap_rte->address_lo.index_15 << 15) |
+ remap_rte->address_lo.index_0_14;
+
+ if ( index > ir_ctrl->iremap_index )
+ panic("%s: index (%d) is larger than remap table entry size (%d)\n",
+ __func__, index, ir_ctrl->iremap_index);
+
+ spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
+
+ iremap_entries =
+ (struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
+ iremap_entry = &iremap_entries[index];
+
+ msg->address_hi = MSI_ADDR_BASE_HI;
+ msg->address_lo =
+ MSI_ADDR_BASE_LO |
+ ((iremap_entry->lo.dm == 0) ?
+ MSI_ADDR_DESTMODE_PHYS:
+ MSI_ADDR_DESTMODE_LOGIC) |
+ ((iremap_entry->lo.dlm != dest_LowestPrio) ?
+ MSI_ADDR_REDIRECTION_CPU:
+ MSI_ADDR_REDIRECTION_LOWPRI) |
+ iremap_entry->lo.dst >> 8;
+
+ msg->data =
+ MSI_DATA_TRIGGER_EDGE |
+ MSI_DATA_LEVEL_ASSERT |
+ ((iremap_entry->lo.dlm != dest_LowestPrio) ?
+ MSI_DATA_DELIVERY_FIXED:
+ MSI_DATA_DELIVERY_LOWPRI) |
+ iremap_entry->lo.vector;
+
+ unmap_vtd_domain_page(iremap_entries);
+ spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
+}
+
+static void msi_msg_to_remap_entry(
+ struct iommu *iommu, struct pci_dev *pdev, struct msi_msg *msg)
+{
+ struct iremap_entry *iremap_entry = NULL, *iremap_entries;
+ struct iremap_entry new_ire;
+ struct msi_msg_remap_entry *remap_rte;
+ unsigned int index;
+ unsigned long flags;
+ struct ir_ctrl *ir_ctrl = iommu_ir_ctrl(iommu);
+ int i = 0;
+
+ remap_rte = (struct msi_msg_remap_entry *) msg;
+ spin_lock_irqsave(&ir_ctrl->iremap_lock, flags);
+
+ iremap_entries =
+ (struct iremap_entry *)map_vtd_domain_page(ir_ctrl->iremap_maddr);
+
+ /* If the entry for a PCI device has been there, use the old entry,
+ * Or, assign a new entry for it.
+ */
+ for ( i = 0; i <= ir_ctrl->iremap_index; i++ )
+ {
+ iremap_entry = &iremap_entries[i];
+ if ( iremap_entry->hi.sid ==
+ ((pdev->bus << 8) | pdev->devfn) )
+ break;
+ }
+
+ if ( i > ir_ctrl->iremap_index )
+ {
+ ir_ctrl->iremap_index++;
+ index = ir_ctrl->iremap_index;
+ }
+ else
+ index = i;
+
+ if ( index > IREMAP_ENTRY_NR - 1 )
+ panic("msi_msg_to_remap_entry: intremap index is more than 256!\n");
+
+ iremap_entry = &iremap_entries[index];
+ memcpy(&new_ire, iremap_entry, sizeof(struct iremap_entry));
+
+ /* Set interrupt remapping table entry */
+ new_ire.lo.fpd = 0;
+ new_ire.lo.dm = (msg->address_lo >> MSI_ADDR_DESTMODE_SHIFT) & 0x1;
+ new_ire.lo.rh = 0;
+ new_ire.lo.tm = (msg->data >> MSI_DATA_TRIGGER_SHIFT) & 0x1;
+ new_ire.lo.dlm = (msg->data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x1;
+ new_ire.lo.avail = 0;
+ new_ire.lo.res_1 = 0;
+ new_ire.lo.vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) &
+ MSI_DATA_VECTOR_MASK;
+ new_ire.lo.res_2 = 0;
+ new_ire.lo.dst = ((msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT)
+ & 0xff) << 8;
+
+ new_ire.hi.sid = (pdev->bus << 8) | pdev->devfn;
+ new_ire.hi.sq = 0;
+ new_ire.hi.svt = 1;
+ new_ire.hi.res_1 = 0;
+ new_ire.lo.p = 1; /* finally, set present bit */
+
+ /* now construct new MSI/MSI-X rte entry */
+ remap_rte->address_lo.dontcare = 0;
+ remap_rte->address_lo.index_15 = index & 0x8000;
+ remap_rte->address_lo.index_0_14 = index & 0x7fff;
+ remap_rte->address_lo.SHV = 1;
+ remap_rte->address_lo.format = 1;
+
+ remap_rte->address_hi = 0;
+ remap_rte->data = 0;
+
+ memcpy(iremap_entry, &new_ire, sizeof(struct iremap_entry));
+ iommu_flush_iec_index(iommu, 0, index);
+ invalidate_sync(iommu);
+
+ unmap_vtd_domain_page(iremap_entries);
+ spin_unlock_irqrestore(&ir_ctrl->iremap_lock, flags);
+ return;
+}
+
+void msi_msg_read_remap_rte(
+ struct msi_desc *msi_desc, struct msi_msg *msg)
+{
+ struct pci_dev *pdev = msi_desc->dev;
+ struct acpi_drhd_unit *drhd = NULL;
+ struct iommu *iommu = NULL;
+ struct ir_ctrl *ir_ctrl;
+
+ drhd = acpi_find_matched_drhd_unit(pdev);
+ iommu = drhd->iommu;
+
+ ir_ctrl = iommu_ir_ctrl(iommu);
+ if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 )
+ return;
+
+ remap_entry_to_msi_msg(iommu, msg);
+}
+
+void msi_msg_write_remap_rte(
+ struct msi_desc *msi_desc, struct msi_msg *msg)
+{
+ struct pci_dev *pdev = msi_desc->dev;
+ struct acpi_drhd_unit *drhd = NULL;
+ struct iommu *iommu = NULL;
+ struct ir_ctrl *ir_ctrl;
+
+ drhd = acpi_find_matched_drhd_unit(msi_desc->dev);
+ iommu = drhd->iommu;
+
+ ir_ctrl = iommu_ir_ctrl(iommu);
+ if ( !iommu || !ir_ctrl || ir_ctrl->iremap_maddr == 0 )
+ return;
+
+ msi_msg_to_remap_entry(iommu, pdev, msg);
}
int intremap_setup(struct iommu *iommu)
@@ -260,6 +439,7 @@ int intremap_setup(struct iommu *iommu)
"Cannot allocate memory for ir_ctrl->iremap_maddr\n");
return -ENODEV;
}
+ ir_ctrl->iremap_index = -1;
}
#if defined(ENABLED_EXTENDED_INTERRUPT_SUPPORT)
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/iommu.c Mon Jun 02 11:35:39 2008 +0900
@@ -112,28 +112,27 @@ struct iommu_flush *iommu_get_flush(stru
return iommu ? &iommu->intel->flush : NULL;
}
-unsigned int clflush_size;
-void clflush_cache_range(void *adr, int size)
+static unsigned int clflush_size;
+static int iommus_incoherent;
+static void __iommu_flush_cache(void *addr, int size)
{
int i;
+
+ if ( !iommus_incoherent )
+ return;
+
for ( i = 0; i < size; i += clflush_size )
- clflush(adr + i);
-}
-
-static void __iommu_flush_cache(struct iommu *iommu, void *addr, int size)
-{
- if ( !ecap_coherent(iommu->ecap) )
- clflush_cache_range(addr, size);
-}
-
-void iommu_flush_cache_entry(struct iommu *iommu, void *addr)
-{
- __iommu_flush_cache(iommu, addr, 8);
-}
-
-void iommu_flush_cache_page(struct iommu *iommu, void *addr)
-{
- __iommu_flush_cache(iommu, addr, PAGE_SIZE_4K);
+ clflush((char *)addr + i);
+}
+
+void iommu_flush_cache_entry(void *addr)
+{
+ __iommu_flush_cache(addr, 8);
+}
+
+void iommu_flush_cache_page(void *addr)
+{
+ __iommu_flush_cache(addr, PAGE_SIZE_4K);
}
int nr_iommus;
@@ -157,7 +156,7 @@ static u64 bus_to_context_maddr(struct i
}
set_root_value(*root, maddr);
set_root_present(*root);
- iommu_flush_cache_entry(iommu, root);
+ iommu_flush_cache_entry(root);
}
maddr = (u64) get_context_addr(*root);
unmap_vtd_domain_page(root_entries);
@@ -191,30 +190,22 @@ static int device_context_mapped(struct
return ret;
}
-static u64 addr_to_dma_page_maddr(struct domain *domain, u64 addr)
+static u64 addr_to_dma_page_maddr(struct domain *domain, u64 addr, int alloc)
{
struct hvm_iommu *hd = domain_hvm_iommu(domain);
- struct acpi_drhd_unit *drhd;
- struct iommu *iommu;
int addr_width = agaw_to_width(hd->agaw);
struct dma_pte *parent, *pte = NULL;
int level = agaw_to_level(hd->agaw);
int offset;
unsigned long flags;
- u64 pte_maddr = 0;
+ u64 pte_maddr = 0, maddr;
u64 *vaddr = NULL;
-
- drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
- iommu = drhd->iommu;
addr &= (((u64)1) << addr_width) - 1;
spin_lock_irqsave(&hd->mapping_lock, flags);
if ( hd->pgd_maddr == 0 )
- {
- hd->pgd_maddr = alloc_pgtable_maddr();
- if ( hd->pgd_maddr == 0 )
- return 0;
- }
+ if ( !alloc || ((hd->pgd_maddr = alloc_pgtable_maddr()) == 0) )
+ goto out;
parent = (struct dma_pte *)map_vtd_domain_page(hd->pgd_maddr);
while ( level > 1 )
@@ -224,7 +215,9 @@ static u64 addr_to_dma_page_maddr(struct
if ( dma_pte_addr(*pte) == 0 )
{
- u64 maddr = alloc_pgtable_maddr();
+ if ( !alloc )
+ break;
+ maddr = alloc_pgtable_maddr();
dma_set_pte_addr(*pte, maddr);
vaddr = map_vtd_domain_page(maddr);
if ( !vaddr )
@@ -236,7 +229,7 @@ static u64 addr_to_dma_page_maddr(struct
*/
dma_set_pte_readable(*pte);
dma_set_pte_writable(*pte);
- iommu_flush_cache_entry(iommu, pte);
+ iommu_flush_cache_entry(pte);
}
else
{
@@ -259,43 +252,9 @@ static u64 addr_to_dma_page_maddr(struct
}
unmap_vtd_domain_page(parent);
+ out:
spin_unlock_irqrestore(&hd->mapping_lock, flags);
return pte_maddr;
-}
-
-/* return address's page at specific level */
-static u64 dma_addr_level_page_maddr(
- struct domain *domain, u64 addr, int level)
-{
- struct hvm_iommu *hd = domain_hvm_iommu(domain);
- struct dma_pte *parent, *pte = NULL;
- int total = agaw_to_level(hd->agaw);
- int offset;
- u64 pg_maddr = hd->pgd_maddr;
-
- if ( pg_maddr == 0 )
- return 0;
-
- parent = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
- while ( level <= total )
- {
- offset = address_level_offset(addr, total);
- pte = &parent[offset];
- if ( dma_pte_addr(*pte) == 0 )
- break;
-
- pg_maddr = pte->val & PAGE_MASK_4K;
- unmap_vtd_domain_page(parent);
-
- if ( level == total )
- return pg_maddr;
-
- parent = map_vtd_domain_page(pte->val);
- total--;
- }
-
- unmap_vtd_domain_page(parent);
- return 0;
}
static void iommu_flush_write_buffer(struct iommu *iommu)
@@ -485,9 +444,12 @@ static int flush_iotlb_reg(void *_iommu,
/* check IOTLB invalidation granularity */
if ( DMA_TLB_IAIG(val) == 0 )
printk(KERN_ERR VTDPREFIX "IOMMU: flush IOTLB failed\n");
+
+#ifdef VTD_DEBUG
if ( DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type) )
printk(KERN_ERR VTDPREFIX "IOMMU: tlb flush request %x, actual %x\n",
(u32)DMA_TLB_IIRG(type), (u32)DMA_TLB_IAIG(val));
+#endif
/* flush context entry will implictly flush write buffer */
return 0;
}
@@ -572,34 +534,36 @@ void iommu_flush_all(void)
/* clear one page's page table */
static void dma_pte_clear_one(struct domain *domain, u64 addr)
{
+ struct hvm_iommu *hd = domain_hvm_iommu(domain);
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
struct dma_pte *page = NULL, *pte = NULL;
u64 pg_maddr;
- drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
-
/* get last level pte */
- pg_maddr = dma_addr_level_page_maddr(domain, addr, 1);
+ pg_maddr = addr_to_dma_page_maddr(domain, addr, 0);
if ( pg_maddr == 0 )
return;
page = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
pte = page + address_level_offset(addr, 1);
- if ( pte )
- {
- dma_clear_pte(*pte);
- iommu_flush_cache_entry(drhd->iommu, pte);
-
- for_each_drhd_unit ( drhd )
- {
- iommu = drhd->iommu;
- if ( cap_caching_mode(iommu->cap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
- addr, 1, 0);
- else if (cap_rwbf(iommu->cap))
- iommu_flush_write_buffer(iommu);
- }
- }
+
+ if ( !dma_pte_present(*pte) )
+ {
+ unmap_vtd_domain_page(page);
+ return;
+ }
+
+ dma_clear_pte(*pte);
+ iommu_flush_cache_entry(pte);
+
+ for_each_drhd_unit ( drhd )
+ {
+ iommu = drhd->iommu;
+ if ( test_bit(iommu->index, &hd->iommu_bitmap) )
+ iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
+ addr, 1, 0);
+ }
+
unmap_vtd_domain_page(page);
}
@@ -626,7 +590,6 @@ static void iommu_free_next_pagetable(u6
static void iommu_free_next_pagetable(u64 pt_maddr, unsigned long index,
int level)
{
- struct acpi_drhd_unit *drhd;
unsigned long next_index;
struct dma_pte *pt_vaddr, *pde;
int next_level;
@@ -636,50 +599,38 @@ static void iommu_free_next_pagetable(u6
pt_vaddr = (struct dma_pte *)map_vtd_domain_page(pt_maddr);
pde = &pt_vaddr[index];
- if ( dma_pte_addr(*pde) != 0 )
- {
- next_level = level - 1;
- if ( next_level > 1 )
- {
- next_index = 0;
- do
- {
- iommu_free_next_pagetable(pde->val,
- next_index, next_level);
- next_index++;
- } while ( next_index < PTE_NUM );
- }
-
- dma_clear_pte(*pde);
- drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
- iommu_flush_cache_entry(drhd->iommu, pde);
- free_pgtable_maddr(pde->val);
- unmap_vtd_domain_page(pt_vaddr);
- }
- else
- unmap_vtd_domain_page(pt_vaddr);
+ if ( dma_pte_addr(*pde) == 0 )
+ goto out;
+
+ next_level = level - 1;
+ if ( next_level > 1 )
+ {
+ for ( next_index = 0; next_index < PTE_NUM; next_index++ )
+ iommu_free_next_pagetable(pde->val, next_index, next_level);
+ }
+
+ dma_clear_pte(*pde);
+ iommu_flush_cache_entry(pde);
+ free_pgtable_maddr(pde->val);
+
+ out:
+ unmap_vtd_domain_page(pt_vaddr);
}
/* free all VT-d page tables when shut down or destroy domain. */
static void iommu_free_pagetable(struct domain *domain)
{
- unsigned long index;
struct hvm_iommu *hd = domain_hvm_iommu(domain);
- int total_level = agaw_to_level(hd->agaw);
-
- if ( hd->pgd_maddr != 0 )
- {
- index = 0;
- do
- {
- iommu_free_next_pagetable(hd->pgd_maddr,
- index, total_level + 1);
- index++;
- } while ( index < PTE_NUM );
-
- free_pgtable_maddr(hd->pgd_maddr);
- hd->pgd_maddr = 0;
- }
+ int i, total_level = agaw_to_level(hd->agaw);
+
+ if ( hd->pgd_maddr == 0 )
+ return;
+
+ for ( i = 0; i < PTE_NUM; i++ )
+ iommu_free_next_pagetable(hd->pgd_maddr, i, total_level + 1);
+
+ free_pgtable_maddr(hd->pgd_maddr);
+ hd->pgd_maddr = 0;
}
static int iommu_set_root_entry(struct iommu *iommu)
@@ -777,16 +728,17 @@ int iommu_disable_translation(struct iom
static struct iommu *vector_to_iommu[NR_VECTORS];
static int iommu_page_fault_do_one(struct iommu *iommu, int type,
- u8 fault_reason, u16 source_id, u32 addr)
+ u8 fault_reason, u16 source_id, u64 addr)
{
dprintk(XENLOG_WARNING VTDPREFIX,
- "iommu_fault:%s: %x:%x.%x addr %x REASON %x iommu->reg = %p\n",
+ "iommu_fault:%s: %x:%x.%x addr %"PRIx64" REASON %x "
+ "iommu->reg = %p\n",
(type ? "DMA Read" : "DMA Write"), (source_id >> 8),
PCI_SLOT(source_id & 0xFF), PCI_FUNC(source_id & 0xFF), addr,
fault_reason, iommu->reg);
if ( fault_reason < 0x20 )
- print_vtd_entries(current->domain, iommu, (source_id >> 8),
+ print_vtd_entries(iommu, (source_id >> 8),
(source_id & 0xff), (addr >> PAGE_SHIFT));
return 0;
@@ -844,7 +796,8 @@ static void iommu_page_fault(int vector,
{
u8 fault_reason;
u16 source_id;
- u32 guest_addr, data;
+ u32 data;
+ u64 guest_addr;
int type;
/* highest 32 bits */
@@ -998,6 +951,8 @@ static int iommu_alloc(struct acpi_drhd_
static int iommu_alloc(struct acpi_drhd_unit *drhd)
{
struct iommu *iommu;
+ unsigned long sagaw;
+ int agaw;
if ( nr_iommus > MAX_IOMMUS )
{
@@ -1020,10 +975,27 @@ static int iommu_alloc(struct acpi_drhd_
set_fixmap_nocache(FIX_IOMMU_REGS_BASE_0 + nr_iommus, drhd->address);
iommu->reg = (void *)fix_to_virt(FIX_IOMMU_REGS_BASE_0 + nr_iommus);
- nr_iommus++;
+ iommu->index = nr_iommus++;
iommu->cap = dmar_readq(iommu->reg, DMAR_CAP_REG);
iommu->ecap = dmar_readq(iommu->reg, DMAR_ECAP_REG);
+
+ /* Calculate number of pagetable levels: between 2 and 4. */
+ sagaw = cap_sagaw(iommu->cap);
+ for ( agaw = level_to_agaw(4); agaw >= 0; agaw-- )
+ if ( test_bit(agaw, &sagaw) )
+ break;
+ if ( agaw < 0 )
+ {
+ gdprintk(XENLOG_ERR VTDPREFIX,
+ "IOMMU: unsupported sagaw %lx\n", sagaw);
+ xfree(iommu);
+ return -ENODEV;
+ }
+ iommu->nr_pt_levels = agaw_to_level(agaw);
+
+ if ( !ecap_coherent(iommu->ecap) )
+ iommus_incoherent = 1;
spin_lock_init(&iommu->lock);
spin_lock_init(&iommu->register_lock);
@@ -1066,9 +1038,7 @@ static int intel_iommu_domain_init(struc
{
struct hvm_iommu *hd = domain_hvm_iommu(d);
struct iommu *iommu = NULL;
- int guest_width = DEFAULT_DOMAIN_ADDRESS_WIDTH;
- int i, adjust_width, agaw;
- unsigned long sagaw;
+ u64 i;
struct acpi_drhd_unit *drhd;
INIT_LIST_HEAD(&hd->pdev_list);
@@ -1076,28 +1046,25 @@ static int intel_iommu_domain_init(struc
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
- /* Calculate AGAW. */
- if ( guest_width > cap_mgaw(iommu->cap) )
- guest_width = cap_mgaw(iommu->cap);
- adjust_width = guestwidth_to_adjustwidth(guest_width);
- agaw = width_to_agaw(adjust_width);
- /* FIXME: hardware doesn't support it, choose a bigger one? */
- sagaw = cap_sagaw(iommu->cap);
- if ( !test_bit(agaw, &sagaw) )
- {
- gdprintk(XENLOG_ERR VTDPREFIX,
- "IOMMU: hardware doesn't support the agaw\n");
- agaw = find_next_bit(&sagaw, 5, agaw);
- if ( agaw >= 5 )
- return -ENODEV;
- }
- hd->agaw = agaw;
+ hd->agaw = width_to_agaw(DEFAULT_DOMAIN_ADDRESS_WIDTH);
if ( d->domain_id == 0 )
{
- /* Set up 1:1 page table for dom0. */
+ extern int xen_in_range(paddr_t start, paddr_t end);
+ extern int tboot_in_range(paddr_t start, paddr_t end);
+
+ /*
+ * Set up 1:1 page table for dom0 except the critical segments
+ * like Xen and tboot.
+ */
for ( i = 0; i < max_page; i++ )
+ {
+ if ( xen_in_range(i << PAGE_SHIFT_4K, (i + 1) << PAGE_SHIFT_4K) ||
+ tboot_in_range(i << PAGE_SHIFT_4K, (i + 1) << PAGE_SHIFT_4K) )
+ continue;
+
iommu_map_page(d, i, i);
+ }
setup_dom0_devices(d);
setup_dom0_rmrr(d);
@@ -1123,7 +1090,8 @@ static int domain_context_mapping_one(
struct hvm_iommu *hd = domain_hvm_iommu(domain);
struct context_entry *context, *context_entries;
unsigned long flags;
- u64 maddr;
+ u64 maddr, pgd_maddr;
+ int agaw;
maddr = bus_to_context_maddr(iommu, bus);
context_entries = (struct context_entry *)map_vtd_domain_page(maddr);
@@ -1136,38 +1104,64 @@ static int domain_context_mapping_one(
}
spin_lock_irqsave(&iommu->lock, flags);
+
+#ifdef CONTEXT_PASSTHRU
+ if ( ecap_pass_thru(iommu->ecap) && (domain->domain_id == 0) )
+ context_set_translation_type(*context, CONTEXT_TT_PASS_THRU);
+ else
+ {
+#endif
+ /* Ensure we have pagetables allocated down to leaf PTE. */
+ if ( hd->pgd_maddr == 0 )
+ {
+ addr_to_dma_page_maddr(domain, 0, 1);
+ if ( hd->pgd_maddr == 0 )
+ {
+ nomem:
+ unmap_vtd_domain_page(context_entries);
+ spin_unlock_irqrestore(&iommu->lock, flags);
+ return -ENOMEM;
+ }
+ }
+
+ /* Skip top levels of page tables for 2- and 3-level DRHDs. */
+ pgd_maddr = hd->pgd_maddr;
+ for ( agaw = level_to_agaw(4);
+ agaw != level_to_agaw(iommu->nr_pt_levels);
+ agaw-- )
+ {
+ struct dma_pte *p = map_vtd_domain_page(pgd_maddr);
+ pgd_maddr = dma_pte_addr(*p);
+ unmap_vtd_domain_page(p);
+ if ( pgd_maddr == 0 )
+ goto nomem;
+ }
+
+ context_set_address_root(*context, pgd_maddr);
+ context_set_translation_type(*context, CONTEXT_TT_MULTI_LEVEL);
+#ifdef CONTEXT_PASSTHRU
+ }
+#endif
+
/*
* domain_id 0 is not valid on Intel's IOMMU, force domain_id to
* be 1 based as required by intel's iommu hw.
*/
context_set_domain_id(context, domain);
- context_set_address_width(*context, hd->agaw);
-
- if ( ecap_pass_thru(iommu->ecap) )
- context_set_translation_type(*context, CONTEXT_TT_PASS_THRU);
-#ifdef CONTEXT_PASSTHRU
- else
- {
-#endif
- ASSERT(hd->pgd_maddr != 0);
- context_set_address_root(*context, hd->pgd_maddr);
- context_set_translation_type(*context, CONTEXT_TT_MULTI_LEVEL);
-#ifdef CONTEXT_PASSTHRU
- }
-#endif
-
+ context_set_address_width(*context, agaw);
context_set_fault_enable(*context);
context_set_present(*context);
- iommu_flush_cache_entry(iommu, context);
+ iommu_flush_cache_entry(context);
unmap_vtd_domain_page(context_entries);
- if ( iommu_flush_context_device(iommu, domain_iommu_domid(domain),
- (((u16)bus) << 8) | devfn,
- DMA_CCMD_MASK_NOBIT, 1) )
+ /* Context entry was previously non-present (with domid 0). */
+ iommu_flush_context_device(iommu, 0, (((u16)bus) << 8) | devfn,
+ DMA_CCMD_MASK_NOBIT, 1);
+ if ( iommu_flush_iotlb_dsi(iommu, 0, 1) )
iommu_flush_write_buffer(iommu);
- else
- iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0);
+
+ set_bit(iommu->index, &hd->iommu_bitmap);
spin_unlock_irqrestore(&iommu->lock, flags);
return 0;
@@ -1314,7 +1308,7 @@ static int domain_context_unmap_one(
spin_lock_irqsave(&iommu->lock, flags);
context_clear_present(*context);
context_clear_entry(*context);
- iommu_flush_cache_entry(iommu, context);
+ iommu_flush_cache_entry(context);
iommu_flush_context_global(iommu, 0);
iommu_flush_iotlb_global(iommu, 0);
unmap_vtd_domain_page(context_entries);
@@ -1395,11 +1389,12 @@ void reassign_device_ownership(
{
struct hvm_iommu *source_hd = domain_hvm_iommu(source);
struct hvm_iommu *target_hd = domain_hvm_iommu(target);
- struct pci_dev *pdev;
+ struct pci_dev *pdev, *pdev2;
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
int status;
unsigned long flags;
+ int found = 0;
pdev_flr(bus, devfn);
@@ -1420,6 +1415,18 @@ void reassign_device_ownership(
list_move(&pdev->list, &target_hd->pdev_list);
spin_unlock_irqrestore(&target_hd->iommu_list_lock, flags);
spin_unlock_irqrestore(&source_hd->iommu_list_lock, flags);
+
+ for_each_pdev ( source, pdev2 )
+ {
+ drhd = acpi_find_matched_drhd_unit(pdev2);
+ if ( drhd->iommu == iommu )
+ {
+ found = 1;
+ break;
+ }
+ }
+ if ( !found )
+ clear_bit(iommu->index, &source_hd->iommu_bitmap);
status = domain_context_mapping(target, iommu, pdev);
if ( status != 0 )
@@ -1477,13 +1484,12 @@ int intel_iommu_map_page(
int intel_iommu_map_page(
struct domain *d, unsigned long gfn, unsigned long mfn)
{
+ struct hvm_iommu *hd = domain_hvm_iommu(d);
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
struct dma_pte *page = NULL, *pte = NULL;
u64 pg_maddr;
-
- drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
- iommu = drhd->iommu;
+ int pte_present;
#ifdef CONTEXT_PASSTHRU
/* do nothing if dom0 and iommu supports pass thru */
@@ -1491,23 +1497,27 @@ int intel_iommu_map_page(
return 0;
#endif
- pg_maddr = addr_to_dma_page_maddr(d, (paddr_t)gfn << PAGE_SHIFT_4K);
+ pg_maddr = addr_to_dma_page_maddr(d, (paddr_t)gfn << PAGE_SHIFT_4K, 1);
if ( pg_maddr == 0 )
return -ENOMEM;
page = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
pte = page + (gfn & LEVEL_MASK);
+ pte_present = dma_pte_present(*pte);
dma_set_pte_addr(*pte, (paddr_t)mfn << PAGE_SHIFT_4K);
dma_set_pte_prot(*pte, DMA_PTE_READ | DMA_PTE_WRITE);
- iommu_flush_cache_entry(iommu, pte);
+ iommu_flush_cache_entry(pte);
unmap_vtd_domain_page(page);
for_each_drhd_unit ( drhd )
{
iommu = drhd->iommu;
- if ( cap_caching_mode(iommu->cap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(d),
- (paddr_t)gfn << PAGE_SHIFT_4K, 1, 0);
- else if ( cap_rwbf(iommu->cap) )
+
+ if ( !test_bit(iommu->index, &hd->iommu_bitmap) )
+ continue;
+
+ if ( iommu_flush_iotlb_psi(iommu, domain_iommu_domid(d),
+ (paddr_t)gfn << PAGE_SHIFT_4K, 1,
+ !pte_present) )
iommu_flush_write_buffer(iommu);
}
@@ -1536,6 +1546,7 @@ int iommu_page_mapping(struct domain *do
int iommu_page_mapping(struct domain *domain, paddr_t iova,
paddr_t hpa, size_t size, int prot)
{
+ struct hvm_iommu *hd = domain_hvm_iommu(domain);
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
u64 start_pfn, end_pfn;
@@ -1543,24 +1554,23 @@ int iommu_page_mapping(struct domain *do
int index;
u64 pg_maddr;
- drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
- iommu = drhd->iommu;
if ( (prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0 )
return -EINVAL;
+
iova = (iova >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K;
start_pfn = hpa >> PAGE_SHIFT_4K;
end_pfn = (PAGE_ALIGN_4K(hpa + size)) >> PAGE_SHIFT_4K;
index = 0;
while ( start_pfn < end_pfn )
{
- pg_maddr = addr_to_dma_page_maddr(domain, iova + PAGE_SIZE_4K * index);
+ pg_maddr = addr_to_dma_page_maddr(domain, iova + PAGE_SIZE_4K*index,
1);
if ( pg_maddr == 0 )
return -ENOMEM;
page = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
pte = page + (start_pfn & LEVEL_MASK);
dma_set_pte_addr(*pte, (paddr_t)start_pfn << PAGE_SHIFT_4K);
dma_set_pte_prot(*pte, prot);
- iommu_flush_cache_entry(iommu, pte);
+ iommu_flush_cache_entry(pte);
unmap_vtd_domain_page(page);
start_pfn++;
index++;
@@ -1569,10 +1579,12 @@ int iommu_page_mapping(struct domain *do
for_each_drhd_unit ( drhd )
{
iommu = drhd->iommu;
- if ( cap_caching_mode(iommu->cap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
- iova, index, 0);
- else if ( cap_rwbf(iommu->cap) )
+
+ if ( !test_bit(iommu->index, &hd->iommu_bitmap) )
+ continue;
+
+ if ( iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
+ iova, index, 1) )
iommu_flush_write_buffer(iommu);
}
@@ -1584,25 +1596,6 @@ int iommu_page_unmapping(struct domain *
dma_pte_clear_range(domain, addr, addr + size);
return 0;
-}
-
-void iommu_flush(struct domain *d, unsigned long gfn, u64 *p2m_entry)
-{
- struct acpi_drhd_unit *drhd;
- struct iommu *iommu = NULL;
- struct dma_pte *pte = (struct dma_pte *) p2m_entry;
-
- for_each_drhd_unit ( drhd )
- {
- iommu = drhd->iommu;
- if ( cap_caching_mode(iommu->cap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(d),
- (paddr_t)gfn << PAGE_SHIFT_4K, 1, 0);
- else if ( cap_rwbf(iommu->cap) )
- iommu_flush_write_buffer(iommu);
- }
-
- iommu_flush_cache_entry(iommu, pte);
}
static int iommu_prepare_rmrr_dev(
@@ -1916,6 +1909,7 @@ struct iommu_ops intel_iommu_ops = {
.map_page = intel_iommu_map_page,
.unmap_page = intel_iommu_unmap_page,
.reassign_device = reassign_device_ownership,
+ .get_device_group_id = NULL,
};
/*
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/iommu.h
--- a/xen/drivers/passthrough/vtd/iommu.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/iommu.h Mon Jun 02 11:35:39 2008 +0900
@@ -236,6 +236,7 @@ struct context_entry {
#define LEVEL_STRIDE (9)
#define LEVEL_MASK ((1 << LEVEL_STRIDE) - 1)
#define PTE_NUM (1 << LEVEL_STRIDE)
+#define level_to_agaw(val) ((val) - 2)
#define agaw_to_level(val) ((val) + 2)
#define agaw_to_width(val) (30 + val * LEVEL_STRIDE)
#define width_to_agaw(w) ((w - 30)/LEVEL_STRIDE)
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/utils.c
--- a/xen/drivers/passthrough/vtd/utils.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/utils.c Mon Jun 02 11:35:39 2008 +0900
@@ -213,109 +213,97 @@ u32 get_level_index(unsigned long gmfn,
return gmfn & LEVEL_MASK;
}
-void print_vtd_entries(
- struct domain *d,
- struct iommu *iommu,
- int bus, int devfn,
- unsigned long gmfn)
-{
- struct hvm_iommu *hd = domain_hvm_iommu(d);
- struct acpi_drhd_unit *drhd;
+void print_vtd_entries(struct iommu *iommu, int bus, int devfn, u64 gmfn)
+{
struct context_entry *ctxt_entry;
struct root_entry *root_entry;
struct dma_pte pte;
u64 *l;
- u32 l_index;
- u32 i = 0;
- int level = agaw_to_level(hd->agaw);
-
- printk("print_vtd_entries: domain_id = %x bdf = %x:%x:%x gmfn = %lx\n",
- d->domain_id, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn);
-
- if ( hd->pgd_maddr == 0 )
- {
- printk(" hd->pgd_maddr == 0\n");
- return;
- }
- printk(" hd->pgd_maddr = %"PRIx64"\n", hd->pgd_maddr);
-
- for_each_drhd_unit ( drhd )
- {
- printk("---- print_vtd_entries %d ----\n", i++);
-
- if ( iommu->root_maddr == 0 )
- {
- printk(" iommu->root_maddr = 0\n");
- continue;
- }
-
- root_entry =
- (struct root_entry *)map_vtd_domain_page(iommu->root_maddr);
+ u32 l_index, level;
+
+ printk("print_vtd_entries: iommu = %p bdf = %x:%x:%x gmfn = %"PRIx64"\n",
+ iommu, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), gmfn);
+
+ if ( iommu->root_maddr == 0 )
+ {
+ printk(" iommu->root_maddr = 0\n");
+ return;
+ }
+
+ root_entry = (struct root_entry *)map_vtd_domain_page(iommu->root_maddr);
- printk(" root_entry = %p\n", root_entry);
- printk(" root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val);
- if ( !root_present(root_entry[bus]) )
- {
- unmap_vtd_domain_page(root_entry);
- printk(" root_entry[%x] not present\n", bus);
- continue;
- }
-
- ctxt_entry =
- (struct context_entry *)map_vtd_domain_page(root_entry[bus].val);
- if ( ctxt_entry == NULL )
- {
- unmap_vtd_domain_page(root_entry);
- printk(" ctxt_entry == NULL\n");
- continue;
- }
-
- printk(" context = %p\n", ctxt_entry);
- printk(" context[%x] = %"PRIx64" %"PRIx64"\n",
- devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo);
- if ( !context_present(ctxt_entry[devfn]) )
+ printk(" root_entry = %p\n", root_entry);
+ printk(" root_entry[%x] = %"PRIx64"\n", bus, root_entry[bus].val);
+ if ( !root_present(root_entry[bus]) )
+ {
+ unmap_vtd_domain_page(root_entry);
+ printk(" root_entry[%x] not present\n", bus);
+ return;
+ }
+
+ ctxt_entry =
+ (struct context_entry *)map_vtd_domain_page(root_entry[bus].val);
+ if ( ctxt_entry == NULL )
+ {
+ unmap_vtd_domain_page(root_entry);
+ printk(" ctxt_entry == NULL\n");
+ return;
+ }
+
+ printk(" context = %p\n", ctxt_entry);
+ printk(" context[%x] = %"PRIx64"_%"PRIx64"\n",
+ devfn, ctxt_entry[devfn].hi, ctxt_entry[devfn].lo);
+ if ( !context_present(ctxt_entry[devfn]) )
+ {
+ unmap_vtd_domain_page(ctxt_entry);
+ unmap_vtd_domain_page(root_entry);
+ printk(" ctxt_entry[%x] not present\n", devfn);
+ return;
+ }
+
+ level = agaw_to_level(context_address_width(ctxt_entry[devfn]));
+ if ( level != VTD_PAGE_TABLE_LEVEL_3 &&
+ level != VTD_PAGE_TABLE_LEVEL_4)
+ {
+ unmap_vtd_domain_page(ctxt_entry);
+ unmap_vtd_domain_page(root_entry);
+ printk("Unsupported VTD page table level (%d)!\n", level);
+ }
+
+ l = maddr_to_virt(ctxt_entry[devfn].lo);
+ do
+ {
+ l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K);
+ printk(" l%d = %p\n", level, l);
+ if ( l == NULL )
{
unmap_vtd_domain_page(ctxt_entry);
unmap_vtd_domain_page(root_entry);
- printk(" ctxt_entry[%x] not present\n", devfn);
- continue;
- }
-
- if ( level != VTD_PAGE_TABLE_LEVEL_3 &&
- level != VTD_PAGE_TABLE_LEVEL_4)
+ printk(" l%d == NULL\n", level);
+ break;
+ }
+ l_index = get_level_index(gmfn, level);
+ printk(" l%d_index = %x\n", level, l_index);
+ printk(" l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]);
+
+ pte.val = l[l_index];
+ if ( !dma_pte_present(pte) )
{
unmap_vtd_domain_page(ctxt_entry);
unmap_vtd_domain_page(root_entry);
- printk("Unsupported VTD page table level (%d)!\n", level);
- continue;
- }
-
- l = maddr_to_virt(ctxt_entry[devfn].lo);
- do
- {
- l = (u64*)(((unsigned long)l >> PAGE_SHIFT_4K) << PAGE_SHIFT_4K);
- printk(" l%d = %p\n", level, l);
- if ( l == NULL )
- {
- unmap_vtd_domain_page(ctxt_entry);
- unmap_vtd_domain_page(root_entry);
- printk(" l%d == NULL\n", level);
- break;
- }
- l_index = get_level_index(gmfn, level);
- printk(" l%d_index = %x\n", level, l_index);
- printk(" l%d[%x] = %"PRIx64"\n", level, l_index, l[l_index]);
-
- pte.val = l[l_index];
- if ( !dma_pte_present(pte) )
- {
- unmap_vtd_domain_page(ctxt_entry);
- unmap_vtd_domain_page(root_entry);
- printk(" l%d[%x] not present\n", level, l_index);
- break;
- }
-
- l = maddr_to_virt(l[l_index]);
- } while ( --level );
- }
-}
+ printk(" l%d[%x] not present\n", level, l_index);
+ break;
+ }
+
+ l = maddr_to_virt(l[l_index]);
+ } while ( --level );
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-set-style: "BSD"
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/vtd.h
--- a/xen/drivers/passthrough/vtd/vtd.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/vtd.h Mon Jun 02 11:35:39 2008 +0900
@@ -42,13 +42,31 @@ struct IO_APIC_route_remap_entry {
};
};
+struct msi_msg_remap_entry {
+ union {
+ u32 val;
+ struct {
+ u32 dontcare:2,
+ index_15:1,
+ SHV:1,
+ format:1,
+ index_0_14:15,
+ addr_id_val:12; /* Interrupt address identifier value,
+ must be 0FEEh */
+ };
+ } address_lo; /* low 32 bits of msi message address */
+
+ u32 address_hi; /* high 32 bits of msi message address */
+ u32 data; /* msi message data */
+};
+
unsigned int get_clflush_size(void);
u64 alloc_pgtable_maddr(void);
void free_pgtable_maddr(u64 maddr);
void *map_vtd_domain_page(u64 maddr);
void unmap_vtd_domain_page(void *va);
-void iommu_flush_cache_entry(struct iommu *iommu, void *addr);
-void iommu_flush_cache_page(struct iommu *iommu, void *addr);
+void iommu_flush_cache_entry(void *addr);
+void iommu_flush_cache_page(void *addr);
#endif // _VTD_H_
diff -r d2a239224cb2 -r f1508348ffab xen/drivers/passthrough/vtd/x86/vtd.c
--- a/xen/drivers/passthrough/vtd/x86/vtd.c Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c Mon Jun 02 11:35:39 2008 +0900
@@ -41,8 +41,6 @@ u64 alloc_pgtable_maddr(void)
{
struct page_info *pg;
u64 *vaddr;
- struct acpi_drhd_unit *drhd;
- struct iommu *iommu;
pg = alloc_domheap_page(NULL, 0);
vaddr = map_domain_page(page_to_mfn(pg));
@@ -50,9 +48,7 @@ u64 alloc_pgtable_maddr(void)
return 0;
memset(vaddr, 0, PAGE_SIZE);
- drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
- iommu = drhd->iommu;
- iommu_flush_cache_page(iommu, vaddr);
+ iommu_flush_cache_page(vaddr);
unmap_domain_page(vaddr);
return page_to_maddr(pg);
@@ -123,181 +119,3 @@ void hvm_dpci_isairq_eoi(struct domain *
}
}
}
-
-void iommu_set_pgd(struct domain *d)
-{
- struct hvm_iommu *hd = domain_hvm_iommu(d);
- unsigned long p2m_table;
-
- p2m_table = mfn_x(pagetable_get_mfn(d->arch.phys_table));
-
- if ( paging_mode_hap(d) )
- {
- int level = agaw_to_level(hd->agaw);
- struct dma_pte *dpte = NULL;
- mfn_t pgd_mfn;
-
- switch ( level )
- {
- case VTD_PAGE_TABLE_LEVEL_3:
- dpte = map_domain_page(p2m_table);
- if ( !dma_pte_present(*dpte) )
- {
- gdprintk(XENLOG_ERR VTDPREFIX,
- "iommu_set_pgd: second level wasn't there\n");
- unmap_domain_page(dpte);
- return;
- }
- pgd_mfn = _mfn(dma_pte_addr(*dpte) >> PAGE_SHIFT_4K);
- hd->pgd_maddr = (paddr_t)(mfn_x(pgd_mfn)) << PAGE_SHIFT_4K;
- unmap_domain_page(dpte);
- break;
- case VTD_PAGE_TABLE_LEVEL_4:
- pgd_mfn = _mfn(p2m_table);
- hd->pgd_maddr = (paddr_t)(mfn_x(pgd_mfn)) << PAGE_SHIFT_4K;
- break;
- default:
- gdprintk(XENLOG_ERR VTDPREFIX,
- "iommu_set_pgd:Unsupported p2m table sharing level!\n");
- break;
- }
- }
- else
- {
-#if CONFIG_PAGING_LEVELS == 3
- struct dma_pte *pte = NULL, *pgd_vaddr = NULL, *pmd_vaddr = NULL;
- int i;
- u64 pmd_maddr;
- unsigned long flags;
- l3_pgentry_t *l3e;
- int level = agaw_to_level(hd->agaw);
-
- spin_lock_irqsave(&hd->mapping_lock, flags);
- hd->pgd_maddr = alloc_pgtable_maddr();
- if ( hd->pgd_maddr == 0 )
- {
- spin_unlock_irqrestore(&hd->mapping_lock, flags);
- gdprintk(XENLOG_ERR VTDPREFIX,
- "Allocate pgd memory failed!\n");
- return;
- }
-
- pgd_vaddr = map_vtd_domain_page(hd->pgd_maddr);
- l3e = map_domain_page(p2m_table);
- switch ( level )
- {
- case VTD_PAGE_TABLE_LEVEL_3: /* Weybridge */
- /* We only support 8 entries for the PAE L3 p2m table */
- for ( i = 0; i < 8 ; i++ )
- {
- /* Don't create new L2 entry, use ones from p2m table */
- pgd_vaddr[i].val = l3e[i].l3 | _PAGE_PRESENT | _PAGE_RW;
- }
- break;
-
- case VTD_PAGE_TABLE_LEVEL_4: /* Stoakley */
- /* We allocate one more page for the top vtd page table. */
- pmd_maddr = alloc_pgtable_maddr();
- if ( pmd_maddr == 0 )
- {
- unmap_vtd_domain_page(pgd_vaddr);
- unmap_domain_page(l3e);
- spin_unlock_irqrestore(&hd->mapping_lock, flags);
- gdprintk(XENLOG_ERR VTDPREFIX,
- "Allocate pmd memory failed!\n");
- return;
- }
-
- pte = &pgd_vaddr[0];
- dma_set_pte_addr(*pte, pmd_maddr);
- dma_set_pte_readable(*pte);
- dma_set_pte_writable(*pte);
-
- pmd_vaddr = map_vtd_domain_page(pmd_maddr);
- for ( i = 0; i < 8; i++ )
- {
- /* Don't create new L2 entry, use ones from p2m table */
- pmd_vaddr[i].val = l3e[i].l3 | _PAGE_PRESENT | _PAGE_RW;
- }
-
- unmap_vtd_domain_page(pmd_vaddr);
- break;
- default:
- gdprintk(XENLOG_ERR VTDPREFIX,
- "iommu_set_pgd:Unsupported p2m table sharing level!\n");
- break;
- }
-
- unmap_vtd_domain_page(pgd_vaddr);
- unmap_domain_page(l3e);
- spin_unlock_irqrestore(&hd->mapping_lock, flags);
-
-#elif CONFIG_PAGING_LEVELS == 4
- mfn_t pgd_mfn;
- l3_pgentry_t *l3e;
- int level = agaw_to_level(hd->agaw);
-
- switch ( level )
- {
- case VTD_PAGE_TABLE_LEVEL_3:
- l3e = map_domain_page(p2m_table);
- if ( (l3e_get_flags(*l3e) & _PAGE_PRESENT) == 0 )
- {
- gdprintk(XENLOG_ERR VTDPREFIX,
- "iommu_set_pgd: second level wasn't there\n");
- unmap_domain_page(l3e);
- return;
- }
-
- pgd_mfn = _mfn(l3e_get_pfn(*l3e));
- hd->pgd_maddr = (paddr_t)(mfn_x(pgd_mfn)) << PAGE_SHIFT_4K;
- unmap_domain_page(l3e);
- break;
- case VTD_PAGE_TABLE_LEVEL_4:
- pgd_mfn = _mfn(p2m_table);
- hd->pgd_maddr = (paddr_t)(mfn_x(pgd_mfn)) << PAGE_SHIFT_4K;
- break;
- default:
- gdprintk(XENLOG_ERR VTDPREFIX,
- "iommu_set_pgd:Unsupported p2m table sharing level!\n");
- break;
- }
-#endif
- }
-}
-
-void iommu_free_pgd(struct domain *d)
-{
-#if CONFIG_PAGING_LEVELS == 3
- struct hvm_iommu *hd = domain_hvm_iommu(d);
- int level = agaw_to_level(hd->agaw);
- struct dma_pte *pgd_vaddr = NULL;
-
- switch ( level )
- {
- case VTD_PAGE_TABLE_LEVEL_3:
- if ( hd->pgd_maddr != 0 )
- {
- free_pgtable_maddr(hd->pgd_maddr);
- hd->pgd_maddr = 0;
- }
- break;
- case VTD_PAGE_TABLE_LEVEL_4:
- if ( hd->pgd_maddr != 0 )
- {
- pgd_vaddr = (struct dma_pte*)map_vtd_domain_page(hd->pgd_maddr);
- if ( pgd_vaddr[0].val != 0 )
- free_pgtable_maddr(pgd_vaddr[0].val);
- unmap_vtd_domain_page(pgd_vaddr);
- free_pgtable_maddr(hd->pgd_maddr);
- hd->pgd_maddr = 0;
- }
- break;
- default:
- gdprintk(XENLOG_ERR VTDPREFIX,
- "Unsupported p2m table sharing level!\n");
- break;
- }
-#endif
-}
-
diff -r d2a239224cb2 -r f1508348ffab xen/include/asm-x86/hvm/hvm.h
--- a/xen/include/asm-x86/hvm/hvm.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/asm-x86/hvm/hvm.h Mon Jun 02 11:35:39 2008 +0900
@@ -147,8 +147,10 @@ void hvm_send_assist_req(struct vcpu *v)
void hvm_set_guest_tsc(struct vcpu *v, u64 guest_tsc);
u64 hvm_get_guest_tsc(struct vcpu *v);
-#define hvm_set_guest_time(vcpu, gtime) hvm_set_guest_tsc(vcpu, gtime)
-#define hvm_get_guest_time(vcpu) hvm_get_guest_tsc(vcpu)
+
+void hvm_init_guest_time(struct domain *d);
+void hvm_set_guest_time(struct vcpu *v, u64 guest_time);
+u64 hvm_get_guest_time(struct vcpu *v);
#define hvm_paging_enabled(v) \
(!!((v)->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PG))
diff -r d2a239224cb2 -r f1508348ffab xen/include/asm-x86/hvm/vcpu.h
--- a/xen/include/asm-x86/hvm/vcpu.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/asm-x86/hvm/vcpu.h Mon Jun 02 11:35:39 2008 +0900
@@ -68,6 +68,9 @@ struct hvm_vcpu {
struct mtrr_state mtrr;
u64 pat_cr;
+ /* In mode delay_for_missed_ticks, VCPUs have differing guest times. */
+ int64_t stime_offset;
+
/* Which cache mode is this VCPU in (CR0:CD/NW)? */
u8 cache_mode;
diff -r d2a239224cb2 -r f1508348ffab xen/include/asm-x86/hvm/vmx/vmx.h
--- a/xen/include/asm-x86/hvm/vmx/vmx.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/asm-x86/hvm/vmx/vmx.h Mon Jun 02 11:35:39 2008 +0900
@@ -49,7 +49,6 @@ void vmx_asm_do_vmentry(void);
void vmx_asm_do_vmentry(void);
void vmx_intr_assist(void);
void vmx_do_resume(struct vcpu *);
-void set_guest_time(struct vcpu *v, u64 gtime);
void vmx_vlapic_msr_changed(struct vcpu *v);
void vmx_realmode(struct cpu_user_regs *regs);
diff -r d2a239224cb2 -r f1508348ffab xen/include/asm-x86/hvm/vpt.h
--- a/xen/include/asm-x86/hvm/vpt.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/asm-x86/hvm/vpt.h Mon Jun 02 11:35:39 2008 +0900
@@ -57,7 +57,7 @@ typedef struct HPETState {
typedef struct HPETState {
struct hpet_registers hpet;
struct vcpu *vcpu;
- uint64_t tsc_freq;
+ uint64_t stime_freq;
uint64_t hpet_to_ns_scale; /* hpet ticks to ns (multiplied by 2^10) */
uint64_t hpet_to_ns_limit; /* max hpet ticks convertable to ns */
uint64_t mc_offset;
@@ -137,6 +137,11 @@ struct pl_time { /* platform time */
struct RTCState vrtc;
struct HPETState vhpet;
struct PMTState vpmt;
+ /* guest_time = Xen sys time + stime_offset */
+ int64_t stime_offset;
+ /* Ensures monotonicity in appropriate timer modes. */
+ uint64_t last_guest_time;
+ spinlock_t pl_time_lock;
};
#define ticks_per_sec(v) (v->domain->arch.hvm_domain.tsc_frequency)
diff -r d2a239224cb2 -r f1508348ffab xen/include/asm-x86/tboot.h
--- a/xen/include/asm-x86/tboot.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/asm-x86/tboot.h Mon Jun 02 11:35:39 2008 +0900
@@ -46,7 +46,15 @@ typedef struct __attribute__ ((__packed_
} uuid_t;
/* used to communicate between tboot and the launched kernel (i.e. Xen) */
-#define MAX_TB_ACPI_SINFO_SIZE 64
+
+typedef struct __attribute__ ((__packed__)) {
+ uint16_t pm1a_cnt;
+ uint16_t pm1b_cnt;
+ uint16_t pm1a_evt;
+ uint16_t pm1b_evt;
+ uint16_t pm1a_cnt_val;
+ uint16_t pm1b_cnt_val;
+} tboot_acpi_sleep_info;
typedef struct __attribute__ ((__packed__)) {
/* version 0x01+ fields: */
@@ -58,8 +66,9 @@ typedef struct __attribute__ ((__packed_
uint32_t shutdown_type; /* type of shutdown (TB_SHUTDOWN_*) */
uint32_t s3_tb_wakeup_entry;/* entry point for tboot s3 wake up */
uint32_t s3_k_wakeup_entry; /* entry point for xen s3 wake up */
- uint8_t acpi_sinfo[MAX_TB_ACPI_SINFO_SIZE];
- /* where kernel put acpi sleep info in Sx */
+ tboot_acpi_sleep_info
+ acpi_sinfo; /* where kernel put acpi sleep info in Sx */
+ uint8_t reserved[52]; /* this pad is for compat with old field */
/* version 0x02+ fields: */
uint32_t tboot_base; /* starting addr for tboot */
uint32_t tboot_size; /* size of tboot */
diff -r d2a239224cb2 -r f1508348ffab xen/include/public/domctl.h
--- a/xen/include/public/domctl.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/public/domctl.h Mon Jun 02 11:35:39 2008 +0900
@@ -448,6 +448,16 @@ typedef struct xen_domctl_assign_device
typedef struct xen_domctl_assign_device xen_domctl_assign_device_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_assign_device_t);
+/* Retrieve sibling devices infomation of machine_bdf */
+#define XEN_DOMCTL_get_device_group 50
+struct xen_domctl_get_device_group {
+ uint32_t machine_bdf; /* IN */
+ uint32_t max_sdevs; /* IN */
+ uint32_t num_sdevs; /* OUT */
+ XEN_GUEST_HANDLE_64(uint32) sdev_array; /* OUT */
+};
+typedef struct xen_domctl_get_device_group xen_domctl_get_device_group_t;
+DEFINE_XEN_GUEST_HANDLE(xen_domctl_get_device_group_t);
/* Pass-through interrupts: bind real irq -> hvm devfn. */
#define XEN_DOMCTL_bind_pt_irq 38
@@ -619,6 +629,7 @@ struct xen_domctl {
struct xen_domctl_hvmcontext hvmcontext;
struct xen_domctl_address_size address_size;
struct xen_domctl_sendtrigger sendtrigger;
+ struct xen_domctl_get_device_group get_device_group;
struct xen_domctl_assign_device assign_device;
struct xen_domctl_bind_pt_irq bind_pt_irq;
struct xen_domctl_memory_mapping memory_mapping;
diff -r d2a239224cb2 -r f1508348ffab xen/include/xen/elfcore.h
--- a/xen/include/xen/elfcore.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/xen/elfcore.h Mon Jun 02 11:35:39 2008 +0900
@@ -66,6 +66,7 @@ typedef struct {
unsigned long xen_compile_time;
unsigned long tainted;
#if defined(__i386__) || defined(__x86_64__)
+ unsigned long xen_phys_start;
unsigned long dom0_pfn_to_mfn_frame_list_list;
#endif
#if defined(__ia64__)
diff -r d2a239224cb2 -r f1508348ffab xen/include/xen/hvm/iommu.h
--- a/xen/include/xen/hvm/iommu.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/xen/hvm/iommu.h Mon Jun 02 11:35:39 2008 +0900
@@ -43,6 +43,7 @@ struct hvm_iommu {
int agaw; /* adjusted guest address width, 0 is level 2 30-bit */
struct list_head g2m_ioport_list; /* guest to machine ioport mapping */
domid_t iommu_domid; /* domain id stored in iommu */
+ u64 iommu_bitmap; /* bitmap of iommu(s) that the domain uses
*/
/* amd iommu support */
int domain_id;
@@ -54,4 +55,7 @@ struct hvm_iommu {
struct iommu_ops *platform_ops;
};
+#define has_iommu_pdevs(domain) \
+ (!list_empty(&(domain->arch.hvm_domain.hvm_iommu.pdev_list)))
+
#endif /* __ASM_X86_HVM_IOMMU_H__ */
diff -r d2a239224cb2 -r f1508348ffab xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/xen/iommu.h Mon Jun 02 11:35:39 2008 +0900
@@ -29,6 +29,7 @@
extern int vtd_enabled;
extern int iommu_enabled;
+extern int iommu_pv_enabled;
#define domain_hvm_iommu(d) (&d->arch.hvm_domain.hvm_iommu)
#define domain_vmx_iommu(d) (&d->arch.hvm_domain.hvm_iommu.vmx_iommu)
@@ -43,7 +44,9 @@ struct iommu {
struct iommu {
struct list_head list;
void __iomem *reg; /* Pointer to hardware regs, virtual addr */
+ u32 index; /* Sequence number of iommu */
u32 gcmd; /* Holds TE, EAFL. Don't need SRTP, SFL, WBF */
+ u32 nr_pt_levels;
u64 cap;
u64 ecap;
spinlock_t lock; /* protect context, domain ids */
@@ -58,14 +61,13 @@ int device_assigned(u8 bus, u8 devfn);
int device_assigned(u8 bus, u8 devfn);
int assign_device(struct domain *d, u8 bus, u8 devfn);
void deassign_device(struct domain *d, u8 bus, u8 devfn);
+int iommu_get_device_group(struct domain *d, u8 bus, u8 devfn,
+ XEN_GUEST_HANDLE_64(uint32) buf, int max_sdevs);
void reassign_device_ownership(struct domain *source,
struct domain *target,
u8 bus, u8 devfn);
int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn);
int iommu_unmap_page(struct domain *d, unsigned long gfn);
-void iommu_flush(struct domain *d, unsigned long gfn, u64 *p2m_entry);
-void iommu_set_pgd(struct domain *d);
-void iommu_free_pgd(struct domain *d);
void iommu_domain_teardown(struct domain *d);
int hvm_do_IRQ_dpci(struct domain *d, unsigned int irq);
int dpci_ioport_intercept(ioreq_t *p);
@@ -76,6 +78,11 @@ unsigned int io_apic_read_remap_rte(unsi
unsigned int io_apic_read_remap_rte(unsigned int apic, unsigned int reg);
void io_apic_write_remap_rte(unsigned int apic,
unsigned int reg, unsigned int value);
+
+struct msi_desc;
+struct msi_msg;
+void msi_msg_read_remap_rte(struct msi_desc *msi_desc, struct msi_msg *msg);
+void msi_msg_write_remap_rte(struct msi_desc *msi_desc, struct msi_msg *msg);
struct qi_ctrl *iommu_qi_ctrl(struct iommu *iommu);
struct ir_ctrl *iommu_ir_ctrl(struct iommu *iommu);
struct iommu_flush *iommu_get_flush(struct iommu *iommu);
@@ -94,6 +101,7 @@ struct iommu_ops {
int (*unmap_page)(struct domain *d, unsigned long gfn);
void (*reassign_device)(struct domain *s, struct domain *t,
u8 bus, u8 devfn);
+ int (*get_device_group_id)(u8 bus, u8 devfn);
};
#endif /* _IOMMU_H_ */
diff -r d2a239224cb2 -r f1508348ffab xen/include/xen/sched.h
--- a/xen/include/xen/sched.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/xen/sched.h Mon Jun 02 11:35:39 2008 +0900
@@ -186,6 +186,8 @@ struct domain
/* Is this an HVM guest? */
bool_t is_hvm;
+ /* Does this guest need iommu mappings? */
+ bool_t need_iommu;
/* Is this guest fully privileged (aka dom0)? */
bool_t is_privileged;
/* Which guest this guest has privileges on */
@@ -515,6 +517,7 @@ static inline void vcpu_unblock(struct v
#define is_hvm_domain(d) ((d)->is_hvm)
#define is_hvm_vcpu(v) (is_hvm_domain(v->domain))
+#define need_iommu(d) ((d)->need_iommu && !(d)->is_hvm)
extern enum cpufreq_controller {
FREQCTL_none, FREQCTL_dom0_kernel
diff -r d2a239224cb2 -r f1508348ffab xen/include/xen/time.h
--- a/xen/include/xen/time.h Mon Jun 02 11:35:02 2008 +0900
+++ b/xen/include/xen/time.h Mon Jun 02 11:35:39 2008 +0900
@@ -47,6 +47,7 @@ struct tm {
};
struct tm gmtime(unsigned long t);
+#define SYSTEM_TIME_HZ 1000000000ULL
#define NOW() ((s_time_t)get_s_time())
#define SECONDS(_s) ((s_time_t)((_s) * 1000000000ULL))
#define MILLISECS(_ms) ((s_time_t)((_ms) * 1000000ULL))
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|