ia64/xen-unstable
changeset 19432:e54eeff2de54
merge with xen-unstable.hg
author | Isaku Yamahata <yamahata@valinux.co.jp> |
---|---|
date | Fri Mar 27 11:07:11 2009 +0900 (2009-03-27) |
parents | 5e4dd7079c48 0b13d9787622 |
children | 56eb2c541255 d5ddc782bc49 |
files | tools/hotplug/Linux/blktap |
line diff
1.1 --- a/Makefile Fri Mar 27 10:54:08 2009 +0900 1.2 +++ b/Makefile Fri Mar 27 11:07:11 2009 +0900 1.3 @@ -203,6 +203,8 @@ uninstall: 1.4 rm -rf $(D)/etc/hotplug/xen-backend.agent 1.5 rm -f $(D)/etc/udev/rules.d/xen-backend.rules 1.6 rm -f $(D)/etc/udev/xen-backend.rules 1.7 + rm -f $(D)/etc/udev/rules.d/xend.rules 1.8 + rm -f $(D)/etc/udev/xend.rules 1.9 rm -f $(D)/etc/sysconfig/xendomains 1.10 rm -rf $(D)/var/run/xen* $(D)/var/lib/xen* 1.11 rm -rf $(D)/boot/*xen*
2.1 --- a/config/NetBSD.mk Fri Mar 27 10:54:08 2009 +0900 2.2 +++ b/config/NetBSD.mk Fri Mar 27 11:07:11 2009 +0900 2.3 @@ -2,3 +2,7 @@ include $(XEN_ROOT)/config/StdGNU.mk 2.4 2.5 # Override settings for this OS 2.6 CURSES_LIBS = -lcurses 2.7 + 2.8 +LIBLEAFDIR_x86_64 = lib 2.9 +LIBEXEC = $(PREFIX)/libexec 2.10 +PRIVATE_BINDIR = $(BINDIR)
3.1 --- a/config/StdGNU.mk Fri Mar 27 10:54:08 2009 +0900 3.2 +++ b/config/StdGNU.mk Fri Mar 27 11:07:11 2009 +0900 3.3 @@ -25,9 +25,12 @@ PREFIX ?= /usr 3.4 BINDIR = $(PREFIX)/bin 3.5 INCLUDEDIR = $(PREFIX)/include 3.6 LIBLEAFDIR = lib 3.7 +LIBLEAFDIR_x86_32 = lib 3.8 LIBLEAFDIR_x86_64 = lib64 3.9 LIBDIR = $(PREFIX)/$(LIBLEAFDIR) 3.10 +LIBDIR_x86_32 = $(PREFIX)/$(LIBLEAFDIR_x86_32) 3.11 LIBDIR_x86_64 = $(PREFIX)/$(LIBLEAFDIR_x86_64) 3.12 +LIBEXEC = $(LIBDIR_x86_32)/xen/bin 3.13 MANDIR = $(PREFIX)/share/man 3.14 MAN1DIR = $(MANDIR)/man1 3.15 MAN8DIR = $(MANDIR)/man8
4.1 --- a/docs/misc/vtd.txt Fri Mar 27 10:54:08 2009 +0900 4.2 +++ b/docs/misc/vtd.txt Fri Mar 27 11:07:11 2009 +0900 4.3 @@ -26,7 +26,18 @@ title Xen-Fedora Core (2.6.18-xen) 4.4 module /boot/vmlinuz-2.6.18.8-xen root=LABEL=/ ro xencons=ttyS console=tty0 console=ttyS0, pciback.hide=(01:00.0)(03:00.0) 4.5 module /boot/initrd-2.6.18-xen.img 4.6 4.7 -12) reboot system 4.8 + or use dynamic hiding via PCI backend sysfs interface: 4.9 + a) check if the driver has binded to the device 4.10 + ls -l /sys/bus/pci/devices/0000:01:00.0/driver 4.11 + ... /sys/bus/pci/devices/0000:01:00.0/driver -> ../../../../bus/pci/drivers/igb 4.12 + b) if yes, then unload the driver first 4.13 + echo -n 0000:01:00.0 >/sys/bus/pci/drivers/igb/unbind 4.14 + c) add the device to the PCI backend 4.15 + echo -n 0000:01:00.0 >/sys/bus/pci/drivers/pciback/new_slot 4.16 + d) let the PCI backend bind to the device 4.17 + echo -n 0000:01:00.0 >/sys/bus/pci/drivers/pciback/bind 4.18 + 4.19 +12) reboot system (not requires if you use the dynamic hiding method) 4.20 13) add "pci" line in /etc/xen/hvm.conf for to assigned devices 4.21 pci = [ '01:00.0', '03:00.0' ] 4.22 15) start hvm guest and use "lspci" to see the passthru device and 4.23 @@ -160,3 +171,82 @@ driver's view are different. As a result 4.24 buffer specified by driver. 4.25 4.26 Such devices assigned to HVM domain currently do not work. 4.27 + 4.28 + 4.29 +Using SR-IOV with VT-d 4.30 +-------------------------------- 4.31 + 4.32 +The Single Root I/O Virtualization is a PCI Express feature supported by 4.33 +some devices such as Intel 82576 which allows you to create virtual PCI 4.34 +devices (Virtual Function) and assign them to the HVM guest. 4.35 + 4.36 +You can use latest lspci (v3.1 and above) to check if your PCIe device 4.37 +supports the SR-IOV capability or not. 4.38 + 4.39 + $ lspci -s 01:00.0 -vvv 4.40 + 4.41 + 01:00.0 Ethernet controller: Intel Corporation 82576 Gigabit Network Connection (rev 01) 4.42 + Subsystem: Intel Corporation Gigabit ET Dual Port Server Adapter 4.43 + 4.44 + ... 4.45 + 4.46 + Capabilities: [160] Single Root I/O Virtualization (SR-IOV) 4.47 + IOVCap: Migration-, Interrupt Message Number: 000 4.48 + IOVCtl: Enable+ Migration- Interrupt- MSE+ ARIHierarchy+ 4.49 + IOVSta: Migration- 4.50 + Initial VFs: 8, Total VFs: 8, Number of VFs: 7, Function Dependency Link: 00 4.51 + VF offset: 128, stride: 2, Device ID: 10ca 4.52 + Supported Page Size: 00000553, System Page Size: 00000001 4.53 + VF Migration: offset: 00000000, BIR: 0 4.54 + Kernel driver in use: igb 4.55 + 4.56 + 4.57 +The function that has the SR-IOV capability is also known as Physical 4.58 +Function. You need the Physical Function driver (runs in the Dom0 and 4.59 +controls the physical resources allocation) to enable the Virtual Function. 4.60 +Following is the Virtual Functions associated with above Physical Function. 4.61 + 4.62 + $ lspci | grep -e 01:1[01].[0246] 4.63 + 4.64 + 01:10.0 Ethernet controller: Intel Corporation Device 10ca (rev 01) 4.65 + 01:10.2 Ethernet controller: Intel Corporation Device 10ca (rev 01) 4.66 + 01:10.4 Ethernet controller: Intel Corporation Device 10ca (rev 01) 4.67 + 01:10.6 Ethernet controller: Intel Corporation Device 10ca (rev 01) 4.68 + 01:11.0 Ethernet controller: Intel Corporation Device 10ca (rev 01) 4.69 + 01:11.2 Ethernet controller: Intel Corporation Device 10ca (rev 01) 4.70 + 01:11.4 Ethernet controller: Intel Corporation Device 10ca (rev 01) 4.71 + 4.72 +We can tell that Physical Function 01:00.0 has 7 Virtual Functions (01:10.0, 4.73 +01:10.2, 01:10.4, 01:10.6, 01:11.0, 01:11.2, 01:11.4). And the Virtual 4.74 +Function PCI Configuration Space looks just like normal PCI device. 4.75 + 4.76 + $ lspci -s 01:10.0 -vvv 4.77 + 4.78 + 01:10.0 Ethernet controller: Intel Corporation 82576 Gigabit Virtual Function 4.79 + Subsystem: Intel Corporation Gigabit Virtual Function 4.80 + Control: I/O- Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx- 4.81 + Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- 4.82 + Region 0: [virtual] Memory at d2840000 (64-bit, non-prefetchable) [size=16K] 4.83 + Region 3: [virtual] Memory at d2860000 (64-bit, non-prefetchable) [size=16K] 4.84 + Capabilities: [70] MSI-X: Enable+ Mask- TabSize=3 4.85 + Vector table: BAR=3 offset=00000000 4.86 + PBA: BAR=3 offset=00002000 4.87 + Capabilities: [a0] Express (v2) Endpoint, MSI 00 4.88 + 4.89 + ... 4.90 + 4.91 + 4.92 +The Virtual Function only appears after the Physical Function driver 4.93 +is loaded. Once the Physical Function driver is unloaded. All Virtual 4.94 +Functions associated with this Physical Function disappear. 4.95 + 4.96 +The Virtual Function is essentially same as the normal PCI device when 4.97 +using it in VT-d environment. You need to hide the Virtual Function, 4.98 +use the Virtual Function bus, device and function number in the HVM 4.99 +guest configuration file and then boot the HVM guest. You also need the 4.100 +Virtual Function driver which is the normal PCI device driver in the 4.101 +HMV guest to drive the Virtual Function. The PCIe SR-IOV specification 4.102 +requires that the Virtual Function can only support MSI/MSI-x if it 4.103 +uses interrupt. This means you also need to enable Xen/MSI support. 4.104 +Since the Virtual Function is dynamically allocated by Physical Function 4.105 +driver, you might want to use the dynamic hiding method mentioned above.
5.1 --- a/extras/mini-os/arch/ia64/mm.c Fri Mar 27 10:54:08 2009 +0900 5.2 +++ b/extras/mini-os/arch/ia64/mm.c Fri Mar 27 11:07:11 2009 +0900 5.3 @@ -162,6 +162,12 @@ int unmap_frames(unsigned long virt_addr 5.4 ASSERT(0); 5.5 } 5.6 5.7 +unsigned long alloc_contig_pages(int order, unsigned int addr_bits) 5.8 +{ 5.9 + /* TODO */ 5.10 + ASSERT(0); 5.11 +} 5.12 + 5.13 void arch_init_p2m(unsigned long max_pfn) 5.14 { 5.15 printk("Warn: p2m map not implemented.\n");
6.1 --- a/extras/mini-os/arch/x86/mm.c Fri Mar 27 10:54:08 2009 +0900 6.2 +++ b/extras/mini-os/arch/x86/mm.c Fri Mar 27 11:07:11 2009 +0900 6.3 @@ -702,6 +702,148 @@ int unmap_frames(unsigned long va, unsig 6.4 } 6.5 6.6 /* 6.7 + * Allocate pages which are contiguous in machine memory. 6.8 + * Returns a VA to where they are mapped or 0 on failure. 6.9 + * 6.10 + * addr_bits indicates if the region has restrictions on where it is 6.11 + * located. Typical values are 32 (if for example PCI devices can't access 6.12 + * 64bit memory) or 0 for no restrictions. 6.13 + * 6.14 + * Allocated pages can be freed using the page allocators free_pages() 6.15 + * function. 6.16 + * 6.17 + * based on Linux function xen_create_contiguous_region() 6.18 + */ 6.19 +#define MAX_CONTIG_ORDER 9 /* 2MB */ 6.20 +unsigned long alloc_contig_pages(int order, unsigned int addr_bits) 6.21 +{ 6.22 + unsigned long in_va, va; 6.23 + unsigned long in_frames[1UL << order], out_frames, mfn; 6.24 + multicall_entry_t call[1UL << order]; 6.25 + unsigned int i, num_pages = 1UL << order; 6.26 + int ret, exch_success; 6.27 + 6.28 + /* pass in num_pages 'extends' of size 1 and 6.29 + * request 1 extend of size 'order */ 6.30 + struct xen_memory_exchange exchange = { 6.31 + .in = { 6.32 + .nr_extents = num_pages, 6.33 + .extent_order = 0, 6.34 + .domid = DOMID_SELF 6.35 + }, 6.36 + .out = { 6.37 + .nr_extents = 1, 6.38 + .extent_order = order, 6.39 + .address_bits = addr_bits, 6.40 + .domid = DOMID_SELF 6.41 + }, 6.42 + .nr_exchanged = 0 6.43 + }; 6.44 + 6.45 + if ( order > MAX_CONTIG_ORDER ) 6.46 + { 6.47 + printk("alloc_contig_pages: order too large 0x%x > 0x%x\n", 6.48 + order, MAX_CONTIG_ORDER); 6.49 + return 0; 6.50 + } 6.51 + 6.52 + /* Allocate some potentially discontiguous pages */ 6.53 + in_va = alloc_pages(order); 6.54 + if ( !in_va ) 6.55 + { 6.56 + printk("alloc_contig_pages: could not get enough pages (order=0x%x\n", 6.57 + order); 6.58 + return 0; 6.59 + } 6.60 + 6.61 + /* set up arguments for exchange hyper call */ 6.62 + set_xen_guest_handle(exchange.in.extent_start, in_frames); 6.63 + set_xen_guest_handle(exchange.out.extent_start, &out_frames); 6.64 + 6.65 + /* unmap current frames, keep a list of MFNs */ 6.66 + for ( i = 0; i < num_pages; i++ ) 6.67 + { 6.68 + int arg = 0; 6.69 + 6.70 + va = in_va + (PAGE_SIZE * i); 6.71 + in_frames[i] = virt_to_mfn(va); 6.72 + 6.73 + /* update P2M mapping */ 6.74 + phys_to_machine_mapping[virt_to_pfn(va)] = INVALID_P2M_ENTRY; 6.75 + 6.76 + /* build multi call */ 6.77 + call[i].op = __HYPERVISOR_update_va_mapping; 6.78 + call[i].args[arg++] = va; 6.79 + call[i].args[arg++] = 0; 6.80 +#ifdef __i386__ 6.81 + call[i].args[arg++] = 0; 6.82 +#endif 6.83 + call[i].args[arg++] = UVMF_INVLPG; 6.84 + } 6.85 + 6.86 + ret = HYPERVISOR_multicall(call, i); 6.87 + if ( ret ) 6.88 + { 6.89 + printk("Odd, update_va_mapping hypercall failed with rc=%d.\n", ret); 6.90 + return 0; 6.91 + } 6.92 + 6.93 + /* try getting a contig range of MFNs */ 6.94 + out_frames = virt_to_pfn(in_va); /* PFNs to populate */ 6.95 + ret = HYPERVISOR_memory_op(XENMEM_exchange, &exchange); 6.96 + if ( ret ) { 6.97 + printk("mem exchanged order=0x%x failed with rc=%d, nr_exchanged=%d\n", 6.98 + order, ret, exchange.nr_exchanged); 6.99 + /* we still need to return the allocated pages above to the pool 6.100 + * ie. map them back into the 1:1 mapping etc. so we continue but 6.101 + * in the end return the pages to the page allocator and return 0. */ 6.102 + exch_success = 0; 6.103 + } 6.104 + else 6.105 + exch_success = 1; 6.106 + 6.107 + /* map frames into 1:1 and update p2m */ 6.108 + for ( i = 0; i < num_pages; i++ ) 6.109 + { 6.110 + int arg = 0; 6.111 + pte_t pte; 6.112 + 6.113 + va = in_va + (PAGE_SIZE * i); 6.114 + mfn = i < exchange.nr_exchanged ? (out_frames + i) : in_frames[i]; 6.115 + pte = __pte(mfn << PAGE_SHIFT | L1_PROT); 6.116 + 6.117 + /* update P2M mapping */ 6.118 + phys_to_machine_mapping[virt_to_pfn(va)] = mfn; 6.119 + 6.120 + /* build multi call */ 6.121 + call[i].op = __HYPERVISOR_update_va_mapping; 6.122 + call[i].args[arg++] = va; 6.123 +#ifdef __x86_64__ 6.124 + call[i].args[arg++] = (pgentry_t)pte.pte; 6.125 +#else 6.126 + call[i].args[arg++] = pte.pte_low; 6.127 + call[i].args[arg++] = pte.pte_high; 6.128 +#endif 6.129 + call[i].args[arg++] = UVMF_INVLPG; 6.130 + } 6.131 + ret = HYPERVISOR_multicall(call, i); 6.132 + if ( ret ) 6.133 + { 6.134 + printk("update_va_mapping hypercall no. 2 failed with rc=%d.\n", ret); 6.135 + return 0; 6.136 + } 6.137 + 6.138 + if ( !exch_success ) 6.139 + { 6.140 + /* since the exchanged failed we just free the pages as well */ 6.141 + free_pages((void *) in_va, order); 6.142 + return 0; 6.143 + } 6.144 + 6.145 + return in_va; 6.146 +} 6.147 + 6.148 +/* 6.149 * Check if a given MFN refers to real memory 6.150 */ 6.151 static long system_ram_end_mfn;
7.1 --- a/extras/mini-os/include/mm.h Fri Mar 27 10:54:08 2009 +0900 7.2 +++ b/extras/mini-os/include/mm.h Fri Mar 27 11:07:11 2009 +0900 7.3 @@ -72,6 +72,7 @@ void do_map_frames(unsigned long addr, 7.4 unsigned long *f, unsigned long n, unsigned long stride, 7.5 unsigned long increment, domid_t id, int may_fail, unsigned long prot); 7.6 int unmap_frames(unsigned long va, unsigned long num_frames); 7.7 +unsigned long alloc_contig_pages(int order, unsigned int addr_bits); 7.8 #ifdef HAVE_LIBC 7.9 extern unsigned long heap, brk, heap_mapped, heap_end; 7.10 #endif
8.1 --- a/extras/mini-os/include/x86/arch_mm.h Fri Mar 27 10:54:08 2009 +0900 8.2 +++ b/extras/mini-os/include/x86/arch_mm.h Fri Mar 27 11:07:11 2009 +0900 8.3 @@ -137,6 +137,9 @@ typedef unsigned long pgentry_t; 8.4 #define IO_PROT (L1_PROT) 8.5 #define IO_PROT_NOCACHE (L1_PROT | _PAGE_PCD) 8.6 8.7 +/* for P2M */ 8.8 +#define INVALID_P2M_ENTRY (~0UL) 8.9 + 8.10 #include "arch_limits.h" 8.11 #define PAGE_SIZE __PAGE_SIZE 8.12 #define PAGE_SHIFT __PAGE_SHIFT
9.1 --- a/stubdom/Makefile Fri Mar 27 10:54:08 2009 +0900 9.2 +++ b/stubdom/Makefile Fri Mar 27 11:07:11 2009 +0900 9.3 @@ -7,8 +7,6 @@ export stubdom=y 9.4 export debug=y 9.5 include $(XEN_ROOT)/Config.mk 9.6 9.7 -IOEMU_OPTIONS=--disable-sdl --disable-opengl --disable-vnc-tls --disable-brlapi --disable-kqemu 9.8 - 9.9 #ZLIB_URL?=http://www.zlib.net 9.10 ZLIB_URL=$(XEN_EXTFILES_URL) 9.11 ZLIB_VERSION=1.2.3 9.12 @@ -237,8 +235,12 @@ ioemu: cross-zlib cross-libpci libxc 9.13 [ -f ioemu/config-host.mak ] || \ 9.14 ( $(absolutify_xen_root); \ 9.15 cd ioemu ; \ 9.16 - CONFIG_STUBDOM=yes XEN_TARGET_ARCH=$(XEN_TARGET_ARCH) CFLAGS="$(TARGET_CFLAGS)" sh ./xen-setup --cc=$(CC) --disable-gcc-check $(IOEMU_OPTIONS)) 9.17 - CPPFLAGS= TARGET_CPPFLAGS="$(TARGET_CPPFLAGS)" $(MAKE) -C ioemu LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) TOOLS= CONFIG_STUBDOM=yes 9.18 + LWIPDIR=$(CURDIR)/lwip-$(XEN_TARGET_ARCH) \ 9.19 + TARGET_CPPFLAGS="$(TARGET_CPPFLAGS)" \ 9.20 + TARGET_CFLAGS="$(TARGET_CFLAGS)" \ 9.21 + TARGET_LDFLAGS="$(TARGET_LDFLAGS)" \ 9.22 + ./xen-setup-stubdom ) 9.23 + $(MAKE) -C ioemu 9.24 9.25 ###### 9.26 # caml 9.27 @@ -312,14 +314,14 @@ install-readme: 9.28 $(INSTALL_DATA) README $(DESTDIR)$(DOCDIR)/README.stubdom 9.29 9.30 install-ioemu: ioemu-stubdom 9.31 - $(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/bin" 9.32 - $(INSTALL_PROG) stubdom-dm "$(DESTDIR)/usr/lib/xen/bin" 9.33 - $(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot" 9.34 - $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-ioemu/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/ioemu-stubdom.gz" 9.35 + $(INSTALL_DIR) "$(DESTDIR)$(LIBEXEC)" 9.36 + $(INSTALL_PROG) stubdom-dm "$(DESTDIR)$(LIBEXEC)" 9.37 + $(INSTALL_DIR) "$(DESTDIR)$(LIBDIR_x86_32)/xen/boot" 9.38 + $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-ioemu/mini-os.gz "$(DESTDIR)$(LIBDIR_x86_32)/xen/boot/ioemu-stubdom.gz" 9.39 9.40 install-grub: pv-grub 9.41 - $(INSTALL_DIR) "$(DESTDIR)/usr/lib/xen/boot" 9.42 - $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)/usr/lib/xen/boot/pv-grub-$(XEN_TARGET_ARCH).gz" 9.43 + $(INSTALL_DIR) "$(DESTDIR)$(LIBDIR_x86_32)/xen/boot" 9.44 + $(INSTALL_DATA) mini-os-$(XEN_TARGET_ARCH)-grub/mini-os.gz "$(DESTDIR)$(LIBDIR_x86_32)/xen/boot/pv-grub-$(XEN_TARGET_ARCH).gz" 9.45 9.46 ####### 9.47 # clean
10.1 --- a/tools/Makefile Fri Mar 27 10:54:08 2009 +0900 10.2 +++ b/tools/Makefile Fri Mar 27 11:07:11 2009 +0900 10.3 @@ -19,11 +19,11 @@ SUBDIRS-y += xenmon 10.4 SUBDIRS-$(VTPM_TOOLS) += vtpm_manager 10.5 SUBDIRS-$(VTPM_TOOLS) += vtpm 10.6 SUBDIRS-y += xenstat 10.7 -SUBDIRS-y += libaio 10.8 -SUBDIRS-y += blktap 10.9 +SUBDIRS-$(CONFIG_Linux) += libaio 10.10 +SUBDIRS-$(CONFIG_Linux) += blktap 10.11 SUBDIRS-y += libfsimage 10.12 SUBDIRS-$(LIBXENAPI_BINDINGS) += libxen 10.13 -SUBDIRS-y += fs-back 10.14 +SUBDIRS-$(CONFIG_Linux) += fs-back 10.15 SUBDIRS-$(CONFIG_IOEMU) += ioemu-dir 10.16 SUBDIRS-y += xenpmd 10.17
11.1 --- a/tools/blktap/drivers/blktapctrl.c Fri Mar 27 10:54:08 2009 +0900 11.2 +++ b/tools/blktap/drivers/blktapctrl.c Fri Mar 27 11:07:11 2009 +0900 11.3 @@ -148,7 +148,8 @@ static int get_tapdisk_pid(blkif_t *blki 11.4 * return 0 on success, -1 on error. 11.5 */ 11.6 11.7 -static int test_path(char *path, char **dev, int *type, blkif_t **blkif) 11.8 +static int test_path(char *path, char **dev, int *type, blkif_t **blkif, 11.9 + int* use_ioemu) 11.10 { 11.11 char *ptr, handle[10]; 11.12 int i, size, found = 0; 11.13 @@ -158,6 +159,17 @@ static int test_path(char *path, char ** 11.14 *type = MAX_DISK_TYPES + 1; 11.15 *blkif = NULL; 11.16 11.17 + if (!strncmp(path, "tapdisk:", strlen("tapdisk:"))) { 11.18 + *use_ioemu = 0; 11.19 + path += strlen("tapdisk:"); 11.20 + } else if (!strncmp(path, "ioemu:", strlen("ioemu:"))) { 11.21 + *use_ioemu = 1; 11.22 + path += strlen("ioemu:"); 11.23 + } else { 11.24 + // Use the default for the image type 11.25 + *use_ioemu = -1; 11.26 + } 11.27 + 11.28 if ( (ptr = strstr(path, ":"))!=NULL) { 11.29 handle_len = (ptr - path); 11.30 memcpy(handle, path, handle_len); 11.31 @@ -174,6 +186,8 @@ static int test_path(char *path, char ** 11.32 } 11.33 11.34 if (found) { 11.35 + if (*use_ioemu == -1) 11.36 + *use_ioemu = dtypes[i]->use_ioemu; 11.37 *type = dtypes[i]->idnum; 11.38 11.39 if (dtypes[i]->single_handler == 1) { 11.40 @@ -185,6 +199,7 @@ static int test_path(char *path, char ** 11.41 *blkif = active_disks[dtypes[i] 11.42 ->idnum]->blkif; 11.43 } 11.44 + 11.45 return 0; 11.46 } 11.47 } 11.48 @@ -216,6 +231,24 @@ static void add_disktype(blkif_t *blkif, 11.49 entry->pprev = pprev; 11.50 } 11.51 11.52 +static int qemu_instance_has_disks(pid_t pid) 11.53 +{ 11.54 + int i; 11.55 + int count = 0; 11.56 + driver_list_entry_t *entry; 11.57 + 11.58 + for (i = 0; i < MAX_DISK_TYPES; i++) { 11.59 + entry = active_disks[i]; 11.60 + while (entry) { 11.61 + if ((entry->blkif->tappid == pid) && dtypes[i]->use_ioemu) 11.62 + count++; 11.63 + entry = entry->next; 11.64 + } 11.65 + } 11.66 + 11.67 + return (count != 0); 11.68 +} 11.69 + 11.70 static int del_disktype(blkif_t *blkif) 11.71 { 11.72 driver_list_entry_t *entry, **pprev; 11.73 @@ -240,6 +273,14 @@ static int del_disktype(blkif_t *blkif) 11.74 DPRINTF("DEL_DISKTYPE: Freeing entry\n"); 11.75 free(entry); 11.76 11.77 + /* 11.78 + * When using ioemu, all disks of one VM are connected to the same 11.79 + * qemu-dm instance. We may close the file handle only if there is 11.80 + * no other disk left for this domain. 11.81 + */ 11.82 + if (dtypes[type]->use_ioemu) 11.83 + return !qemu_instance_has_disks(blkif->tappid); 11.84 + 11.85 /* Caller should close() if no single controller, or list is empty. */ 11.86 return (!dtypes[type]->single_handler || (active_disks[type] == NULL)); 11.87 } 11.88 @@ -504,7 +545,8 @@ static int connect_qemu(blkif_t *blkif, 11.89 static int tapdisk_ioemu_pid = 0; 11.90 static int dom0_readfd = 0; 11.91 static int dom0_writefd = 0; 11.92 - 11.93 + int refresh_pid = 0; 11.94 + 11.95 if (asprintf(&rdctldev, BLKTAP_CTRL_DIR "/qemu-read-%d", domid) < 0) 11.96 return -1; 11.97 11.98 @@ -523,15 +565,23 @@ static int connect_qemu(blkif_t *blkif, 11.99 if (tapdisk_ioemu_pid == 0 || kill(tapdisk_ioemu_pid, 0)) { 11.100 /* No device model and tapdisk-ioemu doesn't run yet */ 11.101 DPRINTF("Launching tapdisk-ioemu\n"); 11.102 - tapdisk_ioemu_pid = launch_tapdisk_ioemu(); 11.103 + launch_tapdisk_ioemu(); 11.104 11.105 dom0_readfd = open_ctrl_socket(wrctldev); 11.106 dom0_writefd = open_ctrl_socket(rdctldev); 11.107 + 11.108 + refresh_pid = 1; 11.109 } 11.110 11.111 DPRINTF("Using tapdisk-ioemu connection\n"); 11.112 blkif->fds[READ] = dom0_readfd; 11.113 blkif->fds[WRITE] = dom0_writefd; 11.114 + 11.115 + if (refresh_pid) { 11.116 + get_tapdisk_pid(blkif); 11.117 + tapdisk_ioemu_pid = blkif->tappid; 11.118 + } 11.119 + 11.120 } else if (access(rdctldev, R_OK | W_OK) == 0) { 11.121 /* Use existing pipe to the device model */ 11.122 DPRINTF("Using qemu-dm connection\n"); 11.123 @@ -605,13 +655,11 @@ static int blktapctrl_new_blkif(blkif_t 11.124 image_t *image; 11.125 blkif_t *exist = NULL; 11.126 static uint16_t next_cookie = 0; 11.127 + int use_ioemu; 11.128 11.129 DPRINTF("Received a poll for a new vbd\n"); 11.130 if ( ((blk=blkif->info) != NULL) && (blk->params != NULL) ) { 11.131 - if (blktap_interface_create(ctlfd, &major, &minor, blkif) < 0) 11.132 - return -1; 11.133 - 11.134 - if (test_path(blk->params, &ptr, &type, &exist) != 0) { 11.135 + if (test_path(blk->params, &ptr, &type, &exist, &use_ioemu) != 0) { 11.136 DPRINTF("Error in blktap device string(%s).\n", 11.137 blk->params); 11.138 goto fail; 11.139 @@ -620,7 +668,7 @@ static int blktapctrl_new_blkif(blkif_t 11.140 blkif->cookie = next_cookie++; 11.141 11.142 if (!exist) { 11.143 - if (type == DISK_TYPE_IOEMU) { 11.144 + if (use_ioemu) { 11.145 if (connect_qemu(blkif, blkif->domid)) 11.146 goto fail; 11.147 } else { 11.148 @@ -634,10 +682,6 @@ static int blktapctrl_new_blkif(blkif_t 11.149 blkif->fds[WRITE] = exist->fds[WRITE]; 11.150 } 11.151 11.152 - add_disktype(blkif, type); 11.153 - blkif->major = major; 11.154 - blkif->minor = minor; 11.155 - 11.156 image = (image_t *)malloc(sizeof(image_t)); 11.157 blkif->prv = (void *)image; 11.158 blkif->ops = &tapdisk_ops; 11.159 @@ -661,11 +705,18 @@ static int blktapctrl_new_blkif(blkif_t 11.160 goto fail; 11.161 } 11.162 11.163 + if (blktap_interface_create(ctlfd, &major, &minor, blkif) < 0) 11.164 + return -1; 11.165 + 11.166 + blkif->major = major; 11.167 + blkif->minor = minor; 11.168 + 11.169 + add_disktype(blkif, type); 11.170 + 11.171 } else return -1; 11.172 11.173 return 0; 11.174 fail: 11.175 - ioctl(ctlfd, BLKTAP_IOCTL_FREEINTF, minor); 11.176 return -EINVAL; 11.177 } 11.178 11.179 @@ -696,6 +747,7 @@ static int unmap_blktapctrl(blkif_t *blk 11.180 } 11.181 11.182 if (del_disktype(blkif)) { 11.183 + DPRINTF("Closing communication pipe to pid %d\n", blkif->tappid); 11.184 close(blkif->fds[WRITE]); 11.185 close(blkif->fds[READ]); 11.186 }
12.1 --- a/tools/blktap/drivers/tapdisk.h Fri Mar 27 10:54:08 2009 +0900 12.2 +++ b/tools/blktap/drivers/tapdisk.h Fri Mar 27 11:07:11 2009 +0900 12.3 @@ -145,6 +145,8 @@ typedef struct disk_info { 12.4 char handle[10]; /* xend handle, e.g. 'ram' */ 12.5 int single_handler; /* is there a single controller for all */ 12.6 /* instances of disk type? */ 12.7 + int use_ioemu; /* backend provider: 0 = tapdisk; 1 = ioemu */ 12.8 + 12.9 #ifdef TAPDISK 12.10 struct tap_disk *drv; 12.11 #endif 12.12 @@ -159,16 +161,6 @@ extern struct tap_disk tapdisk_ram; 12.13 extern struct tap_disk tapdisk_qcow; 12.14 extern struct tap_disk tapdisk_qcow2; 12.15 12.16 -#define MAX_DISK_TYPES 20 12.17 - 12.18 -#define DISK_TYPE_AIO 0 12.19 -#define DISK_TYPE_SYNC 1 12.20 -#define DISK_TYPE_VMDK 2 12.21 -#define DISK_TYPE_RAM 3 12.22 -#define DISK_TYPE_QCOW 4 12.23 -#define DISK_TYPE_QCOW2 5 12.24 -#define DISK_TYPE_IOEMU 6 12.25 - 12.26 12.27 /*Define Individual Disk Parameters here */ 12.28 static disk_info_t aio_disk = { 12.29 @@ -176,6 +168,7 @@ static disk_info_t aio_disk = { 12.30 "raw image (aio)", 12.31 "aio", 12.32 0, 12.33 + 0, 12.34 #ifdef TAPDISK 12.35 &tapdisk_aio, 12.36 #endif 12.37 @@ -186,6 +179,7 @@ static disk_info_t sync_disk = { 12.38 "raw image (sync)", 12.39 "sync", 12.40 0, 12.41 + 0, 12.42 #ifdef TAPDISK 12.43 &tapdisk_sync, 12.44 #endif 12.45 @@ -196,6 +190,7 @@ static disk_info_t vmdk_disk = { 12.46 "vmware image (vmdk)", 12.47 "vmdk", 12.48 1, 12.49 + 0, 12.50 #ifdef TAPDISK 12.51 &tapdisk_vmdk, 12.52 #endif 12.53 @@ -206,6 +201,7 @@ static disk_info_t ram_disk = { 12.54 "ramdisk image (ram)", 12.55 "ram", 12.56 1, 12.57 + 0, 12.58 #ifdef TAPDISK 12.59 &tapdisk_ram, 12.60 #endif 12.61 @@ -216,6 +212,7 @@ static disk_info_t qcow_disk = { 12.62 "qcow disk (qcow)", 12.63 "qcow", 12.64 0, 12.65 + 0, 12.66 #ifdef TAPDISK 12.67 &tapdisk_qcow, 12.68 #endif 12.69 @@ -226,21 +223,12 @@ static disk_info_t qcow2_disk = { 12.70 "qcow2 disk (qcow2)", 12.71 "qcow2", 12.72 0, 12.73 + 0, 12.74 #ifdef TAPDISK 12.75 &tapdisk_qcow2, 12.76 #endif 12.77 }; 12.78 12.79 -static disk_info_t ioemu_disk = { 12.80 - DISK_TYPE_IOEMU, 12.81 - "ioemu disk", 12.82 - "ioemu", 12.83 - 1, 12.84 -#ifdef TAPDISK 12.85 - NULL 12.86 -#endif 12.87 -}; 12.88 - 12.89 /*Main disk info array */ 12.90 static disk_info_t *dtypes[] = { 12.91 &aio_disk, 12.92 @@ -249,7 +237,6 @@ static disk_info_t *dtypes[] = { 12.93 &ram_disk, 12.94 &qcow_disk, 12.95 &qcow2_disk, 12.96 - &ioemu_disk, 12.97 }; 12.98 12.99 typedef struct driver_list_entry {
13.1 --- a/tools/blktap/lib/blktaplib.h Fri Mar 27 10:54:08 2009 +0900 13.2 +++ b/tools/blktap/lib/blktaplib.h Fri Mar 27 11:07:11 2009 +0900 13.3 @@ -210,6 +210,16 @@ typedef struct msg_pid { 13.4 #define CTLMSG_PID 9 13.5 #define CTLMSG_PID_RSP 10 13.6 13.7 +/* disk driver types */ 13.8 +#define MAX_DISK_TYPES 20 13.9 + 13.10 +#define DISK_TYPE_AIO 0 13.11 +#define DISK_TYPE_SYNC 1 13.12 +#define DISK_TYPE_VMDK 2 13.13 +#define DISK_TYPE_RAM 3 13.14 +#define DISK_TYPE_QCOW 4 13.15 +#define DISK_TYPE_QCOW2 5 13.16 + 13.17 /* xenstore/xenbus: */ 13.18 #define DOMNAME "Domain-0" 13.19 int setup_probe_watch(struct xs_handle *h);
14.1 --- a/tools/blktap/lib/xenbus.c Fri Mar 27 10:54:08 2009 +0900 14.2 +++ b/tools/blktap/lib/xenbus.c Fri Mar 27 11:07:11 2009 +0900 14.3 @@ -48,6 +48,7 @@ 14.4 #include <poll.h> 14.5 #include <time.h> 14.6 #include <sys/time.h> 14.7 +#include <unistd.h> 14.8 #include "blktaplib.h" 14.9 #include "list.h" 14.10 #include "xs_api.h" 14.11 @@ -149,6 +150,137 @@ static int backend_remove(struct xs_hand 14.12 return 0; 14.13 } 14.14 14.15 +static int check_sharing(struct xs_handle *h, struct backend_info *be) 14.16 +{ 14.17 + char *dom_uuid; 14.18 + char *cur_dom_uuid; 14.19 + char *path; 14.20 + char *mode; 14.21 + char *params; 14.22 + char **domains; 14.23 + char **devices; 14.24 + int i, j; 14.25 + unsigned int num_dom, num_dev; 14.26 + blkif_info_t *info; 14.27 + int ret = 0; 14.28 + 14.29 + /* If the mode contains '!' or doesn't contain 'w' don't check anything */ 14.30 + xs_gather(h, be->backpath, "mode", NULL, &mode, NULL); 14.31 + if (strchr(mode, '!')) 14.32 + goto out; 14.33 + if (strchr(mode, 'w') == NULL) 14.34 + goto out; 14.35 + 14.36 + /* Get the UUID of the domain we want to attach to */ 14.37 + if (asprintf(&path, "/local/domain/%ld", be->frontend_id) == -1) 14.38 + goto fail; 14.39 + xs_gather(h, path, "vm", NULL, &dom_uuid, NULL); 14.40 + free(path); 14.41 + 14.42 + /* Iterate through the devices of all VMs */ 14.43 + domains = xs_directory(h, XBT_NULL, "backend/tap", &num_dom); 14.44 + if (domains == NULL) 14.45 + num_dom = 0; 14.46 + 14.47 + for (i = 0; !ret && (i < num_dom); i++) { 14.48 + 14.49 + /* If it's the same VM, no action needed */ 14.50 + if (asprintf(&path, "/local/domain/%s", domains[i]) == -1) { 14.51 + ret = -1; 14.52 + break; 14.53 + } 14.54 + xs_gather(h, path, "vm", NULL, &cur_dom_uuid, NULL); 14.55 + free(path); 14.56 + 14.57 + if (!strcmp(cur_dom_uuid, dom_uuid)) { 14.58 + free(cur_dom_uuid); 14.59 + continue; 14.60 + } 14.61 + 14.62 + /* Check the devices */ 14.63 + if (asprintf(&path, "backend/tap/%s", domains[i]) == -1) { 14.64 + ret = -1; 14.65 + free(cur_dom_uuid); 14.66 + break; 14.67 + } 14.68 + devices = xs_directory(h, XBT_NULL, path, &num_dev); 14.69 + if (devices == NULL) 14.70 + num_dev = 0; 14.71 + free(path); 14.72 + 14.73 + for (j = 0; !ret && (j < num_dev); j++) { 14.74 + if (asprintf(&path, "backend/tap/%s/%s", domains[i], devices[j]) == -1) { 14.75 + ret = -1; 14.76 + break; 14.77 + } 14.78 + xs_gather(h, path, "params", NULL, ¶ms, NULL); 14.79 + free(path); 14.80 + 14.81 + info = be->blkif->info; 14.82 + if (strcmp(params, info->params)) { 14.83 + ret = -1; 14.84 + } 14.85 + 14.86 + free(params); 14.87 + } 14.88 + 14.89 + free(cur_dom_uuid); 14.90 + free(devices); 14.91 + } 14.92 + free(domains); 14.93 + free(dom_uuid); 14.94 + goto out; 14.95 + 14.96 +fail: 14.97 + ret = -1; 14.98 +out: 14.99 + free(mode); 14.100 + return ret; 14.101 +} 14.102 + 14.103 +static int check_image(struct xs_handle *h, struct backend_info *be, 14.104 + const char** errmsg) 14.105 +{ 14.106 + const char *tmp; 14.107 + const char *path; 14.108 + int mode; 14.109 + blkif_t *blkif = be->blkif; 14.110 + blkif_info_t *info = blkif->info; 14.111 + 14.112 + /* Strip off the image type */ 14.113 + path = info->params; 14.114 + 14.115 + if (!strncmp(path, "tapdisk:", strlen("tapdisk:"))) { 14.116 + path += strlen("tapdisk:"); 14.117 + } else if (!strncmp(path, "ioemu:", strlen("ioemu:"))) { 14.118 + path += strlen("ioemu:"); 14.119 + } 14.120 + 14.121 + tmp = strchr(path, ':'); 14.122 + if (tmp != NULL) 14.123 + path = tmp + 1; 14.124 + 14.125 + /* Check if the image exists and access is permitted */ 14.126 + mode = R_OK; 14.127 + if (!be->readonly) 14.128 + mode |= W_OK; 14.129 + if (access(path, mode)) { 14.130 + if (errno == ENOENT) 14.131 + *errmsg = "File not found."; 14.132 + else 14.133 + *errmsg = "Insufficient file permissions."; 14.134 + return -1; 14.135 + } 14.136 + 14.137 + /* Check that the image is not attached to a different VM */ 14.138 + if (check_sharing(h, be)) { 14.139 + *errmsg = "File already in use by other domain"; 14.140 + return -1; 14.141 + } 14.142 + 14.143 + return 0; 14.144 +} 14.145 + 14.146 static void ueblktap_setup(struct xs_handle *h, char *bepath) 14.147 { 14.148 struct backend_info *be; 14.149 @@ -156,6 +288,7 @@ static void ueblktap_setup(struct xs_han 14.150 int len, er, deverr; 14.151 long int pdev = 0, handle; 14.152 blkif_info_t *blk; 14.153 + const char* errmsg = NULL; 14.154 14.155 be = be_lookup_be(bepath); 14.156 if (be == NULL) 14.157 @@ -211,6 +344,9 @@ static void ueblktap_setup(struct xs_han 14.158 be->pdev = pdev; 14.159 } 14.160 14.161 + if (check_image(h, be, &errmsg)) 14.162 + goto fail; 14.163 + 14.164 er = blkif_init(be->blkif, handle, be->pdev, be->readonly); 14.165 if (er != 0) { 14.166 DPRINTF("Unable to open device %s\n",blk->params); 14.167 @@ -246,12 +382,21 @@ static void ueblktap_setup(struct xs_han 14.168 } 14.169 14.170 be->blkif->state = CONNECTED; 14.171 + xs_printf(h, be->backpath, "hotplug-status", "connected"); 14.172 + 14.173 DPRINTF("[SETUP] Complete\n\n"); 14.174 goto close; 14.175 14.176 fail: 14.177 - if ( (be != NULL) && (be->blkif != NULL) ) 14.178 + if (be) { 14.179 + if (errmsg == NULL) 14.180 + errmsg = "Setting up the backend failed. See the log " 14.181 + "files in /var/log/xen/ for details."; 14.182 + xs_printf(h, be->backpath, "hotplug-error", errmsg); 14.183 + xs_printf(h, be->backpath, "hotplug-status", "error"); 14.184 + 14.185 backend_remove(h, be); 14.186 + } 14.187 close: 14.188 if (path) 14.189 free(path); 14.190 @@ -286,7 +431,8 @@ static void ueblktap_probe(struct xs_han 14.191 len = strsep_len(bepath, '/', 7); 14.192 if (len < 0) 14.193 goto free_be; 14.194 - bepath[len] = '\0'; 14.195 + if (bepath[len] != '\0') 14.196 + goto free_be; 14.197 14.198 be = malloc(sizeof(*be)); 14.199 if (!be) {
15.1 --- a/tools/console/client/main.c Fri Mar 27 10:54:08 2009 +0900 15.2 +++ b/tools/console/client/main.c Fri Mar 27 11:07:11 2009 +0900 15.3 @@ -35,6 +35,9 @@ 15.4 #include <err.h> 15.5 #include <errno.h> 15.6 #include <string.h> 15.7 +#ifdef __sun__ 15.8 +#include <sys/stropts.h> 15.9 +#endif 15.10 15.11 #include "xs.h" 15.12 15.13 @@ -71,6 +74,21 @@ static void usage(const char *program) { 15.14 , program); 15.15 } 15.16 15.17 +#ifdef __sun__ 15.18 +void cfmakeraw(struct termios *termios_p) 15.19 +{ 15.20 + termios_p->c_iflag &= 15.21 + ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IXON); 15.22 + termios_p->c_oflag &= ~OPOST; 15.23 + termios_p->c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); 15.24 + termios_p->c_cflag &= ~(CSIZE|PARENB); 15.25 + termios_p->c_cflag |= CS8; 15.26 + 15.27 + termios_p->c_cc[VMIN] = 0; 15.28 + termios_p->c_cc[VTIME] = 0; 15.29 +} 15.30 +#endif 15.31 + 15.32 static int get_pty_fd(struct xs_handle *xs, char *path, int seconds) 15.33 /* Check for a pty in xenstore, open it and return its fd. 15.34 * Assumes there is already a watch set in the store for this path. */ 15.35 @@ -80,7 +98,7 @@ static int get_pty_fd(struct xs_handle * 15.36 int xs_fd = xs_fileno(xs), pty_fd = -1; 15.37 int start, now; 15.38 unsigned int len = 0; 15.39 - char *pty_path, **watch_paths;; 15.40 + char *pty_path, **watch_paths; 15.41 15.42 start = now = time(NULL); 15.43 do { 15.44 @@ -104,6 +122,29 @@ static int get_pty_fd(struct xs_handle * 15.45 } 15.46 } 15.47 } while (pty_fd == -1 && (now = time(NULL)) < start + seconds); 15.48 + 15.49 +#ifdef __sun__ 15.50 + if (pty_fd != -1) { 15.51 + struct termios term; 15.52 + 15.53 + /* 15.54 + * The pty may come from either xend (with pygrub) or 15.55 + * xenconsoled. It may have tty semantics set up, or not. 15.56 + * While it isn't strictly necessary to have those 15.57 + * semantics here, it is good to have a consistent 15.58 + * state that is the same as under Linux. 15.59 + * 15.60 + * If tcgetattr fails, they have not been set up, 15.61 + * so go ahead and set them up now, by pushing the 15.62 + * ptem and ldterm streams modules. 15.63 + */ 15.64 + if (tcgetattr(pty_fd, &term) < 0) { 15.65 + ioctl(pty_fd, I_PUSH, "ptem"); 15.66 + ioctl(pty_fd, I_PUSH, "ldterm"); 15.67 + } 15.68 + } 15.69 +#endif 15.70 + 15.71 return pty_fd; 15.72 } 15.73 15.74 @@ -119,12 +160,12 @@ static void init_term(int fd, struct ter 15.75 new_term = *old; 15.76 cfmakeraw(&new_term); 15.77 15.78 - tcsetattr(fd, TCSAFLUSH, &new_term); 15.79 + tcsetattr(fd, TCSANOW, &new_term); 15.80 } 15.81 15.82 static void restore_term(int fd, struct termios *old) 15.83 { 15.84 - tcsetattr(fd, TCSAFLUSH, old); 15.85 + tcsetattr(fd, TCSANOW, old); 15.86 } 15.87 15.88 static int console_loop(int fd, struct xs_handle *xs, char *pty_path) 15.89 @@ -152,7 +193,8 @@ static int console_loop(int fd, struct x 15.90 15.91 if (FD_ISSET(xs_fileno(xs), &fds)) { 15.92 int newfd = get_pty_fd(xs, pty_path, 0); 15.93 - close(fd); 15.94 + if (fd != -1) 15.95 + close(fd); 15.96 if (newfd == -1) 15.97 /* Console PTY has become invalid */ 15.98 return 0;
16.1 --- a/tools/console/daemon/main.c Fri Mar 27 10:54:08 2009 +0900 16.2 +++ b/tools/console/daemon/main.c Fri Mar 27 11:07:11 2009 +0900 16.3 @@ -86,7 +86,9 @@ int main(int argc, char **argv) 16.4 version(argv[0]); 16.5 exit(0); 16.6 case 'v': 16.7 +#ifndef __sun__ 16.8 syslog_option |= LOG_PERROR; 16.9 +#endif 16.10 syslog_mask = LOG_DEBUG; 16.11 break; 16.12 case 'i':
17.1 --- a/tools/examples/xend-config.sxp Fri Mar 27 10:54:08 2009 +0900 17.2 +++ b/tools/examples/xend-config.sxp Fri Mar 27 11:07:11 2009 +0900 17.3 @@ -64,6 +64,7 @@ 17.4 #(xend-relocation-server no) 17.5 (xend-relocation-server yes) 17.6 #(xend-relocation-ssl-server no) 17.7 +#(xend-udev-event-server no) 17.8 17.9 #(xend-unix-path /var/lib/xend/xend-socket) 17.10
18.1 --- a/tools/examples/xmexample.hvm Fri Mar 27 10:54:08 2009 +0900 18.2 +++ b/tools/examples/xmexample.hvm Fri Mar 27 11:07:11 2009 +0900 18.3 @@ -225,6 +225,10 @@ serial='pty' 18.4 #keymap='ja' 18.5 18.6 #----------------------------------------------------------------------------- 18.7 +# Enable/disable xen platform PCI device, default=1 (enabled) 18.8 +#xen_platform_pci=1 18.9 + 18.10 +#----------------------------------------------------------------------------- 18.11 # Configure guest CPUID responses: 18.12 # 18.13 #cpuid=[ '1:ecx=xxxxxxxxxxx00xxxxxxxxxxxxxxxxxxx, 18.14 @@ -264,8 +268,8 @@ serial='pty' 18.15 # Look like a generic 686 : 18.16 # cpuid = [ '0:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0', 18.17 # '1:eax=0x06b1, 18.18 -# ecx=xxxxxxxxxx0000xx00xxx0000000xx0, 18.19 -# edx=xx00000xxxxxxx0xxxxxxxxx0xxxxxx', 18.20 +# ecx=xxxxxxxxxxx0000xx00xxx0000000xx0, 18.21 +# edx=xxx00000xxxxxxx0xxxxxxxxx0xxxxxx', 18.22 # '4:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0', 18.23 # '0x80000000:eax=0x3,ebx=0x0,ecx=0x0,edx=0x0'] 18.24 # with the highest leaf
19.1 --- a/tools/firmware/Makefile Fri Mar 27 10:54:08 2009 +0900 19.2 +++ b/tools/firmware/Makefile Fri Mar 27 11:07:11 2009 +0900 19.3 @@ -2,9 +2,8 @@ XEN_ROOT = ../.. 19.4 include $(XEN_ROOT)/tools/Rules.mk 19.5 19.6 # hvmloader is a 32-bit protected mode binary. 19.7 -# It belongs in /usr/lib, not /usr/lib64. 19.8 TARGET := hvmloader/hvmloader 19.9 -INST_DIR := $(DESTDIR)/usr/lib/xen/boot 19.10 +INST_DIR := $(DESTDIR)$(LIBDIR_x86_32)/xen/boot 19.11 19.12 SUBDIRS := 19.13 SUBDIRS += rombios
20.1 --- a/tools/firmware/hvmloader/acpi/dsdt.asl Fri Mar 27 10:54:08 2009 +0900 20.2 +++ b/tools/firmware/hvmloader/acpi/dsdt.asl Fri Mar 27 11:07:11 2009 +0900 20.3 @@ -981,60 +981,1027 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 20.4 * handle the hotplug action and status, which is beyond the ACPI 20.5 * scope. 20.6 */ 20.7 + Device(S00) 20.8 + { 20.9 + Name (_ADR, 0x00000000) /* Dev 0, Func 0 */ 20.10 + Name (_SUN, 0x00000000) 20.11 20.12 - Device (S1F0) 20.13 + Method (_PS0, 0) 20.14 + { 20.15 + Store (0x00, \_GPE.DPT1) 20.16 + Store (0x80, \_GPE.DPT2) 20.17 + } 20.18 + 20.19 + Method (_PS3, 0) 20.20 + { 20.21 + Store (0x00, \_GPE.DPT1) 20.22 + Store (0x83, \_GPE.DPT2) 20.23 + } 20.24 + 20.25 + Method (_EJ0, 1) 20.26 + { 20.27 + Store (0x00, \_GPE.DPT1) 20.28 + Store (0x88, \_GPE.DPT2) 20.29 + Store (0x1, \_GPE.PH00) /* eject php slot 0x00 */ 20.30 + } 20.31 + 20.32 + Method (_STA, 0) 20.33 + { 20.34 + Store (0x00, \_GPE.DPT1) 20.35 + Store (0x89, \_GPE.DPT2) 20.36 + Return (\_GPE.PH00) /* IN status as the _STA */ 20.37 + } 20.38 + } 20.39 + 20.40 + Device(S01) 20.41 { 20.42 - Name (_ADR, 0x00060000) /* Dev 6, Func 0 */ 20.43 + Name (_ADR, 0x00010000) /* Dev 1, Func 0 */ 20.44 Name (_SUN, 0x00000001) 20.45 20.46 Method (_PS0, 0) 20.47 { 20.48 + Store (0x01, \_GPE.DPT1) 20.49 + Store (0x80, \_GPE.DPT2) 20.50 + } 20.51 + 20.52 + Method (_PS3, 0) 20.53 + { 20.54 + Store (0x01, \_GPE.DPT1) 20.55 + Store (0x83, \_GPE.DPT2) 20.56 + } 20.57 + 20.58 + Method (_EJ0, 1) 20.59 + { 20.60 + Store (0x01, \_GPE.DPT1) 20.61 + Store (0x88, \_GPE.DPT2) 20.62 + Store (0x1, \_GPE.PH01) /* eject php slot 0x01 */ 20.63 + } 20.64 + 20.65 + Method (_STA, 0) 20.66 + { 20.67 + Store (0x01, \_GPE.DPT1) 20.68 + Store (0x89, \_GPE.DPT2) 20.69 + Return (\_GPE.PH01) /* IN status as the _STA */ 20.70 + } 20.71 + } 20.72 + 20.73 + Device(S02) 20.74 + { 20.75 + Name (_ADR, 0x00020000) /* Dev 2, Func 0 */ 20.76 + Name (_SUN, 0x00000002) 20.77 + 20.78 + Method (_PS0, 0) 20.79 + { 20.80 + Store (0x02, \_GPE.DPT1) 20.81 + Store (0x80, \_GPE.DPT2) 20.82 + } 20.83 + 20.84 + Method (_PS3, 0) 20.85 + { 20.86 + Store (0x02, \_GPE.DPT1) 20.87 + Store (0x83, \_GPE.DPT2) 20.88 + } 20.89 + 20.90 + Method (_EJ0, 1) 20.91 + { 20.92 + Store (0x02, \_GPE.DPT1) 20.93 + Store (0x88, \_GPE.DPT2) 20.94 + Store (0x1, \_GPE.PH02) /* eject php slot 0x02 */ 20.95 + } 20.96 + 20.97 + Method (_STA, 0) 20.98 + { 20.99 + Store (0x02, \_GPE.DPT1) 20.100 + Store (0x89, \_GPE.DPT2) 20.101 + Return (\_GPE.PH02) /* IN status as the _STA */ 20.102 + } 20.103 + } 20.104 + 20.105 + Device(S03) 20.106 + { 20.107 + Name (_ADR, 0x00030000) /* Dev 3, Func 0 */ 20.108 + Name (_SUN, 0x00000003) 20.109 + 20.110 + Method (_PS0, 0) 20.111 + { 20.112 + Store (0x03, \_GPE.DPT1) 20.113 + Store (0x80, \_GPE.DPT2) 20.114 + } 20.115 + 20.116 + Method (_PS3, 0) 20.117 + { 20.118 + Store (0x03, \_GPE.DPT1) 20.119 + Store (0x83, \_GPE.DPT2) 20.120 + } 20.121 + 20.122 + Method (_EJ0, 1) 20.123 + { 20.124 + Store (0x03, \_GPE.DPT1) 20.125 + Store (0x88, \_GPE.DPT2) 20.126 + Store (0x1, \_GPE.PH03) /* eject php slot 0x03 */ 20.127 + } 20.128 + 20.129 + Method (_STA, 0) 20.130 + { 20.131 + Store (0x03, \_GPE.DPT1) 20.132 + Store (0x89, \_GPE.DPT2) 20.133 + Return (\_GPE.PH03) /* IN status as the _STA */ 20.134 + } 20.135 + } 20.136 + 20.137 + Device(S04) 20.138 + { 20.139 + Name (_ADR, 0x00040000) /* Dev 4, Func 0 */ 20.140 + Name (_SUN, 0x00000004) 20.141 + 20.142 + Method (_PS0, 0) 20.143 + { 20.144 + Store (0x04, \_GPE.DPT1) 20.145 + Store (0x80, \_GPE.DPT2) 20.146 + } 20.147 + 20.148 + Method (_PS3, 0) 20.149 + { 20.150 + Store (0x04, \_GPE.DPT1) 20.151 + Store (0x83, \_GPE.DPT2) 20.152 + } 20.153 + 20.154 + Method (_EJ0, 1) 20.155 + { 20.156 + Store (0x04, \_GPE.DPT1) 20.157 + Store (0x88, \_GPE.DPT2) 20.158 + Store (0x1, \_GPE.PH04) /* eject php slot 0x04 */ 20.159 + } 20.160 + 20.161 + Method (_STA, 0) 20.162 + { 20.163 + Store (0x04, \_GPE.DPT1) 20.164 + Store (0x89, \_GPE.DPT2) 20.165 + Return (\_GPE.PH04) /* IN status as the _STA */ 20.166 + } 20.167 + } 20.168 + 20.169 + Device(S05) 20.170 + { 20.171 + Name (_ADR, 0x00050000) /* Dev 5, Func 0 */ 20.172 + Name (_SUN, 0x00000005) 20.173 + 20.174 + Method (_PS0, 0) 20.175 + { 20.176 + Store (0x05, \_GPE.DPT1) 20.177 + Store (0x80, \_GPE.DPT2) 20.178 + } 20.179 + 20.180 + Method (_PS3, 0) 20.181 + { 20.182 + Store (0x05, \_GPE.DPT1) 20.183 + Store (0x83, \_GPE.DPT2) 20.184 + } 20.185 + 20.186 + Method (_EJ0, 1) 20.187 + { 20.188 + Store (0x05, \_GPE.DPT1) 20.189 + Store (0x88, \_GPE.DPT2) 20.190 + Store (0x1, \_GPE.PH05) /* eject php slot 0x05 */ 20.191 + } 20.192 + 20.193 + Method (_STA, 0) 20.194 + { 20.195 + Store (0x05, \_GPE.DPT1) 20.196 + Store (0x89, \_GPE.DPT2) 20.197 + Return (\_GPE.PH05) /* IN status as the _STA */ 20.198 + } 20.199 + } 20.200 + 20.201 + Device(S06) 20.202 + { 20.203 + Name (_ADR, 0x00060000) /* Dev 6, Func 0 */ 20.204 + Name (_SUN, 0x00000006) 20.205 + 20.206 + Method (_PS0, 0) 20.207 + { 20.208 + Store (0x06, \_GPE.DPT1) 20.209 + Store (0x80, \_GPE.DPT2) 20.210 + } 20.211 + 20.212 + Method (_PS3, 0) 20.213 + { 20.214 + Store (0x06, \_GPE.DPT1) 20.215 + Store (0x83, \_GPE.DPT2) 20.216 + } 20.217 + 20.218 + Method (_EJ0, 1) 20.219 + { 20.220 + Store (0x06, \_GPE.DPT1) 20.221 + Store (0x88, \_GPE.DPT2) 20.222 + Store (0x1, \_GPE.PH06) /* eject php slot 0x06 */ 20.223 + } 20.224 + 20.225 + Method (_STA, 0) 20.226 + { 20.227 + Store (0x06, \_GPE.DPT1) 20.228 + Store (0x89, \_GPE.DPT2) 20.229 + Return (\_GPE.PH06) /* IN status as the _STA */ 20.230 + } 20.231 + } 20.232 + 20.233 + Device(S07) 20.234 + { 20.235 + Name (_ADR, 0x00070000) /* Dev 7, Func 0 */ 20.236 + Name (_SUN, 0x00000007) 20.237 + 20.238 + Method (_PS0, 0) 20.239 + { 20.240 + Store (0x07, \_GPE.DPT1) 20.241 Store (0x80, \_GPE.DPT2) 20.242 } 20.243 20.244 Method (_PS3, 0) 20.245 { 20.246 + Store (0x07, \_GPE.DPT1) 20.247 + Store (0x83, \_GPE.DPT2) 20.248 + } 20.249 + 20.250 + Method (_EJ0, 1) 20.251 + { 20.252 + Store (0x07, \_GPE.DPT1) 20.253 + Store (0x88, \_GPE.DPT2) 20.254 + Store (0x1, \_GPE.PH07) /* eject php slot 0x07 */ 20.255 + } 20.256 + 20.257 + Method (_STA, 0) 20.258 + { 20.259 + Store (0x07, \_GPE.DPT1) 20.260 + Store (0x89, \_GPE.DPT2) 20.261 + Return (\_GPE.PH07) /* IN status as the _STA */ 20.262 + } 20.263 + } 20.264 + 20.265 + Device(S08) 20.266 + { 20.267 + Name (_ADR, 0x00080000) /* Dev 8, Func 0 */ 20.268 + Name (_SUN, 0x00000008) 20.269 + 20.270 + Method (_PS0, 0) 20.271 + { 20.272 + Store (0x08, \_GPE.DPT1) 20.273 + Store (0x80, \_GPE.DPT2) 20.274 + } 20.275 + 20.276 + Method (_PS3, 0) 20.277 + { 20.278 + Store (0x08, \_GPE.DPT1) 20.279 + Store (0x83, \_GPE.DPT2) 20.280 + } 20.281 + 20.282 + Method (_EJ0, 1) 20.283 + { 20.284 + Store (0x08, \_GPE.DPT1) 20.285 + Store (0x88, \_GPE.DPT2) 20.286 + Store (0x1, \_GPE.PH08) /* eject php slot 0x08 */ 20.287 + } 20.288 + 20.289 + Method (_STA, 0) 20.290 + { 20.291 + Store (0x08, \_GPE.DPT1) 20.292 + Store (0x89, \_GPE.DPT2) 20.293 + Return (\_GPE.PH08) /* IN status as the _STA */ 20.294 + } 20.295 + } 20.296 + 20.297 + Device(S09) 20.298 + { 20.299 + Name (_ADR, 0x00090000) /* Dev 9, Func 0 */ 20.300 + Name (_SUN, 0x00000009) 20.301 + 20.302 + Method (_PS0, 0) 20.303 + { 20.304 + Store (0x09, \_GPE.DPT1) 20.305 + Store (0x80, \_GPE.DPT2) 20.306 + } 20.307 + 20.308 + Method (_PS3, 0) 20.309 + { 20.310 + Store (0x09, \_GPE.DPT1) 20.311 + Store (0x83, \_GPE.DPT2) 20.312 + } 20.313 + 20.314 + Method (_EJ0, 1) 20.315 + { 20.316 + Store (0x09, \_GPE.DPT1) 20.317 + Store (0x88, \_GPE.DPT2) 20.318 + Store (0x1, \_GPE.PH09) /* eject php slot 0x09 */ 20.319 + } 20.320 + 20.321 + Method (_STA, 0) 20.322 + { 20.323 + Store (0x09, \_GPE.DPT1) 20.324 + Store (0x89, \_GPE.DPT2) 20.325 + Return (\_GPE.PH09) /* IN status as the _STA */ 20.326 + } 20.327 + } 20.328 + 20.329 + Device(S0A) 20.330 + { 20.331 + Name (_ADR, 0x000a0000) /* Dev 10, Func 0 */ 20.332 + Name (_SUN, 0x0000000a) 20.333 + 20.334 + Method (_PS0, 0) 20.335 + { 20.336 + Store (0x0a, \_GPE.DPT1) 20.337 + Store (0x80, \_GPE.DPT2) 20.338 + } 20.339 + 20.340 + Method (_PS3, 0) 20.341 + { 20.342 + Store (0x0a, \_GPE.DPT1) 20.343 + Store (0x83, \_GPE.DPT2) 20.344 + } 20.345 + 20.346 + Method (_EJ0, 1) 20.347 + { 20.348 + Store (0x0a, \_GPE.DPT1) 20.349 + Store (0x88, \_GPE.DPT2) 20.350 + Store (0x1, \_GPE.PH0A) /* eject php slot 0x0a */ 20.351 + } 20.352 + 20.353 + Method (_STA, 0) 20.354 + { 20.355 + Store (0x0a, \_GPE.DPT1) 20.356 + Store (0x89, \_GPE.DPT2) 20.357 + Return (\_GPE.PH0A) /* IN status as the _STA */ 20.358 + } 20.359 + } 20.360 + 20.361 + Device(S0B) 20.362 + { 20.363 + Name (_ADR, 0x000b0000) /* Dev 11, Func 0 */ 20.364 + Name (_SUN, 0x0000000b) 20.365 + 20.366 + Method (_PS0, 0) 20.367 + { 20.368 + Store (0x0b, \_GPE.DPT1) 20.369 + Store (0x80, \_GPE.DPT2) 20.370 + } 20.371 + 20.372 + Method (_PS3, 0) 20.373 + { 20.374 + Store (0x0b, \_GPE.DPT1) 20.375 + Store (0x83, \_GPE.DPT2) 20.376 + } 20.377 + 20.378 + Method (_EJ0, 1) 20.379 + { 20.380 + Store (0x0b, \_GPE.DPT1) 20.381 + Store (0x88, \_GPE.DPT2) 20.382 + Store (0x1, \_GPE.PH0B) /* eject php slot 0x0b */ 20.383 + } 20.384 + 20.385 + Method (_STA, 0) 20.386 + { 20.387 + Store (0x0b, \_GPE.DPT1) 20.388 + Store (0x89, \_GPE.DPT2) 20.389 + Return (\_GPE.PH0B) /* IN status as the _STA */ 20.390 + } 20.391 + } 20.392 + 20.393 + Device(S0C) 20.394 + { 20.395 + Name (_ADR, 0x000c0000) /* Dev 12, Func 0 */ 20.396 + Name (_SUN, 0x0000000c) 20.397 + 20.398 + Method (_PS0, 0) 20.399 + { 20.400 + Store (0x0c, \_GPE.DPT1) 20.401 + Store (0x80, \_GPE.DPT2) 20.402 + } 20.403 + 20.404 + Method (_PS3, 0) 20.405 + { 20.406 + Store (0x0c, \_GPE.DPT1) 20.407 + Store (0x83, \_GPE.DPT2) 20.408 + } 20.409 + 20.410 + Method (_EJ0, 1) 20.411 + { 20.412 + Store (0x0c, \_GPE.DPT1) 20.413 + Store (0x88, \_GPE.DPT2) 20.414 + Store (0x1, \_GPE.PH0C) /* eject php slot 0x0c */ 20.415 + } 20.416 + 20.417 + Method (_STA, 0) 20.418 + { 20.419 + Store (0x0c, \_GPE.DPT1) 20.420 + Store (0x89, \_GPE.DPT2) 20.421 + Return (\_GPE.PH0C) /* IN status as the _STA */ 20.422 + } 20.423 + } 20.424 + 20.425 + Device(S0D) 20.426 + { 20.427 + Name (_ADR, 0x000d0000) /* Dev 13, Func 0 */ 20.428 + Name (_SUN, 0x0000000d) 20.429 + 20.430 + Method (_PS0, 0) 20.431 + { 20.432 + Store (0x0d, \_GPE.DPT1) 20.433 + Store (0x80, \_GPE.DPT2) 20.434 + } 20.435 + 20.436 + Method (_PS3, 0) 20.437 + { 20.438 + Store (0x0d, \_GPE.DPT1) 20.439 + Store (0x83, \_GPE.DPT2) 20.440 + } 20.441 + 20.442 + Method (_EJ0, 1) 20.443 + { 20.444 + Store (0x0d, \_GPE.DPT1) 20.445 + Store (0x88, \_GPE.DPT2) 20.446 + Store (0x1, \_GPE.PH0D) /* eject php slot 0x0d */ 20.447 + } 20.448 + 20.449 + Method (_STA, 0) 20.450 + { 20.451 + Store (0x0d, \_GPE.DPT1) 20.452 + Store (0x89, \_GPE.DPT2) 20.453 + Return (\_GPE.PH0D) /* IN status as the _STA */ 20.454 + } 20.455 + } 20.456 + 20.457 + Device(S0E) 20.458 + { 20.459 + Name (_ADR, 0x000e0000) /* Dev 14, Func 0 */ 20.460 + Name (_SUN, 0x0000000e) 20.461 + 20.462 + Method (_PS0, 0) 20.463 + { 20.464 + Store (0x0e, \_GPE.DPT1) 20.465 + Store (0x80, \_GPE.DPT2) 20.466 + } 20.467 + 20.468 + Method (_PS3, 0) 20.469 + { 20.470 + Store (0x0e, \_GPE.DPT1) 20.471 + Store (0x83, \_GPE.DPT2) 20.472 + } 20.473 + 20.474 + Method (_EJ0, 1) 20.475 + { 20.476 + Store (0x0e, \_GPE.DPT1) 20.477 + Store (0x88, \_GPE.DPT2) 20.478 + Store (0x1, \_GPE.PH0E) /* eject php slot 0x0e */ 20.479 + } 20.480 + 20.481 + Method (_STA, 0) 20.482 + { 20.483 + Store (0x0e, \_GPE.DPT1) 20.484 + Store (0x89, \_GPE.DPT2) 20.485 + Return (\_GPE.PH0E) /* IN status as the _STA */ 20.486 + } 20.487 + } 20.488 + 20.489 + Device(S0F) 20.490 + { 20.491 + Name (_ADR, 0x000f0000) /* Dev 15, Func 0 */ 20.492 + Name (_SUN, 0x0000000f) 20.493 + 20.494 + Method (_PS0, 0) 20.495 + { 20.496 + Store (0x0f, \_GPE.DPT1) 20.497 + Store (0x80, \_GPE.DPT2) 20.498 + } 20.499 + 20.500 + Method (_PS3, 0) 20.501 + { 20.502 + Store (0x0f, \_GPE.DPT1) 20.503 Store (0x83, \_GPE.DPT2) 20.504 } 20.505 20.506 Method (_EJ0, 1) 20.507 { 20.508 + Store (0x0f, \_GPE.DPT1) 20.509 Store (0x88, \_GPE.DPT2) 20.510 - Store (0x1, \_GPE.PHP1) /* eject php slot 1*/ 20.511 + Store (0x1, \_GPE.PH0F) /* eject php slot 0x0f */ 20.512 + } 20.513 + 20.514 + Method (_STA, 0) 20.515 + { 20.516 + Store (0x0f, \_GPE.DPT1) 20.517 + Store (0x89, \_GPE.DPT2) 20.518 + Return (\_GPE.PH0F) /* IN status as the _STA */ 20.519 + } 20.520 + } 20.521 + 20.522 + Device(S10) 20.523 + { 20.524 + Name (_ADR, 0x00100000) /* Dev 16, Func 0 */ 20.525 + Name (_SUN, 0x00000010) 20.526 + 20.527 + Method (_PS0, 0) 20.528 + { 20.529 + Store (0x10, \_GPE.DPT1) 20.530 + Store (0x80, \_GPE.DPT2) 20.531 + } 20.532 + 20.533 + Method (_PS3, 0) 20.534 + { 20.535 + Store (0x10, \_GPE.DPT1) 20.536 + Store (0x83, \_GPE.DPT2) 20.537 + } 20.538 + 20.539 + Method (_EJ0, 1) 20.540 + { 20.541 + Store (0x10, \_GPE.DPT1) 20.542 + Store (0x88, \_GPE.DPT2) 20.543 + Store (0x1, \_GPE.PH10) /* eject php slot 0x10 */ 20.544 + } 20.545 + 20.546 + Method (_STA, 0) 20.547 + { 20.548 + Store (0x10, \_GPE.DPT1) 20.549 + Store (0x89, \_GPE.DPT2) 20.550 + Return (\_GPE.PH10) /* IN status as the _STA */ 20.551 + } 20.552 + } 20.553 + 20.554 + Device(S11) 20.555 + { 20.556 + Name (_ADR, 0x00110000) /* Dev 17, Func 0 */ 20.557 + Name (_SUN, 0x00000011) 20.558 + 20.559 + Method (_PS0, 0) 20.560 + { 20.561 + Store (0x11, \_GPE.DPT1) 20.562 + Store (0x80, \_GPE.DPT2) 20.563 + } 20.564 + 20.565 + Method (_PS3, 0) 20.566 + { 20.567 + Store (0x11, \_GPE.DPT1) 20.568 + Store (0x83, \_GPE.DPT2) 20.569 + } 20.570 + 20.571 + Method (_EJ0, 1) 20.572 + { 20.573 + Store (0x11, \_GPE.DPT1) 20.574 + Store (0x88, \_GPE.DPT2) 20.575 + Store (0x1, \_GPE.PH11) /* eject php slot 0x11 */ 20.576 + } 20.577 + 20.578 + Method (_STA, 0) 20.579 + { 20.580 + Store (0x11, \_GPE.DPT1) 20.581 + Store (0x89, \_GPE.DPT2) 20.582 + Return (\_GPE.PH11) /* IN status as the _STA */ 20.583 + } 20.584 + } 20.585 + 20.586 + Device(S12) 20.587 + { 20.588 + Name (_ADR, 0x00120000) /* Dev 18, Func 0 */ 20.589 + Name (_SUN, 0x00000012) 20.590 + 20.591 + Method (_PS0, 0) 20.592 + { 20.593 + Store (0x12, \_GPE.DPT1) 20.594 + Store (0x80, \_GPE.DPT2) 20.595 + } 20.596 + 20.597 + Method (_PS3, 0) 20.598 + { 20.599 + Store (0x12, \_GPE.DPT1) 20.600 + Store (0x83, \_GPE.DPT2) 20.601 + } 20.602 + 20.603 + Method (_EJ0, 1) 20.604 + { 20.605 + Store (0x12, \_GPE.DPT1) 20.606 + Store (0x88, \_GPE.DPT2) 20.607 + Store (0x1, \_GPE.PH12) /* eject php slot 0x12 */ 20.608 + } 20.609 + 20.610 + Method (_STA, 0) 20.611 + { 20.612 + Store (0x12, \_GPE.DPT1) 20.613 + Store (0x89, \_GPE.DPT2) 20.614 + Return (\_GPE.PH12) /* IN status as the _STA */ 20.615 + } 20.616 + } 20.617 + 20.618 + Device(S13) 20.619 + { 20.620 + Name (_ADR, 0x00130000) /* Dev 19, Func 0 */ 20.621 + Name (_SUN, 0x00000013) 20.622 + 20.623 + Method (_PS0, 0) 20.624 + { 20.625 + Store (0x13, \_GPE.DPT1) 20.626 + Store (0x80, \_GPE.DPT2) 20.627 + } 20.628 + 20.629 + Method (_PS3, 0) 20.630 + { 20.631 + Store (0x13, \_GPE.DPT1) 20.632 + Store (0x83, \_GPE.DPT2) 20.633 + } 20.634 + 20.635 + Method (_EJ0, 1) 20.636 + { 20.637 + Store (0x13, \_GPE.DPT1) 20.638 + Store (0x88, \_GPE.DPT2) 20.639 + Store (0x1, \_GPE.PH13) /* eject php slot 0x13 */ 20.640 + } 20.641 + 20.642 + Method (_STA, 0) 20.643 + { 20.644 + Store (0x13, \_GPE.DPT1) 20.645 + Store (0x89, \_GPE.DPT2) 20.646 + Return (\_GPE.PH13) /* IN status as the _STA */ 20.647 + } 20.648 + } 20.649 + 20.650 + Device(S14) 20.651 + { 20.652 + Name (_ADR, 0x00140000) /* Dev 20, Func 0 */ 20.653 + Name (_SUN, 0x00000014) 20.654 + 20.655 + Method (_PS0, 0) 20.656 + { 20.657 + Store (0x14, \_GPE.DPT1) 20.658 + Store (0x80, \_GPE.DPT2) 20.659 + } 20.660 + 20.661 + Method (_PS3, 0) 20.662 + { 20.663 + Store (0x14, \_GPE.DPT1) 20.664 + Store (0x83, \_GPE.DPT2) 20.665 + } 20.666 + 20.667 + Method (_EJ0, 1) 20.668 + { 20.669 + Store (0x14, \_GPE.DPT1) 20.670 + Store (0x88, \_GPE.DPT2) 20.671 + Store (0x1, \_GPE.PH14) /* eject php slot 0x14 */ 20.672 + } 20.673 + 20.674 + Method (_STA, 0) 20.675 + { 20.676 + Store (0x14, \_GPE.DPT1) 20.677 + Store (0x89, \_GPE.DPT2) 20.678 + Return (\_GPE.PH14) /* IN status as the _STA */ 20.679 + } 20.680 + } 20.681 + 20.682 + Device(S15) 20.683 + { 20.684 + Name (_ADR, 0x00150000) /* Dev 21, Func 0 */ 20.685 + Name (_SUN, 0x00000015) 20.686 + 20.687 + Method (_PS0, 0) 20.688 + { 20.689 + Store (0x15, \_GPE.DPT1) 20.690 + Store (0x80, \_GPE.DPT2) 20.691 + } 20.692 + 20.693 + Method (_PS3, 0) 20.694 + { 20.695 + Store (0x15, \_GPE.DPT1) 20.696 + Store (0x83, \_GPE.DPT2) 20.697 + } 20.698 + 20.699 + Method (_EJ0, 1) 20.700 + { 20.701 + Store (0x15, \_GPE.DPT1) 20.702 + Store (0x88, \_GPE.DPT2) 20.703 + Store (0x1, \_GPE.PH15) /* eject php slot 0x15 */ 20.704 + } 20.705 + 20.706 + Method (_STA, 0) 20.707 + { 20.708 + Store (0x15, \_GPE.DPT1) 20.709 + Store (0x89, \_GPE.DPT2) 20.710 + Return (\_GPE.PH15) /* IN status as the _STA */ 20.711 + } 20.712 + } 20.713 + 20.714 + Device(S16) 20.715 + { 20.716 + Name (_ADR, 0x00160000) /* Dev 22, Func 0 */ 20.717 + Name (_SUN, 0x00000016) 20.718 + 20.719 + Method (_PS0, 0) 20.720 + { 20.721 + Store (0x16, \_GPE.DPT1) 20.722 + Store (0x80, \_GPE.DPT2) 20.723 + } 20.724 + 20.725 + Method (_PS3, 0) 20.726 + { 20.727 + Store (0x16, \_GPE.DPT1) 20.728 + Store (0x83, \_GPE.DPT2) 20.729 + } 20.730 + 20.731 + Method (_EJ0, 1) 20.732 + { 20.733 + Store (0x16, \_GPE.DPT1) 20.734 + Store (0x88, \_GPE.DPT2) 20.735 + Store (0x1, \_GPE.PH16) /* eject php slot 0x16 */ 20.736 } 20.737 20.738 Method (_STA, 0) 20.739 { 20.740 + Store (0x16, \_GPE.DPT1) 20.741 Store (0x89, \_GPE.DPT2) 20.742 - Return ( \_GPE.PHP1 ) /* IN status as the _STA */ 20.743 + Return (\_GPE.PH16) /* IN status as the _STA */ 20.744 + } 20.745 + } 20.746 + 20.747 + Device(S17) 20.748 + { 20.749 + Name (_ADR, 0x00170000) /* Dev 23, Func 0 */ 20.750 + Name (_SUN, 0x00000017) 20.751 + 20.752 + Method (_PS0, 0) 20.753 + { 20.754 + Store (0x17, \_GPE.DPT1) 20.755 + Store (0x80, \_GPE.DPT2) 20.756 + } 20.757 + 20.758 + Method (_PS3, 0) 20.759 + { 20.760 + Store (0x17, \_GPE.DPT1) 20.761 + Store (0x83, \_GPE.DPT2) 20.762 + } 20.763 + 20.764 + Method (_EJ0, 1) 20.765 + { 20.766 + Store (0x17, \_GPE.DPT1) 20.767 + Store (0x88, \_GPE.DPT2) 20.768 + Store (0x1, \_GPE.PH17) /* eject php slot 0x17 */ 20.769 + } 20.770 + 20.771 + Method (_STA, 0) 20.772 + { 20.773 + Store (0x17, \_GPE.DPT1) 20.774 + Store (0x89, \_GPE.DPT2) 20.775 + Return (\_GPE.PH17) /* IN status as the _STA */ 20.776 } 20.777 } 20.778 20.779 - Device (S2F0) 20.780 + Device(S18) 20.781 { 20.782 - Name (_ADR, 0x00070000) /* Dev 7, Func 0 */ 20.783 - Name (_SUN, 0x00000002) 20.784 + Name (_ADR, 0x00180000) /* Dev 24, Func 0 */ 20.785 + Name (_SUN, 0x00000018) 20.786 20.787 Method (_PS0, 0) 20.788 { 20.789 - Store (0x90, \_GPE.DPT2) 20.790 + Store (0x18, \_GPE.DPT1) 20.791 + Store (0x80, \_GPE.DPT2) 20.792 + } 20.793 + 20.794 + Method (_PS3, 0) 20.795 + { 20.796 + Store (0x18, \_GPE.DPT1) 20.797 + Store (0x83, \_GPE.DPT2) 20.798 + } 20.799 + 20.800 + Method (_EJ0, 1) 20.801 + { 20.802 + Store (0x18, \_GPE.DPT1) 20.803 + Store (0x88, \_GPE.DPT2) 20.804 + Store (0x1, \_GPE.PH18) /* eject php slot 0x18 */ 20.805 + } 20.806 + 20.807 + Method (_STA, 0) 20.808 + { 20.809 + Store (0x18, \_GPE.DPT1) 20.810 + Store (0x89, \_GPE.DPT2) 20.811 + Return (\_GPE.PH18) /* IN status as the _STA */ 20.812 + } 20.813 + } 20.814 + 20.815 + Device(S19) 20.816 + { 20.817 + Name (_ADR, 0x00190000) /* Dev 25, Func 0 */ 20.818 + Name (_SUN, 0x00000019) 20.819 + 20.820 + Method (_PS0, 0) 20.821 + { 20.822 + Store (0x19, \_GPE.DPT1) 20.823 + Store (0x80, \_GPE.DPT2) 20.824 + } 20.825 + 20.826 + Method (_PS3, 0) 20.827 + { 20.828 + Store (0x19, \_GPE.DPT1) 20.829 + Store (0x83, \_GPE.DPT2) 20.830 + } 20.831 + 20.832 + Method (_EJ0, 1) 20.833 + { 20.834 + Store (0x19, \_GPE.DPT1) 20.835 + Store (0x88, \_GPE.DPT2) 20.836 + Store (0x1, \_GPE.PH19) /* eject php slot 0x19 */ 20.837 + } 20.838 + 20.839 + Method (_STA, 0) 20.840 + { 20.841 + Store (0x19, \_GPE.DPT1) 20.842 + Store (0x89, \_GPE.DPT2) 20.843 + Return (\_GPE.PH19) /* IN status as the _STA */ 20.844 + } 20.845 + } 20.846 + 20.847 + Device(S1A) 20.848 + { 20.849 + Name (_ADR, 0x001a0000) /* Dev 26, Func 0 */ 20.850 + Name (_SUN, 0x0000001a) 20.851 + 20.852 + Method (_PS0, 0) 20.853 + { 20.854 + Store (0x1a, \_GPE.DPT1) 20.855 + Store (0x80, \_GPE.DPT2) 20.856 } 20.857 20.858 Method (_PS3, 0) 20.859 { 20.860 - Store (0x93, \_GPE.DPT2) 20.861 + Store (0x1a, \_GPE.DPT1) 20.862 + Store (0x83, \_GPE.DPT2) 20.863 + } 20.864 + 20.865 + Method (_EJ0, 1) 20.866 + { 20.867 + Store (0x1a, \_GPE.DPT1) 20.868 + Store (0x88, \_GPE.DPT2) 20.869 + Store (0x1, \_GPE.PH1A) /* eject php slot 0x1a */ 20.870 + } 20.871 + 20.872 + Method (_STA, 0) 20.873 + { 20.874 + Store (0x1a, \_GPE.DPT1) 20.875 + Store (0x89, \_GPE.DPT2) 20.876 + Return (\_GPE.PH1A) /* IN status as the _STA */ 20.877 + } 20.878 + } 20.879 + 20.880 + Device(S1B) 20.881 + { 20.882 + Name (_ADR, 0x001b0000) /* Dev 27, Func 0 */ 20.883 + Name (_SUN, 0x0000001b) 20.884 + 20.885 + Method (_PS0, 0) 20.886 + { 20.887 + Store (0x1b, \_GPE.DPT1) 20.888 + Store (0x80, \_GPE.DPT2) 20.889 + } 20.890 + 20.891 + Method (_PS3, 0) 20.892 + { 20.893 + Store (0x1b, \_GPE.DPT1) 20.894 + Store (0x83, \_GPE.DPT2) 20.895 + } 20.896 + 20.897 + Method (_EJ0, 1) 20.898 + { 20.899 + Store (0x1b, \_GPE.DPT1) 20.900 + Store (0x88, \_GPE.DPT2) 20.901 + Store (0x1, \_GPE.PH1B) /* eject php slot 0x1b */ 20.902 + } 20.903 + 20.904 + Method (_STA, 0) 20.905 + { 20.906 + Store (0x1b, \_GPE.DPT1) 20.907 + Store (0x89, \_GPE.DPT2) 20.908 + Return (\_GPE.PH1B) /* IN status as the _STA */ 20.909 + } 20.910 + } 20.911 + 20.912 + Device(S1C) 20.913 + { 20.914 + Name (_ADR, 0x001c0000) /* Dev 28, Func 0 */ 20.915 + Name (_SUN, 0x0000001c) 20.916 + 20.917 + Method (_PS0, 0) 20.918 + { 20.919 + Store (0x1c, \_GPE.DPT1) 20.920 + Store (0x80, \_GPE.DPT2) 20.921 + } 20.922 + 20.923 + Method (_PS3, 0) 20.924 + { 20.925 + Store (0x1c, \_GPE.DPT1) 20.926 + Store (0x83, \_GPE.DPT2) 20.927 } 20.928 20.929 Method (_EJ0, 1) 20.930 { 20.931 - Store (0x98, \_GPE.DPT2) 20.932 - Store (0x1, \_GPE.PHP2) /* eject php slot 1*/ 20.933 + Store (0x1c, \_GPE.DPT1) 20.934 + Store (0x88, \_GPE.DPT2) 20.935 + Store (0x1, \_GPE.PH1C) /* eject php slot 0x1c */ 20.936 + } 20.937 + 20.938 + Method (_STA, 0) 20.939 + { 20.940 + Store (0x1c, \_GPE.DPT1) 20.941 + Store (0x89, \_GPE.DPT2) 20.942 + Return (\_GPE.PH1C) /* IN status as the _STA */ 20.943 + } 20.944 + } 20.945 + 20.946 + Device(S1D) 20.947 + { 20.948 + Name (_ADR, 0x001d0000) /* Dev 29, Func 0 */ 20.949 + Name (_SUN, 0x0000001d) 20.950 + 20.951 + Method (_PS0, 0) 20.952 + { 20.953 + Store (0x1d, \_GPE.DPT1) 20.954 + Store (0x80, \_GPE.DPT2) 20.955 + } 20.956 + 20.957 + Method (_PS3, 0) 20.958 + { 20.959 + Store (0x1d, \_GPE.DPT1) 20.960 + Store (0x83, \_GPE.DPT2) 20.961 + } 20.962 + 20.963 + Method (_EJ0, 1) 20.964 + { 20.965 + Store (0x1d, \_GPE.DPT1) 20.966 + Store (0x88, \_GPE.DPT2) 20.967 + Store (0x1, \_GPE.PH1D) /* eject php slot 0x1d */ 20.968 } 20.969 20.970 Method (_STA, 0) 20.971 { 20.972 - Store (0x99, \_GPE.DPT2) 20.973 - Return ( \_GPE.PHP2 ) /* IN status as the _STA */ 20.974 + Store (0x1d, \_GPE.DPT1) 20.975 + Store (0x89, \_GPE.DPT2) 20.976 + Return (\_GPE.PH1D) /* IN status as the _STA */ 20.977 + } 20.978 + } 20.979 + 20.980 + Device(S1E) 20.981 + { 20.982 + Name (_ADR, 0x001e0000) /* Dev 30, Func 0 */ 20.983 + Name (_SUN, 0x0000001e) 20.984 + 20.985 + Method (_PS0, 0) 20.986 + { 20.987 + Store (0x1e, \_GPE.DPT1) 20.988 + Store (0x80, \_GPE.DPT2) 20.989 + } 20.990 + 20.991 + Method (_PS3, 0) 20.992 + { 20.993 + Store (0x1e, \_GPE.DPT1) 20.994 + Store (0x83, \_GPE.DPT2) 20.995 + } 20.996 + 20.997 + Method (_EJ0, 1) 20.998 + { 20.999 + Store (0x1e, \_GPE.DPT1) 20.1000 + Store (0x88, \_GPE.DPT2) 20.1001 + Store (0x1, \_GPE.PH1E) /* eject php slot 0x1e */ 20.1002 + } 20.1003 + 20.1004 + Method (_STA, 0) 20.1005 + { 20.1006 + Store (0x1e, \_GPE.DPT1) 20.1007 + Store (0x89, \_GPE.DPT2) 20.1008 + Return (\_GPE.PH1E) /* IN status as the _STA */ 20.1009 + } 20.1010 + } 20.1011 + 20.1012 + Device(S1F) 20.1013 + { 20.1014 + Name (_ADR, 0x001f0000) /* Dev 31, Func 0 */ 20.1015 + Name (_SUN, 0x0000001f) 20.1016 + 20.1017 + Method (_PS0, 0) 20.1018 + { 20.1019 + Store (0x1f, \_GPE.DPT1) 20.1020 + Store (0x80, \_GPE.DPT2) 20.1021 + } 20.1022 + 20.1023 + Method (_PS3, 0) 20.1024 + { 20.1025 + Store (0x1f, \_GPE.DPT1) 20.1026 + Store (0x83, \_GPE.DPT2) 20.1027 + } 20.1028 + 20.1029 + Method (_EJ0, 1) 20.1030 + { 20.1031 + Store (0x1f, \_GPE.DPT1) 20.1032 + Store (0x88, \_GPE.DPT2) 20.1033 + Store (0x1, \_GPE.PH1F) /* eject php slot 0x1f */ 20.1034 + } 20.1035 + 20.1036 + Method (_STA, 0) 20.1037 + { 20.1038 + Store (0x1f, \_GPE.DPT1) 20.1039 + Store (0x89, \_GPE.DPT2) 20.1040 + Return (\_GPE.PH1F) /* IN status as the _STA */ 20.1041 } 20.1042 } 20.1043 } 20.1044 @@ -1042,39 +2009,162 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 20.1045 20.1046 Scope (\_GPE) 20.1047 { 20.1048 - OperationRegion (PHP, SystemIO, 0x10c0, 0x03) 20.1049 + OperationRegion (PHP, SystemIO, 0x10c0, 0x22) 20.1050 Field (PHP, ByteAcc, NoLock, Preserve) 20.1051 { 20.1052 - PSTA, 8, /* hotplug controller status reg */ 20.1053 - PHP1, 8, /* hotplug slot 1 control reg */ 20.1054 - PHP2, 8 /* hotplug slot 2 control reg */ 20.1055 - } 20.1056 + PSTA, 8, /* hotplug controller event reg */ 20.1057 + PSTB, 8, /* hotplug controller slot reg */ 20.1058 + PH00, 8, /* hotplug slot 0x00 control reg */ 20.1059 + PH01, 8, /* hotplug slot 0x01 control reg */ 20.1060 + PH02, 8, /* hotplug slot 0x02 control reg */ 20.1061 + PH03, 8, /* hotplug slot 0x03 control reg */ 20.1062 + PH04, 8, /* hotplug slot 0x04 control reg */ 20.1063 + PH05, 8, /* hotplug slot 0x05 control reg */ 20.1064 + PH06, 8, /* hotplug slot 0x06 control reg */ 20.1065 + PH07, 8, /* hotplug slot 0x07 control reg */ 20.1066 + PH08, 8, /* hotplug slot 0x08 control reg */ 20.1067 + PH09, 8, /* hotplug slot 0x09 control reg */ 20.1068 + PH0A, 8, /* hotplug slot 0x0a control reg */ 20.1069 + PH0B, 8, /* hotplug slot 0x0b control reg */ 20.1070 + PH0C, 8, /* hotplug slot 0x0c control reg */ 20.1071 + PH0D, 8, /* hotplug slot 0x0d control reg */ 20.1072 + PH0E, 8, /* hotplug slot 0x0e control reg */ 20.1073 + PH0F, 8, /* hotplug slot 0x0f control reg */ 20.1074 + PH10, 8, /* hotplug slot 0x10 control reg */ 20.1075 + PH11, 8, /* hotplug slot 0x11 control reg */ 20.1076 + PH12, 8, /* hotplug slot 0x12 control reg */ 20.1077 + PH13, 8, /* hotplug slot 0x13 control reg */ 20.1078 + PH14, 8, /* hotplug slot 0x14 control reg */ 20.1079 + PH15, 8, /* hotplug slot 0x15 control reg */ 20.1080 + PH16, 8, /* hotplug slot 0x16 control reg */ 20.1081 + PH17, 8, /* hotplug slot 0x17 control reg */ 20.1082 + PH18, 8, /* hotplug slot 0x18 control reg */ 20.1083 + PH19, 8, /* hotplug slot 0x19 control reg */ 20.1084 + PH1A, 8, /* hotplug slot 0x1a control reg */ 20.1085 + PH1B, 8, /* hotplug slot 0x1b control reg */ 20.1086 + PH1C, 8, /* hotplug slot 0x1c control reg */ 20.1087 + PH1D, 8, /* hotplug slot 0x1d control reg */ 20.1088 + PH1E, 8, /* hotplug slot 0x1e control reg */ 20.1089 + PH1F, 8 /* hotplug slot 0x1f control reg */ 20.1090 + } 20.1091 OperationRegion (DG1, SystemIO, 0xb044, 0x04) 20.1092 Field (DG1, ByteAcc, NoLock, Preserve) 20.1093 { 20.1094 DPT1, 8, 20.1095 DPT2, 8 20.1096 } 20.1097 - Method (_L03, 0, NotSerialized) 20.1098 + Method (_L03, 0, Serialized) 20.1099 { 20.1100 /* detect slot and event(remove/add) */ 20.1101 Name (SLT, 0x0) 20.1102 Name (EVT, 0x0) 20.1103 Store (PSTA, Local1) 20.1104 - ShiftRight (Local1, 0x4, SLT) 20.1105 And (Local1, 0xf, EVT) 20.1106 + Store (PSTB, Local1) /* XXX: Store (PSTB, SLT) ? */ 20.1107 + And (Local1, 0xff, SLT) 20.1108 20.1109 /* debug */ 20.1110 Store (SLT, DPT1) 20.1111 Store (EVT, DPT2) 20.1112 20.1113 - If ( LEqual(SLT, 0x1) ) 20.1114 + Switch (SLT) 20.1115 { 20.1116 - Notify (\_SB.PCI0.S1F0, EVT) 20.1117 - } 20.1118 - ElseIf ( LEqual(SLT, 0x2) ) 20.1119 - { 20.1120 - Notify (\_SB.PCI0.S2F0, EVT) 20.1121 + Case (0x00) { 20.1122 + Notify (\_SB.PCI0.S00, EVT) 20.1123 + } 20.1124 + Case (0x01) { 20.1125 + Notify (\_SB.PCI0.S01, EVT) 20.1126 + } 20.1127 + Case (0x02) { 20.1128 + Notify (\_SB.PCI0.S02, EVT) 20.1129 + } 20.1130 + Case (0x03) { 20.1131 + Notify (\_SB.PCI0.S03, EVT) 20.1132 + } 20.1133 + Case (0x04) { 20.1134 + Notify (\_SB.PCI0.S04, EVT) 20.1135 + } 20.1136 + Case (0x05) { 20.1137 + Notify (\_SB.PCI0.S05, EVT) 20.1138 + } 20.1139 + Case (0x06) { 20.1140 + Notify (\_SB.PCI0.S06, EVT) 20.1141 + } 20.1142 + Case (0x07) { 20.1143 + Notify (\_SB.PCI0.S07, EVT) 20.1144 + } 20.1145 + Case (0x08) { 20.1146 + Notify (\_SB.PCI0.S08, EVT) 20.1147 + } 20.1148 + Case (0x09) { 20.1149 + Notify (\_SB.PCI0.S09, EVT) 20.1150 + } 20.1151 + Case (0x0a) { 20.1152 + Notify (\_SB.PCI0.S0A, EVT) 20.1153 + } 20.1154 + Case (0x0b) { 20.1155 + Notify (\_SB.PCI0.S0B, EVT) 20.1156 + } 20.1157 + Case (0x0c) { 20.1158 + Notify (\_SB.PCI0.S0C, EVT) 20.1159 + } 20.1160 + Case (0x0d) { 20.1161 + Notify (\_SB.PCI0.S0D, EVT) 20.1162 + } 20.1163 + Case (0x0e) { 20.1164 + Notify (\_SB.PCI0.S0E, EVT) 20.1165 + } 20.1166 + Case (0x0f) { 20.1167 + Notify (\_SB.PCI0.S0F, EVT) 20.1168 + } 20.1169 + Case (0x10) { 20.1170 + Notify (\_SB.PCI0.S10, EVT) 20.1171 + } 20.1172 + Case (0x11) { 20.1173 + Notify (\_SB.PCI0.S11, EVT) 20.1174 + } 20.1175 + Case (0x12) { 20.1176 + Notify (\_SB.PCI0.S12, EVT) 20.1177 + } 20.1178 + Case (0x13) { 20.1179 + Notify (\_SB.PCI0.S13, EVT) 20.1180 + } 20.1181 + Case (0x14) { 20.1182 + Notify (\_SB.PCI0.S14, EVT) 20.1183 + } 20.1184 + Case (0x15) { 20.1185 + Notify (\_SB.PCI0.S15, EVT) 20.1186 + } 20.1187 + Case (0x16) { 20.1188 + Notify (\_SB.PCI0.S16, EVT) 20.1189 + } 20.1190 + Case (0x17) { 20.1191 + Notify (\_SB.PCI0.S17, EVT) 20.1192 + } 20.1193 + Case (0x18) { 20.1194 + Notify (\_SB.PCI0.S18, EVT) 20.1195 + } 20.1196 + Case (0x19) { 20.1197 + Notify (\_SB.PCI0.S19, EVT) 20.1198 + } 20.1199 + Case (0x1a) { 20.1200 + Notify (\_SB.PCI0.S1A, EVT) 20.1201 + } 20.1202 + Case (0x1b) { 20.1203 + Notify (\_SB.PCI0.S1B, EVT) 20.1204 + } 20.1205 + Case (0x1c) { 20.1206 + Notify (\_SB.PCI0.S1C, EVT) 20.1207 + } 20.1208 + Case (0x1d) { 20.1209 + Notify (\_SB.PCI0.S1D, EVT) 20.1210 + } 20.1211 + Case (0x1e) { 20.1212 + Notify (\_SB.PCI0.S1E, EVT) 20.1213 + } 20.1214 + Case (0x1f) { 20.1215 + Notify (\_SB.PCI0.S1F, EVT) 20.1216 + } 20.1217 } 20.1218 } 20.1219 }
21.1 --- a/tools/firmware/hvmloader/acpi/dsdt.c Fri Mar 27 10:54:08 2009 +0900 21.2 +++ b/tools/firmware/hvmloader/acpi/dsdt.c Fri Mar 27 11:07:11 2009 +0900 21.3 @@ -5,15 +5,15 @@ 21.4 * Copyright (C) 2000 - 2009 Intel Corporation 21.5 * Supports ACPI Specification Revision 3.0a 21.6 * 21.7 - * Compilation of "dsdt.asl" - Mon Mar 9 09:11:00 2009 21.8 + * Compilation of "dsdt.asl" - Tue Mar 17 10:44:21 2009 21.9 * 21.10 * C source code output 21.11 * 21.12 */ 21.13 unsigned char AmlCode[] = 21.14 { 21.15 - 0x44,0x53,0x44,0x54,0x20,0x18,0x00,0x00, /* 00000000 "DSDT ..." */ 21.16 - 0x02,0x5B,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 ".[Xen..." */ 21.17 + 0x44,0x53,0x44,0x54,0x02,0x32,0x00,0x00, /* 00000000 "DSDT.2.." */ 21.18 + 0x02,0xC6,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ 21.19 0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */ 21.20 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ 21.21 0x20,0x02,0x09,0x20,0x08,0x50,0x4D,0x42, /* 00000020 " .. .PMB" */ 21.22 @@ -56,7 +56,7 @@ unsigned char AmlCode[] = 21.23 0x07,0x0A,0x07,0x00,0x00,0x08,0x50,0x49, /* 00000148 "......PI" */ 21.24 0x43,0x44,0x00,0x14,0x0C,0x5F,0x50,0x49, /* 00000150 "CD..._PI" */ 21.25 0x43,0x01,0x70,0x68,0x50,0x49,0x43,0x44, /* 00000158 "C.phPICD" */ 21.26 - 0x10,0x80,0x60,0x01,0x5F,0x53,0x42,0x5F, /* 00000160 "..`._SB_" */ 21.27 + 0x10,0x83,0xB7,0x02,0x5F,0x53,0x42,0x5F, /* 00000160 "...._SB_" */ 21.28 0x5B,0x80,0x42,0x49,0x4F,0x53,0x00,0x0C, /* 00000168 "[.BIOS.." */ 21.29 0x00,0xA0,0x0E,0x00,0x0A,0x10,0x5B,0x81, /* 00000170 "......[." */ 21.30 0x21,0x42,0x49,0x4F,0x53,0x01,0x55,0x41, /* 00000178 "!BIOS.UA" */ 21.31 @@ -72,8 +72,8 @@ unsigned char AmlCode[] = 21.32 0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00, /* 000001C8 "........" */ 21.33 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000001D0 "........" */ 21.34 0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, /* 000001D8 "........" */ 21.35 - 0x00,0x00,0x79,0x00,0x5B,0x82,0x8B,0x57, /* 000001E0 "..y.[..W" */ 21.36 - 0x01,0x50,0x43,0x49,0x30,0x08,0x5F,0x48, /* 000001E8 ".PCI0._H" */ 21.37 + 0x00,0x00,0x79,0x00,0x5B,0x82,0x8E,0xAE, /* 000001E0 "..y.[..." */ 21.38 + 0x02,0x50,0x43,0x49,0x30,0x08,0x5F,0x48, /* 000001E8 ".PCI0._H" */ 21.39 0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08, /* 000001F0 "ID.A...." */ 21.40 0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,0x41, /* 000001F8 "_UID.._A" */ 21.41 0x44,0x52,0x00,0x08,0x5F,0x42,0x42,0x4E, /* 00000200 "DR.._BBN" */ 21.42 @@ -728,62 +728,890 @@ unsigned char AmlCode[] = 21.43 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00001648 "....._CR" */ 21.44 0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0x78, /* 00001650 "S....G.x" */ 21.45 0x03,0x78,0x03,0x08,0x08,0x22,0x80,0x00, /* 00001658 ".x...".." */ 21.46 - 0x79,0x00,0x5B,0x82,0x4D,0x07,0x53,0x31, /* 00001660 "y.[.M.S1" */ 21.47 - 0x46,0x30,0x08,0x5F,0x41,0x44,0x52,0x0C, /* 00001668 "F0._ADR." */ 21.48 - 0x00,0x00,0x06,0x00,0x08,0x5F,0x53,0x55, /* 00001670 "....._SU" */ 21.49 - 0x4E,0x01,0x14,0x13,0x5F,0x50,0x53,0x30, /* 00001678 "N..._PS0" */ 21.50 - 0x00,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00001680 ".p..\._G" */ 21.51 - 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x13, /* 00001688 "PEDPT2.." */ 21.52 - 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x83, /* 00001690 "_PS3.p.." */ 21.53 - 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001698 "\._GPEDP" */ 21.54 - 0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A,0x30, /* 000016A0 "T2.._EJ0" */ 21.55 - 0x01,0x70,0x0A,0x88,0x5C,0x2E,0x5F,0x47, /* 000016A8 ".p..\._G" */ 21.56 - 0x50,0x45,0x44,0x50,0x54,0x32,0x70,0x01, /* 000016B0 "PEDPT2p." */ 21.57 - 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48, /* 000016B8 "\._GPEPH" */ 21.58 - 0x50,0x31,0x14,0x1E,0x5F,0x53,0x54,0x41, /* 000016C0 "P1.._STA" */ 21.59 - 0x00,0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47, /* 000016C8 ".p..\._G" */ 21.60 - 0x50,0x45,0x44,0x50,0x54,0x32,0xA4,0x5C, /* 000016D0 "PEDPT2.\" */ 21.61 - 0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,0x50, /* 000016D8 "._GPEPHP" */ 21.62 - 0x31,0x5B,0x82,0x4E,0x07,0x53,0x32,0x46, /* 000016E0 "1[.N.S2F" */ 21.63 - 0x30,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 000016E8 "0._ADR.." */ 21.64 - 0x00,0x07,0x00,0x08,0x5F,0x53,0x55,0x4E, /* 000016F0 "...._SUN" */ 21.65 - 0x0A,0x02,0x14,0x13,0x5F,0x50,0x53,0x30, /* 000016F8 "...._PS0" */ 21.66 - 0x00,0x70,0x0A,0x90,0x5C,0x2E,0x5F,0x47, /* 00001700 ".p..\._G" */ 21.67 - 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x13, /* 00001708 "PEDPT2.." */ 21.68 - 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x93, /* 00001710 "_PS3.p.." */ 21.69 - 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001718 "\._GPEDP" */ 21.70 - 0x54,0x32,0x14,0x1F,0x5F,0x45,0x4A,0x30, /* 00001720 "T2.._EJ0" */ 21.71 - 0x01,0x70,0x0A,0x98,0x5C,0x2E,0x5F,0x47, /* 00001728 ".p..\._G" */ 21.72 - 0x50,0x45,0x44,0x50,0x54,0x32,0x70,0x01, /* 00001730 "PEDPT2p." */ 21.73 - 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48, /* 00001738 "\._GPEPH" */ 21.74 - 0x50,0x32,0x14,0x1E,0x5F,0x53,0x54,0x41, /* 00001740 "P2.._STA" */ 21.75 - 0x00,0x70,0x0A,0x99,0x5C,0x2E,0x5F,0x47, /* 00001748 ".p..\._G" */ 21.76 - 0x50,0x45,0x44,0x50,0x54,0x32,0xA4,0x5C, /* 00001750 "PEDPT2.\" */ 21.77 - 0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,0x50, /* 00001758 "._GPEPHP" */ 21.78 - 0x32,0x10,0x4E,0x0B,0x5F,0x47,0x50,0x45, /* 00001760 "2.N._GPE" */ 21.79 - 0x5B,0x80,0x50,0x48,0x50,0x5F,0x01,0x0B, /* 00001768 "[.PHP_.." */ 21.80 - 0xC0,0x10,0x0A,0x03,0x5B,0x81,0x15,0x50, /* 00001770 "....[..P" */ 21.81 - 0x48,0x50,0x5F,0x01,0x50,0x53,0x54,0x41, /* 00001778 "HP_.PSTA" */ 21.82 - 0x08,0x50,0x48,0x50,0x31,0x08,0x50,0x48, /* 00001780 ".PHP1.PH" */ 21.83 - 0x50,0x32,0x08,0x5B,0x80,0x44,0x47,0x31, /* 00001788 "P2.[.DG1" */ 21.84 - 0x5F,0x01,0x0B,0x44,0xB0,0x0A,0x04,0x5B, /* 00001790 "_..D...[" */ 21.85 - 0x81,0x10,0x44,0x47,0x31,0x5F,0x01,0x44, /* 00001798 "..DG1_.D" */ 21.86 - 0x50,0x54,0x31,0x08,0x44,0x50,0x54,0x32, /* 000017A0 "PT1.DPT2" */ 21.87 - 0x08,0x14,0x46,0x07,0x5F,0x4C,0x30,0x33, /* 000017A8 "..F._L03" */ 21.88 - 0x00,0x08,0x53,0x4C,0x54,0x5F,0x00,0x08, /* 000017B0 "..SLT_.." */ 21.89 - 0x45,0x56,0x54,0x5F,0x00,0x70,0x50,0x53, /* 000017B8 "EVT_.pPS" */ 21.90 - 0x54,0x41,0x61,0x7A,0x61,0x0A,0x04,0x53, /* 000017C0 "TAaza..S" */ 21.91 - 0x4C,0x54,0x5F,0x7B,0x61,0x0A,0x0F,0x45, /* 000017C8 "LT_{a..E" */ 21.92 - 0x56,0x54,0x5F,0x70,0x53,0x4C,0x54,0x5F, /* 000017D0 "VT_pSLT_" */ 21.93 - 0x44,0x50,0x54,0x31,0x70,0x45,0x56,0x54, /* 000017D8 "DPT1pEVT" */ 21.94 - 0x5F,0x44,0x50,0x54,0x32,0xA0,0x1B,0x93, /* 000017E0 "_DPT2..." */ 21.95 - 0x53,0x4C,0x54,0x5F,0x01,0x86,0x5C,0x2F, /* 000017E8 "SLT_..\/" */ 21.96 - 0x03,0x5F,0x53,0x42,0x5F,0x50,0x43,0x49, /* 000017F0 "._SB_PCI" */ 21.97 - 0x30,0x53,0x31,0x46,0x30,0x45,0x56,0x54, /* 000017F8 "0S1F0EVT" */ 21.98 - 0x5F,0xA1,0x1E,0xA0,0x1C,0x93,0x53,0x4C, /* 00001800 "_.....SL" */ 21.99 - 0x54,0x5F,0x0A,0x02,0x86,0x5C,0x2F,0x03, /* 00001808 "T_...\/." */ 21.100 - 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00001810 "_SB_PCI0" */ 21.101 - 0x53,0x32,0x46,0x30,0x45,0x56,0x54,0x5F, /* 00001818 "S2F0EVT_" */ 21.102 - 21.103 + 0x79,0x00,0x5B,0x82,0x49,0x0A,0x53,0x30, /* 00001660 "y.[.I.S0" */ 21.104 + 0x30,0x5F,0x08,0x5F,0x41,0x44,0x52,0x00, /* 00001668 "0_._ADR." */ 21.105 + 0x08,0x5F,0x53,0x55,0x4E,0x00,0x14,0x1F, /* 00001670 "._SUN..." */ 21.106 + 0x5F,0x50,0x53,0x30,0x00,0x70,0x00,0x5C, /* 00001678 "_PS0.p.\" */ 21.107 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001680 "._GPEDPT" */ 21.108 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00001688 "1p..\._G" */ 21.109 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x1F, /* 00001690 "PEDPT2.." */ 21.110 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x00,0x5C, /* 00001698 "_PS3.p.\" */ 21.111 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000016A0 "._GPEDPT" */ 21.112 + 0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F,0x47, /* 000016A8 "1p..\._G" */ 21.113 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x2B, /* 000016B0 "PEDPT2.+" */ 21.114 + 0x5F,0x45,0x4A,0x30,0x01,0x70,0x00,0x5C, /* 000016B8 "_EJ0.p.\" */ 21.115 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000016C0 "._GPEDPT" */ 21.116 + 0x31,0x70,0x0A,0x88,0x5C,0x2E,0x5F,0x47, /* 000016C8 "1p..\._G" */ 21.117 + 0x50,0x45,0x44,0x50,0x54,0x32,0x70,0x01, /* 000016D0 "PEDPT2p." */ 21.118 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x50,0x48, /* 000016D8 "\._GPEPH" */ 21.119 + 0x30,0x30,0x14,0x2A,0x5F,0x53,0x54,0x41, /* 000016E0 "00.*_STA" */ 21.120 + 0x00,0x70,0x00,0x5C,0x2E,0x5F,0x47,0x50, /* 000016E8 ".p.\._GP" */ 21.121 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x89, /* 000016F0 "EDPT1p.." */ 21.122 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 000016F8 "\._GPEDP" */ 21.123 + 0x54,0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50, /* 00001700 "T2.\._GP" */ 21.124 + 0x45,0x50,0x48,0x30,0x30,0x5B,0x82,0x4D, /* 00001708 "EPH00[.M" */ 21.125 + 0x0A,0x53,0x30,0x31,0x5F,0x08,0x5F,0x41, /* 00001710 ".S01_._A" */ 21.126 + 0x44,0x52,0x0C,0x00,0x00,0x01,0x00,0x08, /* 00001718 "DR......" */ 21.127 + 0x5F,0x53,0x55,0x4E,0x01,0x14,0x1F,0x5F, /* 00001720 "_SUN..._" */ 21.128 + 0x50,0x53,0x30,0x00,0x70,0x01,0x5C,0x2E, /* 00001728 "PS0.p.\." */ 21.129 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00001730 "_GPEDPT1" */ 21.130 + 0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47,0x50, /* 00001738 "p..\._GP" */ 21.131 + 0x45,0x44,0x50,0x54,0x32,0x14,0x1F,0x5F, /* 00001740 "EDPT2.._" */ 21.132 + 0x50,0x53,0x33,0x00,0x70,0x01,0x5C,0x2E, /* 00001748 "PS3.p.\." */ 21.133 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00001750 "_GPEDPT1" */ 21.134 + 0x70,0x0A,0x83,0x5C,0x2E,0x5F,0x47,0x50, /* 00001758 "p..\._GP" */ 21.135 + 0x45,0x44,0x50,0x54,0x32,0x14,0x2B,0x5F, /* 00001760 "EDPT2.+_" */ 21.136 + 0x45,0x4A,0x30,0x01,0x70,0x01,0x5C,0x2E, /* 00001768 "EJ0.p.\." */ 21.137 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00001770 "_GPEDPT1" */ 21.138 + 0x70,0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50, /* 00001778 "p..\._GP" */ 21.139 + 0x45,0x44,0x50,0x54,0x32,0x70,0x01,0x5C, /* 00001780 "EDPT2p.\" */ 21.140 + 0x2E,0x5F,0x47,0x50,0x45,0x50,0x48,0x30, /* 00001788 "._GPEPH0" */ 21.141 + 0x31,0x14,0x2A,0x5F,0x53,0x54,0x41,0x00, /* 00001790 "1.*_STA." */ 21.142 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001798 "p.\._GPE" */ 21.143 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 000017A0 "DPT1p..\" */ 21.144 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000017A8 "._GPEDPT" */ 21.145 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000017B0 "2.\._GPE" */ 21.146 + 0x50,0x48,0x30,0x31,0x5B,0x82,0x42,0x0B, /* 000017B8 "PH01[.B." */ 21.147 + 0x53,0x30,0x32,0x5F,0x08,0x5F,0x41,0x44, /* 000017C0 "S02_._AD" */ 21.148 + 0x52,0x0C,0x00,0x00,0x02,0x00,0x08,0x5F, /* 000017C8 "R......_" */ 21.149 + 0x53,0x55,0x4E,0x0A,0x02,0x14,0x20,0x5F, /* 000017D0 "SUN... _" */ 21.150 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x02,0x5C, /* 000017D8 "PS0.p..\" */ 21.151 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000017E0 "._GPEDPT" */ 21.152 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 000017E8 "1p..\._G" */ 21.153 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 000017F0 "PEDPT2. " */ 21.154 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x02, /* 000017F8 "_PS3.p.." */ 21.155 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001800 "\._GPEDP" */ 21.156 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00001808 "T1p..\._" */ 21.157 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00001810 "GPEDPT2." */ 21.158 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00001818 ",_EJ0.p." */ 21.159 + 0x02,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001820 ".\._GPED" */ 21.160 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00001828 "PT1p..\." */ 21.161 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001830 "_GPEDPT2" */ 21.162 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001838 "p.\._GPE" */ 21.163 + 0x50,0x48,0x30,0x32,0x14,0x2B,0x5F,0x53, /* 00001840 "PH02.+_S" */ 21.164 + 0x54,0x41,0x00,0x70,0x0A,0x02,0x5C,0x2E, /* 00001848 "TA.p..\." */ 21.165 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00001850 "_GPEDPT1" */ 21.166 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00001858 "p..\._GP" */ 21.167 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00001860 "EDPT2.\." */ 21.168 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x32, /* 00001868 "_GPEPH02" */ 21.169 + 0x5B,0x82,0x42,0x0B,0x53,0x30,0x33,0x5F, /* 00001870 "[.B.S03_" */ 21.170 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00001878 "._ADR..." */ 21.171 + 0x03,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00001880 "..._SUN." */ 21.172 + 0x03,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00001888 ".. _PS0." */ 21.173 + 0x70,0x0A,0x03,0x5C,0x2E,0x5F,0x47,0x50, /* 00001890 "p..\._GP" */ 21.174 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00001898 "EDPT1p.." */ 21.175 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 000018A0 "\._GPEDP" */ 21.176 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 000018A8 "T2. _PS3" */ 21.177 + 0x00,0x70,0x0A,0x03,0x5C,0x2E,0x5F,0x47, /* 000018B0 ".p..\._G" */ 21.178 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 000018B8 "PEDPT1p." */ 21.179 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 000018C0 ".\._GPED" */ 21.180 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 000018C8 "PT2.,_EJ" */ 21.181 + 0x30,0x01,0x70,0x0A,0x03,0x5C,0x2E,0x5F, /* 000018D0 "0.p..\._" */ 21.182 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 000018D8 "GPEDPT1p" */ 21.183 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000018E0 "..\._GPE" */ 21.184 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 000018E8 "DPT2p.\." */ 21.185 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x33, /* 000018F0 "_GPEPH03" */ 21.186 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 000018F8 ".+_STA.p" */ 21.187 + 0x0A,0x03,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001900 "..\._GPE" */ 21.188 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00001908 "DPT1p..\" */ 21.189 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001910 "._GPEDPT" */ 21.190 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001918 "2.\._GPE" */ 21.191 + 0x50,0x48,0x30,0x33,0x5B,0x82,0x42,0x0B, /* 00001920 "PH03[.B." */ 21.192 + 0x53,0x30,0x34,0x5F,0x08,0x5F,0x41,0x44, /* 00001928 "S04_._AD" */ 21.193 + 0x52,0x0C,0x00,0x00,0x04,0x00,0x08,0x5F, /* 00001930 "R......_" */ 21.194 + 0x53,0x55,0x4E,0x0A,0x04,0x14,0x20,0x5F, /* 00001938 "SUN... _" */ 21.195 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x04,0x5C, /* 00001940 "PS0.p..\" */ 21.196 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001948 "._GPEDPT" */ 21.197 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00001950 "1p..\._G" */ 21.198 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00001958 "PEDPT2. " */ 21.199 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x04, /* 00001960 "_PS3.p.." */ 21.200 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001968 "\._GPEDP" */ 21.201 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00001970 "T1p..\._" */ 21.202 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00001978 "GPEDPT2." */ 21.203 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00001980 ",_EJ0.p." */ 21.204 + 0x04,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001988 ".\._GPED" */ 21.205 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00001990 "PT1p..\." */ 21.206 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001998 "_GPEDPT2" */ 21.207 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000019A0 "p.\._GPE" */ 21.208 + 0x50,0x48,0x30,0x34,0x14,0x2B,0x5F,0x53, /* 000019A8 "PH04.+_S" */ 21.209 + 0x54,0x41,0x00,0x70,0x0A,0x04,0x5C,0x2E, /* 000019B0 "TA.p..\." */ 21.210 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 000019B8 "_GPEDPT1" */ 21.211 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 000019C0 "p..\._GP" */ 21.212 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 000019C8 "EDPT2.\." */ 21.213 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x34, /* 000019D0 "_GPEPH04" */ 21.214 + 0x5B,0x82,0x42,0x0B,0x53,0x30,0x35,0x5F, /* 000019D8 "[.B.S05_" */ 21.215 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 000019E0 "._ADR..." */ 21.216 + 0x05,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 000019E8 "..._SUN." */ 21.217 + 0x05,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 000019F0 ".. _PS0." */ 21.218 + 0x70,0x0A,0x05,0x5C,0x2E,0x5F,0x47,0x50, /* 000019F8 "p..\._GP" */ 21.219 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00001A00 "EDPT1p.." */ 21.220 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001A08 "\._GPEDP" */ 21.221 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00001A10 "T2. _PS3" */ 21.222 + 0x00,0x70,0x0A,0x05,0x5C,0x2E,0x5F,0x47, /* 00001A18 ".p..\._G" */ 21.223 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00001A20 "PEDPT1p." */ 21.224 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001A28 ".\._GPED" */ 21.225 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00001A30 "PT2.,_EJ" */ 21.226 + 0x30,0x01,0x70,0x0A,0x05,0x5C,0x2E,0x5F, /* 00001A38 "0.p..\._" */ 21.227 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00001A40 "GPEDPT1p" */ 21.228 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001A48 "..\._GPE" */ 21.229 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00001A50 "DPT2p.\." */ 21.230 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x35, /* 00001A58 "_GPEPH05" */ 21.231 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00001A60 ".+_STA.p" */ 21.232 + 0x0A,0x05,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001A68 "..\._GPE" */ 21.233 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00001A70 "DPT1p..\" */ 21.234 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001A78 "._GPEDPT" */ 21.235 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001A80 "2.\._GPE" */ 21.236 + 0x50,0x48,0x30,0x35,0x5B,0x82,0x42,0x0B, /* 00001A88 "PH05[.B." */ 21.237 + 0x53,0x30,0x36,0x5F,0x08,0x5F,0x41,0x44, /* 00001A90 "S06_._AD" */ 21.238 + 0x52,0x0C,0x00,0x00,0x06,0x00,0x08,0x5F, /* 00001A98 "R......_" */ 21.239 + 0x53,0x55,0x4E,0x0A,0x06,0x14,0x20,0x5F, /* 00001AA0 "SUN... _" */ 21.240 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x06,0x5C, /* 00001AA8 "PS0.p..\" */ 21.241 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001AB0 "._GPEDPT" */ 21.242 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00001AB8 "1p..\._G" */ 21.243 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00001AC0 "PEDPT2. " */ 21.244 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x06, /* 00001AC8 "_PS3.p.." */ 21.245 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001AD0 "\._GPEDP" */ 21.246 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00001AD8 "T1p..\._" */ 21.247 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00001AE0 "GPEDPT2." */ 21.248 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00001AE8 ",_EJ0.p." */ 21.249 + 0x06,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001AF0 ".\._GPED" */ 21.250 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00001AF8 "PT1p..\." */ 21.251 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001B00 "_GPEDPT2" */ 21.252 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001B08 "p.\._GPE" */ 21.253 + 0x50,0x48,0x30,0x36,0x14,0x2B,0x5F,0x53, /* 00001B10 "PH06.+_S" */ 21.254 + 0x54,0x41,0x00,0x70,0x0A,0x06,0x5C,0x2E, /* 00001B18 "TA.p..\." */ 21.255 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00001B20 "_GPEDPT1" */ 21.256 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00001B28 "p..\._GP" */ 21.257 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00001B30 "EDPT2.\." */ 21.258 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x36, /* 00001B38 "_GPEPH06" */ 21.259 + 0x5B,0x82,0x42,0x0B,0x53,0x30,0x37,0x5F, /* 00001B40 "[.B.S07_" */ 21.260 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00001B48 "._ADR..." */ 21.261 + 0x07,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00001B50 "..._SUN." */ 21.262 + 0x07,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00001B58 ".. _PS0." */ 21.263 + 0x70,0x0A,0x07,0x5C,0x2E,0x5F,0x47,0x50, /* 00001B60 "p..\._GP" */ 21.264 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00001B68 "EDPT1p.." */ 21.265 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001B70 "\._GPEDP" */ 21.266 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00001B78 "T2. _PS3" */ 21.267 + 0x00,0x70,0x0A,0x07,0x5C,0x2E,0x5F,0x47, /* 00001B80 ".p..\._G" */ 21.268 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00001B88 "PEDPT1p." */ 21.269 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001B90 ".\._GPED" */ 21.270 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00001B98 "PT2.,_EJ" */ 21.271 + 0x30,0x01,0x70,0x0A,0x07,0x5C,0x2E,0x5F, /* 00001BA0 "0.p..\._" */ 21.272 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00001BA8 "GPEDPT1p" */ 21.273 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001BB0 "..\._GPE" */ 21.274 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00001BB8 "DPT2p.\." */ 21.275 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x37, /* 00001BC0 "_GPEPH07" */ 21.276 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00001BC8 ".+_STA.p" */ 21.277 + 0x0A,0x07,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001BD0 "..\._GPE" */ 21.278 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00001BD8 "DPT1p..\" */ 21.279 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001BE0 "._GPEDPT" */ 21.280 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001BE8 "2.\._GPE" */ 21.281 + 0x50,0x48,0x30,0x37,0x5B,0x82,0x42,0x0B, /* 00001BF0 "PH07[.B." */ 21.282 + 0x53,0x30,0x38,0x5F,0x08,0x5F,0x41,0x44, /* 00001BF8 "S08_._AD" */ 21.283 + 0x52,0x0C,0x00,0x00,0x08,0x00,0x08,0x5F, /* 00001C00 "R......_" */ 21.284 + 0x53,0x55,0x4E,0x0A,0x08,0x14,0x20,0x5F, /* 00001C08 "SUN... _" */ 21.285 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x08,0x5C, /* 00001C10 "PS0.p..\" */ 21.286 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001C18 "._GPEDPT" */ 21.287 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00001C20 "1p..\._G" */ 21.288 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00001C28 "PEDPT2. " */ 21.289 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x08, /* 00001C30 "_PS3.p.." */ 21.290 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001C38 "\._GPEDP" */ 21.291 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00001C40 "T1p..\._" */ 21.292 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00001C48 "GPEDPT2." */ 21.293 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00001C50 ",_EJ0.p." */ 21.294 + 0x08,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001C58 ".\._GPED" */ 21.295 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00001C60 "PT1p..\." */ 21.296 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001C68 "_GPEDPT2" */ 21.297 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001C70 "p.\._GPE" */ 21.298 + 0x50,0x48,0x30,0x38,0x14,0x2B,0x5F,0x53, /* 00001C78 "PH08.+_S" */ 21.299 + 0x54,0x41,0x00,0x70,0x0A,0x08,0x5C,0x2E, /* 00001C80 "TA.p..\." */ 21.300 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00001C88 "_GPEDPT1" */ 21.301 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00001C90 "p..\._GP" */ 21.302 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00001C98 "EDPT2.\." */ 21.303 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x38, /* 00001CA0 "_GPEPH08" */ 21.304 + 0x5B,0x82,0x42,0x0B,0x53,0x30,0x39,0x5F, /* 00001CA8 "[.B.S09_" */ 21.305 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00001CB0 "._ADR..." */ 21.306 + 0x09,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00001CB8 "..._SUN." */ 21.307 + 0x09,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00001CC0 ".. _PS0." */ 21.308 + 0x70,0x0A,0x09,0x5C,0x2E,0x5F,0x47,0x50, /* 00001CC8 "p..\._GP" */ 21.309 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00001CD0 "EDPT1p.." */ 21.310 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001CD8 "\._GPEDP" */ 21.311 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00001CE0 "T2. _PS3" */ 21.312 + 0x00,0x70,0x0A,0x09,0x5C,0x2E,0x5F,0x47, /* 00001CE8 ".p..\._G" */ 21.313 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00001CF0 "PEDPT1p." */ 21.314 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001CF8 ".\._GPED" */ 21.315 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00001D00 "PT2.,_EJ" */ 21.316 + 0x30,0x01,0x70,0x0A,0x09,0x5C,0x2E,0x5F, /* 00001D08 "0.p..\._" */ 21.317 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00001D10 "GPEDPT1p" */ 21.318 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001D18 "..\._GPE" */ 21.319 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00001D20 "DPT2p.\." */ 21.320 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x39, /* 00001D28 "_GPEPH09" */ 21.321 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00001D30 ".+_STA.p" */ 21.322 + 0x0A,0x09,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001D38 "..\._GPE" */ 21.323 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00001D40 "DPT1p..\" */ 21.324 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001D48 "._GPEDPT" */ 21.325 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001D50 "2.\._GPE" */ 21.326 + 0x50,0x48,0x30,0x39,0x5B,0x82,0x42,0x0B, /* 00001D58 "PH09[.B." */ 21.327 + 0x53,0x30,0x41,0x5F,0x08,0x5F,0x41,0x44, /* 00001D60 "S0A_._AD" */ 21.328 + 0x52,0x0C,0x00,0x00,0x0A,0x00,0x08,0x5F, /* 00001D68 "R......_" */ 21.329 + 0x53,0x55,0x4E,0x0A,0x0A,0x14,0x20,0x5F, /* 00001D70 "SUN... _" */ 21.330 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x0A,0x5C, /* 00001D78 "PS0.p..\" */ 21.331 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001D80 "._GPEDPT" */ 21.332 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00001D88 "1p..\._G" */ 21.333 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00001D90 "PEDPT2. " */ 21.334 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x0A, /* 00001D98 "_PS3.p.." */ 21.335 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001DA0 "\._GPEDP" */ 21.336 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00001DA8 "T1p..\._" */ 21.337 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00001DB0 "GPEDPT2." */ 21.338 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00001DB8 ",_EJ0.p." */ 21.339 + 0x0A,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001DC0 ".\._GPED" */ 21.340 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00001DC8 "PT1p..\." */ 21.341 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001DD0 "_GPEDPT2" */ 21.342 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001DD8 "p.\._GPE" */ 21.343 + 0x50,0x48,0x30,0x41,0x14,0x2B,0x5F,0x53, /* 00001DE0 "PH0A.+_S" */ 21.344 + 0x54,0x41,0x00,0x70,0x0A,0x0A,0x5C,0x2E, /* 00001DE8 "TA.p..\." */ 21.345 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00001DF0 "_GPEDPT1" */ 21.346 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00001DF8 "p..\._GP" */ 21.347 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00001E00 "EDPT2.\." */ 21.348 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x41, /* 00001E08 "_GPEPH0A" */ 21.349 + 0x5B,0x82,0x42,0x0B,0x53,0x30,0x42,0x5F, /* 00001E10 "[.B.S0B_" */ 21.350 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00001E18 "._ADR..." */ 21.351 + 0x0B,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00001E20 "..._SUN." */ 21.352 + 0x0B,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00001E28 ".. _PS0." */ 21.353 + 0x70,0x0A,0x0B,0x5C,0x2E,0x5F,0x47,0x50, /* 00001E30 "p..\._GP" */ 21.354 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00001E38 "EDPT1p.." */ 21.355 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001E40 "\._GPEDP" */ 21.356 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00001E48 "T2. _PS3" */ 21.357 + 0x00,0x70,0x0A,0x0B,0x5C,0x2E,0x5F,0x47, /* 00001E50 ".p..\._G" */ 21.358 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00001E58 "PEDPT1p." */ 21.359 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001E60 ".\._GPED" */ 21.360 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00001E68 "PT2.,_EJ" */ 21.361 + 0x30,0x01,0x70,0x0A,0x0B,0x5C,0x2E,0x5F, /* 00001E70 "0.p..\._" */ 21.362 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00001E78 "GPEDPT1p" */ 21.363 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001E80 "..\._GPE" */ 21.364 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00001E88 "DPT2p.\." */ 21.365 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x42, /* 00001E90 "_GPEPH0B" */ 21.366 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00001E98 ".+_STA.p" */ 21.367 + 0x0A,0x0B,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001EA0 "..\._GPE" */ 21.368 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00001EA8 "DPT1p..\" */ 21.369 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001EB0 "._GPEDPT" */ 21.370 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001EB8 "2.\._GPE" */ 21.371 + 0x50,0x48,0x30,0x42,0x5B,0x82,0x42,0x0B, /* 00001EC0 "PH0B[.B." */ 21.372 + 0x53,0x30,0x43,0x5F,0x08,0x5F,0x41,0x44, /* 00001EC8 "S0C_._AD" */ 21.373 + 0x52,0x0C,0x00,0x00,0x0C,0x00,0x08,0x5F, /* 00001ED0 "R......_" */ 21.374 + 0x53,0x55,0x4E,0x0A,0x0C,0x14,0x20,0x5F, /* 00001ED8 "SUN... _" */ 21.375 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x0C,0x5C, /* 00001EE0 "PS0.p..\" */ 21.376 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00001EE8 "._GPEDPT" */ 21.377 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00001EF0 "1p..\._G" */ 21.378 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00001EF8 "PEDPT2. " */ 21.379 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x0C, /* 00001F00 "_PS3.p.." */ 21.380 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001F08 "\._GPEDP" */ 21.381 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00001F10 "T1p..\._" */ 21.382 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00001F18 "GPEDPT2." */ 21.383 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00001F20 ",_EJ0.p." */ 21.384 + 0x0C,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001F28 ".\._GPED" */ 21.385 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00001F30 "PT1p..\." */ 21.386 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00001F38 "_GPEDPT2" */ 21.387 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001F40 "p.\._GPE" */ 21.388 + 0x50,0x48,0x30,0x43,0x14,0x2B,0x5F,0x53, /* 00001F48 "PH0C.+_S" */ 21.389 + 0x54,0x41,0x00,0x70,0x0A,0x0C,0x5C,0x2E, /* 00001F50 "TA.p..\." */ 21.390 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00001F58 "_GPEDPT1" */ 21.391 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00001F60 "p..\._GP" */ 21.392 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00001F68 "EDPT2.\." */ 21.393 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x43, /* 00001F70 "_GPEPH0C" */ 21.394 + 0x5B,0x82,0x42,0x0B,0x53,0x30,0x44,0x5F, /* 00001F78 "[.B.S0D_" */ 21.395 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00001F80 "._ADR..." */ 21.396 + 0x0D,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00001F88 "..._SUN." */ 21.397 + 0x0D,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00001F90 ".. _PS0." */ 21.398 + 0x70,0x0A,0x0D,0x5C,0x2E,0x5F,0x47,0x50, /* 00001F98 "p..\._GP" */ 21.399 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00001FA0 "EDPT1p.." */ 21.400 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00001FA8 "\._GPEDP" */ 21.401 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00001FB0 "T2. _PS3" */ 21.402 + 0x00,0x70,0x0A,0x0D,0x5C,0x2E,0x5F,0x47, /* 00001FB8 ".p..\._G" */ 21.403 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00001FC0 "PEDPT1p." */ 21.404 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00001FC8 ".\._GPED" */ 21.405 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00001FD0 "PT2.,_EJ" */ 21.406 + 0x30,0x01,0x70,0x0A,0x0D,0x5C,0x2E,0x5F, /* 00001FD8 "0.p..\._" */ 21.407 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00001FE0 "GPEDPT1p" */ 21.408 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00001FE8 "..\._GPE" */ 21.409 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00001FF0 "DPT2p.\." */ 21.410 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x44, /* 00001FF8 "_GPEPH0D" */ 21.411 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00002000 ".+_STA.p" */ 21.412 + 0x0A,0x0D,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002008 "..\._GPE" */ 21.413 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00002010 "DPT1p..\" */ 21.414 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002018 "._GPEDPT" */ 21.415 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002020 "2.\._GPE" */ 21.416 + 0x50,0x48,0x30,0x44,0x5B,0x82,0x42,0x0B, /* 00002028 "PH0D[.B." */ 21.417 + 0x53,0x30,0x45,0x5F,0x08,0x5F,0x41,0x44, /* 00002030 "S0E_._AD" */ 21.418 + 0x52,0x0C,0x00,0x00,0x0E,0x00,0x08,0x5F, /* 00002038 "R......_" */ 21.419 + 0x53,0x55,0x4E,0x0A,0x0E,0x14,0x20,0x5F, /* 00002040 "SUN... _" */ 21.420 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x0E,0x5C, /* 00002048 "PS0.p..\" */ 21.421 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002050 "._GPEDPT" */ 21.422 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00002058 "1p..\._G" */ 21.423 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00002060 "PEDPT2. " */ 21.424 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x0E, /* 00002068 "_PS3.p.." */ 21.425 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002070 "\._GPEDP" */ 21.426 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00002078 "T1p..\._" */ 21.427 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00002080 "GPEDPT2." */ 21.428 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00002088 ",_EJ0.p." */ 21.429 + 0x0E,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002090 ".\._GPED" */ 21.430 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00002098 "PT1p..\." */ 21.431 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 000020A0 "_GPEDPT2" */ 21.432 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000020A8 "p.\._GPE" */ 21.433 + 0x50,0x48,0x30,0x45,0x14,0x2B,0x5F,0x53, /* 000020B0 "PH0E.+_S" */ 21.434 + 0x54,0x41,0x00,0x70,0x0A,0x0E,0x5C,0x2E, /* 000020B8 "TA.p..\." */ 21.435 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 000020C0 "_GPEDPT1" */ 21.436 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 000020C8 "p..\._GP" */ 21.437 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 000020D0 "EDPT2.\." */ 21.438 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x45, /* 000020D8 "_GPEPH0E" */ 21.439 + 0x5B,0x82,0x42,0x0B,0x53,0x30,0x46,0x5F, /* 000020E0 "[.B.S0F_" */ 21.440 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 000020E8 "._ADR..." */ 21.441 + 0x0F,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 000020F0 "..._SUN." */ 21.442 + 0x0F,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 000020F8 ".. _PS0." */ 21.443 + 0x70,0x0A,0x0F,0x5C,0x2E,0x5F,0x47,0x50, /* 00002100 "p..\._GP" */ 21.444 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00002108 "EDPT1p.." */ 21.445 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002110 "\._GPEDP" */ 21.446 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00002118 "T2. _PS3" */ 21.447 + 0x00,0x70,0x0A,0x0F,0x5C,0x2E,0x5F,0x47, /* 00002120 ".p..\._G" */ 21.448 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00002128 "PEDPT1p." */ 21.449 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002130 ".\._GPED" */ 21.450 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00002138 "PT2.,_EJ" */ 21.451 + 0x30,0x01,0x70,0x0A,0x0F,0x5C,0x2E,0x5F, /* 00002140 "0.p..\._" */ 21.452 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00002148 "GPEDPT1p" */ 21.453 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002150 "..\._GPE" */ 21.454 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00002158 "DPT2p.\." */ 21.455 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x30,0x46, /* 00002160 "_GPEPH0F" */ 21.456 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00002168 ".+_STA.p" */ 21.457 + 0x0A,0x0F,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002170 "..\._GPE" */ 21.458 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00002178 "DPT1p..\" */ 21.459 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002180 "._GPEDPT" */ 21.460 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002188 "2.\._GPE" */ 21.461 + 0x50,0x48,0x30,0x46,0x5B,0x82,0x42,0x0B, /* 00002190 "PH0F[.B." */ 21.462 + 0x53,0x31,0x30,0x5F,0x08,0x5F,0x41,0x44, /* 00002198 "S10_._AD" */ 21.463 + 0x52,0x0C,0x00,0x00,0x10,0x00,0x08,0x5F, /* 000021A0 "R......_" */ 21.464 + 0x53,0x55,0x4E,0x0A,0x10,0x14,0x20,0x5F, /* 000021A8 "SUN... _" */ 21.465 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x10,0x5C, /* 000021B0 "PS0.p..\" */ 21.466 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000021B8 "._GPEDPT" */ 21.467 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 000021C0 "1p..\._G" */ 21.468 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 000021C8 "PEDPT2. " */ 21.469 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x10, /* 000021D0 "_PS3.p.." */ 21.470 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 000021D8 "\._GPEDP" */ 21.471 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 000021E0 "T1p..\._" */ 21.472 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 000021E8 "GPEDPT2." */ 21.473 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 000021F0 ",_EJ0.p." */ 21.474 + 0x10,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 000021F8 ".\._GPED" */ 21.475 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00002200 "PT1p..\." */ 21.476 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00002208 "_GPEDPT2" */ 21.477 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002210 "p.\._GPE" */ 21.478 + 0x50,0x48,0x31,0x30,0x14,0x2B,0x5F,0x53, /* 00002218 "PH10.+_S" */ 21.479 + 0x54,0x41,0x00,0x70,0x0A,0x10,0x5C,0x2E, /* 00002220 "TA.p..\." */ 21.480 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00002228 "_GPEDPT1" */ 21.481 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00002230 "p..\._GP" */ 21.482 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00002238 "EDPT2.\." */ 21.483 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x30, /* 00002240 "_GPEPH10" */ 21.484 + 0x5B,0x82,0x42,0x0B,0x53,0x31,0x31,0x5F, /* 00002248 "[.B.S11_" */ 21.485 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00002250 "._ADR..." */ 21.486 + 0x11,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00002258 "..._SUN." */ 21.487 + 0x11,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00002260 ".. _PS0." */ 21.488 + 0x70,0x0A,0x11,0x5C,0x2E,0x5F,0x47,0x50, /* 00002268 "p..\._GP" */ 21.489 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00002270 "EDPT1p.." */ 21.490 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002278 "\._GPEDP" */ 21.491 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00002280 "T2. _PS3" */ 21.492 + 0x00,0x70,0x0A,0x11,0x5C,0x2E,0x5F,0x47, /* 00002288 ".p..\._G" */ 21.493 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00002290 "PEDPT1p." */ 21.494 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002298 ".\._GPED" */ 21.495 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 000022A0 "PT2.,_EJ" */ 21.496 + 0x30,0x01,0x70,0x0A,0x11,0x5C,0x2E,0x5F, /* 000022A8 "0.p..\._" */ 21.497 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 000022B0 "GPEDPT1p" */ 21.498 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000022B8 "..\._GPE" */ 21.499 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 000022C0 "DPT2p.\." */ 21.500 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x31, /* 000022C8 "_GPEPH11" */ 21.501 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 000022D0 ".+_STA.p" */ 21.502 + 0x0A,0x11,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000022D8 "..\._GPE" */ 21.503 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 000022E0 "DPT1p..\" */ 21.504 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000022E8 "._GPEDPT" */ 21.505 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000022F0 "2.\._GPE" */ 21.506 + 0x50,0x48,0x31,0x31,0x5B,0x82,0x42,0x0B, /* 000022F8 "PH11[.B." */ 21.507 + 0x53,0x31,0x32,0x5F,0x08,0x5F,0x41,0x44, /* 00002300 "S12_._AD" */ 21.508 + 0x52,0x0C,0x00,0x00,0x12,0x00,0x08,0x5F, /* 00002308 "R......_" */ 21.509 + 0x53,0x55,0x4E,0x0A,0x12,0x14,0x20,0x5F, /* 00002310 "SUN... _" */ 21.510 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x12,0x5C, /* 00002318 "PS0.p..\" */ 21.511 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002320 "._GPEDPT" */ 21.512 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00002328 "1p..\._G" */ 21.513 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00002330 "PEDPT2. " */ 21.514 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x12, /* 00002338 "_PS3.p.." */ 21.515 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002340 "\._GPEDP" */ 21.516 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00002348 "T1p..\._" */ 21.517 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00002350 "GPEDPT2." */ 21.518 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00002358 ",_EJ0.p." */ 21.519 + 0x12,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002360 ".\._GPED" */ 21.520 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00002368 "PT1p..\." */ 21.521 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00002370 "_GPEDPT2" */ 21.522 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002378 "p.\._GPE" */ 21.523 + 0x50,0x48,0x31,0x32,0x14,0x2B,0x5F,0x53, /* 00002380 "PH12.+_S" */ 21.524 + 0x54,0x41,0x00,0x70,0x0A,0x12,0x5C,0x2E, /* 00002388 "TA.p..\." */ 21.525 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00002390 "_GPEDPT1" */ 21.526 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00002398 "p..\._GP" */ 21.527 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 000023A0 "EDPT2.\." */ 21.528 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x32, /* 000023A8 "_GPEPH12" */ 21.529 + 0x5B,0x82,0x42,0x0B,0x53,0x31,0x33,0x5F, /* 000023B0 "[.B.S13_" */ 21.530 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 000023B8 "._ADR..." */ 21.531 + 0x13,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 000023C0 "..._SUN." */ 21.532 + 0x13,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 000023C8 ".. _PS0." */ 21.533 + 0x70,0x0A,0x13,0x5C,0x2E,0x5F,0x47,0x50, /* 000023D0 "p..\._GP" */ 21.534 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 000023D8 "EDPT1p.." */ 21.535 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 000023E0 "\._GPEDP" */ 21.536 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 000023E8 "T2. _PS3" */ 21.537 + 0x00,0x70,0x0A,0x13,0x5C,0x2E,0x5F,0x47, /* 000023F0 ".p..\._G" */ 21.538 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 000023F8 "PEDPT1p." */ 21.539 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002400 ".\._GPED" */ 21.540 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00002408 "PT2.,_EJ" */ 21.541 + 0x30,0x01,0x70,0x0A,0x13,0x5C,0x2E,0x5F, /* 00002410 "0.p..\._" */ 21.542 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00002418 "GPEDPT1p" */ 21.543 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002420 "..\._GPE" */ 21.544 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00002428 "DPT2p.\." */ 21.545 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x33, /* 00002430 "_GPEPH13" */ 21.546 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00002438 ".+_STA.p" */ 21.547 + 0x0A,0x13,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002440 "..\._GPE" */ 21.548 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00002448 "DPT1p..\" */ 21.549 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002450 "._GPEDPT" */ 21.550 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002458 "2.\._GPE" */ 21.551 + 0x50,0x48,0x31,0x33,0x5B,0x82,0x42,0x0B, /* 00002460 "PH13[.B." */ 21.552 + 0x53,0x31,0x34,0x5F,0x08,0x5F,0x41,0x44, /* 00002468 "S14_._AD" */ 21.553 + 0x52,0x0C,0x00,0x00,0x14,0x00,0x08,0x5F, /* 00002470 "R......_" */ 21.554 + 0x53,0x55,0x4E,0x0A,0x14,0x14,0x20,0x5F, /* 00002478 "SUN... _" */ 21.555 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x14,0x5C, /* 00002480 "PS0.p..\" */ 21.556 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002488 "._GPEDPT" */ 21.557 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00002490 "1p..\._G" */ 21.558 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00002498 "PEDPT2. " */ 21.559 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x14, /* 000024A0 "_PS3.p.." */ 21.560 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 000024A8 "\._GPEDP" */ 21.561 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 000024B0 "T1p..\._" */ 21.562 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 000024B8 "GPEDPT2." */ 21.563 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 000024C0 ",_EJ0.p." */ 21.564 + 0x14,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 000024C8 ".\._GPED" */ 21.565 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 000024D0 "PT1p..\." */ 21.566 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 000024D8 "_GPEDPT2" */ 21.567 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000024E0 "p.\._GPE" */ 21.568 + 0x50,0x48,0x31,0x34,0x14,0x2B,0x5F,0x53, /* 000024E8 "PH14.+_S" */ 21.569 + 0x54,0x41,0x00,0x70,0x0A,0x14,0x5C,0x2E, /* 000024F0 "TA.p..\." */ 21.570 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 000024F8 "_GPEDPT1" */ 21.571 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00002500 "p..\._GP" */ 21.572 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00002508 "EDPT2.\." */ 21.573 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x34, /* 00002510 "_GPEPH14" */ 21.574 + 0x5B,0x82,0x42,0x0B,0x53,0x31,0x35,0x5F, /* 00002518 "[.B.S15_" */ 21.575 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00002520 "._ADR..." */ 21.576 + 0x15,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00002528 "..._SUN." */ 21.577 + 0x15,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00002530 ".. _PS0." */ 21.578 + 0x70,0x0A,0x15,0x5C,0x2E,0x5F,0x47,0x50, /* 00002538 "p..\._GP" */ 21.579 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00002540 "EDPT1p.." */ 21.580 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002548 "\._GPEDP" */ 21.581 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00002550 "T2. _PS3" */ 21.582 + 0x00,0x70,0x0A,0x15,0x5C,0x2E,0x5F,0x47, /* 00002558 ".p..\._G" */ 21.583 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00002560 "PEDPT1p." */ 21.584 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002568 ".\._GPED" */ 21.585 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00002570 "PT2.,_EJ" */ 21.586 + 0x30,0x01,0x70,0x0A,0x15,0x5C,0x2E,0x5F, /* 00002578 "0.p..\._" */ 21.587 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00002580 "GPEDPT1p" */ 21.588 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002588 "..\._GPE" */ 21.589 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00002590 "DPT2p.\." */ 21.590 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x35, /* 00002598 "_GPEPH15" */ 21.591 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 000025A0 ".+_STA.p" */ 21.592 + 0x0A,0x15,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000025A8 "..\._GPE" */ 21.593 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 000025B0 "DPT1p..\" */ 21.594 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000025B8 "._GPEDPT" */ 21.595 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000025C0 "2.\._GPE" */ 21.596 + 0x50,0x48,0x31,0x35,0x5B,0x82,0x42,0x0B, /* 000025C8 "PH15[.B." */ 21.597 + 0x53,0x31,0x36,0x5F,0x08,0x5F,0x41,0x44, /* 000025D0 "S16_._AD" */ 21.598 + 0x52,0x0C,0x00,0x00,0x16,0x00,0x08,0x5F, /* 000025D8 "R......_" */ 21.599 + 0x53,0x55,0x4E,0x0A,0x16,0x14,0x20,0x5F, /* 000025E0 "SUN... _" */ 21.600 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x16,0x5C, /* 000025E8 "PS0.p..\" */ 21.601 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000025F0 "._GPEDPT" */ 21.602 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 000025F8 "1p..\._G" */ 21.603 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00002600 "PEDPT2. " */ 21.604 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x16, /* 00002608 "_PS3.p.." */ 21.605 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002610 "\._GPEDP" */ 21.606 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00002618 "T1p..\._" */ 21.607 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00002620 "GPEDPT2." */ 21.608 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00002628 ",_EJ0.p." */ 21.609 + 0x16,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002630 ".\._GPED" */ 21.610 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00002638 "PT1p..\." */ 21.611 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00002640 "_GPEDPT2" */ 21.612 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002648 "p.\._GPE" */ 21.613 + 0x50,0x48,0x31,0x36,0x14,0x2B,0x5F,0x53, /* 00002650 "PH16.+_S" */ 21.614 + 0x54,0x41,0x00,0x70,0x0A,0x16,0x5C,0x2E, /* 00002658 "TA.p..\." */ 21.615 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00002660 "_GPEDPT1" */ 21.616 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00002668 "p..\._GP" */ 21.617 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00002670 "EDPT2.\." */ 21.618 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x36, /* 00002678 "_GPEPH16" */ 21.619 + 0x5B,0x82,0x42,0x0B,0x53,0x31,0x37,0x5F, /* 00002680 "[.B.S17_" */ 21.620 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00002688 "._ADR..." */ 21.621 + 0x17,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00002690 "..._SUN." */ 21.622 + 0x17,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00002698 ".. _PS0." */ 21.623 + 0x70,0x0A,0x17,0x5C,0x2E,0x5F,0x47,0x50, /* 000026A0 "p..\._GP" */ 21.624 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 000026A8 "EDPT1p.." */ 21.625 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 000026B0 "\._GPEDP" */ 21.626 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 000026B8 "T2. _PS3" */ 21.627 + 0x00,0x70,0x0A,0x17,0x5C,0x2E,0x5F,0x47, /* 000026C0 ".p..\._G" */ 21.628 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 000026C8 "PEDPT1p." */ 21.629 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 000026D0 ".\._GPED" */ 21.630 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 000026D8 "PT2.,_EJ" */ 21.631 + 0x30,0x01,0x70,0x0A,0x17,0x5C,0x2E,0x5F, /* 000026E0 "0.p..\._" */ 21.632 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 000026E8 "GPEDPT1p" */ 21.633 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000026F0 "..\._GPE" */ 21.634 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 000026F8 "DPT2p.\." */ 21.635 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x37, /* 00002700 "_GPEPH17" */ 21.636 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00002708 ".+_STA.p" */ 21.637 + 0x0A,0x17,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002710 "..\._GPE" */ 21.638 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00002718 "DPT1p..\" */ 21.639 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002720 "._GPEDPT" */ 21.640 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002728 "2.\._GPE" */ 21.641 + 0x50,0x48,0x31,0x37,0x5B,0x82,0x42,0x0B, /* 00002730 "PH17[.B." */ 21.642 + 0x53,0x31,0x38,0x5F,0x08,0x5F,0x41,0x44, /* 00002738 "S18_._AD" */ 21.643 + 0x52,0x0C,0x00,0x00,0x18,0x00,0x08,0x5F, /* 00002740 "R......_" */ 21.644 + 0x53,0x55,0x4E,0x0A,0x18,0x14,0x20,0x5F, /* 00002748 "SUN... _" */ 21.645 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x18,0x5C, /* 00002750 "PS0.p..\" */ 21.646 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002758 "._GPEDPT" */ 21.647 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00002760 "1p..\._G" */ 21.648 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00002768 "PEDPT2. " */ 21.649 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x18, /* 00002770 "_PS3.p.." */ 21.650 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002778 "\._GPEDP" */ 21.651 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00002780 "T1p..\._" */ 21.652 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00002788 "GPEDPT2." */ 21.653 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00002790 ",_EJ0.p." */ 21.654 + 0x18,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002798 ".\._GPED" */ 21.655 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 000027A0 "PT1p..\." */ 21.656 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 000027A8 "_GPEDPT2" */ 21.657 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000027B0 "p.\._GPE" */ 21.658 + 0x50,0x48,0x31,0x38,0x14,0x2B,0x5F,0x53, /* 000027B8 "PH18.+_S" */ 21.659 + 0x54,0x41,0x00,0x70,0x0A,0x18,0x5C,0x2E, /* 000027C0 "TA.p..\." */ 21.660 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 000027C8 "_GPEDPT1" */ 21.661 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 000027D0 "p..\._GP" */ 21.662 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 000027D8 "EDPT2.\." */ 21.663 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x38, /* 000027E0 "_GPEPH18" */ 21.664 + 0x5B,0x82,0x42,0x0B,0x53,0x31,0x39,0x5F, /* 000027E8 "[.B.S19_" */ 21.665 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 000027F0 "._ADR..." */ 21.666 + 0x19,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 000027F8 "..._SUN." */ 21.667 + 0x19,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00002800 ".. _PS0." */ 21.668 + 0x70,0x0A,0x19,0x5C,0x2E,0x5F,0x47,0x50, /* 00002808 "p..\._GP" */ 21.669 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00002810 "EDPT1p.." */ 21.670 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002818 "\._GPEDP" */ 21.671 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00002820 "T2. _PS3" */ 21.672 + 0x00,0x70,0x0A,0x19,0x5C,0x2E,0x5F,0x47, /* 00002828 ".p..\._G" */ 21.673 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00002830 "PEDPT1p." */ 21.674 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002838 ".\._GPED" */ 21.675 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00002840 "PT2.,_EJ" */ 21.676 + 0x30,0x01,0x70,0x0A,0x19,0x5C,0x2E,0x5F, /* 00002848 "0.p..\._" */ 21.677 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00002850 "GPEDPT1p" */ 21.678 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002858 "..\._GPE" */ 21.679 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00002860 "DPT2p.\." */ 21.680 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x39, /* 00002868 "_GPEPH19" */ 21.681 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00002870 ".+_STA.p" */ 21.682 + 0x0A,0x19,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002878 "..\._GPE" */ 21.683 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00002880 "DPT1p..\" */ 21.684 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002888 "._GPEDPT" */ 21.685 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002890 "2.\._GPE" */ 21.686 + 0x50,0x48,0x31,0x39,0x5B,0x82,0x42,0x0B, /* 00002898 "PH19[.B." */ 21.687 + 0x53,0x31,0x41,0x5F,0x08,0x5F,0x41,0x44, /* 000028A0 "S1A_._AD" */ 21.688 + 0x52,0x0C,0x00,0x00,0x1A,0x00,0x08,0x5F, /* 000028A8 "R......_" */ 21.689 + 0x53,0x55,0x4E,0x0A,0x1A,0x14,0x20,0x5F, /* 000028B0 "SUN... _" */ 21.690 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x1A,0x5C, /* 000028B8 "PS0.p..\" */ 21.691 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000028C0 "._GPEDPT" */ 21.692 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 000028C8 "1p..\._G" */ 21.693 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 000028D0 "PEDPT2. " */ 21.694 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x1A, /* 000028D8 "_PS3.p.." */ 21.695 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 000028E0 "\._GPEDP" */ 21.696 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 000028E8 "T1p..\._" */ 21.697 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 000028F0 "GPEDPT2." */ 21.698 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 000028F8 ",_EJ0.p." */ 21.699 + 0x1A,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002900 ".\._GPED" */ 21.700 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00002908 "PT1p..\." */ 21.701 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00002910 "_GPEDPT2" */ 21.702 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002918 "p.\._GPE" */ 21.703 + 0x50,0x48,0x31,0x41,0x14,0x2B,0x5F,0x53, /* 00002920 "PH1A.+_S" */ 21.704 + 0x54,0x41,0x00,0x70,0x0A,0x1A,0x5C,0x2E, /* 00002928 "TA.p..\." */ 21.705 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00002930 "_GPEDPT1" */ 21.706 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00002938 "p..\._GP" */ 21.707 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00002940 "EDPT2.\." */ 21.708 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x41, /* 00002948 "_GPEPH1A" */ 21.709 + 0x5B,0x82,0x42,0x0B,0x53,0x31,0x42,0x5F, /* 00002950 "[.B.S1B_" */ 21.710 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00002958 "._ADR..." */ 21.711 + 0x1B,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00002960 "..._SUN." */ 21.712 + 0x1B,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00002968 ".. _PS0." */ 21.713 + 0x70,0x0A,0x1B,0x5C,0x2E,0x5F,0x47,0x50, /* 00002970 "p..\._GP" */ 21.714 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00002978 "EDPT1p.." */ 21.715 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002980 "\._GPEDP" */ 21.716 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00002988 "T2. _PS3" */ 21.717 + 0x00,0x70,0x0A,0x1B,0x5C,0x2E,0x5F,0x47, /* 00002990 ".p..\._G" */ 21.718 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00002998 "PEDPT1p." */ 21.719 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 000029A0 ".\._GPED" */ 21.720 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 000029A8 "PT2.,_EJ" */ 21.721 + 0x30,0x01,0x70,0x0A,0x1B,0x5C,0x2E,0x5F, /* 000029B0 "0.p..\._" */ 21.722 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 000029B8 "GPEDPT1p" */ 21.723 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000029C0 "..\._GPE" */ 21.724 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 000029C8 "DPT2p.\." */ 21.725 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x42, /* 000029D0 "_GPEPH1B" */ 21.726 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 000029D8 ".+_STA.p" */ 21.727 + 0x0A,0x1B,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000029E0 "..\._GPE" */ 21.728 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 000029E8 "DPT1p..\" */ 21.729 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 000029F0 "._GPEDPT" */ 21.730 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 000029F8 "2.\._GPE" */ 21.731 + 0x50,0x48,0x31,0x42,0x5B,0x82,0x42,0x0B, /* 00002A00 "PH1B[.B." */ 21.732 + 0x53,0x31,0x43,0x5F,0x08,0x5F,0x41,0x44, /* 00002A08 "S1C_._AD" */ 21.733 + 0x52,0x0C,0x00,0x00,0x1C,0x00,0x08,0x5F, /* 00002A10 "R......_" */ 21.734 + 0x53,0x55,0x4E,0x0A,0x1C,0x14,0x20,0x5F, /* 00002A18 "SUN... _" */ 21.735 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x1C,0x5C, /* 00002A20 "PS0.p..\" */ 21.736 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002A28 "._GPEDPT" */ 21.737 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00002A30 "1p..\._G" */ 21.738 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00002A38 "PEDPT2. " */ 21.739 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x1C, /* 00002A40 "_PS3.p.." */ 21.740 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002A48 "\._GPEDP" */ 21.741 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00002A50 "T1p..\._" */ 21.742 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00002A58 "GPEDPT2." */ 21.743 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00002A60 ",_EJ0.p." */ 21.744 + 0x1C,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002A68 ".\._GPED" */ 21.745 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00002A70 "PT1p..\." */ 21.746 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00002A78 "_GPEDPT2" */ 21.747 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002A80 "p.\._GPE" */ 21.748 + 0x50,0x48,0x31,0x43,0x14,0x2B,0x5F,0x53, /* 00002A88 "PH1C.+_S" */ 21.749 + 0x54,0x41,0x00,0x70,0x0A,0x1C,0x5C,0x2E, /* 00002A90 "TA.p..\." */ 21.750 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00002A98 "_GPEDPT1" */ 21.751 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00002AA0 "p..\._GP" */ 21.752 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00002AA8 "EDPT2.\." */ 21.753 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x43, /* 00002AB0 "_GPEPH1C" */ 21.754 + 0x5B,0x82,0x42,0x0B,0x53,0x31,0x44,0x5F, /* 00002AB8 "[.B.S1D_" */ 21.755 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00002AC0 "._ADR..." */ 21.756 + 0x1D,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00002AC8 "..._SUN." */ 21.757 + 0x1D,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00002AD0 ".. _PS0." */ 21.758 + 0x70,0x0A,0x1D,0x5C,0x2E,0x5F,0x47,0x50, /* 00002AD8 "p..\._GP" */ 21.759 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00002AE0 "EDPT1p.." */ 21.760 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002AE8 "\._GPEDP" */ 21.761 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00002AF0 "T2. _PS3" */ 21.762 + 0x00,0x70,0x0A,0x1D,0x5C,0x2E,0x5F,0x47, /* 00002AF8 ".p..\._G" */ 21.763 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00002B00 "PEDPT1p." */ 21.764 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002B08 ".\._GPED" */ 21.765 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00002B10 "PT2.,_EJ" */ 21.766 + 0x30,0x01,0x70,0x0A,0x1D,0x5C,0x2E,0x5F, /* 00002B18 "0.p..\._" */ 21.767 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00002B20 "GPEDPT1p" */ 21.768 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002B28 "..\._GPE" */ 21.769 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00002B30 "DPT2p.\." */ 21.770 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x44, /* 00002B38 "_GPEPH1D" */ 21.771 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00002B40 ".+_STA.p" */ 21.772 + 0x0A,0x1D,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002B48 "..\._GPE" */ 21.773 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00002B50 "DPT1p..\" */ 21.774 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002B58 "._GPEDPT" */ 21.775 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002B60 "2.\._GPE" */ 21.776 + 0x50,0x48,0x31,0x44,0x5B,0x82,0x42,0x0B, /* 00002B68 "PH1D[.B." */ 21.777 + 0x53,0x31,0x45,0x5F,0x08,0x5F,0x41,0x44, /* 00002B70 "S1E_._AD" */ 21.778 + 0x52,0x0C,0x00,0x00,0x1E,0x00,0x08,0x5F, /* 00002B78 "R......_" */ 21.779 + 0x53,0x55,0x4E,0x0A,0x1E,0x14,0x20,0x5F, /* 00002B80 "SUN... _" */ 21.780 + 0x50,0x53,0x30,0x00,0x70,0x0A,0x1E,0x5C, /* 00002B88 "PS0.p..\" */ 21.781 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002B90 "._GPEDPT" */ 21.782 + 0x31,0x70,0x0A,0x80,0x5C,0x2E,0x5F,0x47, /* 00002B98 "1p..\._G" */ 21.783 + 0x50,0x45,0x44,0x50,0x54,0x32,0x14,0x20, /* 00002BA0 "PEDPT2. " */ 21.784 + 0x5F,0x50,0x53,0x33,0x00,0x70,0x0A,0x1E, /* 00002BA8 "_PS3.p.." */ 21.785 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002BB0 "\._GPEDP" */ 21.786 + 0x54,0x31,0x70,0x0A,0x83,0x5C,0x2E,0x5F, /* 00002BB8 "T1p..\._" */ 21.787 + 0x47,0x50,0x45,0x44,0x50,0x54,0x32,0x14, /* 00002BC0 "GPEDPT2." */ 21.788 + 0x2C,0x5F,0x45,0x4A,0x30,0x01,0x70,0x0A, /* 00002BC8 ",_EJ0.p." */ 21.789 + 0x1E,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002BD0 ".\._GPED" */ 21.790 + 0x50,0x54,0x31,0x70,0x0A,0x88,0x5C,0x2E, /* 00002BD8 "PT1p..\." */ 21.791 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x32, /* 00002BE0 "_GPEDPT2" */ 21.792 + 0x70,0x01,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002BE8 "p.\._GPE" */ 21.793 + 0x50,0x48,0x31,0x45,0x14,0x2B,0x5F,0x53, /* 00002BF0 "PH1E.+_S" */ 21.794 + 0x54,0x41,0x00,0x70,0x0A,0x1E,0x5C,0x2E, /* 00002BF8 "TA.p..\." */ 21.795 + 0x5F,0x47,0x50,0x45,0x44,0x50,0x54,0x31, /* 00002C00 "_GPEDPT1" */ 21.796 + 0x70,0x0A,0x89,0x5C,0x2E,0x5F,0x47,0x50, /* 00002C08 "p..\._GP" */ 21.797 + 0x45,0x44,0x50,0x54,0x32,0xA4,0x5C,0x2E, /* 00002C10 "EDPT2.\." */ 21.798 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x45, /* 00002C18 "_GPEPH1E" */ 21.799 + 0x5B,0x82,0x42,0x0B,0x53,0x31,0x46,0x5F, /* 00002C20 "[.B.S1F_" */ 21.800 + 0x08,0x5F,0x41,0x44,0x52,0x0C,0x00,0x00, /* 00002C28 "._ADR..." */ 21.801 + 0x1F,0x00,0x08,0x5F,0x53,0x55,0x4E,0x0A, /* 00002C30 "..._SUN." */ 21.802 + 0x1F,0x14,0x20,0x5F,0x50,0x53,0x30,0x00, /* 00002C38 ".. _PS0." */ 21.803 + 0x70,0x0A,0x1F,0x5C,0x2E,0x5F,0x47,0x50, /* 00002C40 "p..\._GP" */ 21.804 + 0x45,0x44,0x50,0x54,0x31,0x70,0x0A,0x80, /* 00002C48 "EDPT1p.." */ 21.805 + 0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44,0x50, /* 00002C50 "\._GPEDP" */ 21.806 + 0x54,0x32,0x14,0x20,0x5F,0x50,0x53,0x33, /* 00002C58 "T2. _PS3" */ 21.807 + 0x00,0x70,0x0A,0x1F,0x5C,0x2E,0x5F,0x47, /* 00002C60 ".p..\._G" */ 21.808 + 0x50,0x45,0x44,0x50,0x54,0x31,0x70,0x0A, /* 00002C68 "PEDPT1p." */ 21.809 + 0x83,0x5C,0x2E,0x5F,0x47,0x50,0x45,0x44, /* 00002C70 ".\._GPED" */ 21.810 + 0x50,0x54,0x32,0x14,0x2C,0x5F,0x45,0x4A, /* 00002C78 "PT2.,_EJ" */ 21.811 + 0x30,0x01,0x70,0x0A,0x1F,0x5C,0x2E,0x5F, /* 00002C80 "0.p..\._" */ 21.812 + 0x47,0x50,0x45,0x44,0x50,0x54,0x31,0x70, /* 00002C88 "GPEDPT1p" */ 21.813 + 0x0A,0x88,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002C90 "..\._GPE" */ 21.814 + 0x44,0x50,0x54,0x32,0x70,0x01,0x5C,0x2E, /* 00002C98 "DPT2p.\." */ 21.815 + 0x5F,0x47,0x50,0x45,0x50,0x48,0x31,0x46, /* 00002CA0 "_GPEPH1F" */ 21.816 + 0x14,0x2B,0x5F,0x53,0x54,0x41,0x00,0x70, /* 00002CA8 ".+_STA.p" */ 21.817 + 0x0A,0x1F,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002CB0 "..\._GPE" */ 21.818 + 0x44,0x50,0x54,0x31,0x70,0x0A,0x89,0x5C, /* 00002CB8 "DPT1p..\" */ 21.819 + 0x2E,0x5F,0x47,0x50,0x45,0x44,0x50,0x54, /* 00002CC0 "._GPEDPT" */ 21.820 + 0x32,0xA4,0x5C,0x2E,0x5F,0x47,0x50,0x45, /* 00002CC8 "2.\._GPE" */ 21.821 + 0x50,0x48,0x31,0x46,0x10,0x4D,0x52,0x5F, /* 00002CD0 "PH1F.MR_" */ 21.822 + 0x47,0x50,0x45,0x5B,0x80,0x50,0x48,0x50, /* 00002CD8 "GPE[.PHP" */ 21.823 + 0x5F,0x01,0x0B,0xC0,0x10,0x0A,0x22,0x5B, /* 00002CE0 "_....."[" */ 21.824 + 0x81,0x41,0x0B,0x50,0x48,0x50,0x5F,0x01, /* 00002CE8 ".A.PHP_." */ 21.825 + 0x50,0x53,0x54,0x41,0x08,0x50,0x53,0x54, /* 00002CF0 "PSTA.PST" */ 21.826 + 0x42,0x08,0x50,0x48,0x30,0x30,0x08,0x50, /* 00002CF8 "B.PH00.P" */ 21.827 + 0x48,0x30,0x31,0x08,0x50,0x48,0x30,0x32, /* 00002D00 "H01.PH02" */ 21.828 + 0x08,0x50,0x48,0x30,0x33,0x08,0x50,0x48, /* 00002D08 ".PH03.PH" */ 21.829 + 0x30,0x34,0x08,0x50,0x48,0x30,0x35,0x08, /* 00002D10 "04.PH05." */ 21.830 + 0x50,0x48,0x30,0x36,0x08,0x50,0x48,0x30, /* 00002D18 "PH06.PH0" */ 21.831 + 0x37,0x08,0x50,0x48,0x30,0x38,0x08,0x50, /* 00002D20 "7.PH08.P" */ 21.832 + 0x48,0x30,0x39,0x08,0x50,0x48,0x30,0x41, /* 00002D28 "H09.PH0A" */ 21.833 + 0x08,0x50,0x48,0x30,0x42,0x08,0x50,0x48, /* 00002D30 ".PH0B.PH" */ 21.834 + 0x30,0x43,0x08,0x50,0x48,0x30,0x44,0x08, /* 00002D38 "0C.PH0D." */ 21.835 + 0x50,0x48,0x30,0x45,0x08,0x50,0x48,0x30, /* 00002D40 "PH0E.PH0" */ 21.836 + 0x46,0x08,0x50,0x48,0x31,0x30,0x08,0x50, /* 00002D48 "F.PH10.P" */ 21.837 + 0x48,0x31,0x31,0x08,0x50,0x48,0x31,0x32, /* 00002D50 "H11.PH12" */ 21.838 + 0x08,0x50,0x48,0x31,0x33,0x08,0x50,0x48, /* 00002D58 ".PH13.PH" */ 21.839 + 0x31,0x34,0x08,0x50,0x48,0x31,0x35,0x08, /* 00002D60 "14.PH15." */ 21.840 + 0x50,0x48,0x31,0x36,0x08,0x50,0x48,0x31, /* 00002D68 "PH16.PH1" */ 21.841 + 0x37,0x08,0x50,0x48,0x31,0x38,0x08,0x50, /* 00002D70 "7.PH18.P" */ 21.842 + 0x48,0x31,0x39,0x08,0x50,0x48,0x31,0x41, /* 00002D78 "H19.PH1A" */ 21.843 + 0x08,0x50,0x48,0x31,0x42,0x08,0x50,0x48, /* 00002D80 ".PH1B.PH" */ 21.844 + 0x31,0x43,0x08,0x50,0x48,0x31,0x44,0x08, /* 00002D88 "1C.PH1D." */ 21.845 + 0x50,0x48,0x31,0x45,0x08,0x50,0x48,0x31, /* 00002D90 "PH1E.PH1" */ 21.846 + 0x46,0x08,0x5B,0x80,0x44,0x47,0x31,0x5F, /* 00002D98 "F.[.DG1_" */ 21.847 + 0x01,0x0B,0x44,0xB0,0x0A,0x04,0x5B,0x81, /* 00002DA0 "..D...[." */ 21.848 + 0x10,0x44,0x47,0x31,0x5F,0x01,0x44,0x50, /* 00002DA8 ".DG1_.DP" */ 21.849 + 0x54,0x31,0x08,0x44,0x50,0x54,0x32,0x08, /* 00002DB0 "T1.DPT2." */ 21.850 + 0x14,0x49,0x44,0x5F,0x4C,0x30,0x33,0x08, /* 00002DB8 ".ID_L03." */ 21.851 + 0x08,0x5F,0x54,0x5F,0x30,0x00,0x08,0x53, /* 00002DC0 "._T_0..S" */ 21.852 + 0x4C,0x54,0x5F,0x00,0x08,0x45,0x56,0x54, /* 00002DC8 "LT_..EVT" */ 21.853 + 0x5F,0x00,0x70,0x50,0x53,0x54,0x41,0x61, /* 00002DD0 "_.pPSTAa" */ 21.854 + 0x7B,0x61,0x0A,0x0F,0x45,0x56,0x54,0x5F, /* 00002DD8 "{a..EVT_" */ 21.855 + 0x70,0x50,0x53,0x54,0x42,0x61,0x7B,0x61, /* 00002DE0 "pPSTBa{a" */ 21.856 + 0x0A,0xFF,0x53,0x4C,0x54,0x5F,0x70,0x53, /* 00002DE8 "..SLT_pS" */ 21.857 + 0x4C,0x54,0x5F,0x44,0x50,0x54,0x31,0x70, /* 00002DF0 "LT_DPT1p" */ 21.858 + 0x45,0x56,0x54,0x5F,0x44,0x50,0x54,0x32, /* 00002DF8 "EVT_DPT2" */ 21.859 + 0x70,0x53,0x4C,0x54,0x5F,0x5F,0x54,0x5F, /* 00002E00 "pSLT__T_" */ 21.860 + 0x30,0xA0,0x1B,0x93,0x5F,0x54,0x5F,0x30, /* 00002E08 "0..._T_0" */ 21.861 + 0x00,0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42, /* 00002E10 "..\/._SB" */ 21.862 + 0x5F,0x50,0x43,0x49,0x30,0x53,0x30,0x30, /* 00002E18 "_PCI0S00" */ 21.863 + 0x5F,0x45,0x56,0x54,0x5F,0xA1,0x4C,0x3D, /* 00002E20 "_EVT_.L=" */ 21.864 + 0xA0,0x1B,0x93,0x5F,0x54,0x5F,0x30,0x01, /* 00002E28 "..._T_0." */ 21.865 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002E30 ".\/._SB_" */ 21.866 + 0x50,0x43,0x49,0x30,0x53,0x30,0x31,0x5F, /* 00002E38 "PCI0S01_" */ 21.867 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x3B,0xA0, /* 00002E40 "EVT_.M;." */ 21.868 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x02, /* 00002E48 ".._T_0.." */ 21.869 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002E50 ".\/._SB_" */ 21.870 + 0x50,0x43,0x49,0x30,0x53,0x30,0x32,0x5F, /* 00002E58 "PCI0S02_" */ 21.871 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x39,0xA0, /* 00002E60 "EVT_.M9." */ 21.872 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x03, /* 00002E68 ".._T_0.." */ 21.873 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002E70 ".\/._SB_" */ 21.874 + 0x50,0x43,0x49,0x30,0x53,0x30,0x33,0x5F, /* 00002E78 "PCI0S03_" */ 21.875 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x37,0xA0, /* 00002E80 "EVT_.M7." */ 21.876 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x04, /* 00002E88 ".._T_0.." */ 21.877 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002E90 ".\/._SB_" */ 21.878 + 0x50,0x43,0x49,0x30,0x53,0x30,0x34,0x5F, /* 00002E98 "PCI0S04_" */ 21.879 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x35,0xA0, /* 00002EA0 "EVT_.M5." */ 21.880 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x05, /* 00002EA8 ".._T_0.." */ 21.881 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002EB0 ".\/._SB_" */ 21.882 + 0x50,0x43,0x49,0x30,0x53,0x30,0x35,0x5F, /* 00002EB8 "PCI0S05_" */ 21.883 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x33,0xA0, /* 00002EC0 "EVT_.M3." */ 21.884 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x06, /* 00002EC8 ".._T_0.." */ 21.885 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002ED0 ".\/._SB_" */ 21.886 + 0x50,0x43,0x49,0x30,0x53,0x30,0x36,0x5F, /* 00002ED8 "PCI0S06_" */ 21.887 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x31,0xA0, /* 00002EE0 "EVT_.M1." */ 21.888 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x07, /* 00002EE8 ".._T_0.." */ 21.889 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002EF0 ".\/._SB_" */ 21.890 + 0x50,0x43,0x49,0x30,0x53,0x30,0x37,0x5F, /* 00002EF8 "PCI0S07_" */ 21.891 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2F,0xA0, /* 00002F00 "EVT_.M/." */ 21.892 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x08, /* 00002F08 ".._T_0.." */ 21.893 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F10 ".\/._SB_" */ 21.894 + 0x50,0x43,0x49,0x30,0x53,0x30,0x38,0x5F, /* 00002F18 "PCI0S08_" */ 21.895 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2D,0xA0, /* 00002F20 "EVT_.M-." */ 21.896 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x09, /* 00002F28 ".._T_0.." */ 21.897 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F30 ".\/._SB_" */ 21.898 + 0x50,0x43,0x49,0x30,0x53,0x30,0x39,0x5F, /* 00002F38 "PCI0S09_" */ 21.899 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x2B,0xA0, /* 00002F40 "EVT_.M+." */ 21.900 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0A, /* 00002F48 ".._T_0.." */ 21.901 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F50 ".\/._SB_" */ 21.902 + 0x50,0x43,0x49,0x30,0x53,0x30,0x41,0x5F, /* 00002F58 "PCI0S0A_" */ 21.903 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x29,0xA0, /* 00002F60 "EVT_.M)." */ 21.904 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0B, /* 00002F68 ".._T_0.." */ 21.905 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F70 ".\/._SB_" */ 21.906 + 0x50,0x43,0x49,0x30,0x53,0x30,0x42,0x5F, /* 00002F78 "PCI0S0B_" */ 21.907 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x27,0xA0, /* 00002F80 "EVT_.M'." */ 21.908 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0C, /* 00002F88 ".._T_0.." */ 21.909 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002F90 ".\/._SB_" */ 21.910 + 0x50,0x43,0x49,0x30,0x53,0x30,0x43,0x5F, /* 00002F98 "PCI0S0C_" */ 21.911 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x25,0xA0, /* 00002FA0 "EVT_.M%." */ 21.912 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0D, /* 00002FA8 ".._T_0.." */ 21.913 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002FB0 ".\/._SB_" */ 21.914 + 0x50,0x43,0x49,0x30,0x53,0x30,0x44,0x5F, /* 00002FB8 "PCI0S0D_" */ 21.915 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x23,0xA0, /* 00002FC0 "EVT_.M#." */ 21.916 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0E, /* 00002FC8 ".._T_0.." */ 21.917 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002FD0 ".\/._SB_" */ 21.918 + 0x50,0x43,0x49,0x30,0x53,0x30,0x45,0x5F, /* 00002FD8 "PCI0S0E_" */ 21.919 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x21,0xA0, /* 00002FE0 "EVT_.M!." */ 21.920 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x0F, /* 00002FE8 ".._T_0.." */ 21.921 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00002FF0 ".\/._SB_" */ 21.922 + 0x50,0x43,0x49,0x30,0x53,0x30,0x46,0x5F, /* 00002FF8 "PCI0S0F_" */ 21.923 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1F,0xA0, /* 00003000 "EVT_.M.." */ 21.924 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x10, /* 00003008 ".._T_0.." */ 21.925 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003010 ".\/._SB_" */ 21.926 + 0x50,0x43,0x49,0x30,0x53,0x31,0x30,0x5F, /* 00003018 "PCI0S10_" */ 21.927 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1D,0xA0, /* 00003020 "EVT_.M.." */ 21.928 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x11, /* 00003028 ".._T_0.." */ 21.929 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003030 ".\/._SB_" */ 21.930 + 0x50,0x43,0x49,0x30,0x53,0x31,0x31,0x5F, /* 00003038 "PCI0S11_" */ 21.931 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x1B,0xA0, /* 00003040 "EVT_.M.." */ 21.932 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x12, /* 00003048 ".._T_0.." */ 21.933 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003050 ".\/._SB_" */ 21.934 + 0x50,0x43,0x49,0x30,0x53,0x31,0x32,0x5F, /* 00003058 "PCI0S12_" */ 21.935 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x19,0xA0, /* 00003060 "EVT_.M.." */ 21.936 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x13, /* 00003068 ".._T_0.." */ 21.937 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003070 ".\/._SB_" */ 21.938 + 0x50,0x43,0x49,0x30,0x53,0x31,0x33,0x5F, /* 00003078 "PCI0S13_" */ 21.939 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x17,0xA0, /* 00003080 "EVT_.M.." */ 21.940 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x14, /* 00003088 ".._T_0.." */ 21.941 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003090 ".\/._SB_" */ 21.942 + 0x50,0x43,0x49,0x30,0x53,0x31,0x34,0x5F, /* 00003098 "PCI0S14_" */ 21.943 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x15,0xA0, /* 000030A0 "EVT_.M.." */ 21.944 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x15, /* 000030A8 ".._T_0.." */ 21.945 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000030B0 ".\/._SB_" */ 21.946 + 0x50,0x43,0x49,0x30,0x53,0x31,0x35,0x5F, /* 000030B8 "PCI0S15_" */ 21.947 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x13,0xA0, /* 000030C0 "EVT_.M.." */ 21.948 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x16, /* 000030C8 ".._T_0.." */ 21.949 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000030D0 ".\/._SB_" */ 21.950 + 0x50,0x43,0x49,0x30,0x53,0x31,0x36,0x5F, /* 000030D8 "PCI0S16_" */ 21.951 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x11,0xA0, /* 000030E0 "EVT_.M.." */ 21.952 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x17, /* 000030E8 ".._T_0.." */ 21.953 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000030F0 ".\/._SB_" */ 21.954 + 0x50,0x43,0x49,0x30,0x53,0x31,0x37,0x5F, /* 000030F8 "PCI0S17_" */ 21.955 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0F,0xA0, /* 00003100 "EVT_.M.." */ 21.956 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x18, /* 00003108 ".._T_0.." */ 21.957 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003110 ".\/._SB_" */ 21.958 + 0x50,0x43,0x49,0x30,0x53,0x31,0x38,0x5F, /* 00003118 "PCI0S18_" */ 21.959 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0D,0xA0, /* 00003120 "EVT_.M.." */ 21.960 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x19, /* 00003128 ".._T_0.." */ 21.961 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003130 ".\/._SB_" */ 21.962 + 0x50,0x43,0x49,0x30,0x53,0x31,0x39,0x5F, /* 00003138 "PCI0S19_" */ 21.963 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x0B,0xA0, /* 00003140 "EVT_.M.." */ 21.964 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1A, /* 00003148 ".._T_0.." */ 21.965 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003150 ".\/._SB_" */ 21.966 + 0x50,0x43,0x49,0x30,0x53,0x31,0x41,0x5F, /* 00003158 "PCI0S1A_" */ 21.967 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x09,0xA0, /* 00003160 "EVT_.M.." */ 21.968 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1B, /* 00003168 ".._T_0.." */ 21.969 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003170 ".\/._SB_" */ 21.970 + 0x50,0x43,0x49,0x30,0x53,0x31,0x42,0x5F, /* 00003178 "PCI0S1B_" */ 21.971 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x07,0xA0, /* 00003180 "EVT_.M.." */ 21.972 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1C, /* 00003188 ".._T_0.." */ 21.973 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 00003190 ".\/._SB_" */ 21.974 + 0x50,0x43,0x49,0x30,0x53,0x31,0x43,0x5F, /* 00003198 "PCI0S1C_" */ 21.975 + 0x45,0x56,0x54,0x5F,0xA1,0x4D,0x05,0xA0, /* 000031A0 "EVT_.M.." */ 21.976 + 0x1C,0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1D, /* 000031A8 ".._T_0.." */ 21.977 + 0x86,0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F, /* 000031B0 ".\/._SB_" */ 21.978 + 0x50,0x43,0x49,0x30,0x53,0x31,0x44,0x5F, /* 000031B8 "PCI0S1D_" */ 21.979 + 0x45,0x56,0x54,0x5F,0xA1,0x3D,0xA0,0x1C, /* 000031C0 "EVT_.=.." */ 21.980 + 0x93,0x5F,0x54,0x5F,0x30,0x0A,0x1E,0x86, /* 000031C8 "._T_0..." */ 21.981 + 0x5C,0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50, /* 000031D0 "\/._SB_P" */ 21.982 + 0x43,0x49,0x30,0x53,0x31,0x45,0x5F,0x45, /* 000031D8 "CI0S1E_E" */ 21.983 + 0x56,0x54,0x5F,0xA1,0x1E,0xA0,0x1C,0x93, /* 000031E0 "VT_....." */ 21.984 + 0x5F,0x54,0x5F,0x30,0x0A,0x1F,0x86,0x5C, /* 000031E8 "_T_0...\" */ 21.985 + 0x2F,0x03,0x5F,0x53,0x42,0x5F,0x50,0x43, /* 000031F0 "/._SB_PC" */ 21.986 + 0x49,0x30,0x53,0x31,0x46,0x5F,0x45,0x56, /* 000031F8 "I0S1F_EV" */ 21.987 + 0x54,0x5F, 21.988 }; 21.989 int DsdtLen=sizeof(AmlCode);
22.1 --- a/tools/firmware/hvmloader/config.h Fri Mar 27 10:54:08 2009 +0900 22.2 +++ b/tools/firmware/hvmloader/config.h Fri Mar 27 11:07:11 2009 +0900 22.3 @@ -47,6 +47,7 @@ extern unsigned long pci_mem_start, pci_ 22.4 #define E820_OFFSET 0x8 22.5 22.6 /* Xen Platform Device */ 22.7 +#define XEN_PF_IOBASE 0x10 22.8 #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */ 22.9 22.10 /* Located at BIOS_INFO_PHYSICAL_ADDRESS. */ 22.11 @@ -56,9 +57,7 @@ struct bios_info { 22.12 uint8_t hpet_present:1; /* 0[2] - System has HPET? */ 22.13 uint32_t pci_min, pci_len; /* 4, 8 - PCI I/O hole boundaries */ 22.14 uint32_t bios32_entry; /* 12 - Entry point for 32-bit BIOS */ 22.15 - uint16_t xen_pfiob; /* 16 - Xen platform device I/O ports */ 22.16 }; 22.17 #define BIOSINFO_OFF_bios32_entry 12 22.18 -#define BIOSINFO_OFF_xen_pfiob 16 22.19 22.20 #endif /* __HVMLOADER_CONFIG_H__ */
23.1 --- a/tools/firmware/hvmloader/hvmloader.c Fri Mar 27 10:54:08 2009 +0900 23.2 +++ b/tools/firmware/hvmloader/hvmloader.c Fri Mar 27 11:07:11 2009 +0900 23.3 @@ -539,25 +539,6 @@ static void cmos_write_memory_size(void) 23.4 cmos_outb(0x35, (uint8_t)( alt_mem >> 8)); 23.5 } 23.6 23.7 -static uint16_t xen_platform_io_base(void) 23.8 -{ 23.9 - uint32_t devfn, bar_data; 23.10 - uint16_t vendor_id, device_id; 23.11 - 23.12 - for ( devfn = 0; devfn < 128; devfn++ ) 23.13 - { 23.14 - vendor_id = pci_readw(devfn, PCI_VENDOR_ID); 23.15 - device_id = pci_readw(devfn, PCI_DEVICE_ID); 23.16 - if ( (vendor_id == 0x5853) && (device_id == 0x0001) ) 23.17 - { 23.18 - bar_data = pci_readl(devfn, PCI_BASE_ADDRESS_0); 23.19 - return bar_data & PCI_BASE_ADDRESS_IO_MASK; 23.20 - } 23.21 - } 23.22 - 23.23 - return 0; 23.24 -} 23.25 - 23.26 /* 23.27 * Set up an empty TSS area for virtual 8086 mode to use. 23.28 * The only important thing is that it musn't have any bits set 23.29 @@ -744,7 +725,6 @@ int main(void) 23.30 bios_info->pci_min = pci_mem_start; 23.31 bios_info->pci_len = pci_mem_end - pci_mem_start; 23.32 bios_info->bios32_entry = bios32_addr; 23.33 - bios_info->xen_pfiob = xen_platform_io_base(); 23.34 23.35 printf("Invoking ROMBIOS ...\n"); 23.36 return 0;
24.1 --- a/tools/firmware/rombios/32bit/pmm.c Fri Mar 27 10:54:08 2009 +0900 24.2 +++ b/tools/firmware/rombios/32bit/pmm.c Fri Mar 27 11:07:11 2009 +0900 24.3 @@ -71,10 +71,13 @@ 24.4 24.5 #define DEBUG_PMM 0 24.6 24.7 +#define __stringify(a) #a 24.8 +#define stringify(a) __stringify(a) 24.9 + 24.10 #define ASSERT(_expr, _action) \ 24.11 if (!(_expr)) { \ 24.12 printf("ASSERTION FAIL: %s %s:%d %s()\n", \ 24.13 - __STRING(_expr), __FILE__, __LINE__, __func__); \ 24.14 + stringify(_expr), __FILE__, __LINE__, __func__); \ 24.15 _action; \ 24.16 } else 24.17
25.1 --- a/tools/firmware/rombios/rombios.c Fri Mar 27 10:54:08 2009 +0900 25.2 +++ b/tools/firmware/rombios/rombios.c Fri Mar 27 11:07:11 2009 +0900 25.3 @@ -1418,24 +1418,14 @@ fixup_base_mem_in_k() 25.4 write_word(0x40, 0x13, base_mem >> 10); 25.5 } 25.6 25.7 -ASM_START 25.8 -_rom_write_access_control: 25.9 - push ds 25.10 - mov ax,#(BIOS_INFO_PHYSICAL_ADDRESS >> 4) 25.11 - mov ds,ax 25.12 - mov ax,[BIOSINFO_OFF_xen_pfiob] 25.13 - pop ds 25.14 - ret 25.15 -ASM_END 25.16 - 25.17 void enable_rom_write_access() 25.18 { 25.19 - outb(rom_write_access_control(), 0); 25.20 + outb(XEN_PF_IOBASE, 0); 25.21 } 25.22 25.23 void disable_rom_write_access() 25.24 { 25.25 - outb(rom_write_access_control(), PFFLAG_ROM_LOCK); 25.26 + outb(XEN_PF_IOBASE, PFFLAG_ROM_LOCK); 25.27 } 25.28 25.29 #endif /* HVMASSIST */
26.1 --- a/tools/fs-back/Makefile Fri Mar 27 10:54:08 2009 +0900 26.2 +++ b/tools/fs-back/Makefile Fri Mar 27 11:07:11 2009 +0900 26.3 @@ -16,7 +16,7 @@ CFLAGS += -D_GNU_SOURCE 26.4 LIBS := -L. -L.. -L../lib 26.5 LIBS += $(LDFLAGS_libxenctrl) 26.6 LIBS += $(LDFLAGS_libxenstore) 26.7 -LIBS += -lpthread -lrt 26.8 +LIBS += -lrt 26.9 26.10 OBJS := fs-xenbus.o fs-ops.o 26.11
27.1 --- a/tools/fs-back/fs-backend.c Fri Mar 27 10:54:08 2009 +0900 27.2 +++ b/tools/fs-back/fs-backend.c Fri Mar 27 11:07:11 2009 +0900 27.3 @@ -1,108 +1,76 @@ 27.4 #undef NDEBUG 27.5 +#include <unistd.h> 27.6 #include <stdio.h> 27.7 #include <string.h> 27.8 #include <assert.h> 27.9 #include <malloc.h> 27.10 -#include <pthread.h> 27.11 #include <xenctrl.h> 27.12 #include <aio.h> 27.13 #include <sys/mman.h> 27.14 #include <sys/select.h> 27.15 +#include <sys/socket.h> 27.16 #include <xen/io/ring.h> 27.17 +#include <xc_private.h> 27.18 +#include <err.h> 27.19 +#include "sys-queue.h" 27.20 #include "fs-backend.h" 27.21 +#include "fs-debug.h" 27.22 27.23 struct xs_handle *xsh = NULL; 27.24 static struct fs_export *fs_exports = NULL; 27.25 static int export_id = 0; 27.26 static int mount_id = 0; 27.27 +static int pipefds[2]; 27.28 +static LIST_HEAD(mount_requests_head, fs_mount) mount_requests_head; 27.29 27.30 -static void dispatch_response(struct fs_mount *mount, int priv_req_id) 27.31 +static void free_mount_request(struct fs_mount *mount); 27.32 + 27.33 +static void dispatch_response(struct fs_request *request) 27.34 { 27.35 int i; 27.36 struct fs_op *op; 27.37 - struct fs_request *req = &mount->requests[priv_req_id]; 27.38 27.39 for(i=0;;i++) 27.40 { 27.41 op = fsops[i]; 27.42 /* We should dispatch a response before reaching the end of the array */ 27.43 assert(op != NULL); 27.44 - if(op->type == req->req_shadow.type) 27.45 + if(op->type == request->req_shadow.type) 27.46 { 27.47 - printf("Found op for type=%d\n", op->type); 27.48 + FS_DEBUG("Found op for type=%d\n", op->type); 27.49 /* There needs to be a response handler */ 27.50 assert(op->response_handler != NULL); 27.51 - op->response_handler(mount, req); 27.52 + op->response_handler(request->mount, request); 27.53 break; 27.54 } 27.55 } 27.56 27.57 - req->active = 0; 27.58 - add_id_to_freelist(priv_req_id, mount->freelist); 27.59 + request->active = 0; 27.60 + add_id_to_freelist(request->id, request->mount->freelist); 27.61 } 27.62 27.63 -static void handle_aio_events(struct fs_mount *mount) 27.64 +static void handle_aio_event(struct fs_request *request) 27.65 { 27.66 - int fd, ret, count, i, notify; 27.67 - evtchn_port_t port; 27.68 - /* AIO control block for the evtchn file destriptor */ 27.69 - struct aiocb evtchn_cb; 27.70 - const struct aiocb * cb_list[mount->nr_entries]; 27.71 - int request_ids[mount->nr_entries]; 27.72 - 27.73 - /* Prepare the AIO control block for evtchn */ 27.74 - fd = xc_evtchn_fd(mount->evth); 27.75 - bzero(&evtchn_cb, sizeof(struct aiocb)); 27.76 - evtchn_cb.aio_fildes = fd; 27.77 - evtchn_cb.aio_nbytes = sizeof(port); 27.78 - evtchn_cb.aio_buf = &port; 27.79 - assert(aio_read(&evtchn_cb) == 0); 27.80 + int ret, notify; 27.81 27.82 -wait_again: 27.83 - /* Create list of active AIO requests */ 27.84 - count = 0; 27.85 - for(i=0; i<mount->nr_entries; i++) 27.86 - if(mount->requests[i].active) 27.87 - { 27.88 - cb_list[count] = &mount->requests[i].aiocb; 27.89 - request_ids[count] = i; 27.90 - count++; 27.91 - } 27.92 - /* Add the event channel at the end of the list. Event channel needs to be 27.93 - * handled last as it exits this function. */ 27.94 - cb_list[count] = &evtchn_cb; 27.95 - request_ids[count] = -1; 27.96 - count++; 27.97 + FS_DEBUG("handle_aio_event: mount %s request %d\n", request->mount->frontend, request->id); 27.98 + if (request->active < 0) { 27.99 + request->mount->nr_entries++; 27.100 + if (!request->mount->nr_entries) 27.101 + free_mount_request(request->mount); 27.102 + return; 27.103 + } 27.104 27.105 - /* Block till an AIO requset finishes, or we get an event */ 27.106 - while(1) { 27.107 - int ret = aio_suspend(cb_list, count, NULL); 27.108 - if (!ret) 27.109 - break; 27.110 - assert(errno == EINTR); 27.111 - } 27.112 - for(i=0; i<count; i++) 27.113 - if(aio_error(cb_list[i]) != EINPROGRESS) 27.114 - { 27.115 - if(request_ids[i] >= 0) 27.116 - dispatch_response(mount, request_ids[i]); 27.117 - else 27.118 - goto read_event_channel; 27.119 - } 27.120 - 27.121 - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify); 27.122 - printf("Pushed responces and notify=%d\n", notify); 27.123 + ret = aio_error(&request->aiocb); 27.124 + if(ret != EINPROGRESS && ret != ECANCELED) 27.125 + dispatch_response(request); 27.126 + 27.127 + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&request->mount->ring, notify); 27.128 + FS_DEBUG("Pushed responces and notify=%d\n", notify); 27.129 if(notify) 27.130 - xc_evtchn_notify(mount->evth, mount->local_evtchn); 27.131 - 27.132 - goto wait_again; 27.133 - 27.134 -read_event_channel: 27.135 - assert(aio_return(&evtchn_cb) == sizeof(evtchn_port_t)); 27.136 - assert(xc_evtchn_unmask(mount->evth, mount->local_evtchn) >= 0); 27.137 + xc_evtchn_notify(request->mount->evth, request->mount->local_evtchn); 27.138 } 27.139 27.140 - 27.141 static void allocate_request_array(struct fs_mount *mount) 27.142 { 27.143 int i, nr_entries = mount->nr_entries; 27.144 @@ -116,6 +84,7 @@ static void allocate_request_array(struc 27.145 for(i=0; i< nr_entries; i++) 27.146 { 27.147 requests[i].active = 0; 27.148 + requests[i].mount = mount; 27.149 add_id_to_freelist(i, freelist); 27.150 } 27.151 mount->requests = requests; 27.152 @@ -123,86 +92,102 @@ static void allocate_request_array(struc 27.153 } 27.154 27.155 27.156 -static void *handle_mount(void *data) 27.157 +static void handle_mount(struct fs_mount *mount) 27.158 { 27.159 int more, notify; 27.160 - struct fs_mount *mount = (struct fs_mount *)data; 27.161 - 27.162 - printf("Starting a thread for mount: %d\n", mount->mount_id); 27.163 - allocate_request_array(mount); 27.164 + int nr_consumed=0; 27.165 + RING_IDX cons, rp; 27.166 + struct fsif_request *req; 27.167 27.168 - for(;;) 27.169 - { 27.170 - int nr_consumed=0; 27.171 - RING_IDX cons, rp; 27.172 - struct fsif_request *req; 27.173 - 27.174 - handle_aio_events(mount); 27.175 moretodo: 27.176 - rp = mount->ring.sring->req_prod; 27.177 - xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ 27.178 + rp = mount->ring.sring->req_prod; 27.179 + xen_rmb(); /* Ensure we see queued requests up to 'rp'. */ 27.180 27.181 - while ((cons = mount->ring.req_cons) != rp) 27.182 + while ((cons = mount->ring.req_cons) != rp) 27.183 + { 27.184 + int i; 27.185 + struct fs_op *op; 27.186 + 27.187 + FS_DEBUG("Got a request at %d (of %d)\n", 27.188 + cons, RING_SIZE(&mount->ring)); 27.189 + req = RING_GET_REQUEST(&mount->ring, cons); 27.190 + FS_DEBUG("Request type=%d\n", req->type); 27.191 + for(i=0;;i++) 27.192 { 27.193 - int i; 27.194 - struct fs_op *op; 27.195 - 27.196 - printf("Got a request at %d (of %d)\n", 27.197 - cons, RING_SIZE(&mount->ring)); 27.198 - req = RING_GET_REQUEST(&mount->ring, cons); 27.199 - printf("Request type=%d\n", req->type); 27.200 - for(i=0;;i++) 27.201 + op = fsops[i]; 27.202 + if(op == NULL) 27.203 + { 27.204 + /* We've reached the end of the array, no appropirate 27.205 + * handler found. Warn, ignore and continue. */ 27.206 + FS_DEBUG("WARN: Unknown request type: %d\n", req->type); 27.207 + mount->ring.req_cons++; 27.208 + break; 27.209 + } 27.210 + if(op->type == req->type) 27.211 { 27.212 - op = fsops[i]; 27.213 - if(op == NULL) 27.214 - { 27.215 - /* We've reached the end of the array, no appropirate 27.216 - * handler found. Warn, ignore and continue. */ 27.217 - printf("WARN: Unknown request type: %d\n", req->type); 27.218 - mount->ring.req_cons++; 27.219 - break; 27.220 - } 27.221 - if(op->type == req->type) 27.222 - { 27.223 - /* There needs to be a dispatch handler */ 27.224 - assert(op->dispatch_handler != NULL); 27.225 - op->dispatch_handler(mount, req); 27.226 - break; 27.227 - } 27.228 - } 27.229 + /* There needs to be a dispatch handler */ 27.230 + assert(op->dispatch_handler != NULL); 27.231 + op->dispatch_handler(mount, req); 27.232 + break; 27.233 + } 27.234 + } 27.235 + 27.236 + nr_consumed++; 27.237 + } 27.238 + FS_DEBUG("Backend consumed: %d requests\n", nr_consumed); 27.239 + RING_FINAL_CHECK_FOR_REQUESTS(&mount->ring, more); 27.240 + if(more) goto moretodo; 27.241 + 27.242 + RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify); 27.243 + FS_DEBUG("Pushed responces and notify=%d\n", notify); 27.244 + if(notify) 27.245 + xc_evtchn_notify(mount->evth, mount->local_evtchn); 27.246 +} 27.247 27.248 - nr_consumed++; 27.249 - } 27.250 - printf("Backend consumed: %d requests\n", nr_consumed); 27.251 - RING_FINAL_CHECK_FOR_REQUESTS(&mount->ring, more); 27.252 - if(more) goto moretodo; 27.253 +static void terminate_mount_request(struct fs_mount *mount) { 27.254 + int count = 0, i; 27.255 + 27.256 + FS_DEBUG("terminate_mount_request %s\n", mount->frontend); 27.257 + xenbus_write_backend_state(mount, STATE_CLOSING); 27.258 27.259 - RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&mount->ring, notify); 27.260 - printf("Pushed responces and notify=%d\n", notify); 27.261 - if(notify) 27.262 - xc_evtchn_notify(mount->evth, mount->local_evtchn); 27.263 - } 27.264 - 27.265 - printf("Destroying thread for mount: %d\n", mount->mount_id); 27.266 - xc_gnttab_munmap(mount->gnth, mount->ring.sring, 1); 27.267 + for(i=0; i<mount->nr_entries; i++) 27.268 + if(mount->requests[i].active) { 27.269 + mount->requests[i].active = -1; 27.270 + aio_cancel(mount->requests[i].aiocb.aio_fildes, &mount->requests[i].aiocb); 27.271 + count--; 27.272 + } 27.273 + mount->nr_entries = count; 27.274 + 27.275 + while (!xenbus_frontend_state_changed(mount, STATE_CLOSING)); 27.276 + xenbus_write_backend_state(mount, STATE_CLOSED); 27.277 + 27.278 + xc_gnttab_munmap(mount->gnth, mount->ring.sring, mount->shared_ring_size); 27.279 xc_gnttab_close(mount->gnth); 27.280 xc_evtchn_unbind(mount->evth, mount->local_evtchn); 27.281 xc_evtchn_close(mount->evth); 27.282 + 27.283 + if (!count) 27.284 + free_mount_request(mount); 27.285 +} 27.286 + 27.287 +static void free_mount_request(struct fs_mount *mount) { 27.288 + FS_DEBUG("free_mount_request %s\n", mount->frontend); 27.289 free(mount->frontend); 27.290 - pthread_exit(NULL); 27.291 + free(mount->requests); 27.292 + free(mount->freelist); 27.293 + LIST_REMOVE (mount, entries); 27.294 + free(mount); 27.295 } 27.296 27.297 static void handle_connection(int frontend_dom_id, int export_id, char *frontend) 27.298 { 27.299 struct fs_mount *mount; 27.300 struct fs_export *export; 27.301 - int evt_port; 27.302 - pthread_t handling_thread; 27.303 struct fsif_sring *sring; 27.304 uint32_t dom_ids[MAX_RING_SIZE]; 27.305 int i; 27.306 27.307 - printf("Handling connection from dom=%d, for export=%d\n", 27.308 + FS_DEBUG("Handling connection from dom=%d, for export=%d\n", 27.309 frontend_dom_id, export_id); 27.310 /* Try to find the export on the list */ 27.311 export = fs_exports; 27.312 @@ -214,7 +199,7 @@ static void handle_connection(int fronte 27.313 } 27.314 if(!export) 27.315 { 27.316 - printf("Could not find the export (the id is unknown).\n"); 27.317 + FS_DEBUG("Could not find the export (the id is unknown).\n"); 27.318 return; 27.319 } 27.320 27.321 @@ -223,7 +208,7 @@ static void handle_connection(int fronte 27.322 mount->export = export; 27.323 mount->mount_id = mount_id++; 27.324 xenbus_read_mount_request(mount, frontend); 27.325 - printf("Frontend found at: %s (gref=%d, evtchn=%d)\n", 27.326 + FS_DEBUG("Frontend found at: %s (gref=%d, evtchn=%d)\n", 27.327 mount->frontend, mount->grefs[0], mount->remote_evtchn); 27.328 xenbus_write_backend_node(mount); 27.329 mount->evth = -1; 27.330 @@ -249,18 +234,24 @@ static void handle_connection(int fronte 27.331 mount->nr_entries = mount->ring.nr_ents; 27.332 for (i = 0; i < MAX_FDS; i++) 27.333 mount->fds[i] = -1; 27.334 - xenbus_write_backend_ready(mount); 27.335 27.336 - pthread_create(&handling_thread, NULL, &handle_mount, mount); 27.337 + LIST_INSERT_HEAD(&mount_requests_head, mount, entries); 27.338 + xenbus_watch_frontend_state(mount); 27.339 + xenbus_write_backend_state(mount, STATE_READY); 27.340 + 27.341 + allocate_request_array(mount); 27.342 } 27.343 27.344 static void await_connections(void) 27.345 { 27.346 - int fd, ret, dom_id, export_id; 27.347 + int fd, max_fd, ret, dom_id, export_id; 27.348 fd_set fds; 27.349 char **watch_paths; 27.350 unsigned int len; 27.351 char d; 27.352 + struct fs_mount *pointer; 27.353 + 27.354 + LIST_INIT (&mount_requests_head); 27.355 27.356 assert(xsh != NULL); 27.357 fd = xenbus_get_watch_fd(); 27.358 @@ -268,28 +259,97 @@ static void await_connections(void) 27.359 do { 27.360 FD_ZERO(&fds); 27.361 FD_SET(fd, &fds); 27.362 - ret = select(fd+1, &fds, NULL, NULL, NULL); 27.363 - assert(ret == 1); 27.364 - watch_paths = xs_read_watch(xsh, &len); 27.365 - assert(len == 2); 27.366 - assert(strcmp(watch_paths[1], "conn-watch") == 0); 27.367 - dom_id = -1; 27.368 - export_id = -1; 27.369 - d = 0; 27.370 - printf("Path changed %s\n", watch_paths[0]); 27.371 - sscanf(watch_paths[0], WATCH_NODE"/%d/%d/fronten%c", 27.372 - &dom_id, &export_id, &d); 27.373 - if((dom_id >= 0) && (export_id >= 0) && d == 'd') { 27.374 - char *frontend = xs_read(xsh, XBT_NULL, watch_paths[0], NULL); 27.375 - if (frontend) { 27.376 - handle_connection(dom_id, export_id, frontend); 27.377 - xs_rm(xsh, XBT_NULL, watch_paths[0]); 27.378 - } 27.379 - } 27.380 -next_select: 27.381 - printf("Awaiting next connection.\n"); 27.382 - /* TODO - we need to figure out what to free */ 27.383 - free(watch_paths); 27.384 + FD_SET(pipefds[0], &fds); 27.385 + max_fd = fd > pipefds[0] ? fd : pipefds[0]; 27.386 + LIST_FOREACH(pointer, &mount_requests_head, entries) { 27.387 + int tfd = xc_evtchn_fd(pointer->evth); 27.388 + FD_SET(tfd, &fds); 27.389 + if (tfd > max_fd) max_fd = tfd; 27.390 + } 27.391 + ret = select(max_fd+1, &fds, NULL, NULL, NULL); 27.392 + if (ret < 0) { 27.393 + if (errno == EINTR) continue; 27.394 + /* try to recover */ 27.395 + else if (errno == EBADF) { 27.396 + struct timeval timeout; 27.397 + memset(&timeout, 0x00, sizeof(timeout)); 27.398 + FD_ZERO(&fds); 27.399 + FD_SET(fd, &fds); 27.400 + FD_SET(pipefds[0], &fds); 27.401 + max_fd = fd > pipefds[0] ? fd : pipefds[0]; 27.402 + ret = select(max_fd + 1, &fds, NULL, NULL, &timeout); 27.403 + if (ret < 0) 27.404 + err(1, "select: unrecoverable error occurred: %d\n", errno); 27.405 + 27.406 + /* trying to find the bogus fd among the open event channels */ 27.407 + LIST_FOREACH(pointer, &mount_requests_head, entries) { 27.408 + int tfd = xc_evtchn_fd(pointer->evth); 27.409 + memset(&timeout, 0x00, sizeof(timeout)); 27.410 + FD_ZERO(&fds); 27.411 + FD_SET(tfd, &fds); 27.412 + ret = select(tfd + 1, &fds, NULL, NULL, &timeout); 27.413 + if (ret < 0) { 27.414 + FS_DEBUG("fd %d is bogus, closing the related connection\n", tfd); 27.415 + pointer->evth = fd; 27.416 + terminate_mount_request(pointer); 27.417 + continue; 27.418 + } 27.419 + } 27.420 + continue; 27.421 + } else 27.422 + err(1, "select: unrecoverable error occurred: %d\n", errno); 27.423 + } 27.424 + if (FD_ISSET(fd, &fds)) { 27.425 + watch_paths = xs_read_watch(xsh, &len); 27.426 + if (!strcmp(watch_paths[XS_WATCH_TOKEN], "conn-watch")) { 27.427 + dom_id = -1; 27.428 + export_id = -1; 27.429 + d = 0; 27.430 + FS_DEBUG("Path changed %s\n", watch_paths[0]); 27.431 + sscanf(watch_paths[XS_WATCH_PATH], WATCH_NODE"/%d/%d/fronten%c", 27.432 + &dom_id, &export_id, &d); 27.433 + if((dom_id >= 0) && (export_id >= 0) && d == 'd') { 27.434 + char *frontend = xs_read(xsh, XBT_NULL, watch_paths[XS_WATCH_PATH], NULL); 27.435 + if (frontend) { 27.436 + handle_connection(dom_id, export_id, frontend); 27.437 + xs_rm(xsh, XBT_NULL, watch_paths[XS_WATCH_PATH]); 27.438 + } 27.439 + } 27.440 + } else if (!strcmp(watch_paths[XS_WATCH_TOKEN], "frontend-state")) { 27.441 + LIST_FOREACH(pointer, &mount_requests_head, entries) { 27.442 + if (!strncmp(pointer->frontend, watch_paths[XS_WATCH_PATH], strlen(pointer->frontend))) { 27.443 + char *state = xenbus_read_frontend_state(pointer); 27.444 + if (!state || strcmp(state, STATE_READY)) { 27.445 + xenbus_unwatch_frontend_state(pointer); 27.446 + terminate_mount_request(pointer); 27.447 + } 27.448 + free(state); 27.449 + break; 27.450 + } 27.451 + } 27.452 + } else { 27.453 + FS_DEBUG("xenstore watch event unrecognized\n"); 27.454 + } 27.455 + FS_DEBUG("Awaiting next connection.\n"); 27.456 + /* TODO - we need to figure out what to free */ 27.457 + free(watch_paths); 27.458 + } 27.459 + if (FD_ISSET(pipefds[0], &fds)) { 27.460 + struct fs_request *request; 27.461 + if (read_exact(pipefds[0], &request, sizeof(struct fs_request *)) < 0) 27.462 + err(1, "read request failed\n"); 27.463 + handle_aio_event(request); 27.464 + } 27.465 + LIST_FOREACH(pointer, &mount_requests_head, entries) { 27.466 + if (FD_ISSET(xc_evtchn_fd(pointer->evth), &fds)) { 27.467 + evtchn_port_t port; 27.468 + port = xc_evtchn_pending(pointer->evth); 27.469 + if (port != -1) { 27.470 + handle_mount(pointer); 27.471 + xc_evtchn_unmask(pointer->evth, port); 27.472 + } 27.473 + } 27.474 + } 27.475 } while (1); 27.476 } 27.477 27.478 @@ -312,10 +372,29 @@ static struct fs_export* create_export(c 27.479 return curr_export; 27.480 } 27.481 27.482 +static void aio_signal_handler(int signo, siginfo_t *info, void *context) 27.483 +{ 27.484 + struct fs_request *request = (struct fs_request*) info->si_value.sival_ptr; 27.485 + int saved_errno = errno; 27.486 + if (write_exact(pipefds[1], &request, sizeof(struct fs_request *)) < 0) 27.487 + err(1, "write request filed\n"); 27.488 + errno = saved_errno; 27.489 +} 27.490 27.491 int main(void) 27.492 { 27.493 struct fs_export *export; 27.494 + struct sigaction act; 27.495 + sigset_t enable; 27.496 + 27.497 + sigemptyset(&enable); 27.498 + sigaddset(&enable, SIGUSR2); 27.499 + pthread_sigmask(SIG_UNBLOCK, &enable, NULL); 27.500 + 27.501 + sigfillset(&act.sa_mask); 27.502 + act.sa_flags = SA_SIGINFO; /* do not restart syscalls to interrupt select(); use sa_sigaction */ 27.503 + act.sa_sigaction = aio_signal_handler; 27.504 + sigaction(SIGUSR2, &act, NULL); 27.505 27.506 /* Open the connection to XenStore first */ 27.507 xsh = xs_domain_open(); 27.508 @@ -328,6 +407,9 @@ int main(void) 27.509 export = create_export("default", "/exports"); 27.510 xenbus_register_export(export); 27.511 27.512 + if (socketpair(PF_UNIX,SOCK_STREAM, 0, pipefds) == -1) 27.513 + err(1, "failed to create pipe\n"); 27.514 + 27.515 await_connections(); 27.516 /* Close the connection to XenStore when we are finished with everything */ 27.517 xs_daemon_close(xsh);
28.1 --- a/tools/fs-back/fs-backend.h Fri Mar 27 10:54:08 2009 +0900 28.2 +++ b/tools/fs-back/fs-backend.h Fri Mar 27 11:07:11 2009 +0900 28.3 @@ -7,6 +7,7 @@ 28.4 #include <xen/event_channel.h> 28.5 #include <xen/io/ring.h> 28.6 #include <xen/io/fsif.h> 28.7 +#include "sys-queue.h" 28.8 28.9 #define ROOT_NODE "backend/vfs" 28.10 #define EXPORTS_SUBNODE "exports" 28.11 @@ -25,6 +26,8 @@ struct fs_export 28.12 28.13 struct fs_request 28.14 { 28.15 + struct fs_mount *mount; 28.16 + int id; 28.17 int active; 28.18 void *page; /* Pointer to mapped grant */ 28.19 int count; 28.20 @@ -50,6 +53,7 @@ struct fs_mount 28.21 struct fs_request *requests; 28.22 unsigned short *freelist; 28.23 int fds[MAX_FDS]; 28.24 + LIST_ENTRY(fs_mount) entries; 28.25 }; 28.26 28.27 28.28 @@ -61,7 +65,11 @@ int xenbus_register_export(struct fs_exp 28.29 int xenbus_get_watch_fd(void); 28.30 void xenbus_read_mount_request(struct fs_mount *mount, char *frontend); 28.31 void xenbus_write_backend_node(struct fs_mount *mount); 28.32 -void xenbus_write_backend_ready(struct fs_mount *mount); 28.33 +void xenbus_write_backend_state(struct fs_mount *mount, const char *state); 28.34 +int xenbus_frontend_state_changed(struct fs_mount *mount, const char *oldstate); 28.35 +void xenbus_watch_frontend_state(struct fs_mount *mount); 28.36 +void xenbus_unwatch_frontend_state(struct fs_mount *mount); 28.37 +char* xenbus_read_frontend_state(struct fs_mount *mount); 28.38 28.39 /* File operations, implemented in fs-ops.c */ 28.40 struct fs_op
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/tools/fs-back/fs-debug.h Fri Mar 27 11:07:11 2009 +0900 29.3 @@ -0,0 +1,12 @@ 29.4 +#ifndef __FS_DEBUG__ 29.5 +#define __FS_DEBUG__ 29.6 + 29.7 +// #define DEBUG 1 29.8 + 29.9 +#ifdef DEBUG 29.10 +#define FS_DEBUG(fmt, ...) do { fprintf(stderr, fmt, ## __VA_ARGS__); } while (0) 29.11 +#else 29.12 +#define FS_DEBUG(fmt, ...) do { } while (0) 29.13 +#endif 29.14 + 29.15 +#endif /*__FS_DEBUG__*/
30.1 --- a/tools/fs-back/fs-ops.c Fri Mar 27 10:54:08 2009 +0900 30.2 +++ b/tools/fs-back/fs-ops.c Fri Mar 27 11:07:11 2009 +0900 30.3 @@ -14,6 +14,7 @@ 30.4 #include <sys/mount.h> 30.5 #include <unistd.h> 30.6 #include "fs-backend.h" 30.7 +#include "fs-debug.h" 30.8 30.9 /* For debugging only */ 30.10 #include <sys/time.h> 30.11 @@ -22,12 +23,11 @@ 30.12 30.13 #define BUFFER_SIZE 1024 30.14 30.15 - 30.16 static unsigned short get_request(struct fs_mount *mount, struct fsif_request *req) 30.17 { 30.18 unsigned short id = get_id_from_freelist(mount->freelist); 30.19 30.20 - printf("Private Request id: %d\n", id); 30.21 + FS_DEBUG("Private Request id: %d\n", id); 30.22 memcpy(&mount->requests[id].req_shadow, req, sizeof(struct fsif_request)); 30.23 mount->requests[id].active = 1; 30.24 30.25 @@ -49,12 +49,11 @@ static void dispatch_file_open(struct fs 30.26 { 30.27 char *file_name, full_path[BUFFER_SIZE]; 30.28 int fd; 30.29 - struct timeval tv1, tv2; 30.30 RING_IDX rsp_idx; 30.31 fsif_response_t *rsp; 30.32 uint16_t req_id; 30.33 30.34 - printf("Dispatching file open operation (gref=%d).\n", req->u.fopen.gref); 30.35 + FS_DEBUG("Dispatching file open operation (gref=%d).\n", req->u.fopen.gref); 30.36 /* Read the request, and open file */ 30.37 file_name = xc_gnttab_map_grant_ref(mount->gnth, 30.38 mount->dom_id, 30.39 @@ -62,13 +61,13 @@ static void dispatch_file_open(struct fs 30.40 PROT_READ); 30.41 30.42 req_id = req->id; 30.43 - printf("File open issued for %s\n", file_name); 30.44 + FS_DEBUG("File open issued for %s\n", file_name); 30.45 assert(BUFFER_SIZE > 30.46 strlen(file_name) + strlen(mount->export->export_path) + 1); 30.47 snprintf(full_path, sizeof(full_path), "%s/%s", 30.48 mount->export->export_path, file_name); 30.49 assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0); 30.50 - printf("Issuing open for %s\n", full_path); 30.51 + FS_DEBUG("Issuing open for %s\n", full_path); 30.52 fd = get_fd(mount); 30.53 if (fd >= 0) { 30.54 int real_fd = open(full_path, O_RDWR); 30.55 @@ -77,7 +76,7 @@ static void dispatch_file_open(struct fs 30.56 else 30.57 { 30.58 mount->fds[fd] = real_fd; 30.59 - printf("Got FD: %d for real %d\n", fd, real_fd); 30.60 + FS_DEBUG("Got FD: %d for real %d\n", fd, real_fd); 30.61 } 30.62 } 30.63 /* We can advance the request consumer index, from here on, the request 30.64 @@ -87,7 +86,7 @@ static void dispatch_file_open(struct fs 30.65 30.66 /* Get a response from the ring */ 30.67 rsp_idx = mount->ring.rsp_prod_pvt++; 30.68 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.69 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.70 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.71 rsp->id = req_id; 30.72 rsp->ret_val = (uint64_t)fd; 30.73 @@ -100,7 +99,7 @@ static void dispatch_file_close(struct f 30.74 fsif_response_t *rsp; 30.75 uint16_t req_id; 30.76 30.77 - printf("Dispatching file close operation (fd=%d).\n", req->u.fclose.fd); 30.78 + FS_DEBUG("Dispatching file close operation (fd=%d).\n", req->u.fclose.fd); 30.79 30.80 req_id = req->id; 30.81 if (req->u.fclose.fd < MAX_FDS) { 30.82 @@ -109,7 +108,7 @@ static void dispatch_file_close(struct f 30.83 mount->fds[req->u.fclose.fd] = -1; 30.84 } else 30.85 ret = -1; 30.86 - printf("Got ret: %d\n", ret); 30.87 + FS_DEBUG("Got ret: %d\n", ret); 30.88 /* We can advance the request consumer index, from here on, the request 30.89 * should not be used (it may be overrinden by a response) */ 30.90 mount->ring.req_cons++; 30.91 @@ -117,7 +116,7 @@ static void dispatch_file_close(struct f 30.92 30.93 /* Get a response from the ring */ 30.94 rsp_idx = mount->ring.rsp_prod_pvt++; 30.95 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.96 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.97 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.98 rsp->id = req_id; 30.99 rsp->ret_val = (uint64_t)ret; 30.100 @@ -127,7 +126,7 @@ static void dispatch_file_close(struct f 30.101 static void dispatch_file_read(struct fs_mount *mount, struct fsif_request *req) 30.102 { 30.103 void *buf; 30.104 - int fd, i, count; 30.105 + int fd, count; 30.106 uint16_t req_id; 30.107 unsigned short priv_id; 30.108 struct fs_request *priv_req; 30.109 @@ -143,7 +142,7 @@ static void dispatch_file_read(struct fs 30.110 PROT_WRITE); 30.111 30.112 req_id = req->id; 30.113 - printf("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 30.114 + FS_DEBUG("File read issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 30.115 req->u.fread.fd, req->u.fread.len, req->u.fread.offset); 30.116 30.117 if (req->u.fread.fd < MAX_FDS) 30.118 @@ -152,10 +151,11 @@ static void dispatch_file_read(struct fs 30.119 fd = -1; 30.120 30.121 priv_id = get_request(mount, req); 30.122 - printf("Private id is: %d\n", priv_id); 30.123 + FS_DEBUG("Private id is: %d\n", priv_id); 30.124 priv_req = &mount->requests[priv_id]; 30.125 priv_req->page = buf; 30.126 priv_req->count = count; 30.127 + priv_req->id = priv_id; 30.128 30.129 /* Dispatch AIO read request */ 30.130 bzero(&priv_req->aiocb, sizeof(struct aiocb)); 30.131 @@ -163,9 +163,11 @@ static void dispatch_file_read(struct fs 30.132 priv_req->aiocb.aio_nbytes = req->u.fread.len; 30.133 priv_req->aiocb.aio_offset = req->u.fread.offset; 30.134 priv_req->aiocb.aio_buf = buf; 30.135 + priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 30.136 + priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2; 30.137 + priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req; 30.138 assert(aio_read(&priv_req->aiocb) >= 0); 30.139 30.140 -out: 30.141 /* We can advance the request consumer index, from here on, the request 30.142 * should not be used (it may be overrinden by a response) */ 30.143 mount->ring.req_cons++; 30.144 @@ -185,7 +187,7 @@ static void end_file_read(struct fs_moun 30.145 /* Get a response from the ring */ 30.146 rsp_idx = mount->ring.rsp_prod_pvt++; 30.147 req_id = priv_req->req_shadow.id; 30.148 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.149 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.150 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.151 rsp->id = req_id; 30.152 rsp->ret_val = (uint64_t)aio_return(&priv_req->aiocb); 30.153 @@ -194,7 +196,7 @@ static void end_file_read(struct fs_moun 30.154 static void dispatch_file_write(struct fs_mount *mount, struct fsif_request *req) 30.155 { 30.156 void *buf; 30.157 - int fd, count, i; 30.158 + int fd, count; 30.159 uint16_t req_id; 30.160 unsigned short priv_id; 30.161 struct fs_request *priv_req; 30.162 @@ -210,7 +212,7 @@ static void dispatch_file_write(struct f 30.163 PROT_READ); 30.164 30.165 req_id = req->id; 30.166 - printf("File write issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 30.167 + FS_DEBUG("File write issued for FD=%d (len=%"PRIu64", offest=%"PRIu64")\n", 30.168 req->u.fwrite.fd, req->u.fwrite.len, req->u.fwrite.offset); 30.169 30.170 if (req->u.fwrite.fd < MAX_FDS) 30.171 @@ -219,10 +221,11 @@ static void dispatch_file_write(struct f 30.172 fd = -1; 30.173 30.174 priv_id = get_request(mount, req); 30.175 - printf("Private id is: %d\n", priv_id); 30.176 + FS_DEBUG("Private id is: %d\n", priv_id); 30.177 priv_req = &mount->requests[priv_id]; 30.178 priv_req->page = buf; 30.179 priv_req->count = count; 30.180 + priv_req->id = priv_id; 30.181 30.182 /* Dispatch AIO write request */ 30.183 bzero(&priv_req->aiocb, sizeof(struct aiocb)); 30.184 @@ -230,6 +233,9 @@ static void dispatch_file_write(struct f 30.185 priv_req->aiocb.aio_nbytes = req->u.fwrite.len; 30.186 priv_req->aiocb.aio_offset = req->u.fwrite.offset; 30.187 priv_req->aiocb.aio_buf = buf; 30.188 + priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 30.189 + priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2; 30.190 + priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req; 30.191 assert(aio_write(&priv_req->aiocb) >= 0); 30.192 30.193 30.194 @@ -252,7 +258,7 @@ static void end_file_write(struct fs_mou 30.195 /* Get a response from the ring */ 30.196 rsp_idx = mount->ring.rsp_prod_pvt++; 30.197 req_id = priv_req->req_shadow.id; 30.198 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.199 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.200 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.201 rsp->id = req_id; 30.202 rsp->ret_val = (uint64_t)aio_return(&priv_req->aiocb); 30.203 @@ -260,7 +266,6 @@ static void end_file_write(struct fs_mou 30.204 30.205 static void dispatch_stat(struct fs_mount *mount, struct fsif_request *req) 30.206 { 30.207 - struct fsif_stat_response *buf; 30.208 struct stat stat; 30.209 int fd, ret; 30.210 uint16_t req_id; 30.211 @@ -273,7 +278,7 @@ static void dispatch_stat(struct fs_moun 30.212 else 30.213 fd = -1; 30.214 30.215 - printf("File stat issued for FD=%d\n", req->u.fstat.fd); 30.216 + FS_DEBUG("File stat issued for FD=%d\n", req->u.fstat.fd); 30.217 30.218 /* We can advance the request consumer index, from here on, the request 30.219 * should not be used (it may be overrinden by a response) */ 30.220 @@ -281,12 +286,12 @@ static void dispatch_stat(struct fs_moun 30.221 30.222 /* Stat, and create the response */ 30.223 ret = fstat(fd, &stat); 30.224 - printf("Mode=%o, uid=%d, a_time=%ld\n", 30.225 + FS_DEBUG("Mode=%o, uid=%d, a_time=%ld\n", 30.226 stat.st_mode, stat.st_uid, (long)stat.st_atime); 30.227 30.228 /* Get a response from the ring */ 30.229 rsp_idx = mount->ring.rsp_prod_pvt++; 30.230 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.231 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.232 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.233 rsp->id = req_id; 30.234 rsp->fstat.stat_ret = (uint32_t)ret; 30.235 @@ -320,7 +325,7 @@ static void dispatch_truncate(struct fs_ 30.236 30.237 req_id = req->id; 30.238 length = req->u.ftruncate.length; 30.239 - printf("File truncate issued for FD=%d, length=%"PRId64"\n", req->u.ftruncate.fd, length); 30.240 + FS_DEBUG("File truncate issued for FD=%d, length=%"PRId64"\n", req->u.ftruncate.fd, length); 30.241 30.242 if (req->u.ftruncate.fd < MAX_FDS) 30.243 fd = mount->fds[req->u.ftruncate.fd]; 30.244 @@ -336,7 +341,7 @@ static void dispatch_truncate(struct fs_ 30.245 30.246 /* Get a response from the ring */ 30.247 rsp_idx = mount->ring.rsp_prod_pvt++; 30.248 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.249 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.250 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.251 rsp->id = req_id; 30.252 rsp->ret_val = (uint64_t)ret; 30.253 @@ -350,7 +355,7 @@ static void dispatch_remove(struct fs_mo 30.254 fsif_response_t *rsp; 30.255 uint16_t req_id; 30.256 30.257 - printf("Dispatching remove operation (gref=%d).\n", req->u.fremove.gref); 30.258 + FS_DEBUG("Dispatching remove operation (gref=%d).\n", req->u.fremove.gref); 30.259 /* Read the request, and open file */ 30.260 file_name = xc_gnttab_map_grant_ref(mount->gnth, 30.261 mount->dom_id, 30.262 @@ -358,15 +363,15 @@ static void dispatch_remove(struct fs_mo 30.263 PROT_READ); 30.264 30.265 req_id = req->id; 30.266 - printf("File remove issued for %s\n", file_name); 30.267 + FS_DEBUG("File remove issued for %s\n", file_name); 30.268 assert(BUFFER_SIZE > 30.269 strlen(file_name) + strlen(mount->export->export_path) + 1); 30.270 snprintf(full_path, sizeof(full_path), "%s/%s", 30.271 mount->export->export_path, file_name); 30.272 assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0); 30.273 - printf("Issuing remove for %s\n", full_path); 30.274 + FS_DEBUG("Issuing remove for %s\n", full_path); 30.275 ret = remove(full_path); 30.276 - printf("Got ret: %d\n", ret); 30.277 + FS_DEBUG("Got ret: %d\n", ret); 30.278 /* We can advance the request consumer index, from here on, the request 30.279 * should not be used (it may be overrinden by a response) */ 30.280 mount->ring.req_cons++; 30.281 @@ -374,7 +379,7 @@ static void dispatch_remove(struct fs_mo 30.282 30.283 /* Get a response from the ring */ 30.284 rsp_idx = mount->ring.rsp_prod_pvt++; 30.285 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.286 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.287 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.288 rsp->id = req_id; 30.289 rsp->ret_val = (uint64_t)ret; 30.290 @@ -390,7 +395,7 @@ static void dispatch_rename(struct fs_mo 30.291 fsif_response_t *rsp; 30.292 uint16_t req_id; 30.293 30.294 - printf("Dispatching rename operation (gref=%d).\n", req->u.fremove.gref); 30.295 + FS_DEBUG("Dispatching rename operation (gref=%d).\n", req->u.fremove.gref); 30.296 /* Read the request, and open file */ 30.297 buf = xc_gnttab_map_grant_ref(mount->gnth, 30.298 mount->dom_id, 30.299 @@ -400,7 +405,7 @@ static void dispatch_rename(struct fs_mo 30.300 req_id = req->id; 30.301 old_file_name = buf + req->u.frename.old_name_offset; 30.302 new_file_name = buf + req->u.frename.new_name_offset; 30.303 - printf("File rename issued for %s -> %s (buf=%s)\n", 30.304 + FS_DEBUG("File rename issued for %s -> %s (buf=%s)\n", 30.305 old_file_name, new_file_name, buf); 30.306 assert(BUFFER_SIZE > 30.307 strlen(old_file_name) + strlen(mount->export->export_path) + 1); 30.308 @@ -411,9 +416,9 @@ static void dispatch_rename(struct fs_mo 30.309 snprintf(new_full_path, sizeof(new_full_path), "%s/%s", 30.310 mount->export->export_path, new_file_name); 30.311 assert(xc_gnttab_munmap(mount->gnth, buf, 1) == 0); 30.312 - printf("Issuing rename for %s -> %s\n", old_full_path, new_full_path); 30.313 + FS_DEBUG("Issuing rename for %s -> %s\n", old_full_path, new_full_path); 30.314 ret = rename(old_full_path, new_full_path); 30.315 - printf("Got ret: %d\n", ret); 30.316 + FS_DEBUG("Got ret: %d\n", ret); 30.317 /* We can advance the request consumer index, from here on, the request 30.318 * should not be used (it may be overrinden by a response) */ 30.319 mount->ring.req_cons++; 30.320 @@ -421,7 +426,7 @@ static void dispatch_rename(struct fs_mo 30.321 30.322 /* Get a response from the ring */ 30.323 rsp_idx = mount->ring.rsp_prod_pvt++; 30.324 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.325 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.326 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.327 rsp->id = req_id; 30.328 rsp->ret_val = (uint64_t)ret; 30.329 @@ -438,7 +443,7 @@ static void dispatch_create(struct fs_mo 30.330 fsif_response_t *rsp; 30.331 uint16_t req_id; 30.332 30.333 - printf("Dispatching file create operation (gref=%d).\n", req->u.fcreate.gref); 30.334 + FS_DEBUG("Dispatching file create operation (gref=%d).\n", req->u.fcreate.gref); 30.335 /* Read the request, and create file/directory */ 30.336 mode = req->u.fcreate.mode; 30.337 directory = req->u.fcreate.directory; 30.338 @@ -448,7 +453,7 @@ static void dispatch_create(struct fs_mo 30.339 PROT_READ); 30.340 30.341 req_id = req->id; 30.342 - printf("File create issued for %s\n", file_name); 30.343 + FS_DEBUG("File create issued for %s\n", file_name); 30.344 assert(BUFFER_SIZE > 30.345 strlen(file_name) + strlen(mount->export->export_path) + 1); 30.346 snprintf(full_path, sizeof(full_path), "%s/%s", 30.347 @@ -460,12 +465,12 @@ static void dispatch_create(struct fs_mo 30.348 30.349 if(directory) 30.350 { 30.351 - printf("Issuing create for directory: %s\n", full_path); 30.352 + FS_DEBUG("Issuing create for directory: %s\n", full_path); 30.353 ret = mkdir(full_path, mode); 30.354 } 30.355 else 30.356 { 30.357 - printf("Issuing create for file: %s\n", full_path); 30.358 + FS_DEBUG("Issuing create for file: %s\n", full_path); 30.359 ret = get_fd(mount); 30.360 if (ret >= 0) { 30.361 int real_fd = creat(full_path, mode); 30.362 @@ -474,15 +479,15 @@ static void dispatch_create(struct fs_mo 30.363 else 30.364 { 30.365 mount->fds[ret] = real_fd; 30.366 - printf("Got FD: %d for real %d\n", ret, real_fd); 30.367 + FS_DEBUG("Got FD: %d for real %d\n", ret, real_fd); 30.368 } 30.369 } 30.370 } 30.371 - printf("Got ret %d (errno=%d)\n", ret, errno); 30.372 + FS_DEBUG("Got ret %d (errno=%d)\n", ret, errno); 30.373 30.374 /* Get a response from the ring */ 30.375 rsp_idx = mount->ring.rsp_prod_pvt++; 30.376 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.377 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.378 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.379 rsp->id = req_id; 30.380 rsp->ret_val = (uint64_t)ret; 30.381 @@ -499,7 +504,7 @@ static void dispatch_list(struct fs_moun 30.382 DIR *dir; 30.383 struct dirent *dirent = NULL; 30.384 30.385 - printf("Dispatching list operation (gref=%d).\n", req->u.flist.gref); 30.386 + FS_DEBUG("Dispatching list operation (gref=%d).\n", req->u.flist.gref); 30.387 /* Read the request, and list directory */ 30.388 offset = req->u.flist.offset; 30.389 buf = file_name = xc_gnttab_map_grant_ref(mount->gnth, 30.390 @@ -508,7 +513,7 @@ static void dispatch_list(struct fs_moun 30.391 PROT_READ | PROT_WRITE); 30.392 30.393 req_id = req->id; 30.394 - printf("Dir list issued for %s\n", file_name); 30.395 + FS_DEBUG("Dir list issued for %s\n", file_name); 30.396 assert(BUFFER_SIZE > 30.397 strlen(file_name) + strlen(mount->export->export_path) + 1); 30.398 snprintf(full_path, sizeof(full_path), "%s/%s", 30.399 @@ -552,7 +557,7 @@ error_out: 30.400 30.401 /* Get a response from the ring */ 30.402 rsp_idx = mount->ring.rsp_prod_pvt++; 30.403 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.404 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.405 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.406 rsp->id = req_id; 30.407 rsp->ret_val = ret_val; 30.408 @@ -566,7 +571,7 @@ static void dispatch_chmod(struct fs_mou 30.409 uint16_t req_id; 30.410 int32_t mode; 30.411 30.412 - printf("Dispatching file chmod operation (fd=%d, mode=%o).\n", 30.413 + FS_DEBUG("Dispatching file chmod operation (fd=%d, mode=%o).\n", 30.414 req->u.fchmod.fd, req->u.fchmod.mode); 30.415 req_id = req->id; 30.416 if (req->u.fchmod.fd < MAX_FDS) 30.417 @@ -583,7 +588,7 @@ static void dispatch_chmod(struct fs_mou 30.418 30.419 /* Get a response from the ring */ 30.420 rsp_idx = mount->ring.rsp_prod_pvt++; 30.421 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.422 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.423 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.424 rsp->id = req_id; 30.425 rsp->ret_val = (uint64_t)ret; 30.426 @@ -598,7 +603,7 @@ static void dispatch_fs_space(struct fs_ 30.427 struct statvfs stat; 30.428 int64_t ret; 30.429 30.430 - printf("Dispatching fs space operation (gref=%d).\n", req->u.fspace.gref); 30.431 + FS_DEBUG("Dispatching fs space operation (gref=%d).\n", req->u.fspace.gref); 30.432 /* Read the request, and open file */ 30.433 file_name = xc_gnttab_map_grant_ref(mount->gnth, 30.434 mount->dom_id, 30.435 @@ -606,13 +611,13 @@ static void dispatch_fs_space(struct fs_ 30.436 PROT_READ); 30.437 30.438 req_id = req->id; 30.439 - printf("Fs space issued for %s\n", file_name); 30.440 + FS_DEBUG("Fs space issued for %s\n", file_name); 30.441 assert(BUFFER_SIZE > 30.442 strlen(file_name) + strlen(mount->export->export_path) + 1); 30.443 snprintf(full_path, sizeof(full_path), "%s/%s", 30.444 mount->export->export_path, file_name); 30.445 assert(xc_gnttab_munmap(mount->gnth, file_name, 1) == 0); 30.446 - printf("Issuing fs space for %s\n", full_path); 30.447 + FS_DEBUG("Issuing fs space for %s\n", full_path); 30.448 ret = statvfs(full_path, &stat); 30.449 if(ret >= 0) 30.450 ret = stat.f_bsize * stat.f_bfree; 30.451 @@ -624,7 +629,7 @@ static void dispatch_fs_space(struct fs_ 30.452 30.453 /* Get a response from the ring */ 30.454 rsp_idx = mount->ring.rsp_prod_pvt++; 30.455 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.456 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.457 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.458 rsp->id = req_id; 30.459 rsp->ret_val = (uint64_t)ret; 30.460 @@ -643,15 +648,19 @@ static void dispatch_file_sync(struct fs 30.461 else 30.462 fd = -1; 30.463 30.464 - printf("File sync issued for FD=%d\n", req->u.fsync.fd); 30.465 + FS_DEBUG("File sync issued for FD=%d\n", req->u.fsync.fd); 30.466 30.467 priv_id = get_request(mount, req); 30.468 - printf("Private id is: %d\n", priv_id); 30.469 + FS_DEBUG("Private id is: %d\n", priv_id); 30.470 priv_req = &mount->requests[priv_id]; 30.471 + priv_req->id = priv_id; 30.472 30.473 /* Dispatch AIO read request */ 30.474 bzero(&priv_req->aiocb, sizeof(struct aiocb)); 30.475 priv_req->aiocb.aio_fildes = fd; 30.476 + priv_req->aiocb.aio_sigevent.sigev_notify = SIGEV_SIGNAL; 30.477 + priv_req->aiocb.aio_sigevent.sigev_signo = SIGUSR2; 30.478 + priv_req->aiocb.aio_sigevent.sigev_value.sival_ptr = priv_req; 30.479 assert(aio_fsync(O_SYNC, &priv_req->aiocb) >= 0); 30.480 30.481 30.482 @@ -669,7 +678,7 @@ static void end_file_sync(struct fs_moun 30.483 /* Get a response from the ring */ 30.484 rsp_idx = mount->ring.rsp_prod_pvt++; 30.485 req_id = priv_req->req_shadow.id; 30.486 - printf("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.487 + FS_DEBUG("Writing response at: idx=%d, id=%d\n", rsp_idx, req_id); 30.488 rsp = RING_GET_RESPONSE(&mount->ring, rsp_idx); 30.489 rsp->id = req_id; 30.490 rsp->ret_val = (uint64_t)aio_return(&priv_req->aiocb);
31.1 --- a/tools/fs-back/fs-xenbus.c Fri Mar 27 10:54:08 2009 +0900 31.2 +++ b/tools/fs-back/fs-xenbus.c Fri Mar 27 11:07:11 2009 +0900 31.3 @@ -4,10 +4,12 @@ 31.4 #include <stdarg.h> 31.5 #include <string.h> 31.6 #include <assert.h> 31.7 +#include <sys/select.h> 31.8 #include <xenctrl.h> 31.9 #include <xs.h> 31.10 #include <xen/io/fsif.h> 31.11 #include "fs-backend.h" 31.12 +#include "fs-debug.h" 31.13 31.14 31.15 static bool xenbus_printf(struct xs_handle *xsh, 31.16 @@ -25,7 +27,7 @@ static bool xenbus_printf(struct xs_hand 31.17 snprintf(fullpath, sizeof(fullpath), "%s/%s", node, path); 31.18 vsnprintf(val, sizeof(val), fmt, args); 31.19 va_end(args); 31.20 - printf("xenbus_printf (%s) <= %s.\n", fullpath, val); 31.21 + FS_DEBUG("xenbus_printf (%s) <= %s.\n", fullpath, val); 31.22 31.23 return xs_write(xsh, xbt, fullpath, val, strlen(val)); 31.24 } 31.25 @@ -57,19 +59,19 @@ int xenbus_register_export(struct fs_exp 31.26 assert(xsh != NULL); 31.27 if(xsh == NULL) 31.28 { 31.29 - printf("Could not open connection to xenbus deamon.\n"); 31.30 + FS_DEBUG("Could not open connection to xenbus deamon.\n"); 31.31 goto error_exit; 31.32 } 31.33 - printf("Connection to the xenbus deamon opened successfully.\n"); 31.34 + FS_DEBUG("Connection to the xenbus deamon opened successfully.\n"); 31.35 31.36 /* Start transaction */ 31.37 xst = xs_transaction_start(xsh); 31.38 if(xst == 0) 31.39 { 31.40 - printf("Could not start a transaction.\n"); 31.41 + FS_DEBUG("Could not start a transaction.\n"); 31.42 goto error_exit; 31.43 } 31.44 - printf("XS transaction is %d\n", xst); 31.45 + FS_DEBUG("XS transaction is %d\n", xst); 31.46 31.47 /* Create node string */ 31.48 snprintf(node, sizeof(node), "%s/%d", EXPORTS_NODE, export->export_id); 31.49 @@ -78,7 +80,7 @@ int xenbus_register_export(struct fs_exp 31.50 31.51 if(!xenbus_printf(xsh, xst, node, "name", "%s", export->name)) 31.52 { 31.53 - printf("Could not write the export node.\n"); 31.54 + FS_DEBUG("Could not write the export node.\n"); 31.55 goto error_exit; 31.56 } 31.57 31.58 @@ -87,7 +89,7 @@ int xenbus_register_export(struct fs_exp 31.59 perms.perms = XS_PERM_READ; 31.60 if(!xs_set_permissions(xsh, xst, EXPORTS_NODE, &perms, 1)) 31.61 { 31.62 - printf("Could not set permissions on the export node.\n"); 31.63 + FS_DEBUG("Could not set permissions on the export node.\n"); 31.64 goto error_exit; 31.65 } 31.66 31.67 @@ -166,7 +168,7 @@ void xenbus_write_backend_node(struct fs 31.68 31.69 assert(xsh != NULL); 31.70 self_id = get_self_id(); 31.71 - printf("Our own dom_id=%d\n", self_id); 31.72 + FS_DEBUG("Our own dom_id=%d\n", self_id); 31.73 snprintf(node, sizeof(node), "%s/backend", mount->frontend); 31.74 snprintf(backend_node, sizeof(backend_node), "/local/domain/%d/"ROOT_NODE"/%d", 31.75 self_id, mount->mount_id); 31.76 @@ -176,7 +178,7 @@ void xenbus_write_backend_node(struct fs 31.77 xs_write(xsh, XBT_NULL, node, STATE_INITIALISED, strlen(STATE_INITIALISED)); 31.78 } 31.79 31.80 -void xenbus_write_backend_ready(struct fs_mount *mount) 31.81 +void xenbus_write_backend_state(struct fs_mount *mount, const char *state) 31.82 { 31.83 char node[1024]; 31.84 int self_id; 31.85 @@ -184,6 +186,59 @@ void xenbus_write_backend_ready(struct f 31.86 assert(xsh != NULL); 31.87 self_id = get_self_id(); 31.88 snprintf(node, sizeof(node), ROOT_NODE"/%d/state", mount->mount_id); 31.89 - xs_write(xsh, XBT_NULL, node, STATE_READY, strlen(STATE_READY)); 31.90 + xs_write(xsh, XBT_NULL, node, state, strlen(state)); 31.91 +} 31.92 + 31.93 +void xenbus_watch_frontend_state(struct fs_mount *mount) 31.94 +{ 31.95 + int res; 31.96 + char statepath[1024]; 31.97 + 31.98 + assert(xsh != NULL); 31.99 + snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend); 31.100 + res = xs_watch(xsh, statepath, "frontend-state"); 31.101 + assert(res); 31.102 +} 31.103 + 31.104 +void xenbus_unwatch_frontend_state(struct fs_mount *mount) 31.105 +{ 31.106 + int res; 31.107 + char statepath[1024]; 31.108 + 31.109 + assert(xsh != NULL); 31.110 + snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend); 31.111 + res = xs_unwatch(xsh, statepath, "frontend-state"); 31.112 + assert(res); 31.113 } 31.114 31.115 +int xenbus_frontend_state_changed(struct fs_mount *mount, const char *oldstate) 31.116 +{ 31.117 + unsigned int len; 31.118 + char statepath[1024]; 31.119 + char *state = NULL; 31.120 + 31.121 + assert(xsh != NULL); 31.122 + snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend); 31.123 + state = xs_read(xsh, XBT_NULL, statepath, &len); 31.124 + if (state && len > 0) { 31.125 + if (strcmp(state, oldstate)) { 31.126 + free(state); 31.127 + return 1; 31.128 + } else { 31.129 + free(state); 31.130 + return 0; 31.131 + } 31.132 + } else 31.133 + return 1; 31.134 +} 31.135 + 31.136 +char* xenbus_read_frontend_state(struct fs_mount *mount) 31.137 +{ 31.138 + unsigned int len; 31.139 + char statepath[1024]; 31.140 + 31.141 + assert(xsh != NULL); 31.142 + snprintf(statepath, sizeof(statepath), "%s/state", mount->frontend); 31.143 + return xs_read(xsh, XBT_NULL, statepath, &len); 31.144 +} 31.145 +
32.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 32.2 +++ b/tools/fs-back/sys-queue.h Fri Mar 27 11:07:11 2009 +0900 32.3 @@ -0,0 +1,338 @@ 32.4 +/* $NetBSD: queue.h,v 1.45.14.1 2007/07/18 20:13:24 liamjfoy Exp $ */ 32.5 + 32.6 +/* 32.7 + * Qemu version: Copy from netbsd, removed debug code, removed some of 32.8 + * the implementations. Left in lists, tail queues and circular queues. 32.9 + */ 32.10 + 32.11 +/* 32.12 + * Copyright (c) 1991, 1993 32.13 + * The Regents of the University of California. All rights reserved. 32.14 + * 32.15 + * Redistribution and use in source and binary forms, with or without 32.16 + * modification, are permitted provided that the following conditions 32.17 + * are met: 32.18 + * 1. Redistributions of source code must retain the above copyright 32.19 + * notice, this list of conditions and the following disclaimer. 32.20 + * 2. Redistributions in binary form must reproduce the above copyright 32.21 + * notice, this list of conditions and the following disclaimer in the 32.22 + * documentation and/or other materials provided with the distribution. 32.23 + * 3. Neither the name of the University nor the names of its contributors 32.24 + * may be used to endorse or promote products derived from this software 32.25 + * without specific prior written permission. 32.26 + * 32.27 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 32.28 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32.29 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32.30 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 32.31 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32.32 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32.33 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32.34 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32.35 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32.36 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32.37 + * SUCH DAMAGE. 32.38 + * 32.39 + * @(#)queue.h 8.5 (Berkeley) 8/20/94 32.40 + */ 32.41 + 32.42 +#ifndef _SYS_QUEUE_H_ 32.43 +#define _SYS_QUEUE_H_ 32.44 + 32.45 +/* 32.46 + * This file defines three types of data structures: 32.47 + * lists, tail queues, and circular queues. 32.48 + * 32.49 + * A list is headed by a single forward pointer (or an array of forward 32.50 + * pointers for a hash table header). The elements are doubly linked 32.51 + * so that an arbitrary element can be removed without a need to 32.52 + * traverse the list. New elements can be added to the list before 32.53 + * or after an existing element or at the head of the list. A list 32.54 + * may only be traversed in the forward direction. 32.55 + * 32.56 + * A tail queue is headed by a pair of pointers, one to the head of the 32.57 + * list and the other to the tail of the list. The elements are doubly 32.58 + * linked so that an arbitrary element can be removed without a need to 32.59 + * traverse the list. New elements can be added to the list before or 32.60 + * after an existing element, at the head of the list, or at the end of 32.61 + * the list. A tail queue may be traversed in either direction. 32.62 + * 32.63 + * A circle queue is headed by a pair of pointers, one to the head of the 32.64 + * list and the other to the tail of the list. The elements are doubly 32.65 + * linked so that an arbitrary element can be removed without a need to 32.66 + * traverse the list. New elements can be added to the list before or after 32.67 + * an existing element, at the head of the list, or at the end of the list. 32.68 + * A circle queue may be traversed in either direction, but has a more 32.69 + * complex end of list detection. 32.70 + * 32.71 + * For details on the use of these macros, see the queue(3) manual page. 32.72 + */ 32.73 + 32.74 +/* 32.75 + * List definitions. 32.76 + */ 32.77 +#define LIST_HEAD(name, type) \ 32.78 +struct name { \ 32.79 + struct type *lh_first; /* first element */ \ 32.80 +} 32.81 + 32.82 +#define LIST_HEAD_INITIALIZER(head) \ 32.83 + { NULL } 32.84 + 32.85 +#define LIST_ENTRY(type) \ 32.86 +struct { \ 32.87 + struct type *le_next; /* next element */ \ 32.88 + struct type **le_prev; /* address of previous next element */ \ 32.89 +} 32.90 + 32.91 +/* 32.92 + * List functions. 32.93 + */ 32.94 +#define LIST_INIT(head) do { \ 32.95 + (head)->lh_first = NULL; \ 32.96 +} while (/*CONSTCOND*/0) 32.97 + 32.98 +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ 32.99 + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ 32.100 + (listelm)->field.le_next->field.le_prev = \ 32.101 + &(elm)->field.le_next; \ 32.102 + (listelm)->field.le_next = (elm); \ 32.103 + (elm)->field.le_prev = &(listelm)->field.le_next; \ 32.104 +} while (/*CONSTCOND*/0) 32.105 + 32.106 +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ 32.107 + (elm)->field.le_prev = (listelm)->field.le_prev; \ 32.108 + (elm)->field.le_next = (listelm); \ 32.109 + *(listelm)->field.le_prev = (elm); \ 32.110 + (listelm)->field.le_prev = &(elm)->field.le_next; \ 32.111 +} while (/*CONSTCOND*/0) 32.112 + 32.113 +#define LIST_INSERT_HEAD(head, elm, field) do { \ 32.114 + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ 32.115 + (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ 32.116 + (head)->lh_first = (elm); \ 32.117 + (elm)->field.le_prev = &(head)->lh_first; \ 32.118 +} while (/*CONSTCOND*/0) 32.119 + 32.120 +#define LIST_REMOVE(elm, field) do { \ 32.121 + if ((elm)->field.le_next != NULL) \ 32.122 + (elm)->field.le_next->field.le_prev = \ 32.123 + (elm)->field.le_prev; \ 32.124 + *(elm)->field.le_prev = (elm)->field.le_next; \ 32.125 +} while (/*CONSTCOND*/0) 32.126 + 32.127 +#define LIST_FOREACH(var, head, field) \ 32.128 + for ((var) = ((head)->lh_first); \ 32.129 + (var); \ 32.130 + (var) = ((var)->field.le_next)) 32.131 + 32.132 +/* 32.133 + * List access methods. 32.134 + */ 32.135 +#define LIST_EMPTY(head) ((head)->lh_first == NULL) 32.136 +#define LIST_FIRST(head) ((head)->lh_first) 32.137 +#define LIST_NEXT(elm, field) ((elm)->field.le_next) 32.138 + 32.139 + 32.140 +/* 32.141 + * Tail queue definitions. 32.142 + */ 32.143 +#define _TAILQ_HEAD(name, type, qual) \ 32.144 +struct name { \ 32.145 + qual type *tqh_first; /* first element */ \ 32.146 + qual type *qual *tqh_last; /* addr of last next element */ \ 32.147 +} 32.148 +#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,) 32.149 + 32.150 +#define TAILQ_HEAD_INITIALIZER(head) \ 32.151 + { NULL, &(head).tqh_first } 32.152 + 32.153 +#define _TAILQ_ENTRY(type, qual) \ 32.154 +struct { \ 32.155 + qual type *tqe_next; /* next element */ \ 32.156 + qual type *qual *tqe_prev; /* address of previous next element */\ 32.157 +} 32.158 +#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,) 32.159 + 32.160 +/* 32.161 + * Tail queue functions. 32.162 + */ 32.163 +#define TAILQ_INIT(head) do { \ 32.164 + (head)->tqh_first = NULL; \ 32.165 + (head)->tqh_last = &(head)->tqh_first; \ 32.166 +} while (/*CONSTCOND*/0) 32.167 + 32.168 +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ 32.169 + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ 32.170 + (head)->tqh_first->field.tqe_prev = \ 32.171 + &(elm)->field.tqe_next; \ 32.172 + else \ 32.173 + (head)->tqh_last = &(elm)->field.tqe_next; \ 32.174 + (head)->tqh_first = (elm); \ 32.175 + (elm)->field.tqe_prev = &(head)->tqh_first; \ 32.176 +} while (/*CONSTCOND*/0) 32.177 + 32.178 +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ 32.179 + (elm)->field.tqe_next = NULL; \ 32.180 + (elm)->field.tqe_prev = (head)->tqh_last; \ 32.181 + *(head)->tqh_last = (elm); \ 32.182 + (head)->tqh_last = &(elm)->field.tqe_next; \ 32.183 +} while (/*CONSTCOND*/0) 32.184 + 32.185 +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ 32.186 + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ 32.187 + (elm)->field.tqe_next->field.tqe_prev = \ 32.188 + &(elm)->field.tqe_next; \ 32.189 + else \ 32.190 + (head)->tqh_last = &(elm)->field.tqe_next; \ 32.191 + (listelm)->field.tqe_next = (elm); \ 32.192 + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ 32.193 +} while (/*CONSTCOND*/0) 32.194 + 32.195 +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ 32.196 + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ 32.197 + (elm)->field.tqe_next = (listelm); \ 32.198 + *(listelm)->field.tqe_prev = (elm); \ 32.199 + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ 32.200 +} while (/*CONSTCOND*/0) 32.201 + 32.202 +#define TAILQ_REMOVE(head, elm, field) do { \ 32.203 + if (((elm)->field.tqe_next) != NULL) \ 32.204 + (elm)->field.tqe_next->field.tqe_prev = \ 32.205 + (elm)->field.tqe_prev; \ 32.206 + else \ 32.207 + (head)->tqh_last = (elm)->field.tqe_prev; \ 32.208 + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ 32.209 +} while (/*CONSTCOND*/0) 32.210 + 32.211 +#define TAILQ_FOREACH(var, head, field) \ 32.212 + for ((var) = ((head)->tqh_first); \ 32.213 + (var); \ 32.214 + (var) = ((var)->field.tqe_next)) 32.215 + 32.216 +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ 32.217 + for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ 32.218 + (var); \ 32.219 + (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) 32.220 + 32.221 +/* 32.222 + * Tail queue access methods. 32.223 + */ 32.224 +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) 32.225 +#define TAILQ_FIRST(head) ((head)->tqh_first) 32.226 +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) 32.227 + 32.228 +#define TAILQ_LAST(head, headname) \ 32.229 + (*(((struct headname *)((head)->tqh_last))->tqh_last)) 32.230 +#define TAILQ_PREV(elm, headname, field) \ 32.231 + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) 32.232 + 32.233 + 32.234 +/* 32.235 + * Circular queue definitions. 32.236 + */ 32.237 +#define CIRCLEQ_HEAD(name, type) \ 32.238 +struct name { \ 32.239 + struct type *cqh_first; /* first element */ \ 32.240 + struct type *cqh_last; /* last element */ \ 32.241 +} 32.242 + 32.243 +#define CIRCLEQ_HEAD_INITIALIZER(head) \ 32.244 + { (void *)&head, (void *)&head } 32.245 + 32.246 +#define CIRCLEQ_ENTRY(type) \ 32.247 +struct { \ 32.248 + struct type *cqe_next; /* next element */ \ 32.249 + struct type *cqe_prev; /* previous element */ \ 32.250 +} 32.251 + 32.252 +/* 32.253 + * Circular queue functions. 32.254 + */ 32.255 +#define CIRCLEQ_INIT(head) do { \ 32.256 + (head)->cqh_first = (void *)(head); \ 32.257 + (head)->cqh_last = (void *)(head); \ 32.258 +} while (/*CONSTCOND*/0) 32.259 + 32.260 +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ 32.261 + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ 32.262 + (elm)->field.cqe_prev = (listelm); \ 32.263 + if ((listelm)->field.cqe_next == (void *)(head)) \ 32.264 + (head)->cqh_last = (elm); \ 32.265 + else \ 32.266 + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ 32.267 + (listelm)->field.cqe_next = (elm); \ 32.268 +} while (/*CONSTCOND*/0) 32.269 + 32.270 +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ 32.271 + (elm)->field.cqe_next = (listelm); \ 32.272 + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ 32.273 + if ((listelm)->field.cqe_prev == (void *)(head)) \ 32.274 + (head)->cqh_first = (elm); \ 32.275 + else \ 32.276 + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ 32.277 + (listelm)->field.cqe_prev = (elm); \ 32.278 +} while (/*CONSTCOND*/0) 32.279 + 32.280 +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ 32.281 + (elm)->field.cqe_next = (head)->cqh_first; \ 32.282 + (elm)->field.cqe_prev = (void *)(head); \ 32.283 + if ((head)->cqh_last == (void *)(head)) \ 32.284 + (head)->cqh_last = (elm); \ 32.285 + else \ 32.286 + (head)->cqh_first->field.cqe_prev = (elm); \ 32.287 + (head)->cqh_first = (elm); \ 32.288 +} while (/*CONSTCOND*/0) 32.289 + 32.290 +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ 32.291 + (elm)->field.cqe_next = (void *)(head); \ 32.292 + (elm)->field.cqe_prev = (head)->cqh_last; \ 32.293 + if ((head)->cqh_first == (void *)(head)) \ 32.294 + (head)->cqh_first = (elm); \ 32.295 + else \ 32.296 + (head)->cqh_last->field.cqe_next = (elm); \ 32.297 + (head)->cqh_last = (elm); \ 32.298 +} while (/*CONSTCOND*/0) 32.299 + 32.300 +#define CIRCLEQ_REMOVE(head, elm, field) do { \ 32.301 + if ((elm)->field.cqe_next == (void *)(head)) \ 32.302 + (head)->cqh_last = (elm)->field.cqe_prev; \ 32.303 + else \ 32.304 + (elm)->field.cqe_next->field.cqe_prev = \ 32.305 + (elm)->field.cqe_prev; \ 32.306 + if ((elm)->field.cqe_prev == (void *)(head)) \ 32.307 + (head)->cqh_first = (elm)->field.cqe_next; \ 32.308 + else \ 32.309 + (elm)->field.cqe_prev->field.cqe_next = \ 32.310 + (elm)->field.cqe_next; \ 32.311 +} while (/*CONSTCOND*/0) 32.312 + 32.313 +#define CIRCLEQ_FOREACH(var, head, field) \ 32.314 + for ((var) = ((head)->cqh_first); \ 32.315 + (var) != (const void *)(head); \ 32.316 + (var) = ((var)->field.cqe_next)) 32.317 + 32.318 +#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \ 32.319 + for ((var) = ((head)->cqh_last); \ 32.320 + (var) != (const void *)(head); \ 32.321 + (var) = ((var)->field.cqe_prev)) 32.322 + 32.323 +/* 32.324 + * Circular queue access methods. 32.325 + */ 32.326 +#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) 32.327 +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) 32.328 +#define CIRCLEQ_LAST(head) ((head)->cqh_last) 32.329 +#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next) 32.330 +#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev) 32.331 + 32.332 +#define CIRCLEQ_LOOP_NEXT(head, elm, field) \ 32.333 + (((elm)->field.cqe_next == (void *)(head)) \ 32.334 + ? ((head)->cqh_first) \ 32.335 + : (elm->field.cqe_next)) 32.336 +#define CIRCLEQ_LOOP_PREV(head, elm, field) \ 32.337 + (((elm)->field.cqe_prev == (void *)(head)) \ 32.338 + ? ((head)->cqh_last) \ 32.339 + : (elm->field.cqe_prev)) 32.340 + 32.341 +#endif /* !_SYS_QUEUE_H_ */
33.1 --- a/tools/hotplug/Linux/Makefile Fri Mar 27 10:54:08 2009 +0900 33.2 +++ b/tools/hotplug/Linux/Makefile Fri Mar 27 11:07:11 2009 +0900 33.3 @@ -16,7 +16,6 @@ XEN_SCRIPTS += network-route vif-route 33.4 XEN_SCRIPTS += network-nat vif-nat 33.5 XEN_SCRIPTS += block 33.6 XEN_SCRIPTS += block-enbd block-nbd 33.7 -XEN_SCRIPTS += blktap 33.8 XEN_SCRIPTS += vtpm vtpm-delete 33.9 XEN_SCRIPTS += xen-hotplug-cleanup 33.10 XEN_SCRIPTS += external-device-migrate 33.11 @@ -30,7 +29,7 @@ XEN_HOTPLUG_DIR = /etc/hotplug 33.12 XEN_HOTPLUG_SCRIPTS = xen-backend.agent 33.13 33.14 UDEV_RULES_DIR = /etc/udev 33.15 -UDEV_RULES = xen-backend.rules 33.16 +UDEV_RULES = xen-backend.rules xend.rules 33.17 33.18 DI = $(if $(DISTDIR),$(shell readlink -f $(DISTDIR)),) 33.19 DE = $(if $(DESTDIR),$(shell readlink -f $(DESTDIR)),)
34.1 --- a/tools/hotplug/Linux/blktap Fri Mar 27 10:54:08 2009 +0900 34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 34.3 @@ -1,93 +0,0 @@ 34.4 -#!/bin/bash 34.5 - 34.6 -# Copyright (c) 2005, XenSource Ltd. 34.7 - 34.8 -dir=$(dirname "$0") 34.9 -. "$dir/xen-hotplug-common.sh" 34.10 -. "$dir/block-common.sh" 34.11 - 34.12 -findCommand "$@" 34.13 - 34.14 -## 34.15 -# check_blktap_sharing file mode 34.16 -# 34.17 -# Perform the sharing check for the given blktap and mode. 34.18 -# 34.19 -check_blktap_sharing() 34.20 -{ 34.21 - local file="$1" 34.22 - local mode="$2" 34.23 - 34.24 - local base_path="$XENBUS_BASE_PATH/$XENBUS_TYPE" 34.25 - for dom in $(xenstore-list "$base_path") 34.26 - do 34.27 - for dev in $(xenstore-list "$base_path/$dom") 34.28 - do 34.29 - params=$(xenstore_read "$base_path/$dom/$dev/params" | cut -d: -f2) 34.30 - if [ "$file" = "$params" ] 34.31 - then 34.32 - 34.33 - if [ "$mode" = 'w' ] 34.34 - then 34.35 - if ! same_vm "$dom" 34.36 - then 34.37 - echo 'guest' 34.38 - return 34.39 - fi 34.40 - else 34.41 - local m=$(xenstore_read "$base_path/$dom/$dev/mode") 34.42 - m=$(canonicalise_mode "$m") 34.43 - 34.44 - if [ "$m" = 'w' ] 34.45 - then 34.46 - if ! same_vm "$dom" 34.47 - then 34.48 - echo 'guest' 34.49 - return 34.50 - fi 34.51 - fi 34.52 - fi 34.53 - fi 34.54 - done 34.55 - done 34.56 - 34.57 - echo 'ok' 34.58 -} 34.59 - 34.60 - 34.61 -t=$(xenstore_read_default "$XENBUS_PATH/type" 'MISSING') 34.62 -if [ -n "$t" ] 34.63 -then 34.64 - p=$(xenstore_read "$XENBUS_PATH/params") 34.65 - # if we have a ':', chew from head including : 34.66 - if echo $p | grep -q \: 34.67 - then 34.68 - p=${p#*:} 34.69 - fi 34.70 -fi 34.71 -# some versions of readlink cannot be passed a regular file 34.72 -if [ -L "$p" ]; then 34.73 - file=$(readlink -f "$p") || fatal "$p link does not exist." 34.74 -else 34.75 - file="$p" 34.76 -fi 34.77 - 34.78 -if [ "$command" = 'add' ] 34.79 -then 34.80 - [ -e "$file" ] || { fatal $file does not exist; } 34.81 - 34.82 - FRONTEND_ID=$(xenstore_read "$XENBUS_PATH/frontend-id") 34.83 - FRONTEND_UUID=$(xenstore_read "/local/domain/$FRONTEND_ID/vm") 34.84 - mode=$(xenstore_read "$XENBUS_PATH/mode") 34.85 - mode=$(canonicalise_mode "$mode") 34.86 - 34.87 - if [ "$mode" != '!' ] 34.88 - then 34.89 - result=$(check_blktap_sharing "$file" "$mode") 34.90 - [ "$result" = 'ok' ] || ebusy "$file already in use by other domain" 34.91 - fi 34.92 - 34.93 - success 34.94 -fi 34.95 - 34.96 -exit 0
35.1 --- a/tools/hotplug/Linux/xen-backend.rules Fri Mar 27 10:54:08 2009 +0900 35.2 +++ b/tools/hotplug/Linux/xen-backend.rules Fri Mar 27 11:07:11 2009 +0900 35.3 @@ -1,4 +1,3 @@ 35.4 -SUBSYSTEM=="xen-backend", KERNEL=="tap*", RUN+="/etc/xen/scripts/blktap $env{ACTION}" 35.5 SUBSYSTEM=="xen-backend", KERNEL=="vbd*", RUN+="/etc/xen/scripts/block $env{ACTION}" 35.6 SUBSYSTEM=="xen-backend", KERNEL=="vtpm*", RUN+="/etc/xen/scripts/vtpm $env{ACTION}" 35.7 SUBSYSTEM=="xen-backend", KERNEL=="vif*", ACTION=="online", RUN+="$env{script} online"
36.1 --- a/tools/hotplug/Linux/xen-hotplug-cleanup Fri Mar 27 10:54:08 2009 +0900 36.2 +++ b/tools/hotplug/Linux/xen-hotplug-cleanup Fri Mar 27 11:07:11 2009 +0900 36.3 @@ -14,9 +14,13 @@ claim_lock "block" 36.4 # split backend/DEVCLASS/VMID/DEVID on slashes 36.5 path_array=( ${XENBUS_PATH//\// } ) 36.6 # get /vm/UUID path 36.7 -vm=$(xenstore-read "/local/domain/${path_array[2]}/vm") 36.8 +vm=$(xenstore_read_default "/local/domain/${path_array[2]}/vm" "") 36.9 # construct /vm/UUID/device/DEVCLASS/DEVID 36.10 -vm_dev="$vm/device/${path_array[1]}/${path_array[3]}" 36.11 +if [ "$vm" != "" ]; then 36.12 + vm_dev="$vm/device/${path_array[1]}/${path_array[3]}" 36.13 +else 36.14 + vm_dev= 36.15 +fi 36.16 36.17 # remove device frontend store entries 36.18 xenstore-rm -t \ 36.19 @@ -27,6 +31,6 @@ xenstore-rm -t "$XENBUS_PATH" 2>/ 36.20 xenstore-rm -t "error/$XENBUS_PATH" 2>/dev/null || true 36.21 36.22 # remove device path from /vm/UUID 36.23 -xenstore-rm -t "$vm_dev" 2>/dev/null || true 36.24 +[ "$vm_dev" != "" ] && xenstore-rm -t "$vm_dev" 2>/dev/null || true 36.25 36.26 release_lock "block"
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/tools/hotplug/Linux/xend.rules Fri Mar 27 11:07:11 2009 +0900 37.3 @@ -0,0 +1,3 @@ 37.4 +SUBSYSTEM=="pci", RUN+="socket:/org/xen/xend/udev_event" 37.5 +#SUBSYSTEM=="scsi", RUN+="socket:/org/xen/xend/udev_event" 37.6 +#SUBSYSTEM=="net", KERNEL!="vif[0-9]*.[0-9]*|tap[0-9]*.[0-9]*", RUN+="socket:/org/xen/xend/udev_event"
38.1 --- a/tools/hotplug/NetBSD/Makefile Fri Mar 27 10:54:08 2009 +0900 38.2 +++ b/tools/hotplug/NetBSD/Makefile Fri Mar 27 11:07:11 2009 +0900 38.3 @@ -2,14 +2,12 @@ XEN_ROOT = ../../../ 38.4 include $(XEN_ROOT)/tools/Rules.mk 38.5 38.6 # Xen configuration dir and configs to go there. 38.7 -XEN_CONFIG_DIR = $(PREFIX)/etc/xen 38.8 +XEN_CONFIG_DIR = /etc/xen 38.9 38.10 # Xen script dir and scripts to go there. 38.11 -XEN_SCRIPT_DIR = $(PREFIX)/etc/xen/scripts 38.12 +XEN_SCRIPT_DIR = $(XEN_CONFIG_DIR)/scripts 38.13 XEN_SCRIPTS = 38.14 XEN_SCRIPTS += block-nbsd 38.15 -XEN_SCRIPTS += hvm-nbsd 38.16 -XEN_SCRIPTS += netbsd1-nbsd 38.17 XEN_SCRIPTS += qemu-ifup-nbsd 38.18 XEN_SCRIPTS += vif-bridge-nbsd 38.19 XEN_SCRIPTS += vif-ip-nbsd 38.20 @@ -27,7 +25,7 @@ install: all install-scripts 38.21 38.22 .PHONY: install-scripts 38.23 install-scripts: 38.24 - $(INSTALL_DATA_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR) 38.25 + $(INSTALL_DIR) $(DESTDIR)$(XEN_SCRIPT_DIR) 38.26 set -e; for i in $(XEN_SCRIPTS); \ 38.27 do \ 38.28 $(INSTALL_DATA) $$i $(DESTDIR)$(XEN_SCRIPT_DIR); \
39.1 --- a/tools/libfsimage/zfs/fsys_zfs.c Fri Mar 27 10:54:08 2009 +0900 39.2 +++ b/tools/libfsimage/zfs/fsys_zfs.c Fri Mar 27 11:07:11 2009 +0900 39.3 @@ -298,8 +298,7 @@ uberblock_verify(uberblock_phys_t *ub, i 39.4 return (-1); 39.5 39.6 if (uber->ub_magic == UBERBLOCK_MAGIC && 39.7 - uber->ub_version >= SPA_VERSION_1 && 39.8 - uber->ub_version <= SPA_VERSION) 39.9 + uber->ub_version > 0 && uber->ub_version <= SPA_VERSION) 39.10 return (0); 39.11 39.12 return (-1);
40.1 --- a/tools/libfsimage/zfs/zfs-include/zfs.h Fri Mar 27 10:54:08 2009 +0900 40.2 +++ b/tools/libfsimage/zfs/zfs-include/zfs.h Fri Mar 27 11:07:11 2009 +0900 40.3 @@ -28,17 +28,7 @@ 40.4 /* 40.5 * On-disk version number. 40.6 */ 40.7 -#define SPA_VERSION_1 1ULL 40.8 -#define SPA_VERSION_2 2ULL 40.9 -#define SPA_VERSION_3 3ULL 40.10 -#define SPA_VERSION_4 4ULL 40.11 -#define SPA_VERSION_5 5ULL 40.12 -#define SPA_VERSION_6 6ULL 40.13 -#define SPA_VERSION_7 7ULL 40.14 -#define SPA_VERSION_8 8ULL 40.15 -#define SPA_VERSION_9 9ULL 40.16 -#define SPA_VERSION_10 10ULL 40.17 -#define SPA_VERSION SPA_VERSION_10 40.18 +#define SPA_VERSION 14ULL 40.19 40.20 /* 40.21 * The following are configuration names used in the nvlist describing a pool's
41.1 --- a/tools/libxc/Makefile Fri Mar 27 10:54:08 2009 +0900 41.2 +++ b/tools/libxc/Makefile Fri Mar 27 11:07:11 2009 +0900 41.3 @@ -29,7 +29,7 @@ CTRL_SRCS-$(CONFIG_NetBSD) += xc_netbsd. 41.4 CTRL_SRCS-$(CONFIG_MiniOS) += xc_minios.c 41.5 41.6 GUEST_SRCS-y := 41.7 -GUEST_SRCS-y += xg_private.c 41.8 +GUEST_SRCS-y += xg_private.c xc_suspend.c 41.9 GUEST_SRCS-$(CONFIG_MIGRATE) += xc_domain_restore.c xc_domain_save.c 41.10 GUEST_SRCS-$(CONFIG_HVM) += xc_hvm_build.c 41.11
42.1 --- a/tools/libxc/xc_core.c Fri Mar 27 10:54:08 2009 +0900 42.2 +++ b/tools/libxc/xc_core.c Fri Mar 27 11:07:11 2009 +0900 42.3 @@ -518,7 +518,17 @@ xc_domain_dumpcore_via_callback(int xc_h 42.4 if ( sts != 0 ) 42.5 goto out; 42.6 42.7 + /* 42.8 + * Note: this is the *current* number of pages and may change under 42.9 + * a live dump-core. We'll just take this value, and if more pages 42.10 + * exist, we'll skip them. If there's less, then we'll just not use 42.11 + * all the array... 42.12 + * 42.13 + * We don't want to use the total potential size of the memory map 42.14 + * since that is usually much higher than info.nr_pages. 42.15 + */ 42.16 nr_pages = info.nr_pages; 42.17 + 42.18 if ( !auto_translated_physmap ) 42.19 { 42.20 /* obtain p2m table */
43.1 --- a/tools/libxc/xc_dom_x86.c Fri Mar 27 10:54:08 2009 +0900 43.2 +++ b/tools/libxc/xc_dom_x86.c Fri Mar 27 11:07:11 2009 +0900 43.3 @@ -694,7 +694,7 @@ static int x86_shadow(int xc, domid_t do 43.4 int arch_setup_meminit(struct xc_dom_image *dom) 43.5 { 43.6 int rc; 43.7 - xen_pfn_t pfn; 43.8 + xen_pfn_t pfn, allocsz, i; 43.9 43.10 rc = x86_compat(dom->guest_xc, dom->guest_domid, dom->guest_type); 43.11 if ( rc ) 43.12 @@ -713,9 +713,15 @@ int arch_setup_meminit(struct xc_dom_ima 43.13 dom->p2m_host[pfn] = pfn; 43.14 43.15 /* allocate guest memory */ 43.16 - rc = xc_domain_memory_populate_physmap(dom->guest_xc, dom->guest_domid, 43.17 - dom->total_pages, 0, 0, 43.18 - dom->p2m_host); 43.19 + for ( i = rc = allocsz = 0; (i < dom->total_pages) && !rc; i += allocsz ) 43.20 + { 43.21 + allocsz = dom->total_pages - i; 43.22 + if ( allocsz > 1024*1024 ) 43.23 + allocsz = 1024*1024; 43.24 + rc = xc_domain_memory_populate_physmap( 43.25 + dom->guest_xc, dom->guest_domid, allocsz, 0, 0, &dom->p2m_host[i]); 43.26 + } 43.27 + 43.28 return rc; 43.29 } 43.30
44.1 --- a/tools/libxc/xc_domain_save.c Fri Mar 27 10:54:08 2009 +0900 44.2 +++ b/tools/libxc/xc_domain_save.c Fri Mar 27 11:07:11 2009 +0900 44.3 @@ -744,8 +744,6 @@ static xen_pfn_t *map_and_save_p2m_table 44.4 return success ? p2m : NULL; 44.5 } 44.6 44.7 - 44.8 - 44.9 int xc_domain_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters, 44.10 uint32_t max_factor, uint32_t flags, int (*suspend)(void), 44.11 int hvm, void *(*init_qemu_maps)(int, unsigned),
45.1 --- a/tools/libxc/xc_pm.c Fri Mar 27 10:54:08 2009 +0900 45.2 +++ b/tools/libxc/xc_pm.c Fri Mar 27 11:07:11 2009 +0900 45.3 @@ -306,3 +306,59 @@ int xc_set_cpufreq_para(int xc_handle, i 45.4 45.5 return xc_sysctl(xc_handle, &sysctl); 45.6 } 45.7 + 45.8 +int xc_get_cpufreq_avgfreq(int xc_handle, int cpuid, int *avg_freq) 45.9 +{ 45.10 + int ret = 0; 45.11 + DECLARE_SYSCTL; 45.12 + 45.13 + if ( (xc_handle < 0) || (!avg_freq) ) 45.14 + return -EINVAL; 45.15 + 45.16 + sysctl.cmd = XEN_SYSCTL_pm_op; 45.17 + sysctl.u.pm_op.cmd = GET_CPUFREQ_AVGFREQ; 45.18 + sysctl.u.pm_op.cpuid = cpuid; 45.19 + ret = xc_sysctl(xc_handle, &sysctl); 45.20 + 45.21 + *avg_freq = sysctl.u.pm_op.get_avgfreq; 45.22 + 45.23 + return ret; 45.24 +} 45.25 + 45.26 +int xc_get_cputopo(int xc_handle, struct xc_get_cputopo *info) 45.27 +{ 45.28 + int rc; 45.29 + DECLARE_SYSCTL; 45.30 + 45.31 + sysctl.cmd = XEN_SYSCTL_pm_op; 45.32 + sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_get_cputopo; 45.33 + sysctl.u.pm_op.cpuid = 0; 45.34 + set_xen_guest_handle( sysctl.u.pm_op.get_topo.cpu_to_core, 45.35 + info->cpu_to_core ); 45.36 + set_xen_guest_handle( sysctl.u.pm_op.get_topo.cpu_to_socket, 45.37 + info->cpu_to_socket ); 45.38 + sysctl.u.pm_op.get_topo.max_cpus = info->max_cpus; 45.39 + 45.40 + rc = do_sysctl(xc_handle, &sysctl); 45.41 + info->nr_cpus = sysctl.u.pm_op.get_topo.nr_cpus; 45.42 + 45.43 + return rc; 45.44 +} 45.45 + 45.46 +/* value: 0 - disable sched_smt_power_savings 45.47 + 1 - enable sched_smt_power_savings 45.48 + */ 45.49 +int xc_set_sched_opt_smt(int xc_handle, uint32_t value) 45.50 +{ 45.51 + int rc; 45.52 + DECLARE_SYSCTL; 45.53 + 45.54 + sysctl.cmd = XEN_SYSCTL_pm_op; 45.55 + sysctl.u.pm_op.cmd = XEN_SYSCTL_pm_op_set_sched_opt_smt; 45.56 + sysctl.u.pm_op.cpuid = 0; 45.57 + sysctl.u.pm_op.set_sched_opt_smt = value; 45.58 + rc = do_sysctl(xc_handle, &sysctl); 45.59 + 45.60 + return rc; 45.61 +} 45.62 +
46.1 --- a/tools/libxc/xc_ptrace_core.c Fri Mar 27 10:54:08 2009 +0900 46.2 +++ b/tools/libxc/xc_ptrace_core.c Fri Mar 27 11:07:11 2009 +0900 46.3 @@ -154,7 +154,7 @@ xc_waitdomain_core_compat( 46.4 IPRINTF("Could not allocate m2p array\n"); 46.5 return -1; 46.6 } 46.7 - bzero(m2p_array_compat, sizeof(unsigned long)* 1 << 20); 46.8 + memset(m2p_array_compat, 0, sizeof(unsigned long)* 1 << 20); 46.9 46.10 for (i = 0; i < nr_pages_compat; i++) 46.11 m2p_array_compat[p2m_array_compat[i]] = i;
47.1 --- a/tools/libxc/xc_solaris.c Fri Mar 27 10:54:08 2009 +0900 47.2 +++ b/tools/libxc/xc_solaris.c Fri Mar 27 11:07:11 2009 +0900 47.3 @@ -134,6 +134,8 @@ void *xc_map_foreign_ranges(int xc_handl 47.4 if (rc) 47.5 goto ioctl_failed; 47.6 47.7 + return addr; 47.8 + 47.9 ioctl_failed: 47.10 rc = munmap(addr, size); 47.11 if (rc == -1)
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/tools/libxc/xc_suspend.c Fri Mar 27 11:07:11 2009 +0900 48.3 @@ -0,0 +1,117 @@ 48.4 +/* 48.5 + * This file is subject to the terms and conditions of the GNU General 48.6 + * Public License. See the file "COPYING" in the main directory of 48.7 + * this archive for more details. 48.8 + */ 48.9 + 48.10 +#include "xc_private.h" 48.11 +#include "xenguest.h" 48.12 + 48.13 +#define SUSPEND_LOCK_FILE "/var/lib/xen/suspend_evtchn_lock.d" 48.14 +static int lock_suspend_event(void) 48.15 +{ 48.16 + int fd, rc; 48.17 + mode_t mask; 48.18 + char buf[128]; 48.19 + 48.20 + mask = umask(022); 48.21 + fd = open(SUSPEND_LOCK_FILE, O_CREAT | O_EXCL | O_RDWR, 0666); 48.22 + if (fd < 0) 48.23 + { 48.24 + ERROR("Can't create lock file for suspend event channel\n"); 48.25 + return -EINVAL; 48.26 + } 48.27 + umask(mask); 48.28 + snprintf(buf, sizeof(buf), "%10ld", (long)getpid()); 48.29 + 48.30 + rc = write_exact(fd, buf, strlen(buf)); 48.31 + close(fd); 48.32 + 48.33 + return rc; 48.34 +} 48.35 + 48.36 +static int unlock_suspend_event(void) 48.37 +{ 48.38 + int fd, pid, n; 48.39 + char buf[128]; 48.40 + 48.41 + fd = open(SUSPEND_LOCK_FILE, O_RDWR); 48.42 + 48.43 + if (fd < 0) 48.44 + return -EINVAL; 48.45 + 48.46 + n = read(fd, buf, 127); 48.47 + 48.48 + close(fd); 48.49 + 48.50 + if (n > 0) 48.51 + { 48.52 + sscanf(buf, "%d", &pid); 48.53 + /* We are the owner, so we can simply delete the file */ 48.54 + if (pid == getpid()) 48.55 + { 48.56 + unlink(SUSPEND_LOCK_FILE); 48.57 + return 0; 48.58 + } 48.59 + } 48.60 + 48.61 + return -EPERM; 48.62 +} 48.63 + 48.64 +int xc_await_suspend(int xce, int suspend_evtchn) 48.65 +{ 48.66 + int rc; 48.67 + 48.68 + do { 48.69 + rc = xc_evtchn_pending(xce); 48.70 + if (rc < 0) { 48.71 + ERROR("error polling suspend notification channel: %d", rc); 48.72 + return -1; 48.73 + } 48.74 + } while (rc != suspend_evtchn); 48.75 + 48.76 + /* harmless for one-off suspend */ 48.77 + if (xc_evtchn_unmask(xce, suspend_evtchn) < 0) 48.78 + ERROR("failed to unmask suspend notification channel: %d", rc); 48.79 + 48.80 + return 0; 48.81 +} 48.82 + 48.83 +int xc_suspend_evtchn_release(int xce, int suspend_evtchn) 48.84 +{ 48.85 + if (suspend_evtchn >= 0) 48.86 + xc_evtchn_unbind(xce, suspend_evtchn); 48.87 + 48.88 + return unlock_suspend_event(); 48.89 +} 48.90 + 48.91 +int xc_suspend_evtchn_init(int xc, int xce, int domid, int port) 48.92 +{ 48.93 + int rc, suspend_evtchn = -1; 48.94 + 48.95 + if (lock_suspend_event()) 48.96 + return -EINVAL; 48.97 + 48.98 + suspend_evtchn = xc_evtchn_bind_interdomain(xce, domid, port); 48.99 + if (suspend_evtchn < 0) { 48.100 + ERROR("failed to bind suspend event channel: %d", suspend_evtchn); 48.101 + goto cleanup; 48.102 + } 48.103 + 48.104 + rc = xc_domain_subscribe_for_suspend(xc, domid, port); 48.105 + if (rc < 0) { 48.106 + ERROR("failed to subscribe to domain: %d", rc); 48.107 + goto cleanup; 48.108 + } 48.109 + 48.110 + /* event channel is pending immediately after binding */ 48.111 + xc_await_suspend(xce, suspend_evtchn); 48.112 + 48.113 + return suspend_evtchn; 48.114 + 48.115 +cleanup: 48.116 + if (suspend_evtchn > 0) 48.117 + xc_suspend_evtchn_release(xce, suspend_evtchn); 48.118 + 48.119 + return -1; 48.120 +}
49.1 --- a/tools/libxc/xenctrl.h Fri Mar 27 10:54:08 2009 +0900 49.2 +++ b/tools/libxc/xenctrl.h Fri Mar 27 11:07:11 2009 +0900 49.3 @@ -158,7 +158,7 @@ typedef struct xc_dominfo { 49.4 paused:1, blocked:1, running:1, 49.5 hvm:1, debugged:1; 49.6 unsigned int shutdown_reason; /* only meaningful if shutdown==1 */ 49.7 - unsigned long nr_pages; 49.8 + unsigned long nr_pages; /* current number, not maximum */ 49.9 unsigned long shared_info_frame; 49.10 uint64_t cpu_time; 49.11 unsigned long max_memkb; 49.12 @@ -1242,4 +1242,24 @@ int xc_get_cpufreq_para(int xc_handle, i 49.13 int xc_set_cpufreq_gov(int xc_handle, int cpuid, char *govname); 49.14 int xc_set_cpufreq_para(int xc_handle, int cpuid, 49.15 int ctrl_type, int ctrl_value); 49.16 +int xc_get_cpufreq_avgfreq(int xc_handle, int cpuid, int *avg_freq); 49.17 + 49.18 +struct xc_get_cputopo { 49.19 + /* IN: maximum addressable entry in 49.20 + * the caller-provided cpu_to_core/socket. 49.21 + */ 49.22 + uint32_t max_cpus; 49.23 + uint32_t *cpu_to_core; 49.24 + uint32_t *cpu_to_socket; 49.25 + 49.26 + /* OUT: number of cpus returned 49.27 + * If OUT is greater than IN then the cpu_to_core/socket is truncated! 49.28 + */ 49.29 + uint32_t nr_cpus; 49.30 +}; 49.31 + 49.32 +int xc_get_cputopo(int xc_handle, struct xc_get_cputopo *info); 49.33 + 49.34 +int xc_set_sched_opt_smt(int xc_handle, uint32_t value); 49.35 + 49.36 #endif /* XENCTRL_H */
50.1 --- a/tools/libxc/xenguest.h Fri Mar 27 10:54:08 2009 +0900 50.2 +++ b/tools/libxc/xenguest.h Fri Mar 27 11:07:11 2009 +0900 50.3 @@ -142,4 +142,10 @@ int xc_hvm_build_mem(int xc_handle, 50.4 const char *image_buffer, 50.5 unsigned long image_size); 50.6 50.7 +int xc_suspend_evtchn_release(int xce, int suspend_evtchn); 50.8 + 50.9 +int xc_suspend_evtchn_init(int xc, int xce, int domid, int port); 50.10 + 50.11 +int xc_await_suspend(int xce, int suspend_evtchn); 50.12 + 50.13 #endif /* XENGUEST_H */
51.1 --- a/tools/libxc/xg_private.c Fri Mar 27 10:54:08 2009 +0900 51.2 +++ b/tools/libxc/xg_private.c Fri Mar 27 11:07:11 2009 +0900 51.3 @@ -108,7 +108,7 @@ char *xc_inflate_buffer(const char *in_b 51.4 (256 * ((unsigned char)in_buf[in_size-2] + 51.5 (256 * (unsigned char)in_buf[in_size-1]))))); 51.6 51.7 - bzero(&zStream, sizeof(zStream)); 51.8 + memset(&zStream, 0, sizeof(zStream)); 51.9 out_buf = malloc(out_len + 16); /* Leave a little extra space */ 51.10 if ( out_buf == NULL ) 51.11 {
52.1 --- a/tools/misc/xenpm.c Fri Mar 27 10:54:08 2009 +0900 52.2 +++ b/tools/misc/xenpm.c Fri Mar 27 11:07:11 2009 +0900 52.3 @@ -16,9 +16,6 @@ 52.4 * Place - Suite 330, Boston, MA 02111-1307 USA. 52.5 */ 52.6 52.7 -/* to eliminate warning on `strndup' */ 52.8 -#define _GNU_SOURCE 52.9 - 52.10 #include <stdio.h> 52.11 #include <stdlib.h> 52.12 #include <unistd.h> 52.13 @@ -58,8 +55,10 @@ void show_help(void) 52.14 " it is used in ondemand governor.\n" 52.15 " set-up-threshold [cpuid] <num> set up threshold on CPU <cpuid> or all\n" 52.16 " it is used in ondemand governor.\n" 52.17 - " start start collect Cx/Px statistics,\n" 52.18 - " output after CTRL-C or SIGINT.\n" 52.19 + " get-cpu-topology get thread/core/socket topology info\n" 52.20 + " set-sched-smt enable|disable enable/disable scheduler smt power saving\n" 52.21 + " start [seconds] start collect Cx/Px statistics,\n" 52.22 + " output after CTRL-C or SIGINT or several seconds.\n" 52.23 ); 52.24 } 52.25 /* wrapper function */ 52.26 @@ -224,6 +223,20 @@ static int get_pxstat_by_cpuid(int xc_fd 52.27 return 0; 52.28 } 52.29 52.30 +/* show cpu actual average freq information on CPU cpuid */ 52.31 +static int get_avgfreq_by_cpuid(int xc_fd, int cpuid, int *avgfreq) 52.32 +{ 52.33 + int ret = 0; 52.34 + 52.35 + ret = xc_get_cpufreq_avgfreq(xc_fd, cpuid, avgfreq); 52.36 + if ( ret ) 52.37 + { 52.38 + return errno; 52.39 + } 52.40 + 52.41 + return 0; 52.42 +} 52.43 + 52.44 static int show_pxstat_by_cpuid(int xc_fd, int cpuid) 52.45 { 52.46 int ret = 0; 52.47 @@ -265,6 +278,7 @@ void pxstat_func(int argc, char *argv[]) 52.48 static uint64_t usec_start, usec_end; 52.49 static struct xc_cx_stat *cxstat, *cxstat_start, *cxstat_end; 52.50 static struct xc_px_stat *pxstat, *pxstat_start, *pxstat_end; 52.51 +static int *avgfreq; 52.52 static uint64_t *sum, *sum_cx, *sum_px; 52.53 52.54 static void signal_int_handler(int signo) 52.55 @@ -300,6 +314,9 @@ static void signal_int_handler(int signo 52.56 pxstat_start[i].pt[j].residency; 52.57 } 52.58 52.59 + for ( i = 0; i < max_cpu_nr; i++ ) 52.60 + get_avgfreq_by_cpuid(xc_fd, i, &avgfreq[i]); 52.61 + 52.62 printf("Elapsed time (ms): %"PRIu64"\n", (usec_end - usec_start) / 1000UL); 52.63 for ( i = 0; i < max_cpu_nr; i++ ) 52.64 { 52.65 @@ -331,6 +348,7 @@ static void signal_int_handler(int signo 52.66 res / 1000000UL, 100UL * res / (double)sum_px[i]); 52.67 } 52.68 } 52.69 + printf(" Avg freq\t%d\tKHz\n", avgfreq[i]); 52.70 } 52.71 52.72 /* some clean up and then exits */ 52.73 @@ -344,6 +362,7 @@ static void signal_int_handler(int signo 52.74 free(cxstat); 52.75 free(pxstat); 52.76 free(sum); 52.77 + free(avgfreq); 52.78 xc_interface_close(xc_fd); 52.79 exit(0); 52.80 } 52.81 @@ -352,6 +371,16 @@ void start_gather_func(int argc, char *a 52.82 { 52.83 int i; 52.84 struct timeval tv; 52.85 + int timeout = 0; 52.86 + 52.87 + if ( argc == 1 ) 52.88 + { 52.89 + sscanf(argv[0], "%d", &timeout); 52.90 + if ( timeout <= 0 ) 52.91 + fprintf(stderr, "failed to set timeout seconds, falling back...\n"); 52.92 + else 52.93 + printf("Timeout set to %d seconds\n", timeout); 52.94 + } 52.95 52.96 if ( gettimeofday(&tv, NULL) == -1 ) 52.97 { 52.98 @@ -376,9 +405,18 @@ void start_gather_func(int argc, char *a 52.99 free(cxstat); 52.100 return ; 52.101 } 52.102 + avgfreq = malloc(sizeof(int) * max_cpu_nr); 52.103 + if ( avgfreq == NULL ) 52.104 + { 52.105 + free(sum); 52.106 + free(cxstat); 52.107 + free(pxstat); 52.108 + return ; 52.109 + } 52.110 memset(sum, 0, sizeof(uint64_t) * 2 * max_cpu_nr); 52.111 memset(cxstat, 0, sizeof(struct xc_cx_stat) * 2 * max_cpu_nr); 52.112 memset(pxstat, 0, sizeof(struct xc_px_stat) * 2 * max_cpu_nr); 52.113 + memset(avgfreq, 0, sizeof(int) * max_cpu_nr); 52.114 sum_cx = sum; 52.115 sum_px = sum + max_cpu_nr; 52.116 cxstat_start = cxstat; 52.117 @@ -397,6 +435,7 @@ void start_gather_func(int argc, char *a 52.118 { 52.119 get_cxstat_by_cpuid(xc_fd, i, &cxstat_start[i]); 52.120 get_pxstat_by_cpuid(xc_fd, i, &pxstat_start[i]); 52.121 + get_avgfreq_by_cpuid(xc_fd, i, &avgfreq[i]); 52.122 } 52.123 52.124 if (signal(SIGINT, signal_int_handler) == SIG_ERR) 52.125 @@ -405,9 +444,25 @@ void start_gather_func(int argc, char *a 52.126 free(sum); 52.127 free(pxstat); 52.128 free(cxstat); 52.129 + free(avgfreq); 52.130 return ; 52.131 } 52.132 - printf("Start sampling, waiting for CTRL-C or SIGINT signal ...\n"); 52.133 + 52.134 + if ( timeout > 0 ) 52.135 + { 52.136 + if ( signal(SIGALRM, signal_int_handler) == SIG_ERR ) 52.137 + { 52.138 + fprintf(stderr, "failed to set signal alarm handler\n"); 52.139 + free(sum); 52.140 + free(pxstat); 52.141 + free(cxstat); 52.142 + free(avgfreq); 52.143 + return ; 52.144 + } 52.145 + alarm(timeout); 52.146 + } 52.147 + 52.148 + printf("Start sampling, waiting for CTRL-C or SIGINT or SIGALARM signal ...\n"); 52.149 52.150 pause(); 52.151 } 52.152 @@ -750,6 +805,70 @@ out: 52.153 fprintf(stderr, "failed to set governor name\n"); 52.154 } 52.155 52.156 +#define MAX_NR_CPU 512 52.157 + 52.158 +void cpu_topology_func(int argc, char *argv[]) 52.159 +{ 52.160 + uint32_t cpu_to_core[MAX_NR_CPU]; 52.161 + uint32_t cpu_to_socket[MAX_NR_CPU]; 52.162 + struct xc_get_cputopo info; 52.163 + int i, ret; 52.164 + 52.165 + info.cpu_to_core = cpu_to_core; 52.166 + info.cpu_to_socket = cpu_to_socket; 52.167 + info.max_cpus = MAX_NR_CPU; 52.168 + ret = xc_get_cputopo(xc_fd, &info); 52.169 + if (!ret) 52.170 + { 52.171 + printf("CPU\tcore\tsocket\n"); 52.172 + for (i=0; i<info.nr_cpus; i++) 52.173 + { 52.174 + if ( info.cpu_to_core[i] != INVALID_TOPOLOGY_ID && 52.175 + info.cpu_to_socket[i] != INVALID_TOPOLOGY_ID ) 52.176 + { 52.177 + printf("CPU%d\t %d\t %d\n", i, info.cpu_to_core[i], 52.178 + info.cpu_to_socket[i]); 52.179 + } 52.180 + } 52.181 + } 52.182 + else 52.183 + { 52.184 + printf("Can not get Xen CPU topology!\n"); 52.185 + } 52.186 + 52.187 + return ; 52.188 +} 52.189 + 52.190 +void set_sched_smt_func(int argc, char *argv[]) 52.191 +{ 52.192 + int value, rc; 52.193 + 52.194 + if (argc != 1){ 52.195 + show_help(); 52.196 + exit(-1); 52.197 + } 52.198 + 52.199 + if ( !strncmp(argv[0], "disable", sizeof("disable")) ) 52.200 + { 52.201 + value = 0; 52.202 + } 52.203 + else if ( !strncmp(argv[0], "enable", sizeof("enable")) ) 52.204 + { 52.205 + value = 1; 52.206 + } 52.207 + else 52.208 + { 52.209 + show_help(); 52.210 + exit(-1); 52.211 + } 52.212 + 52.213 + rc = xc_set_sched_opt_smt(xc_fd, value); 52.214 + printf("%s sched_smt_power_savings %s\n", argv[0], 52.215 + rc? "failed":"successeed" ); 52.216 + 52.217 + return; 52.218 +} 52.219 + 52.220 struct { 52.221 const char *name; 52.222 void (*function)(int argc, char *argv[]); 52.223 @@ -765,6 +884,8 @@ struct { 52.224 { "set-scaling-speed", scaling_speed_func }, 52.225 { "set-sampling-rate", scaling_sampling_rate_func }, 52.226 { "set-up-threshold", scaling_up_threshold_func }, 52.227 + { "get-cpu-topology", cpu_topology_func}, 52.228 + { "set-sched-smt", set_sched_smt_func}, 52.229 }; 52.230 52.231 int main(int argc, char *argv[])
53.1 --- a/tools/pygrub/src/pygrub Fri Mar 27 10:54:08 2009 +0900 53.2 +++ b/tools/pygrub/src/pygrub Fri Mar 27 11:07:11 2009 +0900 53.3 @@ -441,7 +441,11 @@ class Grub: 53.4 # Timed out waiting for a keypress 53.5 if mytime != -1: 53.6 mytime += 1 53.7 - if mytime >= int(timeout): 53.8 + # curses.timeout() does not work properly on Solaris 53.9 + # So we may come here even after a key has been pressed. 53.10 + # Check both timeout and mytime to avoid exiting 53.11 + # when we shouldn't. 53.12 + if timeout != -1 and mytime >= int(timeout): 53.13 self.isdone = True 53.14 break 53.15 else: 53.16 @@ -526,7 +530,11 @@ def run_grub(file, entry, fs, arg): 53.17 print "No kernel image selected!" 53.18 sys.exit(1) 53.19 53.20 - img = g.cf.images[sel] 53.21 + try: 53.22 + img = g.cf.images[sel] 53.23 + except: 53.24 + log.debug("PyGrub: Default selection is not valid, using first boot configuration...") 53.25 + img = g.cf.images[0] 53.26 53.27 grubcfg = { "kernel": None, "ramdisk": None, "args": None } 53.28 53.29 @@ -579,6 +587,15 @@ def sniff_solaris(fs, cfg): 53.30 53.31 return cfg 53.32 53.33 +def sniff_netware(fs, cfg): 53.34 + if not fs.file_exists("/nwserver/xnloader.sys"): 53.35 + return cfg 53.36 + 53.37 + if not cfg["kernel"]: 53.38 + cfg["kernel"] = "/nwserver/xnloader.sys" 53.39 + 53.40 + return cfg 53.41 + 53.42 if __name__ == "__main__": 53.43 sel = None 53.44 53.45 @@ -659,6 +676,9 @@ if __name__ == "__main__": 53.46 chosencfg = sniff_solaris(fs, incfg) 53.47 53.48 if not chosencfg["kernel"]: 53.49 + chosencfg = sniff_netware(fs, incfg) 53.50 + 53.51 + if not chosencfg["kernel"]: 53.52 chosencfg = run_grub(file, entry, fs, incfg["args"]) 53.53 53.54 data = fs.open_file(chosencfg["kernel"]).read()
54.1 --- a/tools/python/setup.py Fri Mar 27 10:54:08 2009 +0900 54.2 +++ b/tools/python/setup.py Fri Mar 27 11:07:11 2009 +0900 54.3 @@ -38,6 +38,13 @@ scf = Extension("scf", 54.4 libraries = libraries, 54.5 sources = [ "xen/lowlevel/scf/scf.c" ]) 54.6 54.7 +process = Extension("process", 54.8 + extra_compile_args = extra_compile_args, 54.9 + include_dirs = include_dirs + [ "xen/lowlevel/process" ], 54.10 + library_dirs = library_dirs, 54.11 + libraries = libraries + [ "contract" ], 54.12 + sources = [ "xen/lowlevel/process/process.c" ]) 54.13 + 54.14 acm = Extension("acm", 54.15 extra_compile_args = extra_compile_args, 54.16 include_dirs = include_dirs + [ "xen/lowlevel/acm" ], 54.17 @@ -63,6 +70,7 @@ ptsname = Extension("ptsname", 54.18 modules = [ xc, xs, ptsname, acm, flask ] 54.19 if os.uname()[0] == 'SunOS': 54.20 modules.append(scf) 54.21 + modules.append(process) 54.22 54.23 setup(name = 'xen', 54.24 version = '3.0',
55.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 55.2 +++ b/tools/python/xen/lowlevel/process/process.c Fri Mar 27 11:07:11 2009 +0900 55.3 @@ -0,0 +1,164 @@ 55.4 +/* 55.5 + * Permission is hereby granted, free of charge, to any person obtaining a copy 55.6 + * of this software and associated documentation files (the "Software"), to 55.7 + * deal in the Software without restriction, including without limitation the 55.8 + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 55.9 + * sell copies of the Software, and to permit persons to whom the Software is 55.10 + * furnished to do so, subject to the following conditions: 55.11 + * 55.12 + * The above copyright notice and this permission notice shall be included in 55.13 + * all copies or substantial portions of the Software. 55.14 + * 55.15 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 55.16 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 55.17 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 55.18 + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 55.19 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 55.20 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 55.21 + * DEALINGS IN THE SOFTWARE. 55.22 + * 55.23 + * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 55.24 + * Use is subject to license terms. 55.25 + */ 55.26 + 55.27 +#include <Python.h> 55.28 + 55.29 +#include <libcontract.h> 55.30 +#include <sys/contract/process.h> 55.31 +#include <fcntl.h> 55.32 +#include <stdio.h> 55.33 + 55.34 +/* 55.35 + * On Solaris, xend runs under a contract as an smf(5) service. As a 55.36 + * result, when spawning long-running children such as a domain's 55.37 + * qemu-dm instantiation, we have to make sure it's in a separate 55.38 + * contract. Before we fork, we must activate a separate process 55.39 + * contract template to place the child processes in a new contract. 55.40 + */ 55.41 + 55.42 +static PyObject * 55.43 +pyprocess_activate(PyObject *o, PyObject *args, PyObject *kwargs) 55.44 +{ 55.45 + static char *kwlist[] = { "name", NULL }; 55.46 + char *name = NULL; 55.47 + int flags; 55.48 + int cfd; 55.49 + 55.50 + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", kwlist, &name)) 55.51 + return (NULL); 55.52 + 55.53 + cfd = open64("/system/contract/process/template", O_RDWR); 55.54 + 55.55 + if (cfd == -1) 55.56 + goto err; 55.57 + 55.58 + if ((flags = fcntl(cfd, F_GETFD, 0)) == -1) 55.59 + goto err; 55.60 + 55.61 + if (fcntl(cfd, F_SETFD, flags | FD_CLOEXEC) == -1) 55.62 + goto err; 55.63 + 55.64 + if (name != NULL) 55.65 + ct_pr_tmpl_set_svc_aux(cfd, name); 55.66 + 55.67 + if (ct_tmpl_activate(cfd)) 55.68 + goto err; 55.69 + 55.70 + return (PyInt_FromLong((long)cfd)); 55.71 + 55.72 +err: 55.73 + if (cfd != -1) 55.74 + close(cfd); 55.75 + PyErr_SetFromErrno(PyExc_OSError); 55.76 + return (NULL); 55.77 +} 55.78 + 55.79 +static PyObject * 55.80 +pyprocess_clear(PyObject *o, PyObject *args, PyObject *kwargs) 55.81 +{ 55.82 + static char *kwlist[] = { "contract", NULL }; 55.83 + int cfd; 55.84 + 55.85 + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", kwlist, &cfd)) 55.86 + return (NULL); 55.87 + 55.88 + if (ct_tmpl_clear(cfd) != 0) { 55.89 + PyErr_SetFromErrno(PyExc_OSError); 55.90 + return (NULL); 55.91 + } 55.92 + 55.93 + close(cfd); 55.94 + 55.95 + Py_INCREF(Py_None); 55.96 + return (Py_None); 55.97 +} 55.98 + 55.99 +static PyObject * 55.100 +pyprocess_abandon_latest(PyObject *o, PyObject *args, PyObject *kwargs) 55.101 +{ 55.102 + static char *kwlist[] = { NULL }; 55.103 + static char path[PATH_MAX]; 55.104 + ct_stathdl_t st; 55.105 + ctid_t latest; 55.106 + int cfd; 55.107 + 55.108 + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "", kwlist)) 55.109 + return (NULL); 55.110 + 55.111 + cfd = open64("/system/contract/process/latest", O_RDONLY); 55.112 + if (cfd == -1) 55.113 + goto err; 55.114 + 55.115 + ct_status_read(cfd, CTD_COMMON, &st); 55.116 + latest = ct_status_get_id(st); 55.117 + ct_status_free(st); 55.118 + close(cfd); 55.119 + 55.120 + snprintf(path, PATH_MAX, "/system/contract/process/%ld/ctl", 55.121 + (long)latest); 55.122 + 55.123 + if ((cfd = open64(path, O_WRONLY)) < 0) 55.124 + goto err; 55.125 + if (ct_ctl_abandon(cfd)) 55.126 + goto err; 55.127 + close(cfd); 55.128 + 55.129 + Py_INCREF(Py_None); 55.130 + return (Py_None); 55.131 +err: 55.132 + PyErr_SetFromErrno(PyExc_OSError); 55.133 + return (NULL); 55.134 +} 55.135 + 55.136 +PyDoc_STRVAR(pyprocess_activate__doc__, 55.137 + "activate(name)\n" 55.138 + "\n" 55.139 + "Activate a new process contract template. If name is given,\n" 55.140 + "it is used as the template's auxiliary value.\n" 55.141 + "Returns the new contract template.\n"); 55.142 + 55.143 +PyDoc_STRVAR(pyprocess_clear__doc__, 55.144 + "clear(contract)\n" 55.145 + "\n" 55.146 + "Clear and close the given contract template.\n"); 55.147 + 55.148 +PyDoc_STRVAR(pyprocess_abandon_latest__doc__, 55.149 + "abandon_latest()\n" 55.150 + "\n" 55.151 + "Abandon the latest contract created by this thread.\n"); 55.152 + 55.153 +static struct PyMethodDef pyprocess_module_methods[] = { 55.154 + { "activate", (PyCFunction) pyprocess_activate, 55.155 + METH_VARARGS|METH_KEYWORDS, pyprocess_activate__doc__ }, 55.156 + { "clear", (PyCFunction) pyprocess_clear, 55.157 + METH_VARARGS|METH_KEYWORDS, pyprocess_clear__doc__ }, 55.158 + { "abandon_latest", (PyCFunction) pyprocess_abandon_latest, 55.159 + METH_VARARGS|METH_KEYWORDS, pyprocess_abandon_latest__doc__ }, 55.160 + { NULL, NULL, 0, NULL } 55.161 +}; 55.162 + 55.163 +PyMODINIT_FUNC 55.164 +initprocess(void) 55.165 +{ 55.166 + Py_InitModule("process", pyprocess_module_methods); 55.167 +}
56.1 --- a/tools/python/xen/util/pci.py Fri Mar 27 10:54:08 2009 +0900 56.2 +++ b/tools/python/xen/util/pci.py Fri Mar 27 11:07:11 2009 +0900 56.3 @@ -12,6 +12,7 @@ import re 56.4 import types 56.5 import struct 56.6 import time 56.7 +import threading 56.8 from xen.util import utils 56.9 56.10 PROC_PCI_PATH = '/proc/bus/pci/devices' 56.11 @@ -97,6 +98,7 @@ MSIX_SIZE_MASK = 0x7ff 56.12 56.13 # Global variable to store information from lspci 56.14 lspci_info = None 56.15 +lspci_info_lock = threading.RLock() 56.16 56.17 #Calculate PAGE_SHIFT: number of bits to shift an address to get the page number 56.18 PAGE_SIZE = resource.getpagesize() 56.19 @@ -174,12 +176,16 @@ def get_all_pci_devices(): 56.20 56.21 return pci_devs 56.22 56.23 -def create_lspci_info(): 56.24 +def _create_lspci_info(): 56.25 + """Execute 'lspci' command and parse the result. 56.26 + If the command does not exist, lspci_info will be kept blank ({}). 56.27 + 56.28 + Expects to be protected by lspci_info_lock. 56.29 + """ 56.30 global lspci_info 56.31 + 56.32 lspci_info = {} 56.33 56.34 - # Execute 'lspci' command and parse the result. 56.35 - # If the command does not exist, lspci_info will be kept blank ({}). 56.36 for paragraph in os.popen(LSPCI_CMD + ' -vmm').read().split('\n\n'): 56.37 device_name = None 56.38 device_info = {} 56.39 @@ -195,6 +201,14 @@ def create_lspci_info(): 56.40 if device_name is not None: 56.41 lspci_info[device_name] = device_info 56.42 56.43 +def create_lspci_info(): 56.44 + global lspci_info_lock 56.45 + lspci_info_lock.acquire() 56.46 + try: 56.47 + _create_lspci_info() 56.48 + finally: 56.49 + lspci_info_lock.release() 56.50 + 56.51 def save_pci_conf_space(devs_string): 56.52 pci_list = [] 56.53 cfg_list = [] 56.54 @@ -911,22 +925,27 @@ class PciDevice: 56.55 Since we cannot obtain these data from sysfs, use 'lspci' command. 56.56 """ 56.57 global lspci_info 56.58 + global lspci_info_lock 56.59 56.60 - if lspci_info is None: 56.61 - create_lspci_info() 56.62 - 56.63 + lspci_info_lock.acquire() 56.64 try: 56.65 - device_info = lspci_info[self.name] 56.66 - self.revision = int(device_info['Rev'], 16) 56.67 - self.vendorname = device_info['Vendor'] 56.68 - self.devicename = device_info['Device'] 56.69 - self.classname = device_info['Class'] 56.70 - self.subvendorname = device_info['SVendor'] 56.71 - self.subdevicename = device_info['SDevice'] 56.72 - except KeyError: 56.73 - pass 56.74 + if lspci_info is None: 56.75 + _create_lspci_info() 56.76 56.77 - return True 56.78 + try: 56.79 + device_info = lspci_info[self.name] 56.80 + self.revision = int(device_info['Rev'], 16) 56.81 + self.vendorname = device_info['Vendor'] 56.82 + self.devicename = device_info['Device'] 56.83 + self.classname = device_info['Class'] 56.84 + self.subvendorname = device_info['SVendor'] 56.85 + self.subdevicename = device_info['SDevice'] 56.86 + except KeyError: 56.87 + pass 56.88 + 56.89 + return True 56.90 + finally: 56.91 + lspci_info_lock.release() 56.92 56.93 def __str__(self): 56.94 str = "PCI Device %s\n" % (self.name)
57.1 --- a/tools/python/xen/util/vscsi_util.py Fri Mar 27 10:54:08 2009 +0900 57.2 +++ b/tools/python/xen/util/vscsi_util.py Fri Mar 27 11:07:11 2009 +0900 57.3 @@ -90,7 +90,7 @@ def _vscsi_get_scsidevices_by_lsscsi(opt 57.4 57.5 devices = [] 57.6 57.7 - for scsiinfo in os.popen('lsscsi -g %s' % option).readlines(): 57.8 + for scsiinfo in os.popen('{ lsscsi -g %s; } 2>/dev/null' % option).readlines(): 57.9 s = scsiinfo.split() 57.10 hctl = s[0][1:-1] 57.11 try: 57.12 @@ -112,7 +112,10 @@ def _vscsi_get_scsidevices_by_sysfs(): 57.13 """ get all scsi devices information by sysfs """ 57.14 57.15 devices = [] 57.16 - sysfs_mnt = utils.find_sysfs_mount() 57.17 + try: 57.18 + sysfs_mnt = utils.find_sysfs_mount() 57.19 + except: 57.20 + return devices 57.21 57.22 for dirpath, dirnames, files in os.walk(sysfs_mnt + SYSFS_SCSI_PATH): 57.23 for hctl in dirnames: 57.24 @@ -152,7 +155,9 @@ def vscsi_get_hctl_and_devname_by(target 57.25 elif target.startswith('/dev/'): 57.26 scsi_devices = _vscsi_get_scsidevices_by_lsscsi("| grep %s" % target) 57.27 else: 57.28 - scsi_devices = vscsi_get_scsidevices() 57.29 + scsi_devices = _vscsi_get_scsidevices_by_lsscsi("") 57.30 + if not scsi_devices: 57.31 + scsi_devices = _vscsi_get_scsidevices_by_sysfs() 57.32 57.33 if len(target.split(':')) == 4: 57.34 return _vscsi_get_devname_by(target, scsi_devices) 57.35 @@ -248,7 +253,7 @@ def get_all_scsi_devices(): 57.36 get_scsi_scsilevel(scsi_dev['physical_HCTL']) 57.37 57.38 try: 57.39 - lsscsi_info = os.popen('lsscsi ' + scsi_dev['physical_HCTL']).read().split() 57.40 + lsscsi_info = os.popen('lsscsi %s 2>/dev/null' % scsi_dev['physical_HCTL']).read().split() 57.41 scsi_dev['type'] = lsscsi_info[1] 57.42 except: 57.43 scsi_dev['type'] = None
58.1 --- a/tools/python/xen/web/SrvDir.py Fri Mar 27 10:54:08 2009 +0900 58.2 +++ b/tools/python/xen/web/SrvDir.py Fri Mar 27 11:07:11 2009 +0900 58.3 @@ -20,7 +20,7 @@ import types 58.4 from xen.xend import sxp 58.5 from xen.xend import PrettyPrint 58.6 from xen.xend.Args import ArgError 58.7 -from xen.xend.XendError import XendError 58.8 +from xen.xend.XendError import XendError, XendInvalidDomain 58.9 #from xen.xend.XendLogging import log 58.10 58.11 import resource 58.12 @@ -71,6 +71,8 @@ class SrvDir(SrvBase): 58.13 val = self.get(x) 58.14 except XendError, ex: 58.15 return self.noChild(str(ex)) 58.16 + except XendInvalidDomain, ex: 58.17 + return self.noChild(str(ex)) 58.18 if val is None: 58.19 return self.noChild('Not found: ' + str(x)) 58.20 else:
59.1 --- a/tools/python/xen/web/connection.py Fri Mar 27 10:54:08 2009 +0900 59.2 +++ b/tools/python/xen/web/connection.py Fri Mar 27 11:07:11 2009 +0900 59.3 @@ -292,3 +292,40 @@ def hostAllowed(addrport, hosts_allowed) 59.4 return True 59.5 log.warn("Rejected connection from %s (%s).", addrport[0], fqdn) 59.6 return False 59.7 + 59.8 + 59.9 +class SocketDgramListener: 59.10 + """A connectionless server socket, running listen in a thread. 59.11 + """ 59.12 + 59.13 + def __init__(self, protocol_class): 59.14 + self.protocol = protocol_class() 59.15 + self.sock = self.createSocket() 59.16 + threading.Thread(target=self.main).start() 59.17 + 59.18 + 59.19 + def close(self): 59.20 + try: 59.21 + self.sock.close() 59.22 + except: 59.23 + pass 59.24 + 59.25 + 59.26 + def createSocket(self): 59.27 + raise NotImplementedError() 59.28 + 59.29 + 59.30 + def main(self): 59.31 + try: 59.32 + while True: 59.33 + try: 59.34 + data = self.sock.recv(BUFFER_SIZE) 59.35 + self.protocol.dataReceived(data) 59.36 + except socket.error, ex: 59.37 + if ex.args[0] not in (EWOULDBLOCK, EAGAIN, EINTR): 59.38 + break 59.39 + finally: 59.40 + try: 59.41 + self.close() 59.42 + except: 59.43 + pass
60.1 --- a/tools/python/xen/web/unix.py Fri Mar 27 10:54:08 2009 +0900 60.2 +++ b/tools/python/xen/web/unix.py Fri Mar 27 11:07:11 2009 +0900 60.3 @@ -27,16 +27,19 @@ from xen.util import mkdir 60.4 import connection 60.5 60.6 60.7 -def bind(path): 60.8 - """Create a Unix socket, and bind it to the given path. The socket is 60.9 -created such that only the current user may access it.""" 60.10 +def bind(path, type = socket.SOCK_STREAM): 60.11 + """Create a Unix socket, and bind it to the given path. 60.12 + The socket is created such that only the current user may access it.""" 60.13 60.14 - parent = os.path.dirname(path) 60.15 - mkdir.parents(parent, stat.S_IRWXU, True) 60.16 - if os.path.exists(path): 60.17 - os.unlink(path) 60.18 + if path[0] == '\0': # Abstract namespace is used for the path 60.19 + pass 60.20 + else: 60.21 + parent = os.path.dirname(path) 60.22 + mkdir.parents(parent, stat.S_IRWXU, True) 60.23 + if os.path.exists(path): 60.24 + os.unlink(path) 60.25 60.26 - sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) 60.27 + sock = socket.socket(socket.AF_UNIX, type) 60.28 sock.bind(path) 60.29 return sock 60.30 60.31 @@ -48,8 +51,19 @@ class UnixListener(connection.SocketList 60.32 60.33 60.34 def createSocket(self): 60.35 - return bind(self.path) 60.36 + return bind(self.path, socket.SOCK_STREAM) 60.37 60.38 60.39 def acceptConnection(self, sock, _): 60.40 connection.SocketServerConnection(sock, self.protocol_class) 60.41 + 60.42 + 60.43 +class UnixDgramListener(connection.SocketDgramListener): 60.44 + def __init__(self, path, protocol_class): 60.45 + self.path = path 60.46 + connection.SocketDgramListener.__init__(self, protocol_class) 60.47 + 60.48 + 60.49 + def createSocket(self): 60.50 + return bind(self.path, socket.SOCK_DGRAM) 60.51 +
61.1 --- a/tools/python/xen/xend/XendAPIStore.py Fri Mar 27 10:54:08 2009 +0900 61.2 +++ b/tools/python/xen/xend/XendAPIStore.py Fri Mar 27 11:07:11 2009 +0900 61.3 @@ -25,36 +25,59 @@ You must register both the uuid and type 61.4 by type, to ensure safety 61.5 """ 61.6 61.7 +import threading 61.8 + 61.9 __classes = {} 61.10 +__classes_lock = threading.RLock() 61.11 61.12 def register(uuid, type, inst): 61.13 - __classes[(uuid, type)] = inst 61.14 - return inst 61.15 + __classes_lock.acquire() 61.16 + try: 61.17 + __classes[(uuid, type)] = inst 61.18 + return inst 61.19 + finally: 61.20 + __classes_lock.release() 61.21 61.22 def deregister(uuid, type): 61.23 - old = get(uuid, type) 61.24 - if old is not None: 61.25 - del __classes[(uuid, type)] 61.26 - return old 61.27 + __classes_lock.acquire() 61.28 + try: 61.29 + old = get(uuid, type) 61.30 + if old is not None: 61.31 + del __classes[(uuid, type)] 61.32 + return old 61.33 + finally: 61.34 + __classes_lock.release() 61.35 61.36 def get(uuid, type): 61.37 """ 61.38 Get the instances by uuid and type 61.39 """ 61.40 - return __classes.get((uuid, type), None) 61.41 + __classes_lock.acquire() 61.42 + try: 61.43 + return __classes.get((uuid, type), None) 61.44 + finally: 61.45 + __classes_lock.release() 61.46 61.47 def get_all(all_type): 61.48 """ 61.49 Get all instances by type 61.50 """ 61.51 - return [inst 61.52 - for ((uuid, t), inst) in __classes.items() 61.53 - if t == all_type] 61.54 + __classes_lock.acquire() 61.55 + try: 61.56 + return [inst 61.57 + for ((uuid, t), inst) in __classes.items() 61.58 + if t == all_type] 61.59 + finally: 61.60 + __classes_lock.release() 61.61 61.62 def get_all_uuid(all_type): 61.63 """ 61.64 Get all uuids by type 61.65 """ 61.66 - return [uuid 61.67 - for (uuid, t) in __classes.keys() 61.68 - if t == all_type] 61.69 + __classes_lock.acquire() 61.70 + try: 61.71 + return [uuid 61.72 + for (uuid, t) in __classes.keys() 61.73 + if t == all_type] 61.74 + finally: 61.75 + __classes_lock.release()
62.1 --- a/tools/python/xen/xend/XendCheckpoint.py Fri Mar 27 10:54:08 2009 +0900 62.2 +++ b/tools/python/xen/xend/XendCheckpoint.py Fri Mar 27 11:07:11 2009 +0900 62.3 @@ -114,7 +114,7 @@ def save(fd, dominfo, network, live, dst 62.4 if line == "suspend": 62.5 log.debug("Suspending %d ...", dominfo.getDomid()) 62.6 dominfo.shutdown('suspend') 62.7 - dominfo.waitForShutdown() 62.8 + dominfo.waitForSuspend() 62.9 if line in ('suspend', 'suspended'): 62.10 dominfo.migrateDevices(network, dst, DEV_MIGRATE_STEP2, 62.11 domain_name)
63.1 --- a/tools/python/xen/xend/XendConfig.py Fri Mar 27 10:54:08 2009 +0900 63.2 +++ b/tools/python/xen/xend/XendConfig.py Fri Mar 27 11:07:11 2009 +0900 63.3 @@ -170,6 +170,7 @@ XENAPI_PLATFORM_CFG_TYPES = { 63.4 'xen_extended_power_mgmt': int, 63.5 'pci_msitranslate': int, 63.6 'pci_power_mgmt': int, 63.7 + 'xen_platform_pci': int, 63.8 } 63.9 63.10 # Xen API console 'other_config' keys. 63.11 @@ -464,6 +465,8 @@ class XendConfig(dict): 63.12 self['platform']['rtc_timeoffset'] = 0 63.13 if 'hpet' not in self['platform']: 63.14 self['platform']['hpet'] = 0 63.15 + if 'xen_platform_pci' not in self['platform']: 63.16 + self['platform']['xen_platform_pci'] = 1 63.17 if 'vpt_align' not in self['platform']: 63.18 self['platform']['vpt_align'] = 1 63.19 if 'loader' not in self['platform']: 63.20 @@ -1155,7 +1158,7 @@ class XendConfig(dict): 63.21 return None 63.22 return devid 63.23 63.24 - def device_duplicate_check(self, dev_type, dev_info, defined_config): 63.25 + def device_duplicate_check(self, dev_type, dev_info, defined_config, config): 63.26 defined_devices_sxpr = self.all_devices_sxpr(target = defined_config) 63.27 63.28 if dev_type == 'vbd' or dev_type == 'tap': 63.29 @@ -1174,9 +1177,34 @@ class XendConfig(dict): 63.30 if blkdev_file == o_blkdev_file: 63.31 raise XendConfigError('The file "%s" is already used' % 63.32 blkdev_file) 63.33 + if dev_uname == o_dev_uname: 63.34 + raise XendConfigError('The uname "%s" is already defined' % 63.35 + dev_uname) 63.36 o_blkdev_name = sxp.child_value(o_dev_info, 'dev') 63.37 o_devid = self._blkdev_name_to_number(o_blkdev_name) 63.38 if o_devid != None and devid == o_devid: 63.39 + name_array = blkdev_name.split(':', 2) 63.40 + if len(name_array) == 2 and name_array[1] == 'cdrom': 63.41 + # 63.42 + # Since the device is a cdrom, we are most likely 63.43 + # inserting, changing, or removing a cd. We can 63.44 + # update the old device instead of creating a new 63.45 + # one. 63.46 + # 63.47 + if o_dev_uname != None and dev_uname == None: 63.48 + # 63.49 + # We are removing a cd. We can simply update 63.50 + # the uname on the existing device. 63.51 + # 63.52 + merge_sxp = sxp.from_string("('vbd' ('uname' ''))") 63.53 + else: 63.54 + merge_sxp = config 63.55 + 63.56 + dev_uuid = sxp.child_value(o_dev_info, 'uuid') 63.57 + if dev_uuid != None and \ 63.58 + self.device_update(dev_uuid, cfg_sxp = merge_sxp): 63.59 + return dev_uuid 63.60 + 63.61 raise XendConfigError('The device "%s" is already defined' % 63.62 blkdev_name) 63.63 63.64 @@ -1188,6 +1216,7 @@ class XendConfig(dict): 63.65 if dev_mac.lower() == sxp.child_value(o_dev_info, 'mac').lower(): 63.66 raise XendConfigError('The mac "%s" is already defined' % 63.67 dev_mac) 63.68 + return None 63.69 63.70 def device_add(self, dev_type, cfg_sxp = None, cfg_xenapi = None, 63.71 target = None): 63.72 @@ -1326,7 +1355,9 @@ class XendConfig(dict): 63.73 if not dev_info.get('mac'): 63.74 dev_info['mac'] = randomMAC() 63.75 63.76 - self.device_duplicate_check(dev_type, dev_info, target) 63.77 + ret_uuid = self.device_duplicate_check(dev_type, dev_info, target, config) 63.78 + if ret_uuid != None: 63.79 + return ret_uuid 63.80 63.81 if dev_type == 'vif': 63.82 if dev_info.get('policy') and dev_info.get('label'): 63.83 @@ -1820,8 +1851,11 @@ class XendConfig(dict): 63.84 vscsi_be = vscsi_dict.get('backend', None) 63.85 63.86 # destroy existing XenAPI DSCSI objects 63.87 + vscsi_devid = int(dev_info['devs'][0]['devid']) 63.88 for dscsi_uuid in XendDSCSI.get_by_VM(self['uuid']): 63.89 - XendAPIStore.deregister(dscsi_uuid, "DSCSI") 63.90 + dscsi_inst = XendAPIStore.get(dscsi_uuid, 'DSCSI') 63.91 + if vscsi_devid == dscsi_inst.get_virtual_host(): 63.92 + XendAPIStore.deregister(dscsi_uuid, "DSCSI") 63.93 63.94 # create XenAPI DSCSI objects. 63.95 for vscsi_dev in vscsi_devs:
64.1 --- a/tools/python/xen/xend/XendConstants.py Fri Mar 27 10:54:08 2009 +0900 64.2 +++ b/tools/python/xen/xend/XendConstants.py Fri Mar 27 11:07:11 2009 +0900 64.3 @@ -96,7 +96,7 @@ SHUTDOWN_TIMEOUT = (60.0 * 5) 64.4 ZOMBIE_PREFIX = 'Zombie-' 64.5 64.6 """Minimum time between domain restarts in seconds.""" 64.7 -MINIMUM_RESTART_TIME = 20 64.8 +MINIMUM_RESTART_TIME = 60 64.9 64.10 RESTART_IN_PROGRESS = 'xend/restart_in_progress' 64.11 DUMPCORE_IN_PROGRESS = 'xend/dumpcore_in_progress' 64.12 @@ -135,3 +135,6 @@ VTPM_DELETE_SCRIPT = '/etc/xen/scripts/v 64.13 64.14 XS_VMROOT = "/vm/" 64.15 64.16 +NR_PCI_DEV = 32 64.17 +AUTO_PHP_SLOT = NR_PCI_DEV 64.18 +AUTO_PHP_SLOT_STR = "%02x" % NR_PCI_DEV
65.1 --- a/tools/python/xen/xend/XendDomain.py Fri Mar 27 10:54:08 2009 +0900 65.2 +++ b/tools/python/xen/xend/XendDomain.py Fri Mar 27 11:07:11 2009 +0900 65.3 @@ -1223,7 +1223,7 @@ class XendDomain: 65.4 log.exception("domain_pause") 65.5 raise XendError(str(ex)) 65.6 65.7 - def domain_dump(self, domid, filename, live, crash): 65.8 + def domain_dump(self, domid, filename=None, live=False, crash=False, reset=False): 65.9 """Dump domain core.""" 65.10 65.11 dominfo = self.domain_lookup_nr(domid) 65.12 @@ -1237,13 +1237,25 @@ class XendDomain: 65.13 POWER_STATE_NAMES[DOM_STATE_PAUSED], 65.14 POWER_STATE_NAMES[dominfo._stateGet()]) 65.15 65.16 + dopause = (not live and dominfo._stateGet() == DOM_STATE_RUNNING) 65.17 + if dopause: 65.18 + dominfo.pause() 65.19 + 65.20 try: 65.21 - log.info("Domain core dump requested for domain %s (%d) " 65.22 - "live=%d crash=%d.", 65.23 - dominfo.getName(), dominfo.getDomid(), live, crash) 65.24 - return dominfo.dumpCore(filename) 65.25 - except Exception, ex: 65.26 - raise XendError(str(ex)) 65.27 + try: 65.28 + log.info("Domain core dump requested for domain %s (%d) " 65.29 + "live=%d crash=%d reset=%d.", 65.30 + dominfo.getName(), dominfo.getDomid(), live, crash, reset) 65.31 + dominfo.dumpCore(filename) 65.32 + if crash: 65.33 + self.domain_destroy(domid) 65.34 + elif reset: 65.35 + self.domain_reset(domid) 65.36 + except Exception, ex: 65.37 + raise XendError(str(ex)) 65.38 + finally: 65.39 + if dopause and not crash and not reset: 65.40 + dominfo.unpause() 65.41 65.42 def domain_destroy(self, domid): 65.43 """Terminate domain immediately.
66.1 --- a/tools/python/xen/xend/XendDomainInfo.py Fri Mar 27 10:54:08 2009 +0900 66.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Fri Mar 27 11:07:11 2009 +0900 66.3 @@ -793,7 +793,7 @@ class XendDomainInfo: 66.4 existing_dev_uuid = sxp.child_value(existing_dev_info, 'uuid') 66.5 existing_pci_conf = self.info['devices'][existing_dev_uuid][1] 66.6 existing_pci_devs = existing_pci_conf['devs'] 66.7 - vslt = '0x0' 66.8 + vslt = AUTO_PHP_SLOT_STR 66.9 for x in existing_pci_devs: 66.10 if ( int(x['domain'], 16) == int(dev['domain'], 16) and 66.11 int(x['bus'], 16) == int(dev['bus'], 16) and 66.12 @@ -801,7 +801,7 @@ class XendDomainInfo: 66.13 int(x['func'], 16) == int(dev['func'], 16) ): 66.14 vslt = x['vslt'] 66.15 break 66.16 - if vslt == '0x0': 66.17 + if vslt == AUTO_PHP_SLOT_STR: 66.18 raise VmError("Device %04x:%02x:%02x.%01x is not connected" 66.19 % (int(dev['domain'],16), int(dev['bus'],16), 66.20 int(dev['slot'],16), int(dev['func'],16))) 66.21 @@ -1410,7 +1410,8 @@ class XendDomainInfo: 66.22 for dev_uuid, (dev_type, dev_info) in self.info['devices'].items(): 66.23 if dev_type == 'vfb': 66.24 old_location = dev_info.get('location') 66.25 - listen_host = dev_info.get('vnclisten', 'localhost') 66.26 + listen_host = dev_info.get('vnclisten', \ 66.27 + XendOptions.instance().get_vnclisten_address()) 66.28 new_location = '%s:%s' % (listen_host, str(vnc_port)) 66.29 if old_location == new_location: 66.30 break 66.31 @@ -1495,7 +1496,8 @@ class XendDomainInfo: 66.32 t.mkdir() 66.33 t.set_permissions({'dom' : self.domid, 'read' : True}) 66.34 t.write('vm', self.vmpath) 66.35 - for i in [ 'device', 'control', 'error', 'memory' ]: 66.36 + # NB. Solaris guests use guest/ and hvmpv/ xenstore directories 66.37 + for i in [ 'device', 'control', 'error', 'memory', 'guest', 'hvmpv' ]: 66.38 t.mkdir(i) 66.39 t.set_permissions(i, {'dom' : self.domid}) 66.40 66.41 @@ -2027,26 +2029,31 @@ class XendDomainInfo: 66.42 @raise: XendError if core dumping failed. 66.43 """ 66.44 66.45 - try: 66.46 - if not corefile: 66.47 - this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime()) 66.48 - corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time, 66.49 - self.info['name_label'], self.domid) 66.50 + if not corefile: 66.51 + this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime()) 66.52 + corefile = "/var/xen/dump/%s-%s.%s.core" % (this_time, 66.53 + self.info['name_label'], self.domid) 66.54 66.55 - if os.path.isdir(corefile): 66.56 - raise XendError("Cannot dump core in a directory: %s" % 66.57 - corefile) 66.58 - 66.59 - self._writeVm(DUMPCORE_IN_PROGRESS, 'True') 66.60 - xc.domain_dumpcore(self.domid, corefile) 66.61 + if os.path.isdir(corefile): 66.62 + raise XendError("Cannot dump core in a directory: %s" % 66.63 + corefile) 66.64 + 66.65 + try: 66.66 + try: 66.67 + self._writeVm(DUMPCORE_IN_PROGRESS, 'True') 66.68 + xc.domain_dumpcore(self.domid, corefile) 66.69 + except RuntimeError, ex: 66.70 + corefile_incomp = corefile+'-incomplete' 66.71 + try: 66.72 + os.rename(corefile, corefile_incomp) 66.73 + except: 66.74 + pass 66.75 + 66.76 + log.error("core dump failed: id = %s name = %s: %s", 66.77 + self.domid, self.info['name_label'], str(ex)) 66.78 + raise XendError("Failed to dump core: %s" % str(ex)) 66.79 + finally: 66.80 self._removeVm(DUMPCORE_IN_PROGRESS) 66.81 - except RuntimeError, ex: 66.82 - corefile_incomp = corefile+'-incomplete' 66.83 - os.rename(corefile, corefile_incomp) 66.84 - self._removeVm(DUMPCORE_IN_PROGRESS) 66.85 - log.exception("XendDomainInfo.dumpCore failed: id = %s name = %s", 66.86 - self.domid, self.info['name_label']) 66.87 - raise XendError("Failed to dump core: %s" % str(ex)) 66.88 66.89 # 66.90 # Device creation/deletion functions 66.91 @@ -2544,6 +2551,31 @@ class XendDomainInfo: 66.92 finally: 66.93 self.state_updated.release() 66.94 66.95 + def waitForSuspend(self): 66.96 + """Wait for the guest to respond to a suspend request by 66.97 + shutting down. If the guest hasn't re-written control/shutdown 66.98 + after a certain amount of time, it's obviously not listening and 66.99 + won't suspend, so we give up. HVM guests with no PV drivers 66.100 + should already be shutdown. 66.101 + """ 66.102 + state = "suspend" 66.103 + nr_tries = 60 66.104 + 66.105 + self.state_updated.acquire() 66.106 + try: 66.107 + while self._stateGet() in (DOM_STATE_RUNNING,DOM_STATE_PAUSED): 66.108 + self.state_updated.wait(1.0) 66.109 + if state == "suspend": 66.110 + if nr_tries == 0: 66.111 + msg = ('Timeout waiting for domain %s to suspend' 66.112 + % self.domid) 66.113 + self._writeDom('control/shutdown', '') 66.114 + raise XendError(msg) 66.115 + state = self.readDom('control/shutdown') 66.116 + nr_tries -= 1 66.117 + finally: 66.118 + self.state_updated.release() 66.119 + 66.120 # 66.121 # TODO: recategorise - called from XendCheckpoint 66.122 # 66.123 @@ -2888,7 +2920,9 @@ class XendDomainInfo: 66.124 while True: 66.125 test = 0 66.126 diff = time.time() - start 66.127 - for i in self.getDeviceController('vbd').deviceIDs(): 66.128 + vbds = self.getDeviceController('vbd').deviceIDs() 66.129 + taps = self.getDeviceController('tap').deviceIDs() 66.130 + for i in vbds + taps: 66.131 test = 1 66.132 log.info("Dev %s still active, looping...", i) 66.133 time.sleep(0.1) 66.134 @@ -3669,7 +3703,8 @@ class XendDomainInfo: 66.135 ['v-dev', xenapi_dscsi.get('virtual_HCTL')], 66.136 ['state', xenbusState['Initialising']], 66.137 ['uuid', dscsi_uuid] 66.138 - ] 66.139 + ], 66.140 + ['feature-host', 0] 66.141 ] 66.142 66.143 if self._stateGet() != XEN_API_VM_POWER_STATE_RUNNING: 66.144 @@ -3682,7 +3717,7 @@ class XendDomainInfo: 66.145 raise XendError('Failed to create device') 66.146 66.147 else: 66.148 - new_vscsi_sxp = ['vscsi'] 66.149 + new_vscsi_sxp = ['vscsi', ['feature-host', 0]] 66.150 for existing_dev in sxp.children(cur_vscsi_sxp, 'dev'): 66.151 new_vscsi_sxp.append(existing_dev) 66.152 new_vscsi_sxp.append(sxp.child0(target_vscsi_sxp, 'dev')) 66.153 @@ -3776,7 +3811,7 @@ class XendDomainInfo: 66.154 dev_uuid = sxp.child_value(cur_vscsi_sxp, 'uuid') 66.155 66.156 target_dev = None 66.157 - new_vscsi_sxp = ['vscsi'] 66.158 + new_vscsi_sxp = ['vscsi', ['feature-host', 0]] 66.159 for dev in sxp.children(cur_vscsi_sxp, 'dev'): 66.160 if vHCTL == sxp.child_value(dev, 'v-dev'): 66.161 target_dev = dev 66.162 @@ -3787,7 +3822,7 @@ class XendDomainInfo: 66.163 raise XendError('Failed to destroy device') 66.164 66.165 target_dev.append(['state', xenbusState['Closing']]) 66.166 - target_vscsi_sxp = ['vscsi', target_dev] 66.167 + target_vscsi_sxp = ['vscsi', target_dev, ['feature-host', 0]] 66.168 66.169 if self._stateGet() != XEN_API_VM_POWER_STATE_RUNNING: 66.170
67.1 --- a/tools/python/xen/xend/XendNode.py Fri Mar 27 10:54:08 2009 +0900 67.2 +++ b/tools/python/xen/xend/XendNode.py Fri Mar 27 11:07:11 2009 +0900 67.3 @@ -18,6 +18,7 @@ 67.4 67.5 import os 67.6 import socket 67.7 +import time 67.8 import xen.lowlevel.xc 67.9 67.10 from xen.util import Brctl 67.11 @@ -145,6 +146,18 @@ class XendNode: 67.12 67.13 self.srs = {} 67.14 67.15 + self._init_networks() 67.16 + self._init_PIFs() 67.17 + 67.18 + self._init_SRs() 67.19 + self._init_PBDs() 67.20 + 67.21 + self._init_PPCIs() 67.22 + 67.23 + self._init_PSCSIs() 67.24 + 67.25 + 67.26 + def _init_networks(self): 67.27 # Initialise networks 67.28 # First configure ones off disk 67.29 saved_networks = self.state_store.load_state('network') 67.30 @@ -157,7 +170,16 @@ class XendNode: 67.31 67.32 # Next discover any existing bridges and check 67.33 # they are not already configured 67.34 - bridges = Brctl.get_state().keys() 67.35 + 67.36 + # 'tmpbridge' is a temporary bridge created by network-bridge script. 67.37 + # Wait a couple of seconds for it to be renamed. 67.38 + for i in xrange(20): 67.39 + bridges = Brctl.get_state().keys() 67.40 + if 'tmpbridge' in bridges: 67.41 + time.sleep(0.1) 67.42 + else: 67.43 + break 67.44 + 67.45 configured_bridges = [XendAPIStore.get( 67.46 network_uuid, "network") 67.47 .get_name_label() 67.48 @@ -166,8 +188,10 @@ class XendNode: 67.49 for bridge in bridges 67.50 if bridge not in configured_bridges] 67.51 for unconfigured_bridge in unconfigured_bridges: 67.52 - XendNetwork.create_phy(unconfigured_bridge) 67.53 + if unconfigured_bridge != 'tmpbridge': 67.54 + XendNetwork.create_phy(unconfigured_bridge) 67.55 67.56 + def _init_PIFs(self): 67.57 # Initialise PIFs 67.58 # First configure ones off disk 67.59 saved_pifs = self.state_store.load_state('pif') 67.60 @@ -210,7 +234,8 @@ class XendNode: 67.61 log.debug("Cannot find network for bridge %s " 67.62 "when configuring PIF %s", 67.63 (bridge_name, name)) 67.64 - 67.65 + 67.66 + def _init_SRs(self): 67.67 # initialise storage 67.68 saved_srs = self.state_store.load_state('sr') 67.69 if saved_srs: 67.70 @@ -229,6 +254,7 @@ class XendNode: 67.71 qcow_sr_uuid = uuid.createString() 67.72 self.srs[qcow_sr_uuid] = XendQCoWStorageRepo(qcow_sr_uuid) 67.73 67.74 + def _init_PBDs(self): 67.75 saved_pbds = self.state_store.load_state('pbd') 67.76 if saved_pbds: 67.77 for pbd_uuid, pbd_cfg in saved_pbds.items(): 67.78 @@ -237,8 +263,7 @@ class XendNode: 67.79 except CreateUnspecifiedAttributeError: 67.80 log.warn("Error recreating PBD %s", pbd_uuid) 67.81 67.82 - 67.83 - # Initialise PPCIs 67.84 + def _init_PPCIs(self): 67.85 saved_ppcis = self.state_store.load_state('ppci') 67.86 saved_ppci_table = {} 67.87 if saved_ppcis: 67.88 @@ -271,7 +296,7 @@ class XendNode: 67.89 ppci_uuid = saved_ppci_table.get(pci_dev.name, uuid.createString()) 67.90 XendPPCI(ppci_uuid, ppci_record) 67.91 67.92 - 67.93 + def _init_PSCSIs(self): 67.94 # Initialise PSCSIs 67.95 saved_pscsis = self.state_store.load_state('pscsi') 67.96 saved_pscsi_table = {} 67.97 @@ -290,6 +315,75 @@ class XendNode: 67.98 XendPSCSI(pscsi_uuid, pscsi_record) 67.99 67.100 67.101 + def add_network(self, interface): 67.102 + # TODO 67.103 + log.debug("add_network(): Not implemented.") 67.104 + 67.105 + 67.106 + def remove_network(self, interface): 67.107 + # TODO 67.108 + log.debug("remove_network(): Not implemented.") 67.109 + 67.110 + 67.111 + def add_PPCI(self, pci_name): 67.112 + # Update lspci info 67.113 + PciUtil.create_lspci_info() 67.114 + 67.115 + # Initialise the PPCI 67.116 + saved_ppcis = self.state_store.load_state('ppci') 67.117 + saved_ppci_table = {} 67.118 + if saved_ppcis: 67.119 + for ppci_uuid, ppci_record in saved_ppcis.items(): 67.120 + try: 67.121 + saved_ppci_table[ppci_record['name']] = ppci_uuid 67.122 + except KeyError: 67.123 + pass 67.124 + 67.125 + (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name) 67.126 + pci_dev = PciUtil.PciDevice(domain, bus, slot, func) 67.127 + ppci_record = { 67.128 + 'domain': pci_dev.domain, 67.129 + 'bus': pci_dev.bus, 67.130 + 'slot': pci_dev.slot, 67.131 + 'func': pci_dev.func, 67.132 + 'vendor_id': pci_dev.vendor, 67.133 + 'vendor_name': pci_dev.vendorname, 67.134 + 'device_id': pci_dev.device, 67.135 + 'device_name': pci_dev.devicename, 67.136 + 'revision_id': pci_dev.revision, 67.137 + 'class_code': pci_dev.classcode, 67.138 + 'class_name': pci_dev.classname, 67.139 + 'subsystem_vendor_id': pci_dev.subvendor, 67.140 + 'subsystem_vendor_name': pci_dev.subvendorname, 67.141 + 'subsystem_id': pci_dev.subdevice, 67.142 + 'subsystem_name': pci_dev.subdevicename, 67.143 + 'driver': pci_dev.driver 67.144 + } 67.145 + # If saved uuid exists, use it. Otherwise create one. 67.146 + ppci_uuid = saved_ppci_table.get(pci_dev.name, uuid.createString()) 67.147 + XendPPCI(ppci_uuid, ppci_record) 67.148 + 67.149 + 67.150 + def remove_PPCI(self, pci_name): 67.151 + # Update lspci info 67.152 + PciUtil.create_lspci_info() 67.153 + 67.154 + # Remove the PPCI 67.155 + (domain, bus, slot, func) = PciUtil.parse_pci_name(pci_name) 67.156 + ppci_ref = XendPPCI.get_by_sbdf(domain, bus, slot, func) 67.157 + XendAPIStore.get(ppci_ref, "PPCI").destroy() 67.158 + 67.159 + 67.160 + def add_PSCSI(self): 67.161 + # TODO 67.162 + log.debug("add_network(): Not implemented.") 67.163 + 67.164 + 67.165 + def remove_PSCSI(self): 67.166 + # TODO 67.167 + log.debug("add_network(): Not implemented.") 67.168 + 67.169 + 67.170 ## def network_destroy(self, net_uuid): 67.171 ## del self.networks[net_uuid] 67.172 ## self.save_networks()
68.1 --- a/tools/python/xen/xend/XendOptions.py Fri Mar 27 10:54:08 2009 +0900 68.2 +++ b/tools/python/xen/xend/XendOptions.py Fri Mar 27 11:07:11 2009 +0900 68.3 @@ -75,6 +75,9 @@ class XendOptions: 68.4 """Default for the flag indicating whether xend should run a ssl relocation server.""" 68.5 xend_relocation_ssl_server_default = 'no' 68.6 68.7 + """Default for the flag indicating whether xend should run a udev event server.""" 68.8 + xend_udev_event_server_default = 'no' 68.9 + 68.10 """Default interface address the xend relocation server listens at. """ 68.11 xend_relocation_address_default = '' 68.12 68.13 @@ -216,6 +219,10 @@ class XendOptions: 68.14 def get_xend_relocation_server_ssl_cert_file(self): 68.15 return self.get_config_string("xend-relocation-server-ssl-cert-file") 68.16 68.17 + def get_xend_udev_event_server(self): 68.18 + return self.get_config_bool("xend-udev-event-server", 68.19 + self.xend_udev_event_server_default) 68.20 + 68.21 def get_xend_port(self): 68.22 """Get the port xend listens at for its HTTP interface. 68.23 """
69.1 --- a/tools/python/xen/xend/XendPPCI.py Fri Mar 27 10:54:08 2009 +0900 69.2 +++ b/tools/python/xen/xend/XendPPCI.py Fri Mar 27 11:07:11 2009 +0900 69.3 @@ -20,6 +20,8 @@ from xen.xend.XendBase import XendBase 69.4 from xen.xend.XendBase import XendAPIStore 69.5 from xen.xend import uuid as genuuid 69.6 69.7 +from xen.util.pci import parse_hex 69.8 + 69.9 class XendPPCI(XendBase): 69.10 """Representation of a physical PCI device.""" 69.11 69.12 @@ -72,10 +74,10 @@ class XendPPCI(XendBase): 69.13 69.14 def get_by_sbdf(self, domain, bus, slot, func): 69.15 for ppci in XendAPIStore.get_all("PPCI"): 69.16 - if ppci.get_domain() == int(domain, 16) and \ 69.17 - ppci.get_bus() == int(bus, 16) and \ 69.18 - ppci.get_slot() == int(slot, 16) and \ 69.19 - ppci.get_func() == int(func, 16): 69.20 + if ppci.get_domain() == parse_hex(domain) and \ 69.21 + ppci.get_bus() == parse_hex(bus) and \ 69.22 + ppci.get_slot() == parse_hex(slot) and \ 69.23 + ppci.get_func() == parse_hex(func): 69.24 return ppci.get_uuid() 69.25 return None 69.26
70.1 --- a/tools/python/xen/xend/image.py Fri Mar 27 10:54:08 2009 +0900 70.2 +++ b/tools/python/xen/xend/image.py Fri Mar 27 11:07:11 2009 +0900 70.3 @@ -28,6 +28,7 @@ import sys 70.4 import errno 70.5 import glob 70.6 import traceback 70.7 +import platform 70.8 70.9 import xen.lowlevel.xc 70.10 from xen.xend.XendConstants import * 70.11 @@ -40,6 +41,7 @@ from xen.xend import arch 70.12 from xen.xend import XendOptions 70.13 from xen.util import oshelp 70.14 from xen.util import utils 70.15 +from xen.xend import osdep 70.16 70.17 xc = xen.lowlevel.xc.xc() 70.18 70.19 @@ -226,23 +228,23 @@ class ImageHandler: 70.20 if self.device_model is None: 70.21 return 70.22 70.23 - # If we use a device model, the pipes for communication between 70.24 - # blktapctrl and ioemu must be present before the devices are 70.25 - # created (blktapctrl must access them for new block devices) 70.26 + if platform.system() != 'SunOS': 70.27 + # If we use a device model, the pipes for communication between 70.28 + # blktapctrl and ioemu must be present before the devices are 70.29 + # created (blktapctrl must access them for new block devices) 70.30 70.31 - # mkdir throws an exception if the path already exists 70.32 - try: 70.33 - os.mkdir('/var/run/tap', 0755) 70.34 - except: 70.35 - pass 70.36 + try: 70.37 + os.makedirs('/var/run/tap', 0755) 70.38 + except: 70.39 + pass 70.40 70.41 - try: 70.42 - os.mkfifo('/var/run/tap/qemu-read-%d' % domid, 0600) 70.43 - os.mkfifo('/var/run/tap/qemu-write-%d' % domid, 0600) 70.44 - except OSError, e: 70.45 - log.warn('Could not create blktap pipes for domain %d' % domid) 70.46 - log.exception(e) 70.47 - pass 70.48 + try: 70.49 + os.mkfifo('/var/run/tap/qemu-read-%d' % domid, 0600) 70.50 + os.mkfifo('/var/run/tap/qemu-write-%d' % domid, 0600) 70.51 + except OSError, e: 70.52 + log.warn('Could not create blktap pipes for domain %d' % domid) 70.53 + log.exception(e) 70.54 + pass 70.55 70.56 70.57 # Return a list of cmd line args to the device models based on the 70.58 @@ -407,9 +409,12 @@ class ImageHandler: 70.59 logfd = os.open(self.logfile, logfile_mode) 70.60 70.61 sys.stderr.flush() 70.62 + contract = osdep.prefork("%s:%d" % 70.63 + (self.vm.getName(), self.vm.getDomid())) 70.64 pid = os.fork() 70.65 if pid == 0: #child 70.66 try: 70.67 + osdep.postfork(contract) 70.68 os.dup2(null, 0) 70.69 os.dup2(logfd, 1) 70.70 os.dup2(logfd, 2) 70.71 @@ -426,6 +431,7 @@ class ImageHandler: 70.72 except: 70.73 os._exit(127) 70.74 else: 70.75 + osdep.postfork(contract, abandon=True) 70.76 self.pid = pid 70.77 os.close(null) 70.78 os.close(logfd) 70.79 @@ -482,11 +488,7 @@ class ImageHandler: 70.80 70.81 def _dmfailed(self, message): 70.82 log.warning("domain %s: %s", self.vm.getName(), message) 70.83 - # ideally we would like to forcibly crash the domain with 70.84 - # something like 70.85 - # xc.domain_shutdown(self.vm.getDomid(), DOMAIN_CRASH) 70.86 - # but this can easily lead to very rapid restart loops against 70.87 - # which we currently have no protection 70.88 + xc.domain_shutdown(self.vm.getDomid(), DOMAIN_CRASH) 70.89 70.90 def recreate(self): 70.91 if self.device_model is None: 70.92 @@ -714,6 +716,7 @@ class HVMImageHandler(ImageHandler): 70.93 if 'hvm' not in info['xen_caps']: 70.94 raise HVMRequired() 70.95 70.96 + xen_platform_pci = int(vmConfig['platform'].get('xen_platform_pci',1)) 70.97 rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset') 70.98 70.99 if not self.display : 70.100 @@ -722,13 +725,23 @@ class HVMImageHandler(ImageHandler): 70.101 ("image/device-model", self.device_model), 70.102 ("image/display", self.display)) 70.103 self.vm.permissionsVm("image/dmargs", { 'dom': self.vm.getDomid(), 'read': True } ) 70.104 + 70.105 + if xen_platform_pci == 0: 70.106 + disable_pf = 1 70.107 + log.info("No need to create platform device.[domid:%d]", self.vm.getDomid()) 70.108 + else: 70.109 + disable_pf = 0 70.110 + log.info("Need to create platform device.[domid:%d]", self.vm.getDomid()) 70.111 + 70.112 + xstransact.Store("/local/domain/0/device-model/%i"%self.vm.getDomid(), 70.113 + ('disable_pf', disable_pf)) 70.114 self.vm.storeVm(("rtc/timeoffset", rtc_timeoffset)) 70.115 self.vm.permissionsVm("rtc/timeoffset", { 'dom': self.vm.getDomid(), 'read': True } ) 70.116 70.117 self.apic = int(vmConfig['platform'].get('apic', 0)) 70.118 self.acpi = int(vmConfig['platform'].get('acpi', 0)) 70.119 self.guest_os_type = vmConfig['platform'].get('guest_os_type') 70.120 - 70.121 + 70.122 70.123 # Return a list of cmd line args to the device models based on the 70.124 # xm config file
71.1 --- a/tools/python/xen/xend/osdep.py Fri Mar 27 10:54:08 2009 +0900 71.2 +++ b/tools/python/xen/xend/osdep.py Fri Mar 27 11:07:11 2009 +0900 71.3 @@ -18,6 +18,7 @@ 71.4 # Use is subject to license terms. 71.5 71.6 import os 71.7 +import commands 71.8 71.9 _scripts_dir = { 71.10 "Linux": "/etc/xen/scripts", 71.11 @@ -142,7 +143,79 @@ def _linux_get_cpuinfo(): 71.12 finally: 71.13 f.close() 71.14 71.15 +def _solaris_get_cpuinfo(): 71.16 + cpuinfo = {} 71.17 + 71.18 + # call kstat to extrace specific cpu_info output 71.19 + cmd = "/usr/bin/kstat -p -c misc -m cpu_info" 71.20 + kstatoutput = commands.getoutput (cmd) 71.21 + 71.22 + # walk each line 71.23 + for kstatline in kstatoutput.split('\n'): 71.24 + 71.25 + # split the line on 71.26 + # module:cpu #:module#:name value 71.27 + (module, cpunum, combo, namevalue) = kstatline.split (":") 71.28 + 71.29 + # check to see if this cpunum is already a key. If not, 71.30 + # initialize an empty hash table 71.31 + if not cpuinfo.has_key (int(cpunum)): 71.32 + cpuinfo[int(cpunum)] = {} 71.33 + 71.34 + # split the namevalue output on whitespace 71.35 + data = namevalue.split() 71.36 + 71.37 + # the key will be data[0] 71.38 + key = data[0] 71.39 + 71.40 + # check the length of the data list. If it's larger than 71.41 + # 2, join the rest of the list together with a space. 71.42 + # Otherwise, value is just data[1] 71.43 + if len (data) > 2: 71.44 + value = ' '.join (data[1:]) 71.45 + else: 71.46 + value = data[1] 71.47 + 71.48 + # add this key/value pair to the cpuhash 71.49 + cpuinfo[int(cpunum)][key] = value 71.50 + 71.51 + # Translate Solaris tokens into what Xend expects 71.52 + for key in cpuinfo.keys(): 71.53 + cpuinfo[key]["flags"] = "" 71.54 + cpuinfo[key]["model name"] = cpuinfo[key]["brand"] 71.55 + cpuinfo[key]["cpu MHz"] = cpuinfo[key]["clock_MHz"] 71.56 + 71.57 + # return the hash table 71.58 + return cpuinfo 71.59 + 71.60 _get_cpuinfo = { 71.61 + "SunOS": _solaris_get_cpuinfo 71.62 +} 71.63 + 71.64 +def _default_prefork(name): 71.65 + pass 71.66 + 71.67 +def _default_postfork(ct, abandon=False): 71.68 + pass 71.69 + 71.70 +# call this for long-running processes that should survive a xend 71.71 +# restart 71.72 +def _solaris_prefork(name): 71.73 + from xen.lowlevel import process 71.74 + return process.activate(name) 71.75 + 71.76 +def _solaris_postfork(ct, abandon=False): 71.77 + from xen.lowlevel import process 71.78 + process.clear(ct) 71.79 + if abandon: 71.80 + process.abandon_latest() 71.81 + 71.82 +_get_prefork = { 71.83 + "SunOS": _solaris_prefork 71.84 +} 71.85 + 71.86 +_get_postfork = { 71.87 + "SunOS": _solaris_postfork 71.88 } 71.89 71.90 def _get(var, default=None): 71.91 @@ -154,3 +227,5 @@ pygrub_path = _get(_pygrub_path, "/usr/b 71.92 vif_script = _get(_vif_script, "vif-bridge") 71.93 lookup_balloon_stat = _get(_balloon_stat, _linux_balloon_stat) 71.94 get_cpuinfo = _get(_get_cpuinfo, _linux_get_cpuinfo) 71.95 +prefork = _get(_get_prefork, _default_prefork) 71.96 +postfork = _get(_get_postfork, _default_postfork)
72.1 --- a/tools/python/xen/xend/server/BlktapController.py Fri Mar 27 10:54:08 2009 +0900 72.2 +++ b/tools/python/xen/xend/server/BlktapController.py Fri Mar 27 11:07:11 2009 +0900 72.3 @@ -15,7 +15,8 @@ blktap_disk_types = [ 72.4 'qcow', 72.5 'qcow2', 72.6 72.7 - 'ioemu' 72.8 + 'ioemu', 72.9 + 'tapdisk', 72.10 ] 72.11 72.12 class BlktapController(BlkifController):
74.1 --- a/tools/python/xen/xend/server/SrvDaemon.py Fri Mar 27 10:54:08 2009 +0900 74.2 +++ b/tools/python/xen/xend/server/SrvDaemon.py Fri Mar 27 11:07:11 2009 +0900 74.3 @@ -24,6 +24,7 @@ from xen.xend import osdep 74.4 from xen.util import mkdir 74.5 74.6 import relocate 74.7 +import udevevent 74.8 import SrvServer 74.9 from params import * 74.10 74.11 @@ -336,6 +337,7 @@ class Daemon: 74.12 del xc 74.13 74.14 relocate.listenRelocation() 74.15 + udevevent.listenUdevEvent() 74.16 servers = SrvServer.create() 74.17 servers.start(status) 74.18 del servers
75.1 --- a/tools/python/xen/xend/server/SrvDomain.py Fri Mar 27 10:54:08 2009 +0900 75.2 +++ b/tools/python/xen/xend/server/SrvDomain.py Fri Mar 27 11:07:11 2009 +0900 75.3 @@ -104,7 +104,8 @@ class SrvDomain(SrvDir): 75.4 [['dom', 'int'], 75.5 ['file', 'str'], 75.6 ['live', 'int'], 75.7 - ['crash', 'int']]) 75.8 + ['crash', 'int'], 75.9 + ['reset', 'int']]) 75.10 return fn(req.args, {'dom': self.dom.domid}) 75.11 75.12 def op_migrate(self, op, req):
76.1 --- a/tools/python/xen/xend/server/netif.py Fri Mar 27 10:54:08 2009 +0900 76.2 +++ b/tools/python/xen/xend/server/netif.py Fri Mar 27 11:07:11 2009 +0900 76.3 @@ -24,7 +24,7 @@ import os 76.4 import random 76.5 import re 76.6 76.7 -from xen.xend import XendOptions 76.8 +from xen.xend import XendOptions, sxp 76.9 from xen.xend.server.DevController import DevController 76.10 from xen.xend.XendError import VmError 76.11 from xen.xend.XendXSPolicyAdmin import XSPolicyAdminInstance 76.12 @@ -196,3 +196,23 @@ class NetifController(DevController): 76.13 result[x] = y 76.14 76.15 return result 76.16 + 76.17 + # match a VIF ID from xenstore, or a MAC address stored in the domain config 76.18 + def convertToDeviceNumber(self, devid): 76.19 + try: 76.20 + return int(devid) 76.21 + except ValueError: 76.22 + if type(devid) is not str: 76.23 + raise VmError("devid %s is wrong type" % str(devid)) 76.24 + try: 76.25 + dev = devid.split('/')[-1] 76.26 + return (int(dev)) 76.27 + except ValueError: 76.28 + devs = [d for d in self.vm.info.all_devices_sxpr() 76.29 + if d[0] == 'vif'] 76.30 + for nr in range(len(devs)): 76.31 + dev_type, dev_info = devs[nr] 76.32 + if (sxp.child_value(dev_info, 'mac').lower() == 76.33 + devid.lower()): 76.34 + return nr 76.35 + raise VmError("unknown devid %s" % str(devid))
77.1 --- a/tools/python/xen/xend/server/pciif.py Fri Mar 27 10:54:08 2009 +0900 77.2 +++ b/tools/python/xen/xend/server/pciif.py Fri Mar 27 11:07:11 2009 +0900 77.3 @@ -24,6 +24,7 @@ from xen.xend import sxp 77.4 from xen.xend import arch 77.5 from xen.xend.XendError import VmError 77.6 from xen.xend.XendLogging import log 77.7 +from xen.xend.XendConstants import * 77.8 77.9 from xen.xend.server.DevController import DevController 77.10 from xen.xend.server.DevConstants import xenbusState 77.11 @@ -74,6 +75,7 @@ class PciController(DevController): 77.12 bus = parse_hex(pci_config.get('bus', 0)) 77.13 slot = parse_hex(pci_config.get('slot', 0)) 77.14 func = parse_hex(pci_config.get('func', 0)) 77.15 + vslot = parse_hex(pci_config.get('vslot', 0)) 77.16 77.17 opts = pci_config.get('opts', '') 77.18 if len(opts) > 0: 77.19 @@ -218,7 +220,7 @@ class PciController(DevController): 77.20 try: 77.21 dev_dict['vslt'] = slot_list[i] 77.22 except IndexError: 77.23 - dev_dict['vslt'] = '0x0' 77.24 + dev_dict['vslt'] = AUTO_PHP_SLOT_STR 77.25 77.26 pci_devs.append(dev_dict) 77.27
78.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 78.2 +++ b/tools/python/xen/xend/server/udevevent.py Fri Mar 27 11:07:11 2009 +0900 78.3 @@ -0,0 +1,68 @@ 78.4 +import socket 78.5 + 78.6 +from xen.web import protocol, unix 78.7 + 78.8 +from xen.xend.XendLogging import log 78.9 +from xen.xend import XendNode 78.10 +from xen.xend import XendOptions 78.11 + 78.12 +UDEV_EVENT_PATH = '\0/org/xen/xend/udev_event' 78.13 + 78.14 +class UdevEventProtocol(protocol.Protocol): 78.15 + 78.16 + def __init__(self): 78.17 + protocol.Protocol.__init__(self) 78.18 + 78.19 + def dataReceived(self, data): 78.20 + udev_event = {} 78.21 + for entry in data.split('\0'): 78.22 + try: 78.23 + opt, val = entry.split("=") 78.24 + udev_event[opt] = val 78.25 + except (TypeError, ValueError): 78.26 + pass 78.27 + if udev_event.get('ACTION', None) is None: 78.28 + log.warn("Invalid udev event received") 78.29 + return 78.30 + 78.31 + log.debug("udev event received: %s", udev_event) 78.32 + 78.33 + self._process_event(udev_event) 78.34 + 78.35 + def _process_event(self, udev_event): 78.36 + try: 78.37 + if (udev_event.get('SUBSYSTEM', None) == 'pci'): 78.38 + pci_name = udev_event.get('PCI_SLOT_NAME', None) 78.39 + if (udev_event['ACTION'] == 'add'): 78.40 + log.info("Adding pci device %s", pci_name) 78.41 + XendNode.instance().add_PPCI(pci_name) 78.42 + elif (udev_event['ACTION'] == 'remove'): 78.43 + log.info("Removing pci device %s", pci_name) 78.44 + XendNode.instance().remove_PPCI(pci_name) 78.45 + 78.46 + elif (udev_event.get('SUBSYSTEMS', None) == 'scsi'): 78.47 + if (udev_event['ACTION'] == 'add'): 78.48 + log.info("Adding scsi device") 78.49 + XendNode.instance().add_PSCSI() 78.50 + elif (udev_event['ACTION'] == 'remove'): 78.51 + log.info("Removing scci device") 78.52 + XendNode.instance().remove_PSCSI() 78.53 + 78.54 + elif (udev_event.get('SUBSYSTEM', None) == 'net'): 78.55 + interface = udev_event.get('INTERFACE', None) 78.56 + if (udev_event['ACTION'] == 'add'): 78.57 + log.info("Adding net device %s", interface) 78.58 + XendNode.instance().add_network(interface) 78.59 + elif (udev_event['ACTION'] == 'remove'): 78.60 + log.info("Removing net device %s", interface) 78.61 + XendNode.instance().remove_network(interface) 78.62 + 78.63 + except Exception, e: 78.64 + log.warn("error while processing udev event(): %s" % str(e)) 78.65 + 78.66 + 78.67 +def listenUdevEvent(): 78.68 + xoptions = XendOptions.instance() 78.69 + if xoptions.get_xend_udev_event_server(): 78.70 + unix.UnixDgramListener(UDEV_EVENT_PATH, UdevEventProtocol) 78.71 +
79.1 --- a/tools/python/xen/xm/create.dtd Fri Mar 27 10:54:08 2009 +0900 79.2 +++ b/tools/python/xen/xm/create.dtd Fri Mar 27 11:07:11 2009 +0900 79.3 @@ -47,6 +47,7 @@ 79.4 other_config*)> 79.5 <!ATTLIST vm is_a_template CDATA #REQUIRED 79.6 auto_power_on CDATA #REQUIRED 79.7 + s3_integrity CDATA #REQUIRED 79.8 vcpus_max CDATA #REQUIRED 79.9 vcpus_at_startup CDATA #REQUIRED 79.10 actions_after_shutdown %NORMAL_EXIT; #REQUIRED
80.1 --- a/tools/python/xen/xm/create.py Fri Mar 27 10:54:08 2009 +0900 80.2 +++ b/tools/python/xen/xm/create.py Fri Mar 27 11:07:11 2009 +0900 80.3 @@ -1,4 +1,4 @@ 80.4 -#============================================================================ 80.5 +#============================================================================UTO 80.6 # This library is free software; you can redistribute it and/or 80.7 # modify it under the terms of version 2.1 of the GNU Lesser General Public 80.8 # License as published by the Free Software Foundation. 80.9 @@ -32,6 +32,7 @@ from xen.xend import PrettyPrint as SXPP 80.10 from xen.xend import osdep 80.11 import xen.xend.XendClient 80.12 from xen.xend.XendBootloader import bootloader 80.13 +from xen.xend.XendConstants import * 80.14 from xen.xend.server.DevConstants import xenbusState 80.15 from xen.util import blkif 80.16 from xen.util import vscsi_util 80.17 @@ -322,10 +323,12 @@ gopts.var('disk', val='phy:DEV,VDEV,MODE 80.18 backend driver domain to use for the disk. 80.19 The option may be repeated to add more than one disk.""") 80.20 80.21 -gopts.var('pci', val='BUS:DEV.FUNC[,msitranslate=0|1][,power_mgmt=0|1]', 80.22 +gopts.var('pci', val='BUS:DEV.FUNC[@VSLOT][,msitranslate=0|1][,power_mgmt=0|1]', 80.23 fn=append_value, default=[], 80.24 use="""Add a PCI device to a domain, using given params (in hex). 80.25 For example 'pci=c0:02.1'. 80.26 + If VSLOT is supplied the device will be inserted into that 80.27 + virtual slot in the guest, else a free slot is selected. 80.28 If msitranslate is set, MSI-INTx translation is enabled if possible. 80.29 Guest that doesn't support MSI will get IO-APIC type IRQs 80.30 translated from physical MSI, HVM only. Default is 1. 80.31 @@ -611,6 +614,10 @@ gopts.var('pci_power_mgmt', val='POWERMG 80.32 fn=set_int, default=0, 80.33 use="""Global PCI Power Management flag (0=disable;1=enable).""") 80.34 80.35 +gopts.var('xen_platform_pci', val='0|1', 80.36 + fn=set_int, default=1, 80.37 + use="Is xen_platform_pci used?") 80.38 + 80.39 def err(msg): 80.40 """Print an error to stderr and exit. 80.41 """ 80.42 @@ -692,7 +699,7 @@ def configure_pci(config_devs, vals): 80.43 """Create the config for pci devices. 80.44 """ 80.45 config_pci = [] 80.46 - for (domain, bus, slot, func, opts) in vals.pci: 80.47 + for (domain, bus, slot, func, vslot, opts) in vals.pci: 80.48 config_pci_opts = [] 80.49 d = comma_sep_kv_to_dict(opts) 80.50 80.51 @@ -703,7 +710,7 @@ def configure_pci(config_devs, vals): 80.52 config_pci_opts.append([k, d[k]]) 80.53 80.54 config_pci_bdf = ['dev', ['domain', domain], ['bus', bus], \ 80.55 - ['slot', slot], ['func', func]] 80.56 + ['slot', slot], ['func', func], ['vslot', vslot]] 80.57 map(f, d.keys()) 80.58 if len(config_pci_opts)>0: 80.59 config_pci_bdf.append(['opts', config_pci_opts]) 80.60 @@ -738,6 +745,9 @@ def configure_vscsis(config_devs, vals): 80.61 80.62 feature_host = 0 80.63 if v_dev == 'host': 80.64 + if serverType == SERVER_XEN_API: 80.65 + # TODO 80.66 + raise ValueError("SCSI devices assignment by HBA is not implemeted") 80.67 feature_host = 1 80.68 scsi_info = [] 80.69 devid = get_devid(p_hctl) 80.70 @@ -921,7 +931,7 @@ def configure_hvm(config_image, vals): 80.71 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet', 80.72 'guest_os_type', 'hap', 'opengl', 'cpuid', 'cpuid_check', 80.73 'viridian', 'xen_extended_power_mgmt', 'pci_msitranslate', 80.74 - 'vpt_align', 'pci_power_mgmt' ] 80.75 + 'vpt_align', 'pci_power_mgmt', 'xen_platform_pci' ] 80.76 80.77 for a in args: 80.78 if a in vals.__dict__ and vals.__dict__[a] is not None: 80.79 @@ -1047,16 +1057,21 @@ def preprocess_pci(vals): 80.80 r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \ 80.81 r"(?P<slot>[0-9a-fA-F]{1,2})[.,]" + \ 80.82 r"(?P<func>[0-7])" + \ 80.83 - r"(,(?P<opts>.*))?$", pci_dev_str) 80.84 + r"(@(?P<vslot>[0-9a-fA-F]))?" + \ 80.85 + r"(,(?P<opts>.*))?$", \ 80.86 + pci_dev_str) 80.87 if pci_match!=None: 80.88 pci_dev_info = pci_match.groupdict('') 80.89 if pci_dev_info['domain']=='': 80.90 pci_dev_info['domain']='0' 80.91 + if pci_dev_info['vslot']=='': 80.92 + pci_dev_info['vslot']="%02x" % AUTO_PHP_SLOT 80.93 try: 80.94 pci.append( ('0x'+pci_dev_info['domain'], \ 80.95 '0x'+pci_dev_info['bus'], \ 80.96 '0x'+pci_dev_info['slot'], \ 80.97 '0x'+pci_dev_info['func'], \ 80.98 + '0x'+pci_dev_info['vslot'], \ 80.99 pci_dev_info['opts'])) 80.100 except IndexError: 80.101 err('Error in PCI slot syntax "%s"'%(pci_dev_str))
81.1 --- a/tools/python/xen/xm/main.py Fri Mar 27 10:54:08 2009 +0900 81.2 +++ b/tools/python/xen/xm/main.py Fri Mar 27 11:07:11 2009 +0900 81.3 @@ -1351,22 +1351,8 @@ def xm_dump_core(args): 81.4 else: 81.5 filename = None 81.6 81.7 - if not live: 81.8 - ds = server.xend.domain.pause(dom, True) 81.9 - 81.10 - try: 81.11 - print "Dumping core of domain: %s ..." % str(dom) 81.12 - server.xend.domain.dump(dom, filename, live, crash) 81.13 - 81.14 - if crash: 81.15 - print "Destroying domain: %s ..." % str(dom) 81.16 - server.xend.domain.destroy(dom) 81.17 - elif reset: 81.18 - print "Resetting domain: %s ..." % str(dom) 81.19 - server.xend.domain.reset(dom) 81.20 - finally: 81.21 - if not live and not crash and not reset and ds == DOM_STATE_RUNNING: 81.22 - server.xend.domain.unpause(dom) 81.23 + print "Dumping core of domain: %s ..." % str(dom) 81.24 + server.xend.domain.dump(dom, filename, live, crash, reset) 81.25 81.26 def xm_rename(args): 81.27 arg_check(args, "rename", 2) 81.28 @@ -2231,6 +2217,33 @@ def xm_pci_list_assignable_devices(args) 81.29 print d.name, 81.30 print 81.31 81.32 +def vscsi_sort(devs): 81.33 + def sort_hctl(ds, l): 81.34 + s = [] 81.35 + for d1 in ds: 81.36 + for d2 in d1: 81.37 + v_dev = sxp.child_value(d2, 'v-dev') 81.38 + n = int(v_dev.split(':')[l]) 81.39 + try: 81.40 + j = s[n] 81.41 + except IndexError: 81.42 + j = [] 81.43 + s.extend([ [] for _ in range(len(s), n+1) ]) 81.44 + j.append(d2) 81.45 + s[n] = j 81.46 + return s 81.47 + 81.48 + for i in range(len(devs)): 81.49 + ds1 = [ devs[i][1][0][1] ] 81.50 + ds1 = sort_hctl(ds1, 3) 81.51 + ds1 = sort_hctl(ds1, 2) 81.52 + ds1 = sort_hctl(ds1, 1) 81.53 + ds2 = [] 81.54 + for d in ds1: 81.55 + ds2.extend(d) 81.56 + devs[i][1][0][1] = ds2 81.57 + return devs 81.58 + 81.59 def vscsi_convert_sxp_to_dict(dev_sxp): 81.60 dev_dict = {} 81.61 for opt_val in dev_sxp[1:]: 81.62 @@ -2271,6 +2284,9 @@ def xm_scsi_list(args): 81.63 else: 81.64 devs = server.xend.domain.getDeviceSxprs(dom, 'vscsi') 81.65 81.66 + # Sort devs by virtual HCTL. 81.67 + devs = vscsi_sort(devs) 81.68 + 81.69 if use_long: 81.70 map(PrettyPrint.prettyprint, devs) 81.71 else: 81.72 @@ -2440,7 +2456,7 @@ def parse_pci_configuration(args, state, 81.73 if len(args) == 3: 81.74 vslt = args[2] 81.75 else: 81.76 - vslt = '0x0' #chose a free virtual PCI slot 81.77 + vslt = AUTO_PHP_SLOT_STR 81.78 pci=['pci'] 81.79 pci_match = re.match(r"((?P<domain>[0-9a-fA-F]{1,4})[:,])?" + \ 81.80 r"(?P<bus>[0-9a-fA-F]{1,2})[:,]" + \ 81.81 @@ -2523,6 +2539,9 @@ def parse_scsi_configuration(p_scsi, v_h 81.82 if p_scsi is not None: 81.83 # xm scsi-attach 81.84 if v_hctl == "host": 81.85 + if serverType == SERVER_XEN_API: 81.86 + # TODO 81.87 + raise OptionError("SCSI devices assignment by HBA is not implemeted") 81.88 host_mode = 1 81.89 scsi_devices = vscsi_util.vscsi_get_scsidevices() 81.90 elif len(v_hctl.split(':')) != 4:
82.1 --- a/tools/python/xen/xm/xenapi_create.py Fri Mar 27 10:54:08 2009 +0900 82.2 +++ b/tools/python/xen/xm/xenapi_create.py Fri Mar 27 11:07:11 2009 +0900 82.3 @@ -1048,6 +1048,7 @@ class sxp2xml: 82.4 'hap', 82.5 'pci_msitranslate', 82.6 'pci_power_mgmt', 82.7 + 'xen_platform_pci', 82.8 ] 82.9 82.10 platform_configs = []
83.1 --- a/tools/xcutils/xc_save.c Fri Mar 27 10:54:08 2009 +0900 83.2 +++ b/tools/xcutils/xc_save.c Fri Mar 27 11:07:11 2009 +0900 83.3 @@ -46,97 +46,6 @@ static int compat_suspend(void) 83.4 !strncmp(ans, "done\n", 5)); 83.5 } 83.6 83.7 -static int suspend_evtchn_release(void) 83.8 -{ 83.9 - if (si.suspend_evtchn >= 0) { 83.10 - xc_evtchn_unbind(si.xce, si.suspend_evtchn); 83.11 - si.suspend_evtchn = -1; 83.12 - } 83.13 - if (si.xce >= 0) { 83.14 - xc_evtchn_close(si.xce); 83.15 - si.xce = -1; 83.16 - } 83.17 - 83.18 - return 0; 83.19 -} 83.20 - 83.21 -static int await_suspend(void) 83.22 -{ 83.23 - int rc; 83.24 - 83.25 - do { 83.26 - rc = xc_evtchn_pending(si.xce); 83.27 - if (rc < 0) { 83.28 - warnx("error polling suspend notification channel: %d", rc); 83.29 - return -1; 83.30 - } 83.31 - } while (rc != si.suspend_evtchn); 83.32 - 83.33 - /* harmless for one-off suspend */ 83.34 - if (xc_evtchn_unmask(si.xce, si.suspend_evtchn) < 0) 83.35 - warnx("failed to unmask suspend notification channel: %d", rc); 83.36 - 83.37 - return 0; 83.38 -} 83.39 - 83.40 -static int suspend_evtchn_init(int xc, int domid) 83.41 -{ 83.42 - struct xs_handle *xs; 83.43 - char path[128]; 83.44 - char *portstr; 83.45 - unsigned int plen; 83.46 - int port; 83.47 - int rc; 83.48 - 83.49 - si.xce = -1; 83.50 - si.suspend_evtchn = -1; 83.51 - 83.52 - xs = xs_daemon_open(); 83.53 - if (!xs) { 83.54 - warnx("failed to get xenstore handle"); 83.55 - return -1; 83.56 - } 83.57 - sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid); 83.58 - portstr = xs_read(xs, XBT_NULL, path, &plen); 83.59 - xs_daemon_close(xs); 83.60 - 83.61 - if (!portstr || !plen) { 83.62 - warnx("could not read suspend event channel"); 83.63 - return -1; 83.64 - } 83.65 - 83.66 - port = atoi(portstr); 83.67 - free(portstr); 83.68 - 83.69 - si.xce = xc_evtchn_open(); 83.70 - if (si.xce < 0) { 83.71 - warnx("failed to open event channel handle"); 83.72 - goto cleanup; 83.73 - } 83.74 - 83.75 - si.suspend_evtchn = xc_evtchn_bind_interdomain(si.xce, domid, port); 83.76 - if (si.suspend_evtchn < 0) { 83.77 - warnx("failed to bind suspend event channel: %d", si.suspend_evtchn); 83.78 - goto cleanup; 83.79 - } 83.80 - 83.81 - rc = xc_domain_subscribe_for_suspend(xc, domid, port); 83.82 - if (rc < 0) { 83.83 - warnx("failed to subscribe to domain: %d", rc); 83.84 - goto cleanup; 83.85 - } 83.86 - 83.87 - /* event channel is pending immediately after binding */ 83.88 - await_suspend(); 83.89 - 83.90 - return 0; 83.91 - 83.92 - cleanup: 83.93 - suspend_evtchn_release(); 83.94 - 83.95 - return -1; 83.96 -} 83.97 - 83.98 /** 83.99 * Issue a suspend request to a dedicated event channel in the guest, and 83.100 * receive the acknowledgement from the subscribe event channel. */ 83.101 @@ -150,7 +59,7 @@ static int evtchn_suspend(void) 83.102 return 0; 83.103 } 83.104 83.105 - if (await_suspend() < 0) { 83.106 + if (xc_await_suspend(si.xce, si.suspend_evtchn) < 0) { 83.107 warnx("suspend failed"); 83.108 return 0; 83.109 } 83.110 @@ -303,12 +212,11 @@ static void *init_qemu_maps(int domid, u 83.111 return seg; 83.112 } 83.113 83.114 - 83.115 int 83.116 main(int argc, char **argv) 83.117 { 83.118 unsigned int maxit, max_f; 83.119 - int io_fd, ret; 83.120 + int io_fd, ret, port; 83.121 83.122 if (argc != 6) 83.123 errx(1, "usage: %s iofd domid maxit maxf flags", argv[0]); 83.124 @@ -323,14 +231,37 @@ main(int argc, char **argv) 83.125 max_f = atoi(argv[4]); 83.126 si.flags = atoi(argv[5]); 83.127 83.128 - if (suspend_evtchn_init(si.xc_fd, si.domid) < 0) 83.129 - warnx("suspend event channel initialization failed, using slow path"); 83.130 + si.suspend_evtchn = si.xce = -1; 83.131 + 83.132 + si.xce = xc_evtchn_open(); 83.133 + if (si.xce < 0) 83.134 + warnx("failed to open event channel handle"); 83.135 + 83.136 + if (si.xce > 0) 83.137 + { 83.138 + port = xs_suspend_evtchn_port(si.domid); 83.139 83.140 + if (port < 0) 83.141 + warnx("faield to get the suspend evtchn port\n"); 83.142 + else 83.143 + { 83.144 + si.suspend_evtchn = 83.145 + xc_suspend_evtchn_init(si.xc_fd, si.xce, si.domid, port); 83.146 + 83.147 + if (si.suspend_evtchn < 0) 83.148 + warnx("suspend event channel initialization failed" 83.149 + "using slow path"); 83.150 + } 83.151 + } 83.152 ret = xc_domain_save(si.xc_fd, io_fd, si.domid, maxit, max_f, si.flags, 83.153 &suspend, !!(si.flags & XCFLAGS_HVM), 83.154 &init_qemu_maps, &qemu_flip_buffer); 83.155 83.156 - suspend_evtchn_release(); 83.157 + if (si.suspend_evtchn > 0) 83.158 + xc_suspend_evtchn_release(si.xce, si.suspend_evtchn); 83.159 + 83.160 + if (si.xce > 0) 83.161 + xc_evtchn_close(si.xce); 83.162 83.163 xc_interface_close(si.xc_fd); 83.164
84.1 --- a/tools/xenstore/Makefile Fri Mar 27 10:54:08 2009 +0900 84.2 +++ b/tools/xenstore/Makefile Fri Mar 27 11:07:11 2009 +0900 84.3 @@ -97,9 +97,9 @@ install: all 84.4 $(INSTALL_DIR) $(DESTDIR)$(INCLUDEDIR) 84.5 $(INSTALL_PROG) xenstored $(DESTDIR)$(SBINDIR) 84.6 $(INSTALL_PROG) xenstore-control $(DESTDIR)$(BINDIR) 84.7 - $(INSTALL_PROG) xenstore $(DESTDIR)/usr/bin 84.8 + $(INSTALL_PROG) xenstore $(DESTDIR)$(BINDIR) 84.9 set -e ; for c in $(CLIENTS) ; do \ 84.10 - ln -f $(DESTDIR)/usr/bin/xenstore $(DESTDIR)/usr/bin/$${c} ; \ 84.11 + ln -f $(DESTDIR)$(BINDIR)/xenstore $(DESTDIR)$(BINDIR)/$${c} ; \ 84.12 done 84.13 $(INSTALL_DIR) $(DESTDIR)$(LIBDIR) 84.14 $(INSTALL_PROG) libxenstore.so.$(MAJOR).$(MINOR) $(DESTDIR)$(LIBDIR)
85.1 --- a/tools/xenstore/xs.c Fri Mar 27 10:54:08 2009 +0900 85.2 +++ b/tools/xenstore/xs.c Fri Mar 27 11:07:11 2009 +0900 85.3 @@ -802,6 +802,31 @@ bool xs_is_domain_introduced(struct xs_h 85.4 return rc; 85.5 } 85.6 85.7 +int xs_suspend_evtchn_port(int domid) 85.8 +{ 85.9 + char path[128]; 85.10 + char *portstr; 85.11 + int port; 85.12 + unsigned int plen; 85.13 + struct xs_handle *xs; 85.14 + 85.15 + xs = xs_daemon_open(); 85.16 + if (!xs) 85.17 + return -1; 85.18 + 85.19 + sprintf(path, "/local/domain/%d/device/suspend/event-channel", domid); 85.20 + portstr = xs_read(xs, XBT_NULL, path, &plen); 85.21 + xs_daemon_close(xs); 85.22 + 85.23 + if (!portstr || !plen) 85.24 + return -1; 85.25 + 85.26 + port = atoi(portstr); 85.27 + free(portstr); 85.28 + 85.29 + return port; 85.30 +} 85.31 + 85.32 /* Only useful for DEBUG versions */ 85.33 char *xs_debug_command(struct xs_handle *h, const char *cmd, 85.34 void *data, unsigned int len)
86.1 --- a/tools/xenstore/xs.h Fri Mar 27 10:54:08 2009 +0900 86.2 +++ b/tools/xenstore/xs.h Fri Mar 27 11:07:11 2009 +0900 86.3 @@ -163,6 +163,7 @@ bool xs_is_domain_introduced(struct xs_h 86.4 char *xs_debug_command(struct xs_handle *h, const char *cmd, 86.5 void *data, unsigned int len); 86.6 86.7 +int xs_suspend_evtchn_port(int domid); 86.8 #endif /* _XS_H */ 86.9 86.10 /*
87.1 --- a/tools/xentrace/formats Fri Mar 27 10:54:08 2009 +0900 87.2 +++ b/tools/xentrace/formats Fri Mar 27 11:07:11 2009 +0900 87.3 @@ -118,5 +118,5 @@ 0x0040f00f CPU%(cpu)d %(tsc)d (+%(relt 87.4 0x0040f10f CPU%(cpu)d %(tsc)d (+%(reltsc)8d) shadow_emulate_resync_only [ gfn = 0x%(1)16x ] 87.5 87.6 0x00801001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_freq_change [ %(1)dMHz -> %(2)dMHz ] 87.7 -0x00802001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_idle_entry [ C0 -> C%(1)d ] 87.8 -0x00802002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_idle_exit [ C%(1)d -> C0 ] 87.9 +0x00802001 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_idle_entry [ C0 -> C%(1)d, acpi_pm_tick = %(2)d ] 87.10 +0x00802002 CPU%(cpu)d %(tsc)d (+%(reltsc)8d) cpu_idle_exit [ C%(1)d -> C0, acpi_pm_tick = %(2)d ]
88.1 --- a/tools/xentrace/xentrace_format Fri Mar 27 10:54:08 2009 +0900 88.2 +++ b/tools/xentrace/xentrace_format Fri Mar 27 11:07:11 2009 +0900 88.3 @@ -81,7 +81,11 @@ signal.signal(signal.SIGINT, sighand) 88.4 88.5 interrupted = 0 88.6 88.7 -defs = read_defs(arg[0]) 88.8 +try: 88.9 + defs = read_defs(arg[0]) 88.10 +except IOError, exn: 88.11 + print exn 88.12 + sys.exit(1) 88.13 88.14 # structure of trace record (as output by xentrace): 88.15 # HDR(I) {TSC(Q)} D1(I) D2(I) D3(I) D4(I) D5(I) D6(I) D7(I)
89.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 89.2 +++ b/unmodified_drivers/linux-2.6/compat-include/linux/scatterlist.h Fri Mar 27 11:07:11 2009 +0900 89.3 @@ -0,0 +1,10 @@ 89.4 +#ifndef _LINUX_SCATTERLIST_H 89.5 +#define _LINUX_SCATTERLIST_H 89.6 + 89.7 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,12) 89.8 +#error "This version of Linux should not need compat linux/scatterlist.h" 89.9 +#endif 89.10 + 89.11 +#include <asm/scatterlist.h> 89.12 + 89.13 +#endif /* _LINUX_SCATTERLIST_H */
90.1 --- a/xen/arch/ia64/xen/hypercall.c Fri Mar 27 10:54:08 2009 +0900 90.2 +++ b/xen/arch/ia64/xen/hypercall.c Fri Mar 27 11:07:11 2009 +0900 90.3 @@ -674,6 +674,28 @@ long do_physdev_op(int cmd, XEN_GUEST_HA 90.4 break; 90.5 } 90.6 90.7 + case PHYSDEVOP_manage_pci_add_ext: { 90.8 + struct physdev_manage_pci_ext manage_pci_ext; 90.9 + struct pci_dev_info pdev_info; 90.10 + 90.11 + ret = -EPERM; 90.12 + if ( !IS_PRIV(current->domain) ) 90.13 + break; 90.14 + 90.15 + ret = -EFAULT; 90.16 + if ( copy_from_guest(&manage_pci_ext, arg, 1) != 0 ) 90.17 + break; 90.18 + 90.19 + pdev_info.is_extfn = manage_pci_ext.is_extfn; 90.20 + pdev_info.is_virtfn = manage_pci_ext.is_virtfn; 90.21 + pdev_info.physfn.bus = manage_pci_ext.physfn.bus; 90.22 + pdev_info.physfn.devfn = manage_pci_ext.physfn.devfn; 90.23 + ret = pci_add_device_ext(manage_pci_ext.bus, 90.24 + manage_pci_ext.devfn, 90.25 + &pdev_info); 90.26 + break; 90.27 + } 90.28 + 90.29 default: 90.30 ret = -ENOSYS; 90.31 printk("not implemented do_physdev_op: %d\n", cmd);
91.1 --- a/xen/arch/x86/acpi/cpu_idle.c Fri Mar 27 10:54:08 2009 +0900 91.2 +++ b/xen/arch/x86/acpi/cpu_idle.c Fri Mar 27 11:07:11 2009 +0900 91.3 @@ -167,25 +167,6 @@ static void acpi_idle_do_entry(struct ac 91.4 } 91.5 } 91.6 91.7 -static inline void acpi_idle_update_bm_rld(struct acpi_processor_power *power, 91.8 - struct acpi_processor_cx *target) 91.9 -{ 91.10 - if ( !power->flags.bm_check ) 91.11 - return; 91.12 - 91.13 - if ( power->flags.bm_rld_set && target->type != ACPI_STATE_C3 ) 91.14 - { 91.15 - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 0); 91.16 - power->flags.bm_rld_set = 0; 91.17 - } 91.18 - 91.19 - if ( !power->flags.bm_rld_set && target->type == ACPI_STATE_C3 ) 91.20 - { 91.21 - acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); 91.22 - power->flags.bm_rld_set = 1; 91.23 - } 91.24 -} 91.25 - 91.26 static int acpi_idle_bm_check(void) 91.27 { 91.28 u32 bm_status = 0; 91.29 @@ -239,15 +220,9 @@ static void acpi_processor_idle(void) 91.30 if ( !cx ) 91.31 { 91.32 if ( pm_idle_save ) 91.33 - { 91.34 - printk(XENLOG_DEBUG "call pm_idle_save()\n"); 91.35 pm_idle_save(); 91.36 - } 91.37 else 91.38 - { 91.39 - printk(XENLOG_DEBUG "call acpi_safe_halt()\n"); 91.40 acpi_safe_halt(); 91.41 - } 91.42 return; 91.43 } 91.44 91.45 @@ -258,24 +233,22 @@ static void acpi_processor_idle(void) 91.46 * ------ 91.47 * Invoke the current Cx state to put the processor to sleep. 91.48 */ 91.49 - acpi_idle_update_bm_rld(power, cx); 91.50 - 91.51 switch ( cx->type ) 91.52 { 91.53 case ACPI_STATE_C1: 91.54 case ACPI_STATE_C2: 91.55 if ( cx->type == ACPI_STATE_C1 || local_apic_timer_c2_ok ) 91.56 { 91.57 - /* Trace cpu idle entry */ 91.58 - TRACE_1D(TRC_PM_IDLE_ENTRY, cx->idx); 91.59 /* Get start time (ticks) */ 91.60 t1 = inl(pmtmr_ioport); 91.61 + /* Trace cpu idle entry */ 91.62 + TRACE_2D(TRC_PM_IDLE_ENTRY, cx->idx, t1); 91.63 /* Invoke C2 */ 91.64 acpi_idle_do_entry(cx); 91.65 /* Get end time (ticks) */ 91.66 t2 = inl(pmtmr_ioport); 91.67 /* Trace cpu idle exit */ 91.68 - TRACE_1D(TRC_PM_IDLE_EXIT, cx->idx); 91.69 + TRACE_2D(TRC_PM_IDLE_EXIT, cx->idx, t2); 91.70 91.71 /* Re-enable interrupts */ 91.72 local_irq_enable(); 91.73 @@ -314,8 +287,6 @@ static void acpi_processor_idle(void) 91.74 ACPI_FLUSH_CPU_CACHE(); 91.75 } 91.76 91.77 - /* Trace cpu idle entry */ 91.78 - TRACE_1D(TRC_PM_IDLE_ENTRY, cx->idx); 91.79 /* 91.80 * Before invoking C3, be aware that TSC/APIC timer may be 91.81 * stopped by H/W. Without carefully handling of TSC/APIC stop issues, 91.82 @@ -326,6 +297,8 @@ static void acpi_processor_idle(void) 91.83 91.84 /* Get start time (ticks) */ 91.85 t1 = inl(pmtmr_ioport); 91.86 + /* Trace cpu idle entry */ 91.87 + TRACE_2D(TRC_PM_IDLE_ENTRY, cx->idx, t1); 91.88 /* Invoke C3 */ 91.89 acpi_idle_do_entry(cx); 91.90 /* Get end time (ticks) */ 91.91 @@ -334,7 +307,7 @@ static void acpi_processor_idle(void) 91.92 /* recovering TSC */ 91.93 cstate_restore_tsc(); 91.94 /* Trace cpu idle exit */ 91.95 - TRACE_1D(TRC_PM_IDLE_EXIT, cx->idx); 91.96 + TRACE_2D(TRC_PM_IDLE_EXIT, cx->idx, t2); 91.97 91.98 if ( power->flags.bm_check && power->flags.bm_control ) 91.99 { 91.100 @@ -491,12 +464,22 @@ static void acpi_processor_power_init_bm 91.101 else if ( c->x86_vendor == X86_VENDOR_INTEL ) 91.102 { 91.103 /* 91.104 - * Today all CPUs that support C3 share cache. 91.105 - * TBD: This needs to look at cache shared map, once 91.106 - * multi-core detection patch makes to the base. 91.107 + * Today all MP CPUs that support C3 share cache. 91.108 + * And caches should not be flushed by software while 91.109 + * entering C3 type state. 91.110 */ 91.111 flags->bm_check = 1; 91.112 } 91.113 + 91.114 + /* 91.115 + * On all recent platforms, ARB_DISABLE is a nop. 91.116 + * So, set bm_control to zero to indicate that ARB_DISABLE 91.117 + * is not required while entering C3 type state on 91.118 + * P4, Core and beyond CPUs 91.119 + */ 91.120 + if ( c->x86_vendor == X86_VENDOR_INTEL && 91.121 + (c->x86 > 0x6 || (c->x86 == 6 && c->x86_model >= 14)) ) 91.122 + flags->bm_control = 0; 91.123 } 91.124 91.125 #define VENDOR_INTEL (1) 91.126 @@ -504,7 +487,8 @@ static void acpi_processor_power_init_bm 91.127 91.128 static int check_cx(struct acpi_processor_power *power, xen_processor_cx_t *cx) 91.129 { 91.130 - static int bm_check_flag; 91.131 + static int bm_check_flag = -1; 91.132 + static int bm_control_flag = -1; 91.133 91.134 switch ( cx->reg.space_id ) 91.135 { 91.136 @@ -550,15 +534,17 @@ static int check_cx(struct acpi_processo 91.137 } 91.138 91.139 /* All the logic here assumes flags.bm_check is same across all CPUs */ 91.140 - if ( !bm_check_flag ) 91.141 + if ( bm_check_flag == -1 ) 91.142 { 91.143 /* Determine whether bm_check is needed based on CPU */ 91.144 acpi_processor_power_init_bm_check(&(power->flags)); 91.145 bm_check_flag = power->flags.bm_check; 91.146 + bm_control_flag = power->flags.bm_control; 91.147 } 91.148 else 91.149 { 91.150 power->flags.bm_check = bm_check_flag; 91.151 + power->flags.bm_control = bm_control_flag; 91.152 } 91.153 91.154 if ( power->flags.bm_check ) 91.155 @@ -579,6 +565,15 @@ static int check_cx(struct acpi_processo 91.156 "C3 support without BM control\n")); 91.157 } 91.158 } 91.159 + /* 91.160 + * On older chipsets, BM_RLD needs to be set 91.161 + * in order for Bus Master activity to wake the 91.162 + * system from C3. Newer chipsets handle DMA 91.163 + * during C3 automatically and BM_RLD is a NOP. 91.164 + * In either case, the proper way to 91.165 + * handle BM_RLD is to set it and leave it set. 91.166 + */ 91.167 + acpi_set_register(ACPI_BITREG_BUS_MASTER_RLD, 1); 91.168 } 91.169 else 91.170 {
92.1 --- a/xen/arch/x86/acpi/cpufreq/cpufreq.c Fri Mar 27 10:54:08 2009 +0900 92.2 +++ b/xen/arch/x86/acpi/cpufreq/cpufreq.c Fri Mar 27 11:07:11 2009 +0900 92.3 @@ -232,6 +232,26 @@ static u32 get_cur_val(cpumask_t mask) 92.4 return cmd.val; 92.5 } 92.6 92.7 +struct perf_pair { 92.8 + union { 92.9 + struct { 92.10 + uint32_t lo; 92.11 + uint32_t hi; 92.12 + } split; 92.13 + uint64_t whole; 92.14 + } aperf, mperf; 92.15 +}; 92.16 +static DEFINE_PER_CPU(struct perf_pair, gov_perf_pair); 92.17 +static DEFINE_PER_CPU(struct perf_pair, usr_perf_pair); 92.18 + 92.19 +static void read_measured_perf_ctrs(void *_readin) 92.20 +{ 92.21 + struct perf_pair *readin = _readin; 92.22 + 92.23 + rdmsr(MSR_IA32_APERF, readin->aperf.split.lo, readin->aperf.split.hi); 92.24 + rdmsr(MSR_IA32_MPERF, readin->mperf.split.lo, readin->mperf.split.hi); 92.25 +} 92.26 + 92.27 /* 92.28 * Return the measured active (C0) frequency on this CPU since last call 92.29 * to this function. 92.30 @@ -245,40 +265,13 @@ static u32 get_cur_val(cpumask_t mask) 92.31 * Only IA32_APERF/IA32_MPERF ratio is architecturally defined and 92.32 * no meaning should be associated with absolute values of these MSRs. 92.33 */ 92.34 -static void __get_measured_perf(void *perf_percent) 92.35 +static unsigned int get_measured_perf(unsigned int cpu, unsigned int flag) 92.36 { 92.37 - unsigned int *ratio = perf_percent; 92.38 - union { 92.39 - struct { 92.40 - uint32_t lo; 92.41 - uint32_t hi; 92.42 - } split; 92.43 - uint64_t whole; 92.44 - } aperf_cur, mperf_cur; 92.45 - 92.46 - rdmsr(MSR_IA32_APERF, aperf_cur.split.lo, aperf_cur.split.hi); 92.47 - rdmsr(MSR_IA32_MPERF, mperf_cur.split.lo, mperf_cur.split.hi); 92.48 - 92.49 - wrmsr(MSR_IA32_APERF, 0,0); 92.50 - wrmsr(MSR_IA32_MPERF, 0,0); 92.51 - 92.52 - if (unlikely(((unsigned long)(-1) / 100) < aperf_cur.whole)) { 92.53 - int shift_count = 7; 92.54 - aperf_cur.whole >>= shift_count; 92.55 - mperf_cur.whole >>= shift_count; 92.56 - } 92.57 - 92.58 - if (aperf_cur.whole && mperf_cur.whole) 92.59 - *ratio = (aperf_cur.whole * 100) / mperf_cur.whole; 92.60 - else 92.61 - *ratio = 0; 92.62 -} 92.63 - 92.64 -static unsigned int get_measured_perf(unsigned int cpu) 92.65 -{ 92.66 - struct cpufreq_policy *policy; 92.67 + struct cpufreq_policy *policy; 92.68 + struct perf_pair readin, cur, *saved; 92.69 unsigned int perf_percent; 92.70 cpumask_t cpumask; 92.71 + unsigned int retval; 92.72 92.73 if (!cpu_online(cpu)) 92.74 return 0; 92.75 @@ -287,16 +280,80 @@ static unsigned int get_measured_perf(un 92.76 if (!policy) 92.77 return 0; 92.78 92.79 - /* Usually we take the short path (no IPI) for the sake of performance. */ 92.80 + switch (flag) 92.81 + { 92.82 + case GOV_GETAVG: 92.83 + { 92.84 + saved = &per_cpu(gov_perf_pair, cpu); 92.85 + break; 92.86 + } 92.87 + case USR_GETAVG: 92.88 + { 92.89 + saved = &per_cpu(usr_perf_pair, cpu); 92.90 + break; 92.91 + } 92.92 + default: 92.93 + return 0; 92.94 + } 92.95 + 92.96 if (cpu == smp_processor_id()) { 92.97 - __get_measured_perf((void *)&perf_percent); 92.98 + read_measured_perf_ctrs((void *)&readin); 92.99 } else { 92.100 cpumask = cpumask_of_cpu(cpu); 92.101 - on_selected_cpus(cpumask, __get_measured_perf, 92.102 - (void *)&perf_percent,0,1); 92.103 + on_selected_cpus(cpumask, read_measured_perf_ctrs, 92.104 + (void *)&readin, 0, 1); 92.105 + } 92.106 + 92.107 + cur.aperf.whole = readin.aperf.whole - saved->aperf.whole; 92.108 + cur.mperf.whole = readin.mperf.whole - saved->mperf.whole; 92.109 + saved->aperf.whole = readin.aperf.whole; 92.110 + saved->mperf.whole = readin.mperf.whole; 92.111 + 92.112 +#ifdef __i386__ 92.113 + /* 92.114 + * We dont want to do 64 bit divide with 32 bit kernel 92.115 + * Get an approximate value. Return failure in case we cannot get 92.116 + * an approximate value. 92.117 + */ 92.118 + if (unlikely(cur.aperf.split.hi || cur.mperf.split.hi)) { 92.119 + int shift_count; 92.120 + uint32_t h; 92.121 + 92.122 + h = max_t(uint32_t, cur.aperf.split.hi, cur.mperf.split.hi); 92.123 + shift_count = fls(h); 92.124 + 92.125 + cur.aperf.whole >>= shift_count; 92.126 + cur.mperf.whole >>= shift_count; 92.127 } 92.128 92.129 - return drv_data[cpu]->max_freq * perf_percent / 100; 92.130 + if (((unsigned long)(-1) / 100) < cur.aperf.split.lo) { 92.131 + int shift_count = 7; 92.132 + cur.aperf.split.lo >>= shift_count; 92.133 + cur.mperf.split.lo >>= shift_count; 92.134 + } 92.135 + 92.136 + if (cur.aperf.split.lo && cur.mperf.split.lo) 92.137 + perf_percent = (cur.aperf.split.lo * 100) / cur.mperf.split.lo; 92.138 + else 92.139 + perf_percent = 0; 92.140 + 92.141 +#else 92.142 + if (unlikely(((unsigned long)(-1) / 100) < cur.aperf.whole)) { 92.143 + int shift_count = 7; 92.144 + cur.aperf.whole >>= shift_count; 92.145 + cur.mperf.whole >>= shift_count; 92.146 + } 92.147 + 92.148 + if (cur.aperf.whole && cur.mperf.whole) 92.149 + perf_percent = (cur.aperf.whole * 100) / cur.mperf.whole; 92.150 + else 92.151 + perf_percent = 0; 92.152 + 92.153 +#endif 92.154 + 92.155 + retval = drv_data[policy->cpu]->max_freq * perf_percent / 100; 92.156 + 92.157 + return retval; 92.158 } 92.159 92.160 static unsigned int get_cur_freq_on_cpu(unsigned int cpu)
93.1 --- a/xen/arch/x86/acpi/power.c Fri Mar 27 10:54:08 2009 +0900 93.2 +++ b/xen/arch/x86/acpi/power.c Fri Mar 27 11:07:11 2009 +0900 93.3 @@ -44,16 +44,16 @@ void do_suspend_lowlevel(void); 93.4 93.5 static int device_power_down(void) 93.6 { 93.7 - iommu_suspend(); 93.8 - 93.9 console_suspend(); 93.10 93.11 time_suspend(); 93.12 93.13 i8259A_suspend(); 93.14 - 93.15 + 93.16 ioapic_suspend(); 93.17 - 93.18 + 93.19 + iommu_suspend(); 93.20 + 93.21 lapic_suspend(); 93.22 93.23 return 0; 93.24 @@ -62,16 +62,16 @@ static int device_power_down(void) 93.25 static void device_power_up(void) 93.26 { 93.27 lapic_resume(); 93.28 - 93.29 + 93.30 + iommu_resume(); 93.31 + 93.32 ioapic_resume(); 93.33 93.34 i8259A_resume(); 93.35 - 93.36 + 93.37 time_resume(); 93.38 93.39 console_resume(); 93.40 - 93.41 - iommu_resume(); 93.42 } 93.43 93.44 static void freeze_domains(void)
94.1 --- a/xen/arch/x86/acpi/suspend.c Fri Mar 27 10:54:08 2009 +0900 94.2 +++ b/xen/arch/x86/acpi/suspend.c Fri Mar 27 11:07:11 2009 +0900 94.3 @@ -31,13 +31,9 @@ void save_rest_processor_state(void) 94.4 94.5 void restore_rest_processor_state(void) 94.6 { 94.7 - int cpu = smp_processor_id(); 94.8 - struct tss_struct *t = &init_tss[cpu]; 94.9 struct vcpu *v = current; 94.10 94.11 - /* Rewriting the TSS desc is necessary to clear the Busy flag. */ 94.12 - set_tss_desc(cpu, t); 94.13 - load_TR(cpu); 94.14 + load_TR(); 94.15 94.16 #if defined(CONFIG_X86_64) 94.17 /* Recover syscall MSRs */ 94.18 @@ -47,7 +43,7 @@ void restore_rest_processor_state(void) 94.19 wrmsr(MSR_SYSCALL_MASK, EF_VM|EF_RF|EF_NT|EF_DF|EF_IE|EF_TF, 0U); 94.20 #else /* !defined(CONFIG_X86_64) */ 94.21 if ( supervisor_mode_kernel && cpu_has_sep ) 94.22 - wrmsr(MSR_IA32_SYSENTER_ESP, &t->esp1, 0); 94.23 + wrmsr(MSR_IA32_SYSENTER_ESP, &init_tss[smp_processor_id()].esp1, 0); 94.24 #endif 94.25 94.26 /* Maybe load the debug registers. */
95.1 --- a/xen/arch/x86/boot/build32.mk Fri Mar 27 10:54:08 2009 +0900 95.2 +++ b/xen/arch/x86/boot/build32.mk Fri Mar 27 11:07:11 2009 +0900 95.3 @@ -10,8 +10,9 @@ include $(XEN_ROOT)/Config.mk 95.4 95.5 CFLAGS += -Werror -fno-builtin -msoft-float 95.6 95.7 +# NB. awk invocation is a portable alternative to 'head -n -1' 95.8 %.S: %.bin 95.9 - (od -v -t x $< | head -n -1 | \ 95.10 + (od -v -t x $< | awk 'NR > 1 {print s} {s=$$0}' | \ 95.11 sed 's/ /,0x/g' | sed 's/^[0-9]*,/ .long /') >$@ 95.12 95.13 %.bin: %.lnk
96.1 --- a/xen/arch/x86/cpu/common.c Fri Mar 27 10:54:08 2009 +0900 96.2 +++ b/xen/arch/x86/cpu/common.c Fri Mar 27 11:07:11 2009 +0900 96.3 @@ -614,8 +614,7 @@ void __cpuinit cpu_init(void) 96.4 BUG_ON((get_stack_bottom() & 15) != 0); 96.5 t->rsp0 = get_stack_bottom(); 96.6 #endif 96.7 - set_tss_desc(cpu,t); 96.8 - load_TR(cpu); 96.9 + load_TR(); 96.10 asm volatile ( "lldt %%ax" : : "a" (0) ); 96.11 96.12 /* Clear all 6 debug registers: */
97.1 --- a/xen/arch/x86/cpu/mcheck/Makefile Fri Mar 27 10:54:08 2009 +0900 97.2 +++ b/xen/arch/x86/cpu/mcheck/Makefile Fri Mar 27 11:07:11 2009 +0900 97.3 @@ -2,6 +2,7 @@ obj-y += amd_nonfatal.o 97.4 obj-y += k7.o 97.5 obj-y += amd_k8.o 97.6 obj-y += amd_f10.o 97.7 +obj-y += mctelem.o 97.8 obj-y += mce.o 97.9 obj-y += mce_intel.o 97.10 obj-y += non-fatal.o
98.1 --- a/xen/arch/x86/cpu/mcheck/amd_f10.c Fri Mar 27 10:54:08 2009 +0900 98.2 +++ b/xen/arch/x86/cpu/mcheck/amd_f10.c Fri Mar 27 11:07:11 2009 +0900 98.3 @@ -49,20 +49,21 @@ 98.4 #include "x86_mca.h" 98.5 98.6 98.7 -static int amd_f10_handler(struct mc_info *mi, uint16_t bank, uint64_t status) 98.8 +static enum mca_extinfo 98.9 +amd_f10_handler(struct mc_info *mi, uint16_t bank, uint64_t status) 98.10 { 98.11 struct mcinfo_extended mc_ext; 98.12 98.13 /* Family 0x10 introduced additional MSR that belong to the 98.14 * northbridge bank (4). */ 98.15 - if (bank != 4) 98.16 - return 0; 98.17 + if (mi == NULL || bank != 4) 98.18 + return MCA_EXTINFO_IGNORED; 98.19 98.20 if (!(status & MCi_STATUS_VAL)) 98.21 - return 0; 98.22 + return MCA_EXTINFO_IGNORED; 98.23 98.24 if (!(status & MCi_STATUS_MISCV)) 98.25 - return 0; 98.26 + return MCA_EXTINFO_IGNORED; 98.27 98.28 memset(&mc_ext, 0, sizeof(mc_ext)); 98.29 mc_ext.common.type = MC_TYPE_EXTENDED; 98.30 @@ -73,28 +74,30 @@ static int amd_f10_handler(struct mc_inf 98.31 mc_ext.mc_msr[1].reg = MSR_F10_MC4_MISC2; 98.32 mc_ext.mc_msr[2].reg = MSR_F10_MC4_MISC3; 98.33 98.34 - rdmsrl(MSR_F10_MC4_MISC1, mc_ext.mc_msr[0].value); 98.35 - rdmsrl(MSR_F10_MC4_MISC2, mc_ext.mc_msr[1].value); 98.36 - rdmsrl(MSR_F10_MC4_MISC3, mc_ext.mc_msr[2].value); 98.37 + mca_rdmsrl(MSR_F10_MC4_MISC1, mc_ext.mc_msr[0].value); 98.38 + mca_rdmsrl(MSR_F10_MC4_MISC2, mc_ext.mc_msr[1].value); 98.39 + mca_rdmsrl(MSR_F10_MC4_MISC3, mc_ext.mc_msr[2].value); 98.40 98.41 x86_mcinfo_add(mi, &mc_ext); 98.42 - return 1; 98.43 + return MCA_EXTINFO_LOCAL; 98.44 } 98.45 98.46 98.47 extern void k8_machine_check(struct cpu_user_regs *regs, long error_code); 98.48 98.49 /* AMD Family10 machine check */ 98.50 -void amd_f10_mcheck_init(struct cpuinfo_x86 *c) 98.51 +int amd_f10_mcheck_init(struct cpuinfo_x86 *c) 98.52 { 98.53 uint64_t value; 98.54 uint32_t i; 98.55 int cpu_nr; 98.56 98.57 - machine_check_vector = k8_machine_check; 98.58 - mc_callback_bank_extended = amd_f10_handler; 98.59 + if (!cpu_has(c, X86_FEATURE_MCA)) 98.60 + return 0; 98.61 + 98.62 + x86_mce_vector_register(k8_machine_check); 98.63 + x86_mce_callback_register(amd_f10_handler); 98.64 cpu_nr = smp_processor_id(); 98.65 - wmb(); 98.66 98.67 rdmsrl(MSR_IA32_MCG_CAP, value); 98.68 if (value & MCG_CTL_P) /* Control register present ? */ 98.69 @@ -104,18 +107,9 @@ void amd_f10_mcheck_init(struct cpuinfo_ 98.70 for (i = 0; i < nr_mce_banks; i++) { 98.71 switch (i) { 98.72 case 4: /* Northbridge */ 98.73 - /* Enable error reporting of all errors, 98.74 - * enable error checking and 98.75 - * disable sync flooding */ 98.76 - wrmsrl(MSR_IA32_MC4_CTL, 0x02c3c008ffffffffULL); 98.77 + /* Enable error reporting of all errors */ 98.78 + wrmsrl(MSR_IA32_MC4_CTL, 0xffffffffffffffffULL); 98.79 wrmsrl(MSR_IA32_MC4_STATUS, 0x0ULL); 98.80 - 98.81 - /* XXX: We should write the value 0x1087821UL into 98.82 - * to register F3x180 here, which sits in 98.83 - * the PCI extended configuration space. 98.84 - * Since this is not possible here, we can only hope, 98.85 - * Dom0 is doing that. 98.86 - */ 98.87 break; 98.88 98.89 default: 98.90 @@ -128,4 +122,5 @@ void amd_f10_mcheck_init(struct cpuinfo_ 98.91 98.92 set_in_cr4(X86_CR4_MCE); 98.93 printk("CPU%i: AMD Family10h machine check reporting enabled.\n", cpu_nr); 98.94 + return 1; 98.95 }
99.1 --- a/xen/arch/x86/cpu/mcheck/amd_k8.c Fri Mar 27 10:54:08 2009 +0900 99.2 +++ b/xen/arch/x86/cpu/mcheck/amd_k8.c Fri Mar 27 11:07:11 2009 +0900 99.3 @@ -67,234 +67,27 @@ 99.4 #include <asm/msr.h> 99.5 99.6 #include "mce.h" 99.7 -#include "x86_mca.h" 99.8 99.9 99.10 /* Machine Check Handler for AMD K8 family series */ 99.11 void k8_machine_check(struct cpu_user_regs *regs, long error_code) 99.12 { 99.13 - struct vcpu *vcpu = current; 99.14 - struct domain *curdom; 99.15 - struct mc_info *mc_data; 99.16 - struct mcinfo_global mc_global; 99.17 - struct mcinfo_bank mc_info; 99.18 - uint64_t status, addrv, miscv, uc; 99.19 - uint32_t i; 99.20 - unsigned int cpu_nr; 99.21 - uint32_t xen_impacted = 0; 99.22 -#define DOM_NORMAL 0 99.23 -#define DOM0_TRAP 1 99.24 -#define DOMU_TRAP 2 99.25 -#define DOMU_KILLED 4 99.26 - uint32_t dom_state = DOM_NORMAL; 99.27 - 99.28 - /* This handler runs as interrupt gate. So IPIs from the 99.29 - * polling service routine are defered until we finished. 99.30 - */ 99.31 - 99.32 - /* Disable interrupts for the _vcpu_. It may not re-scheduled to 99.33 - * an other physical CPU or the impacted process in the guest 99.34 - * continues running with corrupted data, otherwise. */ 99.35 - vcpu_schedule_lock_irq(vcpu); 99.36 - 99.37 - mc_data = x86_mcinfo_getptr(); 99.38 - cpu_nr = smp_processor_id(); 99.39 - BUG_ON(cpu_nr != vcpu->processor); 99.40 - 99.41 - curdom = vcpu->domain; 99.42 - 99.43 - memset(&mc_global, 0, sizeof(mc_global)); 99.44 - mc_global.common.type = MC_TYPE_GLOBAL; 99.45 - mc_global.common.size = sizeof(mc_global); 99.46 - 99.47 - mc_global.mc_domid = curdom->domain_id; /* impacted domain */ 99.48 - 99.49 - x86_mc_get_cpu_info(cpu_nr, &mc_global.mc_socketid, 99.50 - &mc_global.mc_coreid, &mc_global.mc_core_threadid, 99.51 - &mc_global.mc_apicid, NULL, NULL, NULL); 99.52 - 99.53 - mc_global.mc_vcpuid = vcpu->vcpu_id; /* impacted vcpu */ 99.54 - mc_global.mc_flags |= MC_FLAG_UNCORRECTABLE; 99.55 - rdmsrl(MSR_IA32_MCG_STATUS, mc_global.mc_gstatus); 99.56 - 99.57 - /* Quick check, who is impacted */ 99.58 - xen_impacted = is_idle_domain(curdom); 99.59 - 99.60 - /* Dom0 */ 99.61 - x86_mcinfo_clear(mc_data); 99.62 - x86_mcinfo_add(mc_data, &mc_global); 99.63 - 99.64 - for (i = 0; i < nr_mce_banks; i++) { 99.65 - struct domain *d; 99.66 - 99.67 - rdmsrl(MSR_IA32_MC0_STATUS + 4 * i, status); 99.68 - 99.69 - if (!(status & MCi_STATUS_VAL)) 99.70 - continue; 99.71 - 99.72 - /* An error happened in this bank. 99.73 - * This is expected to be an uncorrectable error, 99.74 - * since correctable errors get polled. 99.75 - */ 99.76 - uc = status & MCi_STATUS_UC; 99.77 - 99.78 - memset(&mc_info, 0, sizeof(mc_info)); 99.79 - mc_info.common.type = MC_TYPE_BANK; 99.80 - mc_info.common.size = sizeof(mc_info); 99.81 - mc_info.mc_bank = i; 99.82 - mc_info.mc_status = status; 99.83 - 99.84 - addrv = 0; 99.85 - if (status & MCi_STATUS_ADDRV) { 99.86 - rdmsrl(MSR_IA32_MC0_ADDR + 4 * i, addrv); 99.87 - 99.88 - d = maddr_get_owner(addrv); 99.89 - if (d != NULL) 99.90 - mc_info.mc_domid = d->domain_id; 99.91 - } 99.92 - 99.93 - miscv = 0; 99.94 - if (status & MCi_STATUS_MISCV) 99.95 - rdmsrl(MSR_IA32_MC0_MISC + 4 * i, miscv); 99.96 - 99.97 - mc_info.mc_addr = addrv; 99.98 - mc_info.mc_misc = miscv; 99.99 - 99.100 - x86_mcinfo_add(mc_data, &mc_info); /* Dom0 */ 99.101 - 99.102 - if (mc_callback_bank_extended) 99.103 - mc_callback_bank_extended(mc_data, i, status); 99.104 - 99.105 - /* clear status */ 99.106 - wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL); 99.107 - wmb(); 99.108 - add_taint(TAINT_MACHINE_CHECK); 99.109 - } 99.110 - 99.111 - status = mc_global.mc_gstatus; 99.112 - 99.113 - /* clear MCIP or cpu enters shutdown state 99.114 - * in case another MCE occurs. */ 99.115 - status &= ~MCG_STATUS_MCIP; 99.116 - wrmsrl(MSR_IA32_MCG_STATUS, status); 99.117 - wmb(); 99.118 - 99.119 - /* For the details see the discussion "MCE/MCA concept" on xen-devel. 99.120 - * The thread started here: 99.121 - * http://lists.xensource.com/archives/html/xen-devel/2007-05/msg01015.html 99.122 - */ 99.123 - 99.124 - /* MCG_STATUS_RIPV: 99.125 - * When this bit is not set, then the instruction pointer onto the stack 99.126 - * to resume at is not valid. If xen is interrupted, then we panic anyway 99.127 - * right below. Otherwise it is up to the guest to figure out if 99.128 - * guest kernel or guest userland is affected and should kill either 99.129 - * itself or the affected process. 99.130 - */ 99.131 - 99.132 - /* MCG_STATUS_EIPV: 99.133 - * Evaluation of EIPV is the job of the guest. 99.134 - */ 99.135 - 99.136 - if (xen_impacted) { 99.137 - /* Now we are going to panic anyway. Allow interrupts, so that 99.138 - * printk on serial console can work. */ 99.139 - vcpu_schedule_unlock_irq(vcpu); 99.140 - 99.141 - /* Uh, that means, machine check exception 99.142 - * inside Xen occured. */ 99.143 - printk("Machine check exception occured in Xen.\n"); 99.144 - 99.145 - /* if MCG_STATUS_EIPV indicates, the IP on the stack is related 99.146 - * to the error then it makes sense to print a stack trace. 99.147 - * That can be useful for more detailed error analysis and/or 99.148 - * error case studies to figure out, if we can clear 99.149 - * xen_impacted and kill a DomU instead 99.150 - * (i.e. if a guest only control structure is affected, but then 99.151 - * we must ensure the bad pages are not re-used again). 99.152 - */ 99.153 - if (status & MCG_STATUS_EIPV) { 99.154 - printk("MCE: Instruction Pointer is related to the error. " 99.155 - "Therefore, print the execution state.\n"); 99.156 - show_execution_state(regs); 99.157 - } 99.158 - x86_mcinfo_dump(mc_data); 99.159 - mc_panic("End of MCE. Use mcelog to decode above error codes.\n"); 99.160 - } 99.161 - 99.162 - /* If Dom0 registered a machine check handler, which is only possible 99.163 - * with a PV MCA driver, then ... */ 99.164 - if ( guest_has_trap_callback(dom0, 0, TRAP_machine_check) ) { 99.165 - dom_state = DOM0_TRAP; 99.166 - 99.167 - /* ... deliver machine check trap to Dom0. */ 99.168 - send_guest_trap(dom0, 0, TRAP_machine_check); 99.169 - 99.170 - /* Xen may tell Dom0 now to notify the DomU. 99.171 - * But this will happen through a hypercall. */ 99.172 - } else 99.173 - /* Dom0 did not register a machine check handler, but if DomU 99.174 - * did so, then... */ 99.175 - if ( guest_has_trap_callback(curdom, vcpu->vcpu_id, TRAP_machine_check) ) { 99.176 - dom_state = DOMU_TRAP; 99.177 - 99.178 - /* ... deliver machine check trap to DomU */ 99.179 - send_guest_trap(curdom, vcpu->vcpu_id, TRAP_machine_check); 99.180 - } else { 99.181 - /* hmm... noone feels responsible to handle the error. 99.182 - * So, do a quick check if a DomU is impacted or not. 99.183 - */ 99.184 - if (curdom == dom0) { 99.185 - /* Dom0 is impacted. Since noone can't handle 99.186 - * this error, panic! */ 99.187 - x86_mcinfo_dump(mc_data); 99.188 - mc_panic("MCE occured in Dom0, which it can't handle\n"); 99.189 - 99.190 - /* UNREACHED */ 99.191 - } else { 99.192 - dom_state = DOMU_KILLED; 99.193 - 99.194 - /* Enable interrupts. This basically results in 99.195 - * calling sti on the *physical* cpu. But after 99.196 - * domain_crash() the vcpu pointer is invalid. 99.197 - * Therefore, we must unlock the irqs before killing 99.198 - * it. */ 99.199 - vcpu_schedule_unlock_irq(vcpu); 99.200 - 99.201 - /* DomU is impacted. Kill it and continue. */ 99.202 - domain_crash(curdom); 99.203 - } 99.204 - } 99.205 - 99.206 - 99.207 - switch (dom_state) { 99.208 - case DOM0_TRAP: 99.209 - case DOMU_TRAP: 99.210 - /* Enable interrupts. */ 99.211 - vcpu_schedule_unlock_irq(vcpu); 99.212 - 99.213 - /* guest softirqs and event callbacks are scheduled 99.214 - * immediately after this handler exits. */ 99.215 - break; 99.216 - case DOMU_KILLED: 99.217 - /* Nothing to do here. */ 99.218 - break; 99.219 - default: 99.220 - BUG(); 99.221 - } 99.222 + mcheck_cmn_handler(regs, error_code, mca_allbanks); 99.223 } 99.224 99.225 - 99.226 /* AMD K8 machine check */ 99.227 -void amd_k8_mcheck_init(struct cpuinfo_x86 *c) 99.228 +int amd_k8_mcheck_init(struct cpuinfo_x86 *c) 99.229 { 99.230 uint64_t value; 99.231 uint32_t i; 99.232 int cpu_nr; 99.233 99.234 - machine_check_vector = k8_machine_check; 99.235 + /* Check for PPro style MCA; our caller has confirmed MCE support. */ 99.236 + if (!cpu_has(c, X86_FEATURE_MCA)) 99.237 + return 0; 99.238 + 99.239 + x86_mce_vector_register(k8_machine_check); 99.240 cpu_nr = smp_processor_id(); 99.241 - wmb(); 99.242 99.243 rdmsrl(MSR_IA32_MCG_CAP, value); 99.244 if (value & MCG_CTL_P) /* Control register present ? */ 99.245 @@ -304,10 +97,8 @@ void amd_k8_mcheck_init(struct cpuinfo_x 99.246 for (i = 0; i < nr_mce_banks; i++) { 99.247 switch (i) { 99.248 case 4: /* Northbridge */ 99.249 - /* Enable error reporting of all errors, 99.250 - * enable error checking and 99.251 - * disable sync flooding */ 99.252 - wrmsrl(MSR_IA32_MC4_CTL, 0x02c3c008ffffffffULL); 99.253 + /* Enable error reporting of all errors */ 99.254 + wrmsrl(MSR_IA32_MC4_CTL, 0xffffffffffffffffULL); 99.255 wrmsrl(MSR_IA32_MC4_STATUS, 0x0ULL); 99.256 break; 99.257 99.258 @@ -321,4 +112,6 @@ void amd_k8_mcheck_init(struct cpuinfo_x 99.259 99.260 set_in_cr4(X86_CR4_MCE); 99.261 printk("CPU%i: AMD K8 machine check reporting enabled.\n", cpu_nr); 99.262 + 99.263 + return 1; 99.264 }
100.1 --- a/xen/arch/x86/cpu/mcheck/amd_nonfatal.c Fri Mar 27 10:54:08 2009 +0900 100.2 +++ b/xen/arch/x86/cpu/mcheck/amd_nonfatal.c Fri Mar 27 11:07:11 2009 +0900 100.3 @@ -58,22 +58,23 @@ 100.4 #include <xen/smp.h> 100.5 #include <xen/timer.h> 100.6 #include <xen/event.h> 100.7 -#include <asm/processor.h> 100.8 + 100.9 +#include <asm/processor.h> 100.10 #include <asm/system.h> 100.11 #include <asm/msr.h> 100.12 100.13 #include "mce.h" 100.14 -#include "x86_mca.h" 100.15 100.16 static struct timer mce_timer; 100.17 100.18 -#define MCE_PERIOD MILLISECS(15000) 100.19 +#define MCE_PERIOD MILLISECS(10000) 100.20 #define MCE_MIN MILLISECS(2000) 100.21 #define MCE_MAX MILLISECS(30000) 100.22 100.23 static s_time_t period = MCE_PERIOD; 100.24 static int hw_threshold = 0; 100.25 static int adjust = 0; 100.26 +static int variable_period = 1; 100.27 100.28 /* The polling service routine: 100.29 * Collects information of correctable errors and notifies 100.30 @@ -81,99 +82,46 @@ static int adjust = 0; 100.31 */ 100.32 void mce_amd_checkregs(void *info) 100.33 { 100.34 - struct vcpu *vcpu = current; 100.35 - struct mc_info *mc_data; 100.36 - struct mcinfo_global mc_global; 100.37 - struct mcinfo_bank mc_info; 100.38 - uint64_t status, addrv, miscv; 100.39 - unsigned int i; 100.40 + mctelem_cookie_t mctc; 100.41 + struct mca_summary bs; 100.42 unsigned int event_enabled; 100.43 - unsigned int cpu_nr; 100.44 - int error_found; 100.45 - 100.46 - /* We don't need a slot yet. Only allocate one on error. */ 100.47 - mc_data = NULL; 100.48 - 100.49 - cpu_nr = smp_processor_id(); 100.50 - BUG_ON(cpu_nr != vcpu->processor); 100.51 - event_enabled = guest_enabled_event(dom0->vcpu[0], VIRQ_MCA); 100.52 - error_found = 0; 100.53 100.54 - memset(&mc_global, 0, sizeof(mc_global)); 100.55 - mc_global.common.type = MC_TYPE_GLOBAL; 100.56 - mc_global.common.size = sizeof(mc_global); 100.57 - 100.58 - mc_global.mc_domid = vcpu->domain->domain_id; /* impacted domain */ 100.59 - mc_global.mc_vcpuid = vcpu->vcpu_id; /* impacted vcpu */ 100.60 - 100.61 - x86_mc_get_cpu_info(cpu_nr, &mc_global.mc_socketid, 100.62 - &mc_global.mc_coreid, &mc_global.mc_core_threadid, 100.63 - &mc_global.mc_apicid, NULL, NULL, NULL); 100.64 + mctc = mcheck_mca_logout(MCA_POLLER, mca_allbanks, &bs); 100.65 100.66 - mc_global.mc_flags |= MC_FLAG_CORRECTABLE; 100.67 - rdmsrl(MSR_IA32_MCG_STATUS, mc_global.mc_gstatus); 100.68 + event_enabled = guest_enabled_event(dom0->vcpu[0], VIRQ_MCA); 100.69 100.70 - for (i = 0; i < nr_mce_banks; i++) { 100.71 - struct domain *d; 100.72 - 100.73 - rdmsrl(MSR_IA32_MC0_STATUS + i * 4, status); 100.74 - 100.75 - if (!(status & MCi_STATUS_VAL)) 100.76 - continue; 100.77 + if (bs.errcnt && mctc != NULL) { 100.78 + static uint64_t dumpcount = 0; 100.79 100.80 - if (mc_data == NULL) { 100.81 - /* Now we need a slot to fill in error telemetry. */ 100.82 - mc_data = x86_mcinfo_getptr(); 100.83 - BUG_ON(mc_data == NULL); 100.84 - x86_mcinfo_clear(mc_data); 100.85 - x86_mcinfo_add(mc_data, &mc_global); 100.86 - } 100.87 - 100.88 - memset(&mc_info, 0, sizeof(mc_info)); 100.89 - mc_info.common.type = MC_TYPE_BANK; 100.90 - mc_info.common.size = sizeof(mc_info); 100.91 - mc_info.mc_bank = i; 100.92 - mc_info.mc_status = status; 100.93 - 100.94 - /* Increase polling frequency */ 100.95 - error_found = 1; 100.96 + /* If Dom0 enabled the VIRQ_MCA event, then notify it. 100.97 + * Otherwise, if dom0 has had plenty of time to register 100.98 + * the virq handler but still hasn't then dump telemetry 100.99 + * to the Xen console. The call count may be incremented 100.100 + * on multiple cpus at once and is indicative only - just 100.101 + * a simple-minded attempt to avoid spamming the console 100.102 + * for corrected errors in early startup. */ 100.103 100.104 - addrv = 0; 100.105 - if (status & MCi_STATUS_ADDRV) { 100.106 - rdmsrl(MSR_IA32_MC0_ADDR + i * 4, addrv); 100.107 - 100.108 - d = maddr_get_owner(addrv); 100.109 - if (d != NULL) 100.110 - mc_info.mc_domid = d->domain_id; 100.111 + if (event_enabled) { 100.112 + mctelem_commit(mctc); 100.113 + send_guest_global_virq(dom0, VIRQ_MCA); 100.114 + } else if (++dumpcount >= 10) { 100.115 + x86_mcinfo_dump((struct mc_info *)mctelem_dataptr(mctc)); 100.116 + mctelem_dismiss(mctc); 100.117 + } else { 100.118 + mctelem_dismiss(mctc); 100.119 } 100.120 - 100.121 - miscv = 0; 100.122 - if (status & MCi_STATUS_MISCV) 100.123 - rdmsrl(MSR_IA32_MC0_MISC + i * 4, miscv); 100.124 - 100.125 - mc_info.mc_addr = addrv; 100.126 - mc_info.mc_misc = miscv; 100.127 - x86_mcinfo_add(mc_data, &mc_info); 100.128 - 100.129 - if (mc_callback_bank_extended) 100.130 - mc_callback_bank_extended(mc_data, i, status); 100.131 - 100.132 - /* clear status */ 100.133 - wrmsrl(MSR_IA32_MC0_STATUS + i * 4, 0x0ULL); 100.134 - wmb(); 100.135 + 100.136 + } else if (mctc != NULL) { 100.137 + mctelem_dismiss(mctc); 100.138 } 100.139 100.140 - if (error_found > 0) { 100.141 - /* If Dom0 enabled the VIRQ_MCA event, then ... */ 100.142 - if (event_enabled) 100.143 - /* ... notify it. */ 100.144 - send_guest_global_virq(dom0, VIRQ_MCA); 100.145 - else 100.146 - /* ... or dump it */ 100.147 - x86_mcinfo_dump(mc_data); 100.148 - } 100.149 - 100.150 - adjust += error_found; 100.151 + /* adjust is global and all cpus may attempt to increment it without 100.152 + * synchronisation, so they race and the final adjust count 100.153 + * (number of cpus seeing any error) is approximate. We can 100.154 + * guarantee that if any cpu observes an error that the 100.155 + * adjust count is at least 1. */ 100.156 + if (bs.errcnt) 100.157 + adjust++; 100.158 } 100.159 100.160 /* polling service routine invoker: 100.161 @@ -188,7 +136,7 @@ static void mce_amd_work_fn(void *data) 100.162 on_each_cpu(mce_amd_checkregs, data, 1, 1); 100.163 100.164 if (adjust > 0) { 100.165 - if ( !guest_enabled_event(dom0->vcpu[0], VIRQ_MCA) ) { 100.166 + if (!guest_enabled_event(dom0->vcpu[0], VIRQ_MCA) ) { 100.167 /* Dom0 did not enable VIRQ_MCA, so Xen is reporting. */ 100.168 printk("MCE: polling routine found correctable error. " 100.169 " Use mcelog to parse above error output.\n"); 100.170 @@ -199,7 +147,7 @@ static void mce_amd_work_fn(void *data) 100.171 uint64_t value; 100.172 uint32_t counter; 100.173 100.174 - rdmsrl(MSR_IA32_MC4_MISC, value); 100.175 + mca_rdmsrl(MSR_IA32_MC4_MISC, value); 100.176 /* Only the error counter field is of interest 100.177 * Bit field is described in AMD K8 BKDG chapter 6.4.5.5 100.178 */ 100.179 @@ -224,24 +172,24 @@ static void mce_amd_work_fn(void *data) 100.180 value &= ~(0x60FFF00000000ULL); 100.181 /* Counter enable */ 100.182 value |= (1ULL << 51); 100.183 - wrmsrl(MSR_IA32_MC4_MISC, value); 100.184 + mca_wrmsrl(MSR_IA32_MC4_MISC, value); 100.185 wmb(); 100.186 } 100.187 } 100.188 100.189 - if (adjust > 0) { 100.190 + if (variable_period && adjust > 0) { 100.191 /* Increase polling frequency */ 100.192 adjust++; /* adjust == 1 must have an effect */ 100.193 period /= adjust; 100.194 - } else { 100.195 + } else if (variable_period) { 100.196 /* Decrease polling frequency */ 100.197 period *= 2; 100.198 } 100.199 - if (period > MCE_MAX) { 100.200 + if (variable_period && period > MCE_MAX) { 100.201 /* limit: Poll at least every 30s */ 100.202 period = MCE_MAX; 100.203 } 100.204 - if (period < MCE_MIN) { 100.205 + if (variable_period && period < MCE_MIN) { 100.206 /* limit: Poll every 2s. 100.207 * When this is reached an uncorrectable error 100.208 * is expected to happen, if Dom0 does nothing. 100.209 @@ -262,7 +210,7 @@ void amd_nonfatal_mcheck_init(struct cpu 100.210 100.211 /* The threshold bitfields in MSR_IA32_MC4_MISC has 100.212 * been introduced along with the SVME feature bit. */ 100.213 - if (cpu_has(c, X86_FEATURE_SVME)) { 100.214 + if (variable_period && cpu_has(c, X86_FEATURE_SVME)) { 100.215 uint64_t value; 100.216 100.217 /* hw threshold registers present */
101.1 --- a/xen/arch/x86/cpu/mcheck/k7.c Fri Mar 27 10:54:08 2009 +0900 101.2 +++ b/xen/arch/x86/cpu/mcheck/k7.c Fri Mar 27 11:07:11 2009 +0900 101.3 @@ -68,13 +68,16 @@ static fastcall void k7_machine_check(st 101.4 101.5 101.6 /* AMD K7 machine check */ 101.7 -void amd_k7_mcheck_init(struct cpuinfo_x86 *c) 101.8 +int amd_k7_mcheck_init(struct cpuinfo_x86 *c) 101.9 { 101.10 u32 l, h; 101.11 int i; 101.12 101.13 - machine_check_vector = k7_machine_check; 101.14 - wmb(); 101.15 + /* Check for PPro style MCA; our caller has confirmed MCE support. */ 101.16 + if (!cpu_has(c, X86_FEATURE_MCA)) 101.17 + return 0; 101.18 + 101.19 + x86_mce_vector_register(k7_machine_check); 101.20 101.21 rdmsr (MSR_IA32_MCG_CAP, l, h); 101.22 if (l & (1<<8)) /* Control register present ? */ 101.23 @@ -92,4 +95,6 @@ void amd_k7_mcheck_init(struct cpuinfo_x 101.24 set_in_cr4 (X86_CR4_MCE); 101.25 printk (KERN_INFO "CPU%d: AMD K7 machine check reporting enabled.\n", 101.26 smp_processor_id()); 101.27 + 101.28 + return 1; 101.29 }
102.1 --- a/xen/arch/x86/cpu/mcheck/mce.c Fri Mar 27 10:54:08 2009 +0900 102.2 +++ b/xen/arch/x86/cpu/mcheck/mce.c Fri Mar 27 11:07:11 2009 +0900 102.3 @@ -10,104 +10,492 @@ 102.4 #include <xen/smp.h> 102.5 #include <xen/errno.h> 102.6 #include <xen/console.h> 102.7 +#include <xen/sched.h> 102.8 +#include <xen/sched-if.h> 102.9 +#include <xen/cpumask.h> 102.10 +#include <xen/event.h> 102.11 +#include <xen/guest_access.h> 102.12 102.13 -#include <asm/processor.h> 102.14 +#include <asm/processor.h> 102.15 #include <asm/system.h> 102.16 +#include <asm/msr.h> 102.17 102.18 #include "mce.h" 102.19 -#include "x86_mca.h" 102.20 102.21 int mce_disabled = 0; 102.22 unsigned int nr_mce_banks; 102.23 102.24 EXPORT_SYMBOL_GPL(nr_mce_banks); /* non-fatal.o */ 102.25 102.26 -/* XXX For now a fixed array is used. Later this should be changed 102.27 - * to a dynamic allocated array with the size calculated in relation 102.28 - * to physical cpus present in the machine. 102.29 - * The more physical cpus are available, the more entries you need. 102.30 - */ 102.31 -#define MAX_MCINFO 20 102.32 +static void intpose_init(void); 102.33 +static void mcinfo_clear(struct mc_info *); 102.34 102.35 -struct mc_machine_notify { 102.36 - struct mc_info mc; 102.37 - uint32_t fetch_idx; 102.38 - uint32_t valid; 102.39 -}; 102.40 +#define SEG_PL(segsel) ((segsel) & 0x3) 102.41 +#define _MC_MSRINJ_F_REQ_HWCR_WREN (1 << 16) 102.42 102.43 -struct mc_machine { 102.44 +#if 1 /* XXFM switch to 0 for putback */ 102.45 102.46 - /* Array structure used for collecting machine check error telemetry. */ 102.47 - struct mc_info mc[MAX_MCINFO]; 102.48 +#define x86_mcerr(str, err) _x86_mcerr(str, err) 102.49 102.50 - /* We handle multiple machine check reports lockless by 102.51 - * iterating through the array using the producer/consumer concept. 102.52 - */ 102.53 - /* Producer array index to fill with machine check error data. 102.54 - * Index must be increased atomically. */ 102.55 - uint32_t error_idx; 102.56 - 102.57 - /* Consumer array index to fetch machine check error data from. 102.58 - * Index must be increased atomically. */ 102.59 - uint32_t fetch_idx; 102.60 +static int _x86_mcerr(const char *msg, int err) 102.61 +{ 102.62 + printk("x86_mcerr: %s, returning %d\n", 102.63 + msg != NULL ? msg : "", err); 102.64 + return err; 102.65 +} 102.66 +#else 102.67 +#define x86_mcerr(str,err) 102.68 +#endif 102.69 102.70 - /* Integer array holding the indeces of the mc array that allows 102.71 - * a Dom0 to notify a DomU to re-fetch the same machine check error 102.72 - * data. The notification and refetch also uses its own 102.73 - * producer/consumer mechanism, because Dom0 may decide to not report 102.74 - * every error to the impacted DomU. 102.75 - */ 102.76 - struct mc_machine_notify notify[MAX_MCINFO]; 102.77 - 102.78 - /* Array index to get fetch_idx from. 102.79 - * Index must be increased atomically. */ 102.80 - uint32_t notifyproducer_idx; 102.81 - uint32_t notifyconsumer_idx; 102.82 -}; 102.83 - 102.84 -/* Global variable with machine check information. */ 102.85 -struct mc_machine mc_data; 102.86 +cpu_banks_t mca_allbanks; 102.87 102.88 /* Handle unconfigured int18 (should never happen) */ 102.89 static void unexpected_machine_check(struct cpu_user_regs *regs, long error_code) 102.90 -{ 102.91 +{ 102.92 printk(XENLOG_ERR "CPU#%d: Unexpected int18 (Machine Check).\n", 102.93 smp_processor_id()); 102.94 } 102.95 102.96 102.97 +static x86_mce_vector_t _machine_check_vector = unexpected_machine_check; 102.98 + 102.99 +void x86_mce_vector_register(x86_mce_vector_t hdlr) 102.100 +{ 102.101 + _machine_check_vector = hdlr; 102.102 + wmb(); 102.103 +} 102.104 + 102.105 /* Call the installed machine check handler for this CPU setup. */ 102.106 -void (*machine_check_vector)(struct cpu_user_regs *regs, long error_code) = unexpected_machine_check; 102.107 + 102.108 +void machine_check_vector(struct cpu_user_regs *regs, long error_code) 102.109 +{ 102.110 + _machine_check_vector(regs, error_code); 102.111 +} 102.112 102.113 /* Init machine check callback handler 102.114 * It is used to collect additional information provided by newer 102.115 * CPU families/models without the need to duplicate the whole handler. 102.116 * This avoids having many handlers doing almost nearly the same and each 102.117 * with its own tweaks ands bugs. */ 102.118 -int (*mc_callback_bank_extended)(struct mc_info *, uint16_t, uint64_t) = NULL; 102.119 +static x86_mce_callback_t mc_callback_bank_extended = NULL; 102.120 + 102.121 +void x86_mce_callback_register(x86_mce_callback_t cbfunc) 102.122 +{ 102.123 + mc_callback_bank_extended = cbfunc; 102.124 +} 102.125 + 102.126 +/* Utility function to perform MCA bank telemetry readout and to push that 102.127 + * telemetry towards an interested dom0 for logging and diagnosis. 102.128 + * The caller - #MC handler or MCA poll function - must arrange that we 102.129 + * do not migrate cpus. */ 102.130 + 102.131 +/* XXFM Could add overflow counting? */ 102.132 +mctelem_cookie_t mcheck_mca_logout(enum mca_source who, cpu_banks_t bankmask, 102.133 + struct mca_summary *sp) 102.134 +{ 102.135 + struct vcpu *v = current; 102.136 + struct domain *d; 102.137 + uint64_t gstatus, status, addr, misc; 102.138 + struct mcinfo_global mcg; /* on stack */ 102.139 + struct mcinfo_common *mic; 102.140 + struct mcinfo_global *mig; /* on stack */ 102.141 + mctelem_cookie_t mctc = NULL; 102.142 + uint32_t uc = 0, pcc = 0; 102.143 + struct mc_info *mci = NULL; 102.144 + mctelem_class_t which = MC_URGENT; /* XXXgcc */ 102.145 + unsigned int cpu_nr; 102.146 + int errcnt = 0; 102.147 + int i; 102.148 + enum mca_extinfo cbret = MCA_EXTINFO_IGNORED; 102.149 + 102.150 + cpu_nr = smp_processor_id(); 102.151 + BUG_ON(cpu_nr != v->processor); 102.152 + 102.153 + mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus); 102.154 + 102.155 + memset(&mcg, 0, sizeof (mcg)); 102.156 + mcg.common.type = MC_TYPE_GLOBAL; 102.157 + mcg.common.size = sizeof (mcg); 102.158 + if (v != NULL && ((d = v->domain) != NULL)) { 102.159 + mcg.mc_domid = d->domain_id; 102.160 + mcg.mc_vcpuid = v->vcpu_id; 102.161 + } else { 102.162 + mcg.mc_domid = -1; 102.163 + mcg.mc_vcpuid = -1; 102.164 + } 102.165 + mcg.mc_gstatus = gstatus; /* MCG_STATUS */ 102.166 + 102.167 + switch (who) { 102.168 + case MCA_MCE_HANDLER: 102.169 + mcg.mc_flags = MC_FLAG_MCE; 102.170 + which = MC_URGENT; 102.171 + break; 102.172 + 102.173 + case MCA_POLLER: 102.174 + case MCA_RESET: 102.175 + mcg.mc_flags = MC_FLAG_POLLED; 102.176 + which = MC_NONURGENT; 102.177 + break; 102.178 + 102.179 + case MCA_CMCI_HANDLER: 102.180 + mcg.mc_flags = MC_FLAG_CMCI; 102.181 + which = MC_NONURGENT; 102.182 + break; 102.183 + 102.184 + default: 102.185 + BUG(); 102.186 + } 102.187 + 102.188 + /* Retrieve detector information */ 102.189 + x86_mc_get_cpu_info(cpu_nr, &mcg.mc_socketid, 102.190 + &mcg.mc_coreid, &mcg.mc_core_threadid, 102.191 + &mcg.mc_apicid, NULL, NULL, NULL); 102.192 + 102.193 + for (i = 0; i < 32 && i < nr_mce_banks; i++) { 102.194 + struct mcinfo_bank mcb; /* on stack */ 102.195 + 102.196 + /* Skip bank if corresponding bit in bankmask is clear */ 102.197 + if (!test_bit(i, bankmask)) 102.198 + continue; 102.199 + 102.200 + mca_rdmsrl(MSR_IA32_MC0_STATUS + i * 4, status); 102.201 + if (!(status & MCi_STATUS_VAL)) 102.202 + continue; /* this bank has no valid telemetry */ 102.203 + 102.204 + /* If this is the first bank with valid MCA DATA, then 102.205 + * try to reserve an entry from the urgent/nonurgent queue 102.206 + * depending on whethere we are called from an exception or 102.207 + * a poller; this can fail (for example dom0 may not 102.208 + * yet have consumed past telemetry). */ 102.209 + if (errcnt == 0) { 102.210 + if ((mctc = mctelem_reserve(which)) != NULL) { 102.211 + mci = mctelem_dataptr(mctc); 102.212 + mcinfo_clear(mci); 102.213 + } 102.214 + } 102.215 + 102.216 + memset(&mcb, 0, sizeof (mcb)); 102.217 + mcb.common.type = MC_TYPE_BANK; 102.218 + mcb.common.size = sizeof (mcb); 102.219 + mcb.mc_bank = i; 102.220 + mcb.mc_status = status; 102.221 + 102.222 + /* form a mask of which banks have logged uncorrected errors */ 102.223 + if ((status & MCi_STATUS_UC) != 0) 102.224 + uc |= (1 << i); 102.225 + 102.226 + /* likewise for those with processor context corrupt */ 102.227 + if ((status & MCi_STATUS_PCC) != 0) 102.228 + pcc |= (1 << i); 102.229 + 102.230 + addr = misc = 0; 102.231 + 102.232 + if (status & MCi_STATUS_ADDRV) { 102.233 + mca_rdmsrl(MSR_IA32_MC0_ADDR + 4 * i, addr); 102.234 + d = maddr_get_owner(addr); 102.235 + if (d != NULL && (who == MCA_POLLER || 102.236 + who == MCA_CMCI_HANDLER)) 102.237 + mcb.mc_domid = d->domain_id; 102.238 + } 102.239 + 102.240 + if (status & MCi_STATUS_MISCV) 102.241 + mca_rdmsrl(MSR_IA32_MC0_MISC + 4 * i, misc); 102.242 + 102.243 + mcb.mc_addr = addr; 102.244 + mcb.mc_misc = misc; 102.245 + 102.246 + if (who == MCA_CMCI_HANDLER) { 102.247 + mca_rdmsrl(MSR_IA32_MC0_CTL2 + i, mcb.mc_ctrl2); 102.248 + rdtscll(mcb.mc_tsc); 102.249 + } 102.250 + 102.251 + /* Increment the error count; if this is the first bank 102.252 + * with a valid error then add the global info to the mcinfo. */ 102.253 + if (errcnt++ == 0 && mci != NULL) 102.254 + x86_mcinfo_add(mci, &mcg); 102.255 + 102.256 + /* Add the bank data */ 102.257 + if (mci != NULL) 102.258 + x86_mcinfo_add(mci, &mcb); 102.259 + 102.260 + if (mc_callback_bank_extended && cbret != MCA_EXTINFO_GLOBAL) { 102.261 + cbret = mc_callback_bank_extended(mci, i, status); 102.262 + } 102.263 + 102.264 + /* Clear status */ 102.265 + mca_wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL); 102.266 + wmb(); 102.267 + } 102.268 + 102.269 + if (mci != NULL && errcnt > 0) { 102.270 + x86_mcinfo_lookup(mic, mci, MC_TYPE_GLOBAL); 102.271 + mig = (struct mcinfo_global *)mic; 102.272 + if (pcc) 102.273 + mcg.mc_flags |= MC_FLAG_UNCORRECTABLE; 102.274 + else if (uc) 102.275 + mcg.mc_flags |= MC_FLAG_RECOVERABLE; 102.276 + else 102.277 + mcg.mc_flags |= MC_FLAG_CORRECTABLE; 102.278 + } 102.279 102.280 102.281 -static void amd_mcheck_init(struct cpuinfo_x86 *ci) 102.282 + if (sp) { 102.283 + sp->errcnt = errcnt; 102.284 + sp->ripv = (gstatus & MCG_STATUS_RIPV) != 0; 102.285 + sp->eipv = (gstatus & MCG_STATUS_EIPV) != 0; 102.286 + sp->uc = uc; 102.287 + sp->pcc = pcc; 102.288 + } 102.289 + 102.290 + return mci != NULL ? mctc : NULL; /* may be NULL */ 102.291 +} 102.292 + 102.293 +#define DOM_NORMAL 0 102.294 +#define DOM0_TRAP 1 102.295 +#define DOMU_TRAP 2 102.296 +#define DOMU_KILLED 4 102.297 + 102.298 +/* Shared #MC handler. */ 102.299 +void mcheck_cmn_handler(struct cpu_user_regs *regs, long error_code, 102.300 + cpu_banks_t bankmask) 102.301 { 102.302 + int xen_state_lost, dom0_state_lost, domU_state_lost; 102.303 + struct vcpu *v = current; 102.304 + struct domain *curdom = v->domain; 102.305 + domid_t domid = curdom->domain_id; 102.306 + int ctx_xen, ctx_dom0, ctx_domU; 102.307 + uint32_t dom_state = DOM_NORMAL; 102.308 + mctelem_cookie_t mctc = NULL; 102.309 + struct mca_summary bs; 102.310 + struct mc_info *mci = NULL; 102.311 + int irqlocked = 0; 102.312 + uint64_t gstatus; 102.313 + int ripv; 102.314 + 102.315 + /* This handler runs as interrupt gate. So IPIs from the 102.316 + * polling service routine are defered until we're finished. 102.317 + */ 102.318 + 102.319 + /* Disable interrupts for the _vcpu_. It may not re-scheduled to 102.320 + * another physical CPU. */ 102.321 + vcpu_schedule_lock_irq(v); 102.322 + irqlocked = 1; 102.323 + 102.324 + /* Read global status; if it does not indicate machine check 102.325 + * in progress then bail as long as we have a valid ip to return to. */ 102.326 + mca_rdmsrl(MSR_IA32_MCG_STATUS, gstatus); 102.327 + ripv = ((gstatus & MCG_STATUS_RIPV) != 0); 102.328 + if (!(gstatus & MCG_STATUS_MCIP) && ripv) { 102.329 + add_taint(TAINT_MACHINE_CHECK); /* questionable */ 102.330 + vcpu_schedule_unlock_irq(v); 102.331 + irqlocked = 0; 102.332 + goto cmn_handler_done; 102.333 + } 102.334 + 102.335 + /* Go and grab error telemetry. We must choose whether to commit 102.336 + * for logging or dismiss the cookie that is returned, and must not 102.337 + * reference the cookie after that action. 102.338 + */ 102.339 + mctc = mcheck_mca_logout(MCA_MCE_HANDLER, bankmask, &bs); 102.340 + if (mctc != NULL) 102.341 + mci = (struct mc_info *)mctelem_dataptr(mctc); 102.342 + 102.343 + /* Clear MCIP or another #MC will enter shutdown state */ 102.344 + gstatus &= ~MCG_STATUS_MCIP; 102.345 + mca_wrmsrl(MSR_IA32_MCG_STATUS, gstatus); 102.346 + wmb(); 102.347 + 102.348 + /* If no valid errors and our stack is intact, we're done */ 102.349 + if (ripv && bs.errcnt == 0) { 102.350 + vcpu_schedule_unlock_irq(v); 102.351 + irqlocked = 0; 102.352 + goto cmn_handler_done; 102.353 + } 102.354 + 102.355 + if (bs.uc || bs.pcc) 102.356 + add_taint(TAINT_MACHINE_CHECK); 102.357 + 102.358 + /* Machine check exceptions will usually be for UC and/or PCC errors, 102.359 + * but it is possible to configure machine check for some classes 102.360 + * of corrected error. 102.361 + * 102.362 + * UC errors could compromise any domain or the hypervisor 102.363 + * itself - for example a cache writeback of modified data that 102.364 + * turned out to be bad could be for data belonging to anyone, not 102.365 + * just the current domain. In the absence of known data poisoning 102.366 + * to prevent consumption of such bad data in the system we regard 102.367 + * all UC errors as terminal. It may be possible to attempt some 102.368 + * heuristics based on the address affected, which guests have 102.369 + * mappings to that mfn etc. 102.370 + * 102.371 + * PCC errors apply to the current context. 102.372 + * 102.373 + * If MCG_STATUS indicates !RIPV then even a #MC that is not UC 102.374 + * and not PCC is terminal - the return instruction pointer 102.375 + * pushed onto the stack is bogus. If the interrupt context is 102.376 + * the hypervisor or dom0 the game is over, otherwise we can 102.377 + * limit the impact to a single domU but only if we trampoline 102.378 + * somewhere safely - we can't return and unwind the stack. 102.379 + * Since there is no trampoline in place we will treat !RIPV 102.380 + * as terminal for any context. 102.381 + */ 102.382 + ctx_xen = SEG_PL(regs->cs) == 0; 102.383 + ctx_dom0 = !ctx_xen && (domid == dom0->domain_id); 102.384 + ctx_domU = !ctx_xen && !ctx_dom0; 102.385 + 102.386 + xen_state_lost = bs.uc != 0 || (ctx_xen && (bs.pcc || !ripv)) || 102.387 + !ripv; 102.388 + dom0_state_lost = bs.uc != 0 || (ctx_dom0 && (bs.pcc || !ripv)); 102.389 + domU_state_lost = bs.uc != 0 || (ctx_domU && (bs.pcc || !ripv)); 102.390 + 102.391 + if (xen_state_lost) { 102.392 + /* Now we are going to panic anyway. Allow interrupts, so that 102.393 + * printk on serial console can work. */ 102.394 + vcpu_schedule_unlock_irq(v); 102.395 + irqlocked = 0; 102.396 + 102.397 + printk("Terminal machine check exception occured in " 102.398 + "hypervisor context.\n"); 102.399 + 102.400 + /* If MCG_STATUS_EIPV indicates, the IP on the stack is related 102.401 + * to the error then it makes sense to print a stack trace. 102.402 + * That can be useful for more detailed error analysis and/or 102.403 + * error case studies to figure out, if we can clear 102.404 + * xen_impacted and kill a DomU instead 102.405 + * (i.e. if a guest only control structure is affected, but then 102.406 + * we must ensure the bad pages are not re-used again). 102.407 + */ 102.408 + if (bs.eipv & MCG_STATUS_EIPV) { 102.409 + printk("MCE: Instruction Pointer is related to the " 102.410 + "error, therefore print the execution state.\n"); 102.411 + show_execution_state(regs); 102.412 + } 102.413 + 102.414 + /* Commit the telemetry so that panic flow can find it. */ 102.415 + if (mctc != NULL) { 102.416 + x86_mcinfo_dump(mci); 102.417 + mctelem_commit(mctc); 102.418 + } 102.419 + mc_panic("Hypervisor state lost due to machine check " 102.420 + "exception.\n"); 102.421 + /*NOTREACHED*/ 102.422 + } 102.423 + 102.424 + /* 102.425 + * Xen hypervisor state is intact. If dom0 state is lost then 102.426 + * give it a chance to decide what to do if it has registered 102.427 + * a handler for this event, otherwise panic. 102.428 + * 102.429 + * XXFM Could add some Solaris dom0 contract kill here? 102.430 + */ 102.431 + if (dom0_state_lost) { 102.432 + if (guest_has_trap_callback(dom0, 0, TRAP_machine_check)) { 102.433 + dom_state = DOM0_TRAP; 102.434 + send_guest_trap(dom0, 0, TRAP_machine_check); 102.435 + /* XXFM case of return with !ripv ??? */ 102.436 + } else { 102.437 + /* Commit telemetry for panic flow. */ 102.438 + if (mctc != NULL) { 102.439 + x86_mcinfo_dump(mci); 102.440 + mctelem_commit(mctc); 102.441 + } 102.442 + mc_panic("Dom0 state lost due to machine check " 102.443 + "exception\n"); 102.444 + /*NOTREACHED*/ 102.445 + } 102.446 + } 102.447 + 102.448 + /* 102.449 + * If a domU has lost state then send it a trap if it has registered 102.450 + * a handler, otherwise crash the domain. 102.451 + * XXFM Revisit this functionality. 102.452 + */ 102.453 + if (domU_state_lost) { 102.454 + if (guest_has_trap_callback(v->domain, v->vcpu_id, 102.455 + TRAP_machine_check)) { 102.456 + dom_state = DOMU_TRAP; 102.457 + send_guest_trap(curdom, v->vcpu_id, 102.458 + TRAP_machine_check); 102.459 + } else { 102.460 + dom_state = DOMU_KILLED; 102.461 + /* Enable interrupts. This basically results in 102.462 + * calling sti on the *physical* cpu. But after 102.463 + * domain_crash() the vcpu pointer is invalid. 102.464 + * Therefore, we must unlock the irqs before killing 102.465 + * it. */ 102.466 + vcpu_schedule_unlock_irq(v); 102.467 + irqlocked = 0; 102.468 + 102.469 + /* DomU is impacted. Kill it and continue. */ 102.470 + domain_crash(curdom); 102.471 + } 102.472 + } 102.473 + 102.474 + switch (dom_state) { 102.475 + case DOM0_TRAP: 102.476 + case DOMU_TRAP: 102.477 + /* Enable interrupts. */ 102.478 + vcpu_schedule_unlock_irq(v); 102.479 + irqlocked = 0; 102.480 + 102.481 + /* guest softirqs and event callbacks are scheduled 102.482 + * immediately after this handler exits. */ 102.483 + break; 102.484 + case DOMU_KILLED: 102.485 + /* Nothing to do here. */ 102.486 + break; 102.487 + 102.488 + case DOM_NORMAL: 102.489 + vcpu_schedule_unlock_irq(v); 102.490 + irqlocked = 0; 102.491 + break; 102.492 + } 102.493 + 102.494 +cmn_handler_done: 102.495 + BUG_ON(irqlocked); 102.496 + BUG_ON(!ripv); 102.497 + 102.498 + if (bs.errcnt) { 102.499 + /* Not panicing, so forward telemetry to dom0 now if it 102.500 + * is interested. */ 102.501 + if (guest_enabled_event(dom0->vcpu[0], VIRQ_MCA)) { 102.502 + if (mctc != NULL) 102.503 + mctelem_commit(mctc); 102.504 + send_guest_global_virq(dom0, VIRQ_MCA); 102.505 + } else { 102.506 + x86_mcinfo_dump(mci); 102.507 + if (mctc != NULL) 102.508 + mctelem_dismiss(mctc); 102.509 + } 102.510 + } else if (mctc != NULL) { 102.511 + mctelem_dismiss(mctc); 102.512 + } 102.513 +} 102.514 + 102.515 +static int amd_mcheck_init(struct cpuinfo_x86 *ci) 102.516 +{ 102.517 + int rc = 0; 102.518 102.519 switch (ci->x86) { 102.520 case 6: 102.521 - amd_k7_mcheck_init(ci); 102.522 + rc = amd_k7_mcheck_init(ci); 102.523 break; 102.524 102.525 case 0xf: 102.526 - amd_k8_mcheck_init(ci); 102.527 + rc = amd_k8_mcheck_init(ci); 102.528 break; 102.529 102.530 case 0x10: 102.531 - amd_f10_mcheck_init(ci); 102.532 + rc = amd_f10_mcheck_init(ci); 102.533 break; 102.534 102.535 default: 102.536 /* Assume that machine check support is available. 102.537 * The minimum provided support is at least the K8. */ 102.538 - amd_k8_mcheck_init(ci); 102.539 + rc = amd_k8_mcheck_init(ci); 102.540 } 102.541 + 102.542 + return rc; 102.543 } 102.544 102.545 /*check the existence of Machine Check*/ 102.546 @@ -116,50 +504,82 @@ int mce_available(struct cpuinfo_x86 *c) 102.547 return cpu_has(c, X86_FEATURE_MCE) && cpu_has(c, X86_FEATURE_MCA); 102.548 } 102.549 102.550 +/* 102.551 + * Check if bank 0 is usable for MCE. It isn't for AMD K7, 102.552 + * and Intel P6 family before model 0x1a. 102.553 + */ 102.554 +int mce_firstbank(struct cpuinfo_x86 *c) 102.555 +{ 102.556 + if (c->x86 == 6) { 102.557 + if (c->x86_vendor == X86_VENDOR_AMD) 102.558 + return 1; 102.559 + 102.560 + if (c->x86_vendor == X86_VENDOR_INTEL && c->x86_model < 0x1a) 102.561 + return 1; 102.562 + } 102.563 + 102.564 + return 0; 102.565 +} 102.566 + 102.567 /* This has to be run for each processor */ 102.568 void mcheck_init(struct cpuinfo_x86 *c) 102.569 { 102.570 + int inited = 0, i; 102.571 + 102.572 if (mce_disabled == 1) { 102.573 printk(XENLOG_INFO "MCE support disabled by bootparam\n"); 102.574 return; 102.575 } 102.576 102.577 + for (i = 0; i < MAX_NR_BANKS; i++) 102.578 + set_bit(i,mca_allbanks); 102.579 + 102.580 + /* Enforce at least MCE support in CPUID information. Individual 102.581 + * families may also need to enforce a check for MCA support. */ 102.582 if (!cpu_has(c, X86_FEATURE_MCE)) { 102.583 printk(XENLOG_INFO "CPU%i: No machine check support available\n", 102.584 smp_processor_id()); 102.585 return; 102.586 } 102.587 102.588 - memset(&mc_data, 0, sizeof(struct mc_machine)); 102.589 + intpose_init(); 102.590 + mctelem_init(sizeof (struct mc_info)); 102.591 102.592 switch (c->x86_vendor) { 102.593 case X86_VENDOR_AMD: 102.594 - amd_mcheck_init(c); 102.595 + inited = amd_mcheck_init(c); 102.596 break; 102.597 102.598 case X86_VENDOR_INTEL: 102.599 + switch (c->x86) { 102.600 + case 5: 102.601 #ifndef CONFIG_X86_64 102.602 - if (c->x86==5) 102.603 - intel_p5_mcheck_init(c); 102.604 + inited = intel_p5_mcheck_init(c); 102.605 #endif 102.606 - /*If it is P6 or P4 family, including CORE 2 DUO series*/ 102.607 - if (c->x86 == 6 || c->x86==15) 102.608 - { 102.609 - printk(KERN_DEBUG "MCE: Intel newly family MC Init\n"); 102.610 - intel_mcheck_init(c); 102.611 + break; 102.612 + 102.613 + case 6: 102.614 + case 15: 102.615 + inited = intel_mcheck_init(c); 102.616 + break; 102.617 } 102.618 break; 102.619 102.620 #ifndef CONFIG_X86_64 102.621 case X86_VENDOR_CENTAUR: 102.622 - if (c->x86==5) 102.623 - winchip_mcheck_init(c); 102.624 + if (c->x86==5) { 102.625 + inited = winchip_mcheck_init(c); 102.626 + } 102.627 break; 102.628 #endif 102.629 102.630 default: 102.631 break; 102.632 } 102.633 + 102.634 + if (!inited) 102.635 + printk(XENLOG_INFO "CPU%i: No machine check initialization\n", 102.636 + smp_processor_id()); 102.637 } 102.638 102.639 102.640 @@ -176,191 +596,12 @@ static void __init mcheck_enable(char *s 102.641 custom_param("nomce", mcheck_disable); 102.642 custom_param("mce", mcheck_enable); 102.643 102.644 - 102.645 -#include <xen/guest_access.h> 102.646 -#include <asm/traps.h> 102.647 - 102.648 -struct mc_info *x86_mcinfo_getptr(void) 102.649 -{ 102.650 - struct mc_info *mi; 102.651 - uint32_t entry, next; 102.652 - 102.653 - for (;;) { 102.654 - entry = mc_data.error_idx; 102.655 - smp_rmb(); 102.656 - next = entry + 1; 102.657 - if (cmpxchg(&mc_data.error_idx, entry, next) == entry) 102.658 - break; 102.659 - } 102.660 - 102.661 - mi = &(mc_data.mc[(entry % MAX_MCINFO)]); 102.662 - BUG_ON(mc_data.error_idx < mc_data.fetch_idx); 102.663 - 102.664 - return mi; 102.665 -} 102.666 - 102.667 -static int x86_mcinfo_matches_guest(const struct mc_info *mi, 102.668 - const struct domain *d, const struct vcpu *v) 102.669 -{ 102.670 - struct mcinfo_common *mic; 102.671 - struct mcinfo_global *mig; 102.672 - 102.673 - x86_mcinfo_lookup(mic, mi, MC_TYPE_GLOBAL); 102.674 - mig = (struct mcinfo_global *)mic; 102.675 - if (mig == NULL) 102.676 - return 0; 102.677 - 102.678 - if (d->domain_id != mig->mc_domid) 102.679 - return 0; 102.680 - 102.681 - if (v->vcpu_id != mig->mc_vcpuid) 102.682 - return 0; 102.683 - 102.684 - return 1; 102.685 -} 102.686 - 102.687 - 102.688 -#define x86_mcinfo_mcdata(idx) (mc_data.mc[(idx % MAX_MCINFO)]) 102.689 - 102.690 -static struct mc_info *x86_mcinfo_getfetchptr(uint32_t *fetch_idx, 102.691 - const struct domain *d, const struct vcpu *v) 102.692 -{ 102.693 - struct mc_info *mi; 102.694 - 102.695 - /* This function is called from the fetch hypercall with 102.696 - * the mc_lock spinlock held. Thus, no need for locking here. 102.697 - */ 102.698 - mi = &(x86_mcinfo_mcdata(mc_data.fetch_idx)); 102.699 - if ((d != dom0) && !x86_mcinfo_matches_guest(mi, d, v)) { 102.700 - /* Bogus domU command detected. */ 102.701 - *fetch_idx = 0; 102.702 - return NULL; 102.703 - } 102.704 - 102.705 - *fetch_idx = mc_data.fetch_idx; 102.706 - mc_data.fetch_idx++; 102.707 - BUG_ON(mc_data.fetch_idx > mc_data.error_idx); 102.708 - 102.709 - return mi; 102.710 -} 102.711 - 102.712 - 102.713 -static void x86_mcinfo_marknotified(struct xen_mc_notifydomain *mc_notifydomain) 102.714 -{ 102.715 - struct mc_machine_notify *mn; 102.716 - struct mcinfo_common *mic = NULL; 102.717 - struct mcinfo_global *mig; 102.718 - struct domain *d; 102.719 - int i; 102.720 - 102.721 - /* This function is called from the notifier hypercall with 102.722 - * the mc_notify_lock spinlock held. Thus, no need for locking here. 102.723 - */ 102.724 - 102.725 - /* First invalidate entries for guests that disappeared after 102.726 - * notification (e.g. shutdown/crash). This step prevents the 102.727 - * notification array from filling up with stalling/leaking entries. 102.728 - */ 102.729 - for (i = mc_data.notifyconsumer_idx; i < mc_data.notifyproducer_idx; i++) { 102.730 - mn = &(mc_data.notify[(i % MAX_MCINFO)]); 102.731 - x86_mcinfo_lookup(mic, &mn->mc, MC_TYPE_GLOBAL); 102.732 - BUG_ON(mic == NULL); 102.733 - mig = (struct mcinfo_global *)mic; 102.734 - d = get_domain_by_id(mig->mc_domid); 102.735 - if (d == NULL) { 102.736 - /* Domain does not exist. */ 102.737 - mn->valid = 0; 102.738 - } 102.739 - if ((!mn->valid) && (i == mc_data.notifyconsumer_idx)) 102.740 - mc_data.notifyconsumer_idx++; 102.741 - } 102.742 - 102.743 - /* Now put in the error telemetry. Since all error data fetchable 102.744 - * by domUs are uncorrectable errors, they are very important. 102.745 - * So we dump them before overriding them. When a guest takes that long, 102.746 - * then we can assume something bad already happened (crash, hang, etc.) 102.747 - */ 102.748 - mn = &(mc_data.notify[(mc_data.notifyproducer_idx % MAX_MCINFO)]); 102.749 - 102.750 - if (mn->valid) { 102.751 - struct mcinfo_common *mic = NULL; 102.752 - struct mcinfo_global *mig; 102.753 - 102.754 - /* To not loose the information, we dump it. */ 102.755 - x86_mcinfo_lookup(mic, &mn->mc, MC_TYPE_GLOBAL); 102.756 - BUG_ON(mic == NULL); 102.757 - mig = (struct mcinfo_global *)mic; 102.758 - printk(XENLOG_WARNING "Domain ID %u was notified by Dom0 to " 102.759 - "fetch machine check error telemetry. But Domain ID " 102.760 - "did not do that in time.\n", 102.761 - mig->mc_domid); 102.762 - x86_mcinfo_dump(&mn->mc); 102.763 - } 102.764 - 102.765 - memcpy(&mn->mc, &(x86_mcinfo_mcdata(mc_notifydomain->fetch_idx)), 102.766 - sizeof(struct mc_info)); 102.767 - mn->fetch_idx = mc_notifydomain->fetch_idx; 102.768 - mn->valid = 1; 102.769 - 102.770 - mc_data.notifyproducer_idx++; 102.771 - 102.772 - /* By design there can never be more notifies than machine check errors. 102.773 - * If that ever happens, then we hit a bug. */ 102.774 - BUG_ON(mc_data.notifyproducer_idx > mc_data.fetch_idx); 102.775 - BUG_ON(mc_data.notifyconsumer_idx > mc_data.notifyproducer_idx); 102.776 -} 102.777 - 102.778 -static struct mc_info *x86_mcinfo_getnotifiedptr(uint32_t *fetch_idx, 102.779 - const struct domain *d, const struct vcpu *v) 102.780 -{ 102.781 - struct mc_machine_notify *mn = NULL; 102.782 - uint32_t i; 102.783 - int found; 102.784 - 102.785 - /* This function is called from the fetch hypercall with 102.786 - * the mc_notify_lock spinlock held. Thus, no need for locking here. 102.787 - */ 102.788 - 102.789 - /* The notifier data is filled in the order guests get notified, but 102.790 - * guests may fetch them in a different order. That's why we need 102.791 - * the game with valid/invalid entries. */ 102.792 - found = 0; 102.793 - for (i = mc_data.notifyconsumer_idx; i < mc_data.notifyproducer_idx; i++) { 102.794 - mn = &(mc_data.notify[(i % MAX_MCINFO)]); 102.795 - if (!mn->valid) { 102.796 - if (i == mc_data.notifyconsumer_idx) 102.797 - mc_data.notifyconsumer_idx++; 102.798 - continue; 102.799 - } 102.800 - if (x86_mcinfo_matches_guest(&mn->mc, d, v)) { 102.801 - found = 1; 102.802 - break; 102.803 - } 102.804 - } 102.805 - 102.806 - if (!found) { 102.807 - /* This domain has never been notified. This must be 102.808 - * a bogus domU command. */ 102.809 - *fetch_idx = 0; 102.810 - return NULL; 102.811 - } 102.812 - 102.813 - BUG_ON(mn == NULL); 102.814 - *fetch_idx = mn->fetch_idx; 102.815 - mn->valid = 0; 102.816 - 102.817 - BUG_ON(mc_data.notifyconsumer_idx > mc_data.notifyproducer_idx); 102.818 - return &mn->mc; 102.819 -} 102.820 - 102.821 - 102.822 -void x86_mcinfo_clear(struct mc_info *mi) 102.823 +static void mcinfo_clear(struct mc_info *mi) 102.824 { 102.825 memset(mi, 0, sizeof(struct mc_info)); 102.826 x86_mcinfo_nentries(mi) = 0; 102.827 } 102.828 102.829 - 102.830 int x86_mcinfo_add(struct mc_info *mi, void *mcinfo) 102.831 { 102.832 int i; 102.833 @@ -380,7 +621,7 @@ int x86_mcinfo_add(struct mc_info *mi, v 102.834 end2 = (unsigned long)((uint8_t *)mic_index + mic->size); 102.835 102.836 if (end1 < end2) 102.837 - return -ENOSPC; /* No space. Can't add entry. */ 102.838 + return x86_mcerr("mcinfo_add: no more sparc", -ENOSPC); 102.839 102.840 /* there's enough space. add entry. */ 102.841 memcpy(mic_index, mic, mic->size); 102.842 @@ -389,7 +630,6 @@ int x86_mcinfo_add(struct mc_info *mi, v 102.843 return 0; 102.844 } 102.845 102.846 - 102.847 /* Dump machine check information in a format, 102.848 * mcelog can parse. This is used only when 102.849 * Dom0 does not take the notification. */ 102.850 @@ -404,7 +644,7 @@ void x86_mcinfo_dump(struct mc_info *mi) 102.851 if (mic == NULL) 102.852 return; 102.853 mc_global = (struct mcinfo_global *)mic; 102.854 - if (mc_global->mc_flags & MC_FLAG_UNCORRECTABLE) { 102.855 + if (mc_global->mc_flags & MC_FLAG_MCE) { 102.856 printk(XENLOG_WARNING 102.857 "CPU%d: Machine Check Exception: %16"PRIx64"\n", 102.858 mc_global->mc_coreid, mc_global->mc_gstatus); 102.859 @@ -424,7 +664,7 @@ void x86_mcinfo_dump(struct mc_info *mi) 102.860 goto next; 102.861 102.862 mc_bank = (struct mcinfo_bank *)mic; 102.863 - 102.864 + 102.865 printk(XENLOG_WARNING "Bank %d: %16"PRIx64, 102.866 mc_bank->mc_bank, 102.867 mc_bank->mc_status); 102.868 @@ -441,8 +681,6 @@ next: 102.869 } while (1); 102.870 } 102.871 102.872 - 102.873 - 102.874 static void do_mc_get_cpu_info(void *v) 102.875 { 102.876 int cpu = smp_processor_id(); 102.877 @@ -533,183 +771,394 @@ void x86_mc_get_cpu_info(unsigned cpu, u 102.878 } 102.879 } 102.880 102.881 +#define INTPOSE_NENT 50 102.882 + 102.883 +static struct intpose_ent { 102.884 + unsigned int cpu_nr; 102.885 + uint64_t msr; 102.886 + uint64_t val; 102.887 +} intpose_arr[INTPOSE_NENT]; 102.888 + 102.889 +static void intpose_init(void) 102.890 +{ 102.891 + static int done; 102.892 + int i; 102.893 + 102.894 + if (done++ > 0) 102.895 + return; 102.896 + 102.897 + for (i = 0; i < INTPOSE_NENT; i++) { 102.898 + intpose_arr[i].cpu_nr = -1; 102.899 + } 102.900 + 102.901 +} 102.902 + 102.903 +struct intpose_ent *intpose_lookup(unsigned int cpu_nr, uint64_t msr, 102.904 + uint64_t *valp) 102.905 +{ 102.906 + int i; 102.907 + 102.908 + for (i = 0; i < INTPOSE_NENT; i++) { 102.909 + if (intpose_arr[i].cpu_nr == cpu_nr && 102.910 + intpose_arr[i].msr == msr) { 102.911 + if (valp != NULL) 102.912 + *valp = intpose_arr[i].val; 102.913 + return &intpose_arr[i]; 102.914 + } 102.915 + } 102.916 + 102.917 + return NULL; 102.918 +} 102.919 + 102.920 +static void intpose_add(unsigned int cpu_nr, uint64_t msr, uint64_t val) 102.921 +{ 102.922 + struct intpose_ent *ent; 102.923 + int i; 102.924 + 102.925 + if ((ent = intpose_lookup(cpu_nr, msr, NULL)) != NULL) { 102.926 + ent->val = val; 102.927 + return; 102.928 + } 102.929 + 102.930 + for (i = 0, ent = &intpose_arr[0]; i < INTPOSE_NENT; i++, ent++) { 102.931 + if (ent->cpu_nr == -1) { 102.932 + ent->cpu_nr = cpu_nr; 102.933 + ent->msr = msr; 102.934 + ent->val = val; 102.935 + return; 102.936 + } 102.937 + } 102.938 + 102.939 + printk("intpose_add: interpose array full - request dropped\n"); 102.940 +} 102.941 + 102.942 +void intpose_inval(unsigned int cpu_nr, uint64_t msr) 102.943 +{ 102.944 + struct intpose_ent *ent; 102.945 + 102.946 + if ((ent = intpose_lookup(cpu_nr, msr, NULL)) != NULL) { 102.947 + ent->cpu_nr = -1; 102.948 + } 102.949 +} 102.950 + 102.951 +#define IS_MCA_BANKREG(r) \ 102.952 + ((r) >= MSR_IA32_MC0_CTL && \ 102.953 + (r) <= MSR_IA32_MC0_MISC + (nr_mce_banks - 1) * 4 && \ 102.954 + ((r) - MSR_IA32_MC0_CTL) % 4 != 0) /* excludes MCi_CTL */ 102.955 + 102.956 +static int x86_mc_msrinject_verify(struct xen_mc_msrinject *mci) 102.957 +{ 102.958 + struct cpuinfo_x86 *c; 102.959 + int i, errs = 0; 102.960 + 102.961 + c = &cpu_data[smp_processor_id()]; 102.962 + 102.963 + for (i = 0; i < mci->mcinj_count; i++) { 102.964 + uint64_t reg = mci->mcinj_msr[i].reg; 102.965 + const char *reason = NULL; 102.966 + 102.967 + if (IS_MCA_BANKREG(reg)) { 102.968 + if (c->x86_vendor == X86_VENDOR_AMD)