diff --git a/.hgtags b/.hgtags index 04c9da8e0d..78c6645d6c 100644 --- a/.hgtags +++ b/.hgtags @@ -13,3 +13,4 @@ fb875591fd72e15c31879c0e9034d99b80225595 RELEASE-2.0.4 30c521db4c71960b0cf1d9c9e1b658e77b535a3e split-1.0 3d330e41f41ce1bc118c02346e18949ad5d67f6b split-1.1 c8fdb0caa77b429cf47f9707926e83947778cb48 RELEASE-3.0.0 +af0573e9e5258db0a9d28aa954dd302ddd2c2d23 3.0.2-rc diff --git a/Makefile b/Makefile index f9f80d1e9f..3cd9d53b99 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ # Grand Unified Makefile for Xen. # -KERNELS ?= linux-2.6-xen0 linux-2.6-xenU +KERNELS ?= linux-2.6-xen # You may use wildcards in the above e.g. KERNELS=*2.6* XKERNELS := $(foreach kernel, $(KERNELS), $(patsubst buildconfigs/mk.%,%,$(wildcard buildconfigs/mk.$(kernel))) ) diff --git a/buildconfigs/linux-defconfig_xen0_ia64 b/buildconfigs/linux-defconfig_xen0_ia64 index 13466c6b42..2dbb12644e 100644 --- a/buildconfigs/linux-defconfig_xen0_ia64 +++ b/buildconfigs/linux-defconfig_xen0_ia64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc3-xen0 -# Thu Feb 16 13:20:46 2006 +# Linux kernel version: 2.6.16-xen0 +# Mon Mar 27 14:46:03 2006 # # @@ -95,8 +95,7 @@ CONFIG_ARCH_XEN=y CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_BLKDEV_FRONTEND=y -CONFIG_XEN_VT=y -CONFIG_VT=y +CONFIG_XEN_BLKDEV_BACKEND=y CONFIG_XEN_SYSFS=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_DMA_IS_DMA32=y @@ -378,7 +377,7 @@ CONFIG_BLK_DEV_IDESCSI=y # # IDE chipset support/bugfixes # -CONFIG_IDE_GENERIC=y +# CONFIG_IDE_GENERIC is not set CONFIG_BLK_DEV_IDEPCI=y # CONFIG_IDEPCI_SHARE_IRQ is not set # CONFIG_BLK_DEV_OFFBOARD is not set @@ -706,6 +705,7 @@ CONFIG_GAMEPORT=y # # Character devices # +CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_HW_CONSOLE=y CONFIG_SERIAL_NONSTANDARD=y @@ -1252,11 +1252,7 @@ CONFIG_USB_MON=y # CONFIG_INFINIBAND is not set # -# SN Devices -# - -# -# EDAC - error detection and reporting (RAS) +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # # diff --git a/buildconfigs/linux-defconfig_xenU_ia64 b/buildconfigs/linux-defconfig_xenU_ia64 index ea85bd82f0..da7a4e5b0c 100644 --- a/buildconfigs/linux-defconfig_xenU_ia64 +++ b/buildconfigs/linux-defconfig_xenU_ia64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc3-xenU -# Thu Feb 16 13:47:59 2006 +# Linux kernel version: 2.6.16-xenU +# Mon Mar 27 14:01:13 2006 # # @@ -92,8 +92,7 @@ CONFIG_ARCH_XEN=y CONFIG_XEN_PRIVILEGED_GUEST=y CONFIG_XEN_BLKDEV_GRANT=y CONFIG_XEN_BLKDEV_FRONTEND=y -# CONFIG_XEN_VT is not set -# CONFIG_VT is not set +CONFIG_XEN_BLKDEV_BACKEND=y CONFIG_XEN_SYSFS=y CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y CONFIG_DMA_IS_DMA32=y @@ -607,6 +606,9 @@ CONFIG_SERIO=y # # Character devices # +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +CONFIG_HW_CONSOLE=y # CONFIG_SERIAL_NONSTANDARD is not set # @@ -864,6 +866,13 @@ CONFIG_FB_RADEON_DEBUG=y # CONFIG_FB_TRIDENT is not set # CONFIG_FB_VIRTUAL is not set +# +# Console display driver support +# +CONFIG_VGA_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FRAMEBUFFER_CONSOLE is not set + # # Logo configuration # @@ -1122,11 +1131,7 @@ CONFIG_USB_MON=y # CONFIG_INFINIBAND is not set # -# SN Devices -# - -# -# EDAC - error detection and reporting (RAS) +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # # diff --git a/buildconfigs/linux-defconfig_xen_x86_64 b/buildconfigs/linux-defconfig_xen_x86_64 index 290e90a92d..58a24a5954 100644 --- a/buildconfigs/linux-defconfig_xen_x86_64 +++ b/buildconfigs/linux-defconfig_xen_x86_64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16-rc3-xen -# Mon Feb 20 11:37:11 2006 +# Linux kernel version: 2.6.16-xen +# Mon Mar 27 09:43:44 2006 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -102,6 +102,8 @@ CONFIG_X86_PC=y # CONFIG_MPSC is not set CONFIG_GENERIC_CPU=y CONFIG_X86_64_XEN=y +CONFIG_X86_NO_TSS=y +CONFIG_X86_NO_IDT=y CONFIG_X86_L1_CACHE_BYTES=128 CONFIG_X86_L1_CACHE_SHIFT=7 CONFIG_X86_GOOD_APIC=y @@ -1138,7 +1140,7 @@ CONFIG_AMD8111_ETH=m CONFIG_AMD8111E_NAPI=y CONFIG_ADAPTEC_STARFIRE=m CONFIG_ADAPTEC_STARFIRE_NAPI=y -CONFIG_B44=m +# CONFIG_B44 is not set CONFIG_FORCEDETH=m CONFIG_DGRS=m CONFIG_EEPRO100=m @@ -1782,8 +1784,8 @@ CONFIG_VIDEO_DPC=m CONFIG_VIDEO_HEXIUM_ORION=m CONFIG_VIDEO_HEXIUM_GEMINI=m CONFIG_VIDEO_CX88=m -CONFIG_VIDEO_CX88_DVB=m CONFIG_VIDEO_CX88_ALSA=m +CONFIG_VIDEO_CX88_DVB=m CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y CONFIG_VIDEO_CX88_VP3054=m CONFIG_VIDEO_EM28XX=m @@ -2331,11 +2333,7 @@ CONFIG_INFINIBAND_IPOIB=m CONFIG_INFINIBAND_SRP=m # -# SN Devices -# - -# -# EDAC - error detection and reporting (RAS) +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) # CONFIG_EDAC=m diff --git a/linux-2.6-xen-sparse/arch/ia64/Kconfig b/linux-2.6-xen-sparse/arch/ia64/Kconfig index 3f6f2315ad..54584bdbac 100644 --- a/linux-2.6-xen-sparse/arch/ia64/Kconfig +++ b/linux-2.6-xen-sparse/arch/ia64/Kconfig @@ -84,19 +84,6 @@ config XEN_BLKDEV_BACKEND bool default y -config XEN_VT - bool "Override for turning on CONFIG_VT for domU" - default y - help - Hack to turn off CONFIG_VT for domU - -config VT - bool - default y if XEN && XEN_VT - default n if XEN && !XEN_VT - help - Hack to turn off CONFIG_VT for domU - config XEN_SYSFS bool "Export Xen attributes in sysfs" depends on XEN && SYSFS diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c index e478453086..fecc02beb1 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c @@ -506,6 +506,22 @@ setup_arch (char **cmdline_p) conswitchp = &vga_con; # endif } +#ifdef CONFIG_XEN + if (running_on_xen) { + extern shared_info_t *HYPERVISOR_shared_info; + + /* xen_start_info isn't setup yet, get the flags manually */ + if (HYPERVISOR_shared_info->arch.flags & SIF_INITDOMAIN) { + if (!(HYPERVISOR_shared_info->arch.flags & SIF_PRIVILEGED)) + panic("Xen granted us console access " + "but not privileged status"); + } else { + extern int console_use_vt; + conswitchp = NULL; + console_use_vt = 0; + } + } +#endif #endif /* enable IA-64 Machine Check Abort Handling unless disabled */ diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S index 6f797e457d..08b5f53f6a 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/entry-xen.S @@ -855,32 +855,12 @@ ecrit: /**** END OF CRITICAL REGION ****/ # i.e. it just resumes from the next instruction interrupted with the same context. # Hypervisor uses this for application faults while it executes. +# Unlike i386 there is no need to reload the saved segment selectors: +# Xen already reloaded all valid ones and zeroed the others. ENTRY(failsafe_callback) - addq $0x10,%rsp /* skip rcx and r11 */ -1: mov (%rsp),%ds -2: mov 8(%rsp),%es -3: mov 16(%rsp),%fs -4: mov 24(%rsp),%gs - addq $0x20,%rsp /* skip the above selectors */ + addq $0x30,%rsp /* skip %rcx,%r11,%ds,%es,%fs,%gs */ SAVE_ALL jmp error_exit -.section .fixup,"ax"; \ -6: movq $0,(%rsp); \ - jmp 1b; \ -7: movq $0,8(%rsp); \ - jmp 2b; \ -8: movq $0,16(%rsp); \ - jmp 3b; \ -9: movq $0,24(%rsp); \ - jmp 4b; \ -.previous; \ -.section __ex_table,"a";\ - .align 16; \ - .quad 1b,6b; \ - .quad 2b,7b; \ - .quad 3b,8b; \ - .quad 4b,9b; \ -.previous #if 0 .section __ex_table,"a" diff --git a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c index 84f35c8841..61158a6034 100644 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c @@ -1039,8 +1039,7 @@ static int __init xenbus_probe_init(void) xsd_port_intf = create_xen_proc_entry("xsd_port", 0400); if (xsd_port_intf) xsd_port_intf->read_proc = xsd_port_read; - } - else + } else xenstored_ready = 1; /* Initialize the interface to xenstore. */ diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h index 96093ba4bf..5b8d8be639 100644 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h +++ b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/processor.h @@ -237,20 +237,11 @@ extern unsigned long mmu_cr4_features; static inline void set_in_cr4 (unsigned long mask) { + unsigned cr4; mmu_cr4_features |= mask; - switch (mask) { - case X86_CR4_OSFXSR: - case X86_CR4_OSXMMEXCPT: - break; - default: - do { - const char *msg = "Xen unsupported cr4 update\n"; - (void)HYPERVISOR_console_io( - CONSOLEIO_write, __builtin_strlen(msg), - (char *)msg); - BUG(); - } while (0); - } + cr4 = read_cr4(); + cr4 |= mask; + write_cr4(cr4); } static inline void clear_in_cr4 (unsigned long mask) diff --git a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h index 6fe7ccd450..e000547f62 100644 --- a/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h +++ b/linux-2.6-xen-sparse/include/asm-x86_64/mach-xen/asm/processor.h @@ -141,31 +141,21 @@ extern unsigned long mmu_cr4_features; static inline void set_in_cr4 (unsigned long mask) { mmu_cr4_features |= mask; - switch (mask) { - case X86_CR4_OSFXSR: - case X86_CR4_OSXMMEXCPT: - break; - default: - do { - const char *msg = "Xen unsupported cr4 update\n"; - (void)HYPERVISOR_console_io( - CONSOLEIO_write, __builtin_strlen(msg), - (char *)msg); - BUG(); - } while (0); - } + __asm__("movq %%cr4,%%rax\n\t" + "orq %0,%%rax\n\t" + "movq %%rax,%%cr4\n" + : : "irg" (mask) + :"ax"); } static inline void clear_in_cr4 (unsigned long mask) { -#ifndef CONFIG_XEN mmu_cr4_features &= ~mask; __asm__("movq %%cr4,%%rax\n\t" "andq %0,%%rax\n\t" "movq %%rax,%%cr4\n" : : "irg" (~mask) :"ax"); -#endif } diff --git a/tools/Makefile b/tools/Makefile index c2f22da959..375b5633b5 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -37,6 +37,7 @@ install: check $(MAKE) -C $$subdir $@; \ done $(MAKE) ioemuinstall + $(INSTALL_DIR) -p $(DESTDIR)/var/xen/dump clean: check_clean @set -e; for subdir in $(SUBDIRS); do \ diff --git a/tools/debugger/gdb/README b/tools/debugger/gdb/README index 0aa9d68772..9af7336486 100644 --- a/tools/debugger/gdb/README +++ b/tools/debugger/gdb/README @@ -11,8 +11,8 @@ To build the GDB server: to your test machine. To build a debuggable guest kernel image: - 1. cd linux-2.6.12-xenU - 2. ARCH=xen make menuconfig + 1. cd linux-2.6.xx-xenU + 2. make menuconfig 3. From within the configurator, enable the following options: # Kernel hacking -> Compile the kernel with debug info [*] -> Compile the kernel with frame pointers diff --git a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv index a586a51db9..fae0f3b838 100644 --- a/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv +++ b/tools/debugger/gdb/gdb-6.2.1-xen-sparse/gdb/gdbserver/configure.srv @@ -61,7 +61,7 @@ case "${target}" in srv_linux_thread_db=yes ;; x86_64-*-linux*) srv_regobj=reg-x86-64.o - srv_tgtobj="linux-low.o linux-x86-64-low.o i387-fp.o" + srv_tgtobj="linux-xen-low.o linux-x86-64-low.o i387-fp.o" srv_linux_regsets=yes ;; xscale*-*-linux*) srv_regobj=reg-arm.o diff --git a/tools/examples/xen-backend.agent b/tools/examples/xen-backend.agent index 72bbafda21..e662015da2 100755 --- a/tools/examples/xen-backend.agent +++ b/tools/examples/xen-backend.agent @@ -2,6 +2,10 @@ PATH=/etc/xen/scripts:$PATH +. /etc/xen/scripts/locking.sh + +claim_lock xenbus_hotplug_global + case "$XENBUS_TYPE" in vbd) /etc/xen/scripts/block "$ACTION" @@ -25,3 +29,5 @@ case "$ACTION" in offline) ;; esac + +release_lock xenbus_hotplug_global diff --git a/tools/ioemu/hw/pcnet.c b/tools/ioemu/hw/pcnet.c index fcf4a3528e..993b71d0ca 100644 --- a/tools/ioemu/hw/pcnet.c +++ b/tools/ioemu/hw/pcnet.c @@ -45,21 +45,6 @@ #define PCNET_PNPMMIO_SIZE 0x20 -typedef struct PCNetState_st PCNetState; - -struct PCNetState_st { - PCIDevice dev; - NetDriverState *nd; - int mmio_io_addr, rap, isr, lnkst; - target_phys_addr_t rdra, tdra; - uint8_t prom[16]; - uint16_t csr[128]; - uint16_t bcr[32]; - uint64_t timer; - int xmit_pos, recv_pos; - uint8_t buffer[4096]; -}; - #include "pcnet.h" static void pcnet_poll(PCNetState *s); @@ -217,6 +202,11 @@ static void pcnet_init(PCNetState *s) CSR_RCVRC(s) = CSR_RCVRL(s); CSR_XMTRC(s) = CSR_XMTRL(s); + /* flush any cached receive descriptors */ + s->crmd.rmd1.own = 0; + s->nrmd.rmd1.own = 0; + s->nnrmd.rmd1.own = 0; + #ifdef PCNET_DEBUG printf("pcnet ss32=%d rdra=0x%08x[%d] tdra=0x%08x[%d]\n", BCR_SSIZE32(s), @@ -239,6 +229,11 @@ static void pcnet_start(PCNetState *s) if (!CSR_DRX(s)) s->csr[0] |= 0x0020; /* set RXON */ + /* flush any cached receive descriptors */ + s->crmd.rmd1.own = 0; + s->nrmd.rmd1.own = 0; + s->nnrmd.rmd1.own = 0; + s->csr[0] &= ~0x0004; /* clear STOP bit */ s->csr[0] |= 0x0002; } @@ -260,29 +255,21 @@ static void pcnet_rdte_poll(PCNetState *s) s->csr[28] = s->csr[29] = 0; if (s->rdra) { int bad = 0; -#if 1 target_phys_addr_t crda = pcnet_rdra_addr(s, CSR_RCVRC(s)); target_phys_addr_t nrda = pcnet_rdra_addr(s, -1 + CSR_RCVRC(s)); target_phys_addr_t nnrd = pcnet_rdra_addr(s, -2 + CSR_RCVRC(s)); -#else - target_phys_addr_t crda = s->rdra + - (CSR_RCVRL(s) - CSR_RCVRC(s)) * - (BCR_SWSTYLE(s) ? 16 : 8 ); - int nrdc = CSR_RCVRC(s)<=1 ? CSR_RCVRL(s) : CSR_RCVRC(s)-1; - target_phys_addr_t nrda = s->rdra + - (CSR_RCVRL(s) - nrdc) * - (BCR_SWSTYLE(s) ? 16 : 8 ); - int nnrc = nrdc<=1 ? CSR_RCVRL(s) : nrdc-1; - target_phys_addr_t nnrd = s->rdra + - (CSR_RCVRL(s) - nnrc) * - (BCR_SWSTYLE(s) ? 16 : 8 ); -#endif - CHECK_RMD(PHYSADDR(s,crda), bad); + if (!s->crmd.rmd1.own) { + CHECK_RMD(&(s->crmd),PHYSADDR(s,crda), bad); + } if (!bad) { - CHECK_RMD(PHYSADDR(s,nrda), bad); + if (s->crmd.rmd1.own && !s->nrmd.rmd1.own) { + CHECK_RMD(&(s->nrmd),PHYSADDR(s,nrda), bad); + } if (bad || (nrda == crda)) nrda = 0; - CHECK_RMD(PHYSADDR(s,nnrd), bad); + if (s->crmd.rmd1.own && s->nrmd.rmd1.own && !s->nnrmd.rmd1.own) { + CHECK_RMD(&(s->nnrmd),PHYSADDR(s,nnrd), bad); + } if (bad || (nnrd == crda)) nnrd = 0; s->csr[28] = crda & 0xffff; @@ -303,14 +290,12 @@ static void pcnet_rdte_poll(PCNetState *s) } if (CSR_CRDA(s)) { - struct pcnet_RMD rmd; - RMDLOAD(&rmd, PHYSADDR(s,CSR_CRDA(s))); - CSR_CRBC(s) = rmd.rmd1.bcnt; - CSR_CRST(s) = ((uint32_t *)&rmd)[1] >> 16; + CSR_CRBC(s) = s->crmd.rmd1.bcnt; + CSR_CRST(s) = ((uint32_t *)&(s->crmd))[1] >> 16; #ifdef PCNET_DEBUG_RMD_X printf("CRDA=0x%08x CRST=0x%04x RCVRC=%d RMD1=0x%08x RMD2=0x%08x\n", PHYSADDR(s,CSR_CRDA(s)), CSR_CRST(s), CSR_RCVRC(s), - ((uint32_t *)&rmd)[1], ((uint32_t *)&rmd)[2]); + ((uint32_t *)&(s->crmd))[1], ((uint32_t *)&(s->crmd))[2]); PRINT_RMD(&rmd); #endif } else { @@ -318,10 +303,8 @@ static void pcnet_rdte_poll(PCNetState *s) } if (CSR_NRDA(s)) { - struct pcnet_RMD rmd; - RMDLOAD(&rmd, PHYSADDR(s,CSR_NRDA(s))); - CSR_NRBC(s) = rmd.rmd1.bcnt; - CSR_NRST(s) = ((uint32_t *)&rmd)[1] >> 16; + CSR_NRBC(s) = s->nrmd.rmd1.bcnt; + CSR_NRST(s) = ((uint32_t *)&(s->nrmd))[1] >> 16; } else { CSR_NRBC(s) = CSR_NRST(s) = 0; } @@ -336,6 +319,7 @@ static int pcnet_tdte_poll(PCNetState *s) (CSR_XMTRL(s) - CSR_XMTRC(s)) * (BCR_SWSTYLE(s) ? 16 : 8 ); int bad = 0; + s->csr[0] &= ~0x0008; /* clear TDMD */ CHECK_TMD(PHYSADDR(s, cxda),bad); if (!bad) { if (CSR_CXDA(s) != cxda) { @@ -354,12 +338,8 @@ static int pcnet_tdte_poll(PCNetState *s) } if (CSR_CXDA(s)) { - struct pcnet_TMD tmd; - - TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s))); - - CSR_CXBC(s) = tmd.tmd1.bcnt; - CSR_CXST(s) = ((uint32_t *)&tmd)[1] >> 16; + CSR_CXBC(s) = s->tmd.tmd1.bcnt; + CSR_CXST(s) = ((uint32_t *)&(s->tmd))[1] >> 16; } else { CSR_CXBC(s) = CSR_CXST(s) = 0; } @@ -373,14 +353,11 @@ static int pcnet_can_receive(void *opaque) if (CSR_STOP(s) || CSR_SPND(s)) return 0; - if (s->recv_pos > 0) - return 0; - pcnet_rdte_poll(s); if (!(CSR_CRST(s) & 0x8000)) { return 0; } - return sizeof(s->buffer)-16; + return sizeof(s->rx_buffer)-16; } #define MIN_BUF_SIZE 60 @@ -389,7 +366,7 @@ static void pcnet_receive(void *opaque, const uint8_t *buf, int size) { PCNetState *s = opaque; int is_padr = 0, is_bcast = 0, is_ladr = 0; - uint8_t buf1[60]; + int pad; if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size) return; @@ -399,12 +376,10 @@ static void pcnet_receive(void *opaque, const uint8_t *buf, int size) #endif /* if too small buffer, then expand it */ - if (size < MIN_BUF_SIZE) { - memcpy(buf1, buf, size); - memset(buf1 + size, 0, MIN_BUF_SIZE - size); - buf = buf1; - size = MIN_BUF_SIZE; - } + if (size < MIN_BUF_SIZE) + pad = MIN_BUF_SIZE - size + 4; + else + pad = 4; if (CSR_PROM(s) || (is_padr=padr_match(s, buf, size)) @@ -413,124 +388,74 @@ static void pcnet_receive(void *opaque, const uint8_t *buf, int size) pcnet_rdte_poll(s); - if (!(CSR_CRST(s) & 0x8000) && s->rdra) { - struct pcnet_RMD rmd; - int rcvrc = CSR_RCVRC(s)-1,i; - target_phys_addr_t nrda; - for (i = CSR_RCVRL(s)-1; i > 0; i--, rcvrc--) { - if (rcvrc <= 1) - rcvrc = CSR_RCVRL(s); - nrda = s->rdra + - (CSR_RCVRL(s) - rcvrc) * - (BCR_SWSTYLE(s) ? 16 : 8 ); - RMDLOAD(&rmd, PHYSADDR(s,nrda)); - if (rmd.rmd1.own) { + if (size > 2000) { #ifdef PCNET_DEBUG_RMD - printf("pcnet - scan buffer: RCVRC=%d PREV_RCVRC=%d\n", - rcvrc, CSR_RCVRC(s)); + printf("pcnet - oversize packet discarded.\n"); #endif - CSR_RCVRC(s) = rcvrc; - pcnet_rdte_poll(s); - break; - } - } - } - - if (!(CSR_CRST(s) & 0x8000)) { + } else if (!(CSR_CRST(s) & 0x8000)) { #ifdef PCNET_DEBUG_RMD printf("pcnet - no buffer: RCVRC=%d\n", CSR_RCVRC(s)); #endif s->csr[0] |= 0x1000; /* Set MISS flag */ CSR_MISSC(s)++; } else { - uint8_t *src = &s->buffer[8]; + uint8_t *src = &s->rx_buffer[8]; target_phys_addr_t crda = CSR_CRDA(s); - struct pcnet_RMD rmd; + target_phys_addr_t nrda = CSR_NRDA(s); + target_phys_addr_t nnrda = CSR_NNRD(s); int pktcount = 0; + int packet_size = size + pad; memcpy(src, buf, size); - - if (!CSR_ASTRP_RCV(s)) { - uint32_t fcs = ~0; -#if 0 - uint8_t *p = s->buffer; - - ((uint32_t *)p)[0] = ((uint32_t *)p)[1] = 0xaaaaaaaa; - p[7] = 0xab; -#else - uint8_t *p = src; -#endif - - while (size < 46) { - src[size++] = 0; - } - - while (p != &src[size]) { - CRC(fcs, *p++); - } - ((uint32_t *)&src[size])[0] = htonl(fcs); - size += 4; /* FCS at end of packet */ - } else size += 4; + memset(src + size, 0, pad); + size += pad; #ifdef PCNET_DEBUG_MATCH PRINT_PKTHDR(buf); #endif - RMDLOAD(&rmd, PHYSADDR(s,crda)); - /*if (!CSR_LAPPEN(s))*/ - rmd.rmd1.stp = 1; + s->crmd.rmd1.stp = 1; + do { + int count = MIN(4096 - s->crmd.rmd1.bcnt,size); + target_phys_addr_t rbadr = PHYSADDR(s, s->crmd.rmd0.rbadr); + cpu_physical_memory_write(rbadr, src, count); + cpu_physical_memory_set_dirty(rbadr); + cpu_physical_memory_set_dirty(rbadr+count); + src += count; size -= count; + if (size > 0 && s->nrmd.rmd1.own) { + RMDSTORE(&(s->crmd), PHYSADDR(s,crda)); + crda = nrda; + nrda = nnrda; + s->crmd = s->nrmd; + s->nrmd = s->nnrmd; + s->nnrmd.rmd1.own = 0; + } + pktcount++; + } while (size > 0 && s->crmd.rmd1.own); -#define PCNET_RECV_STORE() do { \ - int count = MIN(4096 - rmd.rmd1.bcnt,size); \ - target_phys_addr_t rbadr = PHYSADDR(s, rmd.rmd0.rbadr); \ - cpu_physical_memory_write(rbadr, src, count); \ - cpu_physical_memory_set_dirty(rbadr); \ - cpu_physical_memory_set_dirty(rbadr+count); \ - src += count; size -= count; \ - rmd.rmd2.mcnt = count; rmd.rmd1.own = 0; \ - RMDSTORE(&rmd, PHYSADDR(s,crda)); \ - pktcount++; \ -} while (0) - - PCNET_RECV_STORE(); - if ((size > 0) && CSR_NRDA(s)) { - target_phys_addr_t nrda = CSR_NRDA(s); - RMDLOAD(&rmd, PHYSADDR(s,nrda)); - if (rmd.rmd1.own) { - crda = nrda; - PCNET_RECV_STORE(); - if ((size > 0) && (nrda=CSR_NNRD(s))) { - RMDLOAD(&rmd, PHYSADDR(s,nrda)); - if (rmd.rmd1.own) { - crda = nrda; - PCNET_RECV_STORE(); - } - } - } - } - -#undef PCNET_RECV_STORE - - RMDLOAD(&rmd, PHYSADDR(s,crda)); if (size == 0) { - rmd.rmd1.enp = 1; - rmd.rmd1.pam = !CSR_PROM(s) && is_padr; - rmd.rmd1.lafm = !CSR_PROM(s) && is_ladr; - rmd.rmd1.bam = !CSR_PROM(s) && is_bcast; + s->crmd.rmd1.enp = 1; + s->crmd.rmd2.mcnt = packet_size; + s->crmd.rmd1.pam = !CSR_PROM(s) && is_padr; + s->crmd.rmd1.lafm = !CSR_PROM(s) && is_ladr; + s->crmd.rmd1.bam = !CSR_PROM(s) && is_bcast; } else { - rmd.rmd1.oflo = 1; - rmd.rmd1.buff = 1; - rmd.rmd1.err = 1; + s->crmd.rmd1.oflo = 1; + s->crmd.rmd1.buff = 1; + s->crmd.rmd1.err = 1; } - RMDSTORE(&rmd, PHYSADDR(s,crda)); + RMDSTORE(&(s->crmd), PHYSADDR(s,crda)); s->csr[0] |= 0x0400; + s->crmd = s->nrmd; + s->nrmd = s->nnrmd; + s->nnrmd.rmd1.own = 0; #ifdef PCNET_DEBUG printf("RCVRC=%d CRDA=0x%08x BLKS=%d\n", CSR_RCVRC(s), PHYSADDR(s,CSR_CRDA(s)), pktcount); #endif #ifdef PCNET_DEBUG_RMD - PRINT_RMD(&rmd); + PRINT_RMD(&s->crmd); #endif while (pktcount--) { @@ -551,80 +476,88 @@ static void pcnet_receive(void *opaque, const uint8_t *buf, int size) static void pcnet_transmit(PCNetState *s) { - target_phys_addr_t xmit_cxda = 0; + target_phys_addr_t start_addr = 0; + struct pcnet_TMD start_tmd; int count = CSR_XMTRL(s)-1; - s->xmit_pos = -1; + int xmit_pos = 0; + int len; + if (!CSR_TXON(s)) { s->csr[0] &= ~0x0008; return; } - txagain: - if (pcnet_tdte_poll(s)) { - struct pcnet_TMD tmd; - - TMDLOAD(&tmd, PHYSADDR(s,CSR_CXDA(s))); + while (pcnet_tdte_poll(s)) { #ifdef PCNET_DEBUG_TMD printf(" TMDLOAD 0x%08x\n", PHYSADDR(s,CSR_CXDA(s))); - PRINT_TMD(&tmd); + PRINT_TMD(&(s->tmd)); #endif - if (tmd.tmd1.stp) { - s->xmit_pos = 0; - if (!tmd.tmd1.enp) { - cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr), - s->buffer, 4096 - tmd.tmd1.bcnt); - s->xmit_pos += 4096 - tmd.tmd1.bcnt; - } - xmit_cxda = PHYSADDR(s,CSR_CXDA(s)); - } - if (tmd.tmd1.enp && (s->xmit_pos >= 0)) { - cpu_physical_memory_read(PHYSADDR(s, tmd.tmd0.tbadr), - s->buffer + s->xmit_pos, 4096 - tmd.tmd1.bcnt); - s->xmit_pos += 4096 - tmd.tmd1.bcnt; - - tmd.tmd1.own = 0; - TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); - -#ifdef PCNET_DEBUG - printf("pcnet_transmit size=%d\n", s->xmit_pos); -#endif - if (CSR_LOOP(s)) - pcnet_receive(s, s->buffer, s->xmit_pos); - else - qemu_send_packet(s->nd, s->buffer, s->xmit_pos); - - s->csr[0] &= ~0x0008; /* clear TDMD */ - s->csr[4] |= 0x0004; /* set TXSTRT */ - s->xmit_pos = -1; - } else { - tmd.tmd1.own = 0; - TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); - } - if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && tmd.tmd1.ltint)) - s->csr[0] |= 0x0200; /* set TINT */ - - if (CSR_XMTRC(s)<=1) + len = 4096 - s->tmd.tmd1.bcnt; + if (CSR_XMTRC(s) <= 1) CSR_XMTRC(s) = CSR_XMTRL(s); else CSR_XMTRC(s)--; - if (count--) - goto txagain; - } else - if (s->xmit_pos >= 0) { - struct pcnet_TMD tmd; - TMDLOAD(&tmd, PHYSADDR(s,xmit_cxda)); - tmd.tmd2.buff = tmd.tmd2.uflo = tmd.tmd1.err = 1; - tmd.tmd1.own = 0; - TMDSTORE(&tmd, PHYSADDR(s,xmit_cxda)); + /* handle start followed by start */ + if (s->tmd.tmd1.stp && start_addr) { + TMDSTORE(&start_tmd, start_addr); + start_addr = 0; + xmit_pos = 0; + } + if ((xmit_pos + len) < sizeof(s->tx_buffer)) { + cpu_physical_memory_read(PHYSADDR(s, s->tmd.tmd0.tbadr), + s->tx_buffer + xmit_pos, len); + xmit_pos += len; + } else { + s->tmd.tmd2.buff = s->tmd.tmd2.uflo = s->tmd.tmd1.err = 1; + TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s))); + if (start_addr == PHYSADDR(s,CSR_CXDA(s))) + start_addr = 0; /* don't clear own bit twice */ + continue; + } + if (s->tmd.tmd1.stp) { + if (s->tmd.tmd1.enp) { + if (CSR_LOOP(s)) + pcnet_receive(s, s->tx_buffer, xmit_pos); + else + qemu_send_packet(s->nd, s->tx_buffer, xmit_pos); + + s->csr[4] |= 0x0008; /* set TXSTRT */ + TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s))); + xmit_pos = 0; + count--; + } else { + start_tmd = s->tmd; + start_addr = PHYSADDR(s,CSR_CXDA(s)); + } + } else if (s->tmd.tmd1.enp) { + TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s))); + if (start_addr) { + TMDSTORE(&start_tmd, start_addr); + } + start_addr = 0; + xmit_pos = 0; + count--; + + } else { + TMDSTORE(&(s->tmd), PHYSADDR(s,CSR_CXDA(s))); + } + if (!CSR_TOKINTD(s) || (CSR_LTINTEN(s) && s->tmd.tmd1.ltint)) + s->csr[0] |= 0x0200; /* set TINT */ + + if (count <= 0) + break; + + } + if (start_addr) { + start_tmd.tmd2.buff = start_tmd.tmd2.uflo = start_tmd.tmd1.err = 1; + TMDSTORE(&start_tmd, PHYSADDR(s,start_addr)); s->csr[0] |= 0x0200; /* set TINT */ if (!CSR_DXSUFLO(s)) { s->csr[0] &= ~0x0010; - } else - if (count--) - goto txagain; + } } } diff --git a/tools/ioemu/hw/pcnet.h b/tools/ioemu/hw/pcnet.h index f9760b9287..7c60098aa0 100644 --- a/tools/ioemu/hw/pcnet.h +++ b/tools/ioemu/hw/pcnet.h @@ -177,6 +177,26 @@ struct pcnet_RMD { } rmd3; }; +typedef struct PCNetState_st PCNetState; + +struct PCNetState_st { + PCIDevice dev; + NetDriverState *nd; + int mmio_io_addr, rap, isr, lnkst; + target_phys_addr_t rdra, tdra; + uint8_t prom[16]; + uint16_t csr[128]; + uint16_t bcr[32]; + uint64_t timer; + int recv_pos; + uint8_t tx_buffer[2048]; + uint8_t rx_buffer[2048]; + struct pcnet_TMD tmd; + struct pcnet_RMD crmd; + struct pcnet_RMD nrmd; + struct pcnet_RMD nnrmd; +}; + #define PRINT_TMD(T) printf( \ "TMD0 : TBADR=0x%08x\n" \ @@ -230,18 +250,17 @@ static inline void pcnet_tmd_load(PCNetState *s, struct pcnet_TMD *tmd, target_p cpu_physical_memory_read(addr+4, (void *)&tmd->tmd1, 4); cpu_physical_memory_read(addr, (void *)&tmd->tmd0, 4); } else { - uint32_t xda[4]; - cpu_physical_memory_read(addr, - (void *)&xda[0], sizeof(xda)); - ((uint32_t *)tmd)[0] = xda[2]; - ((uint32_t *)tmd)[1] = xda[1]; - ((uint32_t *)tmd)[2] = xda[0]; - ((uint32_t *)tmd)[3] = xda[3]; + uint32_t xda[2]; + cpu_physical_memory_read(addr+4, (void *)&xda[0], sizeof(xda)); + ((uint32_t *)tmd)[0] = xda[1]; + ((uint32_t *)tmd)[1] = xda[0]; + ((uint32_t *)tmd)[2] = 0; } } static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, target_phys_addr_t addr) { + tmd->tmd1.own = 0; cpu_physical_memory_set_dirty(addr); if (!BCR_SWSTYLE(s)) { uint16_t xda[4]; @@ -259,13 +278,10 @@ static inline void pcnet_tmd_store(PCNetState *s, struct pcnet_TMD *tmd, target_ cpu_physical_memory_write(addr+8, (void *)&tmd->tmd2, 4); cpu_physical_memory_write(addr+4, (void *)&tmd->tmd1, 4); } else { - uint32_t xda[4]; + uint32_t xda[2]; xda[0] = ((uint32_t *)tmd)[2]; xda[1] = ((uint32_t *)tmd)[1]; - xda[2] = ((uint32_t *)tmd)[0]; - xda[3] = ((uint32_t *)tmd)[3]; - cpu_physical_memory_write(addr, - (void *)&xda[0], sizeof(xda)); + cpu_physical_memory_write(addr, (void *)&xda[0], sizeof(xda)); } cpu_physical_memory_set_dirty(addr+15); } @@ -286,22 +302,21 @@ static inline void pcnet_rmd_load(PCNetState *s, struct pcnet_RMD *rmd, target_p } else if (BCR_SWSTYLE(s) != 3) { - rmd->rmd2.zeros = 0; + ((uint32_t *)rmd)[2] = 0; cpu_physical_memory_read(addr+4, (void *)&rmd->rmd1, 4); cpu_physical_memory_read(addr, (void *)&rmd->rmd0, 4); } else { - uint32_t rda[4]; - cpu_physical_memory_read(addr, - (void *)&rda[0], sizeof(rda)); - ((uint32_t *)rmd)[0] = rda[2]; - ((uint32_t *)rmd)[1] = rda[1]; - ((uint32_t *)rmd)[2] = rda[0]; - ((uint32_t *)rmd)[3] = rda[3]; + uint32_t rda[2]; + cpu_physical_memory_read(addr+4, (void *)&rda[0], sizeof(rda)); + ((uint32_t *)rmd)[0] = rda[1]; + ((uint32_t *)rmd)[1] = rda[0]; + ((uint32_t *)rmd)[2] = 0; } } static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_phys_addr_t addr) { + rmd->rmd1.own = 0; cpu_physical_memory_set_dirty(addr); if (!BCR_SWSTYLE(s)) { uint16_t rda[4]; \ @@ -319,13 +334,10 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_ cpu_physical_memory_write(addr+8, (void *)&rmd->rmd2, 4); cpu_physical_memory_write(addr+4, (void *)&rmd->rmd1, 4); } else { - uint32_t rda[4]; + uint32_t rda[2]; rda[0] = ((uint32_t *)rmd)[2]; rda[1] = ((uint32_t *)rmd)[1]; - rda[2] = ((uint32_t *)rmd)[0]; - rda[3] = ((uint32_t *)rmd)[3]; - cpu_physical_memory_write(addr, - (void *)&rda[0], sizeof(rda)); + cpu_physical_memory_write(addr, (void *)&rda[0], sizeof(rda)); } cpu_physical_memory_set_dirty(addr+15); } @@ -340,79 +352,16 @@ static inline void pcnet_rmd_store(PCNetState *s, struct pcnet_RMD *rmd, target_ #define RMDSTORE(RMD,ADDR) pcnet_rmd_store(s,RMD,ADDR) -#if 1 - -#define CHECK_RMD(ADDR,RES) do { \ - struct pcnet_RMD rmd; \ - RMDLOAD(&rmd,(ADDR)); \ - (RES) |= (rmd.rmd1.ones != 15); \ +#define CHECK_RMD(RMD,ADDR,RES) do { \ + RMDLOAD((RMD),(ADDR)); \ + (RES) |= ((RMD)->rmd1.ones != 15); \ } while (0) -#define CHECK_TMD(ADDR,RES) do { \ - struct pcnet_TMD tmd; \ - TMDLOAD(&tmd,(ADDR)); \ - (RES) |= (tmd.tmd1.ones != 15); \ +#define CHECK_TMD(ADDR,RES) do { \ + TMDLOAD(&(s->tmd),(ADDR)); \ + (RES) |= (s->tmd.tmd1.ones != 15); \ } while (0) -#else - -#define CHECK_RMD(ADDR,RES) do { \ - switch (BCR_SWSTYLE(s)) { \ - case 0x00: \ - do { \ - uint16_t rda[4]; \ - cpu_physical_memory_read((ADDR), \ - (void *)&rda[0], sizeof(rda)); \ - (RES) |= (rda[2] & 0xf000)!=0xf000; \ - (RES) |= (rda[3] & 0xf000)!=0x0000; \ - } while (0); \ - break; \ - case 0x01: \ - case 0x02: \ - do { \ - uint32_t rda[4]; \ - cpu_physical_memory_read((ADDR), \ - (void *)&rda[0], sizeof(rda)); \ - (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \ - (RES) |= (rda[2] & 0x0000f000L)!=0x00000000L; \ - } while (0); \ - break; \ - case 0x03: \ - do { \ - uint32_t rda[4]; \ - cpu_physical_memory_read((ADDR), \ - (void *)&rda[0], sizeof(rda)); \ - (RES) |= (rda[0] & 0x0000f000L)!=0x00000000L; \ - (RES) |= (rda[1] & 0x0000f000L)!=0x0000f000L; \ - } while (0); \ - break; \ - } \ -} while (0) - -#define CHECK_TMD(ADDR,RES) do { \ - switch (BCR_SWSTYLE(s)) { \ - case 0x00: \ - do { \ - uint16_t xda[4]; \ - cpu_physical_memory_read((ADDR), \ - (void *)&xda[0], sizeof(xda)); \ - (RES) |= (xda[2] & 0xf000)!=0xf000;\ - } while (0); \ - break; \ - case 0x01: \ - case 0x02: \ - case 0x03: \ - do { \ - uint32_t xda[4]; \ - cpu_physical_memory_read((ADDR), \ - (void *)&xda[0], sizeof(xda)); \ - (RES) |= (xda[1] & 0x0000f000L)!=0x0000f000L; \ - } while (0); \ - break; \ - } \ -} while (0) - -#endif #define PRINT_PKTHDR(BUF) do { \ struct ether_header *hdr = (void *)(BUF); \ diff --git a/tools/libxc/Makefile b/tools/libxc/Makefile index 67cdf207f1..cbe5855a1d 100644 --- a/tools/libxc/Makefile +++ b/tools/libxc/Makefile @@ -21,16 +21,12 @@ SRCS += xc_private.c SRCS += xc_sedf.c SRCS += xc_tbuf.c -ifeq ($(XEN_TARGET_ARCH),x86_32) +ifeq ($(patsubst x86%,x86,$(XEN_TARGET_ARCH)),x86) SRCS += xc_ptrace.c SRCS += xc_ptrace_core.c SRCS += xc_pagetab.c endif -ifeq ($(XEN_TARGET_ARCH),x86_64) -SRCS += xc_pagetab.c -endif - BUILD_SRCS := BUILD_SRCS += xc_linux_build.c BUILD_SRCS += xc_load_bin.c diff --git a/tools/libxc/xc_ptrace.c b/tools/libxc/xc_ptrace.c index f3144c7c80..715cb73b39 100644 --- a/tools/libxc/xc_ptrace.c +++ b/tools/libxc/xc_ptrace.c @@ -38,9 +38,6 @@ static char *ptrace_names[] = { }; #endif -/* XXX application state */ -static long nr_pages = 0; -static unsigned long *page_array = NULL; static int current_domid = -1; static int current_isfile; @@ -196,6 +193,60 @@ map_domain_va_pae( return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1))); } +#ifdef __x86_64__ +static void * +map_domain_va( + int xc_handle, + int cpu, + void *guest_va, + int perm) +{ + unsigned long l3p, l2p, l1p, p, va = (unsigned long)guest_va; + uint64_t *l4, *l3, *l2, *l1; + static void *v; + + if ((ctxt[cpu].ctrlreg[4] & 0x20) == 0 ) /* legacy ia32 mode */ + return map_domain_va_pae(xc_handle, cpu, guest_va, perm); + + if (fetch_regs(xc_handle, cpu, NULL)) + return NULL; + + l4 = xc_map_foreign_range( + xc_handle, current_domid, PAGE_SIZE, PROT_READ, ctxt[cpu].ctrlreg[3] >> PAGE_SHIFT); + if ( l4 == NULL ) + return NULL; + + l3p = l4[l4_table_offset(va)] >> PAGE_SHIFT; + l3 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l3p); + if ( l3 == NULL ) + return NULL; + + l2p = l3[l3_table_offset(va)] >> PAGE_SHIFT; + l2 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, PROT_READ, l2p); + if ( l2 == NULL ) + return NULL; + + l1p = l2[l2_table_offset(va)] >> PAGE_SHIFT; + l1 = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, l1p); + if ( l1 == NULL ) + return NULL; + + p = l1[l1_table_offset(va)] >> PAGE_SHIFT; + if ( v != NULL ) + munmap(v, PAGE_SIZE); + v = xc_map_foreign_range(xc_handle, current_domid, PAGE_SIZE, perm, p); + if ( v == NULL ) + return NULL; + + return (void *)((unsigned long)v | (va & (PAGE_SIZE - 1))); +} +#endif + +#ifdef __i386__ +/* XXX application state */ +static long nr_pages = 0; +static unsigned long *page_array = NULL; + static void * map_domain_va( int xc_handle, @@ -216,15 +267,18 @@ map_domain_va( static unsigned long page_phys[MAX_VIRT_CPUS]; static unsigned long *page_virt[MAX_VIRT_CPUS]; static int prev_perm[MAX_VIRT_CPUS]; - static enum { MODE_UNKNOWN, MODE_32, MODE_PAE } mode; + static enum { MODE_UNKNOWN, MODE_32, MODE_PAE, MODE_64 } mode; if ( mode == MODE_UNKNOWN ) { xen_capabilities_info_t caps; (void)xc_version(xc_handle, XENVER_capabilities, caps); - mode = MODE_32; - if ( strstr(caps, "_x86_32p") ) + if ( strstr(caps, "-x86_64") ) + mode = MODE_64; + else if ( strstr(caps, "-x86_32p") ) mode = MODE_PAE; + else if ( strstr(caps, "-x86_32") ) + mode = MODE_32; } if ( mode == MODE_PAE ) @@ -304,6 +358,8 @@ map_domain_va( return (void *)(((unsigned long)page_virt[cpu]) | (va & BSD_PAGE_MASK)); } +#endif + static int __xc_waitdomain( int xc_handle, diff --git a/tools/libxc/xc_ptrace.h b/tools/libxc/xc_ptrace.h index d959ecaab8..2119d9c984 100644 --- a/tools/libxc/xc_ptrace.h +++ b/tools/libxc/xc_ptrace.h @@ -10,6 +10,96 @@ #define PDRSHIFT 22 #define PSL_T 0x00000100 /* trace enable bit */ +#ifdef __x86_64__ +struct gdb_regs +{ + unsigned long r15; + unsigned long r14; + unsigned long r13; + unsigned long r12; + unsigned long rbp; + unsigned long rbx; + unsigned long r11; + unsigned long r10; + unsigned long r9; + unsigned long r8; + unsigned long rax; + unsigned long rcx; + unsigned long rdx; + unsigned long rsi; + unsigned long rdi; + unsigned long orig_rax; + unsigned long rip; + unsigned long xcs; + unsigned long eflags; + unsigned long rsp; + unsigned long xss; + unsigned long fs_base; + unsigned long gs_base; + unsigned long xds; + unsigned long xes; + unsigned long xfs; + unsigned long xgs; +}; + +#define SET_PT_REGS(pt, xc) \ +{ \ + pt.r8 = xc.r8; \ + pt.r9 = xc.r9; \ + pt.r10 = xc.r10; \ + pt.r11 = xc.r11; \ + pt.r12 = xc.r12; \ + pt.r13 = xc.r13; \ + pt.r14 = xc.r14; \ + pt.r15 = xc.r15; \ + pt.rbx = xc.rbx; \ + pt.rcx = xc.rcx; \ + pt.rdx = xc.rdx; \ + pt.rsi = xc.rsi; \ + pt.rdi = xc.rdi; \ + pt.rbp = xc.rbp; \ + pt.rax = xc.rax; \ + pt.rip = xc.rip; \ + pt.xcs = xc.cs; \ + pt.eflags = xc.eflags; \ + pt.rsp = xc.rsp; \ + pt.xss = xc.ss; \ + pt.xes = xc.es; \ + pt.xds = xc.ds; \ + pt.xfs = xc.fs; \ + pt.xgs = xc.gs; \ +} + +#define SET_XC_REGS(pt, xc) \ +{ \ + xc.r8 = pt->r8; \ + xc.r9 = pt->r9; \ + xc.r10 = pt->r10; \ + xc.r11 = pt->r11; \ + xc.r12 = pt->r12; \ + xc.r13 = pt->r13; \ + xc.r14 = pt->r14; \ + xc.r15 = pt->r15; \ + xc.rbx = pt->rbx; \ + xc.rcx = pt->rcx; \ + xc.rdx = pt->rdx; \ + xc.rsi = pt->rsi; \ + xc.rdi = pt->rdi; \ + xc.rbp = pt->rbp; \ + xc.rax = pt->rax; \ + xc.rip = pt->rip; \ + xc.cs = pt->xcs; \ + xc.eflags = pt->eflags; \ + xc.rsp = pt->rsp; \ + xc.ss = pt->xss; \ + xc.es = pt->xes; \ + xc.ds = pt->xds; \ + xc.fs = pt->xfs; \ + xc.gs = pt->xgs; \ +} + +#elif __i386__ + struct gdb_regs { long ebx; /* 0 */ long ecx; /* 4 */ @@ -30,8 +120,6 @@ struct gdb_regs { int xss; /* 64 */ }; - -#define printval(x) printf("%s = %lx\n", #x, (long)x); #define SET_PT_REGS(pt, xc) \ { \ pt.ebx = xc.ebx; \ @@ -71,7 +159,9 @@ struct gdb_regs { xc.fs = pt->xfs; \ xc.gs = pt->xgs; \ } +#endif +#define printval(x) printf("%s = %lx\n", #x, (long)x); #define vtopdi(va) ((va) >> PDRSHIFT) #define vtopti(va) (((va) >> PAGE_SHIFT) & 0x3ff) #endif diff --git a/tools/python/xen/xend/XendError.py b/tools/python/xen/xend/XendError.py index efe7fe5e32..f78a71f031 100644 --- a/tools/python/xen/xend/XendError.py +++ b/tools/python/xen/xend/XendError.py @@ -19,6 +19,10 @@ from xmlrpclib import Fault import XendClient +class XendInvalidDomain(Fault): + def __init__(self, value): + Fault.__init__(self, XendClient.ERROR_INVALID_DOMAIN, value) + class XendError(Fault): def __init__(self, value): diff --git a/tools/python/xen/xend/server/XMLRPCServer.py b/tools/python/xen/xend/server/XMLRPCServer.py index 1e553a84e3..7d03cfb3dc 100644 --- a/tools/python/xen/xend/server/XMLRPCServer.py +++ b/tools/python/xen/xend/server/XMLRPCServer.py @@ -23,35 +23,21 @@ from xen.xend import XendDomain, XendDomainInfo, XendNode, \ from xen.util.xmlrpclib2 import UnixXMLRPCServer, TCPXMLRPCServer from xen.xend.XendClient import XML_RPC_SOCKET, ERROR_INVALID_DOMAIN +from xen.xend.XendError import * def lookup(domid): - try: - return XendDomain.instance().domain_lookup_by_name_or_id(domid) - except exn: - log.exception(exn) - raise exn + info = XendDomain.instance().domain_lookup_by_name_or_id(domid) + if not info: + raise XendInvalidDomain(str(domid)) + return info def dispatch(domid, fn, args): info = lookup(domid) - if info: - try: - return getattr(info, fn)(*args) - except exn: - log.exception(exn) - raise exn - else: - raise xmlrpclib.Fault(ERROR_INVALID_DOMAIN, domid) + return getattr(info, fn)(*args) def domain(domid): info = lookup(domid) - if info: - try: - return info.sxpr() - except exn: - log.exception(exn) - raise exn - else: - raise xmlrpclib.Fault(ERROR_INVALID_DOMAIN, domid) + return info.sxpr() def domains(detail=1): if detail < 1: @@ -90,7 +76,7 @@ class XMLRPCServer: if self.use_tcp: # bind to something fixed for now as we may eliminate # tcp support completely. - self.server = TCPXMLRPCServer(("localhost", 8005, False)) + self.server = TCPXMLRPCServer(("localhost", 8005), logRequests=False) else: self.server = UnixXMLRPCServer(XML_RPC_SOCKET, False) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 6bb09b29f6..a636dd5e84 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -1102,12 +1102,6 @@ def main(argv=sys.argv): else: err("Error connecting to xend: %s." % ex[1]) sys.exit(1) - except xmlrpclib.ProtocolError, ex: - if os.geteuid() != 0: - err("Most commands need root access. Please try again as root.") - else: - err("Error connecting to xend: %s." % ex.errmsg) - sys.exit(1) except SystemExit: sys.exit(1) except xmlrpclib.Fault, ex: diff --git a/tools/xentrace/Makefile b/tools/xentrace/Makefile index 1d66129c8d..b02a39b18e 100644 --- a/tools/xentrace/Makefile +++ b/tools/xentrace/Makefile @@ -6,7 +6,7 @@ INSTALL_DATA = $(INSTALL) -m0644 XEN_ROOT=../.. include $(XEN_ROOT)/tools/Rules.mk -CFLAGS += -Werror +CFLAGS += -Werror -D_LARGEFILE64_SOURCE CFLAGS += -I $(XEN_XC) CFLAGS += -I $(XEN_LIBXC) diff --git a/tools/xentrace/formats b/tools/xentrace/formats index 818eef1c60..96ba53212c 100644 --- a/tools/xentrace/formats +++ b/tools/xentrace/formats @@ -16,6 +16,6 @@ 0x00080002 CPU%(cpu)d %(tsc)d VMX_VECTOR [ domid = 0x%(1)08x, eip = 0x%(2)08x, vector = 0x%(3)08x ] 0x00080003 CPU%(cpu)d %(tsc)d VMX_INT [ domid = 0x%(1)08x, trap = 0x%(2)08x, va = 0x%(3)08x ] -0x00090001 CPU%(cpu)d %(tsc)d VMENTRY 0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x -0x00090002 CPU%(cpu)d %(tsc)d VMEXIT 0x%(1)08x 0x%(2)08x 0x%(3)08x +0x00081001 CPU%(cpu)d %(tsc)d VMEXIT 0x%(1)08x 0x%(2)08x 0x%(3)08x +0x00081002 CPU%(cpu)d %(tsc)d VMENTRY 0x%(1)08x 0x%(2)08x 0x%(3)08x 0x%(4)08x 0x%(5)08x diff --git a/tools/xentrace/xentrace.c b/tools/xentrace/xentrace.c index 34b2a6a649..ee320c31dc 100644 --- a/tools/xentrace/xentrace.c +++ b/tools/xentrace/xentrace.c @@ -498,7 +498,7 @@ int main(int argc, char **argv) } if ( opts.outfile ) - outfd = open(opts.outfile, O_WRONLY | O_CREAT); + outfd = open(opts.outfile, O_WRONLY | O_CREAT | O_LARGEFILE, 0644); if(outfd < 0) { diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 22a5bcb418..ea4138f856 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -728,6 +728,8 @@ static void svm_relinquish_guest_resources(struct domain *d) for_each_vcpu ( d, v ) { + if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + continue; #if 0 /* Memory leak by not freeing this. XXXKAF: *Why* is not per core?? */ free_host_save_area(v->arch.hvm_svm.host_save_area); diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 69af5901dc..9e146477cc 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -89,6 +89,8 @@ static void vmx_relinquish_guest_resources(struct domain *d) for_each_vcpu ( d, v ) { + if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + continue; vmx_request_clear_vmcs(v); destroy_vmcs(&v->arch.hvm_vmx); free_monitor_pagetable(v); @@ -988,7 +990,7 @@ static void vmx_io_instruction(struct cpu_user_regs *regs, port = (exit_qualification >> 16) & 0xFFFF; else port = regs->edx & 0xffff; - TRACE_VMEXIT(2, port); + TRACE_VMEXIT(1, port); size = (exit_qualification & 7) + 1; dir = test_bit(3, &exit_qualification); /* direction */ @@ -1913,6 +1915,7 @@ static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs) vector &= 0xff; local_irq_disable(); + TRACE_VMEXIT(1,vector); switch(vector) { case LOCAL_TIMER_VECTOR: @@ -2042,7 +2045,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) { __vmread(GUEST_RIP, &eip); - TRACE_3D(TRC_VMX_VMEXIT, v->domain->domain_id, eip, exit_reason); TRACE_VMEXIT(0,exit_reason); } @@ -2066,7 +2068,6 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs regs) TRACE_VMEXIT(1,vector); perfc_incra(cause_vector, vector); - TRACE_3D(TRC_VMX_VECTOR, v->domain->domain_id, eip, vector); switch (vector) { #ifdef XEN_DEBUGGER case TRAP_debug: @@ -2250,7 +2251,7 @@ asmlinkage void vmx_load_cr2(void) asmlinkage void vmx_trace_vmentry (void) { - TRACE_5D(TRC_VMENTRY, + TRACE_5D(TRC_VMX_VMENTRY, trace_values[smp_processor_id()][0], trace_values[smp_processor_id()][1], trace_values[smp_processor_id()][2], @@ -2266,7 +2267,7 @@ asmlinkage void vmx_trace_vmentry (void) asmlinkage void vmx_trace_vmexit (void) { - TRACE_3D(TRC_VMEXIT,0,0,0); + TRACE_3D(TRC_VMX_VMEXIT,0,0,0); return; } diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 54b1a52184..4977a6d2da 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3351,8 +3351,9 @@ int ptwr_do_page_fault(struct domain *d, unsigned long addr, * permissions in page directories by writing back to the linear mapping. */ if ( (flags = l1e_get_flags(pte) & WRPT_PTE_FLAGS) == WRPT_PTE_FLAGS ) - return !__put_user( - pte.l1, &linear_pg_table[l1_linear_offset(addr)].l1); + return __put_user( + pte.l1, &linear_pg_table[l1_linear_offset(addr)].l1) ? + 0 : EXCRET_not_a_fault; /* We are looking only for read-only mappings of p.t. pages. */ if ( ((flags | _PAGE_RW) != WRPT_PTE_FLAGS) || diff --git a/xen/arch/x86/shadow.c b/xen/arch/x86/shadow.c index 1f312a4fdb..8eacde9735 100644 --- a/xen/arch/x86/shadow.c +++ b/xen/arch/x86/shadow.c @@ -1807,6 +1807,16 @@ static int resync_all(struct domain *d, u32 stype) entry_has_changed( guest_pt[i], snapshot_pt[i], PAGE_FLAG_MASK) ) { + + unsigned long gpfn; + + gpfn = entry_get_pfn(guest_pt[i]); + /* + * Looks like it's longer a page table. + */ + if ( unlikely(gpfn != (gpfn & PGT_mfn_mask)) ) + continue; + need_flush |= validate_entry_change( d, &guest_pt[i], &shadow_pt[i], shadow_type_to_level(stype)); @@ -1851,6 +1861,14 @@ static int resync_all(struct domain *d, u32 stype) { #ifndef GUEST_PGENTRY_32 l4_pgentry_t *shadow4 = shadow; + unsigned long gpfn; + + gpfn = l4e_get_pfn(new_root_e); + /* + * Looks like it's longer a page table. + */ + if ( unlikely(gpfn != (gpfn & PGT_mfn_mask)) ) + continue; if ( d->arch.ops->guest_paging_levels == PAGING_L4 ) { @@ -1894,7 +1912,7 @@ static int resync_all(struct domain *d, u32 stype) unmap_domain_page(snapshot); unmap_domain_page(guest); - if ( unlikely(unshadow) ) + if ( unlikely(unshadow && stype == PGT_root_page_table) ) { for_each_vcpu(d, v) if(smfn == pagetable_get_pfn(v->arch.shadow_table)) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 17e1e80072..95e44db6d9 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -620,6 +620,46 @@ static int fixup_page_fault(unsigned long addr, struct cpu_user_regs *regs) return 0; } +static int spurious_page_fault(unsigned long addr, struct cpu_user_regs *regs) +{ + struct vcpu *v = current; + struct domain *d = v->domain; + int rc; + + /* + * The only possible reason for a spurious page fault not to be picked + * up already is that a page directory was unhooked by writable page table + * logic and then reattached before the faulting VCPU could detect it. + */ + if ( is_idle_domain(d) || /* no ptwr in idle domain */ + IN_HYPERVISOR_RANGE(addr) || /* no ptwr on hypervisor addrs */ + shadow_mode_enabled(d) || /* no ptwr logic in shadow mode */ + ((regs->error_code & 0x1d) != 0) ) /* simple not-present fault? */ + return 0; + + LOCK_BIGLOCK(d); + + /* + * The page directory could have been detached again while we weren't + * holding the per-domain lock. Detect that and fix up if it's the case. + */ + if ( unlikely(d->arch.ptwr[PTWR_PT_ACTIVE].l1va) && + unlikely(l2_linear_offset(addr) == + d->arch.ptwr[PTWR_PT_ACTIVE].l2_idx) ) + { + ptwr_flush(d, PTWR_PT_ACTIVE); + rc = 1; + } + else + { + /* Okay, walk the page tables. Only check for not-present faults.*/ + rc = __spurious_page_fault(addr); + } + + UNLOCK_BIGLOCK(d); + return rc; +} + /* * #PF error code: * Bit 0: Protection violation (=1) ; Page not present (=0) @@ -644,6 +684,13 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs) if ( unlikely(!guest_mode(regs)) ) { + if ( spurious_page_fault(addr, regs) ) + { + DPRINTK("Spurious fault in domain %u:%u at addr %lx\n", + current->domain->domain_id, current->vcpu_id, addr); + return EXCRET_not_a_fault; + } + if ( likely((fixup = search_exception_table(regs->eip)) != 0) ) { perfc_incrc(copy_user_faults); @@ -658,7 +705,7 @@ asmlinkage int do_page_fault(struct cpu_user_regs *regs) panic("CPU%d FATAL PAGE FAULT\n" "[error_code=%04x]\n" "Faulting linear address: %p\n", - smp_processor_id(), regs->error_code, addr); + smp_processor_id(), regs->error_code, _p(addr)); } propagate_page_fault(addr, regs->error_code); diff --git a/xen/arch/x86/x86_32/traps.c b/xen/arch/x86/x86_32/traps.c index 1c570dad29..1c5daca90d 100644 --- a/xen/arch/x86/x86_32/traps.c +++ b/xen/arch/x86/x86_32/traps.c @@ -70,38 +70,77 @@ void show_registers(struct cpu_user_regs *regs) void show_page_walk(unsigned long addr) { - unsigned long mfn = read_cr3() >> PAGE_SHIFT; - intpte_t *ptab, ent; - unsigned long pfn; + unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT; +#ifdef CONFIG_X86_PAE + l3_pgentry_t l3e, *l3t; +#endif + l2_pgentry_t l2e, *l2t; + l1_pgentry_t l1e, *l1t; printk("Pagetable walk from %08lx:\n", addr); #ifdef CONFIG_X86_PAE - ptab = map_domain_page(mfn); - ent = ptab[l3_table_offset(addr)]; - pfn = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT)); - printk(" L3 = %"PRIpte" %08lx\n", ent, pfn); - unmap_domain_page(ptab); - if ( !(ent & _PAGE_PRESENT) ) + l3t = map_domain_page(mfn); + l3e = l3t[l3_table_offset(addr)]; + mfn = l3e_get_pfn(l3e); + pfn = get_gpfn_from_mfn(mfn); + printk(" L3 = %"PRIpte" %08lx\n", l3e_get_intpte(l3e), pfn); + unmap_domain_page(l3t); + if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) return; - mfn = ent >> PAGE_SHIFT; #endif - ptab = map_domain_page(mfn); - ent = ptab[l2_table_offset(addr)]; - pfn = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT)); - printk(" L2 = %"PRIpte" %08lx %s\n", ent, pfn, - (ent & _PAGE_PSE) ? "(PSE)" : ""); - unmap_domain_page(ptab); - if ( !(ent & _PAGE_PRESENT) || (ent & _PAGE_PSE) ) + l2t = map_domain_page(mfn); + l2e = l2t[l2_table_offset(addr)]; + mfn = l2e_get_pfn(l2e); + pfn = get_gpfn_from_mfn(mfn); + printk(" L2 = %"PRIpte" %08lx %s\n", l2e_get_intpte(l2e), pfn, + (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : ""); + unmap_domain_page(l2t); + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) || + (l2e_get_flags(l2e) & _PAGE_PSE) ) return; - mfn = ent >> PAGE_SHIFT; - ptab = map_domain_page(ent >> PAGE_SHIFT); - ent = ptab[l1_table_offset(addr)]; - pfn = get_gpfn_from_mfn((u32)(ent >> PAGE_SHIFT)); - printk(" L1 = %"PRIpte" %08lx\n", ent, pfn); - unmap_domain_page(ptab); + l1t = map_domain_page(mfn); + l1e = l1t[l1_table_offset(addr)]; + mfn = l1e_get_pfn(l1e); + pfn = get_gpfn_from_mfn(mfn); + printk(" L1 = %"PRIpte" %08lx\n", l1e_get_intpte(l1e), pfn); + unmap_domain_page(l1t); +} + +int __spurious_page_fault(unsigned long addr) +{ + unsigned long mfn = read_cr3() >> PAGE_SHIFT; +#ifdef CONFIG_X86_PAE + l3_pgentry_t l3e, *l3t; +#endif + l2_pgentry_t l2e, *l2t; + l1_pgentry_t l1e, *l1t; + +#ifdef CONFIG_X86_PAE + l3t = map_domain_page(mfn); + l3e = l3t[l3_table_offset(addr)]; + mfn = l3e_get_pfn(l3e); + unmap_domain_page(l3t); + if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) + return 0; +#endif + + l2t = map_domain_page(mfn); + l2e = l2t[l2_table_offset(addr)]; + mfn = l2e_get_pfn(l2e); + unmap_domain_page(l2t); + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) + return 0; + if ( l2e_get_flags(l2e) & _PAGE_PSE ) + return 1; + + l1t = map_domain_page(mfn); + l1e = l1t[l1_table_offset(addr)]; + mfn = l1e_get_pfn(l1e); + unmap_domain_page(l1t); + return !!(l1e_get_flags(l1e) & _PAGE_PRESENT); } #define DOUBLEFAULT_STACK_SIZE 1024 diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index e78c8f9453..46835570c4 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -70,31 +70,79 @@ void show_registers(struct cpu_user_regs *regs) void show_page_walk(unsigned long addr) { - unsigned long page = read_cr3(); - + unsigned long pfn, mfn = read_cr3() >> PAGE_SHIFT; + l4_pgentry_t l4e, *l4t; + l3_pgentry_t l3e, *l3t; + l2_pgentry_t l2e, *l2t; + l1_pgentry_t l1e, *l1t; + printk("Pagetable walk from %016lx:\n", addr); - page &= PAGE_MASK; - page = ((unsigned long *) __va(page))[l4_table_offset(addr)]; - printk(" L4 = %016lx\n", page); - if ( !(page & _PAGE_PRESENT) ) + l4t = mfn_to_virt(mfn); + l4e = l4t[l4_table_offset(addr)]; + mfn = l4e_get_pfn(l4e); + pfn = get_gpfn_from_mfn(mfn); + printk(" L4 = %"PRIpte" %016lx\n", l4e_get_intpte(l4e), pfn); + if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) ) return; - page &= PAGE_MASK; - page = ((unsigned long *) __va(page))[l3_table_offset(addr)]; - printk(" L3 = %016lx\n", page); - if ( !(page & _PAGE_PRESENT) ) + l3t = mfn_to_virt(mfn); + l3e = l3t[l3_table_offset(addr)]; + mfn = l3e_get_pfn(l3e); + pfn = get_gpfn_from_mfn(mfn); + printk(" L3 = %"PRIpte" %016lx\n", l3e_get_intpte(l3e), pfn); + if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) return; - page &= PAGE_MASK; - page = ((unsigned long *) __va(page))[l2_table_offset(addr)]; - printk(" L2 = %016lx %s\n", page, (page & _PAGE_PSE) ? "(2MB)" : ""); - if ( !(page & _PAGE_PRESENT) || (page & _PAGE_PSE) ) + l2t = mfn_to_virt(mfn); + l2e = l2t[l2_table_offset(addr)]; + mfn = l2e_get_pfn(l2e); + pfn = get_gpfn_from_mfn(mfn); + printk(" L2 = %"PRIpte" %016lx %s\n", l2e_get_intpte(l2e), pfn, + (l2e_get_flags(l2e) & _PAGE_PSE) ? "(PSE)" : ""); + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) || + (l2e_get_flags(l2e) & _PAGE_PSE) ) return; - page &= PAGE_MASK; - page = ((unsigned long *) __va(page))[l1_table_offset(addr)]; - printk(" L1 = %016lx\n", page); + l1t = mfn_to_virt(mfn); + l1e = l1t[l1_table_offset(addr)]; + mfn = l1e_get_pfn(l1e); + pfn = get_gpfn_from_mfn(mfn); + printk(" L1 = %"PRIpte" %016lx\n", l1e_get_intpte(l1e), pfn); +} + +int __spurious_page_fault(unsigned long addr) +{ + unsigned long mfn = read_cr3() >> PAGE_SHIFT; + l4_pgentry_t l4e, *l4t; + l3_pgentry_t l3e, *l3t; + l2_pgentry_t l2e, *l2t; + l1_pgentry_t l1e, *l1t; + + l4t = mfn_to_virt(mfn); + l4e = l4t[l4_table_offset(addr)]; + mfn = l4e_get_pfn(l4e); + if ( !(l4e_get_flags(l4e) & _PAGE_PRESENT) ) + return 0; + + l3t = mfn_to_virt(mfn); + l3e = l3t[l3_table_offset(addr)]; + mfn = l3e_get_pfn(l3e); + if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) + return 0; + + l2t = mfn_to_virt(mfn); + l2e = l2t[l2_table_offset(addr)]; + mfn = l2e_get_pfn(l2e); + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) + return 0; + if ( l2e_get_flags(l2e) & _PAGE_PSE ) + return 1; + + l1t = mfn_to_virt(mfn); + l1e = l1t[l1_table_offset(addr)]; + mfn = l1e_get_pfn(l1e); + return !!(l1e_get_flags(l1e) & _PAGE_PRESENT); } asmlinkage void double_fault(void); diff --git a/xen/common/page_alloc.c b/xen/common/page_alloc.c index f594a7fe40..4dff2f3679 100644 --- a/xen/common/page_alloc.c +++ b/xen/common/page_alloc.c @@ -219,8 +219,6 @@ unsigned long alloc_boot_pages(unsigned long nr_pfns, unsigned long pfn_align) #define pfn_dom_zone_type(_pfn) \ (((_pfn) <= MAX_DMADOM_PFN) ? MEMZONE_DMADOM : MEMZONE_DOM) -/* Up to 2^20 pages can be allocated at once. */ -#define MAX_ORDER 20 static struct list_head heap[NR_ZONES][MAX_ORDER+1]; static unsigned long avail[NR_ZONES]; diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index de4232f5bd..2cda6c15f5 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -524,6 +524,7 @@ extern always_inline void prefetchw(const void *x) void show_stack(struct cpu_user_regs *regs); void show_registers(struct cpu_user_regs *regs); void show_page_walk(unsigned long addr); +int __spurious_page_fault(unsigned long addr); asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs); extern void mtrr_ap_init(void); diff --git a/xen/include/public/trace.h b/xen/include/public/trace.h index cba4b261ca..8fc009dfeb 100644 --- a/xen/include/public/trace.h +++ b/xen/include/public/trace.h @@ -24,7 +24,6 @@ #define TRC_VMXTIMER 0x00082000 /* VMX timer trace */ #define TRC_VMXINT 0x00084000 /* VMX interrupt trace */ #define TRC_VMXIO 0x00088000 /* VMX io emulation trace */ -#define TRC_VMEXIT_HANDLER 0x00090000 /* VMX handler trace */ /* Trace events per class */ @@ -50,15 +49,12 @@ /* trace events per subclass */ #define TRC_VMX_VMEXIT (TRC_VMXEXIT + 1) -#define TRC_VMX_VECTOR (TRC_VMXEXIT + 2) +#define TRC_VMX_VMENTRY (TRC_VMXEXIT + 2) #define TRC_VMX_TIMER_INTR (TRC_VMXTIMER + 1) #define TRC_VMX_INT (TRC_VMXINT + 1) -#define TRC_VMEXIT (TRC_VMEXIT_HANDLER + 1) -#define TRC_VMENTRY (TRC_VMEXIT_HANDLER + 2) - /* This structure represents a single trace buffer record. */ struct t_rec { diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index facfa2b093..8b9253b020 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -47,7 +47,8 @@ extern void debugtrace_printk(const char *fmt, ...); #define printk(_f , _a...) printf( _f , ## _a ) extern void printf(const char *format, ...) __attribute__ ((format (printf, 1, 2))); -extern void panic(const char *format, ...); +extern void panic(const char *format, ...) + __attribute__ ((format (printf, 1, 2))); extern long vm_assist(struct domain *, unsigned int, unsigned int); /* vsprintf.c */ diff --git a/xen/include/xen/mm.h b/xen/include/xen/mm.h index ecd202d8a4..327758f2c2 100644 --- a/xen/include/xen/mm.h +++ b/xen/include/xen/mm.h @@ -68,6 +68,9 @@ unsigned long avail_domheap_pages(void); #define ALLOC_DOM_DMA 1 +/* Up to 2^20 pages can be allocated at once. */ +#define MAX_ORDER 20 + /* Automatic page scrubbing for dead domains. */ extern struct list_head page_scrub_list; #define page_scrub_schedule_work() \