이 코드는 어떤 문제를 푸나요?
CPU가 주소를 변환하지 못하면 커널이 그 접근의 이유를 판단합니다. 아직 물리 페이지를 붙이지 않은 정상적인 사용자 영역일 수도 있고 잘못된 주소일 수도 있습니다. arm64의 do_translation_fault는 먼저 사용자 주소 범위로 처리할 수 있는지 구분한 뒤 자세한 처리를 넘깁니다.
읽을 범위: v6.6 · arch/arm64/mm/fault.c · do_translation_fault 703–714행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.
먼저 알아둘 개념
FAR와 ESR
FAR은 예외가 보고한 주소, ESR은 접근 종류와 실패 이유 등을 담은 상태 값입니다. 어느 주소를 접근했는지와 왜 실패했는지를 함께 봐야 합니다.
태그가 있는 주소
arm64 주소에는 설정에 따라 태그 정보가 포함될 수 있습니다. 범위를 판정할 때 사용하는 주소와 원래 예외가 보고한 값이 구분될 수 있습니다.
translation fault
페이지 테이블 변환이 성립하지 않은 예외입니다. 유효한 매핑의 권한 위반과 같은 말은 아닙니다.
처음 읽을 때
아직 처음 접근하지 않은 사용자 메모리와 잘못된 커널 포인터가 모두 변환 실패를 일으킬 수 있다고 생각해 보세요. CPU의 같은 종류 알림을 소프트웨어가 문맥에 따라 다르게 처리합니다.
더 깊이 살펴볼 때
do_page_fault 내부의 VMA 조회, 접근 권한 판단과 handle_mm_fault 반환값을 이어서 읽으세요. 이 짧은 함수의 반환 0이 물리 페이지를 새로 만들었다는 뜻은 아닙니다.
그림으로 보는 변화

1. CPU가 변환 실패 보고
FAR, ESR, 저장된 pt_regs
화살표는 예외 처리 분기 순서입니다. 메모리 데이터가 이동하는 방향이 아닙니다.
2. 주소 범위 확인
untagged_addr → is_ttbr0_addr
태그를 제외한 주소로 TTBR0 주소 범위인지 판정합니다.
3. 맞는 처리 경로로 전달
TTBR0 범위: do_page_fault / 그 외: do_bad_area
두 이름은 대안 경로입니다. 위에서 아래로 두 함수를 모두 호출하는 순서가 아닙니다.
do_translation_fault를 한 줄씩 읽기
줄 번호는 v6.6 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.
static int __kprobes do_translation_fault(unsigned long far,
unsigned long esr,
struct pt_regs *regs)
{
unsigned long addr = untagged_addr(far);
if (is_ttbr0_addr(addr))
return do_page_fault(far, esr, regs);
do_bad_area(far, esr, regs);
return 0;
}static int __kprobes do_translation_fault(unsigned long far,주소 변환 실패를 처리할 함수입니다. far는 CPU가 보고한 접근 주소이며 __kprobes는 예외 처리와 프로브 계측의 관계에 필요한 표기입니다.
unsigned long esr,esr에는 실패 종류와 접근 특성이 들어 있습니다. 주소 숫자만으로는 읽기·쓰기 등 예외의 의미를 충분히 알 수 없습니다.
struct pt_regs *regs)regs는 예외가 발생했을 때 저장한 CPU 문맥입니다. 사용자 실행 중이었는지, 어느 명령에서 발생했는지 판단하는 데 사용됩니다.
unsigned long addr = untagged_addr(far);주소 범위를 판정하기 위해 태그를 제외한 addr를 만듭니다. 원래 far 변수 자체를 덮어쓰지는 않습니다.
if (is_ttbr0_addr(addr))해당 주소가 TTBR0 쪽 주소 범위인지 확인합니다. 단순히 현재 커널 모드인지 여부만 검사하는 조건이 아닙니다.
return do_page_fault(far, esr, regs);TTBR0 범위라면 VMA와 실제 메모리 상태를 확인하는 do_page_fault로 원래 예외 정보를 넘기고 그 결과를 반환합니다.
do_bad_area(far, esr, regs);앞 조건에 해당하지 않은 주소는 잘못된 영역 처리로 넘깁니다. 이 줄에서 무조건 사용자 지연 할당을 시도하지 않습니다.
return 0;이 처리 경로의 반환 규약에 따라 0을 돌려줍니다. 새 페이지 할당 성공의 개수를 뜻하지 않습니다.
함께 생각해 볼 질문
page fault가 나면 무조건 프로세스를 종료하나요?
아닙니다. 정상적인 지연 할당이나 파일 매핑을 완성하고 같은 명령을 다시 실행할 수 있습니다.
주소 태그를 제거했는데 왜 원래 far를 넘기나요?
범위 판정용 addr와 예외의 원래 정보를 분리하기 때문입니다. 다음 처리 단계에 원래 FAR 값을 보존합니다.
return 0이면 새 페이지가 생겼다는 뜻인가요?
그렇지 않습니다. 이 예외 처리 인터페이스의 반환 규약을 나타내며 이 경로에서는 do_bad_area 호출 뒤에도 0을 반환합니다.
출처와 읽은 범위
Linux stable v6.6 · arch/arm64/mm/fault.c
해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고
