Add a ton of infrastructure for VKERNEL support. Add code for intercepting
[dragonfly.git] / sys / platform / pc32 / i386 / vm_machdep.c
1 /*-
2  * Copyright (c) 1982, 1986 The Regents of the University of California.
3  * Copyright (c) 1989, 1990 William Jolitz
4  * Copyright (c) 1994 John Dyson
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * the Systems Programming Group of the University of Utah Computer
9  * Science Department, and William Jolitz.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *      This product includes software developed by the University of
22  *      California, Berkeley and its contributors.
23  * 4. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  *      from: @(#)vm_machdep.c  7.3 (Berkeley) 5/13/91
40  *      Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$
41  * $FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.132.2.9 2003/01/25 19:02:23 dillon Exp $
42  * $DragonFly: src/sys/platform/pc32/i386/vm_machdep.c,v 1.47 2006/10/20 17:02:19 dillon Exp $
43  */
44
45 #include "use_npx.h"
46 #include "use_isa.h"
47 #include "opt_reset.h"
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/malloc.h>
52 #include <sys/proc.h>
53 #include <sys/buf.h>
54 #include <sys/interrupt.h>
55 #include <sys/vnode.h>
56 #include <sys/vmmeter.h>
57 #include <sys/kernel.h>
58 #include <sys/sysctl.h>
59 #include <sys/unistd.h>
60
61 #include <machine/clock.h>
62 #include <machine/cpu.h>
63 #include <machine/md_var.h>
64 #include <machine/smp.h>
65 #include <machine/pcb.h>
66 #include <machine/pcb_ext.h>
67 #include <machine/vm86.h>
68 #include <machine/segments.h>
69 #include <machine/globaldata.h> /* npxthread */
70 #include <machine/ipl.h>        /* SWI_ */
71
72 #include <vm/vm.h>
73 #include <vm/vm_param.h>
74 #include <sys/lock.h>
75 #include <vm/vm_kern.h>
76 #include <vm/vm_page.h>
77 #include <vm/vm_map.h>
78 #include <vm/vm_extern.h>
79
80 #include <sys/user.h>
81 #include <sys/thread2.h>
82
83 #include <bus/isa/i386/isa.h>
84
85 static void     cpu_reset_real (void);
86 #ifdef SMP
87 static void     cpu_reset_proxy (void);
88 static u_int    cpu_reset_proxyid;
89 static volatile u_int   cpu_reset_proxy_active;
90 #endif
91 extern int      _ucodesel, _udatasel;
92
93
94 /*
95  * Finish a fork operation, with lwp lp2 nearly set up.
96  * Copy and update the pcb, set up the stack so that the child
97  * ready to run and return to user mode.
98  */
99 void
100 cpu_fork(struct lwp *lp1, struct lwp *lp2, int flags)
101 {
102         struct pcb *pcb2;
103
104         if ((flags & RFPROC) == 0) {
105                 if ((flags & RFMEM) == 0) {
106                         /* unshare user LDT */
107                         struct pcb *pcb1 = lp1->lwp_thread->td_pcb;
108                         struct pcb_ldt *pcb_ldt = pcb1->pcb_ldt;
109                         if (pcb_ldt && pcb_ldt->ldt_refcnt > 1) {
110                                 pcb_ldt = user_ldt_alloc(pcb1,pcb_ldt->ldt_len);
111                                 user_ldt_free(pcb1);
112                                 pcb1->pcb_ldt = pcb_ldt;
113                                 set_user_ldt(pcb1);
114                         }
115                 }
116                 return;
117         }
118
119 #if NNPX > 0
120         /* Ensure that lp1's pcb is up to date. */
121         if (mdcpu->gd_npxthread == lp1->lwp_thread)
122                 npxsave(lp1->lwp_thread->td_savefpu);
123 #endif
124         
125         /*
126          * Copy lp1's PCB.  This really only applies to the
127          * debug registers and FP state, but its faster to just copy the
128          * whole thing.  Because we only save the PCB at switchout time,
129          * the register state (including pcb_gs) may not be current.
130          */
131         pcb2 = lp2->lwp_thread->td_pcb;
132         *pcb2 = *lp1->lwp_thread->td_pcb;
133
134         /*
135          * Create a new fresh stack for the new process.
136          * Copy the trap frame for the return to user mode as if from a
137          * syscall.  This copies the user mode register values.  The
138          * 16 byte offset saves space for vm86, and must match 
139          * common_tss.esp0 (kernel stack pointer on entry from user mode)
140          *
141          * pcb_esp must allocate an additional call-return pointer below
142          * the trap frame which will be restored by cpu_restore from
143          * PCB_EIP, and the thread's td_sp pointer must allocate an
144          * additonal two worsd below the pcb_esp call-return pointer to
145          * hold the LWKT restore function pointer and eflags.
146          *
147          * The LWKT restore function pointer must be set to cpu_restore,
148          * which is our standard heavy weight process switch-in function.
149          * YYY eventually we should shortcut fork_return and fork_trampoline
150          * to use the LWKT restore function directly so we can get rid of
151          * all the extra crap we are setting up.
152          */
153         lp2->lwp_md.md_regs = (struct trapframe *)((char *)pcb2 - 16) - 1;
154         bcopy(lp1->lwp_md.md_regs, lp2->lwp_md.md_regs, sizeof(*lp2->lwp_md.md_regs));
155
156         /*
157          * Set registers for trampoline to user mode.  Leave space for the
158          * return address on stack.  These are the kernel mode register values.
159          */
160         pcb2->pcb_cr3 = vtophys(vmspace_pmap(lp2->lwp_proc->p_vmspace)->pm_pdir);
161         pcb2->pcb_edi = 0;
162         pcb2->pcb_esi = (int)fork_return;       /* fork_trampoline argument */
163         pcb2->pcb_ebp = 0;
164         pcb2->pcb_esp = (int)lp2->lwp_md.md_regs - sizeof(void *);
165         pcb2->pcb_ebx = (int)lp2;               /* fork_trampoline argument */
166         pcb2->pcb_eip = (int)fork_trampoline;
167         lp2->lwp_thread->td_sp = (char *)(pcb2->pcb_esp - sizeof(void *));
168         *(u_int32_t *)lp2->lwp_thread->td_sp = PSL_USER;
169         lp2->lwp_thread->td_sp -= sizeof(void *);
170         *(void **)lp2->lwp_thread->td_sp = (void *)cpu_heavy_restore;
171
172         /*
173          * Segment registers.
174          */
175         pcb2->pcb_gs = rgs();
176
177         /*
178          * pcb2->pcb_ldt:       duplicated below, if necessary.
179          * pcb2->pcb_savefpu:   cloned above.
180          * pcb2->pcb_flags:     cloned above (always 0 here?).
181          * pcb2->pcb_onfault:   cloned above (always NULL here?).
182          */
183
184         /*
185          * XXX don't copy the i/o pages.  this should probably be fixed.
186          */
187         pcb2->pcb_ext = 0;
188
189         /* Copy the LDT, if necessary. */
190         if (pcb2->pcb_ldt != 0) {
191                 if (flags & RFMEM) {
192                         pcb2->pcb_ldt->ldt_refcnt++;
193                 } else {
194                         pcb2->pcb_ldt = user_ldt_alloc(pcb2,
195                                 pcb2->pcb_ldt->ldt_len);
196                 }
197         }
198         bcopy(&lp1->lwp_thread->td_tls, &lp2->lwp_thread->td_tls,
199               sizeof(lp2->lwp_thread->td_tls));
200         /*
201          * Now, cpu_switch() can schedule the new process.
202          * pcb_esp is loaded pointing to the cpu_switch() stack frame
203          * containing the return address when exiting cpu_switch.
204          * This will normally be to fork_trampoline(), which will have
205          * %ebx loaded with the new proc's pointer.  fork_trampoline()
206          * will set up a stack to call fork_return(p, frame); to complete
207          * the return to user-mode.
208          */
209 }
210
211 /*
212  * Intercept the return address from a freshly forked process that has NOT
213  * been scheduled yet.
214  *
215  * This is needed to make kernel threads stay in kernel mode.
216  */
217 void
218 cpu_set_fork_handler(struct lwp *lp, void (*func)(void *), void *arg)
219 {
220         /*
221          * Note that the trap frame follows the args, so the function
222          * is really called like this:  func(arg, frame);
223          */
224         lp->lwp_thread->td_pcb->pcb_esi = (int) func;   /* function */
225         lp->lwp_thread->td_pcb->pcb_ebx = (int) arg;    /* first arg */
226 }
227
228 void
229 cpu_set_thread_handler(thread_t td, void (*rfunc)(void), void *func, void *arg)
230 {
231         td->td_pcb->pcb_esi = (int)func;
232         td->td_pcb->pcb_ebx = (int) arg;
233         td->td_switch = cpu_lwkt_switch;
234         td->td_sp -= sizeof(void *);
235         *(void **)td->td_sp = rfunc;    /* exit function on return */
236         td->td_sp -= sizeof(void *);
237         *(void **)td->td_sp = cpu_kthread_restore;
238 }
239
240 void
241 cpu_proc_exit(void)
242 {
243         struct thread *td = curthread;
244         struct pcb *pcb;
245         struct pcb_ext *ext;
246
247 #if NNPX > 0
248         npxexit();
249 #endif  /* NNPX */
250
251         /*
252          * If we were using a private TSS do a forced-switch to ourselves
253          * to switch back to the common TSS before freeing it.
254          */
255         pcb = td->td_pcb;
256         if ((ext = pcb->pcb_ext) != NULL) {
257                 crit_enter();
258                 pcb->pcb_ext = NULL;
259                 td->td_switch(td);
260                 crit_exit();
261                 kmem_free(kernel_map, (vm_offset_t)ext, ctob(IOPAGES + 1));
262         }
263         user_ldt_free(pcb);
264         if (pcb->pcb_flags & PCB_DBREGS) {
265                 /*
266                  * disable all hardware breakpoints
267                  */
268                 reset_dbregs();
269                 pcb->pcb_flags &= ~PCB_DBREGS;
270         }
271         td->td_gd->gd_cnt.v_swtch++;
272
273         crit_enter_quick(td);
274         lwkt_deschedule_self(td);
275         lwkt_remove_tdallq(td);
276         cpu_thread_exit();
277 }
278
279 /*
280  * Terminate the current thread.  The caller must have already acquired
281  * the thread's rwlock and placed it on a reap list or otherwise notified
282  * a reaper of its existance.  We set a special assembly switch function which
283  * releases td_rwlock after it has cleaned up the MMU state and switched
284  * out the stack.
285  *
286  * Must be caller from a critical section and with the thread descheduled.
287  */
288 void
289 cpu_thread_exit(void)
290 {
291         curthread->td_switch = cpu_exit_switch;
292         curthread->td_flags |= TDF_EXITING;
293         lwkt_switch();
294         panic("cpu_exit");
295 }
296
297 /*
298  * Process Reaper.  Called after the caller has acquired the thread's
299  * rwlock and removed it from the reap list.
300  */
301 void
302 cpu_proc_wait(struct proc *p)
303 {
304         struct thread *td;
305
306         /* drop per-process resources */
307         td = pmap_dispose_proc(p);
308         if (td)
309                 lwkt_free_thread(td);
310 }
311
312 /*
313  * Dump the machine specific header information at the start of a core dump.
314  */
315 int
316 cpu_coredump(struct thread *td, struct vnode *vp, struct ucred *cred)
317 {
318         struct proc *p = td->td_proc;
319         int error;
320         caddr_t tempuser;
321
322         KKASSERT(p);
323         tempuser = kmalloc(ctob(UPAGES), M_TEMP, M_WAITOK);
324         if (!tempuser)
325                 return EINVAL;
326         
327         bzero(tempuser, ctob(UPAGES));
328         bcopy(p->p_addr, tempuser, sizeof(struct user));
329         bcopy(p->p_md.md_regs,
330               tempuser + ((caddr_t) p->p_md.md_regs - (caddr_t) p->p_addr),
331               sizeof(struct trapframe));
332         bcopy(p->p_thread->td_pcb, tempuser + ((char *)p->p_thread->td_pcb - (char *)p->p_addr), sizeof(struct pcb));
333
334         error = vn_rdwr(UIO_WRITE, vp, (caddr_t) tempuser, ctob(UPAGES),
335                         (off_t)0, UIO_SYSSPACE, IO_UNIT, cred, (int *)NULL);
336
337         kfree(tempuser, M_TEMP);
338         
339         return error;
340 }
341
342 #ifdef notyet
343 static void
344 setredzone(u_short *pte, caddr_t vaddr)
345 {
346 /* eventually do this by setting up an expand-down stack segment
347    for ss0: selector, allowing stack access down to top of u.
348    this means though that protection violations need to be handled
349    thru a double fault exception that must do an integral task
350    switch to a known good context, within which a dump can be
351    taken. a sensible scheme might be to save the initial context
352    used by sched (that has physical memory mapped 1:1 at bottom)
353    and take the dump while still in mapped mode */
354 }
355 #endif
356
357 /*
358  * Convert kernel VA to physical address
359  */
360 vm_paddr_t
361 kvtop(void *addr)
362 {
363         vm_paddr_t pa;
364
365         pa = pmap_kextract((vm_offset_t)addr);
366         if (pa == 0)
367                 panic("kvtop: zero page frame");
368         return (pa);
369 }
370
371 /*
372  * Force reset the processor by invalidating the entire address space!
373  */
374
375 #ifdef SMP
376 static void
377 cpu_reset_proxy(void)
378 {
379         u_int saved_mp_lock;
380
381         cpu_reset_proxy_active = 1;
382         while (cpu_reset_proxy_active == 1)
383                 ;        /* Wait for other cpu to disable interupts */
384         saved_mp_lock = mp_lock;
385         mp_lock = 0;    /* BSP */
386         printf("cpu_reset_proxy: Grabbed mp lock for BSP\n");
387         cpu_reset_proxy_active = 3;
388         while (cpu_reset_proxy_active == 3)
389                 ;       /* Wait for other cpu to enable interrupts */
390         stop_cpus((1<<cpu_reset_proxyid));
391         printf("cpu_reset_proxy: Stopped CPU %d\n", cpu_reset_proxyid);
392         DELAY(1000000);
393         cpu_reset_real();
394 }
395 #endif
396
397 void
398 cpu_reset(void)
399 {
400 #ifdef SMP
401         if (smp_active_mask == 1) {
402                 cpu_reset_real();
403                 /* NOTREACHED */
404         } else {
405                 u_int map;
406                 int cnt;
407                 printf("cpu_reset called on cpu#%d\n",mycpu->gd_cpuid);
408
409                 map = mycpu->gd_other_cpus & ~stopped_cpus & smp_active_mask;
410
411                 if (map != 0) {
412                         printf("cpu_reset: Stopping other CPUs\n");
413                         stop_cpus(map);         /* Stop all other CPUs */
414                 }
415
416                 if (mycpu->gd_cpuid == 0) {
417                         DELAY(1000000);
418                         cpu_reset_real();
419                         /* NOTREACHED */
420                 } else {
421                         /* We are not BSP (CPU #0) */
422
423                         cpu_reset_proxyid = mycpu->gd_cpuid;
424                         cpustop_restartfunc = cpu_reset_proxy;
425                         printf("cpu_reset: Restarting BSP\n");
426                         started_cpus = (1<<0);          /* Restart CPU #0 */
427
428                         cnt = 0;
429                         while (cpu_reset_proxy_active == 0 && cnt < 10000000)
430                                 cnt++;  /* Wait for BSP to announce restart */
431                         if (cpu_reset_proxy_active == 0)
432                                 printf("cpu_reset: Failed to restart BSP\n");
433                         __asm __volatile("cli" : : : "memory");
434                         cpu_reset_proxy_active = 2;
435                         cnt = 0;
436                         while (cpu_reset_proxy_active == 2 && cnt < 10000000)
437                                 cnt++;  /* Do nothing */
438                         if (cpu_reset_proxy_active == 2) {
439                                 printf("cpu_reset: BSP did not grab mp lock\n");
440                                 cpu_reset_real();       /* XXX: Bogus ? */
441                         }
442                         cpu_reset_proxy_active = 4;
443                         __asm __volatile("sti" : : : "memory");
444                         while (1);
445                         /* NOTREACHED */
446                 }
447         }
448 #else
449         cpu_reset_real();
450 #endif
451 }
452
453 static void
454 cpu_reset_real(void)
455 {
456         /*
457          * Attempt to do a CPU reset via the keyboard controller,
458          * do not turn of the GateA20, as any machine that fails
459          * to do the reset here would then end up in no man's land.
460          */
461
462 #if !defined(BROKEN_KEYBOARD_RESET)
463         outb(IO_KBD + 4, 0xFE);
464         DELAY(500000);  /* wait 0.5 sec to see if that did it */
465         printf("Keyboard reset did not work, attempting CPU shutdown\n");
466         DELAY(1000000); /* wait 1 sec for printf to complete */
467 #endif
468         /* force a shutdown by unmapping entire address space ! */
469         bzero((caddr_t) PTD, PAGE_SIZE);
470
471         /* "good night, sweet prince .... <THUNK!>" */
472         cpu_invltlb();
473         /* NOTREACHED */
474         while(1);
475 }
476
477 int
478 grow_stack(struct proc *p, u_int sp)
479 {
480         int rv;
481
482         rv = vm_map_growstack (p, sp);
483         if (rv != KERN_SUCCESS)
484                 return (0);
485
486         return (1);
487 }
488
489 SYSCTL_DECL(_vm_stats_misc);
490
491 static int cnt_prezero;
492
493 SYSCTL_INT(_vm_stats_misc, OID_AUTO,
494         cnt_prezero, CTLFLAG_RD, &cnt_prezero, 0, "");
495
496 /*
497  * Implement the pre-zeroed page mechanism.
498  * This routine is called from the idle loop.
499  */
500
501 #define ZIDLE_LO(v)     ((v) * 2 / 3)
502 #define ZIDLE_HI(v)     ((v) * 4 / 5)
503
504 int
505 vm_page_zero_idle(void)
506 {
507         static int free_rover;
508         static int zero_state;
509         vm_page_t m;
510
511         /*
512          * Attempt to maintain approximately 1/2 of our free pages in a
513          * PG_ZERO'd state.   Add some hysteresis to (attempt to) avoid
514          * generally zeroing a page when the system is near steady-state.
515          * Otherwise we might get 'flutter' during disk I/O / IPC or 
516          * fast sleeps.  We also do not want to be continuously zeroing
517          * pages because doing so may flush our L1 and L2 caches too much.
518          */
519
520         if (zero_state && vm_page_zero_count >= ZIDLE_LO(vmstats.v_free_count))
521                 return(0);
522         if (vm_page_zero_count >= ZIDLE_HI(vmstats.v_free_count))
523                 return(0);
524
525 #ifdef SMP
526         if (try_mplock()) {
527 #endif
528                 crit_enter();
529                 __asm __volatile("sti" : : : "memory");
530                 zero_state = 0;
531                 m = vm_page_list_find(PQ_FREE, free_rover, FALSE);
532                 if (m != NULL && (m->flags & PG_ZERO) == 0) {
533                         vm_page_queues[m->queue].lcnt--;
534                         TAILQ_REMOVE(&vm_page_queues[m->queue].pl, m, pageq);
535                         m->queue = PQ_NONE;
536                         crit_exit();
537                         pmap_zero_page(VM_PAGE_TO_PHYS(m));
538                         crit_enter();
539                         vm_page_flag_set(m, PG_ZERO);
540                         m->queue = PQ_FREE + m->pc;
541                         vm_page_queues[m->queue].lcnt++;
542                         TAILQ_INSERT_TAIL(&vm_page_queues[m->queue].pl, m,
543                             pageq);
544                         ++vm_page_zero_count;
545                         ++cnt_prezero;
546                         if (vm_page_zero_count >= ZIDLE_HI(vmstats.v_free_count))
547                                 zero_state = 1;
548                 }
549                 free_rover = (free_rover + PQ_PRIME2) & PQ_L2_MASK;
550                 crit_exit();
551                 __asm __volatile("cli" : : : "memory");
552 #ifdef SMP
553                 rel_mplock();
554 #endif
555                 return (1);
556 #ifdef SMP
557         }
558 #endif
559         /*
560          * We have to enable interrupts for a moment if the try_mplock fails
561          * in order to potentially take an IPI.   XXX this should be in 
562          * swtch.s
563          */
564         __asm __volatile("sti; nop; cli" : : : "memory");
565         return (0);
566 }
567
568 static void
569 swi_vm(void *arg, void *frame)
570 {
571         if (busdma_swi_pending != 0)
572                 busdma_swi();
573 }
574
575 static void
576 swi_vm_setup(void *arg)
577 {
578         register_swi(SWI_VM, swi_vm, NULL, "swi_vm", NULL);
579 }
580
581 SYSINIT(vm_setup, SI_SUB_CPU, SI_ORDER_ANY, swi_vm_setup, NULL);
582
583
584 /*
585  * Tell whether this address is in some physical memory region.
586  * Currently used by the kernel coredump code in order to avoid
587  * dumping the ``ISA memory hole'' which could cause indefinite hangs,
588  * or other unpredictable behaviour.
589  */
590
591 int
592 is_physical_memory(vm_offset_t addr)
593 {
594
595 #if NISA > 0
596         /* The ISA ``memory hole''. */
597         if (addr >= 0xa0000 && addr < 0x100000)
598                 return 0;
599 #endif
600
601         /*
602          * stuff other tests for known memory-mapped devices (PCI?)
603          * here
604          */
605
606         return 1;
607 }