현재 Xilinx Zynq Ultrascale+ 보드의 Linux arm64에서 공유 가상 주소 공간을 생성 중입니다. 앞으로는 내장된 ARM SMMU 500(IOMMU) 및 캐시 일관성 인터페이스(CCI)를 활용하여 사용자 작업 없이 Cortex A53과 FPGA 간에 포인터/주소를 공유할 수 있어야 합니다.
이를 위해 Linux 커널 v4.14.0의 드라이버/iommu/arm-smmu.c iommu 드라이버를 사용하고 이를 수정하여 대부분의 가상화 추상화와 별도의 사용자 정의 커널 모듈 및 ioctl을 제거했습니다. 따라서 각 프로세스에는 자체 aarch64 페이지 테이블을 포함하는 자체 SMMU 컨텍스트 라이브러리가 있습니다. 이제 할당된 페이지를 동일한 가상 주소에 다시 수동으로 매핑함으로써 별도의 페이지 테이블을 사용하여 가상 주소가 있는 FPGA에서 데이터를 성공적으로 읽고 쓸 수 있습니다.
MMU와 SMMU가 동일한 페이지 테이블을 공유할 수 있다면 더 편리할 것입니다. 따라서 두 번째 중복 페이지 테이블을 불필요하게 설정하는 것을 피할 수 있습니다. 이를 위해 다음과 같이 변경했습니다.
39비트 VA 크기 및 40비트 PA 크기(4KB 페이지 크기)를 사용하도록 SMMU 구성
현재 task_struct에서 PGD 포인터를 가져와 올바른 SMMU 컨텍스트 라이브러리 PGD(TTBR) 항목에 전달합니다.
다른 모든 SMMU 하드웨어 구성은 arm-smmu.c와 동일합니다.
그러나 이로 인해 비결정적 동작이 발생합니다. FPGA가 여러 값을 읽고 공유 가상 주소를 사용하여 이를 다른 위치에 다시 쓰는 테스트 사례는 가끔 작동합니다. 필요한 모든 데이터 구조를 설정하고 초기화한 후 FPGA에 값 전송을 지시하기 전에 의도적으로 일시 중지하도록 테스트 프로그램을 구현했습니다. 일시 중지 시간이 길수록 더 많은 값이 올바르게 전송됩니다. 약 10초 동안 일시 중지한 후 테스트는 항상 성공적으로 종료됩니다. 나에게 이것은 Linux에서 생성된 업데이트된 페이지 테이블 항목(PTE)이 여전히 CPU 캐시에 있고 SMMU가 잘못된 페이지 테이블 항목에 액세스하여 전송이 실패하는 캐시 문제처럼 들립니다. SMMU) 변환 오류/오작동). 따라서 Linux 소스 코드의 올바른 위치에서 캐시를 플러시/정리하거나 일부 SMMU 플래그(컨텍스트 라이브러리, 스트림 2 컨텍스트 레지스터...), MMU 플래그 또는 PTE의 메모리/공유 가능성 플래그를 변경해야 합니다.
SMMU의 MAIR 설정이 다르다는 것을 발견했습니다. MMU의 MAIR와 일치하도록 SMMU 코드를 변경하고 필요할 때 올바른 메모리 속성 인덱스를 사용했습니다. 그러나 그것은 작동하지 않았습니다. 또한 ARM SMMU v2 아키텍처 사양의 1.5.2장 "ARM 아키텍처와 SMMU 변환 방식의 차이점"을 확인했습니다.
가장 혼란스러운 점은 수동으로 구축한 페이지 테이블은 제대로 작동하지만 Linux에서 생성된 페이지 테이블이 설명된 비결정적 동작을 유발한다는 것입니다.
Linux에서 생성된 페이지 테이블을 사용/공유하기 위해 SMMU를 올바르게 설정하는 방법이나 Linux가 SMMU와 제대로 작동하도록 페이지 테이블을 구성하는 방식을 변경하는 방법에 대한 정보나 팁이 있습니까?