All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable
@ 2022-06-03 10:26 Etienne Carriere
  2022-06-03 10:27 ` [PATCH v2 2/3] drivers: tee: optee: discover OP-TEE services Etienne Carriere
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Etienne Carriere @ 2022-06-03 10:26 UTC (permalink / raw)
  To: u-boot; +Cc: Etienne Carriere, Patrick Delaunay

Removes local variable child in optee_probe() that is not used.

Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
---
New change not in v1 series.
---
 drivers/tee/optee/core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index a89d62aaf0..c1f5fc4c7a 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -642,7 +642,6 @@ static int optee_probe(struct udevice *dev)
 {
 	struct optee_pdata *pdata = dev_get_plat(dev);
 	u32 sec_caps;
-	struct udevice *child;
 	int ret;
 
 	if (!is_optee_api(pdata->invoke_fn)) {
@@ -673,7 +672,7 @@ static int optee_probe(struct udevice *dev)
 	 * only bind the drivers associated to the supported OP-TEE TA
 	 */
 	if (IS_ENABLED(CONFIG_RNG_OPTEE)) {
-		ret = device_bind_driver(dev, "optee-rng", "optee-rng", &child);
+		ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL);
 		if (ret)
 			return ret;
 	}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 2/3] drivers: tee: optee: discover OP-TEE services
  2022-06-03 10:26 [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable Etienne Carriere
@ 2022-06-03 10:27 ` Etienne Carriere
  2022-06-06 11:35   ` Patrick DELAUNAY
  2022-06-03 10:27 ` [PATCH v2 3/3] drivers: rng: optee_rng: register to CONFIG_OPTEE_SERVICE_DISCOVERY Etienne Carriere
  2022-06-06 11:26 ` [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable Patrick DELAUNAY
  2 siblings, 1 reply; 6+ messages in thread
From: Etienne Carriere @ 2022-06-03 10:27 UTC (permalink / raw)
  To: u-boot; +Cc: Etienne Carriere, Jens Wiklander, Patrick Delaunay

This change defines resources for OP-TEE service drivers to register
themselves for being bound to when OP-TEE firmware reports the related
service is supported. OP-TEE services are discovered during optee
driver probe sequence which mandates optee driver is always probe once
bound.

Discovery of optee services and binding to related U-Boot drivers is
embedded upon configuration switch CONFIG_OPTEE_SERVICE_DISCOVERY.

Cc: Jens Wiklander <jens.wiklander@linaro.org>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
---
Changes since v1:
- Remove all #ifdef CONFIG_OPTEE_SERVICE_DISCOVERY directives and replace
  with if (IS_ENABLED()) where applicable.
- Incidentally rename local function open_session() to open_enum_session()
  and remove local function close_session() for clarity.
- Update commit log to highlight that "optee driver is always probe once
  bound" when CONFIG_OPTEE_SERVICE_DISCOVERY is enable.
---
 drivers/tee/optee/Kconfig   |   8 ++
 drivers/tee/optee/core.c    | 175 ++++++++++++++++++++++++++++++++++--
 include/tee/optee_service.h |  29 ++++++
 3 files changed, 207 insertions(+), 5 deletions(-)
 create mode 100644 include/tee/optee_service.h

diff --git a/drivers/tee/optee/Kconfig b/drivers/tee/optee/Kconfig
index d03028070b..9dc65b0501 100644
--- a/drivers/tee/optee/Kconfig
+++ b/drivers/tee/optee/Kconfig
@@ -37,6 +37,14 @@ config OPTEE_TA_SCP03
 	help
 	  Enables support for controlling (enabling, provisioning) the
 	  Secure Channel Protocol 03 operation in the OP-TEE SCP03 TA.
+
+config OPTEE_SERVICE_DISCOVERY
+	bool "OP-TEE service discovery"
+	default y
+	help
+	  This implements automated driver binding of OP-TEE service drivers by
+	  requesting OP-TEE firmware to enumerate its hosted services.
+
 endmenu
 
 endif
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index c1f5fc4c7a..9a90760379 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -14,6 +14,7 @@
 #include <linux/arm-smccc.h>
 #include <linux/err.h>
 #include <linux/io.h>
+#include <tee/optee_service.h>
 
 #include "optee_smc.h"
 #include "optee_msg.h"
@@ -22,6 +23,25 @@
 #define PAGELIST_ENTRIES_PER_PAGE \
 	((OPTEE_MSG_NONCONTIG_PAGE_SIZE / sizeof(u64)) - 1)
 
+/*
+ * PTA_DEVICE_ENUM interface exposed by OP-TEE to discover enumerated services
+ */
+#define PTA_DEVICE_ENUM		{ 0x7011a688, 0xddde, 0x4053, \
+				  { 0xa5, 0xa9, 0x7b, 0x3c, 0x4d, 0xdf, 0x13, 0xb8 } }
+/*
+ * PTA_CMD_GET_DEVICES - List services without supplicant dependencies
+ *
+ * [out]    memref[0]: List of the UUIDs of service enumerated by OP-TEE
+ */
+#define PTA_CMD_GET_DEVICES		0x0
+
+/*
+ * PTA_CMD_GET_DEVICES_SUPP - List services depending on tee supplicant
+ *
+ * [out]    memref[0]: List of the UUIDs of service enumerated by OP-TEE
+ */
+#define PTA_CMD_GET_DEVICES_SUPP	0x1
+
 typedef void (optee_invoke_fn)(unsigned long, unsigned long, unsigned long,
 			       unsigned long, unsigned long, unsigned long,
 			       unsigned long, unsigned long,
@@ -42,6 +62,138 @@ struct rpc_param {
 	u32	a7;
 };
 
+static struct optee_service *find_service_driver(const struct tee_optee_ta_uuid *uuid)
+{
+	struct optee_service *service;
+	u8 loc_uuid[TEE_UUID_LEN];
+	size_t service_cnt, idx;
+
+	service_cnt = ll_entry_count(struct optee_service, optee_service);
+	service = ll_entry_start(struct optee_service, optee_service);
+
+	for (idx = 0; idx < service_cnt; idx++, service++) {
+		tee_optee_ta_uuid_to_octets(loc_uuid, &service->uuid);
+		if (!memcmp(uuid, loc_uuid, sizeof(uuid)))
+			return service;
+	}
+
+	return NULL;
+}
+
+static int bind_service_list(struct udevice *dev, struct tee_shm *service_list, size_t count)
+{
+	const struct tee_optee_ta_uuid *service_uuid = (const void *)service_list->addr;
+	struct optee_service *service;
+	size_t idx;
+	int ret;
+
+	for (idx = 0; idx < count; idx++) {
+		service = find_service_driver(service_uuid + idx);
+		if (!service)
+			continue;
+
+		ret = device_bind_driver(dev, service->driver_name, service->driver_name, NULL);
+		if (ret) {
+			dev_warn(dev, "%s was not bound: %d, ignored\n", service->driver_name, ret);
+			continue;
+		}
+	}
+
+	return 0;
+}
+
+static int __enum_services(struct udevice *dev, struct tee_shm *shm, u32 *shm_size, u32 tee_sess)
+{
+	struct tee_invoke_arg arg = { };
+	struct tee_param param = { };
+	int ret = 0;
+
+	arg.func = PTA_CMD_GET_DEVICES;
+	arg.session = tee_sess;
+
+	/* Fill invoke cmd params */
+	param.attr = TEE_PARAM_ATTR_TYPE_MEMREF_OUTPUT;
+	param.u.memref.shm = shm;
+	param.u.memref.size = *shm_size;
+
+	ret = tee_invoke_func(dev, &arg, 1, &param);
+	if (ret || (arg.ret && arg.ret != TEE_ERROR_SHORT_BUFFER)) {
+		dev_err(dev, "PTA_CMD_GET_DEVICES invoke function err: 0x%x\n", arg.ret);
+		return -EINVAL;
+	}
+
+	*shm_size = param.u.memref.size;
+
+	return 0;
+}
+
+static int enum_services(struct udevice *dev, struct tee_shm **shm, size_t *count, u32 tee_sess)
+{
+	size_t shm_size = 0;
+	int ret;
+
+	ret = __enum_services(dev, NULL, &shm_size, tee_sess);
+	if (ret)
+		return ret;
+
+	ret = tee_shm_alloc(dev, shm_size, 0, shm);
+	if (ret) {
+		dev_err(dev, "Failed to allocated shared memory: %d\n", ret);
+		return ret;
+	}
+
+	ret = __enum_services(dev, *shm, &shm_size, tee_sess);
+	if (ret)
+		tee_shm_free(*shm);
+	else
+		*count = shm_size / sizeof(struct tee_optee_ta_uuid);
+
+	return ret;
+}
+
+static int open_enum_session(struct udevice *dev, u32 *tee_sess)
+{
+	const struct tee_optee_ta_uuid pta_uuid = PTA_DEVICE_ENUM;
+	struct tee_open_session_arg arg = { };
+	int ret;
+
+	tee_optee_ta_uuid_to_octets(arg.uuid, &pta_uuid);
+
+	ret = tee_open_session(dev, &arg, 0, NULL);
+	if (ret || arg.ret) {
+		if (!ret)
+			ret = -EIO;
+		return ret;
+	}
+
+	*tee_sess = arg.session;
+
+	return 0;
+}
+
+static int bind_service_drivers(struct udevice *dev)
+{
+	struct tee_shm *service_list = NULL;
+	size_t service_count;
+	u32 tee_sess;
+	int ret;
+
+	ret = open_enum_session(dev, &tee_sess);
+	if (ret)
+		return ret;
+
+	ret = enum_services(dev, &service_list, &service_count, tee_sess);
+	if (!ret) {
+		ret = bind_service_list(dev, service_list, service_count);
+
+		tee_shm_free(service_list);
+	}
+
+	tee_close_session(dev, tee_sess);
+
+	return ret;
+}
+
 /**
  * reg_pair_to_ptr() - Make a pointer of 2 32-bit values
  * @reg0:	High bits of the pointer
@@ -638,6 +790,14 @@ static int optee_of_to_plat(struct udevice *dev)
 	return 0;
 }
 
+static int optee_bind(struct udevice *dev)
+{
+	if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY))
+		dev_or_flags(dev, DM_FLAG_PROBE_AFTER_BIND);
+
+	return 0;
+}
+
 static int optee_probe(struct udevice *dev)
 {
 	struct optee_pdata *pdata = dev_get_plat(dev);
@@ -667,11 +827,15 @@ static int optee_probe(struct udevice *dev)
 		return -ENOENT;
 	}
 
-	/*
-	 * in U-Boot, the discovery of TA on the TEE bus is not supported:
-	 * only bind the drivers associated to the supported OP-TEE TA
-	 */
-	if (IS_ENABLED(CONFIG_RNG_OPTEE)) {
+	if (IS_ENABLED(CONFIG_OPTEE_SERVICE_DISCOVERY)) {
+		ret = bind_service_drivers(dev);
+		if (ret)
+			return ret;
+	} else if (IS_ENABLED(CONFIG_RNG_OPTEE)) {
+		/*
+		 * Discovery of TAs on the TEE bus is not supported in U-Boot:
+		 * only bind the drivers associated to the supported OP-TEE TA
+		 */
 		ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL);
 		if (ret)
 			return ret;
@@ -691,6 +855,7 @@ U_BOOT_DRIVER(optee) = {
 	.of_match = optee_match,
 	.of_to_plat = optee_of_to_plat,
 	.probe = optee_probe,
+	.bind = optee_bind,
 	.ops = &optee_ops,
 	.plat_auto	= sizeof(struct optee_pdata),
 	.priv_auto	= sizeof(struct optee_private),
diff --git a/include/tee/optee_service.h b/include/tee/optee_service.h
new file mode 100644
index 0000000000..31732979da
--- /dev/null
+++ b/include/tee/optee_service.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+/*
+ * (C) Copyright 2022 Linaro Limited
+ */
+
+#ifndef _OPTEE_SERVICE_H
+#define _OPTEE_SERVICE_H
+
+/*
+ * struct optee_service - Discoverable OP-TEE service
+ *
+ * @driver_name - Name of the related driver
+ * @uuid - UUID of the OP-TEE service related to the driver
+ *
+ * Use macro OPTEE_SERVICE_DRIVER() to register a driver related to an
+ * OP-TEE service discovered when driver asks OP-TEE services enumaration.
+ */
+struct optee_service {
+	const char *driver_name;
+	const struct tee_optee_ta_uuid uuid;
+};
+
+#define OPTEE_SERVICE_DRIVER(__name) \
+	ll_entry_declare(struct optee_service, __name, optee_service)
+
+#define OPTEE_SERVICE_DRIVER_GET(__name) \
+	ll_entry_get(struct optee_service, __name, optee_service)
+
+#endif /* _OPTEE_SERVICE_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH v2 3/3] drivers: rng: optee_rng: register to CONFIG_OPTEE_SERVICE_DISCOVERY
  2022-06-03 10:26 [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable Etienne Carriere
  2022-06-03 10:27 ` [PATCH v2 2/3] drivers: tee: optee: discover OP-TEE services Etienne Carriere
@ 2022-06-03 10:27 ` Etienne Carriere
  2022-06-06 11:36   ` Patrick DELAUNAY
  2022-06-06 11:26 ` [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable Patrick DELAUNAY
  2 siblings, 1 reply; 6+ messages in thread
From: Etienne Carriere @ 2022-06-03 10:27 UTC (permalink / raw)
  To: u-boot; +Cc: Etienne Carriere, Sughosh Ganu, Patrick Delaunay

Changes optee_rng driver to register itself has a OP-TEE service so
that a device is bound for the driver when OP-TEE enumerates the
PTA RNG service.

Cc: Sughosh Ganu <sughosh.ganu@linaro.org>
Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
---
No change since v1.
---
 drivers/rng/Kconfig     |  1 +
 drivers/rng/optee_rng.c | 12 +++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/rng/Kconfig b/drivers/rng/Kconfig
index c10f7d345b..14e95a6213 100644
--- a/drivers/rng/Kconfig
+++ b/drivers/rng/Kconfig
@@ -34,6 +34,7 @@ config RNG_MSM
 config RNG_OPTEE
 	bool "OP-TEE based Random Number Generator support"
 	depends on DM_RNG && OPTEE
+	default y if OPTEE_SERVICE_DISCOVERY
 	help
 	  This driver provides support for the OP-TEE based Random Number
 	  Generator on ARM SoCs where hardware entropy sources are not
diff --git a/drivers/rng/optee_rng.c b/drivers/rng/optee_rng.c
index aa8ce864d3..90d9434395 100644
--- a/drivers/rng/optee_rng.c
+++ b/drivers/rng/optee_rng.c
@@ -11,6 +11,9 @@
 #include <dm/device.h>
 #include <dm/device_compat.h>
 #include <linux/sizes.h>
+#include <tee/optee_service.h>
+
+#define DRIVER_NAME	"optee-rng"
 
 #define TEE_ERROR_HEALTH_TEST_FAIL	0x00000001
 
@@ -35,6 +38,13 @@
 #define TA_HWRNG_UUID { 0xab7a617c, 0xb8e7, 0x4d8f, \
 			{ 0x83, 0x01, 0xd0, 0x9b, 0x61, 0x03, 0x6b, 0x64 } }
 
+#ifdef CONFIG_OPTEE_SERVICE_DISCOVERY
+OPTEE_SERVICE_DRIVER(optee_rng) = {
+	.uuid = TA_HWRNG_UUID,
+	.driver_name = DRIVER_NAME,
+};
+#endif
+
 /** open_session_ta_hwrng() - Open session with hwrng Trusted App
  *
  * @dev:		device
@@ -177,7 +187,7 @@ static const struct dm_rng_ops optee_rng_ops = {
 };
 
 U_BOOT_DRIVER(optee_rng) = {
-	.name = "optee-rng",
+	.name = DRIVER_NAME,
 	.id = UCLASS_RNG,
 	.ops = &optee_rng_ops,
 	.probe = optee_rng_probe,
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable
  2022-06-03 10:26 [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable Etienne Carriere
  2022-06-03 10:27 ` [PATCH v2 2/3] drivers: tee: optee: discover OP-TEE services Etienne Carriere
  2022-06-03 10:27 ` [PATCH v2 3/3] drivers: rng: optee_rng: register to CONFIG_OPTEE_SERVICE_DISCOVERY Etienne Carriere
@ 2022-06-06 11:26 ` Patrick DELAUNAY
  2 siblings, 0 replies; 6+ messages in thread
From: Patrick DELAUNAY @ 2022-06-06 11:26 UTC (permalink / raw)
  To: Etienne Carriere, u-boot

Hi,

On 6/3/22 12:26, Etienne Carriere wrote:
> Removes local variable child in optee_probe() that is not used.
>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> ---
> New change not in v1 series.
> ---
>   drivers/tee/optee/core.c | 3 +--
>   1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
> index a89d62aaf0..c1f5fc4c7a 100644
> --- a/drivers/tee/optee/core.c
> +++ b/drivers/tee/optee/core.c
> @@ -642,7 +642,6 @@ static int optee_probe(struct udevice *dev)
>   {
>   	struct optee_pdata *pdata = dev_get_plat(dev);
>   	u32 sec_caps;
> -	struct udevice *child;
>   	int ret;
>   
>   	if (!is_optee_api(pdata->invoke_fn)) {
> @@ -673,7 +672,7 @@ static int optee_probe(struct udevice *dev)
>   	 * only bind the drivers associated to the supported OP-TEE TA
>   	 */
>   	if (IS_ENABLED(CONFIG_RNG_OPTEE)) {
> -		ret = device_bind_driver(dev, "optee-rng", "optee-rng", &child);
> +		ret = device_bind_driver(dev, "optee-rng", "optee-rng", NULL);
>   		if (ret)
>   			return ret;
>   	}



Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Thanks
Patrick



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 2/3] drivers: tee: optee: discover OP-TEE services
  2022-06-03 10:27 ` [PATCH v2 2/3] drivers: tee: optee: discover OP-TEE services Etienne Carriere
@ 2022-06-06 11:35   ` Patrick DELAUNAY
  0 siblings, 0 replies; 6+ messages in thread
From: Patrick DELAUNAY @ 2022-06-06 11:35 UTC (permalink / raw)
  To: Etienne Carriere, u-boot; +Cc: Jens Wiklander

Hi Etienne,

On 6/3/22 12:27, Etienne Carriere wrote:
> This change defines resources for OP-TEE service drivers to register
> themselves for being bound to when OP-TEE firmware reports the related
> service is supported. OP-TEE services are discovered during optee
> driver probe sequence which mandates optee driver is always probe once
> bound.
>
> Discovery of optee services and binding to related U-Boot drivers is
> embedded upon configuration switch CONFIG_OPTEE_SERVICE_DISCOVERY.
>
> Cc: Jens Wiklander <jens.wiklander@linaro.org>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> ---
> Changes since v1:
> - Remove all #ifdef CONFIG_OPTEE_SERVICE_DISCOVERY directives and replace
>    with if (IS_ENABLED()) where applicable.
> - Incidentally rename local function open_session() to open_enum_session()
>    and remove local function close_session() for clarity.
> - Update commit log to highlight that "optee driver is always probe once
>    bound" when CONFIG_OPTEE_SERVICE_DISCOVERY is enable.
> ---
>   drivers/tee/optee/Kconfig   |   8 ++
>   drivers/tee/optee/core.c    | 175 ++++++++++++++++++++++++++++++++++--
>   include/tee/optee_service.h |  29 ++++++
>   3 files changed, 207 insertions(+), 5 deletions(-)
>   create mode 100644 include/tee/optee_service.h
>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Thanks
Patrick


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH v2 3/3] drivers: rng: optee_rng: register to CONFIG_OPTEE_SERVICE_DISCOVERY
  2022-06-03 10:27 ` [PATCH v2 3/3] drivers: rng: optee_rng: register to CONFIG_OPTEE_SERVICE_DISCOVERY Etienne Carriere
@ 2022-06-06 11:36   ` Patrick DELAUNAY
  0 siblings, 0 replies; 6+ messages in thread
From: Patrick DELAUNAY @ 2022-06-06 11:36 UTC (permalink / raw)
  To: Etienne Carriere, u-boot; +Cc: Sughosh Ganu

Hi Etienne,

On 6/3/22 12:27, Etienne Carriere wrote:
> Changes optee_rng driver to register itself has a OP-TEE service so
> that a device is bound for the driver when OP-TEE enumerates the
> PTA RNG service.
>
> Cc: Sughosh Ganu <sughosh.ganu@linaro.org>
> Cc: Patrick Delaunay <patrick.delaunay@foss.st.com>
> Signed-off-by: Etienne Carriere <etienne.carriere@linaro.org>
> ---
> No change since v1.
> ---
>   drivers/rng/Kconfig     |  1 +
>   drivers/rng/optee_rng.c | 12 +++++++++++-
>   2 files changed, 12 insertions(+), 1 deletion(-)
>

Reviewed-by: Patrick Delaunay <patrick.delaunay@foss.st.com>

Thanks
Patrick


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-06-06 11:36 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-03 10:26 [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable Etienne Carriere
2022-06-03 10:27 ` [PATCH v2 2/3] drivers: tee: optee: discover OP-TEE services Etienne Carriere
2022-06-06 11:35   ` Patrick DELAUNAY
2022-06-03 10:27 ` [PATCH v2 3/3] drivers: rng: optee_rng: register to CONFIG_OPTEE_SERVICE_DISCOVERY Etienne Carriere
2022-06-06 11:36   ` Patrick DELAUNAY
2022-06-06 11:26 ` [PATCH v2 1/3] drivers: tee: optee: remove unused probe local variable Patrick DELAUNAY

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.