[Krafton Jungle] PintOS 2.0.0
크래프톤 정글 PintOS
 
Loading...
Searching...
No Matches
exception.c File Reference
#include "userprog/exception.h"
#include <inttypes.h>
#include <stdio.h>
#include "userprog/gdt.h"
#include "threads/interrupt.h"
#include "threads/thread.h"
#include "intrinsic.h"
Include dependency graph for exception.c:

Functions

static void kill (struct intr_frame *)
 
static void page_fault (struct intr_frame *)
 
void exception_init (void)
 
void exception_print_stats (void)
 

Variables

static long long page_fault_cnt
 

Function Documentation

◆ exception_init()

void exception_init ( void  )
31 {
32 /* These exceptions can be raised explicitly by a user program,
33 e.g. via the INT, INT3, INTO, and BOUND instructions. Thus,
34 we set DPL==3, meaning that user programs are allowed to
35 invoke them via these instructions. */
36 intr_register_int (3, 3, INTR_ON, kill, "#BP Breakpoint Exception");
37 intr_register_int (4, 3, INTR_ON, kill, "#OF Overflow Exception");
39 "#BR BOUND Range Exceeded Exception");
40
41 /* These exceptions have DPL==0, preventing user processes from
42 invoking them via the INT instruction. They can still be
43 caused indirectly, e.g. #DE can be caused by dividing by
44 0. */
45 intr_register_int (0, 0, INTR_ON, kill, "#DE Divide Error");
46 intr_register_int (1, 0, INTR_ON, kill, "#DB Debug Exception");
47 intr_register_int (6, 0, INTR_ON, kill, "#UD Invalid Opcode Exception");
49 "#NM Device Not Available Exception");
50 intr_register_int (11, 0, INTR_ON, kill, "#NP Segment Not Present");
51 intr_register_int (12, 0, INTR_ON, kill, "#SS Stack Fault Exception");
52 intr_register_int (13, 0, INTR_ON, kill, "#GP General Protection Exception");
53 intr_register_int (16, 0, INTR_ON, kill, "#MF x87 FPU Floating-Point Error");
55 "#XF SIMD Floating-Point Exception");
56
57 /* Most exceptions can be handled with interrupts turned on.
58 We need to disable interrupts for page faults because the
59 fault address is stored in CR2 and needs to be preserved. */
60 intr_register_int (14, 0, INTR_OFF, page_fault, "#PF Page-Fault Exception");
61}
static void kill(struct intr_frame *)
Definition: exception.c:71
static void page_fault(struct intr_frame *)
Definition: exception.c:120
@ INTR_ON
Definition: interrupt.h:10
@ INTR_OFF
Definition: interrupt.h:9
void intr_register_int(uint8_t vec, int dpl, enum intr_level, intr_handler_func *, const char *name)
Definition: interrupt.c:248
Here is the call graph for this function:
Here is the caller graph for this function:

◆ exception_print_stats()

void exception_print_stats ( void  )
65 {
66 printf ("Exception: %lld page faults\n", page_fault_cnt);
67}
static long long page_fault_cnt
Definition: exception.c:10
int printf(const char *,...) PRINTF_FORMAT(1
Here is the call graph for this function:
Here is the caller graph for this function:

◆ kill()

static void kill ( struct intr_frame f)
static
71 {
72 /* This interrupt is one (probably) caused by a user process.
73 For example, the process might have tried to access unmapped
74 virtual memory (a page fault). For now, we simply kill the
75 user process. Later, we'll want to handle page faults in
76 the kernel. Real Unix-like operating systems pass most
77 exceptions back to the process via signals, but we don't
78 implement them. */
79
80 /* The interrupt frame's code segment value tells us where the
81 exception originated. */
82 switch (f->cs) {
83 case SEL_UCSEG:
84 /* User's code segment, so it's a user exception, as we
85 expected. Kill the user process. */
86 printf ("%s: dying due to interrupt %#04llx (%s).\n",
87 thread_name (), f->vec_no, intr_name (f->vec_no));
89 thread_exit ();
90
91 case SEL_KCSEG:
92 /* Kernel's code segment, which indicates a kernel bug.
93 Kernel code shouldn't throw exceptions. (Page faults
94 may cause kernel exceptions--but they shouldn't arrive
95 here.) Panic the kernel to make the point. */
97 PANIC ("Kernel bug - unexpected interrupt in kernel");
98
99 default:
100 /* Some other code segment? Shouldn't happen. Panic the
101 kernel. */
102 printf ("Interrupt %#04llx (%s) in unknown segment %04x\n",
103 f->vec_no, intr_name (f->vec_no), f->cs);
104 thread_exit ();
105 }
106}
#define PANIC(...)
Definition: debug.h:14
const char * intr_name(uint8_t vec)
Definition: interrupt.c:405
void intr_dump_frame(const struct intr_frame *)
Definition: interrupt.c:381
#define SEL_UCSEG
Definition: loader.h:39
#define SEL_KCSEG
Definition: loader.h:36
uint64_t vec_no
Definition: interrupt.h:48
uint16_t cs
Definition: interrupt.h:56
const char * thread_name(void)
Definition: thread.c:293
void thread_exit(void) NO_RETURN
Definition: thread.c:325
Here is the call graph for this function:
Here is the caller graph for this function:

◆ page_fault()

static void page_fault ( struct intr_frame f)
static
120 {
121 bool not_present; /* True: not-present page, false: writing r/o page. */
122 bool write; /* True: access was write, false: access was read. */
123 bool user; /* True: access by user, false: access by kernel. */
124 void *fault_addr; /* Fault address. */
125
126 /* Obtain faulting address, the virtual address that was
127 accessed to cause the fault. It may point to code or to
128 data. It is not necessarily the address of the instruction
129 that caused the fault (that's f->rip). */
130
131 fault_addr = (void *) rcr2();
132
133 /* Turn interrupts back on (they were only off so that we could
134 be assured of reading CR2 before it changed). */
135 intr_enable ();
136
137
138 /* Determine cause. */
139 not_present = (f->error_code & PF_P) == 0;
140 write = (f->error_code & PF_W) != 0;
141 user = (f->error_code & PF_U) != 0;
142
143#ifdef VM
144 /* For project 3 and later. */
145 if (vm_try_handle_fault (f, fault_addr, user, write, not_present))
146 return;
147#endif
148
149 exit(-1); // TC "bad-*" 통과를 위함(exit를 안해주면 kill로 그냥 삭제됨)
150 /* Count page faults. */
152
153 /* If the fault is true fault, show info and exit. */
154 printf ("Page fault at %p: %s error %s page in %s context.\n",
155 fault_addr,
156 not_present ? "not present" : "rights violation",
157 write ? "writing" : "reading",
158 user ? "user" : "kernel");
159 kill (f);
160}
#define PF_W
Definition: exception.h:6
#define PF_P
Definition: exception.h:5
#define PF_U
Definition: exception.h:7
enum intr_level intr_enable(void)
Definition: interrupt.c:136
void exit(int status) NO_RETURN
현재 프로세스를 종료시키는 시스템 콜
Definition: syscall.c:173
int write(int fd, const void *buffer, unsigned length)
열린 파일에 데이터를 쓰는 시스템 콜
Definition: syscall.c:336
uint64_t error_code
Definition: interrupt.h:52
bool vm_try_handle_fault(struct intr_frame *f, void *addr, bool user, bool write, bool not_present)
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ page_fault_cnt

long long page_fault_cnt
static