File 0006-ivsc-load-symbols-by-kprobe.patch of Package intel-ipu6

From: TheSola10 <me@thesola.io>
Date: Thu, 1 Sep 2022 14:12:12 +0200
Subject: ivsc: load symbols by kprobe

Signed-off-by: You-Sheng Yang (vicamo) <vicamo.yang@canonical.com>
---
 Makefile                     |  4 ++-
 backport-include/linux/vsc.h | 63 ++++++++++++++++++++++++++++++++++++++++----
 drivers/media/i2c/hi556.c    |  7 +++++
 drivers/media/i2c/hm2170.c   |  7 +++++
 drivers/media/i2c/hm2172.c   |  7 +++++
 drivers/media/i2c/ov01a10.c  |  7 +++++
 drivers/media/i2c/ov01a1s.c  |  7 +++++
 drivers/media/i2c/ov02c10.c  |  7 +++++
 drivers/media/i2c/ov02e10.c  |  7 +++++
 9 files changed, 110 insertions(+), 6 deletions(-)

diff --git a/Makefile b/Makefile
index 1eb8dcb..d9ba6bb 100644
--- a/Makefile
+++ b/Makefile
@@ -61,7 +61,9 @@ ifeq ($(call version_lt,$(KERNEL_VERSION),$(KV_IVSC)),true)
 ccflags-y += -I$(src)/backport-include/drivers/misc/mei/
 endif
 
-subdir-ccflags-y += -I$(src)/include/ \
+subdir-ccflags-y += \
+	-I$(src)/backport-include/ \
+	-I$(src)/include/ \
 	-DCONFIG_VIDEO_V4L2_SUBDEV_API=1
 
 subdir-ccflags-$(CONFIG_IPU_ISYS_BRIDGE) += \
diff --git a/backport-include/linux/vsc.h b/backport-include/linux/vsc.h
index 8f8d404..71486dd 100644
--- a/backport-include/linux/vsc.h
+++ b/backport-include/linux/vsc.h
@@ -4,6 +4,15 @@
 #define _LINUX_VSC_H_
 
 #include <linux/types.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0))
+#include <linux/kprobes.h>
+#ifndef CONFIG_KPROBES
+# error "You need kprobes :("
+#endif
+#endif
+
 
 /**
  * @brief VSC camera ownership definition
@@ -48,6 +57,42 @@ struct vsc_camera_status {
 typedef void (*vsc_privacy_callback_t)(void *handle,
 				       enum vsc_privacy_status status);
 
+
+typedef int (*vsc_acquire_camera_sensor_t)(struct vsc_mipi_config *,
+					   vsc_privacy_callback_t,
+					   void *,
+					   struct vsc_camera_status *);
+typedef int (*vsc_release_camera_sensor_t)(struct vsc_camera_status *);
+
+static vsc_acquire_camera_sensor_t __p_vsc_acquire_camera_sensor = NULL;
+static vsc_release_camera_sensor_t __p_vsc_release_camera_sensor = NULL;
+
+static int init_vsc_symbols(void)
+{
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0))
+	typedef unsigned long (*kallsyms_lookup_name_t)(const char *name);
+	struct kprobe probe;
+	int ret;
+	kallsyms_lookup_name_t kallsyms_lookup_name;
+
+	memset(&probe, 0, sizeof(probe));
+	probe.symbol_name = "kallsyms_lookup_name";
+	ret = register_kprobe(&probe);
+	if (ret)
+		return ret;
+
+	kallsyms_lookup_name = (kallsyms_lookup_name_t) probe.addr;
+	unregister_kprobe(&probe);
+#endif
+
+	__p_vsc_acquire_camera_sensor =
+		(vsc_acquire_camera_sensor_t) kallsyms_lookup_name("vsc_acquire_camera_sensor");
+	__p_vsc_release_camera_sensor =
+		(vsc_release_camera_sensor_t) kallsyms_lookup_name("vsc_release_camera_sensor");
+
+	return 0;
+}
+
 /**
  * @brief Acquire camera sensor ownership to IPU
  *
@@ -62,10 +107,13 @@ typedef void (*vsc_privacy_callback_t)(void *handle,
  * @retval -EAGAIN VSC device not ready
  * @retval negative values for other errors
  */
-int vsc_acquire_camera_sensor(struct vsc_mipi_config *config,
-			      vsc_privacy_callback_t callback,
-			      void *handle,
-			      struct vsc_camera_status *status);
+static int vsc_acquire_camera_sensor(struct vsc_mipi_config *config,
+				      vsc_privacy_callback_t callback,
+				      void *handle,
+				      struct vsc_camera_status *status)
+{
+	return __p_vsc_acquire_camera_sensor(config, callback, handle, status);
+}
 
 /**
  * @brief Release camera sensor ownership
@@ -78,6 +126,11 @@ int vsc_acquire_camera_sensor(struct vsc_mipi_config *config,
  * @retval -EAGAIN VSC device not ready
  * @retval negative values for other errors
  */
-int vsc_release_camera_sensor(struct vsc_camera_status *status);
+static int vsc_release_camera_sensor(struct vsc_camera_status *status)
+{
+	return __p_vsc_release_camera_sensor(status);
+}
+
+MODULE_SOFTDEP("pre: intel_vsc");
 
 #endif
diff --git a/drivers/media/i2c/hi556.c b/drivers/media/i2c/hi556.c
index 4fc020b..a67df87 100644
--- a/drivers/media/i2c/hi556.c
+++ b/drivers/media/i2c/hi556.c
@@ -1369,6 +1369,13 @@ static int hi556_probe(struct i2c_client *client)
 	bool full_power;
 	int ret;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && \
+    IS_ENABLED(CONFIG_INTEL_VSC)
+	ret = init_vsc_symbols();
+	if (ret)
+		return ret;
+#endif
+
 	ret = hi556_check_hwcfg(&client->dev);
 	if (ret)
 		return dev_err_probe(&client->dev, ret,
diff --git a/drivers/media/i2c/hm2170.c b/drivers/media/i2c/hm2170.c
index 102eec2..19d3734 100644
--- a/drivers/media/i2c/hm2170.c
+++ b/drivers/media/i2c/hm2170.c
@@ -1309,6 +1309,13 @@ static int hm2170_probe(struct i2c_client *client)
 	struct hm2170 *hm2170;
 	int ret = 0;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && \
+    IS_ENABLED(CONFIG_INTEL_VSC)
+	ret = init_vsc_symbols();
+	if (ret)
+		return ret;
+#endif
+
 	/* Check HW config */
 	ret = hm2170_check_hwcfg(&client->dev);
 	if (ret) {
diff --git a/drivers/media/i2c/hm2172.c b/drivers/media/i2c/hm2172.c
index 3362d31..a10f9ad 100644
--- a/drivers/media/i2c/hm2172.c
+++ b/drivers/media/i2c/hm2172.c
@@ -1737,6 +1737,13 @@ static int hm2172_probe(struct i2c_client *client)
 	struct hm2172 *hm217;
 	int ret;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && \
+    IS_ENABLED(CONFIG_INTEL_VSC)
+	ret = init_vsc_symbols();
+	if (ret)
+		return ret;
+#endif
+
 	/* Check HW config */
 	ret = hm2172_check_hwcfg(&client->dev);
 	if (ret) {
diff --git a/drivers/media/i2c/ov01a10.c b/drivers/media/i2c/ov01a10.c
index 78ae018..d08fbe9 100644
--- a/drivers/media/i2c/ov01a10.c
+++ b/drivers/media/i2c/ov01a10.c
@@ -1004,6 +1004,13 @@ static int ov01a10_probe(struct i2c_client *client)
 	struct ov01a10 *ov01a10;
 	int ret = 0;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && \
+    IS_ENABLED(CONFIG_INTEL_VSC)
+	ret = init_vsc_symbols();
+	if (ret)
+		return ret;
+#endif
+
 	/* Check HW config */
 	ret = ov01a10_check_hwcfg(&client->dev);
 	if (ret) {
diff --git a/drivers/media/i2c/ov01a1s.c b/drivers/media/i2c/ov01a1s.c
index f7cf221..eb2b792 100644
--- a/drivers/media/i2c/ov01a1s.c
+++ b/drivers/media/i2c/ov01a1s.c
@@ -1160,6 +1160,13 @@ static int ov01a1s_probe(struct i2c_client *client)
 	struct ov01a1s *ov01a1s;
 	int ret = 0;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && \
+    IS_ENABLED(CONFIG_INTEL_VSC)
+	ret = init_vsc_symbols();
+	if (ret)
+		return ret;
+#endif
+
 	/* Check HW config */
 	ret = ov01a1s_check_hwcfg(&client->dev);
 	if (ret) {
diff --git a/drivers/media/i2c/ov02c10.c b/drivers/media/i2c/ov02c10.c
index 95e1638..a6194f4 100644
--- a/drivers/media/i2c/ov02c10.c
+++ b/drivers/media/i2c/ov02c10.c
@@ -1491,6 +1491,13 @@ static int ov02c10_probe(struct i2c_client *client)
 	struct ov02c10 *ov02c10;
 	int ret = 0;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && \
+    IS_ENABLED(CONFIG_INTEL_VSC)
+	ret = init_vsc_symbols();
+	if (ret)
+		return ret;
+#endif
+
 	/* Check HW config */
 	ret = ov02c10_check_hwcfg(&client->dev);
 	if (ret) {
diff --git a/drivers/media/i2c/ov02e10.c b/drivers/media/i2c/ov02e10.c
index 916def9..7004354 100644
--- a/drivers/media/i2c/ov02e10.c
+++ b/drivers/media/i2c/ov02e10.c
@@ -1124,6 +1124,13 @@ static int ov02e10_probe(struct i2c_client *client)
 	struct ov02e10 *ov02e;
 	int ret;
 
+#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0) && \
+    IS_ENABLED(CONFIG_INTEL_VSC)
+	ret = init_vsc_symbols();
+	if (ret)
+		return ret;
+#endif
+
 	/* Check HW config */
 	ret = ov02e10_check_hwcfg(&client->dev);
 	if (ret) {
openSUSE Build Service is sponsored by