@@ -39,20 +39,27 @@ pub extern "C" fn trap_handler(tf: &mut TrapFrame) {
39
39
trap_handler_no_frame ( & mut tf. sepc ) ;
40
40
}
41
41
42
+ use crate :: memory:: AccessType ;
42
43
#[ inline]
43
44
pub fn trap_handler_no_frame ( sepc : & mut usize ) {
44
45
use self :: scause:: { Exception as E , Interrupt as I , Trap } ;
45
46
let scause = scause:: read ( ) ;
46
47
let stval = stval:: read ( ) ;
48
+ let is_user = false ;
47
49
trace ! ( "Interrupt @ CPU{}: {:?} " , super :: cpu:: id( ) , scause. cause( ) ) ;
48
50
match scause. cause ( ) {
49
51
Trap :: Interrupt ( I :: SupervisorExternal ) => external ( ) ,
50
52
Trap :: Interrupt ( I :: SupervisorSoft ) => ipi ( ) ,
51
53
Trap :: Interrupt ( I :: SupervisorTimer ) => timer ( ) ,
52
- Trap :: Exception ( E :: LoadPageFault ) => page_fault ( stval, sepc) ,
53
- Trap :: Exception ( E :: StorePageFault ) => page_fault ( stval, sepc) ,
54
- Trap :: Exception ( E :: InstructionPageFault ) => page_fault ( stval, sepc) ,
55
- _ => panic ! ( "unhandled trap {:?}" , scause. cause( ) ) ,
54
+ Trap :: Exception ( E :: LoadPageFault ) => page_fault ( stval, sepc, AccessType :: read ( is_user) ) ,
55
+ Trap :: Exception ( E :: StorePageFault ) => page_fault ( stval, sepc, AccessType :: write ( is_user) ) ,
56
+ Trap :: Exception ( E :: InstructionPageFault ) => {
57
+ page_fault ( stval, sepc, AccessType :: execute ( is_user) )
58
+ }
59
+ _ => {
60
+ let bits = scause. bits ( ) ;
61
+ panic ! ( "unhandled trap {:?} ({})" , scause. cause( ) , bits) ;
62
+ }
56
63
}
57
64
trace ! ( "Interrupt end" ) ;
58
65
}
@@ -62,7 +69,6 @@ fn external() {
62
69
unsafe {
63
70
super :: board:: handle_external_interrupt ( ) ;
64
71
}
65
-
66
72
IRQ_MANAGER
67
73
. read ( )
68
74
. try_handle_interrupt ( Some ( SupervisorExternal ) ) ;
@@ -78,11 +84,11 @@ pub fn timer() {
78
84
crate :: trap:: timer ( ) ;
79
85
}
80
86
81
- fn page_fault ( stval : usize , sepc : & mut usize ) {
87
+ fn page_fault ( stval : usize , sepc : & mut usize , access : AccessType ) {
82
88
let addr = stval;
83
89
info ! ( "\n EXCEPTION: Page Fault @ {:#x}" , addr) ;
84
90
85
- if crate :: memory:: handle_page_fault ( addr) {
91
+ if crate :: memory:: handle_page_fault_ext ( addr, access ) {
86
92
return ;
87
93
}
88
94
extern "C" {
@@ -94,6 +100,7 @@ fn page_fault(stval: usize, sepc: &mut usize) {
94
100
* sepc = crate :: memory:: read_user_fixup as usize ;
95
101
return ;
96
102
}
103
+ error ! ( "unhandled page fault {:#x} from {:#x}" , addr, sepc) ;
97
104
panic ! ( "unhandled page fault" ) ;
98
105
}
99
106
@@ -121,8 +128,8 @@ pub fn wait_for_interrupt() {
121
128
}
122
129
}
123
130
124
- pub fn handle_user_page_fault ( thread : & Arc < Thread > , addr : usize ) -> bool {
125
- thread. vm . lock ( ) . handle_page_fault ( addr)
131
+ pub fn handle_user_page_fault_ext ( thread : & Arc < Thread > , addr : usize , access : AccessType ) -> bool {
132
+ thread. vm . lock ( ) . handle_page_fault_ext ( addr, access )
126
133
}
127
134
128
135
pub fn handle_reserved_inst ( tf : & mut UserContext ) -> bool {
0 commit comments