From 3a23990c80dc02936a1902d21936e13ef25a44dad904e0db734ab34667093258 Mon Sep 17 00:00:00 2001 From: OBS User unknown Date: Thu, 6 Mar 2008 01:36:51 +0000 Subject: [PATCH] OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/xen?expand=0&rev=39 --- 16769-pci-high-memory-resource.patch | 1000 ++++ 16859-x86_emulate-clts-fix.patch | 21 + 16929-hvm-guest-crash-fix.patch | 26 + 16930-shadow-pinning-logic-fix.patch | 34 + 16932-xend-hvm-localtime.patch | 87 + ...pe-strip.patch => 16945-blktap-strip.patch | 16 +- 16947-fvmachine-xenstore.patch | 69 + 16962-cross-page-write-failure.patch | 21 + 16965-xend-leak.patch | 24 + 16976-x86_emulate-sahf-fix.patch | 22 + 16977-xend-restart-count.patch | 61 + 16980-x86_emulate-macro-fix.patch | 36 + 16988-xm-reboot.patch | 62 + 16989-xend-coredump.patch | 250 + 16995-x86_emulate-mul-fix.patch | 35 + 16998-x86_emulate-imul-fix.patch | 20 + 17003-qemu-queue-mouse.patch | 197 + 17017-hpet-configuration.patch | 1134 ++++ 17036-mismatched-save-rest-fix.patch | 235 + 17113-xend-restore.patch | 27 + 32on64-extra-mem.patch | 2 +- blktap.patch | 8 +- block-iscsi | 90 +- cdrom-removable.patch | 56 +- disable_emulated_device.diff | 20 - ept-novell-x64.patch | 1021 ++++ etc_pam.d_xen-api | 7 + hvm-ide-flush-o_direct.patch | 18 + init.xendomains | 46 +- livemig-ept-novell-i386.patch | 209 + livemig-ept-novell-x64.patch | 331 ++ multinet-common.sh | 350 +- network-multinet | 32 +- ns_tools.patch | 96 + ns_xen_base.patch | 425 ++ ns_xen_extension.patch | 4645 +++++++++++++++++ pv-driver-build.patch | 15 + pv_32_16_color_trans.patch | 39 + pvdrv_emulation_control.patch | 24 + svm-cr8-performance.diff | 85 - sysconfig.xend | 2 +- vnc-i18n-keys.diff | 2 +- vpid-novell.patch | 341 ++ x86_emulate.patch | 10 +- xen-api-auth.patch | 12 + xen-domUloader.diff | 17 +- xen-fbback-resize.patch | 421 +- xen-hvm-default-bridge.diff | 2 +- xen-hvm-default-pae.diff | 2 +- xen-ioemu-hvm-pv-support.diff | 59 +- xen-no-dummy-nfs-ip.diff | 2 +- xen-qcow-realpath-buffer-overflow.patch | 13 + xen-tightvnc-args.diff | 2 +- xen-xmexample.diff | 2 +- xen.changes | 105 +- xen.spec | 204 +- xenapi-console-protocol.patch | 2 +- xenapiusers | 1 + xend-core-dump-loc.diff | 2 +- xmclone.sh | 2 +- 60 files changed, 11208 insertions(+), 891 deletions(-) create mode 100644 16769-pci-high-memory-resource.patch create mode 100644 16859-x86_emulate-clts-fix.patch create mode 100644 16929-hvm-guest-crash-fix.patch create mode 100644 16930-shadow-pinning-logic-fix.patch create mode 100644 16932-xend-hvm-localtime.patch rename xen-blktab-subtype-strip.patch => 16945-blktap-strip.patch (74%) create mode 100644 16947-fvmachine-xenstore.patch create mode 100644 16962-cross-page-write-failure.patch create mode 100644 16965-xend-leak.patch create mode 100644 16976-x86_emulate-sahf-fix.patch create mode 100644 16977-xend-restart-count.patch create mode 100644 16980-x86_emulate-macro-fix.patch create mode 100644 16988-xm-reboot.patch create mode 100644 16989-xend-coredump.patch create mode 100644 16995-x86_emulate-mul-fix.patch create mode 100644 16998-x86_emulate-imul-fix.patch create mode 100644 17003-qemu-queue-mouse.patch create mode 100644 17017-hpet-configuration.patch create mode 100644 17036-mismatched-save-rest-fix.patch create mode 100644 17113-xend-restore.patch delete mode 100644 disable_emulated_device.diff create mode 100644 ept-novell-x64.patch create mode 100644 etc_pam.d_xen-api create mode 100644 hvm-ide-flush-o_direct.patch create mode 100644 livemig-ept-novell-i386.patch create mode 100644 livemig-ept-novell-x64.patch create mode 100644 ns_tools.patch create mode 100644 ns_xen_base.patch create mode 100644 ns_xen_extension.patch create mode 100644 pv_32_16_color_trans.patch create mode 100644 pvdrv_emulation_control.patch delete mode 100644 svm-cr8-performance.diff create mode 100644 vpid-novell.patch create mode 100644 xen-api-auth.patch create mode 100644 xen-qcow-realpath-buffer-overflow.patch create mode 100644 xenapiusers diff --git a/16769-pci-high-memory-resource.patch b/16769-pci-high-memory-resource.patch new file mode 100644 index 0000000..c4e7f8d --- /dev/null +++ b/16769-pci-high-memory-resource.patch @@ -0,0 +1,1000 @@ +# HG changeset patch +# User Keir Fraser +# Date 1200926373 0 +# Node ID 6fed70d658ea735fc18d89c7e46951114be5e584 +# Parent f1947dddb5a05d7b03ec9c8d8d09fe4fd500c485 +hvm: Allow PCI high-memory resource to be decided by hvmloader at +HVM-guest boot time. Also make a few PCI0 resource ResourceProducer +type -- this seems to be specified by some randomly-sampled real ACPI +systems. +Signed-off-by: Keir Fraser + +Index: xen-3.2-testing/tools/firmware/hvmloader/acpi/build.c +=================================================================== +--- xen-3.2-testing.orig/tools/firmware/hvmloader/acpi/build.c ++++ xen-3.2-testing/tools/firmware/hvmloader/acpi/build.c +@@ -65,8 +65,9 @@ static int uart_exists(uint16_t uart_bas + static int construct_bios_info_table(uint8_t *buf) + { + struct bios_info { +- uint8_t com1_present:1; +- uint8_t com2_present:1; ++ uint8_t com1_present:1; ++ uint8_t com2_present:1; ++ uint32_t pci_min, pci_len; + } *bios_info = (struct bios_info *)buf; + + memset(bios_info, 0, sizeof(*bios_info)); +@@ -74,6 +75,9 @@ static int construct_bios_info_table(uin + bios_info->com1_present = uart_exists(0x3f8); + bios_info->com2_present = uart_exists(0x2f8); + ++ bios_info->pci_min = 0xf0000000; ++ bios_info->pci_len = 0x05000000; ++ + return align16(sizeof(*bios_info)); + } + +Index: xen-3.2-testing/tools/firmware/hvmloader/acpi/dsdt.asl +=================================================================== +--- xen-3.2-testing.orig/tools/firmware/hvmloader/acpi/dsdt.asl ++++ xen-3.2-testing/tools/firmware/hvmloader/acpi/dsdt.asl +@@ -48,7 +48,10 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, + OperationRegion(BIOS, SystemMemory, 0xEA000, 16) + Field(BIOS, ByteAcc, NoLock, Preserve) { + UAR1, 1, +- UAR2, 1 ++ UAR2, 1, ++ Offset(4), ++ PMIN, 32, ++ PLEN, 32 + } + + /* Fix HCT test for 0x400 pci memory: +@@ -82,7 +85,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, + { + /* bus number is from 0 - 255*/ + WordBusNumber( +- ResourceConsumer, MinFixed, MaxFixed, SubDecode, ++ ResourceProducer, MinFixed, MaxFixed, SubDecode, + 0x0000, + 0x0000, + 0x00FF, +@@ -117,14 +120,25 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, + 0x00020000) + + DWordMemory( +- ResourceConsumer, PosDecode, MinFixed, MaxFixed, ++ ResourceProducer, PosDecode, MinFixed, MaxFixed, + Cacheable, ReadWrite, + 0x00000000, + 0xF0000000, + 0xF4FFFFFF, + 0x00000000, +- 0x05000000) ++ 0x05000000, ++ ,, _Y01) + }) ++ ++ CreateDWordField(PRT0, \_SB.PCI0._CRS._Y01._MIN, MMIN) ++ CreateDWordField(PRT0, \_SB.PCI0._CRS._Y01._MAX, MMAX) ++ CreateDWordField(PRT0, \_SB.PCI0._CRS._Y01._LEN, MLEN) ++ ++ Store(\_SB.PMIN, MMIN) ++ Store(\_SB.PLEN, MLEN) ++ Add(MMIN, MLEN, MMAX) ++ Subtract(MMAX, One, MMAX) ++ + Return (PRT0) + } + +Index: xen-3.2-testing/tools/firmware/hvmloader/acpi/dsdt.c +=================================================================== +--- xen-3.2-testing.orig/tools/firmware/hvmloader/acpi/dsdt.c ++++ xen-3.2-testing/tools/firmware/hvmloader/acpi/dsdt.c +@@ -5,15 +5,15 @@ + * Copyright (C) 2000 - 2006 Intel Corporation + * Supports ACPI Specification Revision 3.0a + * +- * Compilation of "dsdt.asl" - Tue Sep 11 16:12:28 2007 ++ * Compilation of "dsdt.asl" - Mon Jan 21 14:11:31 2008 + * + * C source code output + * + */ + unsigned char AmlCode[] = + { +- 0x44,0x53,0x44,0x54,0x19,0x0E,0x00,0x00, /* 00000000 "DSDT...." */ +- 0x02,0x6A,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 ".jXen..." */ ++ 0x44,0x53,0x44,0x54,0x6F,0x0E,0x00,0x00, /* 00000000 "DSDTo..." */ ++ 0x02,0xE1,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ + 0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */ + 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ + 0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */ +@@ -27,442 +27,452 @@ unsigned char AmlCode[] = + 0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08, /* 00000060 "........" */ + 0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F, /* 00000068 "PICD..._" */ + 0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49, /* 00000070 "PIC.phPI" */ +- 0x43,0x44,0x10,0x4E,0xD9,0x5F,0x53,0x42, /* 00000078 "CD.N._SB" */ ++ 0x43,0x44,0x10,0x44,0xDF,0x5F,0x53,0x42, /* 00000078 "CD.D._SB" */ + 0x5F,0x5B,0x80,0x42,0x49,0x4F,0x53,0x00, /* 00000080 "_[.BIOS." */ + 0x0C,0x00,0xA0,0x0E,0x00,0x0A,0x10,0x5B, /* 00000088 ".......[" */ +- 0x81,0x10,0x42,0x49,0x4F,0x53,0x01,0x55, /* 00000090 "..BIOS.U" */ ++ 0x81,0x1C,0x42,0x49,0x4F,0x53,0x01,0x55, /* 00000090 "..BIOS.U" */ + 0x41,0x52,0x31,0x01,0x55,0x41,0x52,0x32, /* 00000098 "AR1.UAR2" */ +- 0x01,0x5B,0x82,0x49,0x04,0x4D,0x45,0x4D, /* 000000A0 ".[.I.MEM" */ +- 0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 000000A8 "0._HID.A" */ +- 0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52,0x53, /* 000000B0 "...._CRS" */ +- 0x11,0x33,0x0A,0x30,0x8A,0x2B,0x00,0x00, /* 000000B8 ".3.0.+.." */ +- 0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C0 "........" */ +- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000C8 "........" */ +- 0x00,0x00,0xFF,0xFF,0x09,0x00,0x00,0x00, /* 000000D0 "........" */ +- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D8 "........" */ +- 0x00,0x00,0x00,0x00,0x0A,0x00,0x00,0x00, /* 000000E0 "........" */ +- 0x00,0x00,0x79,0x00,0x5B,0x82,0x4B,0xD2, /* 000000E8 "..y.[.K." */ +- 0x50,0x43,0x49,0x30,0x08,0x5F,0x48,0x49, /* 000000F0 "PCI0._HI" */ +- 0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08,0x5F, /* 000000F8 "D.A...._" */ +- 0x55,0x49,0x44,0x00,0x08,0x5F,0x41,0x44, /* 00000100 "UID.._AD" */ +- 0x52,0x00,0x08,0x5F,0x42,0x42,0x4E,0x00, /* 00000108 "R.._BBN." */ +- 0x14,0x44,0x08,0x5F,0x43,0x52,0x53,0x00, /* 00000110 ".D._CRS." */ +- 0x08,0x50,0x52,0x54,0x30,0x11,0x42,0x07, /* 00000118 ".PRT0.B." */ +- 0x0A,0x6E,0x88,0x0D,0x00,0x02,0x0F,0x00, /* 00000120 ".n......" */ +- 0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00, /* 00000128 "........" */ +- 0x00,0x01,0x47,0x01,0xF8,0x0C,0xF8,0x0C, /* 00000130 "..G....." */ +- 0x01,0x08,0x88,0x0D,0x00,0x01,0x0C,0x03, /* 00000138 "........" */ +- 0x00,0x00,0x00,0x00,0xF7,0x0C,0x00,0x00, /* 00000140 "........" */ +- 0xF8,0x0C,0x88,0x0D,0x00,0x01,0x0C,0x03, /* 00000148 "........" */ +- 0x00,0x00,0x00,0x0D,0xFF,0xFF,0x00,0x00, /* 00000150 "........" */ +- 0x00,0xF3,0x87,0x17,0x00,0x00,0x0C,0x03, /* 00000158 "........" */ +- 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00, /* 00000160 "........" */ +- 0xFF,0xFF,0x0B,0x00,0x00,0x00,0x00,0x00, /* 00000168 "........" */ +- 0x00,0x00,0x02,0x00,0x87,0x17,0x00,0x00, /* 00000170 "........" */ +- 0x0D,0x03,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000178 "........" */ +- 0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00,0x00, /* 00000180 "........" */ +- 0x00,0x00,0x00,0x00,0x00,0x05,0x79,0x00, /* 00000188 "......y." */ +- 0xA4,0x50,0x52,0x54,0x30,0x08,0x42,0x55, /* 00000190 ".PRT0.BU" */ +- 0x46,0x41,0x11,0x09,0x0A,0x06,0x23,0x20, /* 00000198 "FA....# " */ +- 0x0C,0x18,0x79,0x00,0x08,0x42,0x55,0x46, /* 000001A0 "..y..BUF" */ +- 0x42,0x11,0x09,0x0A,0x06,0x23,0x00,0x00, /* 000001A8 "B....#.." */ +- 0x18,0x79,0x00,0x8B,0x42,0x55,0x46,0x42, /* 000001B0 ".y..BUFB" */ +- 0x01,0x49,0x52,0x51,0x56,0x5B,0x82,0x48, /* 000001B8 ".IRQV[.H" */ +- 0x08,0x4C,0x4E,0x4B,0x41,0x08,0x5F,0x48, /* 000001C0 ".LNKA._H" */ +- 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 000001C8 "ID.A...." */ +- 0x5F,0x55,0x49,0x44,0x01,0x14,0x1C,0x5F, /* 000001D0 "_UID..._" */ +- 0x53,0x54,0x41,0x00,0x7B,0x50,0x49,0x52, /* 000001D8 "STA.{PIR" */ +- 0x41,0x0A,0x80,0x60,0xA0,0x08,0x93,0x60, /* 000001E0 "A..`...`" */ +- 0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4, /* 000001E8 "........" */ +- 0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53, /* 000001F0 "...._PRS" */ +- 0x00,0xA4,0x42,0x55,0x46,0x41,0x14,0x11, /* 000001F8 "..BUFA.." */ +- 0x5F,0x44,0x49,0x53,0x00,0x7D,0x50,0x49, /* 00000200 "_DIS.}PI" */ +- 0x52,0x41,0x0A,0x80,0x50,0x49,0x52,0x41, /* 00000208 "RA..PIRA" */ +- 0x14,0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B, /* 00000210 ".._CRS.{" */ +- 0x50,0x49,0x52,0x41,0x0A,0x0F,0x60,0x79, /* 00000218 "PIRA..`y" */ +- 0x01,0x60,0x49,0x52,0x51,0x56,0xA4,0x42, /* 00000220 ".`IRQV.B" */ +- 0x55,0x46,0x42,0x14,0x1B,0x5F,0x53,0x52, /* 00000228 "UFB.._SR" */ +- 0x53,0x01,0x8B,0x68,0x01,0x49,0x52,0x51, /* 00000230 "S..h.IRQ" */ +- 0x31,0x82,0x49,0x52,0x51,0x31,0x60,0x76, /* 00000238 "1.IRQ1`v" */ +- 0x60,0x70,0x60,0x50,0x49,0x52,0x41,0x5B, /* 00000240 "`p`PIRA[" */ +- 0x82,0x49,0x08,0x4C,0x4E,0x4B,0x42,0x08, /* 00000248 ".I.LNKB." */ +- 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0C, /* 00000250 "_HID.A.." */ +- 0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A,0x02, /* 00000258 ".._UID.." */ +- 0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 00000260 ".._STA.{" */ +- 0x50,0x49,0x52,0x42,0x0A,0x80,0x60,0xA0, /* 00000268 "PIRB..`." */ +- 0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 00000270 "..`....." */ +- 0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 00000278 "......._" */ +- 0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 00000280 "PRS..BUF" */ +- 0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 00000288 "A.._DIS." */ +- 0x7D,0x50,0x49,0x52,0x42,0x0A,0x80,0x50, /* 00000290 "}PIRB..P" */ +- 0x49,0x52,0x42,0x14,0x1A,0x5F,0x43,0x52, /* 00000298 "IRB.._CR" */ +- 0x53,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A, /* 000002A0 "S.{PIRB." */ +- 0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 000002A8 ".`y.`IRQ" */ +- 0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 000002B0 "V.BUFB.." */ +- 0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 000002B8 "_SRS..h." */ +- 0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 000002C0 "IRQ1.IRQ" */ +- 0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 000002C8 "1`v`p`PI" */ +- 0x52,0x42,0x5B,0x82,0x49,0x08,0x4C,0x4E, /* 000002D0 "RB[.I.LN" */ +- 0x4B,0x43,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 000002D8 "KC._HID." */ +- 0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49, /* 000002E0 "A...._UI" */ +- 0x44,0x0A,0x03,0x14,0x1C,0x5F,0x53,0x54, /* 000002E8 "D...._ST" */ +- 0x41,0x00,0x7B,0x50,0x49,0x52,0x43,0x0A, /* 000002F0 "A.{PIRC." */ +- 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 000002F8 ".`...`.." */ +- 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 00000300 "........" */ +- 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 00000308 ".._PRS.." */ +- 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 00000310 "BUFA.._D" */ +- 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x43, /* 00000318 "IS.}PIRC" */ +- 0x0A,0x80,0x50,0x49,0x52,0x43,0x14,0x1A, /* 00000320 "..PIRC.." */ +- 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 00000328 "_CRS.{PI" */ +- 0x52,0x43,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 00000330 "RC..`y.`" */ +- 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 00000338 "IRQV.BUF" */ +- 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000340 "B.._SRS." */ +- 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 00000348 ".h.IRQ1." */ +- 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 00000350 "IRQ1`v`p" */ +- 0x60,0x50,0x49,0x52,0x43,0x5B,0x82,0x49, /* 00000358 "`PIRC[.I" */ +- 0x08,0x4C,0x4E,0x4B,0x44,0x08,0x5F,0x48, /* 00000360 ".LNKD._H" */ +- 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 00000368 "ID.A...." */ +- 0x5F,0x55,0x49,0x44,0x0A,0x04,0x14,0x1C, /* 00000370 "_UID...." */ +- 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 00000378 "_STA.{PI" */ +- 0x52,0x44,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 00000380 "RD..`..." */ +- 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 00000388 "`......." */ +- 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 00000390 "....._PR" */ +- 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 00000398 "S..BUFA." */ +- 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 000003A0 "._DIS.}P" */ +- 0x49,0x52,0x44,0x0A,0x80,0x50,0x49,0x52, /* 000003A8 "IRD..PIR" */ +- 0x44,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 000003B0 "D.._CRS." */ +- 0x7B,0x50,0x49,0x52,0x44,0x0A,0x0F,0x60, /* 000003B8 "{PIRD..`" */ +- 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 000003C0 "y.`IRQV." */ +- 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 000003C8 "BUFB.._S" */ +- 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 000003D0 "RS..h.IR" */ +- 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 000003D8 "Q1.IRQ1`" */ +- 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x44, /* 000003E0 "v`p`PIRD" */ +- 0x5B,0x82,0x3A,0x48,0x50,0x45,0x54,0x08, /* 000003E8 "[.:HPET." */ +- 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01, /* 000003F0 "_HID.A.." */ +- 0x03,0x08,0x5F,0x55,0x49,0x44,0x00,0x08, /* 000003F8 ".._UID.." */ +- 0x5F,0x43,0x52,0x53,0x11,0x1F,0x0A,0x1C, /* 00000400 "_CRS...." */ +- 0x87,0x17,0x00,0x00,0x0D,0x01,0x00,0x00, /* 00000408 "........" */ +- 0x00,0x00,0x00,0x00,0xD0,0xFE,0xFF,0x03, /* 00000410 "........" */ +- 0xD0,0xFE,0x00,0x00,0x00,0x00,0x00,0x04, /* 00000418 "........" */ +- 0x00,0x00,0x79,0x00,0x14,0x16,0x5F,0x50, /* 00000420 "..y..._P" */ +- 0x52,0x54,0x00,0xA0,0x0A,0x50,0x49,0x43, /* 00000428 "RT...PIC" */ +- 0x44,0xA4,0x50,0x52,0x54,0x41,0xA4,0x50, /* 00000430 "D.PRTA.P" */ +- 0x52,0x54,0x50,0x08,0x50,0x52,0x54,0x50, /* 00000438 "RTP.PRTP" */ +- 0x12,0x49,0x36,0x3C,0x12,0x0D,0x04,0x0C, /* 00000440 ".I6<...." */ +- 0xFF,0xFF,0x01,0x00,0x00,0x4C,0x4E,0x4B, /* 00000448 ".....LNK" */ +- 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000450 "B......." */ +- 0x01,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00, /* 00000458 "...LNKC." */ +- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 00000460 "........" */ +- 0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000468 "..LNKD.." */ +- 0x0E,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A, /* 00000470 "........" */ +- 0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000478 ".LNKA..." */ +- 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x00,0x4C, /* 00000480 ".......L" */ +- 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000488 "NKC....." */ +- 0xFF,0xFF,0x02,0x00,0x01,0x4C,0x4E,0x4B, /* 00000490 ".....LNK" */ +- 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000498 "D......." */ +- 0x02,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41, /* 000004A0 "....LNKA" */ +- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02, /* 000004A8 "........" */ +- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00, /* 000004B0 "...LNKB." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 000004B8 "........" */ +- 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 000004C0 ".LNKD..." */ +- 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x01,0x4C, /* 000004C8 ".......L" */ +- 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000004D0 "NKA....." */ +- 0xFF,0xFF,0x03,0x00,0x0A,0x02,0x4C,0x4E, /* 000004D8 "......LN" */ +- 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000004E0 "KB......" */ +- 0xFF,0x03,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000004E8 ".....LNK" */ +- 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000004F0 "C......." */ +- 0x04,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00, /* 000004F8 "...LNKA." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000500 "........" */ +- 0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 00000508 ".LNKB..." */ +- 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02, /* 00000510 "........" */ +- 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 00000518 "LNKC...." */ +- 0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03,0x4C, /* 00000520 ".......L" */ +- 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000528 "NKD....." */ +- 0xFF,0xFF,0x05,0x00,0x00,0x4C,0x4E,0x4B, /* 00000530 ".....LNK" */ +- 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000538 "B......." */ +- 0x05,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00, /* 00000540 "...LNKC." */ +- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 00000548 "........" */ +- 0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000550 "..LNKD.." */ +- 0x0E,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A, /* 00000558 "........" */ +- 0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000560 ".LNKA..." */ +- 0x04,0x0C,0xFF,0xFF,0x06,0x00,0x00,0x4C, /* 00000568 ".......L" */ +- 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000570 "NKC....." */ +- 0xFF,0xFF,0x06,0x00,0x01,0x4C,0x4E,0x4B, /* 00000578 ".....LNK" */ +- 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000580 "D......." */ +- 0x06,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41, /* 00000588 "....LNKA" */ +- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06, /* 00000590 "........" */ +- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00, /* 00000598 "...LNKB." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x07,0x00, /* 000005A0 "........" */ +- 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 000005A8 ".LNKD..." */ +- 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x01,0x4C, /* 000005B0 ".......L" */ +- 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000005B8 "NKA....." */ +- 0xFF,0xFF,0x07,0x00,0x0A,0x02,0x4C,0x4E, /* 000005C0 "......LN" */ +- 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000005C8 "KB......" */ +- 0xFF,0x07,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000005D0 ".....LNK" */ +- 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000005D8 "C......." */ +- 0x08,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00, /* 000005E0 "...LNKA." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 000005E8 "........" */ +- 0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 000005F0 ".LNKB..." */ +- 0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x02, /* 000005F8 "........" */ +- 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 00000600 "LNKC...." */ +- 0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03,0x4C, /* 00000608 ".......L" */ +- 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000610 "NKD....." */ +- 0xFF,0xFF,0x09,0x00,0x00,0x4C,0x4E,0x4B, /* 00000618 ".....LNK" */ +- 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000620 "B......." */ +- 0x09,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00, /* 00000628 "...LNKC." */ +- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 00000630 "........" */ +- 0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000638 "..LNKD.." */ +- 0x0E,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A, /* 00000640 "........" */ +- 0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000648 ".LNKA..." */ +- 0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x4C, /* 00000650 ".......L" */ +- 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000658 "NKC....." */ +- 0xFF,0xFF,0x0A,0x00,0x01,0x4C,0x4E,0x4B, /* 00000660 ".....LNK" */ +- 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000668 "D......." */ +- 0x0A,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41, /* 00000670 "....LNKA" */ +- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A, /* 00000678 "........" */ +- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00, /* 00000680 "...LNKB." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0B,0x00, /* 00000688 "........" */ +- 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000690 ".LNKD..." */ +- 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x01,0x4C, /* 00000698 ".......L" */ +- 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 000006A0 "NKA....." */ +- 0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x4C,0x4E, /* 000006A8 "......LN" */ +- 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 000006B0 "KB......" */ +- 0xFF,0x0B,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000006B8 ".....LNK" */ +- 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006C0 "C......." */ +- 0x0C,0x00,0x00,0x4C,0x4E,0x4B,0x41,0x00, /* 000006C8 "...LNKA." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 000006D0 "........" */ +- 0x01,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0E, /* 000006D8 ".LNKB..." */ +- 0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x02, /* 000006E0 "........" */ +- 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 000006E8 "LNKC...." */ +- 0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x4C, /* 000006F0 ".......L" */ +- 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 000006F8 "NKD....." */ +- 0xFF,0xFF,0x0D,0x00,0x00,0x4C,0x4E,0x4B, /* 00000700 ".....LNK" */ +- 0x42,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000708 "B......." */ +- 0x0D,0x00,0x01,0x4C,0x4E,0x4B,0x43,0x00, /* 00000710 "...LNKC." */ +- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 00000718 "........" */ +- 0x0A,0x02,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000720 "..LNKD.." */ +- 0x0E,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A, /* 00000728 "........" */ +- 0x03,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000730 ".LNKA..." */ +- 0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x4C, /* 00000738 ".......L" */ +- 0x4E,0x4B,0x43,0x00,0x12,0x0D,0x04,0x0C, /* 00000740 "NKC....." */ +- 0xFF,0xFF,0x0E,0x00,0x01,0x4C,0x4E,0x4B, /* 00000748 ".....LNK" */ +- 0x44,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000750 "D......." */ +- 0x0E,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x41, /* 00000758 "....LNKA" */ +- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E, /* 00000760 "........" */ +- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x42,0x00, /* 00000768 "...LNKB." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0F,0x00, /* 00000770 "........" */ +- 0x00,0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0D, /* 00000778 ".LNKD..." */ +- 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x01,0x4C, /* 00000780 ".......L" */ +- 0x4E,0x4B,0x41,0x00,0x12,0x0E,0x04,0x0C, /* 00000788 "NKA....." */ +- 0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x4C,0x4E, /* 00000790 "......LN" */ +- 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000798 "KB......" */ +- 0xFF,0x0F,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 000007A0 ".....LNK" */ +- 0x43,0x00,0x08,0x50,0x52,0x54,0x41,0x12, /* 000007A8 "C..PRTA." */ +- 0x41,0x2F,0x3C,0x12,0x0B,0x04,0x0C,0xFF, /* 000007B0 "A/<....." */ +- 0xFF,0x01,0x00,0x00,0x00,0x0A,0x14,0x12, /* 000007B8 "........" */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01, /* 000007C0 "........" */ +- 0x00,0x0A,0x15,0x12,0x0C,0x04,0x0C,0xFF, /* 000007C8 "........" */ +- 0xFF,0x01,0x00,0x0A,0x02,0x00,0x0A,0x16, /* 000007D0 "........" */ +- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 000007D8 "........" */ +- 0x0A,0x03,0x00,0x0A,0x17,0x12,0x0B,0x04, /* 000007E0 "........" */ +- 0x0C,0xFF,0xFF,0x02,0x00,0x00,0x00,0x0A, /* 000007E8 "........" */ +- 0x18,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x02, /* 000007F0 "........" */ +- 0x00,0x01,0x00,0x0A,0x19,0x12,0x0C,0x04, /* 000007F8 "........" */ +- 0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x02,0x00, /* 00000800 "........" */ +- 0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000808 "........" */ +- 0x02,0x00,0x0A,0x03,0x00,0x0A,0x1B,0x12, /* 00000810 "........" */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00, /* 00000818 "........" */ +- 0x00,0x0A,0x1C,0x12,0x0B,0x04,0x0C,0xFF, /* 00000820 "........" */ +- 0xFF,0x03,0x00,0x01,0x00,0x0A,0x1D,0x12, /* 00000828 "........" */ +- 0x0C,0x04,0x0C,0xFF,0xFF,0x03,0x00,0x0A, /* 00000830 "........" */ +- 0x02,0x00,0x0A,0x1E,0x12,0x0C,0x04,0x0C, /* 00000838 "........" */ +- 0xFF,0xFF,0x03,0x00,0x0A,0x03,0x00,0x0A, /* 00000840 "........" */ +- 0x1F,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x04, /* 00000848 "........" */ +- 0x00,0x00,0x00,0x0A,0x20,0x12,0x0B,0x04, /* 00000850 ".... ..." */ +- 0x0C,0xFF,0xFF,0x04,0x00,0x01,0x00,0x0A, /* 00000858 "........" */ +- 0x21,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x04, /* 00000860 "!......." */ +- 0x00,0x0A,0x02,0x00,0x0A,0x22,0x12,0x0C, /* 00000868 ".....".." */ +- 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x03, /* 00000870 "........" */ +- 0x00,0x0A,0x23,0x12,0x0B,0x04,0x0C,0xFF, /* 00000878 "..#....." */ +- 0xFF,0x05,0x00,0x00,0x00,0x0A,0x24,0x12, /* 00000880 "......$." */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01, /* 00000888 "........" */ +- 0x00,0x0A,0x25,0x12,0x0C,0x04,0x0C,0xFF, /* 00000890 "..%....." */ +- 0xFF,0x05,0x00,0x0A,0x02,0x00,0x0A,0x26, /* 00000898 ".......&" */ +- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 000008A0 "........" */ +- 0x0A,0x03,0x00,0x0A,0x27,0x12,0x0B,0x04, /* 000008A8 "....'..." */ +- 0x0C,0xFF,0xFF,0x06,0x00,0x00,0x00,0x0A, /* 000008B0 "........" */ +- 0x28,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x06, /* 000008B8 "(......." */ +- 0x00,0x01,0x00,0x0A,0x29,0x12,0x0C,0x04, /* 000008C0 "....)..." */ +- 0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x02,0x00, /* 000008C8 "........" */ +- 0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 000008D0 ".*......" */ +- 0x06,0x00,0x0A,0x03,0x00,0x0A,0x2B,0x12, /* 000008D8 "......+." */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00, /* 000008E0 "........" */ +- 0x00,0x0A,0x2C,0x12,0x0B,0x04,0x0C,0xFF, /* 000008E8 "..,....." */ +- 0xFF,0x07,0x00,0x01,0x00,0x0A,0x2D,0x12, /* 000008F0 "......-." */ +- 0x0C,0x04,0x0C,0xFF,0xFF,0x07,0x00,0x0A, /* 000008F8 "........" */ +- 0x02,0x00,0x0A,0x2E,0x12,0x0C,0x04,0x0C, /* 00000900 "........" */ +- 0xFF,0xFF,0x07,0x00,0x0A,0x03,0x00,0x0A, /* 00000908 "........" */ +- 0x2F,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x08, /* 00000910 "/......." */ +- 0x00,0x00,0x00,0x0A,0x11,0x12,0x0B,0x04, /* 00000918 "........" */ +- 0x0C,0xFF,0xFF,0x08,0x00,0x01,0x00,0x0A, /* 00000920 "........" */ +- 0x12,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x08, /* 00000928 "........" */ +- 0x00,0x0A,0x02,0x00,0x0A,0x13,0x12,0x0C, /* 00000930 "........" */ +- 0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x03, /* 00000938 "........" */ +- 0x00,0x0A,0x14,0x12,0x0B,0x04,0x0C,0xFF, /* 00000940 "........" */ +- 0xFF,0x09,0x00,0x00,0x00,0x0A,0x15,0x12, /* 00000948 "........" */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x01, /* 00000950 "........" */ +- 0x00,0x0A,0x16,0x12,0x0C,0x04,0x0C,0xFF, /* 00000958 "........" */ +- 0xFF,0x09,0x00,0x0A,0x02,0x00,0x0A,0x17, /* 00000960 "........" */ +- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 00000968 "........" */ +- 0x0A,0x03,0x00,0x0A,0x18,0x12,0x0B,0x04, /* 00000970 "........" */ +- 0x0C,0xFF,0xFF,0x0A,0x00,0x00,0x00,0x0A, /* 00000978 "........" */ +- 0x19,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0A, /* 00000980 "........" */ +- 0x00,0x01,0x00,0x0A,0x1A,0x12,0x0C,0x04, /* 00000988 "........" */ +- 0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x02,0x00, /* 00000990 "........" */ +- 0x0A,0x1B,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000998 "........" */ +- 0x0A,0x00,0x0A,0x03,0x00,0x0A,0x1C,0x12, /* 000009A0 "........" */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00, /* 000009A8 "........" */ +- 0x00,0x0A,0x1D,0x12,0x0B,0x04,0x0C,0xFF, /* 000009B0 "........" */ +- 0xFF,0x0B,0x00,0x01,0x00,0x0A,0x1E,0x12, /* 000009B8 "........" */ +- 0x0C,0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x0A, /* 000009C0 "........" */ +- 0x02,0x00,0x0A,0x1F,0x12,0x0C,0x04,0x0C, /* 000009C8 "........" */ +- 0xFF,0xFF,0x0B,0x00,0x0A,0x03,0x00,0x0A, /* 000009D0 "........" */ +- 0x20,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0C, /* 000009D8 " ......." */ +- 0x00,0x00,0x00,0x0A,0x21,0x12,0x0B,0x04, /* 000009E0 "....!..." */ +- 0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x00,0x0A, /* 000009E8 "........" */ +- 0x22,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0C, /* 000009F0 ""......." */ +- 0x00,0x0A,0x02,0x00,0x0A,0x23,0x12,0x0C, /* 000009F8 ".....#.." */ +- 0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x03, /* 00000A00 "........" */ +- 0x00,0x0A,0x24,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A08 "..$....." */ +- 0xFF,0x0D,0x00,0x00,0x00,0x0A,0x25,0x12, /* 00000A10 "......%." */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x01, /* 00000A18 "........" */ +- 0x00,0x0A,0x26,0x12,0x0C,0x04,0x0C,0xFF, /* 00000A20 "..&....." */ +- 0xFF,0x0D,0x00,0x0A,0x02,0x00,0x0A,0x27, /* 00000A28 ".......'" */ +- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 00000A30 "........" */ +- 0x0A,0x03,0x00,0x0A,0x28,0x12,0x0B,0x04, /* 00000A38 "....(..." */ +- 0x0C,0xFF,0xFF,0x0E,0x00,0x00,0x00,0x0A, /* 00000A40 "........" */ +- 0x29,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0E, /* 00000A48 ")......." */ +- 0x00,0x01,0x00,0x0A,0x2A,0x12,0x0C,0x04, /* 00000A50 "....*..." */ +- 0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x02,0x00, /* 00000A58 "........" */ +- 0x0A,0x2B,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A60 ".+......" */ +- 0x0E,0x00,0x0A,0x03,0x00,0x0A,0x2C,0x12, /* 00000A68 "......,." */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00, /* 00000A70 "........" */ +- 0x00,0x0A,0x2D,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A78 "..-....." */ +- 0xFF,0x0F,0x00,0x01,0x00,0x0A,0x2E,0x12, /* 00000A80 "........" */ +- 0x0C,0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x0A, /* 00000A88 "........" */ +- 0x02,0x00,0x0A,0x2F,0x12,0x0C,0x04,0x0C, /* 00000A90 ".../...." */ +- 0xFF,0xFF,0x0F,0x00,0x0A,0x03,0x00,0x0A, /* 00000A98 "........" */ +- 0x10,0x5B,0x82,0x46,0x37,0x49,0x53,0x41, /* 00000AA0 ".[.F7ISA" */ +- 0x5F,0x08,0x5F,0x41,0x44,0x52,0x0C,0x00, /* 00000AA8 "_._ADR.." */ +- 0x00,0x01,0x00,0x5B,0x80,0x50,0x49,0x52, /* 00000AB0 "...[.PIR" */ +- 0x51,0x02,0x0A,0x60,0x0A,0x04,0x10,0x2E, /* 00000AB8 "Q..`...." */ +- 0x5C,0x00,0x5B,0x81,0x29,0x5C,0x2F,0x04, /* 00000AC0 "\.[.)\/." */ +- 0x5F,0x53,0x42,0x5F,0x50,0x43,0x49,0x30, /* 00000AC8 "_SB_PCI0" */ +- 0x49,0x53,0x41,0x5F,0x50,0x49,0x52,0x51, /* 00000AD0 "ISA_PIRQ" */ +- 0x01,0x50,0x49,0x52,0x41,0x08,0x50,0x49, /* 00000AD8 ".PIRA.PI" */ +- 0x52,0x42,0x08,0x50,0x49,0x52,0x43,0x08, /* 00000AE0 "RB.PIRC." */ +- 0x50,0x49,0x52,0x44,0x08,0x5B,0x82,0x46, /* 00000AE8 "PIRD.[.F" */ +- 0x0B,0x53,0x59,0x53,0x52,0x08,0x5F,0x48, /* 00000AF0 ".SYSR._H" */ +- 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08, /* 00000AF8 "ID.A...." */ +- 0x5F,0x55,0x49,0x44,0x01,0x08,0x43,0x52, /* 00000B00 "_UID..CR" */ +- 0x53,0x5F,0x11,0x4E,0x08,0x0A,0x8A,0x47, /* 00000B08 "S_.N...G" */ +- 0x01,0x10,0x00,0x10,0x00,0x00,0x10,0x47, /* 00000B10 ".......G" */ +- 0x01,0x22,0x00,0x22,0x00,0x00,0x0C,0x47, /* 00000B18 "."."...G" */ +- 0x01,0x30,0x00,0x30,0x00,0x00,0x10,0x47, /* 00000B20 ".0.0...G" */ +- 0x01,0x44,0x00,0x44,0x00,0x00,0x1C,0x47, /* 00000B28 ".D.D...G" */ +- 0x01,0x62,0x00,0x62,0x00,0x00,0x02,0x47, /* 00000B30 ".b.b...G" */ +- 0x01,0x65,0x00,0x65,0x00,0x00,0x0B,0x47, /* 00000B38 ".e.e...G" */ +- 0x01,0x72,0x00,0x72,0x00,0x00,0x0E,0x47, /* 00000B40 ".r.r...G" */ +- 0x01,0x80,0x00,0x80,0x00,0x00,0x01,0x47, /* 00000B48 ".......G" */ +- 0x01,0x84,0x00,0x84,0x00,0x00,0x03,0x47, /* 00000B50 ".......G" */ +- 0x01,0x88,0x00,0x88,0x00,0x00,0x01,0x47, /* 00000B58 ".......G" */ +- 0x01,0x8C,0x00,0x8C,0x00,0x00,0x03,0x47, /* 00000B60 ".......G" */ +- 0x01,0x90,0x00,0x90,0x00,0x00,0x10,0x47, /* 00000B68 ".......G" */ +- 0x01,0xA2,0x00,0xA2,0x00,0x00,0x1C,0x47, /* 00000B70 ".......G" */ +- 0x01,0xE0,0x00,0xE0,0x00,0x00,0x10,0x47, /* 00000B78 ".......G" */ +- 0x01,0xA0,0x08,0xA0,0x08,0x00,0x04,0x47, /* 00000B80 ".......G" */ +- 0x01,0xC0,0x0C,0xC0,0x0C,0x00,0x10,0x47, /* 00000B88 ".......G" */ +- 0x01,0xD0,0x04,0xD0,0x04,0x00,0x02,0x79, /* 00000B90 ".......y" */ +- 0x00,0x14,0x0B,0x5F,0x43,0x52,0x53,0x00, /* 00000B98 "..._CRS." */ +- 0xA4,0x43,0x52,0x53,0x5F,0x5B,0x82,0x2B, /* 00000BA0 ".CRS_[.+" */ +- 0x50,0x49,0x43,0x5F,0x08,0x5F,0x48,0x49, /* 00000BA8 "PIC_._HI" */ +- 0x44,0x0B,0x41,0xD0,0x08,0x5F,0x43,0x52, /* 00000BB0 "D.A.._CR" */ +- 0x53,0x11,0x18,0x0A,0x15,0x47,0x01,0x20, /* 00000BB8 "S....G. " */ +- 0x00,0x20,0x00,0x01,0x02,0x47,0x01,0xA0, /* 00000BC0 ". ...G.." */ +- 0x00,0xA0,0x00,0x01,0x02,0x22,0x04,0x00, /* 00000BC8 ".....".." */ +- 0x79,0x00,0x5B,0x82,0x47,0x05,0x44,0x4D, /* 00000BD0 "y.[.G.DM" */ +- 0x41,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000BD8 "A0._HID." */ +- 0x41,0xD0,0x02,0x00,0x08,0x5F,0x43,0x52, /* 00000BE0 "A...._CR" */ +- 0x53,0x11,0x41,0x04,0x0A,0x3D,0x2A,0x10, /* 00000BE8 "S.A..=*." */ +- 0x04,0x47,0x01,0x00,0x00,0x00,0x00,0x00, /* 00000BF0 ".G......" */ +- 0x10,0x47,0x01,0x81,0x00,0x81,0x00,0x00, /* 00000BF8 ".G......" */ +- 0x03,0x47,0x01,0x87,0x00,0x87,0x00,0x00, /* 00000C00 ".G......" */ +- 0x01,0x47,0x01,0x89,0x00,0x89,0x00,0x00, /* 00000C08 ".G......" */ +- 0x03,0x47,0x01,0x8F,0x00,0x8F,0x00,0x00, /* 00000C10 ".G......" */ +- 0x01,0x47,0x01,0xC0,0x00,0xC0,0x00,0x00, /* 00000C18 ".G......" */ +- 0x20,0x47,0x01,0x80,0x04,0x80,0x04,0x00, /* 00000C20 " G......" */ +- 0x10,0x79,0x00,0x5B,0x82,0x25,0x54,0x4D, /* 00000C28 ".y.[.%TM" */ +- 0x52,0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000C30 "R_._HID." */ +- 0x41,0xD0,0x01,0x00,0x08,0x5F,0x43,0x52, /* 00000C38 "A...._CR" */ +- 0x53,0x11,0x10,0x0A,0x0D,0x47,0x01,0x40, /* 00000C40 "S....G.@" */ +- 0x00,0x40,0x00,0x00,0x04,0x22,0x01,0x00, /* 00000C48 ".@...".." */ +- 0x79,0x00,0x5B,0x82,0x25,0x52,0x54,0x43, /* 00000C50 "y.[.%RTC" */ +- 0x5F,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000C58 "_._HID.A" */ +- 0xD0,0x0B,0x00,0x08,0x5F,0x43,0x52,0x53, /* 00000C60 "...._CRS" */ +- 0x11,0x10,0x0A,0x0D,0x47,0x01,0x70,0x00, /* 00000C68 "....G.p." */ +- 0x70,0x00,0x00,0x02,0x22,0x00,0x01,0x79, /* 00000C70 "p..."..y" */ +- 0x00,0x5B,0x82,0x22,0x53,0x50,0x4B,0x52, /* 00000C78 ".[."SPKR" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000C80 "._HID.A." */ +- 0x08,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C88 "..._CRS." */ +- 0x0D,0x0A,0x0A,0x47,0x01,0x61,0x00,0x61, /* 00000C90 "...G.a.a" */ +- 0x00,0x00,0x01,0x79,0x00,0x5B,0x82,0x31, /* 00000C98 "...y.[.1" */ +- 0x50,0x53,0x32,0x4D,0x08,0x5F,0x48,0x49, /* 00000CA0 "PS2M._HI" */ +- 0x44,0x0C,0x41,0xD0,0x0F,0x13,0x08,0x5F, /* 00000CA8 "D.A...._" */ +- 0x43,0x49,0x44,0x0C,0x41,0xD0,0x0F,0x13, /* 00000CB0 "CID.A..." */ +- 0x14,0x09,0x5F,0x53,0x54,0x41,0x00,0xA4, /* 00000CB8 ".._STA.." */ +- 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000CC0 "..._CRS." */ +- 0x08,0x0A,0x05,0x22,0x00,0x10,0x79,0x00, /* 00000CC8 "..."..y." */ +- 0x5B,0x82,0x42,0x04,0x50,0x53,0x32,0x4B, /* 00000CD0 "[.B.PS2K" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000CD8 "._HID.A." */ +- 0x03,0x03,0x08,0x5F,0x43,0x49,0x44,0x0C, /* 00000CE0 "..._CID." */ +- 0x41,0xD0,0x03,0x0B,0x14,0x09,0x5F,0x53, /* 00000CE8 "A....._S" */ +- 0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F, /* 00000CF0 "TA....._" */ +- 0x43,0x52,0x53,0x11,0x18,0x0A,0x15,0x47, /* 00000CF8 "CRS....G" */ +- 0x01,0x60,0x00,0x60,0x00,0x00,0x01,0x47, /* 00000D00 ".`.`...G" */ +- 0x01,0x64,0x00,0x64,0x00,0x00,0x01,0x22, /* 00000D08 ".d.d..."" */ +- 0x02,0x00,0x79,0x00,0x5B,0x82,0x3A,0x46, /* 00000D10 "..y.[.:F" */ +- 0x44,0x43,0x30,0x08,0x5F,0x48,0x49,0x44, /* 00000D18 "DC0._HID" */ +- 0x0C,0x41,0xD0,0x07,0x00,0x14,0x09,0x5F, /* 00000D20 ".A....._" */ +- 0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 00000D28 "STA....." */ +- 0x5F,0x43,0x52,0x53,0x11,0x1B,0x0A,0x18, /* 00000D30 "_CRS...." */ +- 0x47,0x01,0xF0,0x03,0xF0,0x03,0x01,0x06, /* 00000D38 "G......." */ +- 0x47,0x01,0xF7,0x03,0xF7,0x03,0x01,0x01, /* 00000D40 "G......." */ +- 0x22,0x40,0x00,0x2A,0x04,0x00,0x79,0x00, /* 00000D48 ""@.*..y." */ +- 0x5B,0x82,0x46,0x04,0x55,0x41,0x52,0x31, /* 00000D50 "[.F.UAR1" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000D58 "._HID.A." */ +- 0x05,0x01,0x08,0x5F,0x55,0x49,0x44,0x01, /* 00000D60 "..._UID." */ +- 0x14,0x19,0x5F,0x53,0x54,0x41,0x00,0xA0, /* 00000D68 ".._STA.." */ +- 0x0D,0x93,0x5E,0x5E,0x5E,0x5E,0x55,0x41, /* 00000D70 "..^^^^UA" */ +- 0x52,0x31,0x00,0xA4,0x00,0xA1,0x04,0xA4, /* 00000D78 "R1......" */ +- 0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000D80 "..._CRS." */ +- 0x10,0x0A,0x0D,0x47,0x01,0xF8,0x03,0xF8, /* 00000D88 "...G...." */ +- 0x03,0x08,0x08,0x22,0x10,0x00,0x79,0x00, /* 00000D90 "..."..y." */ +- 0x5B,0x82,0x47,0x04,0x55,0x41,0x52,0x32, /* 00000D98 "[.G.UAR2" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000DA0 "._HID.A." */ +- 0x05,0x01,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000DA8 "..._UID." */ +- 0x02,0x14,0x19,0x5F,0x53,0x54,0x41,0x00, /* 00000DB0 "..._STA." */ +- 0xA0,0x0D,0x93,0x5E,0x5E,0x5E,0x5E,0x55, /* 00000DB8 "...^^^^U" */ +- 0x41,0x52,0x32,0x00,0xA4,0x00,0xA1,0x04, /* 00000DC0 "AR2....." */ +- 0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53, /* 00000DC8 "...._CRS" */ +- 0x11,0x10,0x0A,0x0D,0x47,0x01,0xF8,0x02, /* 00000DD0 "....G..." */ +- 0xF8,0x02,0x08,0x08,0x22,0x08,0x00,0x79, /* 00000DD8 "...."..y" */ +- 0x00,0x5B,0x82,0x36,0x4C,0x54,0x50,0x31, /* 00000DE0 ".[.6LTP1" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000DE8 "._HID.A." */ +- 0x04,0x00,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000DF0 "..._UID." */ +- 0x02,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 00000DF8 "..._STA." */ +- 0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53, /* 00000E00 "...._CRS" */ +- 0x11,0x10,0x0A,0x0D,0x47,0x01,0x78,0x03, /* 00000E08 "....G.x." */ +- 0x78,0x03,0x08,0x08,0x22,0x80,0x00,0x79, /* 00000E10 "x..."..y" */ +- 0x00, ++ 0x01,0x00,0x1E,0x50,0x4D,0x49,0x4E,0x20, /* 000000A0 "...PMIN " */ ++ 0x50,0x4C,0x45,0x4E,0x20,0x5B,0x82,0x49, /* 000000A8 "PLEN [.I" */ ++ 0x04,0x4D,0x45,0x4D,0x30,0x08,0x5F,0x48, /* 000000B0 ".MEM0._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08, /* 000000B8 "ID.A...." */ ++ 0x5F,0x43,0x52,0x53,0x11,0x33,0x0A,0x30, /* 000000C0 "_CRS.3.0" */ ++ 0x8A,0x2B,0x00,0x00,0x0D,0x03,0x00,0x00, /* 000000C8 ".+......" */ ++ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D0 "........" */ ++ 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF, /* 000000D8 "........" */ ++ 0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */ ++ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */ ++ 0x0A,0x00,0x00,0x00,0x00,0x00,0x79,0x00, /* 000000F0 "......y." */ ++ 0x5B,0x82,0x45,0xD7,0x50,0x43,0x49,0x30, /* 000000F8 "[.E.PCI0" */ ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000100 "._HID.A." */ ++ 0x0A,0x03,0x08,0x5F,0x55,0x49,0x44,0x00, /* 00000108 "..._UID." */ ++ 0x08,0x5F,0x41,0x44,0x52,0x00,0x08,0x5F, /* 00000110 "._ADR.._" */ ++ 0x42,0x42,0x4E,0x00,0x14,0x4E,0x0C,0x5F, /* 00000118 "BBN..N._" */ ++ 0x43,0x52,0x53,0x00,0x08,0x50,0x52,0x54, /* 00000120 "CRS..PRT" */ ++ 0x30,0x11,0x42,0x07,0x0A,0x6E,0x88,0x0D, /* 00000128 "0.B..n.." */ ++ 0x00,0x02,0x0E,0x00,0x00,0x00,0x00,0x00, /* 00000130 "........" */ ++ 0xFF,0x00,0x00,0x00,0x00,0x01,0x47,0x01, /* 00000138 "......G." */ ++ 0xF8,0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D, /* 00000140 "........" */ ++ 0x00,0x01,0x0C,0x03,0x00,0x00,0x00,0x00, /* 00000148 "........" */ ++ 0xF7,0x0C,0x00,0x00,0xF8,0x0C,0x88,0x0D, /* 00000150 "........" */ ++ 0x00,0x01,0x0C,0x03,0x00,0x00,0x00,0x0D, /* 00000158 "........" */ ++ 0xFF,0xFF,0x00,0x00,0x00,0xF3,0x87,0x17, /* 00000160 "........" */ ++ 0x00,0x00,0x0C,0x03,0x00,0x00,0x00,0x00, /* 00000168 "........" */ ++ 0x00,0x00,0x0A,0x00,0xFF,0xFF,0x0B,0x00, /* 00000170 "........" */ ++ 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, /* 00000178 "........" */ ++ 0x87,0x17,0x00,0x00,0x0C,0x03,0x00,0x00, /* 00000180 "........" */ ++ 0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF, /* 00000188 "........" */ ++ 0xFF,0xF4,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000190 "........" */ ++ 0x00,0x05,0x79,0x00,0x8A,0x50,0x52,0x54, /* 00000198 "..y..PRT" */ ++ 0x30,0x0A,0x5C,0x4D,0x4D,0x49,0x4E,0x8A, /* 000001A0 "0.\MMIN." */ ++ 0x50,0x52,0x54,0x30,0x0A,0x60,0x4D,0x4D, /* 000001A8 "PRT0.`MM" */ ++ 0x41,0x58,0x8A,0x50,0x52,0x54,0x30,0x0A, /* 000001B0 "AX.PRT0." */ ++ 0x68,0x4D,0x4C,0x45,0x4E,0x70,0x50,0x4D, /* 000001B8 "hMLENpPM" */ ++ 0x49,0x4E,0x4D,0x4D,0x49,0x4E,0x70,0x50, /* 000001C0 "INMMINpP" */ ++ 0x4C,0x45,0x4E,0x4D,0x4C,0x45,0x4E,0x72, /* 000001C8 "LENMLENr" */ ++ 0x4D,0x4D,0x49,0x4E,0x4D,0x4C,0x45,0x4E, /* 000001D0 "MMINMLEN" */ ++ 0x4D,0x4D,0x41,0x58,0x74,0x4D,0x4D,0x41, /* 000001D8 "MMAXtMMA" */ ++ 0x58,0x01,0x4D,0x4D,0x41,0x58,0xA4,0x50, /* 000001E0 "X.MMAX.P" */ ++ 0x52,0x54,0x30,0x08,0x42,0x55,0x46,0x41, /* 000001E8 "RT0.BUFA" */ ++ 0x11,0x09,0x0A,0x06,0x23,0x20,0x0C,0x18, /* 000001F0 "....# .." */ ++ 0x79,0x00,0x08,0x42,0x55,0x46,0x42,0x11, /* 000001F8 "y..BUFB." */ ++ 0x09,0x0A,0x06,0x23,0x00,0x00,0x18,0x79, /* 00000200 "...#...y" */ ++ 0x00,0x8B,0x42,0x55,0x46,0x42,0x01,0x49, /* 00000208 "..BUFB.I" */ ++ 0x52,0x51,0x56,0x5B,0x82,0x48,0x08,0x4C, /* 00000210 "RQV[.H.L" */ ++ 0x4E,0x4B,0x41,0x08,0x5F,0x48,0x49,0x44, /* 00000218 "NKA._HID" */ ++ 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 00000220 ".A...._U" */ ++ 0x49,0x44,0x01,0x14,0x1C,0x5F,0x53,0x54, /* 00000228 "ID..._ST" */ ++ 0x41,0x00,0x7B,0x50,0x49,0x52,0x41,0x0A, /* 00000230 "A.{PIRA." */ ++ 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 00000238 ".`...`.." */ ++ 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 00000240 "........" */ ++ 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 00000248 ".._PRS.." */ ++ 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 00000250 "BUFA.._D" */ ++ 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x41, /* 00000258 "IS.}PIRA" */ ++ 0x0A,0x80,0x50,0x49,0x52,0x41,0x14,0x1A, /* 00000260 "..PIRA.." */ ++ 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 00000268 "_CRS.{PI" */ ++ 0x52,0x41,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 00000270 "RA..`y.`" */ ++ 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 00000278 "IRQV.BUF" */ ++ 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000280 "B.._SRS." */ ++ 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 00000288 ".h.IRQ1." */ ++ 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 00000290 "IRQ1`v`p" */ ++ 0x60,0x50,0x49,0x52,0x41,0x5B,0x82,0x49, /* 00000298 "`PIRA[.I" */ ++ 0x08,0x4C,0x4E,0x4B,0x42,0x08,0x5F,0x48, /* 000002A0 ".LNKB._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 000002A8 "ID.A...." */ ++ 0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,0x1C, /* 000002B0 "_UID...." */ ++ 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 000002B8 "_STA.{PI" */ ++ 0x52,0x42,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 000002C0 "RB..`..." */ ++ 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 000002C8 "`......." */ ++ 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 000002D0 "....._PR" */ ++ 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 000002D8 "S..BUFA." */ ++ 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 000002E0 "._DIS.}P" */ ++ 0x49,0x52,0x42,0x0A,0x80,0x50,0x49,0x52, /* 000002E8 "IRB..PIR" */ ++ 0x42,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 000002F0 "B.._CRS." */ ++ 0x7B,0x50,0x49,0x52,0x42,0x0A,0x0F,0x60, /* 000002F8 "{PIRB..`" */ ++ 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000300 "y.`IRQV." */ ++ 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000308 "BUFB.._S" */ ++ 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 00000310 "RS..h.IR" */ ++ 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 00000318 "Q1.IRQ1`" */ ++ 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x42, /* 00000320 "v`p`PIRB" */ ++ 0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x43, /* 00000328 "[.I.LNKC" */ ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000330 "._HID.A." */ ++ 0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000338 "..._UID." */ ++ 0x03,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00, /* 00000340 "..._STA." */ ++ 0x7B,0x50,0x49,0x52,0x43,0x0A,0x80,0x60, /* 00000348 "{PIRC..`" */ ++ 0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A, /* 00000350 "...`...." */ ++ 0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B, /* 00000358 "........" */ ++ 0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55, /* 00000360 "_PRS..BU" */ ++ 0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53, /* 00000368 "FA.._DIS" */ ++ 0x00,0x7D,0x50,0x49,0x52,0x43,0x0A,0x80, /* 00000370 ".}PIRC.." */ ++ 0x50,0x49,0x52,0x43,0x14,0x1A,0x5F,0x43, /* 00000378 "PIRC.._C" */ ++ 0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x43, /* 00000380 "RS.{PIRC" */ ++ 0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52, /* 00000388 "..`y.`IR" */ ++ 0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14, /* 00000390 "QV.BUFB." */ ++ 0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68, /* 00000398 "._SRS..h" */ ++ 0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52, /* 000003A0 ".IRQ1.IR" */ ++ 0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50, /* 000003A8 "Q1`v`p`P" */ ++ 0x49,0x52,0x43,0x5B,0x82,0x49,0x08,0x4C, /* 000003B0 "IRC[.I.L" */ ++ 0x4E,0x4B,0x44,0x08,0x5F,0x48,0x49,0x44, /* 000003B8 "NKD._HID" */ ++ 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 000003C0 ".A...._U" */ ++ 0x49,0x44,0x0A,0x04,0x14,0x1C,0x5F,0x53, /* 000003C8 "ID...._S" */ ++ 0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x44, /* 000003D0 "TA.{PIRD" */ ++ 0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A, /* 000003D8 "..`...`." */ ++ 0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A, /* 000003E0 "........" */ ++ 0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00, /* 000003E8 "..._PRS." */ ++ 0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F, /* 000003F0 ".BUFA.._" */ ++ 0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52, /* 000003F8 "DIS.}PIR" */ ++ 0x44,0x0A,0x80,0x50,0x49,0x52,0x44,0x14, /* 00000400 "D..PIRD." */ ++ 0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50, /* 00000408 "._CRS.{P" */ ++ 0x49,0x52,0x44,0x0A,0x0F,0x60,0x79,0x01, /* 00000410 "IRD..`y." */ ++ 0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55, /* 00000418 "`IRQV.BU" */ ++ 0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53, /* 00000420 "FB.._SRS" */ ++ 0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31, /* 00000428 "..h.IRQ1" */ ++ 0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60, /* 00000430 ".IRQ1`v`" */ ++ 0x70,0x60,0x50,0x49,0x52,0x44,0x5B,0x82, /* 00000438 "p`PIRD[." */ ++ 0x3A,0x48,0x50,0x45,0x54,0x08,0x5F,0x48, /* 00000440 ":HPET._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x01,0x03,0x08, /* 00000448 "ID.A...." */ ++ 0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,0x43, /* 00000450 "_UID.._C" */ ++ 0x52,0x53,0x11,0x1F,0x0A,0x1C,0x87,0x17, /* 00000458 "RS......" */ ++ 0x00,0x00,0x0D,0x01,0x00,0x00,0x00,0x00, /* 00000460 "........" */ ++ 0x00,0x00,0xD0,0xFE,0xFF,0x03,0xD0,0xFE, /* 00000468 "........" */ ++ 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, /* 00000470 "........" */ ++ 0x79,0x00,0x14,0x16,0x5F,0x50,0x52,0x54, /* 00000478 "y..._PRT" */ ++ 0x00,0xA0,0x0A,0x50,0x49,0x43,0x44,0xA4, /* 00000480 "...PICD." */ ++ 0x50,0x52,0x54,0x41,0xA4,0x50,0x52,0x54, /* 00000488 "PRTA.PRT" */ ++ 0x50,0x08,0x50,0x52,0x54,0x50,0x12,0x49, /* 00000490 "P.PRTP.I" */ ++ 0x36,0x3C,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000498 "6<......" */ ++ 0x01,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 000004A0 "...LNKB." */ ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 000004A8 "........" */ ++ 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 000004B0 ".LNKC..." */ ++ 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02, /* 000004B8 "........" */ ++ 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000004C0 "LNKD...." */ ++ 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C, /* 000004C8 ".......L" */ ++ 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 000004D0 "NKA....." */ ++ 0xFF,0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B, /* 000004D8 ".....LNK" */ ++ 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000004E0 "C......." */ ++ 0x02,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 000004E8 "...LNKD." */ ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 000004F0 "........" */ ++ 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000004F8 "..LNKA.." */ ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000500 "........" */ ++ 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 00000508 ".LNKB..." */ ++ 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C, /* 00000510 ".......L" */ ++ 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000518 "NKD....." */ ++ 0xFF,0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B, /* 00000520 ".....LNK" */ ++ 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000528 "A......." */ ++ 0x03,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000530 "....LNKB" */ ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03, /* 00000538 "........" */ ++ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000540 "...LNKC." */ ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000548 "........" */ ++ 0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000550 ".LNKA..." */ ++ 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C, /* 00000558 ".......L" */ ++ 0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 00000560 "NKB....." */ ++ 0xFF,0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E, /* 00000568 "......LN" */ ++ 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000570 "KC......" */ ++ 0xFF,0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000578 ".....LNK" */ ++ 0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000580 "D......." */ ++ 0x05,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 00000588 "...LNKB." */ ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 00000590 "........" */ ++ 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000598 ".LNKC..." */ ++ 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02, /* 000005A0 "........" */ ++ 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000005A8 "LNKD...." */ ++ 0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03,0x4C, /* 000005B0 ".......L" */ ++ 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 000005B8 "NKA....." */ ++ 0xFF,0xFF,0x06,0x00,0x00,0x4C,0x4E,0x4B, /* 000005C0 ".....LNK" */ ++ 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000005C8 "C......." */ ++ 0x06,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 000005D0 "...LNKD." */ ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 000005D8 "........" */ ++ 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000005E0 "..LNKA.." */ ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A, /* 000005E8 "........" */ ++ 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 000005F0 ".LNKB..." */ ++ 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00,0x4C, /* 000005F8 ".......L" */ ++ 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000600 "NKD....." */ ++ 0xFF,0xFF,0x07,0x00,0x01,0x4C,0x4E,0x4B, /* 00000608 ".....LNK" */ ++ 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000610 "A......." */ ++ 0x07,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000618 "....LNKB" */ ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07, /* 00000620 "........" */ ++ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000628 "...LNKC." */ ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000630 "........" */ ++ 0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000638 ".LNKA..." */ ++ 0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01,0x4C, /* 00000640 ".......L" */ ++ 0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 00000648 "NKB....." */ ++ 0xFF,0xFF,0x08,0x00,0x0A,0x02,0x4C,0x4E, /* 00000650 "......LN" */ ++ 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000658 "KC......" */ ++ 0xFF,0x08,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000660 ".....LNK" */ ++ 0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000668 "D......." */ ++ 0x09,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 00000670 "...LNKB." */ ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 00000678 "........" */ ++ 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000680 ".LNKC..." */ ++ 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02, /* 00000688 "........" */ ++ 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000690 "LNKD...." */ ++ 0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03,0x4C, /* 00000698 ".......L" */ ++ 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 000006A0 "NKA....." */ ++ 0xFF,0xFF,0x0A,0x00,0x00,0x4C,0x4E,0x4B, /* 000006A8 ".....LNK" */ ++ 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006B0 "C......." */ ++ 0x0A,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 000006B8 "...LNKD." */ ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 000006C0 "........" */ ++ 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000006C8 "..LNKA.." */ ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A, /* 000006D0 "........" */ ++ 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 000006D8 ".LNKB..." */ ++ 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x4C, /* 000006E0 ".......L" */ ++ 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 000006E8 "NKD....." */ ++ 0xFF,0xFF,0x0B,0x00,0x01,0x4C,0x4E,0x4B, /* 000006F0 ".....LNK" */ ++ 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000006F8 "A......." */ ++ 0x0B,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000700 "....LNKB" */ ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000708 "........" */ ++ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000710 "...LNKC." */ ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000718 "........" */ ++ 0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000720 ".LNKA..." */ ++ 0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x4C, /* 00000728 ".......L" */ ++ 0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 00000730 "NKB....." */ ++ 0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x4C,0x4E, /* 00000738 "......LN" */ ++ 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000740 "KC......" */ ++ 0xFF,0x0C,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000748 ".....LNK" */ ++ 0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000750 "D......." */ ++ 0x0D,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 00000758 "...LNKB." */ ++ 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 00000760 "........" */ ++ 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000768 ".LNKC..." */ ++ 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02, /* 00000770 "........" */ ++ 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000778 "LNKD...." */ ++ 0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x4C, /* 00000780 ".......L" */ ++ 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 00000788 "NKA....." */ ++ 0xFF,0xFF,0x0E,0x00,0x00,0x4C,0x4E,0x4B, /* 00000790 ".....LNK" */ ++ 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000798 "C......." */ ++ 0x0E,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 000007A0 "...LNKD." */ ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 000007A8 "........" */ ++ 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000007B0 "..LNKA.." */ ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A, /* 000007B8 "........" */ ++ 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 000007C0 ".LNKB..." */ ++ 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x4C, /* 000007C8 ".......L" */ ++ 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 000007D0 "NKD....." */ ++ 0xFF,0xFF,0x0F,0x00,0x01,0x4C,0x4E,0x4B, /* 000007D8 ".....LNK" */ ++ 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000007E0 "A......." */ ++ 0x0F,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 000007E8 "....LNKB" */ ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F, /* 000007F0 "........" */ ++ 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 000007F8 "...LNKC." */ ++ 0x08,0x50,0x52,0x54,0x41,0x12,0x41,0x2F, /* 00000800 ".PRTA.A/" */ ++ 0x3C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01, /* 00000808 "<......." */ ++ 0x00,0x00,0x00,0x0A,0x14,0x12,0x0B,0x04, /* 00000810 "........" */ ++ 0x0C,0xFF,0xFF,0x01,0x00,0x01,0x00,0x0A, /* 00000818 "........" */ ++ 0x15,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01, /* 00000820 "........" */ ++ 0x00,0x0A,0x02,0x00,0x0A,0x16,0x12,0x0C, /* 00000828 "........" */ ++ 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03, /* 00000830 "........" */ ++ 0x00,0x0A,0x17,0x12,0x0B,0x04,0x0C,0xFF, /* 00000838 "........" */ ++ 0xFF,0x02,0x00,0x00,0x00,0x0A,0x18,0x12, /* 00000840 "........" */ ++ 0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01, /* 00000848 "........" */ ++ 0x00,0x0A,0x19,0x12,0x0C,0x04,0x0C,0xFF, /* 00000850 "........" */ ++ 0xFF,0x02,0x00,0x0A,0x02,0x00,0x0A,0x1A, /* 00000858 "........" */ ++ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000860 "........" */ ++ 0x0A,0x03,0x00,0x0A,0x1B,0x12,0x0B,0x04, /* 00000868 "........" */ ++ 0x0C,0xFF,0xFF,0x03,0x00,0x00,0x00,0x0A, /* 00000870 "........" */ ++ 0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03, /* 00000878 "........" */ ++ 0x00,0x01,0x00,0x0A,0x1D,0x12,0x0C,0x04, /* 00000880 "........" */ ++ 0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02,0x00, /* 00000888 "........" */ ++ 0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000890 "........" */ ++ 0x03,0x00,0x0A,0x03,0x00,0x0A,0x1F,0x12, /* 00000898 "........" */ ++ 0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00, /* 000008A0 "........" */ ++ 0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF, /* 000008A8 ".. ....." */ ++ 0xFF,0x04,0x00,0x01,0x00,0x0A,0x21,0x12, /* 000008B0 "......!." */ ++ 0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A, /* 000008B8 "........" */ ++ 0x02,0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C, /* 000008C0 "..."...." */ ++ 0xFF,0xFF,0x04,0x00,0x0A,0x03,0x00,0x0A, /* 000008C8 "........" */ ++ 0x23,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05, /* 000008D0 "#......." */ ++ 0x00,0x00,0x00,0x0A,0x24,0x12,0x0B,0x04, /* 000008D8 "....$..." */ ++ 0x0C,0xFF,0xFF,0x05,0x00,0x01,0x00,0x0A, /* 000008E0 "........" */ ++ 0x25,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05, /* 000008E8 "%......." */ ++ 0x00,0x0A,0x02,0x00,0x0A,0x26,0x12,0x0C, /* 000008F0 ".....&.." */ ++ 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03, /* 000008F8 "........" */ ++ 0x00,0x0A,0x27,0x12,0x0B,0x04,0x0C,0xFF, /* 00000900 "..'....." */ ++ 0xFF,0x06,0x00,0x00,0x00,0x0A,0x28,0x12, /* 00000908 "......(." */ ++ 0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01, /* 00000910 "........" */ ++ 0x00,0x0A,0x29,0x12,0x0C,0x04,0x0C,0xFF, /* 00000918 "..)....." */ ++ 0xFF,0x06,0x00,0x0A,0x02,0x00,0x0A,0x2A, /* 00000920 ".......*" */ ++ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000928 "........" */ ++ 0x0A,0x03,0x00,0x0A,0x2B,0x12,0x0B,0x04, /* 00000930 "....+..." */ ++ 0x0C,0xFF,0xFF,0x07,0x00,0x00,0x00,0x0A, /* 00000938 "........" */ ++ 0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07, /* 00000940 ",......." */ ++ 0x00,0x01,0x00,0x0A,0x2D,0x12,0x0C,0x04, /* 00000948 "....-..." */ ++ 0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02,0x00, /* 00000950 "........" */ ++ 0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000958 "........" */ ++ 0x07,0x00,0x0A,0x03,0x00,0x0A,0x2F,0x12, /* 00000960 "....../." */ ++ 0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x00, /* 00000968 "........" */ ++ 0x00,0x0A,0x11,0x12,0x0B,0x04,0x0C,0xFF, /* 00000970 "........" */ ++ 0xFF,0x08,0x00,0x01,0x00,0x0A,0x12,0x12, /* 00000978 "........" */ ++ 0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A, /* 00000980 "........" */ ++ 0x02,0x00,0x0A,0x13,0x12,0x0C,0x04,0x0C, /* 00000988 "........" */ ++ 0xFF,0xFF,0x08,0x00,0x0A,0x03,0x00,0x0A, /* 00000990 "........" */ ++ 0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09, /* 00000998 "........" */ ++ 0x00,0x00,0x00,0x0A,0x15,0x12,0x0B,0x04, /* 000009A0 "........" */ ++ 0x0C,0xFF,0xFF,0x09,0x00,0x01,0x00,0x0A, /* 000009A8 "........" */ ++ 0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09, /* 000009B0 "........" */ ++ 0x00,0x0A,0x02,0x00,0x0A,0x17,0x12,0x0C, /* 000009B8 "........" */ ++ 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03, /* 000009C0 "........" */ ++ 0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF, /* 000009C8 "........" */ ++ 0xFF,0x0A,0x00,0x00,0x00,0x0A,0x19,0x12, /* 000009D0 "........" */ ++ 0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01, /* 000009D8 "........" */ ++ 0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF, /* 000009E0 "........" */ ++ 0xFF,0x0A,0x00,0x0A,0x02,0x00,0x0A,0x1B, /* 000009E8 "........" */ ++ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 000009F0 "........" */ ++ 0x0A,0x03,0x00,0x0A,0x1C,0x12,0x0B,0x04, /* 000009F8 "........" */ ++ 0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x00,0x0A, /* 00000A00 "........" */ ++ 0x1D,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000A08 "........" */ ++ 0x00,0x01,0x00,0x0A,0x1E,0x12,0x0C,0x04, /* 00000A10 "........" */ ++ 0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x00, /* 00000A18 "........" */ ++ 0x0A,0x1F,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A20 "........" */ ++ 0x0B,0x00,0x0A,0x03,0x00,0x0A,0x20,0x12, /* 00000A28 "...... ." */ ++ 0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x00, /* 00000A30 "........" */ ++ 0x00,0x0A,0x21,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A38 "..!....." */ ++ 0xFF,0x0C,0x00,0x01,0x00,0x0A,0x22,0x12, /* 00000A40 "......"." */ ++ 0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A, /* 00000A48 "........" */ ++ 0x02,0x00,0x0A,0x23,0x12,0x0C,0x04,0x0C, /* 00000A50 "...#...." */ ++ 0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x00,0x0A, /* 00000A58 "........" */ ++ 0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000A60 "$......." */ ++ 0x00,0x00,0x00,0x0A,0x25,0x12,0x0B,0x04, /* 00000A68 "....%..." */ ++ 0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x00,0x0A, /* 00000A70 "........" */ ++ 0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000A78 "&......." */ ++ 0x00,0x0A,0x02,0x00,0x0A,0x27,0x12,0x0C, /* 00000A80 ".....'.." */ ++ 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03, /* 00000A88 "........" */ ++ 0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A90 "..(....." */ ++ 0xFF,0x0E,0x00,0x00,0x00,0x0A,0x29,0x12, /* 00000A98 "......)." */ ++ 0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01, /* 00000AA0 "........" */ ++ 0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF, /* 00000AA8 "..*....." */ ++ 0xFF,0x0E,0x00,0x0A,0x02,0x00,0x0A,0x2B, /* 00000AB0 ".......+" */ ++ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000AB8 "........" */ ++ 0x0A,0x03,0x00,0x0A,0x2C,0x12,0x0B,0x04, /* 00000AC0 "....,..." */ ++ 0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x0A, /* 00000AC8 "........" */ ++ 0x2D,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000AD0 "-......." */ ++ 0x00,0x01,0x00,0x0A,0x2E,0x12,0x0C,0x04, /* 00000AD8 "........" */ ++ 0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x00, /* 00000AE0 "........" */ ++ 0x0A,0x2F,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000AE8 "./......" */ ++ 0x0F,0x00,0x0A,0x03,0x00,0x0A,0x10,0x5B, /* 00000AF0 ".......[" */ ++ 0x82,0x46,0x37,0x49,0x53,0x41,0x5F,0x08, /* 00000AF8 ".F7ISA_." */ ++ 0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x01, /* 00000B00 "_ADR...." */ ++ 0x00,0x5B,0x80,0x50,0x49,0x52,0x51,0x02, /* 00000B08 ".[.PIRQ." */ ++ 0x0A,0x60,0x0A,0x04,0x10,0x2E,0x5C,0x00, /* 00000B10 ".`....\." */ ++ 0x5B,0x81,0x29,0x5C,0x2F,0x04,0x5F,0x53, /* 00000B18 "[.)\/._S" */ ++ 0x42,0x5F,0x50,0x43,0x49,0x30,0x49,0x53, /* 00000B20 "B_PCI0IS" */ ++ 0x41,0x5F,0x50,0x49,0x52,0x51,0x01,0x50, /* 00000B28 "A_PIRQ.P" */ ++ 0x49,0x52,0x41,0x08,0x50,0x49,0x52,0x42, /* 00000B30 "IRA.PIRB" */ ++ 0x08,0x50,0x49,0x52,0x43,0x08,0x50,0x49, /* 00000B38 ".PIRC.PI" */ ++ 0x52,0x44,0x08,0x5B,0x82,0x46,0x0B,0x53, /* 00000B40 "RD.[.F.S" */ ++ 0x59,0x53,0x52,0x08,0x5F,0x48,0x49,0x44, /* 00000B48 "YSR._HID" */ ++ 0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55, /* 00000B50 ".A...._U" */ ++ 0x49,0x44,0x01,0x08,0x43,0x52,0x53,0x5F, /* 00000B58 "ID..CRS_" */ ++ 0x11,0x4E,0x08,0x0A,0x8A,0x47,0x01,0x10, /* 00000B60 ".N...G.." */ ++ 0x00,0x10,0x00,0x00,0x10,0x47,0x01,0x22, /* 00000B68 ".....G."" */ ++ 0x00,0x22,0x00,0x00,0x0C,0x47,0x01,0x30, /* 00000B70 "."...G.0" */ ++ 0x00,0x30,0x00,0x00,0x10,0x47,0x01,0x44, /* 00000B78 ".0...G.D" */ ++ 0x00,0x44,0x00,0x00,0x1C,0x47,0x01,0x62, /* 00000B80 ".D...G.b" */ ++ 0x00,0x62,0x00,0x00,0x02,0x47,0x01,0x65, /* 00000B88 ".b...G.e" */ ++ 0x00,0x65,0x00,0x00,0x0B,0x47,0x01,0x72, /* 00000B90 ".e...G.r" */ ++ 0x00,0x72,0x00,0x00,0x0E,0x47,0x01,0x80, /* 00000B98 ".r...G.." */ ++ 0x00,0x80,0x00,0x00,0x01,0x47,0x01,0x84, /* 00000BA0 ".....G.." */ ++ 0x00,0x84,0x00,0x00,0x03,0x47,0x01,0x88, /* 00000BA8 ".....G.." */ ++ 0x00,0x88,0x00,0x00,0x01,0x47,0x01,0x8C, /* 00000BB0 ".....G.." */ ++ 0x00,0x8C,0x00,0x00,0x03,0x47,0x01,0x90, /* 00000BB8 ".....G.." */ ++ 0x00,0x90,0x00,0x00,0x10,0x47,0x01,0xA2, /* 00000BC0 ".....G.." */ ++ 0x00,0xA2,0x00,0x00,0x1C,0x47,0x01,0xE0, /* 00000BC8 ".....G.." */ ++ 0x00,0xE0,0x00,0x00,0x10,0x47,0x01,0xA0, /* 00000BD0 ".....G.." */ ++ 0x08,0xA0,0x08,0x00,0x04,0x47,0x01,0xC0, /* 00000BD8 ".....G.." */ ++ 0x0C,0xC0,0x0C,0x00,0x10,0x47,0x01,0xD0, /* 00000BE0 ".....G.." */ ++ 0x04,0xD0,0x04,0x00,0x02,0x79,0x00,0x14, /* 00000BE8 ".....y.." */ ++ 0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4,0x43, /* 00000BF0 "._CRS..C" */ ++ 0x52,0x53,0x5F,0x5B,0x82,0x2B,0x50,0x49, /* 00000BF8 "RS_[.+PI" */ ++ 0x43,0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B, /* 00000C00 "C_._HID." */ ++ 0x41,0xD0,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C08 "A.._CRS." */ ++ 0x18,0x0A,0x15,0x47,0x01,0x20,0x00,0x20, /* 00000C10 "...G. . " */ ++ 0x00,0x01,0x02,0x47,0x01,0xA0,0x00,0xA0, /* 00000C18 "...G...." */ ++ 0x00,0x01,0x02,0x22,0x04,0x00,0x79,0x00, /* 00000C20 "..."..y." */ ++ 0x5B,0x82,0x47,0x05,0x44,0x4D,0x41,0x30, /* 00000C28 "[.G.DMA0" */ ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000C30 "._HID.A." */ ++ 0x02,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C38 "..._CRS." */ ++ 0x41,0x04,0x0A,0x3D,0x2A,0x10,0x04,0x47, /* 00000C40 "A..=*..G" */ ++ 0x01,0x00,0x00,0x00,0x00,0x00,0x10,0x47, /* 00000C48 ".......G" */ ++ 0x01,0x81,0x00,0x81,0x00,0x00,0x03,0x47, /* 00000C50 ".......G" */ ++ 0x01,0x87,0x00,0x87,0x00,0x00,0x01,0x47, /* 00000C58 ".......G" */ ++ 0x01,0x89,0x00,0x89,0x00,0x00,0x03,0x47, /* 00000C60 ".......G" */ ++ 0x01,0x8F,0x00,0x8F,0x00,0x00,0x01,0x47, /* 00000C68 ".......G" */ ++ 0x01,0xC0,0x00,0xC0,0x00,0x00,0x20,0x47, /* 00000C70 "...... G" */ ++ 0x01,0x80,0x04,0x80,0x04,0x00,0x10,0x79, /* 00000C78 ".......y" */ ++ 0x00,0x5B,0x82,0x25,0x54,0x4D,0x52,0x5F, /* 00000C80 ".[.%TMR_" */ ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000C88 "._HID.A." */ ++ 0x01,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C90 "..._CRS." */ ++ 0x10,0x0A,0x0D,0x47,0x01,0x40,0x00,0x40, /* 00000C98 "...G.@.@" */ ++ 0x00,0x00,0x04,0x22,0x01,0x00,0x79,0x00, /* 00000CA0 "..."..y." */ ++ 0x5B,0x82,0x25,0x52,0x54,0x43,0x5F,0x08, /* 00000CA8 "[.%RTC_." */ ++ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B, /* 00000CB0 "_HID.A.." */ ++ 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000CB8 ".._CRS.." */ ++ 0x0A,0x0D,0x47,0x01,0x70,0x00,0x70,0x00, /* 00000CC0 "..G.p.p." */ ++ 0x00,0x02,0x22,0x00,0x01,0x79,0x00,0x5B, /* 00000CC8 ".."..y.[" */ ++ 0x82,0x22,0x53,0x50,0x4B,0x52,0x08,0x5F, /* 00000CD0 "."SPKR._" */ ++ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x08,0x00, /* 00000CD8 "HID.A..." */ ++ 0x08,0x5F,0x43,0x52,0x53,0x11,0x0D,0x0A, /* 00000CE0 "._CRS..." */ ++ 0x0A,0x47,0x01,0x61,0x00,0x61,0x00,0x00, /* 00000CE8 ".G.a.a.." */ ++ 0x01,0x79,0x00,0x5B,0x82,0x31,0x50,0x53, /* 00000CF0 ".y.[.1PS" */ ++ 0x32,0x4D,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000CF8 "2M._HID." */ ++ 0x41,0xD0,0x0F,0x13,0x08,0x5F,0x43,0x49, /* 00000D00 "A...._CI" */ ++ 0x44,0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09, /* 00000D08 "D.A....." */ ++ 0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F, /* 00000D10 "_STA...." */ ++ 0x08,0x5F,0x43,0x52,0x53,0x11,0x08,0x0A, /* 00000D18 "._CRS..." */ ++ 0x05,0x22,0x00,0x10,0x79,0x00,0x5B,0x82, /* 00000D20 "."..y.[." */ ++ 0x42,0x04,0x50,0x53,0x32,0x4B,0x08,0x5F, /* 00000D28 "B.PS2K._" */ ++ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x03,0x03, /* 00000D30 "HID.A..." */ ++ 0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0, /* 00000D38 "._CID.A." */ ++ 0x03,0x0B,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000D40 "...._STA" */ ++ 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000D48 "....._CR" */ ++ 0x53,0x11,0x18,0x0A,0x15,0x47,0x01,0x60, /* 00000D50 "S....G.`" */ ++ 0x00,0x60,0x00,0x00,0x01,0x47,0x01,0x64, /* 00000D58 ".`...G.d" */ ++ 0x00,0x64,0x00,0x00,0x01,0x22,0x02,0x00, /* 00000D60 ".d...".." */ ++ 0x79,0x00,0x5B,0x82,0x3A,0x46,0x44,0x43, /* 00000D68 "y.[.:FDC" */ ++ 0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000D70 "0._HID.A" */ ++ 0xD0,0x07,0x00,0x14,0x09,0x5F,0x53,0x54, /* 00000D78 "....._ST" */ ++ 0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000D80 "A....._C" */ ++ 0x52,0x53,0x11,0x1B,0x0A,0x18,0x47,0x01, /* 00000D88 "RS....G." */ ++ 0xF0,0x03,0xF0,0x03,0x01,0x06,0x47,0x01, /* 00000D90 "......G." */ ++ 0xF7,0x03,0xF7,0x03,0x01,0x01,0x22,0x40, /* 00000D98 "......"@" */ ++ 0x00,0x2A,0x04,0x00,0x79,0x00,0x5B,0x82, /* 00000DA0 ".*..y.[." */ ++ 0x46,0x04,0x55,0x41,0x52,0x31,0x08,0x5F, /* 00000DA8 "F.UAR1._" */ ++ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,0x01, /* 00000DB0 "HID.A..." */ ++ 0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x19, /* 00000DB8 "._UID..." */ ++ 0x5F,0x53,0x54,0x41,0x00,0xA0,0x0D,0x93, /* 00000DC0 "_STA...." */ ++ 0x5E,0x5E,0x5E,0x5E,0x55,0x41,0x52,0x31, /* 00000DC8 "^^^^UAR1" */ ++ 0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A,0x0F, /* 00000DD0 "........" */ ++ 0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A, /* 00000DD8 "._CRS..." */ ++ 0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03,0x08, /* 00000DE0 ".G......" */ ++ 0x08,0x22,0x10,0x00,0x79,0x00,0x5B,0x82, /* 00000DE8 "."..y.[." */ ++ 0x47,0x04,0x55,0x41,0x52,0x32,0x08,0x5F, /* 00000DF0 "G.UAR2._" */ ++ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,0x01, /* 00000DF8 "HID.A..." */ ++ 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14, /* 00000E00 "._UID..." */ ++ 0x19,0x5F,0x53,0x54,0x41,0x00,0xA0,0x0D, /* 00000E08 "._STA..." */ ++ 0x93,0x5E,0x5E,0x5E,0x5E,0x55,0x41,0x52, /* 00000E10 ".^^^^UAR" */ ++ 0x32,0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A, /* 00000E18 "2......." */ ++ 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000E20 ".._CRS.." */ ++ 0x0A,0x0D,0x47,0x01,0xF8,0x02,0xF8,0x02, /* 00000E28 "..G....." */ ++ 0x08,0x08,0x22,0x08,0x00,0x79,0x00,0x5B, /* 00000E30 ".."..y.[" */ ++ 0x82,0x36,0x4C,0x54,0x50,0x31,0x08,0x5F, /* 00000E38 ".6LTP1._" */ ++ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x04,0x00, /* 00000E40 "HID.A..." */ ++ 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14, /* 00000E48 "._UID..." */ ++ 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000E50 "._STA..." */ ++ 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000E58 ".._CRS.." */ ++ 0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,0x03, /* 00000E60 "..G.x.x." */ ++ 0x08,0x08,0x22,0x80,0x00,0x79,0x00, + }; + int DsdtLen=sizeof(AmlCode); diff --git a/16859-x86_emulate-clts-fix.patch b/16859-x86_emulate-clts-fix.patch new file mode 100644 index 0000000..c2b0918 --- /dev/null +++ b/16859-x86_emulate-clts-fix.patch @@ -0,0 +1,21 @@ +# HG changeset patch +# User Keir Fraser +# Date 1201096764 0 +# Node ID 7f940c605893749225a5605fb8a1fa38972bdeb6 +# Parent c364f80eb4b591f8ecd9dd803081923b94a8c688 +x86_emulate: Fix CLTS emulation. +Signed-off-by: Keir Fraser + +Index: xen-3.2-testing/xen/arch/x86/x86_emulate.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/x86_emulate.c ++++ xen-3.2-testing/xen/arch/x86/x86_emulate.c +@@ -177,7 +177,7 @@ static uint8_t opcode_table[256] = { + + static uint8_t twobyte_table[256] = { + /* 0x00 - 0x07 */ +- 0, ImplicitOps|ModRM, 0, 0, 0, ImplicitOps, 0, 0, ++ 0, ImplicitOps|ModRM, 0, 0, 0, 0, ImplicitOps, 0, + /* 0x08 - 0x0F */ + ImplicitOps, ImplicitOps, 0, 0, 0, ImplicitOps|ModRM, 0, 0, + /* 0x10 - 0x17 */ diff --git a/16929-hvm-guest-crash-fix.patch b/16929-hvm-guest-crash-fix.patch new file mode 100644 index 0000000..177911b --- /dev/null +++ b/16929-hvm-guest-crash-fix.patch @@ -0,0 +1,26 @@ +# HG changeset patch +# User Keir Fraser +# Date 1201607262 0 +# Node ID 128f7bc0a277375571b4817fc65bfcd14e00a7ec +# Parent 7aa2149a3b0e94eb01b39ae8cf4a41bc225be94e +x86: Fix HVM hypercall preemption causing guest crash. +Signed-off-by: Yu Zhao + +Index: xen-3.2-testing/xen/arch/x86/domain.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/domain.c ++++ xen-3.2-testing/xen/arch/x86/domain.c +@@ -1507,7 +1507,12 @@ unsigned long hypercall_create_continuat + { + regs = guest_cpu_user_regs(); + regs->eax = op; +- regs->eip -= 2; /* re-execute 'syscall' / 'int 0x82' */ ++ /* ++ * For PV guest, we update EIP to re-execute 'syscall' / 'int 0x82'; ++ * HVM does not need this since 'vmcall' / 'vmmcall' is fault-like. ++ */ ++ if ( !is_hvm_vcpu(current) ) ++ regs->eip -= 2; /* re-execute 'syscall' / 'int 0x82' */ + + #ifdef __x86_64__ + if ( !is_hvm_vcpu(current) ? diff --git a/16930-shadow-pinning-logic-fix.patch b/16930-shadow-pinning-logic-fix.patch new file mode 100644 index 0000000..9be4b0e --- /dev/null +++ b/16930-shadow-pinning-logic-fix.patch @@ -0,0 +1,34 @@ +# HG changeset patch +# User Keir Fraser +# Date 1201607430 0 +# Node ID 193afcdb85b211d72f940e086397490ce72f06e6 +# Parent 128f7bc0a277375571b4817fc65bfcd14e00a7ec +x86: Fix shadow pinning logic (for PV live relo). +From: Tim Deegan +Signed-off-by: Keir Fraser + +Index: xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/shadow/multi.c ++++ xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c +@@ -3518,8 +3518,18 @@ sh_set_toplevel_shadow(struct vcpu *v, + v->arch.shadow_table[slot] = new_entry; + + /* Decrement the refcount of the old contents of this slot */ +- if ( !pagetable_is_null(old_entry) ) +- sh_put_ref(v, pagetable_get_mfn(old_entry), 0); ++ if ( !pagetable_is_null(old_entry) ) { ++ mfn_t old_smfn = pagetable_get_mfn(old_entry); ++ /* Need to repin the old toplevel shadow if it's been unpinned ++ * by shadow_prealloc(): in PV mode we're still running on this ++ * shadow and it's not safe to free it yet. */ ++ if ( !mfn_to_shadow_page(old_smfn)->pinned && !sh_pin(v, old_smfn) ) ++ { ++ SHADOW_ERROR("can't re-pin %#lx\n", mfn_x(old_smfn)); ++ domain_crash(v->domain); ++ } ++ sh_put_ref(v, old_smfn, 0); ++ } + } + + diff --git a/16932-xend-hvm-localtime.patch b/16932-xend-hvm-localtime.patch new file mode 100644 index 0000000..9f3fbe2 --- /dev/null +++ b/16932-xend-hvm-localtime.patch @@ -0,0 +1,87 @@ +# HG changeset patch +# User Keir Fraser +# Date 1201619751 0 +# Node ID 04e24b9dcc1649e86d3e94a81489dab9c6ec82bc +# Parent 98c2665056ea4fe63e02c943536db686fcedc459 +xend: Obey localtime config option for HVM guests as well as PV guests. +Signed-off-by: Keir Fraser + +Index: xen-3.2-testing/tools/python/xen/lowlevel/xc/xc.c +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/lowlevel/xc/xc.c ++++ xen-3.2-testing/tools/python/xen/lowlevel/xc/xc.c +@@ -1154,23 +1154,13 @@ static PyObject *pyxc_domain_iomem_permi + static PyObject *pyxc_domain_set_time_offset(XcObject *self, PyObject *args) + { + uint32_t dom; +- int32_t time_offset_seconds; +- time_t calendar_time; +- struct tm local_time; +- struct tm utc_time; ++ int32_t offset; + +- if (!PyArg_ParseTuple(args, "i", &dom)) ++ if (!PyArg_ParseTuple(args, "ii", &dom, &offset)) + return NULL; + +- calendar_time = time(NULL); +- localtime_r(&calendar_time, &local_time); +- gmtime_r(&calendar_time, &utc_time); +- /* set up to get calendar time based on utc_time, with local dst setting */ +- utc_time.tm_isdst = local_time.tm_isdst; +- time_offset_seconds = (int32_t)difftime(calendar_time, mktime(&utc_time)); +- +- if (xc_domain_set_time_offset(self->xc_handle, dom, time_offset_seconds) != 0) +- return NULL; ++ if (xc_domain_set_time_offset(self->xc_handle, dom, offset) != 0) ++ return pyxc_error_to_exception(); + + Py_INCREF(zero); + return zero; +@@ -1619,6 +1609,7 @@ static PyMethodDef pyxc_methods[] = { + METH_VARARGS, "\n" + "Set a domain's time offset to Dom0's localtime\n" + " dom [int]: Domain whose time offset is being set.\n" ++ " offset [int]: Time offset from UTC in seconds.\n" + "Returns: [int] 0 on success; -1 on error.\n" }, + + { "domain_send_trigger", +Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -1708,10 +1708,14 @@ class XendDomainInfo: + self._configureBootloader() + + try: +- self.image = image.create(self, self.info) +- + if self.info['platform'].get('localtime', 0): +- xc.domain_set_time_offset(self.domid) ++ t = time.time() ++ loc = time.localtime(t) ++ utc = time.gmtime(t) ++ timeoffset = int(time.mktime(loc) - time.mktime(utc)) ++ self.info['platform']['rtc_timeoffset'] = timeoffset ++ ++ self.image = image.create(self, self.info) + + xc.domain_setcpuweight(self.domid, \ + self.info['vcpus_params']['weight']) +Index: xen-3.2-testing/tools/python/xen/xend/image.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.2-testing/tools/python/xen/xend/image.py +@@ -342,6 +342,12 @@ class LinuxImageHandler(ImageHandler): + flags = 0 + vhpt = 0 + ++ def configure(self, vmConfig): ++ ImageHandler.configure(self, vmConfig) ++ rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset') ++ if rtc_timeoffset is not None: ++ xc.domain_set_time_offset(self.vm.getDomid(), rtc_timeoffset) ++ + def buildDomain(self): + store_evtchn = self.vm.getStorePort() + console_evtchn = self.vm.getConsolePort() diff --git a/xen-blktab-subtype-strip.patch b/16945-blktap-strip.patch similarity index 74% rename from xen-blktab-subtype-strip.patch rename to 16945-blktap-strip.patch index 1681b53..30c582f 100644 --- a/xen-blktab-subtype-strip.patch +++ b/16945-blktap-strip.patch @@ -1,8 +1,8 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c =================================================================== ---- xen-3.2-testing.orig/tools/ioemu/xenstore.c 2008-01-31 07:52:20.000000000 -0700 -+++ xen-3.2-testing/tools/ioemu/xenstore.c 2008-01-31 07:56:00.000000000 -0700 -@@ -478,7 +478,7 @@ +--- xen-3.2-testing.orig/tools/ioemu/xenstore.c ++++ xen-3.2-testing/tools/ioemu/xenstore.c +@@ -418,7 +418,7 @@ void xenstore_record_dm_state(char *stat void xenstore_process_event(void *opaque) { @@ -11,7 +11,7 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c unsigned int len, num, hd_index; vec = xs_read_watch(xsh, &num); -@@ -505,8 +505,23 @@ +@@ -440,8 +440,23 @@ void xenstore_process_event(void *opaque goto out; hd_index = vec[XS_WATCH_TOKEN][2] - 'a'; image = xs_read(xsh, XBT_NULL, vec[XS_WATCH_PATH], &len); @@ -21,12 +21,12 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c + goto out; /* gone */ + + /* Strip off blktap sub-type prefix */ -+ bpath = strdup(vec[XS_WATCH_PATH]); ++ bpath = strdup(vec[XS_WATCH_PATH]); + if (bpath == NULL) + goto out; -+ if ((offset = strrchr(bpath, '/')) != NULL) ++ if ((offset = strrchr(bpath, '/')) != NULL) + *offset = '\0'; -+ if (pasprintf(&buf, "%s/type", bpath) == -1) ++ if (pasprintf(&buf, "%s/type", bpath) == -1) + goto out; + drv = xs_read(xsh, XBT_NULL, buf, &len); + if (drv && !strcmp(drv, "tap") && ((offset = strchr(image, ':')) != NULL)) @@ -37,7 +37,7 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c do_eject(0, vec[XS_WATCH_TOKEN]); bs_table[hd_index]->filename[0] = 0; -@@ -521,6 +536,9 @@ +@@ -456,6 +471,9 @@ void xenstore_process_event(void *opaque } out: diff --git a/16947-fvmachine-xenstore.patch b/16947-fvmachine-xenstore.patch new file mode 100644 index 0000000..a9d3e07 --- /dev/null +++ b/16947-fvmachine-xenstore.patch @@ -0,0 +1,69 @@ +Index: xen-3.2-testing/tools/ioemu/hw/xen_machine_fv.c +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/hw/xen_machine_fv.c ++++ xen-3.2-testing/tools/ioemu/hw/xen_machine_fv.c +@@ -205,6 +205,8 @@ static void xen_init_fv(uint64_t ram_siz + } + #endif + ++ xenstore_parse_domain_config(domid); ++ + xc_get_hvm_param(xc_handle, domid, HVM_PARAM_IOREQ_PFN, &ioreq_pfn); + fprintf(logfile, "shared page at pfn %lx\n", ioreq_pfn); + shared_page = xc_map_foreign_range(xc_handle, domid, XC_PAGE_SIZE, +Index: xen-3.2-testing/tools/ioemu/vl.c +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/vl.c ++++ xen-3.2-testing/tools/ioemu/vl.c +@@ -7593,7 +7593,7 @@ int main(int argc, char **argv) + #ifdef CONFIG_DM + bdrv_init(); + xc_handle = xc_interface_open(); +- xenstore_parse_domain_config(domid); ++ xenstore_daemon_open(); + #endif /* CONFIG_DM */ + + #ifdef USE_KQEMU +Index: xen-3.2-testing/tools/ioemu/vl.h +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/vl.h ++++ xen-3.2-testing/tools/ioemu/vl.h +@@ -1454,6 +1454,7 @@ void readline_start(const char *prompt, + ReadLineFunc *readline_func, void *opaque); + + /* xenstore.c */ ++void xenstore_daemon_open(void); + void xenstore_parse_domain_config(int domid); + int xenstore_fd(void); + void xenstore_process_event(void *opaque); +Index: xen-3.2-testing/tools/ioemu/xenstore.c +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/xenstore.c ++++ xen-3.2-testing/tools/ioemu/xenstore.c +@@ -77,6 +77,13 @@ static void waitForDevice(char *fn) + return; + } + ++void xenstore_daemon_open(void) ++{ ++ xsh = xs_daemon_open(); ++ if (xsh == NULL) ++ fprintf(logfile, "Could not contact xenstore for domain config\n"); ++} ++ + void xenstore_parse_domain_config(int domid) + { + char **e = NULL; +@@ -89,12 +96,6 @@ void xenstore_parse_domain_config(int do + for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) + media_filename[i] = NULL; + +- xsh = xs_daemon_open(); +- if (xsh == NULL) { +- fprintf(logfile, "Could not contact xenstore for domain config\n"); +- return; +- } +- + path = xs_get_domain_path(xsh, domid); + if (path == NULL) { + fprintf(logfile, "xs_get_domain_path() error\n"); diff --git a/16962-cross-page-write-failure.patch b/16962-cross-page-write-failure.patch new file mode 100644 index 0000000..dacc47e --- /dev/null +++ b/16962-cross-page-write-failure.patch @@ -0,0 +1,21 @@ +# HG changeset patch +# User Keir Fraser +# Date 1201864887 0 +# Node ID 3787e70b2ab219de50dff7417917fd9f9ccfcc35 +# Parent 396ab902b02daf14deed0f3261c1c179b7378b4d +x86 shadow: Fix cross-page write emulation failure. +Signed-off-by: Disheng Su + +Index: xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/shadow/multi.c ++++ xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c +@@ -4076,7 +4076,7 @@ static void *emulate_map_dest(struct vcp + sh_ctxt->mfn2 = emulate_gva_to_mfn(v, (vaddr + bytes - 1) & PAGE_MASK, + sh_ctxt); + if ( !mfn_valid(sh_ctxt->mfn2) ) +- return ((mfn_x(sh_ctxt->mfn1) == BAD_GVA_TO_GFN) ? ++ return ((mfn_x(sh_ctxt->mfn2) == BAD_GVA_TO_GFN) ? + MAPPING_EXCEPTION : MAPPING_UNHANDLEABLE); + + /* Cross-page writes mean probably not a pagetable */ diff --git a/16965-xend-leak.patch b/16965-xend-leak.patch new file mode 100644 index 0000000..86278a7 --- /dev/null +++ b/16965-xend-leak.patch @@ -0,0 +1,24 @@ +# HG changeset patch +# User Keir Fraser +# Date 1201949604 0 +# Node ID b1b93caa7d8e2414af06f06c3a9734675f715bad +# Parent 5d84464dc1fc013110c25dc0ff1f99585e699fa3 +xend: Fix grow of the LEGACY_UNSUPPORTED_BY_XENAPI_CFG list each time +we instantiate a new XendConfig. +Signed-off-by: Pascal Bouchareine + +Index: xen-3.2-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.2-testing/tools/python/xen/xend/XendConfig.py +@@ -501,8 +501,8 @@ class XendConfig(dict): + int(sxp.child_value(sxp_cfg, "cpu_cap", 0)) + + # Only extract options we know about. +- extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG +- extract_keys += XENAPI_CFG_TO_LEGACY_CFG.values() ++ extract_keys = LEGACY_UNSUPPORTED_BY_XENAPI_CFG + \ ++ XENAPI_CFG_TO_LEGACY_CFG.values() + + for key in extract_keys: + val = sxp.child_value(sxp_cfg, key) diff --git a/16976-x86_emulate-sahf-fix.patch b/16976-x86_emulate-sahf-fix.patch new file mode 100644 index 0000000..9bf981f --- /dev/null +++ b/16976-x86_emulate-sahf-fix.patch @@ -0,0 +1,22 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202207359 0 +# Node ID 32e9c52fc6d9a6104afb2dbd84a89395b16f0e34 +# Parent 99b8ffe250888d0c3fe86b726edf18f620072045 +x86_emulate: Fix SAHF emulation. +Signed-off-by: Xiaohui Xin +Signed-off-by: Kevin Tian + +Index: xen-3.2-testing/xen/arch/x86/x86_emulate.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/x86_emulate.c ++++ xen-3.2-testing/xen/arch/x86/x86_emulate.c +@@ -2176,7 +2176,7 @@ x86_emulate( + } + + case 0x9e: /* sahf */ +- *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02; ++ *(uint8_t *)&_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02; + break; + + case 0x9f: /* lahf */ diff --git a/16977-xend-restart-count.patch b/16977-xend-restart-count.patch new file mode 100644 index 0000000..1f853d6 --- /dev/null +++ b/16977-xend-restart-count.patch @@ -0,0 +1,61 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202207975 0 +# Node ID def2adbce510a31711f22cf15f5afe51f875e3ea +# Parent 32e9c52fc6d9a6104afb2dbd84a89395b16f0e34 +xend: Restore values of /vm/uuid/xend/* to recreated domains. + +When guest domains are restarted, previous values of /vm/uuid/xend/* +in xenstore are lost. (e.g. previous_restart_time, +last_shutdown_reason). This patch restores them to restarting domains. +And we should update /vm/uuid/xend/restart_count of restarting +domains, not previous domains. + +Signed-off-by: Masaki Kanno + +Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -880,6 +880,9 @@ class XendDomainInfo: + def _gatherVm(self, *args): + return xstransact.Gather(self.vmpath, *args) + ++ def _listRecursiveVm(self, *args): ++ return xstransact.ListRecursive(self.vmpath, *args) ++ + def storeVm(self, *args): + return xstransact.Store(self.vmpath, *args) + +@@ -1387,6 +1390,7 @@ class XendDomainInfo: + + self._writeVm('xend/previous_restart_time', str(now)) + ++ prev_vm_xend = self._listRecursiveVm('xend') + new_dom_info = self.info + try: + if rename: +@@ -1405,8 +1409,13 @@ class XendDomainInfo: + try: + new_dom = XendDomain.instance().domain_create_from_dict( + new_dom_info) ++ for x in prev_vm_xend[0][1]: ++ new_dom._writeVm('xend/%s' % x[0], x[1]) + new_dom.waitForDevices() + new_dom.unpause() ++ rst_cnt = new_dom._readVm('xend/restart_count') ++ rst_cnt = int(rst_cnt) + 1 ++ new_dom._writeVm('xend/restart_count', str(rst_cnt)) + new_dom._removeVm(RESTART_IN_PROGRESS) + except: + if new_dom: +@@ -1442,9 +1451,6 @@ class XendDomainInfo: + self.vmpath = XS_VMROOT + new_uuid + # Write out new vm node to xenstore + self._storeVmDetails() +- rst_cnt = self._readVm('xend/restart_count') +- rst_cnt = int(rst_cnt) + 1 +- self._writeVm('xend/restart_count', str(rst_cnt)) + self._preserve() + return new_dom_info + diff --git a/16980-x86_emulate-macro-fix.patch b/16980-x86_emulate-macro-fix.patch new file mode 100644 index 0000000..8687e33 --- /dev/null +++ b/16980-x86_emulate-macro-fix.patch @@ -0,0 +1,36 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202226659 0 +# Node ID bf4a24c172d23ae9839ee564225d49ed95167de3 +# Parent 92734271810aaa32d27fce777684649995fb1665 +x86_emulate: fix side-effect macro call. +Signed-off-by: Samuel Thibault + +Index: xen-3.2-testing/xen/arch/x86/x86_emulate.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/x86_emulate.c ++++ xen-3.2-testing/xen/arch/x86/x86_emulate.c +@@ -546,7 +546,8 @@ do { + + #define jmp_rel(rel) \ + do { \ +- _regs.eip += (int)(rel); \ ++ int _rel = (int)(rel); \ ++ _regs.eip += _rel; \ + if ( !mode_64bit() ) \ + _regs.eip = ((op_bytes == 2) \ + ? (uint16_t)_regs.eip : (uint32_t)_regs.eip); \ +@@ -2543,9 +2544,11 @@ x86_emulate( + break; + } + +- case 0xeb: /* jmp (short) */ +- jmp_rel(insn_fetch_type(int8_t)); ++ case 0xeb: /* jmp (short) */ { ++ int rel = insn_fetch_type(int8_t); ++ jmp_rel(rel); + break; ++ } + + case 0xf1: /* int1 (icebp) */ + src.val = EXC_DB; diff --git a/16988-xm-reboot.patch b/16988-xm-reboot.patch new file mode 100644 index 0000000..b6669aa --- /dev/null +++ b/16988-xm-reboot.patch @@ -0,0 +1,62 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202376466 0 +# Node ID d04593aa1605fd337423b2c1296e275424e06656 +# Parent 45b2e7d59e3a1895e903cbb7939e79c2f1f351d6 +xm reboot: Fix wait option of xm reboot command + +When I rebooted a domain by xm reboot command with wait option, +I saw the following message. But, rebooting the domain succeeded. + Domain vm1 destroyed for failed in rebooting + +The cause why the message was shown is the domain is destroyed +temporarily by processing of xm reboot command. The domain +information is not gotten from Xend by server.xend.domains() +function till recreating the domain is completed. +This patch fixes processing of xm reboot command in Xm side. +It waits just a bit till recreating the domain is completed, +then it measures the success or failure of the reboot of the +domain. + +Signed-off-by: Masaki Kanno + +diff -r 45b2e7d59e3a -r d04593aa1605 tools/python/xen/xm/shutdown.py +--- a/tools/python/xen/xm/shutdown.py Thu Feb 07 09:21:19 2008 +0000 ++++ b/tools/python/xen/xm/shutdown.py Thu Feb 07 09:27:46 2008 +0000 +@@ -23,6 +23,8 @@ from opts import * + from opts import * + from main import server, serverType, SERVER_XEN_API, get_single_vm + from xen.xend.XendAPIConstants import * ++ ++RECREATING_TIMEOUT = 30 + + gopts = Opts(use="""[options] [DOM] + +@@ -53,6 +55,7 @@ def wait_reboot(opts, doms, rcs): + if serverType == SERVER_XEN_API: + opts.err("Cannot wait for reboot w/ XenAPI (yet)") + ++ recreating = {} + while doms: + alive = server.xend.domains(0) + reboot = [] +@@ -61,9 +64,17 @@ def wait_reboot(opts, doms, rcs): + rc = server.xend.domain.getRestartCount(d) + if rc == rcs[d]: continue + reboot.append(d) ++ ++ # Probably the domain is being recreated now. ++ # We have to wait just a bit for recreating the domain. ++ elif not recreating.has_key(d): ++ recreating[d] = 0 + else: +- opts.info("Domain %s destroyed for failed in rebooting" % d) +- doms.remove(d) ++ recreating[d] += 1 ++ if recreating[d] > RECREATING_TIMEOUT: ++ opts.info("Domain %s destroyed for failing to reboot" % d) ++ doms.remove(d) ++ + for d in reboot: + opts.info("Domain %s rebooted" % d) + doms.remove(d) diff --git a/16989-xend-coredump.patch b/16989-xend-coredump.patch new file mode 100644 index 0000000..4659e58 --- /dev/null +++ b/16989-xend-coredump.patch @@ -0,0 +1,250 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202376535 0 +# Node ID 58e5e9ae0f8dcc4abb390d46d89e49c65e62607b +# Parent d04593aa1605fd337423b2c1296e275424e06656 +Add 'coredump-destroy' and 'coredump-restart' actions for crashed domains. + +Xen-API already specifies these actions for the 'on_crash' domain exit +event. This patch makes them available for use in traditional domU +config files and through the xm tool as well. + +Signed-off-by: Jim Fehlig + +Index: xen-3.2-testing/docs/man/xmdomain.cfg.pod.5 +=================================================================== +--- xen-3.2-testing.orig/docs/man/xmdomain.cfg.pod.5 ++++ xen-3.2-testing/docs/man/xmdomain.cfg.pod.5 +@@ -298,6 +298,22 @@ it holds, so that the new one may take t + + =back + ++=over 4 ++ ++Additionally, the "on_crash" event can also take: ++ ++=item B ++ ++Dump the crashed domain's core and then destroy it. ++ ++=back ++ ++=item B ++ ++Dump the crashed domain's core and then restart it. ++ ++=back ++ + =head1 EXAMPLES + + The following are quick examples of ways that domains might be +Index: xen-3.2-testing/tools/examples/xmexample.hvm +=================================================================== +--- xen-3.2-testing.orig/tools/examples/xmexample.hvm ++++ xen-3.2-testing/tools/examples/xmexample.hvm +@@ -87,6 +87,11 @@ disk = [ 'file:/var/images/min-el3-i386. + # "rename-restart", meaning that the old domain is not cleaned up, but is + # renamed and a new domain started in its place. + # ++# In the event a domain stops due to a crash, you have the additional options: ++# ++# "coredump-destroy", meaning dump the crashed domain's core and then destroy; ++# "coredump-restart', meaning dump the crashed domain's core and the restart. ++# + # The default is + # + # on_poweroff = 'destroy' +Index: xen-3.2-testing/tools/examples/xmexample1 +=================================================================== +--- xen-3.2-testing.orig/tools/examples/xmexample1 ++++ xen-3.2-testing/tools/examples/xmexample1 +@@ -155,6 +155,11 @@ extra = "4" + # "rename-restart", meaning that the old domain is not cleaned up, but is + # renamed and a new domain started in its place. + # ++# In the event a domain stops due to a crash, you have the additional options: ++# ++# "coredump-destroy", meaning dump the crashed domain's core and then destroy; ++# "coredump-restart', meaning dump the crashed domain's core and the restart. ++# + # The default is + # + # on_poweroff = 'destroy' +Index: xen-3.2-testing/tools/examples/xmexample2 +=================================================================== +--- xen-3.2-testing.orig/tools/examples/xmexample2 ++++ xen-3.2-testing/tools/examples/xmexample2 +@@ -191,6 +191,11 @@ extra = "4 VMID=%d usr=/dev/sda6" % vmid + # "rename-restart", meaning that the old domain is not cleaned up, but is + # renamed and a new domain started in its place. + # ++# In the event a domain stops due to a crash, you have the additional options: ++# ++# "coredump-destroy", meaning dump the crashed domain's core and then destroy; ++# "coredump-restart', meaning dump the crashed domain's core and the restart. ++# + # The default is + # + # on_poweroff = 'destroy' +Index: xen-3.2-testing/tools/examples/xmexample3 +=================================================================== +--- xen-3.2-testing.orig/tools/examples/xmexample3 ++++ xen-3.2-testing/tools/examples/xmexample3 +@@ -177,6 +177,11 @@ extra = "4 VMID=%d" % vmid + # "rename-restart", meaning that the old domain is not cleaned up, but is + # renamed and a new domain started in its place. + # ++# In the event a domain stops due to a crash, you have the additional options: ++# ++# "coredump-destroy", meaning dump the crashed domain's core and then destroy; ++# "coredump-restart', meaning dump the crashed domain's core and the restart. ++# + # The default is + # + # on_poweroff = 'destroy' +Index: xen-3.2-testing/tools/python/xen/xend/XendAPIConstants.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendAPIConstants.py ++++ xen-3.2-testing/tools/python/xen/xend/XendAPIConstants.py +@@ -51,6 +51,18 @@ XEN_API_ON_CRASH_BEHAVIOUR = [ + 'rename_restart' + ] + ++XEN_API_ON_CRASH_BEHAVIOUR_FILTER = { ++ 'destroy' : 'destroy', ++ 'coredump-destroy' : 'coredump_and_destroy', ++ 'coredump_and_destroy' : 'coredump_and_destroy', ++ 'restart' : 'restart', ++ 'coredump-restart' : 'coredump_and_restart', ++ 'coredump_and_restart' : 'coredump_and_restart', ++ 'preserve' : 'preserve', ++ 'rename-restart' : 'rename_restart', ++ 'rename_restart' : 'rename_restart', ++} ++ + XEN_API_VBD_MODE = ['RO', 'RW'] + XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral'] + XEN_API_VBD_TYPE = ['CD', 'Disk'] +Index: xen-3.2-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.2-testing/tools/python/xen/xend/XendConfig.py +@@ -241,7 +241,8 @@ LEGACY_XENSTORE_VM_PARAMS = [ + ## Config Choices + ## + +-CONFIG_RESTART_MODES = ('restart', 'destroy', 'preserve', 'rename-restart') ++CONFIG_RESTART_MODES = ('restart', 'destroy', 'preserve', 'rename-restart', ++ 'coredump-destroy', 'coredump-restart') + CONFIG_OLD_DOM_STATES = ('running', 'blocked', 'paused', 'shutdown', + 'crashed', 'dying') + +Index: xen-3.2-testing/tools/python/xen/xend/XendConstants.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendConstants.py ++++ xen-3.2-testing/tools/python/xen/xend/XendConstants.py +@@ -52,7 +52,9 @@ restart_modes = [ + "restart", + "destroy", + "preserve", +- "rename-restart" ++ "rename-restart", ++ "coredump-destroy", ++ "coredump-restart" + ] + + DOM_STATES = [ +Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -1257,14 +1257,6 @@ class XendDomainInfo: + self.info['name_label'], self.domid) + self._writeVm(LAST_SHUTDOWN_REASON, 'crash') + +- if xoptions.get_enable_dump(): +- try: +- self.dumpCore() +- except XendError: +- # This error has been logged -- there's nothing more +- # we can do in this context. +- pass +- + restart_reason = 'crash' + self._stateSet(DOM_STATE_HALTED) + +@@ -1332,14 +1324,30 @@ class XendDomainInfo: + def _clearRestart(self): + self._removeDom("xend/shutdown_start_time") + ++ def _maybeDumpCore(self, reason): ++ if reason == 'crash': ++ if xoptions.get_enable_dump() or self.get_on_crash() \ ++ in ['coredump_and_destroy', 'coredump_and_restart']: ++ try: ++ self.dumpCore() ++ except XendError: ++ # This error has been logged -- there's nothing more ++ # we can do in this context. ++ pass + + def _maybeRestart(self, reason): ++ # Before taking configured action, dump core if configured to do so. ++ # ++ self._maybeDumpCore(reason) ++ + # Dispatch to the correct method based upon the configured on_{reason} + # behaviour. + actions = {"destroy" : self.destroy, + "restart" : self._restart, + "preserve" : self._preserve, +- "rename-restart" : self._renameRestart} ++ "rename-restart" : self._renameRestart, ++ "coredump-destroy" : self.destroy, ++ "coredump-restart" : self._restart} + + action_conf = { + 'poweroff': 'actions_after_shutdown', +@@ -2551,9 +2559,10 @@ class XendDomainInfo: + + def get_on_crash(self): + after_crash = self.info.get('actions_after_crash') +- if not after_crash or after_crash not in XEN_API_ON_CRASH_BEHAVIOUR: ++ if not after_crash or after_crash not in \ ++ XEN_API_ON_CRASH_BEHAVIOUR + restart_modes: + return XEN_API_ON_CRASH_BEHAVIOUR[0] +- return after_crash ++ return XEN_API_ON_CRASH_BEHAVIOUR_FILTER[after_crash] + + def get_dev_config_by_uuid(self, dev_class, dev_uuid): + """ Get's a device configuration either from XendConfig or +Index: xen-3.2-testing/tools/python/xen/xm/create.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xm/create.py ++++ xen-3.2-testing/tools/python/xen/xm/create.py +@@ -260,15 +260,17 @@ gopts.var('on_reboot', val='destroy|rest + renamed and a new domain started in its place. + """) + +-gopts.var('on_crash', val='destroy|restart|preserve|rename-restart', ++gopts.var('on_crash', val='destroy|restart|preserve|rename-restart|coredump-destroy|ciredump-restart', + fn=set_value, default=None, +- use="""Behaviour when a domain exits with reason 'crash'. +- - destroy: the domain is cleaned up as normal; +- - restart: a new domain is started in place of the old one; +- - preserve: no clean-up is done until the domain is manually +- destroyed (using xm destroy, for example); +- - rename-restart: the old domain is not cleaned up, but is +- renamed and a new domain started in its place. ++ use="""Behaviour when a domain exits with reason 'crash'. ++ - destroy: the domain is cleaned up as normal; ++ - restart: a new domain is started in place of the old one; ++ - preserve: no clean-up is done until the domain is manually ++ destroyed (using xm destroy, for example); ++ - rename-restart: the old domain is not cleaned up, but is ++ renamed and a new domain started in its place. ++ - coredump-destroy: dump the domain's core, followed by destroy ++ - coredump-restart: dump the domain's core, followed by restart + """) + + gopts.var('blkif', val='no|yes', diff --git a/16995-x86_emulate-mul-fix.patch b/16995-x86_emulate-mul-fix.patch new file mode 100644 index 0000000..8e9c449 --- /dev/null +++ b/16995-x86_emulate-mul-fix.patch @@ -0,0 +1,35 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202407244 0 +# Node ID 445edf4089a3ccaca977665423e903b5300832cb +# Parent e6cf98edf0c573d86c59863c6b861f9a4d6350c3 +x86_emulate: Fix MUL emulation. +Signed-off-by: Keir Fraser + +Index: xen-3.2-testing/xen/arch/x86/x86_emulate.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/x86_emulate.c ++++ xen-3.2-testing/xen/arch/x86/x86_emulate.c +@@ -1547,11 +1547,14 @@ x86_emulate( + switch ( src.bytes ) + { + case 1: ++ dst.val = (uint8_t)dst.val; + dst.val *= src.val; + if ( (uint8_t)dst.val != (uint16_t)dst.val ) + _regs.eflags |= EFLG_OF|EFLG_CF; ++ dst.bytes = 2; + break; + case 2: ++ dst.val = (uint16_t)dst.val; + dst.val *= src.val; + if ( (uint16_t)dst.val != (uint32_t)dst.val ) + _regs.eflags |= EFLG_OF|EFLG_CF; +@@ -1559,6 +1562,7 @@ x86_emulate( + break; + #ifdef __x86_64__ + case 4: ++ dst.val = (uint32_t)dst.val; + dst.val *= src.val; + if ( (uint32_t)dst.val != dst.val ) + _regs.eflags |= EFLG_OF|EFLG_CF; diff --git a/16998-x86_emulate-imul-fix.patch b/16998-x86_emulate-imul-fix.patch new file mode 100644 index 0000000..3b37ef0 --- /dev/null +++ b/16998-x86_emulate-imul-fix.patch @@ -0,0 +1,20 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202412636 0 +# Node ID 1b750b9cf4319c076bb831d26dcdcffbd5cfb913 +# Parent 8e4cd0658c4152a02576892e895e63772bd9df1c +x86_emulate: Fix IMUL r/m8 emulation. +Signed-off-by: Keir Fraser + +Index: xen-3.2-testing/xen/arch/x86/x86_emulate.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/x86_emulate.c ++++ xen-3.2-testing/xen/arch/x86/x86_emulate.c +@@ -1592,6 +1592,7 @@ x86_emulate( + (uint16_t)(int8_t)dst.val); + if ( (int8_t)dst.val != (uint16_t)dst.val ) + _regs.eflags |= EFLG_OF|EFLG_CF; ++ dst.bytes = 2; + break; + case 2: + dst.val = ((uint32_t)(int16_t)src.val * diff --git a/17003-qemu-queue-mouse.patch b/17003-qemu-queue-mouse.patch new file mode 100644 index 0000000..063875c --- /dev/null +++ b/17003-qemu-queue-mouse.patch @@ -0,0 +1,197 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202723858 0 +# Node ID 96b418cf047e6d869740efd3660ab175303a3148 +# Parent c68ce89542c7fbba9d00fd3a7d4e190476554e55 +qemu: Queue mouse clicks. + +qemu doesn't enqueue mouse events, just records the latest mouse +state. This can cause some lost mouse double clicks if the events are +not processed fast enought. This patch implements a simple queue for +left mouse click events. + +Signed-off-by: Stefano Stabellini + +diff -r c68ce89542c7 -r 96b418cf047e tools/ioemu/hw/usb-hid.c +--- a/tools/ioemu/hw/usb-hid.c Mon Feb 11 09:47:19 2008 +0000 ++++ b/tools/ioemu/hw/usb-hid.c Mon Feb 11 09:57:38 2008 +0000 +@@ -224,15 +224,37 @@ static const uint8_t qemu_tablet_hid_rep + 0xC0, /* End Collection */ + }; + ++static int currentbutton = 0; ++typedef struct _mouseclick { ++ int button_state; ++ struct _mouseclick *next; ++} mouseclick; ++static mouseclick mousequeue[20]; ++static mouseclick *head = mousequeue; ++static mouseclick *tail = mousequeue; ++ + static void usb_mouse_event(void *opaque, + int dx1, int dy1, int dz1, int buttons_state) + { + USBMouseState *s = opaque; ++ ++ if (s->status_changed == 1){ ++ //A mouse event is lost ++ if (buttons_state != currentbutton && tail->next != head) { ++ //A left click event is lost: let's add it to the queue ++ //counter++; ++ tail->button_state = buttons_state; ++ tail = tail->next; ++ } ++ } ++ else { ++ s->buttons_state = buttons_state; ++ } + + s->dx += dx1; + s->dy += dy1; + s->dz += dz1; +- s->buttons_state = buttons_state; ++ currentbutton = buttons_state; + s->status_changed = 1; + } + +@@ -240,11 +262,24 @@ static void usb_tablet_event(void *opaqu + int x, int y, int dz, int buttons_state) + { + USBMouseState *s = opaque; ++ ++ if (s->status_changed == 1){ ++ //A mouse event is lost ++ if (buttons_state != currentbutton && tail->next != head) { ++ //A left click event is lost: let's add it to the queue ++ //counter++; ++ tail->button_state = buttons_state; ++ tail = tail->next; ++ } ++ } ++ else { ++ s->buttons_state = buttons_state; ++ } + + s->x = x; + s->y = y; + s->dz += dz; +- s->buttons_state = buttons_state; ++ currentbutton = buttons_state; + s->status_changed = 1; + } + +@@ -493,10 +528,17 @@ static int usb_mouse_handle_data(USBDevi + else if (s->kind == USB_TABLET) + ret = usb_tablet_poll(s, p->data, p->len); + +- if (!s->status_changed) ++ if (!s->status_changed) { + ret = USB_RET_NAK; +- else +- s->status_changed = 0; ++ } else { ++ if (head != tail) { ++ s->buttons_state = head->button_state; ++ head = head->next; ++ } ++ else { ++ s->status_changed = 0; ++ } ++ } + + } else { + goto fail; +@@ -567,6 +609,14 @@ USBDevice *usb_tablet_init(void) + USBDevice *usb_tablet_init(void) + { + USBMouseState *s; ++ int i; ++ ++ for (i = 0; i < 19; i++) { ++ mousequeue[i].button_state = 0; ++ mousequeue[i].next = &(mousequeue[i + 1]); ++ } ++ mousequeue[i].button_state = 0; ++ mousequeue[i].next = mousequeue; + + s = qemu_mallocz(sizeof(USBMouseState)); + if (!s) +@@ -591,6 +641,14 @@ USBDevice *usb_mouse_init(void) + USBDevice *usb_mouse_init(void) + { + USBMouseState *s; ++ int i; ++ ++ for (i = 0; i < 19; i++) { ++ mousequeue[i].button_state = 0; ++ mousequeue[i].next = &(mousequeue[i + 1]); ++ } ++ mousequeue[i].button_state = 0; ++ mousequeue[i].next = mousequeue; + + s = qemu_mallocz(sizeof(USBMouseState)); + if (!s) +diff -r c68ce89542c7 -r 96b418cf047e tools/ioemu/sdl.c +--- a/tools/ioemu/sdl.c Mon Feb 11 09:47:19 2008 +0000 ++++ b/tools/ioemu/sdl.c Mon Feb 11 09:57:38 2008 +0000 +@@ -259,11 +259,9 @@ static void sdl_grab_end(void) + sdl_update_caption(); + } + +-static void sdl_send_mouse_event(int dz) +-{ +- int dx, dy, state, buttons; +- state = SDL_GetRelativeMouseState(&dx, &dy); +- buttons = 0; ++static void sdl_send_mouse_event(int dx, int dy, int dz, int state) ++{ ++ int buttons = 0; + if (state & SDL_BUTTON(SDL_BUTTON_LEFT)) + buttons |= MOUSE_EVENT_LBUTTON; + if (state & SDL_BUTTON(SDL_BUTTON_RIGHT)) +@@ -425,11 +423,19 @@ static void sdl_refresh(DisplayState *ds + case SDL_MOUSEMOTION: + if (gui_grab || kbd_mouse_is_absolute() || + absolute_enabled) { +- sdl_send_mouse_event(0); ++ int dx, dy, state; ++ state = SDL_GetRelativeMouseState(&dx, &dy); ++ sdl_send_mouse_event(dx, dy, 0, state); ++ } ++ break; ++ case SDL_MOUSEBUTTONUP: ++ if (gui_grab || kbd_mouse_is_absolute()) { ++ int dx, dy, state; ++ state = SDL_GetRelativeMouseState(&dx, &dy); ++ sdl_send_mouse_event(dx, dy, 0, state); + } + break; + case SDL_MOUSEBUTTONDOWN: +- case SDL_MOUSEBUTTONUP: + { + SDL_MouseButtonEvent *bev = &ev->button; + if (!gui_grab && !kbd_mouse_is_absolute()) { +@@ -439,16 +445,19 @@ static void sdl_refresh(DisplayState *ds + sdl_grab_start(); + } + } else { +- int dz; ++ int dx, dy, dz, state; + dz = 0; ++ state = SDL_GetRelativeMouseState(&dx, &dy); + #ifdef SDL_BUTTON_WHEELUP +- if (bev->button == SDL_BUTTON_WHEELUP && ev->type == SDL_MOUSEBUTTONDOWN) { ++ if (bev->button == SDL_BUTTON_WHEELUP) { + dz = -1; +- } else if (bev->button == SDL_BUTTON_WHEELDOWN && ev->type == SDL_MOUSEBUTTONDOWN) { ++ } else if (bev->button == SDL_BUTTON_WHEELDOWN) { + dz = 1; ++ } else { ++ state = bev->button | state; + } + #endif +- sdl_send_mouse_event(dz); ++ sdl_send_mouse_event(dx, dy, dz, state); + } + } + break; diff --git a/17017-hpet-configuration.patch b/17017-hpet-configuration.patch new file mode 100644 index 0000000..216e5c7 --- /dev/null +++ b/17017-hpet-configuration.patch @@ -0,0 +1,1134 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202741129 0 +# Node ID 209512f6d89c0650d065fad4f70a8a39a46b8460 +# Parent 17020f4eb0aaa2a3ee183696569abda065b27a3d +x86 hvm: Allow HPET to be configured as a per-domain config option. + +A new platform variable 'hpet' is added, which defaults to 0 for new +guests (that is, hpet disabled). Default is off (no hpet) because +hpet is currently less accurate in keeping time than PIT (because no +timer_mode adjustments). + +Signed-off-by: Dan Magenheimer +Signed-off-by: Keir Fraser + +Index: xen-3.2-testing/tools/firmware/hvmloader/acpi/build.c +=================================================================== +--- xen-3.2-testing.orig/tools/firmware/hvmloader/acpi/build.c ++++ xen-3.2-testing/tools/firmware/hvmloader/acpi/build.c +@@ -62,11 +62,18 @@ static int uart_exists(uint16_t uart_bas + return ((b == 0) && (c == 0xf)); + } + ++static int hpet_exists(unsigned long hpet_base) ++{ ++ uint32_t hpet_id = *(uint32_t *)hpet_base; ++ return ((hpet_id >> 16) == 0x8086); ++} ++ + static int construct_bios_info_table(uint8_t *buf) + { + struct bios_info { + uint8_t com1_present:1; + uint8_t com2_present:1; ++ uint8_t hpet_present:1; + uint32_t pci_min, pci_len; + } *bios_info = (struct bios_info *)buf; + +@@ -75,6 +82,8 @@ static int construct_bios_info_table(uin + bios_info->com1_present = uart_exists(0x3f8); + bios_info->com2_present = uart_exists(0x2f8); + ++ bios_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS); ++ + bios_info->pci_min = 0xf0000000; + bios_info->pci_len = 0x05000000; + +@@ -272,9 +281,12 @@ static int construct_secondary_tables(ui + } + + /* HPET. */ +- hpet = (struct acpi_20_hpet *)&buf[offset]; +- offset += construct_hpet(hpet); +- table_ptrs[nr_tables++] = (unsigned long)hpet; ++ if ( hpet_exists(ACPI_HPET_ADDRESS) ) ++ { ++ hpet = (struct acpi_20_hpet *)&buf[offset]; ++ offset += construct_hpet(hpet); ++ table_ptrs[nr_tables++] = (unsigned long)hpet; ++ } + + /* Processor Object SSDT. */ + table_ptrs[nr_tables++] = (unsigned long)&buf[offset]; +Index: xen-3.2-testing/tools/firmware/hvmloader/acpi/dsdt.asl +=================================================================== +--- xen-3.2-testing.orig/tools/firmware/hvmloader/acpi/dsdt.asl ++++ xen-3.2-testing/tools/firmware/hvmloader/acpi/dsdt.asl +@@ -49,6 +49,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, + Field(BIOS, ByteAcc, NoLock, Preserve) { + UAR1, 1, + UAR2, 1, ++ HPET, 1, + Offset(4), + PMIN, 32, + PLEN, 32 +@@ -296,6 +297,13 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, + Device(HPET) { + Name(_HID, EISAID("PNP0103")) + Name(_UID, 0) ++ Method (_STA, 0, NotSerialized) { ++ If(LEqual(\_SB.HPET, 0)) { ++ Return(0x00) ++ } Else { ++ Return(0x0F) ++ } ++ } + Name(_CRS, ResourceTemplate() { + DWordMemory( + ResourceConsumer, PosDecode, MinFixed, MaxFixed, +Index: xen-3.2-testing/tools/firmware/hvmloader/acpi/dsdt.c +=================================================================== +--- xen-3.2-testing.orig/tools/firmware/hvmloader/acpi/dsdt.c ++++ xen-3.2-testing/tools/firmware/hvmloader/acpi/dsdt.c +@@ -5,15 +5,15 @@ + * Copyright (C) 2000 - 2006 Intel Corporation + * Supports ACPI Specification Revision 3.0a + * +- * Compilation of "dsdt.asl" - Mon Jan 21 14:11:31 2008 ++ * Compilation of "dsdt.asl" - Mon Feb 11 13:31:53 2008 + * + * C source code output + * + */ + unsigned char AmlCode[] = + { +- 0x44,0x53,0x44,0x54,0x6F,0x0E,0x00,0x00, /* 00000000 "DSDTo..." */ +- 0x02,0xE1,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 "..Xen..." */ ++ 0x44,0x53,0x44,0x54,0x8E,0x0E,0x00,0x00, /* 00000000 "DSDT...." */ ++ 0x02,0x6E,0x58,0x65,0x6E,0x00,0x00,0x00, /* 00000008 ".nXen..." */ + 0x48,0x56,0x4D,0x00,0x00,0x00,0x00,0x00, /* 00000010 "HVM....." */ + 0x00,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C, /* 00000018 "....INTL" */ + 0x07,0x07,0x06,0x20,0x08,0x50,0x4D,0x42, /* 00000020 "... .PMB" */ +@@ -27,452 +27,456 @@ unsigned char AmlCode[] = + 0x04,0x0A,0x07,0x0A,0x07,0x00,0x00,0x08, /* 00000060 "........" */ + 0x50,0x49,0x43,0x44,0x00,0x14,0x0C,0x5F, /* 00000068 "PICD..._" */ + 0x50,0x49,0x43,0x01,0x70,0x68,0x50,0x49, /* 00000070 "PIC.phPI" */ +- 0x43,0x44,0x10,0x44,0xDF,0x5F,0x53,0x42, /* 00000078 "CD.D._SB" */ ++ 0x43,0x44,0x10,0x43,0xE1,0x5F,0x53,0x42, /* 00000078 "CD.C._SB" */ + 0x5F,0x5B,0x80,0x42,0x49,0x4F,0x53,0x00, /* 00000080 "_[.BIOS." */ + 0x0C,0x00,0xA0,0x0E,0x00,0x0A,0x10,0x5B, /* 00000088 ".......[" */ +- 0x81,0x1C,0x42,0x49,0x4F,0x53,0x01,0x55, /* 00000090 "..BIOS.U" */ ++ 0x81,0x21,0x42,0x49,0x4F,0x53,0x01,0x55, /* 00000090 ".!BIOS.U" */ + 0x41,0x52,0x31,0x01,0x55,0x41,0x52,0x32, /* 00000098 "AR1.UAR2" */ +- 0x01,0x00,0x1E,0x50,0x4D,0x49,0x4E,0x20, /* 000000A0 "...PMIN " */ +- 0x50,0x4C,0x45,0x4E,0x20,0x5B,0x82,0x49, /* 000000A8 "PLEN [.I" */ +- 0x04,0x4D,0x45,0x4D,0x30,0x08,0x5F,0x48, /* 000000B0 ".MEM0._H" */ +- 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x02,0x08, /* 000000B8 "ID.A...." */ +- 0x5F,0x43,0x52,0x53,0x11,0x33,0x0A,0x30, /* 000000C0 "_CRS.3.0" */ +- 0x8A,0x2B,0x00,0x00,0x0D,0x03,0x00,0x00, /* 000000C8 ".+......" */ +- 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D0 "........" */ +- 0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF, /* 000000D8 "........" */ +- 0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E0 "........" */ ++ 0x01,0x48,0x50,0x45,0x54,0x01,0x00,0x1D, /* 000000A0 ".HPET..." */ ++ 0x50,0x4D,0x49,0x4E,0x20,0x50,0x4C,0x45, /* 000000A8 "PMIN PLE" */ ++ 0x4E,0x20,0x5B,0x82,0x49,0x04,0x4D,0x45, /* 000000B0 "N [.I.ME" */ ++ 0x4D,0x30,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 000000B8 "M0._HID." */ ++ 0x41,0xD0,0x0C,0x02,0x08,0x5F,0x43,0x52, /* 000000C0 "A...._CR" */ ++ 0x53,0x11,0x33,0x0A,0x30,0x8A,0x2B,0x00, /* 000000C8 "S.3.0.+." */ ++ 0x00,0x0D,0x03,0x00,0x00,0x00,0x00,0x00, /* 000000D0 "........" */ ++ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000D8 "........" */ ++ 0x00,0x00,0x00,0xFF,0xFF,0x09,0x00,0x00, /* 000000E0 "........" */ + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 000000E8 "........" */ +- 0x0A,0x00,0x00,0x00,0x00,0x00,0x79,0x00, /* 000000F0 "......y." */ +- 0x5B,0x82,0x45,0xD7,0x50,0x43,0x49,0x30, /* 000000F8 "[.E.PCI0" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000100 "._HID.A." */ +- 0x0A,0x03,0x08,0x5F,0x55,0x49,0x44,0x00, /* 00000108 "..._UID." */ +- 0x08,0x5F,0x41,0x44,0x52,0x00,0x08,0x5F, /* 00000110 "._ADR.._" */ +- 0x42,0x42,0x4E,0x00,0x14,0x4E,0x0C,0x5F, /* 00000118 "BBN..N._" */ +- 0x43,0x52,0x53,0x00,0x08,0x50,0x52,0x54, /* 00000120 "CRS..PRT" */ +- 0x30,0x11,0x42,0x07,0x0A,0x6E,0x88,0x0D, /* 00000128 "0.B..n.." */ +- 0x00,0x02,0x0E,0x00,0x00,0x00,0x00,0x00, /* 00000130 "........" */ +- 0xFF,0x00,0x00,0x00,0x00,0x01,0x47,0x01, /* 00000138 "......G." */ +- 0xF8,0x0C,0xF8,0x0C,0x01,0x08,0x88,0x0D, /* 00000140 "........" */ +- 0x00,0x01,0x0C,0x03,0x00,0x00,0x00,0x00, /* 00000148 "........" */ +- 0xF7,0x0C,0x00,0x00,0xF8,0x0C,0x88,0x0D, /* 00000150 "........" */ +- 0x00,0x01,0x0C,0x03,0x00,0x00,0x00,0x0D, /* 00000158 "........" */ +- 0xFF,0xFF,0x00,0x00,0x00,0xF3,0x87,0x17, /* 00000160 "........" */ +- 0x00,0x00,0x0C,0x03,0x00,0x00,0x00,0x00, /* 00000168 "........" */ +- 0x00,0x00,0x0A,0x00,0xFF,0xFF,0x0B,0x00, /* 00000170 "........" */ +- 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00, /* 00000178 "........" */ +- 0x87,0x17,0x00,0x00,0x0C,0x03,0x00,0x00, /* 00000180 "........" */ +- 0x00,0x00,0x00,0x00,0x00,0xF0,0xFF,0xFF, /* 00000188 "........" */ +- 0xFF,0xF4,0x00,0x00,0x00,0x00,0x00,0x00, /* 00000190 "........" */ +- 0x00,0x05,0x79,0x00,0x8A,0x50,0x52,0x54, /* 00000198 "..y..PRT" */ +- 0x30,0x0A,0x5C,0x4D,0x4D,0x49,0x4E,0x8A, /* 000001A0 "0.\MMIN." */ +- 0x50,0x52,0x54,0x30,0x0A,0x60,0x4D,0x4D, /* 000001A8 "PRT0.`MM" */ +- 0x41,0x58,0x8A,0x50,0x52,0x54,0x30,0x0A, /* 000001B0 "AX.PRT0." */ +- 0x68,0x4D,0x4C,0x45,0x4E,0x70,0x50,0x4D, /* 000001B8 "hMLENpPM" */ +- 0x49,0x4E,0x4D,0x4D,0x49,0x4E,0x70,0x50, /* 000001C0 "INMMINpP" */ +- 0x4C,0x45,0x4E,0x4D,0x4C,0x45,0x4E,0x72, /* 000001C8 "LENMLENr" */ +- 0x4D,0x4D,0x49,0x4E,0x4D,0x4C,0x45,0x4E, /* 000001D0 "MMINMLEN" */ +- 0x4D,0x4D,0x41,0x58,0x74,0x4D,0x4D,0x41, /* 000001D8 "MMAXtMMA" */ +- 0x58,0x01,0x4D,0x4D,0x41,0x58,0xA4,0x50, /* 000001E0 "X.MMAX.P" */ +- 0x52,0x54,0x30,0x08,0x42,0x55,0x46,0x41, /* 000001E8 "RT0.BUFA" */ +- 0x11,0x09,0x0A,0x06,0x23,0x20,0x0C,0x18, /* 000001F0 "....# .." */ +- 0x79,0x00,0x08,0x42,0x55,0x46,0x42,0x11, /* 000001F8 "y..BUFB." */ +- 0x09,0x0A,0x06,0x23,0x00,0x00,0x18,0x79, /* 00000200 "...#...y" */ +- 0x00,0x8B,0x42,0x55,0x46,0x42,0x01,0x49, /* 00000208 "..BUFB.I" */ +- 0x52,0x51,0x56,0x5B,0x82,0x48,0x08,0x4C, /* 00000210 "RQV[.H.L" */ +- 0x4E,0x4B,0x41,0x08,0x5F,0x48,0x49,0x44, /* 00000218 "NKA._HID" */ +- 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 00000220 ".A...._U" */ +- 0x49,0x44,0x01,0x14,0x1C,0x5F,0x53,0x54, /* 00000228 "ID..._ST" */ +- 0x41,0x00,0x7B,0x50,0x49,0x52,0x41,0x0A, /* 00000230 "A.{PIRA." */ +- 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 00000238 ".`...`.." */ +- 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 00000240 "........" */ +- 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 00000248 ".._PRS.." */ +- 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 00000250 "BUFA.._D" */ +- 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x41, /* 00000258 "IS.}PIRA" */ +- 0x0A,0x80,0x50,0x49,0x52,0x41,0x14,0x1A, /* 00000260 "..PIRA.." */ +- 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 00000268 "_CRS.{PI" */ +- 0x52,0x41,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 00000270 "RA..`y.`" */ +- 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 00000278 "IRQV.BUF" */ +- 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000280 "B.._SRS." */ +- 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 00000288 ".h.IRQ1." */ +- 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 00000290 "IRQ1`v`p" */ +- 0x60,0x50,0x49,0x52,0x41,0x5B,0x82,0x49, /* 00000298 "`PIRA[.I" */ +- 0x08,0x4C,0x4E,0x4B,0x42,0x08,0x5F,0x48, /* 000002A0 ".LNKB._H" */ +- 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 000002A8 "ID.A...." */ +- 0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,0x1C, /* 000002B0 "_UID...." */ +- 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 000002B8 "_STA.{PI" */ +- 0x52,0x42,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 000002C0 "RB..`..." */ +- 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 000002C8 "`......." */ +- 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 000002D0 "....._PR" */ +- 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 000002D8 "S..BUFA." */ +- 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 000002E0 "._DIS.}P" */ +- 0x49,0x52,0x42,0x0A,0x80,0x50,0x49,0x52, /* 000002E8 "IRB..PIR" */ +- 0x42,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 000002F0 "B.._CRS." */ +- 0x7B,0x50,0x49,0x52,0x42,0x0A,0x0F,0x60, /* 000002F8 "{PIRB..`" */ +- 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000300 "y.`IRQV." */ +- 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000308 "BUFB.._S" */ +- 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 00000310 "RS..h.IR" */ +- 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 00000318 "Q1.IRQ1`" */ +- 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x42, /* 00000320 "v`p`PIRB" */ +- 0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x43, /* 00000328 "[.I.LNKC" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000330 "._HID.A." */ +- 0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 00000338 "..._UID." */ +- 0x03,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00, /* 00000340 "..._STA." */ +- 0x7B,0x50,0x49,0x52,0x43,0x0A,0x80,0x60, /* 00000348 "{PIRC..`" */ +- 0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A, /* 00000350 "...`...." */ +- 0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B, /* 00000358 "........" */ +- 0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55, /* 00000360 "_PRS..BU" */ +- 0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53, /* 00000368 "FA.._DIS" */ +- 0x00,0x7D,0x50,0x49,0x52,0x43,0x0A,0x80, /* 00000370 ".}PIRC.." */ +- 0x50,0x49,0x52,0x43,0x14,0x1A,0x5F,0x43, /* 00000378 "PIRC.._C" */ +- 0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x43, /* 00000380 "RS.{PIRC" */ +- 0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52, /* 00000388 "..`y.`IR" */ +- 0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14, /* 00000390 "QV.BUFB." */ +- 0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68, /* 00000398 "._SRS..h" */ +- 0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52, /* 000003A0 ".IRQ1.IR" */ +- 0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50, /* 000003A8 "Q1`v`p`P" */ +- 0x49,0x52,0x43,0x5B,0x82,0x49,0x08,0x4C, /* 000003B0 "IRC[.I.L" */ +- 0x4E,0x4B,0x44,0x08,0x5F,0x48,0x49,0x44, /* 000003B8 "NKD._HID" */ +- 0x0C,0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55, /* 000003C0 ".A...._U" */ +- 0x49,0x44,0x0A,0x04,0x14,0x1C,0x5F,0x53, /* 000003C8 "ID...._S" */ +- 0x54,0x41,0x00,0x7B,0x50,0x49,0x52,0x44, /* 000003D0 "TA.{PIRD" */ +- 0x0A,0x80,0x60,0xA0,0x08,0x93,0x60,0x0A, /* 000003D8 "..`...`." */ +- 0x80,0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A, /* 000003E0 "........" */ +- 0x0B,0x14,0x0B,0x5F,0x50,0x52,0x53,0x00, /* 000003E8 "..._PRS." */ +- 0xA4,0x42,0x55,0x46,0x41,0x14,0x11,0x5F, /* 000003F0 ".BUFA.._" */ +- 0x44,0x49,0x53,0x00,0x7D,0x50,0x49,0x52, /* 000003F8 "DIS.}PIR" */ +- 0x44,0x0A,0x80,0x50,0x49,0x52,0x44,0x14, /* 00000400 "D..PIRD." */ +- 0x1A,0x5F,0x43,0x52,0x53,0x00,0x7B,0x50, /* 00000408 "._CRS.{P" */ +- 0x49,0x52,0x44,0x0A,0x0F,0x60,0x79,0x01, /* 00000410 "IRD..`y." */ +- 0x60,0x49,0x52,0x51,0x56,0xA4,0x42,0x55, /* 00000418 "`IRQV.BU" */ +- 0x46,0x42,0x14,0x1B,0x5F,0x53,0x52,0x53, /* 00000420 "FB.._SRS" */ +- 0x01,0x8B,0x68,0x01,0x49,0x52,0x51,0x31, /* 00000428 "..h.IRQ1" */ +- 0x82,0x49,0x52,0x51,0x31,0x60,0x76,0x60, /* 00000430 ".IRQ1`v`" */ +- 0x70,0x60,0x50,0x49,0x52,0x44,0x5B,0x82, /* 00000438 "p`PIRD[." */ +- 0x3A,0x48,0x50,0x45,0x54,0x08,0x5F,0x48, /* 00000440 ":HPET._H" */ +- 0x49,0x44,0x0C,0x41,0xD0,0x01,0x03,0x08, /* 00000448 "ID.A...." */ +- 0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,0x43, /* 00000450 "_UID.._C" */ +- 0x52,0x53,0x11,0x1F,0x0A,0x1C,0x87,0x17, /* 00000458 "RS......" */ +- 0x00,0x00,0x0D,0x01,0x00,0x00,0x00,0x00, /* 00000460 "........" */ +- 0x00,0x00,0xD0,0xFE,0xFF,0x03,0xD0,0xFE, /* 00000468 "........" */ +- 0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00, /* 00000470 "........" */ +- 0x79,0x00,0x14,0x16,0x5F,0x50,0x52,0x54, /* 00000478 "y..._PRT" */ +- 0x00,0xA0,0x0A,0x50,0x49,0x43,0x44,0xA4, /* 00000480 "...PICD." */ +- 0x50,0x52,0x54,0x41,0xA4,0x50,0x52,0x54, /* 00000488 "PRTA.PRT" */ +- 0x50,0x08,0x50,0x52,0x54,0x50,0x12,0x49, /* 00000490 "P.PRTP.I" */ +- 0x36,0x3C,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000498 "6<......" */ +- 0x01,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 000004A0 "...LNKB." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 000004A8 "........" */ +- 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 000004B0 ".LNKC..." */ +- 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02, /* 000004B8 "........" */ +- 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000004C0 "LNKD...." */ +- 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C, /* 000004C8 ".......L" */ +- 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 000004D0 "NKA....." */ +- 0xFF,0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B, /* 000004D8 ".....LNK" */ +- 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000004E0 "C......." */ +- 0x02,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 000004E8 "...LNKD." */ +- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 000004F0 "........" */ +- 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000004F8 "..LNKA.." */ +- 0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000500 "........" */ +- 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 00000508 ".LNKB..." */ +- 0x04,0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C, /* 00000510 ".......L" */ +- 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000518 "NKD....." */ +- 0xFF,0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B, /* 00000520 ".....LNK" */ +- 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000528 "A......." */ +- 0x03,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000530 "....LNKB" */ +- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03, /* 00000538 "........" */ +- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000540 "...LNKC." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00, /* 00000548 "........" */ +- 0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000550 ".LNKA..." */ +- 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C, /* 00000558 ".......L" */ +- 0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 00000560 "NKB....." */ +- 0xFF,0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E, /* 00000568 "......LN" */ +- 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000570 "KC......" */ +- 0xFF,0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000578 ".....LNK" */ +- 0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000580 "D......." */ +- 0x05,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 00000588 "...LNKB." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 00000590 "........" */ +- 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000598 ".LNKC..." */ +- 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02, /* 000005A0 "........" */ +- 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 000005A8 "LNKD...." */ +- 0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03,0x4C, /* 000005B0 ".......L" */ +- 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 000005B8 "NKA....." */ +- 0xFF,0xFF,0x06,0x00,0x00,0x4C,0x4E,0x4B, /* 000005C0 ".....LNK" */ +- 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000005C8 "C......." */ +- 0x06,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 000005D0 "...LNKD." */ +- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 000005D8 "........" */ +- 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000005E0 "..LNKA.." */ +- 0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A, /* 000005E8 "........" */ +- 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 000005F0 ".LNKB..." */ +- 0x04,0x0C,0xFF,0xFF,0x07,0x00,0x00,0x4C, /* 000005F8 ".......L" */ +- 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 00000600 "NKD....." */ +- 0xFF,0xFF,0x07,0x00,0x01,0x4C,0x4E,0x4B, /* 00000608 ".....LNK" */ +- 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000610 "A......." */ +- 0x07,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000618 "....LNKB" */ +- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07, /* 00000620 "........" */ +- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000628 "...LNKC." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00, /* 00000630 "........" */ +- 0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000638 ".LNKA..." */ +- 0x04,0x0C,0xFF,0xFF,0x08,0x00,0x01,0x4C, /* 00000640 ".......L" */ +- 0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 00000648 "NKB....." */ +- 0xFF,0xFF,0x08,0x00,0x0A,0x02,0x4C,0x4E, /* 00000650 "......LN" */ +- 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000658 "KC......" */ +- 0xFF,0x08,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000660 ".....LNK" */ +- 0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000668 "D......." */ +- 0x09,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 00000670 "...LNKB." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 00000678 "........" */ +- 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000680 ".LNKC..." */ +- 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02, /* 00000688 "........" */ +- 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000690 "LNKD...." */ +- 0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03,0x4C, /* 00000698 ".......L" */ +- 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 000006A0 "NKA....." */ +- 0xFF,0xFF,0x0A,0x00,0x00,0x4C,0x4E,0x4B, /* 000006A8 ".....LNK" */ +- 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 000006B0 "C......." */ +- 0x0A,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 000006B8 "...LNKD." */ +- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 000006C0 "........" */ +- 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000006C8 "..LNKA.." */ +- 0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A, /* 000006D0 "........" */ +- 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 000006D8 ".LNKB..." */ +- 0x04,0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x4C, /* 000006E0 ".......L" */ +- 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 000006E8 "NKD....." */ +- 0xFF,0xFF,0x0B,0x00,0x01,0x4C,0x4E,0x4B, /* 000006F0 ".....LNK" */ +- 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000006F8 "A......." */ +- 0x0B,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 00000700 "....LNKB" */ +- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000708 "........" */ +- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 00000710 "...LNKC." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00, /* 00000718 "........" */ +- 0x00,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D, /* 00000720 ".LNKA..." */ +- 0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x4C, /* 00000728 ".......L" */ +- 0x4E,0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C, /* 00000730 "NKB....." */ +- 0xFF,0xFF,0x0C,0x00,0x0A,0x02,0x4C,0x4E, /* 00000738 "......LN" */ +- 0x4B,0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000740 "KC......" */ +- 0xFF,0x0C,0x00,0x0A,0x03,0x4C,0x4E,0x4B, /* 00000748 ".....LNK" */ +- 0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000750 "D......." */ +- 0x0D,0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00, /* 00000758 "...LNKB." */ +- 0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 00000760 "........" */ +- 0x01,0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E, /* 00000768 ".LNKC..." */ +- 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02, /* 00000770 "........" */ +- 0x4C,0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04, /* 00000778 "LNKD...." */ +- 0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x4C, /* 00000780 ".......L" */ +- 0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C, /* 00000788 "NKA....." */ +- 0xFF,0xFF,0x0E,0x00,0x00,0x4C,0x4E,0x4B, /* 00000790 ".....LNK" */ +- 0x43,0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF, /* 00000798 "C......." */ +- 0x0E,0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00, /* 000007A0 "...LNKD." */ +- 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 000007A8 "........" */ +- 0x0A,0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12, /* 000007B0 "..LNKA.." */ +- 0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A, /* 000007B8 "........" */ +- 0x03,0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D, /* 000007C0 ".LNKB..." */ +- 0x04,0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x4C, /* 000007C8 ".......L" */ +- 0x4E,0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C, /* 000007D0 "NKD....." */ +- 0xFF,0xFF,0x0F,0x00,0x01,0x4C,0x4E,0x4B, /* 000007D8 ".....LNK" */ +- 0x41,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 000007E0 "A......." */ +- 0x0F,0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42, /* 000007E8 "....LNKB" */ +- 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F, /* 000007F0 "........" */ +- 0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00, /* 000007F8 "...LNKC." */ +- 0x08,0x50,0x52,0x54,0x41,0x12,0x41,0x2F, /* 00000800 ".PRTA.A/" */ +- 0x3C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01, /* 00000808 "<......." */ +- 0x00,0x00,0x00,0x0A,0x14,0x12,0x0B,0x04, /* 00000810 "........" */ +- 0x0C,0xFF,0xFF,0x01,0x00,0x01,0x00,0x0A, /* 00000818 "........" */ +- 0x15,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01, /* 00000820 "........" */ +- 0x00,0x0A,0x02,0x00,0x0A,0x16,0x12,0x0C, /* 00000828 "........" */ +- 0x04,0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03, /* 00000830 "........" */ +- 0x00,0x0A,0x17,0x12,0x0B,0x04,0x0C,0xFF, /* 00000838 "........" */ +- 0xFF,0x02,0x00,0x00,0x00,0x0A,0x18,0x12, /* 00000840 "........" */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01, /* 00000848 "........" */ +- 0x00,0x0A,0x19,0x12,0x0C,0x04,0x0C,0xFF, /* 00000850 "........" */ +- 0xFF,0x02,0x00,0x0A,0x02,0x00,0x0A,0x1A, /* 00000858 "........" */ +- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00, /* 00000860 "........" */ +- 0x0A,0x03,0x00,0x0A,0x1B,0x12,0x0B,0x04, /* 00000868 "........" */ +- 0x0C,0xFF,0xFF,0x03,0x00,0x00,0x00,0x0A, /* 00000870 "........" */ +- 0x1C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03, /* 00000878 "........" */ +- 0x00,0x01,0x00,0x0A,0x1D,0x12,0x0C,0x04, /* 00000880 "........" */ +- 0x0C,0xFF,0xFF,0x03,0x00,0x0A,0x02,0x00, /* 00000888 "........" */ +- 0x0A,0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000890 "........" */ +- 0x03,0x00,0x0A,0x03,0x00,0x0A,0x1F,0x12, /* 00000898 "........" */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00, /* 000008A0 "........" */ +- 0x00,0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF, /* 000008A8 ".. ....." */ +- 0xFF,0x04,0x00,0x01,0x00,0x0A,0x21,0x12, /* 000008B0 "......!." */ +- 0x0C,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A, /* 000008B8 "........" */ +- 0x02,0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C, /* 000008C0 "..."...." */ +- 0xFF,0xFF,0x04,0x00,0x0A,0x03,0x00,0x0A, /* 000008C8 "........" */ +- 0x23,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05, /* 000008D0 "#......." */ +- 0x00,0x00,0x00,0x0A,0x24,0x12,0x0B,0x04, /* 000008D8 "....$..." */ +- 0x0C,0xFF,0xFF,0x05,0x00,0x01,0x00,0x0A, /* 000008E0 "........" */ +- 0x25,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05, /* 000008E8 "%......." */ +- 0x00,0x0A,0x02,0x00,0x0A,0x26,0x12,0x0C, /* 000008F0 ".....&.." */ +- 0x04,0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03, /* 000008F8 "........" */ +- 0x00,0x0A,0x27,0x12,0x0B,0x04,0x0C,0xFF, /* 00000900 "..'....." */ +- 0xFF,0x06,0x00,0x00,0x00,0x0A,0x28,0x12, /* 00000908 "......(." */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01, /* 00000910 "........" */ +- 0x00,0x0A,0x29,0x12,0x0C,0x04,0x0C,0xFF, /* 00000918 "..)....." */ +- 0xFF,0x06,0x00,0x0A,0x02,0x00,0x0A,0x2A, /* 00000920 ".......*" */ +- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00, /* 00000928 "........" */ +- 0x0A,0x03,0x00,0x0A,0x2B,0x12,0x0B,0x04, /* 00000930 "....+..." */ +- 0x0C,0xFF,0xFF,0x07,0x00,0x00,0x00,0x0A, /* 00000938 "........" */ +- 0x2C,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07, /* 00000940 ",......." */ +- 0x00,0x01,0x00,0x0A,0x2D,0x12,0x0C,0x04, /* 00000948 "....-..." */ +- 0x0C,0xFF,0xFF,0x07,0x00,0x0A,0x02,0x00, /* 00000950 "........" */ +- 0x0A,0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000958 "........" */ +- 0x07,0x00,0x0A,0x03,0x00,0x0A,0x2F,0x12, /* 00000960 "....../." */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x00, /* 00000968 "........" */ +- 0x00,0x0A,0x11,0x12,0x0B,0x04,0x0C,0xFF, /* 00000970 "........" */ +- 0xFF,0x08,0x00,0x01,0x00,0x0A,0x12,0x12, /* 00000978 "........" */ +- 0x0C,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A, /* 00000980 "........" */ +- 0x02,0x00,0x0A,0x13,0x12,0x0C,0x04,0x0C, /* 00000988 "........" */ +- 0xFF,0xFF,0x08,0x00,0x0A,0x03,0x00,0x0A, /* 00000990 "........" */ +- 0x14,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09, /* 00000998 "........" */ +- 0x00,0x00,0x00,0x0A,0x15,0x12,0x0B,0x04, /* 000009A0 "........" */ +- 0x0C,0xFF,0xFF,0x09,0x00,0x01,0x00,0x0A, /* 000009A8 "........" */ +- 0x16,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09, /* 000009B0 "........" */ +- 0x00,0x0A,0x02,0x00,0x0A,0x17,0x12,0x0C, /* 000009B8 "........" */ +- 0x04,0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03, /* 000009C0 "........" */ +- 0x00,0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF, /* 000009C8 "........" */ +- 0xFF,0x0A,0x00,0x00,0x00,0x0A,0x19,0x12, /* 000009D0 "........" */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01, /* 000009D8 "........" */ +- 0x00,0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF, /* 000009E0 "........" */ +- 0xFF,0x0A,0x00,0x0A,0x02,0x00,0x0A,0x1B, /* 000009E8 "........" */ +- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00, /* 000009F0 "........" */ +- 0x0A,0x03,0x00,0x0A,0x1C,0x12,0x0B,0x04, /* 000009F8 "........" */ +- 0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x00,0x0A, /* 00000A00 "........" */ +- 0x1D,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000A08 "........" */ +- 0x00,0x01,0x00,0x0A,0x1E,0x12,0x0C,0x04, /* 00000A10 "........" */ +- 0x0C,0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x00, /* 00000A18 "........" */ +- 0x0A,0x1F,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A20 "........" */ +- 0x0B,0x00,0x0A,0x03,0x00,0x0A,0x20,0x12, /* 00000A28 "...... ." */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x00, /* 00000A30 "........" */ +- 0x00,0x0A,0x21,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A38 "..!....." */ +- 0xFF,0x0C,0x00,0x01,0x00,0x0A,0x22,0x12, /* 00000A40 "......"." */ +- 0x0C,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A, /* 00000A48 "........" */ +- 0x02,0x00,0x0A,0x23,0x12,0x0C,0x04,0x0C, /* 00000A50 "...#...." */ +- 0xFF,0xFF,0x0C,0x00,0x0A,0x03,0x00,0x0A, /* 00000A58 "........" */ +- 0x24,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000A60 "$......." */ +- 0x00,0x00,0x00,0x0A,0x25,0x12,0x0B,0x04, /* 00000A68 "....%..." */ +- 0x0C,0xFF,0xFF,0x0D,0x00,0x01,0x00,0x0A, /* 00000A70 "........" */ +- 0x26,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000A78 "&......." */ +- 0x00,0x0A,0x02,0x00,0x0A,0x27,0x12,0x0C, /* 00000A80 ".....'.." */ +- 0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03, /* 00000A88 "........" */ +- 0x00,0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF, /* 00000A90 "..(....." */ +- 0xFF,0x0E,0x00,0x00,0x00,0x0A,0x29,0x12, /* 00000A98 "......)." */ +- 0x0B,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01, /* 00000AA0 "........" */ +- 0x00,0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF, /* 00000AA8 "..*....." */ +- 0xFF,0x0E,0x00,0x0A,0x02,0x00,0x0A,0x2B, /* 00000AB0 ".......+" */ +- 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00, /* 00000AB8 "........" */ +- 0x0A,0x03,0x00,0x0A,0x2C,0x12,0x0B,0x04, /* 00000AC0 "....,..." */ +- 0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x00,0x0A, /* 00000AC8 "........" */ +- 0x2D,0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000AD0 "-......." */ +- 0x00,0x01,0x00,0x0A,0x2E,0x12,0x0C,0x04, /* 00000AD8 "........" */ +- 0x0C,0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x00, /* 00000AE0 "........" */ +- 0x0A,0x2F,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000AE8 "./......" */ +- 0x0F,0x00,0x0A,0x03,0x00,0x0A,0x10,0x5B, /* 00000AF0 ".......[" */ +- 0x82,0x46,0x37,0x49,0x53,0x41,0x5F,0x08, /* 00000AF8 ".F7ISA_." */ +- 0x5F,0x41,0x44,0x52,0x0C,0x00,0x00,0x01, /* 00000B00 "_ADR...." */ +- 0x00,0x5B,0x80,0x50,0x49,0x52,0x51,0x02, /* 00000B08 ".[.PIRQ." */ +- 0x0A,0x60,0x0A,0x04,0x10,0x2E,0x5C,0x00, /* 00000B10 ".`....\." */ +- 0x5B,0x81,0x29,0x5C,0x2F,0x04,0x5F,0x53, /* 00000B18 "[.)\/._S" */ +- 0x42,0x5F,0x50,0x43,0x49,0x30,0x49,0x53, /* 00000B20 "B_PCI0IS" */ +- 0x41,0x5F,0x50,0x49,0x52,0x51,0x01,0x50, /* 00000B28 "A_PIRQ.P" */ +- 0x49,0x52,0x41,0x08,0x50,0x49,0x52,0x42, /* 00000B30 "IRA.PIRB" */ +- 0x08,0x50,0x49,0x52,0x43,0x08,0x50,0x49, /* 00000B38 ".PIRC.PI" */ +- 0x52,0x44,0x08,0x5B,0x82,0x46,0x0B,0x53, /* 00000B40 "RD.[.F.S" */ +- 0x59,0x53,0x52,0x08,0x5F,0x48,0x49,0x44, /* 00000B48 "YSR._HID" */ +- 0x0C,0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55, /* 00000B50 ".A...._U" */ +- 0x49,0x44,0x01,0x08,0x43,0x52,0x53,0x5F, /* 00000B58 "ID..CRS_" */ +- 0x11,0x4E,0x08,0x0A,0x8A,0x47,0x01,0x10, /* 00000B60 ".N...G.." */ +- 0x00,0x10,0x00,0x00,0x10,0x47,0x01,0x22, /* 00000B68 ".....G."" */ +- 0x00,0x22,0x00,0x00,0x0C,0x47,0x01,0x30, /* 00000B70 "."...G.0" */ +- 0x00,0x30,0x00,0x00,0x10,0x47,0x01,0x44, /* 00000B78 ".0...G.D" */ +- 0x00,0x44,0x00,0x00,0x1C,0x47,0x01,0x62, /* 00000B80 ".D...G.b" */ +- 0x00,0x62,0x00,0x00,0x02,0x47,0x01,0x65, /* 00000B88 ".b...G.e" */ +- 0x00,0x65,0x00,0x00,0x0B,0x47,0x01,0x72, /* 00000B90 ".e...G.r" */ +- 0x00,0x72,0x00,0x00,0x0E,0x47,0x01,0x80, /* 00000B98 ".r...G.." */ +- 0x00,0x80,0x00,0x00,0x01,0x47,0x01,0x84, /* 00000BA0 ".....G.." */ +- 0x00,0x84,0x00,0x00,0x03,0x47,0x01,0x88, /* 00000BA8 ".....G.." */ +- 0x00,0x88,0x00,0x00,0x01,0x47,0x01,0x8C, /* 00000BB0 ".....G.." */ +- 0x00,0x8C,0x00,0x00,0x03,0x47,0x01,0x90, /* 00000BB8 ".....G.." */ +- 0x00,0x90,0x00,0x00,0x10,0x47,0x01,0xA2, /* 00000BC0 ".....G.." */ +- 0x00,0xA2,0x00,0x00,0x1C,0x47,0x01,0xE0, /* 00000BC8 ".....G.." */ +- 0x00,0xE0,0x00,0x00,0x10,0x47,0x01,0xA0, /* 00000BD0 ".....G.." */ +- 0x08,0xA0,0x08,0x00,0x04,0x47,0x01,0xC0, /* 00000BD8 ".....G.." */ +- 0x0C,0xC0,0x0C,0x00,0x10,0x47,0x01,0xD0, /* 00000BE0 ".....G.." */ +- 0x04,0xD0,0x04,0x00,0x02,0x79,0x00,0x14, /* 00000BE8 ".....y.." */ +- 0x0B,0x5F,0x43,0x52,0x53,0x00,0xA4,0x43, /* 00000BF0 "._CRS..C" */ +- 0x52,0x53,0x5F,0x5B,0x82,0x2B,0x50,0x49, /* 00000BF8 "RS_[.+PI" */ +- 0x43,0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B, /* 00000C00 "C_._HID." */ +- 0x41,0xD0,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C08 "A.._CRS." */ +- 0x18,0x0A,0x15,0x47,0x01,0x20,0x00,0x20, /* 00000C10 "...G. . " */ +- 0x00,0x01,0x02,0x47,0x01,0xA0,0x00,0xA0, /* 00000C18 "...G...." */ +- 0x00,0x01,0x02,0x22,0x04,0x00,0x79,0x00, /* 00000C20 "..."..y." */ +- 0x5B,0x82,0x47,0x05,0x44,0x4D,0x41,0x30, /* 00000C28 "[.G.DMA0" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000C30 "._HID.A." */ +- 0x02,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C38 "..._CRS." */ +- 0x41,0x04,0x0A,0x3D,0x2A,0x10,0x04,0x47, /* 00000C40 "A..=*..G" */ +- 0x01,0x00,0x00,0x00,0x00,0x00,0x10,0x47, /* 00000C48 ".......G" */ +- 0x01,0x81,0x00,0x81,0x00,0x00,0x03,0x47, /* 00000C50 ".......G" */ +- 0x01,0x87,0x00,0x87,0x00,0x00,0x01,0x47, /* 00000C58 ".......G" */ +- 0x01,0x89,0x00,0x89,0x00,0x00,0x03,0x47, /* 00000C60 ".......G" */ +- 0x01,0x8F,0x00,0x8F,0x00,0x00,0x01,0x47, /* 00000C68 ".......G" */ +- 0x01,0xC0,0x00,0xC0,0x00,0x00,0x20,0x47, /* 00000C70 "...... G" */ +- 0x01,0x80,0x04,0x80,0x04,0x00,0x10,0x79, /* 00000C78 ".......y" */ +- 0x00,0x5B,0x82,0x25,0x54,0x4D,0x52,0x5F, /* 00000C80 ".[.%TMR_" */ +- 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000C88 "._HID.A." */ +- 0x01,0x00,0x08,0x5F,0x43,0x52,0x53,0x11, /* 00000C90 "..._CRS." */ +- 0x10,0x0A,0x0D,0x47,0x01,0x40,0x00,0x40, /* 00000C98 "...G.@.@" */ +- 0x00,0x00,0x04,0x22,0x01,0x00,0x79,0x00, /* 00000CA0 "..."..y." */ +- 0x5B,0x82,0x25,0x52,0x54,0x43,0x5F,0x08, /* 00000CA8 "[.%RTC_." */ +- 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B, /* 00000CB0 "_HID.A.." */ +- 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000CB8 ".._CRS.." */ +- 0x0A,0x0D,0x47,0x01,0x70,0x00,0x70,0x00, /* 00000CC0 "..G.p.p." */ +- 0x00,0x02,0x22,0x00,0x01,0x79,0x00,0x5B, /* 00000CC8 ".."..y.[" */ +- 0x82,0x22,0x53,0x50,0x4B,0x52,0x08,0x5F, /* 00000CD0 "."SPKR._" */ +- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x08,0x00, /* 00000CD8 "HID.A..." */ +- 0x08,0x5F,0x43,0x52,0x53,0x11,0x0D,0x0A, /* 00000CE0 "._CRS..." */ +- 0x0A,0x47,0x01,0x61,0x00,0x61,0x00,0x00, /* 00000CE8 ".G.a.a.." */ +- 0x01,0x79,0x00,0x5B,0x82,0x31,0x50,0x53, /* 00000CF0 ".y.[.1PS" */ +- 0x32,0x4D,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000CF8 "2M._HID." */ +- 0x41,0xD0,0x0F,0x13,0x08,0x5F,0x43,0x49, /* 00000D00 "A...._CI" */ +- 0x44,0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09, /* 00000D08 "D.A....." */ +- 0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F, /* 00000D10 "_STA...." */ +- 0x08,0x5F,0x43,0x52,0x53,0x11,0x08,0x0A, /* 00000D18 "._CRS..." */ +- 0x05,0x22,0x00,0x10,0x79,0x00,0x5B,0x82, /* 00000D20 "."..y.[." */ +- 0x42,0x04,0x50,0x53,0x32,0x4B,0x08,0x5F, /* 00000D28 "B.PS2K._" */ +- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x03,0x03, /* 00000D30 "HID.A..." */ +- 0x08,0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0, /* 00000D38 "._CID.A." */ +- 0x03,0x0B,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000D40 "...._STA" */ +- 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000D48 "....._CR" */ +- 0x53,0x11,0x18,0x0A,0x15,0x47,0x01,0x60, /* 00000D50 "S....G.`" */ +- 0x00,0x60,0x00,0x00,0x01,0x47,0x01,0x64, /* 00000D58 ".`...G.d" */ +- 0x00,0x64,0x00,0x00,0x01,0x22,0x02,0x00, /* 00000D60 ".d...".." */ +- 0x79,0x00,0x5B,0x82,0x3A,0x46,0x44,0x43, /* 00000D68 "y.[.:FDC" */ +- 0x30,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000D70 "0._HID.A" */ +- 0xD0,0x07,0x00,0x14,0x09,0x5F,0x53,0x54, /* 00000D78 "....._ST" */ +- 0x41,0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43, /* 00000D80 "A....._C" */ +- 0x52,0x53,0x11,0x1B,0x0A,0x18,0x47,0x01, /* 00000D88 "RS....G." */ +- 0xF0,0x03,0xF0,0x03,0x01,0x06,0x47,0x01, /* 00000D90 "......G." */ +- 0xF7,0x03,0xF7,0x03,0x01,0x01,0x22,0x40, /* 00000D98 "......"@" */ +- 0x00,0x2A,0x04,0x00,0x79,0x00,0x5B,0x82, /* 00000DA0 ".*..y.[." */ +- 0x46,0x04,0x55,0x41,0x52,0x31,0x08,0x5F, /* 00000DA8 "F.UAR1._" */ +- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,0x01, /* 00000DB0 "HID.A..." */ +- 0x08,0x5F,0x55,0x49,0x44,0x01,0x14,0x19, /* 00000DB8 "._UID..." */ +- 0x5F,0x53,0x54,0x41,0x00,0xA0,0x0D,0x93, /* 00000DC0 "_STA...." */ +- 0x5E,0x5E,0x5E,0x5E,0x55,0x41,0x52,0x31, /* 00000DC8 "^^^^UAR1" */ +- 0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A,0x0F, /* 00000DD0 "........" */ +- 0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A, /* 00000DD8 "._CRS..." */ +- 0x0D,0x47,0x01,0xF8,0x03,0xF8,0x03,0x08, /* 00000DE0 ".G......" */ +- 0x08,0x22,0x10,0x00,0x79,0x00,0x5B,0x82, /* 00000DE8 "."..y.[." */ +- 0x47,0x04,0x55,0x41,0x52,0x32,0x08,0x5F, /* 00000DF0 "G.UAR2._" */ +- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x05,0x01, /* 00000DF8 "HID.A..." */ +- 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14, /* 00000E00 "._UID..." */ +- 0x19,0x5F,0x53,0x54,0x41,0x00,0xA0,0x0D, /* 00000E08 "._STA..." */ +- 0x93,0x5E,0x5E,0x5E,0x5E,0x55,0x41,0x52, /* 00000E10 ".^^^^UAR" */ +- 0x32,0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A, /* 00000E18 "2......." */ +- 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000E20 ".._CRS.." */ +- 0x0A,0x0D,0x47,0x01,0xF8,0x02,0xF8,0x02, /* 00000E28 "..G....." */ +- 0x08,0x08,0x22,0x08,0x00,0x79,0x00,0x5B, /* 00000E30 ".."..y.[" */ +- 0x82,0x36,0x4C,0x54,0x50,0x31,0x08,0x5F, /* 00000E38 ".6LTP1._" */ +- 0x48,0x49,0x44,0x0C,0x41,0xD0,0x04,0x00, /* 00000E40 "HID.A..." */ +- 0x08,0x5F,0x55,0x49,0x44,0x0A,0x02,0x14, /* 00000E48 "._UID..." */ +- 0x09,0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A, /* 00000E50 "._STA..." */ +- 0x0F,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000E58 ".._CRS.." */ +- 0x0A,0x0D,0x47,0x01,0x78,0x03,0x78,0x03, /* 00000E60 "..G.x.x." */ +- 0x08,0x08,0x22,0x80,0x00,0x79,0x00, ++ 0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x00, /* 000000F0 "........" */ ++ 0x00,0x00,0x00,0x79,0x00,0x5B,0x82,0x4F, /* 000000F8 "...y.[.O" */ ++ 0xD8,0x50,0x43,0x49,0x30,0x08,0x5F,0x48, /* 00000100 ".PCI0._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x0A,0x03,0x08, /* 00000108 "ID.A...." */ ++ 0x5F,0x55,0x49,0x44,0x00,0x08,0x5F,0x41, /* 00000110 "_UID.._A" */ ++ 0x44,0x52,0x00,0x08,0x5F,0x42,0x42,0x4E, /* 00000118 "DR.._BBN" */ ++ 0x00,0x14,0x4E,0x0C,0x5F,0x43,0x52,0x53, /* 00000120 "..N._CRS" */ ++ 0x00,0x08,0x50,0x52,0x54,0x30,0x11,0x42, /* 00000128 "..PRT0.B" */ ++ 0x07,0x0A,0x6E,0x88,0x0D,0x00,0x02,0x0E, /* 00000130 "..n....." */ ++ 0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00, /* 00000138 "........" */ ++ 0x00,0x00,0x01,0x47,0x01,0xF8,0x0C,0xF8, /* 00000140 "...G...." */ ++ 0x0C,0x01,0x08,0x88,0x0D,0x00,0x01,0x0C, /* 00000148 "........" */ ++ 0x03,0x00,0x00,0x00,0x00,0xF7,0x0C,0x00, /* 00000150 "........" */ ++ 0x00,0xF8,0x0C,0x88,0x0D,0x00,0x01,0x0C, /* 00000158 "........" */ ++ 0x03,0x00,0x00,0x00,0x0D,0xFF,0xFF,0x00, /* 00000160 "........" */ ++ 0x00,0x00,0xF3,0x87,0x17,0x00,0x00,0x0C, /* 00000168 "........" */ ++ 0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x0A, /* 00000170 "........" */ ++ 0x00,0xFF,0xFF,0x0B,0x00,0x00,0x00,0x00, /* 00000178 "........" */ ++ 0x00,0x00,0x00,0x02,0x00,0x87,0x17,0x00, /* 00000180 "........" */ ++ 0x00,0x0C,0x03,0x00,0x00,0x00,0x00,0x00, /* 00000188 "........" */ ++ 0x00,0x00,0xF0,0xFF,0xFF,0xFF,0xF4,0x00, /* 00000190 "........" */ ++ 0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x79, /* 00000198 ".......y" */ ++ 0x00,0x8A,0x50,0x52,0x54,0x30,0x0A,0x5C, /* 000001A0 "..PRT0.\" */ ++ 0x4D,0x4D,0x49,0x4E,0x8A,0x50,0x52,0x54, /* 000001A8 "MMIN.PRT" */ ++ 0x30,0x0A,0x60,0x4D,0x4D,0x41,0x58,0x8A, /* 000001B0 "0.`MMAX." */ ++ 0x50,0x52,0x54,0x30,0x0A,0x68,0x4D,0x4C, /* 000001B8 "PRT0.hML" */ ++ 0x45,0x4E,0x70,0x50,0x4D,0x49,0x4E,0x4D, /* 000001C0 "ENpPMINM" */ ++ 0x4D,0x49,0x4E,0x70,0x50,0x4C,0x45,0x4E, /* 000001C8 "MINpPLEN" */ ++ 0x4D,0x4C,0x45,0x4E,0x72,0x4D,0x4D,0x49, /* 000001D0 "MLENrMMI" */ ++ 0x4E,0x4D,0x4C,0x45,0x4E,0x4D,0x4D,0x41, /* 000001D8 "NMLENMMA" */ ++ 0x58,0x74,0x4D,0x4D,0x41,0x58,0x01,0x4D, /* 000001E0 "XtMMAX.M" */ ++ 0x4D,0x41,0x58,0xA4,0x50,0x52,0x54,0x30, /* 000001E8 "MAX.PRT0" */ ++ 0x08,0x42,0x55,0x46,0x41,0x11,0x09,0x0A, /* 000001F0 ".BUFA..." */ ++ 0x06,0x23,0x20,0x0C,0x18,0x79,0x00,0x08, /* 000001F8 ".# ..y.." */ ++ 0x42,0x55,0x46,0x42,0x11,0x09,0x0A,0x06, /* 00000200 "BUFB...." */ ++ 0x23,0x00,0x00,0x18,0x79,0x00,0x8B,0x42, /* 00000208 "#...y..B" */ ++ 0x55,0x46,0x42,0x01,0x49,0x52,0x51,0x56, /* 00000210 "UFB.IRQV" */ ++ 0x5B,0x82,0x48,0x08,0x4C,0x4E,0x4B,0x41, /* 00000218 "[.H.LNKA" */ ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000220 "._HID.A." */ ++ 0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x01, /* 00000228 "..._UID." */ ++ 0x14,0x1C,0x5F,0x53,0x54,0x41,0x00,0x7B, /* 00000230 ".._STA.{" */ ++ 0x50,0x49,0x52,0x41,0x0A,0x80,0x60,0xA0, /* 00000238 "PIRA..`." */ ++ 0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A,0x09, /* 00000240 "..`....." */ ++ 0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B,0x5F, /* 00000248 "......._" */ ++ 0x50,0x52,0x53,0x00,0xA4,0x42,0x55,0x46, /* 00000250 "PRS..BUF" */ ++ 0x41,0x14,0x11,0x5F,0x44,0x49,0x53,0x00, /* 00000258 "A.._DIS." */ ++ 0x7D,0x50,0x49,0x52,0x41,0x0A,0x80,0x50, /* 00000260 "}PIRA..P" */ ++ 0x49,0x52,0x41,0x14,0x1A,0x5F,0x43,0x52, /* 00000268 "IRA.._CR" */ ++ 0x53,0x00,0x7B,0x50,0x49,0x52,0x41,0x0A, /* 00000270 "S.{PIRA." */ ++ 0x0F,0x60,0x79,0x01,0x60,0x49,0x52,0x51, /* 00000278 ".`y.`IRQ" */ ++ 0x56,0xA4,0x42,0x55,0x46,0x42,0x14,0x1B, /* 00000280 "V.BUFB.." */ ++ 0x5F,0x53,0x52,0x53,0x01,0x8B,0x68,0x01, /* 00000288 "_SRS..h." */ ++ 0x49,0x52,0x51,0x31,0x82,0x49,0x52,0x51, /* 00000290 "IRQ1.IRQ" */ ++ 0x31,0x60,0x76,0x60,0x70,0x60,0x50,0x49, /* 00000298 "1`v`p`PI" */ ++ 0x52,0x41,0x5B,0x82,0x49,0x08,0x4C,0x4E, /* 000002A0 "RA[.I.LN" */ ++ 0x4B,0x42,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 000002A8 "KB._HID." */ ++ 0x41,0xD0,0x0C,0x0F,0x08,0x5F,0x55,0x49, /* 000002B0 "A...._UI" */ ++ 0x44,0x0A,0x02,0x14,0x1C,0x5F,0x53,0x54, /* 000002B8 "D...._ST" */ ++ 0x41,0x00,0x7B,0x50,0x49,0x52,0x42,0x0A, /* 000002C0 "A.{PIRB." */ ++ 0x80,0x60,0xA0,0x08,0x93,0x60,0x0A,0x80, /* 000002C8 ".`...`.." */ ++ 0xA4,0x0A,0x09,0xA1,0x04,0xA4,0x0A,0x0B, /* 000002D0 "........" */ ++ 0x14,0x0B,0x5F,0x50,0x52,0x53,0x00,0xA4, /* 000002D8 ".._PRS.." */ ++ 0x42,0x55,0x46,0x41,0x14,0x11,0x5F,0x44, /* 000002E0 "BUFA.._D" */ ++ 0x49,0x53,0x00,0x7D,0x50,0x49,0x52,0x42, /* 000002E8 "IS.}PIRB" */ ++ 0x0A,0x80,0x50,0x49,0x52,0x42,0x14,0x1A, /* 000002F0 "..PIRB.." */ ++ 0x5F,0x43,0x52,0x53,0x00,0x7B,0x50,0x49, /* 000002F8 "_CRS.{PI" */ ++ 0x52,0x42,0x0A,0x0F,0x60,0x79,0x01,0x60, /* 00000300 "RB..`y.`" */ ++ 0x49,0x52,0x51,0x56,0xA4,0x42,0x55,0x46, /* 00000308 "IRQV.BUF" */ ++ 0x42,0x14,0x1B,0x5F,0x53,0x52,0x53,0x01, /* 00000310 "B.._SRS." */ ++ 0x8B,0x68,0x01,0x49,0x52,0x51,0x31,0x82, /* 00000318 ".h.IRQ1." */ ++ 0x49,0x52,0x51,0x31,0x60,0x76,0x60,0x70, /* 00000320 "IRQ1`v`p" */ ++ 0x60,0x50,0x49,0x52,0x42,0x5B,0x82,0x49, /* 00000328 "`PIRB[.I" */ ++ 0x08,0x4C,0x4E,0x4B,0x43,0x08,0x5F,0x48, /* 00000330 ".LNKC._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x0C,0x0F,0x08, /* 00000338 "ID.A...." */ ++ 0x5F,0x55,0x49,0x44,0x0A,0x03,0x14,0x1C, /* 00000340 "_UID...." */ ++ 0x5F,0x53,0x54,0x41,0x00,0x7B,0x50,0x49, /* 00000348 "_STA.{PI" */ ++ 0x52,0x43,0x0A,0x80,0x60,0xA0,0x08,0x93, /* 00000350 "RC..`..." */ ++ 0x60,0x0A,0x80,0xA4,0x0A,0x09,0xA1,0x04, /* 00000358 "`......." */ ++ 0xA4,0x0A,0x0B,0x14,0x0B,0x5F,0x50,0x52, /* 00000360 "....._PR" */ ++ 0x53,0x00,0xA4,0x42,0x55,0x46,0x41,0x14, /* 00000368 "S..BUFA." */ ++ 0x11,0x5F,0x44,0x49,0x53,0x00,0x7D,0x50, /* 00000370 "._DIS.}P" */ ++ 0x49,0x52,0x43,0x0A,0x80,0x50,0x49,0x52, /* 00000378 "IRC..PIR" */ ++ 0x43,0x14,0x1A,0x5F,0x43,0x52,0x53,0x00, /* 00000380 "C.._CRS." */ ++ 0x7B,0x50,0x49,0x52,0x43,0x0A,0x0F,0x60, /* 00000388 "{PIRC..`" */ ++ 0x79,0x01,0x60,0x49,0x52,0x51,0x56,0xA4, /* 00000390 "y.`IRQV." */ ++ 0x42,0x55,0x46,0x42,0x14,0x1B,0x5F,0x53, /* 00000398 "BUFB.._S" */ ++ 0x52,0x53,0x01,0x8B,0x68,0x01,0x49,0x52, /* 000003A0 "RS..h.IR" */ ++ 0x51,0x31,0x82,0x49,0x52,0x51,0x31,0x60, /* 000003A8 "Q1.IRQ1`" */ ++ 0x76,0x60,0x70,0x60,0x50,0x49,0x52,0x43, /* 000003B0 "v`p`PIRC" */ ++ 0x5B,0x82,0x49,0x08,0x4C,0x4E,0x4B,0x44, /* 000003B8 "[.I.LNKD" */ ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 000003C0 "._HID.A." */ ++ 0x0C,0x0F,0x08,0x5F,0x55,0x49,0x44,0x0A, /* 000003C8 "..._UID." */ ++ 0x04,0x14,0x1C,0x5F,0x53,0x54,0x41,0x00, /* 000003D0 "..._STA." */ ++ 0x7B,0x50,0x49,0x52,0x44,0x0A,0x80,0x60, /* 000003D8 "{PIRD..`" */ ++ 0xA0,0x08,0x93,0x60,0x0A,0x80,0xA4,0x0A, /* 000003E0 "...`...." */ ++ 0x09,0xA1,0x04,0xA4,0x0A,0x0B,0x14,0x0B, /* 000003E8 "........" */ ++ 0x5F,0x50,0x52,0x53,0x00,0xA4,0x42,0x55, /* 000003F0 "_PRS..BU" */ ++ 0x46,0x41,0x14,0x11,0x5F,0x44,0x49,0x53, /* 000003F8 "FA.._DIS" */ ++ 0x00,0x7D,0x50,0x49,0x52,0x44,0x0A,0x80, /* 00000400 ".}PIRD.." */ ++ 0x50,0x49,0x52,0x44,0x14,0x1A,0x5F,0x43, /* 00000408 "PIRD.._C" */ ++ 0x52,0x53,0x00,0x7B,0x50,0x49,0x52,0x44, /* 00000410 "RS.{PIRD" */ ++ 0x0A,0x0F,0x60,0x79,0x01,0x60,0x49,0x52, /* 00000418 "..`y.`IR" */ ++ 0x51,0x56,0xA4,0x42,0x55,0x46,0x42,0x14, /* 00000420 "QV.BUFB." */ ++ 0x1B,0x5F,0x53,0x52,0x53,0x01,0x8B,0x68, /* 00000428 "._SRS..h" */ ++ 0x01,0x49,0x52,0x51,0x31,0x82,0x49,0x52, /* 00000430 ".IRQ1.IR" */ ++ 0x51,0x31,0x60,0x76,0x60,0x70,0x60,0x50, /* 00000438 "Q1`v`p`P" */ ++ 0x49,0x52,0x44,0x5B,0x82,0x44,0x05,0x48, /* 00000440 "IRD[.D.H" */ ++ 0x50,0x45,0x54,0x08,0x5F,0x48,0x49,0x44, /* 00000448 "PET._HID" */ ++ 0x0C,0x41,0xD0,0x01,0x03,0x08,0x5F,0x55, /* 00000450 ".A...._U" */ ++ 0x49,0x44,0x00,0x14,0x18,0x5F,0x53,0x54, /* 00000458 "ID..._ST" */ ++ 0x41,0x00,0xA0,0x0C,0x93,0x5E,0x5E,0x5E, /* 00000460 "A....^^^" */ ++ 0x48,0x50,0x45,0x54,0x00,0xA4,0x00,0xA1, /* 00000468 "HPET...." */ ++ 0x04,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000470 "....._CR" */ ++ 0x53,0x11,0x1F,0x0A,0x1C,0x87,0x17,0x00, /* 00000478 "S......." */ ++ 0x00,0x0D,0x01,0x00,0x00,0x00,0x00,0x00, /* 00000480 "........" */ ++ 0x00,0xD0,0xFE,0xFF,0x03,0xD0,0xFE,0x00, /* 00000488 "........" */ ++ 0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x79, /* 00000490 ".......y" */ ++ 0x00,0x14,0x16,0x5F,0x50,0x52,0x54,0x00, /* 00000498 "..._PRT." */ ++ 0xA0,0x0A,0x50,0x49,0x43,0x44,0xA4,0x50, /* 000004A0 "..PICD.P" */ ++ 0x52,0x54,0x41,0xA4,0x50,0x52,0x54,0x50, /* 000004A8 "RTA.PRTP" */ ++ 0x08,0x50,0x52,0x54,0x50,0x12,0x49,0x36, /* 000004B0 ".PRTP.I6" */ ++ 0x3C,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x01, /* 000004B8 "<......." */ ++ 0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 000004C0 "..LNKB.." */ ++ 0x0D,0x04,0x0C,0xFF,0xFF,0x01,0x00,0x01, /* 000004C8 "........" */ ++ 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 000004D0 "LNKC...." */ ++ 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x02,0x4C, /* 000004D8 ".......L" */ ++ 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 000004E0 "NKD....." */ ++ 0xFF,0xFF,0x01,0x00,0x0A,0x03,0x4C,0x4E, /* 000004E8 "......LN" */ ++ 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000004F0 "KA......" */ ++ 0xFF,0x02,0x00,0x00,0x4C,0x4E,0x4B,0x43, /* 000004F8 "....LNKC" */ ++ 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x02, /* 00000500 "........" */ ++ 0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 00000508 "..LNKD.." */ ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000510 "........" */ ++ 0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 00000518 ".LNKA..." */ ++ 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A,0x03, /* 00000520 "........" */ ++ 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 00000528 "LNKB...." */ ++ 0x0C,0xFF,0xFF,0x03,0x00,0x00,0x4C,0x4E, /* 00000530 "......LN" */ ++ 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000538 "KD......" */ ++ 0xFF,0x03,0x00,0x01,0x4C,0x4E,0x4B,0x41, /* 00000540 "....LNKA" */ ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03, /* 00000548 "........" */ ++ 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00, /* 00000550 "...LNKB." */ ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 00000558 "........" */ ++ 0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000560 "..LNKC.." */ ++ 0x0D,0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00, /* 00000568 "........" */ ++ 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000570 "LNKA...." */ ++ 0x0C,0xFF,0xFF,0x04,0x00,0x01,0x4C,0x4E, /* 00000578 "......LN" */ ++ 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000580 "KB......" */ ++ 0xFF,0x04,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000588 ".....LNK" */ ++ 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000590 "C......." */ ++ 0x04,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44, /* 00000598 "....LNKD" */ ++ 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x05, /* 000005A0 "........" */ ++ 0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 000005A8 "..LNKB.." */ ++ 0x0D,0x04,0x0C,0xFF,0xFF,0x05,0x00,0x01, /* 000005B0 "........" */ ++ 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 000005B8 "LNKC...." */ ++ 0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x02,0x4C, /* 000005C0 ".......L" */ ++ 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 000005C8 "NKD....." */ ++ 0xFF,0xFF,0x05,0x00,0x0A,0x03,0x4C,0x4E, /* 000005D0 "......LN" */ ++ 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000005D8 "KA......" */ ++ 0xFF,0x06,0x00,0x00,0x4C,0x4E,0x4B,0x43, /* 000005E0 "....LNKC" */ ++ 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x06, /* 000005E8 "........" */ ++ 0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 000005F0 "..LNKD.." */ ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A, /* 000005F8 "........" */ ++ 0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 00000600 ".LNKA..." */ ++ 0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A,0x03, /* 00000608 "........" */ ++ 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 00000610 "LNKB...." */ ++ 0x0C,0xFF,0xFF,0x07,0x00,0x00,0x4C,0x4E, /* 00000618 "......LN" */ ++ 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000620 "KD......" */ ++ 0xFF,0x07,0x00,0x01,0x4C,0x4E,0x4B,0x41, /* 00000628 "....LNKA" */ ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07, /* 00000630 "........" */ ++ 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00, /* 00000638 "...LNKB." */ ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x07,0x00, /* 00000640 "........" */ ++ 0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000648 "..LNKC.." */ ++ 0x0D,0x04,0x0C,0xFF,0xFF,0x08,0x00,0x00, /* 00000650 "........" */ ++ 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000658 "LNKA...." */ ++ 0x0C,0xFF,0xFF,0x08,0x00,0x01,0x4C,0x4E, /* 00000660 "......LN" */ ++ 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000668 "KB......" */ ++ 0xFF,0x08,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000670 ".....LNK" */ ++ 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000678 "C......." */ ++ 0x08,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44, /* 00000680 "....LNKD" */ ++ 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x09, /* 00000688 "........" */ ++ 0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000690 "..LNKB.." */ ++ 0x0D,0x04,0x0C,0xFF,0xFF,0x09,0x00,0x01, /* 00000698 "........" */ ++ 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 000006A0 "LNKC...." */ ++ 0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x02,0x4C, /* 000006A8 ".......L" */ ++ 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 000006B0 "NKD....." */ ++ 0xFF,0xFF,0x09,0x00,0x0A,0x03,0x4C,0x4E, /* 000006B8 "......LN" */ ++ 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000006C0 "KA......" */ ++ 0xFF,0x0A,0x00,0x00,0x4C,0x4E,0x4B,0x43, /* 000006C8 "....LNKC" */ ++ 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0A, /* 000006D0 "........" */ ++ 0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 000006D8 "..LNKD.." */ ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A, /* 000006E0 "........" */ ++ 0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 000006E8 ".LNKA..." */ ++ 0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A,0x03, /* 000006F0 "........" */ ++ 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 000006F8 "LNKB...." */ ++ 0x0C,0xFF,0xFF,0x0B,0x00,0x00,0x4C,0x4E, /* 00000700 "......LN" */ ++ 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 00000708 "KD......" */ ++ 0xFF,0x0B,0x00,0x01,0x4C,0x4E,0x4B,0x41, /* 00000710 "....LNKA" */ ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000718 "........" */ ++ 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00, /* 00000720 "...LNKB." */ ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0B,0x00, /* 00000728 "........" */ ++ 0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,0x12, /* 00000730 "..LNKC.." */ ++ 0x0D,0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x00, /* 00000738 "........" */ ++ 0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0D,0x04, /* 00000740 "LNKA...." */ ++ 0x0C,0xFF,0xFF,0x0C,0x00,0x01,0x4C,0x4E, /* 00000748 "......LN" */ ++ 0x4B,0x42,0x00,0x12,0x0E,0x04,0x0C,0xFF, /* 00000750 "KB......" */ ++ 0xFF,0x0C,0x00,0x0A,0x02,0x4C,0x4E,0x4B, /* 00000758 ".....LNK" */ ++ 0x43,0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF, /* 00000760 "C......." */ ++ 0x0C,0x00,0x0A,0x03,0x4C,0x4E,0x4B,0x44, /* 00000768 "....LNKD" */ ++ 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0D, /* 00000770 "........" */ ++ 0x00,0x00,0x4C,0x4E,0x4B,0x42,0x00,0x12, /* 00000778 "..LNKB.." */ ++ 0x0D,0x04,0x0C,0xFF,0xFF,0x0D,0x00,0x01, /* 00000780 "........" */ ++ 0x4C,0x4E,0x4B,0x43,0x00,0x12,0x0E,0x04, /* 00000788 "LNKC...." */ ++ 0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x02,0x4C, /* 00000790 ".......L" */ ++ 0x4E,0x4B,0x44,0x00,0x12,0x0E,0x04,0x0C, /* 00000798 "NKD....." */ ++ 0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x4C,0x4E, /* 000007A0 "......LN" */ ++ 0x4B,0x41,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000007A8 "KA......" */ ++ 0xFF,0x0E,0x00,0x00,0x4C,0x4E,0x4B,0x43, /* 000007B0 "....LNKC" */ ++ 0x00,0x12,0x0D,0x04,0x0C,0xFF,0xFF,0x0E, /* 000007B8 "........" */ ++ 0x00,0x01,0x4C,0x4E,0x4B,0x44,0x00,0x12, /* 000007C0 "..LNKD.." */ ++ 0x0E,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A, /* 000007C8 "........" */ ++ 0x02,0x4C,0x4E,0x4B,0x41,0x00,0x12,0x0E, /* 000007D0 ".LNKA..." */ ++ 0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A,0x03, /* 000007D8 "........" */ ++ 0x4C,0x4E,0x4B,0x42,0x00,0x12,0x0D,0x04, /* 000007E0 "LNKB...." */ ++ 0x0C,0xFF,0xFF,0x0F,0x00,0x00,0x4C,0x4E, /* 000007E8 "......LN" */ ++ 0x4B,0x44,0x00,0x12,0x0D,0x04,0x0C,0xFF, /* 000007F0 "KD......" */ ++ 0xFF,0x0F,0x00,0x01,0x4C,0x4E,0x4B,0x41, /* 000007F8 "....LNKA" */ ++ 0x00,0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000800 "........" */ ++ 0x00,0x0A,0x02,0x4C,0x4E,0x4B,0x42,0x00, /* 00000808 "...LNKB." */ ++ 0x12,0x0E,0x04,0x0C,0xFF,0xFF,0x0F,0x00, /* 00000810 "........" */ ++ 0x0A,0x03,0x4C,0x4E,0x4B,0x43,0x00,0x08, /* 00000818 "..LNKC.." */ ++ 0x50,0x52,0x54,0x41,0x12,0x41,0x2F,0x3C, /* 00000820 "PRTA.A/<" */ ++ 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 00000828 "........" */ ++ 0x00,0x00,0x0A,0x14,0x12,0x0B,0x04,0x0C, /* 00000830 "........" */ ++ 0xFF,0xFF,0x01,0x00,0x01,0x00,0x0A,0x15, /* 00000838 "........" */ ++ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x01,0x00, /* 00000840 "........" */ ++ 0x0A,0x02,0x00,0x0A,0x16,0x12,0x0C,0x04, /* 00000848 "........" */ ++ 0x0C,0xFF,0xFF,0x01,0x00,0x0A,0x03,0x00, /* 00000850 "........" */ ++ 0x0A,0x17,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000858 "........" */ ++ 0x02,0x00,0x00,0x00,0x0A,0x18,0x12,0x0B, /* 00000860 "........" */ ++ 0x04,0x0C,0xFF,0xFF,0x02,0x00,0x01,0x00, /* 00000868 "........" */ ++ 0x0A,0x19,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000870 "........" */ ++ 0x02,0x00,0x0A,0x02,0x00,0x0A,0x1A,0x12, /* 00000878 "........" */ ++ 0x0C,0x04,0x0C,0xFF,0xFF,0x02,0x00,0x0A, /* 00000880 "........" */ ++ 0x03,0x00,0x0A,0x1B,0x12,0x0B,0x04,0x0C, /* 00000888 "........" */ ++ 0xFF,0xFF,0x03,0x00,0x00,0x00,0x0A,0x1C, /* 00000890 "........" */ ++ 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x03,0x00, /* 00000898 "........" */ ++ 0x01,0x00,0x0A,0x1D,0x12,0x0C,0x04,0x0C, /* 000008A0 "........" */ ++ 0xFF,0xFF,0x03,0x00,0x0A,0x02,0x00,0x0A, /* 000008A8 "........" */ ++ 0x1E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x03, /* 000008B0 "........" */ ++ 0x00,0x0A,0x03,0x00,0x0A,0x1F,0x12,0x0B, /* 000008B8 "........" */ ++ 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x00,0x00, /* 000008C0 "........" */ ++ 0x0A,0x20,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000008C8 ". ......" */ ++ 0x04,0x00,0x01,0x00,0x0A,0x21,0x12,0x0C, /* 000008D0 ".....!.." */ ++ 0x04,0x0C,0xFF,0xFF,0x04,0x00,0x0A,0x02, /* 000008D8 "........" */ ++ 0x00,0x0A,0x22,0x12,0x0C,0x04,0x0C,0xFF, /* 000008E0 ".."....." */ ++ 0xFF,0x04,0x00,0x0A,0x03,0x00,0x0A,0x23, /* 000008E8 ".......#" */ ++ 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 000008F0 "........" */ ++ 0x00,0x00,0x0A,0x24,0x12,0x0B,0x04,0x0C, /* 000008F8 "...$...." */ ++ 0xFF,0xFF,0x05,0x00,0x01,0x00,0x0A,0x25, /* 00000900 ".......%" */ ++ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x05,0x00, /* 00000908 "........" */ ++ 0x0A,0x02,0x00,0x0A,0x26,0x12,0x0C,0x04, /* 00000910 "....&..." */ ++ 0x0C,0xFF,0xFF,0x05,0x00,0x0A,0x03,0x00, /* 00000918 "........" */ ++ 0x0A,0x27,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000920 ".'......" */ ++ 0x06,0x00,0x00,0x00,0x0A,0x28,0x12,0x0B, /* 00000928 ".....(.." */ ++ 0x04,0x0C,0xFF,0xFF,0x06,0x00,0x01,0x00, /* 00000930 "........" */ ++ 0x0A,0x29,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000938 ".)......" */ ++ 0x06,0x00,0x0A,0x02,0x00,0x0A,0x2A,0x12, /* 00000940 "......*." */ ++ 0x0C,0x04,0x0C,0xFF,0xFF,0x06,0x00,0x0A, /* 00000948 "........" */ ++ 0x03,0x00,0x0A,0x2B,0x12,0x0B,0x04,0x0C, /* 00000950 "...+...." */ ++ 0xFF,0xFF,0x07,0x00,0x00,0x00,0x0A,0x2C, /* 00000958 ".......," */ ++ 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x07,0x00, /* 00000960 "........" */ ++ 0x01,0x00,0x0A,0x2D,0x12,0x0C,0x04,0x0C, /* 00000968 "...-...." */ ++ 0xFF,0xFF,0x07,0x00,0x0A,0x02,0x00,0x0A, /* 00000970 "........" */ ++ 0x2E,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x07, /* 00000978 "........" */ ++ 0x00,0x0A,0x03,0x00,0x0A,0x2F,0x12,0x0B, /* 00000980 "...../.." */ ++ 0x04,0x0C,0xFF,0xFF,0x08,0x00,0x00,0x00, /* 00000988 "........" */ ++ 0x0A,0x11,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000990 "........" */ ++ 0x08,0x00,0x01,0x00,0x0A,0x12,0x12,0x0C, /* 00000998 "........" */ ++ 0x04,0x0C,0xFF,0xFF,0x08,0x00,0x0A,0x02, /* 000009A0 "........" */ ++ 0x00,0x0A,0x13,0x12,0x0C,0x04,0x0C,0xFF, /* 000009A8 "........" */ ++ 0xFF,0x08,0x00,0x0A,0x03,0x00,0x0A,0x14, /* 000009B0 "........" */ ++ 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 000009B8 "........" */ ++ 0x00,0x00,0x0A,0x15,0x12,0x0B,0x04,0x0C, /* 000009C0 "........" */ ++ 0xFF,0xFF,0x09,0x00,0x01,0x00,0x0A,0x16, /* 000009C8 "........" */ ++ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x09,0x00, /* 000009D0 "........" */ ++ 0x0A,0x02,0x00,0x0A,0x17,0x12,0x0C,0x04, /* 000009D8 "........" */ ++ 0x0C,0xFF,0xFF,0x09,0x00,0x0A,0x03,0x00, /* 000009E0 "........" */ ++ 0x0A,0x18,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 000009E8 "........" */ ++ 0x0A,0x00,0x00,0x00,0x0A,0x19,0x12,0x0B, /* 000009F0 "........" */ ++ 0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x01,0x00, /* 000009F8 "........" */ ++ 0x0A,0x1A,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000A00 "........" */ ++ 0x0A,0x00,0x0A,0x02,0x00,0x0A,0x1B,0x12, /* 00000A08 "........" */ ++ 0x0C,0x04,0x0C,0xFF,0xFF,0x0A,0x00,0x0A, /* 00000A10 "........" */ ++ 0x03,0x00,0x0A,0x1C,0x12,0x0B,0x04,0x0C, /* 00000A18 "........" */ ++ 0xFF,0xFF,0x0B,0x00,0x00,0x00,0x0A,0x1D, /* 00000A20 "........" */ ++ 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0B,0x00, /* 00000A28 "........" */ ++ 0x01,0x00,0x0A,0x1E,0x12,0x0C,0x04,0x0C, /* 00000A30 "........" */ ++ 0xFF,0xFF,0x0B,0x00,0x0A,0x02,0x00,0x0A, /* 00000A38 "........" */ ++ 0x1F,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0B, /* 00000A40 "........" */ ++ 0x00,0x0A,0x03,0x00,0x0A,0x20,0x12,0x0B, /* 00000A48 "..... .." */ ++ 0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x00,0x00, /* 00000A50 "........" */ ++ 0x0A,0x21,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000A58 ".!......" */ ++ 0x0C,0x00,0x01,0x00,0x0A,0x22,0x12,0x0C, /* 00000A60 ".....".." */ ++ 0x04,0x0C,0xFF,0xFF,0x0C,0x00,0x0A,0x02, /* 00000A68 "........" */ ++ 0x00,0x0A,0x23,0x12,0x0C,0x04,0x0C,0xFF, /* 00000A70 "..#....." */ ++ 0xFF,0x0C,0x00,0x0A,0x03,0x00,0x0A,0x24, /* 00000A78 ".......$" */ ++ 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 00000A80 "........" */ ++ 0x00,0x00,0x0A,0x25,0x12,0x0B,0x04,0x0C, /* 00000A88 "...%...." */ ++ 0xFF,0xFF,0x0D,0x00,0x01,0x00,0x0A,0x26, /* 00000A90 ".......&" */ ++ 0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0D,0x00, /* 00000A98 "........" */ ++ 0x0A,0x02,0x00,0x0A,0x27,0x12,0x0C,0x04, /* 00000AA0 "....'..." */ ++ 0x0C,0xFF,0xFF,0x0D,0x00,0x0A,0x03,0x00, /* 00000AA8 "........" */ ++ 0x0A,0x28,0x12,0x0B,0x04,0x0C,0xFF,0xFF, /* 00000AB0 ".(......" */ ++ 0x0E,0x00,0x00,0x00,0x0A,0x29,0x12,0x0B, /* 00000AB8 ".....).." */ ++ 0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x01,0x00, /* 00000AC0 "........" */ ++ 0x0A,0x2A,0x12,0x0C,0x04,0x0C,0xFF,0xFF, /* 00000AC8 ".*......" */ ++ 0x0E,0x00,0x0A,0x02,0x00,0x0A,0x2B,0x12, /* 00000AD0 "......+." */ ++ 0x0C,0x04,0x0C,0xFF,0xFF,0x0E,0x00,0x0A, /* 00000AD8 "........" */ ++ 0x03,0x00,0x0A,0x2C,0x12,0x0B,0x04,0x0C, /* 00000AE0 "...,...." */ ++ 0xFF,0xFF,0x0F,0x00,0x00,0x00,0x0A,0x2D, /* 00000AE8 ".......-" */ ++ 0x12,0x0B,0x04,0x0C,0xFF,0xFF,0x0F,0x00, /* 00000AF0 "........" */ ++ 0x01,0x00,0x0A,0x2E,0x12,0x0C,0x04,0x0C, /* 00000AF8 "........" */ ++ 0xFF,0xFF,0x0F,0x00,0x0A,0x02,0x00,0x0A, /* 00000B00 "........" */ ++ 0x2F,0x12,0x0C,0x04,0x0C,0xFF,0xFF,0x0F, /* 00000B08 "/......." */ ++ 0x00,0x0A,0x03,0x00,0x0A,0x10,0x5B,0x82, /* 00000B10 "......[." */ ++ 0x46,0x37,0x49,0x53,0x41,0x5F,0x08,0x5F, /* 00000B18 "F7ISA_._" */ ++ 0x41,0x44,0x52,0x0C,0x00,0x00,0x01,0x00, /* 00000B20 "ADR....." */ ++ 0x5B,0x80,0x50,0x49,0x52,0x51,0x02,0x0A, /* 00000B28 "[.PIRQ.." */ ++ 0x60,0x0A,0x04,0x10,0x2E,0x5C,0x00,0x5B, /* 00000B30 "`....\.[" */ ++ 0x81,0x29,0x5C,0x2F,0x04,0x5F,0x53,0x42, /* 00000B38 ".)\/._SB" */ ++ 0x5F,0x50,0x43,0x49,0x30,0x49,0x53,0x41, /* 00000B40 "_PCI0ISA" */ ++ 0x5F,0x50,0x49,0x52,0x51,0x01,0x50,0x49, /* 00000B48 "_PIRQ.PI" */ ++ 0x52,0x41,0x08,0x50,0x49,0x52,0x42,0x08, /* 00000B50 "RA.PIRB." */ ++ 0x50,0x49,0x52,0x43,0x08,0x50,0x49,0x52, /* 00000B58 "PIRC.PIR" */ ++ 0x44,0x08,0x5B,0x82,0x46,0x0B,0x53,0x59, /* 00000B60 "D.[.F.SY" */ ++ 0x53,0x52,0x08,0x5F,0x48,0x49,0x44,0x0C, /* 00000B68 "SR._HID." */ ++ 0x41,0xD0,0x0C,0x02,0x08,0x5F,0x55,0x49, /* 00000B70 "A...._UI" */ ++ 0x44,0x01,0x08,0x43,0x52,0x53,0x5F,0x11, /* 00000B78 "D..CRS_." */ ++ 0x4E,0x08,0x0A,0x8A,0x47,0x01,0x10,0x00, /* 00000B80 "N...G..." */ ++ 0x10,0x00,0x00,0x10,0x47,0x01,0x22,0x00, /* 00000B88 "....G."." */ ++ 0x22,0x00,0x00,0x0C,0x47,0x01,0x30,0x00, /* 00000B90 ""...G.0." */ ++ 0x30,0x00,0x00,0x10,0x47,0x01,0x44,0x00, /* 00000B98 "0...G.D." */ ++ 0x44,0x00,0x00,0x1C,0x47,0x01,0x62,0x00, /* 00000BA0 "D...G.b." */ ++ 0x62,0x00,0x00,0x02,0x47,0x01,0x65,0x00, /* 00000BA8 "b...G.e." */ ++ 0x65,0x00,0x00,0x0B,0x47,0x01,0x72,0x00, /* 00000BB0 "e...G.r." */ ++ 0x72,0x00,0x00,0x0E,0x47,0x01,0x80,0x00, /* 00000BB8 "r...G..." */ ++ 0x80,0x00,0x00,0x01,0x47,0x01,0x84,0x00, /* 00000BC0 "....G..." */ ++ 0x84,0x00,0x00,0x03,0x47,0x01,0x88,0x00, /* 00000BC8 "....G..." */ ++ 0x88,0x00,0x00,0x01,0x47,0x01,0x8C,0x00, /* 00000BD0 "....G..." */ ++ 0x8C,0x00,0x00,0x03,0x47,0x01,0x90,0x00, /* 00000BD8 "....G..." */ ++ 0x90,0x00,0x00,0x10,0x47,0x01,0xA2,0x00, /* 00000BE0 "....G..." */ ++ 0xA2,0x00,0x00,0x1C,0x47,0x01,0xE0,0x00, /* 00000BE8 "....G..." */ ++ 0xE0,0x00,0x00,0x10,0x47,0x01,0xA0,0x08, /* 00000BF0 "....G..." */ ++ 0xA0,0x08,0x00,0x04,0x47,0x01,0xC0,0x0C, /* 00000BF8 "....G..." */ ++ 0xC0,0x0C,0x00,0x10,0x47,0x01,0xD0,0x04, /* 00000C00 "....G..." */ ++ 0xD0,0x04,0x00,0x02,0x79,0x00,0x14,0x0B, /* 00000C08 "....y..." */ ++ 0x5F,0x43,0x52,0x53,0x00,0xA4,0x43,0x52, /* 00000C10 "_CRS..CR" */ ++ 0x53,0x5F,0x5B,0x82,0x2B,0x50,0x49,0x43, /* 00000C18 "S_[.+PIC" */ ++ 0x5F,0x08,0x5F,0x48,0x49,0x44,0x0B,0x41, /* 00000C20 "_._HID.A" */ ++ 0xD0,0x08,0x5F,0x43,0x52,0x53,0x11,0x18, /* 00000C28 ".._CRS.." */ ++ 0x0A,0x15,0x47,0x01,0x20,0x00,0x20,0x00, /* 00000C30 "..G. . ." */ ++ 0x01,0x02,0x47,0x01,0xA0,0x00,0xA0,0x00, /* 00000C38 "..G....." */ ++ 0x01,0x02,0x22,0x04,0x00,0x79,0x00,0x5B, /* 00000C40 ".."..y.[" */ ++ 0x82,0x47,0x05,0x44,0x4D,0x41,0x30,0x08, /* 00000C48 ".G.DMA0." */ ++ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x02, /* 00000C50 "_HID.A.." */ ++ 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x41, /* 00000C58 ".._CRS.A" */ ++ 0x04,0x0A,0x3D,0x2A,0x10,0x04,0x47,0x01, /* 00000C60 "..=*..G." */ ++ 0x00,0x00,0x00,0x00,0x00,0x10,0x47,0x01, /* 00000C68 "......G." */ ++ 0x81,0x00,0x81,0x00,0x00,0x03,0x47,0x01, /* 00000C70 "......G." */ ++ 0x87,0x00,0x87,0x00,0x00,0x01,0x47,0x01, /* 00000C78 "......G." */ ++ 0x89,0x00,0x89,0x00,0x00,0x03,0x47,0x01, /* 00000C80 "......G." */ ++ 0x8F,0x00,0x8F,0x00,0x00,0x01,0x47,0x01, /* 00000C88 "......G." */ ++ 0xC0,0x00,0xC0,0x00,0x00,0x20,0x47,0x01, /* 00000C90 "..... G." */ ++ 0x80,0x04,0x80,0x04,0x00,0x10,0x79,0x00, /* 00000C98 "......y." */ ++ 0x5B,0x82,0x25,0x54,0x4D,0x52,0x5F,0x08, /* 00000CA0 "[.%TMR_." */ ++ 0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0,0x01, /* 00000CA8 "_HID.A.." */ ++ 0x00,0x08,0x5F,0x43,0x52,0x53,0x11,0x10, /* 00000CB0 ".._CRS.." */ ++ 0x0A,0x0D,0x47,0x01,0x40,0x00,0x40,0x00, /* 00000CB8 "..G.@.@." */ ++ 0x00,0x04,0x22,0x01,0x00,0x79,0x00,0x5B, /* 00000CC0 ".."..y.[" */ ++ 0x82,0x25,0x52,0x54,0x43,0x5F,0x08,0x5F, /* 00000CC8 ".%RTC_._" */ ++ 0x48,0x49,0x44,0x0C,0x41,0xD0,0x0B,0x00, /* 00000CD0 "HID.A..." */ ++ 0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A, /* 00000CD8 "._CRS..." */ ++ 0x0D,0x47,0x01,0x70,0x00,0x70,0x00,0x00, /* 00000CE0 ".G.p.p.." */ ++ 0x02,0x22,0x00,0x01,0x79,0x00,0x5B,0x82, /* 00000CE8 "."..y.[." */ ++ 0x22,0x53,0x50,0x4B,0x52,0x08,0x5F,0x48, /* 00000CF0 ""SPKR._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x08,0x00,0x08, /* 00000CF8 "ID.A...." */ ++ 0x5F,0x43,0x52,0x53,0x11,0x0D,0x0A,0x0A, /* 00000D00 "_CRS...." */ ++ 0x47,0x01,0x61,0x00,0x61,0x00,0x00,0x01, /* 00000D08 "G.a.a..." */ ++ 0x79,0x00,0x5B,0x82,0x31,0x50,0x53,0x32, /* 00000D10 "y.[.1PS2" */ ++ 0x4D,0x08,0x5F,0x48,0x49,0x44,0x0C,0x41, /* 00000D18 "M._HID.A" */ ++ 0xD0,0x0F,0x13,0x08,0x5F,0x43,0x49,0x44, /* 00000D20 "...._CID" */ ++ 0x0C,0x41,0xD0,0x0F,0x13,0x14,0x09,0x5F, /* 00000D28 ".A....._" */ ++ 0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F,0x08, /* 00000D30 "STA....." */ ++ 0x5F,0x43,0x52,0x53,0x11,0x08,0x0A,0x05, /* 00000D38 "_CRS...." */ ++ 0x22,0x00,0x10,0x79,0x00,0x5B,0x82,0x42, /* 00000D40 ""..y.[.B" */ ++ 0x04,0x50,0x53,0x32,0x4B,0x08,0x5F,0x48, /* 00000D48 ".PS2K._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x03,0x03,0x08, /* 00000D50 "ID.A...." */ ++ 0x5F,0x43,0x49,0x44,0x0C,0x41,0xD0,0x03, /* 00000D58 "_CID.A.." */ ++ 0x0B,0x14,0x09,0x5F,0x53,0x54,0x41,0x00, /* 00000D60 "..._STA." */ ++ 0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52,0x53, /* 00000D68 "...._CRS" */ ++ 0x11,0x18,0x0A,0x15,0x47,0x01,0x60,0x00, /* 00000D70 "....G.`." */ ++ 0x60,0x00,0x00,0x01,0x47,0x01,0x64,0x00, /* 00000D78 "`...G.d." */ ++ 0x64,0x00,0x00,0x01,0x22,0x02,0x00,0x79, /* 00000D80 "d..."..y" */ ++ 0x00,0x5B,0x82,0x3A,0x46,0x44,0x43,0x30, /* 00000D88 ".[.:FDC0" */ ++ 0x08,0x5F,0x48,0x49,0x44,0x0C,0x41,0xD0, /* 00000D90 "._HID.A." */ ++ 0x07,0x00,0x14,0x09,0x5F,0x53,0x54,0x41, /* 00000D98 "...._STA" */ ++ 0x00,0xA4,0x0A,0x0F,0x08,0x5F,0x43,0x52, /* 00000DA0 "....._CR" */ ++ 0x53,0x11,0x1B,0x0A,0x18,0x47,0x01,0xF0, /* 00000DA8 "S....G.." */ ++ 0x03,0xF0,0x03,0x01,0x06,0x47,0x01,0xF7, /* 00000DB0 ".....G.." */ ++ 0x03,0xF7,0x03,0x01,0x01,0x22,0x40,0x00, /* 00000DB8 "....."@." */ ++ 0x2A,0x04,0x00,0x79,0x00,0x5B,0x82,0x46, /* 00000DC0 "*..y.[.F" */ ++ 0x04,0x55,0x41,0x52,0x31,0x08,0x5F,0x48, /* 00000DC8 ".UAR1._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,0x08, /* 00000DD0 "ID.A...." */ ++ 0x5F,0x55,0x49,0x44,0x01,0x14,0x19,0x5F, /* 00000DD8 "_UID..._" */ ++ 0x53,0x54,0x41,0x00,0xA0,0x0D,0x93,0x5E, /* 00000DE0 "STA....^" */ ++ 0x5E,0x5E,0x5E,0x55,0x41,0x52,0x31,0x00, /* 00000DE8 "^^^UAR1." */ ++ 0xA4,0x00,0xA1,0x04,0xA4,0x0A,0x0F,0x08, /* 00000DF0 "........" */ ++ 0x5F,0x43,0x52,0x53,0x11,0x10,0x0A,0x0D, /* 00000DF8 "_CRS...." */ ++ 0x47,0x01,0xF8,0x03,0xF8,0x03,0x08,0x08, /* 00000E00 "G......." */ ++ 0x22,0x10,0x00,0x79,0x00,0x5B,0x82,0x47, /* 00000E08 ""..y.[.G" */ ++ 0x04,0x55,0x41,0x52,0x32,0x08,0x5F,0x48, /* 00000E10 ".UAR2._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x05,0x01,0x08, /* 00000E18 "ID.A...." */ ++ 0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,0x19, /* 00000E20 "_UID...." */ ++ 0x5F,0x53,0x54,0x41,0x00,0xA0,0x0D,0x93, /* 00000E28 "_STA...." */ ++ 0x5E,0x5E,0x5E,0x5E,0x55,0x41,0x52,0x32, /* 00000E30 "^^^^UAR2" */ ++ 0x00,0xA4,0x00,0xA1,0x04,0xA4,0x0A,0x0F, /* 00000E38 "........" */ ++ 0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A, /* 00000E40 "._CRS..." */ ++ 0x0D,0x47,0x01,0xF8,0x02,0xF8,0x02,0x08, /* 00000E48 ".G......" */ ++ 0x08,0x22,0x08,0x00,0x79,0x00,0x5B,0x82, /* 00000E50 "."..y.[." */ ++ 0x36,0x4C,0x54,0x50,0x31,0x08,0x5F,0x48, /* 00000E58 "6LTP1._H" */ ++ 0x49,0x44,0x0C,0x41,0xD0,0x04,0x00,0x08, /* 00000E60 "ID.A...." */ ++ 0x5F,0x55,0x49,0x44,0x0A,0x02,0x14,0x09, /* 00000E68 "_UID...." */ ++ 0x5F,0x53,0x54,0x41,0x00,0xA4,0x0A,0x0F, /* 00000E70 "_STA...." */ ++ 0x08,0x5F,0x43,0x52,0x53,0x11,0x10,0x0A, /* 00000E78 "._CRS..." */ ++ 0x0D,0x47,0x01,0x78,0x03,0x78,0x03,0x08, /* 00000E80 ".G.x.x.." */ ++ 0x08,0x22,0x80,0x00,0x79,0x00, + }; + int DsdtLen=sizeof(AmlCode); +Index: xen-3.2-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.2-testing/tools/python/xen/xend/XendConfig.py +@@ -127,7 +127,7 @@ LEGACY_CFG_TO_XENAPI_CFG = reverse_dict( + XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 'boot', 'device_model', 'display', + 'fda', 'fdb', 'keymap', 'isa', 'localtime', 'monitor', + 'nographic', 'pae', 'rtc_timeoffset', 'serial', 'sdl', +- 'soundhw','stdvga', 'usb', 'usbdevice', 'vnc', ++ 'soundhw','stdvga', 'usb', 'usbdevice', 'hpet', 'vnc', + 'vncconsole', 'vncdisplay', 'vnclisten', 'timer_mode', + 'vncpasswd', 'vncunused', 'xauthority', 'pci', 'vhpt', + 'guest_os_type' ] +Index: xen-3.2-testing/tools/python/xen/xend/XendConstants.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendConstants.py ++++ xen-3.2-testing/tools/python/xen/xend/XendConstants.py +@@ -47,6 +47,7 @@ HVM_PARAM_NVRAM_FD = 7 + HVM_PARAM_VHPT_SIZE = 8 + HVM_PARAM_BUFPIOREQ_PFN = 9 + HVM_PARAM_TIMER_MODE = 10 ++HVM_PARAM_HPET_ENABLED = 11 + + restart_modes = [ + "restart", +Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py ++++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py +@@ -1682,6 +1682,12 @@ class XendDomainInfo: + xc.hvm_set_param(self.domid, HVM_PARAM_TIMER_MODE, + long(self.info["platform"].get("timer_mode"))) + ++ # Optionally enable virtual HPET ++ hpet = self.info["platform"].get("hpet") ++ if hvm and hpet is not None: ++ xc.hvm_set_param(self.domid, HVM_PARAM_HPET_ENABLED, ++ long(hpet)) ++ + # Set maximum number of vcpus in domain + xc.domain_max_vcpus(self.domid, int(self.info['VCPUs_max'])) + +Index: xen-3.2-testing/tools/python/xen/xm/create.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xm/create.py ++++ xen-3.2-testing/tools/python/xen/xm/create.py +@@ -194,6 +194,10 @@ gopts.var('pae', val='PAE', + fn=set_int, default=1, + use="Disable or enable PAE of HVM domain.") + ++gopts.var('hpet', val='HPET', ++ fn=set_int, default=0, ++ use="Enable virtual high-precision event timer.") ++ + gopts.var('timer_mode', val='TIMER_MODE', + fn=set_int, default=0, + use="""Timer mode (0=delay virtual time when ticks are missed; +@@ -725,7 +729,7 @@ def configure_hvm(config_image, vals): + 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', + 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', + 'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor', +- 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', ++ 'acpi', 'apic', 'usb', 'usbdevice', 'keymap', 'pci', 'hpet', + 'guest_os_type'] + + for a in args: +Index: xen-3.2-testing/tools/python/xen/xm/xenapi_create.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xm/xenapi_create.py ++++ xen-3.2-testing/tools/python/xen/xm/xenapi_create.py +@@ -818,7 +818,8 @@ class sxp2xml: + + + def extract_platform(self, image, document): +- platform_keys = ['acpi', 'apic', 'pae', 'vhpt', 'timer_mode'] ++ platform_keys = ['acpi', 'apic', 'pae', 'vhpt', 'timer_mode', ++ 'hap', 'hpet'] + + def extract_platform_key(key): + platform = document.createElement("platform") +Index: xen-3.2-testing/xen/arch/x86/hvm/hpet.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/hpet.c ++++ xen-3.2-testing/xen/arch/x86/hvm/hpet.c +@@ -353,7 +353,8 @@ static void hpet_write( + + static int hpet_range(struct vcpu *v, unsigned long addr) + { +- return ((addr >= HPET_BASE_ADDRESS) && ++ return (v->domain->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] && ++ (addr >= HPET_BASE_ADDRESS) && + (addr < (HPET_BASE_ADDRESS + HPET_MMAP_SIZE))); + } + +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/hvm.c ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm.c +@@ -235,6 +235,8 @@ int hvm_domain_initialise(struct domain + spin_lock_init(&d->arch.hvm_domain.irq_lock); + spin_lock_init(&d->arch.hvm_domain.uc_lock); + ++ d->arch.hvm_domain.params[HVM_PARAM_HPET_ENABLED] = 1; ++ + hvm_init_cacheattr_region_list(d); + + rc = paging_enable(d, PG_refcounts|PG_translate|PG_external); +Index: xen-3.2-testing/xen/include/public/hvm/params.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/public/hvm/params.h ++++ xen-3.2-testing/xen/include/public/hvm/params.h +@@ -81,6 +81,9 @@ + #define HVMPTM_no_missed_ticks_pending 2 + #define HVMPTM_one_missed_tick_pending 3 + +-#define HVM_NR_PARAMS 11 ++/* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */ ++#define HVM_PARAM_HPET_ENABLED 11 ++ ++#define HVM_NR_PARAMS 12 + + #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/17036-mismatched-save-rest-fix.patch b/17036-mismatched-save-rest-fix.patch new file mode 100644 index 0000000..4f6de1f --- /dev/null +++ b/17036-mismatched-save-rest-fix.patch @@ -0,0 +1,235 @@ +# HG changeset patch +# User Keir Fraser +# Date 1202899393 0 +# Node ID 0164d924cebacfef62673a49c2f4ad395df5444b +# Parent 27314cfbcefe8ee261da3ea827eb8336c32ad987 +Tools: fix save/restore of 32-bit PV guests with 64-bit tools +by removing some obvious typos, handling CR3 folding and hvirt_start +based on guest word-size, and understanding 32-bit INVALID_MFN. + +Signed-off-by: Tim Deegan + +Index: xen-3.2-testing/tools/libxc/xc_domain_restore.c +=================================================================== +--- xen-3.2-testing.orig/tools/libxc/xc_domain_restore.c ++++ xen-3.2-testing/tools/libxc/xc_domain_restore.c +@@ -251,7 +251,7 @@ static xen_pfn_t *load_p2m_frame_list( + + /* Now that we know the guest's word-size, can safely allocate + * the p2m frame list */ +- if ( (p2m_frame_list = malloc(P2M_FL_SIZE)) == NULL ) ++ if ( (p2m_frame_list = malloc(P2M_TOOLS_FL_SIZE)) == NULL ) + { + ERROR("Couldn't allocate p2m_frame_list array"); + return NULL; +@@ -1040,7 +1040,7 @@ int xc_domain_restore(int xc_handle, int + SET_FIELD(&ctxt, gdt_frames[j], p2m[pfn]); + } + /* Uncanonicalise the page table base pointer. */ +- pfn = xen_cr3_to_pfn(GET_FIELD(&ctxt, ctrlreg[3])); ++ pfn = UNFOLD_CR3(GET_FIELD(&ctxt, ctrlreg[3])); + + if ( pfn >= p2m_size ) + { +@@ -1057,12 +1057,12 @@ int xc_domain_restore(int xc_handle, int + (unsigned long)pt_levels<= p2m_size ) + { + ERROR("User PT base is bad: pfn=%lu p2m_size=%lu", +@@ -1077,7 +1077,7 @@ int xc_domain_restore(int xc_handle, int + (unsigned long)pt_levels< sizeof (xen_pfn_t) ) + for ( i = p2m_size - 1; i >= 0; i-- ) + ((uint64_t *)p2m)[i] = p2m[i]; +- else if ( guest_width > sizeof (xen_pfn_t) ) ++ else if ( guest_width < sizeof (xen_pfn_t) ) + for ( i = 0; i < p2m_size; i++ ) + ((uint32_t *)p2m)[i] = p2m[i]; + +Index: xen-3.2-testing/tools/libxc/xc_domain_save.c +=================================================================== +--- xen-3.2-testing.orig/tools/libxc/xc_domain_save.c ++++ xen-3.2-testing/tools/libxc/xc_domain_save.c +@@ -61,10 +61,11 @@ unsigned int guest_width; + + #define mfn_to_pfn(_mfn) (live_m2p[(_mfn)]) + +-#define pfn_to_mfn(_pfn) \ +- ((xen_pfn_t) ((guest_width==8) \ +- ? (((uint64_t *)live_p2m)[(_pfn)]) \ +- : (((uint32_t *)live_p2m)[(_pfn)]))) ++#define pfn_to_mfn(_pfn) \ ++ ((xen_pfn_t) ((guest_width==8) \ ++ ? (((uint64_t *)live_p2m)[(_pfn)]) \ ++ : ((((uint32_t *)live_p2m)[(_pfn)]) == 0xffffffffU \ ++ ? (-1UL) : (((uint32_t *)live_p2m)[(_pfn)])))) + + /* + * Returns TRUE if the given machine frame number has a unique mapping +@@ -496,10 +497,9 @@ static int canonicalize_pagetable(unsign + xen_start = L3_PAGETABLE_ENTRIES_PAE; + + /* +- ** in PAE only the L2 mapping the top 1GB contains Xen mappings. +- ** We can spot this by looking for the guest linear mapping which +- ** Xen always ensures is present in that L2. Guests must ensure +- ** that this check will fail for other L2s. ++ ** In PAE only the L2 mapping the top 1GB contains Xen mappings. ++ ** We can spot this by looking for the guest's mappingof the m2p. ++ ** Guests must ensure that this check will fail for other L2s. + */ + if ( (pt_levels == 3) && (type == XEN_DOMCTL_PFINFO_L2TAB) ) + { +@@ -555,7 +555,13 @@ static int canonicalize_pagetable(unsign + /* This will happen if the type info is stale which + is quite feasible under live migration */ + pfn = 0; /* zap it - we'll retransmit this page later */ +- race = 1; /* inform the caller of race; fatal if !live */ ++ /* XXX: We can't spot Xen mappings in compat-mode L2es ++ * from 64-bit tools, but the only thing in them is the ++ * compat m2p, so we quietly zap them. This doesn't ++ * count as a race, so don't report it. */ ++ if ( !(type == XEN_DOMCTL_PFINFO_L2TAB ++ && sizeof (unsigned long) > guest_width) ) ++ race = 1; /* inform the caller; fatal if !live */ + } + else + pfn = mfn_to_pfn(mfn); +@@ -690,7 +696,7 @@ static xen_pfn_t *map_and_save_p2m_table + else + p2m_frame_list_list[i] = 0; + else if ( guest_width < sizeof(unsigned long) ) +- for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i++ ) ++ for ( i = PAGE_SIZE/sizeof(unsigned long) - 1; i >= 0; i-- ) + p2m_frame_list_list[i] = ((uint32_t *)p2m_frame_list_list)[i]; + + live_p2m_frame_list = +@@ -704,19 +710,20 @@ static xen_pfn_t *map_and_save_p2m_table + } + + /* Get a local copy of the live_P2M_frame_list */ +- if ( !(p2m_frame_list = malloc(P2M_FL_SIZE)) ) ++ if ( !(p2m_frame_list = malloc(P2M_TOOLS_FL_SIZE)) ) + { + ERROR("Couldn't allocate p2m_frame_list array"); + goto out; + } +- memcpy(p2m_frame_list, live_p2m_frame_list, P2M_FL_SIZE); ++ memset(p2m_frame_list, 0, P2M_TOOLS_FL_SIZE); ++ memcpy(p2m_frame_list, live_p2m_frame_list, P2M_GUEST_FL_SIZE); + + /* Canonicalize guest's unsigned long vs ours */ + if ( guest_width > sizeof(unsigned long) ) + for ( i = 0; i < P2M_FL_ENTRIES; i++ ) + p2m_frame_list[i] = ((uint64_t *)p2m_frame_list)[i]; + else if ( guest_width < sizeof(unsigned long) ) +- for ( i = P2M_FL_ENTRIES - 1; i >= 0; i++ ) ++ for ( i = P2M_FL_ENTRIES - 1; i >= 0; i-- ) + p2m_frame_list[i] = ((uint32_t *)p2m_frame_list)[i]; + + +@@ -1559,31 +1566,26 @@ int xc_domain_save(int xc_handle, int io + } + + /* Canonicalise the page table base pointer. */ +- if ( !MFN_IS_IN_PSEUDOPHYS_MAP(xen_cr3_to_pfn( +- GET_FIELD(&ctxt, ctrlreg[3]))) ) ++ if ( !MFN_IS_IN_PSEUDOPHYS_MAP(UNFOLD_CR3( ++ GET_FIELD(&ctxt, ctrlreg[3]))) ) + { + ERROR("PT base is not in range of pseudophys map"); + goto out; + } + SET_FIELD(&ctxt, ctrlreg[3], +- xen_pfn_to_cr3( +- mfn_to_pfn( +- xen_cr3_to_pfn( +- GET_FIELD(&ctxt, ctrlreg[3]))))); ++ FOLD_CR3(mfn_to_pfn(UNFOLD_CR3(GET_FIELD(&ctxt, ctrlreg[3]))))); + + /* Guest pagetable (x86/64) stored in otherwise-unused CR1. */ + if ( (pt_levels == 4) && ctxt.x64.ctrlreg[1] ) + { +- if ( !MFN_IS_IN_PSEUDOPHYS_MAP( +- xen_cr3_to_pfn(ctxt.x64.ctrlreg[1])) ) ++ if ( !MFN_IS_IN_PSEUDOPHYS_MAP(UNFOLD_CR3(ctxt.x64.ctrlreg[1])) ) + { + ERROR("PT base is not in range of pseudophys map"); + goto out; + } + /* Least-significant bit means 'valid PFN'. */ + ctxt.x64.ctrlreg[1] = 1 | +- xen_pfn_to_cr3( +- mfn_to_pfn(xen_cr3_to_pfn(ctxt.x64.ctrlreg[1]))); ++ FOLD_CR3(mfn_to_pfn(UNFOLD_CR3(ctxt.x64.ctrlreg[1]))); + } + + if ( write_exact(io_fd, &ctxt, ((guest_width==8) +Index: xen-3.2-testing/tools/libxc/xg_private.h +=================================================================== +--- xen-3.2-testing.orig/tools/libxc/xg_private.h ++++ xen-3.2-testing/tools/libxc/xg_private.h +@@ -155,7 +155,9 @@ typedef l4_pgentry_64_t l4_pgentry_t; + #define P2M_FL_ENTRIES (((p2m_size)+FPP-1)/FPP) + + /* Size in bytes of the pfn_to_mfn_frame_list */ +-#define P2M_FL_SIZE ((P2M_FL_ENTRIES)*(guest_width)) ++#define P2M_GUEST_FL_SIZE ((P2M_FL_ENTRIES) * (guest_width)) ++#define P2M_TOOLS_FL_SIZE ((P2M_FL_ENTRIES) * \ ++ MAX((sizeof (xen_pfn_t)), guest_width)) + + /* Masks for PTE<->PFN conversions */ + #define MADDR_BITS_X86 ((guest_width == 8) ? 52 : 44) +Index: xen-3.2-testing/tools/libxc/xg_save_restore.h +=================================================================== +--- xen-3.2-testing.orig/tools/libxc/xg_save_restore.h ++++ xen-3.2-testing/tools/libxc/xg_save_restore.h +@@ -68,6 +68,13 @@ static inline int get_platform_info(int + + *guest_width = domctl.u.address_size.size / 8; + ++ /* 64-bit tools will see the 64-bit hvirt_start, but 32-bit guests ++ * will be using the compat one. */ ++ if ( *guest_width < sizeof (unsigned long) ) ++ /* XXX need to fix up a way of extracting this value from Xen if ++ * XXX it becomes variable for domU */ ++ *hvirt_start = 0xf5800000; ++ + if (strstr(xen_caps, "xen-3.0-x86_64")) + /* Depends on whether it's a compat 32-on-64 guest */ + *pt_levels = ( (*guest_width == 8) ? 4 : 3 ); +@@ -136,6 +143,16 @@ typedef union + (_p)->x32._f = (_v); \ + } while (0) + ++#define UNFOLD_CR3(_c) \ ++ ((uint64_t)((guest_width == 8) \ ++ ? ((_c) >> 12) \ ++ : (((uint32_t)(_c) >> 12) | ((uint32_t)(_c) << 20)))) ++ ++#define FOLD_CR3(_c) \ ++ ((uint64_t)((guest_width == 8) \ ++ ? ((uint64_t)(_c)) << 12 \ ++ : (((uint32_t)(_c) << 12) | ((uint32_t)(_c) >> 20)))) ++ + #define MEMCPY_FIELD(_d, _s, _f) do { \ + if (guest_width == 8) \ + memcpy(&(_d)->x64._f, &(_s)->x64._f,sizeof((_d)->x64._f)); \ diff --git a/17113-xend-restore.patch b/17113-xend-restore.patch new file mode 100644 index 0000000..777fbd5 --- /dev/null +++ b/17113-xend-restore.patch @@ -0,0 +1,27 @@ +# HG changeset patch +# User Keir Fraser +# Date 1204036539 0 +# Node ID 9dd235d6174d1944caf53798a07ecf509678eead +# Parent b6323bf8dae0116a206a303b66b8fa539ba7c52d +Fix restore of saved image containing rtc_timeoffset + +Saved images contain rtc_timeoffset as a string value, resulting in a +TypeError exception when calling xc.domain_set_time_offset() on +restore. Cast rtc_timeoffset to int before calling +xc.domain_set_time_offset(). + +Signed-off-by: Jim Fehlig + +Index: xen-3.2-testing/tools/python/xen/xend/image.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.2-testing/tools/python/xen/xend/image.py +@@ -346,7 +346,7 @@ class LinuxImageHandler(ImageHandler): + ImageHandler.configure(self, vmConfig) + rtc_timeoffset = vmConfig['platform'].get('rtc_timeoffset') + if rtc_timeoffset is not None: +- xc.domain_set_time_offset(self.vm.getDomid(), rtc_timeoffset) ++ xc.domain_set_time_offset(self.vm.getDomid(), int(rtc_timeoffset)) + + def buildDomain(self): + store_evtchn = self.vm.getStorePort() diff --git a/32on64-extra-mem.patch b/32on64-extra-mem.patch index 5e6240f..e90c31a 100644 --- a/32on64-extra-mem.patch +++ b/32on64-extra-mem.patch @@ -2,7 +2,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -1772,7 +1772,7 @@ class XendDomainInfo: +@@ -1796,7 +1796,7 @@ class XendDomainInfo: xc.domain_setmaxmem(self.domid, maxmem) # Make sure there's enough RAM available for the domain diff --git a/blktap.patch b/blktap.patch index 4a1bc3d..22eb296 100644 --- a/blktap.patch +++ b/blktap.patch @@ -5,7 +5,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -2078,7 +2078,7 @@ class XendDomainInfo: +@@ -2102,7 +2102,7 @@ class XendDomainInfo: (fn, BOOTLOADER_LOOPBACK_DEVICE)) vbd = { @@ -18,7 +18,7 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c =================================================================== --- xen-3.2-testing.orig/tools/ioemu/xenstore.c +++ xen-3.2-testing/tools/ioemu/xenstore.c -@@ -81,9 +81,9 @@ void xenstore_parse_domain_config(int do +@@ -88,9 +88,9 @@ void xenstore_parse_domain_config(int do { char **e = NULL; char *buf = NULL, *path; @@ -30,7 +30,7 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c unsigned int len, num, hd_index; for(i = 0; i < MAX_DISKS + MAX_SCSI_DISKS; i++) -@@ -116,6 +116,14 @@ void xenstore_parse_domain_config(int do +@@ -117,6 +117,14 @@ void xenstore_parse_domain_config(int do bpath = xs_read(xsh, XBT_NULL, buf, &len); if (bpath == NULL) continue; @@ -45,7 +45,7 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c /* read the name of the device */ if (pasprintf(&buf, "%s/dev", bpath) == -1) continue; -@@ -250,6 +258,7 @@ void xenstore_parse_domain_config(int do +@@ -251,6 +259,7 @@ void xenstore_parse_domain_config(int do free(type); free(params); free(dev); diff --git a/block-iscsi b/block-iscsi index c30b000..7958b63 100644 --- a/block-iscsi +++ b/block-iscsi @@ -10,58 +10,36 @@ # open-iscsi database below /var/lib/open-iscsi/node.db # # (c) Kurt Garloff , 2006-09-04, GNU GPL +# Contributors: Jim Fehlig +# Stefan de Konink dir=$(dirname "$0") . "$dir/block-common.sh" -#command=$1 -#echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node" +# echo "DBG:xen/scripts/block-iscsi $1 $2 XENBUS_PATH=$XENBUS_PATH $par $node" -#write_dev() -#{ -# echo "$1" -#} - -sess_lun_to_bdev() -{ - unset dev - cnt=`ls -d $1/device/target*/*:0:*:$2/block* | wc -l` - nm=`ls -d $1/device/target*/*:0:*:$2/block*` - for n in $nm; do - d=`readlink $n` - d=${d##*/} - if test -z "$dev"; then dev=$d; else dev="$dev $d"; fi - done -} - -# Arguments: IQN name, LUN find_sdev() { unset dev - lun=${2:-0} for session in /sys/class/iscsi_session/session*; do - if ! test -e $session; then return; fi - if test $1 = `cat $session/targetname`; then - sess_lun_to_bdev $session $lun - #echo "fs: $1[$lun] ($cnt) -> $dev" 1>&2 + if [ "$1" = "`cat $session/targetname`" ]; then + dev=`readlink $session/device/target*/*:0:*/block*` + dev=${dev##*/} return fi done -} +} find_sdev_rev() { unset tgt for session in /sys/class/iscsi_session/session*; do - if ! test -e $session; then return; fi - sess_lun_to_bdev $session "*" - for d in $dev; do - if test "$d" = "$1"; then - tgt=`cat $session/targetname` - #echo "fsr: $2 -> $tgt ($cnt)" 1>&2 - return - fi - done + dev=`readlink $session/device/target*/*:0:*/block*` + dev=${dev##*/} + if [ "$dev" = "$1" ]; then + tgt=`cat $session/targetname` + return + fi done } @@ -71,42 +49,32 @@ case "$command" in /etc/init.d/open-iscsi status >/dev/null 2>&1 || { /etc/init.d/open-iscsi start >/dev/null 2>&1; sleep 1; } # list of targets on node + /sbin/iscsiadm -m discovery | sed "s/ .*//g" | while read line; do /sbin/iscsiadm -m discovery -t sendtargets -p $line; done >/dev/null par=`xenstore-read $XENBUS_PATH/params` || true - TGTID=$par; TGTID=${TGTID//@/:} - LUN=${TGTID##*,}; TGTID=${TGTID%,*} - if test $LUN = $TGTID; then unset LUN; fi - #echo "add $TGTID lun $LUN" 1>&2 - while read rec port uuid; do - rec=${rec%]}; rec=${rec#[} - if test $uuid = $TGTID; then - find_sdev $TGTID $LUN - if test -z "$dev"; then - #echo iscsiadm -m node -T $uuid -p $port -l 1>&2 - iscsiadm -m node -r $rec -l || exit 2 - usleep 100000 - find_sdev $TGTID $LUN - fi - xenstore-write $XENBUS_PATH/node /dev/$dev + TGTID=`echo $par | sed "s/\/\///g"` + while read rec uuid; do + if [ "$uuid" = "$TGTID" ]; then + find_sdev $TGTID + if [ -z "$dev" ]; then + /sbin/iscsiadm -m node -T $uuid -p $rec --login || exit 2 + sleep 4 + find_sdev $TGTID + fi + xenstore-write $XENBUS_PATH/node /dev/$dev write_dev /dev/$dev - exit 0 + exit 0 fi - done < <(iscsiadm -m node) + done < <(/sbin/iscsiadm -m node) exit 1 ;; + remove) node=`xenstore-read $XENBUS_PATH/node` || true dev=$node; dev=${dev#/dev/} find_sdev_rev $dev - #echo "remove $dev:$tgt" 1>&2 - if test -x /sbin/blockdev -a -n "$node"; then blockdev --flushbufs $node; fi + if [ -x /sbin/blockdev -a -n "$node" ]; then blockdev --flushbufs "$node"; fi test -z "$tgt" && exit 2 - while read rec port uuid; do - if test $uuid = $tgt; then - rec=${rec%]}; rec=${rec#[} - iscsiadm -m node -r $rec -u - exit 0 - fi - done < <(iscsiadm -m node) + /sbin/iscsiadm -m node -T $tgt --logout exit 1 ;; esac diff --git a/cdrom-removable.patch b/cdrom-removable.patch index 06b2af5..d5dea42 100644 --- a/cdrom-removable.patch +++ b/cdrom-removable.patch @@ -1,7 +1,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/server/HalDaemon.py =================================================================== ---- /dev/null -+++ xen-3.2-testing/tools/python/xen/xend/server/HalDaemon.py +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/tools/python/xen/xend/server/HalDaemon.py 2008-02-29 08:11:00.000000000 -0700 @@ -0,0 +1,238 @@ +#!/usr/bin/env python +# -*- mode: python; -*- @@ -243,8 +243,8 @@ Index: xen-3.2-testing/tools/python/xen/xend/server/HalDaemon.py + Index: xen-3.2-testing/tools/python/xen/xend/server/Hald.py =================================================================== ---- /dev/null -+++ xen-3.2-testing/tools/python/xen/xend/server/Hald.py +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/tools/python/xen/xend/server/Hald.py 2008-02-29 08:11:00.000000000 -0700 @@ -0,0 +1,125 @@ +#============================================================================ +# This library is free software; you can redistribute it and/or @@ -373,9 +373,9 @@ Index: xen-3.2-testing/tools/python/xen/xend/server/Hald.py + watcher.shutdown() Index: xen-3.2-testing/tools/python/xen/xend/server/SrvServer.py =================================================================== ---- xen-3.2-testing.orig/tools/python/xen/xend/server/SrvServer.py -+++ xen-3.2-testing/tools/python/xen/xend/server/SrvServer.py -@@ -56,6 +56,7 @@ from xen.web.SrvDir import SrvDir +--- xen-3.2-testing.orig/tools/python/xen/xend/server/SrvServer.py 2008-01-16 13:19:05.000000000 -0700 ++++ xen-3.2-testing/tools/python/xen/xend/server/SrvServer.py 2008-02-29 08:11:00.000000000 -0700 +@@ -56,6 +56,7 @@ from SrvRoot import SrvRoot from XMLRPCServer import XMLRPCServer @@ -383,7 +383,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/server/SrvServer.py xoptions = XendOptions.instance() -@@ -245,6 +246,8 @@ def _loadConfig(servers, root, reload): +@@ -245,6 +246,8 @@ if xoptions.get_xend_unix_xmlrpc_server(): servers.add(XMLRPCServer(XendAPI.AUTH_PAM, False)) @@ -394,9 +394,9 @@ Index: xen-3.2-testing/tools/python/xen/xend/server/SrvServer.py root = SrvDir() Index: xen-3.2-testing/tools/ioemu/xenstore.c =================================================================== ---- xen-3.2-testing.orig/tools/ioemu/xenstore.c -+++ xen-3.2-testing/tools/ioemu/xenstore.c -@@ -215,6 +215,13 @@ void xenstore_parse_domain_config(int do +--- xen-3.2-testing.orig/tools/ioemu/xenstore.c 2008-02-29 08:10:59.000000000 -0700 ++++ xen-3.2-testing/tools/ioemu/xenstore.c 2008-02-29 08:11:38.000000000 -0700 +@@ -216,6 +216,13 @@ bdrv_set_type_hint(bs_table[hd_index], BDRV_TYPE_CDROM); if (pasprintf(&buf, "%s/params", bpath) != -1) xs_watch(xsh, buf, dev); @@ -410,7 +410,7 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c } /* open device now if media present */ if (params[0]) { -@@ -416,6 +423,50 @@ void xenstore_record_dm_state(char *stat +@@ -417,6 +424,50 @@ free(path); } @@ -460,8 +460,8 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c + void xenstore_process_event(void *opaque) { - char **vec, *image = NULL; -@@ -435,6 +486,11 @@ void xenstore_process_event(void *opaque + char **vec, *offset, *bpath = NULL, *buf = NULL, *drv = NULL, *image = NULL; +@@ -436,6 +487,11 @@ goto out; } @@ -473,3 +473,31 @@ Index: xen-3.2-testing/tools/ioemu/xenstore.c if (strncmp(vec[XS_WATCH_TOKEN], "hd", 2) || strlen(vec[XS_WATCH_TOKEN]) != 3) goto out; +Index: xen-3.2-testing/tools/ioemu/hw/ide.c +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/hw/ide.c 2008-02-29 08:11:33.000000000 -0700 ++++ xen-3.2-testing/tools/ioemu/hw/ide.c 2008-02-29 08:16:50.000000000 -0700 +@@ -350,6 +350,7 @@ + uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4]; + QEMUTimer *sector_write_timer; /* only used for win2k instal hack */ + uint32_t irq_count; /* counts IRQs when using win2k install hack */ ++ uint8_t send_ua; /* send SENSE_UNIT_ATTENTION on next ready */ + } IDEState; + + #define BM_STATUS_DMAING 0x01 +@@ -1403,8 +1404,15 @@ + switch(s->io_buffer[0]) { + case GPCMD_TEST_UNIT_READY: + if (bdrv_is_inserted(s->bs)) { ++ if (s->send_ua) { ++ ide_atapi_cmd_error(s, SENSE_UNIT_ATTENTION, ++ ASC_MEDIUM_NOT_PRESENT); ++ s->send_ua = 0; ++ break; ++ } + ide_atapi_cmd_ok(s); + } else { ++ s->send_ua = 1; + ide_atapi_cmd_error(s, SENSE_NOT_READY, + ASC_MEDIUM_NOT_PRESENT); + xenstore_check_new_media_present(1000); diff --git a/disable_emulated_device.diff b/disable_emulated_device.diff deleted file mode 100644 index 5a3138f..0000000 --- a/disable_emulated_device.diff +++ /dev/null @@ -1,20 +0,0 @@ -Disable the emulated devices when we are loading PV drivers. - -Signed-off-by: K. Y. Srinivasan - -Index: xen-unstable/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c -=================================================================== ---- xen-unstable.orig/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c -+++ xen-unstable/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c -@@ -247,6 +247,11 @@ static int __devinit platform_pci_init(s - platform_mmio = mmio_addr; - platform_mmiolen = mmio_len; - -+ /* -+ * Disconnect the emulated devices. -+ */ -+ outl(1, (ioaddr + 4)); -+ - ret = get_hypercall_stubs(); - if (ret < 0) - goto out; diff --git a/ept-novell-x64.patch b/ept-novell-x64.patch new file mode 100644 index 0000000..4cf97d8 --- /dev/null +++ b/ept-novell-x64.patch @@ -0,0 +1,1021 @@ +Index: xen-3.2-testing/tools/libxc/xc_hvm_build.c +=================================================================== +--- xen-3.2-testing.orig/tools/libxc/xc_hvm_build.c ++++ xen-3.2-testing/tools/libxc/xc_hvm_build.c +@@ -20,6 +20,7 @@ + #include + + #define SCRATCH_PFN 0xFFFFF ++#define HVM_IDENT_PT_PAGE 0xE8000 + + static void build_e820map(void *e820_page, unsigned long long mem_size) + { +@@ -154,6 +155,7 @@ static int setup_guest(int xc_handle, + struct xen_add_to_physmap xatp; + struct shared_info *shared_info; + void *e820_page; ++ uint32_t *ident_pt; + struct elf_binary elf; + uint64_t v_start, v_end; + int rc; +@@ -254,6 +256,18 @@ static int setup_guest(int xc_handle, + xc_set_hvm_param(xc_handle, dom, HVM_PARAM_BUFIOREQ_PFN, shared_page_nr-2); + xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IOREQ_PFN, shared_page_nr); + ++ /* Fill it with 32-bit, non-PAE superpage entries, each mapping 4MB ++ * of virtual address space onto the same physical address range */ ++ if ( (ident_pt = xc_map_foreign_range( ++ xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, ++ HVM_IDENT_PT_PAGE >> PAGE_SHIFT)) == NULL ) ++ goto error_out; ++ for ( i = 0; i < PAGE_SIZE / sizeof(*ident_pt); i++ ) ++ ident_pt[i] = (i << 22) | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER ++ | _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_PSE; ++ munmap(ident_pt , PAGE_SIZE); ++ xc_set_hvm_param(xc_handle, dom, HVM_PARAM_IDENT_PT, HVM_IDENT_PT_PAGE); ++ + /* Insert JMP instruction at address 0x0 to reach entry point. */ + entry_eip = elf_uval(&elf, elf.ehdr, e_entry); + if ( entry_eip != 0 ) +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/hvm.c ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm.c +@@ -1969,6 +1969,10 @@ long do_hvm_op(unsigned long op, XEN_GUE + } + d->arch.hvm_domain.params[a.index] = a.value; + rc = 0; ++ ++ if ( paging_mode_hap(d) && (a.index == HVM_PARAM_IDENT_PT) ) ++ for_each_vcpu(d, v) ++ paging_update_cr3(v); + } + else + { +Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/vmcs.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c ++++ xen-3.2-testing/xen/arch/x86/hvm/vmx/vmcs.c +@@ -105,11 +105,23 @@ static void vmx_init_vmcs_config(void) + + if ( _vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ) + { +- min = 0; +- opt = (SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | +- SECONDARY_EXEC_WBINVD_EXITING); ++ u32 min2 = 0, opt2; ++ ++ opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | ++ SECONDARY_EXEC_WBINVD_EXITING | ++ SECONDARY_EXEC_ENABLE_EPT; + _vmx_secondary_exec_control = adjust_vmx_controls( +- min, opt, MSR_IA32_VMX_PROCBASED_CTLS2); ++ min2, opt2, MSR_IA32_VMX_PROCBASED_CTLS2); ++ ++ if ( _vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT ) ++ { ++ /* INVLPG and CR3 accesses don't need to cause VMExits */ ++ min &= ~(CPU_BASED_INVLPG_EXITING | ++ CPU_BASED_CR3_LOAD_EXITING | ++ CPU_BASED_CR3_STORE_EXITING); ++ _vmx_cpu_based_exec_control = adjust_vmx_controls( ++ min, opt, MSR_IA32_VMX_PROCBASED_CTLS); ++ } + } + + #if defined(__i386__) +@@ -301,6 +313,8 @@ int vmx_cpu_up(void) + return 0; + } + ++ ept_sync_all(); ++ + return 1; + } + +@@ -439,6 +453,7 @@ void vmx_disable_intercept_for_msr(struc + + static int construct_vmcs(struct vcpu *v) + { ++ struct domain *d = v->domain; + uint16_t sysenter_cs; + unsigned long sysenter_eip; + +@@ -448,10 +463,23 @@ static int construct_vmcs(struct vcpu *v + __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control); + __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control); + __vmwrite(VM_ENTRY_CONTROLS, vmx_vmentry_control); +- __vmwrite(CPU_BASED_VM_EXEC_CONTROL, vmx_cpu_based_exec_control); ++ + v->arch.hvm_vmx.exec_control = vmx_cpu_based_exec_control; +- if ( vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS ) +- __vmwrite(SECONDARY_VM_EXEC_CONTROL, vmx_secondary_exec_control); ++ v->arch.hvm_vmx.secondary_exec_control = vmx_secondary_exec_control; ++ ++ if ( paging_mode_shadow(d) ) ++ { ++ v->arch.hvm_vmx.exec_control |= CPU_BASED_INVLPG_EXITING | ++ CPU_BASED_CR3_LOAD_EXITING | ++ CPU_BASED_CR3_STORE_EXITING; ++ v->arch.hvm_vmx.secondary_exec_control &= ~SECONDARY_EXEC_ENABLE_EPT; ++ } ++ ++ if ( cpu_has_vmx_secondary_exec_control ) ++ __vmwrite(SECONDARY_VM_EXEC_CONTROL, ++ v->arch.hvm_vmx.secondary_exec_control); ++ ++ __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control); + + /* MSR access bitmap. */ + if ( cpu_has_vmx_msr_bitmap ) +@@ -569,7 +597,10 @@ static int construct_vmcs(struct vcpu *v + __vmwrite(VMCS_LINK_POINTER_HIGH, ~0UL); + #endif + +- __vmwrite(EXCEPTION_BITMAP, HVM_TRAP_MASK | (1U << TRAP_page_fault)); ++ if ( paging_mode_hap(d) ) ++ __vmwrite(EXCEPTION_BITMAP, HVM_TRAP_MASK); ++ else ++ __vmwrite(EXCEPTION_BITMAP, HVM_TRAP_MASK | (1U << TRAP_page_fault)); + + v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_PE | X86_CR0_ET; + hvm_update_guest_cr(v, 0); +@@ -584,6 +615,19 @@ static int construct_vmcs(struct vcpu *v + __vmwrite(TPR_THRESHOLD, 0); + } + ++ if ( paging_mode_hap(d) ) ++ { ++ v->arch.hvm_vmx.ept_control.etmt = EPT_DEFAULT_MT; ++ v->arch.hvm_vmx.ept_control.gaw = EPT_DEFAULT_GAW; ++ v->arch.hvm_vmx.ept_control.asr = ++ pagetable_get_pfn(d->arch.phys_table); ++ ++ __vmwrite(EPT_POINTER, v->arch.hvm_vmx.ept_control.eptp); ++#ifdef CONFIG_X86_PAE ++ __vmwrite(EPT_POINTER_HIGH, v->arch.hvm_vmx.ept_control.eptp >> 32); ++#endif ++ } ++ + vmx_vmcs_exit(v); + + paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */ +@@ -929,6 +973,8 @@ void vmcs_dump_vcpu(struct vcpu *v) + (uint32_t)vmr(IDT_VECTORING_ERROR_CODE)); + printk("TPR Threshold = 0x%02x\n", + (uint32_t)vmr(TPR_THRESHOLD)); ++ printk("EPT pointer = 0x%08x%08x\n", ++ (uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER)); + + vmx_vmcs_exit(v); + } +Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/vmx.c ++++ xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +@@ -90,6 +90,8 @@ static int vmx_vcpu_initialise(struct vc + return rc; + } + ++ ept_sync_domain(v); ++ + vmx_install_vlapic_mapping(v); + + #ifndef VMXASSIST +@@ -530,20 +532,23 @@ static int vmx_restore_cr0_cr3( + unsigned long mfn = 0; + p2m_type_t p2mt; + +- if ( cr0 & X86_CR0_PG ) ++ if ( paging_mode_shadow(v->domain) ) + { +- mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt)); +- if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) ) ++ if ( cr0 & X86_CR0_PG ) + { +- gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%lx\n", cr3); +- return -EINVAL; ++ mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt)); ++ if ( !p2m_is_ram(p2mt) || !get_page(mfn_to_page(mfn), v->domain) ) ++ { ++ gdprintk(XENLOG_ERR, "Invalid CR3 value=0x%lx\n", cr3); ++ return -EINVAL; ++ } + } +- } + +- if ( v->arch.hvm_vcpu.guest_cr[0] & X86_CR0_PG ) +- put_page(pagetable_get_page(v->arch.guest_table)); ++ if ( hvm_paging_enabled(v) ) ++ put_page(pagetable_get_page(v->arch.guest_table)); + +- v->arch.guest_table = pagetable_from_pfn(mfn); ++ v->arch.guest_table = pagetable_from_pfn(mfn); ++ } + + v->arch.hvm_vcpu.guest_cr[0] = cr0 | X86_CR0_ET; + v->arch.hvm_vcpu.guest_cr[3] = cr3; +@@ -1014,6 +1019,45 @@ static enum hvm_intblk vmx_interrupt_blo + return hvm_intblk_none; + } + ++/* the caller needs to check if the guest is switching to PAE mode */ ++static void vmx_load_pdptrs(struct vcpu *v) ++{ ++ unsigned long cr3 = v->arch.hvm_vcpu.guest_cr[3], mfn; ++ p2m_type_t p2mt; ++ char *p; ++ u64 *guest_pdptrs; ++ ++ if ( cr3 & 0x1fUL ) ++ { ++ domain_crash(v->domain); ++ return; ++ } ++ ++ mfn = mfn_x(gfn_to_mfn(v->domain, cr3 >> PAGE_SHIFT, &p2mt)); ++ p = map_domain_page(mfn); ++ ++ guest_pdptrs = (u64 *)(p + (cr3 & ~PAGE_MASK)); ++ ++ /* TODO: check if guest PDPTRS are valid */ ++ ++ vmx_vmcs_enter(v); ++ ++ __vmwrite(GUEST_PDPTR0, guest_pdptrs[0]); ++ __vmwrite(GUEST_PDPTR1, guest_pdptrs[1]); ++ __vmwrite(GUEST_PDPTR2, guest_pdptrs[2]); ++ __vmwrite(GUEST_PDPTR3, guest_pdptrs[3]); ++#ifdef CONFIG_X86_PAE ++ __vmwrite(GUEST_PDPTR0_HIGH, guest_pdptrs[0] >> 32); ++ __vmwrite(GUEST_PDPTR1_HIGH, guest_pdptrs[1] >> 32); ++ __vmwrite(GUEST_PDPTR2_HIGH, guest_pdptrs[2] >> 32); ++ __vmwrite(GUEST_PDPTR3_HIGH, guest_pdptrs[3] >> 32); ++#endif ++ ++ vmx_vmcs_exit(v); ++ ++ unmap_domain_page(p); ++} ++ + static void vmx_update_host_cr3(struct vcpu *v) + { + ASSERT((v == current) || !vcpu_runnable(v)); +@@ -1039,21 +1083,57 @@ static void vmx_update_guest_cr(struct v + __vm_clear_bit(EXCEPTION_BITMAP, TRAP_no_device); + } + ++ if ( paging_mode_hap(v->domain) ) ++ { ++ if ( hvm_paging_enabled(v) ) ++ v->arch.hvm_vmx.exec_control &= ~(CPU_BASED_CR3_LOAD_EXITING | ++ CPU_BASED_CR3_STORE_EXITING); ++ else ++ v->arch.hvm_vmx.exec_control |= CPU_BASED_CR3_LOAD_EXITING | ++ CPU_BASED_CR3_STORE_EXITING; ++ __vmwrite(CPU_BASED_VM_EXEC_CONTROL, v->arch.hvm_vmx.exec_control); ++ } ++ + v->arch.hvm_vcpu.hw_cr[0] = + v->arch.hvm_vcpu.guest_cr[0] | +- X86_CR0_NE | X86_CR0_PG | X86_CR0_WP | X86_CR0_PE; ++ X86_CR0_NE | X86_CR0_PG | X86_CR0_PE; ++ ++ if ( paging_mode_shadow(v->domain) ) ++ v->arch.hvm_vcpu.hw_cr[0] |= X86_CR0_WP; ++ + __vmwrite(GUEST_CR0, v->arch.hvm_vcpu.hw_cr[0]); + __vmwrite(CR0_READ_SHADOW, v->arch.hvm_vcpu.guest_cr[0]); ++ vmx_update_guest_cr(v, 4); ++ + break; + case 2: + /* CR2 is updated in exit stub. */ + break; + case 3: ++ if ( paging_mode_hap(v->domain) ) ++ { ++ if ( !hvm_paging_enabled(v) ) ++ v->arch.hvm_vcpu.hw_cr[3] = ++ v->domain->arch.hvm_domain.params[HVM_PARAM_IDENT_PT]; ++ ++ /* EPT needs to load PDPTRS into VMCS for PAE. */ ++ if ( hvm_pae_enabled(v) && ++ !(v->arch.hvm_vcpu.guest_efer & EFER_LMA) ) ++ vmx_load_pdptrs(v); ++ } + __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr[3]); + break; + case 4: +- v->arch.hvm_vcpu.hw_cr[4] = +- v->arch.hvm_vcpu.guest_cr[4] | HVM_CR4_HOST_MASK; ++ v->arch.hvm_vcpu.hw_cr[4] = HVM_CR4_HOST_MASK; ++ if ( paging_mode_hap(v->domain) ) ++ v->arch.hvm_vcpu.hw_cr[4] &= ~X86_CR4_PAE; ++ v->arch.hvm_vcpu.hw_cr[4] |= v->arch.hvm_vcpu.guest_cr[4]; ++ if ( paging_mode_hap(v->domain) && !hvm_paging_enabled(v) ) ++ { ++ v->arch.hvm_vcpu.hw_cr[4] |= X86_CR4_PSE; ++ if ( v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PAE ) ++ v->arch.hvm_vcpu.hw_cr[4] &= ~X86_CR4_PAE; ++ } + __vmwrite(GUEST_CR4, v->arch.hvm_vcpu.hw_cr[4]); + __vmwrite(CR4_READ_SHADOW, v->arch.hvm_vcpu.guest_cr[4]); + break; +@@ -1121,6 +1201,7 @@ static int vmx_event_pending(struct vcpu + + static struct hvm_function_table vmx_function_table = { + .name = "VMX", ++ .p2m_init = ept_p2m_init, + .domain_initialise = vmx_domain_initialise, + .domain_destroy = vmx_domain_destroy, + .vcpu_initialise = vmx_vcpu_initialise, +@@ -1178,6 +1259,12 @@ void start_vmx(void) + return; + } + ++ if ( cpu_has_vmx_ept ) ++ { ++ printk("VMX: EPT is available.\n"); ++ vmx_function_table.hap_supported = 1; ++ } ++ + setup_vmcs_dump(); + + hvm_enable(&vmx_function_table); +@@ -2690,6 +2777,18 @@ void vmx_wbinvd_intercept(void) + wbinvd(); + } + ++static void ept_handle_violation(unsigned long qualification, paddr_t gpa) ++{ ++ if ( unlikely(((qualification >> 7) & 0x3) != 0x3) ) ++ { ++ domain_crash(current->domain); ++ return; ++ } ++ ++ /* must be MMIO */ ++ handle_mmio(gpa); ++} ++ + static void vmx_failed_vmentry(unsigned int exit_reason, + struct cpu_user_regs *regs) + { +@@ -2729,6 +2828,15 @@ asmlinkage void vmx_vmexit_handler(struc + unsigned long exit_qualification, inst_len = 0; + struct vcpu *v = current; + ++ if ( paging_mode_hap(v->domain) && hvm_paging_enabled(v) ) ++ { ++ __asm__ __volatile__ ("mov"__OS" %%cr2, %0" ++ : "=r"(v->arch.hvm_vcpu.guest_cr[2])); ++ ++ /* __hvm_copy() need this when paging is enabled. */ ++ v->arch.hvm_vcpu.guest_cr[3] = __vmread(GUEST_CR3); ++ } ++ + exit_reason = __vmread(VM_EXIT_REASON); + + hvmtrace_vmexit(v, regs->eip, exit_reason); +@@ -2969,6 +3077,21 @@ asmlinkage void vmx_vmexit_handler(struc + break; + } + ++ case EXIT_REASON_EPT_VIOLATION: ++ { ++ paddr_t gpa = __vmread(GUEST_PHYSICAL_ADDRESS); ++#ifdef CONFIG_X86_PAE ++ gpa |= (paddr_t)__vmread(GUEST_PHYSICAL_ADDRESS_HIGH) << 32; ++#endif ++ exit_qualification = __vmread(EXIT_QUALIFICATION); ++ ept_handle_violation(exit_qualification, gpa); ++ break; ++ } ++ ++ case EXIT_REASON_EPT_MISCONFIG: ++ domain_crash(current->domain); ++ break; ++ + default: + exit_and_crash: + gdprintk(XENLOG_ERR, "Bad vmexit (reason %x)\n", exit_reason); +Index: xen-3.2-testing/xen/arch/x86/mm/Makefile +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/Makefile ++++ xen-3.2-testing/xen/arch/x86/mm/Makefile +@@ -3,3 +3,4 @@ subdir-y += hap + + obj-y += paging.o + obj-y += p2m.o ++obj-y += p2m-ept.o +Index: xen-3.2-testing/xen/arch/x86/mm/p2m-ept.c +=================================================================== +--- /dev/null ++++ xen-3.2-testing/xen/arch/x86/mm/p2m-ept.c +@@ -0,0 +1,177 @@ ++/* ++ * ept-p2m.c: use the EPT page table as p2m ++ * Copyright (c) 2007, Intel Corporation. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms and conditions of the GNU General Public License, ++ * version 2, as published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope it will be useful, but WITHOUT ++ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ++ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for ++ * more details. ++ * ++ * You should have received a copy of the GNU General Public License along with ++ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple ++ * Place - Suite 330, Boston, MA 02111-1307 USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ept_next_level(struct domain *d, bool_t read_only, ++ ept_entry_t **table, unsigned long *gfn_remainder, ++ u32 shift) ++{ ++ ept_entry_t *ept_entry, *next; ++ u32 index; ++ ++ index = *gfn_remainder >> shift; ++ *gfn_remainder &= (1UL << shift) - 1; ++ ++ ept_entry = (*table) + index; ++ ++ if ( !(ept_entry->epte & 0x7) ) ++ { ++ struct page_info *pg; ++ ++ if ( read_only ) ++ return 0; ++ ++ pg = d->arch.p2m.alloc_page(d); ++ if ( pg == NULL ) ++ return 0; ++ pg->count_info = 1; ++ pg->u.inuse.type_info = 1 | PGT_validated; ++ list_add_tail(&pg->list, &d->arch.p2m.pages); ++ ++ ept_entry->emt = 0; ++ ept_entry->sp_avail = 0; ++ ept_entry->avail1 = 0; ++ ept_entry->mfn = page_to_mfn(pg); ++ ept_entry->rsvd = 0; ++ ept_entry->avail2 = 0; ++ /* last step */ ++ ept_entry->r = ept_entry->w = ept_entry->x = 1; ++ } ++ ++ next = map_domain_page(ept_entry->mfn); ++ unmap_domain_page(*table); ++ *table = next; ++ ++ return 1; ++} ++ ++static int ++ept_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn, p2m_type_t p2mt) ++{ ++ ept_entry_t *table = ++ map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table))); ++ unsigned long gfn_remainder = gfn; ++ ept_entry_t *ept_entry; ++ u32 index; ++ int i, rv = 0; ++ ++ /* should check if gfn obeys GAW here */ ++ ++ for ( i = EPT_DEFAULT_GAW; i > 0; i-- ) ++ if ( !ept_next_level(d, 0, &table, &gfn_remainder, i * EPT_TABLE_ORDER) ) ++ goto out; ++ ++ index = gfn_remainder; ++ ept_entry = table + index; ++ ++ if ( mfn_valid(mfn_x(mfn)) ) ++ { ++ /* Track the highest gfn for which we have ever had a valid mapping */ ++ if ( gfn > d->arch.p2m.max_mapped_pfn ) ++ d->arch.p2m.max_mapped_pfn = gfn; ++ ++ ept_entry->emt = EPT_DEFAULT_MT; ++ ept_entry->sp_avail = 0; ++ ept_entry->avail1 = p2mt; ++ ept_entry->mfn = mfn_x(mfn); ++ ept_entry->rsvd = 0; ++ ept_entry->avail2 = 0; ++ /* last step */ ++ ept_entry->r = ept_entry->w = ept_entry->x = 1; ++ } ++ else ++ ept_entry->epte = 0; ++ ++ /* Success */ ++ rv = 1; ++ ++ out: ++ unmap_domain_page(table); ++ if ( d->vcpu[0] ) ++ ept_sync_domain(d->vcpu[0]); ++ return rv; ++} ++ ++/* Read ept p2m entries */ ++static mfn_t ept_get_entry(struct domain *d, unsigned long gfn, p2m_type_t *t) ++{ ++ ept_entry_t *table = ++ map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table))); ++ unsigned long gfn_remainder = gfn; ++ ept_entry_t *ept_entry; ++ u32 index; ++ int i; ++ mfn_t mfn = _mfn(INVALID_MFN); ++ ++ *t = p2m_mmio_dm; ++ ++ /* This pfn is higher than the highest the p2m map currently holds */ ++ if ( gfn > d->arch.p2m.max_mapped_pfn ) ++ goto out; ++ ++ /* should check if gfn obeys GAW here */ ++ ++ for ( i = EPT_DEFAULT_GAW; i > 0; i-- ) ++ if ( !ept_next_level(d, 1, &table, &gfn_remainder, i * EPT_TABLE_ORDER) ) ++ goto out; ++ ++ index = gfn_remainder; ++ ept_entry = table + index; ++ ++ if ( (ept_entry->epte & 0x7) == 0x7 ) ++ { ++ if ( ept_entry->avail1 != p2m_invalid ) ++ { ++ *t = ept_entry->avail1; ++ mfn = _mfn(ept_entry->mfn); ++ } ++ } ++ ++ out: ++ unmap_domain_page(table); ++ return mfn; ++} ++ ++static mfn_t ept_get_entry_fast(unsigned long gfn, p2m_type_t *t) ++{ ++ return ept_get_entry(current->domain, gfn, t); ++} ++ ++void ept_p2m_init(struct domain *d) ++{ ++ d->arch.p2m.set_entry = ept_set_entry; ++ d->arch.p2m.get_entry = ept_get_entry; ++ d->arch.p2m.get_entry_fast = ept_get_entry_fast; ++} ++ ++/* ++ * Local variables: ++ * mode: C ++ * c-set-style: "BSD" ++ * c-basic-offset: 4 ++ * tab-width: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +Index: xen-3.2-testing/xen/arch/x86/mm/p2m.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/p2m.c ++++ xen-3.2-testing/xen/arch/x86/mm/p2m.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + /* Debugging and auditing of the P2M code? */ + #define P2M_AUDIT 0 +@@ -202,7 +203,7 @@ p2m_next_level(struct domain *d, mfn_t * + + // Returns 0 on error (out of memory) + static int +-set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, p2m_type_t p2mt) ++p2m_set_entry(struct domain *d, unsigned long gfn, mfn_t mfn, p2m_type_t p2mt) + { + // XXX -- this might be able to be faster iff current->domain == d + mfn_t table_mfn = pagetable_get_mfn(d->arch.phys_table); +@@ -266,14 +267,28 @@ set_p2m_entry(struct domain *d, unsigned + return rv; + } + ++static mfn_t ++p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t); + + /* Init the datastructures for later use by the p2m code */ + void p2m_init(struct domain *d) + { + p2m_lock_init(d); + INIT_LIST_HEAD(&d->arch.p2m.pages); ++ ++ d->arch.p2m.set_entry = p2m_set_entry; ++ d->arch.p2m.get_entry = p2m_gfn_to_mfn; ++ d->arch.p2m.get_entry_fast = p2m_gfn_to_mfn_fast; ++ ++ if ( is_hvm_domain(d) ) ++ hvm_p2m_init(d); + } + ++static inline ++int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, p2m_type_t p2mt) ++{ ++ return d->arch.p2m.set_entry(d, gfn, mfn, p2mt); ++} + + // Allocate a new p2m table for a domain. + // +@@ -392,8 +407,8 @@ void p2m_teardown(struct domain *d) + p2m_unlock(d); + } + +-mfn_t +-gfn_to_mfn_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t) ++static mfn_t ++p2m_gfn_to_mfn(struct domain *d, unsigned long gfn, p2m_type_t *t) + /* Read another domain's p2m entries */ + { + mfn_t mfn; +Index: xen-3.2-testing/xen/include/asm-x86/domain.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/domain.h ++++ xen-3.2-testing/xen/include/asm-x86/domain.h +@@ -131,6 +131,27 @@ struct hap_domain { + /************************************************/ + /* p2m handling */ + /************************************************/ ++/* ++ * The upper levels of the p2m pagetable always contain full rights; all ++ * variation in the access control bits is made in the level-1 PTEs. ++ * ++ * In addition to the phys-to-machine translation, each p2m PTE contains ++ * *type* information about the gfn it translates, helping Xen to decide ++ * on the correct course of action when handling a page-fault to that ++ * guest frame. We store the type in the "available" bits of the PTEs ++ * in the table, which gives us 8 possible types on 32-bit systems. ++ * Further expansions of the type system will only be supported on ++ * 64-bit Xen. ++ */ ++typedef enum { ++ p2m_invalid = 0, /* Nothing mapped here */ ++ p2m_ram_rw = 1, /* Normal read/write guest RAM */ ++ p2m_ram_logdirty = 2, /* Temporarily read-only for log-dirty */ ++ p2m_ram_ro = 3, /* Read-only; writes go to the device model */ ++ p2m_mmio_dm = 4, /* Reads and write go to the device model */ ++ p2m_mmio_direct = 5, /* Read/write mapping of genuine MMIO area */ ++} p2m_type_t; ++ + struct p2m_domain { + /* Lock that protects updates to the p2m */ + spinlock_t lock; +@@ -144,6 +165,11 @@ struct p2m_domain { + struct page_info * (*alloc_page )(struct domain *d); + void (*free_page )(struct domain *d, + struct page_info *pg); ++ int (*set_entry )(struct domain *d, unsigned long gfn, ++ mfn_t mfn, p2m_type_t p2mt); ++ mfn_t (*get_entry )(struct domain *d, unsigned long gfn, ++ p2m_type_t *p2mt); ++ mfn_t (*get_entry_fast)(unsigned long gfn, p2m_type_t *p2mt); + + /* Highest guest frame that's ever been mapped in the p2m */ + unsigned long max_mapped_pfn; +Index: xen-3.2-testing/xen/include/asm-x86/hvm/hvm.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hvm/hvm.h ++++ xen-3.2-testing/xen/include/asm-x86/hvm/hvm.h +@@ -60,6 +60,9 @@ struct hvm_function_table { + /* Support Hardware-Assisted Paging? */ + int hap_supported; + ++ /* Initialise p2m resources */ ++ void (*p2m_init)(struct domain *d); ++ + /* + * Initialise/destroy HVM domain/vcpu resources + */ +@@ -127,6 +130,12 @@ struct hvm_function_table { + extern struct hvm_function_table hvm_funcs; + extern int hvm_enabled; + ++static inline void hvm_p2m_init(struct domain *d) ++{ ++ if ( hvm_funcs.p2m_init ) ++ return hvm_funcs.p2m_init(d); ++} ++ + int hvm_domain_initialise(struct domain *d); + void hvm_domain_relinquish_resources(struct domain *d); + void hvm_domain_destroy(struct domain *d); +Index: xen-3.2-testing/xen/include/asm-x86/hvm/vmx/vmcs.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hvm/vmx/vmcs.h ++++ xen-3.2-testing/xen/include/asm-x86/hvm/vmx/vmcs.h +@@ -57,6 +57,9 @@ struct vmx_msr_state { + unsigned long msrs[VMX_MSR_COUNT]; + }; + ++#define EPT_DEFAULT_MT 6 ++#define EPT_DEFAULT_GAW 3 ++ + struct arch_vmx_struct { + /* Virtual address of VMCS. */ + struct vmcs_struct *vmcs; +@@ -73,8 +76,19 @@ struct arch_vmx_struct { + int active_cpu; + int launched; + ++ union { ++ struct { ++ u64 etmt :3, ++ gaw :3, ++ rsvd :6, ++ asr :52; ++ }; ++ u64 eptp; ++ } ept_control; ++ + /* Cache of cpu execution control. */ + u32 exec_control; ++ u32 secondary_exec_control; + + #ifdef __x86_64__ + struct vmx_msr_state msr_state; +@@ -111,6 +125,8 @@ void vmx_vmcs_exit(struct vcpu *v); + #define CPU_BASED_MWAIT_EXITING 0x00000400 + #define CPU_BASED_RDPMC_EXITING 0x00000800 + #define CPU_BASED_RDTSC_EXITING 0x00001000 ++#define CPU_BASED_CR3_LOAD_EXITING 0x00008000 ++#define CPU_BASED_CR3_STORE_EXITING 0x00010000 + #define CPU_BASED_CR8_LOAD_EXITING 0x00080000 + #define CPU_BASED_CR8_STORE_EXITING 0x00100000 + #define CPU_BASED_TPR_SHADOW 0x00200000 +@@ -139,6 +155,7 @@ extern u32 vmx_vmexit_control; + extern u32 vmx_vmentry_control; + + #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 ++#define SECONDARY_EXEC_ENABLE_EPT 0x00000002 + #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 + extern u32 vmx_secondary_exec_control; + +@@ -154,6 +171,10 @@ extern bool_t cpu_has_vmx_ins_outs_instr + (vmx_pin_based_exec_control & PIN_BASED_VIRTUAL_NMIS) + #define cpu_has_vmx_msr_bitmap \ + (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP) ++#define cpu_has_vmx_secondary_exec_control \ ++ (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) ++#define cpu_has_vmx_ept \ ++ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT) + + /* GUEST_INTERRUPTIBILITY_INFO flags. */ + #define VMX_INTR_SHADOW_STI 0x00000001 +@@ -195,11 +216,23 @@ enum vmcs_field { + VIRTUAL_APIC_PAGE_ADDR = 0x00002012, + VIRTUAL_APIC_PAGE_ADDR_HIGH = 0x00002013, + APIC_ACCESS_ADDR = 0x00002014, +- APIC_ACCESS_ADDR_HIGH = 0x00002015, ++ APIC_ACCESS_ADDR_HIGH = 0x00002015, ++ EPT_POINTER = 0x0000201a, ++ EPT_POINTER_HIGH = 0x0000201b, ++ GUEST_PHYSICAL_ADDRESS = 0x00002400, ++ GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, + VMCS_LINK_POINTER = 0x00002800, + VMCS_LINK_POINTER_HIGH = 0x00002801, + GUEST_IA32_DEBUGCTL = 0x00002802, + GUEST_IA32_DEBUGCTL_HIGH = 0x00002803, ++ GUEST_PDPTR0 = 0x0000280a, ++ GUEST_PDPTR0_HIGH = 0x0000280b, ++ GUEST_PDPTR1 = 0x0000280c, ++ GUEST_PDPTR1_HIGH = 0x0000280d, ++ GUEST_PDPTR2 = 0x0000280e, ++ GUEST_PDPTR2_HIGH = 0x0000280f, ++ GUEST_PDPTR3 = 0x00002810, ++ GUEST_PDPTR3_HIGH = 0x00002811, + PIN_BASED_VM_EXEC_CONTROL = 0x00004000, + CPU_BASED_VM_EXEC_CONTROL = 0x00004002, + EXCEPTION_BITMAP = 0x00004004, +Index: xen-3.2-testing/xen/include/asm-x86/hvm/vmx/vmx.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hvm/vmx/vmx.h ++++ xen-3.2-testing/xen/include/asm-x86/hvm/vmx/vmx.h +@@ -23,9 +23,27 @@ + #include + #include + #include +-#include + #include ++#include + #include ++#include ++ ++typedef union { ++ struct { ++ u64 r : 1, ++ w : 1, ++ x : 1, ++ emt : 4, ++ sp_avail : 1, ++ avail1 : 4, ++ mfn : 45, ++ rsvd : 5, ++ avail2 : 2; ++ }; ++ u64 epte; ++} ept_entry_t; ++ ++#define EPT_TABLE_ORDER 9 + + void vmx_asm_vmexit_handler(struct cpu_user_regs); + void vmx_asm_do_vmentry(void); +@@ -85,6 +103,8 @@ int vmx_realmode_io_complete(void); + #define EXIT_REASON_MACHINE_CHECK 41 + #define EXIT_REASON_TPR_BELOW_THRESHOLD 43 + #define EXIT_REASON_APIC_ACCESS 44 ++#define EXIT_REASON_EPT_VIOLATION 48 ++#define EXIT_REASON_EPT_MISCONFIG 49 + #define EXIT_REASON_WBINVD 54 + + /* +@@ -151,12 +171,14 @@ int vmx_realmode_io_complete(void); + #define VMREAD_OPCODE ".byte 0x0f,0x78\n" + #define VMRESUME_OPCODE ".byte 0x0f,0x01,0xc3\n" + #define VMWRITE_OPCODE ".byte 0x0f,0x79\n" ++#define INVEPT_OPCODE ".byte 0x66,0x0f,0x38,0x80\n" /* m128,r64/32 */ + #define VMXOFF_OPCODE ".byte 0x0f,0x01,0xc4\n" + #define VMXON_OPCODE ".byte 0xf3,0x0f,0xc7\n" + ++#define MODRM_EAX_08 ".byte 0x08\n" /* ECX, [EAX] */ + #define MODRM_EAX_06 ".byte 0x30\n" /* [EAX], with reg/opcode: /6 */ + #define MODRM_EAX_07 ".byte 0x38\n" /* [EAX], with reg/opcode: /7 */ +-#define MODRM_EAX_ECX ".byte 0xc1\n" /* [EAX], [ECX] */ ++#define MODRM_EAX_ECX ".byte 0xc1\n" /* EAX, ECX */ + + static inline void __vmptrld(u64 addr) + { +@@ -240,6 +262,21 @@ static inline void __vm_clear_bit(unsign + __vmwrite(field, __vmread(field) & ~(1UL << bit)); + } + ++static inline void __invept(int ext, u64 eptp, u64 gpa) ++{ ++ struct { ++ u64 eptp, gpa; ++ } operand = {eptp, gpa}; ++ ++ __asm__ __volatile__ ( INVEPT_OPCODE ++ MODRM_EAX_08 ++ /* CF==1 or ZF==1 --> rc = -1 */ ++ "ja 1f ; ud2 ; 1:\n" ++ : ++ : "a" (&operand), "c" (ext) ++ : "memory"); ++} ++ + static inline void __vmxoff(void) + { + asm volatile ( +@@ -269,6 +306,29 @@ static inline int __vmxon(u64 addr) + return rc; + } + ++static inline void __ept_sync_domain(void *info) ++{ ++ struct vcpu *v = info; ++ if ( !hvm_funcs.hap_supported ) ++ return; ++ ++ __invept(1, v->arch.hvm_vmx.ept_control.eptp, 0); ++} ++ ++static inline void ept_sync_domain(struct vcpu *v) ++{ ++ __ept_sync_domain(v); ++ smp_call_function(__ept_sync_domain, v, 1, 0); ++} ++ ++static inline void ept_sync_all(void) ++{ ++ if ( !hvm_funcs.hap_supported ) ++ return; ++ ++ __invept(2, 0, 0); ++} ++ + static inline void __vmx_inject_exception( + struct vcpu *v, int trap, int type, int error_code) + { +@@ -314,4 +374,6 @@ static inline void vmx_inject_nmi(struct + HVM_DELIVER_NO_ERROR_CODE); + } + ++void ept_p2m_init(struct domain *d); ++ + #endif /* __ASM_X86_HVM_VMX_VMX_H__ */ +Index: xen-3.2-testing/xen/include/asm-x86/p2m.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/p2m.h ++++ xen-3.2-testing/xen/include/asm-x86/p2m.h +@@ -43,27 +43,6 @@ + */ + #define phys_to_machine_mapping ((l1_pgentry_t *)RO_MPT_VIRT_START) + +-/* +- * The upper levels of the p2m pagetable always contain full rights; all +- * variation in the access control bits is made in the level-1 PTEs. +- * +- * In addition to the phys-to-machine translation, each p2m PTE contains +- * *type* information about the gfn it translates, helping Xen to decide +- * on the correct course of action when handling a page-fault to that +- * guest frame. We store the type in the "available" bits of the PTEs +- * in the table, which gives us 8 possible types on 32-bit systems. +- * Further expansions of the type system will only be supported on +- * 64-bit Xen. +- */ +-typedef enum { +- p2m_invalid = 0, /* Nothing mapped here */ +- p2m_ram_rw = 1, /* Normal read/write guest RAM */ +- p2m_ram_logdirty = 2, /* Temporarily read-only for log-dirty */ +- p2m_ram_ro = 3, /* Read-only; writes go to the device model */ +- p2m_mmio_dm = 4, /* Reads and write go to the device model */ +- p2m_mmio_direct = 5, /* Read/write mapping of genuine MMIO area */ +-} p2m_type_t; +- + /* We use bitmaps and maks to handle groups of types */ + #define p2m_to_mask(_t) (1UL << (_t)) + +@@ -92,10 +71,16 @@ static inline p2m_type_t p2m_flags_to_ty + /* Type is stored in the "available" bits, 9, 10 and 11 */ + return (flags >> 9) & 0x7; + } +- ++ + /* Read the current domain's p2m table (through the linear mapping). */ + static inline mfn_t gfn_to_mfn_current(unsigned long gfn, p2m_type_t *t) + { ++ return current->domain->arch.p2m.get_entry_fast(gfn, t); ++} ++ ++/* Read the current domain's p2m table (through the linear mapping). */ ++static inline mfn_t p2m_gfn_to_mfn_fast(unsigned long gfn, p2m_type_t *t) ++{ + mfn_t mfn = _mfn(INVALID_MFN); + p2m_type_t p2mt = p2m_mmio_dm; + /* XXX This is for compatibility with the old model, where anything not +@@ -133,7 +118,11 @@ static inline mfn_t gfn_to_mfn_current(u + } + + /* Read another domain's P2M table, mapping pages as we go */ +-mfn_t gfn_to_mfn_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t); ++static inline ++mfn_t gfn_to_mfn_foreign(struct domain *d, unsigned long gfn, p2m_type_t *t) ++{ ++ return d->arch.p2m.get_entry(d, gfn, t); ++} + + /* General conversion function from gfn to mfn */ + #define gfn_to_mfn(d, g, t) _gfn_to_mfn((d), (g), (t)) +@@ -149,7 +138,7 @@ static inline mfn_t _gfn_to_mfn(struct d + } + if ( likely(current->domain == d) ) + return gfn_to_mfn_current(gfn, t); +- else ++ else + return gfn_to_mfn_foreign(d, gfn, t); + } + +Index: xen-3.2-testing/xen/include/public/hvm/params.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/public/hvm/params.h ++++ xen-3.2-testing/xen/include/public/hvm/params.h +@@ -76,6 +76,7 @@ + * Guest time always tracks wallclock (i.e., real) time. + */ + #define HVM_PARAM_TIMER_MODE 10 ++#define HVM_PARAM_IDENT_PT 12 + #define HVMPTM_delay_for_missed_ticks 0 + #define HVMPTM_no_delay_for_missed_ticks 1 + #define HVMPTM_no_missed_ticks_pending 2 +@@ -84,6 +85,6 @@ + /* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */ + #define HVM_PARAM_HPET_ENABLED 11 + +-#define HVM_NR_PARAMS 12 ++#define HVM_NR_PARAMS 13 + + #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ diff --git a/etc_pam.d_xen-api b/etc_pam.d_xen-api new file mode 100644 index 0000000..343bc70 --- /dev/null +++ b/etc_pam.d_xen-api @@ -0,0 +1,7 @@ +#%PAM-1.0 +auth required pam_listfile.so onerr=fail item=user \ + sense=allow file=/etc/xen/xenapiusers +auth include common-auth +account include common-account +password include common-password +session include common-session diff --git a/hvm-ide-flush-o_direct.patch b/hvm-ide-flush-o_direct.patch new file mode 100644 index 0000000..aeb78f1 --- /dev/null +++ b/hvm-ide-flush-o_direct.patch @@ -0,0 +1,18 @@ +Index: xen-3.2-testing/tools/ioemu/hw/ide.c +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/hw/ide.c ++++ xen-3.2-testing/tools/ioemu/hw/ide.c +@@ -1023,12 +1023,12 @@ static void ide_write_dma_cb(void *opaqu + + /* end of transfer ? */ + if (s->nsector == 0) { ++ eot: + /* Ensure the data hit disk before telling the guest OS so. */ + if (!s->write_cache) + bdrv_flush(s->bs); + s->status = READY_STAT | SEEK_STAT; + ide_set_irq(s); +- eot: + bm->status &= ~BM_STATUS_DMAING; + bm->status |= BM_STATUS_INT; + bm->dma_cb = NULL; diff --git a/init.xendomains b/init.xendomains index 259dbff..9b4c46b 100644 --- a/init.xendomains +++ b/init.xendomains @@ -321,47 +321,31 @@ stop() rc_status -v continue fi - # HVM domains currently can't migrate or save so don't even try. - hvm=0 - vmpath=`xenstore-read /local/domain/$id/vm 2> /dev/null` - if [ $? = 0 ]; then - [ `xenstore-read "$vmpath/image/ostype" 2> /dev/null` = hvm ] && hvm=1 - fi if [ -n "$XENDOMAINS_MIGRATE" ]; then echo -n " $name: " echo -n "migrating... " - if [ $hvm != 0 ]; then - echo -n "(unsupported for fully virtualized)" - rc_status -s + migrate_with_watchdog $id "$XENDOMAINS_MIGRATE" + if [ $? -ne 0 ]; then + rc_failed + rc_status -v else - migrate_with_watchdog $id "$XENDOMAINS_MIGRATE" - if [ $? -ne 0 ]; then - rc_failed - rc_status -v - else - rc_reset - rc_status -v - continue - fi + rc_reset + rc_status -v + continue fi fi if [ -n "$XENDOMAINS_SAVE" ]; then echo -n " $name: " echo -n "saving... " - if [ $hvm != 0 ]; then - echo -n "(unsupported for fully virtualized)" - rc_status -s + save_with_watchdog $id "$XENDOMAINS_SAVE/$name" + if [ $? -ne 0 ]; then + rm -f "$XENDOMAINS_SAVE/$name" + rc_failed + rc_status -v else - save_with_watchdog $id "$XENDOMAINS_SAVE/$name" - if [ $? -ne 0 ]; then - rm -f "$XENDOMAINS_SAVE/$name" - rc_failed - rc_status -v - else - rc_reset - rc_status -v - continue - fi + rc_reset + rc_status -v + continue fi fi if [ -n "$XENDOMAINS_SHUTDOWN" ]; then diff --git a/livemig-ept-novell-i386.patch b/livemig-ept-novell-i386.patch new file mode 100644 index 0000000..167c68c --- /dev/null +++ b/livemig-ept-novell-i386.patch @@ -0,0 +1,209 @@ +Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/vmx.c ++++ xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised }; + +@@ -2854,9 +2855,44 @@ void vmx_wbinvd_intercept(void) + + static void ept_handle_violation(unsigned long qualification, paddr_t gpa) + { +- if ( unlikely(((qualification >> 7) & 0x3) != 0x3) ) ++ unsigned long gla_validity = qualification & EPT_GLA_VALIDITY_MASK; ++ struct domain *d = current->domain; ++ u64 gfn = gpa >> PAGE_SHIFT; ++ mfn_t mfn; ++ p2m_type_t t; ++ ++ /* GPA exceeds GAW. */ ++ if ( unlikely(qualification & EPT_GAW_VIOLATION) ) + { +- domain_crash(current->domain); ++ printk("EPT violation: guest physical address %"PRIpaddr" exceeded " ++ "its width limit.\n", gpa); ++ domain_crash(d); ++ } ++ ++ if ( gla_validity == EPT_GLA_VALIDITY_RSVD || ++ gla_validity == EPT_GLA_VALIDITY_PDPTR_LOAD ) ++ { ++ printk("ept violation: reserved bit or pdptr load violation.\n"); ++ domain_crash(d); ++ } ++ ++ mfn = gfn_to_mfn(d, gfn, &t); ++ ++ if ( unlikely( gla_validity != EPT_GLA_VALIDITY_MATCH) ) ++ { ++ if ( p2m_is_ram(t) && paging_mode_log_dirty(d) ) ++ goto mark_dirty; ++ domain_crash(d); ++ return; ++ } ++ ++mark_dirty: ++ ++ if ( p2m_is_ram(t) && paging_mode_log_dirty(d) ) ++ { ++ paging_mark_dirty(d, mfn_x(mfn)); ++ p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw); ++ flush_tlb_mask(d->domain_dirty_cpumask); + return; + } + +Index: xen-3.2-testing/xen/arch/x86/mm/hap/hap.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/hap/hap.c ++++ xen-3.2-testing/xen/arch/x86/mm/hap/hap.c +@@ -61,7 +61,7 @@ int hap_enable_log_dirty(struct domain * + hap_unlock(d); + + /* set l1e entries of P2M table to be read-only. */ +- p2m_change_type_global(d, p2m_ram_rw, p2m_ram_logdirty); ++ p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_logdirty); + flush_tlb_mask(d->domain_dirty_cpumask); + return 0; + } +@@ -73,14 +73,14 @@ int hap_disable_log_dirty(struct domain + hap_unlock(d); + + /* set l1e entries of P2M table with normal mode */ +- p2m_change_type_global(d, p2m_ram_logdirty, p2m_ram_rw); ++ p2m_change_entry_type_global(d, p2m_ram_logdirty, p2m_ram_rw); + return 0; + } + + void hap_clean_dirty_bitmap(struct domain *d) + { + /* set l1e entries of P2M table to be read-only. */ +- p2m_change_type_global(d, p2m_ram_rw, p2m_ram_logdirty); ++ p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_logdirty); + flush_tlb_mask(d->domain_dirty_cpumask); + } + +Index: xen-3.2-testing/xen/arch/x86/mm/p2m.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/p2m.c ++++ xen-3.2-testing/xen/arch/x86/mm/p2m.c +@@ -279,11 +279,19 @@ void p2m_init(struct domain *d) + d->arch.p2m.set_entry = p2m_set_entry; + d->arch.p2m.get_entry = p2m_gfn_to_mfn; + d->arch.p2m.get_entry_fast = p2m_gfn_to_mfn_fast; ++ d->arch.p2m.change_entry_type_global = p2m_change_type_global; + + if ( is_hvm_domain(d) ) + hvm_p2m_init(d); + } + ++void p2m_change_entry_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt) ++{ ++ p2m_lock(d); ++ d->arch.p2m.change_entry_type_global(d, ot, nt); ++ p2m_unlock(d); ++} ++ + static inline + int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, p2m_type_t p2mt) + { +@@ -806,8 +814,6 @@ void p2m_change_type_global(struct domai + if ( pagetable_get_pfn(d->arch.phys_table) == 0 ) + return; + +- p2m_lock(d); +- + #if CONFIG_PAGING_LEVELS == 4 + l4e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table))); + #elif CONFIG_PAGING_LEVELS == 3 +@@ -878,7 +884,6 @@ void p2m_change_type_global(struct domai + unmap_domain_page(l2e); + #endif + +- p2m_unlock(d); + } + + /* Modify the p2m type of a single gfn from ot to nt, returning the +Index: xen-3.2-testing/xen/include/asm-x86/domain.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/domain.h ++++ xen-3.2-testing/xen/include/asm-x86/domain.h +@@ -171,6 +171,8 @@ struct p2m_domain { + p2m_type_t *p2mt); + mfn_t (*get_entry_fast)(unsigned long gfn, p2m_type_t *p2mt); + ++ void (*change_entry_type_global)(struct domain *d, ++ p2m_type_t ot, p2m_type_t nt); + /* Highest guest frame that's ever been mapped in the p2m */ + unsigned long max_mapped_pfn; + }; +Index: xen-3.2-testing/xen/include/asm-x86/hap.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hap.h ++++ xen-3.2-testing/xen/include/asm-x86/hap.h +@@ -97,6 +97,49 @@ extern struct paging_mode hap_paging_pro + extern struct paging_mode hap_paging_pae_mode; + extern struct paging_mode hap_paging_long_mode; + ++/* EPT violation qualifications definitions */ ++/* bit offset 0 in exit qualification */ ++#define _EPT_READ_VIOLATION 0 ++#define EPT_READ_VIOLATION (1UL<<_EPT_READ_VIOLATION) ++/* bit offset 1 in exit qualification */ ++#define _EPT_WRITE_VIOLATION 1 ++#define EPT_WRITE_VIOLATION (1UL<<_EPT_WRITE_VIOLATION) ++/* bit offset 2 in exit qualification */ ++#define _EPT_EXEC_VIOLATION 2 ++#define EPT_EXEC_VIOLATION (1UL<<_EPT_EXEC_VIOLATION) ++ ++/* bit offset 3 in exit qualification */ ++#define _EPT_EFFECTIVE_READ 3 ++#define EPT_EFFECTIVE_READ (1UL<<_EPT_EFFECTIVE_READ) ++/* bit offset 4 in exit qualification */ ++#define _EPT_EFFECTIVE_WRITE 4 ++#define EPT_EFFECTIVE_WRITE (1UL<<_EPT_EFFECTIVE_WRITE) ++/* bit offset 5 in exit qualification */ ++#define _EPT_EFFECTIVE_EXEC 5 ++#define EPT_EFFECTIVE_EXEC (1UL<<_EPT_EFFECTIVE_EXEC) ++ ++/* bit offset 6 in exit qualification */ ++#define _EPT_GAW_VIOLATION 6 ++#define EPT_GAW_VIOLATION (1UL<<_EPT_GAW_VIOLATION) ++ ++/* bits offset 7 & 8 in exit qualification */ ++#define _EPT_GLA_VALIDITY 7 ++#define EPT_GLA_VALIDITY_MASK (3UL<<_EPT_GLA_VALIDITY) ++/* gla != gpa, when load PDPTR */ ++#define EPT_GLA_VALIDITY_PDPTR_LOAD (0UL<<_EPT_GLA_VALIDITY) ++/* gla != gpa, during guest page table walking */ ++#define EPT_GLA_VALIDITY_GPT_WALK (1UL<<_EPT_GLA_VALIDITY) ++/* reserved */ ++#define EPT_GLA_VALIDITY_RSVD (2UL<<_EPT_GLA_VALIDITY) ++/* gla == gpa, normal case */ ++#define EPT_GLA_VALIDITY_MATCH (3UL<<_EPT_GLA_VALIDITY) ++ ++#define EPT_EFFECTIVE_MASK (EPT_EFFECTIVE_READ | \ ++ EPT_EFFECTIVE_WRITE | \ ++ EPT_EFFECTIVE_EXEC) ++ ++#define EPT_PAGETABLE_ENTRIES 512 ++ + #endif /* XEN_HAP_H */ + + /* +Index: xen-3.2-testing/xen/include/asm-x86/p2m.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/p2m.h ++++ xen-3.2-testing/xen/include/asm-x86/p2m.h +@@ -209,6 +209,7 @@ void guest_physmap_remove_page(struct do + + /* Change types across all p2m entries in a domain */ + void p2m_change_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt); ++void p2m_change_entry_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt); + + /* Compare-exchange the type of a single p2m entry */ + p2m_type_t p2m_change_type(struct domain *d, unsigned long gfn, diff --git a/livemig-ept-novell-x64.patch b/livemig-ept-novell-x64.patch new file mode 100644 index 0000000..b40dbe8 --- /dev/null +++ b/livemig-ept-novell-x64.patch @@ -0,0 +1,331 @@ +Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/vmx.c ++++ xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised }; + +@@ -2854,9 +2855,44 @@ void vmx_wbinvd_intercept(void) + + static void ept_handle_violation(unsigned long qualification, paddr_t gpa) + { +- if ( unlikely(((qualification >> 7) & 0x3) != 0x3) ) ++ unsigned long gla_validity = qualification & EPT_GLA_VALIDITY_MASK; ++ struct domain *d = current->domain; ++ u64 gfn = gpa >> PAGE_SHIFT; ++ mfn_t mfn; ++ p2m_type_t t; ++ ++ /* GPA exceeds GAW. */ ++ if ( unlikely(qualification & EPT_GAW_VIOLATION) ) + { +- domain_crash(current->domain); ++ printk("EPT violation: guest physical address %"PRIpaddr" exceeded " ++ "its width limit.\n", gpa); ++ domain_crash(d); ++ } ++ ++ if ( gla_validity == EPT_GLA_VALIDITY_RSVD || ++ gla_validity == EPT_GLA_VALIDITY_PDPTR_LOAD ) ++ { ++ printk("ept violation: reserved bit or pdptr load violation.\n"); ++ domain_crash(d); ++ } ++ ++ mfn = gfn_to_mfn(d, gfn, &t); ++ ++ if ( unlikely( gla_validity != EPT_GLA_VALIDITY_MATCH) ) ++ { ++ if ( p2m_is_ram(t) && paging_mode_log_dirty(d) ) ++ goto mark_dirty; ++ domain_crash(d); ++ return; ++ } ++ ++mark_dirty: ++ ++ if ( p2m_is_ram(t) && paging_mode_log_dirty(d) ) ++ { ++ paging_mark_dirty(d, mfn_x(mfn)); ++ p2m_change_type(d, gfn, p2m_ram_logdirty, p2m_ram_rw); ++ flush_tlb_mask(d->domain_dirty_cpumask); + return; + } + +Index: xen-3.2-testing/xen/arch/x86/mm/hap/hap.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/hap/hap.c ++++ xen-3.2-testing/xen/arch/x86/mm/hap/hap.c +@@ -61,7 +61,7 @@ int hap_enable_log_dirty(struct domain * + hap_unlock(d); + + /* set l1e entries of P2M table to be read-only. */ +- p2m_change_type_global(d, p2m_ram_rw, p2m_ram_logdirty); ++ p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_logdirty); + flush_tlb_mask(d->domain_dirty_cpumask); + return 0; + } +@@ -73,14 +73,14 @@ int hap_disable_log_dirty(struct domain + hap_unlock(d); + + /* set l1e entries of P2M table with normal mode */ +- p2m_change_type_global(d, p2m_ram_logdirty, p2m_ram_rw); ++ p2m_change_entry_type_global(d, p2m_ram_logdirty, p2m_ram_rw); + return 0; + } + + void hap_clean_dirty_bitmap(struct domain *d) + { + /* set l1e entries of P2M table to be read-only. */ +- p2m_change_type_global(d, p2m_ram_rw, p2m_ram_logdirty); ++ p2m_change_entry_type_global(d, p2m_ram_rw, p2m_ram_logdirty); + flush_tlb_mask(d->domain_dirty_cpumask); + } + +Index: xen-3.2-testing/xen/arch/x86/mm/p2m-ept.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/p2m-ept.c ++++ xen-3.2-testing/xen/arch/x86/mm/p2m-ept.c +@@ -23,6 +23,27 @@ + #include + #include + #include ++#include ++ ++static void ept_p2m_type_to_flags(ept_entry_t *entry, p2m_type_t type) ++{ ++ switch(type) ++ { ++ case p2m_invalid: ++ case p2m_mmio_dm: ++ default: ++ return; ++ case p2m_ram_rw: ++ case p2m_mmio_direct: ++ entry->r = entry->w = entry->x = 1; ++ return; ++ case p2m_ram_logdirty: ++ case p2m_ram_ro: ++ entry->r = entry->x = 1; ++ entry->w = 0; ++ return; ++ } ++} + + static int ept_next_level(struct domain *d, bool_t read_only, + ept_entry_t **table, unsigned long *gfn_remainder, +@@ -100,6 +121,7 @@ ept_set_entry(struct domain *d, unsigned + ept_entry->avail2 = 0; + /* last step */ + ept_entry->r = ept_entry->w = ept_entry->x = 1; ++ ept_p2m_type_to_flags(ept_entry, p2mt); + } + else + ept_entry->epte = 0; +@@ -140,13 +162,10 @@ static mfn_t ept_get_entry(struct domain + index = gfn_remainder; + ept_entry = table + index; + +- if ( (ept_entry->epte & 0x7) == 0x7 ) ++ if ( ept_entry->avail1 != p2m_invalid ) + { +- if ( ept_entry->avail1 != p2m_invalid ) +- { +- *t = ept_entry->avail1; +- mfn = _mfn(ept_entry->mfn); +- } ++ *t = ept_entry->avail1; ++ mfn = _mfn(ept_entry->mfn); + } + + out: +@@ -159,11 +178,64 @@ static mfn_t ept_get_entry_fast(unsigned + return ept_get_entry(current->domain, gfn, t); + } + ++/* Walk the whole p2m table, changing any entries of the old type ++ * to the new type. This is used in hardware-assisted paging to ++ * quickly enable or diable log-dirty tracking */ ++ ++static void ept_change_entry_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt) ++{ ++ if ( pagetable_get_pfn(d->arch.phys_table) == 0 ) ++ return; ++ ++ if ( EPT_DEFAULT_GAW == 3 ) ++ { ++ ept_entry_t *l4e, *l3e, *l2e, *l1e; ++ int i4, i3, i2, i1; ++ ++ l4e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table))); ++ for (i4 = 0; i4 < EPT_PAGETABLE_ENTRIES; i4++ ) ++ { ++ if ( !(l4e+i4)->epte || (l4e+i4)->sp_avail) ++ continue; ++ l3e = map_domain_page((l4e+i4)->mfn); ++ for ( i3 = 0; i3 < EPT_PAGETABLE_ENTRIES; i3++ ) ++ { ++ if ( !(l3e+i3)->epte || (l3e+i3)->sp_avail ) ++ continue; ++ l2e = map_domain_page((l3e+i3)->mfn); ++ for ( i2 = 0; i2 < EPT_PAGETABLE_ENTRIES; i2++ ) ++ { ++ if ( !(l2e+i2)->epte || (l2e+i2)->sp_avail ) ++ continue; ++ l1e = map_domain_page((l2e+i2)->mfn); ++ for ( i1 = 0; i1 < EPT_PAGETABLE_ENTRIES; i1++ ) ++ { ++ if ( !(l1e+i1)->epte ) ++ continue; ++ if ( (l1e+i1)->avail1 != ot ) ++ continue; ++ (l1e+i1)->avail1 = nt; ++ ept_p2m_type_to_flags(l1e+i1, nt); ++ } ++ unmap_domain_page(l1e); ++ } ++ unmap_domain_page(l2e); ++ } ++ unmap_domain_page(l3e); ++ } ++ unmap_domain_page(l4e); ++ ++ if ( d->vcpu[0] ) ++ ept_sync_domain(d->vcpu[0]); ++ } ++} ++ + void ept_p2m_init(struct domain *d) + { + d->arch.p2m.set_entry = ept_set_entry; + d->arch.p2m.get_entry = ept_get_entry; + d->arch.p2m.get_entry_fast = ept_get_entry_fast; ++ d->arch.p2m.change_entry_type_global = ept_change_entry_type_global; + } + + /* +Index: xen-3.2-testing/xen/arch/x86/mm/p2m.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/p2m.c ++++ xen-3.2-testing/xen/arch/x86/mm/p2m.c +@@ -279,11 +279,19 @@ void p2m_init(struct domain *d) + d->arch.p2m.set_entry = p2m_set_entry; + d->arch.p2m.get_entry = p2m_gfn_to_mfn; + d->arch.p2m.get_entry_fast = p2m_gfn_to_mfn_fast; ++ d->arch.p2m.change_entry_type_global = p2m_change_type_global; + + if ( is_hvm_domain(d) ) + hvm_p2m_init(d); + } + ++void p2m_change_entry_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt) ++{ ++ p2m_lock(d); ++ d->arch.p2m.change_entry_type_global(d, ot, nt); ++ p2m_unlock(d); ++} ++ + static inline + int set_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn, p2m_type_t p2mt) + { +@@ -806,8 +814,6 @@ void p2m_change_type_global(struct domai + if ( pagetable_get_pfn(d->arch.phys_table) == 0 ) + return; + +- p2m_lock(d); +- + #if CONFIG_PAGING_LEVELS == 4 + l4e = map_domain_page(mfn_x(pagetable_get_mfn(d->arch.phys_table))); + #elif CONFIG_PAGING_LEVELS == 3 +@@ -878,7 +884,6 @@ void p2m_change_type_global(struct domai + unmap_domain_page(l2e); + #endif + +- p2m_unlock(d); + } + + /* Modify the p2m type of a single gfn from ot to nt, returning the +Index: xen-3.2-testing/xen/include/asm-x86/domain.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/domain.h ++++ xen-3.2-testing/xen/include/asm-x86/domain.h +@@ -171,6 +171,8 @@ struct p2m_domain { + p2m_type_t *p2mt); + mfn_t (*get_entry_fast)(unsigned long gfn, p2m_type_t *p2mt); + ++ void (*change_entry_type_global)(struct domain *d, ++ p2m_type_t ot, p2m_type_t nt); + /* Highest guest frame that's ever been mapped in the p2m */ + unsigned long max_mapped_pfn; + }; +Index: xen-3.2-testing/xen/include/asm-x86/hap.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hap.h ++++ xen-3.2-testing/xen/include/asm-x86/hap.h +@@ -97,6 +97,49 @@ extern struct paging_mode hap_paging_pro + extern struct paging_mode hap_paging_pae_mode; + extern struct paging_mode hap_paging_long_mode; + ++/* EPT violation qualifications definitions */ ++/* bit offset 0 in exit qualification */ ++#define _EPT_READ_VIOLATION 0 ++#define EPT_READ_VIOLATION (1UL<<_EPT_READ_VIOLATION) ++/* bit offset 1 in exit qualification */ ++#define _EPT_WRITE_VIOLATION 1 ++#define EPT_WRITE_VIOLATION (1UL<<_EPT_WRITE_VIOLATION) ++/* bit offset 2 in exit qualification */ ++#define _EPT_EXEC_VIOLATION 2 ++#define EPT_EXEC_VIOLATION (1UL<<_EPT_EXEC_VIOLATION) ++ ++/* bit offset 3 in exit qualification */ ++#define _EPT_EFFECTIVE_READ 3 ++#define EPT_EFFECTIVE_READ (1UL<<_EPT_EFFECTIVE_READ) ++/* bit offset 4 in exit qualification */ ++#define _EPT_EFFECTIVE_WRITE 4 ++#define EPT_EFFECTIVE_WRITE (1UL<<_EPT_EFFECTIVE_WRITE) ++/* bit offset 5 in exit qualification */ ++#define _EPT_EFFECTIVE_EXEC 5 ++#define EPT_EFFECTIVE_EXEC (1UL<<_EPT_EFFECTIVE_EXEC) ++ ++/* bit offset 6 in exit qualification */ ++#define _EPT_GAW_VIOLATION 6 ++#define EPT_GAW_VIOLATION (1UL<<_EPT_GAW_VIOLATION) ++ ++/* bits offset 7 & 8 in exit qualification */ ++#define _EPT_GLA_VALIDITY 7 ++#define EPT_GLA_VALIDITY_MASK (3UL<<_EPT_GLA_VALIDITY) ++/* gla != gpa, when load PDPTR */ ++#define EPT_GLA_VALIDITY_PDPTR_LOAD (0UL<<_EPT_GLA_VALIDITY) ++/* gla != gpa, during guest page table walking */ ++#define EPT_GLA_VALIDITY_GPT_WALK (1UL<<_EPT_GLA_VALIDITY) ++/* reserved */ ++#define EPT_GLA_VALIDITY_RSVD (2UL<<_EPT_GLA_VALIDITY) ++/* gla == gpa, normal case */ ++#define EPT_GLA_VALIDITY_MATCH (3UL<<_EPT_GLA_VALIDITY) ++ ++#define EPT_EFFECTIVE_MASK (EPT_EFFECTIVE_READ | \ ++ EPT_EFFECTIVE_WRITE | \ ++ EPT_EFFECTIVE_EXEC) ++ ++#define EPT_PAGETABLE_ENTRIES 512 ++ + #endif /* XEN_HAP_H */ + + /* +Index: xen-3.2-testing/xen/include/asm-x86/p2m.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/p2m.h ++++ xen-3.2-testing/xen/include/asm-x86/p2m.h +@@ -209,6 +209,7 @@ void guest_physmap_remove_page(struct do + + /* Change types across all p2m entries in a domain */ + void p2m_change_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt); ++void p2m_change_entry_type_global(struct domain *d, p2m_type_t ot, p2m_type_t nt); + + /* Compare-exchange the type of a single p2m entry */ + p2m_type_t p2m_change_type(struct domain *d, unsigned long gfn, diff --git a/multinet-common.sh b/multinet-common.sh index aa4581a..53ca633 100644 --- a/multinet-common.sh +++ b/multinet-common.sh @@ -2,8 +2,8 @@ #============================================================================ # multinet-common.sh # -# Version = 3.0.0 -# Date = 2008-01-30 +# Version = 3.0.1 +# Date = 2008-02-07 # # Maintainer(s) = Ron Terry - ron (at) pronetworkconsulting (dot) com # @@ -16,7 +16,7 @@ # Function library for network-multinet and all other multinet related # network scripts # -# Vars (should not require modification): +# Vars (should not need to be changed): # # BRIDGE_NAME -Name of bridged networks # HOSTONLY_NAME -Name of hostonly networks @@ -598,21 +598,6 @@ manage_firewall() { #***** Traditional Bridge Helper Functions ******************************** -setup_bridge_port() { -# This function configures a network interface to be a port on -# a bridge by removing any IP addresses bound to it. -# -# Usage: setup_bridge_port - - local DEV="$1" - - # take interface down ... - ip link set ${DEV} down - - # ... and configure it - ip addr flush ${DEV} > /dev/null 2>&1 -} - create_bridge() { # This function creates a bridge. # @@ -630,15 +615,7 @@ create_bridge() { brctl addbr ${BRIDGE} brctl stp ${BRIDGE} off brctl setfd ${BRIDGE} 0 - - # Create an ifcfg file for the bridge - #echo "Creating $IFCFG_FILE_DIR/ifcfg-${BRIDGE}";read - echo "NAME='Xen Virtual - ${BRIDGE}'" > $IFCFG_FILE_DIR/ifcfg-${BRIDGE} fi - - # Bring the bridge up - #echo "Bridge $BRIDGE up";read - ip link set ${BRIDGE} up } delete_bridge() { @@ -671,10 +648,6 @@ delete_bridge() { # Remove the bridge #echo "Removing $BRIDGE";read brctl delbr ${BRIDGE} - - # Remove the bridge's ifcfg file - #echo "Removing $IFCFG_FILE_DIR/ifcfg-${BRIDGE}";read - rm -f $IFCFG_FILE_DIR/ifcfg-${BRIDGE} fi } @@ -691,7 +664,6 @@ add_to_bridge() { # Don't add $dev to $bridge if it's already on a bridge. if [ -e "/sys/class/net/${BRIDGE}/brif/${DEV}" ]; then - ip link set ${DEV} up || true return fi brctl addif ${BRIDGE} ${DEV} @@ -713,6 +685,8 @@ add_to_bridge2() { echo -n " Waiting for ${DEV} to negotiate link." ip link set ${DEV} up + + for i in `seq ${MAXTRIES}` ; do if ifconfig ${DEV} | grep -q RUNNING ; then break @@ -730,56 +704,6 @@ add_to_bridge2() { add_to_bridge ${BRIDGE} ${DEV} } -rename_interfaces() { -# This function renames network interface DST SRC -# -# Usage: rename_interfaces $SRC $DST -# -# Vars: SRC -Name of the sourec interface -# DST -Name of the destination interface - - local DEV=$1 - local NEW_DEV=$2 - - # Bring down interface - #echo "Bring down ${DEV}";read - ip link set ${DEV} down - - # Rename physical and virtual interfaces - #echo "Rename ${DEV} to ${NEW_DEV}";read - ip link set ${DEV} name ${NEW_DEV} - - # Bring interface back up - #echo "Bring ${NEW_DEV} back up";read - ip link set ${NEW_DEV} up -} - -transfer_mac() { -# This function transfers the mac address from one network interface -# to another -# -# Usage: transfer_mac $SRC $DST -# -# Vars: SRC -Name of the sourec interface -# DST -Name of the destination interface -# MAC -MAC address to transfer - - local SRC=$1 - local DST=$2 - - # Find MAC Address - #echo "Find MAC address of ${SRC}";read - local MAC=`ip link show ${SRC} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'` - - # Assign the physical MAC to the new interface - #echo "Assign the physical MAC to ${DST}";echo "ip link set ${DST} down";echo "ip link set ${DST} addr ${MAC}";echo "ip link set ${DST} arp on";echo "ip link set ${DST} up";read - ip link set ${DST} down - ip link set ${DST} addr ${MAC} - ip link set ${DST} arp on - ip link set ${DST} multicast on - ip link set ${DST} up -} - transfer_addrs() { # This function transfers all IP addresses (including aliases) from one # network interface to another @@ -787,26 +711,27 @@ transfer_addrs() { # Usage: transfer_addrs $DEV $BRIDGE # transfer_addrs $BRIDGE $DEV # -# Vars: $DEV/$SRC -Source interface +# Vars: $DEV/$SRC -Source interface # $BRIDGE/$DST -Destination interface local SRC=$1 local DST=$2 - # Ensure their is an address to transfer + # Ensure there is an address to transfer # echo "Ensure there is an address to transfer";echo "ifup ${SRC}";echo "ip link set ${DST} up";read - ifup $SRC > /dev/null 2>&1 - ip link set $DST up + if ! ip addr show $SRC| grep -qw "UP" + then + ip link set $SRC up + #ifup $SRC > /dev/null 2>&1 + fi # Don't bother if $DST already has IP addresses. if ip addr show dev ${DST} | egrep -q '^ *inet ' ; then return fi - # Find the IP Address and Subnet Mask - #echo "Find the IP address and Subnet Mask";read - local IPADDR="`ip addr show dev ${SRC} | grep 'inet ' | sed 's/^ *//g' | cut -d ' ' -f 2 | cut -d '/' -f 1`" - local SNM="`ipcalc $IPADDR | grep Netmask | sed 's/Netmask: *//g' | cut -d ' ' -f 1`" + # Record default route on ${SRC} + DEFAULT_GW=`ip route show dev ${SRC} | fgrep default | sed 's/default via //'` # Address lines start with 'inet' and have the device in them. # Replace 'inet' with 'ip addr add' and change the device name $SRC @@ -824,25 +749,6 @@ s/secondary// p }" | sh -e - # Remove IP address and Subnet Mask from SRC ifcfg file - #echo "Remove IP Address and Subnet Mask from $IFCFG_FILE_DIR/ifcfg-${SRC}";read - #sed -i '/^IPADDR=.*/d' $IFCFG_FILE_DIR/ifcfg-${SRC} - #sed -i '/^NETMASK=.*/d' $IFCFG_FILE_DIR/ifcfg-${SRC} - - # Write IP Address and Subnet mask out to ifcfg file - #echo "Write out IP Address and Subnet Mask to $IFCFG_FILE_DIR/ifcfg-${DST}";read - if [ -e $IFCFG_FILE_DIR/ifcfg-${DST} ] - then - grep -q "IPADDR=" $IFCFG_FILE_DIR/ifcfg-${DST} || echo "IPADDR='$IPADDR'" >> $IFCFG_FILE_DIR/ifcfg-${DST} - grep -q "NETMASK=" $IFCFG_FILE_DIR/ifcfg-${DST} || echo "NETMASK='$SNM'" >> $IFCFG_FILE_DIR/ifcfg-${DST} - grep -q "BOOTPROTO=" $IFCFG_FILE_DIR/ifcfg-${DST} || echo "BOOTPROTO='static'" >> $IFCFG_FILE_DIR/ifcfg-${DST} - grep -q "STARTMODE=" $IFCFG_FILE_DIR/ifcfg-${DST} || echo "STARTMODE='manual'" >> $IFCFG_FILE_DIR/ifcfg-${DST} - fi - - # Bring the interface down and back up again - #echo "Bring ${DST} down and back up again";read - ip link set ${DST} down - ifup ${DST} > /dev/null 2>&1 } transfer_routes() { @@ -930,37 +836,22 @@ find_active_vlans() { echo "$VLANS" } -find_bridged_netdev() { -# This function finds the network interface ($netdev) that is associated -# with the bridge by matching MAC addresses. -# -# Usage: find_bridges_netdev - - local bridge=$1 - - bmac=`ip link show ${bridge} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'` - for i in `ls /sys/class/net/${bridge}/brif` ; do - mac=`ip link show ${i} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'` - if [ "${bmac}" = "$MAC" ] && [ ! "${bridge}" = "${i}" ] ; then - netdev=${i} - return 0 - fi - done - return 1 -} - create_normal_bridge() { # This fuction creates a bridge on a normal network interface # -# Usage: create_normal_bridge start|stop $DEV $PDEV $BRIDGE +# Usage: create_normal_bridge start|stop $DEV $BRIDGE # # Vars: $DEV -Network interface name -# $PDEV -Name interface will be renamed to # $BRIDGE -Name of the bridge local DEV="$2" - local PDEV="$3" - local BRIDGE="$4" + local BRIDGE="$3" + + local BONDED="no" + if [ -e /sys/class/net/$DEV/bonding ] + then + BONDED="yes" + fi # Find and bring down any active VLANs local VLANS=$(find_active_vlans "${DEV}") @@ -971,52 +862,61 @@ create_normal_bridge() { case $1 in start) - # Ensure there is a bridge to transfer to + # Create ${BRIDGE} #echo "Create the bridge. \(create_bridge ${BRIDGE}\)";read create_bridge ${BRIDGE} - # Transfer the IP address to the virtual interface + # Transfer IP address from ${DEV} to the ${BRIDGE} #echo "Transfer the IP address from ${DEV} to ${BRIDGE}";read transfer_addrs ${DEV} ${BRIDGE} - # Rename physical and virtual interfaces - #echo "Rename ${DEV} to ${PDEV}";read - rename_interfaces ${DEV} ${PDEV} + # Flush addresses from ${DEV} + #echo "Flush addresses from ${DEV}";read + ip addr flush ${DEV} > /dev/null 2>&1 - # Configure $PDEV as a bridge port - #echo "Configure ${PDEV} as a bridge port";read - setup_bridge_port ${PDEV} + # Add ${DEV} to ${BRIDGE} + #echo "Add ${DEV} to ${BRIDGE}";read + brctl addif ${BRIDGE} ${DEV} + + # Bring up ${BRIDGE} + #echo "Bring up ${BRIDGE}";read + ip link set dev ${BRIDGE} up + + # If default route was on ${DEV}, then transfer it to ${BRIDGE} + #echo "Add gw ${DEFAULT_GW}";read + [ -n "${DEFAULT_GW}" ] && ip route add default dev ${BRIDGE} via ${DEFAULT_GW} - # Bring bridge up and add interfaces to it - #echo "Bring ${BRIDGE} up and add ${PDEV} to it";read - ip link set ${BRIDGE} up - add_to_bridge2 ${BRIDGE} ${PDEV} ;; stop) # Remove interface from bridge - #echo "Remove interface ${PDEV} from ${BRIDGE}";read - brctl delif ${BRIDGE} ${PDEV} + brctl delif ${BRIDGE} ${DEV} + + # If interface is a bond, use ifdown and don't transfer addresses. + # Addresses will be reassigned when ifup'ing the bond. + #echo "Remove interface ${DEV} from ${BRIDGE}";read + if [ "x${BONDED}" = "xyes" ] + then + ifdown ${DEV} + else + ip link set ${DEV} down + # Transfer IP address back to original interface + #echo "Transfer IP address from ${BRIDGE} to ${DEV}";read + transfer_addrs ${BRIDGE} ${DEV} + fi - # Transfer IP address back to original interface - #echo "Transfer IP address from ${BRIDGE} to ${PDEV}";read - transfer_addrs ${BRIDGE} ${PDEV} - - # Configure $PDEV as a bridge port - #echo "Configure ${BRIDGE} as a bridge port";read - #setup_bridge_port ${BRIDGE} - # Remove bridge ${BRIDGE} #echo "Remove the bridge";read delete_bridge ${BRIDGE} - # Rename physical and virtual network interfaces - #echo "Rename ${PDEV} to ${DEV}";read - #ip link set ${PDEV} name ${DEV} - rename_interfaces ${PDEV} ${DEV} - - # Bring renamed physical interface up - #echo "Bring up ${DEV}";read - ifup ${DEV} > /dev/null 2>&1 + # If bonded, just ifup the bond. Otherwise use ip to bring up the interface + # and if default route was on ${BRIDGE} transfer it back to ${DEV} + if [ "x${BONDED}" = "xyes" ] + then + ifup ${DEV} + else + ip link set ${DEV} up + [ -n "${DEFAULT_GW}" ] && ip route add default dev ${DEV} via ${DEFAULT_GW} + fi ;; esac @@ -1032,18 +932,16 @@ create_normal_bridge() { #***** NAT/HostOnly Helper Functions ************************************** configure_bridge_as_dom0_interface() { -# This function configures the MAC and IP address of a bridge to be a +# This function configures the IP address of a bridge to be a # network interface in Dom0. # -# Usage: configure_dom0_bridge_interface $BRIDGE $IPADDR $MAC +# Usage: configure_dom0_bridge_interface $BRIDGE $IPADDR # # Vars: $BRIDGE -bridge name # $IPADDR -IP address to assign to the bridge -# $MAC -MAC address to assign to the bridge local BRIDGE="$1" local IPADDR="$2" - local MAC="$3" case $CMD_OPT in start) @@ -1051,16 +949,12 @@ configure_bridge_as_dom0_interface() { #echo "Taking the $BRIDGE down";read ip link set $BRIDGE down - # Assifge bridge a MAC address - #echo "Assign $BRIDGE a MAC address";read - ip link set $BRIDGE addr $MAC - # Assign the bridge an IP address #echo"Assign $BRIDGE the IP address: $IPADDR";read ip addr flush $BRIDGE > /dev/null 2>&1 ip addr add $IPADDR brd + dev $BRIDGE - # Bring the brisge back up + # Bring the bridge back up #echo "Bridge $BRIDGE back up";read ip link set $BRIDGE up @@ -1073,12 +967,8 @@ configure_bridge_as_dom0_interface() { #echo "Taking $BRIDGE down";read ip link set $BRIDGE down - # Remove MAC address from bridge - #echo "Remove MAC address from $BRIDGE";read - ip link set $BRIDGE addr fe:ff:ff:ff:ff:ff - # Remove IP address from the bridge - #echo "Remove teh IP address from $BRIDGE";read + #echo "Remove the IP address from $BRIDGE";read ip addr flush $BRIDGE > /dev/null 2>&1 ;; status) @@ -1097,15 +987,11 @@ configure_bridged_networks() { # Vars: $DEV -Network device to create the bridge on # $NUMBER -Number of the bridge being created/removed # $BRIDGE -Name of the bridge -# $PDEV -What to rename the interface attached to the bridge to # Set local function variables local DEV=$2 local NUMBER=$3 local BRIDGE=$BRIDGE_NAME$NUMBER - local PDEV="p$DEV" - - local BRIDGE_IFCFG_FILE="ifcfg-$BRIDGE" # Test if $BRIDGE is set if [ "$BRIDGE" = "null" ] @@ -1116,10 +1002,15 @@ configure_bridged_networks() { case $1 in start) # Test if $BRIDGE already exists - if [ -e "/sys/class/net/${BRIDGE}/bridge" ]; then + if [ -e "/sys/class/net/$BRIDGE/bridge" ] + then + # Skip this bridge + #------------------------------------------------------------------ + echo " $BRIDGE exists and is already configured." + echo " Skipping $BRIDGE" return fi - + if /sbin/ip link show $DEV | grep -qw UP then echo "" @@ -1131,8 +1022,8 @@ configure_bridged_networks() { echo "" # Create bridge - create_normal_bridge start $DEV $PDEV $BRIDGE - + create_normal_bridge start $DEV $BRIDGE + if [ "${antispoof}" = "yes" ] then antispoofing @@ -1140,7 +1031,7 @@ configure_bridged_networks() { # Write entry into networktab #--------------------------------------------------------------------- - echo "$BRIDGE,bridge,$NUMBER,$DEV,,,dhcp-off" >> $NETWORKTAB + echo "$BRIDGE,bridge,$NUMBER,$DEV,dhcp-off" >> $NETWORKTAB echo "" else echo " Physical Interface $DEV is not up. Skipping $BRIDGE" @@ -1163,7 +1054,7 @@ configure_bridged_networks() { echo "" # Remove bridge with normal network interface (i.e. ethX) - create_normal_bridge stop $DEV $PDEV $BRIDGE + create_normal_bridge stop $DEV $BRIDGE # Remove entry from networktab file #--------------------------------------------------------------------- @@ -1203,7 +1094,6 @@ configure_local_networks() { local BRIDGE=$ROUTE_NAME$NUMBER ;; esac - #local MAC=$5 local IPADDR=$5 local DHCP_SRV=$6 @@ -1229,7 +1119,7 @@ configure_local_networks() { #---- do start or stop -------------------------------------------- case $1 in start) - if ! brctl show | grep -qw $BRIDGE || /sbin/ip address show $BRIDGE > /dev/null + if ! [ -e "/sys/class/net/$BRIDGE/bridge" ] then # Create the network #------------------------------------------------------------------ @@ -1242,7 +1132,7 @@ configure_local_networks() { create_bridge $BRIDGE > /dev/null 2>&1 # Configure the bridge as a Dom0 network interface - configure_bridge_as_dom0_interface $BRIDGE $IPADDR $MAC > /dev/null 2>&1 + configure_bridge_as_dom0_interface $BRIDGE $IPADDR > /dev/null 2>&1 # Set up the bridge as a hostonly / NAT / Routed network case $TYPE in @@ -1306,14 +1196,6 @@ configure_local_networks() { ;; esac - # Write out new ifcfg file for the bridge - #--------------------------------------------------------------------- - echo "NAME='XEN Virtual Network - $BRIDGE'" > $IFCFG_FILE_DIR/ifcfg-$BRIDGE - grep -q "IPADDR=" $IFCFG_FILE_DIR/ifcfg-$BRIDGE || echo "IPADDR='$IP'" >> $IFCFG_FILE_DIR/ifcfg-$BRIDGE - grep -q "NETMASK=" $IFCFG_FILE_DIR/ifcfg-$BRIDGE || echo "NETMASK='$SNM'" >> $IFCFG_FILE_DIR/ifcfg-$BRIDGE - grep -q "BOOTPROTO=" $IFCFG_FILE_DIR/ifcfg-$BRIDGE || echo "BOOTPROTO='static'" >> $IFCFG_FILE_DIR/ifcfg-$BRIDGE - grep -q "STARTMODE=" $IFCFG_FILE_DIR/ifcfg-$BRIDGE || echo "STARTMODE='manual'" >> $IFCFG_FILE_DIR/ifcfg-$BRIDGE - # Configure DHCP for the network #--------------------------------------------------------------------- #if ! [ "$DHCP_SRV" = "dhcp-on" ] @@ -1329,13 +1211,13 @@ configure_local_networks() { # write entry into networktab #--------------------------------------------------------------------- - echo "$BRIDGE,$TYPE,$NUMBER,$DEV,,$IPADDR,$DHCP_SRV" >> $NETWORKTAB + echo "$BRIDGE,$TYPE,$NUMBER,$IPADDR,$DHCP_SRV" >> $NETWORKTAB echo "============================================================" else # Skip this bridge #------------------------------------------------------------------ - echo " Virtual Interface $BRIDGE exists and is already configured." + echo " $BRIDGE exists and is already configured." echo " Skipping $BRIDGE" fi ;; @@ -1409,16 +1291,12 @@ configure_local_networks() { echo "============================================================" # unconfigure the veth - configure_bridge_as_dom0_interface $DEV $IPADDR $MAC > /dev/null 2>&1 + configure_bridge_as_dom0_interface $DEV $IPADDR > /dev/null 2>&1 # Remove the bridge #echo "Removing $BRIDGE";read delete_bridge $BRIDGE - # Remove network ifcfg config file - #--------------------------------------------------------------------- - rm -f $IFCFG_FILE_DIR/ifcfg-$BRIDGE - # Remove entry from networktab file #--------------------------------------------------------------------- sed -i "/$BRIDGE/d" $NETWORKTAB @@ -1458,14 +1336,13 @@ configure_nohost_networks() { echo "" echo "============================================================" local DEV=$2 - local PDEV="p${DEV}" local MAC=`ip link show ${DEV} | grep 'link\/ether' | sed -e 's/.*ether \(..:..:..:..:..:..\).*/\1/'` local NUMBER=$3 local BRIDGE=${NOHOST_NAME}${NUMBER} case $1 in start) - if ! brctl show | grep -qw "^${BRIDGE}" + if ! [ -e "/sys/class/net/${BRIDGE}/bridge" ] then echo "" echo "============================================================" @@ -1480,28 +1357,24 @@ configure_nohost_networks() { #echo "Create the bridge. \(create_bridge ${BRIDGE}\)";read create_bridge ${BRIDGE} - # Rename physical and virtual interfaces - #echo "Rename ${DEV} to ${PDEV}";read - rename_interfaces ${DEV} ${PDEV} - - # Configure $PDEV as a bridge port - #echo "Configure ${PDEV} as a bridge port";read - setup_bridge_port ${PDEV} + # Configure $DEV as a bridge port + #echo "Configure ${DEV} as a bridge port";read + setup_bridge_port ${DEV} # Bring bridge up and add interfaces to it - #echo "Bring ${BRIDGE} up and add ${PDEV} to it";read + #echo "Bring ${BRIDGE} up and add ${DEV} to it";read ip link set ${BRIDGE} up - add_to_bridge2 ${BRIDGE} ${PDEV} - - # Write out new ifcfg file for the bridge - #--------------------------------------------------------------------- - #echo "NAME='XEN Virtual Network - $BRIDGE'" > $IFCFG_FILE_DIR/ifcfg-$BRIDGE - grep -q "STARTMODE=" $IFCFG_FILE_DIR/ifcfg-$BRIDGE || echo "STARTMODE='manual'" >> $IFCFG_FILE_DIR/ifcfg-$BRIDGE + #add_to_bridge2 ${BRIDGE} ${DEV} + add_to_bridge ${BRIDGE} ${DEV} # Write entry into networktab file #--------------------------------------------------------------------- - echo "${BRIDGE},nohost,${NUMBER},${DEV},,,," >> ${NETWORKTAB} - + echo "${BRIDGE},nohost,${NUMBER},${DEV},,," >> ${NETWORKTAB} + else + # Skip this bridge + #------------------------------------------------------------------ + echo " $BRIDGE exists and is already configured." + echo " Skipping $BRIDGE" fi ;; stop) @@ -1516,18 +1389,13 @@ configure_nohost_networks() { #--------------------------------------------------------------------- # Remove interface from bridge - #echo "Remove interface ${PDEV} from ${BRIDGE}";read - brctl delif ${BRIDGE} ${PDEV} + #echo "Remove interface ${DEV} from ${BRIDGE}";read + brctl delif ${BRIDGE} ${DEV} # Remove bridge ${BRIDGE} #echo "Remove the bridge";read delete_bridge ${BRIDGE} - # Rename physical and virtual network interfaces - #echo "Rename ${PDEV} to ${DEV}";read - #ip link set ${PDEV} name ${DEV} - rename_interfaces ${PDEV} ${DEV} - # Bring renamed physical interface up #echo "Bring up ${DEV}";read ifup ${DEV} > /dev/null 2>&1 @@ -1562,7 +1430,7 @@ configure_empty_networks() { case $1 in start) - if ! brctl show | grep -qw "^$BRIDGE" + if ! [ -e "/sys/class/net/${BRIDGE}/bridge" ] then echo "Configuring Virtual Network: $BRIDGE" echo " of type: empty" @@ -1573,15 +1441,14 @@ configure_empty_networks() { # create the bridge create_bridge $BRIDGE - # Write out new ifcfg file for the bridge - #--------------------------------------------------------------------- - #echo "NAME='XEN Virtual Network - $BRIDGE'" > $IFCFG_FILE_DIR/ifcfg-$BRIDGE - grep -q "STARTMODE=" $IFCFG_FILE_DIR/ifcfg-$BRIDGE || echo "STARTMODE='manual'" >> $IFCFG_FILE_DIR/ifcfg-$BRIDGE - # Write entry into networktab file #--------------------------------------------------------------------- - echo "$BRIDGE,empty,$NUMBER,,,,," >> $NETWORKTAB - + echo "$BRIDGE,empty,$NUMBER,,,," >> $NETWORKTAB + else + # Skip this bridge + #------------------------------------------------------------------ + echo " $BRIDGE exists and is already configured." + echo " Skipping $BRIDGE" fi ;; stop) @@ -1645,7 +1512,7 @@ remove_all_networks() { configure_bridged_networks stop $NET_DEV $NET_NUMBER ;; nat|hostonly|route) - configure_local_networks stop $NET_DEV $NET_TYPE $NET_NUMBER $NET_DEV_MAC $NET_DEV_IP $NET_DHCP_SRV + configure_local_networks stop $NET_DEV $NET_TYPE $NET_NUMBER $NET_DEV_IP $NET_DHCP_SRV ;; nohost) configure_nohost_networks stop $NET_DEV $NET_NUMBER @@ -1655,15 +1522,6 @@ remove_all_networks() { ;; esac done - - # Remove any remaining networks - #--------------------------------------------------------------------- - local LEFTOVER_NETS="`find /sys/class/net/ -name brif | cut -d '/' -f 5`" - - for NET in $LEFTOVER_NETS - do - delete_bridge $NET - done } #***** DHCP Functions ***************************************************** diff --git a/network-multinet b/network-multinet index 176a037..e801233 100644 --- a/network-multinet +++ b/network-multinet @@ -37,16 +37,16 @@ # -This type of network is similiar to a VMware "HOST ONLY" # network. # -# nat: -Networks that are connected to Dom0 and are private from the +# nat: -Networks that are connected to Dom0 and are privet from the # physical network but VMs can get out to the physical network # -This type of network will allow VMs connected to it to access -# Dom0, the "outside world" via NAT and other VMs connected to it. +# Dom0,the "outside world" via NAT and other VMs connected to it. # -This type of network is similiar to a VMware "NAT" network. # # routed: -Networks that are not directly connected to the physical network -# but who's traffic is directly routed to other networks +# but whi's traffic is directly routed to other networks # -This type of network will allow VMs connected to it to access -# Dom0, the "outside world" via routing through Dom0 and other VMs +# Dom0,the "outside world" via routing through Dom0 and other VMs # connected to it. # # empty: -Networks that are not connected to either Dom0 or the physical @@ -60,12 +60,13 @@ # This script requires that the vif-bridge script be used as the vif # creation script (as opposed to vif-nat/vif-route). # -# This script will verify that a requested physical interface is present and -# up before creating the network and connecting the physical interface to it. +# This script will test for the presence of the physical interfaces +# configured to be connected to bridged networks and only attempt to +# create networks on the ones that are present and up. # # Edit the NETWORK_LIST variable to define which networks to create on which # interfaces. The default is to create a bridged network on the first -# active network interface. +# interface active network interface. # # To enable this script edit the network-script field in the # /etc/xen/xend-config.sxp file. @@ -112,7 +113,7 @@ SCRIPT_PATH="/etc/xen/scripts" #### Script Functions ##################################################### usage() { -# Gives hlep about usage parameters +# Gives help about usage parameters echo "Usage: $0 {start|stop|restart|status}" exit 1 } @@ -129,6 +130,8 @@ get_option() { esac } +. $SCRIPT_PATH/multinet-common.sh + make_config_dirs() { # Create temporary storage directory if needed. if ! [ -d "$NETWORK_SAVE_PATH" ] @@ -138,16 +141,13 @@ make_config_dirs() { } -. $SCRIPT_PATH/multinet-common.sh - #***** Network Creation Main Function ************************************* create_networks() { - VIF_COUNT=0 - for NETWORK in $NETWORK_LIST do + local NET_TYPE=`echo $NETWORK | cut -d "," -f 1` local NET_NUMBER=`echo $NETWORK | cut -d "," -f 2` local NET_DEV=`echo $NETWORK | cut -d "," -f 3` @@ -204,7 +204,7 @@ run_prestart_scripts() { echo "Running pre-start scripts" echo test -d $PLUGIN_DIR/pre-start || mkdir -p $PLUGIN_DIR/pre-start - if ls $PLUGIN_DIR/pre-start/*.sh > /dev/null 2&>1 + if ls $PLUGIN_DIR/pre-start/*.sh > /dev/null 2>&1 then for SCRIPT in `ls $PLUGIN_DIR/pre-start/*.sh` do @@ -228,7 +228,7 @@ run_poststart_scripts() { echo "Running post-start scripts" echo test -d $PLUGIN_DIR/post-start || mkdir -p $PLUGIN_DIR/post-start - if ls $PLUGIN_DIR/post-start/*.sh > /dev/null 2&>1 + if ls $PLUGIN_DIR/post-start/*.sh > /dev/null 2>&1 then for SCRIPT in `ls $PLUGIN_DIR/post-start/*.sh` do @@ -253,7 +253,7 @@ run_prestop_scripts() { echo "Running pre-stop scripts" echo test -d $PLUGIN_DIR/pre-stop || mkdir -p $PLUGIN_DIR/pre-stop - if ls $PLUGIN_DIR/pre-stop/*.sh > /dev/null 2&>1 + if ls $PLUGIN_DIR/pre-stop/*.sh > /dev/null 2>&1 then for SCRIPT in `ls $PLUGIN_DIR/pre-stop/*.sh` do @@ -277,7 +277,7 @@ run_poststop_scripts() { echo "Running post-stop scripts" echo test -d $PLUGIN_DIR/post-stop || mkdir -p $PLUGIN_DIR/post-stop - if ls $PLUGIN_DIR/post-stop/*.sh > /dev/null 2&>1 + if ls $PLUGIN_DIR/post-stop/*.sh > /dev/null 2>&1 then for SCRIPT in `ls $PLUGIN_DIR/post-stop/*.sh` do diff --git a/ns_tools.patch b/ns_tools.patch new file mode 100644 index 0000000..314bc6f --- /dev/null +++ b/ns_tools.patch @@ -0,0 +1,96 @@ +Index: xen-3.2-testing/tools/python/xen/lowlevel/xc/xc.c +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/lowlevel/xc/xc.c ++++ xen-3.2-testing/tools/python/xen/lowlevel/xc/xc.c +@@ -632,14 +632,14 @@ static PyObject *pyxc_hvm_build(XcObject + int i; + #endif + char *image; +- int memsize, vcpus = 1, acpi = 0, apic = 1; ++ int memsize, vcpus = 1, acpi = 0, apic = 1, extid = 0; + + static char *kwd_list[] = { "domid", +- "memsize", "image", "vcpus", "acpi", ++ "memsize", "image", "vcpus", "extid", "acpi", + "apic", NULL }; +- if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iii", kwd_list, ++ if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iis|iiii", kwd_list, + &dom, &memsize, +- &image, &vcpus, &acpi, &apic) ) ++ &image, &vcpus, &extid, &acpi, &apic) ) + return NULL; + + if ( xc_hvm_build(self->xc_handle, dom, memsize, image) != 0 ) +@@ -664,6 +664,7 @@ static PyObject *pyxc_hvm_build(XcObject + va_hvm->checksum = -sum; + munmap(va_map, XC_PAGE_SIZE); + #endif ++ xc_set_hvm_param(self->xc_handle, dom, HVM_PARAM_EXTEND_HYPERVISOR, extid); + + return Py_BuildValue("{}"); + } +Index: xen-3.2-testing/tools/python/xen/xend/XendConfig.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/XendConfig.py ++++ xen-3.2-testing/tools/python/xen/xend/XendConfig.py +@@ -126,7 +126,7 @@ LEGACY_CFG_TO_XENAPI_CFG = reverse_dict( + # Platform configuration keys. + XENAPI_PLATFORM_CFG = [ 'acpi', 'apic', 'boot', 'device_model', 'display', + 'fda', 'fdb', 'keymap', 'isa', 'localtime', 'monitor', +- 'nographic', 'pae', 'rtc_timeoffset', 'serial', 'sdl', ++ 'nographic', 'pae', 'extid', 'rtc_timeoffset', 'serial', 'sdl', + 'soundhw','stdvga', 'usb', 'usbdevice', 'hpet', 'vnc', + 'vncconsole', 'vncdisplay', 'vnclisten', 'timer_mode', + 'vncpasswd', 'vncunused', 'xauthority', 'pci', 'vhpt', +Index: xen-3.2-testing/tools/python/xen/xend/image.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/image.py ++++ xen-3.2-testing/tools/python/xen/xend/image.py +@@ -432,6 +432,7 @@ class HVMImageHandler(ImageHandler): + + self.apic = int(vmConfig['platform'].get('apic', 0)) + self.acpi = int(vmConfig['platform'].get('acpi', 0)) ++ self.extid = int(vmConfig['platform'].get('extid', 0)) + self.guest_os_type = vmConfig['platform'].get('guest_os_type') + + # Return a list of cmd line args to the device models based on the +@@ -522,6 +523,7 @@ class HVMImageHandler(ImageHandler): + log.debug("store_evtchn = %d", store_evtchn) + log.debug("memsize = %d", mem_mb) + log.debug("vcpus = %d", self.vm.getVCpuCount()) ++ log.debug("extid = %d", self.extid) + log.debug("acpi = %d", self.acpi) + log.debug("apic = %d", self.apic) + +@@ -529,6 +531,7 @@ class HVMImageHandler(ImageHandler): + image = self.kernel, + memsize = mem_mb, + vcpus = self.vm.getVCpuCount(), ++ extid = self.extid, + acpi = self.acpi, + apic = self.apic) + rc['notes'] = { 'SUSPEND_CANCEL': 1 } +Index: xen-3.2-testing/tools/python/xen/xm/create.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xm/create.py ++++ xen-3.2-testing/tools/python/xen/xm/create.py +@@ -203,6 +203,10 @@ gopts.var('timer_mode', val='TIMER_MODE' + use="""Timer mode (0=delay virtual time when ticks are missed; + 1=virtual time is always wallclock time.""") + ++gopts.var('extid', val='EXTID', ++ fn=set_int, default=0, ++ use="Specify extention ID for a HVM domain.") ++ + gopts.var('acpi', val='ACPI', + fn=set_int, default=1, + use="Disable or enable ACPI of HVM domain.") +@@ -729,7 +733,7 @@ def configure_vifs(config_devs, vals): + def configure_hvm(config_image, vals): + """Create the config for HVM devices. + """ +- args = [ 'device_model', 'pae', 'vcpus', 'boot', 'fda', 'fdb', 'timer_mode', ++ args = [ 'device_model', 'pae', 'extid', 'vcpus', 'boot', 'fda', 'fdb', 'timer_mode', + 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'soundhw', + 'vnc', 'vncdisplay', 'vncunused', 'vncconsole', 'vnclisten', + 'sdl', 'display', 'xauthority', 'rtc_timeoffset', 'monitor', diff --git a/ns_xen_base.patch b/ns_xen_base.patch new file mode 100644 index 0000000..f30bcb7 --- /dev/null +++ b/ns_xen_base.patch @@ -0,0 +1,425 @@ +%patch +Index: xen-3.2-testing/xen/arch/x86/hvm/svm/svm.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/svm/svm.c ++++ xen-3.2-testing/xen/arch/x86/hvm/svm/svm.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + + u32 svm_feature_flags; + +@@ -73,6 +74,7 @@ static void *hsa[NR_CPUS] __read_mostly; + /* vmcb used for extended host state */ + static void *root_vmcb[NR_CPUS] __read_mostly; + ++ + static void inline __update_guest_eip( + struct cpu_user_regs *regs, unsigned int inst_len) + { +@@ -882,7 +884,7 @@ static struct hvm_function_table svm_fun + .set_tsc_offset = svm_set_tsc_offset, + .inject_exception = svm_inject_exception, + .init_hypercall_page = svm_init_hypercall_page, +- .event_pending = svm_event_pending ++ .event_pending = svm_event_pending, + }; + + int start_svm(struct cpuinfo_x86 *c) +@@ -1044,6 +1046,7 @@ static void svm_vmexit_do_cpuid(struct v + HVMTRACE_3D(CPUID, v, input, + ((uint64_t)eax << 32) | ebx, ((uint64_t)ecx << 32) | edx); + ++ ext_intercept_do_cpuid(input, regs); + inst_len = __get_instruction_length(v, INSTR_CPUID, NULL); + __update_guest_eip(regs, inst_len); + } +@@ -1739,6 +1742,11 @@ static void svm_do_msr_access( + /* is it a read? */ + if (vmcb->exitinfo1 == 0) + { ++ if (ext_intercept_do_msr_read(ecx, regs)) ++ { ++ goto done; ++ } ++ + switch (ecx) { + case MSR_IA32_TSC: + msr_content = hvm_get_guest_time(v); +@@ -1829,6 +1837,11 @@ static void svm_do_msr_access( + } + else + { ++ if (ext_intercept_do_msr_write(ecx, regs)) ++ { ++ goto done_1; ++ } ++ + msr_content = (u32)regs->eax | ((u64)regs->edx << 32); + + hvmtrace_msr_write(v, ecx, msr_content); +@@ -1889,6 +1902,7 @@ static void svm_do_msr_access( + } + break; + } ++done_1: + + inst_len = __get_instruction_length(v, INSTR_WRMSR, NULL); + } +Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/vmx.c ++++ xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +@@ -50,6 +50,7 @@ + #include + #include + #include ++#include + #include + + enum handler_return { HNDL_done, HNDL_unhandled, HNDL_exception_raised }; +@@ -65,6 +66,7 @@ static void vmx_install_vlapic_mapping(s + static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr); + static void vmx_update_guest_efer(struct vcpu *v); + ++ + static int vmx_domain_initialise(struct domain *d) + { + if ( vmx_alloc_vpid(d) == 0 ) +@@ -1362,7 +1364,8 @@ void vmx_cpuid_intercept( + unsigned int count = *ecx; + + #ifdef VMXASSIST +- if ( input == 0x40000003 ) ++ if (( input == 0x40000003 ) && ++ (vmx_guest_x86_mode(current) == 0)) + { + /* + * NB. Unsupported interface for private use of VMXASSIST only. +@@ -1443,12 +1446,13 @@ void vmx_cpuid_intercept( + + static void vmx_do_cpuid(struct cpu_user_regs *regs) + { +- unsigned int eax, ebx, ecx, edx; ++ unsigned int eax, ebx, ecx, edx, input; + + eax = regs->eax; + ebx = regs->ebx; + ecx = regs->ecx; + edx = regs->edx; ++ input = eax; + + vmx_cpuid_intercept(&eax, &ebx, &ecx, &edx); + +@@ -1456,6 +1460,7 @@ static void vmx_do_cpuid(struct cpu_user + regs->ebx = ebx; + regs->ecx = ecx; + regs->edx = edx; ++ ext_intercept_do_cpuid(input, regs); + } + + #define CASE_GET_REG_P(REG, reg) \ +@@ -2440,6 +2445,9 @@ static int vmx_do_msr_read(struct cpu_us + + HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x", ecx); + ++ if (ext_intercept_do_msr_read(ecx, regs)) ++ goto done; ++ + switch ( ecx ) + { + case MSR_IA32_TSC: +@@ -2662,6 +2670,9 @@ static int vmx_do_msr_write(struct cpu_u + HVM_DBG_LOG(DBG_LEVEL_1, "ecx=%x, eax=%x, edx=%x", + ecx, (u32)regs->eax, (u32)regs->edx); + ++ if (ext_intercept_do_msr_write(ecx, regs)) ++ return 1; ++ + msr_content = (u32)regs->eax | ((u64)regs->edx << 32); + + hvmtrace_msr_write(v, ecx, msr_content); +Index: xen-3.2-testing/xen/include/asm-x86/hvm/domain.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hvm/domain.h ++++ xen-3.2-testing/xen/include/asm-x86/hvm/domain.h +@@ -74,6 +74,10 @@ struct hvm_domain { + + /* Pass-through */ + struct hvm_iommu hvm_iommu; ++ /* Hvm extension handle */ ++ void *ext_handle; /* will be NULL on creation (memset)*/ ++ struct extension_intercept_vector *ext_vector; ++ + }; + + #endif /* __ASM_X86_HVM_DOMAIN_H__ */ +Index: xen-3.2-testing/xen/include/public/hvm/params.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/public/hvm/params.h ++++ xen-3.2-testing/xen/include/public/hvm/params.h +@@ -50,10 +50,12 @@ + + #define HVM_PARAM_BUFIOREQ_PFN 6 + ++#define HVM_PARAM_EXTEND_HYPERVISOR 7 ++ + #ifdef __ia64__ +-#define HVM_PARAM_NVRAM_FD 7 +-#define HVM_PARAM_VHPT_SIZE 8 +-#define HVM_PARAM_BUFPIOREQ_PFN 9 ++#define HVM_PARAM_NVRAM_FD 8 ++#define HVM_PARAM_VHPT_SIZE 9 ++#define HVM_PARAM_BUFPIOREQ_PFN 10 + #endif + + /* +@@ -75,7 +77,8 @@ + * Missed interrupts are collapsed together and delivered as one 'late tick'. + * Guest time always tracks wallclock (i.e., real) time. + */ +-#define HVM_PARAM_TIMER_MODE 10 ++//KYS Check the modifications done to this file ++#define HVM_PARAM_TIMER_MODE 11 + #define HVM_PARAM_IDENT_PT 12 + #define HVMPTM_delay_for_missed_ticks 0 + #define HVMPTM_no_delay_for_missed_ticks 1 +@@ -83,8 +86,8 @@ + #define HVMPTM_one_missed_tick_pending 3 + + /* Boolean: Enable virtual HPET (high-precision event timer)? (x86-only) */ +-#define HVM_PARAM_HPET_ENABLED 11 ++#define HVM_PARAM_HPET_ENABLED 12 + +-#define HVM_NR_PARAMS 13 ++#define HVM_NR_PARAMS 14 + + #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ +Index: xen-3.2-testing/xen/arch/x86/hvm/Makefile +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/Makefile ++++ xen-3.2-testing/xen/arch/x86/hvm/Makefile +@@ -1,5 +1,6 @@ + subdir-y += svm + subdir-y += vmx ++subdir-y += hvm_ext + + obj-y += hvm.o + obj-y += i8254.o +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/hvm.c ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -118,6 +119,7 @@ void hvm_migrate_timers(struct vcpu *v) + rtc_migrate_timers(v); + hpet_migrate_timers(v); + pt_migrate(v); ++ ext_intercept_do_migrate_timers(v); + } + + void hvm_do_resume(struct vcpu *v) +@@ -281,6 +283,7 @@ void hvm_domain_relinquish_resources(str + + void hvm_domain_destroy(struct domain *d) + { ++ ext_intercept_domain_destroy(d); + hvm_funcs.domain_destroy(d); + vioapic_deinit(d); + hvm_destroy_cacheattr_region_list(d); +@@ -449,8 +452,14 @@ int hvm_vcpu_initialise(struct vcpu *v) + { + int rc; + ++ if ((rc = ext_intercept_vcpu_initialize(v)) != 0) ++ goto fail1; ++ + if ( (rc = vlapic_init(v)) != 0 ) ++ { ++ ext_intercept_vcpu_destroy(v); + goto fail1; ++ } + + if ( (rc = hvm_funcs.vcpu_initialise(v)) != 0 ) + goto fail2; +@@ -498,12 +507,14 @@ int hvm_vcpu_initialise(struct vcpu *v) + hvm_funcs.vcpu_destroy(v); + fail2: + vlapic_destroy(v); ++ ext_intercept_vcpu_destroy(v); + fail1: + return rc; + } + + void hvm_vcpu_destroy(struct vcpu *v) + { ++ ext_intercept_vcpu_destroy(v); + vlapic_destroy(v); + hvm_funcs.vcpu_destroy(v); + +@@ -1575,6 +1586,10 @@ int hvm_do_hypercall(struct cpu_user_reg + case 0: + break; + } ++ if (ext_intercept_do_hypercall(regs)) ++ { ++ return HVM_HCALL_completed; ++ } + + if ( (eax >= NR_hypercalls) || !hvm_hypercall32_table[eax] ) + { +@@ -1729,6 +1744,7 @@ int hvm_bringup_ap(int vcpuid, int tramp + vcpu_wake(v); + + gdprintk(XENLOG_INFO, "AP %d bringup succeeded.\n", vcpuid); ++ ext_intercept_vcpu_up(v); + return 0; + } + +@@ -1966,6 +1982,9 @@ long do_hvm_op(unsigned long op, XEN_GUE + if ( a.value > HVMPTM_one_missed_tick_pending ) + goto param_fail; + break; ++ case HVM_PARAM_EXTEND_HYPERVISOR: ++ if (hvm_ext_bind(d, (int)a.value)) ++ goto param_fail; + } + d->arch.hvm_domain.params[a.index] = a.value; + rc = 0; +Index: xen-3.2-testing/xen/arch/x86/x86_64/asm-offsets.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/x86_64/asm-offsets.c ++++ xen-3.2-testing/xen/arch/x86/x86_64/asm-offsets.c +@@ -146,4 +146,7 @@ void __dummy__(void) + BLANK(); + + OFFSET(CPUINFO_ext_features, struct cpuinfo_x86, x86_capability[1]); ++ BLANK(); ++ ++ OFFSET(DOM_ext_vector, struct domain, arch.hvm_domain.ext_vector); + } +Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/x86_64/exits.S +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/x86_64/exits.S ++++ xen-3.2-testing/xen/arch/x86/hvm/vmx/x86_64/exits.S +@@ -112,6 +112,14 @@ vmx_process_softirqs: + ALIGN + ENTRY(vmx_asm_do_vmentry) + GET_CURRENT(%rbx) ++ mov VCPU_domain(%rbx),%rax ++ mov DOM_ext_vector(%rax),%rdx ++ test %rdx,%rdx ++ je vmx_no_ext_vector ++ sti ++ callq *(%rdx) ++vmx_no_ext_vector: ++ + cli # tests must not race interrupts + + movl VCPU_processor(%rbx),%eax +Index: xen-3.2-testing/xen/arch/x86/hvm/svm/x86_64/exits.S +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/svm/x86_64/exits.S ++++ xen-3.2-testing/xen/arch/x86/hvm/svm/x86_64/exits.S +@@ -37,6 +37,14 @@ + + ENTRY(svm_asm_do_resume) + GET_CURRENT(%rbx) ++ mov VCPU_domain(%rbx),%rax ++ mov DOM_ext_vector(%rax),%rdx ++ test %rdx,%rdx ++ je svm_no_ext_vector ++ sti ++ callq *(%rdx) ++svm_no_ext_vector: ++ + CLGI + + movl VCPU_processor(%rbx),%eax +Index: xen-3.2-testing/xen/arch/x86/hvm/save.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/save.c ++++ xen-3.2-testing/xen/arch/x86/hvm/save.c +@@ -23,6 +23,8 @@ + + #include + #include ++#include ++#include + + void arch_hvm_save(struct domain *d, struct hvm_save_header *hdr) + { +@@ -31,8 +33,7 @@ void arch_hvm_save(struct domain *d, str + /* Save some CPUID bits */ + cpuid(1, &eax, &ebx, &ecx, &edx); + hdr->cpuid = eax; +- +- hdr->pad0 = 0; ++ hdr->ext_id = d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR]; + } + + int arch_hvm_load(struct domain *d, struct hvm_save_header *hdr) +@@ -61,6 +62,9 @@ int arch_hvm_load(struct domain *d, stru + + /* VGA state is not saved/restored, so we nobble the cache. */ + d->arch.hvm_domain.stdvga.cache = 0; ++ d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR] = hdr->ext_id; ++ if (hvm_ext_bind(d, hdr->ext_id)) ++ return -1; + + return 0; + } +Index: xen-3.2-testing/xen/include/public/arch-x86/hvm/save.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/public/arch-x86/hvm/save.h ++++ xen-3.2-testing/xen/include/public/arch-x86/hvm/save.h +@@ -38,7 +38,7 @@ struct hvm_save_header { + uint32_t version; /* File format version */ + uint64_t changeset; /* Version of Xen that saved this file */ + uint32_t cpuid; /* CPUID[0x01][%eax] on the saving machine */ +- uint32_t pad0; ++ uint32_t ext_id; /* extension ID */ + }; + + DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header); +@@ -422,9 +422,30 @@ struct hvm_hw_mtrr { + + DECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr); + ++struct hvm_ns_veridian_dom { ++ uint64_t guestid_msr; ++ uint64_t hypercall_msr; ++ uint32_t long_mode; ++ uint32_t pad0; ++}; ++DECLARE_HVM_SAVE_TYPE(NS_VERIDIAN_DOM, 15, struct hvm_ns_veridian_dom); ++ ++struct hvm_ns_veridian_cpu { ++ uint64_t control_msr; ++ uint64_t version_msr; ++ uint64_t sief_msr; ++ uint64_t simp_msr; ++ uint64_t eom_msr; ++ uint64_t int_msr[16]; ++ struct { ++ uint64_t config; ++ uint64_t count; ++ } timers[4]; ++}; ++DECLARE_HVM_SAVE_TYPE(NS_VERIDIAN_CPU, 16, struct hvm_ns_veridian_cpu); + /* + * Largest type-code in use + */ +-#define HVM_SAVE_CODE_MAX 14 ++#define HVM_SAVE_CODE_MAX 16 + + #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */ diff --git a/ns_xen_extension.patch b/ns_xen_extension.patch new file mode 100644 index 0000000..c405fc2 --- /dev/null +++ b/ns_xen_extension.patch @@ -0,0 +1,4645 @@ +%patch +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/Makefile 2008-02-26 14:01:28.000000000 -0500 +@@ -0,0 +1,3 @@ ++subdir-y += novell ++ ++obj-y += hvm_ext.o +Index: xen-3.2-testing/xen/include/asm-x86/hvm/hvm_extensions.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/include/asm-x86/hvm/hvm_extensions.h 2008-02-26 18:57:43.000000000 -0500 +@@ -0,0 +1,252 @@ ++/**************************************************************************** ++ | ++ | Copyright (c) [2007, 2008] Novell, Inc. ++ | All Rights Reserved. ++ | ++ | This program is free software; you can redistribute it and/or ++ | modify it under the terms of version 2 of the GNU General Public License as ++ | published by the Free Software Foundation. ++ | ++ | This program is distributed in the hope that it will be useful, ++ | but WITHOUT ANY WARRANTY; without even the implied warranty of ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ | GNU General Public License for more details. ++ | ++ | You should have received a copy of the GNU General Public License ++ | along with this program; if not, contact Novell, Inc. ++ | ++ | To contact Novell about this file by physical or electronic mail, ++ | you may find current contact information at www.novell.com ++ | ++ |*************************************************************************** ++*/ ++ ++/* ++ * hvm_extensions.h ++ * This file implements a framework for extending the hypervisor ++ * functionality in a modular fashion. The framework is comprised of ++ * two components: A) A set of intercepts that will allow the extension ++ * module to implement its functionality by intercepting the corresponding ++ * code paths in Xen and B) A controlled runtime for the extension module. ++ * Initially the goal was to pacakage the extension module as a boot-time ++ * loadable module. This may not be the way we wend up packaging it. ++ * ++ * Engineering Contact: K. Y. Srinivasan ++ */ ++ ++#ifndef HVM_EXTENSION_H ++#define HVM_EXTENSION_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++ ++/* ++ * Hypervisor extension hooks. ++ */ ++typedef struct extension_intercept_vector { ++ /* Do not move the first field (do_continuation). Offset ++ * hardcoded in assembly files exits.S (VMX and SVM). ++ */ ++ void (*do_continuation)(void); ++ int (*domain_create)(struct domain *d); ++ void (*domain_destroy)(struct domain *d); ++ int (*vcpu_initialize)(struct vcpu *v); ++ void (*vcpu_destroy)(struct vcpu *v); ++ int (*do_cpuid)(uint32_t idx, struct cpu_user_regs *regs); ++ int (*do_msr_read)(uint32_t idx, struct cpu_user_regs *regs); ++ int (*do_msr_write)(uint32_t idx, struct cpu_user_regs *regs); ++ int (*do_hypercall)(struct cpu_user_regs *pregs); ++ void (*do_migrate_timers)(struct vcpu *v); ++ void (*vcpu_up)(struct vcpu *v); ++} extension_intercept_vector_t; ++ ++static inline int ++ext_intercept_domain_create(struct domain *d) ++{ ++ if (d->arch.hvm_domain.ext_vector) { ++ return(d->arch.hvm_domain.ext_vector->domain_create(d)); ++ } ++ return (0); ++} ++ ++static inline void ++ext_intercept_domain_destroy(struct domain *d) ++{ ++ if (d->arch.hvm_domain.ext_vector) { ++ d->arch.hvm_domain.ext_vector->domain_destroy(d); ++ } ++} ++ ++static inline int ++ext_intercept_vcpu_initialize(struct vcpu *v) ++{ ++ struct domain *d = v->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ return(d->arch.hvm_domain.ext_vector->vcpu_initialize(v)); ++ } ++ return (0); ++} ++ ++ ++static inline void ++ext_intercept_vcpu_up(struct vcpu *v) ++{ ++ struct domain *d = current->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ return(d->arch.hvm_domain. ++ ext_vector->vcpu_up(v)); ++ } ++} ++ ++static inline void ++ext_intercept_vcpu_destroy(struct vcpu *v) ++{ ++ struct domain *d = v->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ d->arch.hvm_domain.ext_vector->vcpu_destroy(v); ++ } ++} ++ ++static inline int ++ext_intercept_do_cpuid(uint32_t idx, struct cpu_user_regs *regs) ++{ ++ struct domain *d = current->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ return(d->arch.hvm_domain.ext_vector->do_cpuid( ++ idx, regs)); ++ } ++ return (0); ++} ++ ++static inline int ++ext_intercept_do_msr_read(uint32_t idx, struct cpu_user_regs *regs) ++{ ++ struct domain *d = current->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ return(d->arch.hvm_domain. ++ ext_vector->do_msr_read(idx, regs)); ++ } ++ return (0); ++} ++static inline int ++ext_intercept_do_msr_write(uint32_t idx, struct cpu_user_regs *regs) ++{ ++ struct domain *d = current->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ return(d->arch.hvm_domain. ++ ext_vector->do_msr_write(idx, regs)); ++ } ++ return (0); ++} ++ ++static inline int ++ext_intercept_do_hypercall(struct cpu_user_regs *regs) ++{ ++ struct domain *d = current->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ return(d->arch.hvm_domain. ++ ext_vector->do_hypercall(regs)); ++ } ++ return (0); ++} ++ ++static inline void ++ext_intercept_do_migrate_timers(struct vcpu *v) ++{ ++ struct domain *d = current->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ return(d->arch.hvm_domain. ++ ext_vector->do_migrate_timers(v)); ++ } ++} ++ ++static inline void ++ext_intercept_do_continuation(void) ++{ ++ struct domain *d = current->domain; ++ if (d->arch.hvm_domain.ext_vector) { ++ d->arch.hvm_domain. ++ ext_vector->do_continuation(); ++ } ++} ++ ++/* ++ * Base hypervisor support available to extension modules. ++ * We may choose to do away with this level of indirection! ++ * It may still be useful to have a controlled environment for the ++ * extension modules. ++ */ ++typedef struct xen_call_vector { ++ /* ++ * We may want to embed version/compiler info here to avoid mismatches ++ */ ++ struct hvm_function_table *hvmFuncTable; ++ struct hvm_mmio_handler *mmIoHandler; ++ void (*extPanic)(const char *s, ...); ++ void (*extPrintk)(const char *format, ...); ++ void (*extPostInterrupt)(struct vcpu *v, int vector, int type); ++ void (*extSetTimer)(struct timer *timer, s_time_t expires); ++ s_time_t (*extGetTimeSinceBoot)(void); ++ void * (*extGetVirtFromGmfn)(struct domain *d, unsigned long gmfn); ++ unsigned long (*extGetMfnFromGmfn)(struct domain *d, unsigned long gmfn); ++ unsigned long (*extGetMfnFromGva)(unsigned long va); ++ void (*extUnmapDomainPage)(void *p); ++ void *(*extAllocMem)(size_t size); ++ void (*extFreeMem)(void *ptr); ++ enum hvm_copy_result (*extCopyToGuestPhysical)(paddr_t paddr, void *buf, int size); ++ enum hvm_copy_result (*extCopyFromGuestPhysical)(void *buf, paddr_t paddr, int size); ++ void *(*extAllocDomHeapPage)(void); ++ void (*extFreeDomHeapPage)(void *); ++ void * (*extGetVirtFromPagePtr)(void *); ++ void (*extVcpuPause)(struct vcpu *v); ++ void (*extVcpuUnPause)(struct vcpu *v); ++ void (*extArchGetDomainInfoCtxt)(struct vcpu *v, ++ struct vcpu_guest_context *); ++ int (*extArchSetDomainInfoCtxt)(struct vcpu *v, ++ struct vcpu_guest_context *); ++ int (*extCpuIsIntel)(void ); ++ int (*extWrmsrHypervisorRegs)(uint32_t idx, uint32_t eax, ++ uint32_t edx); ++ void (*extKillTimer)(struct timer *timer); ++ void (*extMigrateTimer)(struct timer *timer, unsigned int new_cpu); ++} xen_call_vector_t; ++ ++#define MAX_EXTENSION_ID 1 ++ ++/* ++ * int hvm_ext_bind(struct domain *d, int ext_id) ++ * Bind the specified domain to the specified extension module. ++ * ++ * Calling/Exit State: ++ * None. ++ * ++ * Remarks: ++ * The goal is to support per-domain extension modules. Domain ++ * creating tools will have to specify the needed extension ++ * module ID. For now it is hard coded. ++ */ ++int hvm_ext_bind(struct domain *d, int ext_id); ++ ++/* ++ * int hvm_ext_register(int ext_id, ++ * struct extension_intercept_vector *ext_vector, ++ * struct xen_call_vector *xen_vector) ++ * Register the extension module with the hypervisor ++ * Calling/Exit State: ++ * None. ++ */ ++ ++int hvm_ext_register(int ext_id, struct extension_intercept_vector *ext_vector, ++ struct xen_call_vector *xen_vector); ++ ++ ++#endif +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/hvm_ext.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/hvm_ext.c 2008-02-26 14:01:28.000000000 -0500 +@@ -0,0 +1,350 @@ ++/**************************************************************************** ++ | ++ | Copyright (c) [2007, 2008] Novell, Inc. ++ | All Rights Reserved. ++ | ++ | This program is free software; you can redistribute it and/or ++ | modify it under the terms of version 2 of the GNU General Public License as ++ | published by the Free Software Foundation. ++ | ++ | This program is distributed in the hope that it will be useful, ++ | but WITHOUT ANY WARRANTY; without even the implied warranty of ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ | GNU General Public License for more details. ++ | ++ | You should have received a copy of the GNU General Public License ++ | along with this program; if not, contact Novell, Inc. ++ | ++ | To contact Novell about this file by physical or electronic mail, ++ | you may find current contact information at www.novell.com ++ | ++ |*************************************************************************** ++*/ ++ ++/* ++ * hvm_ext.c ++ * Glue code for implementing the extension module. ++ * ++ * Engineering Contact: K. Y. Srinivasan ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++struct extension_intercept_vector *intercept_vector; ++ ++/* ++ * static void ++ * hvm_ext_inject_interrupt(struct vcpu *v, int vector, int type) ++ * Inject the specified exception to the specified virtual cpu. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void ++hvm_ext_inject_interrupt(struct vcpu *v, int vector, int type) ++{ ++ struct vlapic *vlapic = vcpu_vlapic(v); ++ ++ /* ++ * XXXKYS: Check the trigger mode. ++ */ ++ if (vlapic_set_irq(vlapic, vector, 1)) { ++ vcpu_kick(v); ++ } ++} ++ ++/* ++ * static void ++ * hvm_ext_set_timer(struct timer *timer, s_time_t expires) ++ * Set a timeout. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void ++hvm_ext_set_timer(struct timer *timer, s_time_t expires) ++{ ++ set_timer(timer, expires); ++} ++ ++/* ++ * static void ++ * hvm_ext_kill_timer(struct timer *timer) ++ * Kill the specified timer. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void ++hvm_ext_kill_timer(struct timer *timer) ++{ ++ kill_timer(timer); ++} ++ ++/* ++ * static void ++ * hvm_ext_migrate_timer(struct timer *timer, unsigned int new_cpu) ++ * Migrate the timer to the new cpu. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void ++hvm_ext_migrate_timer(struct timer *timer, unsigned int new_cpu) ++{ ++ migrate_timer(timer, new_cpu); ++} ++ ++ ++/* ++ * static void * ++ * hvm_ext_get_virt_from_gmfn(struct domain *d, unsigned long gmfn) ++ * Given a guest frame number return a virtual address at which ++ * the specified page can be accessed in the hypervisor. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void * ++hvm_ext_get_virt_from_gmfn(struct domain *d, unsigned long gmfn) ++{ ++ unsigned long mfn = gmfn_to_mfn(d, gmfn); ++ if (mfn == INVALID_MFN) { ++ return (NULL); ++ } ++ return (map_domain_page_global(mfn)); ++} ++ ++/* ++ * static unsigned long ++ * hvm_ext_get_mfn_from_gmfn(struct domain *d, unsigned long gmfn) ++ * Get the machine frame number given the guest frame number. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static unsigned long ++hvm_ext_get_mfn_from_gmfn(struct domain *d, unsigned long gmfn) ++{ ++ return (gmfn_to_mfn(d, gmfn)); ++} ++ ++/* ++ * static unsigned long ++ * hvm_ext_get_mfn_from_gva(unsigned long va) ++ * Given the guest virtual address return the machine frame number backing the ++ * address. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static unsigned long ++hvm_ext_get_mfn_from_gva(unsigned long va) ++{ ++ uint32_t pfec = PFEC_page_present; ++ unsigned long gfn; ++ gfn = paging_gva_to_gfn(current, va, &pfec); ++ return (gmfn_to_mfn((current->domain), gfn)); ++} ++ ++/* ++ * static void * ++ * hvm_ext_alloc_mem(size_t size) ++ * Allocate specified bytes of memory. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void * ++hvm_ext_alloc_mem(size_t size) ++{ ++ return (xmalloc_bytes(size)); ++} ++ ++/* ++ * static void * ++ * hvm_ext_alloc_domheap_page(void) ++ * Allocate a page from the per-domain heap. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void * ++hvm_ext_alloc_domheap_page(void) ++{ ++ return (alloc_domheap_page(NULL)); ++} ++ ++/* ++ * static void ++ * hvm_ext_free_domheap_page(void *p) ++ * Free a dom heap page. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void ++hvm_ext_free_domheap_page(void *p) ++{ ++ free_domheap_pages(p, 0); ++} ++ ++/* ++ * static void * ++ * hvm_ext_get_virt_from_page_ptr(void *page) ++ * Map the specified page a return a hypervisor VA. ++ * ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void * ++hvm_ext_get_virt_from_page_ptr(void *page) ++{ ++ struct page_info *pg = page; ++ unsigned long mfn = page_to_mfn(pg); ++ return (map_domain_page_global(mfn)); ++} ++ ++extern struct cpuinfo_x86 boot_cpu_data; ++ ++/* ++ * static int ++ * hvm_ext_cpu_is_intel(void) ++ * Check if the CPU vendor is Intel. ++ * ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static int ++hvm_ext_cpu_is_intel(void) ++{ ++ if (boot_cpu_data.x86_vendor == 0) { ++ return (1); ++ } ++ return (0); ++} ++ ++/* ++ * int ++ * hvm_ext_bind(struct domain *d, int ext_id) ++ * Bind the specified domain with the specified extension module. ++ * ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++int ++hvm_ext_bind(struct domain *d, int ext_id) ++{ ++ int i; ++ /* ++ * XXXKYS: Assuming that this function will be called before the ++ * new domain begins to run. It is critical that this be the case. ++ */ ++ if (ext_id == 0) { ++ /* ++ * This is the default value for this parameter. ++ */ ++ return (0); ++ } ++ d->arch.hvm_domain.ext_vector = intercept_vector; ++ /* ++ * Let the extension initialize its state. ++ */ ++ if (intercept_vector->domain_create(d)) { ++ return (1); ++ } ++ for (i=0; i < MAX_VIRT_CPUS; i++) { ++ if (d->vcpu[i] != NULL) { ++ if (intercept_vector->vcpu_initialize(d->vcpu[i])) { ++ int j; ++ for (j= (i-1); j >=0; j--) { ++ intercept_vector->vcpu_destroy( ++ d->vcpu[j]); ++ } ++ intercept_vector->domain_destroy(d); ++ return (1); ++ } ++ } ++ } ++ return (0); ++} ++ ++ ++void extPanic(const char *fmt, ...) ++{ ++ domain_crash_synchronous(); ++} ++ ++/* ++ * For now we will support only one extension; id==1! ++ */ ++ ++extern struct hvm_function_table hvm_funcs; ++extern struct hvm_mmio_handler vlapic_mmio_handler; ++ ++/* ++ * int ++ * hvm_ext_register(int ext_id, struct extension_intercept_vector *ext_vector, ++ * ++ * Register the invoking extension module with the hypervisor. ++ * ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++int ++hvm_ext_register(int ext_id, struct extension_intercept_vector *ext_vector, ++ struct xen_call_vector *xen_vector) ++{ ++ ASSERT(ext_id == 1); ++ intercept_vector = ext_vector; ++ /* ++ * Populate the vector of services from the xen side; ultimately ++ * we may decide to get rid of this level of indirection; it may ++ * still be useful to limit the breadth of xen dependency here. ++ */ ++ xen_vector->hvmFuncTable = &hvm_funcs; ++ xen_vector->mmIoHandler = &vlapic_mmio_handler; ++ xen_vector->extPanic = extPanic; ++ xen_vector->extPrintk = printk; ++ xen_vector->extPostInterrupt = hvm_ext_inject_interrupt; ++ xen_vector->extSetTimer = hvm_ext_set_timer; ++ xen_vector->extKillTimer = hvm_ext_kill_timer; ++ xen_vector->extMigrateTimer = hvm_ext_migrate_timer; ++ xen_vector->extGetTimeSinceBoot = get_s_time; ++ xen_vector->extGetVirtFromGmfn = hvm_ext_get_virt_from_gmfn; ++ xen_vector->extGetMfnFromGmfn = hvm_ext_get_mfn_from_gmfn; ++ ++ xen_vector->extGetMfnFromGva = hvm_ext_get_mfn_from_gva; ++#ifdef CONFIG_DOMAIN_PAGE ++ xen_vector->extUnmapDomainPage = unmap_domain_page_global; ++#endif ++ xen_vector->extAllocMem = hvm_ext_alloc_mem; ++ xen_vector->extFreeMem = xfree; ++ xen_vector->extCopyToGuestPhysical = hvm_copy_to_guest_phys; ++ xen_vector->extCopyFromGuestPhysical = hvm_copy_from_guest_phys; ++ xen_vector->extAllocDomHeapPage = hvm_ext_alloc_domheap_page; ++ xen_vector->extFreeDomHeapPage = hvm_ext_free_domheap_page; ++ xen_vector->extGetVirtFromPagePtr = hvm_ext_get_virt_from_page_ptr; ++ xen_vector->extVcpuPause = vcpu_pause; ++ xen_vector->extVcpuUnPause = vcpu_unpause; ++ xen_vector->extArchGetDomainInfoCtxt = arch_get_info_guest; ++ xen_vector->extArchSetDomainInfoCtxt = arch_set_info_guest; ++ xen_vector->extCpuIsIntel = hvm_ext_cpu_is_intel; ++ xen_vector->extWrmsrHypervisorRegs = wrmsr_hypervisor_regs; ++ ++ return 0; ++} +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/Makefile +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/Makefile 2008-02-26 14:01:28.000000000 -0500 +@@ -0,0 +1,2 @@ ++obj-y += nsintercept.o ++obj-y += nshypercall.o +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/ns_errno.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/ns_errno.h 2008-02-26 14:01:28.000000000 -0500 +@@ -0,0 +1,62 @@ ++/**************************************************************************** ++ | ++ | Copyright (c) [2007, 2008] Novell, Inc. ++ | All Rights Reserved. ++ | ++ | This program is free software; you can redistribute it and/or ++ | modify it under the terms of version 2 of the GNU General Public License as ++ | published by the Free Software Foundation. ++ | ++ | This program is distributed in the hope that it will be useful, ++ | but WITHOUT ANY WARRANTY; without even the implied warranty of ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ | GNU General Public License for more details. ++ | ++ | You should have received a copy of the GNU General Public License ++ | along with this program; if not, contact Novell, Inc. ++ | ++ | To contact Novell about this file by physical or electronic mail, ++ | you may find current contact information at www.novell.com ++ | ++ |*************************************************************************** ++*/ ++ ++/* ++ * ns_errno.h ++ * Error codes for the Novell Shim. ++ * ++ * Engineering Contact: K. Y. Srinivasan ++ */ ++ ++#ifndef NS_ERRNO_H ++#define NS_ERRNO_H ++ ++#define NS_STATUS_SUCCESS 0x0000 ++#define NS_STATUS_INVALID_HYPERCALL_CODE 0x0002 ++#define NS_STATUS_INVALID_HYPERCALL_INPUT 0x0003 ++#define NS_STATUS_INVALID_ALIGNMENT 0x0004 ++#define NS_STATUS_INVALID_PARAMETER 0x0005 ++#define NS_STATUS_ACCESS_DENIED 0x0006 ++#define NS_STATUS_INVALID_PARTITION_STATE 0x0007 ++#define NS_STATUS_OPERATION_DENIED 0x0008 ++#define NS_STATUS_UNKNOWN_PROPERTY 0x0009 ++#define NS_STATUS_PROPERTY_VALUE_OUT_OF_RANGE 0x000A ++#define NS_STATUS_INSUFFICIENT_MEMORY 0x000B ++#define NS_STATUS_PARTITION_TOO_DEEP 0x000C ++#define NS_STATUS_INVALID_PARTITION_ID 0x000D ++#define NS_STATUS_INVALID_VP_INDEX 0x000E ++#define NS_STATUS_UNABLE_TO_RESTORE_STATE 0x000F ++#define NS_STATUS_NOT_FOUND 0x0010 ++#define NS_STATUS_INVALID_PORT_ID 0x0011 ++#define NS_STATUS_INVALID_CONNECTION_ID 0x0012 ++#define NS_STATUS_INSUFFICIENT_BUFFERS 0x0013 ++#define NS_STATUS_NOT_ACKNOWLEDGED 0x0014 ++#define NS_STATUS_INVALID_VP_STATE 0x0015 ++#define NS_STATUS_ACKNOWLEDGED 0x0016 ++#define NS_STATUS_INVALID_SAVE_RESTORE_STATE 0x0017 ++#define NS_STATUS_NO_MEMORY_4PAGES 0x0100 ++#define NS_STATUS_NO_MEMORY_16PAGES 0x0101 ++#define NS_STATUS_NO_MEMORY_64PAGES 0x0102 ++#define NS_STATUS_NO_MEMORY_256PAGES 0x0103 ++#define NS_STATUS_NO_MEMORY_1024PAGES 0x0104 ++#endif +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/ns_shim.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/ns_shim.h 2008-02-26 14:01:28.000000000 -0500 +@@ -0,0 +1,480 @@ ++/**************************************************************************** ++ | ++ | Copyright (c) [2007, 2008] Novell, Inc. ++ | All Rights Reserved. ++ | ++ | This program is free software; you can redistribute it and/or ++ | modify it under the terms of version 2 of the GNU General Public License as ++ | published by the Free Software Foundation. ++ | ++ | This program is distributed in the hope that it will be useful, ++ | but WITHOUT ANY WARRANTY; without even the implied warranty of ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ | GNU General Public License for more details. ++ | ++ | You should have received a copy of the GNU General Public License ++ | along with this program; if not, contact Novell, Inc. ++ | ++ | To contact Novell about this file by physical or electronic mail, ++ | you may find current contact information at www.novell.com ++ | ++ |*************************************************************************** ++*/ ++ ++/* ++ * Novell Shim Implementation. ++ * ++ * Engineering Contact: K. Y. Srinivasan ++ */ ++ ++#ifndef NS_SHIM_H ++#define NS_SHIM_H ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "nshypercall.h" ++ ++/* ++ * Synthetic MSR addresses ++ */ ++#define NS_MSR_GUEST_OS_ID 0x40000000 ++#define NS_MSR_HYPERCALL 0x40000001 ++#define NS_MSR_VP_INDEX 0x40000002 ++#define NS_MSR_SYSTEM_RESET 0x40000003 ++#define NS_MSR_TIME_REF_COUNT 0x40000020 ++#define NS_MSR_EOI 0x40000070 ++#define NS_MSR_ICR 0x40000071 ++#define NS_MSR_TPR 0x40000072 ++ ++#define NS_MSR_SCONTROL 0x40000080 ++#define NS_MSR_SVERSION 0x40000081 ++#define NS_MSR_SIEFP 0x40000082 ++#define NS_MSR_SIMP 0x40000083 ++#define NS_MSR_SEOM 0x40000084 ++#define NS_MSR_SINT0 0x40000090 ++#define NS_MSR_SINT1 0x40000091 ++#define NS_MSR_SINT2 0x40000092 ++#define NS_MSR_SINT3 0x40000093 ++#define NS_MSR_SINT4 0x40000094 ++#define NS_MSR_SINT5 0x40000095 ++#define NS_MSR_SINT6 0x40000096 ++#define NS_MSR_SINT7 0x40000097 ++#define NS_MSR_SINT8 0x40000098 ++#define NS_MSR_SINT9 0x40000099 ++#define NS_MSR_SINT10 0x4000009A ++#define NS_MSR_SINT11 0x4000009B ++#define NS_MSR_SINT12 0x4000009C ++#define NS_MSR_SINT13 0x4000009D ++#define NS_MSR_SINT14 0x4000009E ++#define NS_MSR_SINT15 0x4000009F ++ ++#define NS_MSR_TIMER0_CONFIG 0x400000B0 ++#define NS_MSR_TIMER0_COUNT 0x400000B1 ++#define NS_MSR_TIMER1_CONFIG 0x400000B2 ++#define NS_MSR_TIMER1_COUNT 0x400000B3 ++#define NS_MSR_TIMER2_CONFIG 0x400000B4 ++#define NS_MSR_TIMER2_COUNT 0x400000B5 ++#define NS_MSR_TIMER3_CONFIG 0x400000B6 ++#define NS_MSR_TIMER3_COUNT 0x400000B7 ++ ++/* ++ * MSR for supporting PV drivers on longhorn. ++ */ ++#define NS_MSR_PVDRV_HCALL 0x40001000 ++ ++/* ++ * MSR for supporting other enlightened oses. ++ */ ++#define NS_MSR_NONLH_GUEST_OS_ID 0x40001000 ++ ++/* ++ * Novell Shim VCPU flags. ++ * A VCPU is considered up when it is capable of invoking hypercalls. ++ */ ++#define NS_VCPU_BOOT_CPU 0x00000001 ++#define NS_VCPU_UP 0x00000002 ++ ++/* ++ * Novell shim flush flags. ++ */ ++ ++#define NS_FLUSH_TLB 0X01 ++#define NS_FLUSH_INVLPG 0X02 ++ ++/* ++ * We use the following global state to manage TLB flush requests from the ++ * guest. At most only one flush can be active in the guest; we may have to ++ * revisit this if this is a bottleneck. ++ */ ++typedef struct nsGlobalFlushState { ++ int cpuCount; //0 unused; else #cpus participating ++ cpumask_t waiters; //Cpus waiting for the flush block ++ struct vcpu *currentOwner; ++ u64 retVal; ++ flushVa_t *flushParam; ++ unsigned short repCount; ++} nsGlobalFlushState_t; ++ ++typedef struct nsSpinLock { ++ unsigned long flags; ++ spinlock_t spinLock; ++ struct nsVcpu *owner; ++ void *retAddr; ++} nsSpinLock_t; ++ ++/* ++ * Novell shim message structure. ++ */ ++typedef enum { ++ /* ++ * For now we only support timer messages ++ */ ++ nsMessageTypeNone = 0x00000000, ++ nsMessageTimerExpired = 0x80000010 ++} nsMessageType; ++ ++typedef struct nsTimerMessage { ++ nsMessageType messageType; ++ u8 pad1[3]; ++ u8 messageSize; ++ u32 timerIndex; ++ u32 pad2; ++ u64 expirationTime; ++} nsTimerMessage_t; ++ ++typedef struct nsMessage { ++ nsMessageType messageType; ++ uint8_t messageSize; ++ uint8_t flags; ++ uint8_t reserved[2]; ++ uint32_t reserved1; ++ uint64_t payLoad[30]; ++} nsMessage_t; ++ ++ ++typedef struct nsVcpTimerState { ++ u64 config; ++ u64 count; /*expiration time in 100ns units*/ ++ int timerIndex; ++ struct nsVcpu *thisCpu; ++ struct timer vcpuTimer; ++} nsVcpTimerState_t; ++ ++/* ++ * Stats structure. ++ */ ++ ++typedef struct { ++ u64 numSwitches; ++ u64 numFlushes; ++ u64 numFlushesPosted; ++ u64 numFlushRanges; ++ u64 numFlushRangesPosted; ++ ++ u64 numTprReads; ++ u64 numIcrReads; ++ u64 numEoiWrites; ++ u64 numTprWrites; ++ u64 numIcrWrites; ++ ++ u64 numGFSAcquires; ++ u64 numGFSReleases; ++ u64 numTlbFlushes; ++ u64 numInvlPages; ++ u64 numTimeOuts; ++} nsVcpuStats_t; ++ ++typedef struct nsVcpu { ++ /* ++ * Per-vcpu state to support the Novell shim; ++ */ ++ int nsVcplockDepth; ++ unsigned long nsVcpuFlags; ++ unsigned char nsVcpFlushRequest; ++ unsigned char nsVcpWaitingOnGFS; ++ unsigned char nsVcpFlushPending; ++ unsigned char nsVcpWaitingForCleanup; ++ unsigned short nsVcpRepCount; ++ /* ++ * Synthetic msrs. ++ */ ++ u64 nsVcpSControlMsr; ++ u64 nsVcpSVersionMsr; ++ u64 nsVcpSIefpMsr; ++ u64 nsVcpSimpMsr; ++ u64 nsVcpEomMsr; ++ ++ u64 nsVcpSIntMsr[16]; ++ /* ++ * Timer MSRs. ++ */ ++ nsVcpTimerState_t nsVcpTimers[4]; ++ void *nsVcpSiefPage; ++ void *nsVcpSimPage; ++ /* ++ * Hypercall input/output processing. ++ * We keep these pages mapped in the hypervisor space. ++ */ ++ void *nsVcpInputBuffer; /*input buffer virt address*/ ++ void *nsVcpInputBufferPage; /*input buffer struct page */ ++ void *nsVcpOutputBuffer; /*output buffer virt address*/ ++ void *nsVcpOutputBufferPage; /*output buffer struct page */ ++ struct vcpu *nsVcpXenVcpu; /*corresponding xen vcpu*/ ++ nsVcpuStats_t nsVcpStats; ++} nsVcpu_t; ++ ++/* ++ * Events of interest for gathering stats. ++ */ ++#define NS_CSWITCH 1 ++#define NS_FLUSH_VA_STAT 2 ++#define NS_FLUSH_RANGE 3 ++#define NS_FLUSH_VA_POSTED 4 ++#define NS_FLUSH_RANGE_POSTED 5 ++#define NS_TPR_READ 6 ++#define NS_ICR_READ 7 ++#define NS_TPR_WRITE 8 ++#define NS_ICR_WRITE 9 ++#define NS_EOI_WRITE 10 ++ ++#define NS_GFS_ACQUIRE 11 ++#define NS_GFS_RELEASE 12 ++#define NS_TLB_FLUSH 13 ++#define NS_INVL_PG 14 ++#define NS_TIMEOUTS 15 ++ ++void nsCollectStats(int event, nsVcpuStats_t *ststp); ++ ++#define NS_STATS //KYS: Temporary ++ ++#ifdef NS_STATS ++#define NS_STATS_COLLECT(event, statp) nsCollectStats(event, statp) ++#else ++define NS_STATS_COLLECT(event, statp) ++#endif ++ ++typedef struct nsPartition { ++ /* ++ * State maintained on a per guest basis to implement ++ * the Novell shim. ++ */ ++ nsSpinLock_t nsLock; ++ atomic_t nsNumVcpusActive; ++ u64 nsGuestIdMsr; ++ u64 nsHypercallMsr; ++ u64 nsPrivileges; ++ u64 nsSupportedFeatures; ++ unsigned long nsHypercallMfn; ++ int nsLongModeGuest; ++ /* ++ * Each VCPU here corresponds to the vcpu in the underlying hypervisor; ++ * they share the same ID. ++ */ ++ nsVcpu_t nsVcpuState[MAX_VIRT_CPUS]; ++ nsGlobalFlushState_t nsFlushState; ++} nsPartition_t; ++ ++/* ++ * Max CPUID leaves supported. ++ */ ++ ++#define NX_MAX_CPUID_LEAVES 5 ++ ++/* ++ * We don't want to intercept instructions coming from the hvm bootstrap code. ++ * ++ */ ++#define NS_BIOS_HIGH_ADDR ++/* ++ * Privilege flags. ++ */ ++ ++#define NS_ACCESS_VP_RUNTIME (1ULL << 0) ++#define NS_ACCESS_TIME_REF_CNT (1ULL << 1) ++#define NS_ACCESS_SYNC_MSRS (1ULL << 2) ++#define NS_ACCESS_SYNC_TIMERS (1ULL << 3) ++#define NS_ACCESS_APIC_MSRS (1ULL << 4) ++#define NS_ACCESS_PARTITION_ID (1ULL << 33) ++ ++#define nsGetCurrentPartition() \ ++((current)->domain->arch.hvm_domain.ext_handle) ++ ++#define nsGetCurrentVcpuIndex() (current)->vcpu_id ++ ++#define NS_PANIC(x) \ ++do {\ ++ nsXenVector.extPrintk("File is: %s\n", __FILE__);\ ++ nsXenVector.extPrintk("Line is: %d\n", __LINE__);\ ++ nsXenVector.extPanic((x));\ ++} while (0); ++ ++#define NS_ASSERT(x) \ ++do {\ ++ if (!(x)) \ ++ NS_PANIC("ASSERTION FAILED\n")\ ++} while (0); ++ ++#define nsDebugPrint(x) \ ++do { \ ++ nsXenVector.extPrintk("File is: %s\n", __FILE__);\ ++ nsXenVector.extPrintk("Line is: %d\n", __LINE__);\ ++ nsXenVector.extPrintk((x));\ ++} while (0); ++ ++/* Hooks into Xen */ ++extern xen_call_vector_t nsXenVector; ++ ++/* ++ * static inline int ++ * nsInvalidCpuState(void) ++ * Check to see if the calling CPU is in the "correct state" to invoke ++ * the functionality implemented in the Novell Shim (Adaptor). ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline int ++nsInvalidCpuState(void) ++{ ++ int cpuState; ++ cpuState = nsXenVector.hvmFuncTable->guest_x86_mode(current); ++ if ((cpuState == 4) || (cpuState == 8)) { ++ return (0); ++ } ++ return (1); ++} ++ ++/* ++ * inline u64 ++ * nsBuildHcallRetVal(int code, int reps) ++ * ++ * Given the return code and the number of successfully completed count, ++ * compose a return value compliant with the Viridian specification. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline u64 ++nsBuildHcallRetVal(int code, int reps) ++{ ++ u64 retVal=0; ++ retVal |= (code & 0xff); ++ retVal |= (((long long)(reps & 0xfff)) << 32); ++ return (retVal); ++} ++ ++ ++/* ++ * static inline void nsSetSysCallRetVal(struct cpu_user_regs *pregs, ++ * int longModeGuest, u64 retVal) ++ * Set the return value in the saved guest registers ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline void nsSetSysCallRetVal(struct cpu_user_regs *pregs, ++ int longModeGuest, u64 retVal) ++{ ++ if (longModeGuest) { ++ pregs->eax = retVal; ++ } else { ++ pregs->edx = (u32)(retVal >> 32); ++ pregs->eax = (u32)(retVal); ++ } ++} ++ ++/* ++ * static inline int ++ * nsPrivilegeCheck(nsPartition_t *curp, u64 flags) ++ * Check if the caller is privileged to perform the operation ++ * specified by the flags argument. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline int ++nsPrivilegeCheck(nsPartition_t *curp, u64 flags) ++{ ++ return ((curp->nsPrivileges & flags)? 1: 0); ++} ++ ++/* void ++ * nsHandleHyperCall(u64 opcode, u64 input, u64 output, ++ * u64 *retVal); ++ * Common entry point for handling all the extension hypercalls. ++ * ++ * Calling/Exit State: ++ * Based on the hypercall; the caller may give up the CPU while ++ * processing the hypercall. No locks should be held on entry and ++ * no locks will be held on return. ++ * ++ */ ++void ++nsHandleHyperCall(u64 opcode, u64 input, u64 output, ++ u64 *retVal); ++ ++/* ++ * void nsDoTlbFlush(void); ++ * Perform TLB flush on the invoking virtual CPU. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++void nsDoTlbFlush(void); ++ ++/* ++ * void ++ * nsLockAcquire(nsVcpu_t *vcpup, nsSpinLock_t *nsLock) ++ * Acquire the specified lock. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++void nsLockAcquire(nsVcpu_t *vcpup, nsSpinLock_t *lock); ++ ++/* ++ * void ++ * nsLockRelease(nsVcpu_t *vcpup, nsSpinLock_t *nsLock) ++ * Release the specified spin lock. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++void nsLockRelease(nsVcpu_t *vcpup, nsSpinLock_t *lock); ++ ++/* ++ * void ++ * nsLockInit(nsSpinLock_t *nsLock) ++ * Initialize the specified spin lock. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++void nsLockInit(nsSpinLock_t *lock); ++ ++/* ++ * void nsPrintStats(nsPartition_t *curp, int i) ++ * Print the per-vcpu stats for the specified partition. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++void nsPrintStats(nsPartition_t *curp, int i); ++ ++#define NS_LOCK_OWNED(v, l) \ ++((l)->owner == (v)) ++#endif /*NS_SHIM_H */ +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/nshypercall.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/nshypercall.c 2008-02-28 13:17:22.000000000 -0500 +@@ -0,0 +1,1232 @@ ++/**************************************************************************** ++ | ++ | Copyright (c) [2007, 2008] Novell, Inc. ++ | All Rights Reserved. ++ | ++ | This program is free software; you can redistribute it and/or ++ | modify it under the terms of version 2 of the GNU General Public License as ++ | published by the Free Software Foundation. ++ | ++ | This program is distributed in the hope that it will be useful, ++ | but WITHOUT ANY WARRANTY; without even the implied warranty of ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ | GNU General Public License for more details. ++ | ++ | You should have received a copy of the GNU General Public License ++ | along with this program; if not, contact Novell, Inc. ++ | ++ | To contact Novell about this file by physical or electronic mail, ++ | you may find current contact information at www.novell.com ++ | ++ |*************************************************************************** ++*/ ++ ++/* ++ * nshypercall.c. ++ * This file implements the hypercall component of the Novell Shim. Hopefully ++ * we can host this component either as a driver in the guest or an extension ++ * to the Xen hypervisor. ++ * ++ * Engineering Contact: K. Y. Srinivasan ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include "ns_shim.h" ++#include "ns_errno.h" ++#include "nshypercall.h" ++ ++ ++ ++void nsDoTlbFlush(void); ++static void ++nsFlushPostProcess(nsPartition_t *curp, nsVcpu_t *curVcpup); ++ ++ ++ ++/* ++ * void nsCollectStats(int event, nsVcpuStats_t *statsp) ++ * Collect stats. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++void nsCollectStats(int event, nsVcpuStats_t *statsp) ++{ ++ switch (event) { ++ case NS_CSWITCH: ++ statsp->numSwitches++; ++ return; ++ case NS_FLUSH_VA: ++ statsp->numFlushes++; ++ return; ++ case NS_FLUSH_RANGE: ++ statsp->numFlushRanges++; ++ return; ++ case NS_FLUSH_VA_POSTED: ++ statsp->numFlushesPosted++; ++ return; ++ case NS_FLUSH_RANGE_POSTED: ++ statsp->numFlushRangesPosted++; ++ return; ++ case NS_TPR_READ: ++ statsp->numTprReads++; ++ return; ++ case NS_ICR_READ: ++ statsp->numIcrReads++; ++ return; ++ case NS_TPR_WRITE: ++ statsp->numTprWrites++; ++ return; ++ case NS_ICR_WRITE: ++ statsp->numIcrWrites++; ++ return; ++ case NS_EOI_WRITE: ++ statsp->numEoiWrites++; ++ return; ++ ++ case NS_GFS_ACQUIRE: ++ statsp->numGFSAcquires++; ++ return; ++ case NS_GFS_RELEASE: ++ statsp->numGFSReleases++; ++ return; ++ case NS_TLB_FLUSH: ++ statsp->numTlbFlushes++; ++ return; ++ case NS_INVL_PG: ++ statsp->numInvlPages++; ++ return; ++ } ++} ++ ++/* ++ * void ++ * nsPrintStats(nsPartition_t *curp, int i) ++ * Print stats. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++void ++nsPrintStats(nsPartition_t *curp, int i) ++{ ++ nsVcpu_t *v; ++ v = &curp->nsVcpuState[i]; ++ printk("Printing stats for vcpu ID: %d\n", i); ++ printk("Flush pending: %d\n", (int)v->nsVcpFlushPending); ++ printk("Flush Request: %d\n", (int)v->nsVcpFlushRequest); ++ printk("Waiting on GFS: %d\n", (int)v->nsVcpWaitingOnGFS); ++ printk("Waiting for cleanup: %d\n", (int)v->nsVcpWaitingForCleanup); ++ ++ printk("Number of context switches: %lu\n", v->nsVcpStats.numSwitches); ++ printk("Number of flushes: %lu\n", v->nsVcpStats.numFlushes); ++ printk("Number of flushes posted: %lu\n", v->nsVcpStats.numFlushesPosted); ++ printk("Number of flush ranges: %lu\n", v->nsVcpStats.numFlushRanges); ++ printk("Number of flush ranges posted: %lu\n", v->nsVcpStats.numFlushRangesPosted); ++ printk("Number of TPR reads: %lu\n", v->nsVcpStats.numTprReads); ++ printk("Number of ICR reads: %lu\n", v->nsVcpStats.numIcrReads); ++ printk("Number of Eoi writes: %lu\n", v->nsVcpStats.numEoiWrites); ++ printk("Number of Tpr writes: %lu\n", v->nsVcpStats.numTprWrites); ++ printk("Number of Icr writes: %lu\n", v->nsVcpStats.numIcrWrites); ++ printk("Number of GFS acuires: %lu\n", v->nsVcpStats.numGFSAcquires); ++ printk("Number of GFS releases: %lu\n", v->nsVcpStats.numGFSReleases); ++ printk("Number of TLB flushes: %lu\n", v->nsVcpStats.numTlbFlushes); ++ printk("Number of INVLPG flushes: %lu\n", v->nsVcpStats.numInvlPages); ++ printk("Number of TIMEOUTS: %lu\n", v->nsVcpStats.numTimeOuts); ++ ++} ++ ++/* ++ * static inline void nsWakeupWaiters(nsPartition_t *curp) ++ * Wakeup all the VCPUs that may be blocked on the Global ++ * flush state waiting to exclusively own the global flush ++ * state. ++ * ++ * Calling/Exit State: ++ * The partition-wide spin lock nsLock is held on entry and ++ * this lock is held on exit. ++ */ ++static inline void nsWakeupWaiters(nsPartition_t *curp) ++{ ++ int i; ++ if (!cpus_empty(curp->nsFlushState.waiters)) { ++ /* ++ * Need to wakeup potential waiters that ++ * are waiting for the ++ * flush block to become available. ++ */ ++ for (i=0; i < MAX_VIRT_CPUS; i++) { ++ struct vcpu *curVcpu; ++ if (!cpu_isset(i, curp->nsFlushState.waiters)) ++ continue; ++ curVcpu = ++ curp->nsVcpuState[i].nsVcpXenVcpu; ++ NS_ASSERT(curVcpu != NULL); ++ if ( test_and_clear_bit(_VPF_blocked_in_xen, ++ &curVcpu->pause_flags) ) { ++ vcpu_wake(curVcpu); ++ } ++ } ++ cpus_clear(curp->nsFlushState.waiters); ++ } ++} ++ ++/* ++ * static void nsAcquireGlobalFlushState(nsPartition_t *curp, nsVcpu_t *vcpup) ++ * Acquire the global flush state for exclusive use by the calling ++ * VCPU. ++ * ++ * Calling/Exit State: ++ * On entry nsLock is held and this lock is held on exit. If the calling ++ * VCPU is required to give up the CPU, this lock will be dropped. ++ */ ++static void nsAcquireGlobalFlushState(nsPartition_t *curp, nsVcpu_t *vcpup) ++{ ++acquireGFSAgain: ++ NS_ASSERT(vcpup->nsVcpWaitingOnGFS == 0); ++ NS_ASSERT(vcpup->nsVcpWaitingForCleanup == 0); ++ NS_ASSERT(NS_LOCK_OWNED(vcpup, &curp->nsLock)); ++ if (curp->nsFlushState.currentOwner != NULL) { ++ /* ++ * Somebody is in the midst of flushing; deal with this ++ * situation. ++ */ ++ /* ++ * We need to wait for the current flush sequence ++ * to end. ++ */ ++ NS_ASSERT(curp->nsFlushState.currentOwner != current); ++ NS_ASSERT(vcpup->nsVcpWaitingForCleanup == 0); ++ if (vcpup->nsVcpFlushPending) { ++ nsLockRelease(vcpup, &curp->nsLock); ++ nsDoTlbFlush(); ++ nsLockAcquire(vcpup, &curp->nsLock); ++ } ++ vcpup->nsVcpWaitingOnGFS = 1; ++ cpu_set(current->vcpu_id, curp->nsFlushState.waiters); ++ nsLockRelease(vcpup, &curp->nsLock); ++ wait_on_xen_event_channel(0, ++ ((curp->nsFlushState.currentOwner == NULL) || ++ (vcpup->nsVcpFlushPending) || ++ (cpus_empty(curp->nsFlushState.waiters)))); ++ nsLockAcquire(vcpup, &curp->nsLock); ++ cpu_clear(current->vcpu_id, curp->nsFlushState.waiters); ++ vcpup->nsVcpWaitingOnGFS = 0; ++ goto acquireGFSAgain; ++ } ++ curp->nsFlushState.repCount = vcpup->nsVcpRepCount; ++ curp->nsFlushState.flushParam = ++ vcpup->nsVcpInputBuffer; ++ NS_STATS_COLLECT(NS_GFS_ACQUIRE, &vcpup->nsVcpStats); ++} ++ ++/* ++ * static void nsReleaseGlobalFlushState(nsPartition_t *curp, nsVcpu_t *vcpup, ++ * int lockOwned) ++ * There can at most be one TLB flush event active in the system. All of the ++ * VCPUs that are part of the flush sequence need to relaese their hold ++ * on the global flush object before the global flush object can be freed. ++ * This function manages the release of the global flush object. ++ * If the "lockOwned" parameter is non-zero; on entry the nsLock is held. ++ * ++ * Calling/Exit State: ++ * The current owner of GFS may be forced to give up the CPU. ++ * On exit nsLock is held. ++ */ ++static void nsReleaseGlobalFlushState(nsPartition_t *curp, nsVcpu_t *vcpup, ++ int lockOwned) ++{ ++ if (!lockOwned) { ++ nsLockAcquire(vcpup, &curp->nsLock); ++ } ++ NS_ASSERT(curp->nsFlushState.cpuCount >= 0); ++ NS_ASSERT(curp->nsFlushState.currentOwner != NULL); ++ ++ if (vcpup->nsVcpFlushPending) { ++ curp->nsFlushState.cpuCount--; ++ NS_ASSERT(curp->nsFlushState.cpuCount >= 0); ++ vcpup->nsVcpFlushPending = 0; ++ mb(); ++ } ++ ++nsReleaseGFS: ++ if (curp->nsFlushState.cpuCount > 0) { ++ if (curp->nsFlushState.currentOwner == current) { ++ /* ++ * We are the initiator; need to wait for ++ * others to complete. ++ */ ++ nsWakeupWaiters(curp); ++ vcpup->nsVcpWaitingForCleanup = 1; ++ nsLockRelease(vcpup, &curp->nsLock); ++ wait_on_xen_event_channel(0,(curp->nsFlushState.cpuCount == 0)); ++ nsLockAcquire(vcpup, &curp->nsLock); ++ vcpup->nsVcpWaitingForCleanup = 0; ++ goto nsReleaseGFS; ++ } else { ++ return; ++ } ++ } ++ NS_ASSERT(curp->nsFlushState.cpuCount == 0); ++ if (curp->nsFlushState.currentOwner == current) { ++ /* We are the current owner; do the final cleanup. ++ * But first set the return value. This has been stashed ++ * before we blocked. ++ */ ++ NS_STATS_COLLECT(NS_GFS_RELEASE, &vcpup->nsVcpStats); ++ vcpup->nsVcpFlushRequest = 0; ++ vcpup->nsVcpFlushPending = 0; ++ vcpup->nsVcpWaitingForCleanup = 0; ++ nsSetSysCallRetVal(guest_cpu_user_regs(), ++ curp->nsLongModeGuest, ++ curp->nsFlushState.retVal); ++ curp->nsFlushState.cpuCount = 0; ++ curp->nsFlushState.currentOwner = NULL; ++ mb(); ++ curp->nsFlushState.retVal = 0; ++ curp->nsFlushState.flushParam = NULL; ++ curp->nsFlushState.repCount = 0; ++ nsWakeupWaiters(curp); ++ } else { ++ /* ++ * We are not the owner; wakeup the owner. ++ */ ++ if ( test_and_clear_bit(_VPF_blocked_in_xen, ++ &(curp->nsFlushState.currentOwner->pause_flags))){ ++ vcpu_wake(curp->nsFlushState.currentOwner); ++ } ++ } ++} ++ ++ ++/* ++ * static inline int nsFlushPermitted(nsVcpu_t *vcpup) ++ * Check to see if we can execute a TLB flush on the calling vcpu. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline int nsFlushPermitted(nsVcpu_t *vcpup) ++{ ++ if (!hvm_paging_enabled(current)) { ++ return (0); ++ } ++ if (current->arch.hvm_vmx.vmxassist_enabled) { ++ return (0); ++ } ++ if (nsInvalidCpuState()) { ++ return (0); ++ } ++ ++ return (1); ++} ++ ++/* ++ * void ++ * nsDoTlbFlush(void) ++ * Perform flush operations based on the state of GFS. VCPUs may be ++ * forced to relinquish the physical CPU while attempting to flush; in ++ * those events, thi is also the continuation point for execution. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++void ++nsDoTlbFlush(void) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ nsVcpu_t *vcpup = &curp->nsVcpuState[nsGetCurrentVcpuIndex()]; ++ flushVa_t *flushArgp; ++ int i,j, numPages; ++ u64 *pgList; ++ long baseVa; ++ unsigned short repCount; ++ ++ NS_ASSERT(local_irq_is_enabled()); ++ ++ NS_ASSERT(vcpup->nsVcplockDepth == 0); ++ ++ nsLockAcquire(vcpup, &curp->nsLock); ++ if (vcpup->nsVcpWaitingForCleanup) { ++ /* ++ * This is the continuation point for us; cleanup ++ * the global flush state. ++ */ ++ vcpup->nsVcpWaitingForCleanup =0; ++ NS_ASSERT(curp->nsFlushState.currentOwner == current); ++ nsReleaseGlobalFlushState(curp, vcpup, 1); ++ } else if (vcpup->nsVcpWaitingOnGFS) { ++ /* ++ * This is the continuation point for us; acquire ++ * GFS and proceed with our flush operation. ++ */ ++ vcpup->nsVcpWaitingOnGFS =0; ++ nsAcquireGlobalFlushState(curp, vcpup); ++ /* ++ * Now do the rest of the syscall processing ++ */ ++ nsFlushPostProcess(curp, vcpup); ++ } ++ if (!vcpup->nsVcpFlushPending) { ++ nsLockRelease(vcpup, &curp->nsLock); ++ return; ++ } ++ flushArgp = curp->nsFlushState.flushParam; ++ repCount = curp->nsFlushState.repCount; ++ /* ++ * At this point a flush has been posted; see if we can perform a ++ * flush given our state. ++ */ ++ if (!nsFlushPermitted(vcpup)) { ++ nsReleaseGlobalFlushState(curp, vcpup, 1); ++ nsLockRelease(vcpup, &curp->nsLock); ++ NS_ASSERT(vcpup->nsVcplockDepth == 0); ++ return; ++ } ++ nsLockRelease(vcpup, &curp->nsLock); ++ if (vcpup->nsVcpFlushPending & NS_FLUSH_TLB) { ++ NS_STATS_COLLECT(NS_TLB_FLUSH, &vcpup->nsVcpStats); ++ paging_update_cr3(current); ++ } else { ++ pgList = &flushArgp->gva; ++ NS_ASSERT(vcpup->nsVcpFlushPending == NS_FLUSH_INVLPG); ++ NS_ASSERT(pgList != NULL); ++ NS_ASSERT(repCount >=1); ++ NS_STATS_COLLECT(NS_INVL_PG, &vcpup->nsVcpStats); ++ for (i = 0; i < repCount; i++) { ++ baseVa = (long)(pgList[i] & PAGE_MASK); ++ numPages = (int)(~baseVa & pgList[i]); ++ for (j = 0; j <= numPages; j++) { ++ if (paging_invlpg(current, ++ (baseVa + (j << PAGE_SHIFT)))) { ++ flush_tlb_one_local((baseVa + ++ (j<< PAGE_SHIFT))); ++ } ++ //KYS: need to deal with ASIDS ++ } ++ } ++ } ++ /* ++ * Do post processing on the global flush state. ++ */ ++ nsReleaseGlobalFlushState(curp, vcpup, 0); ++ nsLockRelease(vcpup, &curp->nsLock); ++ NS_ASSERT(vcpup->nsVcplockDepth == 0); ++} ++ ++/* ++ * static int ++ * nsGetVpRegisters(paddr_t input, paddr_t output) ++ * Get the VCP register state. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static int ++nsGetVpRegisters(paddr_t input, paddr_t output) ++{ ++ nsVcpu_t *vcpup, *targetp; ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ getVpRegistersInput_t *inBuf; ++ getVpRegistersOutput_t *outBuf; ++ struct vcpu_guest_context *vcpuCtx; ++ u32 *regIndexp; ++ getVpRegistersOutput_t *outRegp; ++ u32 numOutputBytes = 0; ++ ++ vcpup = &curp->nsVcpuState[nsGetCurrentVcpuIndex()]; ++ inBuf = vcpup->nsVcpInputBuffer; ++ outBuf = vcpup->nsVcpOutputBuffer; ++ outRegp = outBuf; ++ /* ++ * Copy the input data to the per-cpu input buffer. ++ * This may be an overkill; obviously it is better to only ++ * copy what we need. XXXKYS: Check with Mike. ++ */ ++ if (nsXenVector.extCopyFromGuestPhysical(inBuf, input, PAGE_SIZE)) { ++ return (NS_STATUS_INVALID_ALIGNMENT); ++ } ++ /* ++ * If the partition ID specified does not match with the current ++ * domain return appropriate error. ++ */ ++ if ((u64)current->domain->domain_id != inBuf-> partitionId) { ++ return (NS_STATUS_ACCESS_DENIED); ++ } ++ if (inBuf->vpIndex > MAX_VIRT_CPUS) { ++ return (NS_STATUS_INVALID_VP_INDEX); ++ } ++ targetp = &curp->nsVcpuState[inBuf->vpIndex]; ++ if (!(targetp->nsVcpuFlags & NS_VCPU_UP)) { ++ return (NS_STATUS_INVALID_VP_STATE); ++ } ++ if ((vcpuCtx = ++ nsXenVector.extAllocMem(sizeof(struct vcpu_guest_context))) ++ == NULL) { ++ return (NS_STATUS_INSUFFICIENT_MEMORY); ++ } ++ ++ /* ++ * Get the register state of the specified vcp. ++ */ ++ if (current->vcpu_id != inBuf->vpIndex) { ++ nsXenVector.extVcpuPause(targetp->nsVcpXenVcpu); ++ } ++ nsXenVector.extArchGetDomainInfoCtxt(targetp->nsVcpXenVcpu, vcpuCtx); ++ if (current->vcpu_id != inBuf->vpIndex) { ++ nsXenVector.extVcpuUnPause(targetp->nsVcpXenVcpu); ++ } ++ /* ++ * Now that we have the register state; select what we want and ++ * populate the output buffer. ++ */ ++ regIndexp = &inBuf->regIndex; ++ while (*regIndexp != 0) { ++ switch (*regIndexp) { ++ /* ++ * XXXKYS: need mapping code here; populate ++ * outBuf. ++ */ ++ NS_PANIC("nsGetVpRegisters not supported\n"); ++ } ++ regIndexp++; ++ outRegp++ ; /*128 bit registers */ ++ numOutputBytes +=16; ++ if ((char *)regIndexp > ((char *)inBuf + PAGE_SIZE)) { ++ /* ++ *input list not reminated correctly; bail out. ++ */ ++ NS_PANIC("nsGetVpRegisters:input list not terminated\n"); ++ break; ++ } ++ } ++ if (nsXenVector.extCopyToGuestPhysical(output, outBuf, ++ numOutputBytes)) { ++ /* Some problem copying data out*/ ++ NS_PANIC("nsGetVpRegisters:copyout problem\n"); ++ } ++ nsXenVector.extFreeMem(vcpuCtx); ++ return (NS_STATUS_SUCCESS); ++} ++ ++/* ++ * static int ++ * nsSetVpRegisters(paddr_t input, paddr_t output) ++ * Set the VCPU register state. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static int ++nsSetVpRegisters(paddr_t input, paddr_t output) ++{ ++ nsVcpu_t *vcpup, *targetp; ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ setVpRegistersInput_t *inBuf; ++ struct vcpu_guest_context *vcpuCtx; ++ setVpRegisterSpec_t *regIndexp; ++ int retVal = NS_STATUS_SUCCESS; ++ ++ vcpup = &curp->nsVcpuState[nsGetCurrentVcpuIndex()]; ++ inBuf = vcpup->nsVcpInputBuffer; ++ /* ++ * Copy the input data to the per-cpu input buffer. ++ * This may be an overkill; obviously it is better to only ++ * copy what we need. XXXKYS: Check with Mike. ++ */ ++ if (nsXenVector.extCopyFromGuestPhysical(inBuf, input, PAGE_SIZE)) { ++ return (NS_STATUS_INVALID_ALIGNMENT); ++ } ++ /* ++ * If the partition ID specified does not match with the current ++ * domain return appropriate error. ++ */ ++ if ((u64)current->domain->domain_id != inBuf-> partitionId) { ++ return (NS_STATUS_ACCESS_DENIED); ++ } ++ if (inBuf->vpIndex > MAX_VIRT_CPUS) { ++ return (NS_STATUS_INVALID_VP_INDEX); ++ } ++ targetp = &curp->nsVcpuState[inBuf->vpIndex]; ++ if (!(targetp->nsVcpuFlags & NS_VCPU_UP)) { ++ return (NS_STATUS_INVALID_VP_STATE); ++ } ++ if ((vcpuCtx = ++ nsXenVector.extAllocMem(sizeof(struct vcpu_guest_context))) ++ == NULL) { ++ return (NS_STATUS_INSUFFICIENT_MEMORY); ++ } ++ /* ++ * XXXKYS: Is it sufficient to just pause the target vcpu; on the ++ * xen side domain is paused for this call. CHECK. ++ */ ++ if (current->vcpu_id != inBuf->vpIndex) { ++ nsXenVector.extVcpuPause(targetp->nsVcpXenVcpu); ++ } ++ ++ nsXenVector.extArchGetDomainInfoCtxt(targetp->nsVcpXenVcpu, vcpuCtx); ++ /* ++ * Now that we have the register state; update the register state ++ * based on what we are given. ++ */ ++ regIndexp = &inBuf->regSpec; ++ /* ++ * XXXKYS: Assuming the list is terminated by a regName that is 0. ++ * Check with Mike. ++ */ ++ while (regIndexp->regName != 0) { ++ switch (regIndexp->regName) { ++ /* ++ * XXXKYS: need mapping code here; populate ++ * vcpuCtx ++ */ ++ NS_PANIC("nsSetVpRegisters not supported\n"); ++ } ++ regIndexp++; ++ if ((char *)regIndexp > ((char *)inBuf + PAGE_SIZE)) { ++ /* ++ *input list not reminated correctly; bail out. ++ */ ++ NS_PANIC("nsSetVpRegisters:input list not terminated\n"); ++ break; ++ } ++ } ++ /* ++ * Now set register state. ++ * ++ * XXXKYS: Is it sufficient to just pause the target vcpu; on the ++ * xen side domain is paused for this call. CHECK. ++ */ ++ ++ if (nsXenVector.extArchSetDomainInfoCtxt(targetp->nsVcpXenVcpu, vcpuCtx)) { ++ retVal = NS_STATUS_INVALID_PARAMETER; ++ } ++ if (current->vcpu_id != inBuf->vpIndex) { ++ nsXenVector.extVcpuUnPause(targetp->nsVcpXenVcpu); ++ } ++ nsXenVector.extFreeMem(vcpuCtx); ++ return (retVal); ++} ++ ++/* ++ * static int ++ * nsSwitchVa(paddr_t input) ++ * ++ * Switch the page table base of the calling vcpu. ++ * ++ * Calling/Exit State: ++ * None. ++ * ++ * Remarks: ++ * The spec specifies that the input register is pointing to a guest ++ * physical that has the new page table base. However it appears that the ++ * page table base is being passed in the input register. ++ */ ++static int ++nsSwitchVa(paddr_t input) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ nsVcpu_t *vcpup = &curp->nsVcpuState[nsGetCurrentVcpuIndex()]; ++ ++ /* ++ * XXXKYS: the spec sys the asID is passed via memory at offset 0 of ++ * the page whose GPA is in the input register. However, it appears ++ * the current build of longhorn (longhorn-2007-02-06-x86_64-fv-02) ++ * passes the asID in the input register instead. Need to check if ++ * future builds do this. ++ */ ++ hvm_set_cr3(input); ++ NS_STATS_COLLECT(NS_CSWITCH, &vcpup->nsVcpStats); ++ return (NS_STATUS_SUCCESS); ++} ++ ++/* ++ * static int ++ * nsFlushPostProcess(nsPartition_t *curp, nsVcpu_t *curVcpup) ++ * ++ * Perform the flush operation once GFS is acquired. ++ * ++ * Calling/Exit State: ++ * On entry nsLock is held; on exit this lock continues to be held. ++ */ ++ ++static void ++nsFlushPostProcess(nsPartition_t *curp, nsVcpu_t *curVcpup) ++{ ++ int target; ++ nsVcpu_t *vcpup; ++ cpumask_t vcpuMask; ++ struct flushVa *flushArgp; ++ ++ flushArgp = curVcpup->nsVcpInputBuffer; ++ vcpuMask = flushArgp->vMask; ++ /* ++ * On entry we must own the global flush state. ++ */ ++ NS_ASSERT(NS_LOCK_OWNED(curVcpup, &curp->nsLock)); ++ NS_ASSERT(curp->nsFlushState.cpuCount == 0); ++ NS_ASSERT(curp->nsFlushState.currentOwner == NULL); ++ ++ curp->nsFlushState.retVal = ++ nsBuildHcallRetVal(NS_STATUS_SUCCESS, curVcpup->nsVcpRepCount); ++ curp->nsFlushState.currentOwner = current; ++ if (cpu_isset(current->vcpu_id, vcpuMask)) { ++ curp->nsFlushState.cpuCount = 1; ++ curVcpup->nsVcpFlushPending = ++ curVcpup->nsVcpFlushRequest; ++ mb(); ++#ifdef NS_STATS ++ if (curVcpup->nsVcpFlushRequest == NS_FLUSH_TLB) { ++ NS_STATS_COLLECT(NS_FLUSH_VA_POSTED, &curVcpup->nsVcpStats); ++ } else { ++ NS_STATS_COLLECT(NS_FLUSH_RANGE_POSTED, &curVcpup->nsVcpStats); ++ } ++#endif ++ ++ cpu_clear(current->vcpu_id, vcpuMask); ++ } ++ if (cpus_empty(vcpuMask)) { ++ /* ++ * We are done. ++ */ ++ goto flushVaDone; ++ } ++ while (!cpus_empty(vcpuMask)) { ++ target = first_cpu(vcpuMask); ++ vcpup = &curp->nsVcpuState[target]; ++ cpu_clear(target, vcpuMask); ++ if (!(vcpup->nsVcpuFlags & NS_VCPU_UP)) { ++ continue; ++ } ++ if (!nsFlushPermitted(vcpup)) { ++ continue; ++ } ++ curp->nsFlushState.cpuCount++; ++ vcpup->nsVcpFlushPending = ++ curVcpup->nsVcpFlushRequest; ++ mb(); ++#ifdef NS_STATS ++ if (curVcpup->nsVcpFlushRequest == NS_FLUSH_TLB) { ++ NS_STATS_COLLECT(NS_FLUSH_VA_POSTED, &vcpup->nsVcpStats); ++ } else { ++ NS_STATS_COLLECT(NS_FLUSH_RANGE_POSTED, &vcpup->nsVcpStats); ++ } ++#endif ++ ++ /* ++ * We need to force these VCPUs into the hypervisor for ++ * them to act on the pending request. ++ */ ++ ++ vcpu_kick(vcpup->nsVcpXenVcpu); ++ if ( test_and_clear_bit(_VPF_blocked_in_xen, ++ &vcpup->nsVcpXenVcpu->pause_flags) ) { ++ vcpu_wake(vcpup->nsVcpXenVcpu); ++ } ++ ++ } ++ /* ++ * Now that we have posted the state; wait for other CPUs to perform ++ * flushes; we need to wait for all the CPUs to complete the flush ++ * before returning. ++ */ ++flushVaDone: ++ /* ++ * If we are included in this round of tlb flush; we will wait for ++ * other CPUs in the tlb flush function; else we wait right here. ++ */ ++ if (!curVcpup->nsVcpFlushPending) { ++ nsReleaseGlobalFlushState(curp, curVcpup, 1); ++ } ++ return; ++} ++ ++/* ++ * static int ++ * nsFlushVa(paddr_t input) ++ * Perform a TLB flush on the specified set of VCPUs. ++ * ++ * Calling/Exit State: ++ * No locks can be held on entry and no locks will be held on return. ++ * The calling VCPU may relinquish the physical CPU. ++ */ ++static int ++nsFlushVa(paddr_t input) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ int i; ++ nsVcpu_t *curVcpup; ++ ++ flushVa_t *flushArgp; ++ cpumask_t vcpuMask; ++ u64 asId, inputMask, retVal; ++ int flushGlobal = 1; ++ ++ curVcpup = &curp->nsVcpuState[nsGetCurrentVcpuIndex()]; ++ flushArgp = curVcpup->nsVcpInputBuffer; ++ ++ NS_ASSERT(curVcpup->nsVcplockDepth == 0); ++ NS_ASSERT(curVcpup->nsVcpFlushRequest == 0); ++ NS_ASSERT(curVcpup->nsVcpWaitingForCleanup == 0); ++ NS_ASSERT(curVcpup->nsVcpWaitingOnGFS == 0); ++ ++ if (nsXenVector.extCopyFromGuestPhysical(flushArgp, input, ++ sizeof(*flushArgp))) { ++ return (NS_STATUS_INVALID_ALIGNMENT); ++ } ++ inputMask = flushArgp->pMask; ++ asId = flushArgp->asHandle; ++ cpus_clear(vcpuMask); ++ /* ++ * Deal with all trivial error conditions. ++ */ ++ if (flushArgp->flags != 0 && (!(flushArgp->flags & ++ (NS_FLUSH_ALL_PROCESSORS | ++ NS_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES | ++ NS_FLUSH_NON_GLOBAL_MAPPINGS_ONLY)))) { ++ return (NS_STATUS_INVALID_PARAMETER); ++ } ++ if (((flushArgp->pMask) == 0) && ++ !(flushArgp->flags & NS_FLUSH_ALL_PROCESSORS)) { ++ return (NS_STATUS_INVALID_PARAMETER); ++ } ++ ++ if (flushArgp->flags & NS_FLUSH_ALL_PROCESSORS) { ++ for (i=0; i< MAX_VIRT_CPUS; i++) { ++ if (current->domain->vcpu[i] != NULL) { ++ cpu_set(i, vcpuMask); ++ } ++ } ++ } else { ++ i = 0; ++ while (inputMask) { ++ if (inputMask &0x1) { ++ cpu_set(i, vcpuMask); ++ } ++ inputMask = (inputMask >> 1); ++ i++; ++ } ++ } ++ ++ if (flushArgp->flags & NS_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES) { ++ asId = NS_ALL_AS; ++ } ++ if (flushArgp->flags & NS_FLUSH_NON_GLOBAL_MAPPINGS_ONLY) { ++ flushGlobal = 0; ++ } ++ /* ++ * Now operate on what we are given ++ * XXXKYS: For now we are ignoring asId and fushGlobal flag. ++ * May have to revisit this. But first stash away the processed ++ * parameters for subsequent use. ++ */ ++ flushArgp->asHandle = asId; ++ flushArgp->flags = flushGlobal; ++ flushArgp->vMask = vcpuMask; ++ ++ curVcpup->nsVcpRepCount = 0; ++ curVcpup->nsVcpFlushRequest = NS_FLUSH_TLB; ++ ++ retVal = nsBuildHcallRetVal(NS_STATUS_SUCCESS, 0); ++ nsSetSysCallRetVal(guest_cpu_user_regs(), ++ curp->nsLongModeGuest, ++ retVal); ++ NS_STATS_COLLECT(NS_FLUSH_VA_STAT, &curVcpup->nsVcpStats); ++ nsLockAcquire(curVcpup, &curp->nsLock); ++ nsAcquireGlobalFlushState(curp, curVcpup); ++ nsFlushPostProcess(curp, curVcpup); ++ nsLockRelease(curVcpup, &curp->nsLock); ++ return (NS_STATUS_SUCCESS); ++} ++ ++/* ++ * static int ++ * nsFlushVaRange(paddr_t input, unsigned short startIndex, ++ * unsigned short repCount, unsigned short *repsDone) ++ * Perform a INVLPG flush on the specified set of VCPUs. ++ * ++ * Calling/Exit State: ++ * No locks can be held on entry and no locks will be held on return. ++ * The calling VCPU may relinquish the physical CPU. ++ */ ++static int ++nsFlushVaRange(paddr_t input, unsigned short startIndex, ++unsigned short repCount, unsigned short *repsDone) ++{ ++ nsVcpu_t *curVcpup; ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ flushVa_t *flushArgp; ++ cpumask_t vcpuMask; ++ u64 asId, inputMask, retVal; ++ int flushGlobal = 1; ++ int flushAllProc = 0; ++ int i; ++ ++ curVcpup = &curp->nsVcpuState[nsGetCurrentVcpuIndex()]; ++ flushArgp = curVcpup->nsVcpInputBuffer; ++ NS_ASSERT(curVcpup->nsVcplockDepth == 0); ++ NS_ASSERT(curVcpup->nsVcpFlushRequest == 0); ++ NS_ASSERT(curVcpup->nsVcpWaitingForCleanup == 0); ++ NS_ASSERT(curVcpup->nsVcpWaitingOnGFS == 0); ++ NS_ASSERT(repCount >=1); ++ NS_ASSERT(((sizeof(*flushArgp)) + 8*(repCount -1)) <= PAGE_SIZE); ++ if (nsXenVector.extCopyFromGuestPhysical(flushArgp, input, ++ ((sizeof(*flushArgp)) + 8*(repCount -1)))) { ++ return (NS_STATUS_INVALID_ALIGNMENT); ++ } ++ *repsDone = repCount; ++ inputMask = flushArgp->pMask; ++ asId = flushArgp->asHandle; ++ cpus_clear(vcpuMask); ++ /* ++ * Deal with all trivial error conditions. ++ */ ++ if (flushArgp->flags != 0 && (!(flushArgp->flags & ++ (NS_FLUSH_ALL_PROCESSORS | ++ NS_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES | ++ NS_FLUSH_NON_GLOBAL_MAPPINGS_ONLY)))) { ++ return (NS_STATUS_INVALID_PARAMETER); ++ } ++ if ((flushArgp->pMask == 0) && ++ !(flushArgp->flags & NS_FLUSH_ALL_PROCESSORS)) { ++ return (NS_STATUS_INVALID_PARAMETER); ++ } ++ ++ if (flushArgp->flags & NS_FLUSH_ALL_PROCESSORS) { ++ flushAllProc = 1; ++ for (i=0; i< MAX_VIRT_CPUS; i++) { ++ if (current->domain->vcpu[i] != NULL) { ++ cpu_set(i, vcpuMask); ++ } ++ } ++ } else { ++ i = 0; ++ /* ++ * populate the vcpu mask based on the input. ++ */ ++ while (inputMask) { ++ if (inputMask & 0x1) { ++ cpu_set(i, vcpuMask); ++ } ++ inputMask = (inputMask >> 1); ++ i++; ++ } ++ } ++ if (flushArgp->flags & NS_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES) { ++ asId = NS_ALL_AS; ++ } ++ if (flushArgp->flags & NS_FLUSH_NON_GLOBAL_MAPPINGS_ONLY) { ++ flushGlobal = 0; ++ } ++ /* ++ * Now operate on what we are given ++ * XXXKYS: For now we are ignoring asId and fushGlobal flag. ++ * May have to revisit this. ++ * May have to revisit this. But first stash away the processed ++ * parameters for subsequent use. ++ */ ++ flushArgp->asHandle = asId; ++ flushArgp->flags = flushGlobal; ++ flushArgp->vMask = vcpuMask; ++ ++ curVcpup->nsVcpRepCount = repCount; ++ curVcpup->nsVcpFlushRequest = NS_FLUSH_INVLPG; ++ ++ retVal = nsBuildHcallRetVal(NS_STATUS_SUCCESS, repCount); ++ nsSetSysCallRetVal(guest_cpu_user_regs(), ++ curp->nsLongModeGuest, ++ retVal); ++ ++ ++ NS_STATS_COLLECT(NS_FLUSH_RANGE, &curVcpup->nsVcpStats); ++ nsLockAcquire(curVcpup, &curp->nsLock); ++ nsAcquireGlobalFlushState(curp, curVcpup); ++ nsFlushPostProcess(curp, curVcpup); ++ nsLockRelease(curVcpup, &curp->nsLock); ++ return (NS_STATUS_SUCCESS); ++} ++ ++/* void ++ * nsHandleHyperCall(u64 opcode, u64 input, u64 output, ++ * u64 *retVal); ++ * Common entry point for handling all the extension hypercalls. ++ * ++ * Calling/Exit State: ++ * Based on the hypercall; the caller may give up the CPU while ++ * processing the hypercall. No locks should be held on entry and ++ * no locks will be held on return. ++ * ++ */ ++ ++void ++nsHandleHyperCall(u64 opcode, u64 input, u64 output, ++ u64 *retVal) ++{ ++ unsigned short verb; ++ unsigned short repCount; ++ unsigned short repsDone =0; ++ unsigned short startIndex; ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ u64 partitionId; ++ int value; ++ ++ ++ verb = (short)(opcode & 0xffff); ++ repCount = (short)((opcode >>32) & 0xfff); ++ startIndex = (short)((opcode >> 48) & 0xfff); ++ switch (verb) { ++ case NS_CREATE_PARTITION: ++ /* ++ * Xen only allows dom0 to create domains. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_INITIALIZE_PARTITION: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_DELETE_PARTITION: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_GET_PARTITION_PROPERTY: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_SET_PARTITION_PROPERTY: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_GET_PARTITION_ID: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_PARTITION_ID)) { ++ *retVal = ++ nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ } ++ partitionId = (u64)current->domain->domain_id; ++ if (nsXenVector.extCopyToGuestPhysical(output, ++ &partitionId, 8)) { ++ /* ++ * Invalid output area. ++ */ ++ *retVal = ++ nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ } ++ *retVal = nsBuildHcallRetVal(NS_STATUS_SUCCESS, 0); ++ return; ++ case NS_GET_NEXT_CHILD_PARTITION: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_SET_LOGICAL_PROCESSOR_RUN_TIME_GROUP: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_CLEAR_LOGICAL_PROCESSOR_RUN_TIME_GROUP: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_NOTIFY_LOGICAL_PROCESSOR_POWER_STATE: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_GET_LOGICAL_PROCESSOR_RUN_TIME: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_DEPOSIT_MEMORY: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_WITHDRAW_MEMORY: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_GET_MEMORY_BALANCE: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_MAP_GPA_PAGES: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_UNMAP_GPA_PAGES: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_INSTALL_INTERCEPT: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_CREATE_VP: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_TERMINATE_VP: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_DELETE_VP: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_GET_NEXT_VP: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_GET_VP_REGISTERS: ++ *retVal = nsBuildHcallRetVal( ++ nsGetVpRegisters(input, output), 0); ++ return; ++ case NS_SET_VP_REGISTERS: ++ *retVal = nsBuildHcallRetVal( ++ nsSetVpRegisters(input, output), 0); ++ case NS_SWITCH_VA: ++ *retVal = ++ nsBuildHcallRetVal(nsSwitchVa(input), 0); ++ return; ++ case NS_FLUSH_VA: ++ *retVal = ++ nsBuildHcallRetVal(nsFlushVa(input), 0); ++ return; ++ case NS_FLUSH_VA_LIST: ++ value = nsFlushVaRange(input, startIndex, ++ repCount, &repsDone); ++ *retVal = nsBuildHcallRetVal(value, repsDone); ++ return; ++ ++ case NS_TRASLATE_VA: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_READ_GPA: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_WRITE_GPA: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_ASSERT_VIRTUAL_INTERRUPT: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_CLEAR_VIRTUAL_INTERRUPT: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_CREATE_PORT: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_DELETE_PORT: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_CONNECT_PORT: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_GET_PORT_PROPERTY: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_DISCONNECT_PORT: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_POST_MESSAGE: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case NS_POST_EVENT: ++ /* ++ * We don't support this. ++ */ ++ *retVal = nsBuildHcallRetVal(NS_STATUS_ACCESS_DENIED, 0); ++ return; ++ case 0: ++ /* ++ * 32 bit longhorn invokes hypercall with verb == 0; need to ++ * check with Mike (XXXKYS). For now ignore it. ++ */ ++ *retVal = ++ nsBuildHcallRetVal(NS_STATUS_INVALID_HYPERCALL_CODE, 0); ++ return; ++ default: ++ nsXenVector.extPrintk("Unkown hypercall: verb is: %d\n", verb); ++ *retVal = ++ nsBuildHcallRetVal(NS_STATUS_INVALID_HYPERCALL_CODE, 0); ++ return; ++ } ++} +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/nshypercall.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/nshypercall.h 2008-02-26 14:01:28.000000000 -0500 +@@ -0,0 +1,125 @@ ++/**************************************************************************** ++ | ++ | Copyright (c) [2007, 2008] Novell, Inc. ++ | All Rights Reserved. ++ | ++ | This program is free software; you can redistribute it and/or ++ | modify it under the terms of version 2 of the GNU General Public License as ++ | published by the Free Software Foundation. ++ | ++ | This program is distributed in the hope that it will be useful, ++ | but WITHOUT ANY WARRANTY; without even the implied warranty of ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ | GNU General Public License for more details. ++ | ++ | You should have received a copy of the GNU General Public License ++ | along with this program; if not, contact Novell, Inc. ++ | ++ | To contact Novell about this file by physical or electronic mail, ++ | you may find current contact information at www.novell.com ++ | ++ |*************************************************************************** ++*/ ++ ++/* ++ * nshypercall.h ++ * Memory layouts for the various hypercalls supported. ++ * ++ * Engineering Contact: K. Y. Srinivasan ++ */ ++ ++#ifndef NS_HYPERCALL_H ++#define NS_HYPERCALL_H ++ ++#include ++ ++ ++typedef struct getVpRegistersInput { ++ u64 partitionId; ++ u64 vpIndex; ++ u32 regIndex; ++} getVpRegistersInput_t; ++ ++typedef struct getVpRegistersOutput { ++ u64 lowValue; ++ u64 highValue; ++} getVpRegistersOutput_t; ++ ++ ++ ++typedef struct setVpRegisterSpec { ++ u32 regName; ++ u32 pad; ++ u64 pad1; ++ u64 lowValue; ++ u64 highValue; ++} setVpRegisterSpec_t; ++typedef struct setVpRegistersInput { ++ u64 partitionId; ++ u64 vpIndex; ++ setVpRegisterSpec_t regSpec; ++} setVpRegistersInput_t; ++ ++ ++typedef struct flushVa { ++ u64 asHandle; ++ u64 flags; ++ union { ++ u64 processorMask; ++ cpumask_t vcpuMask; ++ } procMask; ++#define pMask procMask.processorMask ++#define vMask procMask.vcpuMask ++ u64 gva; ++} flushVa_t; ++ ++#define NS_FLUSH_ALL_PROCESSORS 0x00000001 ++#define NS_FLUSH_ALL_VIRTUAL_ADDRESS_SPACES 0x00000002 ++#define NS_FLUSH_NON_GLOBAL_MAPPINGS_ONLY 0x00000004 ++ ++#define NS_ALL_AS (-1) ++ ++/* ++ * Hypercall verbs. ++ */ ++ ++#define NS_CREATE_PARTITION 0x0010 ++#define NS_INITIALIZE_PARTITION 0x0011 ++#define NS_DELETE_PARTITION 0x0014 ++#define NS_GET_PARTITION_PROPERTY 0x0017 ++#define NS_SET_PARTITION_PROPERTY 0x0018 ++#define NS_GET_PARTITION_ID 0x0015 ++#define NS_GET_NEXT_CHILD_PARTITION 0x0016 ++#define NS_SET_LOGICAL_PROCESSOR_RUN_TIME_GROUP 0x0005 ++#define NS_CLEAR_LOGICAL_PROCESSOR_RUN_TIME_GROUP 0x0006 ++#define NS_NOTIFY_LOGICAL_PROCESSOR_POWER_STATE 0x0007 ++#define NS_GET_LOGICAL_PROCESSOR_RUN_TIME 0x0004 ++#define NS_DEPOSIT_MEMORY 0x001C ++#define NS_WITHDRAW_MEMORY 0x001D ++#define NS_GET_MEMORY_BALANCE 0x001E ++#define NS_MAP_GPA_PAGES 0x001A ++#define NS_UNMAP_GPA_PAGES 0x001B ++#define NS_INSTALL_INTERCEPT 0x0019 ++#define NS_CREATE_VP 0x001F ++#define NS_TERMINATE_VP 0x0020 ++#define NS_DELETE_VP 0x0021 ++#define NS_GET_NEXT_VP 0x0027 ++#define NS_GET_VP_REGISTERS 0x0022 ++#define NS_SET_VP_REGISTERS 0x0023 ++#define NS_SWITCH_VA 0x0001 ++#define NS_FLUSH_VA 0x0002 ++#define NS_FLUSH_VA_LIST 0x0003 ++#define NS_TRASLATE_VA 0x0024 ++#define NS_READ_GPA 0x0025 ++#define NS_WRITE_GPA 0x0026 ++#define NS_ASSERT_VIRTUAL_INTERRUPT 0x002A ++#define NS_CLEAR_VIRTUAL_INTERRUPT 0x002C ++#define NS_CREATE_PORT 0x002D ++#define NS_DELETE_PORT 0x002E ++#define NS_CONNECT_PORT 0x002F ++#define NS_GET_PORT_PROPERTY 0x0031 ++#define NS_DISCONNECT_PORT 0x0030 ++#define NS_POST_MESSAGE 0x0032 ++#define NS_POST_EVENT 0x0034 ++ ++#endif /* NS_HYPERCALL_H */ +Index: xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/nsintercept.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ xen-3.2-testing/xen/arch/x86/hvm/hvm_ext/novell/nsintercept.c 2008-02-28 13:18:54.000000000 -0500 +@@ -0,0 +1,2093 @@ ++/**************************************************************************** ++ | ++ | Copyright (c) [2007, 2008] Novell, Inc. ++ | All Rights Reserved. ++ | ++ | This program is free software; you can redistribute it and/or ++ | modify it under the terms of version 2 of the GNU General Public License as ++ | published by the Free Software Foundation. ++ | ++ | This program is distributed in the hope that it will be useful, ++ | but WITHOUT ANY WARRANTY; without even the implied warranty of ++ | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ | GNU General Public License for more details. ++ | ++ | You should have received a copy of the GNU General Public License ++ | along with this program; if not, contact Novell, Inc. ++ | ++ | To contact Novell about this file by physical or electronic mail, ++ | you may find current contact information at www.novell.com ++ | ++ |*************************************************************************** ++*/ ++ ++/* ++ * nsintercept.c. ++ * This file implements the intercepts to support the Novell Shim. ++ * ++ * Engineering Contact: K. Y. Srinivasan ++ */ ++ ++#include ++ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++ ++ ++/* ++ * Local includes; extension specific. ++ */ ++#include "ns_errno.h" ++#include "ns_shim.h" ++ ++ ++/* ++ * Implement Novell Shim. ++ */ ++ ++ ++/* ++ * Hypervisor intercept vector. ++ */ ++static int ++nsDomainCreate(struct domain *d); ++static void ++nsDomainDestroy(struct domain *d); ++static int ++nsVcpuInitialize(struct vcpu *v); ++static void ++nsVcpuUp(struct vcpu *v); ++static void ++nsVcpuDestroy(struct vcpu *v); ++static int ++nsDoCpuId(uint32_t input, struct cpu_user_regs *regs); ++static int ++nsDoRdMsr(uint32_t idx, struct cpu_user_regs *regs); ++static int ++nsDoWrMsr(uint32_t idx, struct cpu_user_regs *regs); ++static int ++nsDoHyperCall(struct cpu_user_regs *pregs); ++static void ++nsDoMigrateTimers(struct vcpu *v); ++ ++extension_intercept_vector_t nsExtensionVector = { ++ .domain_create = nsDomainCreate, ++ .domain_destroy = nsDomainDestroy, ++ .vcpu_initialize = nsVcpuInitialize, ++ .vcpu_destroy = nsVcpuDestroy, ++ .do_cpuid = nsDoCpuId, ++ .do_msr_read = nsDoRdMsr, ++ .do_msr_write = nsDoWrMsr, ++ .do_hypercall = nsDoHyperCall, ++ .do_continuation = nsDoTlbFlush, ++ .do_migrate_timers = nsDoMigrateTimers, ++ .vcpu_up = nsVcpuUp ++}; ++ ++/* ++ * Hooks into xen services; to be populated by our proxy in xen. ++ */ ++ ++xen_call_vector_t nsXenVector; ++ ++static inline void ++nsInjectException(int trap); ++ ++static inline void ++nsHypercallPageInitialize(void *hypercallPage, nsPartition_t *curp); ++ ++static inline void ++nsInitEventPage(void *siefPage); ++ ++static inline void ++nsInitMessagePage(void *simPage); ++ ++/* ++ * static int __init nsExtensionInit(void) ++ * Initialize the extensiom module. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static int __init nsExtensionInit(void) ++{ ++ int retVal; ++ retVal = hvm_ext_register(1, &nsExtensionVector, &nsXenVector); ++ NS_ASSERT(retVal == 0); ++ nsXenVector.extPrintk("NS Extension Initialized\n"); ++ return 0; ++} ++__initcall(nsExtensionInit); ++ ++/* ++ * Our lock primitives. ++ */ ++/* ++ * void ++ * nsLockAcquire(nsVcpu_t *vcpup, nsSpinLock_t *nsLock) ++ * Acquire the specified lock. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++void ++nsLockAcquire(nsVcpu_t *vcpup, nsSpinLock_t *nsLock) ++{ ++ NS_ASSERT(nsLock->owner != vcpup); ++ spin_lock_irqsave(&nsLock->spinLock, nsLock->flags); ++ nsLock->owner = vcpup; ++ nsLock->retAddr = __builtin_return_address(0); ++ vcpup->nsVcplockDepth++; ++} ++ ++/* ++ * void ++ * nsLockRelease(nsVcpu_t *vcpup, nsSpinLock_t *nsLock) ++ * Release the specified spin lock. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++void ++nsLockRelease(nsVcpu_t *vcpup, nsSpinLock_t *nsLock) ++{ ++ NS_ASSERT((nsLock->owner == vcpup)); ++ nsLock->owner = NULL; ++ vcpup->nsVcplockDepth--; ++ NS_ASSERT(vcpup->nsVcplockDepth >= 0); ++ spin_unlock_irqrestore(&nsLock->spinLock, nsLock->flags); ++} ++ ++/* ++ * void ++ * nsLockInit(nsSpinLock_t *nsLock) ++ * Initialize the specified spin lock. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++void ++nsLockInit(nsSpinLock_t *nsLock) ++{ ++ spin_lock_init(&nsLock->spinLock); ++ nsLock->owner = NULL; ++ nsLock->retAddr = NULL; ++} ++ ++/* ++ * static inline void nsWriteGuestIdMsr(nsPartition_t *curp, ++ * nsVcpu_t *curVcpu, ++ * u64 msrContent) ++ * Write the guest ID. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsWriteGuestIdMsr(nsPartition_t *curp, nsVcpu_t *curVcpu, u64 msrContent) ++{ ++ curp->nsGuestIdMsr = msrContent; ++ if (curp->nsGuestIdMsr == 0) { ++ /* ++ * Guest has cleared the guest ID; ++ * clear the hypercall page. ++ */ ++ if (curp->nsHypercallMsr) { ++ curVcpu->nsVcpuFlags &= ~NS_VCPU_UP; ++ } ++ } ++} ++ ++/* ++ * static inline void nsWriteHypercallMsr(nsPartition_t *curp, ++ * nsVcpu_t *curVcpu, ++ * u64 msrContent) ++ * Write hypercall msr. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline void ++nsWriteHypercallMsr(nsPartition_t *curp, ++ nsVcpu_t *curVcpu, ++ u64 msrContent) ++{ ++ unsigned long gmfn; ++ void *hypercallPage; ++ struct domain *d = curVcpu->nsVcpXenVcpu->domain; ++ ++ nsLockAcquire(curVcpu, &curp->nsLock); ++ gmfn = (msrContent >> 12); ++ if (curp->nsGuestIdMsr == 0) { ++ /* Nothing to do if the guest is not registered*/ ++ nsLockRelease(curVcpu, &curp->nsLock); ++ return; ++ } ++ /* ++ * Guest is registered; see if we can turn-on the ++ * hypercall page. ++ * XXXKYS: Can the guest write the GPA in one call and ++ * subsequently enable it? Check. For now assume that all the ++ * info is specified in one call. ++ */ ++ if (((u32)msrContent & (0x00000001)) == 0) { ++ /* ++ * The client is not enabling the hypercall; just ++ * ignore everything. ++ */ ++ nsLockRelease(curVcpu, &curp->nsLock); ++ return; ++ } ++ hypercallPage = nsXenVector.extGetVirtFromGmfn(d,gmfn); ++ if (hypercallPage == NULL) { ++ /* ++ * The guest specified a bogus GPA; inject a GP fault ++ * into the guest. ++ */ ++ nsInjectException(TRAP_gp_fault); ++ nsLockRelease(curVcpu, &curp->nsLock); ++ return; ++ } ++ nsHypercallPageInitialize(hypercallPage, curp); ++ curp->nsHypercallMfn = nsXenVector.extGetMfnFromGmfn(d, gmfn); ++#ifdef CONFIG_DOMAIN_PAGE ++ nsXenVector.extUnmapDomainPage(hypercallPage); ++#endif ++ curp->nsHypercallMsr = msrContent; ++ nsLockRelease(curVcpu, &curp->nsLock); ++ curVcpu->nsVcpuFlags |= NS_VCPU_UP; ++} ++ ++/* ++ * static inline void nsWriteSxMsr(uint32_t idx, nsPartition_t *curp, ++ * nsVcpu_t *curVcpu, ++ * u64 msrContent) ++ * Write SIEFP or SIMP msr. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline void nsWriteSxMsr(uint32_t idx, nsPartition_t *curp, ++ nsVcpu_t *curVcpu, ++ u64 msrContent) ++{ ++ unsigned long gmfn; ++ void *sxPage; ++ struct domain *d = curVcpu->nsVcpXenVcpu->domain; ++ gmfn = (msrContent >> 12); ++ /* ++ * Can the client enable the siefp and specify ++ * the base address in two ++ * different calls? XXXKYS: For now assume ++ * that it is done in one call. ++ */ ++ if (!((u32)msrContent & (0x00000001))) { ++ /* ++ * The client is not enabling the sx page; just ++ * ignore everything. ++ */ ++ return; ++ } ++ sxPage = nsXenVector.extGetVirtFromGmfn(d, gmfn); ++ if (sxPage == NULL) { ++ /* ++ * The guest specified a bogus GPA; inject a GP fault ++ * into the guest. ++ */ ++ nsInjectException(TRAP_gp_fault); ++ return; ++ } ++ switch (idx) { ++ case NS_MSR_SIEFP: ++ nsInitEventPage(sxPage); ++ curVcpu->nsVcpSIefpMsr = msrContent; ++ curVcpu->nsVcpSiefPage = sxPage; ++ break; ++ case NS_MSR_SIMP: ++ nsInitMessagePage(sxPage); ++ curVcpu->nsVcpSimpMsr = msrContent; ++ curVcpu->nsVcpSimPage = sxPage; ++ break; ++ } ++ ++} ++ ++/* ++ * Time this domain booted. ++ */ ++s_time_t nsDomainBootTime; ++ ++/* ++ * static inline u64 ++ * nsGetTimeSinceDomainBoot(void) ++ * Retrieve the time since boot in 100ns units. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline u64 ++nsGetTimeSinceDomainBoot(void) ++{ ++ u64 curTime = nsXenVector.extGetTimeSinceBoot(); ++ return ((curTime - nsDomainBootTime)/100) ; ++} ++ ++/* ++ * static inline int ++ * nsCallFromBios(struct cpu_user_regs *regs) ++ * Check if the caller is in the right state to consumE the services of the ++ * extension module. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline int ++nsCallFromBios(struct cpu_user_regs *regs) ++{ ++ if (hvm_paging_enabled(current)) { ++ return (0); ++ } else { ++ return (1); ++ } ++} ++ ++/* ++ * static inline void ++ * nsInjectException(int trap) ++ * Injecct the specified exception into the invoking virtual CPU. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline void ++nsInjectException(int trap) ++{ ++ nsXenVector.hvmFuncTable->inject_exception(trap, 0, 0); ++} ++ ++ ++/* ++ * static inline int ++ * nsOsRegistered(void) ++ * Check to see if the guest has registered itself with the Novell Shim. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline int ++nsOsRegistered(void) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ return (curp->nsGuestIdMsr != 0?1:0); ++} ++ ++ ++/* ++ * static inline void ++ * nsSetPartitionPrivileges(nsPartition_t *nspp) ++ * Set the partitionwide privileges. Currently it is harcoded. ++ * We could perhaps make this an attribute of the domain and have the ++ * configuration tools manage it. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline void ++nsSetPartitionPrivileges(nsPartition_t *nspp) ++{ ++ /* ++ * This is based on the hypervisor spec under section 5.2.3. ++ */ ++ nspp->nsPrivileges = 0x000000020000007f; ++} ++ ++/* ++ * static inline u32 ++ * nsGetRecommendations(void) ++ * Get the recommendations. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline u32 ++nsGetRecommendations(void) ++{ ++ /* ++ *For now we recommend all the features. Need to validate. ++ */ ++ if ( paging_mode_hap(current->domain)) { ++ /* ++ * If HAP is enabled; the guest should not use TLB flush ++ * related enlightenments. ++ */ ++ return (0x19); ++ } else { ++ return (0x1f); ++ } ++} ++ ++/* ++ * static inline void ++ * nsSetPartitionFeatures(nsPartition_t *nspp) ++ * Set the partitionwide features. Currently it is harcoded. ++ * We could perhaps make this an attribute of the domain and have the ++ * configuration tools manage it. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline void ++nsSetPartitionFeatures(nsPartition_t *nspp) ++{ ++ nspp->nsSupportedFeatures = 0x1f; ++} ++ ++static inline u16 ++nsGetGuestMajor(void) ++{ ++ return (0); ++} ++static inline u16 ++nsGetGuestMinor(void) ++{ ++ return (0); ++} ++static inline u32 ++nsGetGuestServicePack(void) ++{ ++ return (0); ++} ++ ++static inline u8 ++nsGetGuestServiceBranchInfo(void) ++{ ++ return (0); ++} ++static inline u32 ++nsGetGuestServiceNumber(void) ++{ ++ return (0); ++} ++ ++/* ++ * static inline u32 ++ * nsGetSupportedSyntheticMsrs(void) ++ * Get the synthetic MSRs supported by the Novell Shim. Currently ++ * it is hardcoded. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline u32 ++nsGetSupportedSyntheticMsrs(void) ++{ ++ /* ++ * All MSRS in the spec version 0.83 including RESET MSR. ++ */ ++ return (0xff); ++} ++ ++ ++/* ++ * static inline u32 ++ * nsGetMaxVcpusSupported(void) ++ * Retrieve the maximum vcpus supported. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline u32 ++nsGetMaxVcpusSupported(void) ++{ ++ return MAX_VIRT_CPUS; ++} ++ ++/* ++ * static inline u32 ++ * nsGetMaxLcpusSupported(void) ++ * Retrieve the maximum physical cpus supported. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline u32 ++nsGetMaxLcpusSupported(void) ++{ ++ return NR_CPUS; ++} ++ ++ ++/* ++ * static inline void ++ * nsReadIcr(u64 *icrContent) ++ * Read the ICR of the local APIC of the calling VCPU. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsReadIcr(u64 *icrContent) ++{ ++ u32 icrLow, icrHigh; ++ u64 retVal; ++ ++ ++ icrLow = nsXenVector.mmIoHandler->read_handler(current, ++ (vlapic_base_address(vcpu_vlapic(current)) + 0x300), 4); ++ icrHigh = nsXenVector.mmIoHandler->read_handler(current, ++ (vlapic_base_address(vcpu_vlapic(current)) + 0x310), 4); ++ retVal = icrHigh; ++ *icrContent = ((retVal << 32) | icrLow); ++ ++} ++ ++/* ++ * static inline void ++ * nsReadTpr(u64 *tprContent) ++ * Read the TPR of the local APIC of the calling VCPU. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsReadTpr(u64 *tprContent) ++{ ++ u32 tprLow; ++ ++ ++ tprLow = nsXenVector.mmIoHandler->read_handler(current, ++ (vlapic_base_address(vcpu_vlapic(current)) + 0x80), 4); ++ *tprContent = (u64)tprLow; ++ ++} ++ ++/* ++ * static inline void ++ * nsWriteEoi(u64 msrContent) ++ * Write the EOI register of the local APIC of the calling VCPU. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsWriteEoi(u64 msrContent) ++{ ++ u32 eoi = (u32)msrContent; ++ ++ nsXenVector.mmIoHandler->write_handler(current, ++ (vlapic_base_address(vcpu_vlapic(current)) + 0xb0), 4, eoi); ++ ++} ++ ++/* ++ * static inline void ++ * nsWriteIcr(u64 msrContent) ++ * Write the ICR register of the local APIC of the calling VCPU. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsWriteIcr(u64 msrContent) ++{ ++ u32 icrLow, icrHigh; ++ icrLow = (u32)msrContent; ++ icrHigh = (u32)(msrContent >> 32); ++ ++ if (icrHigh != 0) { ++ nsXenVector.mmIoHandler->write_handler(current, ++ (vlapic_base_address(vcpu_vlapic(current)) + 0x310), 4, ++ icrHigh); ++ } ++ if (icrLow != 0) { ++ nsXenVector.mmIoHandler->write_handler(current, ++ (vlapic_base_address(vcpu_vlapic(current)) + 0x300), 4, ++ icrLow); ++ } ++ ++} ++ ++/* ++ * static inline void ++ * nsWriteTpr(u64 msrContent) ++ * Write the TPR register of the local APIC of the calling VCPU. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsWriteTpr(u64 msrContent) ++{ ++ u32 tpr = (u32)msrContent; ++ ++ ++ nsXenVector.mmIoHandler->write_handler(current, ++ (vlapic_base_address(vcpu_vlapic(current)) + 0x80), 4, tpr); ++ ++} ++ ++/* ++ * static inline void ++ * nsHypercallPageInitialize(void *hypercallPage, nsPartition_t *curp) ++ * Initialize the hypercall page to support the Novell Shim Hypercalls. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsHypercallPageInitialize(void *hypercallPage, nsPartition_t *curp) ++{ ++ char *p; ++ ++ if (nsXenVector.hvmFuncTable->guest_x86_mode(current) == 8) { ++ curp->nsLongModeGuest = 1; ++ } else { ++ curp->nsLongModeGuest = 0; ++ } ++ ++ memset(hypercallPage, 0, PAGE_SIZE); ++ p = (char *)(hypercallPage) ; ++ *(u8 *)(p + 0) = 0x0f; /* vmcall */ ++ *(u8 *)(p + 1) = 0x01; ++ if (nsXenVector.extCpuIsIntel()) { ++ *(u8 *)(p + 2) = 0xc1; ++ } else { ++ *(u8 *)(p + 2) = 0xd9; ++ } ++ *(u8 *)(p + 3) = 0xc3; /* ret */ ++} ++ ++/* ++ * static inline void ++ * nsInitEventPage(void *siefPage) ++ * Initialize the per-vcpu event page. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsInitEventPage(void *siefPage) ++{ ++ memset(siefPage, 0, PAGE_SIZE); ++} ++ ++/* ++ * static inline void ++ * nsInitMessagePage(void *siefPage) ++ * Initialize the per-vcpu message page. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsInitMessagePage(void *simPage) ++{ ++ memset(simPage, 0, PAGE_SIZE); ++} ++ ++ ++/* ++ * static inline void ++ * nsProcessMessageQ(nsPartition_t *curp, nsVcpu_t *curVcpu) ++ * Process the message queue. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsProcessMessageQ(nsPartition_t *curp, nsVcpu_t *curVcpu) ++{ ++ /* ++ * XXXKYS: we currently do not support queued messages. ++ */ ++} ++ ++/* ++ * static inline void ++ * nsScheduleTimeOut(nsVcpTimerState_t *timer) ++ * Schedule a timeout based on the specified timer. ++ * ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static inline void ++nsScheduleTimeOut(nsVcpTimerState_t *timer) ++{ ++ /* ++ * We maintain the count in the units of 100ns. Furthermore, ++ * this is not relative to NOW() but rather absolute. ++ */ ++ nsXenVector.extSetTimer(&timer->vcpuTimer, (timer->count * 100)); ++} ++ ++/* ++ * static void ++ * nsTimeOutHandler(void *arg) ++ * The timeout handler for Novell Shim/Adaptor. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static void ++nsTimeOutHandler(void *arg) ++{ ++ nsVcpTimerState_t *timerData = arg; ++ nsVcpu_t *curVcpu = timerData->thisCpu; ++ int sIntNum; ++ int vector; ++ if (!(curVcpu->nsVcpSControlMsr & 0x9)) { ++ goto nsToPostProcess; ++ } ++ /* ++ * SynIC is enabled; do further processing. Timeouts are posted as ++ * messages; verify if the message page is enabled. ++ */ ++ if (!(curVcpu->nsVcpSimpMsr & 0x1)) { ++ goto nsToPostProcess; ++ } ++ sIntNum = (((u32)(timerData->config >> 16)) & 0x0000000f); ++ /* ++ * First post the message and then optionally deal with the ++ * interrupt notification. ++ */ ++ if (curVcpu->nsVcpSimPage == NULL) { ++ NS_PANIC("Novell Shim: Sim page not setup\n"); ++ } ++ if ((((nsMessage_t *)curVcpu->nsVcpSimPage)[sIntNum]).messageType != ++ nsMessageTypeNone) { ++ /* ++ * The message slot is not empty just silently return. ++ */ ++ goto nsToPostProcess; ++ } ++ /* ++ * The slot is available; post the message. ++ */ ++ (((nsTimerMessage_t *)curVcpu->nsVcpSimPage)[sIntNum]).messageType = ++ nsMessageTimerExpired; ++ (((nsTimerMessage_t *)curVcpu->nsVcpSimPage)[sIntNum]).messageSize = ++ sizeof(nsTimerMessage_t); ++ (((nsTimerMessage_t *)curVcpu->nsVcpSimPage)[sIntNum]).timerIndex = ++ timerData->timerIndex; ++ (((nsTimerMessage_t *)curVcpu->nsVcpSimPage)[sIntNum]).expirationTime = ++ timerData->count; ++ if ((curVcpu->nsVcpSIntMsr[sIntNum] >> 16) &0x1) { ++ /* ++ * The designated sintx register is masked; just return. ++ */ ++ goto nsToPostProcess; ++ } ++ vector = ((u32)curVcpu->nsVcpSIntMsr[sIntNum] &0xff); ++ ++ /* ++ * Now post the interrupt to the VCPU. ++ * XXXKYS: What is the delivery mode for interrupts delivered here. ++ * Check with Mike? ++ */ ++ nsXenVector.extPostInterrupt(current, vector, APIC_DM_FIXED); ++ ++ /* ++ * If auto eoi is set; deal with that. ++ */ ++ if (((u32)(curVcpu->nsVcpSIntMsr[sIntNum] >> 16)) & 0x1) { ++ nsWriteEoi(0); ++ } ++ ++nsToPostProcess: ++ /* ++ * Prior to returning, deal with all the post timeout issues. ++ */ ++ if (((u32)(timerData->config)) & 0x00000002) { ++ NS_STATS_COLLECT(NS_TIMEOUTS, &curVcpu->nsVcpStats); ++ nsScheduleTimeOut(timerData); ++ } ++} ++ ++/* ++ * static inline void ++ * nsTimerInit(nsVcpu_t *vcpup, int timer) ++ * Initialize the specified timer structure. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline void ++nsTimerInit(nsVcpu_t *vcpup, int timer) ++{ ++ vcpup->nsVcpTimers[timer].config = 0; ++ vcpup->nsVcpTimers[timer].count = 0; ++ vcpup->nsVcpTimers[timer].thisCpu = vcpup; ++ vcpup->nsVcpTimers[timer].timerIndex = timer; ++ init_timer(&vcpup->nsVcpTimers[timer].vcpuTimer, nsTimeOutHandler, ++ &vcpup->nsVcpTimers[timer], current->processor); ++} ++ ++/* ++ * static inline int ++ * nsAccessTimeRefCnt(nsPartition_t *curp, u64 *msrContent) ++ * Read the per-partition time base. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static inline int ++nsAccessTimeRefCnt(nsPartition_t *curp, u64 *msrContent) ++{ ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_TIME_REF_CNT)) { ++ /* ++ * The partition does not have the privilege to ++ * read this; return error. ++ */ ++ return (0); ++ } ++ *msrContent = nsGetTimeSinceDomainBoot(); ++ return (1); ++} ++ ++/* ++ * static void ++ * nsDoMigrateTimers(struct vcpu *v) ++ * The binding between this vcpu and the physical cpu has changed; migrate ++ * the timers for this vcpu. ++ * ++ * Calling/Exit State: ++ * The new binding is already in place. ++ */ ++ ++static void ++nsDoMigrateTimers(struct vcpu *v) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ nsVcpu_t *vcpup; ++ int i; ++ vcpup = &curp->nsVcpuState[nsGetCurrentVcpuIndex()]; ++ ++ for (i=0; i<4; i++) { ++ nsXenVector.extMigrateTimer(&vcpup->nsVcpTimers[i].vcpuTimer, ++ v->processor); ++ } ++} ++ ++/* ++ * static void ++ * nsVcpuUp(struct vcpu *v) ++ * A secondary processor has come on line; mark the processor as up. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static void ++nsVcpuUp(struct vcpu *v) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ nsVcpu_t *vcpup; ++ vcpup = &curp->nsVcpuState[v->vcpu_id]; ++ vcpup->nsVcpuFlags |= NS_VCPU_UP; ++} ++ ++/* ++ * static int ++ * nsDoHyperCall(struct cpu_user_regs *pregs) ++ * Intercept for implementing Extension hypercalls. ++ * ++ * Calling/Exit State: ++ * Based on the hypercall; the caller may give up the CPU while ++ * processing the hypercall. No locks should be held on entry and ++ * no locks will be held on return. ++ * ++ * ++ */ ++ ++static int ++nsDoHyperCall(struct cpu_user_regs *pregs) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ nsVcpu_t *vcpup; ++ int longModeGuest = curp->nsLongModeGuest; ++ unsigned long hypercallMfn; ++ unsigned long gmfn; ++ gmfn = (curp->nsHypercallMsr >> 12); ++ ++ hypercallMfn = nsXenVector.extGetMfnFromGva(pregs->eip); ++ ++ if (hypercallMfn == curp->nsHypercallMfn) { ++ u64 opcode, input, output, retVal; ++ vcpup = &curp->nsVcpuState[nsGetCurrentVcpuIndex()]; ++ ++ /* ++ * This is an extension hypercall; process it; but first make ++ * sure that the CPU is in the right state for invoking ++ * the hypercall - protected mode at CPL 0. ++ */ ++ if (nsInvalidCpuState()) { ++ nsInjectException(TRAP_gp_fault); ++ retVal = nsBuildHcallRetVal(NS_STATUS_INVALID_VP_STATE, ++ 0); ++ nsSetSysCallRetVal(pregs, longModeGuest, retVal); ++ return (1); ++ } ++ if (longModeGuest) { ++ opcode = pregs->ecx; ++ input = pregs->edx; ++ output = pregs->r8; ++ } else { ++ opcode = ++ ((((u64)pregs->edx) << 32) | ((u64)pregs->eax)); ++ input = ++ ((((u64)pregs->ebx) << 32) | ((u64)pregs->ecx)); ++ output = ++ ((((u64)pregs->edi) << 32) | ((u64)pregs->esi)); ++ } ++ NS_ASSERT(vcpup->nsVcplockDepth == 0); ++ nsHandleHyperCall(opcode, input, output, &retVal); ++ nsSetSysCallRetVal(pregs, longModeGuest, retVal); ++ NS_ASSERT(vcpup->nsVcplockDepth == 0); ++ return (1); ++ } ++ /* ++ * This hypercall page is not the page for extension. ++ */ ++ return (0); ++} ++ ++/* ++ * static int ++ * nsDomainCreate(struct domain *d) ++ * NS intercept for domain creation. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++ ++static int ++nsDomainCreate(struct domain *d) ++{ ++ nsPartition_t *nspp; ++ nspp = nsXenVector.extAllocMem(sizeof(nsPartition_t)); ++ if (nspp == NULL) { ++ nsDebugPrint("Memory allocation failed\n"); ++ return (1); ++ } ++ memset(nspp, 0, sizeof(*nspp)); ++ nsLockInit(&nspp->nsLock); ++ /* ++ * Set the partition wide privilege; We can start with no privileges ++ * and progressively turn on fancier hypervisor features. ++ */ ++ nsSetPartitionPrivileges(nspp); ++ nsSetPartitionFeatures(nspp); ++ /* ++ * Stash away pointer to our state in the hvm domain structure. ++ */ ++ d->arch.hvm_domain.ext_handle = nspp; ++ nsDomainBootTime = nsXenVector.extGetTimeSinceBoot(); ++ return (0); ++} ++ ++ ++ ++/* ++ * static void ++ * nsDomainDestroy(struct domain *d) ++ * NS intercept for the domain destruction. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void ++nsDomainDestroy(struct domain *d) ++{ ++ int i; ++ nsPartition_t *curp = d->arch.hvm_domain.ext_handle; ++ nsXenVector.extPrintk("NS Domain Being Destroyed\n"); ++ NS_ASSERT(curp != NULL); ++ nsXenVector.extPrintk("DUMP STATS\n"); ++ nsXenVector.extPrintk("GFS cpucount is %d\n", curp->nsFlushState.cpuCount); ++ if (curp->nsFlushState.currentOwner != NULL) { ++ nsXenVector.extPrintk("GFS owner is %d\n", curp->nsFlushState.currentOwner->vcpu_id); ++ } else { ++ nsXenVector.extPrintk("GFS is free\n"); ++ } ++ if (!cpus_empty(curp->nsFlushState.waiters)) { ++ nsXenVector.extPrintk("GFS: waiters not empty\n"); ++ } else { ++ nsXenVector.extPrintk("GFS: waiters empty\n"); ++ } ++ for (i=0; i < MAX_VIRT_CPUS; i++) { ++ if (d->vcpu[i] != NULL) { ++ nsPrintStats(curp, i); ++ } ++ } ++ ++ nsXenVector.extFreeMem(d->arch.hvm_domain.ext_handle); ++ d->arch.hvm_domain.ext_handle = NULL; ++} ++ ++/* ++ * static int ++ * nsVcpuInitialize(struct vcpu *v) ++ * NS intercept for vcpu creation. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static int ++nsVcpuInitialize(struct vcpu *v) ++{ ++ nsVcpu_t *vcpup; ++ nsPartition_t *curp = v->domain->arch.hvm_domain.ext_handle; ++ int i; ++ vcpup = &curp->nsVcpuState[v->vcpu_id]; ++ atomic_inc(&curp->nsNumVcpusActive); ++ if (v->vcpu_id == 0) { ++ vcpup->nsVcpuFlags |= NS_VCPU_BOOT_CPU; ++ } ++ /* ++ * Initialize all the synthetic MSRs corresponding to this VCPU. ++ * Note that all state is set to 0 to begin ++ * with. ++ */ ++ vcpup->nsVcpSVersionMsr = 0x00000001; ++ /* ++ * Initialize the synthetic timet structures. ++ */ ++ for (i=0; i < 4; i++) { ++ nsTimerInit(vcpup, i); ++ } ++ /* ++ * Setup the input page for handling hypercalls. ++ * ++ */ ++ vcpup->nsVcpInputBufferPage = ++ nsXenVector.extAllocDomHeapPage(); ++ if (vcpup->nsVcpInputBufferPage == NULL) { ++ nsDebugPrint("Memory allocation failed\n"); ++ return (1); ++ } ++ vcpup->nsVcpInputBuffer = ++ nsXenVector.extGetVirtFromPagePtr(vcpup->nsVcpInputBufferPage); ++ if (vcpup->nsVcpInputBuffer == NULL) { ++ nsDebugPrint("Coud not get VA\n"); ++ nsXenVector.extFreeDomHeapPage(vcpup->nsVcpInputBufferPage); ++ return (1); ++ } ++ memset(vcpup->nsVcpInputBuffer, 0, PAGE_SIZE); ++ vcpup->nsVcpOutputBufferPage = ++ nsXenVector.extAllocDomHeapPage(); ++ if (vcpup->nsVcpOutputBufferPage == NULL) { ++ nsDebugPrint("Memory allocation failed\n"); ++#ifdef CONFIG_DOMAIN_PAGE ++ nsXenVector.extUnmapDomainPage(vcpup->nsVcpInputBuffer); ++#endif ++ nsXenVector.extFreeDomHeapPage(vcpup->nsVcpInputBufferPage); ++ return (1); ++ } ++ vcpup->nsVcpOutputBuffer = ++ nsXenVector.extGetVirtFromPagePtr(vcpup->nsVcpOutputBufferPage); ++ if (vcpup->nsVcpOutputBuffer == NULL) { ++ nsDebugPrint("Coud not get VA\n"); ++ nsXenVector.extFreeDomHeapPage(vcpup->nsVcpOutputBufferPage); ++#ifdef CONFIG_DOMAIN_PAGE ++ nsXenVector.extUnmapDomainPage(vcpup->nsVcpInputBuffer); ++#endif ++ nsXenVector.extFreeDomHeapPage(vcpup->nsVcpInputBufferPage); ++ return (1); ++ } ++ vcpup->nsVcpXenVcpu = v; ++ vcpup->nsVcpFlushRequest = 0; ++ ++ return (0); ++} ++ ++/* ++ * static void ++ * nsVcpuDestroy(struct vcpu *v) ++ * NS intercept for domain destruction. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++static void ++nsVcpuDestroy(struct vcpu *v) ++{ ++ nsVcpu_t *vcpup; ++ nsPartition_t *curp = v->domain->arch.hvm_domain.ext_handle; ++ int i; ++ ++ vcpup = &curp->nsVcpuState[v->vcpu_id]; ++ atomic_dec(&curp->nsNumVcpusActive); ++ vcpup->nsVcpuFlags &= ~NS_VCPU_UP; ++ /* ++ * Get rid of the pages we have allocated for this VCPU. ++ */ ++#ifdef CONFIG_DOMAIN_PAGE ++ nsXenVector.extUnmapDomainPage(vcpup->nsVcpSiefPage); ++ nsXenVector.extUnmapDomainPage(vcpup->nsVcpSimPage); ++ nsXenVector.extUnmapDomainPage(vcpup->nsVcpInputBuffer); ++ nsXenVector.extUnmapDomainPage(vcpup->nsVcpOutputBuffer); ++#endif ++ ++ nsXenVector.extFreeDomHeapPage(vcpup->nsVcpInputBufferPage); ++ nsXenVector.extFreeDomHeapPage(vcpup->nsVcpOutputBufferPage); ++ /* ++ * Kill the timers ++ */ ++ for (i=0; i < 4; i++) { ++ nsXenVector.extKillTimer(&vcpup->nsVcpTimers[i].vcpuTimer); ++ } ++ return; ++} ++ ++/* ++ * static int nsVcpuSave(struct domain *d, hvm_domain_context_t *h) ++ * Save per-cpu shim state to support either migration or domain save. ++ * ++ * Calling exit state: ++ * None. ++ */ ++static int ++nsVcpuSave(struct domain *d, hvm_domain_context_t *h) ++{ ++ struct vcpu *v; ++ struct hvm_ns_veridian_cpu ctxt; ++ ++ nsVcpu_t *vcpup; ++ nsPartition_t *curp = d->arch.hvm_domain.ext_handle; ++ int i; ++ ++ if (curp == NULL) { ++ return 0; ++ } ++ for_each_vcpu(d, v) { ++ vcpup = &curp->nsVcpuState[v->vcpu_id]; ++ ++ NS_ASSERT(vcpup->nsVcplockDepth == 0); ++ NS_ASSERT(vcpup->nsVcpFlushRequest == 0); ++ NS_ASSERT(vcpup->nsVcpWaitingOnGFS == 0); ++ NS_ASSERT(vcpup->nsVcpFlushPending == 0); ++ NS_ASSERT(vcpup->nsVcpWaitingForCleanup == 0); ++ /* ++ * We don't need to save state for a ++ * vcpu that is down; the restore ++ * code will leave it down if there is nothing saved. ++ */ ++ if ( test_bit(_VPF_down, &v->pause_flags) ) ++ continue; ++ ctxt.control_msr = vcpup->nsVcpSControlMsr; ++ ctxt.version_msr = vcpup->nsVcpSVersionMsr; ++ ctxt.sief_msr = vcpup->nsVcpSIefpMsr; ++ ctxt.simp_msr = vcpup->nsVcpSimpMsr; ++ ctxt.eom_msr = vcpup->nsVcpEomMsr; ++ for (i=0; i < 16; i++) ++ ctxt.int_msr[i] = vcpup->nsVcpSIntMsr[i]; ++ for (i=0; i < 4; i++) { ++ ctxt.timers[i].config = vcpup->nsVcpTimers[i].config; ++ /* ++ * Save the count in units of 100ns relative to NOW() ++ * When we restore we will add NOW() to properly ++ * account for the elapsed time when the timer was ++ * active. ++ */ ++ if (vcpup->nsVcpTimers[i].count > ((NOW())/100)) { ++ ctxt.timers[i].count = ++ (vcpup->nsVcpTimers[i].count - ((NOW())/100)); ++ } else { ++ ctxt.timers[i].count = 0; ++ } ++ } ++ if ( hvm_save_entry(NS_VERIDIAN_CPU, ++ v->vcpu_id, h, &ctxt) != 0 ) ++ return 1; ++ } ++ ++ return 0; ++} ++ ++/* ++ * static int nsVcpuRestore(struct domain *d, hvm_domain_context_t *h) ++ * Restore per-cpu shim state to support either migration or domain save. ++ * ++ * Calling exit state: ++ * None. ++ */ ++static int ++nsVcpuRestore(struct domain *d, hvm_domain_context_t *h) ++{ ++ int vcpuid, i; ++ struct hvm_ns_veridian_cpu ctxt; ++ ++ nsVcpu_t *vcpup; ++ nsPartition_t *curp = d->arch.hvm_domain.ext_handle; ++ ++ if (curp == NULL) { ++ return 0; ++ } ++ /* Which vcpu is this? */ ++ vcpuid = hvm_load_instance(h); ++ vcpup = &curp->nsVcpuState[vcpuid]; ++ NS_ASSERT(vcpup != NULL); ++ if ( hvm_load_entry(NS_VERIDIAN_CPU, h, &ctxt) != 0 ) ++ return -22; ++ ++ vcpup->nsVcpSControlMsr = ctxt.control_msr; ++ vcpup->nsVcpSVersionMsr = ctxt.version_msr; ++ ++ nsWriteSxMsr(NS_MSR_SIEFP, curp, vcpup, ctxt.sief_msr); ++ nsWriteSxMsr(NS_MSR_SIMP, curp, vcpup, ctxt.simp_msr); ++ ++ vcpup->nsVcpEomMsr = ctxt.eom_msr; ++ for (i=0; i<16; i++) ++ vcpup->nsVcpSIntMsr[i] = ctxt.int_msr[i]; ++ for (i=0; i < 4; i++) { ++ vcpup->nsVcpTimers[i].config = ctxt.timers[i].config; ++ vcpup->nsVcpTimers[i].count = ++ (ctxt.timers[i].count + ((NOW())/100)); ++ if ((vcpup->nsVcpTimers[i].config | 0x9)) { ++ /* ++ * XXXKYS: Some issues with regards to time ++ * management here: ++ * 1) We will ignore the elapsed wall clock time ++ * when the domain was not running. ++ * 2) Clearly we should account fot the time that ++ * has elapsed when the domain was running with ++ * respect to the timeouts that were scheduled ++ * prior to saving the domain. ++ * We will deal with on the save side. ++ */ ++ nsScheduleTimeOut(&vcpup->nsVcpTimers[i]); ++ NS_STATS_COLLECT(NS_TIMEOUTS, &vcpup->nsVcpStats); ++ } ++ } ++ ++ vcpup->nsVcpuFlags |= NS_VCPU_UP; ++ return 0; ++} ++ ++ ++ ++/* ++ * static int nsDomSave(struct domain *d, hvm_domain_context_t *h) ++ * Save per-domain shim state to support either migration or domain save. ++ * ++ * Calling exit state: ++ * None. ++ */ ++ ++static int ++nsDomSave(struct domain *d, hvm_domain_context_t *h) ++{ ++ struct hvm_ns_veridian_dom ctxt; ++ nsPartition_t *curp = d->arch.hvm_domain.ext_handle; ++ ++ if (curp == NULL) { ++ return 0; ++ } ++ ++ ctxt.guestid_msr = curp->nsGuestIdMsr; ++ ctxt.hypercall_msr = curp->nsHypercallMsr; ++ ctxt.long_mode = curp->nsLongModeGuest; ++ ctxt.pad0 = 0; ++ return (hvm_save_entry(NS_VERIDIAN_DOM, 0, h, &ctxt)); ++} ++ ++/* ++ * static int nsDomRestore(struct domain *d, hvm_domain_context_t *h) ++ * Restore per-domain shim state to support either migration or domain save. ++ * ++ * Calling exit state: ++ * None. ++ */ ++ ++static int ++nsDomRestore(struct domain *d, hvm_domain_context_t *h) ++{ ++ struct hvm_ns_veridian_dom ctxt; ++ nsPartition_t *curp = d->arch.hvm_domain.ext_handle; ++ ++ if (curp == NULL) { ++ return 0; ++ } ++ ++ if ( hvm_load_entry(NS_VERIDIAN_DOM, h, &ctxt) != 0 ) ++ return -22; ++ curp->nsGuestIdMsr = ctxt.guestid_msr; ++ curp->nsHypercallMsr = ctxt.hypercall_msr; ++ curp->nsLongModeGuest = ctxt.long_mode; ++ curp->nsHypercallMfn = ++ nsXenVector.extGetMfnFromGmfn(d, (ctxt.hypercall_msr >> 12)); ++ ++ return 0; ++} ++ ++HVM_REGISTER_SAVE_RESTORE(NS_VERIDIAN_DOM, nsDomSave, nsDomRestore, ++ 1, HVMSR_PER_DOM); ++ ++ ++HVM_REGISTER_SAVE_RESTORE(NS_VERIDIAN_CPU, nsVcpuSave , nsVcpuRestore, ++ 1, HVMSR_PER_VCPU); ++ ++ ++/* ++ * static int ++ * nsPreProcessCpuIdLeaves(unsigned int input, struct cpu_user_regs *regs) ++ * ++ * Preprocess cpuid leaves. Both xen and Veridian use identical cpuid ++ * leaves for getting info from the hypervisor. ++ * ++ * Calling exit state: ++ * None. ++ */ ++static int ++nsPreProcessCpuIdLeaves(unsigned int input, struct cpu_user_regs *regs) ++{ ++ uint32_t idx; ++ struct domain *d = current->domain; ++ int extid = d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR]; ++ ++ if (extid == 1) { ++ /* ++ * Enlightened Windows guest; need to remap and handle ++ * leaves used by PV front-end drivers. ++ */ ++ if ((input >= 0x40000000) && (input <= 0x40000005)) { ++ return (0); ++ } ++ /* ++ * PV drivers use cpuid to query the hypervisor for details. On ++ * Windows we will use the following leaves for this: ++ * ++ * 4096: VMM Sinature (corresponds to 0x40000000 on Linux) ++ * 4097: VMM Version (corresponds to 0x40000001 on Linux) ++ * 4098: Hypercall details (corresponds to 0x40000002 on Linux) ++ */ ++ if ((input >= 0x40001000) && (input <= 0x40001002)) { ++ idx = (input - 0x40001000); ++ switch (idx) { ++ case 0: ++ regs->eax = 0x40000002; /* Largest leaf */ ++ regs->ebx = 0x566e6558;/*Signature 1: "XenV" */ ++ regs->ecx = 0x65584d4d; /*Signature 2: "MMXe" */ ++ regs->edx = 0x4d4d566e; /*Signature 3: "nVMM"*/ ++ break; ++ case 1: ++ regs->eax = ++ (XEN_VERSION << 16) | ++ XEN_SUBVERSION; ++ regs->ebx = 0; /* Reserved */ ++ regs->ecx = 0; /* Reserved */ ++ regs->edx = 0; /* Reserved */ ++ break; ++ ++ case 2: ++ regs->eax = 1; /*Number of hypercall-transfer pages*/ ++ /*In linux this is 0x40000000 */ ++ regs->ebx = 0x40001000; /* MSR base address */ ++ regs->ecx = 0; /* Features 1 */ ++ regs->edx = 0; /* Features 2 */ ++ break; ++ } ++ } ++ return (1); ++ } else { ++ /* ++ * For now this is all other "enlightened guests" ++ */ ++ if ((input >= 0x40000000) && (input <= 0x40000002)) { ++ /* ++ * These leaves have already been correctly ++ * processed; just return. ++ */ ++ return (1); ++ } ++ return (0); ++ } ++} ++ ++/* ++ * static int ++ * nsDoCpuId(unsigned int input, struct cpu_user_regs *regs) ++ * NS intercept for cpuid instruction ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static int ++nsDoCpuId(unsigned int input, struct cpu_user_regs *regs) ++{ ++ uint32_t idx; ++ ++ /* ++ * hvmloader uses cpuid to set up a hypercall page; we don't want to ++ * intercept calls coming from the bootstrap (bios) code in the HVM ++ * guest; we discriminate based on the instruction pointer. ++ */ ++ if (nsCallFromBios(regs)) { ++ /* ++ * We don't intercept this. ++ */ ++ return (0); ++ } ++ ++ if (input == 0x00000001) { ++ regs->ecx = (regs->ecx | 0x80000000); ++ return (1); ++ } ++ ++ if (nsPreProcessCpuIdLeaves(input, regs)) { ++ return (0); ++ } ++ idx = (input - 0x40000000); ++ ++ switch (idx) { ++ case 0: ++ /* ++ * 0x40000000: Hypervisor identification. ++ */ ++ regs->eax = 0x40000005; /* For now clamp this */ ++ regs->ebx = 0x65766f4e; /* "Nove" */ ++ regs->ecx = 0x68536c6c; /* "llSh" */ ++ regs->edx = 0x76486d69; /* "imHv" */ ++ break; ++ ++ case 1: ++ /* ++ * 0x40000001: Hypervisor identification. ++ */ ++ regs->eax = 0x31237648; /* "Hv#1*/ ++ regs->ebx = 0; /* Reserved */ ++ regs->ecx = 0; /* Reserved */ ++ regs->edx = 0; /* Reserved */ ++ break; ++ case 2: ++ /* ++ * 0x40000002: Guest Info ++ */ ++ if (nsOsRegistered()) { ++ regs->eax = nsGetGuestMajor(); ++ regs->ebx = ++ (nsGetGuestMajor() << 16) | nsGetGuestMinor(); ++ regs->ecx = nsGetGuestServicePack(); ++ regs->edx = ++ (nsGetGuestServiceBranchInfo() << 24) | ++ nsGetGuestServiceNumber(); ++ } else { ++ regs->eax = 0; ++ regs->ebx = 0; ++ regs->ecx = 0; ++ regs->edx = 0; ++ } ++ break; ++ case 3: ++ /* ++ * 0x40000003: Feature identification. ++ */ ++ regs->eax = nsGetSupportedSyntheticMsrs(); ++ /* We only support AcessSelfPartitionId bit 1 */ ++ regs->ebx = 0x2; ++ regs->ecx = 0; /* Reserved */ ++ regs->edx = 0; /*No MWAIT (bit 0), No debugging (bit 1)*/ ++ break; ++ case 4: ++ /* ++ * 0x40000004: Imlementation recommendations. ++ */ ++ regs->eax = nsGetRecommendations(); ++ regs->ebx = 0; /* Reserved */ ++ regs->ecx = 0; /* Reserved */ ++ regs->edx = 0; /* Reserved */ ++ break; ++ case 5: ++ /* ++ * 0x40000005: Implementation limits. ++ * Currently we retrieve maximum number of vcpus and ++ * logical processors (hardware threads) supported. ++ */ ++ regs->eax = nsGetMaxVcpusSupported(); ++ regs->ebx = nsGetMaxLcpusSupported(); ++ regs->ecx = 0; /* Reserved */ ++ regs->edx = 0; /* Reserved */ ++ break; ++ ++ default: ++ /* ++ * We don't handle this leaf. ++ */ ++ return (0); ++ ++ } ++ return (1); ++} ++ ++/* ++ * static int ++ * nsDoRdMsr(uint32_t idx, struct cpu_user_regs *regs) ++ * NS intercept for reading MSRS. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static int ++nsDoRdMsr(uint32_t idx, struct cpu_user_regs *regs) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ unsigned int vcpuIndex = nsGetCurrentVcpuIndex(); ++ u64 msrContent = 0; ++ nsVcpu_t *curVcpu = &curp->nsVcpuState[vcpuIndex]; ++ int synInt, timer; ++ struct domain *d = current->domain; ++ int extid = d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR]; ++ u64 timerCount; ++ ++ /* ++ * hvmloader uses rdmsr; we don't want to ++ * intercept calls coming from the bootstrap (bios) code in the HVM ++ * guest; we descriminate based on the instruction pointer. ++ */ ++ if (nsCallFromBios(regs)) { ++ /* ++ * We don't intercept this. ++ */ ++ return (0); ++ } ++ if (extid > 1) { ++ /* ++ * For now this is all other "Enlightened" operating systems ++ * other than Longhorn. ++ */ ++ if (idx == 0x40000000) { ++ /* ++ * PV driver hypercall setup. Let xen handle this. ++ */ ++ return (0); ++ } ++ if (idx == 0x40001000) { ++ idx = 0x40000000; ++ } ++ } ++ switch (idx) { ++ case NS_MSR_GUEST_OS_ID: ++ nsLockAcquire(curVcpu, &curp->nsLock); ++ regs->eax = (u32)(curp->nsGuestIdMsr & 0xFFFFFFFF); ++ regs->edx = (u32)(curp->nsGuestIdMsr >> 32); ++ nsLockRelease(curVcpu, &curp->nsLock); ++ break; ++ case NS_MSR_HYPERCALL: ++ nsLockAcquire(curVcpu, &curp->nsLock); ++ regs->eax = (u32)(curp->nsHypercallMsr & 0xFFFFFFFF); ++ regs->edx = (u32)(curp->nsHypercallMsr >> 32); ++ nsLockRelease(curVcpu, &curp->nsLock); ++ if ((((u32)curp->nsHypercallMsr) & (0x00000001)) != 0) { ++ curVcpu->nsVcpuFlags |= NS_VCPU_UP; ++ } ++ break; ++ case NS_MSR_VP_INDEX: ++ regs->eax = (u32)(vcpuIndex); ++ regs->edx = (u32)(0x0); ++ break; ++ case NS_MSR_ICR: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_APIC_MSRS)) { ++ goto msrReadError; ++ } ++ nsReadIcr(&msrContent); ++ NS_STATS_COLLECT(NS_ICR_READ, &curVcpu->nsVcpStats); ++ regs->eax = (u32)(msrContent & 0xFFFFFFFF); ++ regs->edx = (u32)(msrContent >> 32); ++ break; ++ case NS_MSR_TPR: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_APIC_MSRS)) { ++ goto msrReadError; ++ } ++ nsReadTpr(&msrContent); ++ NS_STATS_COLLECT(NS_TPR_READ, &curVcpu->nsVcpStats); ++ regs->eax = (u32)(msrContent & 0xFFFFFFFF); ++ regs->edx = (u32)(msrContent >> 32); ++ break; ++ /* ++ * The following synthetic MSRs are implemented in the Novell Shim. ++ */ ++ case NS_MSR_SCONTROL: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrReadError; ++ } ++ regs->eax = (u32)(curVcpu->nsVcpSControlMsr & 0xFFFFFFFF); ++ regs->edx = (u32)(curVcpu->nsVcpSControlMsr >> 32); ++ break; ++ case NS_MSR_SVERSION: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrReadError; ++ } ++ regs->eax = (u32)(curVcpu->nsVcpSVersionMsr & 0xFFFFFFFF); ++ regs->edx = (u32)(curVcpu->nsVcpSVersionMsr >> 32); ++ break; ++ case NS_MSR_SIEFP: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrReadError; ++ } ++ regs->eax = (u32)(curVcpu->nsVcpSIefpMsr & 0xFFFFFFFF); ++ regs->edx = (u32)(curVcpu->nsVcpSIefpMsr >> 32); ++ break; ++ case NS_MSR_SIMP: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrReadError; ++ } ++ regs->eax = (u32)(curVcpu->nsVcpSimpMsr & 0xFFFFFFFF); ++ regs->edx = (u32)(curVcpu->nsVcpSimpMsr >> 32); ++ break; ++ case NS_MSR_SINT0: ++ synInt = 0; ++ goto synIntReadProcess; ++ case NS_MSR_SINT1: ++ synInt = 1; ++ goto synIntReadProcess; ++ case NS_MSR_SINT2: ++ synInt = 2; ++ goto synIntReadProcess; ++ case NS_MSR_SINT3: ++ synInt = 3; ++ goto synIntReadProcess; ++ case NS_MSR_SINT4: ++ synInt = 4; ++ goto synIntReadProcess; ++ case NS_MSR_SINT5: ++ synInt = 5; ++ goto synIntReadProcess; ++ case NS_MSR_SINT6: ++ synInt = 6; ++ goto synIntReadProcess; ++ case NS_MSR_SINT7: ++ synInt = 7; ++ goto synIntReadProcess; ++ case NS_MSR_SINT8: ++ synInt = 8; ++ goto synIntReadProcess; ++ case NS_MSR_SINT9: ++ synInt = 9; ++ goto synIntReadProcess; ++ case NS_MSR_SINT10: ++ synInt = 10; ++ goto synIntReadProcess; ++ case NS_MSR_SINT11: ++ synInt = 11; ++ goto synIntReadProcess; ++ case NS_MSR_SINT12: ++ synInt = 12; ++ goto synIntReadProcess; ++ case NS_MSR_SINT13: ++ synInt = 13; ++ goto synIntReadProcess; ++ case NS_MSR_SINT14: ++ synInt = 14; ++ goto synIntReadProcess; ++ case NS_MSR_SINT15: ++ synInt = 15; ++synIntReadProcess: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrReadError; ++ } ++ regs->eax = (u32)(curVcpu->nsVcpSIntMsr[synInt] & 0xFFFFFFFF); ++ regs->edx = (u32)(curVcpu->nsVcpSIntMsr[synInt] >> 32); ++ break; ++ ++ case NS_MSR_SEOM: ++ /* ++ * This is a write only register; reads return 0. ++ */ ++ regs->eax = 0; ++ regs->edx = 0; ++ break; ++ case NS_MSR_TIME_REF_COUNT: ++ if (!nsAccessTimeRefCnt(curp, &msrContent)) { ++ goto msrReadError; ++ } ++ regs->eax = (u32)(msrContent & 0xFFFFFFFF); ++ regs->edx = (u32)(msrContent >> 32); ++ break; ++ /* ++ * Synthetic timer MSRs. ++ */ ++ case NS_MSR_TIMER0_CONFIG: ++ timer = 0; ++ goto processTimerConfigRead; ++ case NS_MSR_TIMER1_CONFIG: ++ timer = 1; ++ goto processTimerConfigRead; ++ case NS_MSR_TIMER2_CONFIG: ++ timer = 2; ++ goto processTimerConfigRead; ++ case NS_MSR_TIMER3_CONFIG: ++ timer = 3; ++processTimerConfigRead: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_TIMERS)) { ++ goto msrReadError; ++ } ++ regs->eax = ++ (u32)(curVcpu->nsVcpTimers[timer].config & 0xFFFFFFFF); ++ regs->edx = ++ (u32)(curVcpu->nsVcpTimers[timer].config >> 32); ++ break; ++ case NS_MSR_TIMER0_COUNT: ++ timer = 0; ++ goto processTimerCountRead; ++ case NS_MSR_TIMER1_COUNT: ++ timer = 1; ++ goto processTimerCountRead; ++ case NS_MSR_TIMER2_COUNT: ++ timer = 2; ++ goto processTimerCountRead; ++ case NS_MSR_TIMER3_COUNT: ++ timer = 3; ++processTimerCountRead: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_TIMERS)) { ++ goto msrReadError; ++ } ++ timerCount = curVcpu->nsVcpTimers[timer].count; ++ if (timerCount > ((NOW())/100)) { ++ timerCount -= ((NOW())/100); ++ } else { ++ timerCount = 0; ++ } ++ regs->eax = ++ (u32)(timerCount & 0xFFFFFFFF); ++ regs->edx = ++ (u32)(timerCount >> 32); ++ break; ++ case NS_MSR_PVDRV_HCALL: ++ regs->eax = 0; ++ regs->edx = 0; ++ break; ++ case NS_MSR_SYSTEM_RESET: ++ regs->eax = 0; ++ regs->edx = 0; ++ break; ++ default: ++ /* ++ * We did not handle the MSR address specified; ++ * let the caller figure out ++ * What to do. ++ */ ++ return (0); ++ } ++ return (1); ++msrReadError: ++ /* ++ * Have to inject #GP fault. ++ */ ++ nsInjectException(TRAP_gp_fault); ++ return (1); ++} ++ ++/* ++ * static int ++ * nsDoWrMsr(uint32_t idx, struct cpu_user_regs *regs) ++ * NS intercept for writing MSRS. ++ * ++ * Calling/Exit State: ++ * None. ++ */ ++ ++static int ++nsDoWrMsr(uint32_t idx, struct cpu_user_regs *regs) ++{ ++ nsPartition_t *curp = nsGetCurrentPartition(); ++ unsigned int vcpuIndex = nsGetCurrentVcpuIndex(); ++ u64 msrContent = 0; ++ nsVcpu_t *curVcpu = &curp->nsVcpuState[vcpuIndex]; ++ int synInt, timer; ++ struct domain *d = current->domain; ++ int extid = d->arch.hvm_domain.params[HVM_PARAM_EXTEND_HYPERVISOR]; ++ ++ /* ++ * hvmloader uses wrmsr; we don't want to ++ * intercept calls coming from the bootstrap (bios) code in the HVM ++ * guest; we descriminate based on the instruction pointer. ++ */ ++ if (nsCallFromBios(regs)) { ++ /* ++ * We don't intercept this. ++ */ ++ return (0); ++ } ++ msrContent = ++ (u32)regs->eax | ((u64)regs->edx << 32); ++ if (extid > 1) { ++ /* ++ * For now this is all other "Enlightened" operating systems ++ * other than Longhorn. ++ */ ++ if (idx == 0x40000000) { ++ /* ++ * PV driver hypercall setup. Let xen handle this. ++ */ ++ return (0); ++ } ++ if (idx == 0x40001000) { ++ idx = 0x40000000; ++ } ++ } ++ switch (idx) { ++ case NS_MSR_GUEST_OS_ID: ++ nsWriteGuestIdMsr(curp, curVcpu, msrContent); ++ break; ++ case NS_MSR_HYPERCALL: ++ nsWriteHypercallMsr(curp, curVcpu, msrContent); ++ break; ++ ++ case NS_MSR_VP_INDEX: ++ goto msrWriteError; ++ ++ case NS_MSR_EOI: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_APIC_MSRS)) { ++ goto msrWriteError; ++ } ++ nsWriteEoi(msrContent); ++ NS_STATS_COLLECT(NS_EOI_WRITE, &curVcpu->nsVcpStats); ++ break; ++ case NS_MSR_ICR: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_APIC_MSRS)) { ++ goto msrWriteError; ++ } ++ nsWriteIcr(msrContent); ++ NS_STATS_COLLECT(NS_ICR_WRITE, &curVcpu->nsVcpStats); ++ break; ++ case NS_MSR_TPR: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_APIC_MSRS)) { ++ goto msrWriteError; ++ } ++ nsWriteTpr(msrContent); ++ NS_STATS_COLLECT(NS_TPR_WRITE, &curVcpu->nsVcpStats); ++ break; ++ ++ /* ++ * The following MSRs are synthetic MSRs supported in the Novell Shim. ++ */ ++ case NS_MSR_SCONTROL: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrWriteError; ++ } ++ curVcpu->nsVcpSControlMsr = msrContent; ++ break; ++ case NS_MSR_SVERSION: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrWriteError; ++ } ++ /* ++ * This is a read-only MSR; generate #GP ++ */ ++ nsInjectException(TRAP_gp_fault); ++ break; ++ case NS_MSR_SIEFP: ++ case NS_MSR_SIMP: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrWriteError; ++ } ++ nsWriteSxMsr(idx, curp, curVcpu, msrContent); ++ break; ++ case NS_MSR_SINT0: ++ synInt = 0; ++ goto synIntWrProcess; ++ case NS_MSR_SINT1: ++ synInt = 1; ++ goto synIntWrProcess; ++ case NS_MSR_SINT2: ++ synInt = 2; ++ goto synIntWrProcess; ++ case NS_MSR_SINT3: ++ synInt = 3; ++ goto synIntWrProcess; ++ case NS_MSR_SINT4: ++ synInt = 4; ++ goto synIntWrProcess; ++ case NS_MSR_SINT5: ++ synInt = 5; ++ goto synIntWrProcess; ++ case NS_MSR_SINT6: ++ synInt = 6; ++ goto synIntWrProcess; ++ case NS_MSR_SINT7: ++ synInt = 7; ++ goto synIntWrProcess; ++ case NS_MSR_SINT8: ++ synInt = 8; ++ goto synIntWrProcess; ++ case NS_MSR_SINT9: ++ synInt = 9; ++ goto synIntWrProcess; ++ case NS_MSR_SINT10: ++ synInt = 10; ++ goto synIntWrProcess; ++ case NS_MSR_SINT11: ++ synInt = 11; ++ goto synIntWrProcess; ++ case NS_MSR_SINT12: ++ synInt = 12; ++ goto synIntWrProcess; ++ case NS_MSR_SINT13: ++ synInt = 13; ++ goto synIntWrProcess; ++ case NS_MSR_SINT14: ++ synInt = 14; ++ goto synIntWrProcess; ++ case NS_MSR_SINT15: ++ synInt = 15; ++synIntWrProcess: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrWriteError; ++ } ++ /* ++ * XXXKYS: We assume that the synInt registers will be ++ * first written before the interrupt generation can occur. ++ * Specifically if SINT is masked all interrupts that may have ++ * been generated will be lost. Also when SINT is disabled; ++ * its effects will be only felt for subsequent interrupts that ++ * may be posted. XXXKYS: CHECK ++ */ ++ curVcpu->nsVcpSIntMsr[synInt] = msrContent; ++ break; ++ ++ case NS_MSR_SEOM: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_MSRS)) { ++ goto msrWriteError; ++ } ++ curVcpu->nsVcpEomMsr = msrContent; ++ nsProcessMessageQ(curp, curVcpu); ++ break; ++ case NS_MSR_TIME_REF_COUNT: ++ /* ++ * This is a read-only msr. ++ */ ++ goto msrWriteError; ++ ++ /* ++ * Synthetic timer MSRs. ++ */ ++ case NS_MSR_TIMER0_CONFIG: ++ timer = 0; ++ goto processTimerConfig; ++ case NS_MSR_TIMER1_CONFIG: ++ timer = 1; ++ goto processTimerConfig; ++ case NS_MSR_TIMER2_CONFIG: ++ timer = 2; ++ goto processTimerConfig; ++ case NS_MSR_TIMER3_CONFIG: ++ timer = 3; ++processTimerConfig: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_TIMERS)) { ++ goto msrWriteError; ++ } ++ /* ++ * Assume that the client is going to write the whole msr. ++ */ ++ if (!(msrContent & 0x9)) { ++ /* ++ * We are neither setting Auto Enable or Enable; ++ * silently exit. ++ * Should this be considered to turn off a ++ * timer that may be currently ++ * active; XXXKYS: Check. For now we are ++ * not doing anything here. ++ */ ++ break; ++ } ++ if (!(((u32)(msrContent >> 16)) & 0x0000000f)) { ++ /* ++ * sintx is 0; clear the enable bit(s). ++ */ ++ msrContent &= ~(0x1); ++ } ++ curVcpu->nsVcpTimers[timer].config = msrContent; ++ /* ++ * XXXKYS: Can any order be assumed here; ++ * should we just act on whatever is in the ++ * count register. For now act as if the count ++ * register is valid and act on it. ++ */ ++ if (msrContent & 0x1) { ++ nsScheduleTimeOut(&curVcpu->nsVcpTimers[timer]); ++ NS_STATS_COLLECT(NS_TIMEOUTS, &curVcpu->nsVcpStats); ++ } ++ break; ++ case NS_MSR_TIMER0_COUNT: ++ timer = 0; ++ goto processTimerCount; ++ case NS_MSR_TIMER1_COUNT: ++ timer = 1; ++ goto processTimerCount; ++ case NS_MSR_TIMER2_COUNT: ++ timer = 2; ++ goto processTimerCount; ++ case NS_MSR_TIMER3_COUNT: ++ timer = 3; ++processTimerCount: ++ if (!nsPrivilegeCheck(curp, NS_ACCESS_SYNC_TIMERS)) { ++ goto msrWriteError; ++ } ++ curVcpu->nsVcpTimers[timer].count = ++ (msrContent + ((NOW())/100)); ++ if ((curVcpu->nsVcpTimers[timer].config | 0x9)) { ++ nsScheduleTimeOut(&curVcpu->nsVcpTimers[timer]); ++ NS_STATS_COLLECT(NS_TIMEOUTS, &curVcpu->nsVcpStats); ++ } ++ ++ break; ++ case NS_MSR_PVDRV_HCALL: ++ /* ++ * Establish the hypercall page for PV drivers. ++ */ ++ nsXenVector.extWrmsrHypervisorRegs(0x40000000, regs->eax, ++ regs->edx); ++ break; ++ case NS_MSR_SYSTEM_RESET: ++ /* ++ * Shutdown the domain/partition. ++ */ ++ if (msrContent & 0x1) { ++ domain_shutdown(d, SHUTDOWN_reboot); ++ } ++ break; ++ ++ default: ++ /* ++ * We did not handle the MSR address; ++ * let the caller deal with this. ++ */ ++ return (0); ++ } ++ return (1); ++msrWriteError: ++ /* ++ * Have to inject #GP fault. ++ */ ++ nsInjectException(TRAP_gp_fault); ++ return (1); ++} diff --git a/pv-driver-build.patch b/pv-driver-build.patch index e2c9bfc..82441ed 100644 --- a/pv-driver-build.patch +++ b/pv-driver-build.patch @@ -24,3 +24,18 @@ Index: xen-3.2-testing/unmodified_drivers/linux-2.6/compat-include/xen/platform- #define setup_xen_features xen_setup_features #endif +Index: xen-3.2-testing/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c +=================================================================== +--- xen-3.2-testing.orig/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c ++++ xen-3.2-testing/unmodified_drivers/linux-2.6/platform-pci/platform-compat.c +@@ -119,7 +119,9 @@ void *kzalloc(size_t size, int flags) + EXPORT_SYMBOL(kzalloc); + #endif + +-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) ++#if defined(CONFIG_SUSE_KERNEL) \ ++ ? LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16) \ ++ : LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) + /* Simplified asprintf. */ + char *kasprintf(gfp_t gfp, const char *fmt, ...) + { diff --git a/pv_32_16_color_trans.patch b/pv_32_16_color_trans.patch new file mode 100644 index 0000000..eaf9e97 --- /dev/null +++ b/pv_32_16_color_trans.patch @@ -0,0 +1,39 @@ +Index: xen-3.2-testing/tools/ioemu/hw/xenfb.c +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/hw/xenfb.c 2008-02-26 07:38:20.000000000 -0700 ++++ xen-3.2-testing/tools/ioemu/hw/xenfb.c 2008-02-26 07:43:56.000000000 -0700 +@@ -1103,6 +1103,25 @@ + } \ + } + ++/* 32 bit to 16 bit pixel munging, dst algo came from RealVNC transInitTempl.h */ ++#define BLT_32_16(SRC_T,DST_T,RRS,GRS,BRS,RLS,GLS,BLS,RIM,GIM,BIM,ROM,GOM,BOM) \ ++ for (line = y ; line < h ; line++) { \ ++ SRC_T *src = (SRC_T *)(xenfb->pixels \ ++ + (line * xenfb->row_stride) \ ++ + (x * xenfb->depth / 8)); \ ++ DST_T *dst = (DST_T *)(xenfb->ds->data \ ++ + (line * xenfb->ds->linesize) \ ++ + (x * xenfb->ds->depth / 8)); \ ++ int col; \ ++ for (col = x ; col < w ; col++) { \ ++ *dst = ((((*src >> RRS & RIM) * ROM + RIM/2) / RIM) << RLS) | \ ++ ((((*src >> GRS & GIM) * GOM + GIM/2) / GIM) << GLS ) | \ ++ ((((*src >> BRS & BIM) * BOM + BIM/2) / BIM) << BLS); \ ++ src++; \ ++ dst++; \ ++ } \ ++ } ++ + + /* This copies data from the guest framebuffer region, into QEMU's copy + * NB. QEMU's copy is stored in the pixel format of a) the local X +@@ -1139,7 +1158,7 @@ + if (xenfb->ds->depth == 8) { + BLT(uint32_t, uint8_t, 16, 8, 0, 5, 2, 0, 255, 255, 255); + } else if (xenfb->ds->depth == 16) { +- BLT(uint32_t, uint16_t, 16, 8, 0, 11, 5, 0, 255, 255, 255); ++ BLT_32_16(uint32_t, uint16_t, 16, 8, 0, 11, 5, 0, 255, 255, 255, 31, 63, 31); + } + } + } diff --git a/pvdrv_emulation_control.patch b/pvdrv_emulation_control.patch new file mode 100644 index 0000000..1fd2bfe --- /dev/null +++ b/pvdrv_emulation_control.patch @@ -0,0 +1,24 @@ +Index: xen-3.2-testing/tools/ioemu/hw/xen_platform.c +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/hw/xen_platform.c ++++ xen-3.2-testing/tools/ioemu/hw/xen_platform.c +@@ -57,6 +57,19 @@ static void platform_ioport_write(void * + net_tap_shutdown_all(); + fprintf(logfile, "Done.\n"); + break; ++ case 8: ++ if (val ==1 ) { ++ fprintf(logfile, "Disconnect IDE hard disk...\n"); ++ ide_unplug_harddisks(); ++ fprintf(logfile, "Done.\n"); ++ } else if (val == 2) { ++ fprintf(logfile, "Disconnect netifs...\n"); ++ pci_unplug_netifs(); ++ fprintf(logfile, "Shutdown taps...\n"); ++ net_tap_shutdown_all(); ++ fprintf(logfile, "Done.\n"); ++ } ++ break; + default: + fprintf(logfile, "Write to bad port %x (base %x) on evtchn device.\n", + addr, ioport_base); diff --git a/svm-cr8-performance.diff b/svm-cr8-performance.diff deleted file mode 100644 index 3e38cce..0000000 --- a/svm-cr8-performance.diff +++ /dev/null @@ -1,85 +0,0 @@ -[SVM] Greatly reduce total number of CR8 intercepts - -This patch reduces the number of CR8 intercept to a fraction of the -number of CR8 intercepts without. First, CR8 read intercepts are -completely disabled since the SVM vTPR is kept kept in sync with the HVM -vLAPIC. Second, CR8 write intercepts are enabled and disabled based -upon certain conditions. Most of the time, CR8 write intercepts are -disabled. They are enabled only when there is a pending interrupt that -can't be delivered because of either the current ISR or TPR (aka PPR) -because this is the only time the TPR matters. - -With this patch, the number of CR8 intercepts dropped from around -10,000,000 to around 6,000 during boot of Windows 2003 Server 64-bit -(this is a rough estimate). - -Signed-off-by: Travis Betak - -Index: xen-3.1-testing/xen/arch/x86/hvm/svm/intr.c -=================================================================== ---- xen-3.1-testing.orig/xen/arch/x86/hvm/svm/intr.c -+++ xen-3.1-testing/xen/arch/x86/hvm/svm/intr.c -@@ -63,9 +63,20 @@ static inline int svm_inject_extint(stru - asmlinkage void svm_intr_assist(void) - { - struct vcpu *v = current; -+ struct vlapic *vlapic = vcpu_vlapic(v); - struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; - int intr_type = APIC_DM_EXTINT; - int intr_vector = -1; -+ vintr_t *intr = &vmcb->vintr; -+ -+ /* -+ * Before doing anything else, we need to sync up the VLAPIC's TPR with -+ * SVM's vTPR if CR8 writes are currently disabled. It's OK if the -+ * guest doesn't touch the CR8 (e.g. 32-bit Windows) because we update -+ * the vTPR on MMIO writes to the TPR -+ */ -+ if ( !(vmcb->cr_intercepts & CR_INTERCEPT_CR8_WRITE) ) -+ vlapic_set_reg(vlapic, APIC_TASKPRI, (intr->fields.tpr & 0x0F) << 4); - - /* - * Previous Interrupt delivery caused this intercept? -@@ -98,7 +109,22 @@ asmlinkage void svm_intr_assist(void) - pt_update_irq(v); - hvm_set_callback_irq_level(); - if ( !cpu_has_pending_irq(v) ) -+ { -+ /* -+ * Before we return, let's check if there is a pending interrupt -+ * that just happens to be blocked (either ISR or TPR aka PPR). -+ * Enable CR8 write intercepts in case the guest unmasks the -+ * pending interrupt. -+ */ -+ if ( vlapic_enabled(vlapic) -+ && (vlapic_find_highest_irr(vlapic) != -1) ) -+ vmcb->cr_intercepts |= CR_INTERCEPT_CR8_WRITE; -+ - return; -+ } -+ -+ /* It should be fairly safe to disable CR8 write intercepts here */ -+ vmcb->cr_intercepts &= ~CR_INTERCEPT_CR8_WRITE; - - /* - * If the guest can't take an interrupt right now, create a 'fake' -Index: xen-3.1-testing/xen/arch/x86/hvm/svm/vmcb.c -=================================================================== ---- xen-3.1-testing.orig/xen/arch/x86/hvm/svm/vmcb.c -+++ xen-3.1-testing/xen/arch/x86/hvm/svm/vmcb.c -@@ -130,8 +130,13 @@ static int construct_vmcb(struct vcpu *v - /* Intercept all debug-register writes. */ - vmcb->dr_intercepts = DR_INTERCEPT_ALL_WRITES; - -- /* Intercept all control-register accesses, except to CR2. */ -- vmcb->cr_intercepts = ~(CR_INTERCEPT_CR2_READ | CR_INTERCEPT_CR2_WRITE); -+ /* -+ * Intercept all control-register accesses except for CR2 reads/writes -+ * and CR8 reads (and actually CR8 writes, but that's a special case -+ * that's handled in svm/intr.c). -+ */ -+ vmcb->cr_intercepts = ~(CR_INTERCEPT_CR2_READ | CR_INTERCEPT_CR2_WRITE -+ | CR_INTERCEPT_CR8_READ); - - /* I/O and MSR permission bitmaps. */ - arch_svm->msrpm = alloc_xenheap_pages(get_order_from_bytes(MSRPM_SIZE)); diff --git a/sysconfig.xend b/sysconfig.xend index fbc54e9..34135df 100644 --- a/sysconfig.xend +++ b/sysconfig.xend @@ -61,7 +61,7 @@ # # Used by network-multinet v3.x only # -NETWORK_LIST="bridge,0,default,default,dhcp-off nat,0,none,172.22.0.1/16,dhcp-off hostonly,0,none,172.23.0.1/16,dhcp-off empty,0,none,," +NETWORK_LIST="bridge,0,default,default,dhcp-off hostonly,0,none,172.23.0.1/16,dhcp-off" ## Type: string(eth0,eth1,eth2,eth3) ## Default: "eth0" diff --git a/vnc-i18n-keys.diff b/vnc-i18n-keys.diff index f1bf46c..0be1881 100644 --- a/vnc-i18n-keys.diff +++ b/vnc-i18n-keys.diff @@ -48,7 +48,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -1542,6 +1542,9 @@ class XendDomainInfo: +@@ -1556,6 +1556,9 @@ class XendDomainInfo: if devclass in XendDevices.valid_devices(): log.info("createDevice: %s : %s" % (devclass, scrub_password(config))) dev_uuid = config.get('uuid') diff --git a/vpid-novell.patch b/vpid-novell.patch new file mode 100644 index 0000000..61266d1 --- /dev/null +++ b/vpid-novell.patch @@ -0,0 +1,341 @@ +Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/vmcs.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/vmcs.c ++++ xen-3.2-testing/xen/arch/x86/hvm/vmx/vmcs.c +@@ -38,6 +38,9 @@ + #include + #include + ++static int opt_vpid_enabled = 1; ++boolean_param("vpid", opt_vpid_enabled); ++ + /* Dynamic (run-time adjusted) execution control flags. */ + u32 vmx_pin_based_exec_control __read_mostly; + u32 vmx_cpu_based_exec_control __read_mostly; +@@ -110,6 +113,8 @@ static void vmx_init_vmcs_config(void) + opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | + SECONDARY_EXEC_WBINVD_EXITING | + SECONDARY_EXEC_ENABLE_EPT; ++ if ( opt_vpid_enabled ) ++ opt2 |= SECONDARY_EXEC_ENABLE_VPID; + _vmx_secondary_exec_control = adjust_vmx_controls( + min2, opt2, MSR_IA32_VMX_PROCBASED_CTLS2); + +@@ -315,6 +320,8 @@ int vmx_cpu_up(void) + + ept_sync_all(); + ++ vpid_sync_all(); ++ + return 1; + } + +@@ -628,6 +635,13 @@ static int construct_vmcs(struct vcpu *v + #endif + } + ++ if ( cpu_has_vmx_vpid ) ++ { ++ v->arch.hvm_vmx.vpid = v->vcpu_id + ++ v->domain->arch.hvm_domain.vmx_vpid_base; ++ __vmwrite(VIRTUAL_PROCESSOR_ID, v->arch.hvm_vmx.vpid); ++ } ++ + vmx_vmcs_exit(v); + + paging_update_paging_modes(v); /* will update HOST & GUEST_CR3 as reqd */ +@@ -821,6 +835,7 @@ void vmx_do_resume(struct vcpu *v) + vmx_load_vmcs(v); + hvm_migrate_timers(v); + vmx_set_host_env(v); ++ vpid_sync_vcpu_all(v); + } + + debug_state = v->domain->debugger_attached; +@@ -975,6 +990,8 @@ void vmcs_dump_vcpu(struct vcpu *v) + (uint32_t)vmr(TPR_THRESHOLD)); + printk("EPT pointer = 0x%08x%08x\n", + (uint32_t)vmr(EPT_POINTER_HIGH), (uint32_t)vmr(EPT_POINTER)); ++ printk("virtual processor ID = 0x%04x\n", ++ (uint32_t)vmr(VIRTUAL_PROCESSOR_ID)); + + vmx_vmcs_exit(v); + } +Index: xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/hvm/vmx/vmx.c ++++ xen-3.2-testing/xen/arch/x86/hvm/vmx/vmx.c +@@ -58,18 +58,23 @@ static void vmx_ctxt_switch_to(struct vc + + static int vmx_alloc_vlapic_mapping(struct domain *d); + static void vmx_free_vlapic_mapping(struct domain *d); ++static int vmx_alloc_vpid(struct domain *d); ++static void vmx_free_vpid(struct domain *d); + static void vmx_install_vlapic_mapping(struct vcpu *v); + static void vmx_update_guest_cr(struct vcpu *v, unsigned int cr); + static void vmx_update_guest_efer(struct vcpu *v); + + static int vmx_domain_initialise(struct domain *d) + { +- return vmx_alloc_vlapic_mapping(d); ++ if ( vmx_alloc_vpid(d) == 0 ) ++ return vmx_alloc_vlapic_mapping(d); ++ return -EBUSY; + } + + static void vmx_domain_destroy(struct domain *d) + { + vmx_free_vlapic_mapping(d); ++ vmx_free_vpid(d); + } + + static int vmx_vcpu_initialise(struct vcpu *v) +@@ -1122,6 +1127,7 @@ static void vmx_update_guest_cr(struct v + vmx_load_pdptrs(v); + } + __vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr[3]); ++ vpid_sync_vcpu_all(v); + break; + case 4: + v->arch.hvm_vcpu.hw_cr[4] = HVM_CR4_HOST_MASK; +@@ -1170,9 +1176,14 @@ static void vmx_update_guest_efer(struct + + static void vmx_flush_guest_tlbs(void) + { +- /* No tagged TLB support on VMX yet. The fact that we're in Xen +- * at all means any guest will have a clean TLB when it's next run, +- * because VMRESUME will flush it for us. */ ++ /* If VPID (i.e. tagged TLB support) is not enabled, the fact that ++ * we're in Xen at all means any guest will have a clean TLB when ++ * it's next run, because VMRESUME will flush it for us. ++ * ++ * If enabled, we invalidate all translations associated with all ++ * VPID values */ ++ if (0) ++ vpid_sync_all(); + } + + static void vmx_inject_exception( +@@ -1226,6 +1237,11 @@ static struct hvm_function_table vmx_fun + .cpu_down = vmx_cpu_down, + }; + ++static int vpid_bitmap_size; ++static int vpid_bitmap_bytes; ++static void *vpid_bitmap; ++static spinlock_t vpid_lock; ++ + void start_vmx(void) + { + static int bootstrapped; +@@ -1265,6 +1281,26 @@ void start_vmx(void) + vmx_function_table.hap_supported = 1; + } + ++ if ( cpu_has_vmx_vpid ) ++ { ++ printk("VMX: VPID is available.\n"); ++ ++ vpid_bitmap_size = (1 << VMCS_VPID_WIDTH) / MAX_VIRT_CPUS; ++ vpid_bitmap_bytes = vpid_bitmap_size / (BITS_PER_LONG / BYTES_PER_LONG); ++ vpid_bitmap = xmalloc_bytes(vpid_bitmap_bytes); ++ memset(vpid_bitmap, 0, vpid_bitmap_bytes); ++ if ( vpid_bitmap == NULL ) ++ { ++ printk("VMX: failed to allocate VPID bitmap.\n"); ++ return; ++ } ++ ++ /* vpid 0 is used by hypervisor itself */ ++ set_bit(0, vpid_bitmap); ++ ++ spin_lock_init(&vpid_lock); ++ } ++ + setup_vmcs_dump(); + + hvm_enable(&vmx_function_table); +@@ -2534,6 +2570,45 @@ static void vmx_free_vlapic_mapping(stru + free_xenheap_page(mfn_to_virt(mfn)); + } + ++static int vmx_alloc_vpid(struct domain *d) ++{ ++ int vpid; ++ ++ if ( !cpu_has_vmx_vpid ) ++ return 0; ++ ++ spin_lock(&vpid_lock); ++ ++ vpid = find_first_zero_bit(vpid_bitmap, vpid_bitmap_size); ++ if ( vpid >= vpid_bitmap_size ) ++ { ++ spin_unlock(&vpid_lock); ++ printk("VPID is used up.\n"); ++ return -EBUSY; ++ } ++ if ( test_and_set_bit(vpid, vpid_bitmap) ) ++ { ++ spin_unlock(&vpid_lock); ++ printk("VPID allocation bug, fix your code!\n"); ++ return -EBUSY; ++ } ++ ++ spin_unlock(&vpid_lock); ++ ++ d->arch.hvm_domain.vmx_vpid_base = vpid * MAX_VIRT_CPUS; ++ return 0; ++} ++ ++static void vmx_free_vpid(struct domain *d) ++{ ++ if ( !cpu_has_vmx_vpid ) ++ return; ++ ++ spin_lock(&vpid_lock); ++ clear_bit(d->arch.hvm_domain.vmx_vpid_base / MAX_VIRT_CPUS, vpid_bitmap); ++ spin_unlock(&vpid_lock); ++} ++ + static void vmx_install_vlapic_mapping(struct vcpu *v) + { + paddr_t virt_page_ma, apic_page_ma; +Index: xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c +=================================================================== +--- xen-3.2-testing.orig/xen/arch/x86/mm/shadow/multi.c ++++ xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c +@@ -35,6 +35,7 @@ + #include + #include + #include ++#include + #include "private.h" + #include "types.h" + +@@ -3106,6 +3107,7 @@ sh_invlpg(struct vcpu *v, unsigned long + == SH_type_fl1_shadow ) + { + flush_tlb_local(); ++ vpid_sync_vcpu_all(v); + return 0; + } + +Index: xen-3.2-testing/xen/include/asm-x86/hvm/domain.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hvm/domain.h ++++ xen-3.2-testing/xen/include/asm-x86/hvm/domain.h +@@ -61,6 +61,7 @@ struct hvm_domain { + uint64_t params[HVM_NR_PARAMS]; + + unsigned long vmx_apic_access_mfn; ++ unsigned long vmx_vpid_base; + + /* Memory ranges with pinned cache attributes. */ + struct list_head pinned_cacheattr_ranges; +Index: xen-3.2-testing/xen/include/asm-x86/hvm/vmx/vmcs.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hvm/vmx/vmcs.h ++++ xen-3.2-testing/xen/include/asm-x86/hvm/vmx/vmcs.h +@@ -90,6 +90,8 @@ struct arch_vmx_struct { + u32 exec_control; + u32 secondary_exec_control; + ++ u16 vpid; ++ + #ifdef __x86_64__ + struct vmx_msr_state msr_state; + unsigned long shadow_gs; +@@ -156,6 +158,7 @@ extern u32 vmx_vmentry_control; + + #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 + #define SECONDARY_EXEC_ENABLE_EPT 0x00000002 ++#define SECONDARY_EXEC_ENABLE_VPID 0x00000020 + #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 + extern u32 vmx_secondary_exec_control; + +@@ -175,6 +178,8 @@ extern bool_t cpu_has_vmx_ins_outs_instr + (vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) + #define cpu_has_vmx_ept \ + (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_EPT) ++#define cpu_has_vmx_vpid \ ++ (vmx_secondary_exec_control & SECONDARY_EXEC_ENABLE_VPID) + + /* GUEST_INTERRUPTIBILITY_INFO flags. */ + #define VMX_INTR_SHADOW_STI 0x00000001 +@@ -184,6 +189,7 @@ extern bool_t cpu_has_vmx_ins_outs_instr + + /* VMCS field encodings. */ + enum vmcs_field { ++ VIRTUAL_PROCESSOR_ID = 0x00000000, + GUEST_ES_SELECTOR = 0x00000800, + GUEST_CS_SELECTOR = 0x00000802, + GUEST_SS_SELECTOR = 0x00000804, +@@ -323,6 +329,8 @@ enum vmcs_field { + HOST_RIP = 0x00006c16, + }; + ++#define VMCS_VPID_WIDTH (16) ++ + void vmx_disable_intercept_for_msr(struct vcpu *v, u32 msr); + int vmx_read_guest_msr(struct vcpu *v, u32 msr, u64 *val); + int vmx_write_guest_msr(struct vcpu *v, u32 msr, u64 val); +Index: xen-3.2-testing/xen/include/asm-x86/hvm/vmx/vmx.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/asm-x86/hvm/vmx/vmx.h ++++ xen-3.2-testing/xen/include/asm-x86/hvm/vmx/vmx.h +@@ -172,6 +172,7 @@ int vmx_realmode_io_complete(void); + #define VMRESUME_OPCODE ".byte 0x0f,0x01,0xc3\n" + #define VMWRITE_OPCODE ".byte 0x0f,0x79\n" + #define INVEPT_OPCODE ".byte 0x66,0x0f,0x38,0x80\n" /* m128,r64/32 */ ++#define INVVPID_OPCODE ".byte 0x66,0x0f,0x38,0x81\n" /* m128,r64/32 */ + #define VMXOFF_OPCODE ".byte 0x0f,0x01,0xc4\n" + #define VMXON_OPCODE ".byte 0xf3,0x0f,0xc7\n" + +@@ -277,6 +278,23 @@ static inline void __invept(int ext, u64 + : "memory"); + } + ++static inline void __invvpid(int ext, u16 vpid, u64 gva) ++{ ++ struct { ++ u64 vpid:16; ++ u64 rsvd:48; ++ u64 gva; ++ } __attribute__ ((packed)) operand = {vpid, 0, gva}; ++ ++ __asm__ __volatile__ ( INVVPID_OPCODE ++ MODRM_EAX_08 ++ /* CF==1 or ZF==1 --> rc = -1 */ ++ "ja 1f ; ud2 ; 1:\n" ++ : ++ : "a" (&operand), "c" (ext) ++ : "memory"); ++} ++ + static inline void __vmxoff(void) + { + asm volatile ( +@@ -329,6 +347,22 @@ static inline void ept_sync_all(void) + __invept(2, 0, 0); + } + ++static inline void vpid_sync_vcpu_all(struct vcpu *v) ++{ ++ if ( !cpu_has_vmx_vpid ) ++ return; ++ ++ __invvpid(1, v->arch.hvm_vmx.vpid, 0); ++} ++ ++static inline void vpid_sync_all(void) ++{ ++ if ( !cpu_has_vmx_vpid ) ++ return; ++ ++ __invvpid(2, 0, 0); ++} ++ + static inline void __vmx_inject_exception( + struct vcpu *v, int trap, int type, int error_code) + { diff --git a/x86_emulate.patch b/x86_emulate.patch index 203826d..31d07ca 100644 --- a/x86_emulate.patch +++ b/x86_emulate.patch @@ -101,7 +101,7 @@ Index: xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c =================================================================== --- xen-3.2-testing.orig/xen/arch/x86/mm/shadow/multi.c +++ xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c -@@ -4244,7 +4244,8 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u +@@ -4254,7 +4254,8 @@ sh_x86_emulate_cmpxchg(struct vcpu *v, u return rv; } @@ -111,7 +111,7 @@ Index: xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c sh_x86_emulate_cmpxchg8b(struct vcpu *v, unsigned long vaddr, unsigned long old_lo, unsigned long old_hi, unsigned long new_lo, unsigned long new_hi, -@@ -4280,6 +4281,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v, +@@ -4290,6 +4291,7 @@ sh_x86_emulate_cmpxchg8b(struct vcpu *v, shadow_unlock(v->domain); return rv; } @@ -119,7 +119,7 @@ Index: xen-3.2-testing/xen/arch/x86/mm/shadow/multi.c /**************************************************************************/ -@@ -4566,7 +4568,9 @@ struct paging_mode sh_paging_mode = { +@@ -4576,7 +4578,9 @@ struct paging_mode sh_paging_mode = { .shadow.detach_old_tables = sh_detach_old_tables, .shadow.x86_emulate_write = sh_x86_emulate_write, .shadow.x86_emulate_cmpxchg = sh_x86_emulate_cmpxchg, @@ -144,7 +144,7 @@ Index: xen-3.2-testing/xen/arch/x86/x86_emulate.c #endif #include -@@ -2978,60 +2981,64 @@ x86_emulate( +@@ -2986,60 +2989,64 @@ x86_emulate( src.val = x86_seg_gs; goto pop_seg; @@ -253,7 +253,7 @@ Index: xen-3.2-testing/xen/arch/x86/x86_emulate.c case 0xc8 ... 0xcf: /* bswap */ dst.type = OP_REG; -@@ -3041,7 +3048,7 @@ x86_emulate( +@@ -3049,7 +3056,7 @@ x86_emulate( { default: /* case 2: */ /* Undefined behaviour. Writes zero on all tested CPUs. */ diff --git a/xen-api-auth.patch b/xen-api-auth.patch new file mode 100644 index 0000000..f2d2acd --- /dev/null +++ b/xen-api-auth.patch @@ -0,0 +1,12 @@ +diff -r 854b4e5a009f tools/python/xen/xend/XendAuthSessions.py +--- a/tools/python/xen/xend/XendAuthSessions.py Tue Feb 05 16:42:18 2008 -0700 ++++ b/tools/python/xen/xend/XendAuthSessions.py Fri Feb 22 17:24:01 2008 -0700 +@@ -84,7 +84,7 @@ class XendAuthSessions: + # if PAM doesn't exist, let's ignore it + return False + +- pam_auth.start("login") ++ pam_auth.start("xen-api") + pam_auth.set_item(PAM.PAM_USER, username) + + def _pam_conv(auth, query_list, user_data = None): diff --git a/xen-domUloader.diff b/xen-domUloader.diff index 0a235dc..62e92ec 100644 --- a/xen-domUloader.diff +++ b/xen-domUloader.diff @@ -147,7 +147,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py from xen.xend.XendError import XendError, VmError from xen.xend.XendDevices import XendDevices from xen.xend.XendTask import XendTask -@@ -1498,6 +1498,10 @@ class XendDomainInfo: +@@ -1512,6 +1512,10 @@ class XendDomainInfo: deviceClass, config = self.info['devices'].get(dev_uuid) self._waitForDevice(deviceClass, config['devid']) @@ -158,7 +158,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py def _waitForDevice_destroy(self, deviceClass, devid, backpath): return self.getDeviceController(deviceClass).waitForDevice_destroy( devid, backpath) -@@ -2026,8 +2030,11 @@ class XendDomainInfo: +@@ -2050,8 +2054,11 @@ class XendDomainInfo: blexec = osdep.pygrub_path blcfg = None @@ -172,7 +172,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py if not disks: msg = "Had a bootloader specified, but no disks are bootable" -@@ -2038,13 +2045,10 @@ class XendDomainInfo: +@@ -2062,13 +2069,10 @@ class XendDomainInfo: devtype = devinfo[0] disk = devinfo[1]['uname'] @@ -189,7 +189,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py log.info("Mounting %s on %s." % (fn, BOOTLOADER_LOOPBACK_DEVICE)) -@@ -2056,7 +2060,9 @@ class XendDomainInfo: +@@ -2080,7 +2084,9 @@ class XendDomainInfo: from xen.xend import XendDomain dom0 = XendDomain.instance().privilegedDomain() @@ -200,3 +200,12 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py fn = BOOTLOADER_LOOPBACK_DEVICE try: +@@ -2091,7 +2097,7 @@ class XendDomainInfo: + log.info("Unmounting %s from %s." % + (fn, BOOTLOADER_LOOPBACK_DEVICE)) + +- dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE) ++ dom0.destroyDevice('tap', BOOTLOADER_LOOPBACK_DEVICE, rm_cfg = True) + + if blcfg is None: + msg = "Had a bootloader specified, but can't find disk" diff --git a/xen-fbback-resize.patch b/xen-fbback-resize.patch index ddfa382..939df20 100644 --- a/xen-fbback-resize.patch +++ b/xen-fbback-resize.patch @@ -1,152 +1,8 @@ -diff -r 15cfd1f8fa38 tools/ioemu/hw/xenfb.c ---- a/tools/ioemu/hw/xenfb.c Tue Jan 08 16:45:08 2008 +0000 -+++ b/tools/ioemu/hw/xenfb.c Thu Jan 17 12:16:49 2008 -0700 -@@ -8,6 +8,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -45,6 +46,7 @@ struct xenfb { - struct xs_handle *xsh; /* xs daemon handle */ - struct xenfb_device fb, kbd; - void *pixels; /* guest framebuffer data */ -+ void *old_pixels; /* guest FB data before remapping to extended */ - size_t fb_len; /* size of framebuffer */ - int row_stride; /* width of one row in framebuffer */ - int depth; /* colour depth of guest framebuffer */ -@@ -52,7 +54,9 @@ struct xenfb { - int height; /* pixel height of guest framebuffer */ - int abs_pointer_wanted; /* Whether guest supports absolute pointer */ - int button_state; /* Last seen pointer button state */ -- char protocol[64]; /* frontend protocol */ -+ char protocol[64]; /* frontend protocol */ -+ int otherend_bsize; /* frontend bit size */ -+ int gnttabdev; - }; - - /* Functions for frontend/backend state machine*/ -@@ -78,6 +82,9 @@ static void xenfb_invalidate(void *opaqu - static void xenfb_invalidate(void *opaque); - static void xenfb_screen_dump(void *opaque, const char *name); - static int xenfb_register_console(struct xenfb *xenfb); -+static int xenfb_send_resize(struct xenfb *xenfb, int width, int height); -+static void xenfb_map_extended_fb(struct xenfb *xenfb, int, int, int); -+static int xenfb_send_map_extended_done(struct xenfb *xenfb); - - /* - * Tables to map from scancode to Linux input layer keycode. -@@ -261,9 +268,19 @@ struct xenfb *xenfb_new(int domid, Displ - if (!xenfb->xsh) - goto fail; - -+ xenfb->gnttabdev = xc_gnttab_open(); -+ if (xenfb->gnttabdev == -1) { -+ fprintf(stderr, "FB: Can't open gnttab device\n"); -+ } -+ - xenfb->ds = ds; - xenfb_device_set_domain(&xenfb->fb, domid); - xenfb_device_set_domain(&xenfb->kbd, domid); -+ -+ /* Indicate we have the frame buffer resize feature, requires grant tables */ -+ if (xenfb->gnttabdev > 0) { -+ xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "feature-resize", "1"); -+ } - - fprintf(stderr, "FB: Waiting for KBD backend creation\n"); - xenfb_wait_for_backend(&xenfb->kbd, xenfb_backend_created_kbd); -@@ -320,6 +337,58 @@ static void xenfb_copy_mfns(int mode, in - - for (i = 0; i < count; i++) - dst[i] = (mode == 32) ? src32[i] : src64[i]; -+} -+ -+static void xenfb_map_extended_fb(struct xenfb *xenfb, int extended_mem_length, -+ int gref_cnt, int gref) -+{ -+ int n_fbmfns; -+ unsigned long *fbmfns = NULL; -+ void *page; -+ int i; -+ int ep_gref; -+ int amt; -+ int index; -+ void *pixels; -+ int *grefs; -+ -+ grefs = xc_gnttab_map_grant_ref (xenfb->gnttabdev, -+ xenfb->fb.otherend_id, -+ gref, 0); -+ if (NULL == grefs) { -+ fprintf(stderr,"FB: Can't map to grant refs\n"); -+ return; -+ } -+ n_fbmfns = (extended_mem_length + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; -+ fbmfns = malloc(sizeof(unsigned long) * n_fbmfns); -+ if (fbmfns) { -+ ep_gref = PAGE_SIZE/(xenfb->otherend_bsize/8); -+ amt = index = 0; -+ for(i = 0; i < gref_cnt; i++) { -+ page = xc_gnttab_map_grant_ref (xenfb->gnttabdev, -+ xenfb->fb.otherend_id, -+ grefs[i], 0); -+ if (page) { -+ index = i * ep_gref; -+ amt = ep_gref; -+ if (n_fbmfns - index < ep_gref) -+ amt = n_fbmfns - index; -+ xenfb_copy_mfns(xenfb->otherend_bsize, amt, &fbmfns[index], page); -+ xc_gnttab_munmap(xenfb->gnttabdev, page, 1); -+ } -+ else -+ goto gref_error; -+ } -+ pixels = xc_map_foreign_pages(xenfb->xc, xenfb->fb.otherend_id, -+ PROT_READ | PROT_WRITE, fbmfns, n_fbmfns); -+ if (pixels) { -+ xenfb->old_pixels = xenfb->pixels; -+ xenfb->pixels = pixels; -+ } -+ free(fbmfns); -+ } -+gref_error: -+ xc_gnttab_munmap(xenfb->gnttabdev, grefs, 1); - } - - static int xenfb_map_fb(struct xenfb *xenfb, int domid) -@@ -377,6 +446,7 @@ static int xenfb_map_fb(struct xenfb *xe - #endif - } - -+ xenfb->otherend_bsize = mode; - n_fbmfns = (xenfb->fb_len + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; - n_fbdirs = n_fbmfns * mode / 8; - n_fbdirs = (n_fbdirs + (XC_PAGE_SIZE - 1)) / XC_PAGE_SIZE; -@@ -456,6 +526,10 @@ static void xenfb_detach_dom(struct xenf - munmap(xenfb->pixels, xenfb->fb_len); - xenfb->pixels = NULL; - } -+ if (xenfb->old_pixels) { -+ munmap(xenfb->old_pixels, xenfb->fb_len); -+ xenfb->old_pixels = NULL; -+ } - } - - /* Remove the backend area in xenbus since the framebuffer really is -@@ -473,6 +547,9 @@ void xenfb_shutdown(struct xenfb *xenfb) - xc_evtchn_close(xenfb->evt_xch); - if (xenfb->xsh) - xs_daemon_close(xenfb->xsh); -+ if (xenfb->gnttabdev > 0) -+ xc_gnttab_close(xenfb->gnttabdev); -+ - free(xenfb); - } - -@@ -510,6 +587,22 @@ static void xenfb_on_fb_event(struct xen +Index: xen-3.2-testing/tools/ioemu/hw/xenfb.c +=================================================================== +--- xen-3.2-testing.orig/tools/ioemu/hw/xenfb.c ++++ xen-3.2-testing/tools/ioemu/hw/xenfb.c +@@ -510,6 +510,12 @@ static void xenfb_on_fb_event(struct xen } xenfb_guest_copy(xenfb, x, y, w, h); break; @@ -155,98 +11,60 @@ diff -r 15cfd1f8fa38 tools/ioemu/hw/xenfb.c + xenfb->height = event->resize.height; + xenfb->row_stride = event->resize.stride; + dpy_resize(xenfb->ds, xenfb->width, xenfb->height); -+ xenfb_send_resize(xenfb, xenfb->width, xenfb->height); -+ break; -+ case XENFB_TYPE_MAP_EXTENDED: -+ if (xenfb->gnttabdev > 0) { -+ xenfb_map_extended_fb(xenfb, -+ event->map_extended.extended_mem_length, -+ event->map_extended.gref_cnt, -+ event->map_extended.gref); -+ } -+ xenfb_send_map_extended_done(xenfb); + break; } } mb(); /* ensure we're done with ring contents */ -@@ -555,6 +648,41 @@ static int xenfb_on_state_change(struct - return 0; - } +@@ -672,6 +678,7 @@ static void xenfb_dispatch_store(void *o + static int xenfb_read_frontend_fb_config(struct xenfb *xenfb) { + struct xenfb_page *fb_page; + int val; ++ int videoram; -+/* Send an event to the framebuffer frontend driver */ -+static int xenfb_fb_event(struct xenfb *xenfb, -+ union xenfb_in_event *event) -+{ -+ uint32_t prod; -+ struct xenfb_page *page = xenfb->fb.page; -+ -+ if (xenfb->fb.state != XenbusStateConnected) -+ return 0; -+ -+ prod = page->in_prod; -+ if (prod - page->in_cons == XENFB_IN_RING_LEN) { -+ errno = EAGAIN; -+ return -1; -+ } -+ -+ mb(); /* ensure ring space available */ -+ XENFB_IN_RING_REF(page, prod) = *event; -+ wmb(); /* ensure ring contents visible */ -+ page->in_prod = prod + 1; -+ return xc_evtchn_notify(xenfb->evt_xch, xenfb->fb.port); -+} -+ -+/* Send a extended memory map done event to kbd driver */ -+static int xenfb_send_map_extended_done(struct xenfb *xenfb) -+{ -+ union xenfb_in_event event; -+ -+ memset(&event, 0, XENFB_IN_EVENT_SIZE); -+ event.type = XENFB_TYPE_MAP_EXTENDED_DONE; -+ -+ return xenfb_fb_event(xenfb, &event); -+} -+ -+ - /* Send an event to the keyboard frontend driver */ - static int xenfb_kbd_event(struct xenfb *xenfb, - union xenkbd_in_event *event) -@@ -601,6 +729,19 @@ static int xenfb_send_motion(struct xenf - event.motion.rel_x = rel_x; - event.motion.rel_y = rel_y; - event.motion.rel_z = rel_z; -+ -+ return xenfb_kbd_event(xenfb, &event); -+} -+ -+/* Send a resize event to kbd driver */ -+static int xenfb_send_resize(struct xenfb *xenfb, int width, int height) -+{ -+ union xenkbd_in_event event; -+ -+ memset(&event, 0, XENKBD_IN_EVENT_SIZE); -+ event.type = XENKBD_TYPE_FBRESIZE; -+ event.fbresize.width = width; -+ event.fbresize.height = height; + if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.otherend, "feature-update", + "%d", &val) < 0) +@@ -686,19 +693,34 @@ static int xenfb_read_frontend_fb_config + xenfb->protocol[0] = '\0'; + xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "request-update", "1"); - return xenfb_kbd_event(xenfb, &event); - } -diff -r 15cfd1f8fa38 xen/include/public/io/fbif.h ---- a/xen/include/public/io/fbif.h Tue Jan 08 16:45:08 2008 +0000 -+++ b/xen/include/public/io/fbif.h Thu Jan 17 08:16:28 2008 -0700 -@@ -29,8 +29,9 @@ - /* Out events (frontend -> backend) */ +- /* TODO check for permitted ranges */ ++ if (xenfb_xs_scanf1(xenfb->xsh, xenfb->fb.nodename, "videoram", "%d", &videoram) < 0) ++ videoram = 0; ++ videoram = videoram * 1024 * 1024; ++ + fb_page = xenfb->fb.page; + xenfb->depth = fb_page->depth; + xenfb->width = fb_page->width; + xenfb->height = fb_page->height; +- /* TODO check for consistency with the above */ + xenfb->fb_len = fb_page->mem_length; + xenfb->row_stride = fb_page->line_length; ++ /* Protect against hostile frontend, limit fb_len to configured */ ++ if (videoram && xenfb->fb_len > videoram) { ++ xenfb->fb_len = videoram; ++ if (xenfb->row_stride * xenfb->height > xenfb->fb_len) ++ xenfb->height = xenfb->fb_len / xenfb->row_stride; ++ } + fprintf(stderr, "Framebuffer depth %d width %d height %d line %d\n", + fb_page->depth, fb_page->width, fb_page->height, fb_page->line_length); + if (xenfb_map_fb(xenfb, xenfb->fb.otherend_id) < 0) + return -1; - /* -- * Out events may be sent only when requested by backend, and receipt -- * of an unknown out event is an error. -+ * Out event update is sent only when requested by backend -+ * Events resize and map_extended are frontend generated -+ * It is an error to send any unknown event types - */ - - /* Event type 1 currently not used */ -@@ -50,12 +51,44 @@ struct xenfb_update ++ /* Indicate we have the frame buffer resize feature */ ++ xenfb_xs_printf(xenfb->xsh, xenfb->fb.nodename, "feature-resize", "1"); ++ ++ /* Tell kbd the screen res */ ++ xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "width", "%d", xenfb->width); ++ xenfb_xs_printf(xenfb->xsh, xenfb->kbd.nodename, "height", "%d", xenfb->height); ++ + if (xenfb_switch_state(&xenfb->fb, XenbusStateConnected)) + return -1; + if (xenfb_switch_state(&xenfb->kbd, XenbusStateConnected)) +Index: xen-3.2-testing/xen/include/public/io/fbif.h +=================================================================== +--- xen-3.2-testing.orig/xen/include/public/io/fbif.h ++++ xen-3.2-testing/xen/include/public/io/fbif.h +@@ -50,12 +50,28 @@ struct xenfb_update int32_t height; /* rect height */ }; @@ -261,23 +79,8 @@ diff -r 15cfd1f8fa38 xen/include/public/io/fbif.h + uint8_t type; /* XENFB_TYPE_RESIZE */ + int32_t width; /* width in pixels */ + int32_t height; /* height in pixels */ -+ int32_t stride; /* stride in pixels */ -+ int32_t depth; /* future */ -+}; -+ -+/* -+ * Framebuffer map extended memory event -+ * Causes backend to map extended frame buffer memory -+ * for larger screen resolution support -+ */ -+#define XENFB_TYPE_MAP_EXTENDED 4 -+ -+struct xenfb_map_extended -+{ -+ uint8_t type; /* XENFB_TYPE_MAP_EXTENDED */ -+ int32_t extended_mem_length; /* extended frame buffer len (in bytes) */ -+ int32_t gref_cnt; /* number of mapping refernces used */ -+ int32_t gref; /* reference to mapping references */ ++ int32_t stride; /* stride in bytes */ ++ int32_t depth; /* depth in bits */ +}; + #define XENFB_OUT_EVENT_SIZE 40 @@ -287,84 +90,66 @@ diff -r 15cfd1f8fa38 xen/include/public/io/fbif.h uint8_t type; struct xenfb_update update; + struct xenfb_resize resize; -+ struct xenfb_map_extended map_extended; char pad[XENFB_OUT_EVENT_SIZE]; }; -@@ -63,14 +96,26 @@ union xenfb_out_event - - /* - * Frontends should ignore unknown in events. -- * No in events currently defined. - */ -+ -+/* -+ * Framebuffer map extended memory done event -+ * Causes fronted to end foreign access to extended memory -+ * grant table references -+ */ -+#define XENFB_TYPE_MAP_EXTENDED_DONE 1 -+ -+struct xenfb_map_extended_done -+{ -+ uint8_t type; /* XENFB_TYPE_MAP_EXTENDED_DONE */ -+}; - - #define XENFB_IN_EVENT_SIZE 40 - - union xenfb_in_event - { - uint8_t type; -+ struct xenfb_map_extended_done map_extended_done; - char pad[XENFB_IN_EVENT_SIZE]; - }; - -@@ -116,8 +161,9 @@ struct xenfb_page +@@ -109,15 +125,17 @@ struct xenfb_page + * Each directory page holds PAGE_SIZE / sizeof(*pd) + * framebuffer pages, and can thus map up to PAGE_SIZE * + * PAGE_SIZE / sizeof(*pd) bytes. With PAGE_SIZE == 4096 and +- * sizeof(unsigned long) == 4, that's 4 Megs. Two directory +- * pages should be enough for a while. ++ * sizeof(unsigned long) == 4/8, that's 4 Megs 32 bit and 2 Megs ++ * 64 bit. 256 directories give enough room for a 512 Meg ++ * framebuffer with a max resolution of 12,800x10,240. Should ++ * be enough for a while with room leftover for expansion. + */ +- unsigned long pd[2]; ++ unsigned long pd[256]; }; /* - * Wart: xenkbd needs to know resolution. Put it here until a better - * solution is found, but don't leak it to the backend. -+ * Wart: xenkbd needs to know resolution of initial frame buffer. Put -+ * it here until a better solution is found, but don't leak it to -+ * the backend. ++ * Wart: xenkbd needs to know default resolution. Put it here until a ++ * better solution is found, but don't leak it to the backend. */ #ifdef __KERNEL__ #define XENFB_WIDTH 800 -diff -r 15cfd1f8fa38 xen/include/public/io/kbdif.h ---- a/xen/include/public/io/kbdif.h Tue Jan 08 16:45:08 2008 +0000 -+++ b/xen/include/public/io/kbdif.h Thu Jan 17 10:43:35 2008 -0700 -@@ -44,6 +44,12 @@ - * request-abs-update in xenstore. - */ - #define XENKBD_TYPE_POS 4 -+/* -+ * Frame buffer resize event. Adjusts absolute max X and Y axis -+ * values in input ptr device. Necessary for proper scaling -+ * when the screen resolution changes -+ */ -+#define XENKBD_TYPE_FBRESIZE 5 +Index: xen-3.2-testing/tools/python/xen/xend/server/vfbif.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xend/server/vfbif.py ++++ xen-3.2-testing/tools/python/xen/xend/server/vfbif.py +@@ -6,7 +6,7 @@ import xen.xend + import os - struct xenkbd_motion - { -@@ -68,6 +74,12 @@ struct xenkbd_position - int32_t abs_z; /* absolute Z position (wheel) */ - }; + CONFIG_ENTRIES = ['type', 'vncdisplay', 'vnclisten', 'vncpasswd', 'vncunused', +- 'display', 'xauthority', 'keymap', ++ 'videoram', 'display', 'xauthority', 'keymap', + 'uuid', 'location', 'protocol'] -+struct xenkbd_fbresize -+{ -+ uint8_t type; /* XENKBD_TYPE_FBRESIZE */ -+ int32_t width; /* frame buffer width in pixels */ -+ int32_t height; /* frame buffer height in pixels */ -+}; - #define XENKBD_IN_EVENT_SIZE 40 - - union xenkbd_in_event -@@ -76,6 +88,7 @@ union xenkbd_in_event - struct xenkbd_motion motion; - struct xenkbd_key key; - struct xenkbd_position pos; -+ struct xenkbd_fbresize fbresize; - char pad[XENKBD_IN_EVENT_SIZE]; - }; + class VfbifController(DevController): +Index: xen-3.2-testing/tools/python/xen/xm/create.py +=================================================================== +--- xen-3.2-testing.orig/tools/python/xen/xm/create.py ++++ xen-3.2-testing/tools/python/xen/xm/create.py +@@ -496,6 +496,10 @@ gopts.var('vncunused', val='', + use="""Try to find an unused port for the VNC server. + Only valid when vnc=1.""") ++gopts.var('videoram', val='', ++ fn=set_value, default=None, ++ use="""Amount of videoram PV guest can allocate for frame buffer.""") ++ + gopts.var('sdl', val='', + fn=set_value, default=None, + use="""Should the device model use SDL?""") +@@ -626,7 +630,7 @@ def configure_vfbs(config_devs, vals): + d['type'] = 'sdl' + for (k,v) in d.iteritems(): + if not k in [ 'vnclisten', 'vncunused', 'vncdisplay', 'display', +- 'xauthority', 'type', 'vncpasswd' ]: ++ 'videoram', 'xauthority', 'type', 'vncpasswd' ]: + err("configuration option %s unknown to vfbs" % k) + config.append([k,v]) + if not d.has_key("keymap"): diff --git a/xen-hvm-default-bridge.diff b/xen-hvm-default-bridge.diff index 412d74b..cfef793 100644 --- a/xen-hvm-default-bridge.diff +++ b/xen-hvm-default-bridge.diff @@ -44,7 +44,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/image.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xend/image.py +++ xen-3.2-testing/tools/python/xen/xend/image.py -@@ -485,13 +485,16 @@ class HVMImageHandler(ImageHandler): +@@ -491,13 +491,16 @@ class HVMImageHandler(ImageHandler): mac = devinfo.get('mac') if mac is None: raise VmError("MAC address not specified or generated.") diff --git a/xen-hvm-default-pae.diff b/xen-hvm-default-pae.diff index 0abac5f..c804751 100644 --- a/xen-hvm-default-pae.diff +++ b/xen-hvm-default-pae.diff @@ -4,7 +4,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/image.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xend/image.py +++ xen-3.2-testing/tools/python/xen/xend/image.py -@@ -580,7 +580,7 @@ class X86_HVM_ImageHandler(HVMImageHandl +@@ -586,7 +586,7 @@ class X86_HVM_ImageHandler(HVMImageHandl def configure(self, vmConfig): HVMImageHandler.configure(self, vmConfig) diff --git a/xen-ioemu-hvm-pv-support.diff b/xen-ioemu-hvm-pv-support.diff index 370a70f..538aa8a 100644 --- a/xen-ioemu-hvm-pv-support.diff +++ b/xen-ioemu-hvm-pv-support.diff @@ -2,7 +2,7 @@ Index: xen-3.2-testing/tools/ioemu/hw/ide.c =================================================================== --- xen-3.2-testing.orig/tools/ioemu/hw/ide.c +++ xen-3.2-testing/tools/ioemu/hw/ide.c -@@ -394,6 +394,9 @@ typedef struct PCIIDEState { +@@ -395,6 +395,9 @@ typedef struct PCIIDEState { int type; /* see IDE_TYPE_xxx */ } PCIIDEState; @@ -12,7 +12,7 @@ Index: xen-3.2-testing/tools/ioemu/hw/ide.c #if defined(__ia64__) #include -@@ -2237,6 +2240,27 @@ static void ide_reset(IDEState *s) +@@ -2245,6 +2248,27 @@ static void ide_reset(IDEState *s) ide_dummy_transfer_stop(s); } @@ -40,7 +40,7 @@ Index: xen-3.2-testing/tools/ioemu/hw/ide.c struct partition { uint8_t boot_ind; /* 0x80 - active */ uint8_t head; /* starting head */ -@@ -2638,6 +2662,9 @@ void pci_cmd646_ide_init(PCIBus *bus, Bl +@@ -2646,6 +2670,9 @@ void pci_cmd646_ide_init(PCIBus *bus, Bl sizeof(PCIIDEState), -1, NULL, NULL); @@ -50,12 +50,22 @@ Index: xen-3.2-testing/tools/ioemu/hw/ide.c d->type = IDE_TYPE_CMD646; pci_conf = d->dev.config; pci_conf[0x00] = 0x95; // CMD646 -@@ -2812,6 +2839,9 @@ void pci_piix_ide_init(PCIBus *bus, Bloc +@@ -2820,6 +2847,9 @@ void pci_piix_ide_init(PCIBus *bus, Bloc NULL, NULL); d->type = IDE_TYPE_PIIX3; + if (principal_ide_controller) + abort(); ++ principal_ide_controller = d; + pci_conf = d->dev.config; + pci_conf[0x00] = 0x86; // Intel + pci_conf[0x01] = 0x80; +@@ -2866,6 +2896,9 @@ void pci_piix3_ide_init(PCIBus *bus, Blo + NULL, NULL); + d->type = IDE_TYPE_PIIX3; + ++ if (principal_ide_controller) ++ abort(); + principal_ide_controller = d; pci_conf = d->dev.config; pci_conf[0x00] = 0x86; // Intel @@ -64,7 +74,7 @@ Index: xen-3.2-testing/tools/ioemu/hw/pci.c =================================================================== --- xen-3.2-testing.orig/tools/ioemu/hw/pci.c +++ xen-3.2-testing/tools/ioemu/hw/pci.c -@@ -571,6 +571,28 @@ void pci_nic_init(PCIBus *bus, NICInfo * +@@ -573,6 +573,28 @@ void pci_nic_init(PCIBus *bus, NICInfo * } } @@ -97,20 +107,17 @@ Index: xen-3.2-testing/tools/ioemu/hw/xen_platform.c =================================================================== --- xen-3.2-testing.orig/tools/ioemu/hw/xen_platform.c +++ xen-3.2-testing/tools/ioemu/hw/xen_platform.c -@@ -28,10 +28,47 @@ +@@ -23,15 +23,53 @@ + * THE SOFTWARE. + */ + #include "vl.h" ++#include + + #include extern FILE *logfile; +static uint32_t ioport_base; -+ - static void platform_ioport_map(PCIDevice *pci_dev, int region_num, - uint32_t addr, uint32_t size, int type) - { -- /* nothing yet */ -+ ioport_base = addr; -+ -+ register_ioport_write(addr, 1, 1, platform_ioport_write, NULL); -+} + +static void platform_ioport_write(void *opaque, uint32_t addr, uint32_t val) +{ @@ -143,6 +150,15 @@ Index: xen-3.2-testing/tools/ioemu/hw/xen_platform.c + addr, ioport_base); + break; + } ++} ++ + static void platform_ioport_map(PCIDevice *pci_dev, int region_num, + uint32_t addr, uint32_t size, int type) + { +- /* nothing yet */ ++ ioport_base = addr; ++ ++ register_ioport_write(addr, 16, 4, platform_ioport_write, NULL); } static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr) @@ -150,7 +166,7 @@ Index: xen-3.2-testing/tools/ioemu/vl.c =================================================================== --- xen-3.2-testing.orig/tools/ioemu/vl.c +++ xen-3.2-testing/tools/ioemu/vl.c -@@ -194,6 +194,19 @@ int xc_handle; +@@ -197,6 +197,20 @@ int xc_handle; char domain_name[64] = "Xen-no-name"; extern int domid; @@ -159,6 +175,7 @@ Index: xen-3.2-testing/tools/ioemu/vl.c + IOCanRWHandler *fd_read_poll; + IOHandler *fd_read; + IOHandler *fd_write; ++ int deleted; + void *opaque; + /* temporary data */ + struct pollfd *ufd; @@ -170,7 +187,7 @@ Index: xen-3.2-testing/tools/ioemu/vl.c /***********************************************************/ /* x86 ISA bus support */ -@@ -3333,6 +3346,7 @@ void net_slirp_smb(const char *exported_ +@@ -3404,6 +3418,7 @@ void net_slirp_smb(const char *exported_ typedef struct TAPState { VLANClientState *vc; int fd; @@ -178,7 +195,7 @@ Index: xen-3.2-testing/tools/ioemu/vl.c } TAPState; static void tap_receive(void *opaque, const uint8_t *buf, int size) -@@ -3360,6 +3374,36 @@ static void tap_send(void *opaque) +@@ -3431,6 +3446,36 @@ static void tap_send(void *opaque) } } @@ -215,7 +232,7 @@ Index: xen-3.2-testing/tools/ioemu/vl.c /* fd support */ static TAPState *net_tap_fd_init(VLANState *vlan, int fd) -@@ -3371,6 +3415,8 @@ static TAPState *net_tap_fd_init(VLANSta +@@ -3442,6 +3487,8 @@ static TAPState *net_tap_fd_init(VLANSta return NULL; s->fd = fd; s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s); @@ -224,7 +241,7 @@ Index: xen-3.2-testing/tools/ioemu/vl.c qemu_set_fd_handler(s->fd, tap_send, NULL, s); snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd); return s; -@@ -4332,20 +4378,6 @@ void dumb_display_init(DisplayState *ds) +@@ -4412,20 +4459,6 @@ void dumb_display_init(DisplayState *ds) #define MAX_IO_HANDLERS 64 @@ -249,7 +266,7 @@ Index: xen-3.2-testing/tools/ioemu/vl.h =================================================================== --- xen-3.2-testing.orig/tools/ioemu/vl.h +++ xen-3.2-testing/tools/ioemu/vl.h -@@ -1492,6 +1492,8 @@ void kqemu_record_dump(void); +@@ -1497,6 +1497,8 @@ void kqemu_record_dump(void); extern char domain_name[]; void destroy_hvm_domain(void); diff --git a/xen-no-dummy-nfs-ip.diff b/xen-no-dummy-nfs-ip.diff index d0dc49c..5e747dd 100644 --- a/xen-no-dummy-nfs-ip.diff +++ b/xen-no-dummy-nfs-ip.diff @@ -2,7 +2,7 @@ Index: xen-3.2-testing/tools/python/xen/xm/create.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xm/create.py +++ xen-3.2-testing/tools/python/xen/xm/create.py -@@ -886,9 +886,8 @@ def preprocess_access_control(vals): +@@ -892,9 +892,8 @@ def preprocess_access_control(vals): def preprocess_ip(vals): if vals.ip or vals.dhcp != 'off': diff --git a/xen-qcow-realpath-buffer-overflow.patch b/xen-qcow-realpath-buffer-overflow.patch new file mode 100644 index 0000000..fd1e978 --- /dev/null +++ b/xen-qcow-realpath-buffer-overflow.patch @@ -0,0 +1,13 @@ +Index: xen-3.2-testing/tools/blktap/drivers/block-qcow.c +=================================================================== +--- xen-3.2-testing.orig/tools/blktap/drivers/block-qcow.c ++++ xen-3.2-testing/tools/blktap/drivers/block-qcow.c +@@ -1223,7 +1223,7 @@ int qcow_create(const char *filename, ui + int shift, length, adjust, flags = 0, ret = 0; + QCowHeader header; + QCowHeader_ext exthdr; +- char backing_filename[1024], *ptr; ++ char backing_filename[PATH_MAX], *ptr; + uint64_t tmp, size, total_length; + struct stat st; + diff --git a/xen-tightvnc-args.diff b/xen-tightvnc-args.diff index 0a136f8..1775ba1 100644 --- a/xen-tightvnc-args.diff +++ b/xen-tightvnc-args.diff @@ -2,7 +2,7 @@ Index: xen-3.2-testing/tools/python/xen/xm/create.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xm/create.py +++ xen-3.2-testing/tools/python/xen/xm/create.py -@@ -980,8 +980,7 @@ def spawn_vnc(display): +@@ -986,8 +986,7 @@ def spawn_vnc(display): returns the port that the vncviewer is listening on and sets the global vncpid. On failure, returns 0. Note that vncviewer is daemonized. """ diff --git a/xen-xmexample.diff b/xen-xmexample.diff index 4012b95..0ed618a 100644 --- a/xen-xmexample.diff +++ b/xen-xmexample.diff @@ -142,7 +142,7 @@ Index: xen-3.2-testing/docs/man/xmdomain.cfg.pod.5 many Linux distros you will not need a ramdisk if using the default xen kernel. -@@ -307,14 +307,14 @@ configured. They should not be consider +@@ -323,14 +323,14 @@ configured. They should not be consider =item I diff --git a/xen.changes b/xen.changes index 93f5016..b607037 100644 --- a/xen.changes +++ b/xen.changes @@ -1,24 +1,115 @@ +------------------------------------------------------------------- +Fri Feb 29 09:58:06 MST 2008 - carnold@novell.com + +- bnc#357966 - VT-D dosen't work for HVM guest. + +------------------------------------------------------------------- +Fri Feb 29 08:35:11 MST 2008 - plc@novell.com + +- Send UNIT_ATTENTION when CD drive has newly inserted media and + becomes ready. bnc#365386 + +------------------------------------------------------------------- +Thu Feb 28 16:42:16 MST 2008 - jfehlig@novell.com + +- Updated block-iscsi script and xen-domUloader patch, bnc #365385 + +------------------------------------------------------------------- +Thu Feb 28 11:34:52 MST 2008 - carnold@novell.com + +- Add support for Intel EPT / VPID. + +------------------------------------------------------------------- +Tue Feb 26 14:12:17 MST 2008 - carnold@novell.com + +- bnc#362415 - SLE-based installs 32-bit fully-virtualized have + network problems during installs. +- bnc#358244 - Time remaining does not change properly for FV SLES10 + SP2 guest. +- bnc#363053 - Install remaining time always shows 2:00:00 + +------------------------------------------------------------------- +Tue Feb 26 10:37:11 MST 2008 - carnold@novell.com + +- bnc#359457 - Xen full virt has data integrity issue. + +------------------------------------------------------------------- +Tue Feb 26 08:34:17 MST 2008 - plc@novell.com + +- Tranlate colors from 32 bit to 16 bit when viewing a 32 bit PV + VM from a 16 bit client. bnc#351470 + Also includes upstream mouse queue patch. + +------------------------------------------------------------------- +Fri Feb 22 17:57:38 MST 2008 - jfehlig@novell.com + +- Added PAM configuration files for remote authentication via + Xen API. bnc #353464 + +------------------------------------------------------------------- +Tue Feb 19 13:22:32 MST 2008 - carnold@novell.com + +- Fix PV drivers for HVM guests. + +------------------------------------------------------------------- +Fri Feb 15 14:08:35 MST 2008 - carnold@novell.com + +- Support for pxe booting fully virtualized guests in vm-install is + complete. + +------------------------------------------------------------------- +Thu Feb 14 11:47:50 MST 2008 - carnold@novell.com + +- Added upstream changesets that fix various bugs. + 16859 16929 16930 16945 16947 16962 16976 16980 16995 16998 17036 + +------------------------------------------------------------------- +Wed Feb 13 17:42:17 MST 2008 - jfehlig@novell.com + +- Updated network-multinet + - Simplify bridge creation + - Create traditional bridge and hostonly networks by default + +------------------------------------------------------------------- +Fri Feb 8 11:01:49 MST 2008 - jfehlig@novell.com + +- Added upstream changesets 16932, 16965, 16977, and 16988 to fix + various bugs in tool stack +- Also added upstream changeset 16989 to complete fate #302941. + +------------------------------------------------------------------- +Mon Feb 4 14:01:56 MST 2008 - plc@novell.com + +- Replaced xen-blktab-subtype-strip.patch with official upstream + changeset for bnc#353065. + ------------------------------------------------------------------- Fri Feb 1 16:11:59 MST 2008 - carnold@novell.com - Update to xen 3.2 FCS. Changeset 16718 - Merge xen-tools and xen-tools-ioemu into xen-tools. -------------------------------------------------------------------- -Sat Jan 12 00:37:41 CET 2008 - carnold@suse.de - -- Update to xen 3.2 RC5. Changeset 16701 - ------------------------------------------------------------------- Wed Dec 19 16:16:36 MST 2007 - carnold@novell.com - Update to xen 3.2 RC2. Changeset 16646 +------------------------------------------------------------------- +Thu Dec 13 15:37:09 MST 2007 - carnold@novell.com + +- Added agent support for HP Proliant hardware. + +------------------------------------------------------------------- +Wed Dec 5 13:04:17 MST 2007 - carnold@novell.com + +- #338108 - VUL-0: Xen security issues in SLE10 +- #279062 - Timer ISR/1: Time went backwards + ------------------------------------------------------------------- Thu Nov 29 13:44:29 MST 2007 - carnold@novell.com - Added part of upstream c/s 15211. Fixed open call with O_CREAT - because it had no mode flags. + because it had no mode flags (15211-fix-open-mode.patch). ------------------------------------------------------------------- Mon Nov 5 09:38:14 MST 2007 - jfehlig@novell.com @@ -29,7 +120,7 @@ Mon Nov 5 09:38:14 MST 2007 - jfehlig@novell.com ------------------------------------------------------------------- Thu Nov 1 13:17:46 MDT 2007 - carnold@novell.com -- 334445: xenbaked: Fix security vulnerability CVE-2007-3919. +- #334445: xenbaked: Fix security vulnerability CVE-2007-3919. ------------------------------------------------------------------- Thu Nov 1 11:30:35 MDT 2007 - carnold@novell.com diff --git a/xen.spec b/xen.spec index d8cf133..68055f1 100644 --- a/xen.spec +++ b/xen.spec @@ -1,5 +1,5 @@ # -# spec file for package xen (Version 3.2.0_16718_02) +# spec file for package xen (Version 3.2.0_16718_06) # # Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. # This file and all modifications and additions to the pristine @@ -10,6 +10,7 @@ # norootforbuild + Name: xen %define xvers 3.2 %define xvermaj 3 @@ -20,7 +21,7 @@ Name: xen %else %define with_kmp 0 %endif -BuildRequires: LibVNCServer-devel SDL-devel autoconf automake bin86 curl-devel dev86 graphviz latex2html libjpeg-devel libxml2-devel openssl openssl-devel python-devel transfig +BuildRequires: LibVNCServer-devel SDL-devel autoconf automake bin86 curl-devel dev86 graphviz latex2html libjpeg-devel libxml2-devel openssl openssl-devel pciutils-devel python-devel transfig %if %suse_version >= 1030 BuildRequires: texlive texlive-latex %else @@ -32,7 +33,7 @@ BuildRequires: glibc-32bit glibc-devel-32bit %if %{?with_kmp}0 BuildRequires: kernel-source kernel-syms module-init-tools xorg-x11 %endif -Version: 3.2.0_16718_02 +Version: 3.2.0_16718_06 Release: 1 License: GPL v2 only Group: System/Kernel @@ -60,17 +61,40 @@ Source19: network-multinet Source20: multinet-common.sh Source21: multinet-include.template Source22: xend-network +# Xen API remote authentication sources +Source23: etc_pam.d_xen-api +Source24: xenapiusers # Upstream patches Patch0: 16716-xend-version.patch Patch1: 16718-batched-mmu-updates.patch -Patch2: 16777-xend-block-attach.patch -Patch3: 16873-net-nat.patch -Patch4: 16877-blktap.patch -Patch5: 16883-xend-crashed-state.patch -Patch6: 16884-xend-rename-restart.patch -Patch7: 16885-xend-config-comments.patch -Patch8: 16886-xenstore-leak.patch -Patch9: 16890-xenapi-version.patch +Patch2: 16769-pci-high-memory-resource.patch +Patch3: 16777-xend-block-attach.patch +Patch4: 16859-x86_emulate-clts-fix.patch +Patch5: 16873-net-nat.patch +Patch6: 16877-blktap.patch +Patch7: 16883-xend-crashed-state.patch +Patch8: 16884-xend-rename-restart.patch +Patch9: 16885-xend-config-comments.patch +Patch10: 16886-xenstore-leak.patch +Patch11: 16890-xenapi-version.patch +Patch12: 16929-hvm-guest-crash-fix.patch +Patch13: 16930-shadow-pinning-logic-fix.patch +Patch14: 16932-xend-hvm-localtime.patch +Patch15: 16945-blktap-strip.patch +Patch16: 16947-fvmachine-xenstore.patch +Patch17: 16962-cross-page-write-failure.patch +Patch18: 16965-xend-leak.patch +Patch19: 16976-x86_emulate-sahf-fix.patch +Patch20: 16977-xend-restart-count.patch +Patch21: 16980-x86_emulate-macro-fix.patch +Patch22: 16988-xm-reboot.patch +Patch23: 16989-xend-coredump.patch +Patch24: 16995-x86_emulate-mul-fix.patch +Patch25: 16998-x86_emulate-imul-fix.patch +Patch26: 17003-qemu-queue-mouse.patch +Patch27: 17017-hpet-configuration.patch +Patch28: 17036-mismatched-save-rest-fix.patch +Patch29: 17113-xend-restore.patch # Our patches Patch100: xen-config.diff Patch101: xend-config.diff @@ -99,25 +123,25 @@ Patch130: xen-generate-foreign-headers.diff Patch131: tools-xc_kexec.diff Patch132: tools-kboot.diff Patch133: libxen_permissive.patch -Patch134: xen-ioemu-hvm-pv-support.diff -Patch135: xenapi-console-protocol.patch -Patch136: xen-disable-qemu-monitor.diff -Patch137: supported_module.diff -Patch138: disable_emulated_device.diff -Patch140: qemu-security-etch1.diff -Patch141: vnc-i18n-keys.diff -Patch142: rpmlint.diff -Patch143: cdrom-removable.patch +Patch134: xenapi-console-protocol.patch +Patch135: xen-disable-qemu-monitor.diff +Patch136: supported_module.diff +Patch137: qemu-security-etch1.diff +Patch138: vnc-i18n-keys.diff +Patch139: rpmlint.diff +Patch140: cdrom-removable.patch Patch150: bridge-suse.diff Patch151: bridge-bonding.diff Patch152: bridge-hostonly.diff Patch153: bridge-vlan.diff Patch154: keymap_nl-be.patch -Patch155: svm-cr8-performance.diff -Patch156: xen-fbback-resize.patch -Patch157: xend-core-dump-loc.diff -Patch158: blktap.patch -Patch159: xen-blktab-subtype-strip.patch +Patch155: xen-fbback-resize.patch +Patch156: xend-core-dump-loc.diff +Patch157: blktap.patch +Patch158: xen-qcow-realpath-buffer-overflow.patch +Patch159: xen-api-auth.patch +Patch160: pv_32_16_color_trans.patch +Patch161: hvm-ide-flush-o_direct.patch # Patches from Jan Patch240: xenctx.patch Patch241: const-callback-arg.patch @@ -127,8 +151,21 @@ Patch244: pv-drv-mkbuildtree.patch Patch245: x86_emulate.patch Patch246: x86-extra-trap-info.patch Patch247: 32on64-extra-mem.patch -# Ky PV Driver Patches +# PV Driver Patches Patch350: pv-driver-build.patch +Patch351: xen-ioemu-hvm-pv-support.diff +Patch352: pvdrv_emulation_control.patch +# Intel EPT / VPID patches +Patch400: ept-novell-x64.patch +Patch401: vpid-novell.patch +Patch402: livemig-ept-novell-x64.patch +Patch403: livemig-ept-novell-i386.patch +%ifarch x86_64 +# novell_shim patches +Patch500: ns_tools.patch +Patch501: ns_xen_base.patch +Patch502: ns_xen_extension.patch +%endif Url: http://www.cl.cam.ac.uk/Research/SRG/netos/xen/ BuildRoot: %{_tmppath}/%{name}-%{version}-build %define pysite %(python -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib()") @@ -243,7 +280,8 @@ Authors: Summary: Xen Virtualization: Control tools for domain 0 Group: System/Kernel Requires: xen-libs = %{version} -Requires: bridge-utils multipath-tools python python-curses python-xml pyxml +Requires: bridge-utils ipcalc multipath-tools python python-curses python-pam python-xml pyxml +Obsoletes: xen-tools-ioemu AutoReqProv: on %description tools @@ -458,6 +496,26 @@ Authors: %patch7 -p1 %patch8 -p1 %patch9 -p1 +%patch10 -p1 +%patch11 -p1 +%patch12 -p1 +%patch13 -p1 +%patch14 -p1 +%patch15 -p1 +%patch16 -p1 +%patch17 -p1 +%patch18 -p1 +%patch19 -p1 +%patch20 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 +%patch27 -p1 +%patch28 -p1 +%patch29 -p1 %patch100 -p1 %patch101 -p1 %patch102 -p1 @@ -485,25 +543,25 @@ Authors: %patch131 -p1 %patch132 -p1 %patch133 -p1 -#%patch134 -p1 # 3.1 disabled - re-port +%patch134 -p1 %patch135 -p1 %patch136 -p1 %patch137 -p1 -#%patch138 -p1 # 3.1 disabled - Currently not disabling FV devices when loading PV drivers +%patch138 -p1 +%patch139 -p1 %patch140 -p1 -%patch141 -p1 -%patch142 -p1 -%patch143 -p1 %patch150 -p1 #%patch151 -p1 # dump if all goes well with defaulting to network-multinet #%patch152 -p1 # dump if all goes well with defaulting to network-multinet #%patch153 -p1 # dump if all goes well with defaulting to network-multinet %patch154 -p1 -#%patch155 -p1 # AMD CR8 Performance - not clean for unstable +%patch155 -p1 %patch156 -p1 %patch157 -p1 %patch158 -p1 -%patch159 -p1 +%patch159 -p1 +%patch160 -p1 +%patch161 -p1 %patch240 -p1 %patch241 -p1 %patch242 -p1 @@ -513,6 +571,20 @@ Authors: %patch246 -p1 %patch247 -p1 %patch350 -p1 +%patch351 -p1 +%patch352 -p1 +%patch400 -p1 +%patch401 -p1 +%ifarch x86_64 +%patch402 -p1 +%else +%patch403 -p1 +%endif +%ifarch x86_64 +%patch500 -p1 +%patch501 -p1 +%patch502 -p1 +%endif %build XEN_EXTRAVERSION=%version-%release @@ -627,6 +699,10 @@ install -m644 %SOURCE18 $RPM_BUILD_ROOT/var/adm/fillup-templates/sysconfig.xend install -m755 %SOURCE19 %SOURCE20 $RPM_BUILD_ROOT/etc/xen/scripts/ install -m644 %SOURCE21 $RPM_BUILD_ROOT/etc/xen/scripts/multinet.d/ install -m755 %SOURCE22 $RPM_BUILD_ROOT/usr/sbin/ +# Xen API remote authentication files +install -d $RPM_BUILD_ROOT/etc/pam.d +install -m644 %SOURCE23 $RPM_BUILD_ROOT/etc/pam.d/xen-api +install -m644 %SOURCE24 $RPM_BUILD_ROOT/etc/xen/ # logrotate install -m644 -D %SOURCE7 $RPM_BUILD_ROOT/etc/logrotate.d/xen # directories @@ -686,7 +762,7 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %defattr(-,root,root) %{_libdir}/fs/ %{_libdir}/libblktap.so.* -%{_libdir}/libflask.so* +%{_libdir}/libflask.so.* %{_libdir}/libfsimage.so.* %{_libdir}/libxen*.so.* @@ -747,6 +823,8 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %config /etc/xen/vm %config /etc/xen/*.sxp %config /etc/xen/*.xml +%config(noreplace) /etc/xen/xenapiusers +%config /etc/pam.d/xen-api %dir /etc/udev %dir /etc/udev/rules.d /etc/udev/rules.d/40-xen.rules @@ -783,7 +861,7 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info %{_libdir}/libblktap.a %{_libdir}/libblktap.so %{_libdir}/libflask.a -%{_libdir}/libflask.so* +%{_libdir}/libflask.so %{_libdir}/libfsimage.so %{_libdir}/libxen*.a %{_libdir}/libxen*.so @@ -826,21 +904,67 @@ rm -f $RPM_BUILD_ROOT/%pysite/*.egg-info /sbin/ldconfig %changelog +* Fri Feb 29 2008 carnold@novell.com +- bnc#357966 - VT-D dosen't work for HVM guest. +* Fri Feb 29 2008 plc@novell.com +- Send UNIT_ATTENTION when CD drive has newly inserted media and + becomes ready. bnc#365386 +* Thu Feb 28 2008 jfehlig@novell.com +- Updated block-iscsi script and xen-domUloader patch, bnc #365385 +* Thu Feb 28 2008 carnold@novell.com +- Add support for Intel EPT / VPID. +* Tue Feb 26 2008 carnold@novell.com +- bnc#362415 - SLE-based installs 32-bit fully-virtualized have + network problems during installs. +- bnc#358244 - Time remaining does not change properly for FV SLES10 + SP2 guest. +- bnc#363053 - Install remaining time always shows 2:00:00 +* Tue Feb 26 2008 carnold@novell.com +- bnc#359457 - Xen full virt has data integrity issue. +* Tue Feb 26 2008 plc@novell.com +- Tranlate colors from 32 bit to 16 bit when viewing a 32 bit PV + VM from a 16 bit client. bnc#351470 + Also includes upstream mouse queue patch. +* Fri Feb 22 2008 jfehlig@novell.com +- Added PAM configuration files for remote authentication via + Xen API. bnc #353464 +* Tue Feb 19 2008 carnold@novell.com +- Fix PV drivers for HVM guests. +* Fri Feb 15 2008 carnold@novell.com +- Support for pxe booting fully virtualized guests in vm-install is + complete. +* Thu Feb 14 2008 carnold@novell.com +- Added upstream changesets that fix various bugs. + 16859 16929 16930 16945 16947 16962 16976 16980 16995 16998 17036 +* Wed Feb 13 2008 jfehlig@novell.com +- Updated network-multinet + - Simplify bridge creation + - Create traditional bridge and hostonly networks by default +* Fri Feb 08 2008 jfehlig@novell.com +- Added upstream changesets 16932, 16965, 16977, and 16988 to fix + various bugs in tool stack +- Also added upstream changeset 16989 to complete fate #302941. +* Mon Feb 04 2008 plc@novell.com +- Replaced xen-blktab-subtype-strip.patch with official upstream + changeset for bnc#353065. * Fri Feb 01 2008 carnold@novell.com - Update to xen 3.2 FCS. Changeset 16718 - Merge xen-tools and xen-tools-ioemu into xen-tools. -* Fri Jan 11 2008 carnold@suse.de -- Update to xen 3.2 RC5. Changeset 16701 * Wed Dec 19 2007 carnold@novell.com - Update to xen 3.2 RC2. Changeset 16646 +* Thu Dec 13 2007 carnold@novell.com +- Added agent support for HP Proliant hardware. +* Wed Dec 05 2007 carnold@novell.com +- #338108 - VUL-0: Xen security issues in SLE10 +- #279062 - Timer ISR/1: Time went backwards * Thu Nov 29 2007 carnold@novell.com - Added part of upstream c/s 15211. Fixed open call with O_CREAT - because it had no mode flags. + because it had no mode flags (15211-fix-open-mode.patch). * Mon Nov 05 2007 jfehlig@novell.com - Added upstream c/s 15434 to allow access to serial devices. Bug #338486. * Thu Nov 01 2007 carnold@novell.com -- 334445: xenbaked: Fix security vulnerability CVE-2007-3919. +- #334445: xenbaked: Fix security vulnerability CVE-2007-3919. * Thu Nov 01 2007 carnold@novell.com - #310279: Kernel Panic while booting Xen * Tue Oct 02 2007 ccoffing@novell.com diff --git a/xenapi-console-protocol.patch b/xenapi-console-protocol.patch index 5cafa0f..b2408c8 100644 --- a/xenapi-console-protocol.patch +++ b/xenapi-console-protocol.patch @@ -2,7 +2,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -2707,6 +2707,14 @@ class XendDomainInfo: +@@ -2732,6 +2732,14 @@ class XendDomainInfo: if not config.has_key('backend'): config['backend'] = "00000000-0000-0000-0000-000000000000" diff --git a/xenapiusers b/xenapiusers new file mode 100644 index 0000000..20fd8bb --- /dev/null +++ b/xenapiusers @@ -0,0 +1 @@ +root diff --git a/xend-core-dump-loc.diff b/xend-core-dump-loc.diff index b735be3..ace271b 100644 --- a/xend-core-dump-loc.diff +++ b/xend-core-dump-loc.diff @@ -2,7 +2,7 @@ Index: xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py =================================================================== --- xen-3.2-testing.orig/tools/python/xen/xend/XendDomainInfo.py +++ xen-3.2-testing/tools/python/xen/xend/XendDomainInfo.py -@@ -1490,7 +1490,7 @@ class XendDomainInfo: +@@ -1504,7 +1504,7 @@ class XendDomainInfo: try: if not corefile: this_time = time.strftime("%Y-%m%d-%H%M.%S", time.localtime()) diff --git a/xmclone.sh b/xmclone.sh index 8d6a597..756b2af 100644 --- a/xmclone.sh +++ b/xmclone.sh @@ -567,7 +567,7 @@ else # Deal with block devices fi echo "Copying from source block device ($BOOTIMAGE) to the new target device ($DOMU_ROOTDEV)" echo "(This may take a few minutes!)" - if ! dd if=$BOOTIMAGE of=$DOMU_ROOTDEV + if ! dd if=$BOOTIMAGE of=$DOMU_ROOTDEV bs=4K then echo "Failed to copy from $BOOTIMAGE to $DOMU_ROOTDEV" >&2 exit 1