Linux-ACPI Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH 0/6] ACPICA / ACPI: OSL: Rework GPE registers access code
@ 2020-09-04 17:19 Rafael J. Wysocki
  2020-09-04 17:21 ` [PATCH 1/6] ACPICA: Validate GPE blocks at init time Rafael J. Wysocki
                   ` (5 more replies)
  0 siblings, 6 replies; 10+ messages in thread
From: Rafael J. Wysocki @ 2020-09-04 17:19 UTC (permalink / raw)
  To: Linux ACPI; +Cc: LKML, Erik Kaneda, Bob Moore

Hi All,

The underlying issue here is that in Linux calling
acpi_os_read_memory() or acpi_os_write_memory() from an interrupt
handler is generally invalid, because these functions may attempt
to map memory on the fly.  It is only valid to call them from an
interrupt handler if it is known that there is a memory mapping
covering the physical address passed as the argument.

However, in that case using acpi_os_read_memory() or
acpi_os_write_memory() for accessing memory is inefficient, because
they need to look up the mapping in question every time in a global
list, and it would be much more straightforward to use the (known
already) logical address of the target memory region.

In ACPICA this problem affects GPE registers that are accessed
with the help of acpi_hw_read() and acpi_hw_write() which is
inefficient not just because they end up calling
acpi_os_read_memory() or acpi_os_write_memory() if the GPE
registers are located in system memory, but also because these
functions check things that need not be checked for GPE registers
in particular and they do that on every access.

This series of patches reworks the GPE register accesses in ACPICA
to be more efficient by omitting the unnecessary checks and making it
possible to use logical addresses directly if these registers are
located in system memory.

The first four patches modify ACPICA and the last two add the
requisite OS support to Linux on top of that.

Please refer to the changelogs of the patches for details.

Thanks,
Rafael




^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 1/6] ACPICA: Validate GPE blocks at init time
  2020-09-04 17:19 [PATCH 0/6] ACPICA / ACPI: OSL: Rework GPE registers access code Rafael J. Wysocki
@ 2020-09-04 17:21 ` Rafael J. Wysocki
  2020-09-04 17:22 ` [PATCH 2/6] ACPICA: Introduce acpi_hw_gpe_read() and acpi_hw_gpe_write() Rafael J. Wysocki
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Rafael J. Wysocki @ 2020-09-04 17:21 UTC (permalink / raw)
  To: Linux ACPI; +Cc: LKML, Erik Kaneda, Bob Moore

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

Some of the checks done by acpi_hw_read() and acpi_hw_write(),
which are used for accessing GPE registers, are redundant in the
specific case of GPE registers and the ones that are not redundant
can be done upfront at the initialization time so as to fail the
initialization if they are not passed instead of failing every
access to the affected GPE registers going forward (including
accesses from the SCI interrupt handler).

Modify the GPE blocks initialization code accordingly.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpica/achware.h  |  2 ++
 drivers/acpi/acpica/evgpeblk.c | 17 +++++++++++++++++
 drivers/acpi/acpica/hwvalid.c  | 30 ++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+)

diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index ebf6453d0e21..f1f644b58b15 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -73,6 +73,8 @@ acpi_status acpi_hw_read_port(acpi_io_address address, u32 *value, u32 width);
 
 acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width);
 
+acpi_status acpi_hw_validate_io_block(u64 address, u32 bit_width, u32 count);
+
 /*
  * hwgpe - GPE support
  */
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 132adff1e131..eb5d98757fdc 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -317,6 +317,23 @@ acpi_ev_create_gpe_block(struct acpi_namespace_node *gpe_device,
 		return_ACPI_STATUS(AE_OK);
 	}
 
+	/* Validate the space_ID */
+
+	if ((space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) &&
+	    (space_id != ACPI_ADR_SPACE_SYSTEM_IO)) {
+		ACPI_ERROR((AE_INFO,
+			    "Unsupported address space: 0x%X", space_id));
+		return_ACPI_STATUS(AE_SUPPORT);
+	}
+
+	if (space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
+		status = acpi_hw_validate_io_block(address,
+						   ACPI_GPE_REGISTER_WIDTH,
+						   register_count);
+		if (ACPI_FAILURE(status))
+			return_ACPI_STATUS(status);
+	}
+
 	/* Allocate a new GPE block */
 
 	gpe_block = ACPI_ALLOCATE_ZEROED(sizeof(struct acpi_gpe_block_info));
diff --git a/drivers/acpi/acpica/hwvalid.c b/drivers/acpi/acpica/hwvalid.c
index 4d94861e6093..b2ca7dfd3fc9 100644
--- a/drivers/acpi/acpica/hwvalid.c
+++ b/drivers/acpi/acpica/hwvalid.c
@@ -292,3 +292,33 @@ acpi_status acpi_hw_write_port(acpi_io_address address, u32 value, u32 width)
 
 	return (AE_OK);
 }
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_validate_io_block
+ *
+ * PARAMETERS:  Address             Address of I/O port/register blobk
+ *              bit_width           Number of bits (8,16,32) in each register
+ *              count               Number of registers in the block
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Validates a block of I/O ports/registers.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_validate_io_block(u64 address, u32 bit_width, u32 count)
+{
+	acpi_status status;
+
+	while (count--) {
+		status = acpi_hw_validate_io_request((acpi_io_address)address,
+						     bit_width);
+		if (ACPI_FAILURE(status))
+			return_ACPI_STATUS(status);
+
+		address += ACPI_DIV_8(bit_width);
+	}
+
+	return_ACPI_STATUS(AE_OK);
+}
-- 
2.26.2





^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 2/6] ACPICA: Introduce acpi_hw_gpe_read() and acpi_hw_gpe_write()
  2020-09-04 17:19 [PATCH 0/6] ACPICA / ACPI: OSL: Rework GPE registers access code Rafael J. Wysocki
  2020-09-04 17:21 ` [PATCH 1/6] ACPICA: Validate GPE blocks at init time Rafael J. Wysocki
@ 2020-09-04 17:22 ` Rafael J. Wysocki
  2020-09-04 17:23 ` [PATCH 3/6] ACPICA: Introduce special struct type for GPE register addresses Rafael J. Wysocki
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Rafael J. Wysocki @ 2020-09-04 17:22 UTC (permalink / raw)
  To: Linux ACPI; +Cc: LKML, Erik Kaneda, Bob Moore

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

Now that GPE blocks are validated at the initialization time, accesses
to GPE registers can be made more straightforward by ommitting all of
the redundant checks in acpi_hw_read() and acpi_hw_write() and only
invoking the OS-provided helper for the given type of access (read or
write) and the address space holding these registers.

For this reason, introduce simplified routines for accessing GPE
registers, acpi_hw_gpe_read() and acpi_hw_gpe_write(), designed in
accordance with the above observation, and modify all of the code
accessing GPE registers to use them instead of acpi_hw_read() and
acpi_hw_write(), respectively.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpica/achware.h  |  4 ++
 drivers/acpi/acpica/evgpe.c    |  4 +-
 drivers/acpi/acpica/evgpeblk.c |  4 +-
 drivers/acpi/acpica/hwgpe.c    | 92 ++++++++++++++++++++++++++++------
 4 files changed, 84 insertions(+), 20 deletions(-)

diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index f1f644b58b15..4dba7229f9c1 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -78,6 +78,10 @@ acpi_status acpi_hw_validate_io_block(u64 address, u32 bit_width, u32 count);
 /*
  * hwgpe - GPE support
  */
+acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_generic_address *reg);
+
+acpi_status acpi_hw_gpe_write(u64 value, struct acpi_generic_address *reg);
+
 u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info);
 
 acpi_status
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c
index 3e39907fedd9..06b9c8dd11c9 100644
--- a/drivers/acpi/acpica/evgpe.c
+++ b/drivers/acpi/acpica/evgpe.c
@@ -656,14 +656,14 @@ acpi_ev_detect_gpe(struct acpi_namespace_node *gpe_device,
 
 	/* GPE currently enabled (enable bit == 1)? */
 
-	status = acpi_hw_read(&enable_reg, &gpe_register_info->enable_address);
+	status = acpi_hw_gpe_read(&enable_reg, &gpe_register_info->enable_address);
 	if (ACPI_FAILURE(status)) {
 		goto error_exit;
 	}
 
 	/* GPE currently active (status bit == 1)? */
 
-	status = acpi_hw_read(&status_reg, &gpe_register_info->status_address);
+	status = acpi_hw_gpe_read(&status_reg, &gpe_register_info->status_address);
 	if (ACPI_FAILURE(status)) {
 		goto error_exit;
 	}
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index eb5d98757fdc..150c916dca5e 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -251,14 +251,14 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
 
 		/* Disable all GPEs within this register */
 
-		status = acpi_hw_write(0x00, &this_register->enable_address);
+		status = acpi_hw_gpe_write(0x00, &this_register->enable_address);
 		if (ACPI_FAILURE(status)) {
 			goto error_exit;
 		}
 
 		/* Clear any pending GPE events within this register */
 
-		status = acpi_hw_write(0xFF, &this_register->status_address);
+		status = acpi_hw_gpe_write(0xFF, &this_register->status_address);
 		if (ACPI_FAILURE(status)) {
 			goto error_exit;
 		}
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 49c46d4dd070..6cc88524839d 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -24,6 +24,66 @@ static acpi_status
 acpi_hw_gpe_enable_write(u8 enable_mask,
 			 struct acpi_gpe_register_info *gpe_register_info);
 
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_gpe_read
+ *
+ * PARAMETERS:  value               - Where the value is returned
+ *              reg                 - GAS register structure
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Read from a GPE register in either memory or IO space.
+ *
+ * LIMITATIONS: <These limitations also apply to acpi_hw_gpe_write>
+ *      space_ID must be system_memory or system_IO.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_generic_address *reg)
+{
+	acpi_status status;
+	u32 value32;
+
+	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+		return acpi_os_read_memory((acpi_physical_address)reg->address,
+					    value, ACPI_GPE_REGISTER_WIDTH);
+	}
+
+	status = acpi_os_read_port((acpi_io_address)reg->address,
+				   &value32, ACPI_GPE_REGISTER_WIDTH);
+	if (ACPI_FAILURE(status))
+		return_ACPI_STATUS(status);
+
+	*value = (u64)value32;
+
+	return_ACPI_STATUS(AE_OK);
+}
+
+/******************************************************************************
+ *
+ * FUNCTION:    acpi_hw_gpe_write
+ *
+ * PARAMETERS:  value               - Value to be written
+ *              reg                 - GAS register structure
+ *
+ * RETURN:      Status
+ *
+ * DESCRIPTION: Write to a GPE register in either memory or IO space.
+ *
+ ******************************************************************************/
+
+acpi_status acpi_hw_gpe_write(u64 value, struct acpi_generic_address *reg)
+{
+	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+		return acpi_os_write_memory((acpi_physical_address)reg->address,
+					    value, ACPI_GPE_REGISTER_WIDTH);
+	}
+
+	return acpi_os_write_port((acpi_io_address)reg->address, (u32)value,
+				  ACPI_GPE_REGISTER_WIDTH);
+}
+
 /******************************************************************************
  *
  * FUNCTION:	acpi_hw_get_gpe_register_bit
@@ -79,7 +139,8 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
 
 	/* Get current value of the enable register that contains this GPE */
 
-	status = acpi_hw_read(&enable_mask, &gpe_register_info->enable_address);
+	status = acpi_hw_gpe_read(&enable_mask,
+				  &gpe_register_info->enable_address);
 	if (ACPI_FAILURE(status)) {
 		return (status);
 	}
@@ -118,9 +179,8 @@ acpi_hw_low_set_gpe(struct acpi_gpe_event_info *gpe_event_info, u32 action)
 
 		/* Write the updated enable mask */
 
-		status =
-		    acpi_hw_write(enable_mask,
-				  &gpe_register_info->enable_address);
+		status = acpi_hw_gpe_write(enable_mask,
+					   &gpe_register_info->enable_address);
 	}
 	return (status);
 }
@@ -158,8 +218,8 @@ acpi_status acpi_hw_clear_gpe(struct acpi_gpe_event_info *gpe_event_info)
 	 */
 	register_bit = acpi_hw_get_gpe_register_bit(gpe_event_info);
 
-	status =
-	    acpi_hw_write(register_bit, &gpe_register_info->status_address);
+	status = acpi_hw_gpe_write(register_bit,
+				   &gpe_register_info->status_address);
 	return (status);
 }
 
@@ -227,7 +287,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info,
 
 	/* GPE currently enabled (enable bit == 1)? */
 
-	status = acpi_hw_read(&in_byte, &gpe_register_info->enable_address);
+	status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->enable_address);
 	if (ACPI_FAILURE(status)) {
 		return (status);
 	}
@@ -238,7 +298,7 @@ acpi_hw_get_gpe_status(struct acpi_gpe_event_info *gpe_event_info,
 
 	/* GPE currently active (status bit == 1)? */
 
-	status = acpi_hw_read(&in_byte, &gpe_register_info->status_address);
+	status = acpi_hw_gpe_read(&in_byte, &gpe_register_info->status_address);
 	if (ACPI_FAILURE(status)) {
 		return (status);
 	}
@@ -274,7 +334,8 @@ acpi_hw_gpe_enable_write(u8 enable_mask,
 
 	gpe_register_info->enable_mask = enable_mask;
 
-	status = acpi_hw_write(enable_mask, &gpe_register_info->enable_address);
+	status = acpi_hw_gpe_write(enable_mask,
+				   &gpe_register_info->enable_address);
 	return (status);
 }
 
@@ -341,9 +402,8 @@ acpi_hw_clear_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
 
 		/* Clear status on all GPEs in this register */
 
-		status =
-		    acpi_hw_write(0xFF,
-				  &gpe_block->register_info[i].status_address);
+		status = acpi_hw_gpe_write(0xFF,
+					   &gpe_block->register_info[i].status_address);
 		if (ACPI_FAILURE(status)) {
 			return (status);
 		}
@@ -481,14 +541,14 @@ acpi_hw_get_gpe_block_status(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
 	for (i = 0; i < gpe_block->register_count; i++) {
 		gpe_register_info = &gpe_block->register_info[i];
 
-		status = acpi_hw_read(&in_enable,
-				      &gpe_register_info->enable_address);
+		status = acpi_hw_gpe_read(&in_enable,
+					  &gpe_register_info->enable_address);
 		if (ACPI_FAILURE(status)) {
 			continue;
 		}
 
-		status = acpi_hw_read(&in_status,
-				      &gpe_register_info->status_address);
+		status = acpi_hw_gpe_read(&in_status,
+					  &gpe_register_info->status_address);
 		if (ACPI_FAILURE(status)) {
 			continue;
 		}
-- 
2.26.2





^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 3/6] ACPICA: Introduce special struct type for GPE register addresses
  2020-09-04 17:19 [PATCH 0/6] ACPICA / ACPI: OSL: Rework GPE registers access code Rafael J. Wysocki
  2020-09-04 17:21 ` [PATCH 1/6] ACPICA: Validate GPE blocks at init time Rafael J. Wysocki
  2020-09-04 17:22 ` [PATCH 2/6] ACPICA: Introduce acpi_hw_gpe_read() and acpi_hw_gpe_write() Rafael J. Wysocki
@ 2020-09-04 17:23 ` Rafael J. Wysocki
  2020-09-04 17:24 ` [PATCH 4/6] ACPICA: Add support for using logical addresses of GPE blocks Rafael J. Wysocki
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 10+ messages in thread
From: Rafael J. Wysocki @ 2020-09-04 17:23 UTC (permalink / raw)
  To: Linux ACPI; +Cc: LKML, Erik Kaneda, Bob Moore

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

Notice that the bit_width, bit_offset and access_width fields in
struct acpi_generic_address are not used during GPE register
accesses any more, so introduce a simplified address structure
type, struct acpi_gpe_address, to represent addresses of GPE
registers and use it instead of struct acpi_generic_address in
struct acpi_gpe_register_info.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpica/achware.h  |  4 ++--
 drivers/acpi/acpica/aclocal.h  | 11 +++++++++--
 drivers/acpi/acpica/evgpeblk.c |  6 ------
 drivers/acpi/acpica/hwgpe.c    |  8 ++++----
 4 files changed, 15 insertions(+), 14 deletions(-)

diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h
index 4dba7229f9c1..6ab92e28330d 100644
--- a/drivers/acpi/acpica/achware.h
+++ b/drivers/acpi/acpica/achware.h
@@ -78,9 +78,9 @@ acpi_status acpi_hw_validate_io_block(u64 address, u32 bit_width, u32 count);
 /*
  * hwgpe - GPE support
  */
-acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_generic_address *reg);
+acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg);
 
-acpi_status acpi_hw_gpe_write(u64 value, struct acpi_generic_address *reg);
+acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg);
 
 u32 acpi_hw_get_gpe_register_bit(struct acpi_gpe_event_info *gpe_event_info);
 
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h
index af58cd2dc9d3..f83b98fa13ac 100644
--- a/drivers/acpi/acpica/aclocal.h
+++ b/drivers/acpi/acpica/aclocal.h
@@ -454,11 +454,18 @@ struct acpi_gpe_event_info {
 	u8 disable_for_dispatch;	/* Masked during dispatching */
 };
 
+/* GPE register address */
+
+struct acpi_gpe_address {
+	u8 space_id;	/* Address space where the register exists */
+	u64 address;	/* 64-bit address of the register */
+};
+
 /* Information about a GPE register pair, one per each status/enable pair in an array */
 
 struct acpi_gpe_register_info {
-	struct acpi_generic_address status_address;	/* Address of status reg */
-	struct acpi_generic_address enable_address;	/* Address of enable reg */
+	struct acpi_gpe_address status_address;	/* Address of status reg */
+	struct acpi_gpe_address enable_address;	/* Address of enable reg */
 	u16 base_gpe_number;	/* Base GPE number for this register */
 	u8 enable_for_wake;	/* GPEs to keep enabled when sleeping */
 	u8 enable_for_run;	/* GPEs to keep enabled when running */
diff --git a/drivers/acpi/acpica/evgpeblk.c b/drivers/acpi/acpica/evgpeblk.c
index 150c916dca5e..f5298be4273a 100644
--- a/drivers/acpi/acpica/evgpeblk.c
+++ b/drivers/acpi/acpica/evgpeblk.c
@@ -233,12 +233,6 @@ acpi_ev_create_gpe_info_blocks(struct acpi_gpe_block_info *gpe_block)
 
 		this_register->status_address.space_id = gpe_block->space_id;
 		this_register->enable_address.space_id = gpe_block->space_id;
-		this_register->status_address.bit_width =
-		    ACPI_GPE_REGISTER_WIDTH;
-		this_register->enable_address.bit_width =
-		    ACPI_GPE_REGISTER_WIDTH;
-		this_register->status_address.bit_offset = 0;
-		this_register->enable_address.bit_offset = 0;
 
 		/* Init the event_info for each GPE within this register */
 
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index 6cc88524839d..a0e71f34c77a 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -29,7 +29,7 @@ acpi_hw_gpe_enable_write(u8 enable_mask,
  * FUNCTION:    acpi_hw_gpe_read
  *
  * PARAMETERS:  value               - Where the value is returned
- *              reg                 - GAS register structure
+ *              reg                 - GPE register structure
  *
  * RETURN:      Status
  *
@@ -40,7 +40,7 @@ acpi_hw_gpe_enable_write(u8 enable_mask,
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_generic_address *reg)
+acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
 {
 	acpi_status status;
 	u32 value32;
@@ -65,7 +65,7 @@ acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_generic_address *reg)
  * FUNCTION:    acpi_hw_gpe_write
  *
  * PARAMETERS:  value               - Value to be written
- *              reg                 - GAS register structure
+ *              reg                 - GPE register structure
  *
  * RETURN:      Status
  *
@@ -73,7 +73,7 @@ acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_generic_address *reg)
  *
  ******************************************************************************/
 
-acpi_status acpi_hw_gpe_write(u64 value, struct acpi_generic_address *reg)
+acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg)
 {
 	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
 		return acpi_os_write_memory((acpi_physical_address)reg->address,
-- 
2.26.2






^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 4/6] ACPICA: Add support for using logical addresses of GPE blocks
  2020-09-04 17:19 [PATCH 0/6] ACPICA / ACPI: OSL: Rework GPE registers access code Rafael J. Wysocki
                   ` (2 preceding siblings ...)
  2020-09-04 17:23 ` [PATCH 3/6] ACPICA: Introduce special struct type for GPE register addresses Rafael J. Wysocki
@ 2020-09-04 17:24 ` Rafael J. Wysocki
  2020-10-16 14:30   ` Matthieu Baerts
  2020-09-04 17:24 ` [PATCH 5/6] ACPI: OSL: Change the type of acpi_os_map_generic_address() return value Rafael J. Wysocki
  2020-09-04 17:25 ` [PATCH 6/6] ACPI: OSL: Make ACPICA use logical addresses of GPE blocks Rafael J. Wysocki
  5 siblings, 1 reply; 10+ messages in thread
From: Rafael J. Wysocki @ 2020-09-04 17:24 UTC (permalink / raw)
  To: Linux ACPI; +Cc: LKML, Erik Kaneda, Bob Moore

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

The logical address of every GPE block in system memory must be
known before passing it to acpi_ev_initialize_gpe_block(), because
memory cannot be mapped on the fly from an interrupt handler.
Accordingly, the host OS must map every GPE block in system
memory upfront and it can store the logical addresses of GPE
blocks for future use.

If these logical addresses were known to ACPICA, it could use them
instead of the corresponding physical addresses of GPE block for
GPE register accesses and the memory mapping lookups carried out
by acpi_os_read_memory() and acpi_os_write_memory() on every
attempt to access a GPE register would not be necessary any more.

To allow that to happen, introduce the ACPI_GPE_USE_LOGICAL_ADDRESSES
symbol to indicate whether or not the host OS wants ACPICA to use the
logical addresses of GPE registers in system memory directly (which
is the case if this symbol is defined).  Moreover, conditional on
whether ACPI_GPE_USE_LOGICAL_ADDRESSES is defined, introduce two new
global variables for storing the logical addresses of the FADT GPE
blocks 0 and 1, respectively, acpi_gbl_xgpe0_block_logical_address and
acpi_gbl_xgpe1_block_logical_address, make acpi_ev_gpe_initialize()
pass their values instead of the physical addresses of the GPE blocks
in question to acpi_ev_create_gpe_block() and modify
acpi_hw_gpe_read() and acpi_hw_gpe_write() to access memory directly
via the addresses stored in the struct acpi_gpe_address objects,
which are expected to be the logical addresses of GPE registers if
ACPI_GPE_USE_LOGICAL_ADDRESSES is defined.

With the above changes in place, a host OS wanting ACPICA to
access GPE registers directly through their logical addresses
needs to define the ACPI_GPE_USE_LOGICAL_ADDRESSES symbol and
make sure that the logical addresses of the FADT GPE blocks 0
and 1 are stored in acpi_gbl_xgpe0_block_logical_address and
acpi_gbl_xgpe1_block_logical_address, respectively, prior to
calling acpi_ev_gpe_initialize().

[If such a host OS also uses acpi_install_gpe_block() to add
 non-FADT GPE register blocks located in system memory, it must
 pass their logical addresses instead of their physical addresses
 to this function.]

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/acpica/acglobal.h  |  6 ++++++
 drivers/acpi/acpica/evgpeinit.c | 23 +++++++++++++++++------
 drivers/acpi/acpica/hwgpe.c     | 10 ++++++++++
 3 files changed, 33 insertions(+), 6 deletions(-)

diff --git a/drivers/acpi/acpica/acglobal.h b/drivers/acpi/acpica/acglobal.h
index 1030a0ce1599..5215ff1cbbbe 100644
--- a/drivers/acpi/acpica/acglobal.h
+++ b/drivers/acpi/acpica/acglobal.h
@@ -42,6 +42,12 @@ ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1a_enable);
 ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1b_status);
 ACPI_GLOBAL(struct acpi_generic_address, acpi_gbl_xpm1b_enable);
 
+#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
+ACPI_GLOBAL(void *, acpi_gbl_xgpe0_block_logical_address);
+ACPI_GLOBAL(void *, acpi_gbl_xgpe1_block_logical_address);
+
+#endif				/* ACPI_GPE_USE_LOGICAL_ADDRESSES */
+
 /*
  * Handle both ACPI 1.0 and ACPI 2.0+ Integer widths. The integer width is
  * determined by the revision of the DSDT: If the DSDT revision is less than
diff --git a/drivers/acpi/acpica/evgpeinit.c b/drivers/acpi/acpica/evgpeinit.c
index 6effd8076dcc..6d82d30d8f7b 100644
--- a/drivers/acpi/acpica/evgpeinit.c
+++ b/drivers/acpi/acpica/evgpeinit.c
@@ -32,6 +32,16 @@ ACPI_MODULE_NAME("evgpeinit")
  * kernel boot time as well.
  */
 
+#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
+#define ACPI_FADT_GPE_BLOCK_ADDRESS(N)	\
+	acpi_gbl_FADT.xgpe##N##_block.space_id == \
+					ACPI_ADR_SPACE_SYSTEM_MEMORY ? \
+		(u64)acpi_gbl_xgpe##N##_block_logical_address : \
+		acpi_gbl_FADT.xgpe##N##_block.address
+#else
+#define ACPI_FADT_GPE_BLOCK_ADDRESS(N)	acpi_gbl_FADT.xgpe##N##_block.address
+#endif		/* ACPI_GPE_USE_LOGICAL_ADDRESSES */
+
 /*******************************************************************************
  *
  * FUNCTION:    acpi_ev_gpe_initialize
@@ -49,6 +59,7 @@ acpi_status acpi_ev_gpe_initialize(void)
 	u32 register_count1 = 0;
 	u32 gpe_number_max = 0;
 	acpi_status status;
+	u64 address;
 
 	ACPI_FUNCTION_TRACE(ev_gpe_initialize);
 
@@ -85,8 +96,9 @@ acpi_status acpi_ev_gpe_initialize(void)
 	 * If EITHER the register length OR the block address are zero, then that
 	 * particular block is not supported.
 	 */
-	if (acpi_gbl_FADT.gpe0_block_length &&
-	    acpi_gbl_FADT.xgpe0_block.address) {
+	address = ACPI_FADT_GPE_BLOCK_ADDRESS(0);
+
+	if (acpi_gbl_FADT.gpe0_block_length && address) {
 
 		/* GPE block 0 exists (has both length and address > 0) */
 
@@ -97,7 +109,6 @@ acpi_status acpi_ev_gpe_initialize(void)
 		/* Install GPE Block 0 */
 
 		status = acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
-						  acpi_gbl_FADT.xgpe0_block.
 						  address,
 						  acpi_gbl_FADT.xgpe0_block.
 						  space_id, register_count0, 0,
@@ -110,8 +121,9 @@ acpi_status acpi_ev_gpe_initialize(void)
 		}
 	}
 
-	if (acpi_gbl_FADT.gpe1_block_length &&
-	    acpi_gbl_FADT.xgpe1_block.address) {
+	address = ACPI_FADT_GPE_BLOCK_ADDRESS(1);
+
+	if (acpi_gbl_FADT.gpe1_block_length && address) {
 
 		/* GPE block 1 exists (has both length and address > 0) */
 
@@ -137,7 +149,6 @@ acpi_status acpi_ev_gpe_initialize(void)
 
 			status =
 			    acpi_ev_create_gpe_block(acpi_gbl_fadt_gpe_device,
-						     acpi_gbl_FADT.xgpe1_block.
 						     address,
 						     acpi_gbl_FADT.xgpe1_block.
 						     space_id, register_count1,
diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
index a0e71f34c77a..37bb67ef3232 100644
--- a/drivers/acpi/acpica/hwgpe.c
+++ b/drivers/acpi/acpica/hwgpe.c
@@ -46,8 +46,13 @@ acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
 	u32 value32;
 
 	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
+		*value = (u64)ACPI_GET8(reg->address);
+		return_ACPI_STATUS(AE_OK);
+#else
 		return acpi_os_read_memory((acpi_physical_address)reg->address,
 					    value, ACPI_GPE_REGISTER_WIDTH);
+#endif
 	}
 
 	status = acpi_os_read_port((acpi_io_address)reg->address,
@@ -76,8 +81,13 @@ acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
 acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg)
 {
 	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
+		ACPI_SET8(reg->address, value);
+		return_ACPI_STATUS(AE_OK);
+#else
 		return acpi_os_write_memory((acpi_physical_address)reg->address,
 					    value, ACPI_GPE_REGISTER_WIDTH);
+#endif
 	}
 
 	return acpi_os_write_port((acpi_io_address)reg->address, (u32)value,
-- 
2.26.2





^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 5/6] ACPI: OSL: Change the type of acpi_os_map_generic_address() return value
  2020-09-04 17:19 [PATCH 0/6] ACPICA / ACPI: OSL: Rework GPE registers access code Rafael J. Wysocki
                   ` (3 preceding siblings ...)
  2020-09-04 17:24 ` [PATCH 4/6] ACPICA: Add support for using logical addresses of GPE blocks Rafael J. Wysocki
@ 2020-09-04 17:24 ` Rafael J. Wysocki
  2020-09-04 17:25 ` [PATCH 6/6] ACPI: OSL: Make ACPICA use logical addresses of GPE blocks Rafael J. Wysocki
  5 siblings, 0 replies; 10+ messages in thread
From: Rafael J. Wysocki @ 2020-09-04 17:24 UTC (permalink / raw)
  To: Linux ACPI; +Cc: LKML, Erik Kaneda, Bob Moore

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

Modify acpi_os_map_generic_address() to return the pointer returned
by acpi_os_map_iomem() which represents the logical address
corresponding to the struct acpi_generic_address argument passed to
it or NULL if that address cannot be obtained (for example, the
argument does not represent an address in system memory or it could
not be mapped by the OS).

Among other things, that will allow the ACPI OS layer to pass the
logical addresses of the FADT GPE blocks 0 and 1 to ACPICA going
forward.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/apei/apei-base.c |  6 +++++-
 drivers/acpi/osl.c            | 18 +++++++-----------
 include/acpi/acpi_io.h        |  2 +-
 3 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index e358d0046494..552fd9ffaca4 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -632,7 +632,11 @@ int apei_map_generic_address(struct acpi_generic_address *reg)
 	rc = apei_check_gar(reg, &address, &access_bit_width);
 	if (rc)
 		return rc;
-	return acpi_os_map_generic_address(reg);
+
+	if (!acpi_os_map_generic_address(reg))
+		return -ENXIO;
+
+	return 0;
 }
 EXPORT_SYMBOL_GPL(apei_map_generic_address);
 
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 4a0b07792233..3a50d8fa310b 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -447,24 +447,19 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
-int acpi_os_map_generic_address(struct acpi_generic_address *gas)
+void __iomem *acpi_os_map_generic_address(struct acpi_generic_address *gas)
 {
 	u64 addr;
-	void __iomem *virt;
 
 	if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
-		return 0;
+		return NULL;
 
 	/* Handle possible alignment issues */
 	memcpy(&addr, &gas->address, sizeof(addr));
 	if (!addr || !gas->bit_width)
-		return -EINVAL;
-
-	virt = acpi_os_map_iomem(addr, gas->bit_width / 8);
-	if (!virt)
-		return -EIO;
+		return NULL;
 
-	return 0;
+	return acpi_os_map_iomem(addr, gas->bit_width / 8);
 }
 EXPORT_SYMBOL(acpi_os_map_generic_address);
 
@@ -1756,10 +1751,11 @@ acpi_status __init acpi_os_initialize(void)
 		 * Use acpi_os_map_generic_address to pre-map the reset
 		 * register if it's in system memory.
 		 */
-		int rv;
+		void *rv;
 
 		rv = acpi_os_map_generic_address(&acpi_gbl_FADT.reset_register);
-		pr_debug(PREFIX "%s: map reset_reg status %d\n", __func__, rv);
+		pr_debug(PREFIX "%s: map reset_reg %s\n", __func__,
+			 rv ? "successful" : "failed");
 	}
 	acpi_os_initialized = true;
 
diff --git a/include/acpi/acpi_io.h b/include/acpi/acpi_io.h
index 12d8bd333fe7..027faa8883aa 100644
--- a/include/acpi/acpi_io.h
+++ b/include/acpi/acpi_io.h
@@ -21,7 +21,7 @@ void __iomem __ref
 void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size);
 void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
 
-int acpi_os_map_generic_address(struct acpi_generic_address *addr);
+void __iomem *acpi_os_map_generic_address(struct acpi_generic_address *addr);
 void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
 
 #endif
-- 
2.26.2





^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH 6/6] ACPI: OSL: Make ACPICA use logical addresses of GPE blocks
  2020-09-04 17:19 [PATCH 0/6] ACPICA / ACPI: OSL: Rework GPE registers access code Rafael J. Wysocki
                   ` (4 preceding siblings ...)
  2020-09-04 17:24 ` [PATCH 5/6] ACPI: OSL: Change the type of acpi_os_map_generic_address() return value Rafael J. Wysocki
@ 2020-09-04 17:25 ` Rafael J. Wysocki
  5 siblings, 0 replies; 10+ messages in thread
From: Rafael J. Wysocki @ 2020-09-04 17:25 UTC (permalink / raw)
  To: Linux ACPI; +Cc: LKML, Erik Kaneda, Bob Moore

From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>

Define ACPI_GPE_USE_LOGICAL_ADDRESSES in aclinux.h and modify
acpi_os_initialize() to store the logical addresses of the FADT GPE
blocks 0 and 1 in acpi_gbl_xgpe0_block_logical_address and
acpi_gbl_xgpe1_block_logical_address, respectively, so as to allow
ACPICA to use them for accessing GPE registers in system memory,
instead of using their physical addresses and looking up the
corresponding logical addresses on every access attempt, which is
inefficient.

Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
---
 drivers/acpi/osl.c              | 12 ++++++++++--
 include/acpi/platform/aclinux.h |  4 ++++
 2 files changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 3a50d8fa310b..0002973fbcde 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -1744,8 +1744,12 @@ acpi_status __init acpi_os_initialize(void)
 {
 	acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
 	acpi_os_map_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
-	acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
-	acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
+
+	acpi_gbl_xgpe0_block_logical_address =
+		acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe0_block);
+	acpi_gbl_xgpe1_block_logical_address =
+		acpi_os_map_generic_address(&acpi_gbl_FADT.xgpe1_block);
+
 	if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) {
 		/*
 		 * Use acpi_os_map_generic_address to pre-map the reset
@@ -1783,8 +1787,12 @@ acpi_status acpi_os_terminate(void)
 
 	acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe1_block);
 	acpi_os_unmap_generic_address(&acpi_gbl_FADT.xgpe0_block);
+	acpi_gbl_xgpe0_block_logical_address = NULL;
+	acpi_gbl_xgpe1_block_logical_address = NULL;
+
 	acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1b_event_block);
 	acpi_os_unmap_generic_address(&acpi_gbl_FADT.xpm1a_event_block);
+
 	if (acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER)
 		acpi_os_unmap_generic_address(&acpi_gbl_FADT.reset_register);
 
diff --git a/include/acpi/platform/aclinux.h b/include/acpi/platform/aclinux.h
index 987e2af7c335..4151c76141fa 100644
--- a/include/acpi/platform/aclinux.h
+++ b/include/acpi/platform/aclinux.h
@@ -118,6 +118,10 @@
 
 #define USE_NATIVE_ALLOCATE_ZEROED
 
+/* Use logical addresses for accessing GPE registers in system memory */
+
+#define ACPI_GPE_USE_LOGICAL_ADDRESSES
+
 /*
  * Overrides for in-kernel ACPICA
  */
-- 
2.26.2





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/6] ACPICA: Add support for using logical addresses of GPE blocks
  2020-09-04 17:24 ` [PATCH 4/6] ACPICA: Add support for using logical addresses of GPE blocks Rafael J. Wysocki
@ 2020-10-16 14:30   ` Matthieu Baerts
  2020-10-16 17:15     ` Rafael J. Wysocki
  0 siblings, 1 reply; 10+ messages in thread
From: Matthieu Baerts @ 2020-10-16 14:30 UTC (permalink / raw)
  To: Rafael J. Wysocki, Linux ACPI; +Cc: LKML, Erik Kaneda, Bob Moore

Hi Rafael,

On 04/09/2020 19:24, Rafael J. Wysocki wrote:
> From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> 
> The logical address of every GPE block in system memory must be
> known before passing it to acpi_ev_initialize_gpe_block(), because
> memory cannot be mapped on the fly from an interrupt handler.
> Accordingly, the host OS must map every GPE block in system
> memory upfront and it can store the logical addresses of GPE
> blocks for future use.

(...)

> diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
> index a0e71f34c77a..37bb67ef3232 100644
> --- a/drivers/acpi/acpica/hwgpe.c
> +++ b/drivers/acpi/acpica/hwgpe.c
> @@ -46,8 +46,13 @@ acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
>   	u32 value32;
>   
>   	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
> +#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
> +		*value = (u64)ACPI_GET8(reg->address);

Thank you for the patch!

When compiling net-next repo, recently sync with Linus repo, I got an 
error when using i386 arch because of this line above.

Here are the commands I used:


================================================
$ make defconfig KBUILD_DEFCONFIG=i386_defconfig
*** Default configuration is based on 'i386_defconfig'
#
# configuration written to .config
#
$ scripts/config --disable DRM --disable PCCARD --disable ATA --disable 
MD --disable PPS --disable SOUND --disable USB --disable IOMMU_SUPPORT 
--disable INPUT_LEDS --disable AGP --disable VGA_ARB --disable EFI 
--disable WLAN --disable WIRELESS --disable LOGO --disable NFS_FS 
--disable XFRM_USER --disable INET6_AH --disable INET6_ESP --disable 
NETDEVICES -e KUNIT -d KUNIT_DEBUGFS -d KUNIT_TEST -d KUNIT_EXAMPLE_TEST 
-d EXT4_KUNIT_TESTS -d SYSCTL_KUNIT_TEST -d LIST_KUNIT_TEST -d 
LINEAR_RANGES_TEST -d BITS_TEST -d KUNIT_ALL_TESTS -e INET_DIAG -d 
INET_UDP_DIAG -d INET_RAW_DIAG -d INET_DIAG_DESTROY -e MPTCP -e 
MPTCP_IPV6 -e MPTCP_KUNIT_TESTS
$ KCFLAGS=-Werror make -j8 -l8
scripts/kconfig/conf  --syncconfig Kconfig
(...)
   CC      drivers/acpi/acpica/hwgpe.o
In file included from ./include/acpi/acpi.h:24,
                  from drivers/acpi/acpica/hwgpe.c:10:
drivers/acpi/acpica/hwgpe.c: In function 'acpi_hw_gpe_read':
./include/acpi/actypes.h:501:48: error: cast to pointer from integer of 
different size [-Werror=int-to-pointer-cast]
   501 | #define ACPI_CAST_PTR(t, p)             ((t *) (acpi_uintptr_t) 
(p))
       |                                                ^
drivers/acpi/acpica/acmacros.h:18:41: note: in expansion of macro 
'ACPI_CAST_PTR'
    18 | #define ACPI_CAST8(ptr)                 ACPI_CAST_PTR (u8, (ptr))
       |                                         ^~~~~~~~~~~~~
drivers/acpi/acpica/acmacros.h:22:43: note: in expansion of macro 
'ACPI_CAST8'
    22 | #define ACPI_GET8(ptr)                  (*ACPI_CAST8 (ptr))
       |                                           ^~~~~~~~~~
drivers/acpi/acpica/hwgpe.c:50:17: note: in expansion of macro 'ACPI_GET8'
    50 |   *value = (u64)ACPI_GET8(reg->address);
       |                 ^~~~~~~~~
drivers/acpi/acpica/hwgpe.c: In function 'acpi_hw_gpe_write':
./include/acpi/actypes.h:501:48: error: cast to pointer from integer of 
different size [-Werror=int-to-pointer-cast]
   501 | #define ACPI_CAST_PTR(t, p)             ((t *) (acpi_uintptr_t) 
(p))
       |                                                ^
drivers/acpi/acpica/acmacros.h:18:41: note: in expansion of macro 
'ACPI_CAST_PTR'
    18 | #define ACPI_CAST8(ptr)                 ACPI_CAST_PTR (u8, (ptr))
       |                                         ^~~~~~~~~~~~~
drivers/acpi/acpica/acmacros.h:26:43: note: in expansion of macro 
'ACPI_CAST8'
    26 | #define ACPI_SET8(ptr, val)             (*ACPI_CAST8 (ptr) = 
(u8) (val))
       |                                           ^~~~~~~~~~
drivers/acpi/acpica/hwgpe.c:85:3: note: in expansion of macro 'ACPI_SET8'
    85 |   ACPI_SET8(reg->address, value);
       |   ^~~~~~~~~
cc1: all warnings being treated as errors
make[3]: *** [scripts/Makefile.build:283: drivers/acpi/acpica/hwgpe.o] 
Error 1
make[2]: *** [scripts/Makefile.build:500: drivers/acpi/acpica] Error 2
make[1]: *** [scripts/Makefile.build:500: drivers/acpi] Error 2
make: *** [Makefile:1777: drivers] Error 2
================================================


> +		return_ACPI_STATUS(AE_OK);
> +#else
>   		return acpi_os_read_memory((acpi_physical_address)reg->address,
>   					    value, ACPI_GPE_REGISTER_WIDTH);
> +#endif
>   	}
>   
>   	status = acpi_os_read_port((acpi_io_address)reg->address,
> @@ -76,8 +81,13 @@ acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
>   acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg)
>   {
>   	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
> +#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
> +		ACPI_SET8(reg->address, value);

(and also because of this line)

By chance, do you already have a fix for that? I didn't see any other 
email related to this issue, I am surprised no bot already reported the 
problem but maybe I didn't look everywhere :)

Cheers,
Matt
-- 
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/6] ACPICA: Add support for using logical addresses of GPE blocks
  2020-10-16 14:30   ` Matthieu Baerts
@ 2020-10-16 17:15     ` Rafael J. Wysocki
  2020-10-16 18:12       ` Matthieu Baerts
  0 siblings, 1 reply; 10+ messages in thread
From: Rafael J. Wysocki @ 2020-10-16 17:15 UTC (permalink / raw)
  To: Matthieu Baerts; +Cc: Linux ACPI, LKML, Erik Kaneda, Bob Moore

On Friday, October 16, 2020 4:30:55 PM CEST Matthieu Baerts wrote:
> Hi Rafael,

Hi,

> On 04/09/2020 19:24, Rafael J. Wysocki wrote:
> > From: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com>
> > 
> > The logical address of every GPE block in system memory must be
> > known before passing it to acpi_ev_initialize_gpe_block(), because
> > memory cannot be mapped on the fly from an interrupt handler.
> > Accordingly, the host OS must map every GPE block in system
> > memory upfront and it can store the logical addresses of GPE
> > blocks for future use.
> 
> (...)
> 
> > diff --git a/drivers/acpi/acpica/hwgpe.c b/drivers/acpi/acpica/hwgpe.c
> > index a0e71f34c77a..37bb67ef3232 100644
> > --- a/drivers/acpi/acpica/hwgpe.c
> > +++ b/drivers/acpi/acpica/hwgpe.c
> > @@ -46,8 +46,13 @@ acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
> >   	u32 value32;
> >   
> >   	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
> > +#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
> > +		*value = (u64)ACPI_GET8(reg->address);
> 
> Thank you for the patch!
> 
> When compiling net-next repo, recently sync with Linus repo, I got an 
> error when using i386 arch because of this line above.
> 
> Here are the commands I used:
> 
> 
> ================================================
> $ make defconfig KBUILD_DEFCONFIG=i386_defconfig
> *** Default configuration is based on 'i386_defconfig'
> #
> # configuration written to .config
> #
> $ scripts/config --disable DRM --disable PCCARD --disable ATA --disable 
> MD --disable PPS --disable SOUND --disable USB --disable IOMMU_SUPPORT 
> --disable INPUT_LEDS --disable AGP --disable VGA_ARB --disable EFI 
> --disable WLAN --disable WIRELESS --disable LOGO --disable NFS_FS 
> --disable XFRM_USER --disable INET6_AH --disable INET6_ESP --disable 
> NETDEVICES -e KUNIT -d KUNIT_DEBUGFS -d KUNIT_TEST -d KUNIT_EXAMPLE_TEST 
> -d EXT4_KUNIT_TESTS -d SYSCTL_KUNIT_TEST -d LIST_KUNIT_TEST -d 
> LINEAR_RANGES_TEST -d BITS_TEST -d KUNIT_ALL_TESTS -e INET_DIAG -d 
> INET_UDP_DIAG -d INET_RAW_DIAG -d INET_DIAG_DESTROY -e MPTCP -e 
> MPTCP_IPV6 -e MPTCP_KUNIT_TESTS
> $ KCFLAGS=-Werror make -j8 -l8
> scripts/kconfig/conf  --syncconfig Kconfig
> (...)
>    CC      drivers/acpi/acpica/hwgpe.o
> In file included from ./include/acpi/acpi.h:24,
>                   from drivers/acpi/acpica/hwgpe.c:10:
> drivers/acpi/acpica/hwgpe.c: In function 'acpi_hw_gpe_read':
> ./include/acpi/actypes.h:501:48: error: cast to pointer from integer of 
> different size [-Werror=int-to-pointer-cast]
>    501 | #define ACPI_CAST_PTR(t, p)             ((t *) (acpi_uintptr_t) 
> (p))
>        |                                                ^
> drivers/acpi/acpica/acmacros.h:18:41: note: in expansion of macro 
> 'ACPI_CAST_PTR'
>     18 | #define ACPI_CAST8(ptr)                 ACPI_CAST_PTR (u8, (ptr))
>        |                                         ^~~~~~~~~~~~~
> drivers/acpi/acpica/acmacros.h:22:43: note: in expansion of macro 
> 'ACPI_CAST8'
>     22 | #define ACPI_GET8(ptr)                  (*ACPI_CAST8 (ptr))
>        |                                           ^~~~~~~~~~
> drivers/acpi/acpica/hwgpe.c:50:17: note: in expansion of macro 'ACPI_GET8'
>     50 |   *value = (u64)ACPI_GET8(reg->address);
>        |                 ^~~~~~~~~
> drivers/acpi/acpica/hwgpe.c: In function 'acpi_hw_gpe_write':
> ./include/acpi/actypes.h:501:48: error: cast to pointer from integer of 
> different size [-Werror=int-to-pointer-cast]
>    501 | #define ACPI_CAST_PTR(t, p)             ((t *) (acpi_uintptr_t) 
> (p))
>        |                                                ^
> drivers/acpi/acpica/acmacros.h:18:41: note: in expansion of macro 
> 'ACPI_CAST_PTR'
>     18 | #define ACPI_CAST8(ptr)                 ACPI_CAST_PTR (u8, (ptr))
>        |                                         ^~~~~~~~~~~~~
> drivers/acpi/acpica/acmacros.h:26:43: note: in expansion of macro 
> 'ACPI_CAST8'
>     26 | #define ACPI_SET8(ptr, val)             (*ACPI_CAST8 (ptr) = 
> (u8) (val))
>        |                                           ^~~~~~~~~~
> drivers/acpi/acpica/hwgpe.c:85:3: note: in expansion of macro 'ACPI_SET8'
>     85 |   ACPI_SET8(reg->address, value);
>        |   ^~~~~~~~~
> cc1: all warnings being treated as errors

This is what causes the build to terminate.

> make[3]: *** [scripts/Makefile.build:283: drivers/acpi/acpica/hwgpe.o] 
> Error 1
> make[2]: *** [scripts/Makefile.build:500: drivers/acpi/acpica] Error 2
> make[1]: *** [scripts/Makefile.build:500: drivers/acpi] Error 2
> make: *** [Makefile:1777: drivers] Error 2
> ================================================
> 
> 
> > +		return_ACPI_STATUS(AE_OK);
> > +#else
> >   		return acpi_os_read_memory((acpi_physical_address)reg->address,
> >   					    value, ACPI_GPE_REGISTER_WIDTH);
> > +#endif
> >   	}
> >   
> >   	status = acpi_os_read_port((acpi_io_address)reg->address,
> > @@ -76,8 +81,13 @@ acpi_status acpi_hw_gpe_read(u64 *value, struct acpi_gpe_address *reg)
> >   acpi_status acpi_hw_gpe_write(u64 value, struct acpi_gpe_address *reg)
> >   {
> >   	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
> > +#ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
> > +		ACPI_SET8(reg->address, value);
> 
> (and also because of this line)
> 
> By chance, do you already have a fix for that?

Can you please try the appended patch?

> I didn't see any other 
> email related to this issue, I am surprised no bot already reported the 
> problem but maybe I didn't look everywhere :)

No, they didn't AFAICS.

---
 drivers/acpi/acpica/hwgpe.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Index: linux-pm/drivers/acpi/acpica/hwgpe.c
===================================================================
--- linux-pm.orig/drivers/acpi/acpica/hwgpe.c
+++ linux-pm/drivers/acpi/acpica/hwgpe.c
@@ -47,7 +47,7 @@ acpi_status acpi_hw_gpe_read(u64 *value,
 
 	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
 #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
-		*value = (u64)ACPI_GET8(reg->address);
+		*value = (u64)ACPI_GET8((unsigned long)reg->address);
 		return_ACPI_STATUS(AE_OK);
 #else
 		return acpi_os_read_memory((acpi_physical_address)reg->address,
@@ -82,7 +82,7 @@ acpi_status acpi_hw_gpe_write(u64 value,
 {
 	if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
 #ifdef ACPI_GPE_USE_LOGICAL_ADDRESSES
-		ACPI_SET8(reg->address, value);
+		ACPI_SET8((unsigned long)reg->address, value);
 		return_ACPI_STATUS(AE_OK);
 #else
 		return acpi_os_write_memory((acpi_physical_address)reg->address,




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH 4/6] ACPICA: Add support for using logical addresses of GPE blocks
  2020-10-16 17:15     ` Rafael J. Wysocki
@ 2020-10-16 18:12       ` Matthieu Baerts
  0 siblings, 0 replies; 10+ messages in thread
From: Matthieu Baerts @ 2020-10-16 18:12 UTC (permalink / raw)
  To: Rafael J. Wysocki; +Cc: Linux ACPI, LKML, Erik Kaneda, Bob Moore

Hi Rafael,

On 16/10/2020 19:15, Rafael J. Wysocki wrote:
> On Friday, October 16, 2020 4:30:55 PM CEST Matthieu Baerts wrote:
>>
>> By chance, do you already have a fix for that?
> 
> Can you please try the appended patch?

Thank you for the patch, this fixes the compilation warning I got.

Reported-and-tested-by: Matthieu Baerts <matthieu.baerts@tessares.net>

Cheers,
Matt
-- 
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, back to index

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-04 17:19 [PATCH 0/6] ACPICA / ACPI: OSL: Rework GPE registers access code Rafael J. Wysocki
2020-09-04 17:21 ` [PATCH 1/6] ACPICA: Validate GPE blocks at init time Rafael J. Wysocki
2020-09-04 17:22 ` [PATCH 2/6] ACPICA: Introduce acpi_hw_gpe_read() and acpi_hw_gpe_write() Rafael J. Wysocki
2020-09-04 17:23 ` [PATCH 3/6] ACPICA: Introduce special struct type for GPE register addresses Rafael J. Wysocki
2020-09-04 17:24 ` [PATCH 4/6] ACPICA: Add support for using logical addresses of GPE blocks Rafael J. Wysocki
2020-10-16 14:30   ` Matthieu Baerts
2020-10-16 17:15     ` Rafael J. Wysocki
2020-10-16 18:12       ` Matthieu Baerts
2020-09-04 17:24 ` [PATCH 5/6] ACPI: OSL: Change the type of acpi_os_map_generic_address() return value Rafael J. Wysocki
2020-09-04 17:25 ` [PATCH 6/6] ACPI: OSL: Make ACPICA use logical addresses of GPE blocks Rafael J. Wysocki

Linux-ACPI Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-acpi/0 linux-acpi/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-acpi linux-acpi/ https://lore.kernel.org/linux-acpi \
		linux-acpi@vger.kernel.org
	public-inbox-index linux-acpi

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-acpi


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git