From 3095cdaf509be61190dfe2554ef6aee6bfbb4a4f Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 24 Mar 2006 10:57:52 +0100 Subject: [PATCH 01/19] Update gdb documentation * Kernel isn't 2.6.12 anymore * ARCH=xen isn't needed for make anymore Signed-Off-By: Horms --- tools/debugger/gdb/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 From 7e273af3ec8363a4d961119d0f055ca8d78ba31f Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 24 Mar 2006 10:59:31 +0100 Subject: [PATCH 02/19] This patch is mainly a cleanup of vmx related xentrace code. One minor xentrace bug is fixed. Signed-off-by: Xiaowei Yang Signed-off-by: Yunfeng Zhao --- tools/xentrace/Makefile | 2 +- tools/xentrace/formats | 4 ++-- tools/xentrace/xentrace.c | 2 +- xen/arch/x86/hvm/vmx/vmx.c | 9 ++++----- xen/include/public/trace.h | 6 +----- 5 files changed, 9 insertions(+), 14 deletions(-) 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/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 69af5901dc..1c1a9fb8fa 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -988,7 +988,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 +1913,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 +2043,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 +2066,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 +2249,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 +2265,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/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 { From 1a8bbf93b8f9d10585d3d796fa6dda5eefae15b6 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 24 Mar 2006 12:14:58 +0100 Subject: [PATCH 03/19] Detect spurious faults taken in the hypervisor that are due to writable pagetable logic. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 5 +- xen/arch/x86/traps.c | 47 ++++++++++++++++++ xen/arch/x86/x86_32/traps.c | 85 ++++++++++++++++++++++++--------- xen/arch/x86/x86_64/traps.c | 82 ++++++++++++++++++++++++------- xen/include/asm-x86/processor.h | 1 + 5 files changed, 178 insertions(+), 42 deletions(-) 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/traps.c b/xen/arch/x86/traps.c index 17e1e80072..653786e9e3 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); 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/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); From 3e0dfe69c98490d48b9706ec028756266a6af155 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 24 Mar 2006 12:28:58 +0100 Subject: [PATCH 04/19] Create /var/xen/dump/ during tools installation, or core files are not written even if we set (enable-dump yes) in xend-config.sxp. Signed-off-by: Akio Takebe --- tools/Makefile | 1 + 1 file changed, 1 insertion(+) 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 \ From 76e09e82387ec2eef675ae705348f655586b7bb3 Mon Sep 17 00:00:00 2001 From: "anthony@rhesis.austin.ibm.com" Date: Fri, 24 Mar 2006 14:31:12 +0100 Subject: [PATCH 05/19] 1) Introduce new exception type XendInvalidDomain that maps to the high level XEND_INVALID_DOMAIN faultType. 2) Fix exception logic in XMLRPCServer 3) Fix TCP server 4) Remove catching of ProtocolError in main.py. ProtocolErrors only occur when there is an exception in the exception handling code which shouldn't ever happen. I've reproduced the error cases described by Ewan with xend_domain_setTargetMemory and once I fixed the exception logic, I get a normal faultType of 1 as would be expected. Signed-off-by: Anthony Liguori --- tools/python/xen/xend/XendError.py | 4 +++ tools/python/xen/xend/server/XMLRPCServer.py | 30 ++++++-------------- tools/python/xen/xm/main.py | 6 ---- 3 files changed, 12 insertions(+), 28 deletions(-) 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: From 5ebad7be891d2ca5e57523ecf5c6880b54e84800 Mon Sep 17 00:00:00 2001 From: "harry@localhost.localdomain" Date: Fri, 24 Mar 2006 14:31:20 +0100 Subject: [PATCH 06/19] Fix bug 515 by adding a global lock around the hotplug scripts in the non-udev hotplug case only. There are two possible root causes for 515, both of which are only problems in the non-udev hotplug case because udev uses udevsend which already implements the required serialisation. 1) Script concurrency. 2) Kernel reordering hotplug events. This changeset fixes (1) but not (2). Since (1) is the problem that seems to be happening this is probably OK. A fix for (2) for the hotplug case might be to add extra serialisation using state changes in the store but this would impact all the drivers and the code and extra complexity would be redundant once everyone had moved to udev. This doesn't seem worthwhile unless we actually start to see (2) happening. --- tools/examples/xen-backend.agent | 6 ++++++ 1 file changed, 6 insertions(+) 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 From b0ceb872c7c07e46be74b45ec1cab4d98040dfbc Mon Sep 17 00:00:00 2001 From: "emellor@leeni.uk.xensource.com" Date: Fri, 24 Mar 2006 14:36:14 +0100 Subject: [PATCH 07/19] Switch the default build to make the -xen kernel, not the -xen0 and -xenU kernels. Distros will be using -xen exclusively, so this change means that developers and users of unstable will be (by default) using the same configuration as the distros. This can be overridden by setting KERNELS="linux-2.6-xen0 linux-2.6-xenU" on the command line. Signed-off-by: Ewan Mellor --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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))) ) From 4d2384d45609101b35bc8450f3ebd724d07c6ba4 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Fri, 24 Mar 2006 17:48:03 +0100 Subject: [PATCH 08/19] Added tag 3.0.2-rc for changeset af0573e9e5258db0a9d28aa954dd302ddd2c2d23 --- .hgtags | 1 + 1 file changed, 1 insertion(+) 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 From 9c6543d4af04e8bbbdc879164a60cf86e20553ee Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 26 Mar 2006 11:35:11 +0100 Subject: [PATCH 09/19] Add format printf attribute to panic() prototype and fix the error this catches. Signed-off-by: Jimi Xenidis Signed-off-by: Keir Fraser --- xen/arch/x86/traps.c | 2 +- xen/include/xen/lib.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 653786e9e3..95e44db6d9 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -705,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/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 */ From ac58fadfa5bfd652bd8c85a5e68b11309886d167 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 26 Mar 2006 11:39:04 +0100 Subject: [PATCH 10/19] The attached patch to the qemu emulation of the pcnet hardware fixes several problems. It will now only read and write a transmit or receive descriptor once. It will correctly handle transmitting frames with more than two fragments. It will discard oversize frames instead of corrupting memory. I have tested all the changes I have made and even seen an improvement in receive performance from 1.7MB/s to 3.3MB/s. Your mileage will vary. The code could be simplified if multi-fragment frames were deleted. It appears that both Linux and Windows XP don't use fragmented frames. The mac crc computation code was deleted, since it has never been used. The code was checking the wrong bit in the control register. I tested type 3 descriptors by modifying the linux pcnet32 driver, but did not see any difference in performance over type 2 currently used. I have not made any change to type 0 (16-bit) transmit/receive descriptors as I have no way to test the changes. Please test this as soon as possible, as I will be on vacation next week and in a class the following week. I will check email from time to time, but my ability to make changes to code will be greatly dimished. One other thing I noticed in my testing, is that if I tell a linux domU to reboot, it will reboot but not have any pcnet32 device after rebooting. By doing a shutdown, xm destroy and xm create, I was able to get around that problem. Signed-off-by: Don Fry --- tools/ioemu/hw/pcnet.c | 341 +++++++++++++++++------------------------ tools/ioemu/hw/pcnet.h | 137 ++++++----------- 2 files changed, 180 insertions(+), 298 deletions(-) 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); \ From 3df5f295f80c11fea441c4e74aa23b7b3ed2d28d Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 26 Mar 2006 11:42:17 +0100 Subject: [PATCH 11/19] Fix build error with debug=y inxen/ia64 by moving MAX_ORDER definition has moved into a header file. Signed-off-by: Masaki Kanno --- xen/common/page_alloc.c | 2 -- xen/include/xen/mm.h | 3 +++ 2 files changed, 3 insertions(+), 2 deletions(-) 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/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() \ From 2e0416c354ec5f5df3e20ac2dda7f6cdc832230c Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 26 Mar 2006 11:43:53 +0100 Subject: [PATCH 12/19] Don't reclaim vcpus that are not put into use yet when destroying HVM domain. Otherwise, when running a debug=y xen, we will get a assertion failure in vmx_request_clear_vmcs(), since some vcpus may be not initialized for HVM use yet. Signed-off-by: Xin Li Signed-off-by: Jun Nakajima --- xen/arch/x86/hvm/svm/svm.c | 2 ++ xen/arch/x86/hvm/vmx/vmx.c | 2 ++ 2 files changed, 4 insertions(+) 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 1c1a9fb8fa..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); From f3a1bad634502f2f4fad13e9f4d5de16aa8a1d31 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 26 Mar 2006 11:45:35 +0100 Subject: [PATCH 13/19] Allow 64-bit Xen to run 64-bit hvm SMP guests. Signed-off-by: Jun Nakajima --- xen/arch/x86/shadow.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) 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)) From 3ad72f8da88c8c892cb73320a847dd8871015ab2 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Sun, 26 Mar 2006 11:50:39 +0100 Subject: [PATCH 14/19] Fix 64-bit HVM guest debug via gdbserver: 1. gdb_regs for 64bit, and macros to transfer regisers between ptrace registers to gdb registers 2. xc_ptrace code building for 64bit 3. Implementation of new map_domain_va for 64bit 4. gdbserver-xen build configuration fixes for 64bit From: Nitin Kamble Signed-off-by: Keir Fraser --- .../gdb/gdbserver/configure.srv | 2 +- tools/libxc/Makefile | 6 +- tools/libxc/xc_ptrace.c | 68 ++++++++++++-- tools/libxc/xc_ptrace.h | 94 ++++++++++++++++++- 4 files changed, 156 insertions(+), 14 deletions(-) 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/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 From 044cc18bf52caef1858384e3852f7a3bda58847c Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Mon, 27 Mar 2006 11:16:36 +0100 Subject: [PATCH 15/19] Whitespace. Signed-off-by: Christian Limpach --- linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) 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. */ From 638f779fc5bc5094ec783ffc5e6655e6390b5aaf Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Mon, 27 Mar 2006 18:03:03 +0100 Subject: [PATCH 16/19] Make -xen default kernel compile on x86_64 by removing b44 module. This patch ends up affecting a couple other lines because it is the result of a new make menuconfig, but those changes should be harmless. Signed-off-by: Sean Dague --- buildconfigs/linux-defconfig_xen_x86_64 | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) 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 From 9dd08d8ffb4dae4e8ce07d9baf358e010710b757 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 28 Mar 2006 09:57:48 +0100 Subject: [PATCH 17/19] Add -xen buildconfig for ia64 and tweak CONFIG_VT setup to avoid initializing on domUs. Remove CONFIG_IDE_GENERIC as this is unnecessary on ia64 systems (no ISA IDE controllers) and causes long timeouts booting domU. Signed-off-by: Alex Williamson --- buildconfigs/linux-defconfig_xen0_ia64 | 16 +++++-------- buildconfigs/linux-defconfig_xenU_ia64 | 23 +++++++++++-------- linux-2.6-xen-sparse/arch/ia64/Kconfig | 13 ----------- linux-2.6-xen-sparse/arch/ia64/kernel/setup.c | 16 +++++++++++++ 4 files changed, 36 insertions(+), 32 deletions(-) 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/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 */ From 80605be3afe9175d0de5048b312ba91ebc327415 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Tue, 28 Mar 2006 10:01:35 +0100 Subject: [PATCH 18/19] Simplify the failsafe callback handler in x86/64 linux. It doesn't need to try reloading segment selectors (unlike i386 linux). Signed-off-by: Keir Fraser --- .../arch/x86_64/kernel/entry-xen.S | 26 +++---------------- 1 file changed, 3 insertions(+), 23 deletions(-) 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" From e8e51446b51c7aaf6aa46ec24aacc89f7cac4ee3 Mon Sep 17 00:00:00 2001 From: "cl349@firebug.cl.cam.ac.uk" Date: Tue, 28 Mar 2006 10:09:44 +0100 Subject: [PATCH 19/19] Remove special handling of {set,clear}_in_cr4(). Signed-off-by: Christian Limpach --- .../include/asm-i386/mach-xen/asm/processor.h | 17 ++++------------ .../asm-x86_64/mach-xen/asm/processor.h | 20 +++++-------------- 2 files changed, 9 insertions(+), 28 deletions(-) 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 }