UbixOS
2.0
pagefault.c
Go to the documentation of this file.
1
/*-
2
* Copyright (c) 2002-2018 The UbixOS Project.
3
* All rights reserved.
4
*
5
* This was developed by Christopher W. Olsen for the UbixOS Project.
6
*
7
* Redistribution and use in source and binary forms, with or without modification, are permitted
8
* provided that the following conditions are met:
9
*
10
* 1) Redistributions of source code must retain the above copyright notice, this list of
11
* conditions, the following disclaimer and the list of authors.
12
* 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13
* conditions, the following disclaimer and the list of authors in the documentation and/or
14
* other materials provided with the distribution.
15
* 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16
* endorse or promote products derived from this software without specific prior written
17
* permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
*/
28
29
#include <
vmm/vmm.h
>
30
#include <
ubixos/sched.h
>
31
#include <
ubixos/kpanic.h
>
32
#include <
ubixos/spinlock.h
>
33
#include <
lib/kprintf.h
>
34
#include <
sys/trap.h
>
35
36
static
struct
spinLock
pageFaultSpinLock =
SPIN_LOCK_INITIALIZER
;
37
38
/*****************************************************************************************
39
40
Function: void vmm_pageFault(uInt32 memAddr,uInt32 eip,uInt32 esp);
41
Description: This is the page fault handler, it will handle COW and trap all other
42
exceptions and segfault the thread.
43
44
Notes:
45
46
07/30/02 - Fixed COW However I Need To Think Of A Way To Impliment
47
A Paging System Also Start To Add Security Levels
48
49
07/27/04 - Added spin locking to ensure that we are thread safe. I know that spining a
50
cpu is a waste of resources but for now it prevents errors.
51
52
*****************************************************************************************/
53
/* void vmm_pageFault(uInt32 memAddr,uInt32 eip,uInt32 esp) { */
54
void
vmm_pageFault
(
struct
trapframe
*frame,
uint32_t
cr2) {
55
uInt32
i = 0x0, pageTableIndex = 0x0, pageDirectoryIndex = 0x0;
56
uInt32
*pageDir = 0x0, *pageTable = 0x0;
57
uInt32
*src = 0x0, *dst = 0x0;
58
59
uint32_t
esp = frame->
tf_esp
;
60
uint32_t
eip = frame->
tf_eip
;
61
uint32_t
memAddr = cr2;
62
63
//MrOlsen 2017-12-15 -
64
kprintf
(
"CR2: [0x%X], EIP: 0x%X, ERR: 0x%X, PID: %i\n"
, cr2, frame->
tf_eip
, frame->
tf_err
,
_current
->
id
);
65
66
/* Try to aquire lock otherwise spin till we do */
67
spinLock
(&pageFaultSpinLock);
68
69
/* Set page dir pointer to the address of the visable page directory */
70
pageDir = (
uint32_t
*)
PD_BASE_ADDR
;
71
72
/* UBU - This is a temp panic for 0x0 read write later on I will handle this differently */
73
if
(memAddr == 0x0) {
74
kprintf
(
"Segfault At Address: [0x%X], ESP: [0x%X], PID: [%i], EIP: [0x%X]\n"
, memAddr, esp,
_current
->
id
, eip);
75
kpanic
(
"Error We Wrote To 0x0\n"
);
76
}
77
78
/* Calculate The Page Directory Index */
79
pageDirectoryIndex =
PD_INDEX
(memAddr);
80
81
/* Calculate The Page Table Index */
82
pageTableIndex =
PT_INDEX
(memAddr);
83
84
/* UBU - This is a temporary routine for handling access to a page of a non existant page table */
85
if
(pageDir[pageDirectoryIndex] == 0x0) {
86
kprintf
(
"Segfault At Address: [0x%X][0x%X][%i][0x%X], Not A Valid Page Table\n"
, memAddr, esp,
_current
->
id
, eip);
87
spinUnlock
(&pageFaultSpinLock);
88
endTask
(
_current
->
id
);
89
}
90
else
{
91
/* Set pageTable To Point To Virtual Address Of Page Table */
92
pageTable = (
uint32_t
*) (
PT_BASE_ADDR
+ (
PAGE_SIZE
* pageDirectoryIndex));
93
94
/* Test if this is a COW on page */
95
if
(((
uint32_t
) pageTable[pageTableIndex] &
PAGE_COW
) ==
PAGE_COW
) {
96
/* Set Src To Base Address Of Page To Copy */
97
src = (
uInt32
*) (memAddr & 0xFFFFF000);
98
/* Allocate A Free Page For Destination */
99
/* USE vmInfo */
100
dst = (
uInt32
*)
vmm_getFreeVirtualPage
(
_current
->
id
, 1, 0x1);
101
/* Copy Memory */
102
for
(i = 0; i <
PD_ENTRIES
; i++) {
103
dst[i] = src[i];
104
}
105
/* Adjust The COW Counter For Physical Page */
106
adjustCowCounter
(((
uInt32
) pageTable[pageTableIndex] & 0xFFFFF000), -1);
107
/* Remap In New Page */
108
pageTable[pageTableIndex] = (
uInt32
) (
vmm_getPhysicalAddr
((
uInt32
) dst) | (memAddr & 0xFFF));
109
/* Unlink From Memory Map Allocated Page */
110
vmm_unmapPage
((
uInt32
) dst, 1);
111
}
112
else
if
(pageTable[pageTableIndex] != 0x0) {
113
kprintf
(
"Security failed pagetable not user permission\n"
);
114
kprintf
(
"pageDir: [0x%X]\n"
, pageDir[pageDirectoryIndex]);
115
kprintf
(
"pageTable: [0x%X:0x%X:0x%X:0x%X]\n"
, pageTable[pageTableIndex], pageTableIndex, pageDirectoryIndex, eip);
116
kprintf
(
"Segfault At Address: [0x%X][0x%X][%i][0x%X] Non Mapped.\n"
, memAddr, esp,
_current
->
id
, eip);
117
kpanic
(
"SIT HERE FOR NOW"
);
118
die_if_kernel
(
"SEGFAULT"
, frame, 0xC);
119
spinUnlock
(&pageFaultSpinLock);
120
endTask
(
_current
->
id
);
121
}
122
else
if
(memAddr < (
_current
->
td
.
vm_dsize
+
_current
->
td
.
vm_daddr
)) {
123
kprintf
(
"THIS IS BAD"
);
124
die_if_kernel
(
"SEGFAULT"
, frame, 0xC);
125
pageTable[pageTableIndex] = (
uInt32
)
vmm_findFreePage
(
_current
->
id
) |
PAGE_DEFAULT
;
126
}
127
else
{
128
spinUnlock
(&pageFaultSpinLock);
129
/* Need To Create A Routine For Attempting To Access Non Mapped Memory */
130
kprintf
(
"pageDir: [0x%X]\n"
, pageDir[pageDirectoryIndex]);
131
kprintf
(
"pageTable: [0x%X:0x%X:0x%X:0x%X]\n"
, pageTable[pageTableIndex], pageTableIndex, pageDirectoryIndex, eip);
132
kprintf
(
"Segfault At Address: [0x%X][0x%X][%i][0x%X] Non Mapped!\n"
, memAddr, esp,
_current
->
id
, eip);
133
die_if_kernel
(
"SEGFAULT"
, frame, 0xC);
134
kpanic
(
"SIT HERE FOR NOW"
);
135
kprintf
(
"Out Of Stack Space: [0x%X]\n"
, memAddr & 0xFF0000);
136
endTask
(
_current
->
id
);
137
}
138
}
139
asm
volatile
(
140
"movl %cr3,%eax\n"
141
"movl %eax,%cr3\n"
142
);
143
144
/* Release the spin lock */
145
spinUnlock
(&pageFaultSpinLock);
146
kprintf
(
"CR2-RET"
);
147
return
;
148
}
trapframe::tf_eip
int tf_eip
Definition:
trap.h:50
spinlock.h
uInt32
unsigned long int uInt32
Definition:
objgfx30.h:49
trap.h
PAGE_COW
#define PAGE_COW
Definition:
paging.h:64
spinUnlock
void spinUnlock(spinLock_t *lock)
Definition:
spinlock.c:36
vmm.h
vmm_getPhysicalAddr
uint32_t vmm_getPhysicalAddr(uint32_t)
Definition:
getphysicaladdr.c:38
adjustCowCounter
int adjustCowCounter(uint32_t baseAddr, int adjustment)
SPIN_LOCK_INITIALIZER
#define SPIN_LOCK_INITIALIZER
Definition:
spinlock.h:36
sched.h
kpanic
void kpanic(const char *fmt,...)
print panic message and halt system
Definition:
kpanic.c:41
vmm_unmapPage
void vmm_unmapPage(uint32_t, unmapFlags_t)
Definition:
unmappage.c:47
taskStruct::td
struct thread td
Definition:
sched.h:78
spinLock
void spinLock(spinLock_t *lock)
Definition:
spinlock.c:55
kpanic.h
taskStruct::id
pidType id
Definition:
sched.h:63
vmm_findFreePage
uint32_t vmm_findFreePage(pidType pid)
Definition:
vmm_memory.c:221
vmm_getFreeVirtualPage
void * vmm_getFreeVirtualPage(pidType, int, int)
Definition:
getfreevirtualpage.c:47
trapframe::tf_err
int tf_err
Definition:
trap.h:49
kprintf.h
PD_INDEX
#define PD_INDEX(v_addr)
Definition:
paging.h:40
PAGE_DEFAULT
#define PAGE_DEFAULT
Definition:
paging.h:68
PD_BASE_ADDR
#define PD_BASE_ADDR
Definition:
paging.h:45
uint32_t
__uint32_t uint32_t
Definition:
types.h:46
trapframe
Definition:
trap.h:34
endTask
void endTask(pidType)
Definition:
endtask.c:44
thread::vm_dsize
u_long vm_dsize
Definition:
thread.h:44
_current
kTask_t * _current
Definition:
sched.c:50
PT_INDEX
#define PT_INDEX(v_addr)
Definition:
paging.h:42
thread::vm_daddr
u_long vm_daddr
Definition:
thread.h:43
spinLock
Definition:
spinlock.h:41
die_if_kernel
void die_if_kernel(char *str, struct trapframe *regs, long err)
Definition:
trap.c:59
PD_ENTRIES
#define PD_ENTRIES
Definition:
paging.h:48
PAGE_SIZE
#define PAGE_SIZE
Definition:
paging.h:37
trapframe::tf_esp
int tf_esp
Definition:
trap.h:54
kprintf
int kprintf(const char *,...)
Definition:
kprintf.c:259
PT_BASE_ADDR
#define PT_BASE_ADDR
Definition:
paging.h:46
vmm_pageFault
void vmm_pageFault(struct trapframe *frame, uint32_t cr2)
Definition:
pagefault.c:53
vmm
pagefault.c
Generated by
1.8.16