diff options
author | royger <royger@FreeBSD.org> | 2014-04-04 14:54:54 +0000 |
---|---|---|
committer | royger <royger@FreeBSD.org> | 2014-04-04 14:54:54 +0000 |
commit | 382b727d121cbeff12dbc714df3a87f09f488862 (patch) | |
tree | c5cac117c2ab4fbab4faa253474ec94ef4dca085 /sys/i386 | |
parent | d7785b5ded2bde054f92db763f087b9e79a24cb1 (diff) | |
download | FreeBSD-src-382b727d121cbeff12dbc714df3a87f09f488862.zip FreeBSD-src-382b727d121cbeff12dbc714df3a87f09f488862.tar.gz |
MFC r263001
Move asm IPIs handlers to C code, so both Xen and native IPI handlers
share the same code.
Approved by: gibbs
Sponsored by: Citrix Systems R&D
Diffstat (limited to 'sys/i386')
-rw-r--r-- | sys/i386/i386/apic_vector.s | 145 | ||||
-rw-r--r-- | sys/i386/i386/mp_machdep.c | 66 | ||||
-rw-r--r-- | sys/i386/include/smp.h | 4 | ||||
-rw-r--r-- | sys/i386/xen/mp_machdep.c | 25 |
4 files changed, 121 insertions, 119 deletions
diff --git a/sys/i386/i386/apic_vector.s b/sys/i386/i386/apic_vector.s index adedbc4..3d1999e 100644 --- a/sys/i386/i386/apic_vector.s +++ b/sys/i386/i386/apic_vector.s @@ -163,39 +163,21 @@ IDTVEC(xen_intr_upcall) */ .text SUPERALIGN_TEXT -IDTVEC(invltlb) - pushl %eax - pushl %ds - movl $KDSEL, %eax /* Kernel data selector */ - movl %eax, %ds - -#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) - pushl %fs - movl $KPSEL, %eax /* Private space selector */ - movl %eax, %fs - movl PCPU(CPUID), %eax - popl %fs -#ifdef COUNT_XINVLTLB_HITS - incl xhits_gbl(,%eax,4) -#endif -#ifdef COUNT_IPIS - movl ipi_invltlb_counts(,%eax,4),%eax - incl (%eax) -#endif -#endif - - movl %cr3, %eax /* invalidate the TLB */ - movl %eax, %cr3 - +invltlb_ret: movl lapic, %eax movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ + POP_FRAME + iret + + SUPERALIGN_TEXT +IDTVEC(invltlb) + PUSH_FRAME + SET_KERNEL_SREGS + cld - lock - incl smp_tlb_wait + call invltlb_handler - popl %ds - popl %eax - iret + jmp invltlb_ret /* * Single page TLB shootdown @@ -203,38 +185,13 @@ IDTVEC(invltlb) .text SUPERALIGN_TEXT IDTVEC(invlpg) - pushl %eax - pushl %ds - movl $KDSEL, %eax /* Kernel data selector */ - movl %eax, %ds - -#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) - pushl %fs - movl $KPSEL, %eax /* Private space selector */ - movl %eax, %fs - movl PCPU(CPUID), %eax - popl %fs -#ifdef COUNT_XINVLTLB_HITS - incl xhits_pg(,%eax,4) -#endif -#ifdef COUNT_IPIS - movl ipi_invlpg_counts(,%eax,4),%eax - incl (%eax) -#endif -#endif - - movl smp_tlb_addr1, %eax - invlpg (%eax) /* invalidate single page */ - - movl lapic, %eax - movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ + PUSH_FRAME + SET_KERNEL_SREGS + cld - lock - incl smp_tlb_wait + call invlpg_handler - popl %ds - popl %eax - iret + jmp invltlb_ret /* * Page range TLB shootdown. @@ -242,44 +199,13 @@ IDTVEC(invlpg) .text SUPERALIGN_TEXT IDTVEC(invlrng) - pushl %eax - pushl %edx - pushl %ds - movl $KDSEL, %eax /* Kernel data selector */ - movl %eax, %ds - -#if defined(COUNT_XINVLTLB_HITS) || defined(COUNT_IPIS) - pushl %fs - movl $KPSEL, %eax /* Private space selector */ - movl %eax, %fs - movl PCPU(CPUID), %eax - popl %fs -#ifdef COUNT_XINVLTLB_HITS - incl xhits_rng(,%eax,4) -#endif -#ifdef COUNT_IPIS - movl ipi_invlrng_counts(,%eax,4),%eax - incl (%eax) -#endif -#endif + PUSH_FRAME + SET_KERNEL_SREGS + cld - movl smp_tlb_addr1, %edx - movl smp_tlb_addr2, %eax -1: invlpg (%edx) /* invalidate single page */ - addl $PAGE_SIZE, %edx - cmpl %eax, %edx - jb 1b + call invlrng_handler - movl lapic, %eax - movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ - - lock - incl smp_tlb_wait - - popl %ds - popl %edx - popl %eax - iret + jmp invltlb_ret /* * Invalidate cache. @@ -287,32 +213,13 @@ IDTVEC(invlrng) .text SUPERALIGN_TEXT IDTVEC(invlcache) - pushl %eax - pushl %ds - movl $KDSEL, %eax /* Kernel data selector */ - movl %eax, %ds - -#ifdef COUNT_IPIS - pushl %fs - movl $KPSEL, %eax /* Private space selector */ - movl %eax, %fs - movl PCPU(CPUID), %eax - popl %fs - movl ipi_invlcache_counts(,%eax,4),%eax - incl (%eax) -#endif - - wbinvd - - movl lapic, %eax - movl $0, LA_EOI(%eax) /* End Of Interrupt to APIC */ + PUSH_FRAME + SET_KERNEL_SREGS + cld - lock - incl smp_tlb_wait + call invlcache_handler - popl %ds - popl %eax - iret + jmp invltlb_ret /* * Handler for IPIs sent via the per-cpu IPI bitmap. diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 8ee8653..53ac6df 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -1551,6 +1551,72 @@ cpususpend_handler(void) CPU_CLR_ATOMIC(cpu, &suspended_cpus); CPU_CLR_ATOMIC(cpu, &started_cpus); } + +/* + * Handlers for TLB related IPIs + */ +void +invltlb_handler(void) +{ + uint64_t cr3; +#ifdef COUNT_XINVLTLB_HITS + xhits_gbl[PCPU_GET(cpuid)]++; +#endif /* COUNT_XINVLTLB_HITS */ +#ifdef COUNT_IPIS + (*ipi_invltlb_counts[PCPU_GET(cpuid)])++; +#endif /* COUNT_IPIS */ + + cr3 = rcr3(); + load_cr3(cr3); + atomic_add_int(&smp_tlb_wait, 1); +} + +void +invlpg_handler(void) +{ +#ifdef COUNT_XINVLTLB_HITS + xhits_pg[PCPU_GET(cpuid)]++; +#endif /* COUNT_XINVLTLB_HITS */ +#ifdef COUNT_IPIS + (*ipi_invlpg_counts[PCPU_GET(cpuid)])++; +#endif /* COUNT_IPIS */ + + invlpg(smp_tlb_addr1); + + atomic_add_int(&smp_tlb_wait, 1); +} + +void +invlrng_handler(void) +{ + vm_offset_t addr; +#ifdef COUNT_XINVLTLB_HITS + xhits_rng[PCPU_GET(cpuid)]++; +#endif /* COUNT_XINVLTLB_HITS */ +#ifdef COUNT_IPIS + (*ipi_invlrng_counts[PCPU_GET(cpuid)])++; +#endif /* COUNT_IPIS */ + + addr = smp_tlb_addr1; + do { + invlpg(addr); + addr += PAGE_SIZE; + } while (addr < smp_tlb_addr2); + + atomic_add_int(&smp_tlb_wait, 1); +} + +void +invlcache_handler(void) +{ +#ifdef COUNT_IPIS + (*ipi_invlcache_counts[PCPU_GET(cpuid)])++; +#endif /* COUNT_IPIS */ + + wbinvd(); + atomic_add_int(&smp_tlb_wait, 1); +} + /* * This is called once the rest of the system is up and running and we're * ready to let the AP's out of the pen. diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index 43dad10..a0936e9 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -63,6 +63,10 @@ void cpustop_handler(void); #ifndef XEN void cpususpend_handler(void); #endif +void invltlb_handler(void); +void invlpg_handler(void); +void invlrng_handler(void); +void invlcache_handler(void); void init_secondary(void); void ipi_startup(int apic_id, int vector); void ipi_all_but_self(u_int ipi); diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index c48fcb2..1bc6572 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -1276,6 +1276,31 @@ cpustop_handler(void) } /* + * Handlers for TLB related IPIs + * + * On i386 Xen PV this are no-ops since this port doesn't support SMP. + */ +void +invltlb_handler(void) +{ +} + +void +invlpg_handler(void) +{ +} + +void +invlrng_handler(void) +{ +} + +void +invlcache_handler(void) +{ +} + +/* * This is called once the rest of the system is up and running and we're * ready to let the AP's out of the pen. */ |