[커널 17차] 70주차
2022.01.01 23:42
SDEI 관련 (arch/arm64/kernel/entry.S)
- vector table에서 CONFIG_UNMAP_KERNEL_AT_EL0가 설정된 경우 X30를 저장하지 않고 덮어쓰는 부분이 있음
- mrs x30, tpidrro_el0
- 그런데 커널 코드에서 x30을 저장하는 부분은 tramp_vector 부분임
- msr tpidrro_el0, x30 (tramp_ventry)
- 그런데 tramp_ventry는 SDEI (software delegate exception interface)를 통해서 접근하는 것으로 보인다
- __sdei_asm_entry_trampoline 부분
- 그런데 SDEI는 OS/Hypervisor와 Secure firmware 간의 exception 통신을 위한 인터페이스인 것으로 보임
- https://developer.arm.com/architectures/system-architectures/software-standards/sdei
- 따라서 tramp_ventry는 인터럽트 발생 후 EL3 펌웨어가 인터럽트를 가로채서 SDEI를 통해 trampoline 관련 처리를 모두 하고 커널로 돌아가서 통상적인 벡터 처리를 하고 다시 리턴할 때는 다시 SDEI를 통해 trampoline 처리 후 EL0로 돌아가는 것으로 보인다
copy_from_user() 코드 분석
- fixup code에서는 특별히 처리하는 것은 없고 그저 dst addr에서 src addr까지 1B를 copy하는 테스트를 수행한다
- 그리고 copy되지 않고 남은 데이터 바이트 수를 리턴한다
- user_ldp, user_stp, user_ldst 등의 매크로로 sttr, ldtr 등의 명령어와 함께 exception table entry 생성을 수행한다
demand loading 실행시 do_mem_abort() —> do_page_fault() 순서대로 수행하고
- __do_page_fault() 내에서 페이지 테이블을 demand loading하고 생성한다
- 이후 return 0으로 exception 발생한 코드를 다시 재수행한다
- 만약 에러가 발생한 경우에는 no_context로 이동하여 __do_kernel_fault() —> fixup_exception() —> search_exception_tables() 순서대로 실행되어
- exception table entry를 찾아서 regs->pc를 fixup code로 변경하고 fixup을 수행한다
trap_init()
- 커널의 bug break hook, fault break hook, kasan break hook 코드를 kernel break hook에 연결한다. 이 때 함수 register_kernel_break_hook()를 사용한다
- 그리고 debug fault code 중 hardware single-step, aarch64 breakpoint fault 처리 함수를 등록한다. 이는 함수 debug_traps_init()를 이용해서 실행된다
register_kernel_break_hook()
- 전역 변수 list head 포인터 kernel_break_hook가 존재해서 kernel의 break hook 코드들을 여기에 list head로 달아준다
- break hook 코드는 구조체 break_hook으로 정의되어 관리되며 다음과 같다
struct break_hook {
struct list_head node;
int (*fn)(struct pt_regs *regs, unsigned int esr);
u16 imm;
u16 mask; /* These bits are ignored when comparing with imm */
};
- 여기서 node를 통해 break_hook이 연결되어 관리되며 특히 kernel break hook은 kernel_break_hook list head 전역 변수가 관리한다.
- 함수 fn에 필요한 함수를 달아준다
- bug break hook에는 함수 bug_handler(), fault break hook에는 함수 reserved_fault_handler(), kanas break hook에는 함수 kasan_handler()가 달리게 된다
- 함수를 등록할 때 spin lock과 rcu를 이용한다
debug_traps_init()
- 함수 hook_debug_fault_code()를 이용해서 hardware single-step, aarch64 breakpoint fault 처리 함수를 등록한다
- 전역 변수 fault_info 구조체 배열 debug_fault_info[]의 1번 6번 엔트리에 hardware single-step, aarch64 breakpoint fault 처리 함수와 code signal, name을 등록한다
- 각각 single_step_handler, brk_handler 함수가 등록된다
Hooking 함수 사용
- 실제 사용하는 경우 함수 call_break_hook()에 의해서 사용된다. 그리고 call_break_hook()은 brk_handler()에서 호출된다
brk_handler()
- call_break_hook()에서 kernel_break_hook list를 돌면서 esr 입력 조건에 맞는 hook 함수를 골라서 실행한다
- 결과적으로는 BRK immediate에서 immediate에 따라 hook 함수를 고르게 된다
- 함수 esr_to_debug_fault_info()에서 debug_fault_info[] 배열에서 esr에 따른 offset을 계산해서 호출하게 된다
- 그리고 esr_to_debug_fault_info() 함수는 do_debug_exception() 함수에서 호출된다
- 함수 do_debug_exception()는 el1_dbg(), el0_dbg() 함수에서 호출된다
- 함수 el1_dbg(), el0_dbg()는 el1h_64_sync_handler()에서 호출된다
- 하드웨어 ESR_EL1에는 EC에 111100이 들어간다 (BRK 명령어에 의한 exception 발생) —> debug_fault_info[] 배열의 6번 인덱스가 된다
- BRK 명령어가 아니라 software step exception 발생하면 EC에 110010/110011이 들어간다. breakpoint, watchpoint 등도 고유한 EC 값이 주어진다
- el1h_64_sync_handler()에서 breakpoint, software step, watchpoint, BRK 모두 el1_dbg()을 호출하게 된다
- hardware breakpoint 및 watchpoint 등은 breakpoint_handler(), watchpoint_handler() 함수에서 처리되며 이들은 arch/arm64/kernel/hw_breakpoint.c 파일에 존재한다
- 이들은 함수 arch_hw_breakpoint_init()에서 등록된다
arm64 DEBUG 관련 내용
- https://developer.arm.com/documentation/102120/0100/Introduction-to-debug
ESR_EL1 레지스터
- https://developer.arm.com/documentation/ddi0595/2021-06/AArch64-Registers/ESR-EL1--Exception-Syndrome-Register--EL1-
BRK 명령어
- https://developer.arm.com/documentation/ddi0602/2021-12/Base-Instructions/BRK--Breakpoint-instruction-
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
공지 | [공지] 스터디 정리 노트 공간입니다. | woos | 2016.05.14 | 623 |
106 | [커널 17차] 76주차 [1] | ㅇㅇㅇ | 2022.02.19 | 139 |
105 | [커널 17차] 75주차 | ㅇㅇㅇ | 2022.02.05 | 74 |
104 | [커널 17차] 73주차 | ㅇㅇㅇ | 2022.01.23 | 73 |
103 | [커널 17차] 72주차 | ㅇㅇㅇ | 2022.01.16 | 88 |
102 | [커널 17차] 71주차 | ㅇㅇㅇ | 2022.01.09 | 145 |
» | [커널 17차] 70주차 | ㅇㅇㅇ | 2022.01.01 | 202 |
100 | [커널 17차] 68주차 | ㅇㅇㅇ | 2021.12.18 | 158 |
99 | [커널 17차] 66~67주차 | ㅇㅇㅇ | 2021.12.11 | 78 |
98 | [커널 17차] 65주차 | ㅇㅇㅇ | 2021.11.28 | 180 |
97 | [커널 17차] 64주차 | ㅇㅇㅇ | 2021.11.21 | 64 |
96 | [커널 17차] 63주차 | ㅇㅇㅇ | 2021.11.14 | 62 |
95 | [커널 17차] 62주차 | ㅇㅇㅇ | 2021.11.07 | 123 |
94 | [커널 17차] 61주차 | ㅇㅇㅇ | 2021.10.31 | 79 |
93 | [커널 17차] 60주차 | ㅇㅇㅇ | 2021.10.24 | 97 |
92 | [커널 17차] 59주차 | ㅇㅇㅇ | 2021.10.17 | 167 |
91 | [커널 17차] 58주차 | ㅇㅇㅇ | 2021.10.10 | 67 |
90 | [커널 17차] 57주차 | ㅇㅇㅇ | 2021.10.04 | 66 |
89 | [커널 17차] 56주차 | ㅇㅇㅇ | 2021.10.03 | 27521 |
88 | [커널 17차] 55주차 | ㅇㅇㅇ | 2021.10.03 | 26 |
87 | [커널 17차] 54주차 | ㅇㅇㅇ | 2021.09.11 | 115 |
.