svn commit: r246992 - in projects/amd64_xen_pv/sys/amd64: amd64 include xen

Cherry G. Mathew cherry at FreeBSD.org
Tue Feb 19 14:39:11 UTC 2013


Author: cherry
Date: Tue Feb 19 14:39:10 2013
New Revision: 246992
URL: http://svnweb.freebsd.org/changeset/base/246992

Log:
  First cut at cpu_switch(9) for xen. This is still WIP\n
  genassym.c: Generate required symbols in assembler scope\n
  machdep.c: - init TLS related per-cpu fields
  	   - enable further cpu initialisation
  	   - remove redundate private functions for rflag manipulation
  	   - add xen stack switch code for cpu_switch(9) support
  
  Approved by: gibbs(implicit)

Modified:
  projects/amd64_xen_pv/sys/amd64/amd64/cpu_switch.S
  projects/amd64_xen_pv/sys/amd64/amd64/genassym.c
  projects/amd64_xen_pv/sys/amd64/include/cpufunc.h
  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	Tue Feb 19 13:40:35 2013	(r246991)
+++ projects/amd64_xen_pv/sys/amd64/amd64/cpu_switch.S	Tue Feb 19 14:39:10 2013	(r246992)
@@ -106,9 +106,11 @@ ENTRY(cpu_switch)
 	movq	%rbx,PCB_RBX(%r8)
 	movq	%rax,PCB_RIP(%r8)
 
+#ifndef XEN
 	testl	$PCB_DBREGS,PCB_FLAGS(%r8)
 	jnz	store_dr			/* static predict not taken */
 done_store_dr:
+#endif	/* !XEN */
 
 	/* have we used fp, and need a save? */
 	cmpq	%rdi,PCPU(FPCURTHREAD)
@@ -145,7 +147,23 @@ ctx_switch_xsave:
 	SETLK	%rdx, TD_LOCK(%rdi)		/* Release the old thread */
 	jmp	sw1
 swinact:
+#ifndef XEN
 	movq	%rcx,%cr3			/* new address space */
+#else
+	pushq	%rdi
+	pushq	%rsi
+	pushq	%rdx
+	pushq	%r8
+
+	movq	%rcx, %rdi
+	callq	xen_pt_switch
+
+	popq	%r8
+	popq	%rdx
+	popq	%rsi
+	popq	%rdi
+
+#endif  /* XEN */
 	movl	PCPU(CPUID), %eax
 	/* Release bit from old pmap->pm_active */
 	movq	PCPU(CURPMAP),%rcx
@@ -158,7 +176,6 @@ swact:
 	addq	$VM_PMAP,%rdx
 	LK btsl	%eax,PM_ACTIVE(%rdx)		/* set new */
 	movq	%rdx,PCPU(CURPMAP)
-
 sw1:
 #if defined(SCHED_ULE) && defined(SMP)
 	/* Wait for the new thread to become unblocked */
@@ -185,7 +202,9 @@ sw1:
 	cmpq	$0, P_MD+MD_LDT(%rcx)
 	jne	do_ldt
 	xorl	%eax,%eax
-ld_ldt:	lldt	%ax
+ld_ldt:
+#ifndef XEN
+	lldt	%ax
 
 	/* Restore fs base in GDT */
 	movl	PCB_FSBASE(%r8),%eax
@@ -204,7 +223,79 @@ ld_ldt:	lldt	%ax
 	movb	%al,4(%rdx)
 	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
+
+	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	
+#endif	/* !XEN */
 do_kthread:
 	/* Do we need to reload tss ? */
 	movq	PCPU(TSSP),%rax
@@ -219,12 +310,12 @@ done_tss:
 	/* Update the TSS_RSP0 pointer for the next interrupt */
 	movq	%r8,COMMON_TSS_RSP0(%rdx)
 	movq	%rsi,PCPU(CURTHREAD)		/* into next thread */
-
+#ifndef	XEN
 	/* Test if debug registers should be restored. */
 	testl	$PCB_DBREGS,PCB_FLAGS(%r8)
 	jnz	load_dr				/* static predict not taken */
 done_load_dr:
-
+#endif	/* !XEN */
 	/* Restore context. */
 	movq	PCB_R15(%r8),%r15
 	movq	PCB_R14(%r8),%r14
@@ -247,6 +338,7 @@ done_load_dr:
 	 * We use jumps rather than call in order to avoid the stack.
 	 */
 
+#ifndef XEN
 store_dr:
 	movq	%dr7,%rax			/* yes, do the save */
 	movq	%dr0,%r15
@@ -297,14 +389,41 @@ do_tss:	movq	%rdx,PCPU(TSSP)
 	movb	$0x89,5(%rax)	/* unset busy */
 	movl	$TSSSEL,%eax
 	ltr	%ax
+#else
+do_tss:
+	pushq	%rsi
+	pushq	%rdx
+	pushq	%r8
+
+	movq	%r8, %rdi
+	callq	xen_set_proc
+
+	popq	%r8
+	popq	%rdx
+	popq	%rsi
+#endif 	/* !XEN */
 	jmp	done_tss
-
+	
 do_ldt:	movq	PCPU(LDT),%rax
+#ifndef XEN	
 	movq	P_MD+MD_LDT_SD(%rcx),%rdx
 	movq	%rdx,(%rax)
 	movq	P_MD+MD_LDT_SD+8(%rcx),%rdx
 	movq	%rdx,8(%rax)
 	movl	$LDTSEL,%eax
+#else	/* !XEN */
+	pushq	%rsi
+	pushq	%rdx
+	pushq	%r8
+	
+	movq	P_MD+MD_LDT_SD(%rcx),%rsi
+	movq	P_MD+MD_LDT_SD+8(%rcx),%rdi
+	callq	xen_set_ldt
+
+	popq	%r8
+	popq	%rdx
+	popq	%rsi
+#endif	/* !XEN */
 	jmp	ld_ldt
 END(cpu_switch)
 

Modified: projects/amd64_xen_pv/sys/amd64/amd64/genassym.c
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/amd64/genassym.c	Tue Feb 19 13:40:35 2013	(r246991)
+++ projects/amd64_xen_pv/sys/amd64/amd64/genassym.c	Tue Feb 19 14:39:10 2013	(r246992)
@@ -236,6 +236,8 @@ ASSYM(LA_ICR_LO, offsetof(struct LAPIC, 
 ASSYM(LA_ICR_HI, offsetof(struct LAPIC, icr_hi));
 ASSYM(LA_ISR, offsetof(struct LAPIC, isr0));
 
+ASSYM(SEL_UPL, SEL_UPL);
+ASSYM(SDT_MEMRWA, SDT_MEMRWA);
 ASSYM(KCSEL, GSEL(GCODE_SEL, SEL_KPL));
 ASSYM(KDSEL, GSEL(GDATA_SEL, SEL_KPL));
 ASSYM(KUCSEL, GSEL(GUCODE_SEL, SEL_UPL));

Modified: projects/amd64_xen_pv/sys/amd64/include/cpufunc.h
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/include/cpufunc.h	Tue Feb 19 13:40:35 2013	(r246991)
+++ projects/amd64_xen_pv/sys/amd64/include/cpufunc.h	Tue Feb 19 14:39:10 2013	(r246992)
@@ -44,12 +44,15 @@
 #endif
 
 #ifdef XEN
+struct pcb; /* Forward declaration */
+
 extern void xen_cli(void);
 extern void xen_sti(void);
 extern u_long xen_rcr2(void);
 extern void xen_load_cr3(u_long data);
 extern void xen_tlb_flush(void);
 extern void xen_invlpg(vm_offset_t addr);
+extern void xen_set_proc(struct pcb *newpcb);
 extern void write_rflags(u_long rflags);
 extern u_long read_rflags(void);
 #endif /* XEN */

Modified: projects/amd64_xen_pv/sys/amd64/xen/machdep.c
==============================================================================
--- projects/amd64_xen_pv/sys/amd64/xen/machdep.c	Tue Feb 19 13:40:35 2013	(r246991)
+++ projects/amd64_xen_pv/sys/amd64/xen/machdep.c	Tue Feb 19 14:39:10 2013	(r246992)
@@ -489,6 +489,11 @@ initxen(struct start_info *si)
 	PCPU_SET(prvspace, pc);
 	PCPU_SET(curthread, &thread0);
 
+	PCPU_SET(tssp, &common_tss[0]); /* Dummy - see definition */
+	PCPU_SET(commontssp, &common_tss[0]); /* Dummy - see definition */
+	PCPU_SET(fs32p, (void *)xpmap_ptom(VTOP(&gdt[GUFS32_SEL]))); /* Note: On Xen PV, we set the machine address. */
+	PCPU_SET(gs32p, (void *)xpmap_ptom(VTOP(&gdt[GUGS32_SEL]))); /* Note: On Xen PV, we set the machine address. */
+
 	/*
 	 * Initialize mutexes.
 	 *
@@ -518,8 +523,8 @@ initxen(struct start_info *si)
 #endif
 
 	identify_cpu();		/* Final stage of CPU initialization */
-	//initializecpu();
-	//initializecpucache();
+	initializecpu();
+	initializecpucache();
 
 	init_param2(physmem);
 
@@ -1225,21 +1230,6 @@ vprintk(const char *fmt, __va_list ap)
 }
 
 
-static __inline void
-cpu_write_rflags(u_long rf)
-{
-	__asm __volatile("pushq %0; popfq" : : "r" (rf));
-}
-
-static __inline u_long
-cpu_read_rflags(void)
-{
-	u_long	rf;
-
-	__asm __volatile("pushfq; popq %0" : "=r" (rf));
-	return (rf);
-}
-
 #ifdef KTR
 static __inline u_long
 rrbp(void)
@@ -1297,6 +1287,13 @@ xen_rcr2(void)
 	return (HYPERVISOR_shared_info->vcpu_info[curcpu].arch.cr2);
 }
 
+void
+xen_set_proc(struct pcb *newpcb)
+{
+	HYPERVISOR_stack_switch(GSEL(GDATA_SEL, SEL_KPL), 
+		(unsigned long) PCPU_GET(rsp0));
+}
+
 char *console_page;
 #include <machine/tss.h>
 struct amd64tss common_tss[MAXCPU];


More information about the svn-src-projects mailing list