Skip site navigation (1)Skip section navigation (2)
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>