Pārlūkot izejas kodu

BT: Add secure mode check to avoid BT ON

Adds secure peripheral check to ensure bluetooth is not powered on
if secure state for Bluetooth is enabled

Change-Id: I3ac13ec38ec30f03bf747d317fdacbe58f022cd0
satish kumar sugasi 2 gadi atpakaļ
vecāks
revīzija
594501303c
5 mainītis faili ar 117 papildinājumiem un 3 dzēšanām
  1. 13 0
      Android.mk
  2. 4 1
      Kbuild
  3. 2 0
      include/btpower.h
  4. 1 0
      pwr/Makefile
  5. 97 2
      pwr/btpower.c

+ 13 - 0
Android.mk

@@ -11,6 +11,12 @@ BT_SELECT += CONFIG_BTFM_SLIM=m
 #endif
 BT_SELECT += CONFIG_I2C_RTC6226_QCA=m
 
+ifeq ($(TARGET_KERNEL_DLKM_SECURE_MSM_OVERRIDE), true)
+ifeq ($(ENABLE_PERIPHERAL_STATE_UTILS), true)
+BT_SELECT += CONFIG_BT_HW_SECURE_DISABLE=y
+endif
+endif
+
 LOCAL_PATH := $(call my-dir)
 
 # This makefile is only for DLKM
@@ -33,6 +39,13 @@ BT_SRC_FILES := \
 	$(wildcard $(LOCAL_PATH)/*) \
 	$(wildcard $(LOCAL_PATH)/*/*) \
 
+ifeq ($(TARGET_KERNEL_DLKM_SECURE_MSM_OVERRIDE), true)
+ifeq ($(ENABLE_PERIPHERAL_STATE_UTILS), true)
+KBUILD_REQUIRED_KOS := smcinvoke_dlkm.ko
+endif
+endif
+
+
 # Module.symvers needs to be generated as a intermediate module so that
 # other modules which depend on BT platform modules can set local
 # dependencies to it.

+ 4 - 1
Kbuild

@@ -10,11 +10,14 @@ ifeq ($(CONFIG_I2C_RTC6226_QCA),m)
 KBUILD_CPPFLAGS += -DCONFIG_I2C_RTC6226_QCA
 endif
 
-
 ifeq ($(CONFIG_SLIM_BTFM_CODEC), m)
 KBUILD_CPPFLAGS += -DCONFIG_SLIM_BTFM_CODEC
 endif
 
+ifeq ($(CONFIG_BT_HW_SECURE_DISABLE), y)
+KBUILD_CPPFLAGS += -DCONFIG_BT_HW_SECURE_DISABLE
+endif
+
 obj-$(CONFIG_MSM_BT_POWER) += pwr/
 obj-$(CONFIG_BTFM_SLIM) += slimbus/
 obj-$(CONFIG_I2C_RTC6226_QCA) += rtc6226/

+ 2 - 0
include/btpower.h

@@ -78,6 +78,8 @@ struct btpower_platform_data {
 	int pdc_init_table_len;
 	const char **pdc_init_table;
 	int bt_device_type;
+	bool sec_peri_feature_disable;
+	int bt_sec_hw_disable;
 #ifdef CONFIG_MSM_BT_OOBS
 	struct file *reffilp_obs;
 	struct task_struct *reftask_obs;

+ 1 - 0
pwr/Makefile

@@ -1,2 +1,3 @@
 ccflags-y += -I$(BT_ROOT)/include
+
 obj-$(CONFIG_MSM_BT_POWER)  += btpower.o

+ 97 - 2
pwr/btpower.c

@@ -32,6 +32,18 @@
 #endif
 #include <linux/fs.h>
 
+#ifdef CONFIG_BT_HW_SECURE_DISABLE
+#include "linux/smcinvoke.h"
+#include "linux/smcinvoke_object.h"
+#include "linux/IClientEnv.h"
+
+#define PERISEC_HW_STATE_UID 0x108
+#define PERISEC_HW_OP_GET_STATE 1
+#define PERISEC_HW_BLUETOOTH_UID 0x502
+#define PERISEC_FEATURE_NOT_SUPPORTED 12
+#define PERISEC_PERIPHERAL_NOT_FOUND 10
+#endif
+
 #define PWR_SRC_NOT_AVAILABLE -2
 #define DEFAULT_INVALID_VALUE -1
 #define PWR_SRC_INIT_STATE_IDX 0
@@ -241,6 +253,76 @@ static int bt_major;
 static int soc_id;
 static bool probe_finished;
 
+
+#ifdef CONFIG_BT_HW_SECURE_DISABLE
+int perisec_cnss_bt_hw_disable_check(struct btpower_platform_data *plat_priv)
+{
+	struct Object client_env;
+	struct Object app_object;
+	int bt_uid = PERISEC_HW_BLUETOOTH_UID;
+	union ObjectArg obj_arg[2] = {{{0, 0}}};
+	int ret;
+	u8 state = 0;
+
+	/* Once this flag is set, secure peripheral feature
+	 * will not be supported till next reboot
+	 */
+	if (plat_priv->sec_peri_feature_disable)
+		return 0;
+
+	/* get rootObj */
+	ret = get_client_env_object(&client_env);
+	if (ret) {
+		pr_debug("Failed to get client_env_object, ret: %d\n", ret);
+		goto end;
+	}
+	ret = IClientEnv_open(client_env, PERISEC_HW_STATE_UID, &app_object);
+	if (ret) {
+		pr_debug("Failed to get app_object, ret: %d\n",  ret);
+		if (ret == PERISEC_FEATURE_NOT_SUPPORTED) {
+			ret = 0; /* Do not Assert */
+			plat_priv->sec_peri_feature_disable = true;
+			pr_debug("Secure HW feature not supported\n");
+		}
+		goto exit_release_clientenv;
+	}
+
+	obj_arg[0].b = (struct ObjectBuf) {&bt_uid, sizeof(u32)};
+	obj_arg[1].b = (struct ObjectBuf) {&state, sizeof(u8)};
+	ret = Object_invoke(app_object, PERISEC_HW_OP_GET_STATE, obj_arg,
+			    ObjectCounts_pack(1, 1, 0, 0));
+
+	pr_debug("SMC invoke ret: %d state: %d\n", ret, state);
+	if (ret) {
+		if (ret == PERISEC_PERIPHERAL_NOT_FOUND) {
+			ret = 0; /* Do not Assert */
+			plat_priv->sec_peri_feature_disable = true;
+			pr_debug("Secure HW mode is not updated. Peripheral not found\n");
+		}
+		Object_release(app_object);
+	} else {
+		if (state == 1)
+			plat_priv->bt_sec_hw_disable = 1;
+		else
+			plat_priv->bt_sec_hw_disable = 0;
+	}
+
+exit_release_clientenv:
+	Object_release(client_env);
+end:
+	if (ret) {
+		pr_err("SecMode:Unable to get sec mode BT Hardware status\n");
+	}
+	return ret;
+}
+#else
+int perisec_cnss_bt_hw_disable_check(struct btpower_platform_data *plat_priv)
+{
+	return 0;
+}
+#endif
+
+
 #ifdef CONFIG_MSM_BT_OOBS
 static void btpower_uart_transport_locked(struct btpower_platform_data *drvdata,
 					  bool locked)
@@ -682,7 +764,13 @@ static int bluetooth_power(int on)
 
 	pr_debug("%s: on: %d\n", __func__, on);
 
+	rc = perisec_cnss_bt_hw_disable_check(bt_power_pdata);
 	if (on == 1) {
+		if (bt_power_pdata->bt_sec_hw_disable) {
+			pr_err("%s:secure hw mode on,BT ON not allowed",
+				 __func__);
+			return -EINVAL;
+		}
 		rc = bt_power_vreg_set(BT_POWER_ENABLE);
 		if (rc < 0) {
 			pr_err("%s: bt_power regulators config failed\n",
@@ -714,8 +802,14 @@ static int bluetooth_power(int on)
 		}
 	} else if (on == 0) {
 		// Power Off
-		if (bt_power_pdata->bt_gpio_sys_rst > 0)
-			bt_configure_gpios(on);
+		if (bt_power_pdata->bt_gpio_sys_rst > 0) {
+			if (bt_power_pdata->bt_sec_hw_disable) {
+				pr_err("%s: secure hw mode on, not allowed to access gpio",
+					__func__);
+			}else {
+				bt_configure_gpios(on);
+			}
+		}
 gpio_fail:
 		if (bt_power_pdata->bt_gpio_sys_rst > 0)
 			gpio_free(bt_power_pdata->bt_gpio_sys_rst);
@@ -1106,6 +1200,7 @@ static int bt_power_probe(struct platform_device *pdev)
 
 	bt_power_pdata->pdev = pdev;
 
+	ret = perisec_cnss_bt_hw_disable_check(bt_power_pdata);
 	if (pdev->dev.of_node) {
 		ret = bt_power_populate_dt_pinfo(pdev);
 		if (ret < 0) {