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

ARMv9 가상화·플랫폼·성능 관측

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

CPU 명령 집합만으로 보조 CPU를 켤 수 있는 것은 아닙니다. Linux는 펌웨어가 제공하는 전원 인터페이스와 플랫폼 정보를 사용합니다. 아래에서는 v6.18.37의 PSCI CPU_ON 호출 함수를 읽어 Linux CPU 번호, 하드웨어 식별자, 시작 물리 주소가 만나는 지점을 설명합니다.

읽을 범위: v6.18.37 · arch/arm64/kernel/psci.c · cpu_psci_cpu_boot 39–47행입니다. 아래에 이 범위의 원문과 각 줄의 설명을 실었습니다. 추가 그림은 별도 고정 소스인 arch/arm64/kvm/arm.c의 vCPU 실행·trace 지점을 비교합니다. 그 밖의 경로는 기존 분석에서 함께 읽으실 수 있습니다.

먼저 알아둘 개념

PSCI

CPU 전원과 기동 등에 사용하는 펌웨어 인터페이스입니다. GIC나 SMMU의 레지스터 동작을 모두 대신하는 API는 아닙니다.

논리 CPU 번호

Linux 내부의 CPU 인덱스입니다. cpu_logical_map으로 하드웨어가 알아들을 식별자에 연결합니다.

시작 주소

아직 커널의 정상 가상 주소 실행 환경이 없는 CPU가 진입할 수 있도록 물리 주소를 전달합니다.

처음 읽을 때

기동 요청 CPU와 새로 켜지는 CPU를 분리해 어느 쪽이 어떤 함수를 실행하는지 설명하십시오.

더 깊이 살펴볼 때

CPU_ON 요청 성공과 Linux online 완료를 구분하고 entry 어셈블리의 스택·MMU 준비로 연결하십시오.

그림으로 보는 변화

물리 CPU 기동과 가상 CPU 실행을 나누어 읽기

PSCI CPU_ON / KVM vCPU 실행 / KVM의 관측 지점

두 줄은 하나의 직선 호출 경로가 아닙니다. 왼쪽은 호스트의 물리 CPU 기동 요청, 오른쪽은 KVM의 게스트 가상 CPU 실행입니다.

플랫폼 · PSCI 물리 CPU

  1. cpu_psci_cpu_boot(cpu)가 Linux 논리 CPU 번호를 받습니다.
  2. secondary_entry의 물리 주소와 cpu_logical_map(cpu)의 대상 ID로 psci_ops.cpu_on을 요청합니다.
  3. 오류를 조건부로 기록하고 결과 err를 반환합니다. 이 함수가 Linux online 완료를 측정하지는 않습니다.

가상화 · KVM 게스트 vCPU

  1. kvm_arch_vcpu_ioctl_run()은 사용자 공간의 vCPU 실행 요청에 연결된 함수입니다.
  2. 루프에서 kvm_arm_vcpu_enter_exit()을 호출하고, 그 helper는 kvm_call_hyp_ret(__kvm_vcpu_run, vcpu)로 게스트 실행을 넘깁니다.
  3. 호출 뒤 vcpu->stat.exits++로 exit 횟수를 올립니다. 이것은 물리 CPU 기동 요청의 완료 신호가 아닙니다.

관측 지점 · trace_kvm_entry()와 trace_kvm_exit()이 게스트 진입·이탈 지점에 있습니다. 이 코드만으로 실제 trace 수집 여부나 애플리케이션 성능을 결론 내리지는 않습니다.

PSCI의 CPU_ON 반환과 KVM의 vCPU exit 횟수는 서로 다른 대상을 나타냅니다. 이 보조 그림은 물리 CPU online 완료, 모든 KVM exit 원인, PMU 계수값, 종단 간 처리량·지연시간을 검증하지 않습니다.

v6.18.37 코드에서 확인한 대상·반환·관측
경로코드가 다루는 대상읽을 때 구분할 점
psci.c CPU_ON논리 CPU 번호 → 하드웨어 대상 ID와 물리 시작 주소 → 펌웨어 요청err는 요청 결과이며 게스트 vCPU 실행·Linux online 완료의 증거가 아닙니다.
kvm/arm.c vCPU run사용자 공간 vCPU 실행 요청에서 게스트 실행 helper 호출물리 보조 CPU를 켜는 PSCI host 경로와 별개입니다.
kvm/arm.c trace·exit게스트 entry/exit trace 지점과 vcpu->stat.exits 갱신관측 가능한 코드 지점·횟수이며 성능 수치나 trace 활성화의 증명은 아닙니다.
ARMv9 가상화·플랫폼·성능 관측의 단계별 개념 그림
기존 그림은 psci.c의 호스트 물리 CPU 기동 요청만 단순화합니다. 위 도식·표는 별도 KVM vCPU 실행 및 관측 지점을 구분해 보입니다.
1단계 설명

1단계 고정

GIF 원본 열기

1. 대상과 시작점 결정

논리 CPU를 하드웨어 ID로 바꾸고 secondary_entry 물리 주소를 준비합니다.

화살표는 제어 요청에 넣을 값의 변환입니다.

2. 펌웨어 호출

PSCI cpu_on이 대상 CPU 기동을 요청합니다.

다른 CPU에서 바로 일반 C 함수를 호출한다는 뜻이 아닙니다.

3. 요청 결과 반환

이 함수는 err를 돌려줍니다. 여기서 보조 CPU의 Linux online 완료를 확인하지는 않습니다.

PSCI 요청 결과와 보조 CPU 준비 완료는 서로 다른 상태입니다.

cpu_psci_cpu_boot를 한 줄씩 읽기

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

static int cpu_psci_cpu_boot(unsigned int cpu)
{
	phys_addr_t pa_secondary_entry = __pa_symbol(secondary_entry);
	int err = psci_ops.cpu_on(cpu_logical_map(cpu), pa_secondary_entry);
	if (err && err != -EPERM)
		pr_err("failed to boot CPU%d (%d)\n", cpu, err);

	return err;
}
static int cpu_psci_cpu_boot(unsigned int cpu)

논리 CPU 번호를 받아 PSCI를 통한 보조 CPU 기동을 요청하는 함수입니다.

	phys_addr_t pa_secondary_entry = __pa_symbol(secondary_entry);

secondary_entry 커널 기호를 펌웨어에 전달할 물리 주소로 변환합니다. 새 CPU가 아직 정상 커널 VA 환경을 갖췄다고 가정하지 않습니다.

	int err = psci_ops.cpu_on(cpu_logical_map(cpu), pa_secondary_entry);

논리 CPU 번호를 하드웨어 식별자로 변환하고 PSCI CPU_ON을 호출합니다. 실제 SMCCC 통로 선택과 펌웨어 처리는 PSCI 구현에 위임합니다.

	if (err && err != -EPERM)

오류가 있으며 그 값이 EPERM이 아닌지 검사합니다. 모든 실패를 똑같이 로그로 반복하지 않도록 구분합니다.

		pr_err("failed to boot CPU%d (%d)\n", cpu, err);

일반적인 기동 실패이면 CPU 번호와 오류를 기록합니다.

	return err;

펌웨어 요청 결과를 호출자에게 반환합니다. 성공값은 보조 CPU의 모든 Linux 초기화가 끝났다는 보장이 아닙니다.

함께 생각해 볼 질문

CPU_ON 반환 0이면 이미 스케줄링 중입니까?

기동 요청 성공과 보조 CPU의 Linux 초기화 완료는 구분해야 합니다.

Linux CPU 번호가 MPIDR 값입니까?

아닙니다. cpu_logical_map으로 연결하는 별도 값입니다.

GIC와 SMMU는 PSCI 호출에 포함됩니까?

각 기능의 초기화와 상태 관리는 별도의 드라이버 및 플랫폼 경로로 이루어집니다.

출처와 읽은 범위

비교 그림의 추가 근거: v6.18.37 arch/arm64/kvm/arm.c vCPU 진입 helper 1138–1153행, vCPU 실행 함수 1155–1165행, 게스트 진입·exit 횟수 1240–1249행, exit trace 1302행 (stable 원문). 본문 줄별 분석의 PSCI 범위와 다른 코드입니다.

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

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

맨 위로 ↑