defer pmap switching until it's really needed
to avoid frequent loading of cr3 register, which involves tlb flush. with some fixes/improvements from Stephan Uphoff and Bang Jun-Young.
This commit is contained in:
parent
b07c616019
commit
d749a2d0b4
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: cpu.c,v 1.17 2004/02/13 11:36:13 wiz Exp $ */
|
/* $NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.17 2004/02/13 11:36:13 wiz Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.18 2004/02/20 17:35:01 yamt Exp $");
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
#include "opt_multiprocessor.h"
|
#include "opt_multiprocessor.h"
|
||||||
|
@ -314,10 +314,12 @@ cpu_attach(parent, self, aux)
|
||||||
kstack + USPACE - 16 - sizeof (struct trapframe);
|
kstack + USPACE - 16 - sizeof (struct trapframe);
|
||||||
pcb->pcb_tss.tss_esp =
|
pcb->pcb_tss.tss_esp =
|
||||||
kstack + USPACE - 16 - sizeof (struct trapframe);
|
kstack + USPACE - 16 - sizeof (struct trapframe);
|
||||||
pcb->pcb_pmap = pmap_kernel();
|
|
||||||
pcb->pcb_cr0 = rcr0();
|
pcb->pcb_cr0 = rcr0();
|
||||||
pcb->pcb_cr3 = pcb->pcb_pmap->pm_pdirpa;
|
pcb->pcb_cr3 = pmap_kernel()->pm_pdirpa;
|
||||||
#endif
|
#endif
|
||||||
|
pmap_reference(pmap_kernel());
|
||||||
|
ci->ci_pmap = pmap_kernel();
|
||||||
|
ci->ci_tlbstate = TLBSTATE_STALE;
|
||||||
|
|
||||||
/* further PCB init done later. */
|
/* further PCB init done later. */
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $NetBSD: genassym.cf,v 1.39 2003/11/04 10:33:15 dsl Exp $
|
# $NetBSD: genassym.cf,v 1.40 2004/02/20 17:35:01 yamt Exp $
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright (c) 1998 The NetBSD Foundation, Inc.
|
# Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||||
|
@ -258,6 +258,9 @@ endif
|
||||||
|
|
||||||
define CPU_INFO_SELF offsetof(struct cpu_info, ci_self)
|
define CPU_INFO_SELF offsetof(struct cpu_info, ci_self)
|
||||||
define CPU_INFO_RESCHED offsetof(struct cpu_info, ci_want_resched)
|
define CPU_INFO_RESCHED offsetof(struct cpu_info, ci_want_resched)
|
||||||
|
define CPU_INFO_WANT_PMAPLOAD offsetof(struct cpu_info, ci_want_pmapload)
|
||||||
|
define CPU_INFO_TLBSTATE offsetof(struct cpu_info, ci_tlbstate)
|
||||||
|
define TLBSTATE_VALID TLBSTATE_VALID
|
||||||
define CPU_INFO_CURLWP offsetof(struct cpu_info, ci_curlwp)
|
define CPU_INFO_CURLWP offsetof(struct cpu_info, ci_curlwp)
|
||||||
define CPU_INFO_CURPCB offsetof(struct cpu_info, ci_curpcb)
|
define CPU_INFO_CURPCB offsetof(struct cpu_info, ci_curpcb)
|
||||||
define CPU_INFO_IDLE_PCB offsetof(struct cpu_info, ci_idle_pcb)
|
define CPU_INFO_IDLE_PCB offsetof(struct cpu_info, ci_idle_pcb)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: locore.S,v 1.23 2004/02/16 17:11:27 wiz Exp $ */
|
/* $NetBSD: locore.S,v 1.24 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
||||||
|
@ -701,6 +701,7 @@ NENTRY(proc_trampoline)
|
||||||
pushl %ebx
|
pushl %ebx
|
||||||
call *%esi
|
call *%esi
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
INTRFASTEXIT
|
INTRFASTEXIT
|
||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
|
|
||||||
|
@ -778,7 +779,7 @@ ENTRY(kcopy)
|
||||||
pushl %edi
|
pushl %edi
|
||||||
GET_CURPCB(%eax) # load curpcb into eax and set on-fault
|
GET_CURPCB(%eax) # load curpcb into eax and set on-fault
|
||||||
pushl PCB_ONFAULT(%eax)
|
pushl PCB_ONFAULT(%eax)
|
||||||
movl $_C_LABEL(copy_fault), PCB_ONFAULT(%eax)
|
movl $_C_LABEL(kcopy_fault), PCB_ONFAULT(%eax)
|
||||||
|
|
||||||
movl 16(%esp),%esi
|
movl 16(%esp),%esi
|
||||||
movl 20(%esp),%edi
|
movl 20(%esp),%edi
|
||||||
|
@ -871,6 +872,7 @@ _C_LABEL(copyin_func):
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int copyout(const void *kaddr, void *uaddr, size_t len) */
|
/* LINTSTUB: Func: int copyout(const void *kaddr, void *uaddr, size_t len) */
|
||||||
ENTRY(copyout)
|
ENTRY(copyout)
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
jmp *_C_LABEL(copyout_func)
|
jmp *_C_LABEL(copyout_func)
|
||||||
|
|
||||||
#if defined(I386_CPU)
|
#if defined(I386_CPU)
|
||||||
|
@ -1012,6 +1014,7 @@ ENTRY(i486_copyout)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int copyin(const void *uaddr, void *kaddr, size_t len) */
|
/* LINTSTUB: Func: int copyin(const void *uaddr, void *kaddr, size_t len) */
|
||||||
ENTRY(copyin)
|
ENTRY(copyin)
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
jmp *_C_LABEL(copyin_func)
|
jmp *_C_LABEL(copyin_func)
|
||||||
|
|
||||||
#if defined(I386_CPU) || defined(I486_CPU) || defined(I586_CPU) || \
|
#if defined(I386_CPU) || defined(I486_CPU) || defined(I586_CPU) || \
|
||||||
|
@ -1062,6 +1065,19 @@ ENTRY(i386_copyin)
|
||||||
NENTRY(copy_efault)
|
NENTRY(copy_efault)
|
||||||
movl $EFAULT,%eax
|
movl $EFAULT,%eax
|
||||||
|
|
||||||
|
/*
|
||||||
|
* kcopy_fault is used by kcopy and copy_fault is used by copyin/out.
|
||||||
|
*
|
||||||
|
* they're distinguished for lazy pmap switching. see trap().
|
||||||
|
*/
|
||||||
|
/* LINTSTUB: Ignore */
|
||||||
|
NENTRY(kcopy_fault)
|
||||||
|
GET_CURPCB(%edx)
|
||||||
|
popl PCB_ONFAULT(%edx)
|
||||||
|
popl %edi
|
||||||
|
popl %esi
|
||||||
|
ret
|
||||||
|
|
||||||
/* LINTSTUB: Ignore */
|
/* LINTSTUB: Ignore */
|
||||||
NENTRY(copy_fault)
|
NENTRY(copy_fault)
|
||||||
GET_CURPCB(%edx)
|
GET_CURPCB(%edx)
|
||||||
|
@ -1083,6 +1099,8 @@ ENTRY(copyoutstr)
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
|
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
|
|
||||||
movl 12(%esp),%esi # esi = from
|
movl 12(%esp),%esi # esi = from
|
||||||
movl 16(%esp),%edi # edi = to
|
movl 16(%esp),%edi # edi = to
|
||||||
movl 20(%esp),%edx # edx = maxlen
|
movl 20(%esp),%edx # edx = maxlen
|
||||||
|
@ -1200,6 +1218,9 @@ ENTRY(copyoutstr)
|
||||||
ENTRY(copyinstr)
|
ENTRY(copyinstr)
|
||||||
pushl %esi
|
pushl %esi
|
||||||
pushl %edi
|
pushl %edi
|
||||||
|
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
|
|
||||||
GET_CURPCB(%ecx)
|
GET_CURPCB(%ecx)
|
||||||
movl $_C_LABEL(copystr_fault),PCB_ONFAULT(%ecx)
|
movl $_C_LABEL(copystr_fault),PCB_ONFAULT(%ecx)
|
||||||
|
|
||||||
|
@ -1311,6 +1332,7 @@ ENTRY(copystr)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: long fuword(const void *base) */
|
/* LINTSTUB: Func: long fuword(const void *base) */
|
||||||
ENTRY(fuword)
|
ENTRY(fuword)
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||||
ja _C_LABEL(fusuaddrfault)
|
ja _C_LABEL(fusuaddrfault)
|
||||||
|
@ -1327,6 +1349,7 @@ ENTRY(fuword)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int fusword(const void *base) */
|
/* LINTSTUB: Func: int fusword(const void *base) */
|
||||||
ENTRY(fusword)
|
ENTRY(fusword)
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
cmpl $VM_MAXUSER_ADDRESS-2,%edx
|
cmpl $VM_MAXUSER_ADDRESS-2,%edx
|
||||||
ja _C_LABEL(fusuaddrfault)
|
ja _C_LABEL(fusuaddrfault)
|
||||||
|
@ -1344,6 +1367,8 @@ ENTRY(fusword)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int fuswintr(const void *base) */
|
/* LINTSTUB: Func: int fuswintr(const void *base) */
|
||||||
ENTRY(fuswintr)
|
ENTRY(fuswintr)
|
||||||
|
cmpl $TLBSTATE_VALID, CPUVAR(TLBSTATE)
|
||||||
|
jnz _C_LABEL(fusuaddrfault)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
cmpl $VM_MAXUSER_ADDRESS-2,%edx
|
cmpl $VM_MAXUSER_ADDRESS-2,%edx
|
||||||
ja _C_LABEL(fusuaddrfault)
|
ja _C_LABEL(fusuaddrfault)
|
||||||
|
@ -1361,6 +1386,7 @@ ENTRY(fuswintr)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int fubyte(const void *base) */
|
/* LINTSTUB: Func: int fubyte(const void *base) */
|
||||||
ENTRY(fubyte)
|
ENTRY(fubyte)
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
cmpl $VM_MAXUSER_ADDRESS-1,%edx
|
cmpl $VM_MAXUSER_ADDRESS-1,%edx
|
||||||
ja _C_LABEL(fusuaddrfault)
|
ja _C_LABEL(fusuaddrfault)
|
||||||
|
@ -1405,6 +1431,7 @@ NENTRY(fusuaddrfault)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int suword(void *base, long c) */
|
/* LINTSTUB: Func: int suword(void *base, long c) */
|
||||||
ENTRY(suword)
|
ENTRY(suword)
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
cmpl $VM_MAXUSER_ADDRESS-4,%edx
|
||||||
ja _C_LABEL(fusuaddrfault)
|
ja _C_LABEL(fusuaddrfault)
|
||||||
|
@ -1452,6 +1479,7 @@ ENTRY(suword)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int susword(void *base, short c) */
|
/* LINTSTUB: Func: int susword(void *base, short c) */
|
||||||
ENTRY(susword)
|
ENTRY(susword)
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
cmpl $VM_MAXUSER_ADDRESS-2,%edx
|
cmpl $VM_MAXUSER_ADDRESS-2,%edx
|
||||||
ja _C_LABEL(fusuaddrfault)
|
ja _C_LABEL(fusuaddrfault)
|
||||||
|
@ -1500,6 +1528,8 @@ ENTRY(susword)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int suswintr(void *base, short c) */
|
/* LINTSTUB: Func: int suswintr(void *base, short c) */
|
||||||
ENTRY(suswintr)
|
ENTRY(suswintr)
|
||||||
|
cmpl $TLBSTATE_VALID, CPUVAR(TLBSTATE)
|
||||||
|
jnz _C_LABEL(fusuaddrfault)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
cmpl $VM_MAXUSER_ADDRESS-2,%edx
|
cmpl $VM_MAXUSER_ADDRESS-2,%edx
|
||||||
ja _C_LABEL(fusuaddrfault)
|
ja _C_LABEL(fusuaddrfault)
|
||||||
|
@ -1537,6 +1567,7 @@ ENTRY(suswintr)
|
||||||
*/
|
*/
|
||||||
/* LINTSTUB: Func: int subyte(void *base, int c) */
|
/* LINTSTUB: Func: int subyte(void *base, int c) */
|
||||||
ENTRY(subyte)
|
ENTRY(subyte)
|
||||||
|
DO_DEFERRED_SWITCH(%eax)
|
||||||
movl 4(%esp),%edx
|
movl 4(%esp),%edx
|
||||||
cmpl $VM_MAXUSER_ADDRESS-1,%edx
|
cmpl $VM_MAXUSER_ADDRESS-1,%edx
|
||||||
ja _C_LABEL(fusuaddrfault)
|
ja _C_LABEL(fusuaddrfault)
|
||||||
|
@ -1722,7 +1753,7 @@ ENTRY(cpu_switch)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pushl %esi
|
pushl %esi
|
||||||
call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc)
|
call _C_LABEL(pmap_deactivate2) # pmap_deactivate(oldproc)
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
|
|
||||||
movl L_ADDR(%esi),%esi
|
movl L_ADDR(%esi),%esi
|
||||||
|
@ -1749,11 +1780,6 @@ ENTRY(cpu_switch)
|
||||||
movl PCB_ESP(%edi),%esp
|
movl PCB_ESP(%edi),%esp
|
||||||
movl PCB_EBP(%edi),%ebp
|
movl PCB_EBP(%edi),%ebp
|
||||||
|
|
||||||
|
|
||||||
/* Switch address space. */
|
|
||||||
movl PCB_CR3(%edi),%ecx
|
|
||||||
movl %ecx,%cr3
|
|
||||||
|
|
||||||
/* Switch TSS. Reset "task busy" flag before loading. */
|
/* Switch TSS. Reset "task busy" flag before loading. */
|
||||||
#ifdef MULTIPROCESSOR
|
#ifdef MULTIPROCESSOR
|
||||||
movl CPUVAR(GDT),%eax
|
movl CPUVAR(GDT),%eax
|
||||||
|
@ -1872,7 +1898,7 @@ switch_resume:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pushl %esi
|
pushl %esi
|
||||||
call _C_LABEL(pmap_deactivate) # pmap_deactivate(oldproc)
|
call _C_LABEL(pmap_deactivate2) # pmap_deactivate(oldproc)
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
|
|
||||||
movl L_ADDR(%esi),%esi
|
movl L_ADDR(%esi),%esi
|
||||||
|
@ -2066,10 +2092,6 @@ ENTRY(cpu_exit)
|
||||||
movl _C_LABEL(gdt),%eax
|
movl _C_LABEL(gdt),%eax
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Switch address space. */
|
|
||||||
movl PCB_CR3(%esi),%ecx
|
|
||||||
movl %ecx,%cr3
|
|
||||||
|
|
||||||
/* Switch TSS. */
|
/* Switch TSS. */
|
||||||
andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
|
andl $~0x0200,4-SEL_KPL(%eax,%edx,1)
|
||||||
ltr %dx
|
ltr %dx
|
||||||
|
@ -2134,6 +2156,12 @@ syscall1:
|
||||||
INTRENTRY
|
INTRENTRY
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
|
cmpl $0, CPUVAR(WANT_PMAPLOAD)
|
||||||
|
jz 1f
|
||||||
|
pushl $6f
|
||||||
|
call _C_LABEL(printf)
|
||||||
|
addl $4, %esp
|
||||||
|
1:
|
||||||
movl CPUVAR(ILEVEL),%ebx
|
movl CPUVAR(ILEVEL),%ebx
|
||||||
testl %ebx,%ebx
|
testl %ebx,%ebx
|
||||||
jz 1f
|
jz 1f
|
||||||
|
@ -2151,7 +2179,8 @@ syscall1:
|
||||||
pushl %esp
|
pushl %esp
|
||||||
call *P_MD_SYSCALL(%edx) # get pointer to syscall() function
|
call *P_MD_SYSCALL(%edx) # get pointer to syscall() function
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
2: /* Check for ASTs on exit to user mode. */
|
syscall_checkast:
|
||||||
|
/* Check for ASTs on exit to user mode. */
|
||||||
cli
|
cli
|
||||||
CHECK_ASTPENDING(%eax)
|
CHECK_ASTPENDING(%eax)
|
||||||
je 1f
|
je 1f
|
||||||
|
@ -2162,11 +2191,13 @@ syscall1:
|
||||||
pushl %esp
|
pushl %esp
|
||||||
call _C_LABEL(trap)
|
call _C_LABEL(trap)
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
jmp 2b
|
jmp syscall_checkast /* re-check ASTs */
|
||||||
|
1: CHECK_DEFERRED_SWITCH(%eax)
|
||||||
|
jnz 9f
|
||||||
#ifndef DIAGNOSTIC
|
#ifndef DIAGNOSTIC
|
||||||
1: INTRFASTEXIT
|
INTRFASTEXIT
|
||||||
#else /* DIAGNOSTIC */
|
#else /* DIAGNOSTIC */
|
||||||
1: cmpl $IPL_NONE,CPUVAR(ILEVEL)
|
cmpl $IPL_NONE,CPUVAR(ILEVEL)
|
||||||
jne 3f
|
jne 3f
|
||||||
INTRFASTEXIT
|
INTRFASTEXIT
|
||||||
3: sti
|
3: sti
|
||||||
|
@ -2180,7 +2211,11 @@ syscall1:
|
||||||
jmp 2b
|
jmp 2b
|
||||||
4: .asciz "WARNING: SPL NOT LOWERED ON SYSCALL EXIT\n"
|
4: .asciz "WARNING: SPL NOT LOWERED ON SYSCALL EXIT\n"
|
||||||
5: .asciz "WARNING: SPL NOT ZERO ON SYSCALL ENTRY\n"
|
5: .asciz "WARNING: SPL NOT ZERO ON SYSCALL ENTRY\n"
|
||||||
|
6: .asciz "WARNING: WANT PMAPLOAD ON SYSCALL ENTRY\n"
|
||||||
#endif /* DIAGNOSTIC */
|
#endif /* DIAGNOSTIC */
|
||||||
|
9: sti
|
||||||
|
call _C_LABEL(pmap_load)
|
||||||
|
jmp syscall_checkast /* re-check ASTs */
|
||||||
|
|
||||||
#if NNPX > 0
|
#if NNPX > 0
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: mach_sigcode.S,v 1.5 2003/08/20 21:48:37 fvdl Exp $ */
|
/* $NetBSD: mach_sigcode.S,v 1.6 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||||
|
@ -125,4 +125,10 @@ IDTVEC(mach_trap)
|
||||||
call _C_LABEL(trap)
|
call _C_LABEL(trap)
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
jmp 2b
|
jmp 2b
|
||||||
1: INTRFASTEXIT
|
1: CHECK_DEFERRED_SWITCH(%eax)
|
||||||
|
jnz 9f
|
||||||
|
INTRFASTEXIT
|
||||||
|
9: sti
|
||||||
|
call _C_LABEL(pmap_load)
|
||||||
|
cli
|
||||||
|
jmp 2b
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pmap.c,v 1.170 2004/02/13 11:36:14 wiz Exp $ */
|
/* $NetBSD: pmap.c,v 1.171 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -60,7 +60,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.170 2004/02/13 11:36:14 wiz Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.171 2004/02/20 17:35:01 yamt Exp $");
|
||||||
|
|
||||||
#include "opt_cputype.h"
|
#include "opt_cputype.h"
|
||||||
#include "opt_user_ldt.h"
|
#include "opt_user_ldt.h"
|
||||||
|
@ -501,6 +501,8 @@ static void pmap_tmpunmap_pa(void);
|
||||||
static void pmap_tmpunmap_pvepte(struct pv_entry *);
|
static void pmap_tmpunmap_pvepte(struct pv_entry *);
|
||||||
static void pmap_unmap_ptes(struct pmap *);
|
static void pmap_unmap_ptes(struct pmap *);
|
||||||
|
|
||||||
|
static boolean_t pmap_reactivate(struct pmap *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* p m a p i n l i n e h e l p e r f u n c t i o n s
|
* p m a p i n l i n e h e l p e r f u n c t i o n s
|
||||||
*/
|
*/
|
||||||
|
@ -514,8 +516,9 @@ __inline static boolean_t
|
||||||
pmap_is_curpmap(pmap)
|
pmap_is_curpmap(pmap)
|
||||||
struct pmap *pmap;
|
struct pmap *pmap;
|
||||||
{
|
{
|
||||||
|
|
||||||
return((pmap == pmap_kernel()) ||
|
return((pmap == pmap_kernel()) ||
|
||||||
(pmap->pm_pdirpa == (paddr_t) rcr3()));
|
(pmap == curcpu()->ci_pmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -663,24 +666,33 @@ pmap_map_ptes(pmap)
|
||||||
struct pmap *pmap;
|
struct pmap *pmap;
|
||||||
{
|
{
|
||||||
pd_entry_t opde;
|
pd_entry_t opde;
|
||||||
|
struct pmap *ourpmap;
|
||||||
|
struct cpu_info *ci;
|
||||||
|
|
||||||
/* the kernel's pmap is always accessible */
|
/* the kernel's pmap is always accessible */
|
||||||
if (pmap == pmap_kernel()) {
|
if (pmap == pmap_kernel()) {
|
||||||
return(PTE_BASE);
|
return(PTE_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ci = curcpu();
|
||||||
|
if (ci->ci_want_pmapload &&
|
||||||
|
vm_map_pmap(&ci->ci_curlwp->l_proc->p_vmspace->vm_map) == pmap)
|
||||||
|
pmap_load();
|
||||||
|
|
||||||
/* if curpmap then we are always mapped */
|
/* if curpmap then we are always mapped */
|
||||||
if (pmap_is_curpmap(pmap)) {
|
if (pmap_is_curpmap(pmap)) {
|
||||||
simple_lock(&pmap->pm_obj.vmobjlock);
|
simple_lock(&pmap->pm_obj.vmobjlock);
|
||||||
return(PTE_BASE);
|
return(PTE_BASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ourpmap = ci->ci_pmap;
|
||||||
|
|
||||||
/* need to lock both curpmap and pmap: use ordered locking */
|
/* need to lock both curpmap and pmap: use ordered locking */
|
||||||
if ((unsigned) pmap < (unsigned) curpcb->pcb_pmap) {
|
if ((unsigned) pmap < (unsigned) ourpmap) {
|
||||||
simple_lock(&pmap->pm_obj.vmobjlock);
|
simple_lock(&pmap->pm_obj.vmobjlock);
|
||||||
simple_lock(&curpcb->pcb_pmap->pm_obj.vmobjlock);
|
simple_lock(&ourpmap->pm_obj.vmobjlock);
|
||||||
} else {
|
} else {
|
||||||
simple_lock(&curpcb->pcb_pmap->pm_obj.vmobjlock);
|
simple_lock(&ourpmap->pm_obj.vmobjlock);
|
||||||
simple_lock(&pmap->pm_obj.vmobjlock);
|
simple_lock(&pmap->pm_obj.vmobjlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -690,7 +702,7 @@ pmap_map_ptes(pmap)
|
||||||
if (!pmap_valid_entry(opde) || (opde & PG_FRAME) != pmap->pm_pdirpa) {
|
if (!pmap_valid_entry(opde) || (opde & PG_FRAME) != pmap->pm_pdirpa) {
|
||||||
*APDP_PDE = (pd_entry_t) (pmap->pm_pdirpa | PG_RW | PG_V);
|
*APDP_PDE = (pd_entry_t) (pmap->pm_pdirpa | PG_RW | PG_V);
|
||||||
if (pmap_valid_entry(opde))
|
if (pmap_valid_entry(opde))
|
||||||
pmap_apte_flush(curpcb->pcb_pmap);
|
pmap_apte_flush(ourpmap);
|
||||||
}
|
}
|
||||||
return(APTE_BASE);
|
return(APTE_BASE);
|
||||||
}
|
}
|
||||||
|
@ -703,19 +715,22 @@ __inline static void
|
||||||
pmap_unmap_ptes(pmap)
|
pmap_unmap_ptes(pmap)
|
||||||
struct pmap *pmap;
|
struct pmap *pmap;
|
||||||
{
|
{
|
||||||
|
|
||||||
if (pmap == pmap_kernel()) {
|
if (pmap == pmap_kernel()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (pmap_is_curpmap(pmap)) {
|
if (pmap_is_curpmap(pmap)) {
|
||||||
simple_unlock(&pmap->pm_obj.vmobjlock);
|
simple_unlock(&pmap->pm_obj.vmobjlock);
|
||||||
} else {
|
} else {
|
||||||
|
struct pmap *ourpmap = curcpu()->ci_pmap;
|
||||||
|
|
||||||
#if defined(MULTIPROCESSOR)
|
#if defined(MULTIPROCESSOR)
|
||||||
*APDP_PDE = 0;
|
*APDP_PDE = 0;
|
||||||
pmap_apte_flush(curpcb->pcb_pmap);
|
pmap_apte_flush(ourpmap);
|
||||||
#endif
|
#endif
|
||||||
COUNT(apdp_pde_unmap);
|
COUNT(apdp_pde_unmap);
|
||||||
simple_unlock(&pmap->pm_obj.vmobjlock);
|
simple_unlock(&pmap->pm_obj.vmobjlock);
|
||||||
simple_unlock(&curpcb->pcb_pmap->pm_obj.vmobjlock);
|
simple_unlock(&ourpmap->pm_obj.vmobjlock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,8 +967,6 @@ pmap_bootstrap(kva_start)
|
||||||
* operation of the system.
|
* operation of the system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
curpcb->pcb_pmap = kpm; /* proc0's pcb */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Begin to enable global TLB entries if they are supported.
|
* Begin to enable global TLB entries if they are supported.
|
||||||
* The G bit has no effect until the CR4_PGE bit is set in CR4,
|
* The G bit has no effect until the CR4_PGE bit is set in CR4,
|
||||||
|
@ -1764,6 +1777,10 @@ pmap_destroy(pmap)
|
||||||
struct pmap *pmap;
|
struct pmap *pmap;
|
||||||
{
|
{
|
||||||
int refs;
|
int refs;
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
struct cpu_info *ci;
|
||||||
|
CPU_INFO_ITERATOR cii;
|
||||||
|
#endif /* DIAGNOSTIC */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* drop reference count
|
* drop reference count
|
||||||
|
@ -1776,6 +1793,12 @@ pmap_destroy(pmap)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef DIAGNOSTIC
|
||||||
|
for (CPU_INFO_FOREACH(cii, ci))
|
||||||
|
if (ci->ci_pmap == pmap)
|
||||||
|
panic("destroying pmap being used");
|
||||||
|
#endif /* DIAGNOSTIC */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* reference count is zero, free pmap resources and then free pmap.
|
* reference count is zero, free pmap resources and then free pmap.
|
||||||
*/
|
*/
|
||||||
|
@ -1904,31 +1927,26 @@ pmap_ldt_cleanup(l)
|
||||||
#endif /* USER_LDT */
|
#endif /* USER_LDT */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pmap_activate: activate a process' pmap (fill in %cr3 and LDT info)
|
* pmap_activate: activate a process' pmap
|
||||||
*
|
*
|
||||||
* => called from cpu_switch()
|
* => called from cpu_switch()
|
||||||
* => if proc is the curlwp, then load it into the MMU
|
* => if lwp is the curlwp, then set ci_want_pmapload so that
|
||||||
|
* actual MMU context switch will be done by pmap_load() later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
pmap_activate(l)
|
pmap_activate(l)
|
||||||
struct lwp *l;
|
struct lwp *l;
|
||||||
{
|
{
|
||||||
|
struct cpu_info *ci = curcpu();
|
||||||
struct pcb *pcb = &l->l_addr->u_pcb;
|
struct pcb *pcb = &l->l_addr->u_pcb;
|
||||||
struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap;
|
struct pmap *pmap = vm_map_pmap(&l->l_proc->p_vmspace->vm_map);
|
||||||
|
|
||||||
pcb->pcb_pmap = pmap;
|
|
||||||
pcb->pcb_ldt_sel = pmap->pm_ldt_sel;
|
pcb->pcb_ldt_sel = pmap->pm_ldt_sel;
|
||||||
pcb->pcb_cr3 = pmap->pm_pdirpa;
|
pcb->pcb_cr3 = pmap->pm_pdirpa;
|
||||||
if (l == curlwp) {
|
if (l == ci->ci_curlwp) {
|
||||||
lcr3(pcb->pcb_cr3);
|
KASSERT(ci->ci_want_pmapload == 0);
|
||||||
lldt(pcb->pcb_ldt_sel);
|
KASSERT(ci->ci_tlbstate != TLBSTATE_VALID);
|
||||||
|
|
||||||
/*
|
|
||||||
* mark the pmap in use by this processor.
|
|
||||||
*/
|
|
||||||
x86_atomic_setbits_l(&pmap->pm_cpus, (1U << cpu_number()));
|
|
||||||
|
|
||||||
#ifdef KSTACK_CHECK_DR0
|
#ifdef KSTACK_CHECK_DR0
|
||||||
/*
|
/*
|
||||||
* setup breakpoint on the top of stack
|
* setup breakpoint on the top of stack
|
||||||
|
@ -1938,9 +1956,130 @@ pmap_activate(l)
|
||||||
else
|
else
|
||||||
dr0(KSTACK_LOWEST_ADDR(l), 1, 3, 1);
|
dr0(KSTACK_LOWEST_ADDR(l), 1, 3, 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* no need to switch to kernel vmspace because
|
||||||
|
* it's a subset of any vmspace.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (pmap == pmap_kernel()) {
|
||||||
|
ci->ci_want_pmapload = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ci->ci_want_pmapload = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pmap_reactivate: try to regain reference to the pmap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static boolean_t
|
||||||
|
pmap_reactivate(struct pmap *pmap)
|
||||||
|
{
|
||||||
|
struct cpu_info *ci = curcpu();
|
||||||
|
u_int32_t cpumask = 1U << ci->ci_cpuid;
|
||||||
|
int s;
|
||||||
|
boolean_t result;
|
||||||
|
u_int32_t oldcpus;
|
||||||
|
|
||||||
|
KASSERT(pmap->pm_pdirpa == rcr3());
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if we still have a lazy reference to this pmap,
|
||||||
|
* we can assume that there was no tlb shootdown
|
||||||
|
* for this pmap in the meantime.
|
||||||
|
*/
|
||||||
|
|
||||||
|
s = splipi(); /* protect from tlb shootdown ipis. */
|
||||||
|
oldcpus = pmap->pm_cpus;
|
||||||
|
x86_atomic_setbits_l(&pmap->pm_cpus, cpumask);
|
||||||
|
if (oldcpus & cpumask) {
|
||||||
|
KASSERT(ci->ci_tlbstate == TLBSTATE_LAZY);
|
||||||
|
/* got it */
|
||||||
|
result = TRUE;
|
||||||
|
} else {
|
||||||
|
KASSERT(ci->ci_tlbstate == TLBSTATE_STALE);
|
||||||
|
result = FALSE;
|
||||||
|
}
|
||||||
|
ci->ci_tlbstate = TLBSTATE_VALID;
|
||||||
|
splx(s);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pmap_load: actually switch pmap. (fill in %cr3 and LDT info)
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
pmap_load()
|
||||||
|
{
|
||||||
|
struct cpu_info *ci = curcpu();
|
||||||
|
u_int32_t cpumask = 1U << ci->ci_cpuid;
|
||||||
|
struct pmap *pmap;
|
||||||
|
struct pmap *oldpmap;
|
||||||
|
struct lwp *l;
|
||||||
|
int s;
|
||||||
|
|
||||||
|
KASSERT(ci->ci_want_pmapload);
|
||||||
|
|
||||||
|
l = ci->ci_curlwp;
|
||||||
|
KASSERT(l != NULL);
|
||||||
|
pmap = vm_map_pmap(&l->l_proc->p_vmspace->vm_map);
|
||||||
|
KASSERT(pmap != pmap_kernel());
|
||||||
|
oldpmap = ci->ci_pmap;
|
||||||
|
|
||||||
|
KASSERT(pmap->pm_ldt_sel == l->l_addr->u_pcb.pcb_ldt_sel);
|
||||||
|
lldt(pmap->pm_ldt_sel);
|
||||||
|
|
||||||
|
if (pmap == oldpmap) {
|
||||||
|
if (!pmap_reactivate(pmap)) {
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pmap has been changed during deactivated.
|
||||||
|
* our tlb may be stale.
|
||||||
|
*/
|
||||||
|
|
||||||
|
tlbflush();
|
||||||
|
}
|
||||||
|
|
||||||
|
ci->ci_want_pmapload = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* actually switch pmap.
|
||||||
|
*/
|
||||||
|
|
||||||
|
x86_atomic_clearbits_l(&oldpmap->pm_cpus, cpumask);
|
||||||
|
|
||||||
|
KASSERT(oldpmap->pm_pdirpa == rcr3());
|
||||||
|
KASSERT((pmap->pm_cpus & cpumask) == 0);
|
||||||
|
|
||||||
|
KERNEL_LOCK(LK_EXCLUSIVE | LK_CANRECURSE);
|
||||||
|
pmap_reference(pmap);
|
||||||
|
KERNEL_UNLOCK();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* mark the pmap in use by this processor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
s = splipi();
|
||||||
|
x86_atomic_setbits_l(&pmap->pm_cpus, cpumask);
|
||||||
|
ci->ci_pmap = pmap;
|
||||||
|
ci->ci_tlbstate = TLBSTATE_VALID;
|
||||||
|
splx(s);
|
||||||
|
lcr3(pmap->pm_pdirpa);
|
||||||
|
|
||||||
|
ci->ci_want_pmapload = 0;
|
||||||
|
|
||||||
|
KERNEL_LOCK(LK_EXCLUSIVE | LK_CANRECURSE);
|
||||||
|
pmap_destroy(oldpmap);
|
||||||
|
KERNEL_UNLOCK();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pmap_deactivate: deactivate a process' pmap
|
* pmap_deactivate: deactivate a process' pmap
|
||||||
*/
|
*/
|
||||||
|
@ -1949,12 +2088,49 @@ void
|
||||||
pmap_deactivate(l)
|
pmap_deactivate(l)
|
||||||
struct lwp *l;
|
struct lwp *l;
|
||||||
{
|
{
|
||||||
struct pmap *pmap = l->l_proc->p_vmspace->vm_map.pmap;
|
|
||||||
|
|
||||||
/*
|
if (l == curlwp)
|
||||||
* mark the pmap no longer in use by this processor.
|
pmap_deactivate2(l);
|
||||||
*/
|
}
|
||||||
x86_atomic_clearbits_l(&pmap->pm_cpus, (1U << cpu_number()));
|
|
||||||
|
/*
|
||||||
|
* pmap_deactivate2: context switch version of pmap_deactivate.
|
||||||
|
* always treat l as curlwp.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
pmap_deactivate2(l)
|
||||||
|
struct lwp *l;
|
||||||
|
{
|
||||||
|
struct pmap *pmap;
|
||||||
|
struct cpu_info *ci = curcpu();
|
||||||
|
|
||||||
|
if (ci->ci_want_pmapload) {
|
||||||
|
KASSERT(vm_map_pmap(&l->l_proc->p_vmspace->vm_map)
|
||||||
|
!= pmap_kernel());
|
||||||
|
KASSERT(vm_map_pmap(&l->l_proc->p_vmspace->vm_map)
|
||||||
|
!= ci->ci_pmap || ci->ci_tlbstate != TLBSTATE_VALID);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* userspace has not been touched.
|
||||||
|
* nothing to do here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ci->ci_want_pmapload = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pmap = vm_map_pmap(&l->l_proc->p_vmspace->vm_map);
|
||||||
|
|
||||||
|
if (pmap == pmap_kernel()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
KASSERT(pmap->pm_pdirpa == rcr3());
|
||||||
|
KASSERT(ci->ci_pmap == pmap);
|
||||||
|
|
||||||
|
KASSERT(ci->ci_tlbstate == TLBSTATE_VALID);
|
||||||
|
ci->ci_tlbstate = TLBSTATE_LAZY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -2380,6 +2556,8 @@ pmap_do_remove(pmap, sva, eva, flags)
|
||||||
struct vm_page *ptp;
|
struct vm_page *ptp;
|
||||||
int32_t cpumask = 0;
|
int32_t cpumask = 0;
|
||||||
TAILQ_HEAD(, vm_page) empty_ptps;
|
TAILQ_HEAD(, vm_page) empty_ptps;
|
||||||
|
struct cpu_info *ci;
|
||||||
|
struct pmap *curpmap;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* we lock in the pmap => pv_head direction
|
* we lock in the pmap => pv_head direction
|
||||||
|
@ -2388,8 +2566,12 @@ pmap_do_remove(pmap, sva, eva, flags)
|
||||||
TAILQ_INIT(&empty_ptps);
|
TAILQ_INIT(&empty_ptps);
|
||||||
|
|
||||||
PMAP_MAP_TO_HEAD_LOCK();
|
PMAP_MAP_TO_HEAD_LOCK();
|
||||||
|
|
||||||
ptes = pmap_map_ptes(pmap); /* locks pmap */
|
ptes = pmap_map_ptes(pmap); /* locks pmap */
|
||||||
|
|
||||||
|
ci = curcpu();
|
||||||
|
curpmap = ci->ci_pmap;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* removing one page? take shortcut function.
|
* removing one page? take shortcut function.
|
||||||
*/
|
*/
|
||||||
|
@ -2438,7 +2620,7 @@ pmap_do_remove(pmap, sva, eva, flags)
|
||||||
* here if we're using APTE space.
|
* here if we're using APTE space.
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
pmap_tlb_shootdown(curpcb->pcb_pmap,
|
pmap_tlb_shootdown(curpmap,
|
||||||
((vaddr_t)ptes) + ptp->offset, opte,
|
((vaddr_t)ptes) + ptp->offset, opte,
|
||||||
&cpumask);
|
&cpumask);
|
||||||
#if defined(MULTIPROCESSOR)
|
#if defined(MULTIPROCESSOR)
|
||||||
|
@ -2446,8 +2628,7 @@ pmap_do_remove(pmap, sva, eva, flags)
|
||||||
* Always shoot down the pmap's self-mapping
|
* Always shoot down the pmap's self-mapping
|
||||||
* of the PTP.
|
* of the PTP.
|
||||||
* XXXthorpej Redundant shootdown can happen
|
* XXXthorpej Redundant shootdown can happen
|
||||||
* here if pmap == curpcb->pcb_pmap (not APTE
|
* here if pmap == curpmap (not APTE space).
|
||||||
* space).
|
|
||||||
*/
|
*/
|
||||||
pmap_tlb_shootdown(pmap,
|
pmap_tlb_shootdown(pmap,
|
||||||
((vaddr_t)PTE_BASE) + ptp->offset, opte,
|
((vaddr_t)PTE_BASE) + ptp->offset, opte,
|
||||||
|
@ -2537,14 +2718,14 @@ pmap_do_remove(pmap, sva, eva, flags)
|
||||||
* if we're using APTE space.
|
* if we're using APTE space.
|
||||||
*/
|
*/
|
||||||
#endif
|
#endif
|
||||||
pmap_tlb_shootdown(curpcb->pcb_pmap,
|
pmap_tlb_shootdown(curpmap,
|
||||||
((vaddr_t)ptes) + ptp->offset, opte, &cpumask);
|
((vaddr_t)ptes) + ptp->offset, opte, &cpumask);
|
||||||
#if defined(MULTIPROCESSOR)
|
#if defined(MULTIPROCESSOR)
|
||||||
/*
|
/*
|
||||||
* Always shoot down the pmap's self-mapping
|
* Always shoot down the pmap's self-mapping
|
||||||
* of the PTP.
|
* of the PTP.
|
||||||
* XXXthorpej Redundant shootdown can happen here
|
* XXXthorpej Redundant shootdown can happen here
|
||||||
* if pmap == curpcb->pcb_pmap (not APTE space).
|
* if pmap == curpmap (not APTE space).
|
||||||
*/
|
*/
|
||||||
pmap_tlb_shootdown(pmap,
|
pmap_tlb_shootdown(pmap,
|
||||||
((vaddr_t)PTE_BASE) + ptp->offset, opte, &cpumask);
|
((vaddr_t)PTE_BASE) + ptp->offset, opte, &cpumask);
|
||||||
|
@ -2585,6 +2766,8 @@ pmap_page_remove(pg)
|
||||||
int32_t cpumask = 0;
|
int32_t cpumask = 0;
|
||||||
TAILQ_HEAD(, vm_page) empty_ptps;
|
TAILQ_HEAD(, vm_page) empty_ptps;
|
||||||
struct vm_page *ptp;
|
struct vm_page *ptp;
|
||||||
|
struct cpu_info *ci;
|
||||||
|
struct pmap *curpmap;
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
int bank, off;
|
int bank, off;
|
||||||
|
@ -2604,6 +2787,9 @@ pmap_page_remove(pg)
|
||||||
/* set pv_head => pmap locking */
|
/* set pv_head => pmap locking */
|
||||||
PMAP_HEAD_TO_MAP_LOCK();
|
PMAP_HEAD_TO_MAP_LOCK();
|
||||||
|
|
||||||
|
ci = curcpu();
|
||||||
|
curpmap = ci->ci_pmap;
|
||||||
|
|
||||||
/* XXX: needed if we hold head->map lock? */
|
/* XXX: needed if we hold head->map lock? */
|
||||||
simple_lock(&pvh->pvh_lock);
|
simple_lock(&pvh->pvh_lock);
|
||||||
|
|
||||||
|
@ -2657,7 +2843,7 @@ pmap_page_remove(pg)
|
||||||
opte = x86_atomic_testset_ul(
|
opte = x86_atomic_testset_ul(
|
||||||
&pve->pv_pmap->pm_pdir[pdei(pve->pv_va)],
|
&pve->pv_pmap->pm_pdir[pdei(pve->pv_va)],
|
||||||
0);
|
0);
|
||||||
pmap_tlb_shootdown(curpcb->pcb_pmap,
|
pmap_tlb_shootdown(curpmap,
|
||||||
((vaddr_t)ptes) + pve->pv_ptp->offset,
|
((vaddr_t)ptes) + pve->pv_ptp->offset,
|
||||||
opte, &cpumask);
|
opte, &cpumask);
|
||||||
#if defined(MULTIPROCESSOR)
|
#if defined(MULTIPROCESSOR)
|
||||||
|
@ -3427,8 +3613,9 @@ pmap_dump(pmap, sva, eva)
|
||||||
void
|
void
|
||||||
pmap_tlb_shootnow(int32_t cpumask)
|
pmap_tlb_shootnow(int32_t cpumask)
|
||||||
{
|
{
|
||||||
|
struct cpu_info *self;
|
||||||
#ifdef MULTIPROCESSOR
|
#ifdef MULTIPROCESSOR
|
||||||
struct cpu_info *ci, *self;
|
struct cpu_info *ci;
|
||||||
CPU_INFO_ITERATOR cii;
|
CPU_INFO_ITERATOR cii;
|
||||||
int s;
|
int s;
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
|
@ -3439,13 +3626,13 @@ pmap_tlb_shootnow(int32_t cpumask)
|
||||||
if (cpumask == 0)
|
if (cpumask == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#ifdef MULTIPROCESSOR
|
|
||||||
self = curcpu();
|
self = curcpu();
|
||||||
|
#ifdef MULTIPROCESSOR
|
||||||
s = splipi();
|
s = splipi();
|
||||||
self->ci_tlb_ipi_mask = cpumask;
|
self->ci_tlb_ipi_mask = cpumask;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pmap_do_tlb_shootdown(0); /* do *our* work. */
|
pmap_do_tlb_shootdown(self); /* do *our* work. */
|
||||||
|
|
||||||
#ifdef MULTIPROCESSOR
|
#ifdef MULTIPROCESSOR
|
||||||
splx(s);
|
splx(s);
|
||||||
|
@ -3584,6 +3771,40 @@ pmap_tlb_shootdown(pmap, va, pte, cpumaskp)
|
||||||
splx(s);
|
splx(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* pmap_do_tlb_shootdown_checktlbstate: check and update ci_tlbstate.
|
||||||
|
*
|
||||||
|
* => called at splipi.
|
||||||
|
* => return TRUE if we need to maintain user tlbs.
|
||||||
|
*/
|
||||||
|
static __inline boolean_t
|
||||||
|
pmap_do_tlb_shootdown_checktlbstate(struct cpu_info *ci)
|
||||||
|
{
|
||||||
|
|
||||||
|
KASSERT(ci == curcpu());
|
||||||
|
|
||||||
|
if (ci->ci_tlbstate == TLBSTATE_LAZY) {
|
||||||
|
KASSERT(ci->ci_pmap != pmap_kernel());
|
||||||
|
/*
|
||||||
|
* mostly KASSERT(ci->ci_pmap->pm_cpus & (1U << ci->ci_cpuid));
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we no longer want tlb shootdown ipis for this pmap.
|
||||||
|
* mark the pmap no longer in use by this processor.
|
||||||
|
*/
|
||||||
|
|
||||||
|
x86_atomic_clearbits_l(&ci->ci_pmap->pm_cpus,
|
||||||
|
1U << ci->ci_cpuid);
|
||||||
|
ci->ci_tlbstate = TLBSTATE_STALE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ci->ci_tlbstate == TLBSTATE_STALE)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pmap_do_tlb_shootdown:
|
* pmap_do_tlb_shootdown:
|
||||||
*
|
*
|
||||||
|
@ -3592,7 +3813,7 @@ pmap_tlb_shootdown(pmap, va, pte, cpumaskp)
|
||||||
void
|
void
|
||||||
pmap_do_tlb_shootdown(struct cpu_info *self)
|
pmap_do_tlb_shootdown(struct cpu_info *self)
|
||||||
{
|
{
|
||||||
u_long cpu_id = cpu_number();
|
u_long cpu_id = self->ci_cpuid;
|
||||||
struct pmap_tlb_shootdown_q *pq = &pmap_tlb_shootdown_q[cpu_id];
|
struct pmap_tlb_shootdown_q *pq = &pmap_tlb_shootdown_q[cpu_id];
|
||||||
struct pmap_tlb_shootdown_job *pj;
|
struct pmap_tlb_shootdown_job *pj;
|
||||||
int s;
|
int s;
|
||||||
|
@ -3600,6 +3821,7 @@ pmap_do_tlb_shootdown(struct cpu_info *self)
|
||||||
struct cpu_info *ci;
|
struct cpu_info *ci;
|
||||||
CPU_INFO_ITERATOR cii;
|
CPU_INFO_ITERATOR cii;
|
||||||
#endif
|
#endif
|
||||||
|
KASSERT(self == curcpu());
|
||||||
|
|
||||||
s = splipi();
|
s = splipi();
|
||||||
|
|
||||||
|
@ -3607,6 +3829,7 @@ pmap_do_tlb_shootdown(struct cpu_info *self)
|
||||||
|
|
||||||
if (pq->pq_flushg) {
|
if (pq->pq_flushg) {
|
||||||
COUNT(flushg);
|
COUNT(flushg);
|
||||||
|
pmap_do_tlb_shootdown_checktlbstate(self);
|
||||||
tlbflushg();
|
tlbflushg();
|
||||||
pq->pq_flushg = 0;
|
pq->pq_flushg = 0;
|
||||||
pq->pq_flushu = 0;
|
pq->pq_flushu = 0;
|
||||||
|
@ -3618,14 +3841,20 @@ pmap_do_tlb_shootdown(struct cpu_info *self)
|
||||||
*/
|
*/
|
||||||
if (pq->pq_flushu) {
|
if (pq->pq_flushu) {
|
||||||
COUNT(flushu);
|
COUNT(flushu);
|
||||||
|
pmap_do_tlb_shootdown_checktlbstate(self);
|
||||||
tlbflush();
|
tlbflush();
|
||||||
}
|
}
|
||||||
while ((pj = TAILQ_FIRST(&pq->pq_head)) != NULL) {
|
while ((pj = TAILQ_FIRST(&pq->pq_head)) != NULL) {
|
||||||
TAILQ_REMOVE(&pq->pq_head, pj, pj_list);
|
TAILQ_REMOVE(&pq->pq_head, pj, pj_list);
|
||||||
|
|
||||||
if ((!pq->pq_flushu && pmap_is_curpmap(pj->pj_pmap)) ||
|
if ((pj->pj_pte & pmap_pg_g) ||
|
||||||
(pj->pj_pte & pmap_pg_g))
|
pj->pj_pmap == pmap_kernel()) {
|
||||||
pmap_update_pg(pj->pj_va);
|
pmap_update_pg(pj->pj_va);
|
||||||
|
} else if (!pq->pq_flushu &&
|
||||||
|
pj->pj_pmap == self->ci_pmap) {
|
||||||
|
if (pmap_do_tlb_shootdown_checktlbstate(self))
|
||||||
|
pmap_update_pg(pj->pj_va);
|
||||||
|
}
|
||||||
|
|
||||||
pmap_tlb_shootdown_job_put(pq, pj);
|
pmap_tlb_shootdown_job_put(pq, pj);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: spl.S,v 1.7 2003/08/20 21:48:41 fvdl Exp $ */
|
/* $NetBSD: spl.S,v 1.8 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||||
|
@ -150,13 +150,17 @@ IDTVEC(doreti)
|
||||||
jmp *IS_RESUME(%eax)
|
jmp *IS_RESUME(%eax)
|
||||||
2: /* Check for ASTs on exit to user mode. */
|
2: /* Check for ASTs on exit to user mode. */
|
||||||
movl %ebx,CPUVAR(ILEVEL)
|
movl %ebx,CPUVAR(ILEVEL)
|
||||||
5: CHECK_ASTPENDING(%eax)
|
5:
|
||||||
je 3f
|
|
||||||
testb $SEL_RPL,TF_CS(%esp)
|
testb $SEL_RPL,TF_CS(%esp)
|
||||||
|
jnz doreti_checkast
|
||||||
#ifdef VM86
|
#ifdef VM86
|
||||||
jnz 4f
|
|
||||||
testl $PSL_VM,TF_EFLAGS(%esp)
|
testl $PSL_VM,TF_EFLAGS(%esp)
|
||||||
|
jz 6f
|
||||||
|
#else
|
||||||
|
jmp 6f
|
||||||
#endif
|
#endif
|
||||||
|
doreti_checkast:
|
||||||
|
CHECK_ASTPENDING(%eax)
|
||||||
jz 3f
|
jz 3f
|
||||||
4: CLEAR_ASTPENDING(%eax)
|
4: CLEAR_ASTPENDING(%eax)
|
||||||
sti
|
sti
|
||||||
|
@ -168,4 +172,12 @@ IDTVEC(doreti)
|
||||||
cli
|
cli
|
||||||
jmp 5b
|
jmp 5b
|
||||||
3:
|
3:
|
||||||
|
CHECK_DEFERRED_SWITCH(%eax)
|
||||||
|
jnz 9f
|
||||||
|
6:
|
||||||
INTRFASTEXIT
|
INTRFASTEXIT
|
||||||
|
9:
|
||||||
|
sti
|
||||||
|
call _C_LABEL(pmap_load)
|
||||||
|
cli
|
||||||
|
jmp doreti_checkast /* recheck ASTs */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: svr4_sigcode.S,v 1.6 2003/08/20 21:48:42 fvdl Exp $ */
|
/* $NetBSD: svr4_sigcode.S,v 1.7 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||||
|
@ -119,4 +119,10 @@ IDTVEC(svr4_fasttrap)
|
||||||
call _C_LABEL(trap)
|
call _C_LABEL(trap)
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
jmp 2b
|
jmp 2b
|
||||||
1: INTRFASTEXIT
|
1: CHECK_DEFERRED_SWITCH(%eax)
|
||||||
|
jnz 9f
|
||||||
|
INTRFASTEXIT
|
||||||
|
9: sti
|
||||||
|
call _C_LABEL(pmap_load)
|
||||||
|
cli
|
||||||
|
jmp 2b
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: trap.c,v 1.195 2004/02/19 17:02:44 drochner Exp $ */
|
/* $NetBSD: trap.c,v 1.196 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998, 2000 The NetBSD Foundation, Inc.
|
||||||
|
@ -75,7 +75,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.195 2004/02/19 17:02:44 drochner Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.196 2004/02/20 17:35:01 yamt Exp $");
|
||||||
|
|
||||||
#include "opt_ddb.h"
|
#include "opt_ddb.h"
|
||||||
#include "opt_kgdb.h"
|
#include "opt_kgdb.h"
|
||||||
|
@ -216,7 +216,7 @@ trap(frame)
|
||||||
struct proc *p = l ? l->l_proc : 0;
|
struct proc *p = l ? l->l_proc : 0;
|
||||||
int type = frame->tf_trapno;
|
int type = frame->tf_trapno;
|
||||||
struct pcb *pcb;
|
struct pcb *pcb;
|
||||||
extern char fusubail[],
|
extern char fusubail[], kcopy_fault[],
|
||||||
resume_iret[], resume_pop_ds[], resume_pop_es[],
|
resume_iret[], resume_pop_ds[], resume_pop_es[],
|
||||||
resume_pop_fs[], resume_pop_gs[],
|
resume_pop_fs[], resume_pop_gs[],
|
||||||
IDTVEC(osyscall)[];
|
IDTVEC(osyscall)[];
|
||||||
|
@ -616,6 +616,18 @@ copyfault:
|
||||||
|
|
||||||
if (type == T_PAGEFLT) {
|
if (type == T_PAGEFLT) {
|
||||||
KERNEL_UNLOCK();
|
KERNEL_UNLOCK();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* we need to switch pmap now if we're in
|
||||||
|
* the middle of copyin/out.
|
||||||
|
*
|
||||||
|
* but we don't need to do so for kcopy as
|
||||||
|
* it never touch userspace.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (onfault != kcopy_fault &&
|
||||||
|
curcpu()->ci_want_pmapload)
|
||||||
|
pmap_load();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
l->l_flag &= ~L_SA_PAGEFAULT;
|
l->l_flag &= ~L_SA_PAGEFAULT;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: vector.S,v 1.11 2003/12/12 20:17:53 nathanw Exp $ */
|
/* $NetBSD: vector.S,v 1.12 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright 2002 (c) Wasabi Systems, Inc.
|
* Copyright 2002 (c) Wasabi Systems, Inc.
|
||||||
|
@ -860,27 +860,32 @@ calltrap:
|
||||||
pushl %esp
|
pushl %esp
|
||||||
call _C_LABEL(trap)
|
call _C_LABEL(trap)
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
2: /* Check for ASTs on exit to user mode. */
|
testb $SEL_RPL,TF_CS(%esp)
|
||||||
|
jnz alltraps_checkast
|
||||||
|
#ifdef VM86
|
||||||
|
testl $PSL_VM,TF_EFLAGS(%esp)
|
||||||
|
jz 6f
|
||||||
|
#else
|
||||||
|
jmp 6f
|
||||||
|
#endif
|
||||||
|
alltraps_checkast:
|
||||||
|
/* Check for ASTs on exit to user mode. */
|
||||||
cli
|
cli
|
||||||
CHECK_ASTPENDING(%eax)
|
CHECK_ASTPENDING(%eax)
|
||||||
je 1f
|
jz 3f
|
||||||
testb $SEL_RPL,TF_CS(%esp)
|
|
||||||
#ifdef VM86
|
|
||||||
jnz 5f
|
|
||||||
testl $PSL_VM,TF_EFLAGS(%esp)
|
|
||||||
#endif
|
|
||||||
jz 1f
|
|
||||||
5: CLEAR_ASTPENDING(%eax)
|
5: CLEAR_ASTPENDING(%eax)
|
||||||
sti
|
sti
|
||||||
movl $T_ASTFLT,TF_TRAPNO(%esp)
|
movl $T_ASTFLT,TF_TRAPNO(%esp)
|
||||||
pushl %esp
|
pushl %esp
|
||||||
call _C_LABEL(trap)
|
call _C_LABEL(trap)
|
||||||
addl $4,%esp
|
addl $4,%esp
|
||||||
jmp 2b
|
jmp alltraps_checkast /* re-check ASTs */
|
||||||
|
3: CHECK_DEFERRED_SWITCH(%eax)
|
||||||
|
jnz 9f
|
||||||
#ifndef DIAGNOSTIC
|
#ifndef DIAGNOSTIC
|
||||||
1: INTRFASTEXIT
|
6: INTRFASTEXIT
|
||||||
#else
|
#else
|
||||||
1: cmpl CPUVAR(ILEVEL),%ebx
|
6: cmpl CPUVAR(ILEVEL),%ebx
|
||||||
jne 3f
|
jne 3f
|
||||||
INTRFASTEXIT
|
INTRFASTEXIT
|
||||||
3: sti
|
3: sti
|
||||||
|
@ -891,9 +896,12 @@ calltrap:
|
||||||
int $3
|
int $3
|
||||||
#endif /* DDB */
|
#endif /* DDB */
|
||||||
movl %ebx,CPUVAR(ILEVEL)
|
movl %ebx,CPUVAR(ILEVEL)
|
||||||
jmp 2b
|
jmp alltraps_checkast /* re-check ASTs */
|
||||||
4: .asciz "WARNING: SPL NOT LOWERED ON TRAP EXIT\n"
|
4: .asciz "WARNING: SPL NOT LOWERED ON TRAP EXIT\n"
|
||||||
#endif /* DIAGNOSTIC */
|
#endif /* DIAGNOSTIC */
|
||||||
|
9: sti
|
||||||
|
call _C_LABEL(pmap_load)
|
||||||
|
jmp alltraps_checkast /* re-check ASTs */
|
||||||
|
|
||||||
#ifdef IPKDB
|
#ifdef IPKDB
|
||||||
/* LINTSTUB: Ignore */
|
/* LINTSTUB: Ignore */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: cpu.h,v 1.112 2004/01/04 11:44:52 jdolecek Exp $ */
|
/* $NetBSD: cpu.h,v 1.113 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1990 The Regents of the University of California.
|
* Copyright (c) 1990 The Regents of the University of California.
|
||||||
|
@ -61,6 +61,7 @@
|
||||||
#include <lib/libkern/libkern.h> /* offsetof */
|
#include <lib/libkern/libkern.h> /* offsetof */
|
||||||
|
|
||||||
struct intrsource;
|
struct intrsource;
|
||||||
|
struct pmap;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* a bunch of this belongs in cpuvar.h; move it later..
|
* a bunch of this belongs in cpuvar.h; move it later..
|
||||||
|
@ -92,6 +93,13 @@ struct cpu_info {
|
||||||
|
|
||||||
volatile u_int32_t ci_tlb_ipi_mask;
|
volatile u_int32_t ci_tlb_ipi_mask;
|
||||||
|
|
||||||
|
struct pmap *ci_pmap; /* current pmap */
|
||||||
|
int ci_want_pmapload; /* pmap_load() is needed */
|
||||||
|
int ci_tlbstate; /* one of TLBSTATE_ states. see below */
|
||||||
|
#define TLBSTATE_VALID 0 /* all user tlbs are valid */
|
||||||
|
#define TLBSTATE_LAZY 1 /* tlbs are valid but won't be kept uptodate */
|
||||||
|
#define TLBSTATE_STALE 2 /* we might have stale user tlbs */
|
||||||
|
|
||||||
struct pcb *ci_curpcb; /* VA of current HW PCB */
|
struct pcb *ci_curpcb; /* VA of current HW PCB */
|
||||||
struct pcb *ci_idle_pcb; /* VA of current PCB */
|
struct pcb *ci_idle_pcb; /* VA of current PCB */
|
||||||
int ci_idle_tss_sel; /* TSS selector of idle PCB */
|
int ci_idle_tss_sel; /* TSS selector of idle PCB */
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: frameasm.h,v 1.3 2003/10/04 05:57:51 junyoung Exp $ */
|
/* $NetBSD: frameasm.h,v 1.4 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
#ifndef _I386_FRAMEASM_H_
|
#ifndef _I386_FRAMEASM_H_
|
||||||
#define _I386_FRAMEASM_H_
|
#define _I386_FRAMEASM_H_
|
||||||
|
@ -80,6 +80,15 @@
|
||||||
addl $(TF_PUSHSIZE+8),%esp ; \
|
addl $(TF_PUSHSIZE+8),%esp ; \
|
||||||
iret
|
iret
|
||||||
|
|
||||||
|
#define DO_DEFERRED_SWITCH(reg) \
|
||||||
|
cmpl $0, CPUVAR(WANT_PMAPLOAD) ; \
|
||||||
|
jz 1f ; \
|
||||||
|
call _C_LABEL(pmap_load) ; \
|
||||||
|
1:
|
||||||
|
|
||||||
|
#define CHECK_DEFERRED_SWITCH(reg) \
|
||||||
|
cmpl $0, CPUVAR(WANT_PMAPLOAD)
|
||||||
|
|
||||||
#define CHECK_ASTPENDING(reg) movl CPUVAR(CURLWP),reg ; \
|
#define CHECK_ASTPENDING(reg) movl CPUVAR(CURLWP),reg ; \
|
||||||
cmpl $0, reg ; \
|
cmpl $0, reg ; \
|
||||||
je 1f ; \
|
je 1f ; \
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pcb.h,v 1.36 2003/11/09 05:29:59 tsutsui Exp $ */
|
/* $NetBSD: pcb.h,v 1.37 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||||
|
@ -108,7 +108,6 @@ struct pcb {
|
||||||
int vm86_eflags; /* virtual eflags for vm86 mode */
|
int vm86_eflags; /* virtual eflags for vm86 mode */
|
||||||
int vm86_flagmask; /* flag mask for vm86 mode */
|
int vm86_flagmask; /* flag mask for vm86 mode */
|
||||||
void *vm86_userp; /* XXX performance hack */
|
void *vm86_userp; /* XXX performance hack */
|
||||||
struct pmap *pcb_pmap; /* back pointer to our pmap */
|
|
||||||
struct cpu_info *pcb_fpcpu; /* cpu holding our fp state. */
|
struct cpu_info *pcb_fpcpu; /* cpu holding our fp state. */
|
||||||
u_long pcb_iomap[NIOPORTS/32]; /* I/O bitmap */
|
u_long pcb_iomap[NIOPORTS/32]; /* I/O bitmap */
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $NetBSD: pmap.h,v 1.78 2003/10/27 13:44:20 junyoung Exp $ */
|
/* $NetBSD: pmap.h,v 1.79 2004/02/20 17:35:01 yamt Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
|
@ -342,12 +342,14 @@ void pmap_activate(struct lwp *);
|
||||||
void pmap_bootstrap(vaddr_t);
|
void pmap_bootstrap(vaddr_t);
|
||||||
boolean_t pmap_clear_attrs(struct vm_page *, int);
|
boolean_t pmap_clear_attrs(struct vm_page *, int);
|
||||||
void pmap_deactivate(struct lwp *);
|
void pmap_deactivate(struct lwp *);
|
||||||
|
void pmap_deactivate2(struct lwp *);
|
||||||
void pmap_page_remove (struct vm_page *);
|
void pmap_page_remove (struct vm_page *);
|
||||||
void pmap_remove(struct pmap *, vaddr_t, vaddr_t);
|
void pmap_remove(struct pmap *, vaddr_t, vaddr_t);
|
||||||
boolean_t pmap_test_attrs(struct vm_page *, int);
|
boolean_t pmap_test_attrs(struct vm_page *, int);
|
||||||
void pmap_write_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t);
|
void pmap_write_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t);
|
||||||
int pmap_exec_fixup(struct vm_map *, struct trapframe *,
|
int pmap_exec_fixup(struct vm_map *, struct trapframe *,
|
||||||
struct pcb *);
|
struct pcb *);
|
||||||
|
void pmap_load(void);
|
||||||
|
|
||||||
vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
|
vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue