https://lore.kernel.org/patchwork/patch/852156/
리눅스에 반영된 cpu_do_switch_mm 시에 위 패치에 대해서 궁금한게 있는데요..
패치 내용중 일부는 아래와 같습니다
여기서 패치전 코드는 TTBR0에 해당 user task의 pgd + asid를 넣어주고 있었는데
패치 후에는 TTBR1에만 asid를 넣어주고 있는것을 확인했습니다.
제가 생각하기에 TTBR0 과 TTBR1 레지스터 모두에 asid 를 넣어주어야 하지 않을까 싶은데요..
왜 asid 를 커널에만 사용하는건지... 아니면 제가 잘못 이해하고 있는건지 궁금합니다.
diff --git a/arch/arm64/mm/proc.S b/arch/arm64/mm/proc.S index 877d42fb0df6..0bd7550b7230 100644 --- a/arch/arm64/mm/proc.S +++ b/arch/arm64/mm/proc.S @@ -139,9 +139,12 @@ ENDPROC(cpu_do_resume) */ ENTRY(cpu_do_switch_mm) pre_ttbr0_update_workaround x0, x2, x3 + mrs x2, ttbr1_el1 mmid x1, x1 // get mm->context.id - bfi x0, x1, #48, #16 // set the ASID - msr ttbr0_el1, x0 // set TTBR0 + bfi x2, x1, #48, #16 // set the ASID + msr ttbr1_el1, x2 // in TTBR1 (since TCR.A1 is set) + isb + msr ttbr0_el1, x0 // now update TTBR0 isb post_ttbr0_update_workaround ret @@ -225,7 +228,7 @@ ENTRY(__cpu_setup) * both user and kernel. */ ldr x10, =TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ - TCR_TG_FLAGS | TCR_ASID16 | TCR_TBI0 + TCR_TG_FLAGS | TCR_ASID16 | TCR_TBI0 | TCR_A1 tcr_set_idmap_t0sz x10, x9 /*
댓글 3
-
문c(문영일)
2019.10.22 10:06
-
suesueng
2019.10.23 18:51
답변 정말 감사합니다. 전달해주신 참고 링크에 commit 정보를 좀 찾아보았는데
아래 링크에 이 패치와 연관된 패치들이 정리되어 있어 확인해보았습니다.
https://lore.kernel.org/patchwork/cover/852139
정확히 이해는 안되지만 ㅠ user 와 kernel page 영역 변환에 관련해서 ttbr1 로 옮기는것이 더 빠르다는것 같습니다..감사합니다~
-
문c(문영일)
2019.10.23 22:27
좋은 링크를 찾으셨네요. 예전에 읽었었는데 오늘 다시 보니 새롭습니다. ^^
최근 몇 년 동안 side channel attack을 이슈로 컴퓨터 세상이 떠들썩했었습니다.
기존 커널에서 원칙적으로 유저가 커널 영역에 접근 못 하던 것을 위의 공격으로 뚫리는 일이 발생하였었죠.
이때부터 리눅스 커널도 동일한 문제로 보안을 향상하려고 유저가 커널 영역에 접근하지 못하게 여러 패치가 적용되었고, 그 반대로 커널에서조차 일반적인 방법으로 유저 영역의 접근을 불가능하게 만드는 패치들이 적용되었습니다.
그러면서 보안을 올린 반대급부로 HW가 지원하지 않아 일시적으로 cost가 높은 TLB flush를 더 많이 사용하게 되어 큰 성능 저하가 발생하였습니다.
이에 대해 조금이라도 성능을 끌어 올리려고 노력하는 여러 결과 중 하나가 위의 질문하신 TTBR1에 asid를 사용하는 방법 또한 포함되는 것으로 보입니다.
최근에 보안 문제로 시도되는 패치와 솔루션이 너무 많아 보안 레벨로 변경되는 패치 분석이 점점 어려워지고 있습니다.
추후에 다시 한번 유저 영역과 커널 영역에 대한 보안 패치들의 코드를 모두 확인해야 할 것 같습니다.
감사합니다.
.
안녕하세요? 문c블로그(http://jake.dothome.co.kr)의 문영일입니다.
ARM64 아키텍처에서는 ASID 값을 TTBR0 또는 TTBR1 둘 중 하나에서 유지 관리하도록
설정할 수 있습니다. TCR.A1 플래그를 1로 설정하면 TTBR1을 선택하게 할 수 있습니다.
이런 기능을 사용하여 이 번 패치에서는 TTBR1을 사용하여 ASID 값을 지정하도록
패치하였습니다.
참고: https://github.com/torvalds/linux/commit/7655abb953860485940d4de74fb45a8192149bb6
참고로 보안을 이유로 몇 개의 API(copy_from_user, copy_to_user, ...)를 제외하고는 커널도
유저 공간에 직접 접근을 하지 못하게 하였습니다.
(예: ARMv8.1의 PAN 기능 또는 TTBR0를 zero 페이지에 매핑하는 sw 에뮬레이션을 사용합니다.)
참고: http://jake.dothome.co.kr/copy_from_user
결론:
TTBR0를 zero 페이지에 매핑하는 방법을 사용하느라 ASID를 TTBR1으로 옮겼다고 생각이
드는데, 확실한지는 모르겠습니다.
감사합니다.