# ARM SMMUv3·IOMMU·DMA 소스 분석

v6.18.37 / drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c

장치용 페이지 표를 고친 뒤에도 SMMU가 옛 번역을 기억할 수 있습니다. CPU TLB를 지웠다는 사실만으로 장치의 IOTLB가 갱신되는 것은 아닙니다. v6.18.37의 arm_smmu_iotlb_sync를 읽어 모아 둔 무효화 범위를 SMMU 경로에 전달하는 과정을 설명합니다.

## arm_smmu_iotlb_sync

```c

static void arm_smmu_iotlb_sync(struct iommu_domain *domain,
				struct iommu_iotlb_gather *gather)
{
	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);

	if (!gather->pgsize)
		return;

	arm_smmu_tlb_inv_range_domain(gather->start,
				      gather->end - gather->start + 1,
				      gather->pgsize, true, smmu_domain);
}

```

### 3458행

```c

static void arm_smmu_iotlb_sync(struct iommu_domain *domain,

```

IOMMU domain에 모아 둔 무효화 작업을 반영하는 드라이버 콜백입니다.

### 3459행

```c

				struct iommu_iotlb_gather *gather)

```

gather에는 여러 변경에서 수집한 시작·끝 주소와 page size가 들어 있습니다.

### 3461행

```c

	struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);

```

일반 iommu_domain을 SMMU 드라이버의 확장 자료구조로 바꿔 하드웨어별 정보를 얻습니다.

### 3463행

```c

	if (!gather->pgsize)

```

수집된 페이지 크기가 없으면 유효한 무효화 범위가 없는 경우로 처리합니다.

### 3464행

```c

		return;

```

빈 요청은 추가 SMMU 명령 없이 종료합니다.

### 3466행

```c

	arm_smmu_tlb_inv_range_domain(gather->start,

```

수집한 시작 주소부터 domain의 TLB 범위를 무효화하는 하위 경로에 넘깁니다.

### 3467행

```c

				      gather->end - gather->start + 1,

```

end가 포함형 끝 주소이므로 길이는 end-start+1입니다. 예를 들어 0x1000~0x1fff는 설명용으로 0x1000바이트 범위입니다.

### 3468행

```c

				      gather->pgsize, true, smmu_domain);

```

페이지 크기와 leaf 무효화 조건, 해당 SMMU domain을 전달합니다. 실제 CMDQ 명령 구성·완료는 호출된 함수 아래에서 진행합니다.

