Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d410ee51 authored by Bob Moore's avatar Bob Moore Committed by Len Brown
Browse files

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: default avatarBob Moore <robert.moore@intel.com>
Acked-by: default avatarSuresh Siddha <suresh.b.siddha@intel.com>
Signed-off-by: default avatarLin Ming <ming.m.lin@intel.com>
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent b419148e
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -103,9 +103,9 @@

#define ACPI_MAX_REFERENCE_COUNT        0x1000

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

#define ACPI_SYSMEM_REGION_WINDOW_SIZE  4096
#define ACPI_DEFAULT_PAGE_SIZE          4096	/* Must be power of 2 */

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

+25 −10
Original line number Diff line number Diff line
@@ -77,7 +77,8 @@ acpi_ex_system_memory_space_handler(u32 function,
	void *logical_addr_ptr = NULL;
	struct acpi_mem_space_context *mem_info = region_context;
	u32 length;
	acpi_size window_size;
	acpi_size map_length;
	acpi_size page_boundary_map_length;
#ifdef ACPI_MISALIGNMENT_NOT_SUPPORTED
	u32 remainder;
#endif
@@ -144,25 +145,39 @@ acpi_ex_system_memory_space_handler(u32 function,
		}

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

		if (window_size > ACPI_SYSMEM_REGION_WINDOW_SIZE) {
			window_size = ACPI_SYSMEM_REGION_WINDOW_SIZE;
		/*
		 * If mapping the entire remaining portion of the region will cross
		 * a page boundary, just map up to the page boundary, do not cross.
		 * On some systems, crossing a page boundary while mapping regions
		 * can cause warnings if the pages have different attributes
		 * due to resource management
		 */
		page_boundary_map_length =
		    ACPI_ROUND_UP(address, ACPI_DEFAULT_PAGE_SIZE) - address;

		if (!page_boundary_map_length) {
			page_boundary_map_length = ACPI_DEFAULT_PAGE_SIZE;
		}

		if (map_length > page_boundary_map_length) {
			map_length = page_boundary_map_length;
		}

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

		mem_info->mapped_logical_address =
			acpi_os_map_memory((acpi_physical_address) address, window_size);
		mem_info->mapped_logical_address = acpi_os_map_memory((acpi_physical_address) address, map_length);
		if (!mem_info->mapped_logical_address) {
			ACPI_ERROR((AE_INFO,
				    "Could not map memory at %8.8X%8.8X, size %X",
				    ACPI_FORMAT_NATIVE_UINT(address),
				    (u32) window_size));
				    (u32) map_length));
			mem_info->mapped_length = 0;
			return_ACPI_STATUS(AE_NO_MEMORY);
		}
@@ -170,7 +185,7 @@ acpi_ex_system_memory_space_handler(u32 function,
		/* Save the physical address and mapping size */

		mem_info->mapped_physical_address = address;
		mem_info->mapped_length = window_size;
		mem_info->mapped_length = map_length;
	}

	/*