Skip to contentSkip to conversation

ACPICA: 20161117 Release

PATCH In review Lv Zheng 4 participants 40 messages Nov 30, 2016 – Dec 14, 2016

Subsystems (9)
lore
Share & tools
lore

Lv Zheng

author
#0 lore raw

cover ACPICA: 20161117 Release

The 20161117 ACPICA kernel-resident subsystem updates are linuxized based on the linux-pm/linux-next branch.

The patchset has passed the following build/boot tests. Build tests are performed as follows:
1. i386 + allyes
2. i386 + allno
3. i386 + default + ACPI_DEBUGGER=y
4. i386 + default + ACPI_DEBUGGER=n + ACPI_DEBUG=y
5. i386 + default + ACPI_DEBUG=n + ACPI=y
6. i386 + default + ACPI=n
7. x86_64 + allyes
8. x86_64 + allno
9. x86_64 + default + ACPI_DEBUGGER=y
10.x86_64 + default + ACPI_DEBUGGER=n + ACPI_DEBUG=y 11.x86_64 + default + ACPI_DEBUG=n + ACPI=y
12.x86_64 + default + ACPI=n
Boot tests are performed as follows:
1. i386 + default + ACPI_DEBUGGER=y
2. x86_64 + default + ACPI_DEBUGGER=y
Where:
1. i386: machine named as "Dell Inspiron Mini 1010"
2. x86_64: machine named as "Microsoft Surface Pro 3"
3. default: kernel configuration with following items enabled:
All hardware drivers related to the machines of i386/x86_64 All "drivers/acpi" configurations
All "drivers/platform" drivers
All other drivers that link the APIs provided by ACPICA subsystem

The divergences checking result:
Before applying (20160930 Release):
508 lines
After applying (20161117 Release):
467 lines

Bob Moore (3):
ACPICA: Fix for implicit result conversion for the ToXXXX functions
ACPICA: Utilities: Add new decode function for parser values
ACPICA: Update version to 20161117

Lv Zheng (8):
ACPICA: Namespace: Add acpi_ns_handle_to_name()
ACPICA: Back port of "ACPICA: Dispatcher: Tune interpreter lock
around AcpiEvInitializeRegion()"
ACPICA: Events: Fix acpi_ev_initialize_region() return value
ACPICA: Tables: Cleanup acpi_tb_install_and_load_table()
ACPICA: Tables: Add acpi_tb_unload_table()
ACPICA: Tables: Add an error message complaining driver bugs
ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel
ACPICA: Tables: Allow FADT to be customized with virtual address

 drivers/acpi/acpica/acevents.h    |    4 +-
 drivers/acpi/acpica/acnamesp.h    |    3 +
 drivers/acpi/acpica/acopcode.h    |   14 ++--
 drivers/acpi/acpica/actables.h    |   11 ++-
 drivers/acpi/acpica/acutils.h     |    2 +
 drivers/acpi/acpica/amlcode.h     |   21 +++++-
 drivers/acpi/acpica/dsinit.c      |    4 +-
 drivers/acpi/acpica/dsopcode.c    |    2 +-
 drivers/acpi/acpica/dswload2.c    |   13 +---
 drivers/acpi/acpica/evrgnini.c    |   59 ++++++---------
 drivers/acpi/acpica/exconfig.c    |   42 +----------
 drivers/acpi/acpica/exconvrt.c    |    1 -
 drivers/acpi/acpica/exresop.c     |    1 -
 drivers/acpi/acpica/nsnames.c     |   45 ++++++++++++
 drivers/acpi/acpica/nsxfname.c    |   43 +++--------
 drivers/acpi/acpica/tbdata.c      |   81 +++++++++++---------
 drivers/acpi/acpica/tbfadt.c      |   14 ++--
 drivers/acpi/acpica/tbutils.c     |   85 +++++++++++++++++++++
 drivers/acpi/acpica/tbxface.c     |  146 +++++++++++++++++++++++++------------
 drivers/acpi/acpica/tbxfload.c    |   38 +---------
 drivers/acpi/acpica/utdecode.c    |   49 +++++++++++++
 drivers/acpi/osl.c                |   31 +++++++-
 include/acpi/acpixf.h             |   14 +++-
 include/acpi/actbl.h              |    1 +
 include/acpi/platform/aclinuxex.h |    1 -
 25 files changed, 458 insertions(+), 267 deletions(-)
Signature · 1 line
1.7.10
author
#1 lore raw

PATCH 1/11 ACPICA: Namespace: Add acpi_ns_handle_to_name()

ACPICA commit f9fe27a68a90c9d32dd3156241a5e788fb6956ea

This patch adds acpi_ns_handle_to_name() so that in the acpi_get_name():
1. Logics can be made simpler,
2. Lock held for acpi_ns_handle_to_name() can also be applied to acpi_ns_handle_to_pathname().
The lock might be useless (see Link 1 below), but kept as acpi_get_name() is an external API. Except the lock correction, this patch is a functional no-op. BZ 1182, Lv Zheng.

---
 drivers/acpi/acpica/acnamesp.h |    3 +++
 drivers/acpi/acpica/nsnames.c  |   45 ++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/acpica/nsxfname.c |   43 ++++++++++----------------------------
 3 files changed, 59 insertions(+), 32 deletions(-)
drivers/acpi/acpica/acnamesp.h +3 -0
index bb7fca1..7affdcd 100644
@@ -292,6 +292,9 @@ char *acpi_ns_get_normalized_pathname(struct acpi_namespace_node *node,
 char *acpi_ns_name_of_current_scope(struct acpi_walk_state *walk_state);
 
 acpi_status
+acpi_ns_handle_to_name(acpi_handle target_handle, struct acpi_buffer *buffer);
+
+acpi_status
 acpi_ns_handle_to_pathname(acpi_handle target_handle,
 			   struct acpi_buffer *buffer, u8 no_trailing);
 
drivers/acpi/acpica/nsnames.c +45 -0

51 lines not on this page · raw message

drivers/acpi/acpica/nsxfname.c +11 -32

64 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#2 lore raw

PATCH 2/11 ACPICA: Back port of "ACPICA: Dispatcher: Tune interpreter lock around AcpiEvInitializeRegion()"

In reply to Lv Zheng

ACPICA commit bc481e758e54f7644fd0b657119ca7763d8b6a9c

This is a back port result of the following commit:
Commit: 8633db6b027952449e155a316f4ae3a530bbe18f
Subject: ACPICA: Dispatcher: Fix interpreter locking around acpi_ev_initialize_region()

---
 drivers/acpi/acpica/dsinit.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/acpica/dsinit.c +2 -2
index 54d48b9..5de3f10 100644
@@ -221,8 +221,8 @@
 	 */
 	status =
 	    acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-				   0, acpi_ds_init_one_object, NULL, &info,
-				   NULL);
+				   ACPI_NS_WALK_NO_UNLOCK,
+				   acpi_ds_init_one_object, NULL, &info, NULL);
 	if (ACPI_FAILURE(status)) {
 		ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
 	}
Signature · 1 line
1.7.10
#3 lore raw

Re: [PATCH 02/11] ACPICA: Back port of "ACPICA: Dispatcher: Tune interpreter lock around AcpiEvInitializeRegion()"

Quoted 19 lines · Lv Zheng

ACPICA commit bc481e758e54f7644fd0b657119ca7763d8b6a9c

This is a back port result of the following commit:
Commit: 8633db6b027952449e155a316f4ae3a530bbe18f
Subject: ACPICA: Dispatcher: Fix interpreter locking around acpi_ev_initialize_region()

---
 drivers/acpi/acpica/dsinit.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/acpica/dsinit.c +0 -0
index 54d48b9..5de3f10 100644
@@ -221,8 +221,8 @@
         */

drivers/acpi/acpica/dsinit.c

Quoted 10 lines
drivers/acpi/acpica/dsinit.c +2 -3
        status =
            acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-                                  0, acpi_ds_init_one_object, NULL, &info,
-                                  NULL);
+                                  ACPI_NS_WALK_NO_UNLOCK,
+                                  acpi_ds_init_one_object, NULL, &info, NULL);
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
        }
--

This isn't necessary IMO, the current code linux-next code looks like the change has been made in there already AFAICS (please double check, though).

I'm skipping this patch.

Thanks,
Rafael

author
#4 lore raw

RE: [PATCH 02/11] ACPICA: Back port of "ACPICA: Dispatcher: Tune interpreter lock around AcpiEvInitializeRegion()"

Hi, Rafael

Quoted 30 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Rafael J. Wysocki
Subject: Re: [PATCH 02/11] ACPICA: Back port of "ACPICA: Dispatcher: Tune interpreter lock around AcpiEvInitializeRegion()"

Quoted 25 lines · Lv Zheng

ACPICA commit bc481e758e54f7644fd0b657119ca7763d8b6a9c

This is a back port result of the following commit:
Commit: 8633db6b027952449e155a316f4ae3a530bbe18f
Subject: ACPICA: Dispatcher: Fix interpreter locking around acpi_ev_initialize_region()

---
 drivers/acpi/acpica/dsinit.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/acpica/dsinit.c +2 -2
index 54d48b9..5de3f10 100644
@@ -221,8 +221,8 @@
         */
        status =
            acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-                                  0, acpi_ds_init_one_object, NULL, &info,
-                                  NULL);
+                                  ACPI_NS_WALK_NO_UNLOCK,
+                                  acpi_ds_init_one_object, NULL, &info, NULL);
Quoted 8 lines

drivers/acpi/acpica/dsinit.c

Quoted 4 lines
drivers/acpi/acpica/dsinit.c +0 -1
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
        }
--

This isn't necessary IMO, the current code linux-next code looks like the change has been made in there already AFAICS (please double check, though).

The fix was in Linux, however, when it is back ported to ACPICA, Bob asked me to do this change. Using ACPI_NS_WALK_NO_UNLOCK instead of meaningless 0.
So during this release cycle, this change is detected out as the only difference of the back ported commit.

Quoted 2 lines

I'm skipping this patch.

If this is skipped, it leaves us 14 lines divergences. Hope we can have this kind of divergences eliminated.

Thanks and best regards
Lv

#5 lore raw

Re: [PATCH 02/11] ACPICA: Back port of "ACPICA: Dispatcher: Tune interpreter lock around AcpiEvInitializeRegion()"

Quoted 46 lines · Lv

Hi, Rafael

Quoted 30 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Rafael J. Wysocki
Subject: Re: [PATCH 02/11] ACPICA: Back port of "ACPICA: Dispatcher: Tune interpreter lock around AcpiEvInitializeRegion()"

Quoted 25 lines · Lv Zheng

ACPICA commit bc481e758e54f7644fd0b657119ca7763d8b6a9c

This is a back port result of the following commit:
Commit: 8633db6b027952449e155a316f4ae3a530bbe18f
Subject: ACPICA: Dispatcher: Fix interpreter locking around acpi_ev_initialize_region()

---
 drivers/acpi/acpica/dsinit.c |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/acpi/acpica/dsinit.c +2 -2
index 54d48b9..5de3f10 100644
@@ -221,8 +221,8 @@
         */
        status =
            acpi_ns_walk_namespace(ACPI_TYPE_ANY, start_node, ACPI_UINT32_MAX,
-                                  0, acpi_ds_init_one_object, NULL, &info,
-                                  NULL);
+                                  ACPI_NS_WALK_NO_UNLOCK,
+                                  acpi_ds_init_one_object, NULL, &info, NULL);
Quoted 8 lines

drivers/acpi/acpica/dsinit.c

Quoted 4 lines
drivers/acpi/acpica/dsinit.c +0 -1
        if (ACPI_FAILURE(status)) {
                ACPI_EXCEPTION((AE_INFO, status, "During WalkNamespace"));
        }
--

This isn't necessary IMO, the current code linux-next code looks like the change has been made in there already AFAICS (please double check, though).

The fix was in Linux, however, when it is back ported to ACPICA, Bob asked me to do this change. Using ACPI_NS_WALK_NO_UNLOCK instead of meaningless 0.
So during this release cycle, this change is detected out as the only difference of the back ported commit.

Quoted 1 line
Quoted 4 lines
Quoted 1 line

I'm skipping this patch.

If this is skipped, it leaves us 14 lines divergences. Hope we can have this kind of divergences eliminated.

OK, my bad.

I forgot to merge back the revert I made before into the acpica branch.

Sorry for the noise, everything applies now.

Thanks,
Rafael

author
#6 lore raw

PATCH 4/11 ACPICA: Events: Fix acpi_ev_initialize_region() return value

In reply to Lv Zheng

ACPICA commit 543342ab7a676f4eb0c9f100d349388a84dff0e8

This patch changes acpi_ev_initialize_region(), stop returning AE_NOT_EXIST from it so that, not only in acpi_ds_load2_end_op(), but all places invoking this function won't emit exceptions. The exception can be seen in acpi_ds_initialize_objects() when certain table loading mode is chosen.

This patch also removes useless acpi_ns_locked from acpi_ev_initialize_region() as this function will always be invoked with interpreter lock held now, and the lock granularity has been tuned to lock around _REG execution, thus it is now handled by acpi_ex_exit_interpreter(). Lv Zheng.

---
 drivers/acpi/acpica/acevents.h |    4 +--
 drivers/acpi/acpica/dsopcode.c |    2 +-
 drivers/acpi/acpica/dswload2.c |   13 +--------
 drivers/acpi/acpica/evrgnini.c |   59 ++++++++++++++++------------------------
 4 files changed, 27 insertions(+), 51 deletions(-)
drivers/acpi/acpica/acevents.h +1 -3
index 92fa47c..8a0049d 100644
@@ -243,9 +243,7 @@ union acpi_operand_object *acpi_ev_find_region_handler(acpi_adr_space_type
 			     u32 function,
 			     void *handler_context, void **region_context);
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-			  u8 acpi_ns_locked);
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj);
 
 /*
  * evsci - SCI (System Control Interrupt) handling/dispatch
drivers/acpi/acpica/dsopcode.c +1 -1
index 4cc9d98..77fd7c8 100644
@@ -84,7 +84,7 @@ acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
 
 	/* Namespace is NOT locked */
 
-	status = acpi_ev_initialize_region(obj_desc, FALSE);
+	status = acpi_ev_initialize_region(obj_desc);
 	return (status);
 }
 
drivers/acpi/acpica/dswload2.c +1 -12
index e362182..651f35a 100644
@@ -609,18 +609,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
 
 			status =
 			    acpi_ev_initialize_region
-			    (acpi_ns_get_attached_object(node), FALSE);
-
-			if (ACPI_FAILURE(status)) {
-				/*
-				 *  If AE_NOT_EXIST is returned, it is not fatal
-				 *  because many regions get created before a handler
-				 *  is installed for said region.
-				 */
-				if (AE_NOT_EXIST == status) {
-					status = AE_OK;
-				}
-			}
+			    (acpi_ns_get_attached_object(node));
 			break;
 
 		case AML_NAME_OP:
drivers/acpi/acpica/evrgnini.c +24 -35

101 lines not on this page · raw message

Signature · 1 line
1.7.10
#7 lore raw

Re: [PATCH 04/11] ACPICA: Events: Fix acpi_ev_initialize_region() return value

Quoted 61 lines · Lv Zheng

ACPICA commit 543342ab7a676f4eb0c9f100d349388a84dff0e8

This patch changes acpi_ev_initialize_region(), stop returning AE_NOT_EXIST from it so that, not only in acpi_ds_load2_end_op(), but all places invoking this function won't emit exceptions. The exception can be seen in acpi_ds_initialize_objects() when certain table loading mode is chosen.

This patch also removes useless acpi_ns_locked from acpi_ev_initialize_region() as this function will always be invoked with interpreter lock held now, and the lock granularity has been tuned to lock around _REG execution, thus it is now handled by acpi_ex_exit_interpreter(). Lv Zheng.

---
 drivers/acpi/acpica/acevents.h |    4 +--
 drivers/acpi/acpica/dsopcode.c |    2 +-
 drivers/acpi/acpica/dswload2.c |   13 +--------
 drivers/acpi/acpica/evrgnini.c |   59 ++++++++++++++++------------------------
 4 files changed, 27 insertions(+), 51 deletions(-)
drivers/acpi/acpica/acevents.h +1 -3
index 92fa47c..8a0049d 100644
@@ -243,9 +243,7 @@ union acpi_operand_object *acpi_ev_find_region_handler(acpi_adr_space_type
                             u32 function,
                             void *handler_context, void **region_context);
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-                         u8 acpi_ns_locked);
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj);
 
 /*
  * evsci - SCI (System Control Interrupt) handling/dispatch
drivers/acpi/acpica/dsopcode.c +1 -1
index 4cc9d98..77fd7c8 100644
@@ -84,7 +84,7 @@ acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
 
        /* Namespace is NOT locked */
 
-       status = acpi_ev_initialize_region(obj_desc, FALSE);
+       status = acpi_ev_initialize_region(obj_desc);
        return (status);
 }
 
drivers/acpi/acpica/dswload2.c +0 -3
index e362182..651f35a 100644
@@ -609,18 +609,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
 
                        status =
                            acpi_ev_initialize_region
-                           (acpi_ns_get_attached_object(node), FALSE);
-
-                       if (ACPI_FAILURE(status)) {

drivers/acpi/acpica/dswload2.c acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) · line 612

Quoted 10 lines
drivers/acpi/acpica/dswload2.c +1 -9
-                               /*
-                                *  If AE_NOT_EXIST is returned, it is not fatal
-                                *  because many regions get created before a handler
-                                *  is installed for said region.
-                                */
-                               if (AE_NOT_EXIST == status) {
-                                       status = AE_OK;
-                               }
-                       }
+                           (acpi_ns_get_attached_object(node));

This hunk doesn't apply for me.

We have acpi_ex_exit_interpreter() / acpi_ex_enter_interpreter() around the acpi_ev_initialize_region() in linux-next.

Quoted 70 lines
drivers/acpi/acpica/dswload2.c +0 -0
                        break;
 
                case AML_NAME_OP:
drivers/acpi/acpica/evrgnini.c +16 -16
index 75ddd16..a909225 100644
@@ -479,7 +479,6 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
  * FUNCTION:    acpi_ev_initialize_region
  *
  * PARAMETERS:  region_obj      - Region we are initializing
- *              acpi_ns_locked  - Is namespace locked?
  *
  * RETURN:      Status
  *
@@ -497,19 +496,28 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
  *              method for this region.
  *
+ * NOTE:        Possible incompliance:
+ *              There is a behavior conflict in automatic _REG execution:
+ *              1. When the interpreter is evaluating a method, we can only
+ *                 automatically run _REG for the following case:
+ *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
+ *              2. When the interpreter is loading a table, we can also
+ *                 automatically run _REG for the following case:
+ *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
+ *              Though this may not be compliant to the de-facto standard, the
+ *              logic is kept in order not to trigger regressions. And keeping
+ *              this logic should be taken care by the caller of this function.
+ *
  ******************************************************************************/
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-                         u8 acpi_ns_locked)
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
 {
        union acpi_operand_object *handler_obj;
        union acpi_operand_object *obj_desc;
        acpi_adr_space_type space_id;
        struct acpi_namespace_node *node;
-       acpi_status status;
 
-       ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
+       ACPI_FUNCTION_TRACE(ev_initialize_region);
 
        if (!region_obj) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -580,39 +588,17 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
                                                  handler_obj, region_obj,
                                                  obj_desc));
 
-                               status =
-                                   acpi_ev_attach_region(handler_obj,
-                                                         region_obj,
-                                                         acpi_ns_locked);
+                               (void)acpi_ev_attach_region(handler_obj,
+                                                           region_obj, FALSE);
 
                                /*
                                 * Tell all users that this region is usable by
                                 * running the _REG method
                                 */
-                               if (acpi_ns_locked) {
-                                       status =
-                                           acpi_ut_release_mutex
-                                           (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE(status)) {
-                                               return_ACPI_STATUS(status);

drivers/acpi/acpica/evrgnini.c static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) · line 601

Quoted 10 lines
drivers/acpi/acpica/evrgnini.c +2 -6
-                                       }
-                               }
-
                                acpi_ex_exit_interpreter();
-                               status =
-                                   acpi_ev_execute_reg_method(region_obj,
-                                                              ACPI_REG_CONNECT);
+                               (void)acpi_ev_execute_reg_method(region_obj,
+                                                                ACPI_REG_CONNECT);
                                acpi_ex_enter_interpreter();

And this also doesn't apply, because we don't invoke acpi_ex_exit_interpreter() / acpi_ex_enter_interpreter() around the acpi_ev_execute_reg_method() call in linux-next.

Quoted 23 lines
drivers/acpi/acpica/evrgnini.c +4 -12
-
-                               if (acpi_ns_locked) {
-                                       status =
-                                           acpi_ut_acquire_mutex
-                                           (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE(status)) {
-                                               return_ACPI_STATUS(status);
-                                       }
-                               }
-
                                return_ACPI_STATUS(AE_OK);
                        }
                }
@@ -622,12 +608,15 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
                node = node->parent;
        }
 
-       /* If we get here, there is no handler for this region */
-
+       /*
+        * If we get here, there is no handler for this region. This is not
+        * fatal because many regions get created before a handler is installed
+        * for said region.

drivers/acpi/acpica/evrgnini.c static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)

Quoted 10 lines
drivers/acpi/acpica/evrgnini.c +2 -2
+        */
        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
                          "No handler for RegionType %s(%X) (RegionObj %p)\n",
                          acpi_ut_get_region_name(space_id), space_id,
                          region_obj));
 
-       return_ACPI_STATUS(AE_NOT_EXIST);
+       return_ACPI_STATUS(AE_OK);
 }
--

Thanks,
Rafael

author
#8 lore raw

RE: [PATCH 04/11] ACPICA: Events: Fix acpi_ev_initialize_region() return value

Hi, Rafael

Quoted 79 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Rafael J. Wysocki
Subject: Re: [PATCH 04/11] ACPICA: Events: Fix acpi_ev_initialize_region() return value

Quoted 61 lines · Lv Zheng

ACPICA commit 543342ab7a676f4eb0c9f100d349388a84dff0e8

This patch changes acpi_ev_initialize_region(), stop returning AE_NOT_EXIST from it so that, not only in acpi_ds_load2_end_op(), but all places invoking this function won't emit exceptions. The exception can be seen in acpi_ds_initialize_objects() when certain table loading mode is chosen.

This patch also removes useless acpi_ns_locked from acpi_ev_initialize_region() as this function will always be invoked with interpreter lock held now, and the lock granularity has been tuned to lock around _REG execution, thus it is now handled by acpi_ex_exit_interpreter(). Lv Zheng.

---
 drivers/acpi/acpica/acevents.h |    4 +--
 drivers/acpi/acpica/dsopcode.c |    2 +-
 drivers/acpi/acpica/dswload2.c |   13 +--------
 drivers/acpi/acpica/evrgnini.c |   59 ++++++++++++++++------------------------
 4 files changed, 27 insertions(+), 51 deletions(-)
drivers/acpi/acpica/acevents.h +1 -3
index 92fa47c..8a0049d 100644
@@ -243,9 +243,7 @@ union acpi_operand_object *acpi_ev_find_region_handler(acpi_adr_space_type
                             u32 function,
                             void *handler_context, void **region_context);
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-                         u8 acpi_ns_locked);
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj);
 
 /*
  * evsci - SCI (System Control Interrupt) handling/dispatch
drivers/acpi/acpica/dsopcode.c +1 -1
index 4cc9d98..77fd7c8 100644
@@ -84,7 +84,7 @@ acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
 
        /* Namespace is NOT locked */
 
-       status = acpi_ev_initialize_region(obj_desc, FALSE);
+       status = acpi_ev_initialize_region(obj_desc);
        return (status);
 }
 
drivers/acpi/acpica/dswload2.c +0 -3
index e362182..651f35a 100644
@@ -609,18 +609,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
 
                        status =
                            acpi_ev_initialize_region
-                           (acpi_ns_get_attached_object(node), FALSE);
-
-                       if (ACPI_FAILURE(status)) {

drivers/acpi/acpica/dswload2.c acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) · line 612

Quoted 10 lines
drivers/acpi/acpica/dswload2.c +1 -9
-                               /*
-                                *  If AE_NOT_EXIST is returned, it is not fatal
-                                *  because many regions get created before a handler
-                                *  is installed for said region.
-                                */
-                               if (AE_NOT_EXIST == status) {
-                                       status = AE_OK;
-                               }
-                       }
+                           (acpi_ns_get_attached_object(node));

This hunk doesn't apply for me.

Quoted 2 lines

We have acpi_ex_exit_interpreter() / acpi_ex_enter_interpreter() around the acpi_ev_initialize_region() in linux-next.

This commit only changes returning value.
Lock changes are not included.

We never invokes acpi_ev_initialize_region with acpi_ns_locked=true. So all if (acpi_ns_locked) code pieces are useless and deleted in this commit.

Quoted 77 lines
Quoted 77 lines
drivers/acpi/acpica/dswload2.c +0 -0
                        break;
 
                case AML_NAME_OP:
drivers/acpi/acpica/evrgnini.c +16 -21
index 75ddd16..a909225 100644
@@ -479,7 +479,6 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
  * FUNCTION:    acpi_ev_initialize_region
  *
  * PARAMETERS:  region_obj      - Region we are initializing
- *              acpi_ns_locked  - Is namespace locked?
  *
  * RETURN:      Status
  *
@@ -497,19 +496,28 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
  *              method for this region.
  *
+ * NOTE:        Possible incompliance:
+ *              There is a behavior conflict in automatic _REG execution:
+ *              1. When the interpreter is evaluating a method, we can only
+ *                 automatically run _REG for the following case:
+ *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
+ *              2. When the interpreter is loading a table, we can also
+ *                 automatically run _REG for the following case:
+ *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
+ *              Though this may not be compliant to the de-facto standard, the
+ *              logic is kept in order not to trigger regressions. And keeping
+ *              this logic should be taken care by the caller of this function.
+ *
  ******************************************************************************/
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-                         u8 acpi_ns_locked)
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
 {
        union acpi_operand_object *handler_obj;
        union acpi_operand_object *obj_desc;
        acpi_adr_space_type space_id;
        struct acpi_namespace_node *node;
-       acpi_status status;
 
-       ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
+       ACPI_FUNCTION_TRACE(ev_initialize_region);
 
        if (!region_obj) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -580,39 +588,17 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
                                                  handler_obj, region_obj,
                                                  obj_desc));
 
-                               status =
-                                   acpi_ev_attach_region(handler_obj,
-                                                         region_obj,
-                                                         acpi_ns_locked);
+                               (void)acpi_ev_attach_region(handler_obj,
+                                                           region_obj, FALSE);
 
                                /*
                                 * Tell all users that this region is usable by
                                 * running the _REG method
                                 */
-                               if (acpi_ns_locked) {
-                                       status =
-                                           acpi_ut_release_mutex
-                                           (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE(status)) {
-                                               return_ACPI_STATUS(status);
-                                       }
-                               }
-
                                acpi_ex_exit_interpreter();
-                               status =
-                                   acpi_ev_execute_reg_method(region_obj,
Quoted 9 lines

drivers/acpi/acpica/evrgnini.c static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) · line 601

Quoted 4 lines
drivers/acpi/acpica/evrgnini.c +2 -1
-                                                              ACPI_REG_CONNECT);
+                               (void)acpi_ev_execute_reg_method(region_obj,
+                                                                ACPI_REG_CONNECT);
                                acpi_ex_enter_interpreter();

And this also doesn't apply, because we don't invoke acpi_ex_exit_interpreter() / acpi_ex_enter_interpreter() around the acpi_ev_execute_reg_method() call in linux-next.

acpi_ex_exit_interpreter() / acpi_ex_enter_interpreter() are not-modified-lines. Please check again.

Unlock before _REG is the minimum requirement as ACPICA will reacquire interpreter lock when _REG is evaluated. Before applying the following commit (which is in the upstream):
https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=8633db6b02
ACPICA unlocks the entire walk namespace process.

However this change did nothing to the locks.
Only changed the returning value of acpi_ev_initialize_region(). Always returning AE_OK instead of AE_NOT_EXIST.
Other than this, changes are no-ops.

Thanks and best regards
Lv

Quoted 41 lines
Quoted 24 lines
drivers/acpi/acpica/evrgnini.c +4 -12
-
-                               if (acpi_ns_locked) {
-                                       status =
-                                           acpi_ut_acquire_mutex
-                                           (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE(status)) {
-                                               return_ACPI_STATUS(status);
-                                       }
-                               }
-
                                return_ACPI_STATUS(AE_OK);
                        }
                }
@@ -622,12 +608,15 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
                node = node->parent;
        }
 
-       /* If we get here, there is no handler for this region */
-
+       /*
+        * If we get here, there is no handler for this region. This is not
+        * fatal because many regions get created before a handler is installed
+        * for said region.

drivers/acpi/acpica/evrgnini.c static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)

Quoted 10 lines
drivers/acpi/acpica/evrgnini.c +2 -2
+        */
        ACPI_DEBUG_PRINT((ACPI_DB_OPREGION,
                          "No handler for RegionType %s(%X) (RegionObj %p)\n",
                          acpi_ut_get_region_name(space_id), space_id,
                          region_obj));
 
-       return_ACPI_STATUS(AE_NOT_EXIST);
+       return_ACPI_STATUS(AE_OK);
 }
--

Thanks,
Rafael
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

#9 lore raw

Re: [PATCH 04/11] ACPICA: Events: Fix acpi_ev_initialize_region() return value

Quoted 177 lines · Lv

Hi, Rafael

Quoted 79 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Rafael J. Wysocki
Subject: Re: [PATCH 04/11] ACPICA: Events: Fix acpi_ev_initialize_region() return value

Quoted 61 lines · Lv Zheng

ACPICA commit 543342ab7a676f4eb0c9f100d349388a84dff0e8

This patch changes acpi_ev_initialize_region(), stop returning AE_NOT_EXIST from it so that, not only in acpi_ds_load2_end_op(), but all places invoking this function won't emit exceptions. The exception can be seen in acpi_ds_initialize_objects() when certain table loading mode is chosen.

This patch also removes useless acpi_ns_locked from acpi_ev_initialize_region() as this function will always be invoked with interpreter lock held now, and the lock granularity has been tuned to lock around _REG execution, thus it is now handled by acpi_ex_exit_interpreter(). Lv Zheng.

---
 drivers/acpi/acpica/acevents.h |    4 +--
 drivers/acpi/acpica/dsopcode.c |    2 +-
 drivers/acpi/acpica/dswload2.c |   13 +--------
 drivers/acpi/acpica/evrgnini.c |   59 ++++++++++++++++------------------------
 4 files changed, 27 insertions(+), 51 deletions(-)
drivers/acpi/acpica/acevents.h +1 -3
index 92fa47c..8a0049d 100644
@@ -243,9 +243,7 @@ union acpi_operand_object *acpi_ev_find_region_handler(acpi_adr_space_type
                             u32 function,
                             void *handler_context, void **region_context);
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-                         u8 acpi_ns_locked);
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj);
 
 /*
  * evsci - SCI (System Control Interrupt) handling/dispatch
drivers/acpi/acpica/dsopcode.c +1 -1
index 4cc9d98..77fd7c8 100644
@@ -84,7 +84,7 @@ acpi_status acpi_ds_initialize_region(acpi_handle obj_handle)
 
        /* Namespace is NOT locked */
 
-       status = acpi_ev_initialize_region(obj_desc, FALSE);
+       status = acpi_ev_initialize_region(obj_desc);
        return (status);
 }
 
drivers/acpi/acpica/dswload2.c +0 -3
index e362182..651f35a 100644
@@ -609,18 +609,7 @@ acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state)
 
                        status =
                            acpi_ev_initialize_region
-                           (acpi_ns_get_attached_object(node), FALSE);
-
-                       if (ACPI_FAILURE(status)) {

drivers/acpi/acpica/dswload2.c acpi_status acpi_ds_load2_end_op(struct acpi_walk_state *walk_state) · line 612

Quoted 10 lines
drivers/acpi/acpica/dswload2.c +1 -9
-                               /*
-                                *  If AE_NOT_EXIST is returned, it is not fatal
-                                *  because many regions get created before a handler
-                                *  is installed for said region.
-                                */
-                               if (AE_NOT_EXIST == status) {
-                                       status = AE_OK;
-                               }
-                       }
+                           (acpi_ns_get_attached_object(node));

This hunk doesn't apply for me.

Quoted 2 lines

We have acpi_ex_exit_interpreter() / acpi_ex_enter_interpreter() around the acpi_ev_initialize_region() in linux-next.

This commit only changes returning value.
Lock changes are not included.

We never invokes acpi_ev_initialize_region with acpi_ns_locked=true. So all if (acpi_ns_locked) code pieces are useless and deleted in this commit.

Quoted 77 lines
Quoted 77 lines
drivers/acpi/acpica/dswload2.c +0 -0
                        break;
 
                case AML_NAME_OP:
drivers/acpi/acpica/evrgnini.c +16 -21
index 75ddd16..a909225 100644
@@ -479,7 +479,6 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
  * FUNCTION:    acpi_ev_initialize_region
  *
  * PARAMETERS:  region_obj      - Region we are initializing
- *              acpi_ns_locked  - Is namespace locked?
  *
  * RETURN:      Status
  *
@@ -497,19 +496,28 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
  * MUTEX:       Interpreter should be unlocked, because we may run the _REG
  *              method for this region.
  *
+ * NOTE:        Possible incompliance:
+ *              There is a behavior conflict in automatic _REG execution:
+ *              1. When the interpreter is evaluating a method, we can only
+ *                 automatically run _REG for the following case:
+ *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
+ *              2. When the interpreter is loading a table, we can also
+ *                 automatically run _REG for the following case:
+ *                   operation_region (OPR1, 0x80, 0x1000010, 0x4)
+ *              Though this may not be compliant to the de-facto standard, the
+ *              logic is kept in order not to trigger regressions. And keeping
+ *              this logic should be taken care by the caller of this function.
+ *
  ******************************************************************************/
 
-acpi_status
-acpi_ev_initialize_region(union acpi_operand_object *region_obj,
-                         u8 acpi_ns_locked)
+acpi_status acpi_ev_initialize_region(union acpi_operand_object *region_obj)
 {
        union acpi_operand_object *handler_obj;
        union acpi_operand_object *obj_desc;
        acpi_adr_space_type space_id;
        struct acpi_namespace_node *node;
-       acpi_status status;
 
-       ACPI_FUNCTION_TRACE_U32(ev_initialize_region, acpi_ns_locked);
+       ACPI_FUNCTION_TRACE(ev_initialize_region);
 
        if (!region_obj) {
                return_ACPI_STATUS(AE_BAD_PARAMETER);
@@ -580,39 +588,17 @@ static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node)
                                                  handler_obj, region_obj,
                                                  obj_desc));
 
-                               status =
-                                   acpi_ev_attach_region(handler_obj,
-                                                         region_obj,
-                                                         acpi_ns_locked);
+                               (void)acpi_ev_attach_region(handler_obj,
+                                                           region_obj, FALSE);
 
                                /*
                                 * Tell all users that this region is usable by
                                 * running the _REG method
                                 */
-                               if (acpi_ns_locked) {
-                                       status =
-                                           acpi_ut_release_mutex
-                                           (ACPI_MTX_NAMESPACE);
-                                       if (ACPI_FAILURE(status)) {
-                                               return_ACPI_STATUS(status);
-                                       }
-                               }
-
                                acpi_ex_exit_interpreter();
-                               status =
-                                   acpi_ev_execute_reg_method(region_obj,
Quoted 9 lines

drivers/acpi/acpica/evrgnini.c static u8 acpi_ev_is_pci_root_bridge(struct acpi_namespace_node *node) · line 601

Quoted 4 lines
drivers/acpi/acpica/evrgnini.c +2 -1
-                                                              ACPI_REG_CONNECT);
+                               (void)acpi_ev_execute_reg_method(region_obj,
+                                                                ACPI_REG_CONNECT);
                                acpi_ex_enter_interpreter();

And this also doesn't apply, because we don't invoke acpi_ex_exit_interpreter() / acpi_ex_enter_interpreter() around the acpi_ev_execute_reg_method() call in linux-next.

Quoted 2 lines

acpi_ex_exit_interpreter() / acpi_ex_enter_interpreter() are not-modified-lines. Please check again.

As I said in the previous message, this was a result of my mistake.

Fixed now and everything applies as it should.

Thanks,
Rafael

author
#10 lore raw

PATCH 5/11 ACPICA: Tables: Cleanup acpi_tb_install_and_load_table()

In reply to Lv Zheng

ACPICA commit 7fdac0289faa1c28b91413c8e394e87372aa69e6

acpi_tb_install_and_load_table() can invoke acpi_tb_load_table() to eliminate redundant code.

No functional change. Lv Zheng.

---
 drivers/acpi/acpica/actables.h |    3 +--
 drivers/acpi/acpica/exconfig.c |    7 +++----
 drivers/acpi/acpica/tbdata.c   |   45 +++++-----------------------------------
 drivers/acpi/acpica/tbxfload.c |    7 +++----
 4 files changed, 12 insertions(+), 50 deletions(-)
drivers/acpi/acpica/actables.h +1 -2
index e85953b..1850005 100644
@@ -127,8 +127,7 @@
 acpi_tb_load_table(u32 table_index, struct acpi_namespace_node *parent_node);
 
 acpi_status
-acpi_tb_install_and_load_table(struct acpi_table_header *table,
-			       acpi_physical_address address,
+acpi_tb_install_and_load_table(acpi_physical_address address,
 			       u8 flags, u8 override, u32 *table_index);
 
 void acpi_tb_terminate(void);
drivers/acpi/acpica/exconfig.c +3 -4
index 718428b..8b8d620 100644
@@ -437,10 +437,9 @@
 
 	ACPI_INFO(("Dynamic OEM Table Load:"));
 	acpi_ex_exit_interpreter();
-	status =
-	    acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table),
-					   ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
-					   TRUE, &table_index);
+	status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
+						ACPI_TABLE_ORIGIN_INTERNAL_VIRTUAL,
+						TRUE, &table_index);
 	acpi_ex_enter_interpreter();
 	if (ACPI_FAILURE(status)) {
 
drivers/acpi/acpica/tbdata.c +5 -40

70 lines not on this page · raw message

drivers/acpi/acpica/tbxfload.c +3 -4
index 2599e831..77de33b 100644
@@ -330,10 +330,9 @@ acpi_status acpi_load_table(struct acpi_table_header *table)
 	/* Install the table and load it into the namespace */
 
 	ACPI_INFO(("Host-directed Dynamic ACPI Table Load:"));
-	status =
-	    acpi_tb_install_and_load_table(table, ACPI_PTR_TO_PHYSADDR(table),
-					   ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
-					   FALSE, &table_index);
+	status = acpi_tb_install_and_load_table(ACPI_PTR_TO_PHYSADDR(table),
+						ACPI_TABLE_ORIGIN_EXTERNAL_VIRTUAL,
+						FALSE, &table_index);
 	return_ACPI_STATUS(status);
 }
 
Signature · 1 line
1.7.10
author
#11 lore raw

PATCH 6/11 ACPICA: Tables: Add acpi_tb_unload_table()

In reply to Lv Zheng

ACPICA commit 80e24663b212daac0c32767fdbd8a46892292f1f

This patch introduces acpi_tb_unload_table() to eliminate redundant code from acpi_ex_unload_table() and acpi_unload_parent_table().

No functional change. Lv Zheng.

---
 drivers/acpi/acpica/actables.h |    2 ++
 drivers/acpi/acpica/exconfig.c |   35 +----------------------------
 drivers/acpi/acpica/tbdata.c   |   48 ++++++++++++++++++++++++++++++++++++++++
 drivers/acpi/acpica/tbxfload.c |   31 +-------------------------
 4 files changed, 52 insertions(+), 64 deletions(-)
drivers/acpi/acpica/actables.h +2 -0
index 1850005..7dd527f 100644
@@ -130,6 +130,8 @@
 acpi_tb_install_and_load_table(acpi_physical_address address,
 			       u8 flags, u8 override, u32 *table_index);
 
+acpi_status acpi_tb_unload_table(u32 table_index);
+
 void acpi_tb_terminate(void);
 
 acpi_status acpi_tb_delete_namespace_by_owner(u32 table_index);
drivers/acpi/acpica/exconfig.c +1 -34
index 8b8d620..c32c782 100644
@@ -499,7 +499,6 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 	acpi_status status = AE_OK;
 	union acpi_operand_object *table_desc = ddb_handle;
 	u32 table_index;
-	struct acpi_table_header *table;
 
 	ACPI_FUNCTION_TRACE(ex_unload_table);
 
@@ -536,39 +535,7 @@ acpi_status acpi_ex_unload_table(union acpi_operand_object *ddb_handle)
 	 * strict order requirement against it.
 	 */
 	acpi_ex_exit_interpreter();
-
-	/* Ensure the table is still loaded */
-
-	if (!acpi_tb_is_table_loaded(table_index)) {
-		status = AE_NOT_EXIST;
-		goto lock_and_exit;
-	}
-
-	/* Invoke table handler if present */
-
-	if (acpi_gbl_table_handler) {
-		status = acpi_get_table_by_index(table_index, &table);
-		if (ACPI_SUCCESS(status)) {
-			(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
-						     table,
-						     acpi_gbl_table_handler_context);
-		}
-	}
-
-	/* Delete the portion of the namespace owned by this table */
-
-	status = acpi_tb_delete_namespace_by_owner(table_index);
-	if (ACPI_FAILURE(status)) {
-		goto lock_and_exit;
-	}
-
-	(void)acpi_tb_release_owner_id(table_index);
-	acpi_tb_set_table_loaded_flag(table_index, FALSE);
-
-lock_and_exit:
-
-	/* Re-acquire the interpreter lock */
-
+	status = acpi_tb_unload_table(table_index);
 	acpi_ex_enter_interpreter();
 
 	/*
drivers/acpi/acpica/tbdata.c +48 -0

51 lines not on this page · raw message

drivers/acpi/acpica/tbxfload.c +1 -30
index 77de33b..82019c0 100644
@@ -408,37 +408,8 @@ acpi_status acpi_unload_parent_table(acpi_handle object)
 			break;
 		}
 
-		/* Ensure the table is actually loaded */
-
 		(void)acpi_ut_release_mutex(ACPI_MTX_TABLES);
-		if (!acpi_tb_is_table_loaded(i)) {
-			status = AE_NOT_EXIST;
-			(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
-			break;
-		}
-
-		/* Invoke table handler if present */
-
-		if (acpi_gbl_table_handler) {
-			(void)acpi_gbl_table_handler(ACPI_TABLE_EVENT_UNLOAD,
-						     acpi_gbl_root_table_list.
-						     tables[i].pointer,
-						     acpi_gbl_table_handler_context);
-		}
-
-		/*
-		 * Delete all namespace objects owned by this table. Note that
-		 * these objects can appear anywhere in the namespace by virtue
-		 * of the AML "Scope" operator. Thus, we need to track ownership
-		 * by an ID, not simply a position within the hierarchy.
-		 */
-		status = acpi_tb_delete_namespace_by_owner(i);
-		if (ACPI_FAILURE(status)) {
-			break;
-		}
-
-		status = acpi_tb_release_owner_id(i);
-		acpi_tb_set_table_loaded_flag(i, FALSE);
+		status = acpi_tb_unload_table(i);
 		(void)acpi_ut_acquire_mutex(ACPI_MTX_TABLES);
 		break;
 	}
Signature · 1 line
1.7.10
author
#12 lore raw

PATCH 7/11 ACPICA: Tables: Add an error message complaining driver bugs

In reply to Lv Zheng

ACPICA commit 68af3c3aa238dd8040e846ac6b4827a016434d8d

During early OS boot stage, drivers that have mapped system memory should unmap it during the same stage. Linux kernel has an error message indicating the unbalanced early memory mappings.

This patch back ports such error message into ACPICA for the early table mappings, so that ACPICA development environment is also aware of this OS specific requirement and thus is able to ensure the consistent quality locally. Lv Zheng.

---
 drivers/acpi/acpica/tbxface.c |   16 ++++++++++++++++
 1 file changed, 16 insertions(+)
drivers/acpi/acpica/tbxface.c +16 -0
index 4ab6b9c..d5adb7a 100644
@@ -167,6 +167,7 @@ acpi_status acpi_allocate_root_table(u32 initial_table_count)
 acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 {
 	acpi_status status;
+	u32 i;
 
 	ACPI_FUNCTION_TRACE(acpi_reallocate_root_table);
 
@@ -178,6 +179,21 @@ acpi_status ACPI_INIT_FUNCTION acpi_reallocate_root_table(void)
 		return_ACPI_STATUS(AE_SUPPORT);
 	}
 
+	/*
+	 * Ensure OS early boot logic, which is required by some hosts. If the
+	 * table state is reported to be wrong, developers should fix the
+	 * issue by invoking acpi_put_table() for the reported table during the
+	 * early stage.
+	 */
+	for (i = 0; i < acpi_gbl_root_table_list.current_table_count; ++i) {
+		if (acpi_gbl_root_table_list.tables[i].pointer) {
+			ACPI_ERROR((AE_INFO,
+				    "Table [%4.4s] is not invalidated during early boot stage",
+				    acpi_gbl_root_table_list.tables[i].
+				    signature.ascii));
+		}
+	}
+
 	acpi_gbl_root_table_list.flags |= ACPI_ROOT_ALLOW_RESIZE;
 
 	status = acpi_tb_resize_root_table_list();
Signature · 1 line
1.7.10
author
#13 lore raw

PATCH 8/11 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

In reply to Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

---
 drivers/acpi/acpica/actables.h    |    6 ++
 drivers/acpi/acpica/tbutils.c     |   85 ++++++++++++++++++++++++
 drivers/acpi/acpica/tbxface.c     |  130 +++++++++++++++++++++++--------------
 drivers/acpi/osl.c                |   31 ++++++++-
 include/acpi/acpixf.h             |   12 +++-
 include/acpi/actbl.h              |    1 +
 include/acpi/platform/aclinuxex.h |    1 -
 7 files changed, 212 insertions(+), 54 deletions(-)
drivers/acpi/acpica/actables.h +6 -0
index 7dd527f..94be8a8 100644
@@ -166,6 +166,12 @@
 
 acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
 
+acpi_status
+acpi_tb_get_table(struct acpi_table_desc *table_desc,
+		  struct acpi_table_header **out_table);
+
+void acpi_tb_put_table(struct acpi_table_desc *table_desc);
+
 /*
  * tbxfload
  */
drivers/acpi/acpica/tbutils.c +85 -0

88 lines not on this page · raw message

drivers/acpi/acpica/tbxface.c +82 -48

203 lines not on this page · raw message

drivers/acpi/osl.c +29 -2
index 416953a..4d8f2cd 100644
@@ -433,10 +433,37 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
+/*******************************************************************************
+ *
+ * acpi_get_table_with_size()/early_acpi_os_unmap_memory():
+ *
+ * These 2 functions are traditionally used by Linux to map/unmap physical
+ * addressed ACPI tables during the early stage.
+ * They are deprectated now. Do not use them in the new code, but use
+ * acpi_get_table()/acpi_put_table() instead.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_get_table_with_size(char *signature,
+	       u32 instance, struct acpi_table_header **out_table,
+	       acpi_size *tbl_size)
+{
+	acpi_status status;
+
+	status = acpi_get_table(signature, instance, out_table);
+	if (ACPI_SUCCESS(status)) {
+		/* No longer used by early_acpi_os_unmap_memory() */
+		*tbl_size = 0;
+	}
+
+	return (status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
+
 void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
 {
-	if (!acpi_gbl_permanent_mmap)
-		__acpi_unmap_table(virt, size);
+	acpi_put_table(ACPI_CAST_PTR(struct acpi_table_header, virt));
 }
 
 int acpi_os_map_generic_address(struct acpi_generic_address *gas)
include/acpi/acpixf.h +9 -3
index 5c7356a..33828dd 100644
@@ -513,10 +513,12 @@
 			     acpi_get_table(acpi_string signature, u32 instance,
 					    struct acpi_table_header
 					    **out_table))
+ACPI_EXTERNAL_RETURN_VOID(void acpi_put_table(struct acpi_table_header *table))
+
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			     acpi_get_table_by_index(u32 table_index,
-						     struct acpi_table_header
-						     **out_table))
+			    acpi_get_table_by_index(u32 table_index,
+						    struct acpi_table_header
+						    **out_table))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_install_table_handler(acpi_table_handler
 							handler, void *context))
@@ -974,6 +976,10 @@
 						     **out_table,
 						     acpi_size *tbl_size))
 
+ACPI_EXTERNAL_RETURN_VOID(void
+			  early_acpi_os_unmap_memory(void __iomem * virt,
+						     acpi_size size))
+
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			    acpi_get_data_full(acpi_handle object,
 					       acpi_object_handler handler,
include/acpi/actbl.h +1 -0
index c19700e..da5708c 100644
@@ -371,6 +371,7 @@ struct acpi_table_desc {
 	union acpi_name_union signature;
 	acpi_owner_id owner_id;
 	u8 flags;
+	u16 validation_count;
 };
 
 /* Masks for Flags field above */
include/acpi/platform/aclinuxex.h +0 -1
index a5509d8..7dbb114 100644
@@ -142,7 +142,6 @@ static inline void acpi_os_terminate_command_signals(void)
 /*
  * OSL interfaces added by Linux
  */
-void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size);
 
 #endif				/* __KERNEL__ */
 
Signature · 1 line
1.7.10
#14 lore raw

Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

qemu=$HOME/git/qemu/build/x86_64-softmmu/qemu-system-x86_64 mem=$HOME/mem
label_size=$((128*1024)) mem_size=$(((3*1024*1024*1024) + (64 * 1024 *1024))) IMAGE=$HOME/ahci.img

kvm=(

        $qemu
        -enable-kvm
        -cpu kvm64
        -kernel $kernel
        -initrd $initrd
        -m 12G,slots=3,maxmem=40G

        -machine pc-i440fx-2.4,accel=kvm,usb=off,vmport=off,nvdimm
        -cpu SandyBridge
        -smp 2
        -netdev tap,id=hostnet0,ifname=tap0,script=no,downscript=no
        -device

virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:b7:a1:ad,bus=pci.0,addr=0x7
-object
memory-backend-file,id=mem1,share,mem-path=${mem},size=$((label_size + mem_size))

        -device nvdimm,memdev=mem1,id=nv1,label-size=${label_size}
        -device ahci,id=sata0,bus=pci.0,addr=0x8
        -drive file=$IMAGE,if=none,id=drive-sata0-0-0,format=raw
        -device ide-hd,bus=sata0.0,drive=drive-sata0-0-0,id=sata0-0-0
        -boot order=nc
        -no-reboot
        -watchdog i6300esb
        -rtc base=localtime
        -serial stdio
        -display none
        -monitor null

)
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

#15 lore raw

Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 53 lines · Dan Williams
Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines
Quoted 8 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

Would the build problems go away if you reverted "ACPICA: Tables:
Allow FADT to be customized with virtual address" (linux-next commit cf334d3174f9) in addition to it?

Thanks,
Rafael
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

#16 lore raw

Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 59 lines · Rafael J. Wysocki
Quoted 58 lines · Dan Williams
Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

Quoted 7 lines
Quoted 3 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

Would the build problems go away if you reverted "ACPICA: Tables:
Allow FADT to be customized with virtual address" (linux-next commit cf334d3174f9) in addition to it?

Yes, reverting those two commits gets me back to a functional environment:

Revert "ACPICA: Tables: Allow FADT to be customized with virtual address" Revert "ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_un

author
#17 lore raw

RE: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Hi, Rafael and Dan

Quoted 72 lines

From: Dan Williams [mailto:[email protected]]
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 59 lines · Rafael J. Wysocki
Quoted 58 lines · Dan Williams
Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

Quoted 7 lines
Quoted 3 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

Would the build problems go away if you reverted "ACPICA: Tables:
Allow FADT to be customized with virtual address" (linux-next commit cf334d3174f9) in addition to it?

Quoted 5 lines

Yes, reverting those two commits gets me back to a functional environment:

Revert "ACPICA: Tables: Allow FADT to be customized with virtual address" Revert "ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_un

To Dan:
It seems in drivers/acpi/nfit/core.c.
The returned table size is used by the NFIT code. I think it should be changed to use table_header->length.

To Rafael:
I can offer a quick fix for this by returning table_header->length from acpi_get_table_with_size().

Thanks and best regards
Lv
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

#18 lore raw

Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 76 lines · Lv

Hi, Rafael and Dan

Quoted 74 lines

From: Dan Williams [mailto:[email protected]]
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 59 lines · Rafael J. Wysocki
Quoted 58 lines · Dan Williams
Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

Quoted 7 lines
Quoted 3 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

Would the build problems go away if you reverted "ACPICA: Tables:
Allow FADT to be customized with virtual address" (linux-next commit cf334d3174f9) in addition to it?

Yes, reverting those two commits gets me back to a functional environment:

Quoted 8 lines
Quoted 3 lines

Revert "ACPICA: Tables: Allow FADT to be customized with virtual address" Revert "ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_un

To Dan:
It seems in drivers/acpi/nfit/core.c.
The returned table size is used by the NFIT code. I think it should be changed to use table_header->length.

Does the acpi core already validate that table_header->length is correct? i.e. is is possible that a broken implementation could have the wrong length in the header? I was assuming that was the purpose of the _with_size(), but maybe I was wrong?
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

author
#19 lore raw

RE: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Hi, Dan

Quoted 98 lines

-----Original Message-----
From: [email protected] [mailto:[email protected]] On Behalf Of Dan
Williams
Sent: Friday, December 9, 2016 10:05 AM
To: Zheng, Lv <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>; Wysocki, Rafael J <[email protected]>; Rafael J. Wysocki <[email protected]>; Brown, Len <[email protected]>; Lv Zheng <[email protected]>; Linux Kernel Mailing List <[email protected]>; Linux ACPI <[email protected]>; Moore,
Robert <[email protected]>; [email protected] <[email protected]>
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel

Quoted 76 lines · Lv

Hi, Rafael and Dan

Quoted 74 lines

From: Dan Williams [mailto:[email protected]]
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 59 lines · Rafael J. Wysocki
Quoted 58 lines · Dan Williams
Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

Quoted 7 lines
Quoted 3 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

Would the build problems go away if you reverted "ACPICA: Tables:
Allow FADT to be customized with virtual address" (linux-next commit cf334d3174f9) in addition to it?

Yes, reverting those two commits gets me back to a functional environment:

Quoted 8 lines
Quoted 3 lines

Revert "ACPICA: Tables: Allow FADT to be customized with virtual address" Revert "ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_un

To Dan:
It seems in drivers/acpi/nfit/core.c.
The returned table size is used by the NFIT code. I think it should be changed to use table_header->length.

Quoted 4 lines

Does the acpi core already validate that table_header->length is correct? i.e. is is possible that a broken implementation could have the wrong length in the header? I was assuming that was the purpose of the _with_size(), but maybe I was wrong?

That should always be correct.
In acpi_tb_init_table_descriptor(), table_desc->length is set by table_header->length.
In acpi_tb_validate_table(), which calls acpi_tb_acquire_table(), acpi_os_map_memory() always uses table_desc->length.

Thanks and best regards
Lv

Quoted 4 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

author
#20 lore raw

RE: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

In reply to Dan Williams

Hi, Dan

Quoted 91 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Dan Williams
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 76 lines · Lv

Hi, Rafael and Dan

Quoted 74 lines

From: Dan Williams [mailto:[email protected]]
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 59 lines · Rafael J. Wysocki
Quoted 58 lines · Dan Williams
Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

Quoted 7 lines
Quoted 3 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

Would the build problems go away if you reverted "ACPICA: Tables:
Allow FADT to be customized with virtual address" (linux-next commit cf334d3174f9) in addition to it?

Yes, reverting those two commits gets me back to a functional environment:

Quoted 8 lines
Quoted 3 lines

Revert "ACPICA: Tables: Allow FADT to be customized with virtual address" Revert "ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_un

To Dan:
It seems in drivers/acpi/nfit/core.c.
The returned table size is used by the NFIT code. I think it should be changed to use table_header->length.

Quoted 4 lines

Does the acpi core already validate that table_header->length is correct? i.e. is is possible that a broken implementation could have the wrong length in the header? I was assuming that was the purpose of the _with_size(), but maybe I was wrong?

There is no such breakage.
The purpose is not that.

The purpose of the API is:
During the Linux early stage, it is required to unmap the early maps as such pointer cannot be used by late stage. While ACPICA keeps such pointer in table_desc if acpi_get_table() is called.

So Linux guys provided acpi_get_table_with_size(), in which table_desc will not remember the mapped pointer. The size must be returned to the caller as the caller need to use it as a parameter to unmap the memory during early stage.

Thanks and best regards
Lv

Quoted 4 lines

--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html

_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

#21 lore raw

Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

In reply to Zheng, Lv
Quoted 80 lines · Lv

Hi, Rafael and Dan

Quoted 72 lines

From: Dan Williams [mailto:[email protected]]
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 59 lines · Rafael J. Wysocki
Quoted 58 lines · Dan Williams
Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

Quoted 7 lines
Quoted 3 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

Would the build problems go away if you reverted "ACPICA: Tables:
Allow FADT to be customized with virtual address" (linux-next commit cf334d3174f9) in addition to it?

Quoted 5 lines

Yes, reverting those two commits gets me back to a functional environment:

Revert "ACPICA: Tables: Allow FADT to be customized with virtual address" Revert "ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_un

Quoted 7 lines

To Dan:
It seems in drivers/acpi/nfit/core.c.
The returned table size is used by the NFIT code. I think it should be changed to use table_header->length.

To Rafael:
I can offer a quick fix for this by returning table_header->length from acpi_get_table_with_size().

OK

I've dropped the problematic ACPICA commit for now (along with the one that depended on it) to prevent the issue from going in.

The change that you are suggesting would defeat the purpose of what the NFIT code does.

Thanks,
Rafael

author
#22 lore raw

RE: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Hi, Rafael

Quoted 93 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Rafael J. Wysocki
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 80 lines · Lv

Hi, Rafael and Dan

Quoted 72 lines

From: Dan Williams [mailto:[email protected]]
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 59 lines · Rafael J. Wysocki
Quoted 58 lines · Dan Williams
Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

Quoted 7 lines
Quoted 3 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

Would the build problems go away if you reverted "ACPICA: Tables:
Allow FADT to be customized with virtual address" (linux-next commit cf334d3174f9) in addition to it?

Quoted 5 lines

Yes, reverting those two commits gets me back to a functional environment:

Revert "ACPICA: Tables: Allow FADT to be customized with virtual address" Revert "ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_un

Quoted 7 lines

To Dan:
It seems in drivers/acpi/nfit/core.c.
The returned table size is used by the NFIT code. I think it should be changed to use table_header->length.

To Rafael:
I can offer a quick fix for this by returning table_header->length from acpi_get_table_with_size().

Quoted 7 lines

OK

I've dropped the problematic ACPICA commit for now (along with the one that depended on it) to prevent the issue from going in.

The change that you are suggesting would defeat the purpose of what the NFIT code does.

I've just sent the regression fix.
Or we can just wait for Dan to confirm and apply the regression fix if it is working.

Thanks and best regards
Lv
_______________________________________________
Linux-nvdimm mailing list
[email protected]
https://lists.01.org/mailman/listinfo/linux-nvdimm

author
#23 lore raw

RE: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

In reply to Dan Williams

Hi, Dan

Good to see you here!

Quoted 53 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Dan Williams
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel

Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 8 lines
Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

This commit is almost a no-op, unless some code in kernel is using the length field returned by old acpi_get_table_with_size().

Quoted 39 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

qemu=$HOME/git/qemu/build/x86_64-softmmu/qemu-system-x86_64 mem=$HOME/mem
label_size=$((128*1024)) mem_size=$(((3*1024*1024*1024) + (64 * 1024 *1024))) IMAGE=$HOME/ahci.img

kvm=(

        $qemu
        -enable-kvm
        -cpu kvm64
        -kernel $kernel
        -initrd $initrd
        -m 12G,slots=3,maxmem=40G

        -machine pc-i440fx-2.4,accel=kvm,usb=off,vmport=off,nvdimm
        -cpu SandyBridge
        -smp 2
        -netdev tap,id=hostnet0,ifname=tap0,script=no,downscript=no
        -device

virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:b7:a1:ad,bus=pci.0,addr=0x7
-object
memory-backend-file,id=mem1,share,mem-path=${mem},size=$((label_size + mem_size))

        -device nvdimm,memdev=mem1,id=nv1,label-size=${label_size}
        -device ahci,id=sata0,bus=pci.0,addr=0x8
        -drive file=$IMAGE,if=none,id=drive-sata0-0-0,format=raw
        -device ide-hd,bus=sata0.0,drive=drive-sata0-0-0,id=sata0-0-0
        -boot order=nc
        -no-reboot
        -watchdog i6300esb
        -rtc base=localtime
        -serial stdio
        -display none
        -monitor null
Quoted 1 line

)

Let me file a kernel Bugzilla bug to track this issue:
https://bugzilla.kernel.org/show_bug.cgi?id=189891
And see if we can quickly fix it.

Could you also point me the NFIT code that I should take a look at. Thanks in advance.

Best regards
Lv

#24 lore raw

Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

Quoted 109 lines · Lv

Hi, Dan

Good to see you here!

Quoted 53 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Dan Williams
Subject: Re: [PATCH 08/11] ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel

Quoted 48 lines · Lv Zheng

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

Quoted 8 lines
Quoted 3 lines

This commit in -next (071b39575679 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel) causes a regression in my nfit/nvdimm test environment. The nfit produced by QEMU no longer results in a nvdimm bus being created.

This commit is almost a no-op, unless some code in kernel is using the length field returned by old acpi_get_table_with_size().

Quoted 39 lines

I have not root caused it, but I'm using the following command line options to create an nfit in qemu-2.6. Reverting the commit leads compile failures.

qemu=$HOME/git/qemu/build/x86_64-softmmu/qemu-system-x86_64 mem=$HOME/mem
label_size=$((128*1024)) mem_size=$(((3*1024*1024*1024) + (64 * 1024 *1024))) IMAGE=$HOME/ahci.img

kvm=(

        $qemu
        -enable-kvm
        -cpu kvm64
        -kernel $kernel
        -initrd $initrd
        -m 12G,slots=3,maxmem=40G

        -machine pc-i440fx-2.4,accel=kvm,usb=off,vmport=off,nvdimm
        -cpu SandyBridge
        -smp 2
        -netdev tap,id=hostnet0,ifname=tap0,script=no,downscript=no
        -device

virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:b7:a1:ad,bus=pci.0,addr=0x7
-object
memory-backend-file,id=mem1,share,mem-path=${mem},size=$((label_size + mem_size))

        -device nvdimm,memdev=mem1,id=nv1,label-size=${label_size}
        -device ahci,id=sata0,bus=pci.0,addr=0x8
        -drive file=$IMAGE,if=none,id=drive-sata0-0-0,format=raw
        -device ide-hd,bus=sata0.0,drive=drive-sata0-0-0,id=sata0-0-0
        -boot order=nc
        -no-reboot
        -watchdog i6300esb
        -rtc base=localtime
        -serial stdio
        -display none
        -monitor null
Quoted 1 line

)

Quoted 7 lines

Let me file a kernel Bugzilla bug to track this issue:
https://bugzilla.kernel.org/show_bug.cgi?id=189891
And see if we can quickly fix it.

Could you also point me the NFIT code that I should take a look at. Thanks in advance.

Yes, the nfit code is here:

drivers/acpi/nfit/core.c

...and yes it does currently use the size returned from acpi_get_table_with_size() as a double-check against the size supplied in the header. See acpi_nfit_add().

author
#25 lore raw

PATCH 9/11 ACPICA: Tables: Allow FADT to be customized with virtual address

In reply to Lv Zheng

ACPICA commit d98de9ca14891130efc5dcdc871b97eb27b4b0f5

FADT parsing code requires FADT to be installed as ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, using new acpi_tb_get_table()/acpi_tb_put_table(), other address types can also be allowed, thus facilitates FADT customization with virtual address. Lv Zheng.

---
 drivers/acpi/acpica/tbfadt.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/acpi/acpica/tbfadt.c +7 -7
index 5fb838e..81473a4 100644
@@ -311,6 +311,8 @@ void acpi_tb_parse_fadt(void)
 {
 	u32 length;
 	struct acpi_table_header *table;
+	struct acpi_table_desc *fadt_desc;
+	acpi_status status;
 
 	/*
 	 * The FADT has multiple versions with different lengths,
@@ -319,14 +321,12 @@ void acpi_tb_parse_fadt(void)
 	 * Get a local copy of the FADT and convert it to a common format
 	 * Map entire FADT, assumed to be smaller than one page.
 	 */
-	length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;
-
-	table =
-	    acpi_os_map_memory(acpi_gbl_root_table_list.
-			       tables[acpi_gbl_fadt_index].address, length);
-	if (!table) {
+	fadt_desc = &acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index];
+	status = acpi_tb_get_table(fadt_desc, &table);
+	if (ACPI_FAILURE(status)) {
 		return;
 	}
+	length = fadt_desc->length;
 
 	/*
 	 * Validate the FADT checksum before we copy the table. Ignore
@@ -340,7 +340,7 @@ void acpi_tb_parse_fadt(void)
 
 	/* All done with the real FADT, unmap it */
 
-	acpi_os_unmap_memory(table, length);
+	acpi_tb_put_table(fadt_desc);
 
 	/* Obtain the DSDT and FACS tables via their addresses within the FADT */
 
Signature · 1 line
1.7.10
author
#26 lore raw

PATCH 10/11 ACPICA: Utilities: Add new decode function for parser values

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit 198fde8a061ac77357bcf1752e3c988fbe59f128

Implements a decode function for the ARGP_* parser info values for all AML opcodes.

---
 drivers/acpi/acpica/acutils.h  |    2 ++
 drivers/acpi/acpica/amlcode.h  |    1 +
 drivers/acpi/acpica/utdecode.c |   49 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 52 insertions(+)
drivers/acpi/acpica/acutils.h +2 -0
index 0a1b53c..845afb1 100644
@@ -232,6 +232,8 @@ struct acpi_pkg_info {
 
 const char *acpi_ut_get_event_name(u32 event_id);
 
+const char *acpi_ut_get_argument_type_name(u32 arg_type);
+
 char acpi_ut_hex_to_ascii_char(u64 integer, u32 position);
 
 acpi_status acpi_ut_ascii_to_hex_byte(char *two_ascii_chars, u8 *return_byte);
drivers/acpi/acpica/amlcode.h +1 -0
index 04fbd88..8a0f959 100644
@@ -240,6 +240,7 @@
 #define ARGP_QWORDDATA              0x11
 #define ARGP_SIMPLENAME             0x12	/* name_string | local_term | arg_term */
 #define ARGP_NAME_OR_REF            0x13	/* For object_type only */
+#define ARGP_MAX                    0x13
 
 /*
  * Resolved argument types for the AML Interpreter
drivers/acpi/acpica/utdecode.c +49 -0

61 lines not on this page · raw message

Signature · 1 line
1.7.10
author
#27 lore raw

PATCH 11/11 ACPICA: Update version to 20161117

In reply to Lv Zheng

From: Bob Moore <[email protected]>

ACPICA commit 0d5a056877c2e37e0bfce8d262cec339dc8d55fd

Version 20161117.

---
 include/acpi/acpixf.h |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
include/acpi/acpixf.h +1 -1
index 33828dd..0d20c53 100644
@@ -46,7 +46,7 @@
 
 /* Current ACPICA subsystem version in YYYYMMDD format */
 
-#define ACPI_CA_VERSION                 0x20160930
+#define ACPI_CA_VERSION                 0x20161117
 
 #include <acpi/acconfig.h>
 #include <acpi/actypes.h>
Signature · 1 line
1.7.10
author
#28 lore raw

PATCH 1/1 ACPI / OSL: Fix a regression by returning table size via acpi_get_table_with_size()

In reply to Lv Zheng

The returned size is still used by the drivers.

---
 drivers/acpi/osl.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/acpi/osl.c +6 -2
index 5bef0f65..adf1ec4 100644
@@ -445,8 +445,12 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 
 	status = acpi_get_table(signature, instance, out_table);
 	if (ACPI_SUCCESS(status)) {
-		/* No longer used by early_acpi_os_unmap_memory() */
-		*tbl_size = 0;
+		/*
+		 * No longer used by early_acpi_os_unmap_memory(), but still
+		 * used by the ACPI table drivers.
+		 */
+		if (*out_table)
+			*tbl_size = (*out_table)->length;
 	}
 
 	return (status);
Signature · 1 line
1.7.10
#29 lore raw

Re: [PATCH] ACPI / OSL: Fix a regression by returning table size via acpi_get_table_with_size()

Quoted 19 lines · Lv Zheng

The returned size is still used by the drivers.

---
 drivers/acpi/osl.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/acpi/osl.c +0 -2
index 5bef0f65..adf1ec4 100644
@@ -445,8 +445,12 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 
        status = acpi_get_table(signature, instance, out_table);
        if (ACPI_SUCCESS(status)) {
-               /* No longer used by early_acpi_os_unmap_memory() */
-               *tbl_size = 0;

drivers/acpi/osl.c void __ref acpi_os_unmap_memory(void *virt, acpi_size size)

Quoted 10 lines
drivers/acpi/osl.c +6 -1
+               /*
+                * No longer used by early_acpi_os_unmap_memory(), but still
+                * used by the ACPI table drivers.
+                */
+               if (*out_table)
+                       *tbl_size = (*out_table)->length;
        }
 
        return (status);
--

The changelog doesn't explain anything. Please say (a) what the problem is and (b) how it is being addressed by your patch.

Thanks,
Rafael

author
#30 lore raw

RE: [PATCH] ACPI / OSL: Fix a regression by returning table size via acpi_get_table_with_size()

Hi, Rafael

Quoted 32 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Rafael J. Wysocki
Subject: Re: [PATCH] ACPI / OSL: Fix a regression by returning table size via acpi_get_table_with_size()

Quoted 27 lines · Lv Zheng

The returned size is still used by the drivers.

---
 drivers/acpi/osl.c |    8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/acpi/osl.c +6 -2
index 5bef0f65..adf1ec4 100644
@@ -445,8 +445,12 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 
        status = acpi_get_table(signature, instance, out_table);
        if (ACPI_SUCCESS(status)) {
-               /* No longer used by early_acpi_os_unmap_memory() */
-               *tbl_size = 0;
+               /*
+                * No longer used by early_acpi_os_unmap_memory(), but still
+                * used by the ACPI table drivers.
+                */
+               if (*out_table)
+                       *tbl_size = (*out_table)->length;
        }
 
Quoted 5 lines

drivers/acpi/osl.c void __ref acpi_os_unmap_memory(void *virt, acpi_size size)

Quoted 2 lines
drivers/acpi/osl.c +0 -1
        return (status);
--

The changelog doesn't explain anything. Please say (a) what the problem is and (b) how it is being addressed by your patch.

OK, I'll also add fixes tag to it.

Thanks
Lv

author
#31 lore raw

PATCH v2 1/1 ACPI / OSL: Fix a regression by returning acpi_table_header.length instead of 0 from acpi_get_table_with_size()

In reply to Lv Zheng

The following wrong commit triggers issues in acpi_get_table_with_size() users:
Subject: ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel

The function is invented to be a replacement of acpi_get_table() during early stage so that the early mapped pointer will not be stored in ACPICA core and thus the late stage acpi_get_table() won't return a wrong pointer. However the mapping size is returned just because it is required by early_acpi_os_unmap_memory() to unmap the pointer during early stage.

As the mapping size equals to the acpi_table_header.length (see acpi_tb_init_table_descriptor() and acpi_tb_validate_table()), when such a convenient result is returned, driver code will start to use it instead of accessing acpi_table_header to obtain the length.

So the commit can trigger problems in such drivers as it returns 0 now. And it did bring a trouble to drivers/acpi/nfit/core.c. So before cleaning up the drivers, we should keep the old semantics of the API.

This patch fixes the wrong commit by returning the acpi_table_header.length from acpi_get_table_with_size().

---
 drivers/acpi/osl.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/acpi/osl.c +10 -2
index 5bef0f65..d0b273f 100644
@@ -445,8 +445,16 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 
 	status = acpi_get_table(signature, instance, out_table);
 	if (ACPI_SUCCESS(status)) {
-		/* No longer used by early_acpi_os_unmap_memory() */
-		*tbl_size = 0;
+		/*
+		 * "tbl_size" is no longer used by
+		 * early_acpi_os_unmap_memory(), but is still used by the
+		 * ACPI table drivers. So sets it to the length of the
+		 * table when the tbl_size is requested.
+		 * "out_table" is not sanity checked as AE_BAD_PARAMETER
+		 * is returned if it is NULL.
+		 */
+		if (tbl_size && *out_table)
+			*tbl_size = (*out_table)->length;
 	}
 
 	return (status);
Signature · 1 line
1.7.10
#32 lore raw

Re: [PATCH v2] ACPI / OSL: Fix a regression by returning acpi_table_header.length instead of 0 from acpi_get_table_with_size()

Quoted 16 lines · Lv Zheng

The following wrong commit triggers issues in acpi_get_table_with_size() users:
Subject: ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel

The function is invented to be a replacement of acpi_get_table() during early stage so that the early mapped pointer will not be stored in ACPICA core and thus the late stage acpi_get_table() won't return a wrong pointer. However the mapping size is returned just because it is required by early_acpi_os_unmap_memory() to unmap the pointer during early stage.

As the mapping size equals to the acpi_table_header.length (see acpi_tb_init_table_descriptor() and acpi_tb_validate_table()), when such a convenient result is returned, driver code will start to use it instead of accessing acpi_table_header to obtain the length.

Quoted 6 lines

So the commit can trigger problems in such drivers as it returns 0 now. And it did bring a trouble to drivers/acpi/nfit/core.c. So before cleaning up the drivers, we should keep the old semantics of the API.

This patch fixes the wrong commit by returning the acpi_table_header.length from acpi_get_table_with_size().

Well, the way this works isn't particularly straightforward.

Wouldn't it be better to simply drop the check (if it is redundant) from the NFIT driver?

Quoted 31 lines
---
 drivers/acpi/osl.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/acpi/osl.c +10 -3
index 5bef0f65..d0b273f 100644
@@ -445,8 +445,16 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 
        status = acpi_get_table(signature, instance, out_table);
        if (ACPI_SUCCESS(status)) {
-               /* No longer used by early_acpi_os_unmap_memory() */
-               *tbl_size = 0;
+               /*
+                * "tbl_size" is no longer used by
+                * early_acpi_os_unmap_memory(), but is still used by the
+                * ACPI table drivers. So sets it to the length of the
+                * table when the tbl_size is requested.
+                * "out_table" is not sanity checked as AE_BAD_PARAMETER
+                * is returned if it is NULL.
+                */
+               if (tbl_size && *out_table)
+                       *tbl_size = (*out_table)->length;
        }
 
        return (status);
--
Quoted 2 lines

1.7.10

Thanks,
Rafael

author
#33 lore raw

RE: [PATCH v2] ACPI / OSL: Fix a regression by returning acpi_table_header.length instead of 0 from acpi_get_table_with_size()

Hi,

Quoted 21 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Rafael J. Wysocki
Subject: Re: [PATCH v2] ACPI / OSL: Fix a regression by returning acpi_table_header.length instead of 0 from acpi_get_table_with_size()

Quoted 16 lines · Lv Zheng

The following wrong commit triggers issues in acpi_get_table_with_size() users:
Subject: ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel

The function is invented to be a replacement of acpi_get_table() during early stage so that the early mapped pointer will not be stored in ACPICA core and thus the late stage acpi_get_table() won't return a wrong pointer. However the mapping size is returned just because it is required by early_acpi_os_unmap_memory() to unmap the pointer during early stage.

As the mapping size equals to the acpi_table_header.length (see acpi_tb_init_table_descriptor() and acpi_tb_validate_table()), when such a convenient result is returned, driver code will start to use it instead of accessing acpi_table_header to obtain the length.

Quoted 8 lines
Quoted 6 lines

So the commit can trigger problems in such drivers as it returns 0 now. And it did bring a trouble to drivers/acpi/nfit/core.c. So before cleaning up the drivers, we should keep the old semantics of the API.

This patch fixes the wrong commit by returning the acpi_table_header.length from acpi_get_table_with_size().

Well, the way this works isn't particularly straightforward.

I don't know what's your preference here?
Shall we drop the 2 wrong commits, and merge fixed ones to replace them in linux-pm/linux-next? Or can we just merge this fix patch on top of the wrong commits?

Quoted 3 lines

Wouldn't it be better to simply drop the check (if it is redundant) from the NFIT driver?

At this point, I'm not sure if NFIT is the only driver broken by the wrong commit.
My plan was:
1. Keep old behavior working by still providing acpi_get_table_with_size()/early_acpi_os_unmap_memory();
2. Use a set of patches to cleanup acpi_get_table_with_size()/early_acpi_os_unmap_memory() users, So that we can carefully examine every caller, split strange use cases into separate commits to avoid regressions;
3. Remove acpi_get_table_with_size() and early_acpi_os_unmap_memory() if there is no driver using them.

Thanks and best regards
Lv

Quoted 37 lines
Quoted 32 lines
---
 drivers/acpi/osl.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
drivers/acpi/osl.c +10 -3
index 5bef0f65..d0b273f 100644
@@ -445,8 +445,16 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 
        status = acpi_get_table(signature, instance, out_table);
        if (ACPI_SUCCESS(status)) {
-               /* No longer used by early_acpi_os_unmap_memory() */
-               *tbl_size = 0;
+               /*
+                * "tbl_size" is no longer used by
+                * early_acpi_os_unmap_memory(), but is still used by the
+                * ACPI table drivers. So sets it to the length of the
+                * table when the tbl_size is requested.
+                * "out_table" is not sanity checked as AE_BAD_PARAMETER
+                * is returned if it is NULL.
+                */
+               if (tbl_size && *out_table)
+                       *tbl_size = (*out_table)->length;
        }
 
        return (status);
--
Quoted 2 lines

1.7.10

Thanks,
Rafael

#34 lore raw

Re: [PATCH v2] ACPI / OSL: Fix a regression by returning acpi_table_header.length instead of 0 from acpi_get_table_with_size()

Quoted 27 lines · Lv

Hi,

Quoted 25 lines

From: [email protected] [mailto:[email protected]] On Behalf Of Rafael J. Wysocki
Subject: Re: [PATCH v2] ACPI / OSL: Fix a regression by returning acpi_table_header.length instead of 0 from acpi_get_table_with_size()

Quoted 20 lines · Lv Zheng

The following wrong commit triggers issues in acpi_get_table_with_size() users:
Subject: ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel

The function is invented to be a replacement of acpi_get_table() during early stage so that the early mapped pointer will not be stored in ACPICA core and thus the late stage acpi_get_table() won't return a wrong pointer. However the mapping size is returned just because it is required by early_acpi_os_unmap_memory() to unmap the pointer during early stage.

As the mapping size equals to the acpi_table_header.length (see acpi_tb_init_table_descriptor() and acpi_tb_validate_table()), when such a convenient result is returned, driver code will start to use it instead of accessing acpi_table_header to obtain the length.

So the commit can trigger problems in such drivers as it returns 0 now. And it did bring a trouble to drivers/acpi/nfit/core.c. So before cleaning up the drivers, we should keep the old semantics of the API.

Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

This patch fixes the wrong commit by returning the acpi_table_header.length from acpi_get_table_with_size().

Well, the way this works isn't particularly straightforward.

I don't know what's your preference here?
Shall we drop the 2 wrong commits, and merge fixed ones to replace them in linux-pm/linux-next?

Yes.

Quoted 1 line

Or can we just merge this fix patch on top of the wrong commits?

I've already sent a pull request with the 2 problematic commits dropped.

Quoted 5 lines
Quoted 3 lines

Wouldn't it be better to simply drop the check (if it is redundant) from the NFIT driver?

At this point, I'm not sure if NFIT is the only driver broken by the wrong commit.

You can look for acpi_get_table_with_size() users.

It looks like radeon_bios.c may have the same problem.

Quoted 2 lines

My plan was:
1. Keep old behavior working by still providing acpi_get_table_with_size()/early_acpi_os_unmap_memory();

OK

Quoted 3 lines

2. Use a set of patches to cleanup acpi_get_table_with_size()/early_acpi_os_unmap_memory() users, So that we can carefully examine every caller, split strange use cases into separate commits to avoid regressions;
3. Remove acpi_get_table_with_size() and early_acpi_os_unmap_memory() if there is no driver using them.

Looks reasonable in principle.

Thanks,
Rafael

author
#35 lore raw

v3 cover ACPI / osl: Cleans up acpi_get_table_with_size()/early_acpi_os_unmap_memory()

In reply to Lv Zheng

acpi_get_table_with_size() is invented to be a replacement of acpi_get_table() during the early stage so that the early mapped pointer will not be stored in ACPICA core (acpi_get_table() forces to do so) and thus the late stage acpi_get_table() won't return a wrong stored pointer.

Since there is early_acpi_os_unmap_memory() required to be invoked as a reversal of acpi_get_table_with_size(), ACPICA can provide acpi_put_table() to achieve the same purpose. As long as all early stage acpi_get_table() calls are paired by early stage acpi_put_table() calls, mappings should be released before entering the late stage. And the late stage acpi_get_table() calls will map the table using a late stage ioremap mechanism.

This patchset cleans up the old APIs and reduces divergences between Linux and ACPICA upstream.

Lv Zheng (4):
ACPICA: Tables: Back port acpi_get_table_with_size() and
early_acpi_os_unmap_memory() from Linux kernel
ACPICA: Tables: Allow FADT to be customized with virtual address ACPI / osl: Remove
acpi_get_table_with_size()/early_acpi_os_unmap_memory() users
ACPI / osl: Remove deprecated
acpi_get_table_with_size()/early_acpi_os_unmap_memory()

 arch/arm64/include/asm/acpi.h            |    2 +-
 arch/arm64/kernel/acpi.c                 |    7 +-
 drivers/acpi/acpica/actables.h           |    6 ++
 drivers/acpi/acpica/tbfadt.c             |   14 ++--
 drivers/acpi/acpica/tbutils.c            |   85 +++++++++++++++++++
 drivers/acpi/acpica/tbxface.c            |  130 +++++++++++++++++++-----------
 drivers/acpi/bus.c                       |    2 +-
 drivers/acpi/nfit/core.c                 |    3 +-
 drivers/acpi/osl.c                       |   15 ++--
 drivers/acpi/processor_core.c            |    8 +-
 drivers/acpi/spcr.c                      |    8 +-
 drivers/acpi/tables.c                    |   17 ++--
 drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c |    3 +-
 drivers/gpu/drm/radeon/radeon_bios.c     |    3 +-
 drivers/iommu/amd_iommu_init.c           |   10 +--
 drivers/iommu/dmar.c                     |    7 +-
 drivers/mailbox/pcc.c                    |    5 +-
 include/acpi/acpi_io.h                   |    2 +
 include/acpi/acpixf.h                    |   17 ++--
 include/acpi/actbl.h                     |    1 +
 include/acpi/platform/aclinuxex.h        |    1 -
 21 files changed, 224 insertions(+), 122 deletions(-)
Signature · 1 line
1.7.10
author
#36 lore raw

PATCH v3 1/4 ACPICA: Tables: Back port acpi_get_table_with_size() and early_acpi_os_unmap_memory() from Linux kernel

ACPICA commit cac6790954d4d752a083e6122220b8a22febcd07

This patch back ports Linux acpi_get_table_with_size() and early_acpi_os_unmap_memory() into ACPICA upstream to reduce divergences.

The 2 APIs are used by Linux as table management APIs for long time, it contains a hidden logic that during the early stage, the mapped tables should be unmapped before the early stage ends.

During the early stage, tables are handled by the following sequence:
acpi_get_table_with_size();
parse the table
early_acpi_os_unmap_memory();
During the late stage, tables are handled by the following sequence:
acpi_get_table();
parse the table
Linux uses acpi_gbl_permanent_mmap to distinguish the early stage and the late stage.

The reasoning of introducing acpi_get_table_with_size() is: ACPICA will remember the early mapped pointer in acpi_get_table() and Linux isn't able to prevent ACPICA from using the wrong early mapped pointer during the late stage as there is no API provided from ACPICA to be an inverse of acpi_get_table() to forget the early mapped pointer.

But how ACPICA can work with the early/late stage requirement? Inside of ACPICA, tables are ensured to be remained in "INSTALLED" state during the early stage, and they are carefully not transitioned to "VALIDATED" state until the late stage. So the same logic is in fact implemented inside of ACPICA in a different way. The gap is only that the feature is not provided to the OSPMs in an accessible external API style.

It then is possible to fix the gap by providing an inverse of acpi_get_table() from ACPICA, so that the two Linux sequences can be combined:
acpi_get_table();
parse the table
acpi_put_table();
In order to work easier with the current Linux code, acpi_get_table() and acpi_put_table() is implemented in a usage counting based style:
1. When the usage count of the table is increased from 0 to 1, table is

    mapped and .Pointer is set with the mapping address (VALIDATED);

2. When the usage count of the table is decreased from 1 to 0, .Pointer is unset and the mapping address is unmapped (INVALIDATED).
So that we can deploy the new APIs to Linux with minimal effort by just invoking acpi_get_table() in acpi_get_table_with_size() and invoking acpi_put_table() in early_acpi_os_unmap_memory(). Lv Zheng.

---
 drivers/acpi/acpica/actables.h    |    6 ++
 drivers/acpi/acpica/tbutils.c     |   85 ++++++++++++++++++++++++
 drivers/acpi/acpica/tbxface.c     |  130 +++++++++++++++++++++++--------------
 drivers/acpi/osl.c                |   39 ++++++++++-
 include/acpi/acpixf.h             |   12 +++-
 include/acpi/actbl.h              |    1 +
 include/acpi/platform/aclinuxex.h |    1 -
 7 files changed, 220 insertions(+), 54 deletions(-)
drivers/acpi/acpica/actables.h +6 -0
index 7dd527f..94be8a8 100644
@@ -166,6 +166,12 @@
 
 acpi_status acpi_tb_parse_root_table(acpi_physical_address rsdp_address);
 
+acpi_status
+acpi_tb_get_table(struct acpi_table_desc *table_desc,
+		  struct acpi_table_header **out_table);
+
+void acpi_tb_put_table(struct acpi_table_desc *table_desc);
+
 /*
  * tbxfload
  */
drivers/acpi/acpica/tbutils.c +85 -0

88 lines not on this page · raw message

drivers/acpi/acpica/tbxface.c +82 -48

203 lines not on this page · raw message

drivers/acpi/osl.c +37 -2
index 9a4c6ab..d0b273f 100644
@@ -426,10 +426,45 @@ void __ref acpi_os_unmap_memory(void *virt, acpi_size size)
 }
 EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
 
+/*******************************************************************************
+ *
+ * acpi_get_table_with_size()/early_acpi_os_unmap_memory():
+ *
+ * These 2 functions are traditionally used by Linux to map/unmap physical
+ * addressed ACPI tables during the early stage.
+ * They are deprectated now. Do not use them in the new code, but use
+ * acpi_get_table()/acpi_put_table() instead.
+ *
+ ******************************************************************************/
+acpi_status
+acpi_get_table_with_size(char *signature,
+	       u32 instance, struct acpi_table_header **out_table,
+	       acpi_size *tbl_size)
+{
+	acpi_status status;
+
+	status = acpi_get_table(signature, instance, out_table);
+	if (ACPI_SUCCESS(status)) {
+		/*
+		 * "tbl_size" is no longer used by
+		 * early_acpi_os_unmap_memory(), but is still used by the
+		 * ACPI table drivers. So sets it to the length of the
+		 * table when the tbl_size is requested.
+		 * "out_table" is not sanity checked as AE_BAD_PARAMETER
+		 * is returned if it is NULL.
+		 */
+		if (tbl_size && *out_table)
+			*tbl_size = (*out_table)->length;
+	}
+
+	return (status);
+}
+
+ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
+
 void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
 {
-	if (!acpi_gbl_permanent_mmap)
-		__acpi_unmap_table(virt, size);
+	acpi_put_table(ACPI_CAST_PTR(struct acpi_table_header, virt));
 }
 
 int acpi_os_map_generic_address(struct acpi_generic_address *gas)
include/acpi/acpixf.h +9 -3
index 5c7356a..33828dd 100644
@@ -513,10 +513,12 @@
 			     acpi_get_table(acpi_string signature, u32 instance,
 					    struct acpi_table_header
 					    **out_table))
+ACPI_EXTERNAL_RETURN_VOID(void acpi_put_table(struct acpi_table_header *table))
+
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			     acpi_get_table_by_index(u32 table_index,
-						     struct acpi_table_header
-						     **out_table))
+			    acpi_get_table_by_index(u32 table_index,
+						    struct acpi_table_header
+						    **out_table))
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			     acpi_install_table_handler(acpi_table_handler
 							handler, void *context))
@@ -974,6 +976,10 @@
 						     **out_table,
 						     acpi_size *tbl_size))
 
+ACPI_EXTERNAL_RETURN_VOID(void
+			  early_acpi_os_unmap_memory(void __iomem * virt,
+						     acpi_size size))
+
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			    acpi_get_data_full(acpi_handle object,
 					       acpi_object_handler handler,
include/acpi/actbl.h +1 -0
index c19700e..da5708c 100644
@@ -371,6 +371,7 @@ struct acpi_table_desc {
 	union acpi_name_union signature;
 	acpi_owner_id owner_id;
 	u8 flags;
+	u16 validation_count;
 };
 
 /* Masks for Flags field above */
include/acpi/platform/aclinuxex.h +0 -1
index a5509d8..7dbb114 100644
@@ -142,7 +142,6 @@ static inline void acpi_os_terminate_command_signals(void)
 /*
  * OSL interfaces added by Linux
  */
-void early_acpi_os_unmap_memory(void __iomem * virt, acpi_size size);
 
 #endif				/* __KERNEL__ */
 
Signature · 1 line
1.7.10
author
#37 lore raw

PATCH v3 2/4 ACPICA: Tables: Allow FADT to be customized with virtual address

In reply to Lv Zheng

ACPICA commit d98de9ca14891130efc5dcdc871b97eb27b4b0f5

FADT parsing code requires FADT to be installed as ACPI_TABLE_ORIGIN_INTERNAL_PHYSICAL, using new acpi_tb_get_table()/acpi_tb_put_table(), other address types can also be allowed, thus facilitates FADT customization with virtual address. Lv Zheng.

---
 drivers/acpi/acpica/tbfadt.c |   14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/acpi/acpica/tbfadt.c +7 -7
index 5fb838e..81473a4 100644
@@ -311,6 +311,8 @@ void acpi_tb_parse_fadt(void)
 {
 	u32 length;
 	struct acpi_table_header *table;
+	struct acpi_table_desc *fadt_desc;
+	acpi_status status;
 
 	/*
 	 * The FADT has multiple versions with different lengths,
@@ -319,14 +321,12 @@ void acpi_tb_parse_fadt(void)
 	 * Get a local copy of the FADT and convert it to a common format
 	 * Map entire FADT, assumed to be smaller than one page.
 	 */
-	length = acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index].length;
-
-	table =
-	    acpi_os_map_memory(acpi_gbl_root_table_list.
-			       tables[acpi_gbl_fadt_index].address, length);
-	if (!table) {
+	fadt_desc = &acpi_gbl_root_table_list.tables[acpi_gbl_fadt_index];
+	status = acpi_tb_get_table(fadt_desc, &table);
+	if (ACPI_FAILURE(status)) {
 		return;
 	}
+	length = fadt_desc->length;
 
 	/*
 	 * Validate the FADT checksum before we copy the table. Ignore
@@ -340,7 +340,7 @@ void acpi_tb_parse_fadt(void)
 
 	/* All done with the real FADT, unmap it */
 
-	acpi_os_unmap_memory(table, length);
+	acpi_tb_put_table(fadt_desc);
 
 	/* Obtain the DSDT and FACS tables via their addresses within the FADT */
 
Signature · 1 line
1.7.10
author
#38 lore raw

PATCH v3 3/4 ACPI / osl: Remove acpi_get_table_with_size()/early_acpi_os_unmap_memory() users

In reply to Lv Zheng

This patch removes the users of the deprectated APIs:
acpi_get_table_with_size() early_acpi_os_unmap_memory()
The following APIs should be used instead of:
acpi_get_table()
acpi_put_table()

The deprecated APIs are invented to be a replacement of acpi_get_table() during the early stage so that the early mapped pointer will not be stored in ACPICA core and thus the late stage acpi_get_table() won't return a wrong pointer. The mapping size is returned just because it is required by early_acpi_os_unmap_memory() to unmap the pointer during early stage.

But as the mapping size equals to the acpi_table_header.length (see acpi_tb_init_table_descriptor() and acpi_tb_validate_table()), when such a convenient result is returned, driver code will start to use it instead of accessing acpi_table_header to obtain the length.

Thus this patch cleans up the drivers by replacing returned table size with acpi_table_header.length, and should be a no-op.

---
 arch/arm64/kernel/acpi.c                 |    7 +++----
 drivers/acpi/nfit/core.c                 |    3 ++-
 drivers/acpi/processor_core.c            |    8 +++-----
 drivers/acpi/spcr.c                      |    8 +++-----
 drivers/acpi/tables.c                    |   17 +++++++----------
 drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c |    3 ++-
 drivers/gpu/drm/radeon/radeon_bios.c     |    3 ++-
 drivers/iommu/amd_iommu_init.c           |   10 ++++------
 drivers/iommu/dmar.c                     |    7 ++-----
 drivers/mailbox/pcc.c                    |    5 +----
 10 files changed, 29 insertions(+), 42 deletions(-)
arch/arm64/kernel/acpi.c +3 -4
index 252a6d9..64d9cbd6 100644
@@ -132,14 +132,13 @@ static int __init acpi_fadt_sanity_check(void)
 	struct acpi_table_header *table;
 	struct acpi_table_fadt *fadt;
 	acpi_status status;
-	acpi_size tbl_size;
 	int ret = 0;
 
 	/*
 	 * FADT is required on arm64; retrieve it to check its presence
 	 * and carry out revision and ACPI HW reduced compliancy tests
 	 */
-	status = acpi_get_table_with_size(ACPI_SIG_FADT, 0, &table, &tbl_size);
+	status = acpi_get_table(ACPI_SIG_FADT, 0, &table);
 	if (ACPI_FAILURE(status)) {
 		const char *msg = acpi_format_exception(status);
 
@@ -170,10 +169,10 @@ static int __init acpi_fadt_sanity_check(void)
 
 out:
 	/*
-	 * acpi_get_table_with_size() creates FADT table mapping that
+	 * acpi_get_table() creates FADT table mapping that
 	 * should be released after parsing and before resuming boot
 	 */
-	early_acpi_os_unmap_memory(table, tbl_size);
+	acpi_put_table(table);
 	return ret;
 }
 
drivers/acpi/nfit/core.c +2 -1
index 312c4b4..2f82b8e 100644
@@ -2806,12 +2806,13 @@ static int acpi_nfit_add(struct acpi_device *adev)
 	acpi_size sz;
 	int rc = 0;
 
-	status = acpi_get_table_with_size(ACPI_SIG_NFIT, 0, &tbl, &sz);
+	status = acpi_get_table(ACPI_SIG_NFIT, 0, &tbl);
 	if (ACPI_FAILURE(status)) {
 		/* This is ok, we could have an nvdimm hotplugged later */
 		dev_dbg(dev, "failed to find NFIT at startup\n");
 		return 0;
 	}
+	sz = tbl->length;
 
 	acpi_desc = devm_kzalloc(dev, sizeof(*acpi_desc), GFP_KERNEL);
 	if (!acpi_desc)
drivers/acpi/processor_core.c +3 -5
index 5c78ee1..611a558 100644
@@ -154,18 +154,16 @@ static phys_cpuid_t map_madt_entry(struct acpi_table_madt *madt,
 phys_cpuid_t __init acpi_map_madt_entry(u32 acpi_id)
 {
 	struct acpi_table_madt *madt = NULL;
-	acpi_size tbl_size;
 	phys_cpuid_t rv;
 
-	acpi_get_table_with_size(ACPI_SIG_MADT, 0,
-				 (struct acpi_table_header **)&madt,
-				 &tbl_size);
+	acpi_get_table(ACPI_SIG_MADT, 0,
+		       (struct acpi_table_header **)&madt);
 	if (!madt)
 		return PHYS_CPUID_INVALID;
 
 	rv = map_madt_entry(madt, 1, acpi_id, true);
 
-	early_acpi_os_unmap_memory(madt, tbl_size);
+	acpi_put_table((struct acpi_table_header *)madt);
 
 	return rv;
 }
drivers/acpi/spcr.c +3 -5
index e8d7bc7..b8019c4 100644
@@ -33,7 +33,6 @@ int __init parse_spcr(bool earlycon)
 {
 	static char opts[64];
 	struct acpi_table_spcr *table;
-	acpi_size table_size;
 	acpi_status status;
 	char *uart;
 	char *iotype;
@@ -43,9 +42,8 @@ int __init parse_spcr(bool earlycon)
 	if (acpi_disabled)
 		return -ENODEV;
 
-	status = acpi_get_table_with_size(ACPI_SIG_SPCR, 0,
-					  (struct acpi_table_header **)&table,
-					  &table_size);
+	status = acpi_get_table(ACPI_SIG_SPCR, 0,
+				(struct acpi_table_header **)&table);
 
 	if (ACPI_FAILURE(status))
 		return -ENOENT;
@@ -106,6 +104,6 @@ int __init parse_spcr(bool earlycon)
 	err = add_preferred_console(uart, 0, opts + strlen(uart) + 1);
 
 done:
-	early_acpi_os_unmap_memory((void __iomem *)table, table_size);
+	acpi_put_table((struct acpi_table_header *)table);
 	return err;
 }
drivers/acpi/tables.c +7 -10
index cdd56c4..2604189 100644
@@ -333,7 +333,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 			 unsigned int max_entries)
 {
 	struct acpi_table_header *table_header = NULL;
-	acpi_size tbl_size;
 	int count;
 	u32 instance = 0;
 
@@ -346,7 +345,7 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	if (!strncmp(id, ACPI_SIG_MADT, 4))
 		instance = acpi_apic_instance;
 
-	acpi_get_table_with_size(id, instance, &table_header, &tbl_size);
+	acpi_get_table(id, instance, &table_header);
 	if (!table_header) {
 		pr_warn("%4.4s not present\n", id);
 		return -ENODEV;
@@ -355,7 +354,7 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 	count = acpi_parse_entries_array(id, table_size, table_header,
 			proc, proc_num, max_entries);
 
-	early_acpi_os_unmap_memory((char *)table_header, tbl_size);
+	acpi_put_table(table_header);
 	return count;
 }
 
@@ -397,7 +396,6 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
 int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
 {
 	struct acpi_table_header *table = NULL;
-	acpi_size tbl_size;
 
 	if (acpi_disabled)
 		return -ENODEV;
@@ -406,13 +404,13 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
 		return -EINVAL;
 
 	if (strncmp(id, ACPI_SIG_MADT, 4) == 0)
-		acpi_get_table_with_size(id, acpi_apic_instance, &table, &tbl_size);
+		acpi_get_table(id, acpi_apic_instance, &table);
 	else
-		acpi_get_table_with_size(id, 0, &table, &tbl_size);
+		acpi_get_table(id, 0, &table);
 
 	if (table) {
 		handler(table);
-		early_acpi_os_unmap_memory(table, tbl_size);
+		acpi_put_table(table);
 		return 0;
 	} else
 		return -ENODEV;
@@ -426,16 +424,15 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
 static void __init check_multiple_madt(void)
 {
 	struct acpi_table_header *table = NULL;
-	acpi_size tbl_size;
 
-	acpi_get_table_with_size(ACPI_SIG_MADT, 2, &table, &tbl_size);
+	acpi_get_table(ACPI_SIG_MADT, 2, &table);
 	if (table) {
 		pr_warn("BIOS bug: multiple APIC/MADT found, using %d\n",
 			acpi_apic_instance);
 		pr_warn("If \"acpi_apic_instance=%d\" works better, "
 			"notify [email protected]\n",
 			acpi_apic_instance ? 0 : 2);
-		early_acpi_os_unmap_memory(table, tbl_size);
+		acpi_put_table(table);
 
 	} else
 		acpi_apic_instance = 0;
drivers/gpu/drm/amd/amdgpu/amdgpu_bios.c +2 -1
index 4f973a9..8ec1967 100644
@@ -305,8 +305,9 @@ static bool amdgpu_acpi_vfct_bios(struct amdgpu_device *adev)
 	GOP_VBIOS_CONTENT *vbios;
 	VFCT_IMAGE_HEADER *vhdr;
 
-	if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
+	if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
 		return false;
+	tbl_size = hdr->length;
 	if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
 		DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
 		goto out_unmap;
drivers/gpu/drm/radeon/radeon_bios.c +2 -1
index 21b6732..c829cfb 100644
@@ -603,8 +603,9 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
 	GOP_VBIOS_CONTENT *vbios;
 	VFCT_IMAGE_HEADER *vhdr;
 
-	if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
+	if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
 		return false;
+	tbl_size = hdr->length;
 	if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
 		DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
 		goto out_unmap;
drivers/iommu/amd_iommu_init.c +4 -6
index 157e934..eea3d49 100644
@@ -2207,14 +2207,13 @@ static void __init free_dma_resources(void)
 static int __init early_amd_iommu_init(void)
 {
 	struct acpi_table_header *ivrs_base;
-	acpi_size ivrs_size;
 	acpi_status status;
 	int i, remap_cache_sz, ret = 0;
 
 	if (!amd_iommu_detected)
 		return -ENODEV;
 
-	status = acpi_get_table_with_size("IVRS", 0, &ivrs_base, &ivrs_size);
+	status = acpi_get_table("IVRS", 0, &ivrs_base);
 	if (status == AE_NOT_FOUND)
 		return -ENODEV;
 	else if (ACPI_FAILURE(status)) {
@@ -2334,7 +2333,7 @@ static int __init early_amd_iommu_init(void)
 
 out:
 	/* Don't leak any ACPI memory */
-	early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);
+	acpi_put_table(ivrs_base);
 	ivrs_base = NULL;
 
 	return ret;
@@ -2358,10 +2357,9 @@ static int amd_iommu_enable_interrupts(void)
 static bool detect_ivrs(void)
 {
 	struct acpi_table_header *ivrs_base;
-	acpi_size ivrs_size;
 	acpi_status status;
 
-	status = acpi_get_table_with_size("IVRS", 0, &ivrs_base, &ivrs_size);
+	status = acpi_get_table("IVRS", 0, &ivrs_base);
 	if (status == AE_NOT_FOUND)
 		return false;
 	else if (ACPI_FAILURE(status)) {
@@ -2370,7 +2368,7 @@ static bool detect_ivrs(void)
 		return false;
 	}
 
-	early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size);
+	acpi_put_table(ivrs_base);
 
 	/* Make sure ACS will be enabled during PCI probe */
 	pci_request_acs();
drivers/iommu/dmar.c +2 -5
index 8c53748..a88576d 100644
@@ -68,7 +68,6 @@ struct dmar_res_callback {
 LIST_HEAD(dmar_drhd_units);
 
 struct acpi_table_header * __initdata dmar_tbl;
-static acpi_size dmar_tbl_size;
 static int dmar_dev_scope_status = 1;
 static unsigned long dmar_seq_ids[BITS_TO_LONGS(DMAR_UNITS_SUPPORTED)];
 
@@ -543,9 +542,7 @@ static int __init dmar_table_detect(void)
 	acpi_status status = AE_OK;
 
 	/* if we could find DMAR table, then there are DMAR devices */
-	status = acpi_get_table_with_size(ACPI_SIG_DMAR, 0,
-				(struct acpi_table_header **)&dmar_tbl,
-				&dmar_tbl_size);
+	status = acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_tbl);
 
 	if (ACPI_SUCCESS(status) && !dmar_tbl) {
 		pr_warn("Unable to map DMAR\n");
@@ -906,7 +903,7 @@ int __init detect_intel_iommu(void)
 		x86_init.iommu.iommu_init = intel_iommu_init;
 #endif
 
-	early_acpi_os_unmap_memory((void __iomem *)dmar_tbl, dmar_tbl_size);
+	acpi_put_table(dmar_tbl);
 	dmar_tbl = NULL;
 	up_write(&dmar_global_lock);
 
drivers/mailbox/pcc.c +1 -4
index 1f32688..dd9ecd35 100644
@@ -447,7 +447,6 @@ static int pcc_parse_subspace_irq(int id,
  */
 static int __init acpi_pcc_probe(void)
 {
-	acpi_size pcct_tbl_header_size;
 	struct acpi_table_header *pcct_tbl;
 	struct acpi_subtable_header *pcct_entry;
 	struct acpi_table_pcct *acpi_pcct_tbl;
@@ -456,9 +455,7 @@ static int __init acpi_pcc_probe(void)
 	acpi_status status = AE_OK;
 
 	/* Search for PCCT */
-	status = acpi_get_table_with_size(ACPI_SIG_PCCT, 0,
-			&pcct_tbl,
-			&pcct_tbl_header_size);
+	status = acpi_get_table(ACPI_SIG_PCCT, 0, &pcct_tbl);
 
 	if (ACPI_FAILURE(status) || !pcct_tbl) {
 		pr_warn("PCCT header not found.\n");
Signature · 1 line
1.7.10
author
#39 lore raw

PATCH v3 4/4 ACPI / osl: Remove deprecated acpi_get_table_with_size()/early_acpi_os_unmap_memory()

In reply to Lv Zheng

Since all users are cleaned up, remove the 2 deprecated APIs due to no users.
As a Linux variable rather than an ACPICA variable, acpi_gbl_permanent_mmap is renamed to acpi_permanent_mmap to have a consistent coding style across entire Linux ACPI subsystem.

---
 arch/arm64/include/asm/acpi.h |    2 +-
 drivers/acpi/bus.c            |    2 +-
 drivers/acpi/osl.c            |   50 +++++------------------------------------
 include/acpi/acpi_io.h        |    2 ++
 include/acpi/acpixf.h         |   13 -----------
 5 files changed, 9 insertions(+), 60 deletions(-)
arch/arm64/include/asm/acpi.h +1 -1
index d0de0e0..c1976c0 100644
@@ -29,7 +29,7 @@
 
 /* Basic configuration for ACPI */
 #ifdef	CONFIG_ACPI
-/* ACPI table mapping after acpi_gbl_permanent_mmap is set */
+/* ACPI table mapping after acpi_permanent_mmap is set */
 static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
 					    acpi_size size)
 {
drivers/acpi/bus.c +1 -1
index 5cbefd7..95855cb 100644
@@ -974,7 +974,7 @@ void __init acpi_early_init(void)
 	if (!acpi_strict)
 		acpi_gbl_enable_interpreter_slack = TRUE;
 
-	acpi_gbl_permanent_mmap = 1;
+	acpi_permanent_mmap = true;
 
 	/*
 	 * If the machine falls into the DMI check table,
drivers/acpi/osl.c +5 -45

86 lines not on this page · raw message

include/acpi/acpi_io.h +2 -0
index d7d0f49..303315b 100644
@@ -13,6 +13,8 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
 }
 #endif
 
+extern bool acpi_permanent_mmap;
+
 void __iomem *__ref
 acpi_os_map_iomem(acpi_physical_address phys, acpi_size size);
 void __ref acpi_os_unmap_iomem(void __iomem *virt, acpi_size size);
include/acpi/acpixf.h +0 -13
index 33828dd..f5e10dd 100644
@@ -967,19 +967,6 @@
 /*
  * Divergences
  */
-ACPI_GLOBAL(u8, acpi_gbl_permanent_mmap);
-
-ACPI_EXTERNAL_RETURN_STATUS(acpi_status
-			    acpi_get_table_with_size(acpi_string signature,
-						     u32 instance,
-						     struct acpi_table_header
-						     **out_table,
-						     acpi_size *tbl_size))
-
-ACPI_EXTERNAL_RETURN_VOID(void
-			  early_acpi_os_unmap_memory(void __iomem * virt,
-						     acpi_size size))
-
 ACPI_EXTERNAL_RETURN_STATUS(acpi_status
 			    acpi_get_data_full(acpi_handle object,
 					       acpi_object_handler handler,
Signature · 1 line
1.7.10