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