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) {