Documentation/driver-api/cxl/platform/bios-and-efi.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API / CXL / Platform

BIOS/EFI Configuration

CXL platform firmware가 ACPI·memory map·HDM decoder를 구성할 때 Linux가 요구하거나 권장하는 alignment, memory hole, translation과 interleave 규칙을 설명합니다.

Source pathDocumentation/driver-api/cxl/platform/bios-and-efi.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약과 해설

bios-and-efi.rst:1-262

CXL의 정적 구성은 BIOS/EFI가 만든 ACPI table과 physical memory map에서 시작됩니다. `EFI_MEMORY_SP`는 memory 관리를 CXL driver에 맡기고, 2GB alignment는 여러 architecture와 kernel version의 hotplug 호환성을 높입니다. HPA-to-DPA translation은 endpoint decoder에서만 수행해야 하며, memory hole은 연속 HPA chunk마다 root·host bridge·endpoint decoder chain과 CFMWS를 나누는 구성이 가장 안전합니다.

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ======================
4 BIOS/EFI Configuration
5 ======================
6
7 BIOS and EFI are largely responsible for configuring static information about
8 devices (or potential future devices) such that Linux can build the appropriate
9 logical representations of these devices.
10
11 At a high level, this is what occurs during this phase of configuration.
12
13 * The bootloader starts the BIOS/EFI.
14
15 * BIOS/EFI do early device probe to determine static configuration
16
17 * BIOS/EFI creates ACPI Tables that describe static config for the OS
18
19 * BIOS/EFI create the system memory map (EFI Memory Map, E820, etc)
20
21 * BIOS/EFI calls :code:`start_kernel` and begins the Linux Early Boot process.
22
23 Much of what this section is concerned with is ACPI Table production and
24 static memory map configuration. More detail on these tables can be found
25 at :doc:`ACPI Tables <acpi>`.
26
27 .. note::
28 Platform Vendors should read carefully, as this sections has recommendations
29 on physical memory region size and alignment, memory holes, HDM interleave,
30 and what linux expects of HDM decoders trying to work with these features.
31
32 UEFI Settings
33 =============
34 If your platform supports it, the :code:`uefisettings` command can be used to
35 read/write EFI settings. Changes will be reflected on the next reboot. Kexec
36 is not a sufficient reboot.
37
38 One notable configuration here is the EFI_MEMORY_SP (Specific Purpose) bit.
39 When this is enabled, this bit tells linux to defer management of a memory
40 region to a driver (in this case, the CXL driver). Otherwise, the memory is
41 treated as "normal memory", and is exposed to the page allocator during
42 :code:`__init`.
43
44 uefisettings examples
45 ---------------------
46
47 :code:`uefisettings identify` ::
48
49 uefisettings identify
50
51 bios_vendor: xxx
52 bios_version: xxx
53 bios_release: xxx
54 bios_date: xxx
55 product_name: xxx
56 product_family: xxx
57 product_version: xxx
58
59 On some AMD platforms, the :code:`EFI_MEMORY_SP` bit is set via the :code:`CXL
60 Memory Attribute` field. This may be called something else on your platform.
61
62 :code:`uefisettings get "CXL Memory Attribute"` ::
63
64 selector: xxx
65 ...
66 question: Question {
67 name: "CXL Memory Attribute",
68 answer: "Enabled",
69 ...
70 }
71
72 Physical Memory Map
73 ===================
74
75 Physical Address Region Alignment
76 ---------------------------------
77
78 As of Linux v6.14, the hotplug memory system requires memory regions to be
79 uniform in size and alignment. While the CXL specification allows for memory
80 regions as small as 256MB, the supported memory block size and alignment for
81 hotplugged memory is architecture-defined.
82
83 A Linux memory blocks may be as small as 128MB and increase in powers of two.
84
85 * On ARM, the default block size and alignment is either 128MB or 256MB.
86
87 * On x86, the default block size is 256MB, and increases to 2GB as the
88 capacity of the system increases up to 64GB.
89
90 For best support across versions, platform vendors should place CXL memory at
91 a 2GB aligned base address, and regions should be 2GB aligned. This also helps
92 prevent the creating thousands of memory devices (one per block).
93
94 Memory Holes
95 ------------
96
97 Holes in the memory map are tricky. Consider a 4GB device located at base
98 address 0x100000000, but with the following memory map ::
99
100 ---------------------
101 | 0x100000000 |
102 | CXL |
103 | 0x1BFFFFFFF |
104 ---------------------
105 | 0x1C0000000 |
106 | MEMORY HOLE |
107 | 0x1FFFFFFFF |
108 ---------------------
109 | 0x200000000 |
110 | CXL CONT. |
111 | 0x23FFFFFFF |
112 ---------------------
113
114 There are two issues to consider:
115
116 * decoder programming, and
117 * memory block alignment.
118
119 If your architecture requires 2GB uniform size and aligned memory blocks, the
120 only capacity Linux is capable of mapping (as of v6.14) would be the capacity
121 from `0x100000000-0x180000000`. The remaining capacity will be stranded, as
122 they are not of 2GB aligned length.
123
124 Assuming your architecture and memory configuration allows 1GB memory blocks,
125 this memory map is supported and this should be presented as multiple CFMWS
126 in the CEDT that describe each side of the memory hole separately - along with
127 matching decoders.
128
129 Multiple decoders can (and should) be used to manage such a memory hole (see
130 below), but each chunk of a memory hole should be aligned to a reasonable block
131 size (larger alignment is always better). If you intend to have memory holes
132 in the memory map, expect to use one decoder per contiguous chunk of host
133 physical memory.
134
135 As of v6.14, Linux does provide support for memory hotplug of multiple
136 physical memory regions separated by a memory hole described by a single
137 HDM decoder.
138
139
140 Decoder Programming
141 ===================
142 If BIOS/EFI intends to program the decoders to be statically configured,
143 there are a few things to consider to avoid major pitfalls that will
144 prevent Linux compatibility. Some of these recommendations are not
145 required "per the specification", but Linux makes no guarantees of support
146 otherwise.
147
148
149 Translation Point
150 -----------------
151 Per the specification, the only decoders which **TRANSLATE** Host Physical
152 Address (HPA) to Device Physical Address (DPA) are the **Endpoint Decoders**.
153 All other decoders in the fabric are intended to route accesses without
154 translating the addresses.
155
156 This is heavily implied by the specification, see: ::
157
158 CXL Specification 3.1
159 8.2.4.20: CXL HDM Decoder Capability Structure
160 - Implementation Note: CXL Host Bridge and Upstream Switch Port Decoder Flow
161 - Implementation Note: Device Decoder Logic
162
163 Given this, Linux makes a strong assumption that decoders between CPU and
164 endpoint will all be programmed with addresses ranges that are subsets of
165 their parent decoder.
166
167 Due to some ambiguity in how Architecture, ACPI, PCI, and CXL specifications
168 "hand off" responsibility between domains, some early adopting platforms
169 attempted to do translation at the originating memory controller or host
170 bridge. This configuration requires a platform specific extension to the
171 driver and is not officially endorsed - despite being supported.
172
173 It is *highly recommended* **NOT** to do this; otherwise, you are on your own
174 to implement driver support for your platform.
175
176 Interleave and Configuration Flexibility
177 ----------------------------------------
178 If providing cross-host-bridge interleave, a CFMWS entry in the :doc:`CEDT
179 <acpi/cedt>` must be presented with target host-bridges for the interleaved
180 device sets (there may be multiple behind each host bridge).
181
182 If providing intra-host-bridge interleaving, only 1 CFMWS entry in the CEDT is
183 required for that host bridge - if it covers the entire capacity of the devices
184 behind the host bridge.
185
186 If intending to provide users flexibility in programming decoders beyond the
187 root, you may want to provide multiple CFMWS entries in the CEDT intended for
188 different purposes. For example, you may want to consider adding:
189
190 1) A CFMWS entry to cover all interleavable host bridges.
191 2) A CFMWS entry to cover all devices on a single host bridge.
192 3) A CFMWS entry to cover each device.
193
194 A platform may choose to add all of these, or change the mode based on a BIOS
195 setting. For each CFMWS entry, Linux expects descriptions of the described
196 memory regions in the :doc:`SRAT <acpi/srat>` to determine the number of
197 NUMA nodes it should reserve during early boot / init.
198
199 As of v6.14, Linux will create a NUMA node for each CEDT CFMWS entry, even if
200 a matching SRAT entry does not exist; however, this is not guaranteed in the
201 future and such a configuration should be avoided.
202
203 Memory Holes
204 ------------
205 If your platform includes memory holes interspersed between your CXL memory, it
206 is recommended to utilize multiple decoders to cover these regions of memory,
207 rather than try to program the decoders to accept the entire range and expect
208 Linux to manage the overlap.
209
210 For example, consider the Memory Hole described above ::
211
212 ---------------------
213 | 0x100000000 |
214 | CXL |
215 | 0x1BFFFFFFF |
216 ---------------------
217 | 0x1C0000000 |
218 | MEMORY HOLE |
219 | 0x1FFFFFFFF |
220 ---------------------
221 | 0x200000000 |
222 | CXL CONT. |
223 | 0x23FFFFFFF |
224 ---------------------
225
226 Assuming this is provided by a single device attached directly to a host bridge,
227 Linux would expect the following decoder programming ::
228
229 ----------------------- -----------------------
230 | root-decoder-0 | | root-decoder-1 |
231 | base: 0x100000000 | | base: 0x200000000 |
232 | size: 0xC0000000 | | size: 0x40000000 |
233 ----------------------- -----------------------
234 | |
235 ----------------------- -----------------------
236 | HB-decoder-0 | | HB-decoder-1 |
237 | base: 0x100000000 | | base: 0x200000000 |
238 | size: 0xC0000000 | | size: 0x40000000 |
239 ----------------------- -----------------------
240 | |
241 ----------------------- -----------------------
242 | ep-decoder-0 | | ep-decoder-1 |
243 | base: 0x100000000 | | base: 0x200000000 |
244 | size: 0xC0000000 | | size: 0x40000000 |
245 ----------------------- -----------------------
246
247 With a CEDT configuration with two CFMWS describing the above root decoders.
248
249 Linux makes no guarantee of support for strange memory hole situations.
250
251 Multi-Media Devices
252 -------------------
253 The CFMWS field of the CEDT has special restriction bits which describe whether
254 the described memory region allows volatile or persistent memory (or both). If
255 the platform intends to support either:
256
257 1) A device with multiple medias, or
258 2) Using a persistent memory device as normal memory
259
260 A platform may wish to create multiple CEDT CFMWS entries to describe the same
261 memory, with the intent of allowing the end user flexibility in how that memory
262 is configured. Linux does not presently have strong requirements in this area.
263

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

BIOS/EFI 구성 단계

1-31
.. SPDX-License-Identifier: GPL-2.0

BIOS와 EFI는 Linux가 device 또는 향후 장착될 수 있는 device의 적절한 logical representation을 만들 수 있도록 정적 정보를 구성하는 일을 주로 담당합니다.

이 구성 단계에서는 상위 수준에서 다음 작업이 일어납니다.

  • bootloader가 BIOS/EFI를 시작합니다.
  • BIOS/EFI가 early device probe를 수행해 정적 구성을 파악합니다.
  • BIOS/EFI가 OS에 정적 구성을 설명하는 ACPI Table을 만듭니다.
  • BIOS/EFI가 EFI Memory Map, E820 등의 system memory map을 만듭니다.
  • BIOS/EFI가 `start_kernel`을 호출하고 Linux Early Boot 과정을 시작합니다.

이 절은 주로 ACPI Table 생성과 정적 memory map 구성에 초점을 둡니다. table의 자세한 내용은 `ACPI Tables` 문서를 참조하십시오.

Platform vendor는 physical memory region의 크기와 alignment, memory hole, HDM interleave, 그리고 이 기능을 사용하는 HDM decoder에 Linux가 기대하는 조건에 관한 권고를 주의 깊게 읽어야 합니다.

UEFI 설정과 EFI_MEMORY_SP

32-71

platform이 지원한다면 `uefisettings` command로 EFI setting을 읽고 쓸 수 있습니다. 변경 사항은 다음 reboot에 반영되며 kexec는 충분한 reboot가 아닙니다.

중요한 설정 중 하나는 `EFI_MEMORY_SP`(Specific Purpose) bit입니다. 이 bit를 enable하면 Linux는 memory region 관리를 driver, 여기서는 CXL driver에 맡깁니다. 그렇지 않으면 해당 memory는 `normal memory`로 처리되어 `__init` 중 page allocator에 노출됩니다.

`uefisettings identify` 예시는 다음과 같습니다.

uefisettings identify

bios_vendor: xxx
bios_version: xxx
bios_release: xxx
bios_date: xxx
product_name: xxx
product_family: xxx
product_version: xxx

일부 AMD platform에서는 `CXL Memory Attribute` field를 통해 `EFI_MEMORY_SP` bit를 설정합니다. 다른 platform에서는 이름이 다를 수 있습니다.

`uefisettings get "CXL Memory Attribute"` 예시는 다음과 같습니다.

selector: xxx
...
question: Question {
    name: "CXL Memory Attribute",
    answer: "Enabled",
    ...
}

Physical Address Region Alignment

72-93

Linux v6.14 기준 memory hotplug system은 memory region의 크기와 alignment가 균일하기를 요구합니다. CXL specification은 256MB만큼 작은 region을 허용하지만 hotplug memory가 지원하는 block size와 alignment는 architecture가 정의합니다.

Linux memory block은 128MB까지 작을 수 있으며 이후 2의 거듭제곱으로 증가합니다.

  • ARM의 기본 block size와 alignment는 128MB 또는 256MB입니다.
  • x86의 기본 block size는 256MB이며 system capacity가 64GB까지 커짐에 따라 2GB까지 증가합니다.

여러 Linux version에서 가장 잘 지원되도록 platform vendor는 CXL memory를 2GB aligned base address에 배치하고 region도 2GB 단위로 align해야 합니다. 이렇게 하면 block마다 하나씩 수천 개의 memory device가 만들어지는 문제도 줄어듭니다.

Physical Memory Map의 memory hole

94-139

memory map의 hole은 처리하기 까다롭습니다. base address `0x100000000`에 놓인 4GB device가 다음과 같은 memory map을 가진다고 가정합니다.

---------------------
|    0x100000000    |
|        CXL        |
|    0x1BFFFFFFF    |
---------------------
|    0x1C0000000    |
|    MEMORY HOLE    |
|    0x1FFFFFFFF    |
---------------------
|    0x200000000    |
|     CXL CONT.     |
|    0x23FFFFFFF    |
---------------------
CXL memory와 중간 memory hole
RangeTypeSize
0x100000000-0x1BFFFFFFFCXL memory3GB
0x1C0000000-0x1FFFFFFFFMemory hole1GB
0x200000000-0x23FFFFFFFCXL continuation1GB

4GB CXL device의 address range가 중간 memory hole 때문에 두 개의 연속 구간으로 나뉘는 구조입니다.

검토해야 할 문제는 decoder programming과 memory block alignment 두 가지입니다.

architecture가 균일한 2GB 크기와 alignment의 memory block을 요구한다면 Linux v6.14가 mapping할 수 있는 capacity는 `0x100000000-0x180000000`뿐입니다. 나머지는 길이가 2GB 단위로 align되지 않아 사용할 수 없는 capacity로 남습니다.

architecture와 memory 구성이 1GB memory block을 허용한다면 이 memory map은 지원됩니다. CEDT에는 memory hole 양쪽을 따로 설명하는 여러 CFMWS와 이에 대응하는 decoder를 제시해야 합니다.

이런 memory hole을 관리하려면 여러 decoder를 사용할 수 있고 사용해야 합니다. hole의 각 연속 chunk는 합리적인 block size로 align해야 하며 큰 alignment일수록 좋습니다. memory map에 hole을 둘 계획이라면 연속된 host physical memory chunk마다 decoder 하나를 사용해야 합니다.

Linux v6.14는 하나의 HDM decoder가 설명하는 memory hole로 분리된 여러 physical memory region의 memory hotplug를 지원합니다.

Decoder Programming과 translation point

140-175

BIOS/EFI가 decoder를 정적으로 구성하도록 programming하려면 Linux 호환성을 막는 중대한 함정을 피하기 위해 몇 가지 사항을 고려해야 합니다. 일부 권고는 specification의 필수 조건이 아니지만, 따르지 않는 구성에 Linux는 지원을 보장하지 않습니다.

specification에 따르면 Host Physical Address(HPA)를 Device Physical Address(DPA)로 실제 `TRANSLATE`하는 decoder는 `Endpoint Decoder`뿐입니다. fabric의 다른 모든 decoder는 address를 변환하지 않고 access를 route해야 합니다.

CXL Specification 3.1의 관련 근거는 다음과 같습니다.

CXL Specification 3.1
8.2.4.20: CXL HDM Decoder Capability Structure
- Implementation Note: CXL Host Bridge and Upstream Switch Port Decoder Flow
- Implementation Note: Device Decoder Logic

따라서 Linux는 CPU와 endpoint 사이의 모든 decoder가 parent decoder address range의 subset으로 programming된다고 강하게 가정합니다.

Architecture, ACPI, PCI, CXL specification 사이의 책임 인계가 다소 모호해 일부 초기 platform은 시작 memory controller 또는 host bridge에서 translation을 시도했습니다. 이 구성은 platform별 driver extension이 필요하고 지원 사례가 있더라도 공식적으로 권장되지 않습니다.

이 방식을 사용하지 않는 것이 강력히 권장됩니다. 사용한다면 해당 platform의 driver 지원을 직접 구현해야 합니다.

Interleave와 구성 유연성

176-202

host bridge를 가로지르는 `cross-host-bridge` interleave를 제공한다면 CEDT의 CFMWS entry가 interleave된 device set의 target host bridge를 제시해야 합니다. 각 host bridge 뒤에는 여러 device가 있을 수 있습니다.

host bridge 내부 `intra-host-bridge` interleave를 제공한다면 그 host bridge 뒤의 device 전체 capacity를 덮는 경우 CEDT에는 해당 host bridge용 CFMWS entry 하나만 필요합니다.

root 이후 decoder programming을 사용자에게 유연하게 제공하려면 서로 다른 목적의 CFMWS entry를 여러 개 둘 수 있습니다.

  • interleave 가능한 모든 host bridge를 덮는 CFMWS entry
  • 단일 host bridge의 모든 device를 덮는 CFMWS entry
  • 각 device를 덮는 CFMWS entry

platform은 이 entry를 모두 추가하거나 BIOS setting에 따라 mode를 바꿀 수 있습니다. 각 CFMWS entry에 대해 Linux는 early boot/init 중 예약할 NUMA node 수를 결정할 수 있도록 SRAT에 해당 memory region 설명이 있기를 기대합니다.

Linux v6.14는 일치하는 SRAT entry가 없어도 각 CEDT CFMWS entry에 NUMA node를 만들지만, 향후에는 보장되지 않으므로 그런 구성은 피해야 합니다.

Memory hole을 위한 decoder 구성

203-250

CXL memory 사이에 memory hole이 있다면 decoder가 전체 range를 받아들이게 한 뒤 Linux가 overlap을 관리하기를 기대하는 대신, 여러 decoder로 각 memory region을 덮는 것이 권장됩니다.

앞서 설명한 memory hole은 다음과 같습니다.

---------------------
|    0x100000000    |
|        CXL        |
|    0x1BFFFFFFF    |
---------------------
|    0x1C0000000    |
|    MEMORY HOLE    |
|    0x1FFFFFFFF    |
---------------------
|    0x200000000    |
|     CXL CONT.     |
|    0x23FFFFFFF    |
---------------------
Decoder 구성 대상 memory range
RangeTypeSize
0x100000000-0x1BFFFFFFFCXL memory3GB
0x1C0000000-0x1FFFFFFFFMemory hole1GB
0x200000000-0x23FFFFFFFCXL continuation1GB

4GB CXL device의 address range가 중간 memory hole 때문에 두 개의 연속 구간으로 나뉘는 구조입니다.

이 memory가 host bridge에 직접 연결된 단일 device에서 제공된다고 가정하면 Linux는 다음 decoder programming을 기대합니다.

-----------------------   -----------------------
| root-decoder-0      |   | root-decoder-1      |
|   base: 0x100000000 |   |   base: 0x200000000 |
|   size:  0xC0000000 |   |   size:  0x40000000 |
-----------------------   -----------------------
           |                         |
-----------------------   -----------------------
| HB-decoder-0        |   | HB-decoder-1        |
|   base: 0x100000000 |   |   base: 0x200000000 |
|   size:  0xC0000000 |   |   size:  0x40000000 |
-----------------------   -----------------------
           |                         |
-----------------------   -----------------------
| ep-decoder-0        |   | ep-decoder-1        |
|   base: 0x100000000 |   |   base: 0x200000000 |
|   size:  0xC0000000 |   |   size:  0x40000000 |
-----------------------   -----------------------
Memory hole 양쪽의 독립 decoder chain
root-decoder-0 base 0x100000000 size 0xC0000000HB-decoder-0 base 0x100000000 size 0xC0000000ep-decoder-0 base 0x100000000 size 0xC0000000
root-decoder-1 base 0x200000000 size 0x40000000HB-decoder-1 base 0x200000000 size 0x40000000ep-decoder-1 base 0x200000000 size 0x40000000

각 연속 HPA chunk는 root, host bridge, endpoint의 대응 decoder를 따라 독립적으로 route됩니다.

CEDT에는 위의 두 root decoder를 설명하는 두 CFMWS가 있어야 합니다. Linux는 특이한 memory hole 구성에 대한 지원을 보장하지 않습니다.

Multi-Media Device

251-262

CEDT의 CFMWS field에는 해당 memory region이 volatile memory, persistent memory 또는 둘 다를 허용하는지 설명하는 특별한 restriction bit가 있습니다.

platform이 다음 중 하나를 지원하려 한다고 가정합니다.

  • 여러 media를 가진 device
  • persistent memory device를 normal memory로 사용

이 경우 end user가 memory 구성 방식을 유연하게 선택할 수 있도록 동일한 memory를 설명하는 CEDT CFMWS entry를 여러 개 만들 수 있습니다. 현재 Linux는 이 영역에 강한 요구 조건을 두지 않습니다.