# 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
|