Date: Wed, 24 Apr 2013 19:47:00 +0000 (UTC) From: "Cherry G. Mathew" <cherry@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r249855 - in projects/amd64_xen_pv/sys/amd64: amd64 xen Message-ID: <201304241947.r3OJl0SO099608@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: cherry Date: Wed Apr 24 19:47:00 2013 New Revision: 249855 URL: http://svnweb.freebsd.org/changeset/base/249855 Log: Context switch now merges current userland VA into kernel context. fpu context is handled during context switch. ldt related assembler cruft removed - this is already implemented via call to xen_set_ldt() userland tls register context is conditionally fixed up during context switch. Approved by: gibbs(implicit) Modified: projects/amd64_xen_pv/sys/amd64/amd64/cpu_switch.S projects/amd64_xen_pv/sys/amd64/xen/machdep.c Modified: projects/amd64_xen_pv/sys/amd64/amd64/cpu_switch.S ============================================================================== --- projects/amd64_xen_pv/sys/amd64/amd64/cpu_switch.S Wed Apr 24 19:41:21 2013 (r249854) +++ projects/amd64_xen_pv/sys/amd64/amd64/cpu_switch.S Wed Apr 24 19:47:00 2013 (r249855) @@ -77,8 +77,33 @@ ENTRY(cpu_throw) LK btrl %eax,PM_ACTIVE(%rdx) /* clear old */ 1: movq TD_PCB(%rsi),%r8 /* newtd->td_pcb */ +#ifndef XEN movq PCB_CR3(%r8),%rdx movq %rdx,%cr3 /* new address space */ +#else + pushq %rsi + pushq %r8 + + /* + * On xen, the hypervisor loads %cr3 for us on return to + * userland. We use a separate "kernel space" for kernel mode, + * which is setup at boot time (see: pmap.c:pmap_bootstrap) + * + * We need to tell the hypervisor via xen_pt_user_switch() + * about the new user pmap. Additionally, we modify the kernel VA + * space by copying in the userland bits of the new pmap, in + * case the kernel needs to access them. + */ + + movq TD_PROC(%rsi), %rdx /* newproc */ + movq P_VMSPACE(%rdx), %rdx + addq $VM_PMAP, %rdx + movq %rdx, %rdi + callq pmap_xen_userload + + popq %r8 + popq %rsi +#endif jmp swact END(cpu_throw) @@ -129,9 +154,25 @@ ctx_switch_xsave: /* This is patched to xsaveopt if supported, see fpuinit_bsp1() */ xsave (%r8) movq %rcx,%rdx -2: smsw %ax +2: +#ifndef XEN + smsw %ax orb $CR0_TS,%al lmsw %ax +#else + pushq %rdi + pushq %rsi + pushq %rdx + pushq %rax + pushq %r8 + movq $1, %rdi + callq fpu_taskswitch + popq %r8 + popq %rax + popq %rdx + popq %rsi + popq %rdi +#endif xorl %eax,%eax movq %rax,PCPU(FPCURTHREAD) 3: @@ -237,77 +278,12 @@ ld_ldt: shrl $8,%eax movb %al,7(%rdx) #else -#ifdef notyet_xenldt - pushq %rdi - pushq %rsi - pushq %rdx - pushq %r8 - - /* Restore fs base in GDT */ - movl PCB_FSBASE(%r8), %eax - movq %rsp, %rdx /* register_t tmp, %rdx == &tmp */ - subq $8, %rsp /* allocate tmp */ - - /* Reconstruct the_segment_descriptor */ - movq $0, (%rdx) /* Zero it first */ - movw %ax, 2(%rdx) /* .base = %eax */ - shrl $16,%eax - movb %al, 4(%rdx) - shrl $8,%eax - movb %al, 7(%rdx) - movw $0xffff, (%rdx) /* limit = 0xfffff */ - movb $1, 6(%rdx) - movb $1, %al /* p = 1 */ - shlb $2, %al - orb $SEL_UPL, %al /* dpl = SEL_UPL */ - shlb $5, %al - orb $SDT_MEMRWA, %al/* type = SDT_MEMRWA */ - movb %al, 5(%rdx) - movb $0xc, %al - orb %al, 6(%rdx) /* def32 = 1, gran = 1 */ - - movq PCPU(FS32P), %rdi /* dte_ma */ - movq %rdx, %rsi /* dte_ptr */ - callq xen_set_descriptor + /* ldt is already loaded - see do_ldt: below */ - movq 16(%rsp), %r8 /* Restore caller saved %r8 */ - - /* Restore gs base in GDT */ - movl PCB_GSBASE(%r8),%eax - movq %rsp, %rdx /* register_t tmp, %rdx == &tmp */ - addq $8, %rdx /* allocate tmp */ - - /* Reconstruct the_segment_descriptor */ - movq $0, (%rdx) /* Zero it first */ - movw %ax, 2(%rdx) /* .base = %eax */ - shrl $16,%eax - movb %al, 4(%rdx) - shrl $8,%eax - movb %al, 7(%rdx) - movw $0xffff, (%rdx) /* limit = 0xfffff */ - movb $1, 6(%rdx) - movb $1, %al /* p = 1 */ - shlb $2, %al - orb $SEL_UPL, %al /* dpl = SEL_UPL */ - shlb $5, %al - orb $SDT_MEMRWA, %al/* type = SDT_MEMRWA */ - movb %al, 5(%rdx) - movb $0xc, %al - orb %al, 6(%rdx) /* def32 = 1, gran = 1 */ - - movq PCPU(GS32P), %rdi /* dte_ma */ - movq %rdx, %rsi /* dte_ptr */ - callq xen_set_descriptor - - addq $8, %rsp /* De-allocate temp "variable" stackspace */ - /* XXX: Do hypervisor GS/FS update ? */ - - popq %r8 - popq %rdx - popq %rsi - popq %rdi - -#endif + /* + * We setup user tls in xen_set_proc() + * as part of the context switch + */ #endif /* !XEN */ do_kthread: /* Do we need to reload tss ? */ Modified: projects/amd64_xen_pv/sys/amd64/xen/machdep.c ============================================================================== --- projects/amd64_xen_pv/sys/amd64/xen/machdep.c Wed Apr 24 19:41:21 2013 (r249854) +++ projects/amd64_xen_pv/sys/amd64/xen/machdep.c Wed Apr 24 19:47:00 2013 (r249855) @@ -176,7 +176,7 @@ setup_gdt(struct user_segment_descriptor #endif /* 0 */ case GUFS32_SEL: case GUGS32_SEL: - case GUDATA_SEL: /* XXX: why def32 ? */ + case GUDATA_SEL: limit = 0xfffff; type = SDT_MEMRWA; dpl = SEL_UPL; @@ -1364,6 +1364,31 @@ xen_set_proc(struct pcb *newpcb) { HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), (unsigned long) newpcb & ~0xFul); + + if (!(curthread->td_pflags & TDP_KTHREAD)) { /* Only for user proc */ + /* XXX: compat32 */ + if (newpcb->pcb_flags & (PCB_32BIT | PCB_GS32BIT)) { + struct user_segment_descriptor gsd; + gsd = gdt[GUGS32_SEL]; + USD_SETBASE(&gsd, newpcb->pcb_gsbase); + xen_set_descriptor((vm_paddr_t)PCPU_GET(gs32p), (void *)&gsd); + + if (newpcb->pcb_flags & PCB_32BIT) { + gsd = gdt[GUFS32_SEL]; + USD_SETBASE(&gsd, newpcb->pcb_fsbase); + xen_set_descriptor((vm_paddr_t)PCPU_GET(fs32p), (void *)&gsd); + } + + } else { + + HYPERVISOR_set_segment_base(SEGBASE_GS_USER_SEL, + _ugssel); + HYPERVISOR_set_segment_base(SEGBASE_FS, + newpcb->pcb_fsbase); + HYPERVISOR_set_segment_base(SEGBASE_GS_USER, + newpcb->pcb_gsbase); + } + } } char *console_page;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304241947.r3OJl0SO099608>