diff mbox series

[13/14] wifi: iwlwifi: implement GLAI ACPI table loading

Message ID 20240128084842.53994809fbdd.I1bd10aafc387bc04f375e386861ee2bcb82f0a61@changeid (mailing list archive)
State Accepted
Delegated to: Johannes Berg
Headers show
Series wifi: iwlwifi: updates - 2024-01-28 | expand

Commit Message

Korenblit, Miriam Rachel Jan. 28, 2024, 6:53 a.m. UTC
All the regulatory tables from BIOS are going to be loaded
(preferably) from the UEFI instead of the ACPI.
There is a security issue with the fact that anyone can
add these UEFI variables.
The solution for that is to have a lock for all WIFI GUID UEFI
variables, and only if the UEFI variables are locked then we can
read it.
The status of the lock (unlocked, locked, test mode) is indicated
in a ACPI table: Guid Lock ACPI Indicator.
Load this table so the driver knows whether to read from UEFI or
not

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Reviewed-by: Gregory Greenman <gregory.greenman@intel.com>
---
 drivers/net/wireless/intel/iwlwifi/fw/acpi.c  | 35 +++++++++++++++++++
 drivers/net/wireless/intel/iwlwifi/fw/acpi.h  | 13 ++++++-
 .../net/wireless/intel/iwlwifi/fw/runtime.h   |  4 +++
 drivers/net/wireless/intel/iwlwifi/mvm/fw.c   |  2 ++
 4 files changed, 53 insertions(+), 1 deletion(-)
diff mbox series

Patch

diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
index 72a0a9565371..dd68d382d7de 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.c
@@ -1318,3 +1318,38 @@  void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
 	kfree(data);
 }
 IWL_EXPORT_SYMBOL(iwl_acpi_get_phy_filters);
+
+void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt)
+{
+	union acpi_object *wifi_pkg, *data;
+	int tbl_rev;
+
+	data = iwl_acpi_get_object(fwrt->dev, ACPI_GLAI_METHOD);
+	if (IS_ERR(data))
+		return;
+
+	wifi_pkg = iwl_acpi_get_wifi_pkg(fwrt->dev, data,
+					 ACPI_GLAI_WIFI_DATA_SIZE,
+					 &tbl_rev);
+	if (IS_ERR(wifi_pkg))
+		goto out_free;
+
+	if (tbl_rev != 0) {
+		IWL_DEBUG_RADIO(fwrt, "Invalid GLAI revision: %d\n", tbl_rev);
+		goto out_free;
+	}
+
+	if (wifi_pkg->package.elements[1].type != ACPI_TYPE_INTEGER ||
+	    wifi_pkg->package.elements[1].integer.value > ACPI_GLAI_MAX_STATUS)
+		goto out_free;
+
+	fwrt->uefi_tables_lock_status =
+		wifi_pkg->package.elements[1].integer.value;
+
+	IWL_DEBUG_RADIO(fwrt,
+			"Loaded UEFI WIFI GUID lock status: %d from ACPI\n",
+			fwrt->uefi_tables_lock_status);
+out_free:
+	kfree(data);
+}
+IWL_EXPORT_SYMBOL(iwl_acpi_get_guid_lock_status);
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
index 39106ccb4b9b..7b3c6fca7591 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/acpi.h
@@ -25,6 +25,7 @@ 
 #define ACPI_PPAG_METHOD	"PPAG"
 #define ACPI_WTAS_METHOD	"WTAS"
 #define ACPI_WPFC_METHOD	"WPFC"
+#define ACPI_GLAI_METHOD	"GLAI"
 
 #define ACPI_WIFI_DOMAIN	(0x07)
 
@@ -66,7 +67,12 @@ 
 #define ACPI_WRDD_WIFI_DATA_SIZE	2
 #define ACPI_SPLC_WIFI_DATA_SIZE	2
 #define ACPI_ECKV_WIFI_DATA_SIZE	2
-
+/*
+ * One element for domain type,
+ * and one for the status
+ */
+#define ACPI_GLAI_WIFI_DATA_SIZE	2
+#define ACPI_GLAI_MAX_STATUS		2
 /*
  * TAS size: 1 elelment for type,
  *	     1 element for enabled field,
@@ -237,6 +243,8 @@  bool iwl_acpi_is_ppag_approved(struct iwl_fw_runtime *fwrt);
 void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
 			      struct iwl_phy_specific_cfg *filters);
 
+void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt);
+
 #else /* CONFIG_ACPI */
 
 static inline void *iwl_acpi_get_dsm_object(struct device *dev, int rev,
@@ -331,6 +339,9 @@  static inline void iwl_acpi_get_phy_filters(struct iwl_fw_runtime *fwrt,
 {
 }
 
+static inline void iwl_acpi_get_guid_lock_status(struct iwl_fw_runtime *fwrt)
+{
+}
 #endif /* CONFIG_ACPI */
 
 #endif /* __iwl_fw_acpi__ */
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
index 357727774db9..1ec2bcdf92b8 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
+++ b/drivers/net/wireless/intel/iwlwifi/fw/runtime.h
@@ -100,6 +100,9 @@  struct iwl_txf_iter_data {
  * @dump: debug dump data
  * @uats_enabled: VLP or AFC AP is enabled
  * @uats_table: AP type table
+ * @uefi_tables_lock_status: The status of the WIFI GUID UEFI variables lock:
+ *	0: Unlocked, 1 and 2: Locked.
+ *	Only read the UEFI variables if locked.
  */
 struct iwl_fw_runtime {
 	struct iwl_trans *trans;
@@ -175,6 +178,7 @@  struct iwl_fw_runtime {
 	u8 reduced_power_flags;
 	bool uats_enabled;
 	struct iwl_uats_table_cmd uats_table;
+	u8 uefi_tables_lock_status;
 #endif
 };
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
index 175024170357..a6db290923cd 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c
@@ -1402,6 +1402,8 @@  void iwl_mvm_get_acpi_tables(struct iwl_mvm *mvm)
 {
 	int ret;
 
+	iwl_acpi_get_guid_lock_status(&mvm->fwrt);
+
 	/* read PPAG table */
 	ret = iwl_acpi_get_ppag_table(&mvm->fwrt);
 	if (ret < 0) {