# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 63cb737b9a249f0f6450e1d7f46b6b49cfaa78aa
# Parent 529b3f3fb12790dd22d252d504585a642e09fb01
# Parent 9a341c6ef6ae2ce90ccdcf89718d4365426d9d96
merge with xen-unstable.hg
---
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S |
3
linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c |
8
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c |
6
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c |
27 +
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c |
5
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c |
10
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h |
2
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h |
4
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h |
1
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h |
1
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h |
6
tools/check/check_crypto_lib |
11
tools/check/check_openssl_devel |
11
tools/check/check_x11_devel |
11
tools/firmware/vmxassist/vm86.c |
75 ++++
tools/ioemu/hw/piix4acpi.c |
14
tools/ioemu/hw/piix_pci.c |
18 -
tools/ioemu/hw/serial.c |
26 +
tools/ioemu/vl.c |
3
tools/libfsimage/common/fsimage_grub.c |
2
tools/libfsimage/ext2fs/fsys_ext2fs.c |
61 +++
tools/libfsimage/reiserfs/fsys_reiserfs.c |
57 +++
tools/xenstore/xenstored_core.c |
29 +
tools/xenstore/xenstored_domain.c |
41 +-
tools/xenstore/xenstored_domain.h |
4
xen/arch/x86/boot/x86_32.S |
5
xen/arch/x86/boot/x86_64.S |
5
xen/arch/x86/cpu/mcheck/Makefile |
6
xen/arch/x86/cpu/mcheck/mce.c |
4
xen/arch/x86/cpu/mtrr/Makefile |
6
xen/arch/x86/cpu/mtrr/main.c |
8
xen/arch/x86/domain.c |
27 -
xen/arch/x86/hvm/hvm.c |
3
xen/arch/x86/hvm/intercept.c |
6
xen/arch/x86/hvm/io.c |
23 -
xen/arch/x86/hvm/platform.c |
3
xen/arch/x86/hvm/svm/svm.c |
120 +++----
xen/arch/x86/hvm/vioapic.c |
37 --
xen/arch/x86/hvm/vlapic.c |
127 +++-----
xen/arch/x86/hvm/vmx/vmcs.c |
4
xen/arch/x86/hvm/vmx/vmx.c |
156 +++++-----
xen/arch/x86/mm.c |
19 -
xen/arch/x86/oprofile/xenoprof.c |
2
xen/arch/x86/physdev.c |
2
xen/arch/x86/traps.c |
4
xen/arch/x86/x86_32/traps.c |
53 ++-
xen/arch/x86/x86_64/entry.S |
8
xen/arch/x86/x86_64/mm.c |
36 +-
xen/arch/x86/x86_64/traps.c |
49 +--
xen/common/domain.c |
5
xen/include/asm-x86/bitops.h |
2
xen/include/asm-x86/config.h |
6
xen/include/asm-x86/desc.h |
5
xen/include/asm-x86/hvm/support.h |
7
xen/include/asm-x86/hvm/vlapic.h |
2
xen/include/public/elfnote.h |
9
xen/include/public/hvm/ioreq.h |
2
57 files changed, 727 insertions(+), 460 deletions(-)
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S
--- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Fri Nov 10 13:01:23
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S Mon Nov 13 09:58:23
2006 -0700
@@ -9,7 +9,7 @@
#include <asm/page.h>
#include <asm/thread_info.h>
#include <asm/asm-offsets.h>
-#include <xen/interface/arch-x86_32.h>
+#include <xen/interface/xen.h>
#include <xen/interface/elfnote.h>
/*
@@ -192,6 +192,7 @@ ENTRY(cpu_gdt_table)
#endif /* !CONFIG_XEN_COMPAT_030002 */
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, startup_32)
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page)
+ ELFNOTE(Xen, XEN_ELFNOTE_HV_START_LOW, .long, HYPERVISOR_VIRT_START)
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz,
"writable_page_tables|writable_descriptor_tables|auto_translated_physmap|pae_pgdir_above_4gb|supervisor_mode_kernel")
#ifdef CONFIG_X86_PAE
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "yes")
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c Fri Nov 10 13:01:23
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c Mon Nov 13 09:58:23
2006 -0700
@@ -282,12 +282,6 @@ static int spurious_fault(struct pt_regs
pmd_t *pmd;
pte_t *pte;
-#ifdef CONFIG_XEN
- /* Faults in hypervisor area are never spurious. */
- if (address >= HYPERVISOR_VIRT_START)
- return 0;
-#endif
-
/* Reserved-bit violation or user access to kernel space? */
if (error_code & 0x0c)
return 0;
@@ -372,7 +366,7 @@ fastcall void __kprobes do_page_fault(st
if (unlikely(address >= TASK_SIZE)) {
#ifdef CONFIG_XEN
/* Faults in hypervisor area can never be patched up. */
- if (address >= HYPERVISOR_VIRT_START)
+ if (address >= hypervisor_virt_start)
goto bad_area_nosemaphore;
#endif
if (!(error_code & 5))
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/arch/i386/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Fri Nov 10 13:01:23
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/init-xen.c Mon Nov 13 09:58:23
2006 -0700
@@ -130,7 +130,7 @@ static void __init page_table_range_init
pud = pud_offset(pgd, vaddr);
pmd = pmd_offset(pud, vaddr);
for (; (pmd_idx < PTRS_PER_PMD) && (vaddr != end); pmd++,
pmd_idx++) {
- if (vaddr < HYPERVISOR_VIRT_START && pmd_none(*pmd))
+ if (vaddr < hypervisor_virt_start && pmd_none(*pmd))
one_page_table_init(pmd);
vaddr += PMD_SIZE;
@@ -187,7 +187,7 @@ static void __init kernel_physical_mappi
pmd += pmd_idx;
for (; pmd_idx < PTRS_PER_PMD && pfn < max_low_pfn; pmd++,
pmd_idx++) {
unsigned int address = pfn * PAGE_SIZE + PAGE_OFFSET;
- if (address >= HYPERVISOR_VIRT_START)
+ if (address >= hypervisor_virt_start)
continue;
/* Map with big pages if possible, otherwise create
normal page tables. */
@@ -410,7 +410,7 @@ static void __init pagetable_init (void)
* created - mappings will be set by set_fixmap():
*/
vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK;
- page_table_range_init(vaddr, 0, pgd_base);
+ page_table_range_init(vaddr, hypervisor_virt_start, pgd_base);
permanent_kmaps_init(pgd_base);
}
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c
--- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Fri Nov 10 13:01:23
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c Mon Nov 13 09:58:23
2006 -0700
@@ -102,8 +102,11 @@ static void set_pte_pfn(unsigned long va
return;
}
pte = pte_offset_kernel(pmd, vaddr);
- /* <pfn,flags> stored as-is, to permit clearing entries */
- set_pte(pte, pfn_pte(pfn, flags));
+ if (pgprot_val(flags))
+ /* <pfn,flags> stored as-is, to permit clearing entries */
+ set_pte(pte, pfn_pte(pfn, flags));
+ else
+ pte_clear(&init_mm, vaddr, pte);
/*
* It's enough to flush this one mapping.
@@ -140,8 +143,11 @@ static void set_pte_pfn_ma(unsigned long
return;
}
pte = pte_offset_kernel(pmd, vaddr);
- /* <pfn,flags> stored as-is, to permit clearing entries */
- set_pte(pte, pfn_pte_ma(pfn, flags));
+ if (pgprot_val(flags))
+ /* <pfn,flags> stored as-is, to permit clearing entries */
+ set_pte(pte, pfn_pte_ma(pfn, flags));
+ else
+ pte_clear(&init_mm, vaddr, pte);
/*
* It's enough to flush this one mapping.
@@ -186,8 +192,15 @@ void set_pmd_pfn(unsigned long vaddr, un
}
static int nr_fixmaps = 0;
+unsigned long hypervisor_virt_start = HYPERVISOR_VIRT_START;
unsigned long __FIXADDR_TOP = (HYPERVISOR_VIRT_START - 2 * PAGE_SIZE);
EXPORT_SYMBOL(__FIXADDR_TOP);
+
+void __init set_fixaddr_top()
+{
+ BUG_ON(nr_fixmaps > 0);
+ __FIXADDR_TOP = hypervisor_virt_start - 2 * PAGE_SIZE;
+}
void __set_fixmap (enum fixed_addresses idx, maddr_t phys, pgprot_t flags)
{
@@ -209,12 +222,6 @@ void __set_fixmap (enum fixed_addresses
break;
}
nr_fixmaps++;
-}
-
-void set_fixaddr_top(unsigned long top)
-{
- BUG_ON(nr_fixmaps > 0);
- __FIXADDR_TOP = top - PAGE_SIZE;
}
pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c
--- a/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Fri Nov 10 13:01:23
2006 -0700
+++ b/linux-2.6-xen-sparse/arch/x86_64/mm/init-xen.c Mon Nov 13 09:58:23
2006 -0700
@@ -260,7 +260,10 @@ static void set_pte_phys(unsigned long v
return;
}
}
- new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
+ if (pgprot_val(prot))
+ new_pte = pfn_pte(phys >> PAGE_SHIFT, prot);
+ else
+ new_pte = __pte(0);
pte = pte_offset_kernel(pmd, vaddr);
if (!pte_none(*pte) &&
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c
--- a/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Fri Nov 10
13:01:23 2006 -0700
+++ b/linux-2.6-xen-sparse/drivers/xen/privcmd/privcmd.c Mon Nov 13
09:58:23 2006 -0700
@@ -165,7 +165,7 @@ static int privcmd_ioctl(struct inode *i
struct mm_struct *mm = current->mm;
struct vm_area_struct *vma;
xen_pfn_t __user *p;
- unsigned long addr, mfn;
+ unsigned long addr, mfn, nr_pages;
int i;
if (!is_initial_xendomain())
@@ -174,7 +174,8 @@ static int privcmd_ioctl(struct inode *i
if (copy_from_user(&m, udata, sizeof(m)))
return -EFAULT;
- if ((m.num <= 0) || (m.num > (LONG_MAX >> PAGE_SHIFT)))
+ nr_pages = m.num;
+ if ((m.num <= 0) || (nr_pages > (LONG_MAX >> PAGE_SHIFT)))
return -EINVAL;
down_read(&mm->mmap_sem);
@@ -182,8 +183,7 @@ static int privcmd_ioctl(struct inode *i
vma = find_vma(mm, m.addr);
if (!vma ||
(m.addr != vma->vm_start) ||
- ((m.addr + ((unsigned long)m.num<<PAGE_SHIFT)) !=
- vma->vm_end) ||
+ ((m.addr + (nr_pages << PAGE_SHIFT)) != vma->vm_end) ||
!privcmd_enforce_singleshot_mapping(vma)) {
up_read(&mm->mmap_sem);
return -EINVAL;
@@ -191,7 +191,7 @@ static int privcmd_ioctl(struct inode *i
p = m.arr;
addr = m.addr;
- for (i = 0; i < m.num; i++, addr += PAGE_SIZE, p++) {
+ for (i = 0; i < nr_pages; i++, addr += PAGE_SIZE, p++) {
if (get_user(mfn, p)) {
up_read(&mm->mmap_sem);
return -EFAULT;
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h Fri Nov
10 13:01:23 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/fixmap.h Mon Nov
13 09:58:23 2006 -0700
@@ -98,7 +98,7 @@ extern void __set_fixmap(enum fixed_addr
extern void __set_fixmap(enum fixed_addresses idx,
maddr_t phys, pgprot_t flags);
-extern void set_fixaddr_top(unsigned long top);
+extern void set_fixaddr_top(void);
#define set_fixmap(idx, phys) \
__set_fixmap(idx, phys, PAGE_KERNEL)
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Fri Nov
10 13:01:23 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/hypervisor.h Mon Nov
13 09:58:23 2006 -0700
@@ -56,6 +56,10 @@
extern shared_info_t *HYPERVISOR_shared_info;
+#ifdef CONFIG_X86_32
+extern unsigned long hypervisor_virt_start;
+#endif
+
/* arch/xen/i386/kernel/setup.c */
extern start_info_t *xen_start_info;
#ifdef CONFIG_XEN_PRIVILEGED_GUEST
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h
Fri Nov 10 13:01:23 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-2level-defs.h
Mon Nov 13 09:58:23 2006 -0700
@@ -9,7 +9,6 @@
#define PGDIR_SHIFT 22
#define PTRS_PER_PGD 1024
-#define PTRS_PER_PGD_NO_HV (HYPERVISOR_VIRT_START >> PGDIR_SHIFT)
/*
* the i386 is two-level, so we don't really have any
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h
Fri Nov 10 13:01:23 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/pgtable-3level-defs.h
Mon Nov 13 09:58:23 2006 -0700
@@ -8,7 +8,6 @@
*/
#define PGDIR_SHIFT 30
#define PTRS_PER_PGD 4
-#define PTRS_PER_PGD_NO_HV 4
/*
* PMD_SHIFT determines the size of the area a middle-level
diff -r 529b3f3fb127 -r 63cb737b9a24
linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h
--- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Fri Nov
10 13:01:23 2006 -0700
+++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/setup_arch_post.h Mon Nov
13 09:58:23 2006 -0700
@@ -92,8 +92,10 @@ static void __init machine_specific_arch
#endif
if (HYPERVISOR_xen_version(XENVER_platform_parameters,
- &pp) == 0)
- set_fixaddr_top(pp.virt_start - PAGE_SIZE);
+ &pp) == 0) {
+ hypervisor_virt_start = pp.virt_start;
+ set_fixaddr_top();
+ }
machine_to_phys_mapping = (unsigned long *)MACH2PHYS_VIRT_START;
machine_to_phys_nr_ents = MACH2PHYS_NR_ENTRIES;
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/firmware/vmxassist/vm86.c Mon Nov 13 09:58:23 2006 -0700
@@ -813,6 +813,58 @@ pop(struct regs *regs, unsigned prefix,
return 1;
}
+static int
+mov_to_seg(struct regs *regs, unsigned prefix, unsigned opc)
+{
+ unsigned eip = regs->eip - 1;
+ unsigned modrm = fetch8(regs);
+ unsigned addr = operand(prefix, regs, modrm);
+
+ /* Only need to emulate segment loads in real->protected mode. */
+ if (mode != VM86_REAL_TO_PROTECTED)
+ return 0;
+
+ /* Register source only. */
+ if ((modrm & 0xC0) != 0xC0)
+ goto fail;
+
+ switch ((modrm & 0x38) >> 3) {
+ case 0: /* es */
+ regs->ves = getreg16(regs, modrm);
+ saved_rm_regs.ves = 0;
+ oldctx.es_sel = regs->ves;
+ return 1;
+
+ /* case 1: cs */
+
+ case 2: /* ss */
+ regs->uss = getreg16(regs, modrm);
+ saved_rm_regs.uss = 0;
+ oldctx.ss_sel = regs->uss;
+ return 1;
+ case 3: /* ds */
+ regs->vds = getreg16(regs, modrm);
+ saved_rm_regs.vds = 0;
+ oldctx.ds_sel = regs->vds;
+ return 1;
+ case 4: /* fs */
+ regs->vfs = getreg16(regs, modrm);
+ saved_rm_regs.vfs = 0;
+ oldctx.fs_sel = regs->vfs;
+ return 1;
+ case 5: /* gs */
+ regs->vgs = getreg16(regs, modrm);
+ saved_rm_regs.vgs = 0;
+ oldctx.gs_sel = regs->vgs;
+ return 1;
+ }
+
+ fail:
+ printf("%s:%d: missed opcode %02x %02x\n",
+ __FUNCTION__, __LINE__, opc, modrm);
+ return 0;
+}
+
/*
* Emulate a segment load in protected mode
*/
@@ -1257,11 +1309,9 @@ opcode(struct regs *regs)
for (;;) {
switch ((opc = fetch8(regs))) {
- case 0x07:
- if (prefix & DATA32)
- regs->ves = pop32(regs);
- else
- regs->ves = pop16(regs);
+ case 0x07: /* pop %es */
+ regs->ves = (prefix & DATA32) ?
+ pop32(regs) : pop16(regs);
TRACE((regs, regs->eip - eip, "pop %%es"));
if (mode == VM86_REAL_TO_PROTECTED) {
saved_rm_regs.ves = 0;
@@ -1316,6 +1366,16 @@ opcode(struct regs *regs)
}
goto invalid;
+ case 0x1F: /* pop %ds */
+ regs->vds = (prefix & DATA32) ?
+ pop32(regs) : pop16(regs);
+ TRACE((regs, regs->eip - eip, "pop %%ds"));
+ if (mode == VM86_REAL_TO_PROTECTED) {
+ saved_rm_regs.vds = 0;
+ oldctx.ds_sel = regs->vds;
+ }
+ return OPC_EMULATED;
+
case 0x26:
TRACE((regs, regs->eip - eip, "%%es:"));
prefix |= SEG_ES;
@@ -1402,6 +1462,11 @@ opcode(struct regs *regs)
goto invalid;
return OPC_EMULATED;
+ case 0x8E: /* mov r16, sreg */
+ if (!mov_to_seg(regs, prefix, opc))
+ goto invalid;
+ return OPC_EMULATED;
+
case 0x8F: /* addr32 pop r/m16 */
if ((prefix & ADDR32) == 0)
goto invalid;
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/ioemu/hw/piix4acpi.c
--- a/tools/ioemu/hw/piix4acpi.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/ioemu/hw/piix4acpi.c Mon Nov 13 09:58:23 2006 -0700
@@ -398,8 +398,16 @@ void pci_piix4_acpi_init(PCIBus *bus, in
pci_conf[0x0e] = 0x00;
pci_conf[0x3d] = 0x01; /* Hardwired to PIRQA is used */
- pci_register_io_region((PCIDevice *)d, 4, 0x10,
- PCI_ADDRESS_SPACE_IO, acpi_map);
-
+
+ /* PMBA POWER MANAGEMENT BASE ADDRESS, hardcoded to 0x1f40
+ * to make shutdown work for IPF, due to IPF Guest Firmware
+ * will enumerate pci devices.
+ *
+ * TODO: if Guest Firmware or Guest OS will change this PMBA,
+ * More logic will be added.
+ */
+ pci_conf[0x40] = 0x41; /* Special device-specific BAR at 0x40 */
+ pci_conf[0x41] = 0x1f;
+ acpi_map(d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO);
acpi_reset(d);
}
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/ioemu/hw/piix_pci.c
--- a/tools/ioemu/hw/piix_pci.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/ioemu/hw/piix_pci.c Mon Nov 13 09:58:23 2006 -0700
@@ -338,10 +338,14 @@ static void pci_bios_init_device(PCIDevi
break;
case 0x0680:
if (vendor_id == 0x8086 && device_id == 0x7113) {
- /* PIIX4 ACPI PM */
- pci_config_writew(d, 0x20, 0x0000); /* NO smb bus IO enable in
PIIX4 */
+ /*
+ * PIIX4 ACPI PM.
+ * Special device with special PCI config space. No ordinary BARs.
+ */
+ pci_config_writew(d, 0x20, 0x0000); // No smb bus IO enable
pci_config_writew(d, 0x22, 0x0000);
- goto default_map;
+ pci_config_writew(d, 0x3c, 0x0009); // Hardcoded IRQ9
+ pci_config_writew(d, 0x3d, 0x0001);
}
break;
case 0x0300:
@@ -394,14 +398,6 @@ static void pci_bios_init_device(PCIDevi
pic_irq = pci_irqs[pin];
pci_config_writeb(d, PCI_INTERRUPT_LINE, pic_irq);
}
-
- if (class== 0x0680&& vendor_id == 0x8086 && device_id == 0x7113) {
- // PIIX4 ACPI PM
- pci_config_writew(d, 0x20, 0x0000); // NO smb bus IO enable in PIIX4
- pci_config_writew(d, 0x22, 0x0000);
- pci_config_writew(d, 0x3c, 0x0009); // Hardcodeed IRQ9
- pci_config_writew(d, 0x3d, 0x0001);
- }
}
/*
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/ioemu/hw/serial.c
--- a/tools/ioemu/hw/serial.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/ioemu/hw/serial.c Mon Nov 13 09:58:23 2006 -0700
@@ -73,6 +73,11 @@
#define UART_LSR_OE 0x02 /* Overrun error indicator */
#define UART_LSR_DR 0x01 /* Receiver data ready */
+/* Maximum retries for a single byte transmit. */
+#define WRITE_MAX_SINGLE_RETRIES 3
+/* Maximum retries for a sequence of back-to-back unsuccessful transmits. */
+#define WRITE_MAX_TOTAL_RETRIES 10
+
struct SerialState {
uint8_t divider;
uint8_t rbr; /* receive register */
@@ -98,8 +103,12 @@ struct SerialState {
* If a character transmitted via UART cannot be written to its
* destination immediately we remember it here and retry a few times via
* a polling timer.
+ * - write_single_retries: Number of write retries for current byte.
+ * - write_total_retries: Number of write retries for back-to-back
+ * unsuccessful transmits.
*/
- int write_retries;
+ int write_single_retries;
+ int write_total_retries;
char write_chr;
QEMUTimer *write_retry_timer;
};
@@ -217,16 +226,21 @@ static void serial_chr_write(void *opaqu
{
SerialState *s = opaque;
+ /* Cancel any outstanding retry if this is a new byte. */
qemu_del_timer(s->write_retry_timer);
/* Retry every 100ms for 300ms total. */
if (qemu_chr_write(s->chr, &s->write_chr, 1) == -1) {
- if (s->write_retries++ >= 3)
- printf("serial: write error\n");
- else
+ s->write_total_retries++;
+ if (s->write_single_retries++ >= WRITE_MAX_SINGLE_RETRIES)
+ fprintf(stderr, "serial: write error\n");
+ else if (s->write_total_retries <= WRITE_MAX_TOTAL_RETRIES) {
qemu_mod_timer(s->write_retry_timer,
qemu_get_clock(vm_clock) + ticks_per_sec / 10);
- return;
+ return;
+ }
+ } else {
+ s->write_total_retries = 0; /* if successful then reset counter */
}
/* Success: Notify guest that THR is empty. */
@@ -255,7 +269,7 @@ static void serial_ioport_write(void *op
s->lsr &= ~UART_LSR_THRE;
serial_update_irq(s);
s->write_chr = val;
- s->write_retries = 0;
+ s->write_single_retries = 0;
serial_chr_write(s);
}
break;
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/ioemu/vl.c
--- a/tools/ioemu/vl.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/ioemu/vl.c Mon Nov 13 09:58:23 2006 -0700
@@ -6424,7 +6424,8 @@ int main(int argc, char **argv)
page_array[i] = i;
if (xc_domain_translate_gpfn_list(xc_handle, domid, tmp_nr_pages,
page_array, page_array)) {
- fprintf(logfile, "xc_get_pfn_list returned error %d\n", errno);
+ fprintf(logfile, "xc_domain_translate_gpfn_list returned error %d\n",
+ errno);
exit(-1);
}
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/libfsimage/common/fsimage_grub.c
--- a/tools/libfsimage/common/fsimage_grub.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/libfsimage/common/fsimage_grub.c Mon Nov 13 09:58:23 2006 -0700
@@ -126,7 +126,7 @@ fsig_devread(fsi_file_t *ffi, unsigned i
fsig_devread(fsi_file_t *ffi, unsigned int sector, unsigned int offset,
unsigned int bufsize, char *buf)
{
- uint64_t off = ffi->ff_fsi->f_off + ((uint64_t)(sector * 512)) + offset;
+ uint64_t off = ffi->ff_fsi->f_off + ((uint64_t)sector * 512) + offset;
ssize_t bytes_read = 0;
while (bufsize) {
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/libfsimage/ext2fs/fsys_ext2fs.c
--- a/tools/libfsimage/ext2fs/fsys_ext2fs.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/libfsimage/ext2fs/fsys_ext2fs.c Mon Nov 13 09:58:23 2006 -0700
@@ -232,6 +232,7 @@ struct ext2_dir_entry
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#if defined(__i386__) || defined(__x86_64__)
/* include/asm-i386/bitops.h */
/*
* ffz = Find First Zero in word. Undefined if no zero exists,
@@ -250,6 +251,66 @@ ffz (unsigned long word)
: "r" (~word));
return word;
}
+
+#elif defined(__ia64__)
+
+typedef unsigned long __u64;
+
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# define ia64_popcnt(x) __builtin_popcountl(x)
+#else
+# define ia64_popcnt(x) \
+ ({ \
+ __u64 ia64_intri_res; \
+ asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
+ ia64_intri_res; \
+ })
+#endif
+
+static __inline__ unsigned long
+ffz (unsigned long word)
+{
+ unsigned long result;
+
+ result = ia64_popcnt(word & (~word - 1));
+ return result;
+}
+
+#elif defined(__powerpc__)
+
+static __inline__ int
+__ilog2(unsigned long x)
+{
+ int lz;
+
+ asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
+ return BITS_PER_LONG - 1 - lz;
+}
+
+static __inline__ unsigned long
+ffz (unsigned long word)
+{
+ if ((word = ~word) == 0)
+ return BITS_PER_LONG;
+ return __ilog2(word & -word);
+}
+
+#else /* Unoptimized */
+
+static __inline__ unsigned long
+ffz (unsigned long word)
+{
+ unsigned long result;
+
+ result = 0;
+ while(word & 1)
+ {
+ result++;
+ word >>= 1;
+ }
+ return result;
+}
+#endif
/* check filesystem types and read superblock into memory buffer */
int
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/libfsimage/reiserfs/fsys_reiserfs.c
--- a/tools/libfsimage/reiserfs/fsys_reiserfs.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/libfsimage/reiserfs/fsys_reiserfs.c Mon Nov 13 09:58:23 2006 -0700
@@ -363,6 +363,8 @@ struct fsys_reiser_info
#define JOURNAL_START ((__u32 *) (INFO + 1))
#define JOURNAL_END ((__u32 *) (FSYS_BUF + FSYS_BUFLEN))
+#if defined(__i386__) || defined(__x86_64__)
+
#ifdef __amd64
#define BSF "bsfq"
#else
@@ -376,6 +378,61 @@ grub_log2 (unsigned long word)
: "r" (word));
return word;
}
+
+#elif defined(__ia64__)
+
+#if __GNUC__ >= 4 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+# define ia64_popcnt(x) __builtin_popcountl(x)
+#else
+# define ia64_popcnt(x) \
+ ({ \
+ __u64 ia64_intri_res; \
+ asm ("popcnt %0=%1" : "=r" (ia64_intri_res) : "r" (x)); \
+ ia64_intri_res; \
+ })
+#endif
+
+static __inline__ unsigned long
+grub_log2 (unsigned long word)
+{
+ unsigned long result;
+
+ result = ia64_popcnt((word - 1) & ~word);
+ return result;
+}
+
+#elif defined(__powerpc__)
+
+static __inline__ int
+__ilog2(unsigned long x)
+{
+ int lz;
+
+ asm (PPC_CNTLZL "%0,%1" : "=r" (lz) : "r" (x));
+ return BITS_PER_LONG - 1 - lz;
+}
+
+static __inline__ unsigned long
+grub_log2 (unsigned long word)
+{
+ return __ilog2(word & -word);
+}
+
+#else /* Unoptimized */
+
+static __inline__ unsigned long
+grub_log2 (unsigned long word)
+{
+ unsigned long result = 0;
+
+ while (!(word & 1UL))
+ {
+ result++;
+ word >>= 1;
+ }
+ return result;
+}
+#endif
#define log2 grub_log2
static __inline__ int
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/xenstore/xenstored_core.c
--- a/tools/xenstore/xenstored_core.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/xenstore/xenstored_core.c Mon Nov 13 09:58:23 2006 -0700
@@ -575,8 +575,10 @@ struct node *get_node(struct connection
/* If we don't have permission, we don't have node. */
if (node) {
if ((perm_for_conn(conn, node->perms, node->num_perms) & perm)
- != perm)
+ != perm) {
+ errno = EACCES;
node = NULL;
+ }
}
/* Clean up errno if they weren't supposed to know. */
if (!node)
@@ -789,7 +791,7 @@ static void delete_node_single(struct co
corrupt(conn, "Could not delete '%s'", node->name);
return;
}
- domain_entry_dec(conn);
+ domain_entry_dec(conn, node);
}
/* Must not be / */
@@ -840,7 +842,7 @@ static struct node *construct_node(struc
node->children = node->data = NULL;
node->childlen = node->datalen = 0;
node->parent = parent;
- domain_entry_inc(conn);
+ domain_entry_inc(conn, node);
return node;
}
@@ -876,7 +878,7 @@ static struct node *create_node(struct c
* something goes wrong. */
for (i = node; i; i = i->parent) {
if (!write_node(conn, i)) {
- domain_entry_dec(conn);
+ domain_entry_dec(conn, i);
return NULL;
}
talloc_set_destructor(i, destroy_node);
@@ -1106,6 +1108,7 @@ static void do_set_perms(struct connecti
static void do_set_perms(struct connection *conn, struct buffered_data *in)
{
unsigned int num;
+ struct xs_permissions *perms;
char *name, *permstr;
struct node *node;
@@ -1127,12 +1130,24 @@ static void do_set_perms(struct connecti
return;
}
- node->perms = talloc_array(node, struct xs_permissions, num);
- node->num_perms = num;
- if (!xs_strings_to_perms(node->perms, num, permstr)) {
+ perms = talloc_array(node, struct xs_permissions, num);
+ if (!xs_strings_to_perms(perms, num, permstr)) {
send_error(conn, errno);
return;
}
+
+ /* Unprivileged domains may not change the owner. */
+ if (domain_is_unprivileged(conn) &&
+ perms[0].id != node->perms[0].id) {
+ send_error(conn, EPERM);
+ return;
+ }
+
+ domain_entry_dec(conn, node);
+ node->perms = perms;
+ node->num_perms = num;
+ domain_entry_inc(conn, node);
+
if (!write_node(conn, node)) {
send_error(conn, errno);
return;
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/xenstore/xenstored_domain.c
--- a/tools/xenstore/xenstored_domain.c Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/xenstore/xenstored_domain.c Mon Nov 13 09:58:23 2006 -0700
@@ -501,18 +501,35 @@ int domain_init(void)
return xce_handle;
}
-void domain_entry_inc(struct connection *conn)
-{
- if (!conn || !conn->domain)
- return;
- conn->domain->nbentry++;
-}
-
-void domain_entry_dec(struct connection *conn)
-{
- if (!conn || !conn->domain)
- return;
- if (conn->domain->nbentry)
+void domain_entry_inc(struct connection *conn, struct node *node)
+{
+ struct domain *d;
+
+ if (!conn)
+ return;
+
+ if (node->perms && node->perms[0].id != conn->id) {
+ d = find_domain_by_domid(node->perms[0].id);
+ if (d)
+ d->nbentry++;
+ }
+ else if (conn->domain) {
+ conn->domain->nbentry++;
+ }
+}
+
+void domain_entry_dec(struct connection *conn, struct node *node)
+{
+ struct domain *d;
+
+ if (!conn)
+ return;
+
+ if (node->perms && node->perms[0].id != conn->id) {
+ d = find_domain_by_domid(node->perms[0].id);
+ if (d && d->nbentry)
+ d->nbentry--;
+ } else if (conn->domain && conn->domain->nbentry)
conn->domain->nbentry--;
}
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/xenstore/xenstored_domain.h
--- a/tools/xenstore/xenstored_domain.h Fri Nov 10 13:01:23 2006 -0700
+++ b/tools/xenstore/xenstored_domain.h Mon Nov 13 09:58:23 2006 -0700
@@ -50,8 +50,8 @@ bool domain_is_unprivileged(struct conne
bool domain_is_unprivileged(struct connection *conn);
/* Quota manipulation */
-void domain_entry_inc(struct connection *conn);
-void domain_entry_dec(struct connection *conn);
+void domain_entry_inc(struct connection *conn, struct node *);
+void domain_entry_dec(struct connection *conn, struct node *);
int domain_entry(struct connection *conn);
void domain_watch_inc(struct connection *conn);
void domain_watch_dec(struct connection *conn);
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/boot/x86_32.S Mon Nov 13 09:58:23 2006 -0700
@@ -196,21 +196,16 @@ ENTRY(stack_start)
/*** DESCRIPTOR TABLES ***/
-.globl idt
-.globl gdt
-
ALIGN
.word 0
idt_descr:
.word 256*8-1
-idt:
.long idt_table
.word 0
gdt_descr:
.word LAST_RESERVED_GDT_BYTE
-gdt:
.long gdt_table - FIRST_RESERVED_GDT_BYTE
.word 0
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/boot/x86_64.S Mon Nov 13 09:58:23 2006 -0700
@@ -192,9 +192,6 @@ 1: jmp 1b
/*** DESCRIPTOR TABLES ***/
-.globl idt
-.globl gdt
-
.align 8, 0xCC
multiboot_ptr:
.long 0
@@ -210,13 +207,11 @@ cpuid_ext_features:
.word 0
gdt_descr:
.word LAST_RESERVED_GDT_BYTE
-gdt:
.quad gdt_table - FIRST_RESERVED_GDT_BYTE
.word 0,0,0
idt_descr:
.word 256*16-1
-idt:
.quad idt_table
ENTRY(stack_start)
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/cpu/mcheck/Makefile
--- a/xen/arch/x86/cpu/mcheck/Makefile Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/cpu/mcheck/Makefile Mon Nov 13 09:58:23 2006 -0700
@@ -2,6 +2,6 @@ obj-y += mce.o
obj-y += mce.o
obj-y += non-fatal.o
obj-y += p4.o
-obj-y += p5.o
-obj-y += p6.o
-obj-y += winchip.o
+obj-$(x86_32) += p5.o
+obj-$(x86_32) += p6.o
+obj-$(x86_32) += winchip.o
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/cpu/mcheck/mce.c
--- a/xen/arch/x86/cpu/mcheck/mce.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/cpu/mcheck/mce.c Mon Nov 13 09:58:23 2006 -0700
@@ -39,18 +39,22 @@ void mcheck_init(struct cpuinfo_x86 *c)
break;
case X86_VENDOR_INTEL:
+#ifndef CONFIG_X86_64
if (c->x86==5)
intel_p5_mcheck_init(c);
if (c->x86==6)
intel_p6_mcheck_init(c);
+#endif
if (c->x86==15)
intel_p4_mcheck_init(c);
break;
+#ifndef CONFIG_X86_64
case X86_VENDOR_CENTAUR:
if (c->x86==5)
winchip_mcheck_init(c);
break;
+#endif
default:
break;
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/cpu/mtrr/Makefile
--- a/xen/arch/x86/cpu/mtrr/Makefile Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/cpu/mtrr/Makefile Mon Nov 13 09:58:23 2006 -0700
@@ -1,6 +1,6 @@ obj-y += amd.o
-obj-y += amd.o
-obj-y += centaur.o
-obj-y += cyrix.o
+obj-$(x86_32) += amd.o
+obj-$(x86_32) += centaur.o
+obj-$(x86_32) += cyrix.o
obj-y += generic.o
obj-y += main.o
obj-y += state.o
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/cpu/mtrr/main.c
--- a/xen/arch/x86/cpu/mtrr/main.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/cpu/mtrr/main.c Mon Nov 13 09:58:23 2006 -0700
@@ -64,7 +64,11 @@ static void set_mtrr(unsigned int reg, u
static void set_mtrr(unsigned int reg, unsigned long base,
unsigned long size, mtrr_type type);
+#ifndef CONFIG_X86_64
extern int arr3_protected;
+#else
+#define arr3_protected 0
+#endif
static char *mtrr_strings[MTRR_NUM_TYPES] =
{
@@ -539,9 +543,11 @@ extern void centaur_init_mtrr(void);
static void __init init_ifs(void)
{
+#ifndef CONFIG_X86_64
amd_init_mtrr();
cyrix_init_mtrr();
centaur_init_mtrr();
+#endif
}
/* The suspend/resume methods are only for CPU without MTRR. CPU using generic
@@ -593,6 +599,7 @@ void __init mtrr_bp_init(void)
size_and_mask = 0;
}
} else {
+#ifndef CONFIG_X86_64
switch (boot_cpu_data.x86_vendor) {
case X86_VENDOR_AMD:
if (cpu_has_k6_mtrr) {
@@ -619,6 +626,7 @@ void __init mtrr_bp_init(void)
default:
break;
}
+#endif
}
if (mtrr_if) {
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/domain.c Mon Nov 13 09:58:23 2006 -0700
@@ -166,6 +166,9 @@ void vcpu_destroy(struct vcpu *v)
int arch_domain_create(struct domain *d)
{
+#ifdef __x86_64__
+ struct page_info *pg;
+#endif
l1_pgentry_t gdt_l1e;
int vcpuid, pdpt_order;
int i, rc = -ENOMEM;
@@ -194,19 +197,17 @@ int arch_domain_create(struct domain *d)
#else /* __x86_64__ */
- d->arch.mm_perdomain_l2 = alloc_xenheap_page();
- d->arch.mm_perdomain_l3 = alloc_xenheap_page();
- if ( (d->arch.mm_perdomain_l2 == NULL) ||
- (d->arch.mm_perdomain_l3 == NULL) )
+ if ( (pg = alloc_domheap_page(NULL)) == NULL )
goto fail;
-
- memset(d->arch.mm_perdomain_l2, 0, PAGE_SIZE);
+ d->arch.mm_perdomain_l2 = clear_page(page_to_virt(pg));
for ( i = 0; i < (1 << pdpt_order); i++ )
d->arch.mm_perdomain_l2[l2_table_offset(PERDOMAIN_VIRT_START)+i] =
l2e_from_page(virt_to_page(d->arch.mm_perdomain_pt)+i,
__PAGE_HYPERVISOR);
- memset(d->arch.mm_perdomain_l3, 0, PAGE_SIZE);
+ if ( (pg = alloc_domheap_page(NULL)) == NULL )
+ goto fail;
+ d->arch.mm_perdomain_l3 = clear_page(page_to_virt(pg));
d->arch.mm_perdomain_l3[l3_table_offset(PERDOMAIN_VIRT_START)] =
l3e_from_page(virt_to_page(d->arch.mm_perdomain_l2),
__PAGE_HYPERVISOR);
@@ -240,8 +241,8 @@ int arch_domain_create(struct domain *d)
fail:
free_xenheap_page(d->shared_info);
#ifdef __x86_64__
- free_xenheap_page(d->arch.mm_perdomain_l2);
- free_xenheap_page(d->arch.mm_perdomain_l3);
+ free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2));
+ free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3));
#endif
free_xenheap_pages(d->arch.mm_perdomain_pt, pdpt_order);
return rc;
@@ -265,8 +266,8 @@ void arch_domain_destroy(struct domain *
get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)));
#ifdef __x86_64__
- free_xenheap_page(d->arch.mm_perdomain_l2);
- free_xenheap_page(d->arch.mm_perdomain_l3);
+ free_domheap_page(virt_to_page(d->arch.mm_perdomain_l2));
+ free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3));
#endif
free_xenheap_page(d->shared_info);
@@ -587,9 +588,9 @@ static void load_segments(struct vcpu *n
regs->entry_vector = TRAP_syscall;
regs->rflags &= ~(X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF|
X86_EFLAGS_NT|X86_EFLAGS_TF);
- regs->ss = __GUEST_SS;
+ regs->ss = FLAT_KERNEL_SS;
regs->rsp = (unsigned long)(rsp-11);
- regs->cs = __GUEST_CS;
+ regs->cs = FLAT_KERNEL_CS;
regs->rip = nctxt->failsafe_callback_eip;
}
}
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/hvm.c Mon Nov 13 09:58:23 2006 -0700
@@ -517,7 +517,8 @@ int hvm_bringup_ap(int vcpuid, int tramp
if ( bsp->vcpu_id != 0 )
{
gdprintk(XENLOG_ERR, "Not calling hvm_bringup_ap from BSP context.\n");
- domain_crash_synchronous();
+ domain_crash(bsp->domain);
+ return -EINVAL;
}
if ( (v = d->vcpu[vcpuid]) == NULL )
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/intercept.c
--- a/xen/arch/x86/hvm/intercept.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/intercept.c Mon Nov 13 09:58:23 2006 -0700
@@ -253,11 +253,7 @@ int register_io_handler(
struct hvm_io_handler *handler = &d->arch.hvm_domain.io_handler;
int num = handler->num_slot;
- if ( num >= MAX_IO_HANDLER )
- {
- printk("no extra space, register io interceptor failed!\n");
- domain_crash_synchronous();
- }
+ BUG_ON(num >= MAX_IO_HANDLER);
handler->hdl_list[num].addr = addr;
handler->hdl_list[num].size = size;
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/io.c
--- a/xen/arch/x86/hvm/io.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/io.c Mon Nov 13 09:58:23 2006 -0700
@@ -81,9 +81,7 @@ static void set_reg_value (int size, int
regs->ebx |= ((value & 0xFF) << 8);
break;
default:
- printk("Error: size:%x, index:%x are invalid!\n", size, index);
- domain_crash_synchronous();
- break;
+ goto crash;
}
break;
case WORD:
@@ -121,9 +119,7 @@ static void set_reg_value (int size, int
regs->edi |= (value & 0xFFFF);
break;
default:
- printk("Error: size:%x, index:%x are invalid!\n", size, index);
- domain_crash_synchronous();
- break;
+ goto crash;
}
break;
case LONG:
@@ -153,15 +149,13 @@ static void set_reg_value (int size, int
regs->edi = value;
break;
default:
- printk("Error: size:%x, index:%x are invalid!\n", size, index);
- domain_crash_synchronous();
- break;
+ goto crash;
}
break;
default:
- printk("Error: size:%x, index:%x are invalid!\n", size, index);
+ crash:
+ gdprintk(XENLOG_ERR, "size:%x, index:%x are invalid!\n", size, index);
domain_crash_synchronous();
- break;
}
}
#else
@@ -184,7 +178,7 @@ static inline void __set_reg_value(unsig
*reg = value;
break;
default:
- printk("Error: <__set_reg_value>: size:%x is invalid\n", size);
+ gdprintk(XENLOG_ERR, "size:%x is invalid\n", size);
domain_crash_synchronous();
}
}
@@ -226,7 +220,8 @@ static void set_reg_value (int size, int
regs->rbx |= ((value & 0xFF) << 8);
break;
default:
- printk("Error: size:%x, index:%x are invalid!\n", size, index);
+ gdprintk(XENLOG_ERR, "size:%x, index:%x are invalid!\n",
+ size, index);
domain_crash_synchronous();
break;
}
@@ -283,7 +278,7 @@ static void set_reg_value (int size, int
__set_reg_value(®s->r15, size, value);
break;
default:
- printk("Error: <set_reg_value> Invalid index\n");
+ gdprintk(XENLOG_ERR, "Invalid index\n");
domain_crash_synchronous();
}
return;
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/platform.c
--- a/xen/arch/x86/hvm/platform.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/platform.c Mon Nov 13 09:58:23 2006 -0700
@@ -731,8 +731,7 @@ static void hvm_send_assist_req(struct v
{
/* This indicates a bug in the device model. Crash the domain. */
gdprintk(XENLOG_ERR, "Device model set bad IO state %d.\n", p->state);
- domain_crash(v->domain);
- return;
+ domain_crash_synchronous();
}
prepare_wait_on_xen_event_channel(v->arch.hvm_vcpu.xen_port);
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/svm/svm.c
--- a/xen/arch/x86/hvm/svm/svm.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/svm/svm.c Mon Nov 13 09:58:23 2006 -0700
@@ -326,14 +326,14 @@ static inline int long_mode_do_msr_write
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
{
u64 msr_content = (u32)regs->eax | ((u64)regs->edx << 32);
- struct vcpu *vc = current;
- struct vmcb_struct *vmcb = vc->arch.hvm_svm.vmcb;
+ struct vcpu *v = current;
+ struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
HVM_DBG_LOG(DBG_LEVEL_1, "mode_do_msr_write msr %lx "
"msr_content %"PRIx64"\n",
(unsigned long)regs->ecx, msr_content);
- switch (regs->ecx)
+ switch ( regs->ecx )
{
case MSR_EFER:
#ifdef __x86_64__
@@ -342,24 +342,24 @@ static inline int long_mode_do_msr_write
{
printk("Trying to set reserved bit in EFER: %"PRIx64"\n",
msr_content);
- svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}
/* LME: 0 -> 1 */
if ( msr_content & EFER_LME &&
- !test_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state))
- {
- if ( svm_paging_enabled(vc) ||
+ !test_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state))
+ {
+ if ( svm_paging_enabled(v) ||
!test_bit(SVM_CPU_STATE_PAE_ENABLED,
- &vc->arch.hvm_svm.cpu_state) )
+ &v->arch.hvm_svm.cpu_state) )
{
printk("Trying to set LME bit when "
"in paging mode or PAE bit is not set\n");
- svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
return 0;
}
- set_bit(SVM_CPU_STATE_LME_ENABLED, &vc->arch.hvm_svm.cpu_state);
+ set_bit(SVM_CPU_STATE_LME_ENABLED, &v->arch.hvm_svm.cpu_state);
}
/* We have already recorded that we want LME, so it will be set
@@ -374,13 +374,13 @@ static inline int long_mode_do_msr_write
case MSR_FS_BASE:
case MSR_GS_BASE:
- if ( !svm_long_mode_enabled(vc) )
- domain_crash_synchronous();
+ if ( !svm_long_mode_enabled(v) )
+ goto exit_and_crash;
if (!IS_CANO_ADDRESS(msr_content))
{
HVM_DBG_LOG(DBG_LEVEL_1, "Not cano address of msr write\n");
- svm_inject_exception(vc, TRAP_gp_fault, 1, 0);
+ svm_inject_exception(v, TRAP_gp_fault, 1, 0);
}
if (regs->ecx == MSR_FS_BASE)
@@ -412,7 +412,13 @@ static inline int long_mode_do_msr_write
default:
return 0;
}
+
return 1;
+
+ exit_and_crash:
+ gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
+ domain_crash(v->domain);
+ return 1; /* handled */
}
@@ -420,7 +426,6 @@ static inline int long_mode_do_msr_write
__asm__ __volatile__ ("mov %0,%%db" #_reg : : "r" ((_v)->debugreg[_reg]))
#define savedebug(_v,_reg) \
__asm__ __volatile__ ("mov %%db" #_reg ",%0" : : "r"
((_v)->debugreg[_reg]))
-
static inline void svm_save_dr(struct vcpu *v)
{
@@ -938,7 +943,8 @@ static void svm_do_general_protection_fa
svm_dump_vmcb(__func__, vmcb);
svm_dump_regs(__func__, regs);
svm_dump_inst(vmcb->rip);
- __hvm_bug(regs);
+ domain_crash(v->domain);
+ return;
}
HVM_DBG_LOG(DBG_LEVEL_1,
@@ -1169,8 +1175,9 @@ static void svm_get_prefix_info(
if (inst_copy_from_guest(inst, svm_rip2pointer(vmcb), sizeof(inst))
!= MAX_INST_LEN)
{
- printk("%s: get guest instruction failed\n", __func__);
- domain_crash_synchronous();
+ gdprintk(XENLOG_ERR, "get guest instruction failed\n");
+ domain_crash(current->domain);
+ return;
}
for (i = 0; i < MAX_INST_LEN; i++)
@@ -1266,9 +1273,7 @@ static inline int svm_get_io_address(
isize --;
if (isize > 1)
- {
svm_get_prefix_info(vmcb, dir, &seg, &asize);
- }
ASSERT(dir == IOREQ_READ || dir == IOREQ_WRITE);
@@ -1470,8 +1475,10 @@ static int svm_set_cr0(unsigned long val
mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain))
{
- printk("Invalid CR3 value = %lx\n", v->arch.hvm_svm.cpu_cr3);
- domain_crash_synchronous(); /* need to take a clean path */
+ gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n",
+ v->arch.hvm_svm.cpu_cr3, mfn);
+ domain_crash(v->domain);
+ return 0;
}
#if defined(__x86_64__)
@@ -1556,7 +1563,7 @@ static void mov_from_cr(int cr, int gp,
vmcb = v->arch.hvm_svm.vmcb;
ASSERT(vmcb);
- switch (cr)
+ switch ( cr )
{
case 0:
value = v->arch.hvm_svm.cpu_shadow_cr0;
@@ -1582,7 +1589,8 @@ static void mov_from_cr(int cr, int gp,
break;
default:
- __hvm_bug(regs);
+ domain_crash(v->domain);
+ return;
}
set_reg(gp, value, regs, vmcb);
@@ -1602,13 +1610,10 @@ static inline int svm_pgbit_test(struct
*/
static int mov_to_cr(int gpreg, int cr, struct cpu_user_regs *regs)
{
- unsigned long value;
- unsigned long old_cr;
+ unsigned long value, old_cr, old_base_mfn, mfn;
struct vcpu *v = current;
struct vlapic *vlapic = vcpu_vlapic(v);
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
-
- ASSERT(vmcb);
value = get_reg(gpreg, regs, vmcb);
@@ -1623,8 +1628,6 @@ static int mov_to_cr(int gpreg, int cr,
return svm_set_cr0(value);
case 3:
- {
- unsigned long old_base_mfn, mfn;
if (svm_dbg_on)
printk("CR3 write =%lx \n", value );
/* If paging is not enabled yet, simply copy the value to CR3. */
@@ -1644,7 +1647,7 @@ static int mov_to_cr(int gpreg, int cr,
*/
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if (mfn != pagetable_get_pfn(v->arch.guest_table))
- __hvm_bug(regs);
+ goto bad_cr3;
shadow_update_cr3(v);
}
else
@@ -1656,10 +1659,7 @@ static int mov_to_cr(int gpreg, int cr,
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain))
- {
- printk("Invalid CR3 value=%lx\n", value);
- domain_crash_synchronous(); /* need to take a clean path */
- }
+ goto bad_cr3;
old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
v->arch.guest_table = pagetable_from_pfn(mfn);
@@ -1673,10 +1673,8 @@ static int mov_to_cr(int gpreg, int cr,
HVM_DBG_LOG(DBG_LEVEL_VMMU, "Update CR3 value = %lx", value);
}
break;
- }
case 4: /* CR4 */
- {
if (svm_dbg_on)
printk( "write cr4=%lx, cr0=%lx\n",
value, v->arch.hvm_svm.cpu_shadow_cr0 );
@@ -1692,10 +1690,7 @@ static int mov_to_cr(int gpreg, int cr,
mfn = get_mfn_from_gpfn(v->arch.hvm_svm.cpu_cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) ||
!get_page(mfn_to_page(mfn), v->domain) )
- {
- printk("Invalid CR3 value = %lx", v->arch.hvm_svm.cpu_cr3);
- domain_crash_synchronous(); /* need to take a clean path */
- }
+ goto bad_cr3;
/*
* Now arch.guest_table points to machine physical.
@@ -1741,20 +1736,23 @@ static int mov_to_cr(int gpreg, int cr,
shadow_update_paging_modes(v);
}
break;
- }
case 8:
- {
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
break;
- }
default:
- printk("invalid cr: %d\n", cr);
- __hvm_bug(regs);
+ gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
+ domain_crash(v->domain);
+ return 0;
}
return 1;
+
+ bad_cr3:
+ gdprintk(XENLOG_ERR, "Invalid CR3\n");
+ domain_crash(v->domain);
+ return 0;
}
@@ -1857,8 +1855,7 @@ static int svm_cr_access(struct vcpu *v,
break;
default:
- __hvm_bug(regs);
- break;
+ BUG();
}
ASSERT(inst_len);
@@ -2037,16 +2034,15 @@ void svm_handle_invlpg(const short invlp
int inst_len;
struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb;
- ASSERT(vmcb);
/*
* Unknown how many bytes the invlpg instruction will take. Use the
* maximum instruction length here
*/
if (inst_copy_from_guest(opcode, svm_rip2pointer(vmcb), length) < length)
{
- printk("svm_handle_invlpg (): Error reading memory %d bytes\n",
- length);
- __hvm_bug(regs);
+ gdprintk(XENLOG_ERR, "Error reading memory %d bytes\n", length);
+ domain_crash(v->domain);
+ return;
}
if (invlpga)
@@ -2510,7 +2506,7 @@ asmlinkage void svm_vmexit_handler(struc
if (exit_reason == VMEXIT_INVALID)
{
svm_dump_vmcb(__func__, vmcb);
- domain_crash_synchronous();
+ goto exit_and_crash;
}
#ifdef SVM_EXTRA_DEBUG
@@ -2734,8 +2730,7 @@ asmlinkage void svm_vmexit_handler(struc
break;
case VMEXIT_TASK_SWITCH:
- __hvm_bug(regs);
- break;
+ goto exit_and_crash;
case VMEXIT_CPUID:
svm_vmexit_do_cpuid(vmcb, regs->eax, regs);
@@ -2811,15 +2806,16 @@ asmlinkage void svm_vmexit_handler(struc
break;
case VMEXIT_SHUTDOWN:
- printk("Guest shutdown exit\n");
- domain_crash_synchronous();
- break;
+ gdprintk(XENLOG_ERR, "Guest shutdown exit\n");
+ goto exit_and_crash;
default:
- printk("unexpected VMEXIT: exit reason = 0x%x, exitinfo1 = %"PRIx64", "
- "exitinfo2 = %"PRIx64"\n", exit_reason,
- (u64)vmcb->exitinfo1, (u64)vmcb->exitinfo2);
- __hvm_bug(regs); /* should not happen */
+ exit_and_crash:
+ gdprintk(XENLOG_ERR, "unexpected VMEXIT: exit reason = 0x%x, "
+ "exitinfo1 = %"PRIx64", exitinfo2 = %"PRIx64"\n",
+ exit_reason,
+ (u64)vmcb->exitinfo1, (u64)vmcb->exitinfo2);
+ domain_crash(v->domain);
break;
}
@@ -2840,8 +2836,6 @@ asmlinkage void svm_vmexit_handler(struc
printk("svm_vmexit_handler: Returning\n");
}
#endif
-
- return;
}
asmlinkage void svm_load_cr2(void)
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/vioapic.c
--- a/xen/arch/x86/hvm/vioapic.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/vioapic.c Mon Nov 13 09:58:23 2006 -0700
@@ -35,6 +35,7 @@
#include <public/hvm/ioreq.h>
#include <asm/hvm/io.h>
#include <asm/hvm/vpic.h>
+#include <asm/hvm/vlapic.h>
#include <asm/hvm/support.h>
#include <asm/current.h>
#include <asm/event.h>
@@ -285,42 +286,6 @@ static int ioapic_inj_irq(struct vioapic
return result;
}
-#ifndef __ia64__
-static int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t dest)
-{
- int result = 0;
- uint32_t logical_dest;
-
- HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vlapic_match_logical_addr "
- "vcpu=%d vlapic_id=%x dest=%x\n",
- vlapic_vcpu(vlapic)->vcpu_id, VLAPIC_ID(vlapic), dest);
-
- logical_dest = vlapic_get_reg(vlapic, APIC_LDR);
-
- switch ( vlapic_get_reg(vlapic, APIC_DFR) )
- {
- case APIC_DFR_FLAT:
- result = ((dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0);
- break;
- case APIC_DFR_CLUSTER:
- /* Should we support flat cluster mode ?*/
- if ( (GET_APIC_LOGICAL_ID(logical_dest) >> 4
- == ((dest >> 0x4) & 0xf)) &&
- (logical_dest & (dest & 0xf)) )
- result = 1;
- break;
- default:
- gdprintk(XENLOG_WARNING, "error DFR value for lapic of vcpu %d\n",
- vlapic_vcpu(vlapic)->vcpu_id);
- break;
- }
-
- return result;
-}
-#else
-extern int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest);
-#endif
-
static uint32_t ioapic_get_delivery_bitmask(struct vioapic *vioapic,
uint16_t dest,
uint8_t dest_mode,
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/vlapic.c
--- a/xen/arch/x86/hvm/vlapic.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/vlapic.c Mon Nov 13 09:58:23 2006 -0700
@@ -196,63 +196,56 @@ uint32_t vlapic_get_ppr(struct vlapic *v
return ppr;
}
-/* This only for fixed delivery mode */
+int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda)
+{
+ int result = 0;
+ uint8_t logical_id;
+
+ logical_id = GET_APIC_LOGICAL_ID(vlapic_get_reg(vlapic, APIC_LDR));
+
+ switch ( vlapic_get_reg(vlapic, APIC_DFR) )
+ {
+ case APIC_DFR_FLAT:
+ if ( logical_id & mda )
+ result = 1;
+ break;
+ case APIC_DFR_CLUSTER:
+ if ( ((logical_id >> 4) == (mda >> 0x4)) && (logical_id & mda & 0xf) )
+ result = 1;
+ break;
+ default:
+ gdprintk(XENLOG_WARNING, "Bad DFR value for lapic of vcpu %d\n",
+ vlapic_vcpu(vlapic)->vcpu_id);
+ break;
+ }
+
+ return result;
+}
+
static int vlapic_match_dest(struct vcpu *v, struct vlapic *source,
- int short_hand, int dest, int dest_mode,
- int delivery_mode)
+ int short_hand, int dest, int dest_mode)
{
int result = 0;
struct vlapic *target = vcpu_vlapic(v);
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "target %p, source %p, dest 0x%x, "
- "dest_mode 0x%x, short_hand 0x%x, delivery_mode 0x%x.",
- target, source, dest, dest_mode, short_hand, delivery_mode);
-
- if ( unlikely(target == NULL) &&
- ((delivery_mode != APIC_DM_INIT) &&
- (delivery_mode != APIC_DM_STARTUP) &&
- (delivery_mode != APIC_DM_NMI)) )
- {
- HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "uninitialized target vcpu %p, "
- "delivery_mode 0x%x, dest 0x%x.\n",
- v, delivery_mode, dest);
- return result;
- }
+ "dest_mode 0x%x, short_hand 0x%x\n",
+ target, source, dest, dest_mode, short_hand);
switch ( short_hand )
{
- case APIC_DEST_NOSHORT: /* no shorthand */
- if ( !dest_mode ) /* Physical */
- {
- result = ( ((target != NULL) ?
- GET_APIC_ID(vlapic_get_reg(target, APIC_ID)):
- v->vcpu_id)) == dest;
- }
- else /* Logical */
- {
- uint32_t ldr;
- if ( target == NULL )
- break;
- ldr = vlapic_get_reg(target, APIC_LDR);
-
- /* Flat mode */
- if ( vlapic_get_reg(target, APIC_DFR) == APIC_DFR_FLAT )
- {
- result = GET_APIC_LOGICAL_ID(ldr) & dest;
- }
- else
- {
- if ( (delivery_mode == APIC_DM_LOWEST) &&
- (dest == 0xff) )
- {
- /* What shall we do now? */
- gdprintk(XENLOG_ERR, "Broadcast IPI with lowest priority "
- "delivery mode\n");
- domain_crash_synchronous();
- }
- result = ((GET_APIC_LOGICAL_ID(ldr) == (dest & 0xf)) ?
- (GET_APIC_LOGICAL_ID(ldr) >> 4) & (dest >> 4) : 0);
- }
+ case APIC_DEST_NOSHORT:
+ if ( dest_mode == 0 )
+ {
+ /* Physical mode. */
+ if ( (dest == 0xFF) || /* broadcast? */
+ (GET_APIC_ID(vlapic_get_reg(target, APIC_ID)) == dest) )
+ result = 1;
+ }
+ else
+ {
+ /* Logical mode. */
+ result = vlapic_match_logical_addr(target, dest);
}
break;
@@ -271,16 +264,14 @@ static int vlapic_match_dest(struct vcpu
break;
default:
+ gdprintk(XENLOG_WARNING, "Bad dest shorthand value %x\n", short_hand);
break;
}
return result;
}
-/*
- * Add a pending IRQ into lapic.
- * Return 1 if successfully added and 0 if discarded.
- */
+/* Add a pending IRQ into lapic. */
static int vlapic_accept_irq(struct vcpu *v, int delivery_mode,
int vector, int level, int trig_mode)
{
@@ -331,7 +322,7 @@ static int vlapic_accept_irq(struct vcpu
if ( test_and_clear_bit(_VCPUF_initialised, &v->vcpu_flags) )
{
gdprintk(XENLOG_ERR, "Reset hvm vcpu not supported yet\n");
- domain_crash_synchronous();
+ goto exit_and_crash;
}
v->arch.hvm_vcpu.init_sipi_sipi_state =
HVM_VCPU_INIT_SIPI_SIPI_STATE_WAIT_SIPI;
@@ -349,7 +340,7 @@ static int vlapic_accept_irq(struct vcpu
if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
{
gdprintk(XENLOG_ERR, "SIPI for initialized vcpu %x\n", v->vcpu_id);
- domain_crash_synchronous();
+ goto exit_and_crash;
}
if ( hvm_bringup_ap(v->vcpu_id, vector) != 0 )
@@ -359,11 +350,14 @@ static int vlapic_accept_irq(struct vcpu
default:
gdprintk(XENLOG_ERR, "TODO: unsupported delivery mode %x\n",
delivery_mode);
- domain_crash_synchronous();
- break;
+ goto exit_and_crash;
}
return result;
+
+ exit_and_crash:
+ domain_crash(v->domain);
+ return 0;
}
/* This function is used by both ioapic and lapic.The bitmap is for vcpu_id. */
@@ -440,10 +434,9 @@ static void vlapic_ipi(struct vlapic *vl
for_each_vcpu ( vlapic_domain(vlapic), v )
{
- if ( vlapic_match_dest(v, vlapic, short_hand,
- dest, dest_mode, delivery_mode) )
- {
- if ( delivery_mode == APIC_DM_LOWEST)
+ if ( vlapic_match_dest(v, vlapic, short_hand, dest, dest_mode) )
+ {
+ if ( delivery_mode == APIC_DM_LOWEST )
set_bit(v->vcpu_id, &lpr_map);
else
vlapic_accept_irq(v, delivery_mode,
@@ -578,14 +571,17 @@ static unsigned long vlapic_read(struct
default:
gdprintk(XENLOG_ERR, "Local APIC read with len=0x%lx, "
"should be 4 instead.\n", len);
- domain_crash_synchronous();
- break;
+ goto exit_and_crash;
}
HVM_DBG_LOG(DBG_LEVEL_VLAPIC, "offset 0x%x with length 0x%lx, "
"and the result is 0x%lx.", offset, len, result);
return result;
+
+ exit_and_crash:
+ domain_crash(v->domain);
+ return 0;
}
static void vlapic_write(struct vcpu *v, unsigned long address,
@@ -625,7 +621,7 @@ static void vlapic_write(struct vcpu *v,
{
gdprintk(XENLOG_ERR, "Uneven alignment error for "
"2-byte vlapic access\n");
- domain_crash_synchronous();
+ goto exit_and_crash;
}
val = (tmp & ~(0xffff << (8*alignment))) |
@@ -635,8 +631,9 @@ static void vlapic_write(struct vcpu *v,
default:
gdprintk(XENLOG_ERR, "Local APIC write with len = %lx, "
"should be 4 instead\n", len);
- domain_crash_synchronous();
- break;
+ exit_and_crash:
+ domain_crash(v->domain);
+ return;
}
}
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/vmx/vmcs.c
--- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/vmcs.c Mon Nov 13 09:58:23 2006 -0700
@@ -466,14 +466,14 @@ void vm_launch_fail(unsigned long eflags
{
unsigned long error = __vmread(VM_INSTRUCTION_ERROR);
printk("<vm_launch_fail> error code %lx\n", error);
- __hvm_bug(guest_cpu_user_regs());
+ domain_crash_synchronous();
}
void vm_resume_fail(unsigned long eflags)
{
unsigned long error = __vmread(VM_INSTRUCTION_ERROR);
printk("<vm_resume_fail> error code %lx\n", error);
- __hvm_bug(guest_cpu_user_regs());
+ domain_crash_synchronous();
}
void arch_vmx_do_resume(struct vcpu *v)
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/hvm/vmx/vmx.c Mon Nov 13 09:58:23 2006 -0700
@@ -151,15 +151,14 @@ static inline int long_mode_do_msr_read(
case MSR_FS_BASE:
if ( !(vmx_long_mode_enabled(v)) )
- /* XXX should it be GP fault */
- domain_crash_synchronous();
+ goto exit_and_crash;
msr_content = __vmread(GUEST_FS_BASE);
break;
case MSR_GS_BASE:
if ( !(vmx_long_mode_enabled(v)) )
- domain_crash_synchronous();
+ goto exit_and_crash;
msr_content = __vmread(GUEST_GS_BASE);
break;
@@ -183,6 +182,11 @@ static inline int long_mode_do_msr_read(
regs->edx = (u32)(msr_content >> 32);
return 1;
+
+ exit_and_crash:
+ gdprintk(XENLOG_ERR, "Fatal error reading MSR %lx\n", (long)regs->ecx);
+ domain_crash(v->domain);
+ return 1; /* handled */
}
static inline int long_mode_do_msr_write(struct cpu_user_regs *regs)
@@ -233,7 +237,7 @@ static inline int long_mode_do_msr_write
case MSR_FS_BASE:
case MSR_GS_BASE:
if ( !(vmx_long_mode_enabled(v)) )
- domain_crash_synchronous();
+ goto exit_and_crash;
if ( !IS_CANO_ADDRESS(msr_content) )
{
@@ -251,7 +255,7 @@ static inline int long_mode_do_msr_write
case MSR_SHADOW_GS_BASE:
if ( !(vmx_long_mode_enabled(v)) )
- domain_crash_synchronous();
+ goto exit_and_crash;
v->arch.hvm_vmx.msr_content.shadow_gs = msr_content;
wrmsrl(MSR_SHADOW_GS_BASE, msr_content);
@@ -267,6 +271,11 @@ static inline int long_mode_do_msr_write
}
return 1;
+
+ exit_and_crash:
+ gdprintk(XENLOG_ERR, "Fatal error writing MSR %lx\n", (long)regs->ecx);
+ domain_crash(v->domain);
+ return 1; /* handled */
}
static void vmx_restore_msrs(struct vcpu *v)
@@ -726,8 +735,7 @@ static int __get_instruction_length(void
{
int len;
len = __vmread(VM_EXIT_INSTRUCTION_LEN); /* Safe: callers audited */
- if ( (len < 1) || (len > 15) )
- __hvm_bug(guest_cpu_user_regs());
+ BUG_ON((len < 1) || (len > 15));
return len;
}
@@ -823,7 +831,10 @@ static void vmx_do_cpuid(struct cpu_user
/* 8-byte aligned valid pseudophys address from vmxassist, please. */
if ( (value & 7) || (mfn == INVALID_MFN) ||
!v->arch.hvm_vmx.vmxassist_enabled )
- domain_crash_synchronous();
+ {
+ domain_crash(v->domain);
+ return;
+ }
p = map_domain_page(mfn);
value = *((uint64_t *)(p + (value & (PAGE_SIZE - 1))));
@@ -966,8 +977,9 @@ static int check_for_null_selector(unsig
memset(inst, 0, MAX_INST_LEN);
if ( inst_copy_from_guest(inst, eip, inst_len) != inst_len )
{
- printk("check_for_null_selector: get guest instruction failed\n");
- domain_crash_synchronous();
+ gdprintk(XENLOG_ERR, "Get guest instruction failed\n");
+ domain_crash(current->domain);
+ return 0;
}
for ( i = 0; i < inst_len; i++ )
@@ -1169,7 +1181,7 @@ static void vmx_world_save(struct vcpu *
c->ldtr_arbytes.bytes = __vmread(GUEST_LDTR_AR_BYTES);
}
-static void vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
+static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
{
unsigned long mfn, old_base_mfn;
@@ -1192,10 +1204,7 @@ static void vmx_world_restore(struct vcp
*/
mfn = get_mfn_from_gpfn(c->cr3 >> PAGE_SHIFT);
if ( mfn != pagetable_get_pfn(v->arch.guest_table) )
- {
- printk("Invalid CR3 value=%x", c->cr3);
- domain_crash_synchronous();
- }
+ goto bad_cr3;
}
else
{
@@ -1205,13 +1214,8 @@ static void vmx_world_restore(struct vcp
*/
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 c->cr3 = %x", c->cr3);
mfn = get_mfn_from_gpfn(c->cr3 >> PAGE_SHIFT);
- if ( !VALID_MFN(mfn) )
- {
- printk("Invalid CR3 value=%x", c->cr3);
- domain_crash_synchronous();
- }
- if ( !get_page(mfn_to_page(mfn), v->domain) )
- domain_crash_synchronous();
+ if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
+ goto bad_cr3;
old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
@@ -1280,6 +1284,11 @@ static void vmx_world_restore(struct vcp
shadow_update_paging_modes(v);
__vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
+ return 0;
+
+ bad_cr3:
+ gdprintk(XENLOG_ERR, "Invalid CR3 value=%x", c->cr3);
+ return -EINVAL;
}
enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST_RESTORE };
@@ -1320,7 +1329,8 @@ static int vmx_assist(struct vcpu *v, in
if (cp != 0) {
if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
goto error;
- vmx_world_restore(v, &c);
+ if ( vmx_world_restore(v, &c) != 0 )
+ goto error;
v->arch.hvm_vmx.vmxassist_enabled = 1;
return 1;
}
@@ -1337,7 +1347,8 @@ static int vmx_assist(struct vcpu *v, in
if (cp != 0) {
if (hvm_copy_from_guest_phys(&c, cp, sizeof(c)))
goto error;
- vmx_world_restore(v, &c);
+ if ( vmx_world_restore(v, &c) != 0 )
+ goto error;
v->arch.hvm_vmx.vmxassist_enabled = 0;
return 1;
}
@@ -1345,8 +1356,8 @@ static int vmx_assist(struct vcpu *v, in
}
error:
- printk("Failed to transfer to vmxassist\n");
- domain_crash_synchronous();
+ gdprintk(XENLOG_ERR, "Failed to transfer to vmxassist\n");
+ domain_crash(v->domain);
return 0;
}
@@ -1390,9 +1401,10 @@ static int vmx_set_cr0(unsigned long val
mfn = get_mfn_from_gpfn(v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
{
- printk("Invalid CR3 value = %lx (mfn=%lx)\n",
- v->arch.hvm_vmx.cpu_cr3, mfn);
- domain_crash_synchronous(); /* need to take a clean path */
+ gdprintk(XENLOG_ERR, "Invalid CR3 value = %lx (mfn=%lx)\n",
+ v->arch.hvm_vmx.cpu_cr3, mfn);
+ domain_crash(v->domain);
+ return 0;
}
#if defined(__x86_64__)
@@ -1536,12 +1548,12 @@ static int vmx_set_cr0(unsigned long val
*/
static int mov_to_cr(int gp, int cr, struct cpu_user_regs *regs)
{
- unsigned long value;
- unsigned long old_cr;
+ unsigned long value, old_cr, old_base_mfn, mfn;
struct vcpu *v = current;
struct vlapic *vlapic = vcpu_vlapic(v);
- switch ( gp ) {
+ switch ( gp )
+ {
CASE_GET_REG(EAX, eax);
CASE_GET_REG(ECX, ecx);
CASE_GET_REG(EDX, edx);
@@ -1554,8 +1566,8 @@ static int mov_to_cr(int gp, int cr, str
value = __vmread(GUEST_RSP);
break;
default:
- printk("invalid gp: %d\n", gp);
- __hvm_bug(regs);
+ gdprintk(XENLOG_ERR, "invalid gp: %d\n", gp);
+ goto exit_and_crash;
}
TRACE_VMEXIT(1, TYPE_MOV_TO_CR);
@@ -1564,13 +1576,12 @@ static int mov_to_cr(int gp, int cr, str
HVM_DBG_LOG(DBG_LEVEL_1, "CR%d, value = %lx", cr, value);
- switch ( cr ) {
+ switch ( cr )
+ {
case 0:
return vmx_set_cr0(value);
+
case 3:
- {
- unsigned long old_base_mfn, mfn;
-
/*
* If paging is not enabled yet, simply copy the value to CR3.
*/
@@ -1590,7 +1601,7 @@ static int mov_to_cr(int gp, int cr, str
*/
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if (mfn != pagetable_get_pfn(v->arch.guest_table))
- __hvm_bug(regs);
+ goto bad_cr3;
shadow_update_cr3(v);
} else {
/*
@@ -1600,10 +1611,7 @@ static int mov_to_cr(int gp, int cr, str
HVM_DBG_LOG(DBG_LEVEL_VMMU, "CR3 value = %lx", value);
mfn = get_mfn_from_gpfn(value >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) || !get_page(mfn_to_page(mfn), v->domain) )
- {
- printk("Invalid CR3 value=%lx\n", value);
- domain_crash_synchronous(); /* need to take a clean path */
- }
+ goto bad_cr3;
old_base_mfn = pagetable_get_pfn(v->arch.guest_table);
v->arch.guest_table = pagetable_from_pfn(mfn);
if (old_base_mfn)
@@ -1618,9 +1626,8 @@ static int mov_to_cr(int gp, int cr, str
__vmwrite(GUEST_CR3, v->arch.hvm_vcpu.hw_cr3);
}
break;
- }
+
case 4: /* CR4 */
- {
old_cr = v->arch.hvm_vmx.cpu_shadow_cr4;
if ( (value & X86_CR4_PAE) && !(old_cr & X86_CR4_PAE) )
@@ -1633,10 +1640,7 @@ static int mov_to_cr(int gp, int cr, str
mfn = get_mfn_from_gpfn(v->arch.hvm_vmx.cpu_cr3 >> PAGE_SHIFT);
if ( !VALID_MFN(mfn) ||
!get_page(mfn_to_page(mfn), v->domain) )
- {
- printk("Invalid CR3 value = %lx", v->arch.hvm_vmx.cpu_cr3);
- domain_crash_synchronous(); /* need to take a clean path */
- }
+ goto bad_cr3;
/*
* Now arch.guest_table points to machine physical.
@@ -1682,18 +1686,24 @@ static int mov_to_cr(int gp, int cr, str
if ( (old_cr ^ value) & (X86_CR4_PSE | X86_CR4_PGE | X86_CR4_PAE) )
shadow_update_paging_modes(v);
break;
- }
+
case 8:
- {
vlapic_set_reg(vlapic, APIC_TASKPRI, ((value & 0x0F) << 4));
break;
- }
+
default:
- printk("invalid cr: %d\n", gp);
- __hvm_bug(regs);
+ gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
+ domain_crash(v->domain);
+ return 0;
}
return 1;
+
+ bad_cr3:
+ gdprintk(XENLOG_ERR, "Invalid CR3\n");
+ exit_and_crash:
+ domain_crash(v->domain);
+ return 0;
}
/*
@@ -1715,7 +1725,9 @@ static void mov_from_cr(int cr, int gp,
value = (value & 0xF0) >> 4;
break;
default:
- __hvm_bug(regs);
+ gdprintk(XENLOG_ERR, "invalid cr: %d\n", cr);
+ domain_crash(v->domain);
+ break;
}
switch ( gp ) {
@@ -1733,7 +1745,8 @@ static void mov_from_cr(int cr, int gp,
break;
default:
printk("invalid gp: %d\n", gp);
- __hvm_bug(regs);
+ domain_crash(v->domain);
+ break;
}
TRACE_VMEXIT(1, TYPE_MOV_FROM_CR);
@@ -1782,9 +1795,9 @@ static int vmx_cr_access(unsigned long e
return vmx_set_cr0(value);
break;
default:
- __hvm_bug(regs);
- break;
- }
+ BUG();
+ }
+
return 1;
}
@@ -1814,7 +1827,7 @@ static inline void vmx_do_msr_read(struc
msr_content = vcpu_vlapic(v)->apic_base_msr;
break;
default:
- if (long_mode_do_msr_read(regs))
+ if ( long_mode_do_msr_read(regs) )
return;
if ( rdmsr_hypervisor_regs(regs->ecx, &eax, &edx) )
@@ -2044,11 +2057,6 @@ asmlinkage void vmx_vmexit_handler(struc
exit_reason = __vmread(VM_EXIT_REASON);
perfc_incra(vmexits, exit_reason);
-
- if ( (exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT) &&
- (exit_reason != EXIT_REASON_VMCALL) &&
- (exit_reason != EXIT_REASON_IO_INSTRUCTION) )
- HVM_DBG_LOG(DBG_LEVEL_0, "exit reason = %x", exit_reason);
if ( exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT )
local_irq_enable();
@@ -2077,7 +2085,7 @@ asmlinkage void vmx_vmexit_handler(struc
printk("************* VMCS Area **************\n");
vmcs_dump_vcpu();
printk("**************************************\n");
- domain_crash_synchronous();
+ goto exit_and_crash;
}
TRACE_VMEXIT(0, exit_reason);
@@ -2121,8 +2129,6 @@ asmlinkage void vmx_vmexit_handler(struc
#else
case TRAP_debug:
{
- void store_cpu_user_regs(struct cpu_user_regs *regs);
-
if ( test_bit(_DOMF_debugging, &v->domain->domain_flags) )
{
store_cpu_user_regs(regs);
@@ -2193,8 +2199,7 @@ asmlinkage void vmx_vmexit_handler(struc
vmx_do_extint(regs);
break;
case EXIT_REASON_TRIPLE_FAULT:
- domain_crash_synchronous();
- break;
+ goto exit_and_crash;
case EXIT_REASON_PENDING_INTERRUPT:
/* Disable the interrupt window. */
v->arch.hvm_vcpu.u.vmx.exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
@@ -2202,8 +2207,7 @@ asmlinkage void vmx_vmexit_handler(struc
v->arch.hvm_vcpu.u.vmx.exec_control);
break;
case EXIT_REASON_TASK_SWITCH:
- domain_crash_synchronous();
- break;
+ goto exit_and_crash;
case EXIT_REASON_CPUID:
inst_len = __get_instruction_length(); /* Safe: CPUID */
__update_guest_eip(inst_len);
@@ -2268,8 +2272,7 @@ asmlinkage void vmx_vmexit_handler(struc
case EXIT_REASON_MWAIT_INSTRUCTION:
case EXIT_REASON_MONITOR_INSTRUCTION:
case EXIT_REASON_PAUSE_INSTRUCTION:
- domain_crash_synchronous();
- break;
+ goto exit_and_crash;
case EXIT_REASON_VMCLEAR:
case EXIT_REASON_VMLAUNCH:
case EXIT_REASON_VMPTRLD:
@@ -2289,7 +2292,10 @@ asmlinkage void vmx_vmexit_handler(struc
break;
default:
- domain_crash_synchronous(); /* should not happen */
+ exit_and_crash:
+ gdprintk(XENLOG_ERR, "Bad vmexit (reason %x)\n", exit_reason);
+ domain_crash(v->domain);
+ break;
}
}
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/mm.c
--- a/xen/arch/x86/mm.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/mm.c Mon Nov 13 09:58:23 2006 -0700
@@ -1717,7 +1717,7 @@ int new_guest_cr3(unsigned long mfn)
unsigned long old_base_mfn;
if ( is_hvm_domain(d) && !hvm_paging_enabled(v) )
- domain_crash_synchronous();
+ return 0;
if ( shadow_mode_refcounts(d) )
{
@@ -2134,13 +2134,14 @@ int do_mmuext_op(
default:
MEM_LOG("Invalid extended pt command 0x%x", op.cmd);
+ rc = -ENOSYS;
okay = 0;
break;
}
if ( unlikely(!okay) )
{
- rc = -EINVAL;
+ rc = rc ? rc : -EINVAL;
break;
}
@@ -2151,9 +2152,11 @@ int do_mmuext_op(
process_deferred_ops();
/* Add incremental work we have done to the @done output parameter. */
- done += i;
if ( unlikely(!guest_handle_is_null(pdone)) )
+ {
+ done += i;
copy_to_guest(pdone, &done, 1);
+ }
UNLOCK_BIGLOCK(d);
return rc;
@@ -2351,12 +2354,14 @@ int do_mmu_update(
default:
MEM_LOG("Invalid page update command %x", cmd);
+ rc = -ENOSYS;
+ okay = 0;
break;
}
if ( unlikely(!okay) )
{
- rc = -EINVAL;
+ rc = rc ? rc : -EINVAL;
break;
}
@@ -2370,9 +2375,11 @@ int do_mmu_update(
process_deferred_ops();
/* Add incremental work we have done to the @done output parameter. */
- done += i;
if ( unlikely(!guest_handle_is_null(pdone)) )
+ {
+ done += i;
copy_to_guest(pdone, &done, 1);
+ }
UNLOCK_BIGLOCK(d);
return rc;
@@ -3106,7 +3113,7 @@ static int ptwr_emulated_update(
* zap the PRESENT bit on the assumption the bottom half will be
* written immediately after we return to the guest.
*/
- MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte"\n",
+ MEM_LOG("ptwr_emulate: fixing up invalid PAE PTE %"PRIpte,
l1e_get_intpte(nl1e));
l1e_remove_flags(nl1e, _PAGE_PRESENT);
}
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/oprofile/xenoprof.c
--- a/xen/arch/x86/oprofile/xenoprof.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/oprofile/xenoprof.c Mon Nov 13 09:58:23 2006 -0700
@@ -684,7 +684,7 @@ int do_xenoprof_op(int op, XEN_GUEST_HAN
break;
default:
- ret = -EINVAL;
+ ret = -ENOSYS;
}
spin_unlock(&xenoprof_lock);
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/physdev.c Mon Nov 13 09:58:23 2006 -0700
@@ -135,7 +135,7 @@ long do_physdev_op(int cmd, XEN_GUEST_HA
}
default:
- ret = -EINVAL;
+ ret = -ENOSYS;
break;
}
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/traps.c Mon Nov 13 09:58:23 2006 -0700
@@ -1310,8 +1310,10 @@ static int emulate_privileged_op(struct
case 3: /* Write CR3 */
LOCK_BIGLOCK(v->domain);
- (void)new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg)));
+ rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg)));
UNLOCK_BIGLOCK(v->domain);
+ if ( rc == 0 ) /* not okay */
+ goto fail;
break;
case 4:
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/x86_32/traps.c Mon Nov 13 09:58:23 2006 -0700
@@ -179,16 +179,16 @@ unsigned long do_iret(void)
/* Check worst-case stack frame for overlap with Xen protected area. */
if ( unlikely(!access_ok(regs->esp, 40)) )
- domain_crash_synchronous();
+ goto exit_and_crash;
/* Pop and restore EAX (clobbered by hypercall). */
if ( unlikely(__copy_from_user(®s->eax, (void __user *)regs->esp, 4)) )
- domain_crash_synchronous();
+ goto exit_and_crash;
regs->esp += 4;
/* Pop and restore CS and EIP. */
if ( unlikely(__copy_from_user(®s->eip, (void __user *)regs->esp, 8)) )
- domain_crash_synchronous();
+ goto exit_and_crash;
regs->esp += 8;
/*
@@ -196,7 +196,7 @@ unsigned long do_iret(void)
* to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt.
*/
if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) )
- domain_crash_synchronous();
+ goto exit_and_crash;
regs->esp += 4;
regs->eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF;
@@ -204,17 +204,17 @@ unsigned long do_iret(void)
{
/* Return to VM86 mode: pop and restore ESP,SS,ES,DS,FS and GS. */
if ( __copy_from_user(®s->esp, (void __user *)regs->esp, 24) )
- domain_crash_synchronous();
+ goto exit_and_crash;
}
else if ( unlikely(ring_0(regs)) )
{
- domain_crash_synchronous();
+ goto exit_and_crash;
}
else if ( !ring_1(regs) )
{
/* Return to ring 2/3: pop and restore ESP and SS. */
if ( __copy_from_user(®s->esp, (void __user *)regs->esp, 8) )
- domain_crash_synchronous();
+ goto exit_and_crash;
}
/* No longer in NMI context. */
@@ -228,6 +228,11 @@ unsigned long do_iret(void)
* value.
*/
return regs->eax;
+
+ exit_and_crash:
+ gdprintk(XENLOG_ERR, "Fatal error\n");
+ domain_crash(current->domain);
+ return 0;
}
#include <asm/asm_defns.h>
@@ -355,25 +360,33 @@ static long register_guest_callback(stru
break;
default:
+ ret = -ENOSYS;
+ break;
+ }
+
+ return ret;
+}
+
+static long unregister_guest_callback(struct callback_unregister *unreg)
+{
+ long ret;
+
+ switch ( unreg->type )
+ {
+ case CALLBACKTYPE_event:
+ case CALLBACKTYPE_failsafe:
+#ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL
+ case CALLBACKTYPE_sysenter:
+#endif
ret = -EINVAL;
break;
- }
-
- return ret;
-}
-
-static long unregister_guest_callback(struct callback_unregister *unreg)
-{
- long ret;
-
- switch ( unreg->type )
- {
+
case CALLBACKTYPE_nmi:
ret = unregister_guest_nmi_callback();
break;
default:
- ret = -EINVAL;
+ ret = -ENOSYS;
break;
}
@@ -412,7 +425,7 @@ long do_callback_op(int cmd, XEN_GUEST_H
break;
default:
- ret = -EINVAL;
+ ret = -ENOSYS;
break;
}
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/x86_64/entry.S
--- a/xen/arch/x86/x86_64/entry.S Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/x86_64/entry.S Mon Nov 13 09:58:23 2006 -0700
@@ -45,7 +45,7 @@ restore_all_guest:
addq $8,%rsp
popq %rcx # RIP
popq %r11 # CS
- cmpw $__GUEST_CS32,%r11
+ cmpw $FLAT_KERNEL_CS32,%r11
popq %r11 # RFLAGS
popq %rsp # RSP
je 1f
@@ -119,7 +119,7 @@ restore_all_xen:
ALIGN
ENTRY(syscall_enter)
sti
- movl $__GUEST_SS,24(%rsp)
+ movl $FLAT_KERNEL_SS,24(%rsp)
pushq %rcx
pushq $0
movl $TRAP_syscall,4(%rsp)
@@ -298,9 +298,9 @@ FLT13: movq %rax,(%rsi)
movl $TRAP_syscall,UREGS_entry_vector+8(%rsp)
andl $~(X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF|\
X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp)
- movq $__GUEST_SS,UREGS_ss+8(%rsp)
+ movq $FLAT_KERNEL_SS,UREGS_ss+8(%rsp)
movq %rsi,UREGS_rsp+8(%rsp)
- movq $__GUEST_CS,UREGS_cs+8(%rsp)
+ movq $FLAT_KERNEL_CS,UREGS_cs+8(%rsp)
movq TRAPBOUNCE_eip(%rdx),%rax
testq %rax,%rax
jz domain_crash_synchronous
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/x86_64/mm.c
--- a/xen/arch/x86/x86_64/mm.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/x86_64/mm.c Mon Nov 13 09:58:23 2006 -0700
@@ -76,17 +76,17 @@ l2_pgentry_t *virt_to_xen_l2e(unsigned l
void __init paging_init(void)
{
- unsigned long i, mpt_size;
+ unsigned long i, mpt_size, va;
l3_pgentry_t *l3_ro_mpt;
l2_pgentry_t *l2_ro_mpt = NULL;
- struct page_info *pg;
+ struct page_info *l1_pg, *l2_pg;
/* Create user-accessible L2 directory to map the MPT for guests. */
- l3_ro_mpt = alloc_xenheap_page();
- clear_page(l3_ro_mpt);
+ if ( (l2_pg = alloc_domheap_page(NULL)) == NULL )
+ goto nomem;
+ l3_ro_mpt = clear_page(page_to_virt(l2_pg));
idle_pg_table[l4_table_offset(RO_MPT_VIRT_START)] =
- l4e_from_page(
- virt_to_page(l3_ro_mpt), __PAGE_HYPERVISOR | _PAGE_USER);
+ l4e_from_page(l2_pg, __PAGE_HYPERVISOR | _PAGE_USER);
/*
* Allocate and map the machine-to-phys table.
@@ -96,33 +96,37 @@ void __init paging_init(void)
mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL);
for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ )
{
- if ( (pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL )
- panic("Not enough memory for m2p table\n");
+ if ( (l1_pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL )
+ goto nomem;
map_pages_to_xen(
- RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT), page_to_mfn(pg),
+ RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT),
+ page_to_mfn(l1_pg),
1UL << PAGETABLE_ORDER,
PAGE_HYPERVISOR);
memset((void *)(RDWR_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT)), 0x55,
1UL << L2_PAGETABLE_SHIFT);
if ( !((unsigned long)l2_ro_mpt & ~PAGE_MASK) )
{
- unsigned long va = RO_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT);
-
- l2_ro_mpt = alloc_xenheap_page();
- clear_page(l2_ro_mpt);
+ if ( (l2_pg = alloc_domheap_page(NULL)) == NULL )
+ goto nomem;
+ va = RO_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT);
+ l2_ro_mpt = clear_page(page_to_virt(l2_pg));
l3_ro_mpt[l3_table_offset(va)] =
- l3e_from_page(
- virt_to_page(l2_ro_mpt), __PAGE_HYPERVISOR | _PAGE_USER);
+ l3e_from_page(l2_pg, __PAGE_HYPERVISOR | _PAGE_USER);
l2_ro_mpt += l2_table_offset(va);
}
/* NB. Cannot be GLOBAL as shadow_mode_translate reuses this area. */
*l2_ro_mpt++ = l2e_from_page(
- pg, /*_PAGE_GLOBAL|*/_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT);
+ l1_pg, /*_PAGE_GLOBAL|*/_PAGE_PSE|_PAGE_USER|_PAGE_PRESENT);
}
/* Set up linear page table mapping. */
idle_pg_table[l4_table_offset(LINEAR_PT_VIRT_START)] =
l4e_from_paddr(__pa(idle_pg_table), __PAGE_HYPERVISOR);
+ return;
+
+ nomem:
+ panic("Not enough memory for m2p table\n");
}
void __init setup_idle_pagetable(void)
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/arch/x86/x86_64/traps.c Mon Nov 13 09:58:23 2006 -0700
@@ -200,7 +200,7 @@ unsigned long do_iret(void)
{
gdprintk(XENLOG_ERR, "Fault while reading IRET context from "
"guest stack\n");
- domain_crash_synchronous();
+ goto exit_and_crash;
}
/* Returning to user mode? */
@@ -210,7 +210,7 @@ unsigned long do_iret(void)
{
gdprintk(XENLOG_ERR, "Guest switching to user mode with no "
"user page tables\n");
- domain_crash_synchronous();
+ goto exit_and_crash;
}
toggle_guest_mode(v);
}
@@ -236,6 +236,11 @@ unsigned long do_iret(void)
/* Saved %rax gets written back to regs->rax in entry.S. */
return iret_saved.rax;
+
+ exit_and_crash:
+ gdprintk(XENLOG_ERR, "Fatal error\n");
+ domain_crash(v->domain);
+ return 0;
}
asmlinkage void syscall_enter(void);
@@ -285,9 +290,9 @@ void __init percpu_traps_init(void)
stack[14] = 0x41;
stack[15] = 0x53;
- /* pushq $__GUEST_CS64 */
+ /* pushq $FLAT_KERNEL_CS64 */
stack[16] = 0x68;
- *(u32 *)&stack[17] = __GUEST_CS64;
+ *(u32 *)&stack[17] = FLAT_KERNEL_CS64;
/* jmp syscall_enter */
stack[21] = 0xe9;
@@ -317,9 +322,9 @@ void __init percpu_traps_init(void)
stack[14] = 0x41;
stack[15] = 0x53;
- /* pushq $__GUEST_CS32 */
+ /* pushq $FLAT_KERNEL_CS32 */
stack[16] = 0x68;
- *(u32 *)&stack[17] = __GUEST_CS32;
+ *(u32 *)&stack[17] = FLAT_KERNEL_CS32;
/* jmp syscall_enter */
stack[21] = 0xe9;
@@ -369,25 +374,31 @@ static long register_guest_callback(stru
break;
default:
+ ret = -ENOSYS;
+ break;
+ }
+
+ return ret;
+}
+
+static long unregister_guest_callback(struct callback_unregister *unreg)
+{
+ long ret;
+
+ switch ( unreg->type )
+ {
+ case CALLBACKTYPE_event:
+ case CALLBACKTYPE_failsafe:
+ case CALLBACKTYPE_syscall:
ret = -EINVAL;
break;
- }
-
- return ret;
-}
-
-static long unregister_guest_callback(struct callback_unregister *unreg)
-{
- long ret;
-
- switch ( unreg->type )
- {
+
case CALLBACKTYPE_nmi:
ret = unregister_guest_nmi_callback();
break;
default:
- ret = -EINVAL;
+ ret = -ENOSYS;
break;
}
@@ -426,7 +437,7 @@ long do_callback_op(int cmd, XEN_GUEST_H
break;
default:
- ret = -EINVAL;
+ ret = -ENOSYS;
break;
}
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/common/domain.c
--- a/xen/common/domain.c Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/common/domain.c Mon Nov 13 09:58:23 2006 -0700
@@ -22,6 +22,7 @@
#include <xen/delay.h>
#include <xen/shutdown.h>
#include <xen/percpu.h>
+#include <xen/multicall.h>
#include <asm/debugger.h>
#include <public/sched.h>
#include <public/vcpu.h>
@@ -256,6 +257,10 @@ void __domain_crash_synchronous(void)
void __domain_crash_synchronous(void)
{
__domain_crash(current->domain);
+
+ /* Flush multicall state before dying. */
+ this_cpu(mc_state).flags = 0;
+
for ( ; ; )
do_softirq();
}
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/include/asm-x86/bitops.h
--- a/xen/include/asm-x86/bitops.h Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/include/asm-x86/bitops.h Mon Nov 13 09:58:23 2006 -0700
@@ -246,7 +246,7 @@ static __inline__ int constant_test_bit(
return ((1U << (nr & 31)) & (((const volatile unsigned int *) addr)[nr
>> 5])) != 0;
}
-static __inline__ int variable_test_bit(int nr, volatile void * addr)
+static __inline__ int variable_test_bit(int nr, const volatile void * addr)
{
int oldbit;
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/include/asm-x86/config.h Mon Nov 13 09:58:23 2006 -0700
@@ -194,12 +194,6 @@ extern unsigned long _end; /* standard E
#define __HYPERVISOR_DS32 0xe018
#define __HYPERVISOR_DS __HYPERVISOR_DS64
-#define __GUEST_CS64 0xe033
-#define __GUEST_CS32 0xe023
-#define __GUEST_CS __GUEST_CS64
-#define __GUEST_DS 0x0000
-#define __GUEST_SS 0xe02b
-
/* For generic assembly code: use macros to define operation/operand sizes. */
#define __OS "q" /* Operation Suffix */
#define __OP "r" /* Operand Prefix */
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/include/asm-x86/desc.h
--- a/xen/include/asm-x86/desc.h Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/include/asm-x86/desc.h Mon Nov 13 09:58:23 2006 -0700
@@ -155,16 +155,11 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\
#endif
extern struct desc_struct gdt_table[];
-extern struct desc_struct *gdt;
-extern idt_entry_t *idt;
struct Xgt_desc_struct {
unsigned short size;
unsigned long address __attribute__((packed));
};
-
-#define idt_descr (*(struct Xgt_desc_struct *)((char *)&idt - 2))
-#define gdt_descr (*(struct Xgt_desc_struct *)((char *)&gdt - 2))
extern void set_intr_gate(unsigned int irq, void * addr);
extern void set_system_gate(unsigned int n, void *addr);
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/include/asm-x86/hvm/support.h
--- a/xen/include/asm-x86/hvm/support.h Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/include/asm-x86/hvm/support.h Mon Nov 13 09:58:23 2006 -0700
@@ -118,13 +118,6 @@ extern unsigned int opt_hvm_debug_level;
#define HVM_DBG_LOG(level, _f, _a...)
#endif
-#define __hvm_bug(regs) \
- do { \
- printk("__hvm_bug at %s:%d\n", __FILE__, __LINE__); \
- show_execution_state(regs); \
- domain_crash_synchronous(); \
- } while (0)
-
#define TRACE_VMEXIT(index, value) \
current->arch.hvm_vcpu.hvm_trace_values[index] = (value)
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/include/asm-x86/hvm/vlapic.h
--- a/xen/include/asm-x86/hvm/vlapic.h Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/include/asm-x86/hvm/vlapic.h Mon Nov 13 09:58:23 2006 -0700
@@ -90,4 +90,6 @@ struct vlapic *apic_round_robin(
s_time_t get_apictime_scheduled(struct vcpu *v);
+int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t mda);
+
#endif /* __ASM_X86_HVM_VLAPIC_H__ */
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/include/public/elfnote.h
--- a/xen/include/public/elfnote.h Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/include/public/elfnote.h Mon Nov 13 09:58:23 2006 -0700
@@ -138,6 +138,15 @@
*/
#define XEN_ELFNOTE_BSD_SYMTAB 11
+/*
+ * The lowest address the hypervisor hole can begin at (numeric).
+ *
+ * This must not be set higher than HYPERVISOR_VIRT_START. Its presence
+ * also indicates to the hypervisor that the kernel can deal with the
+ * hole starting at a higher address.
+ */
+#define XEN_ELFNOTE_HV_START_LOW 12
+
#endif /* __XEN_PUBLIC_ELFNOTE_H__ */
/*
diff -r 529b3f3fb127 -r 63cb737b9a24 xen/include/public/hvm/ioreq.h
--- a/xen/include/public/hvm/ioreq.h Fri Nov 10 13:01:23 2006 -0700
+++ b/xen/include/public/hvm/ioreq.h Mon Nov 13 09:58:23 2006 -0700
@@ -80,7 +80,7 @@ struct buffered_iopage {
}; /* sizeof this structure must be in one page */
typedef struct buffered_iopage buffered_iopage_t;
-#define ACPI_PM1A_EVT_BLK_ADDRESS 0x000000000000c010
+#define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000001f40
#define ACPI_PM1A_CNT_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04)
#define ACPI_PM_TMR_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08)
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/check/check_crypto_lib
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/check/check_crypto_lib Mon Nov 13 09:58:23 2006 -0700
@@ -0,0 +1,11 @@
+#!/bin/bash
+# CHECK-BUILD CHECK-INSTALL
+
+function error {
+ echo
+ echo " *** Check for crypto library FAILED"
+ exit 1
+}
+
+set -e
+ldconfig -p | grep -q libcrypto.so || error
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/check/check_openssl_devel
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/check/check_openssl_devel Mon Nov 13 09:58:23 2006 -0700
@@ -0,0 +1,11 @@
+#!/bin/bash
+# CHECK-BUILD
+
+function error {
+ echo
+ echo " *** Check for openssl headers FAILED"
+ exit 1
+}
+
+set -e
+[ -e /usr/include/openssl/md5.h ] || error
diff -r 529b3f3fb127 -r 63cb737b9a24 tools/check/check_x11_devel
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tools/check/check_x11_devel Mon Nov 13 09:58:23 2006 -0700
@@ -0,0 +1,11 @@
+#!/bin/bash
+# CHECK-BUILD
+
+function error {
+ echo
+ echo " *** Check for x11 headers FAILED"
+ exit 1
+}
+
+set -e
+[ -e /usr/include/X11/keysymdef.h ] || error
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|