Linux v6.18.37 · 개념과 코드 읽기

ARM Realm·CCA와 Linux RSI 소스 분석

이 코드는 어떤 문제를 푸나요?

Linux가 Realm 안에서 실행되는지는 CPU 제품명만 보고 정하지 않습니다. 호출 통로와 RSI ABI를 확인하고 보호·공유 메모리 처리를 설치한 뒤 활성화합니다. v6.18.37의 arm64_rsi_init 전체를 한 줄씩 읽으며 게스트 지원의 실제 초기화 조건을 확인합니다.

읽을 범위: v6.18.37 · arch/arm64/kernel/rsi.c · arm64_rsi_init 142–161행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 주제 전체의 흐름과 다른 경로는 기존 분석에서 함께 읽으실 수 있습니다.

먼저 알아둘 개념

SMC 통로

이 경로는 SMCCC 통로가 SMC인 경우에만 RSI 초기화를 계속합니다.

ABI 버전 협상

인터페이스가 있다고 해도 요청한 버전의 규칙을 함께 이해하는지 확인해야 합니다.

static key

초기화 후 자주 검사하는 기능 여부를 효율적으로 분기하기 위한 커널 기법입니다. 마지막에 켜기 전까지 초기화 완료로 취급하지 않습니다.

처음 읽을 때

각 실패 조건에서 바로 돌아가는 흐름과 마지막 활성화 순서를 따라가십시오.

더 깊이 살펴볼 때

IPA 상위 비트의 공유 표현, ioremap hook과 메모리 전환 연산 등록이 왜 먼저 필요한지 검토하십시오.

그림으로 보는 변화

ARM Realm·CCA와 Linux RSI 소스 분석의 단계별 개념 그림
각 단계에 화살표 의미와 생략 범위를 표시했습니다. 주소·숫자 예제는 실제 장치 값을 뜻하지 않습니다.
1단계 설명

1단계 고정

GIF 원본 열기

1. 인터페이스 확인

SMC 통로와 RSI 버전·Realm 설정을 확인합니다.

조건을 만족하지 않으면 다음 단계로 가지 않습니다.

2. 메모리 동작 설치

공유 속성 비트와 매핑·전환 연산을 준비합니다.

이 화살표는 게스트 메모리 접근 규칙의 설치입니다.

3. 보호 메모리와 활성화

RAM 상태를 준비한 뒤 rsi_present를 켭니다.

최종 표시는 앞 단계 완료 후 게시됩니다.

arm64_rsi_init를 한 줄씩 읽기

줄 번호는 v6.18.37 원문 기준입니다. 주석·빈 줄을 포함한 함수 전체를 먼저 보고, 그 아래에서 각 줄을 설명합니다.

void __init arm64_rsi_init(void)
{
	if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)
		return;
	if (!rsi_version_matches())
		return;
	if (WARN_ON(rsi_get_realm_config(&config)))
		return;
	prot_ns_shared = __phys_to_pte_val(BIT(config.ipa_bits - 1));

	if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))
		return;

	if (realm_register_memory_enc_ops())
		return;

	arm64_rsi_setup_memory();

	static_branch_enable(&rsi_present);
}
void __init arm64_rsi_init(void)

Realm 게스트의 RSI 초기화 함수이며 부팅 후 회수 가능한 __init 코드입니다.

	if (arm_smccc_1_1_get_conduit() != SMCCC_CONDUIT_SMC)

SMCCC 호출 통로가 SMC인지 확인합니다. 이 구현이 요구하는 통로가 아니면 RSI 초기화를 진행하지 않습니다.

		return;

조건이 맞지 않으면 일반 실행 환경을 유지하며 반환합니다.

	if (!rsi_version_matches())

RSI 존재 및 ABI 버전이 이 커널과 맞는지 확인합니다.

		return;

사용 가능한 버전을 협상하지 못하면 이 기능을 활성화하지 않습니다.

	if (WARN_ON(rsi_get_realm_config(&config)))

Realm 설정을 가져오며 실패하면 경고를 남깁니다. 아래에서는 그 설정의 IPA 폭을 사용합니다.

		return;

설정을 얻지 못했으면 미초기화 값을 쓰지 않고 끝냅니다.

	prot_ns_shared = __phys_to_pte_val(BIT(config.ipa_bits - 1));

IPA 폭의 최상위 비트를 공유 표현에 사용할 PTE 형식으로 변환해 보관합니다. 특정 고정 비트 번호를 모든 플랫폼에 가정하지 않습니다.

	if (arm64_ioremap_prot_hook_register(realm_ioremap_hook))

ioremap이 보호·공유 범위에 맞는 속성을 선택하도록 hook을 등록합니다.

		return;

hook 등록이 실패하면 준비가 끝난 것으로 취급하지 않고 반환합니다.

	if (realm_register_memory_enc_ops())

Realm 메모리 보호·공유 전환에 사용할 연산을 등록합니다.

		return;

연산 등록 실패 시 활성화 표시까지 진행하지 않습니다.

	arm64_rsi_setup_memory();

사용 가능한 메모리 범위를 보호 상태로 준비합니다. 이 helper의 실패 정책은 원문에서 panic으로 이어질 수 있습니다.

	static_branch_enable(&rsi_present);

앞선 초기화가 완료된 뒤 RSI 존재 static key를 켭니다. 이후 코드가 기능 사용 가능을 판단하는 표식입니다.

함께 생각해 볼 질문

CONFIG만 켜면 언제나 Realm입니까?

아닙니다. 런타임 인터페이스와 ABI 확인을 통과해야 합니다.

rsi_present를 맨 앞에서 켜도 됩니까?

후속 코드가 초기화되지 않은 메모리 동작을 사용할 수 있어 순서를 지켜야 합니다.

이 단원의 범위는 호스트입니까, 게스트입니까?

실제 읽는 arm64_rsi_init은 Realm 게스트 측 초기화입니다.

출처와 읽은 범위

Linux stable v6.18.37 · arch/arm64/kernel/rsi.c

해당 버전 원본 파일 · 기존 코드 분석 · 설명 원고

맨 위로 ↑