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

Commit 7c43312a authored by Lv Zheng's avatar Lv Zheng Committed by Rafael J. Wysocki
Browse files

ACPICA: Events: Cleanup GPE dispatcher type obtaining code

ACPICA commit 7926d5ca9452c87f866938dcea8f12e1efb58f89

There is an issue in acpi_install_gpe_handler() and acpi_remove_gpe_handler().
The code to obtain the GPE dispatcher type from the Handler->original_flags
is wrong:
    if (((Handler->original_flags & ACPI_GPE_DISPATCH_METHOD) ||
         (Handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) &&
ACPI_GPE_DISPATCH_NOTIFY is 0x03 and ACPI_GPE_DISPATCH_METHOD is 0x02, thus
this statement is TRUE for the following dispatcher types:
    0x01 (ACPI_GPE_DISPATCH_HANDLER): not expected
    0x02 (ACPI_GPE_DISPATCH_METHOD): expected
    0x03 (ACPI_GPE_DISPATCH_NOTIFY): expected

There is no functional issue due to this because Handler->original_flags is
only set in acpi_install_gpe_handler(), and an earlier checker has excluded
the ACPI_GPE_DISPATCH_HANDLER:
    if ((gpe_event_info->Flags & ACPI_GPE_DISPATCH_MASK) ==
            ACPI_GPE_DISPATCH_HANDLER)
    {
        Status = AE_ALREADY_EXISTS;
        goto free_and_exit;
    }
    ...
    Handler->original_flags = (u8) (gpe_event_info->Flags &
        (ACPI_GPE_XRUPT_TYPE_MASK | ACPI_GPE_DISPATCH_MASK));

We need to clean this up before modifying the GPE dispatcher type values.

In order to prevent such issue from happening in the future, this patch
introduces ACPI_GPE_DISPATCH_TYPE() macro to be used to obtain the GPE
dispatcher types. Lv Zheng.

Link: https://github.com/acpica/acpica/commit/7926d5ca


Signed-off-by: default avatarLv Zheng <lv.zheng@intel.com>
Signed-off-by: default avatarDavid E. Box <david.e.box@linux.intel.com>
Signed-off-by: default avatarBob Moore <robert.moore@intel.com>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent 779ba5a3
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -503,7 +503,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context)

	/* Do the correct dispatch - normal method or implicit notify */

	switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
	switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
	case ACPI_GPE_DISPATCH_NOTIFY:
		/*
		 * Implicit notify.
@@ -707,7 +707,7 @@ acpi_ev_gpe_dispatch(struct acpi_namespace_node *gpe_device,
	 * If there is neither a handler nor a method, leave the GPE
	 * disabled.
	 */
	switch (gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) {
	switch (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)) {
	case ACPI_GPE_DISPATCH_HANDLER:

		/* Invoke the installed handler (at interrupt level) */
+3 −3
Original line number Diff line number Diff line
@@ -474,10 +474,10 @@ acpi_ev_initialize_gpe_block(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
			 * Ignore GPEs that have no corresponding _Lxx/_Exx method
			 * and GPEs that are used to wake the system
			 */
			if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
			if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
			     ACPI_GPE_DISPATCH_NONE)
			    || ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK)
				== ACPI_GPE_DISPATCH_HANDLER)
			    || (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
				ACPI_GPE_DISPATCH_HANDLER)
			    || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) {
				continue;
			}
+2 −2
Original line number Diff line number Diff line
@@ -401,7 +401,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
		return_ACPI_STATUS(AE_OK);
	}

	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
	if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
	    ACPI_GPE_DISPATCH_HANDLER) {

		/* If there is already a handler, ignore this GPE method */
@@ -409,7 +409,7 @@ acpi_ev_match_gpe_method(acpi_handle obj_handle,
		return_ACPI_STATUS(AE_OK);
	}

	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
	if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
	    ACPI_GPE_DISPATCH_METHOD) {
		/*
		 * If there is already a method, ignore this method. But check
+3 −5
Original line number Diff line number Diff line
@@ -324,7 +324,7 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
								 ACPI_GPE_REGISTER_WIDTH)
								+ j];

			if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
			if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
			    ACPI_GPE_DISPATCH_HANDLER) {

				/* Delete an installed handler block */
@@ -333,10 +333,8 @@ acpi_ev_delete_gpe_handlers(struct acpi_gpe_xrupt_info *gpe_xrupt_info,
				gpe_event_info->dispatch.handler = NULL;
				gpe_event_info->flags &=
				    ~ACPI_GPE_DISPATCH_MASK;
			} else
			    if ((gpe_event_info->
				 flags & ACPI_GPE_DISPATCH_MASK) ==
				ACPI_GPE_DISPATCH_NOTIFY) {
			} else if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags)
				   == ACPI_GPE_DISPATCH_NOTIFY) {

				/* Delete the implicit notification device list */

+10 −8
Original line number Diff line number Diff line
@@ -775,7 +775,7 @@ acpi_install_gpe_handler(acpi_handle gpe_device,

	/* Make sure that there isn't a handler there already */

	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) ==
	if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) ==
	    ACPI_GPE_DISPATCH_HANDLER) {
		status = AE_ALREADY_EXISTS;
		goto free_and_exit;
@@ -793,9 +793,10 @@ acpi_install_gpe_handler(acpi_handle gpe_device,
	 * automatically during initialization, in which case it has to be
	 * disabled now to avoid spurious execution of the handler.
	 */
	if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) ||
	     (handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) &&
	    gpe_event_info->runtime_count) {
	if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
	      ACPI_GPE_DISPATCH_METHOD) ||
	     (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
	      ACPI_GPE_DISPATCH_NOTIFY)) && gpe_event_info->runtime_count) {
		handler->originally_enabled = TRUE;
		(void)acpi_ev_remove_gpe_reference(gpe_event_info);

@@ -880,7 +881,7 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,

	/* Make sure that a handler is indeed installed */

	if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) !=
	if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) !=
	    ACPI_GPE_DISPATCH_HANDLER) {
		status = AE_NOT_EXIST;
		goto unlock_and_exit;
@@ -910,9 +911,10 @@ acpi_remove_gpe_handler(acpi_handle gpe_device,
	 * enabled, it should be enabled at this point to restore the
	 * post-initialization configuration.
	 */
	if (((handler->original_flags & ACPI_GPE_DISPATCH_METHOD) ||
	     (handler->original_flags & ACPI_GPE_DISPATCH_NOTIFY)) &&
	    handler->originally_enabled) {
	if (((ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
	      ACPI_GPE_DISPATCH_METHOD) ||
	     (ACPI_GPE_DISPATCH_TYPE(handler->original_flags) ==
	      ACPI_GPE_DISPATCH_NOTIFY)) && handler->originally_enabled) {
		(void)acpi_ev_add_gpe_reference(gpe_event_info);
	}

Loading