trap.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. use log::{error, warn};
  2. use system_error::SystemError;
  3. use crate::{
  4. arch::{CurrentIrqArch, MMArch},
  5. exception::InterruptArch,
  6. mm::VirtAddr,
  7. process::ProcessManager,
  8. smp::core::smp_get_processor_id,
  9. };
  10. use super::{
  11. entry::{set_intr_gate, set_system_trap_gate},
  12. TrapFrame,
  13. };
  14. extern "C" {
  15. fn trap_divide_error();
  16. fn trap_debug();
  17. fn trap_nmi();
  18. fn trap_int3();
  19. fn trap_overflow();
  20. fn trap_bounds();
  21. fn trap_undefined_opcode();
  22. fn trap_dev_not_avaliable();
  23. fn trap_double_fault();
  24. fn trap_coprocessor_segment_overrun();
  25. fn trap_invalid_TSS();
  26. fn trap_segment_not_exists();
  27. fn trap_stack_segment_fault();
  28. fn trap_general_protection();
  29. fn trap_page_fault();
  30. fn trap_x87_FPU_error();
  31. fn trap_alignment_check();
  32. fn trap_machine_check();
  33. fn trap_SIMD_exception();
  34. fn trap_virtualization_exception();
  35. }
  36. bitflags! {
  37. pub struct TrapNr: u64 {
  38. const X86_TRAP_DE = 0;
  39. const X86_TRAP_DB = 1;
  40. const X86_TRAP_NMI = 2;
  41. const X86_TRAP_BP = 3;
  42. const X86_TRAP_OF = 4;
  43. const X86_TRAP_BR = 5;
  44. const X86_TRAP_UD = 6;
  45. const X86_TRAP_NM = 7;
  46. const X86_TRAP_DF = 8;
  47. const X86_TRAP_OLD_MF = 9;
  48. const X86_TRAP_TS = 10;
  49. const X86_TRAP_NP = 11;
  50. const X86_TRAP_SS = 12;
  51. const X86_TRAP_GP = 13;
  52. const X86_TRAP_PF = 14;
  53. const X86_TRAP_SPURIOUS = 15;
  54. const X86_TRAP_MF = 16;
  55. const X86_TRAP_AC = 17;
  56. const X86_TRAP_MC = 18;
  57. const X86_TRAP_XF = 19;
  58. const X86_TRAP_VE = 20;
  59. const X86_TRAP_CP = 21;
  60. const X86_TRAP_VC = 29;
  61. const X86_TRAP_IRET = 32;
  62. }
  63. pub struct X86PfErrorCode : u32{
  64. const X86_PF_PROT = 1 << 0;
  65. const X86_PF_WRITE = 1 << 1;
  66. const X86_PF_USER = 1 << 2;
  67. const X86_PF_RSVD = 1 << 3;
  68. const X86_PF_INSTR = 1 << 4;
  69. const X86_PF_PK = 1 << 5;
  70. const X86_PF_SHSTK = 1 << 6;
  71. const X86_PF_SGX = 1 << 15;
  72. }
  73. }
  74. #[inline(never)]
  75. pub fn arch_trap_init() -> Result<(), SystemError> {
  76. unsafe {
  77. set_intr_gate(0, 0, VirtAddr::new(trap_divide_error as usize));
  78. set_intr_gate(1, 0, VirtAddr::new(trap_debug as usize));
  79. set_intr_gate(2, 0, VirtAddr::new(trap_nmi as usize));
  80. set_system_trap_gate(3, 0, VirtAddr::new(trap_int3 as usize));
  81. set_system_trap_gate(4, 0, VirtAddr::new(trap_overflow as usize));
  82. set_system_trap_gate(5, 0, VirtAddr::new(trap_bounds as usize));
  83. set_intr_gate(6, 0, VirtAddr::new(trap_undefined_opcode as usize));
  84. set_intr_gate(7, 0, VirtAddr::new(trap_dev_not_avaliable as usize));
  85. set_intr_gate(8, 0, VirtAddr::new(trap_double_fault as usize));
  86. set_intr_gate(
  87. 9,
  88. 0,
  89. VirtAddr::new(trap_coprocessor_segment_overrun as usize),
  90. );
  91. set_intr_gate(10, 0, VirtAddr::new(trap_invalid_TSS as usize));
  92. set_intr_gate(11, 0, VirtAddr::new(trap_segment_not_exists as usize));
  93. set_intr_gate(12, 0, VirtAddr::new(trap_stack_segment_fault as usize));
  94. set_intr_gate(13, 0, VirtAddr::new(trap_general_protection as usize));
  95. set_intr_gate(14, 0, VirtAddr::new(trap_page_fault as usize));
  96. // 中断号15由Intel保留,不能使用
  97. set_intr_gate(16, 0, VirtAddr::new(trap_x87_FPU_error as usize));
  98. set_intr_gate(17, 0, VirtAddr::new(trap_alignment_check as usize));
  99. set_intr_gate(18, 0, VirtAddr::new(trap_machine_check as usize));
  100. set_intr_gate(19, 0, VirtAddr::new(trap_SIMD_exception as usize));
  101. set_intr_gate(20, 0, VirtAddr::new(trap_virtualization_exception as usize));
  102. }
  103. return Ok(());
  104. }
  105. /// 处理除法错误 0 #DE
  106. #[no_mangle]
  107. unsafe extern "C" fn do_divide_error(regs: &'static TrapFrame, error_code: u64) {
  108. error!(
  109. "do_divide_error(0), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  110. error_code,
  111. regs.rsp,
  112. regs.rip,
  113. smp_get_processor_id().data(),
  114. ProcessManager::current_pid()
  115. );
  116. panic!("Divide Error");
  117. }
  118. /// 处理调试异常 1 #DB
  119. #[no_mangle]
  120. unsafe extern "C" fn do_debug(regs: &'static TrapFrame, error_code: u64) {
  121. error!(
  122. "do_debug(1), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  123. error_code,
  124. regs.rsp,
  125. regs.rip,
  126. smp_get_processor_id().data(),
  127. ProcessManager::current_pid()
  128. );
  129. panic!("Debug Exception");
  130. }
  131. /// 处理NMI中断 2 NMI
  132. #[no_mangle]
  133. unsafe extern "C" fn do_nmi(regs: &'static TrapFrame, error_code: u64) {
  134. error!(
  135. "do_nmi(2), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  136. error_code,
  137. regs.rsp,
  138. regs.rip,
  139. smp_get_processor_id().data(),
  140. ProcessManager::current_pid()
  141. );
  142. panic!("NMI Interrupt");
  143. }
  144. /// 处理断点异常 3 #BP
  145. #[no_mangle]
  146. unsafe extern "C" fn do_int3(regs: &'static TrapFrame, error_code: u64) {
  147. error!(
  148. "do_int3(3), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  149. error_code,
  150. regs.rsp,
  151. regs.rip,
  152. smp_get_processor_id().data(),
  153. ProcessManager::current_pid()
  154. );
  155. panic!("Int3");
  156. }
  157. /// 处理溢出异常 4 #OF
  158. #[no_mangle]
  159. unsafe extern "C" fn do_overflow(regs: &'static TrapFrame, error_code: u64) {
  160. error!(
  161. "do_overflow(4), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  162. error_code,
  163. regs.rsp,
  164. regs.rip,
  165. smp_get_processor_id().data(),
  166. ProcessManager::current_pid()
  167. );
  168. panic!("Overflow Exception");
  169. }
  170. /// 处理BOUND指令检查异常 5 #BR
  171. #[no_mangle]
  172. unsafe extern "C" fn do_bounds(regs: &'static TrapFrame, error_code: u64) {
  173. error!(
  174. "do_bounds(5), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  175. error_code,
  176. regs.rsp,
  177. regs.rip,
  178. smp_get_processor_id().data(),
  179. ProcessManager::current_pid()
  180. );
  181. panic!("Bounds Check");
  182. }
  183. /// 处理未定义操作码异常 6 #UD
  184. #[no_mangle]
  185. unsafe extern "C" fn do_undefined_opcode(regs: &'static TrapFrame, error_code: u64) {
  186. error!(
  187. "do_undefined_opcode(6), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  188. error_code,
  189. regs.rsp,
  190. regs.rip,
  191. smp_get_processor_id().data(),
  192. ProcessManager::current_pid()
  193. );
  194. panic!("Undefined Opcode");
  195. }
  196. /// 处理设备不可用异常(FPU不存在) 7 #NM
  197. #[no_mangle]
  198. unsafe extern "C" fn do_dev_not_avaliable(regs: &'static TrapFrame, error_code: u64) {
  199. error!(
  200. "do_dev_not_avaliable(7), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  201. error_code,
  202. regs.rsp,
  203. regs.rip,
  204. smp_get_processor_id().data(),
  205. ProcessManager::current_pid()
  206. );
  207. panic!("Device Not Available");
  208. }
  209. /// 处理双重错误 8 #DF
  210. #[no_mangle]
  211. unsafe extern "C" fn do_double_fault(regs: &'static TrapFrame, error_code: u64) {
  212. error!(
  213. "do_double_fault(8), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  214. error_code,
  215. regs.rsp,
  216. regs.rip,
  217. smp_get_processor_id().data(),
  218. ProcessManager::current_pid()
  219. );
  220. panic!("Double Fault");
  221. }
  222. /// 处理协处理器段越界 9 #MF
  223. #[no_mangle]
  224. unsafe extern "C" fn do_coprocessor_segment_overrun(regs: &'static TrapFrame, error_code: u64) {
  225. error!(
  226. "do_coprocessor_segment_overrun(9), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  227. error_code,
  228. regs.rsp,
  229. regs.rip,
  230. smp_get_processor_id().data(),
  231. ProcessManager::current_pid()
  232. );
  233. panic!("Coprocessor Segment Overrun");
  234. }
  235. /// 处理无效TSS 10 #TS
  236. #[no_mangle]
  237. unsafe extern "C" fn do_invalid_TSS(regs: &'static TrapFrame, error_code: u64) {
  238. const ERR_MSG_1: &str =
  239. "The exception occurred during delivery of an event external to the program.\n";
  240. const ERR_MSG_2: &str = "Refers to a descriptor in the IDT.\n";
  241. const ERR_MSG_3: &str = "Refers to a descriptor in the current LDT.\n";
  242. const ERR_MSG_4: &str = "Refers to a descriptor in the GDT.\n";
  243. let msg1: &str = if (error_code & 0x1) != 0 {
  244. ERR_MSG_1
  245. } else {
  246. ""
  247. };
  248. let msg2: &str = if (error_code & 0x02) != 0 {
  249. ERR_MSG_2
  250. } else if (error_code & 0x04) != 0 {
  251. ERR_MSG_3
  252. } else {
  253. ERR_MSG_4
  254. };
  255. error!(
  256. "do_invalid_TSS(10), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}\n{}{}",
  257. error_code,
  258. regs.rsp,
  259. regs.rip,
  260. smp_get_processor_id().data(),
  261. ProcessManager::current_pid(),
  262. msg1,
  263. msg2
  264. );
  265. panic!("Invalid TSS");
  266. }
  267. /// 处理段不存在 11 #NP
  268. #[no_mangle]
  269. unsafe extern "C" fn do_segment_not_exists(regs: &'static TrapFrame, error_code: u64) {
  270. error!(
  271. "do_segment_not_exists(11), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  272. error_code,
  273. regs.rsp,
  274. regs.rip,
  275. smp_get_processor_id().data(),
  276. ProcessManager::current_pid()
  277. );
  278. panic!("Segment Not Exists");
  279. }
  280. /// 处理栈段错误 12 #SS
  281. #[no_mangle]
  282. unsafe extern "C" fn do_stack_segment_fault(regs: &'static TrapFrame, error_code: u64) {
  283. error!(
  284. "do_stack_segment_fault(12), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  285. error_code,
  286. regs.rsp,
  287. regs.rip,
  288. smp_get_processor_id().data(),
  289. ProcessManager::current_pid()
  290. );
  291. panic!("Stack Segment Fault");
  292. }
  293. /// 处理一般保护异常 13 #GP
  294. #[no_mangle]
  295. unsafe extern "C" fn do_general_protection(regs: &'static TrapFrame, error_code: u64) {
  296. const ERR_MSG_1: &str = "The exception occurred during delivery of an event external to the program, such as an interrupt or an earlier exception.";
  297. const ERR_MSG_2: &str = "Refers to a gate descriptor in the IDT;\n";
  298. const ERR_MSG_3: &str = "Refers to a descriptor in the GDT or the current LDT;\n";
  299. const ERR_MSG_4: &str = "Refers to a segment or gate descriptor in the LDT;\n";
  300. const ERR_MSG_5: &str = "Refers to a descriptor in the current GDT;\n";
  301. let msg1: &str = if (error_code & 0x1) != 0 {
  302. ERR_MSG_1
  303. } else {
  304. ""
  305. };
  306. let msg2: &str = if (error_code & 0x02) != 0 {
  307. ERR_MSG_2
  308. } else {
  309. ERR_MSG_3
  310. };
  311. let msg3: &str = if (error_code & 0x02) == 0 {
  312. if (error_code & 0x04) != 0 {
  313. ERR_MSG_4
  314. } else {
  315. ERR_MSG_5
  316. }
  317. } else {
  318. ""
  319. };
  320. error!(
  321. "do_general_protection(13), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t rflags: {:#x}\t CPU: {}, \tpid: {:?}
  322. {}{}{}
  323. Segment Selector Index: {:#x}\n
  324. ",
  325. error_code,
  326. regs.rsp,
  327. regs.rip,
  328. regs.rflags,
  329. smp_get_processor_id().data(),
  330. ProcessManager::current_pid(),
  331. msg1, msg2, msg3,
  332. error_code & 0xfff8
  333. );
  334. panic!("General Protection");
  335. }
  336. /// 处理页错误 14 #PF
  337. #[no_mangle]
  338. unsafe extern "C" fn do_page_fault(regs: &'static TrapFrame, error_code: u64) {
  339. // error!(
  340. // "do_page_fault(14), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}, \nFault Address: {:#x}",
  341. // error_code,
  342. // regs.rsp,
  343. // regs.rip,
  344. // smp_get_processor_id().data(),
  345. // ProcessManager::current_pid(),
  346. // x86::controlregs::cr2()
  347. // );
  348. // if (error_code & 0x01) == 0 {
  349. // print!("Page Not Present,\t");
  350. // }
  351. // if (error_code & 0x02) != 0 {
  352. // print!("Write Access,\t");
  353. // } else {
  354. // print!("Read Access,\t");
  355. // }
  356. // if (error_code & 0x04) != 0 {
  357. // print!("Fault in user(3),\t");
  358. // } else {
  359. // print!("Fault in supervisor(0,1,2),\t");
  360. // }
  361. // if (error_code & 0x08) != 0 {
  362. // print!("Reserved bit violation cause fault,\t");
  363. // }
  364. // if (error_code & 0x10) != 0 {
  365. // print!("Instruction fetch cause fault,\t");
  366. // }
  367. // print!("\n");
  368. // CurrentIrqArch::interrupt_enable();
  369. // panic!("Page Fault");
  370. CurrentIrqArch::interrupt_disable();
  371. let address = x86::controlregs::cr2();
  372. // crate::info!(
  373. // "fault address: {:#x}, error_code: {:#b}, pid: {}\n",
  374. // address,
  375. // error_code,
  376. // ProcessManager::current_pid().data()
  377. // );
  378. let address = VirtAddr::new(address);
  379. let error_code = X86PfErrorCode::from_bits_truncate(error_code as u32);
  380. if address.check_user() {
  381. MMArch::do_user_addr_fault(regs, error_code, address);
  382. } else {
  383. MMArch::do_kern_addr_fault(regs, error_code, address);
  384. }
  385. CurrentIrqArch::interrupt_enable();
  386. }
  387. /// 处理x87 FPU错误 16 #MF
  388. #[no_mangle]
  389. unsafe extern "C" fn do_x87_FPU_error(regs: &'static TrapFrame, error_code: u64) {
  390. error!(
  391. "do_x87_FPU_error(16), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  392. error_code,
  393. regs.rsp,
  394. regs.rip,
  395. smp_get_processor_id().data(),
  396. ProcessManager::current_pid()
  397. );
  398. panic!("x87 FPU Error");
  399. }
  400. /// 处理对齐检查 17 #AC
  401. #[no_mangle]
  402. unsafe extern "C" fn do_alignment_check(regs: &'static TrapFrame, error_code: u64) {
  403. error!(
  404. "do_alignment_check(17), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  405. error_code,
  406. regs.rsp,
  407. regs.rip,
  408. smp_get_processor_id().data(),
  409. ProcessManager::current_pid()
  410. );
  411. panic!("Alignment Check");
  412. }
  413. /// 处理机器检查 18 #MC
  414. #[no_mangle]
  415. unsafe extern "C" fn do_machine_check(regs: &'static TrapFrame, error_code: u64) {
  416. error!(
  417. "do_machine_check(18), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  418. error_code,
  419. regs.rsp,
  420. regs.rip,
  421. smp_get_processor_id().data(),
  422. ProcessManager::current_pid()
  423. );
  424. panic!("Machine Check");
  425. }
  426. /// 处理SIMD异常 19 #XM
  427. #[no_mangle]
  428. unsafe extern "C" fn do_SIMD_exception(regs: &'static TrapFrame, error_code: u64) {
  429. error!(
  430. "do_SIMD_exception(19), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  431. error_code,
  432. regs.rsp,
  433. regs.rip,
  434. smp_get_processor_id().data(),
  435. ProcessManager::current_pid()
  436. );
  437. panic!("SIMD Exception");
  438. }
  439. /// 处理虚拟化异常 20 #VE
  440. #[no_mangle]
  441. unsafe extern "C" fn do_virtualization_exception(regs: &'static TrapFrame, error_code: u64) {
  442. error!(
  443. "do_virtualization_exception(20), \tError code: {:#x},\trsp: {:#x},\trip: {:#x},\t CPU: {}, \tpid: {:?}",
  444. error_code,
  445. regs.rsp,
  446. regs.rip,
  447. smp_get_processor_id().data(),
  448. ProcessManager::current_pid()
  449. );
  450. panic!("Virtualization Exception");
  451. }
  452. #[no_mangle]
  453. unsafe extern "C" fn ignore_int_handler(_regs: &'static TrapFrame, _error_code: u64) {
  454. warn!("Unknown interrupt.");
  455. }