설계 규칙과 실제 제품은 다르다
ARMv9는 CPU 한 종류의 이름이 아니라 여러 CPU가 지켜야 할 architecture 규칙이다. Cortex-A725와 Neoverse V3는 모두 ARMv9 계열일 수 있지만 cache 크기, pipeline, vector 구현과 전력 목표는 다르다.
“이 명령을 실행하면 어떤 결과가 나와야 하는가”라는 공통 언어다. 건물로 치면 안전법규와 도면 표기 규칙에 가깝다.
그 규칙을 얼마나 넓은 pipeline, 어떤 cache와 predictor로 구현했는가다. 결과는 같아도 속도와 전력은 다를 수 있다.
CPU 주변에 memory controller, GIC, SMMU, GPU와 장치를 어떻게 연결했는가다. 실제 주소와 interrupt 번호는 여기서 정해진다.
compiler가 어떤 명령을 만들고 firmware·Linux가 무엇을 켜며 application에 어떤 ABI로 공개하는가다.
따라서 “이 CPU가 ARMv9니까 SME를 쓸 수 있나?”라는 질문은 architecture 이름만으로 답할 수 없다. 제품 TRM의 구현 feature, Linux HWCAP, compiler target을 차례로 확인해야 한다.
문서마다 답하는 질문이 다르다
| 문서 | 답하는 질문 | 답하지 않는 질문 |
|---|---|---|
| Architecture manual | 명령, register, 예외, ordering과 feature의 공통 계약 | 특정 core의 cache 크기·latency·raw PMU event |
| Core TRM | 특정 Cortex·Neoverse 구현의 cache·PMU·power·debug와 구현 정의 동작 | SoC MMIO 주소와 board wiring |
| Component TRM | DSU·CMN·GIC·SMMU·CoreSight block의 register와 integration | 완성 SoC에서의 instance 주소·interrupt 연결 |
| SoC manual | 주소 map, clock·reset, interrupt·IOMMU 연결과 boot strap | architecture 명령의 일반 semantics |
| Software Optimization Guide | pipeline·cache 특성에 맞는 code generation과 scheduling 권고 | 정확성을 정의하는 normative architecture 계약 |
| Errata notice | core revision별 결함, 영향 조건과 workaround | 다른 revision에 자동 적용되는 일반 규칙 |
문제에 따라 첫 문서가 달라진다
| 궁금한 문제 | 첫 문서 | 다음 문서와 이유 |
|---|---|---|
LDAR가 무엇을 보장하나 | DDI 0602 instruction pseudocode | DDI 0487 memory model에서 acquire ordering의 전체 계약 확인. |
| L2 cache가 몇 MB인가 | 해당 Cortex·Neoverse TRM | DSU/CMN 문서에서 shared cache와 cluster·mesh 연결 확인. |
| GIC Distributor 주소가 어디인가 | SoC manual 또는 ACPI/Device Tree | GIC architecture/TRM은 register 의미를, SoC 문서는 실제 instance 주소를 제공. |
| raw PMU event의 의미 | 정확한 core revision TRM | errata에서 오계수 조건, Linux perf driver에서 공개 이름 확인. |
| SVE signal frame가 깨진다 | Linux arm64 SVE ABI 문서 | AAPCS64와 kernel UAPI header에서 VL별 record layout 확인. |
| 특정 VM에서만 DMA fault | SMMUv3 event record와 SoC wiring | Linux IOMMU log, StreamID/PASID, guest Stage 2 mapping을 함께 추적. |
실무 습관: 문서 제목뿐 아니라 issue/revision과 확인 날짜를 기록한다. /latest/ URL은 나중에 다른 issue를 가리킬 수 있고, erratum은 특정 rNpM revision에만 적용될 수 있다.
Cortex와 Neoverse 문서군
제품 이름만으로 architecture revision을 단정하지 않는다. 같은 ARMv9 세대에서도 mobile Cortex와 infrastructure Neoverse는 vector·cache·RAS·PMU·power 목표가 다르고, optional feature 구성도 다르다.
| 계열 | 살펴볼 제품 | TRM에서 우선 볼 장 |
|---|---|---|
| 초기 ARMv9 mobile | Cortex-A510, Cortex-A710, Cortex-X2 | implemented features, cache·TLB, PMU event, reset·power와 errata |
| 후속 mobile | Cortex-A715, Cortex-A520, Cortex-X3, Cortex-X4 | 세대별 branch·memory system 변화와 DSU 조합 |
| 최신 client | Cortex-A725, Cortex-X925, Cortex-A320 | 제품 공개 feature와 공개된 TRM·optimization guide의 범위를 구분 |
| Infrastructure | Neoverse N2, Neoverse V2, Neoverse N3, Neoverse V3 | RAS, MPAM, cache·mesh, PMU·SPE와 server platform 요구 |
문서 공개 범위: 모든 제품이 같은 형태의 공개 TRM을 제공하지는 않는다. 제품 페이지의 Technical Documentation에서 최신 공개 문서를 확인하고, 접근 제한 문서를 공개 문서처럼 링크하지 않는다.
Core 바깥의 system component 문서
cluster 내 core 연결, shared L3, snoop·power domain과 PMU를 정의한다. core TRM의 private cache만 보고 system cache를 추정하지 않는다.
home node, request node, system cache, memory controller와 coherent I/O의 routing·performance·RAS 경계를 설명한다.
Distributor·Redistributor·ITS·virtual interface와 interrupt routing을 담당한다. CPU interface와 SoC interrupt map을 함께 본다.
device stream, translation table, command/event queue, fault와 ATS/PRI integration을 정의한다.
ETE·ETM source, funnel·replicator link, ETF·ETR sink와 debug authentication을 연결한다.
component TRM의 register offset은 block 내부 상대 주소다. 완성 SoC에서 실제 base address, clock, reset과 interrupt는 SoC manual·ACPI·Device Tree에서 찾아야 한다.
Software Optimization Guide를 architecture manual처럼 읽지 않는다
Optimization guide는 pipeline width, execution resource, branch와 cache 특성에 맞춘 권고를 제공한다. “정확히 이렇게 동작해야 한다”는 normative 계약이 아니라 특정 microarchitecture에서 성능을 얻기 위한 지침이다.
- 먼저 정확성을 architecture와 ABI 문서로 확정한다.
- target core의 optimization guide에서 instruction scheduling, alignment와 prefetch 권고를 찾는다.
- compiler가 실제 생성한 assembly를 확인하고
perf stat·SPE로 병목을 측정한다. - big.LITTLE에서는 한 core 최적화가 다른 core에서 손해가 되지 않는지 별도로 측정한다.
CPU revision과 errata는 기능표 뒤에 붙는 부록이 아니다
같은 product name이라도 r0p0, r1p0처럼 revision이 다르면 erratum 적용 여부와 workaround 비용이 달라진다. Linux는 MIDR 범위와 firmware 정보를 보고 일부 기능을 비활성화하거나 alternative instruction을 적용한다.
MIDR_EL1의 implementer, part number, variant, revision과 SoC revision을 기록한다.
특정 sequence, cache state, power transition 또는 virtualization 조건인지 errata notice에서 확인한다.
CPU microcode 성격의 firmware, EL3, kernel, hypervisor 또는 compiler 중 어느 층이 책임지는지 구분한다.
dmesg의 detected CPU features와 erratum workaround 적용 메시지를 제품 문서와 대조한다.
-march, -mcpu, -mtune
| 옵션 | 바꾸는 것 | 사용 기준 |
|---|---|---|
| -march=armv9-a … armv9.7-a | 사용할 수 있는 architecture instruction과 feature 기준선 | 배포 대상 모두가 해당 ISA를 지원하거나 runtime dispatch가 있을 때. |
| -mcpu=<core> | 대개 ISA feature 선택과 해당 core용 scheduling·cost model | 실행 CPU를 특정할 수 있는 firmware·kernel·appliance build. |
| -mtune=<core> | instruction 선택의 architecture 허용 범위는 유지하면서 scheduling·cost 조정 | 호환 ISA 기준선을 유지하고 특정 core 성능을 우선할 때. |
| +feature / +nofeature | SVE2·SME·MTE 등 세부 extension 조정 | compiler가 인식하는 feature 이름과 target CPU 보장을 모두 확인. |
세 가지 build 의도
# 넓은 ARMv9 기준선
cc -O2 -march=armv9-a app.c
# 특정 core에서만 실행할 image
cc -O2 -mcpu=cortex-a720 app.c
# ISA 호환 범위는 유지하고 scheduling만 조정
cc -O2 -march=armv9-a -mtune=neoverse-n2 app.c지원되는 armv9.x-a 값과 feature modifier는 compiler version마다 다르다. GCC·Clang의 해당 release manual에서 확인하고, 빌드 로그에 compiler version을 남긴다.
같은 C 코드가 target에 따라 달라지는 예
배열 합계를 작성했다고 하자. compiler는 target이 명확하지 않으면 넓은 CPU에서 실행되도록 보수적인 명령을 고른다. 높은 -march 기준선을 주면 SVE2 같은 명령을 사용할 수 있고, -mcpu는 그 core의 pipeline에 맞춰 instruction 순서와 unroll 비용까지 조정한다.
입력 source
int sum(const int *p, size_t n) {
int total = 0;
for (size_t i = 0; i < n; ++i)
total += p[i];
return total;
}정확한 생성 결과는 compiler version, optimization option과 signed overflow 판단에 따라 달라지므로 assembly를 직접 확인해야 한다.
세 build와 확인 명령
cc -O3 -march=armv8-a -S sum.c -o sum-v8.s
cc -O3 -march=armv9-a -S sum.c -o sum-v9.s
cc -O3 -mcpu=neoverse-n2 -S sum.c -o sum-n2.s
cc --version
grep -E "while|ld1|addv|ldr|add" sum-*.s-march는 사용할 ISA의 하한을, -mcpu는 ISA와 tuning을 함께, -mtune은 호환 ISA를 유지하면서 scheduling과 cost model을 주로 바꾼다.
배포 binary 전체를 높은 -march로 빌드하면 낮은 CPU에서 program 시작 전에 illegal instruction이 날 수 있다. 공통 baseline 본체와 SVE2·SME 최적화 함수를 별도 object로 만들고 runtime dispatch하는 방식이 안전하다.
ACLE, AAPCS64와 AAELF64
Language extensions
intrinsic, predefined macro, system register 접근과 feature 사용을 C/C++에 노출한다.
Procedure call standard
argument·return register, stack alignment, callee-saved state와 SVE·SME 함수 계약을 정의한다.
ELF object format
relocation, symbol, note와 architecture property가 object·executable에서 표현되는 방식을 정의한다.
명령이 존재해도 ABI가 없으면 library와 debugger가 상태를 교환할 수 없다. 특히 SVE·SME, PAC·BTI·GCS는 compiler attribute, ELF property, loader와 kernel ABI를 함께 확인한다.
HWCAP/HWCAP2와 process ABI
Linux arm64는 userspace가 안전하게 사용할 수 있는 feature를 auxiliary vector의 HWCAP bit로 공개한다. raw ID register를 직접 읽어 architecture feature를 추측하는 대신 kernel이 정규화한 ABI를 우선한다.
| Interface | 확인하는 것 | 대표 ARMv9 연관 기능 |
|---|---|---|
| AT_HWCAP / AT_HWCAP2 | 현재 process가 사용할 수 있는 instruction·ABI feature | SVE, SVE2, SME, MTE, PAC, BTI, GCS, MOPS |
| prctl() | process별 opt-in, vector length와 fault policy | SVE/SME VL, tagged address·MTE, GCS |
| signal frame | 비동기 경계에서 확장 register state 저장 | FPSIMD, SVE, ZA, ZT와 future context record |
| ptrace regset | debugger가 읽고 쓰는 가변 크기 state | SVE/SME, PAC mask·key policy, TLS와 system state |
| KVM ABI | guest에 노출하는 ID register, vCPU feature와 device state | SVE/SME VL, PMU, timer, GIC, protected VM·Realm |
전체 대응표: Linux v6.18.37 원문 순서를 보존한 ELF HWCAP 전문 번역에 AT_HWCAP과 AT_HWCAP2의 모든 항목, 대응 ID register 조건이 표로 정리돼 있다. 이 페이지에서는 ARMv9 실전 흐름만 요약하고 전체 표를 중복 복제하지 않는다.
CPU feature registers와 SVE·SME·MTE·GCS 등 각 feature 문서를 함께 읽는다.
HWCAP으로 안전하게 최적화 함수를 고른다
/proc/cpuinfo 문자열을 직접 해석하기보다 kernel이 현재 process에 보장한 auxiliary vector를 사용한다. 아래 구조는 baseline 함수가 항상 존재하고, SVE2가 있을 때만 최적화 함수를 선택한다.
간단한 runtime dispatch 골격
#include <sys/auxv.h>
#include <asm/hwcap.h>
static int sum_scalar(const int *p, size_t n);
static int sum_sve2(const int *p, size_t n);
int sum_auto(const int *p, size_t n) {
unsigned long hwcap2 = getauxval(AT_HWCAP2);
if (hwcap2 & HWCAP2_SVE2)
return sum_sve2(p, n);
return sum_scalar(p, n);
}sum_sve2()만 SVE2 target으로 compile하고 baseline translation unit에는 SVE2 명령이 섞이지 않게 한다. library에서는 IFUNC, function multiversioning 또는 자체 초기화 table을 사용할 수 있다.
SME는 HWCAP만 확인하고 끝나지 않는다. process별 streaming vector length를 prctl(PR_SME_GET_VL)로 읽고, 함수 ABI가 streaming/ZA state를 올바르게 선언했는지도 확인해야 한다. MTE·GCS 역시 hardware bit에 더해 process opt-in과 loader policy가 필요하다.
Linux source 연결 지도
| 관심사 | 대표 source 위치 | 읽을 질문 |
|---|---|---|
| CPU feature | arch/arm64/kernel/cpufeature.c, arch/arm64/include/asm/cpufeature.h | ID field를 어떻게 sanitize하고 system capability로 만드는가. |
| FPSIMD/SVE/SME | arch/arm64/kernel/fpsimd.c, signal·ptrace 관련 파일 | state ownership, save/restore, VL과 ABI size를 어떻게 관리하는가. |
| MTE | arch/arm64/kernel/mte.c, memory-management 경로 | tag fault mode, page flag와 user ABI를 어떻게 연결하는가. |
| GCS | arch/arm64/kernel/gcs.c와 signal·ELF 경로 | process enable, protected stack mapping과 signal token을 어떻게 검증하는가. |
| KVM | arch/arm64/kvm/ | VHE/nVHE entry, Stage 2, ID register와 device state를 어떻게 가상화하는가. |
| Errata | arch/arm64/kernel/cpu_errata.c, alternative 경로 | MIDR 범위와 capability가 어떤 workaround를 활성화하는가. |
source 경로는 kernel revision에 따라 이동할 수 있다. 이 홈페이지의 번역 문서는 Linux v6.18.37 원문을 기준으로 하므로, 다른 kernel에서 볼 때는 symbol search로 재확인한다.
SVE 기능 하나를 문서에서 Linux source까지 추적한다
- Architecture: DDI 0487·0601에서
ID_AA64PFR0_EL1.SVE, Z/P/FFR state와 trap control을 확인한다. - Boot detection:
arch/arm64/kernel/cpufeature.c에서 ID field가 system capability로 등록되는 조건을 찾는다. - Kernel enable:
CPACR_EL1.ZEN또는 EL2 trap 설정이 언제 풀리는지 FPSIMD/SVE context code를 따라간다. - Userspace ABI: UAPI의
HWCAP_SVE,prctlVL interface와 signal context macro를 연결한다. - Runtime: application의
getauxval()결과와PR_SVE_GET_VL반환값을 확인한다. - Context switch: task가 실제 SVE state를 사용한 뒤 kernel이 thread flag와 register ownership을 어떻게 바꾸는지 추적한다.
이 순서를 MTE·GCS·SME에도 반복하면 “CPU는 지원한다고 하는데 application에서는 왜 안 되지?”라는 문제를 architecture, firmware, kernel detection, process ABI 중 어느 층에서 막혔는지 분리할 수 있다.
FVP와 QEMU에서 기능별로 검증한다
Arm FVP는 architecture와 platform model을 firmware부터 검증하는 데 적합하고, QEMU는 자동화된 OS·userspace 기능 시험에 편리하다. 둘 다 특정 실제 Cortex의 성능을 재현하는 cycle-accurate benchmark 도구로 취급하지 않는다.
- 실험하려는 feature와 EL 구성을 지원하는 FVP 또는 QEMU machine·CPU model을 고른다.
- TF-A, UEFI 또는 direct kernel boot 중 firmware 경계를 시험 목적에 맞게 선택한다.
- kernel config에서 KVM, SVE/SME, MTE, CCA, PMU와 device driver를 명시적으로 확인한다.
- boot log의 ID register 해석과 HWCAP을 저장하고 작은 self-test로 instruction·ABI를 검증한다.
- Realm은 RMM, host KVM, guest kernel과 attestation flow를 한 버전 조합으로 기록한다.
기본 탐지 명령
uname -a
lscpu
cat /proc/cpuinfo
dmesg | grep -Ei 'arm64|sve|sme|mte|gcs|kvm|rme|realm|errat'
perf list
getconf LONG_BIT명령 출력은 환경별 힌트다. application의 최종 feature 선택은 getauxval()과 필요한 prctl() 호출로 결정한다.
실제 탐지 출력은 이렇게 읽는다
| 출력 | 알 수 있는 것 | 알 수 없는 것 |
|---|---|---|
| lscpu | architecture, CPU 목록, cache·topology의 kernel 요약 | 모든 optional feature의 정확한 revision과 firmware 차단 이유 |
| /proc/cpuinfo Features | kernel이 공개한 per-CPU 또는 system feature token | process별 opt-in 상태와 vector length |
| dmesg | feature enable/disable, errata, KVM·SMMU·GIC 초기화 이유 | userspace binary가 실제 해당 명령을 사용했는지 |
| getauxval | 현재 process ABI에서 사용할 수 있는 HWCAP bit | microarchitecture 성능과 raw PMU event 의미 |
| perf list | kernel PMU driver가 제공하는 symbolic event | 모든 implementation-defined event의 정확성·가용성 |
재현 가능한 보고에는 CPU product와 MIDR, SoC·firmware version, kernel config·version, compiler version·option, HWCAP, vector length와 workload command line을 함께 남긴다.
출력 한 줄을 해석하는 방식
Features : ... sve sve2 bti mte ...
sve2 있음 → kernel이 현재 system의 SVE2를 userspace에 공개
mte 있음 → instruction 가용성; 현재 process의 tag-check mode는 별도
bti 있음 → CPU 가용성; ELF property와 loader의 binary 보호는 별도feature token은 “hardware와 kernel이 제공할 수 있다”는 출발점이다. 현재 binary가 해당 명령으로 compile됐는지, loader가 보호를 켰는지, prctl()로 process state가 활성화됐는지는 각각 따로 확인한다.
Linux v6.18.37 소스 분석 8편
Architecture 문서에서 얻은 개념을 실제 구현으로 검증하는 묶음이다. 각 페이지는 핵심 구조체, 호출 경로, 오류 분기, 재현 명령과 원문 source 좌표를 함께 제공한다.
공식 자료
- GNU ToolchainArm GNU Toolchain
- Linux feature statusArm Linux Kernel feature support
- ACLEArm C Language Extensions
- ABIAAPCS64·AAELF64 and Arm ABI specifications
- FVPArm Fixed Virtual Platforms
- First coresFirst Armv9 CPU cores
- ArchitectureDDI 0487: A-profile Architecture Reference Manual