Unify the AIM and Book-E vm_machdep.c implementations, which previously
differed only with respect to the AIM version not following style(9) and some additional features for 64-bit systems and machines with direct maps in the AIM implementation that are no-ops on Book-E (at least for now).
This commit is contained in:
parent
9bff0a1d6a
commit
1cfdc97153
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=256792
@ -101,7 +101,6 @@ powerpc/aim/swtch32.S optional aim powerpc
|
||||
powerpc/aim/swtch64.S optional aim powerpc64
|
||||
powerpc/aim/trap.c optional aim
|
||||
powerpc/aim/uma_machdep.c optional aim
|
||||
powerpc/aim/vm_machdep.c optional aim
|
||||
powerpc/booke/clock.c optional booke
|
||||
powerpc/booke/copyinout.c optional booke
|
||||
powerpc/booke/interrupt.c optional booke
|
||||
@ -113,7 +112,6 @@ powerpc/booke/platform_bare.c optional mpc85xx
|
||||
powerpc/booke/pmap.c optional booke
|
||||
powerpc/booke/swtch.S optional booke
|
||||
powerpc/booke/trap.c optional booke
|
||||
powerpc/booke/vm_machdep.c optional booke
|
||||
powerpc/cpufreq/dfs.c optional cpufreq
|
||||
powerpc/cpufreq/pcr.c optional cpufreq aim
|
||||
powerpc/fpu/fpu_add.c optional fpu_emu powerpc
|
||||
@ -214,6 +212,7 @@ powerpc/powerpc/suswintr.c standard
|
||||
powerpc/powerpc/syncicache.c standard
|
||||
powerpc/powerpc/sys_machdep.c standard
|
||||
powerpc/powerpc/uio_machdep.c standard
|
||||
powerpc/powerpc/vm_machdep.c standard
|
||||
powerpc/ps3/ehci_ps3.c optional ps3 ehci
|
||||
powerpc/ps3/ohci_ps3.c optional ps3 ohci
|
||||
powerpc/ps3/if_glc.c optional ps3 glc
|
||||
|
@ -1,413 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986 The Regents of the University of California.
|
||||
* Copyright (c) 1989, 1990 William Jolitz
|
||||
* Copyright (c) 1994 John Dyson
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the Systems Programming Group of the University of Utah Computer
|
||||
* Science Department, and William Jolitz.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Author: Chris G. Demetriou
|
||||
*
|
||||
* Permission to use, copy, modify and distribute this software and
|
||||
* its documentation is hereby granted, provided that both the copyright
|
||||
* notice and this permission notice appear in all copies of the
|
||||
* software, derivative works or modified versions, and any portions
|
||||
* thereof, and that both notices appear in supporting documentation.
|
||||
*
|
||||
* CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
|
||||
* CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
|
||||
* FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
|
||||
*
|
||||
* Carnegie Mellon requests users of this software to return to
|
||||
*
|
||||
* Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
|
||||
* School of Computer Science
|
||||
* Carnegie Mellon University
|
||||
* Pittsburgh PA 15213-3890
|
||||
*
|
||||
* any improvements or extensions that they make and grant Carnegie the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bio.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/sf_buf.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/fpu.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/pcb.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_page.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
/*
|
||||
* On systems without a direct mapped region (e.g. PPC64),
|
||||
* we use the same code as the Book E implementation. Since
|
||||
* we need to have runtime detection of this, define some machinery
|
||||
* for sf_bufs in this case, and ignore it on systems with direct maps.
|
||||
*/
|
||||
|
||||
#ifndef NSFBUFS
|
||||
#define NSFBUFS (512 + maxusers * 16)
|
||||
#endif
|
||||
|
||||
static int nsfbufs;
|
||||
static int nsfbufspeak;
|
||||
static int nsfbufsused;
|
||||
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufs, CTLFLAG_RDTUN, &nsfbufs, 0,
|
||||
"Maximum number of sendfile(2) sf_bufs available");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufspeak, CTLFLAG_RD, &nsfbufspeak, 0,
|
||||
"Number of sendfile(2) sf_bufs at peak usage");
|
||||
SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufsused, CTLFLAG_RD, &nsfbufsused, 0,
|
||||
"Number of sendfile(2) sf_bufs in use");
|
||||
|
||||
static void sf_buf_init(void *arg);
|
||||
SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL);
|
||||
|
||||
LIST_HEAD(sf_head, sf_buf);
|
||||
|
||||
/* A hash table of active sendfile(2) buffers */
|
||||
static struct sf_head *sf_buf_active;
|
||||
static u_long sf_buf_hashmask;
|
||||
|
||||
#define SF_BUF_HASH(m) (((m) - vm_page_array) & sf_buf_hashmask)
|
||||
|
||||
static TAILQ_HEAD(, sf_buf) sf_buf_freelist;
|
||||
static u_int sf_buf_alloc_want;
|
||||
|
||||
/*
|
||||
* A lock used to synchronize access to the hash table and free list
|
||||
*/
|
||||
static struct mtx sf_buf_lock;
|
||||
|
||||
#ifdef __powerpc64__
|
||||
extern uintptr_t tocbase;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Finish a fork operation, with process p2 nearly set up.
|
||||
* Copy and update the pcb, set up the stack so that the child
|
||||
* ready to run and return to user mode.
|
||||
*/
|
||||
void
|
||||
cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct callframe *cf;
|
||||
struct pcb *pcb;
|
||||
|
||||
KASSERT(td1 == curthread || td1 == &thread0,
|
||||
("cpu_fork: p1 not curproc and not proc0"));
|
||||
CTR3(KTR_PROC, "cpu_fork: called td1=%p p2=%p flags=%x",
|
||||
td1, p2, flags);
|
||||
|
||||
if ((flags & RFPROC) == 0)
|
||||
return;
|
||||
|
||||
pcb = (struct pcb *)((td2->td_kstack +
|
||||
td2->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~0x2fUL);
|
||||
td2->td_pcb = pcb;
|
||||
|
||||
/* Copy the pcb */
|
||||
bcopy(td1->td_pcb, pcb, sizeof(struct pcb));
|
||||
|
||||
/*
|
||||
* Create a fresh stack for the new process.
|
||||
* Copy the trap frame for the return to user mode as if from a
|
||||
* syscall. This copies most of the user mode register values.
|
||||
*/
|
||||
tf = (struct trapframe *)pcb - 1;
|
||||
bcopy(td1->td_frame, tf, sizeof(*tf));
|
||||
|
||||
/* Set up trap frame. */
|
||||
tf->fixreg[FIRSTARG] = 0;
|
||||
tf->fixreg[FIRSTARG + 1] = 0;
|
||||
tf->cr &= ~0x10000000;
|
||||
|
||||
td2->td_frame = tf;
|
||||
|
||||
cf = (struct callframe *)tf - 1;
|
||||
memset(cf, 0, sizeof(struct callframe));
|
||||
#ifdef __powerpc64__
|
||||
cf->cf_toc = tocbase;
|
||||
#endif
|
||||
cf->cf_func = (register_t)fork_return;
|
||||
cf->cf_arg0 = (register_t)td2;
|
||||
cf->cf_arg1 = (register_t)tf;
|
||||
|
||||
pcb->pcb_sp = (register_t)cf;
|
||||
KASSERT(pcb->pcb_sp % 16 == 0, ("stack misaligned"));
|
||||
#ifdef __powerpc64__
|
||||
pcb->pcb_lr = ((register_t *)fork_trampoline)[0];
|
||||
pcb->pcb_toc = ((register_t *)fork_trampoline)[1];
|
||||
#else
|
||||
pcb->pcb_lr = (register_t)fork_trampoline;
|
||||
#endif
|
||||
pcb->pcb_cpu.aim.usr_vsid = 0;
|
||||
|
||||
/* Setup to release spin count in fork_exit(). */
|
||||
td2->td_md.md_spinlock_count = 1;
|
||||
td2->td_md.md_saved_msr = PSL_KERNSET;
|
||||
|
||||
/*
|
||||
* Now cpu_switch() can schedule the new process.
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Intercept the return address from a freshly forked process that has NOT
|
||||
* been scheduled yet.
|
||||
*
|
||||
* This is needed to make kernel threads stay in kernel mode.
|
||||
*/
|
||||
void
|
||||
cpu_set_fork_handler(td, func, arg)
|
||||
struct thread *td;
|
||||
void (*func)(void *);
|
||||
void *arg;
|
||||
{
|
||||
struct callframe *cf;
|
||||
|
||||
CTR4(KTR_PROC, "%s called with td=%p func=%p arg=%p",
|
||||
__func__, td, func, arg);
|
||||
|
||||
cf = (struct callframe *)td->td_pcb->pcb_sp;
|
||||
|
||||
cf->cf_func = (register_t)func;
|
||||
cf->cf_arg0 = (register_t)arg;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_exit(td)
|
||||
register struct thread *td;
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a pool of sf_bufs (sendfile(2) or "super-fast" if you prefer. :-))
|
||||
*/
|
||||
static void
|
||||
sf_buf_init(void *arg)
|
||||
{
|
||||
struct sf_buf *sf_bufs;
|
||||
vm_offset_t sf_base;
|
||||
int i;
|
||||
|
||||
/* Don't bother on systems with a direct map */
|
||||
|
||||
if (hw_direct_map)
|
||||
return;
|
||||
|
||||
nsfbufs = NSFBUFS;
|
||||
TUNABLE_INT_FETCH("kern.ipc.nsfbufs", &nsfbufs);
|
||||
|
||||
sf_buf_active = hashinit(nsfbufs, M_TEMP, &sf_buf_hashmask);
|
||||
TAILQ_INIT(&sf_buf_freelist);
|
||||
sf_base = kva_alloc(nsfbufs * PAGE_SIZE);
|
||||
sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP, M_NOWAIT | M_ZERO);
|
||||
|
||||
for (i = 0; i < nsfbufs; i++) {
|
||||
sf_bufs[i].kva = sf_base + i * PAGE_SIZE;
|
||||
TAILQ_INSERT_TAIL(&sf_buf_freelist, &sf_bufs[i], free_entry);
|
||||
}
|
||||
sf_buf_alloc_want = 0;
|
||||
mtx_init(&sf_buf_lock, "sf_buf", NULL, MTX_DEF);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get an sf_buf from the freelist. Will block if none are available.
|
||||
*/
|
||||
struct sf_buf *
|
||||
sf_buf_alloc(struct vm_page *m, int flags)
|
||||
{
|
||||
struct sf_head *hash_list;
|
||||
struct sf_buf *sf;
|
||||
int error;
|
||||
|
||||
if (hw_direct_map) {
|
||||
/* Shortcut the direct mapped case */
|
||||
|
||||
return ((struct sf_buf *)m);
|
||||
}
|
||||
|
||||
hash_list = &sf_buf_active[SF_BUF_HASH(m)];
|
||||
mtx_lock(&sf_buf_lock);
|
||||
LIST_FOREACH(sf, hash_list, list_entry) {
|
||||
if (sf->m == m) {
|
||||
sf->ref_count++;
|
||||
if (sf->ref_count == 1) {
|
||||
TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
|
||||
nsfbufsused++;
|
||||
nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
while ((sf = TAILQ_FIRST(&sf_buf_freelist)) == NULL) {
|
||||
if (flags & SFB_NOWAIT)
|
||||
goto done;
|
||||
|
||||
sf_buf_alloc_want++;
|
||||
SFSTAT_INC(sf_allocwait);
|
||||
error = msleep(&sf_buf_freelist, &sf_buf_lock,
|
||||
(flags & SFB_CATCH) ? PCATCH | PVM : PVM, "sfbufa", 0);
|
||||
sf_buf_alloc_want--;
|
||||
|
||||
/*
|
||||
* If we got a signal, don't risk going back to sleep.
|
||||
*/
|
||||
if (error)
|
||||
goto done;
|
||||
}
|
||||
|
||||
TAILQ_REMOVE(&sf_buf_freelist, sf, free_entry);
|
||||
if (sf->m != NULL)
|
||||
LIST_REMOVE(sf, list_entry);
|
||||
|
||||
LIST_INSERT_HEAD(hash_list, sf, list_entry);
|
||||
sf->ref_count = 1;
|
||||
sf->m = m;
|
||||
nsfbufsused++;
|
||||
nsfbufspeak = imax(nsfbufspeak, nsfbufsused);
|
||||
pmap_qenter(sf->kva, &sf->m, 1);
|
||||
done:
|
||||
mtx_unlock(&sf_buf_lock);
|
||||
return (sf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detatch mapped page and release resources back to the system.
|
||||
*
|
||||
* Remove a reference from the given sf_buf, adding it to the free
|
||||
* list when its reference count reaches zero. A freed sf_buf still,
|
||||
* however, retains its virtual-to-physical mapping until it is
|
||||
* recycled or reactivated by sf_buf_alloc(9).
|
||||
*/
|
||||
void
|
||||
sf_buf_free(struct sf_buf *sf)
|
||||
{
|
||||
if (hw_direct_map)
|
||||
return;
|
||||
|
||||
mtx_lock(&sf_buf_lock);
|
||||
sf->ref_count--;
|
||||
if (sf->ref_count == 0) {
|
||||
TAILQ_INSERT_TAIL(&sf_buf_freelist, sf, free_entry);
|
||||
nsfbufsused--;
|
||||
|
||||
if (sf_buf_alloc_want > 0)
|
||||
wakeup(&sf_buf_freelist);
|
||||
}
|
||||
mtx_unlock(&sf_buf_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Software interrupt handler for queued VM system processing.
|
||||
*/
|
||||
void
|
||||
swi_vm(void *dummy)
|
||||
{
|
||||
|
||||
if (busdma_swi_pending != 0)
|
||||
busdma_swi();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell whether this address is in some physical memory region.
|
||||
* Currently used by the kernel coredump code in order to avoid
|
||||
* dumping the ``ISA memory hole'' which could cause indefinite hangs,
|
||||
* or other unpredictable behaviour.
|
||||
*/
|
||||
|
||||
|
||||
int
|
||||
is_physical_memory(addr)
|
||||
vm_offset_t addr;
|
||||
{
|
||||
/*
|
||||
* stuff other tests for known memory-mapped devices (PCI?)
|
||||
* here
|
||||
*/
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* CPU threading functions related to the VM layer. These could be used
|
||||
* to map the SLB bits required for the kernel stack instead of forcing a
|
||||
* fixed-size KVA.
|
||||
*/
|
||||
|
||||
void
|
||||
cpu_thread_swapin(struct thread *td)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
cpu_thread_swapout(struct thread *td)
|
||||
{
|
||||
}
|
||||
|
@ -1,33 +1,3 @@
|
||||
/*-
|
||||
* Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com>
|
||||
* Copyright (C) 2006 Semihalf, Rafal Jaworowski <raj@semihalf.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Adapted for Freescale's e500 core CPUs.
|
||||
* sf_buf implementation was derived from sys/arm/arm/vm_machdep.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
||||
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* from: $FreeBSD$
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986 The Regents of the University of California.
|
||||
* Copyright (c) 1989, 1990 William Jolitz
|
||||
@ -48,8 +18,8 @@
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
@ -66,8 +36,9 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91
|
||||
* Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
|
||||
* $FreeBSD$
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1994, 1995, 1996 Carnegie-Mellon University.
|
||||
@ -96,9 +67,6 @@
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
@ -113,18 +81,17 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/sf_buf.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/unistd.h>
|
||||
|
||||
#include <machine/clock.h>
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/fpu.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/spr.h>
|
||||
#include <machine/platform.h>
|
||||
|
||||
#include <dev/ofw/openfirm.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
@ -133,6 +100,13 @@ __FBSDID("$FreeBSD$");
|
||||
#include <vm/vm_map.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
/*
|
||||
* On systems without a direct mapped region (e.g. PPC64),
|
||||
* we use the same code as the Book E implementation. Since
|
||||
* we need to have runtime detection of this, define some machinery
|
||||
* for sf_bufs in this case, and ignore it on systems with direct maps.
|
||||
*/
|
||||
|
||||
#ifndef NSFBUFS
|
||||
#define NSFBUFS (512 + maxusers * 16)
|
||||
#endif
|
||||
@ -150,9 +124,9 @@ SYSCTL_INT(_kern_ipc, OID_AUTO, nsfbufsused, CTLFLAG_RD, &nsfbufsused, 0,
|
||||
|
||||
static void sf_buf_init(void *arg);
|
||||
SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL);
|
||||
|
||||
|
||||
LIST_HEAD(sf_head, sf_buf);
|
||||
|
||||
|
||||
/* A hash table of active sendfile(2) buffers */
|
||||
static struct sf_head *sf_buf_active;
|
||||
static u_long sf_buf_hashmask;
|
||||
@ -167,6 +141,11 @@ static u_int sf_buf_alloc_want;
|
||||
*/
|
||||
static struct mtx sf_buf_lock;
|
||||
|
||||
#ifdef __powerpc64__
|
||||
extern uintptr_t tocbase;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Finish a fork operation, with process p2 nearly set up.
|
||||
* Copy and update the pcb, set up the stack so that the child
|
||||
@ -175,23 +154,20 @@ static struct mtx sf_buf_lock;
|
||||
void
|
||||
cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
{
|
||||
struct proc *p1;
|
||||
struct trapframe *tf;
|
||||
struct callframe *cf;
|
||||
struct pcb *pcb;
|
||||
struct trapframe *tf;
|
||||
struct callframe *cf;
|
||||
struct pcb *pcb;
|
||||
|
||||
KASSERT(td1 == curthread || td1 == &thread0,
|
||||
("cpu_fork: p1 not curproc and not proc0"));
|
||||
CTR3(KTR_PROC, "cpu_fork: called td1=%08x p2=%08x flags=%x", (u_int)td1,
|
||||
(u_int)p2, flags);
|
||||
CTR3(KTR_PROC, "cpu_fork: called td1=%p p2=%p flags=%x",
|
||||
td1, p2, flags);
|
||||
|
||||
if ((flags & RFPROC) == 0)
|
||||
return;
|
||||
|
||||
p1 = td1->td_proc;
|
||||
|
||||
pcb = (struct pcb *)((td2->td_kstack +
|
||||
td2->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~0x3fU);
|
||||
td2->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~0x2fUL);
|
||||
td2->td_pcb = pcb;
|
||||
|
||||
/* Copy the pcb */
|
||||
@ -214,19 +190,31 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags)
|
||||
|
||||
cf = (struct callframe *)tf - 1;
|
||||
memset(cf, 0, sizeof(struct callframe));
|
||||
#ifdef __powerpc64__
|
||||
cf->cf_toc = tocbase;
|
||||
#endif
|
||||
cf->cf_func = (register_t)fork_return;
|
||||
cf->cf_arg0 = (register_t)td2;
|
||||
cf->cf_arg1 = (register_t)tf;
|
||||
|
||||
pcb->pcb_sp = (register_t)cf;
|
||||
KASSERT(pcb->pcb_sp % 16 == 0, ("stack misaligned"));
|
||||
#ifdef __powerpc64__
|
||||
pcb->pcb_lr = ((register_t *)fork_trampoline)[0];
|
||||
pcb->pcb_toc = ((register_t *)fork_trampoline)[1];
|
||||
#else
|
||||
pcb->pcb_lr = (register_t)fork_trampoline;
|
||||
#endif
|
||||
#ifdef AIM
|
||||
pcb->pcb_cpu.aim.usr_vsid = 0;
|
||||
#endif
|
||||
|
||||
/* Setup to release sched_lock in fork_exit(). */
|
||||
/* Setup to release spin count in fork_exit(). */
|
||||
td2->td_md.md_spinlock_count = 1;
|
||||
td2->td_md.md_saved_msr = PSL_KERNSET;
|
||||
|
||||
/*
|
||||
* Now cpu_switch() can schedule the new process.
|
||||
* Now cpu_switch() can schedule the new process.
|
||||
*/
|
||||
}
|
||||
|
||||
@ -241,8 +229,8 @@ cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg)
|
||||
{
|
||||
struct callframe *cf;
|
||||
|
||||
CTR3(KTR_PROC, "cpu_set_fork_handler: called with td=%08x func=%08x arg=%08x",
|
||||
(u_int)td, (u_int)func, (u_int)arg);
|
||||
CTR4(KTR_PROC, "%s called with td=%p func=%p arg=%p",
|
||||
__func__, td, func, arg);
|
||||
|
||||
cf = (struct callframe *)td->td_pcb->pcb_sp;
|
||||
|
||||
@ -266,13 +254,18 @@ sf_buf_init(void *arg)
|
||||
vm_offset_t sf_base;
|
||||
int i;
|
||||
|
||||
/* Don't bother on systems with a direct map */
|
||||
if (hw_direct_map)
|
||||
return;
|
||||
|
||||
nsfbufs = NSFBUFS;
|
||||
TUNABLE_INT_FETCH("kern.ipc.nsfbufs", &nsfbufs);
|
||||
|
||||
sf_buf_active = hashinit(nsfbufs, M_TEMP, &sf_buf_hashmask);
|
||||
TAILQ_INIT(&sf_buf_freelist);
|
||||
sf_base = kva_alloc(nsfbufs * PAGE_SIZE);
|
||||
sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP, M_NOWAIT | M_ZERO);
|
||||
sf_bufs = malloc(nsfbufs * sizeof(struct sf_buf), M_TEMP,
|
||||
M_NOWAIT | M_ZERO);
|
||||
|
||||
for (i = 0; i < nsfbufs; i++) {
|
||||
sf_bufs[i].kva = sf_base + i * PAGE_SIZE;
|
||||
@ -292,6 +285,11 @@ sf_buf_alloc(struct vm_page *m, int flags)
|
||||
struct sf_buf *sf;
|
||||
int error;
|
||||
|
||||
if (hw_direct_map) {
|
||||
/* Shortcut the direct mapped case */
|
||||
return ((struct sf_buf *)m);
|
||||
}
|
||||
|
||||
hash_list = &sf_buf_active[SF_BUF_HASH(m)];
|
||||
mtx_lock(&sf_buf_lock);
|
||||
LIST_FOREACH(sf, hash_list, list_entry) {
|
||||
@ -349,6 +347,8 @@ sf_buf_alloc(struct vm_page *m, int flags)
|
||||
void
|
||||
sf_buf_free(struct sf_buf *sf)
|
||||
{
|
||||
if (hw_direct_map)
|
||||
return;
|
||||
|
||||
mtx_lock(&sf_buf_lock);
|
||||
sf->ref_count--;
|
||||
@ -391,7 +391,9 @@ is_physical_memory(vm_offset_t addr)
|
||||
}
|
||||
|
||||
/*
|
||||
* CPU threading functions related to VM.
|
||||
* CPU threading functions related to the VM layer. These could be used
|
||||
* to map the SLB bits required for the kernel stack instead of forcing a
|
||||
* fixed-size KVA.
|
||||
*/
|
||||
|
||||
void
|
Loading…
Reference in New Issue
Block a user