[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User awilliam@xxxxxxxxxxxx # Date 1170870378 25200 # Node ID fbc233a1dc53dd0928fb8c0062d6582ef210950d # Parent d3f08d39e69530f749fdc7061a4f552bf8049804 # Parent 584ab4fd1ad5de524ea3767e4a9bc1ea6bf6a30f merge with xen-unstable.hg --- .hgignore | 1 extras/mini-os/gnttab.c | 5 extras/mini-os/netfront.c | 4 linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S | 22 -- linux-2.6-xen-sparse/drivers/xen/core/evtchn.c | 6 patches/linux-2.6.18/series | 1 patches/linux-2.6.18/softlockup-no-idle-hz.patch | 32 ++ tools/firmware/rombios/32bit/tcgbios/tcgbios.c | 14 - tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c | 52 +++- tools/firmware/rombios/32bit/util.h | 15 + tools/firmware/rombios/rombios.c | 13 - tools/ioemu/hw/cirrus_vga.c | 31 +- tools/ioemu/hw/tpm_tis.c | 13 - tools/libxc/xc_domain.c | 8 tools/libxc/xc_hvm_save.c | 21 + tools/python/xen/xend/XendLogging.py | 4 tools/python/xen/xm/main.py | 6 tools/python/xen/xm/opts.py | 4 tools/xentrace/xentrace_format | 3 xen/arch/x86/domctl.c | 25 +- xen/arch/x86/hvm/Makefile | 1 xen/arch/x86/hvm/hpet.c | 5 xen/arch/x86/hvm/hvm.c | 36 ++- xen/arch/x86/hvm/i8254.c | 28 +- xen/arch/x86/hvm/intercept.c | 176 ---------------- xen/arch/x86/hvm/irq.c | 181 +++++++++++++++- xen/arch/x86/hvm/rtc.c | 2 xen/arch/x86/hvm/save.c | 229 +++++++++++++++++++++ xen/arch/x86/hvm/svm/svm.c | 1 xen/arch/x86/hvm/svm/vmcb.c | 3 xen/arch/x86/hvm/vioapic.c | 60 ----- xen/arch/x86/hvm/vlapic.c | 23 -- xen/arch/x86/hvm/vmx/vmcs.c | 16 + xen/arch/x86/hvm/vmx/vmx.c | 7 xen/arch/x86/hvm/vpic.c | 2 xen/arch/x86/mm/shadow/multi.c | 8 xen/include/asm-x86/hvm/domain.h | 2 xen/include/asm-x86/hvm/hvm.h | 1 xen/include/asm-x86/hvm/irq.h | 63 +++++ xen/include/asm-x86/hvm/support.h | 34 ++- xen/include/asm-x86/hvm/vlapic.h | 2 xen/include/asm-x86/hvm/vpt.h | 4 xen/include/public/domctl.h | 3 xen/include/public/hvm/save.h | 185 +++++++--------- 44 files changed, 843 insertions(+), 509 deletions(-) diff -r d3f08d39e695 -r fbc233a1dc53 .hgignore --- a/.hgignore Wed Feb 07 10:14:41 2007 -0700 +++ b/.hgignore Wed Feb 07 10:46:18 2007 -0700 @@ -107,6 +107,7 @@ ^tools/firmware/rombios/BIOS-bochs-[^/]*$ ^tools/firmware/rombios/_rombios[^/]*_\.c$ ^tools/firmware/rombios/rombios[^/]*\.s$ +^tools/firmware/rombios/32bit/32bitbios_flat\.h$ ^tools/firmware/vmxassist/gen$ ^tools/firmware/vmxassist/offsets\.h$ ^tools/firmware/vmxassist/vmxassist$ diff -r d3f08d39e695 -r fbc233a1dc53 extras/mini-os/gnttab.c --- a/extras/mini-os/gnttab.c Wed Feb 07 10:14:41 2007 -0700 +++ b/extras/mini-os/gnttab.c Wed Feb 07 10:46:18 2007 -0700 @@ -21,7 +21,12 @@ #define NR_RESERVED_ENTRIES 8 +/* NR_GRANT_FRAMES must be less than or equal to that configured in Xen */ +#ifdef __ia64__ +#define NR_GRANT_FRAMES 1 +#else #define NR_GRANT_FRAMES 4 +#endif #define NR_GRANT_ENTRIES (NR_GRANT_FRAMES * PAGE_SIZE / sizeof(grant_entry_t)) static grant_entry_t *gnttab_table; diff -r d3f08d39e695 -r fbc233a1dc53 extras/mini-os/netfront.c --- a/extras/mini-os/netfront.c Wed Feb 07 10:14:41 2007 -0700 +++ b/extras/mini-os/netfront.c Wed Feb 07 10:46:18 2007 -0700 @@ -349,7 +349,9 @@ done: init_rx_buffers(); unsigned char rawmac[6]; - sscanf(mac,"%x:%x:%x:%x:%x:%x", + /* Special conversion specifier 'hh' needed for __ia64__. Without + this mini-os panics with 'Unaligned reference'. */ + sscanf(mac,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", &rawmac[0], &rawmac[1], &rawmac[2], diff -r d3f08d39e695 -r fbc233a1dc53 linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S --- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Wed Feb 07 10:14:41 2007 -0700 +++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S Wed Feb 07 10:46:18 2007 -0700 @@ -747,7 +747,7 @@ ENTRY(hypervisor_callback) jb 11f cmpl $sysexit_ecrit,%eax ja 11f - addl $0x34,%esp # Remove cs...ebx from stack frame. + addl $OLDESP,%esp # Remove eflags...ebx from stack frame. 11: push %esp call evtchn_do_upcall add $4,%esp @@ -777,18 +777,13 @@ ecrit: /**** END OF CRITICAL REGION *** # provides the number of bytes which have already been popped from the # interrupted stack frame. critical_region_fixup: - addl $critical_fixup_table-scrit,%eax - movzbl (%eax),%eax # %eax contains num bytes popped - cmpb $0xff,%al # 0xff => vcpu_info critical region + movzbl critical_fixup_table-scrit(%eax),%ecx # %eax contains num bytes popped + cmpb $0xff,%cl # 0xff => vcpu_info critical region jne 15f - GET_THREAD_INFO(%ebp) - xorl %eax,%eax -15: mov %esp,%esi - add %eax,%esi # %esi points at end of src region - mov %esp,%edi - add $0x34,%edi # %edi points at end of dst region - mov %eax,%ecx - shr $2,%ecx # convert words to bytes + xorl %ecx,%ecx +15: leal (%esp,%ecx),%esi # %esi points at end of src region + leal OLDESP(%esp),%edi # %edi points at end of dst region + shrl $2,%ecx # convert words to bytes je 17f # skip loop if nothing to copy 16: subl $4,%esi # pre-decrementing copy loop subl $4,%edi @@ -798,6 +793,7 @@ 17: movl %edi,%esp # final %edi is top 17: movl %edi,%esp # final %edi is top of merged stack jmp 11b +.section .rodata,"a" critical_fixup_table: .byte 0xff,0xff,0xff # testb $0xff,(%esi) = __TEST_PENDING .byte 0xff,0xff # jnz 14f @@ -814,6 +810,7 @@ critical_fixup_table: .byte 0x28 # iret .byte 0xff,0xff,0xff,0xff # movb $1,1(%esi) .byte 0x00,0x00 # jmp 11b +.previous # Hypervisor uses this for application faults while it executes. # We get here for two reasons: @@ -1194,6 +1191,7 @@ ENTRY(fixup_4gb_segment) jmp error_code .section .rodata,"a" +.align 4 #include "syscall_table.S" syscall_table_size=(.-sys_call_table) diff -r d3f08d39e695 -r fbc233a1dc53 linux-2.6-xen-sparse/drivers/xen/core/evtchn.c --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Wed Feb 07 10:14:41 2007 -0700 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Wed Feb 07 10:46:18 2007 -0700 @@ -424,7 +424,7 @@ static void unbind_from_irq(unsigned int static void unbind_from_irq(unsigned int irq) { struct evtchn_close close; - int evtchn = evtchn_from_irq(irq); + int cpu, evtchn = evtchn_from_irq(irq); spin_lock(&irq_mapping_update_lock); @@ -452,6 +452,10 @@ static void unbind_from_irq(unsigned int evtchn_to_irq[evtchn] = -1; irq_info[irq] = IRQ_UNBOUND; + + /* Zap stats across IRQ changes of use. */ + for_each_possible_cpu(cpu) + kstat_cpu(cpu).irqs[irq] = 0; } spin_unlock(&irq_mapping_update_lock); diff -r d3f08d39e695 -r fbc233a1dc53 patches/linux-2.6.18/series --- a/patches/linux-2.6.18/series Wed Feb 07 10:14:41 2007 -0700 +++ b/patches/linux-2.6.18/series Wed Feb 07 10:46:18 2007 -0700 @@ -18,3 +18,4 @@ x86-elfnote-as-preprocessor-macro.patch x86-elfnote-as-preprocessor-macro.patch fixaddr-top.patch git-c06cb8b1c4d25e5b4d7a2d7c2462619de1e0dbc4.patch +softlockup-no-idle-hz.patch diff -r d3f08d39e695 -r fbc233a1dc53 patches/linux-2.6.18/softlockup-no-idle-hz.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/linux-2.6.18/softlockup-no-idle-hz.patch Wed Feb 07 10:46:18 2007 -0700 @@ -0,0 +1,56 @@ +diff -pruN ../orig-linux-2.6.18/include/linux/sched.h ./include/linux/sched.h +--- ../orig-linux-2.6.18/include/linux/sched.h 2006-09-20 04:42:06.000000000 +0100 ++++ ./include/linux/sched.h 2007-02-07 01:10:24.000000000 +0000 +@@ -211,10 +211,15 @@ extern void update_process_times(int use + extern void scheduler_tick(void); + + #ifdef CONFIG_DETECT_SOFTLOCKUP ++extern unsigned long softlockup_get_next_event(void); + extern void softlockup_tick(void); + extern void spawn_softlockup_task(void); + extern void touch_softlockup_watchdog(void); + #else ++static inline unsigned long softlockup_get_next_event(void) ++{ ++ return MAX_JIFFY_OFFSET; ++} + static inline void softlockup_tick(void) + { + } +diff -pruN ../orig-linux-2.6.18/kernel/softlockup.c ./kernel/softlockup.c +--- ../orig-linux-2.6.18/kernel/softlockup.c 2006-09-20 04:42:06.000000000 +0100 ++++ ./kernel/softlockup.c 2007-02-07 01:53:22.000000000 +0000 +@@ -40,6 +40,19 @@ void touch_softlockup_watchdog(void) + } + EXPORT_SYMBOL(touch_softlockup_watchdog); + ++unsigned long softlockup_get_next_event(void) ++{ ++ int this_cpu = smp_processor_id(); ++ unsigned long touch_timestamp = per_cpu(touch_timestamp, this_cpu); ++ ++ if (per_cpu(print_timestamp, this_cpu) == touch_timestamp || ++ did_panic || ++ !per_cpu(watchdog_task, this_cpu)) ++ return MAX_JIFFY_OFFSET; ++ ++ return min_t(long, 0, touch_timestamp + HZ - jiffies); ++} ++ + /* + * This callback runs from the timer interrupt, and checks + * whether the watchdog thread has hung or not: +diff -pruN ../orig-linux-2.6.18/kernel/timer.c ./kernel/timer.c +--- ../orig-linux-2.6.18/kernel/timer.c 2006-09-20 04:42:06.000000000 +0100 ++++ ./kernel/timer.c 2007-02-07 01:29:34.000000000 +0000 +@@ -485,7 +485,9 @@ unsigned long next_timer_interrupt(void) + if (hr_expires < 3) + return hr_expires + jiffies; + } +- hr_expires += jiffies; ++ hr_expires = min_t(unsigned long, ++ softlockup_get_next_event(), ++ hr_expires) + jiffies; + + base = __get_cpu_var(tvec_bases); + spin_lock(&base->lock); diff -r d3f08d39e695 -r fbc233a1dc53 tools/firmware/rombios/32bit/tcgbios/tcgbios.c --- a/tools/firmware/rombios/32bit/tcgbios/tcgbios.c Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/firmware/rombios/32bit/tcgbios/tcgbios.c Wed Feb 07 10:46:18 2007 -0700 @@ -146,7 +146,7 @@ static int tpm_driver_to_use = TPM_INVAL static int tpm_driver_to_use = TPM_INVALID_DRIVER; static -uint32_t MA_IsTPMPresent() +uint32_t MA_IsTPMPresent(void) { uint32_t rc = 0; unsigned int i; @@ -263,11 +263,11 @@ void tcpa_acpi_init(void) { struct acpi_20_rsdt *rsdt; uint32_t length; - struct acpi_20_tcpa *tcpa; + struct acpi_20_tcpa *tcpa = (void *)0; uint16_t found = 0; uint16_t rsdp_off; uint16_t off; - struct acpi_20_rsdp *rsdp; + struct acpi_20_rsdp *rsdp = (void *)0; if (MA_IsTPMPresent() == 0) { return; @@ -732,8 +732,8 @@ void tcpa_measure_post(Bit32u from, Bit3 void tcpa_measure_post(Bit32u from, Bit32u to) { struct pcpes pcpes; /* PCClientPCREventStruc */ + int len = to - from; memset(&pcpes, 0x0, sizeof(pcpes)); - int len = to - from; if (len > 0) { sha1((unsigned char *)from, @@ -986,7 +986,7 @@ uint32_t PassThroughToTPM32(struct pttti { uint32_t rc = 0; uint8_t *cmd32; - uint32_t resbuflen; + uint32_t resbuflen = 0; if (TCG_IsShutdownPreBootInterface() != 0) { rc = (TCG_PC_TPMERROR | @@ -1277,9 +1277,7 @@ typedef struct _sha1_ctx { } sha1_ctx; -static inline uint32_t rol(val, rol) - uint32_t val; - uint16_t rol; +static inline uint32_t rol(uint32_t val, uint16_t rol) { return (val << rol) | (val >> (32 - rol)); } diff -r d3f08d39e695 -r fbc233a1dc53 tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c --- a/tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/firmware/rombios/32bit/tcgbios/tpm_drivers.c Wed Feb 07 10:46:18 2007 -0700 @@ -27,12 +27,27 @@ #include "tpm_drivers.h" #include "tcgbios.h" +#define STS_VALID (1 << 7) /* 0x80 */ +#define STS_COMMAND_READY (1 << 6) /* 0x40 */ +#define STS_TPM_GO (1 << 5) /* 0x20 */ +#define STS_DATA_AVAILABLE (1 << 4) /* 0x10 */ +#define STS_EXPECT (1 << 3) /* 0x08 */ +#define STS_RESPONSE_RETRY (1 << 1) /* 0x02 */ + +#define ACCESS_TPM_REG_VALID_STS (1 << 7) /* 0x80 */ +#define ACCESS_ACTIVE_LOCALITY (1 << 5) /* 0x20 */ +#define ACCESS_BEEN_SEIZED (1 << 4) /* 0x10 */ +#define ACCESS_SEIZE (1 << 3) /* 0x08 */ +#define ACCESS_PENDING_REQUEST (1 << 2) /* 0x04 */ +#define ACCESS_REQUEST_USE (1 << 1) /* 0x02 */ +#define ACCESS_TPM_ESTABLISHMENT (1 << 0) /* 0x01 */ + static uint32_t tis_wait_sts(uint8_t *addr, uint32_t time, uint8_t mask, uint8_t expect) { uint32_t rc = 0; while (time > 0) { - uint8_t sts = addr[TPM_STS]; + uint8_t sts = mmio_readb(&addr[TPM_STS]); if ((sts & mask) == expect) { rc = 1; break; @@ -45,16 +60,17 @@ static uint32_t tis_wait_sts(uint8_t *ad static uint32_t tis_activate(uint32_t baseaddr) { - uint32_t rc = 0; + uint32_t rc = 1; uint8_t *tis_addr = (uint8_t*)baseaddr; uint8_t acc; /* request access to locality */ - tis_addr[TPM_ACCESS] = 0x2; + tis_addr[TPM_ACCESS] = ACCESS_REQUEST_USE; - acc = tis_addr[TPM_ACCESS]; - if ((acc & 0x20) != 0) { - tis_addr[TPM_STS] = 0x40; - rc = tis_wait_sts(tis_addr, 100, 0x40, 0x40); + acc = mmio_readb(&tis_addr[TPM_ACCESS]); + if ((acc & ACCESS_ACTIVE_LOCALITY) != 0) { + tis_addr[TPM_STS] = STS_COMMAND_READY; + rc = tis_wait_sts(tis_addr, 100, + STS_COMMAND_READY, STS_COMMAND_READY); } return rc; } @@ -64,8 +80,8 @@ uint32_t tis_ready(uint32_t baseaddr) uint32_t rc = 0; uint8_t *tis_addr = (uint8_t*)baseaddr; - tis_addr[TPM_STS] = 0x40; - rc = tis_wait_sts(tis_addr, 100, 0x40, 0x40); + tis_addr[TPM_STS] = STS_COMMAND_READY; + rc = tis_wait_sts(tis_addr, 100, STS_COMMAND_READY, STS_COMMAND_READY); return rc; } @@ -81,8 +97,7 @@ uint32_t tis_senddata(uint32_t baseaddr, uint16_t burst = 0; uint32_t ctr = 0; while (burst == 0 && ctr < 2000) { - burst = (((uint16_t)tis_addr[TPM_STS+1]) ) + - (((uint16_t)tis_addr[TPM_STS+2]) << 8); + burst = mmio_readw((uint16_t *)&tis_addr[TPM_STS+1]); if (burst == 0) { mssleep(1); ctr++; @@ -120,11 +135,11 @@ uint32_t tis_readresp(uint32_t baseaddr, uint32_t sts; while (offset < len) { - buffer[offset] = tis_addr[TPM_DATA_FIFO]; + buffer[offset] = mmio_readb(&tis_addr[TPM_DATA_FIFO]); offset++; - sts = tis_addr[TPM_STS]; + sts = mmio_readb(&tis_addr[TPM_STS]); /* data left ? */ - if ((sts & 0x10) == 0) { + if ((sts & STS_DATA_AVAILABLE) == 0) { break; } } @@ -136,7 +151,7 @@ uint32_t tis_waitdatavalid(uint32_t base { uint8_t *tis_addr = (uint8_t*)baseaddr; uint32_t rc = 0; - if (tis_wait_sts(tis_addr, 1000, 0x80, 0x80) == 0) { + if (tis_wait_sts(tis_addr, 1000, STS_VALID, STS_VALID) == 0) { rc = TCG_NO_RESPONSE; } return rc; @@ -146,8 +161,9 @@ uint32_t tis_waitrespready(uint32_t base { uint32_t rc = 0; uint8_t *tis_addr = (uint8_t*)baseaddr; - tis_addr[TPM_STS] = 0x20; - if (tis_wait_sts(tis_addr, timeout, 0x10, 0x10) == 0) { + tis_addr[TPM_STS] = STS_TPM_GO; + if (tis_wait_sts(tis_addr, timeout, + STS_DATA_AVAILABLE, STS_DATA_AVAILABLE) == 0) { rc = TCG_NO_RESPONSE; } return rc; @@ -158,7 +174,7 @@ uint32_t tis_probe(uint32_t baseaddr) { uint32_t rc = 0; uint8_t *tis_addr = (uint8_t*)baseaddr; - uint32_t didvid = *(uint32_t*)&tis_addr[TPM_DID_VID]; + uint32_t didvid = mmio_readl((uint32_t *)&tis_addr[TPM_DID_VID]); if ((didvid != 0) && (didvid != 0xffffffff)) { rc = 1; } diff -r d3f08d39e695 -r fbc233a1dc53 tools/firmware/rombios/32bit/util.h --- a/tools/firmware/rombios/32bit/util.h Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/firmware/rombios/32bit/util.h Wed Feb 07 10:46:18 2007 -0700 @@ -24,5 +24,20 @@ void uuid_to_string(char *dest, uint8_t void uuid_to_string(char *dest, uint8_t *uuid); int printf(const char *fmt, ...); +static inline uint8_t mmio_readb(uint8_t *addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline uint16_t mmio_readw(uint16_t *addr) +{ + return *(volatile uint16_t *)addr; +} + +static inline uint32_t mmio_readl(uint32_t *addr) +{ + return *(volatile uint32_t *)addr; +} + #endif diff -r d3f08d39e695 -r fbc233a1dc53 tools/firmware/rombios/rombios.c --- a/tools/firmware/rombios/rombios.c Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/firmware/rombios/rombios.c Wed Feb 07 10:46:18 2007 -0700 @@ -5722,9 +5722,6 @@ int13_cdemu(DS, ES, DI, SI, BP, SP, BX, goto int13_fail; } -#if BX_TCGBIOS - tcpa_ipl((Bit32u)bootseg); /* specs: 8.2.3 steps 4 and 5 */ -#endif switch (GET_AH()) { @@ -7741,6 +7738,10 @@ ASM_END } } +#if BX_TCGBIOS + tcpa_add_bootdevice((Bit32u)0L, (Bit32u)bootdrv); +#endif + /* Canonicalize bootseg:bootip */ bootip = (bootseg & 0x0fff) << 4; bootseg &= 0xf000; @@ -7760,6 +7761,9 @@ ASM_END bootdrv = (Bit8u)(status>>8); bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment); /* Canonicalize bootseg:bootip */ +#if BX_TCGBIOS + tcpa_add_bootdevice((Bit32u)1L, (Bit32u)0L); +#endif bootip = (bootseg & 0x0fff) << 4; bootseg &= 0xf000; break; @@ -7773,6 +7777,9 @@ ASM_END default: return; } +#if BX_TCGBIOS + tcpa_ipl((Bit32u)bootseg); /* specs: 8.2.3 steps 4 and 5 */ +#endif /* Debugging info */ printf("Booting from %x:%x\n", bootseg, bootip); diff -r d3f08d39e695 -r fbc233a1dc53 tools/ioemu/hw/cirrus_vga.c --- a/tools/ioemu/hw/cirrus_vga.c Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/ioemu/hw/cirrus_vga.c Wed Feb 07 10:46:18 2007 -0700 @@ -2571,7 +2571,8 @@ static void *set_vram_mapping(unsigned l return vram_pointer; } -static int unset_vram_mapping(unsigned long begin, unsigned long end) +static int unset_vram_mapping(unsigned long begin, unsigned long end, + void *mapping) { xen_pfn_t *extent_start = NULL; unsigned long nr_extents; @@ -2591,11 +2592,13 @@ static int unset_vram_mapping(unsigned l return -1; } + /* Drop our own references to the vram pages */ + munmap(mapping, nr_extents * TARGET_PAGE_SIZE); + + /* Now drop the guest's mappings */ memset(extent_start, 0, sizeof(xen_pfn_t) * nr_extents); - for (i = 0; i < nr_extents; i++) extent_start[i] = (begin + (i * TARGET_PAGE_SIZE)) >> TARGET_PAGE_BITS; - unset_mm_mapping(xc_handle, domid, nr_extents, 0, extent_start); free(extent_start); @@ -2642,16 +2645,14 @@ static void cirrus_update_memory_access( } else { generic_io: if (s->cirrus_lfb_addr && s->cirrus_lfb_end && s->map_addr) { - int error; - void *old_vram = NULL; - - error = unset_vram_mapping(s->cirrus_lfb_addr, - s->cirrus_lfb_end); - if (!error) - old_vram = vga_update_vram((VGAState *)s, NULL, - VGA_RAM_SIZE); - if (old_vram) - munmap(old_vram, s->map_addr - s->map_end); + void *old_vram; + + old_vram = vga_update_vram((VGAState *)s, NULL, VGA_RAM_SIZE); + + unset_vram_mapping(s->cirrus_lfb_addr, + s->cirrus_lfb_end, + old_vram); + s->map_addr = s->map_end = 0; } s->cirrus_linear_write[0] = cirrus_linear_writeb; @@ -3016,10 +3017,8 @@ void cirrus_stop_acc(CirrusVGAState *s) int error; s->map_addr = 0; error = unset_vram_mapping(s->cirrus_lfb_addr, - s->cirrus_lfb_end); + s->cirrus_lfb_end, s->vram_ptr); fprintf(stderr, "cirrus_stop_acc:unset_vram_mapping.\n"); - - munmap(s->vram_ptr, VGA_RAM_SIZE); } } diff -r d3f08d39e695 -r fbc233a1dc53 tools/ioemu/hw/tpm_tis.c --- a/tools/ioemu/hw/tpm_tis.c Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/ioemu/hw/tpm_tis.c Wed Feb 07 10:46:18 2007 -0700 @@ -517,7 +517,7 @@ static uint32_t tis_mem_readl(void *opaq #ifdef DEBUG_TPM fprintf(logfile," read(%08x) = %08x\n", - addr, + (int)addr, val); #endif @@ -538,7 +538,7 @@ static void tis_mem_writel(void *opaque, #ifdef DEBUG_TPM fprintf(logfile,"write(%08x) = %08x\n", - addr, + (int)addr, val); #endif @@ -757,10 +757,11 @@ static void tpm_save(QEMUFile* f,void* o static void tpm_save(QEMUFile* f,void* opaque) { tpmState* s=(tpmState*)opaque; + uint8_t locty = s->active_loc; int c; /* need to wait for outstanding requests to complete */ - if (IS_COMM_WITH_VTPM(s)) { + if (s->loc[locty].state == STATE_EXECUTION) { int repeats = 30; /* 30 seconds; really should be infty */ while (repeats > 0 && !(s->loc[s->active_loc].sts & STS_DATA_AVAILABLE)) { @@ -777,6 +778,10 @@ static void tpm_save(QEMUFile* f,void* o } } + if (IS_COMM_WITH_VTPM(s)) { + close_vtpm_channel(s, 1); + } + qemu_put_be32s(f,&s->offset); qemu_put_buffer(f, s->buffer.buf, TPM_MAX_PKT); qemu_put_8s(f, &s->active_loc); @@ -993,7 +998,7 @@ static int TPM_Receive(tpmState *s, tpmB uint32_t size = tpm_get_size_from_buffer(buffer->buf); if (size + sizeof(buffer->instance) != off) { fprintf(logfile,"TPM: Packet size is bad! %d != %d\n", - size + sizeof(buffer->instance), + (int)(size + sizeof(buffer->instance)), off); } else { uint32_t ret; diff -r d3f08d39e695 -r fbc233a1dc53 tools/libxc/xc_domain.c --- a/tools/libxc/xc_domain.c Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/libxc/xc_domain.c Wed Feb 07 10:46:18 2007 -0700 @@ -252,12 +252,14 @@ int xc_domain_hvm_getcontext(int xc_hand domctl.u.hvmcontext.size = size; set_xen_guest_handle(domctl.u.hvmcontext.buffer, ctxt_buf); - if ( (ret = lock_pages(ctxt_buf, size)) != 0 ) - return ret; + if ( ctxt_buf ) + if ( (ret = lock_pages(ctxt_buf, size)) != 0 ) + return ret; ret = do_domctl(xc_handle, &domctl); - unlock_pages(ctxt_buf, size); + if ( ctxt_buf ) + unlock_pages(ctxt_buf, size); return (ret < 0 ? -1 : domctl.u.hvmcontext.size); } diff -r d3f08d39e695 -r fbc233a1dc53 tools/libxc/xc_hvm_save.c --- a/tools/libxc/xc_hvm_save.c Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/libxc/xc_hvm_save.c Wed Feb 07 10:46:18 2007 -0700 @@ -33,12 +33,6 @@ #include "xg_save_restore.h" /* - * Size of a buffer big enough to take the HVM state of a domain. - * Ought to calculate this a bit more carefully, or maybe ask Xen. - */ -#define HVM_CTXT_SIZE 8192 - -/* ** Default values for important tuning parameters. Can override by passing ** non-zero replacement values to xc_hvm_save(). ** @@ -286,6 +280,7 @@ int xc_hvm_save(int xc_handle, int io_fd unsigned long *pfn_batch = NULL; /* A copy of hvm domain context buffer*/ + uint32_t hvm_buf_size; uint8_t *hvm_buf = NULL; /* Live mapping of shared info structure */ @@ -431,9 +426,15 @@ int xc_hvm_save(int xc_handle, int io_fd page_array = (unsigned long *) malloc( sizeof(unsigned long) * max_pfn); - hvm_buf = malloc(HVM_CTXT_SIZE); - - if (!to_send ||!to_skip ||!page_array ||!hvm_buf ) { + hvm_buf_size = xc_domain_hvm_getcontext(xc_handle, dom, 0, 0); + if ( hvm_buf_size == -1 ) + { + ERROR("Couldn't get HVM context size from Xen"); + goto out; + } + hvm_buf = malloc(hvm_buf_size); + + if (!to_send ||!to_skip ||!page_array ||!hvm_buf) { ERROR("Couldn't allocate memory"); goto out; } @@ -661,7 +662,7 @@ int xc_hvm_save(int xc_handle, int io_fd } if ( (rec_size = xc_domain_hvm_getcontext(xc_handle, dom, hvm_buf, - HVM_CTXT_SIZE)) == -1) { + hvm_buf_size)) == -1) { ERROR("HVM:Could not get hvm buffer"); goto out; } diff -r d3f08d39e695 -r fbc233a1dc53 tools/python/xen/xend/XendLogging.py --- a/tools/python/xen/xend/XendLogging.py Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/python/xen/xend/XendLogging.py Wed Feb 07 10:46:18 2007 -0700 @@ -52,8 +52,8 @@ if 'TRACE' not in logging.__dict__: for frame in frames: filename = os.path.normcase(frame[1]) if filename != thisfile and filename != logging._srcfile: - major, minor, _, _, _ = sys.version_info - if major == 2 and minor >= 4: + major, minor, micro, _, _ = sys.version_info + if (major, minor, micro) >= (2, 4, 2): return filename, frame[2], frame[3] else: return filename, frame[2] diff -r d3f08d39e695 -r fbc233a1dc53 tools/python/xen/xm/main.py --- a/tools/python/xen/xm/main.py Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/python/xen/xm/main.py Wed Feb 07 10:46:18 2007 -0700 @@ -1144,6 +1144,9 @@ def xm_sched_sedf(args): doms = filter(lambda x : domid_match(domid, x), [parse_doms_info(dom) for dom in getDomains(None, 'running')]) + if domid is not None and doms == []: + err("Domain '%s' does not exist." % domid) + usage('sched-sedf') # print header if we aren't setting any parameters if len(opts.keys()) == 0: @@ -1207,6 +1210,9 @@ def xm_sched_credit(args): for dom in getDomains(None, 'running')]) if weight is None and cap is None: + if domid is not None and doms == []: + err("Domain '%s' does not exist." % domid) + usage('sched-credit') # print header if we aren't setting any parameters print '%-33s %-2s %-6s %-4s' % ('Name','ID','Weight','Cap') diff -r d3f08d39e695 -r fbc233a1dc53 tools/python/xen/xm/opts.py --- a/tools/python/xen/xm/opts.py Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/python/xen/xm/opts.py Wed Feb 07 10:46:18 2007 -0700 @@ -250,7 +250,8 @@ class OptVals: class OptVals: """Class to hold option values. """ - pass + def __init__(self): + self.quiet = False class Opts: """Container for options. @@ -276,7 +277,6 @@ class Opts: self.argv = [] # Option values. self.vals = OptVals() - self.vals.quiet = 0 # Variables for default scripts. self.vars = {} # Option to use for bare words. diff -r d3f08d39e695 -r fbc233a1dc53 tools/xentrace/xentrace_format --- a/tools/xentrace/xentrace_format Wed Feb 07 10:14:41 2007 -0700 +++ b/tools/xentrace/xentrace_format Wed Feb 07 10:46:18 2007 -0700 @@ -107,6 +107,9 @@ while not interrupted: (tsc, event, d1, d2, d3, d4, d5) = struct.unpack(TRCREC, line) + # Event field is 'uint32_t', not 'long'. + event &= 0xffffffff + #tsc = (tscH<<32) | tscL #print i, tsc diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/domctl.c --- a/xen/arch/x86/domctl.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/domctl.c Wed Feb 07 10:46:18 2007 -0700 @@ -326,10 +326,6 @@ long arch_do_domctl( struct hvm_domain_context c; struct domain *d; - c.cur = 0; - c.size = domctl->u.hvmcontext.size; - c.data = NULL; - ret = -ESRCH; if ( (d = get_domain_by_id(domctl->domain)) == NULL ) break; @@ -338,19 +334,38 @@ long arch_do_domctl( if ( !is_hvm_domain(d) ) goto gethvmcontext_out; + c.cur = 0; + c.size = hvm_save_size(d); + c.data = NULL; + + if ( guest_handle_is_null(domctl->u.hvmcontext.buffer) ) + { + /* Client is querying for the correct buffer size */ + domctl->u.hvmcontext.size = c.size; + ret = 0; + goto gethvmcontext_out; + } + + /* Check that the client has a big enough buffer */ + ret = -ENOSPC; + if ( domctl->u.hvmcontext.size < c.size ) + goto gethvmcontext_out; + + /* Allocate our own marshalling buffer */ ret = -ENOMEM; if ( (c.data = xmalloc_bytes(c.size)) == NULL ) goto gethvmcontext_out; ret = hvm_save(d, &c); + domctl->u.hvmcontext.size = c.cur; if ( copy_to_guest(domctl->u.hvmcontext.buffer, c.data, c.size) != 0 ) ret = -EFAULT; + gethvmcontext_out: if ( copy_to_guest(u_domctl, domctl, 1) ) ret = -EFAULT; - gethvmcontext_out: if ( c.data != NULL ) xfree(c.data); diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/Makefile --- a/xen/arch/x86/hvm/Makefile Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/Makefile Wed Feb 07 10:46:18 2007 -0700 @@ -15,3 +15,4 @@ obj-y += vioapic.o obj-y += vioapic.o obj-y += vlapic.o obj-y += vpic.o +obj-y += save.o diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/hpet.c --- a/xen/arch/x86/hvm/hpet.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/hpet.c Wed Feb 07 10:46:18 2007 -0700 @@ -383,6 +383,9 @@ static int hpet_save(struct domain *d, h { HPETState *hp = &d->arch.hvm_domain.pl_time.vhpet; + /* Write the proper value into the main counter */ + hp->hpet.mc64 = hp->mc_offset + hvm_get_guest_time(hp->vcpu); + /* Save the HPET registers */ return hvm_save_entry(HPET, 0, h, &hp->hpet); } @@ -406,7 +409,7 @@ static int hpet_load(struct domain *d, h return 0; } -HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load); +HVM_REGISTER_SAVE_RESTORE(HPET, hpet_save, hpet_load, 1, HVMSR_PER_DOM); void hpet_init(struct vcpu *v) { diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/hvm.c --- a/xen/arch/x86/hvm/hvm.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/hvm.c Wed Feb 07 10:46:18 2007 -0700 @@ -227,7 +227,8 @@ static int hvm_load_cpu_ctxt(struct doma return 0; } -HVM_REGISTER_SAVE_RESTORE(CPU, hvm_save_cpu_ctxt, hvm_load_cpu_ctxt); +HVM_REGISTER_SAVE_RESTORE(CPU, hvm_save_cpu_ctxt, hvm_load_cpu_ctxt, + 1, HVMSR_PER_VCPU); int hvm_vcpu_initialise(struct vcpu *v) { @@ -271,6 +272,24 @@ void hvm_vcpu_destroy(struct vcpu *v) /* Event channel is already freed by evtchn_destroy(). */ /*free_xen_event_channel(v, v->arch.hvm_vcpu.xen_port);*/ +} + + +void hvm_vcpu_reset(struct vcpu *v) +{ + vcpu_pause(v); + + vlapic_reset(vcpu_vlapic(v)); + + hvm_funcs.vcpu_initialise(v); + + set_bit(_VCPUF_down, &v->vcpu_flags); + clear_bit(_VCPUF_initialised, &v->vcpu_flags); + clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); + clear_bit(_VCPUF_fpu_dirtied, &v->vcpu_flags); + clear_bit(_VCPUF_blocked, &v->vcpu_flags); + + vcpu_unpause(v); } static void hvm_vcpu_down(void) @@ -624,19 +643,12 @@ void hvm_hypercall_page_initialise(struc */ int hvm_bringup_ap(int vcpuid, int trampoline_vector) { - struct vcpu *bsp = current, *v; - struct domain *d = bsp->domain; + struct vcpu *v; + struct domain *d = current->domain; struct vcpu_guest_context *ctxt; int rc = 0; BUG_ON(!is_hvm_domain(d)); - - if ( bsp->vcpu_id != 0 ) - { - gdprintk(XENLOG_ERR, "Not calling hvm_bringup_ap from BSP context.\n"); - domain_crash(bsp->domain); - return -EINVAL; - } if ( (v = d->vcpu[vcpuid]) == NULL ) return -ENOENT; @@ -668,8 +680,8 @@ int hvm_bringup_ap(int vcpuid, int tramp goto out; } - if ( test_and_clear_bit(_VCPUF_down, &d->vcpu[vcpuid]->vcpu_flags) ) - vcpu_wake(d->vcpu[vcpuid]); + if ( test_and_clear_bit(_VCPUF_down, &v->vcpu_flags) ) + vcpu_wake(v); gdprintk(XENLOG_INFO, "AP %d bringup suceeded.\n", vcpuid); out: diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/i8254.c --- a/xen/arch/x86/hvm/i8254.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/i8254.c Wed Feb 07 10:46:18 2007 -0700 @@ -83,8 +83,8 @@ static int pit_get_count(PITState *s, in struct hvm_hw_pit_channel *c = &s->hw.channels[channel]; struct periodic_time *pt = &s->pt[channel]; - d = muldiv64(hvm_get_guest_time(pt->vcpu) - - c->count_load_time, PIT_FREQ, ticks_per_sec(pt->vcpu)); + d = muldiv64(hvm_get_guest_time(pt->vcpu) - s->count_load_time[channel], + PIT_FREQ, ticks_per_sec(pt->vcpu)); switch(c->mode) { case 0: case 1: @@ -110,7 +110,7 @@ int pit_get_out(PITState *pit, int chann uint64_t d; int out; - d = muldiv64(current_time - s->count_load_time, + d = muldiv64(current_time - pit->count_load_time[channel], PIT_FREQ, ticks_per_sec(pit->pt[channel].vcpu)); switch(s->mode) { default: @@ -153,7 +153,7 @@ void pit_set_gate(PITState *pit, int cha case 5: if (s->gate < val) { /* restart counting on rising edge */ - s->count_load_time = hvm_get_guest_time(pt->vcpu); + pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); // pit_irq_timer_update(s, s->count_load_time); } break; @@ -161,7 +161,7 @@ void pit_set_gate(PITState *pit, int cha case 3: if (s->gate < val) { /* restart counting on rising edge */ - s->count_load_time = hvm_get_guest_time(pt->vcpu); + pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); // pit_irq_timer_update(s, s->count_load_time); } /* XXX: disable/enable counting */ @@ -177,8 +177,8 @@ int pit_get_gate(PITState *pit, int chan void pit_time_fired(struct vcpu *v, void *priv) { - struct hvm_hw_pit_channel *s = priv; - s->count_load_time = hvm_get_guest_time(v); + uint64_t *count_load_time = priv; + *count_load_time = hvm_get_guest_time(v); } static inline void pit_load_count(PITState *pit, int channel, int val) @@ -190,7 +190,7 @@ static inline void pit_load_count(PITSta if (val == 0) val = 0x10000; - s->count_load_time = hvm_get_guest_time(pt->vcpu); + pit->count_load_time[channel] = hvm_get_guest_time(pt->vcpu); s->count = val; period = DIV_ROUND((val * 1000000000ULL), PIT_FREQ); @@ -203,7 +203,7 @@ static inline void pit_load_count(PITSta val, period, s->mode, - (long long)s->count_load_time); + (long long)pit->count_load_time[channel]); #endif /* Choose a vcpu to set the timer on: current if appropriate else vcpu 0 */ @@ -216,11 +216,13 @@ static inline void pit_load_count(PITSta switch (s->mode) { case 2: /* create periodic time */ - create_periodic_time(v, pt, period, 0, 0, pit_time_fired, s); + create_periodic_time(v, pt, period, 0, 0, pit_time_fired, + &pit->count_load_time[channel]); break; case 1: /* create one shot time */ - create_periodic_time(v, pt, period, 0, 1, pit_time_fired, s); + create_periodic_time(v, pt, period, 0, 1, pit_time_fired, + &pit->count_load_time[channel]); #ifdef DEBUG_PIT printk("HVM_PIT: create one shot time.\n"); #endif @@ -387,7 +389,7 @@ static void pit_info(PITState *pit) printk("pit 0x%x.\n", s->mode); printk("pit 0x%x.\n", s->bcd); printk("pit 0x%x.\n", s->gate); - printk("pit %"PRId64"\n", s->count_load_time); + printk("pit %"PRId64"\n", pit->count_load_time[i]); pt = &pit->pt[i]; if (pt) { @@ -443,7 +445,7 @@ static int pit_load(struct domain *d, hv return 0; } -HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load); +HVM_REGISTER_SAVE_RESTORE(PIT, pit_save, pit_load, 1, HVMSR_PER_DOM); static void pit_reset(void *opaque) { diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/intercept.c --- a/xen/arch/x86/hvm/intercept.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/intercept.c Wed Feb 07 10:46:18 2007 -0700 @@ -29,8 +29,6 @@ #include <asm/current.h> #include <io_ports.h> #include <xen/event.h> -#include <xen/compile.h> -#include <public/version.h> extern struct hvm_mmio_handler hpet_mmio_handler; @@ -157,180 +155,6 @@ static inline void hvm_mmio_access(struc } } -/* List of handlers for various HVM save and restore types */ -static struct { - hvm_save_handler save; - hvm_load_handler load; - const char *name; -} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},}; - -/* Init-time function to add entries to that list */ -void hvm_register_savevm(uint16_t typecode, - const char *name, - hvm_save_handler save_state, - hvm_load_handler load_state) -{ - ASSERT(typecode <= HVM_SAVE_CODE_MAX); - ASSERT(hvm_sr_handlers[typecode].save == NULL); - ASSERT(hvm_sr_handlers[typecode].load == NULL); - hvm_sr_handlers[typecode].save = save_state; - hvm_sr_handlers[typecode].load = load_state; - hvm_sr_handlers[typecode].name = name; -} - - -int hvm_save(struct domain *d, hvm_domain_context_t *h) -{ - uint32_t eax, ebx, ecx, edx; - char *c; - struct hvm_save_header hdr; - struct hvm_save_end end; - hvm_save_handler handler; - uint16_t i; - - hdr.magic = HVM_FILE_MAGIC; - hdr.version = HVM_FILE_VERSION; - - /* Save some CPUID bits */ - cpuid(1, &eax, &ebx, &ecx, &edx); - hdr.cpuid = eax; - - /* Save xen changeset */ - c = strrchr(XEN_CHANGESET, ':'); - if ( c ) - hdr.changeset = simple_strtoll(c, NULL, 16); - else - hdr.changeset = -1ULL; /* Unknown */ - - if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 ) - { - gdprintk(XENLOG_ERR, "HVM save: failed to write header\n"); - return -EFAULT; - } - - /* Save all available kinds of state */ - for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) - { - handler = hvm_sr_handlers[i].save; - if ( handler != NULL ) - { - gdprintk(XENLOG_INFO, "HVM save: %s\n", hvm_sr_handlers[i].name); - if ( handler(d, h) != 0 ) - { - gdprintk(XENLOG_ERR, - "HVM save: failed to save type %"PRIu16"\n", i); - return -EFAULT; - } - } - } - - /* Save an end-of-file marker */ - if ( hvm_save_entry(END, 0, h, &end) != 0 ) - { - /* Run out of data */ - gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n"); - return -EFAULT; - } - - /* Save macros should not have let us overrun */ - ASSERT(h->cur <= h->size); - return 0; -} - -int hvm_load(struct domain *d, hvm_domain_context_t *h) -{ - uint32_t eax, ebx, ecx, edx; - char *c; - uint64_t cset; - struct hvm_save_header hdr; - struct hvm_save_descriptor *desc; - hvm_load_handler handler; - struct vcpu *v; - - /* Read the save header, which must be first */ - if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) - return -1; - - if (hdr.magic != HVM_FILE_MAGIC) { - gdprintk(XENLOG_ERR, - "HVM restore: bad magic number %#"PRIx32"\n", hdr.magic); - return -1; - } - - if (hdr.version != HVM_FILE_VERSION) { - gdprintk(XENLOG_ERR, - "HVM restore: unsupported version %u\n", hdr.version); - return -1; - } - - cpuid(1, &eax, &ebx, &ecx, &edx); - /*TODO: need to define how big a difference is acceptable */ - if (hdr.cpuid != eax) - gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") " - "does not match host (%#"PRIx32").\n", hdr.cpuid, eax); - - - c = strrchr(XEN_CHANGESET, ':'); - if ( hdr.changeset == -1ULL ) - gdprintk(XENLOG_WARNING, - "HVM restore: Xen changeset was not saved.\n"); - else if ( c == NULL ) - gdprintk(XENLOG_WARNING, - "HVM restore: Xen changeset is not available.\n"); - else - { - cset = simple_strtoll(c, NULL, 16); - if ( hdr.changeset != cset ) - gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64 - ") does not match host (%#"PRIx64").\n", hdr.changeset, cset); - } - - /* Down all the vcpus: we only re-enable the ones that had state saved. */ - for_each_vcpu(d, v) - if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) ) - vcpu_sleep_nosync(v); - - while(1) { - - if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) ) - { - /* Run out of data */ - gdprintk(XENLOG_ERR, - "HVM restore: save did not end with a null entry\n"); - return -1; - } - - /* Read the typecode of the next entry and check for the end-marker */ - desc = (struct hvm_save_descriptor *)(&h->data[h->cur]); - if ( desc->typecode == 0 ) - return 0; - - /* Find the handler for this entry */ - if ( desc->typecode > HVM_SAVE_CODE_MAX - || (handler = hvm_sr_handlers[desc->typecode].load) == NULL ) - { - gdprintk(XENLOG_ERR, - "HVM restore: unknown entry typecode %u\n", - desc->typecode); - return -1; - } - - /* Load the entry */ - gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n", - hvm_sr_handlers[desc->typecode].name, desc->instance); - if ( handler(d, h) != 0 ) - { - gdprintk(XENLOG_ERR, - "HVM restore: failed to load entry %u/%u\n", - desc->typecode, desc->instance); - return -1; - } - } - - /* Not reached */ -} - - int hvm_buffered_io_intercept(ioreq_t *p) { struct vcpu *v = current; diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/irq.c --- a/xen/arch/x86/hvm/irq.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/irq.c Wed Feb 07 10:46:18 2007 -0700 @@ -24,16 +24,17 @@ #include <xen/event.h> #include <xen/sched.h> #include <asm/hvm/domain.h> +#include <asm/hvm/support.h> static void __hvm_pci_intx_assert( struct domain *d, unsigned int device, unsigned int intx) { - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; unsigned int gsi, link, isa_irq; ASSERT((device <= 31) && (intx <= 3)); - if ( __test_and_set_bit(device*4 + intx, &hvm_irq->pci_intx) ) + if ( __test_and_set_bit(device*4 + intx, &hvm_irq->pci_intx.i) ) return; gsi = hvm_pci_intx_gsi(device, intx); @@ -41,7 +42,7 @@ static void __hvm_pci_intx_assert( vioapic_irq_positive_edge(d, gsi); link = hvm_pci_intx_link(device, intx); - isa_irq = hvm_irq->pci_link_route[link]; + isa_irq = hvm_irq->pci_link.route[link]; if ( (hvm_irq->pci_link_assert_count[link]++ == 0) && isa_irq && (hvm_irq->gsi_assert_count[isa_irq]++ == 0) ) { @@ -61,19 +62,19 @@ static void __hvm_pci_intx_deassert( static void __hvm_pci_intx_deassert( struct domain *d, unsigned int device, unsigned int intx) { - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; unsigned int gsi, link, isa_irq; ASSERT((device <= 31) && (intx <= 3)); - if ( !__test_and_clear_bit(device*4 + intx, &hvm_irq->pci_intx) ) + if ( !__test_and_clear_bit(device*4 + intx, &hvm_irq->pci_intx.i) ) return; gsi = hvm_pci_intx_gsi(device, intx); --hvm_irq->gsi_assert_count[gsi]; link = hvm_pci_intx_link(device, intx); - isa_irq = hvm_irq->pci_link_route[link]; + isa_irq = hvm_irq->pci_link.route[link]; if ( (--hvm_irq->pci_link_assert_count[link] == 0) && isa_irq && (--hvm_irq->gsi_assert_count[isa_irq] == 0) ) vpic_irq_negative_edge(d, isa_irq); @@ -90,14 +91,14 @@ void hvm_isa_irq_assert( void hvm_isa_irq_assert( struct domain *d, unsigned int isa_irq) { - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq); ASSERT(isa_irq <= 15); spin_lock(&d->arch.hvm_domain.irq_lock); - if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq) && + if ( !__test_and_set_bit(isa_irq, &hvm_irq->isa_irq.i) && (hvm_irq->gsi_assert_count[gsi]++ == 0) ) { vioapic_irq_positive_edge(d, gsi); @@ -110,14 +111,14 @@ void hvm_isa_irq_deassert( void hvm_isa_irq_deassert( struct domain *d, unsigned int isa_irq) { - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; unsigned int gsi = hvm_isa_irq_to_gsi(isa_irq); ASSERT(isa_irq <= 15); spin_lock(&d->arch.hvm_domain.irq_lock); - if ( __test_and_clear_bit(isa_irq, &hvm_irq->isa_irq) && + if ( __test_and_clear_bit(isa_irq, &hvm_irq->isa_irq.i) && (--hvm_irq->gsi_assert_count[gsi] == 0) ) vpic_irq_negative_edge(d, isa_irq); @@ -128,7 +129,7 @@ void hvm_set_callback_irq_level(void) { struct vcpu *v = current; struct domain *d = v->domain; - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; unsigned int gsi, pdev, pintx, asserted; /* Fast lock-free tests. */ @@ -178,17 +179,17 @@ void hvm_set_callback_irq_level(void) void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq) { - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; u8 old_isa_irq; ASSERT((link <= 3) && (isa_irq <= 15)); spin_lock(&d->arch.hvm_domain.irq_lock); - old_isa_irq = hvm_irq->pci_link_route[link]; + old_isa_irq = hvm_irq->pci_link.route[link]; if ( old_isa_irq == isa_irq ) goto out; - hvm_irq->pci_link_route[link] = isa_irq; + hvm_irq->pci_link.route[link] = isa_irq; if ( hvm_irq->pci_link_assert_count[link] == 0 ) goto out; @@ -211,7 +212,7 @@ void hvm_set_pci_link_route(struct domai void hvm_set_callback_via(struct domain *d, uint64_t via) { - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; unsigned int gsi=0, pdev=0, pintx=0; uint8_t via_type; @@ -335,3 +336,153 @@ int is_isa_irq_masked(struct vcpu *v, in (1 << (isa_irq & 7))) && domain_vioapic(v->domain)->redirtbl[gsi].fields.mask); } + +#if 0 /* Keep for debugging */ +static void irq_dump(struct domain *d) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + int i; + printk("PCI 0x%16.16"PRIx64"%16.16"PRIx64 + " ISA 0x%8.8"PRIx32" ROUTE %u %u %u %u\n", + hvm_irq->pci_intx.pad[0], hvm_irq->pci_intx.pad[1], + (uint32_t) hvm_irq->isa_irq.pad[0], + hvm_irq->pci_link.route[0], hvm_irq->pci_link.route[1], + hvm_irq->pci_link.route[2], hvm_irq->pci_link.route[3]); + for ( i = 0 ; i < VIOAPIC_NUM_PINS; i += 8 ) + printk("GSI %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8 + " %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8"\n", + hvm_irq->gsi_assert_count[i+0], + hvm_irq->gsi_assert_count[i+1], + hvm_irq->gsi_assert_count[i+2], + hvm_irq->gsi_assert_count[i+3], + hvm_irq->gsi_assert_count[i+4], + hvm_irq->gsi_assert_count[i+5], + hvm_irq->gsi_assert_count[i+6], + hvm_irq->gsi_assert_count[i+7]); + printk("Link %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8" %2.2"PRIu8"\n", + hvm_irq->pci_link_assert_count[0], + hvm_irq->pci_link_assert_count[1], + hvm_irq->pci_link_assert_count[2], + hvm_irq->pci_link_assert_count[3]); + printk("Callback via %i:0x%"PRIx32",%s asserted\n", + hvm_irq->callback_via_type, hvm_irq->callback_via.gsi, + hvm_irq->callback_via_asserted ? "" : " not"); +} +#endif + +static int irq_save_pci(struct domain *d, hvm_domain_context_t *h) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + + /* Save PCI IRQ lines */ + return ( hvm_save_entry(PCI_IRQ, 0, h, &hvm_irq->pci_intx) ); +} + +static int irq_save_isa(struct domain *d, hvm_domain_context_t *h) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + + /* Save ISA IRQ lines */ + return ( hvm_save_entry(ISA_IRQ, 0, h, &hvm_irq->isa_irq) ); +} + +static int irq_save_link(struct domain *d, hvm_domain_context_t *h) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + + /* Save PCI-ISA link state */ + return ( hvm_save_entry(PCI_LINK, 0, h, &hvm_irq->pci_link) ); +} + +static int irq_load_pci(struct domain *d, hvm_domain_context_t *h) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + int link, dev, intx, gsi; + + /* Load the PCI IRQ lines */ + if ( hvm_load_entry(PCI_IRQ, h, &hvm_irq->pci_intx) != 0 ) + return -EINVAL; + + /* Clear the PCI link assert counts */ + for ( link = 0; link < 4; link++ ) + hvm_irq->pci_link_assert_count[link] = 0; + + /* Clear the GSI link assert counts */ + for ( gsi = 0; gsi < VIOAPIC_NUM_PINS; gsi++ ) + hvm_irq->gsi_assert_count[gsi] = 0; + + /* Recalculate the counts from the IRQ line state */ + for ( dev = 0; dev < 32; dev++ ) + for ( intx = 0; intx < 4; intx++ ) + if ( test_bit(dev*4 + intx, &hvm_irq->pci_intx.i) ) + { + /* Direct GSI assert */ + gsi = hvm_pci_intx_gsi(dev, intx); + hvm_irq->gsi_assert_count[gsi]++; + /* PCI-ISA bridge assert */ + link = hvm_pci_intx_link(dev, intx); + hvm_irq->pci_link_assert_count[link]++; + } + + return 0; +} + +static int irq_load_isa(struct domain *d, hvm_domain_context_t *h) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + int irq; + + /* Load the ISA IRQ lines */ + if ( hvm_load_entry(ISA_IRQ, h, &hvm_irq->isa_irq) != 0 ) + return -EINVAL; + + /* Adjust the GSI assert counts for the ISA IRQ line state. + * This relies on the PCI IRQ state being loaded first. */ + for ( irq = 0; irq < 16; irq++ ) + if ( test_bit(irq, &hvm_irq->isa_irq.i) ) + hvm_irq->gsi_assert_count[hvm_isa_irq_to_gsi(irq)]++; + + return 0; +} + + +static int irq_load_link(struct domain *d, hvm_domain_context_t *h) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + int link, gsi; + + /* Load the PCI-ISA IRQ link routing table */ + if ( hvm_load_entry(PCI_LINK, h, &hvm_irq->pci_link) != 0 ) + return -EINVAL; + + /* Sanity check */ + for ( link = 0; link < 4; link++ ) + if ( hvm_irq->pci_link.route[link] > 15 ) + { + gdprintk(XENLOG_ERR, + "HVM restore: PCI-ISA link %u out of range (%u)\n", + link, hvm_irq->pci_link.route[link]); + return -EINVAL; + } + + /* Adjust the GSI assert counts for the link outputs. + * This relies on the PCI and ISA IRQ state being loaded first */ + for ( link = 0; link < 4; link++ ) + { + if ( hvm_irq->pci_link_assert_count[link] != 0 ) + { + gsi = hvm_irq->pci_link.route[link]; + if ( gsi != 0 ) + hvm_irq->gsi_assert_count[gsi]++; + } + } + + return 0; +} + +HVM_REGISTER_SAVE_RESTORE(PCI_IRQ, irq_save_pci, irq_load_pci, + 1, HVMSR_PER_DOM); +HVM_REGISTER_SAVE_RESTORE(ISA_IRQ, irq_save_isa, irq_load_isa, + 1, HVMSR_PER_DOM); +HVM_REGISTER_SAVE_RESTORE(PCI_LINK, irq_save_link, irq_load_link, + 1, HVMSR_PER_DOM); diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/rtc.c --- a/xen/arch/x86/hvm/rtc.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/rtc.c Wed Feb 07 10:46:18 2007 -0700 @@ -417,7 +417,7 @@ static int rtc_load(struct domain *d, hv return 0; } -HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, rtc_load); +HVM_REGISTER_SAVE_RESTORE(RTC, rtc_save, rtc_load, 1, HVMSR_PER_DOM); void rtc_init(struct vcpu *v, int base) diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/save.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/xen/arch/x86/hvm/save.c Wed Feb 07 10:46:18 2007 -0700 @@ -0,0 +1,229 @@ +/* + * hvm/save.c: Save and restore HVM guest's emulated hardware state. + * + * Copyright (c) 2004, Intel Corporation. + * Copyright (c) 2007, XenSource Inc. + * + * 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 <xen/config.h> +#include <xen/compile.h> +#include <xen/lib.h> +#include <public/version.h> +#include <xen/sched.h> + +#include <asm/hvm/hvm.h> +#include <asm/hvm/support.h> +#include <asm/hvm/domain.h> +#include <asm/current.h> + + +/* List of handlers for various HVM save and restore types */ +static struct { + hvm_save_handler save; + hvm_load_handler load; + const char *name; + size_t size; + int kind; +} hvm_sr_handlers [HVM_SAVE_CODE_MAX + 1] = {{NULL, NULL, "<?>"},}; + +/* Init-time function to add entries to that list */ +void hvm_register_savevm(uint16_t typecode, + const char *name, + hvm_save_handler save_state, + hvm_load_handler load_state, + size_t size, int kind) +{ + ASSERT(typecode <= HVM_SAVE_CODE_MAX); + ASSERT(hvm_sr_handlers[typecode].save == NULL); + ASSERT(hvm_sr_handlers[typecode].load == NULL); + hvm_sr_handlers[typecode].save = save_state; + hvm_sr_handlers[typecode].load = load_state; + hvm_sr_handlers[typecode].name = name; + hvm_sr_handlers[typecode].size = size; + hvm_sr_handlers[typecode].kind = kind; +} + +size_t hvm_save_size(struct domain *d) +{ + struct vcpu *v; + size_t sz; + int i; + + /* Basic overhead for header and footer */ + sz = (2 * sizeof (struct hvm_save_descriptor)) + HVM_SAVE_LENGTH(HEADER); + + /* Plus space for each thing we will be saving */ + for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) + if ( hvm_sr_handlers[i].kind == HVMSR_PER_VCPU ) + for_each_vcpu(d, v) + sz += hvm_sr_handlers[i].size; + else + sz += hvm_sr_handlers[i].size; + + return sz; +} + + +int hvm_save(struct domain *d, hvm_domain_context_t *h) +{ + uint32_t eax, ebx, ecx, edx; + char *c; + struct hvm_save_header hdr; + struct hvm_save_end end; + hvm_save_handler handler; + uint16_t i; + + hdr.magic = HVM_FILE_MAGIC; + hdr.version = HVM_FILE_VERSION; + + /* Save some CPUID bits */ + cpuid(1, &eax, &ebx, &ecx, &edx); + hdr.cpuid = eax; + + /* Save xen changeset */ + c = strrchr(XEN_CHANGESET, ':'); + if ( c ) + hdr.changeset = simple_strtoll(c, NULL, 16); + else + hdr.changeset = -1ULL; /* Unknown */ + + if ( hvm_save_entry(HEADER, 0, h, &hdr) != 0 ) + { + gdprintk(XENLOG_ERR, "HVM save: failed to write header\n"); + return -EFAULT; + } + + /* Save all available kinds of state */ + for ( i = 0; i <= HVM_SAVE_CODE_MAX; i++ ) + { + handler = hvm_sr_handlers[i].save; + if ( handler != NULL ) + { + gdprintk(XENLOG_INFO, "HVM save: %s\n", hvm_sr_handlers[i].name); + if ( handler(d, h) != 0 ) + { + gdprintk(XENLOG_ERR, + "HVM save: failed to save type %"PRIu16"\n", i); + return -EFAULT; + } + } + } + + /* Save an end-of-file marker */ + if ( hvm_save_entry(END, 0, h, &end) != 0 ) + { + /* Run out of data */ + gdprintk(XENLOG_ERR, "HVM save: no room for end marker.\n"); + return -EFAULT; + } + + /* Save macros should not have let us overrun */ + ASSERT(h->cur <= h->size); + return 0; +} + +int hvm_load(struct domain *d, hvm_domain_context_t *h) +{ + uint32_t eax, ebx, ecx, edx; + char *c; + uint64_t cset; + struct hvm_save_header hdr; + struct hvm_save_descriptor *desc; + hvm_load_handler handler; + struct vcpu *v; + + /* Read the save header, which must be first */ + if ( hvm_load_entry(HEADER, h, &hdr) != 0 ) + return -1; + + if (hdr.magic != HVM_FILE_MAGIC) { + gdprintk(XENLOG_ERR, + "HVM restore: bad magic number %#"PRIx32"\n", hdr.magic); + return -1; + } + + if (hdr.version != HVM_FILE_VERSION) { + gdprintk(XENLOG_ERR, + "HVM restore: unsupported version %u\n", hdr.version); + return -1; + } + + cpuid(1, &eax, &ebx, &ecx, &edx); + /*TODO: need to define how big a difference is acceptable */ + if (hdr.cpuid != eax) + gdprintk(XENLOG_WARNING, "HVM restore: saved CPUID (%#"PRIx32") " + "does not match host (%#"PRIx32").\n", hdr.cpuid, eax); + + + c = strrchr(XEN_CHANGESET, ':'); + if ( hdr.changeset == -1ULL ) + gdprintk(XENLOG_WARNING, + "HVM restore: Xen changeset was not saved.\n"); + else if ( c == NULL ) + gdprintk(XENLOG_WARNING, + "HVM restore: Xen changeset is not available.\n"); + else + { + cset = simple_strtoll(c, NULL, 16); + if ( hdr.changeset != cset ) + gdprintk(XENLOG_WARNING, "HVM restore: saved Xen changeset (%#"PRIx64 + ") does not match host (%#"PRIx64").\n", hdr.changeset, cset); + } + + /* Down all the vcpus: we only re-enable the ones that had state saved. */ + for_each_vcpu(d, v) + if ( test_and_set_bit(_VCPUF_down, &v->vcpu_flags) ) + vcpu_sleep_nosync(v); + + while(1) { + + if ( h->size - h->cur < sizeof(struct hvm_save_descriptor) ) + { + /* Run out of data */ + gdprintk(XENLOG_ERR, + "HVM restore: save did not end with a null entry\n"); + return -1; + } + + /* Read the typecode of the next entry and check for the end-marker */ + desc = (struct hvm_save_descriptor *)(&h->data[h->cur]); + if ( desc->typecode == 0 ) + return 0; + + /* Find the handler for this entry */ + if ( desc->typecode > HVM_SAVE_CODE_MAX + || (handler = hvm_sr_handlers[desc->typecode].load) == NULL ) + { + gdprintk(XENLOG_ERR, + "HVM restore: unknown entry typecode %u\n", + desc->typecode); + return -1; + } + + /* Load the entry */ + gdprintk(XENLOG_INFO, "HVM restore: %s %"PRIu16"\n", + hvm_sr_handlers[desc->typecode].name, desc->instance); + if ( handler(d, h) != 0 ) + { + gdprintk(XENLOG_ERR, + "HVM restore: failed to load entry %u/%u\n", + desc->typecode, desc->instance); + return -1; + } + } + + /* Not reached */ +} diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/svm/svm.c --- a/xen/arch/x86/hvm/svm/svm.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/svm/svm.c Wed Feb 07 10:46:18 2007 -0700 @@ -591,6 +591,7 @@ void svm_load_cpu_state(struct vcpu *v, { struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; + vmcb->kerngsbase = data->shadow_gs; /* MSR_LSTAR, MSR_STAR, MSR_CSTAR, MSR_SYSCALL_MASK, MSR_EFER */ vmcb->lstar = data->msr_items[0]; vmcb->star = data->msr_items[1]; diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/svm/vmcb.c --- a/xen/arch/x86/hvm/svm/vmcb.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/svm/vmcb.c Wed Feb 07 10:46:18 2007 -0700 @@ -209,7 +209,8 @@ int svm_create_vmcb(struct vcpu *v) struct arch_svm_struct *arch_svm = &v->arch.hvm_svm; int rc; - if ( (arch_svm->vmcb = alloc_vmcb()) == NULL ) + if ( (arch_svm->vmcb == NULL) && + (arch_svm->vmcb = alloc_vmcb()) == NULL ) { printk("Failed to create a new VMCB\n"); return -ENOMEM; diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/vioapic.c --- a/xen/arch/x86/hvm/vioapic.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/vioapic.c Wed Feb 07 10:46:18 2007 -0700 @@ -125,7 +125,7 @@ static void vioapic_write_redirent( struct hvm_hw_vioapic *vioapic, unsigned int idx, int top_word, uint32_t val) { struct domain *d = vioapic_domain(vioapic); - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; union vioapic_redir_entry *pent, ent; spin_lock(&d->arch.hvm_domain.irq_lock); @@ -446,7 +446,7 @@ void vioapic_update_EOI(struct domain *d void vioapic_update_EOI(struct domain *d, int vector) { struct hvm_hw_vioapic *vioapic = domain_vioapic(d); - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; union vioapic_redir_entry *ent; int gsi; @@ -486,41 +486,10 @@ static void ioapic_info(struct hvm_hw_vi } } -static void hvmirq_info(struct hvm_hw_irq *hvm_irq) -{ - int i; - printk("*****hvmirq state:*****\n"); - for (i = 0; i < BITS_TO_LONGS(32*4); i++) - printk("hvmirq pci_intx[%d]:0x%lx.\n", i, hvm_irq->pci_intx[i]); - - for (i = 0; i < BITS_TO_LONGS(16); i++) - printk("hvmirq isa_irq[%d]:0x%lx.\n", i, hvm_irq->isa_irq[i]); - - for (i = 0; i < BITS_TO_LONGS(1); i++) - printk("hvmirq callback_irq_wire[%d]:0x%lx.\n", i, hvm_irq->callback_irq_wire[i]); - - printk("hvmirq callback_via_type:0x%x.\n", hvm_irq->callback_via_type); - printk("hvmirq callback_via:0x%x.\n", hvm_irq->callback_via.gsi); - - - for (i = 0; i < 4; i++) - printk("hvmirq pci_link_route[%d]:0x%"PRIx8".\n", i, hvm_irq->pci_link_route[i]); - - for (i = 0; i < 4; i++) - printk("hvmirq pci_link_assert_count[%d]:0x%"PRIx8".\n", i, hvm_irq->pci_link_assert_count[i]); - - for (i = 0; i < VIOAPIC_NUM_PINS; i++) - printk("hvmirq gsi_assert_count[%d]:0x%"PRIx8".\n", i, hvm_irq->gsi_assert_count[i]); - - printk("hvmirq round_robin_prev_vcpu:0x%"PRIx8".\n", hvm_irq->round_robin_prev_vcpu); -} #else static void ioapic_info(struct hvm_hw_vioapic *s) { } -static void hvmirq_info(struct hvm_hw_irq *hvm_irq) -{ -} #endif @@ -532,16 +501,6 @@ static int ioapic_save(struct domain *d, /* save io-apic state*/ return ( hvm_save_entry(IOAPIC, 0, h, s) ); } - -static int ioapic_save_irqs(struct domain *d, hvm_domain_context_t *h) -{ - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; - hvmirq_info(hvm_irq); - - /* save IRQ state*/ - return ( hvm_save_entry(IRQ, 0, h, hvm_irq) ); -} - static int ioapic_load(struct domain *d, hvm_domain_context_t *h) { @@ -555,20 +514,7 @@ static int ioapic_load(struct domain *d, return 0; } -static int ioapic_load_irqs(struct domain *d, hvm_domain_context_t *h) -{ - struct hvm_hw_irq *hvm_irq = &d->arch.hvm_domain.irq; - - /* restore irq state */ - if ( hvm_load_entry(IRQ, h, hvm_irq) != 0 ) - return -EINVAL; - - hvmirq_info(hvm_irq); - return 0; -} - -HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load); -HVM_REGISTER_SAVE_RESTORE(IRQ, ioapic_save_irqs, ioapic_load_irqs); +HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_load, 1, HVMSR_PER_DOM); void vioapic_init(struct domain *d) { diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/vlapic.c Wed Feb 07 10:46:18 2007 -0700 @@ -83,8 +83,6 @@ static unsigned int vlapic_lvt_mask[VLAP #define vlapic_base_address(vlapic) \ (vlapic->hw.apic_base_msr & MSR_IA32_APICBASE_BASE) -static int vlapic_reset(struct vlapic *vlapic); - /* * Generic APIC bitmap vector update & search routines. */ @@ -293,8 +291,11 @@ static int vlapic_accept_irq(struct vcpu break; case APIC_DM_SMI: + gdprintk(XENLOG_WARNING, "Ignoring guest SMI\n"); + break; + case APIC_DM_NMI: - gdprintk(XENLOG_WARNING, "Ignoring guest SMI/NMI\n"); + gdprintk(XENLOG_WARNING, "Ignoring guest NMI\n"); break; case APIC_DM_INIT: @@ -303,10 +304,7 @@ static int vlapic_accept_irq(struct vcpu break; /* FIXME How to check the situation after vcpu reset? */ if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) ) - { - gdprintk(XENLOG_ERR, "Reset hvm vcpu not supported yet\n"); - goto exit_and_crash; - } + hvm_vcpu_reset(v); v->arch.hvm_vcpu.init_sipi_sipi_state = HVM_VCPU_INIT_SIPI_SIPI_STATE_WAIT_SIPI; result = 1; @@ -764,7 +762,7 @@ int cpu_get_apic_interrupt(struct vcpu * } /* Reset the VLPAIC back to its power-on/reset state. */ -static int vlapic_reset(struct vlapic *vlapic) +void vlapic_reset(struct vlapic *vlapic) { struct vcpu *v = vlapic_vcpu(vlapic); int i; @@ -793,8 +791,6 @@ static int vlapic_reset(struct vlapic *v vlapic_set_reg(vlapic, APIC_SPIV, 0xff); vlapic->hw.disabled |= VLAPIC_SW_DISABLED; - - return 1; } #ifdef HVM_DEBUG_SUSPEND @@ -908,8 +904,10 @@ static int lapic_load_regs(struct domain return 0; } -HVM_REGISTER_SAVE_RESTORE(LAPIC, lapic_save_hidden, lapic_load_hidden); -HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, lapic_save_regs, lapic_load_regs); +HVM_REGISTER_SAVE_RESTORE(LAPIC, lapic_save_hidden, lapic_load_hidden, + 1, HVMSR_PER_VCPU); +HVM_REGISTER_SAVE_RESTORE(LAPIC_REGS, lapic_save_regs, lapic_load_regs, + 1, HVMSR_PER_VCPU); int vlapic_init(struct vcpu *v) { @@ -922,7 +920,6 @@ int vlapic_init(struct vcpu *v) { dprintk(XENLOG_ERR, "malloc vlapic regs error for vcpu %x\n", v->vcpu_id); - xfree(vlapic); return -ENOMEM; } diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Wed Feb 07 10:46:18 2007 -0700 @@ -295,6 +295,11 @@ static void construct_vmcs(struct vcpu * vmx_vmcs_enter(v); + v->arch.hvm_vmx.cpu_cr2 = 0; + v->arch.hvm_vmx.cpu_cr3 = 0; + memset(&v->arch.hvm_vmx.msr_state, 0, sizeof(v->arch.hvm_vmx.msr_state)); + v->arch.hvm_vmx.vmxassist_enabled = 0; + /* VMCS controls. */ __vmwrite(PIN_BASED_VM_EXEC_CONTROL, vmx_pin_based_exec_control); __vmwrite(VM_EXIT_CONTROLS, vmx_vmexit_control); @@ -448,10 +453,13 @@ static void construct_vmcs(struct vcpu * int vmx_create_vmcs(struct vcpu *v) { - if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL ) - return -ENOMEM; - - __vmx_clear_vmcs(v); + if ( v->arch.hvm_vmx.vmcs == NULL ) + { + if ( (v->arch.hvm_vmx.vmcs = vmx_alloc_vmcs()) == NULL ) + return -ENOMEM; + + __vmx_clear_vmcs(v); + } construct_vmcs(v); diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/vmx/vmx.c Wed Feb 07 10:46:18 2007 -0700 @@ -588,7 +588,7 @@ void vmx_save_cpu_state(struct vcpu *v, int i = 0; data->shadow_gs = guest_state->shadow_gs; - data->vmxassist_enabled = v->arch.hvm_vmx.vmxassist_enabled; + /* save msrs */ data->flags = guest_flags; for (i = 0; i < VMX_MSR_COUNT; i++) @@ -611,10 +611,7 @@ void vmx_load_cpu_state(struct vcpu *v, guest_state->shadow_gs = data->shadow_gs; - /*XXX:no need to restore msrs, current!=vcpu as not called by arch_vmx_do_launch */ -/* vmx_restore_guest_msrs(v);*/ - - v->arch.hvm_vmx.vmxassist_enabled = data->vmxassist_enabled; + v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE); hvm_set_guest_time(v, data->tsc); diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/hvm/vpic.c --- a/xen/arch/x86/hvm/vpic.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/hvm/vpic.c Wed Feb 07 10:46:18 2007 -0700 @@ -440,7 +440,7 @@ static int vpic_load(struct domain *d, h return 0; } -HVM_REGISTER_SAVE_RESTORE(PIC, vpic_save, vpic_load); +HVM_REGISTER_SAVE_RESTORE(PIC, vpic_save, vpic_load, 2, HVMSR_PER_DOM); void vpic_init(struct domain *d) { diff -r d3f08d39e695 -r fbc233a1dc53 xen/arch/x86/mm/shadow/multi.c --- a/xen/arch/x86/mm/shadow/multi.c Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/arch/x86/mm/shadow/multi.c Wed Feb 07 10:46:18 2007 -0700 @@ -3875,11 +3875,9 @@ static inline void * emulate_map_dest(st goto page_fault; } - /* Attempted a write to a bad gfn? This should never happen: - * after all, we're here because this write is to a page table. */ - BUG_ON(!mfn_valid(mfn)); - - ASSERT(sh_mfn_is_a_page_table(mfn)); + if ( !mfn_valid(mfn) ) + return NULL; + *mfnp = mfn; return sh_map_domain_page(mfn) + (vaddr & ~PAGE_MASK); diff -r d3f08d39e695 -r fbc233a1dc53 xen/include/asm-x86/hvm/domain.h --- a/xen/include/asm-x86/hvm/domain.h Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/include/asm-x86/hvm/domain.h Wed Feb 07 10:46:18 2007 -0700 @@ -39,7 +39,7 @@ struct hvm_domain { /* Lock protects access to irq, vpic and vioapic. */ spinlock_t irq_lock; - struct hvm_hw_irq irq; + struct hvm_irq irq; struct hvm_hw_vpic vpic[2]; /* 0=master; 1=slave */ struct hvm_hw_vioapic vioapic; diff -r d3f08d39e695 -r fbc233a1dc53 xen/include/asm-x86/hvm/hvm.h --- a/xen/include/asm-x86/hvm/hvm.h Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/include/asm-x86/hvm/hvm.h Wed Feb 07 10:46:18 2007 -0700 @@ -153,6 +153,7 @@ void hvm_domain_destroy(struct domain *d int hvm_vcpu_initialise(struct vcpu *v); void hvm_vcpu_destroy(struct vcpu *v); +void hvm_vcpu_reset(struct vcpu *vcpu); void hvm_send_assist_req(struct vcpu *v); diff -r d3f08d39e695 -r fbc233a1dc53 xen/include/asm-x86/hvm/irq.h --- a/xen/include/asm-x86/hvm/irq.h Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/include/asm-x86/hvm/irq.h Wed Feb 07 10:46:18 2007 -0700 @@ -27,6 +27,69 @@ #include <asm/hvm/vpic.h> #include <asm/hvm/vioapic.h> #include <public/hvm/save.h> + + +struct hvm_irq { + /* + * Virtual interrupt wires for a single PCI bus. + * Indexed by: device*4 + INTx#. + */ + struct hvm_hw_pci_irqs pci_intx; + + /* + * Virtual interrupt wires for ISA devices. + * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing). + */ + struct hvm_hw_isa_irqs isa_irq; + + /* + * PCI-ISA interrupt router. + * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using + * the traditional 'barber's pole' mapping ((device + INTx#) & 3). + * The router provides a programmable mapping from each link to a GSI. + */ + struct hvm_hw_pci_link pci_link; + + /* Virtual interrupt and via-link for paravirtual platform driver. */ + uint32_t callback_via_asserted; + union { + enum { + HVMIRQ_callback_none, + HVMIRQ_callback_gsi, + HVMIRQ_callback_pci_intx + } callback_via_type; + uint32_t pad; /* So the next field will be aligned */ + }; + union { + uint32_t gsi; + struct { uint8_t dev, intx; } pci; + } callback_via; + + /* Number of INTx wires asserting each PCI-ISA link. */ + u8 pci_link_assert_count[4]; + + /* + * Number of wires asserting each GSI. + * + * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space + * except ISA IRQ 0, which is connected to GSI 2. + * PCI links map into this space via the PCI-ISA bridge. + * + * GSIs 16+ are used only be PCI devices. The mapping from PCI device to + * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16 + */ + u8 gsi_assert_count[VIOAPIC_NUM_PINS]; + + /* + * GSIs map onto PIC/IO-APIC in the usual way: + * 0-7: Master 8259 PIC, IO-APIC pins 0-7 + * 8-15: Slave 8259 PIC, IO-APIC pins 8-15 + * 16+ : IO-APIC pins 16+ + */ + + /* Last VCPU that was delivered a LowestPrio interrupt. */ + u8 round_robin_prev_vcpu; +}; #define hvm_pci_intx_gsi(dev, intx) \ (((((dev)<<2) + ((dev)>>3) + (intx)) & 31) + 16) diff -r d3f08d39e695 -r fbc233a1dc53 xen/include/asm-x86/hvm/support.h --- a/xen/include/asm-x86/hvm/support.h Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/include/asm-x86/hvm/support.h Wed Feb 07 10:46:18 2007 -0700 @@ -221,23 +221,37 @@ typedef int (*hvm_load_handler) (struct typedef int (*hvm_load_handler) (struct domain *d, hvm_domain_context_t *h); -/* Init-time function to declare a pair of handlers for a type */ +/* Init-time function to declare a pair of handlers for a type, + * and the maximum buffer space needed to save this type of state */ void hvm_register_savevm(uint16_t typecode, const char *name, hvm_save_handler save_state, - hvm_load_handler load_state); - -/* Syntactic sugar around that function */ -#define HVM_REGISTER_SAVE_RESTORE(_x, _save, _load) \ -static int __hvm_register_##_x##_save_and_restore(void) \ -{ \ - hvm_register_savevm(HVM_SAVE_CODE(_x), #_x, &_save, &_load); \ - return 0; \ -} \ + hvm_load_handler load_state, + size_t size, int kind); + +/* The space needed for saving can be per-domain or per-vcpu: */ +#define HVMSR_PER_DOM 0 +#define HVMSR_PER_VCPU 1 + +/* Syntactic sugar around that function: specify the max number of + * saves, and this calculates the size of buffer needed */ +#define HVM_REGISTER_SAVE_RESTORE(_x, _save, _load, _num, _k) \ +static int __hvm_register_##_x##_save_and_restore(void) \ +{ \ + hvm_register_savevm(HVM_SAVE_CODE(_x), \ + #_x, \ + &_save, \ + &_load, \ + (_num) * (HVM_SAVE_LENGTH(_x) \ + + sizeof (struct hvm_save_descriptor)), \ + _k); \ + return 0; \ +} \ __initcall(__hvm_register_##_x##_save_and_restore); /* Entry points for saving and restoring HVM domain state */ +size_t hvm_save_size(struct domain *d); int hvm_save(struct domain *d, hvm_domain_context_t *h); int hvm_load(struct domain *d, hvm_domain_context_t *h); diff -r d3f08d39e695 -r fbc233a1dc53 xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/include/asm-x86/hvm/vlapic.h Wed Feb 07 10:46:18 2007 -0700 @@ -78,6 +78,8 @@ int vlapic_init(struct vcpu *v); int vlapic_init(struct vcpu *v); void vlapic_destroy(struct vcpu *v); +void vlapic_reset(struct vlapic *vlapic); + void vlapic_msr_set(struct vlapic *vlapic, uint64_t value); int vlapic_accept_pic_intr(struct vcpu *v); diff -r d3f08d39e695 -r fbc233a1dc53 xen/include/asm-x86/hvm/vpt.h --- a/xen/include/asm-x86/hvm/vpt.h Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/include/asm-x86/hvm/vpt.h Wed Feb 07 10:46:18 2007 -0700 @@ -66,7 +66,7 @@ struct periodic_time { u64 last_plt_gtime; /* platform time when last IRQ is injected */ struct timer timer; /* ac_timer */ time_cb *cb; - void *priv; /* ponit back to platform time source */ + void *priv; /* point back to platform time source */ }; @@ -76,6 +76,8 @@ typedef struct PITState { typedef struct PITState { /* Hardware state */ struct hvm_hw_pit hw; + /* Last time the counters read zero, for calcuating counter reads */ + int64_t count_load_time[3]; /* irq handling */ struct periodic_time pt[3]; } PITState; diff -r d3f08d39e695 -r fbc233a1dc53 xen/include/public/domctl.h --- a/xen/include/public/domctl.h Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/include/public/domctl.h Wed Feb 07 10:46:18 2007 -0700 @@ -390,7 +390,8 @@ DEFINE_XEN_GUEST_HANDLE(xen_domctl_setti #define XEN_DOMCTL_sethvmcontext 34 typedef struct xen_domctl_hvmcontext { uint32_t size; /* IN/OUT: size of buffer / bytes filled */ - XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT */ + XEN_GUEST_HANDLE(uint8_t) buffer; /* IN/OUT: data, or call gethvmcontext + * with NULL buffer to get size req'd */ } xen_domctl_hvmcontext_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_hvmcontext_t); diff -r d3f08d39e695 -r fbc233a1dc53 xen/include/public/hvm/save.h --- a/xen/include/public/hvm/save.h Wed Feb 07 10:14:41 2007 -0700 +++ b/xen/include/public/hvm/save.h Wed Feb 07 10:46:18 2007 -0700 @@ -140,45 +140,16 @@ struct hvm_hw_cpu { uint64_t sysenter_esp; uint64_t sysenter_eip; - /* msr for em64t */ + /* MSRs */ uint64_t shadow_gs; uint64_t flags; - - /* same size as VMX_MSR_COUNT */ uint64_t msr_items[6]; - uint64_t vmxassist_enabled; /* guest's idea of what rdtsc() would return */ uint64_t tsc; }; DECLARE_HVM_SAVE_TYPE(CPU, 2, struct hvm_hw_cpu); - - -/* - * PIT - */ - -struct hvm_hw_pit { - struct hvm_hw_pit_channel { - int64_t count_load_time; - uint32_t count; /* can be 65536 */ - uint16_t latched_count; - uint8_t count_latched; - uint8_t status_latched; - uint8_t status; - uint8_t read_state; - uint8_t write_state; - uint8_t write_latch; - uint8_t rw_mode; - uint8_t mode; - uint8_t bcd; /* not supported */ - uint8_t gate; /* timer start */ - } channels[3]; /* 3 x 24 bytes */ - uint32_t speaker_data_on; -}; - -DECLARE_HVM_SAVE_TYPE(PIT, 3, struct hvm_hw_pit); /* @@ -233,7 +204,7 @@ struct hvm_hw_vpic { uint8_t int_output; }; -DECLARE_HVM_SAVE_TYPE(PIC, 4, struct hvm_hw_vpic); +DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic); /* @@ -275,95 +246,95 @@ struct hvm_hw_vioapic { } redirtbl[VIOAPIC_NUM_PINS]; }; -DECLARE_HVM_SAVE_TYPE(IOAPIC, 5, struct hvm_hw_vioapic); - - -/* - * IRQ - */ - -struct hvm_hw_irq { +DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic); + + +/* + * LAPIC + */ + +struct hvm_hw_lapic { + uint64_t apic_base_msr; + uint32_t disabled; /* VLAPIC_xx_DISABLED */ + uint32_t timer_divisor; +}; + +DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic); + +struct hvm_hw_lapic_regs { + /* A 4k page of register state */ + uint8_t data[0x400]; +}; + +DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs); + + +/* + * IRQs + */ + +struct hvm_hw_pci_irqs { /* * Virtual interrupt wires for a single PCI bus. * Indexed by: device*4 + INTx#. */ - DECLARE_BITMAP(pci_intx, 32*4); - + union { + DECLARE_BITMAP(i, 32*4); + uint64_t pad[2]; + }; +}; + +DECLARE_HVM_SAVE_TYPE(PCI_IRQ, 7, struct hvm_hw_pci_irqs); + +struct hvm_hw_isa_irqs { /* * Virtual interrupt wires for ISA devices. * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing). */ - DECLARE_BITMAP(isa_irq, 16); - - /* Virtual interrupt and via-link for paravirtual platform driver. */ - uint32_t callback_via_asserted; union { - enum { - HVMIRQ_callback_none, - HVMIRQ_callback_gsi, - HVMIRQ_callback_pci_intx - } callback_via_type; - uint32_t pad; /* So the next field will be aligned */ + DECLARE_BITMAP(i, 16); + uint64_t pad[1]; }; - union { - uint32_t gsi; - struct { uint8_t dev, intx; } pci; - } callback_via; - +}; + +DECLARE_HVM_SAVE_TYPE(ISA_IRQ, 8, struct hvm_hw_isa_irqs); + +struct hvm_hw_pci_link { /* * PCI-ISA interrupt router. * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using * the traditional 'barber's pole' mapping ((device + INTx#) & 3). * The router provides a programmable mapping from each link to a GSI. */ - u8 pci_link_route[4]; - - /* Number of INTx wires asserting each PCI-ISA link. */ - u8 pci_link_assert_count[4]; - - /* - * Number of wires asserting each GSI. - * - * GSIs 0-15 are the ISA IRQs. ISA devices map directly into this space - * except ISA IRQ 0, which is connected to GSI 2. - * PCI links map into this space via the PCI-ISA bridge. - * - * GSIs 16+ are used only be PCI devices. The mapping from PCI device to - * GSI is as follows: ((device*4 + device/8 + INTx#) & 31) + 16 - */ - u8 gsi_assert_count[VIOAPIC_NUM_PINS]; - - /* - * GSIs map onto PIC/IO-APIC in the usual way: - * 0-7: Master 8259 PIC, IO-APIC pins 0-7 - * 8-15: Slave 8259 PIC, IO-APIC pins 8-15 - * 16+ : IO-APIC pins 16+ - */ - - /* Last VCPU that was delivered a LowestPrio interrupt. */ - u8 round_robin_prev_vcpu; -}; - -DECLARE_HVM_SAVE_TYPE(IRQ, 6, struct hvm_hw_irq); - -/* - * LAPIC - */ - -struct hvm_hw_lapic { - uint64_t apic_base_msr; - uint32_t disabled; /* VLAPIC_xx_DISABLED */ - uint32_t timer_divisor; -}; - -DECLARE_HVM_SAVE_TYPE(LAPIC, 7, struct hvm_hw_lapic); - -struct hvm_hw_lapic_regs { - /* A 4k page of register state */ - uint8_t data[0x400]; -}; - -DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 8, struct hvm_hw_lapic_regs); + u8 route[4]; +}; + +DECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link); + + +/* + * PIT + */ + +struct hvm_hw_pit { + struct hvm_hw_pit_channel { + uint32_t count; /* can be 65536 */ + uint16_t latched_count; + uint8_t count_latched; + uint8_t status_latched; + uint8_t status; + uint8_t read_state; + uint8_t write_state; + uint8_t write_latch; + uint8_t rw_mode; + uint8_t mode; + uint8_t bcd; /* not supported */ + uint8_t gate; /* timer start */ + } channels[3]; /* 3 x 16 bytes */ + uint32_t speaker_data_on; +}; + +DECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit); /* @@ -378,7 +349,7 @@ struct hvm_hw_rtc { uint8_t cmos_index; }; -DECLARE_HVM_SAVE_TYPE(RTC, 9, struct hvm_hw_rtc); +DECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc); /* @@ -408,13 +379,13 @@ struct hvm_hw_hpet { uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */ }; -DECLARE_HVM_SAVE_TYPE(HPET, 10, struct hvm_hw_hpet); +DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet); /* * Largest type-code in use */ -#define HVM_SAVE_CODE_MAX 10 +#define HVM_SAVE_CODE_MAX 12 /* _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |