이 코드는 어떤 문제를 푸나요?
페이지 표의 내용을 고쳐도 CPU가 TLB에 저장한 옛 번역은 남을 수 있습니다. arm64는 공유 범위 TLBI, x86은 INVLPG/INVPCID와 원격 호출, RISC-V는 SFENCE.VMA와 원격 요청을 조합합니다. 대표로 arm64 전체 EL1 변환 무효화의 짧은 순서를 읽습니다.
읽을 범위: v6.18.37 · arch/arm64/include/asm/tlbflush.h · flush_tlb_all 364–370행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.
먼저 알아둘 개념
TLB
최근 주소 변환과 권한을 저장한 하드웨어 상태입니다. PTE 메모리 변경과 TLB 변경은 별개입니다.
공유 무효화
vmalle1is의 is는 inner-shareable 범위 전파를 나타냅니다. 로컬 vmalle1과 범위가 다릅니다.
완료 조건
옛 매핑을 더 이상 사용하지 않는 시점 전에 메모리를 재사용하면 다른 CPU가 엉뚱한 페이지에 접근할 수 있습니다.
처음 읽을 때
PTE를 지운 순간과 다른 CPU가 옛 TLB를 버린 순간을 타임라인에서 나누십시오.
더 깊이 살펴볼 때
__tlbi_sync_s1ish_kernel의 CPU 기능별 처리와 페이지 테이블 수명·재사용 조건을 추적하십시오.
그림으로 보는 변화

1. PTE 변경 공개
DSB ISHST로 앞선 store가 필요한 순서에 도달하게 합니다.
화살표는 페이지 표 변경이 무효화보다 앞선다는 순서입니다.
2. 옛 번역 무효화
공유 범위 TLBI를 실행합니다.
화살표는 데이터 캐시 삭제가 아니라 주소 번역 무효화입니다.
3. 완료와 명령 동기화
동기화 helper와 ISB를 거칩니다.
TLBI 명령을 보낸 시점과 안전하게 후속 실행하는 시점을 구분합니다.
flush_tlb_all를 한 줄씩 읽기
줄 번호는 v6.18.37 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.
static inline void flush_tlb_all(void)
{
dsb(ishst);
__tlbi(vmalle1is);
__tlbi_sync_s1ish_kernel();
isb();
}static inline void flush_tlb_all(void)커널이 관리하는 EL1 Stage-1 변환을 공유 범위에서 무효화하는 helper입니다. 이름의 all을 모든 장치·모든 Stage-2까지 포함한다고 읽지 않습니다.
dsb(ishst);앞선 페이지 표 store가 inner-shareable 범위에서 무효화보다 앞서도록 DSB ISHST를 수행합니다.
__tlbi(vmalle1is);VMALLE1IS 형태의 TLBI를 발행합니다. EL1 변환을 inner-shareable 범위로 무효화하는 명령이며 일반 RAM 데이터를 지우지 않습니다.
__tlbi_sync_s1ish_kernel();이 helper는 DSB ISH를 수행하고 필요한 반복 TLBI 보완 경로를 호출합니다. 무효화 요청을 보낸 것과 공유 범위에서 완료를 기다리는 것을 구분합니다.
isb();이후 명령 실행이 갱신한 변환 환경과 동기화되도록 ISB를 수행합니다.
함께 생각해 볼 질문
PTE를 0으로 썼으니 페이지를 바로 재사용해도 됩니까?
관련 CPU와 보조 변환기의 무효화·수명 규칙을 먼저 만족해야 합니다.
TLBI가 RAM의 데이터를 지웁니까?
아닙니다. 주소 변환 상태를 무효화합니다.
로컬 flush와 전체 공유 flush는 같습니까?
아닙니다. 원문은 명령과 DSB 범위를 다르게 사용합니다.
출처와 읽은 범위
Linux stable v6.18.37 · arch/arm64/include/asm/tlbflush.h
해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고
