[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] merge with xen-unstable.hg
# HG changeset patch # User awilliam@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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |