Skip to content

Commit d410ee5

Browse files
acpiboblenb
authored andcommitted
ACPICA: avoid "Info: mapping multiple BARs. Your kernel is fine."
Ensure that memory mappings created for operation regions do not cross page boundaries. Crossing a page boundary while mapping regions can cause warnings if the pages have different attributes. Such regions are probably BIOS bugs, and this is the workaround. http://bugzilla.kernel.org/show_bug.cgi?id=14445 [Kernel summit hacking hour] Signed-off-by: Bob Moore <[email protected]> Acked-by: Suresh Siddha <[email protected]> Signed-off-by: Lin Ming <[email protected]> Signed-off-by: Len Brown <[email protected]>
1 parent b419148 commit d410ee5

File tree

2 files changed

+27
-12
lines changed

2 files changed

+27
-12
lines changed

drivers/acpi/acpica/acconfig.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@
103103

104104
#define ACPI_MAX_REFERENCE_COUNT 0x1000
105105

106-
/* Size of cached memory mapping for system memory operation region */
106+
/* Default page size for use in mapping memory for operation regions */
107107

108-
#define ACPI_SYSMEM_REGION_WINDOW_SIZE 4096
108+
#define ACPI_DEFAULT_PAGE_SIZE 4096 /* Must be power of 2 */
109109

110110
/* owner_id tracking. 8 entries allows for 255 owner_ids */
111111

drivers/acpi/acpica/exregion.c

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ acpi_ex_system_memory_space_handler(u32 function,
7777
void *logical_addr_ptr = NULL;
7878
struct acpi_mem_space_context *mem_info = region_context;
7979
u32 length;
80-
acpi_size window_size;
80+
acpi_size map_length;
81+
acpi_size page_boundary_map_length;
8182
#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
8283
u32 remainder;
8384
#endif
@@ -144,33 +145,47 @@ acpi_ex_system_memory_space_handler(u32 function,
144145
}
145146

146147
/*
147-
* Don't attempt to map memory beyond the end of the region, and
148-
* constrain the maximum mapping size to something reasonable.
148+
* Attempt to map from the requested address to the end of the region.
149+
* However, we will never map more than one page, nor will we cross
150+
* a page boundary.
149151
*/
150-
window_size = (acpi_size)
152+
map_length = (acpi_size)
151153
((mem_info->address + mem_info->length) - address);
152154

153-
if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
154-
window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
155+
/*
156+
* If mapping the entire remaining portion of the region will cross
157+
* a page boundary, just map up to the page boundary, do not cross.
158+
* On some systems, crossing a page boundary while mapping regions
159+
* can cause warnings if the pages have different attributes
160+
* due to resource management
161+
*/
162+
page_boundary_map_length =
163+
ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address;
164+
165+
if (!page_boundary_map_length) {
166+
page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE;
167+
}
168+
169+
if (map_length > page_boundary_map_length) {
170+
map_length = page_boundary_map_length;
155171
}
156172

157173
/* Create a new mapping starting at the address given */
158174

159-
mem_info->mapped_logical_address =
160-
acpi_os_map_memory((acpi_physical_address) address, window_size);
175+
mem_info->mapped_logical_address = acpi_os_map_memory((acpi_physical_address) address, map_length);
161176
if (!mem_info->mapped_logical_address) {
162177
ACPI_ERROR((AE_INFO,
163178
"Could not map memory at %8.8X%8.8X, size %X",
164179
ACPI_FORMAT_NATIVE_UINT(address),
165-
(u32) window_size));
180+
(u32) map_length));
166181
mem_info->mapped_length = 0;
167182
return_ACPI_STATUS(AE_NO_MEMORY);
168183
}
169184

170185
/* Save the physical address and mapping size */
171186

172187
mem_info->mapped_physical_address = address;
173-
mem_info->mapped_length = window_size;
188+
mem_info->mapped_length = map_length;
174189
}
175190

176191
/*

0 commit comments

Comments
 (0)