cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

utmutex.c (8580B)


      1// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
      2/*******************************************************************************
      3 *
      4 * Module Name: utmutex - local mutex support
      5 *
      6 ******************************************************************************/
      7
      8#include <acpi/acpi.h>
      9#include "accommon.h"
     10
     11#define _COMPONENT          ACPI_UTILITIES
     12ACPI_MODULE_NAME("utmutex")
     13
     14/* Local prototypes */
     15static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id);
     16
     17static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id);
     18
     19/*******************************************************************************
     20 *
     21 * FUNCTION:    acpi_ut_mutex_initialize
     22 *
     23 * PARAMETERS:  None.
     24 *
     25 * RETURN:      Status
     26 *
     27 * DESCRIPTION: Create the system mutex objects. This includes mutexes,
     28 *              spin locks, and reader/writer locks.
     29 *
     30 ******************************************************************************/
     31
     32acpi_status acpi_ut_mutex_initialize(void)
     33{
     34	u32 i;
     35	acpi_status status;
     36
     37	ACPI_FUNCTION_TRACE(ut_mutex_initialize);
     38
     39	/* Create each of the predefined mutex objects */
     40
     41	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
     42		status = acpi_ut_create_mutex(i);
     43		if (ACPI_FAILURE(status)) {
     44			return_ACPI_STATUS(status);
     45		}
     46	}
     47
     48	/* Create the spinlocks for use at interrupt level or for speed */
     49
     50	status = acpi_os_create_lock (&acpi_gbl_gpe_lock);
     51	if (ACPI_FAILURE (status)) {
     52		return_ACPI_STATUS (status);
     53	}
     54
     55	status = acpi_os_create_raw_lock(&acpi_gbl_hardware_lock);
     56	if (ACPI_FAILURE (status)) {
     57		return_ACPI_STATUS (status);
     58	}
     59
     60	status = acpi_os_create_lock(&acpi_gbl_reference_count_lock);
     61	if (ACPI_FAILURE(status)) {
     62		return_ACPI_STATUS(status);
     63	}
     64
     65	/* Mutex for _OSI support */
     66
     67	status = acpi_os_create_mutex(&acpi_gbl_osi_mutex);
     68	if (ACPI_FAILURE(status)) {
     69		return_ACPI_STATUS(status);
     70	}
     71
     72	/* Create the reader/writer lock for namespace access */
     73
     74	status = acpi_ut_create_rw_lock(&acpi_gbl_namespace_rw_lock);
     75	if (ACPI_FAILURE(status)) {
     76		return_ACPI_STATUS(status);
     77	}
     78
     79	return_ACPI_STATUS(status);
     80}
     81
     82/*******************************************************************************
     83 *
     84 * FUNCTION:    acpi_ut_mutex_terminate
     85 *
     86 * PARAMETERS:  None.
     87 *
     88 * RETURN:      None.
     89 *
     90 * DESCRIPTION: Delete all of the system mutex objects. This includes mutexes,
     91 *              spin locks, and reader/writer locks.
     92 *
     93 ******************************************************************************/
     94
     95void acpi_ut_mutex_terminate(void)
     96{
     97	u32 i;
     98
     99	ACPI_FUNCTION_TRACE(ut_mutex_terminate);
    100
    101	/* Delete each predefined mutex object */
    102
    103	for (i = 0; i < ACPI_NUM_MUTEX; i++) {
    104		acpi_ut_delete_mutex(i);
    105	}
    106
    107	acpi_os_delete_mutex(acpi_gbl_osi_mutex);
    108
    109	/* Delete the spinlocks */
    110
    111	acpi_os_delete_lock(acpi_gbl_gpe_lock);
    112	acpi_os_delete_raw_lock(acpi_gbl_hardware_lock);
    113	acpi_os_delete_lock(acpi_gbl_reference_count_lock);
    114
    115	/* Delete the reader/writer lock */
    116
    117	acpi_ut_delete_rw_lock(&acpi_gbl_namespace_rw_lock);
    118	return_VOID;
    119}
    120
    121/*******************************************************************************
    122 *
    123 * FUNCTION:    acpi_ut_create_mutex
    124 *
    125 * PARAMETERS:  mutex_ID        - ID of the mutex to be created
    126 *
    127 * RETURN:      Status
    128 *
    129 * DESCRIPTION: Create a mutex object.
    130 *
    131 ******************************************************************************/
    132
    133static acpi_status acpi_ut_create_mutex(acpi_mutex_handle mutex_id)
    134{
    135	acpi_status status = AE_OK;
    136
    137	ACPI_FUNCTION_TRACE_U32(ut_create_mutex, mutex_id);
    138
    139	if (!acpi_gbl_mutex_info[mutex_id].mutex) {
    140		status =
    141		    acpi_os_create_mutex(&acpi_gbl_mutex_info[mutex_id].mutex);
    142		acpi_gbl_mutex_info[mutex_id].thread_id =
    143		    ACPI_MUTEX_NOT_ACQUIRED;
    144		acpi_gbl_mutex_info[mutex_id].use_count = 0;
    145	}
    146
    147	return_ACPI_STATUS(status);
    148}
    149
    150/*******************************************************************************
    151 *
    152 * FUNCTION:    acpi_ut_delete_mutex
    153 *
    154 * PARAMETERS:  mutex_ID        - ID of the mutex to be deleted
    155 *
    156 * RETURN:      Status
    157 *
    158 * DESCRIPTION: Delete a mutex object.
    159 *
    160 ******************************************************************************/
    161
    162static void acpi_ut_delete_mutex(acpi_mutex_handle mutex_id)
    163{
    164
    165	ACPI_FUNCTION_TRACE_U32(ut_delete_mutex, mutex_id);
    166
    167	acpi_os_delete_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
    168
    169	acpi_gbl_mutex_info[mutex_id].mutex = NULL;
    170	acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
    171
    172	return_VOID;
    173}
    174
    175/*******************************************************************************
    176 *
    177 * FUNCTION:    acpi_ut_acquire_mutex
    178 *
    179 * PARAMETERS:  mutex_ID        - ID of the mutex to be acquired
    180 *
    181 * RETURN:      Status
    182 *
    183 * DESCRIPTION: Acquire a mutex object.
    184 *
    185 ******************************************************************************/
    186
    187acpi_status acpi_ut_acquire_mutex(acpi_mutex_handle mutex_id)
    188{
    189	acpi_status status;
    190	acpi_thread_id this_thread_id;
    191
    192	ACPI_FUNCTION_NAME(ut_acquire_mutex);
    193
    194	if (mutex_id > ACPI_MAX_MUTEX) {
    195		return (AE_BAD_PARAMETER);
    196	}
    197
    198	this_thread_id = acpi_os_get_thread_id();
    199
    200#ifdef ACPI_MUTEX_DEBUG
    201	{
    202		u32 i;
    203		/*
    204		 * Mutex debug code, for internal debugging only.
    205		 *
    206		 * Deadlock prevention. Check if this thread owns any mutexes of value
    207		 * greater than or equal to this one. If so, the thread has violated
    208		 * the mutex ordering rule. This indicates a coding error somewhere in
    209		 * the ACPI subsystem code.
    210		 */
    211		for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
    212			if (acpi_gbl_mutex_info[i].thread_id == this_thread_id) {
    213				if (i == mutex_id) {
    214					ACPI_ERROR((AE_INFO,
    215						    "Mutex [%s] already acquired by this thread [%u]",
    216						    acpi_ut_get_mutex_name
    217						    (mutex_id),
    218						    (u32)this_thread_id));
    219
    220					return (AE_ALREADY_ACQUIRED);
    221				}
    222
    223				ACPI_ERROR((AE_INFO,
    224					    "Invalid acquire order: Thread %u owns [%s], wants [%s]",
    225					    (u32)this_thread_id,
    226					    acpi_ut_get_mutex_name(i),
    227					    acpi_ut_get_mutex_name(mutex_id)));
    228
    229				return (AE_ACQUIRE_DEADLOCK);
    230			}
    231		}
    232	}
    233#endif
    234
    235	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
    236			  "Thread %u attempting to acquire Mutex [%s]\n",
    237			  (u32)this_thread_id,
    238			  acpi_ut_get_mutex_name(mutex_id)));
    239
    240	status =
    241	    acpi_os_acquire_mutex(acpi_gbl_mutex_info[mutex_id].mutex,
    242				  ACPI_WAIT_FOREVER);
    243	if (ACPI_SUCCESS(status)) {
    244		ACPI_DEBUG_PRINT((ACPI_DB_MUTEX,
    245				  "Thread %u acquired Mutex [%s]\n",
    246				  (u32)this_thread_id,
    247				  acpi_ut_get_mutex_name(mutex_id)));
    248
    249		acpi_gbl_mutex_info[mutex_id].use_count++;
    250		acpi_gbl_mutex_info[mutex_id].thread_id = this_thread_id;
    251	} else {
    252		ACPI_EXCEPTION((AE_INFO, status,
    253				"Thread %u could not acquire Mutex [%s] (0x%X)",
    254				(u32)this_thread_id,
    255				acpi_ut_get_mutex_name(mutex_id), mutex_id));
    256	}
    257
    258	return (status);
    259}
    260
    261/*******************************************************************************
    262 *
    263 * FUNCTION:    acpi_ut_release_mutex
    264 *
    265 * PARAMETERS:  mutex_ID        - ID of the mutex to be released
    266 *
    267 * RETURN:      Status
    268 *
    269 * DESCRIPTION: Release a mutex object.
    270 *
    271 ******************************************************************************/
    272
    273acpi_status acpi_ut_release_mutex(acpi_mutex_handle mutex_id)
    274{
    275	ACPI_FUNCTION_NAME(ut_release_mutex);
    276
    277	ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "Thread %u releasing Mutex [%s]\n",
    278			  (u32)acpi_os_get_thread_id(),
    279			  acpi_ut_get_mutex_name(mutex_id)));
    280
    281	if (mutex_id > ACPI_MAX_MUTEX) {
    282		return (AE_BAD_PARAMETER);
    283	}
    284
    285	/*
    286	 * Mutex must be acquired in order to release it!
    287	 */
    288	if (acpi_gbl_mutex_info[mutex_id].thread_id == ACPI_MUTEX_NOT_ACQUIRED) {
    289		ACPI_ERROR((AE_INFO,
    290			    "Mutex [%s] (0x%X) is not acquired, cannot release",
    291			    acpi_ut_get_mutex_name(mutex_id), mutex_id));
    292
    293		return (AE_NOT_ACQUIRED);
    294	}
    295#ifdef ACPI_MUTEX_DEBUG
    296	{
    297		u32 i;
    298		/*
    299		 * Mutex debug code, for internal debugging only.
    300		 *
    301		 * Deadlock prevention. Check if this thread owns any mutexes of value
    302		 * greater than this one. If so, the thread has violated the mutex
    303		 * ordering rule. This indicates a coding error somewhere in
    304		 * the ACPI subsystem code.
    305		 */
    306		for (i = mutex_id; i < ACPI_NUM_MUTEX; i++) {
    307			if (acpi_gbl_mutex_info[i].thread_id ==
    308			    acpi_os_get_thread_id()) {
    309				if (i == mutex_id) {
    310					continue;
    311				}
    312
    313				ACPI_ERROR((AE_INFO,
    314					    "Invalid release order: owns [%s], releasing [%s]",
    315					    acpi_ut_get_mutex_name(i),
    316					    acpi_ut_get_mutex_name(mutex_id)));
    317
    318				return (AE_RELEASE_DEADLOCK);
    319			}
    320		}
    321	}
    322#endif
    323
    324	/* Mark unlocked FIRST */
    325
    326	acpi_gbl_mutex_info[mutex_id].thread_id = ACPI_MUTEX_NOT_ACQUIRED;
    327
    328	acpi_os_release_mutex(acpi_gbl_mutex_info[mutex_id].mutex);
    329	return (AE_OK);
    330}