← Documents Documentation/arch/x86/pat.rst GitHub 원문 ↗

Linux 6.18.37 · Architecture

PAT (Page Attribute Table)

PAT memory type, mapping API matrix, MTRR 상호작용과 초기화를 설명합니다.

Source pathDocumentation/arch/x86/pat.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

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

1. 요약·해설

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

요약과 해설

pat.rst:1-240

PAT는 page 단위로 WB·UC·WC·WT·UC-를 지정하지만 같은 physical memory의 virtual alias가 서로 다른 type을 갖지 않도록 해야 합니다. kernel mapping API는 `reserve_memtype()`과 `free_memtype()`으로 이를 추적합니다.

driver는 IO region에 `ioremap_[uc|wc]`, RAM range에 `set_memory_[uc|wc|wt]`와 복구용 `set_memory_wb()`를 사용해야 합니다. `arch_phys_wc_add()`는 non-PAT system의 MTRR 효과와 PAT system의 no-op을 통합합니다.

2. 영어 원문 전체

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

원문 전체 펼치기
1 .. SPDX-License-Identifier: GPL-2.0
2
3 ==========================
4 PAT (Page Attribute Table)
5 ==========================
6
7 x86 Page Attribute Table (PAT) allows for setting the memory attribute at the
8 page level granularity. PAT is complementary to the MTRR settings which allows
9 for setting of memory types over physical address ranges. However, PAT is
10 more flexible than MTRR due to its capability to set attributes at page level
11 and also due to the fact that there are no hardware limitations on number of
12 such attribute settings allowed. Added flexibility comes with guidelines for
13 not having memory type aliasing for the same physical memory with multiple
14 virtual addresses.
15
16 PAT allows for different types of memory attributes. The most commonly used
17 ones that will be supported at this time are:
18
19 === ==============
20 WB Write-back
21 UC Uncached
22 WC Write-combined
23 WT Write-through
24 UC- Uncached Minus
25 === ==============
26
27
28 PAT APIs
29 ========
30
31 There are many different APIs in the kernel that allows setting of memory
32 attributes at the page level. In order to avoid aliasing, these interfaces
33 should be used thoughtfully. Below is a table of interfaces available,
34 their intended usage and their memory attribute relationships. Internally,
35 these APIs use a reserve_memtype()/free_memtype() interface on the physical
36 address range to avoid any aliasing.
37
38 +------------------------+----------+--------------+------------------+
39 | API | RAM | ACPI,... | Reserved/Holes |
40 +------------------------+----------+--------------+------------------+
41 | ioremap | -- | UC- | UC- |
42 +------------------------+----------+--------------+------------------+
43 | ioremap_cache | -- | WB | WB |
44 +------------------------+----------+--------------+------------------+
45 | ioremap_uc | -- | UC | UC |
46 +------------------------+----------+--------------+------------------+
47 | ioremap_wc | -- | -- | WC |
48 +------------------------+----------+--------------+------------------+
49 | ioremap_wt | -- | -- | WT |
50 +------------------------+----------+--------------+------------------+
51 | set_memory_uc, | UC- | -- | -- |
52 | set_memory_wb | | | |
53 +------------------------+----------+--------------+------------------+
54 | set_memory_wc, | WC | -- | -- |
55 | set_memory_wb | | | |
56 +------------------------+----------+--------------+------------------+
57 | set_memory_wt, | WT | -- | -- |
58 | set_memory_wb | | | |
59 +------------------------+----------+--------------+------------------+
60 | pci sysfs resource | -- | -- | UC- |
61 +------------------------+----------+--------------+------------------+
62 | pci sysfs resource_wc | -- | -- | WC |
63 | is IORESOURCE_PREFETCH | | | |
64 +------------------------+----------+--------------+------------------+
65 | pci proc | -- | -- | UC- |
66 | !PCIIOC_WRITE_COMBINE | | | |
67 +------------------------+----------+--------------+------------------+
68 | pci proc | -- | -- | WC |
69 | PCIIOC_WRITE_COMBINE | | | |
70 +------------------------+----------+--------------+------------------+
71 | /dev/mem | -- | WB/WC/UC- | WB/WC/UC- |
72 | read-write | | | |
73 +------------------------+----------+--------------+------------------+
74 | /dev/mem | -- | UC- | UC- |
75 | mmap SYNC flag | | | |
76 +------------------------+----------+--------------+------------------+
77 | /dev/mem | -- | WB/WC/UC- | WB/WC/UC- |
78 | mmap !SYNC flag | | | |
79 | and | |(from existing| (from existing |
80 | any alias to this area | |alias) | alias) |
81 +------------------------+----------+--------------+------------------+
82 | /dev/mem | -- | WB | WB |
83 | mmap !SYNC flag | | | |
84 | no alias to this area | | | |
85 | and | | | |
86 | MTRR says WB | | | |
87 +------------------------+----------+--------------+------------------+
88 | /dev/mem | -- | -- | UC- |
89 | mmap !SYNC flag | | | |
90 | no alias to this area | | | |
91 | and | | | |
92 | MTRR says !WB | | | |
93 +------------------------+----------+--------------+------------------+
94
95
96 Advanced APIs for drivers
97 =========================
98
99 A. Exporting pages to users with remap_pfn_range, io_remap_pfn_range,
100 vmf_insert_pfn.
101
102 Drivers wanting to export some pages to userspace do it by using mmap
103 interface and a combination of:
104
105 1) pgprot_noncached()
106 2) io_remap_pfn_range() or remap_pfn_range() or vmf_insert_pfn()
107
108 With PAT support, a new API pgprot_writecombine is being added. So, drivers can
109 continue to use the above sequence, with either pgprot_noncached() or
110 pgprot_writecombine() in step 1, followed by step 2.
111
112 In addition, step 2 internally tracks the region as UC or WC in memtype
113 list in order to ensure no conflicting mapping.
114
115 Note that this set of APIs only works with IO (non RAM) regions. If driver
116 wants to export a RAM region, it has to do set_memory_uc() or set_memory_wc()
117 as step 0 above and also track the usage of those pages and use set_memory_wb()
118 before the page is freed to free pool.
119
120 MTRR effects on PAT / non-PAT systems
121 =====================================
122
123 The following table provides the effects of using write-combining MTRRs when
124 using ioremap*() calls on x86 for both non-PAT and PAT systems. Ideally
125 mtrr_add() usage will be phased out in favor of arch_phys_wc_add() which will
126 be a no-op on PAT enabled systems. The region over which a arch_phys_wc_add()
127 is made, should already have been ioremapped with WC attributes or PAT entries,
128 this can be done by using ioremap_wc() / set_memory_wc(). Devices which
129 combine areas of IO memory desired to remain uncacheable with areas where
130 write-combining is desirable should consider use of ioremap_uc() followed by
131 set_memory_wc() to white-list effective write-combined areas. Such use is
132 nevertheless discouraged as the effective memory type is considered
133 implementation defined, yet this strategy can be used as last resort on devices
134 with size-constrained regions where otherwise MTRR write-combining would
135 otherwise not be effective.
136 ::
137
138 ==== ======= === ========================= =====================
139 MTRR Non-PAT PAT Linux ioremap value Effective memory type
140 ==== ======= === ========================= =====================
141 PAT Non-PAT | PAT
142 |PCD |
143 ||PWT |
144 ||| |
145 WC 000 WB _PAGE_CACHE_MODE_WB WC | WC
146 WC 001 WC _PAGE_CACHE_MODE_WC WC* | WC
147 WC 010 UC- _PAGE_CACHE_MODE_UC_MINUS WC* | UC
148 WC 011 UC _PAGE_CACHE_MODE_UC UC | UC
149 ==== ======= === ========================= =====================
150
151 (*) denotes implementation defined and is discouraged
152
153 .. note:: -- in the above table mean "Not suggested usage for the API". Some
154 of the --'s are strictly enforced by the kernel. Some others are not really
155 enforced today, but may be enforced in future.
156
157 For ioremap and pci access through /sys or /proc - The actual type returned
158 can be more restrictive, in case of any existing aliasing for that address.
159 For example: If there is an existing uncached mapping, a new ioremap_wc can
160 return uncached mapping in place of write-combine requested.
161
162 set_memory_[uc|wc|wt] and set_memory_wb should be used in pairs, where driver
163 will first make a region uc, wc or wt and switch it back to wb after use.
164
165 Over time writes to /proc/mtrr will be deprecated in favor of using PAT based
166 interfaces. Users writing to /proc/mtrr are suggested to use above interfaces.
167
168 Drivers should use ioremap_[uc|wc] to access PCI BARs with [uc|wc] access
169 types.
170
171 Drivers should use set_memory_[uc|wc|wt] to set access type for RAM ranges.
172
173
174 PAT debugging
175 =============
176
177 With CONFIG_DEBUG_FS enabled, PAT memtype list can be examined by::
178
179 # mount -t debugfs debugfs /sys/kernel/debug
180 # cat /sys/kernel/debug/x86/pat_memtype_list
181 PAT memtype list:
182 uncached-minus @ 0x7fadf000-0x7fae0000
183 uncached-minus @ 0x7fb19000-0x7fb1a000
184 uncached-minus @ 0x7fb1a000-0x7fb1b000
185 uncached-minus @ 0x7fb1b000-0x7fb1c000
186 uncached-minus @ 0x7fb1c000-0x7fb1d000
187 uncached-minus @ 0x7fb1d000-0x7fb1e000
188 uncached-minus @ 0x7fb1e000-0x7fb25000
189 uncached-minus @ 0x7fb25000-0x7fb26000
190 uncached-minus @ 0x7fb26000-0x7fb27000
191 uncached-minus @ 0x7fb27000-0x7fb28000
192 uncached-minus @ 0x7fb28000-0x7fb2e000
193 uncached-minus @ 0x7fb2e000-0x7fb2f000
194 uncached-minus @ 0x7fb2f000-0x7fb30000
195 uncached-minus @ 0x7fb31000-0x7fb32000
196 uncached-minus @ 0x80000000-0x90000000
197
198 This list shows physical address ranges and various PAT settings used to
199 access those physical address ranges.
200
201 Another, more verbose way of getting PAT related debug messages is with
202 "debugpat" boot parameter. With this parameter, various debug messages are
203 printed to dmesg log.
204
205 PAT Initialization
206 ==================
207
208 The following table describes how PAT is initialized under various
209 configurations. The PAT MSR must be updated by Linux in order to support WC
210 and WT attributes. Otherwise, the PAT MSR has the value programmed in it
211 by the firmware. Note, Xen enables WC attribute in the PAT MSR for guests.
212
213 ==== ===== ========================== ========= =======
214 MTRR PAT Call Sequence PAT State PAT MSR
215 ==== ===== ========================== ========= =======
216 E E MTRR -> PAT init Enabled OS
217 E D MTRR -> PAT init Disabled -
218 D E MTRR -> PAT disable Disabled BIOS
219 D D MTRR -> PAT disable Disabled -
220 - np/E PAT -> PAT disable Disabled BIOS
221 - np/D PAT -> PAT disable Disabled -
222 E !P/E MTRR -> PAT init Disabled BIOS
223 D !P/E MTRR -> PAT disable Disabled BIOS
224 !M !P/E MTRR stub -> PAT disable Disabled BIOS
225 ==== ===== ========================== ========= =======
226
227 Legend
228
229 ========= =======================================
230 E Feature enabled in CPU
231 D Feature disabled/unsupported in CPU
232 np "nopat" boot option specified
233 !P CONFIG_X86_PAT option unset
234 !M CONFIG_MTRR option unset
235 Enabled PAT state set to enabled
236 Disabled PAT state set to disabled
237 OS PAT initializes PAT MSR with OS setting
238 BIOS PAT keeps PAT MSR with BIOS setting
239 ========= =======================================
240
241

3. 한국어 전문 번역

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

PAT 개요와 memory type

1-27

이 문서는 `SPDX-License-Identifier: GPL-2.0`으로 배포됩니다. x86 Page Attribute Table(PAT)은 page 단위 granularity로 memory attribute를 설정합니다. physical address range에 memory type을 지정하는 MTRR과 상호 보완적입니다.

PAT는 page 단위로 attribute를 지정할 수 있고 설정 수에 hardware 제한이 없어 MTRR보다 유연합니다. 그러나 같은 physical memory를 여러 virtual address로 mapping할 때 memory type alias가 생기지 않도록 지침을 따라야 합니다.

현재 지원하는 가장 일반적인 memory attribute는 다음과 같습니다.

약어memory attribute
`WB`Write-back
`UC`Uncached
`WC`Write-combined
`WT`Write-through
`UC-`Uncached Minus

PAT API와 적용 영역

28-95

kernel에는 page 단위 memory attribute를 설정하는 여러 API가 있습니다. aliasing을 피하려면 신중하게 사용해야 합니다. 내부적으로 이 API들은 physical address range에 `reserve_memtype()`/`free_memtype()` interface를 사용해 충돌하는 alias를 방지합니다.

APIRAMACPI,...Reserved/Holes
`ioremap`--UC-UC-
`ioremap_cache`--WBWB
`ioremap_uc`--UCUC
`ioremap_wc`----WC
`ioremap_wt`----WT
`set_memory_uc`, `set_memory_wb`UC-----
`set_memory_wc`, `set_memory_wb`WC----
`set_memory_wt`, `set_memory_wb`WT----
PCI sysfs `resource`----UC-
PCI sysfs `resource_wc`, `IORESOURCE_PREFETCH` 설정----WC
PCI proc, `!PCIIOC_WRITE_COMBINE`----UC-
PCI proc, `PCIIOC_WRITE_COMBINE`----WC
`/dev/mem` read-write--WB/WC/UC-WB/WC/UC-
`/dev/mem` mmap `SYNC` flag--UC-UC-
`/dev/mem` mmap `!SYNC`, 해당 영역에 alias 존재--기존 alias의 WB/WC/UC-기존 alias의 WB/WC/UC-
`/dev/mem` mmap `!SYNC`, alias 없음, MTRR은 WB--WBWB
`/dev/mem` mmap `!SYNC`, alias 없음, MTRR은 !WB----UC-

driver를 위한 고급 API

96-119

`remap_pfn_range`, `io_remap_pfn_range`, `vmf_insert_pfn`으로 page를 user에게 export할 수 있습니다. userspace에 page를 export하려는 driver는 mmap interface와 다음 순서를 조합합니다.

  • 1단계: `pgprot_noncached()` 또는 PAT 지원 시 `pgprot_writecombine()`을 선택합니다.
  • 2단계: `io_remap_pfn_range()`, `remap_pfn_range()`, `vmf_insert_pfn()` 가운데 하나를 호출합니다.

2단계는 충돌 mapping을 막기 위해 region을 memtype list의 UC 또는 WC로 내부 추적합니다.

이 API 집합은 IO, 즉 non-RAM region에서만 동작합니다. RAM region을 export하려면 위 순서의 0단계로 `set_memory_uc()` 또는 `set_memory_wc()`를 호출해야 합니다. page 사용도 추적하고 free pool로 반환하기 전에 `set_memory_wb()`를 호출해야 합니다.

PAT·non-PAT system에서 MTRR 효과

120-173

다음 표는 x86에서 `ioremap*()`을 호출할 때 write-combining MTRR이 non-PAT 및 PAT system에 미치는 영향을 보여 줍니다. `mtrr_add()`는 PAT system에서 no-op인 `arch_phys_wc_add()`로 단계적으로 대체하는 것이 바람직합니다.

`arch_phys_wc_add()` 대상 region은 `ioremap_wc()` 또는 `set_memory_wc()`를 사용해 이미 WC attribute나 PAT entry로 ioremap되어 있어야 합니다.

uncacheable로 유지할 IO memory와 write-combining이 필요한 영역이 섞인 device는 `ioremap_uc()` 뒤 `set_memory_wc()`를 사용해 effective WC 영역을 white-list할 수 있습니다. effective memory type이 implementation-defined이므로 권장하지 않지만, 크기 제약 때문에 MTRR write-combining이 달리 효과를 내지 못하는 device에서는 최후 수단으로 사용할 수 있습니다.

Write-combining MTRR과 PAT의 effective memory type
MTRRNon-PAT PCD/PWTPATLinux ioremap valueeffective Non-PAT / PAT
WC000WB`_PAGE_CACHE_MODE_WB`WC / WC
WC001WC`_PAGE_CACHE_MODE_WC`WC* / WC
WC010UC-`_PAGE_CACHE_MODE_UC_MINUS`WC* / UC
WC011UC`_PAGE_CACHE_MODE_UC`UC / UC

MTRR이 WC일 때 PCD/PWT와 PAT entry 조합별 Linux mapping 값과 실제 memory type을 비교합니다.

`*`는 implementation-defined이며 사용을 권장하지 않음을 뜻합니다. API 표의 `--`는 권장하지 않는 사용을 뜻합니다. 일부는 kernel이 엄격히 막고, 일부는 현재 막지 않지만 향후 강제될 수 있습니다.

`ioremap`과 `/sys` 또는 `/proc`를 통한 PCI access에서는 해당 address에 기존 alias가 있으면 실제 반환 type이 더 restrictive할 수 있습니다. 예를 들어 기존 uncached mapping이 있으면 새 `ioremap_wc`가 요청한 write-combine 대신 uncached mapping을 반환할 수 있습니다.

`set_memory_[uc|wc|wt]`와 `set_memory_wb`는 쌍으로 사용해야 합니다. driver가 region을 UC, WC, WT로 바꿨다가 사용 뒤 WB로 되돌립니다.

`/proc/mtrr` write는 시간이 지나며 PAT 기반 interface로 폐지될 예정입니다. PCI BAR에 UC/WC로 access할 driver는 `ioremap_[uc|wc]`를 사용하고, RAM range의 access type에는 `set_memory_[uc|wc|wt]`를 사용해야 합니다.

PAT debugging

174-204

`CONFIG_DEBUG_FS`가 활성화되어 있으면 다음과 같이 PAT memtype list를 확인할 수 있습니다.

# mount -t debugfs debugfs /sys/kernel/debug
# cat /sys/kernel/debug/x86/pat_memtype_list
PAT memtype list:
uncached-minus @ 0x7fadf000-0x7fae0000
uncached-minus @ 0x7fb19000-0x7fb1a000
uncached-minus @ 0x7fb1a000-0x7fb1b000
uncached-minus @ 0x7fb1b000-0x7fb1c000
uncached-minus @ 0x7fb1c000-0x7fb1d000
uncached-minus @ 0x7fb1d000-0x7fb1e000
uncached-minus @ 0x7fb1e000-0x7fb25000
uncached-minus @ 0x7fb25000-0x7fb26000
uncached-minus @ 0x7fb26000-0x7fb27000
uncached-minus @ 0x7fb27000-0x7fb28000
uncached-minus @ 0x7fb28000-0x7fb2e000
uncached-minus @ 0x7fb2e000-0x7fb2f000
uncached-minus @ 0x7fb2f000-0x7fb30000
uncached-minus @ 0x7fb31000-0x7fb32000
uncached-minus @ 0x80000000-0x90000000

이 list는 physical address range와 그 range에 access할 때 사용하는 여러 PAT 설정을 보여 줍니다.

더 자세한 PAT debug message가 필요하면 `debugpat` boot parameter를 사용합니다. 여러 debug message가 dmesg log에 출력됩니다.

PAT 초기화

205-240

WC와 WT attribute를 지원하려면 Linux가 PAT MSR을 update해야 합니다. 그렇지 않으면 PAT MSR은 firmware가 programming한 값을 유지합니다. Xen은 guest의 PAT MSR에서 WC attribute를 활성화합니다.

MTRRPATcall sequencePAT statePAT MSR
EEMTRR → PAT initEnabledOS
EDMTRR → PAT initDisabled-
DEMTRR → PAT disableDisabledBIOS
DDMTRR → PAT disableDisabled-
-np/EPAT → PAT disableDisabledBIOS
-np/DPAT → PAT disableDisabled-
E!P/EMTRR → PAT initDisabledBIOS
D!P/EMTRR → PAT disableDisabledBIOS
!M!P/EMTRR stub → PAT disableDisabledBIOS
표기의미
ECPU에서 feature enabled
DCPU에서 feature disabled/unsupported
np`nopat` boot option 지정
!P`CONFIG_X86_PAT` option unset
!M`CONFIG_MTRR` option unset
EnabledPAT state를 enabled로 설정
DisabledPAT state를 disabled로 설정
OSPAT가 OS 설정으로 PAT MSR 초기화
BIOSPAT가 BIOS 설정의 PAT MSR 유지