From owner-p4-projects@FreeBSD.ORG Wed Aug 30 15:32:30 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 4DD2C16A4DF; Wed, 30 Aug 2006 15:32:30 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 28B0416A4DD for ; Wed, 30 Aug 2006 15:32:30 +0000 (UTC) (envelope-from tkuik@freefall.freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id A841643D4C for ; Wed, 30 Aug 2006 15:32:29 +0000 (GMT) (envelope-from tkuik@freefall.freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id k7UFWRUJ085223 for ; Wed, 30 Aug 2006 15:32:27 GMT (envelope-from tkuik@freefall.freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id k7UFWRjZ085220 for perforce@freebsd.org; Wed, 30 Aug 2006 15:32:27 GMT (envelope-from tkuik@freefall.freebsd.org) Date: Wed, 30 Aug 2006 15:32:27 GMT Message-Id: <200608301532.k7UFWRjZ085220@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to tkuik@freefall using -f From: tkuik To: Perforce Change Reviews Cc: Subject: PERFORCE change 105332 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Aug 2006 15:32:30 -0000 http://perforce.freebsd.org/chv.cgi?CH=105332 Change 105332 by tkuik@tkuik_freebsd on 2006/08/30 15:31:50 Fixed problem where the fs & gs descriptors were not being updated during a thread context switch. This problem caused the pthread library to not work properly under XEN. Affected files ... .. //depot/projects/xen3/src/sys/i386-xen/i386-xen/machdep.c#14 edit .. //depot/projects/xen3/src/sys/i386-xen/i386-xen/xen_machdep.c#16 edit .. //depot/projects/xen3/src/sys/i386/i386/swtch.s#4 edit .. //depot/projects/xen3/src/sys/i386/i386/sys_machdep.c#5 edit .. //depot/projects/xen3/src/sys/i386/i386/vm_machdep.c#6 edit Differences ... ==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/machdep.c#14 (text+ko) ==== @@ -2501,6 +2501,10 @@ #endif thread0.td_pcb->pcb_ext = 0; thread0.td_frame = &proc0_tf; +#ifdef XEN + thread0.td_pcb->pcb_fsd = PCPU_GET(fsgs_gdt)[0]; + thread0.td_pcb->pcb_gsd = PCPU_GET(fsgs_gdt)[1]; +#endif } void ==== //depot/projects/xen3/src/sys/i386-xen/i386-xen/xen_machdep.c#16 (text+ko) ==== @@ -44,6 +44,7 @@ #include #include +#include #include #include #include @@ -78,6 +79,7 @@ void ni_cli(void); void ni_sti(void); + void ni_cli(void) { @@ -156,14 +158,14 @@ printk(const char *fmt, ...) { __va_list ap; - int ret; + int retval; static char buf[PRINTK_BUFSIZE]; va_start(ap, fmt); - ret = vsnprintf(buf, PRINTK_BUFSIZE - 1, fmt, ap); + retval = vsnprintf(buf, PRINTK_BUFSIZE - 1, fmt, ap); va_end(ap); - buf[ret] = 0; - (void)HYPERVISOR_console_write(buf, ret); + buf[retval] = 0; + (void)HYPERVISOR_console_write(buf, retval); } @@ -1038,3 +1040,41 @@ panic("xen_failsafe_handler called!\n"); } + +void xen_handle_thread_switch(struct pcb *pcb); + +/* This is called by cpu_switch() when switching threads. */ +/* The pcb arg refers to the process control block of the */ +/* next thread which is to run */ +void +xen_handle_thread_switch(struct pcb *pcb) +{ + uint32_t *a = (uint32_t *)&PCPU_GET(fsgs_gdt)[0]; + uint32_t *b = (uint32_t *)&pcb->pcb_fsd; + multicall_entry_t mcl[3]; + int i = 0; + + /* Notify Xen of task switch */ + mcl[i].op = __HYPERVISOR_stack_switch; + mcl[i].args[0] = GSEL(GDATA_SEL, SEL_KPL); + mcl[i++].args[1] = (unsigned long)pcb; + + /* Check for update of fsd */ + if (*a != *b || *(a+1) != *(b+1)) { + mcl[i].op = __HYPERVISOR_update_descriptor; + *(uint64_t *)&mcl[i].args[0] = vtomach((vm_offset_t)a); + *(uint64_t *)&mcl[i++].args[2] = *(uint64_t *)b; + } + + a += 2; + b += 2; + + /* Check for update of gsd */ + if (*a != *b || *(a+1) != *(b+1)) { + mcl[i].op = __HYPERVISOR_update_descriptor; + *(uint64_t *)&mcl[i].args[0] = vtomach((vm_offset_t)a); + *(uint64_t *)&mcl[i++].args[2] = *(uint64_t *)b; + } + + (void)HYPERVISOR_multicall(mcl, i); +} ==== //depot/projects/xen3/src/sys/i386/i386/swtch.s#4 (text+ko) ==== @@ -221,23 +221,7 @@ movl %esi, 4(%ebx) movl $GPROC0_SEL*8, %esi /* GSEL(GPROC0_SEL, SEL_KPL) */ ltr %si -#else - /* notify Xen of task switch */ - pushl %edx /* &pcb is the new stack base */ - pushl $KDSEL - pushl $HYPERVISOR_STACK_SWITCH - call ni_queue_multicall2 - addl $12,%esp - /* XXX handle DOM0 IOPL case here (KMM) */ - /* we currently don't support running FreeBSD */ - /* in DOM0 so we can skip for now */ - - call ni_execute_multicall_list - -#endif /* XEN */ 3: - -#ifndef XEN /* XXX skip updating selectors for the moment */ /* Copy the %fs and %gs selectors into this pcpu gdt */ leal PCB_FSD(%edx), %esi movl PCPU(FSGS_GDT), %edi @@ -249,7 +233,22 @@ movl 12(%esi), %ebx movl %eax, 8(%edi) movl %ebx, 12(%edi) -#endif +#else + /* Notify Xen of task switch and update fs/gs descriptors */ + pushl %eax + pushl %ecx + pushl %edx + call xen_handle_thread_switch + popl %edx + popl %ecx + popl %eax + + /* XXX handle DOM0 IOPL case here (KMM) */ + /* we currently don't support running FreeBSD */ + /* in DOM0 so we can skip for now */ + +#endif /* XEN */ + /* Restore context. */ movl PCB_EBX(%edx),%ebx movl PCB_ESP(%edx),%esp ==== //depot/projects/xen3/src/sys/i386/i386/sys_machdep.c#5 (text+ko) ==== @@ -182,12 +182,13 @@ critical_enter(); #ifndef XEN PCPU_GET(fsgs_gdt)[0] = sd; + td->td_pcb->pcb_fsd = sd; #else sd.sd_lolimit = 0xc3f0; /* < 4GB limit */ - HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[1]), + HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[0]), *(uint64_t *)&sd); + td->td_pcb->pcb_fsd = PCPU_GET(fsgs_gdt)[0]; #endif - td->td_pcb->pcb_fsd = sd; critical_exit(); td->td_frame->tf_fs = GSEL(GUFS_SEL, SEL_UPL); } @@ -219,12 +220,13 @@ critical_enter(); #ifndef XEN PCPU_GET(fsgs_gdt)[1] = sd; + td->td_pcb->pcb_gsd = sd; #else sd.sd_lolimit = 0xc3f0; /* 4GB limit, wraps around */ HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[1]), *(uint64_t *)&sd); + td->td_pcb->pcb_gsd = PCPU_GET(fsgs_gdt)[1]; #endif - td->td_pcb->pcb_gsd = sd; critical_exit(); load_gs(GSEL(GUGS_SEL, SEL_UPL)); } ==== //depot/projects/xen3/src/sys/i386/i386/vm_machdep.c#6 (text+ko) ==== @@ -503,7 +503,14 @@ /* set %gs */ td->td_pcb->pcb_gsd = sd; if (td == curthread) { +#ifndef XEN PCPU_GET(fsgs_gdt)[1] = sd; +#else + sd.sd_lolimit = 0xc3f0; /* 4GB limit, wraps around */ + HYPERVISOR_update_descriptor(vtomach(&PCPU_GET(fsgs_gdt)[1]), + *(uint64_t *)&sd); + td->td_pcb->pcb_gsd = PCPU_GET(fsgs_gdt)[1]; +#endif load_gs(GSEL(GUGS_SEL, SEL_UPL)); } critical_exit();