linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/3] Add support for Congatec CGEB BIOS interface
@ 2024-07-18  1:15 Mary Strodl
  2024-07-18  1:15 ` [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range Mary Strodl
                   ` (2 more replies)
  0 siblings, 3 replies; 25+ messages in thread
From: Mary Strodl @ 2024-07-18  1:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: akpm, urezki, hch, linux-mm, lee, andi.shyti, linux-i2c, s.hauer,
	christian.gmeiner, Mary Strodl

The following series adds support for the Congatec CGEB interface
found on some Congatec x86 boards. The CGEB interface is a BIOS
interface which provides access to onboard peripherals like I2C
busses and watchdogs. It works by mapping BIOS code and searching
for magic values which specify the entry points to the CGEB call.
The CGEB call is an API provided by the BIOS which provides access
to the functions in an ioctl like fashion.

This series is based on the excellent work of Sascha Hauer and
Christian Gmeiner. You can find their original work here:

http://patchwork.ozlabs.org/patch/219756/
http://patchwork.ozlabs.org/patch/219755/
http://patchwork.ozlabs.org/patch/219757/

http://patchwork.ozlabs.org/patch/483262/
http://patchwork.ozlabs.org/patch/483264/
http://patchwork.ozlabs.org/patch/483261/
http://patchwork.ozlabs.org/patch/483263/

Mary Strodl (1):
  mm: vmalloc: export __vmalloc_node_range

Sascha Hauer (2):
  x86: Add basic support for the Congatec CGEB BIOS interface
  i2c: Add Congatec CGEB I2C driver

 drivers/i2c/busses/Kconfig             |   7 +
 drivers/i2c/busses/Makefile            |   1 +
 drivers/i2c/busses/i2c-congatec-cgeb.c | 187 ++++++++
 drivers/mfd/Kconfig                    |  10 +
 drivers/mfd/Makefile                   |   1 +
 drivers/mfd/congatec-cgeb.c            | 620 +++++++++++++++++++++++++
 include/linux/mfd/congatec-cgeb.h      | 105 +++++
 mm/vmalloc.c                           |   1 +
 8 files changed, 932 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-congatec-cgeb.c
 create mode 100644 drivers/mfd/congatec-cgeb.c
 create mode 100644 include/linux/mfd/congatec-cgeb.h

-- 
2.45.2



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

* [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18  1:15 [PATCH 0/3] Add support for Congatec CGEB BIOS interface Mary Strodl
@ 2024-07-18  1:15 ` Mary Strodl
  2024-07-18  2:53   ` Andrew Morton
  2024-07-18  3:04   ` Christoph Hellwig
  2024-07-18  1:15 ` [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface Mary Strodl
  2024-07-18  1:15 ` [PATCH 3/3] i2c: Add Congatec CGEB I2C driver Mary Strodl
  2 siblings, 2 replies; 25+ messages in thread
From: Mary Strodl @ 2024-07-18  1:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: akpm, urezki, hch, linux-mm, lee, andi.shyti, linux-i2c, s.hauer,
	christian.gmeiner, Mary Strodl

After the ability to allocate PAGE_KERNEL_EXEC memory was removed
from __vmalloc, this seems like the least invasive way to expose
the capability to drivers that need it.

Exports __vmalloc_node_range so that drivers can use it.

Signed-off-by: Mary Strodl <mstrodl@csh.rit.edu>
---
 mm/vmalloc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index e34ea860153f..037b7e0fe430 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3879,6 +3879,7 @@ void *__vmalloc_node_range_noprof(unsigned long size, unsigned long align,
 
 	return NULL;
 }
+EXPORT_SYMBOL(__vmalloc_node_range_noprof);
 
 /**
  * __vmalloc_node - allocate virtually contiguous memory
-- 
2.45.2



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

* [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface
  2024-07-18  1:15 [PATCH 0/3] Add support for Congatec CGEB BIOS interface Mary Strodl
  2024-07-18  1:15 ` [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range Mary Strodl
@ 2024-07-18  1:15 ` Mary Strodl
  2024-07-18  3:56   ` kernel test robot
  2024-07-18 14:01   ` kernel test robot
  2024-07-18  1:15 ` [PATCH 3/3] i2c: Add Congatec CGEB I2C driver Mary Strodl
  2 siblings, 2 replies; 25+ messages in thread
From: Mary Strodl @ 2024-07-18  1:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: akpm, urezki, hch, linux-mm, lee, andi.shyti, linux-i2c, s.hauer,
	christian.gmeiner, Mary Strodl

From: Sascha Hauer <s.hauer@pengutronix.de>

The Congatec CGEB is a BIOS interface found on some Congatec x86
modules. It provides access to on board peripherals like I2C busses
and watchdogs. This driver contains the basic support for accessing
the CGEB interface and registers the child devices.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: Mary Strodl <mstrodl@csh.rit.edu>
---
 drivers/mfd/Kconfig               |  10 +
 drivers/mfd/Makefile              |   1 +
 drivers/mfd/congatec-cgeb.c       | 620 ++++++++++++++++++++++++++++++
 include/linux/mfd/congatec-cgeb.h | 105 +++++
 4 files changed, 736 insertions(+)
 create mode 100644 drivers/mfd/congatec-cgeb.c
 create mode 100644 include/linux/mfd/congatec-cgeb.h

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 266b4f54af60..fa06a9dc34f9 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1206,6 +1206,16 @@ config MFD_RT5120
 	  is targeted at providing the CPU voltage, memory, I/O and peripheral
 	  power rails in home entertainment devices.
 
+config MFD_CONGATEC_CGEB
+	tristate "Support for the Congatec CGEB BIOS interface"
+	depends on X86
+	help
+	  The Congatec CGEB BIOS interface provides access to onboard
+	  peripherals like I2C busses and watchdogs. additional drivers must be
+	  enabled in order to use the functionality of the device.
+	  Say y or m here if you are using a congatec module with CGEB interface,
+	  otherwise say n.
+
 config MFD_RC5T583
 	bool "Ricoh RC5T583 Power Management system device"
 	depends on I2C=y
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c66f07edcd0e..38f31841ac88 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -217,6 +217,7 @@ obj-$(CONFIG_MFD_INTEL_LPSS)	+= intel-lpss.o
 obj-$(CONFIG_MFD_INTEL_LPSS_PCI)	+= intel-lpss-pci.o
 obj-$(CONFIG_MFD_INTEL_LPSS_ACPI)	+= intel-lpss-acpi.o
 obj-$(CONFIG_MFD_INTEL_PMC_BXT)	+= intel_pmc_bxt.o
+obj-$(CONFIG_MFD_CONGATEC_CGEB)	+= congatec-cgeb.o
 obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
 obj-$(CONFIG_MFD_VIPERBOARD)    += viperboard.o
 obj-$(CONFIG_MFD_NTXEC)		+= ntxec.o
diff --git a/drivers/mfd/congatec-cgeb.c b/drivers/mfd/congatec-cgeb.c
new file mode 100644
index 000000000000..2bae1f42c357
--- /dev/null
+++ b/drivers/mfd/congatec-cgeb.c
@@ -0,0 +1,620 @@
+/*
+ * CGEB driver
+ *
+ * (c) 2011 Sascha Hauer, Pengutronix
+ *
+ * Based on code from Congatec AG.
+ *
+ * CGEB is a BIOS interface found on congatech modules. It consists of
+ * code found in the BIOS memory map which is called in a ioctl like
+ * fashion. This file contains the basic driver for this interface
+ * which provides access to the GCEB interface and registers the child
+ * devices like I2C busses and watchdogs.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/congatec-cgeb.h>
+
+#include <generated/autoconf.h>
+
+#define CGOS_BOARD_MAX_SIZE_ID_STRING 16
+
+#define CGEB_VERSION_MAJOR 1
+
+#define CGEB_GET_VERSION_MAJOR(v) (((unsigned long)(v)) >> 24)
+
+/* CGEB Low Descriptor located in 0xc0000-0xfffff */
+#define CGEB_LD_MAGIC "$CGEBLD$"
+
+#pragma pack(push,4)
+
+struct cgeb_low_desc {
+	char magic[8];          /* descriptor magic string */
+	u16 size;               /* size of this descriptor */
+	u16 reserved;
+	char bios_name[8];      /* BIOS name and revision "ppppRvvv" */
+	u32 hi_desc_phys_addr;  /* phys addr of the high descriptor, can be 0 */
+};
+
+/* CGEB High Descriptor located in 0xfff00000-0xffffffff */
+#ifdef CONFIG_X86_64
+#define CGEB_HD_MAGIC "$CGEBQD$"
+#else
+#define CGEB_HD_MAGIC "$CGEBHD$"
+#endif
+
+struct cgeb_high_desc {
+	char magic[8];          /* descriptor magic string */
+	u16 size;               /* size of this descriptor */
+	u16 reserved;
+	u32 data_size;          /* CGEB data area size */
+	u32 code_size;          /* CGEB code area size */
+	u32 entry_rel;          /* CGEB entry point relative to start */
+};
+
+struct cgeb_far_ptr {
+	void* off;
+	u16 seg;
+	u16 pad;
+};
+
+struct cgeb_fps {
+	u32 size;               /* size of the parameter structure */
+	u32 fct;                /* function number */
+	struct cgeb_far_ptr data;       /* CGEB data area */
+	void* cont;             /* private continuation pointer */
+	void* subfps;           /* private sub function parameter
+				 * structure pointer
+				 */
+	void* subfct;           /* sub function pointer */
+	u32 status;             /* result codes of the function */
+	u32 unit;               /* unit number or type */
+	u32 pars[4];            /* input parameters */
+	u32 rets[2];            /* return parameters */
+	void *iptr;             /* input pointer */
+	void *optr;             /* output pointer */
+};
+
+/* continuation status codes */
+#define CGEB_SUCCESS            0
+#define CGEB_NEXT               1
+#define CGEB_DELAY              2
+#define CGEB_NOIRQS             3
+
+#define CGEB_DBG_STR        0x100
+#define CGEB_DBG_HEX        0x101
+#define CGEB_DBG_DEC        0x102
+
+struct cgeb_map_mem {
+	void* phys;             /* physical address */
+	u32 size;               /* size in bytes */
+	struct cgeb_far_ptr virt;
+};
+
+struct cgeb_map_mem_list {
+	u32 count;              /* number of memory map entries */
+	struct cgeb_map_mem entries[];
+};
+
+struct cgeb_boardinfo {
+	u32 size;
+	u32 flags;
+	u32 classes;
+	u32 primary_class;
+	char board[CGOS_BOARD_MAX_SIZE_ID_STRING];
+	/* optional */
+	char vendor[CGOS_BOARD_MAX_SIZE_ID_STRING];
+};
+
+struct cgeb_i2c_info {
+	u32 size;
+	u32 type;
+	u32 frequency;
+	u32 maxFrequency;
+};
+
+#pragma pack(pop)
+
+/* I2C Types */
+#define CGEB_I2C_TYPE_UNKNOWN 0
+#define CGEB_I2C_TYPE_PRIMARY 1
+#define CGEB_I2C_TYPE_SMB     2
+#define CGEB_I2C_TYPE_DDC     3
+#define CGEB_I2C_TYPE_BC      4
+
+struct cgeb_board_data {
+	void *code;
+	void *data;
+	u16 ds;
+	struct cgeb_map_mem_list *map_mem;
+	struct platform_device **devices;
+	int num_devices;
+
+	#ifdef CONFIG_X86_64
+	void (*entry)(void*, struct cgeb_fps *, struct cgeb_fps *, void*);
+	#else
+	/*
+	 * entry points to a bimodal C style function that expects a far pointer
+	 * to a fps. If cs is 0 then it does a near return, otherwise a far
+	 * return. If we ever need a far return then we must not pass cs at all.
+	 * parameters are removed by the caller.
+	 */
+	void __attribute__((regparm(0)))(*entry)(unsigned short,
+			  struct cgeb_fps *, unsigned short);
+	#endif
+};
+
+static unsigned short get_data_segment(void)
+{
+	unsigned short ret;
+
+#ifdef CONFIG_X86_64
+	ret = 0;
+#else
+	asm volatile("mov %%ds, %0\n"
+			  : "=r"(ret)
+			  :
+			  : "memory"
+	);
+#endif
+
+	return ret;
+}
+
+/*
+ * cgeb_call - invoke CGEB BIOS call.
+ *
+ * @board:     board context data
+ * @p:         CGEB parameters for this call
+ * @fct:       CGEB function code
+ * @return:    0 on success or negative error code on failure.
+ *
+ * Call the CGEB BIOS code with the given parameters.
+ */
+unsigned int cgeb_call(struct cgeb_board_data *board,
+		 struct cgeb_function_parameters *p, cgeb_function_t fct)
+{
+	struct cgeb_fps fps;
+	int i;
+
+	memset(&fps, 0, sizeof(fps));
+
+	fps.size = sizeof(fps);
+	fps.fct = fct;
+	fps.data.off = board->data;
+	fps.data.seg = board->ds;
+	fps.data.pad = 0;
+	fps.status = 0;
+	fps.cont = fps.subfct = fps.subfps = 0;
+	fps.unit = p->unit;
+	for (i = 0; i < 4; i++)
+		fps.pars[i] = p->pars[i];
+	fps.iptr = p->iptr;
+	fps.optr = p->optr;
+
+	while (1) {
+		pr_debug("CGEB: CGEB: ->  size %02x, fct %02x, data %04x:%p, status %08x\n",
+				fps.size, fps.fct, fps.data.seg, fps.data.off,
+				fps.status);
+
+#ifdef CONFIG_X86_64
+		board->entry(NULL, &fps, &fps, NULL);
+#else
+		board->entry(0, &fps, fps.data.seg);
+#endif
+
+		pr_debug("CGEB: CGEB: <-  size %02x, fct %02x, data %04x:%p, status %08x\n",
+				fps.size, fps.fct, fps.data.seg, fps.data.off,
+				fps.status);
+
+		switch (fps.status) {
+		case CGEB_SUCCESS:
+			goto out;
+		case CGEB_NEXT:
+			break;  /* simply call again */
+		case CGEB_NOIRQS:
+			__set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(0);
+			break;
+		case CGEB_DELAY:
+			usleep_range(fps.rets[0], fps.rets[0] + 1000);
+			break;
+		case CGEB_DBG_STR:
+			if (fps.optr)
+				pr_debug("CGEB: %s\n", (char *)fps.optr);
+			break;
+		case CGEB_DBG_HEX:
+			pr_debug("CGEB: 0x%08x\n", fps.rets[0]);
+			break;
+		case CGEB_DBG_DEC:
+			pr_debug("CGEB: %d\n", fps.rets[0]);
+			break;
+
+		default:
+			/* unknown continuation code */
+			return -EINVAL;
+		}
+	}
+out:
+	for (i = 0; i < 2; i++)
+		p->rets[i] = fps.rets[i];
+	p->optr = fps.optr;
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(cgeb_call);
+
+/*
+ * cgeb_call_simple - convenience wrapper for cgeb_call
+ *
+ * @board:     board context data
+ * @p:         CGEB parameters for this call
+ * @fct:       CGEB function code
+ * @return:    0 on success or negative error code on failure.
+ *
+ * Call the CGEB BIOS code with the given parameters.
+ */
+int cgeb_call_simple(struct cgeb_board_data *board,
+		 cgeb_function_t fct, u32 unit,
+		 void **optr, u32 *result)
+{
+	struct cgeb_function_parameters p;
+	unsigned int ret;
+
+	memset(&p, 0, sizeof(p));
+	p.unit = unit;
+	p.optr = optr;
+
+	ret = cgeb_call(board, &p, fct);
+	if (optr)
+		*optr = p.optr;
+	if (result)
+		*result = p.rets[0];
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(cgeb_call_simple);
+
+static void *cgeb_find_magic(void *_mem, size_t len, char *magic)
+{
+	u32 magic0 = ((u32 *)magic)[0];
+	u32 magic1 = ((u32 *)magic)[1];
+	int i = 0;
+
+	while (i < len) {
+		u32 *mem = _mem + i;
+
+		if (mem[0] == magic0 && mem[1] == magic1)
+			return mem;
+		i += 16;
+	}
+
+	return NULL;
+}
+
+static void cgeb_unmap_memory(struct cgeb_board_data *board)
+{
+	struct cgeb_map_mem_list *pmm;
+	struct cgeb_map_mem *pmme;
+	unsigned long i;
+
+	if (!board->map_mem)
+		return;
+
+	pmm = board->map_mem;
+	pmme = pmm->entries;
+	for (i = 0; i < pmm->count; i++, pmme++) {
+		if (pmme->virt.off)
+			iounmap((void *)pmme->virt.off);
+		pmme->virt.off = 0;
+		pmme->virt.seg = 0;
+	}
+}
+
+static int cgeb_map_memory(struct cgeb_board_data *board)
+{
+	struct cgeb_map_mem_list *pmm;
+	struct cgeb_map_mem *pmme;
+	int i;
+	int ret;
+
+	ret = cgeb_call_simple(board, CgebMapGetMem, 0, (void *)&board->map_mem,
+			NULL);
+	if (ret)
+		return ret;
+	if (!board->map_mem)
+		return 0;
+
+	pmm = board->map_mem;
+	pmme = pmm->entries;
+
+	pr_debug("CGEB: Memory Map with %d entries\n", pmm->count);
+
+	for (i = 0; i < pmm->count; i++, pmme++) {
+		pr_debug("CGEB: Memory map entry phys=%px, size=%08x\n",
+				pmme->phys, pmme->size);
+		if (pmme->phys && pmme->size) {
+			/* We only want to look at the lower 32 bits */
+			pmme->virt.off =
+				ioremap_cache((u32)(resource_size_t)pmme->phys,
+					pmme->size);
+			if (!pmme->virt.off)
+				return -ENOMEM;
+		 } else {
+			pmme->virt.off = 0;
+		}
+
+		pmme->virt.seg = (pmme->virt.off) ? board->ds : 0;
+
+		pr_debug("CGEB:   Map phys %p, size %08x, virt %04x:%p\n",
+			pmme->phys, pmme->size, pmme->virt.seg,
+			pmme->virt.off);
+	}
+
+	return cgeb_call_simple(board, CgebMapChanged, 0, NULL, NULL);
+}
+
+static struct cgeb_board_data *cgeb_open(resource_size_t base, u32 len)
+{
+	u32 dw;
+	struct cgeb_boardinfo *pbi;
+	struct cgeb_low_desc *low_desc;
+	struct cgeb_high_desc *high_desc = NULL;
+	u32 high_desc_phys;
+	u32 high_desc_len;
+	void __iomem *pcur, *high_desc_virt;
+	int ret;
+
+	struct cgeb_board_data *board;
+
+	board = kzalloc(sizeof(*board), GFP_KERNEL);
+	if (!board)
+		return NULL;
+
+	pcur = ioremap_cache(base, len);
+	if (!pcur)
+		goto err_kfree;
+
+	/* look for the CGEB descriptor */
+	low_desc = cgeb_find_magic(pcur, len, CGEB_LD_MAGIC);
+	if (!low_desc)
+		goto err_kfree;
+
+	pr_debug("CGEB: Found CGEB_LD_MAGIC\n");
+
+	if (low_desc->size < sizeof(struct cgeb_low_desc) - sizeof(long))
+		goto err_kfree;
+
+	if (low_desc->size >= sizeof(struct cgeb_low_desc)
+			&& low_desc->hi_desc_phys_addr)
+		high_desc_phys = low_desc->hi_desc_phys_addr;
+	else
+		high_desc_phys = 0xfff00000;
+
+	high_desc_len = (unsigned int) -(int)high_desc_phys;
+
+	pr_debug("CGEB: Looking for CGEB hi desc between phys 0x%x and 0x%x\n",
+		high_desc_phys, -1);
+
+	high_desc_virt = ioremap_cache(high_desc_phys, high_desc_len);
+	if (!high_desc_virt)
+		goto err_kfree;
+
+	pr_debug("CGEB: Looking for CGEB hi desc between virt 0x%p and 0x%p\n",
+		high_desc_virt, high_desc_virt + high_desc_len - 1);
+
+	high_desc = cgeb_find_magic(high_desc_virt, high_desc_len,
+					CGEB_HD_MAGIC);
+	if (!high_desc)
+		goto err_iounmap;
+
+	pr_debug("CGEB: Found CGEB_HD_MAGIC\n");
+
+	if (high_desc->size < sizeof(struct cgeb_high_desc))
+		goto err_iounmap;
+
+	pr_debug("CGEB: data_size %u, code_size %u, entry_rel %u\n",
+		high_desc->data_size, high_desc->code_size, high_desc->entry_rel);
+
+	board->code = __vmalloc_node_range(high_desc->code_size, 1,
+					   VMALLOC_START, VMALLOC_END,
+					   GFP_KERNEL, PAGE_KERNEL_EXEC,
+					   (VM_WRITE | VM_EXEC), NUMA_NO_NODE,
+					   __builtin_return_address(0));
+	if (!board->code)
+		goto err_iounmap;
+
+	memcpy(board->code, high_desc, high_desc->code_size);
+
+	high_desc = board->code;
+
+	board->entry = (void*)((char*)board->code + high_desc->entry_rel);
+
+	board->ds = get_data_segment();
+
+	ret = cgeb_call_simple(board, CgebGetCgebVersion, 0, NULL, &dw);
+	if (ret)
+		goto err_vfree;
+
+	if (CGEB_GET_VERSION_MAJOR(dw) != CGEB_VERSION_MAJOR)
+		goto err_vfree;
+
+	pr_debug("CGEB: BIOS interface revision: %d.%d\n",
+			dw >> 16, dw & 0xffff);
+
+	if (high_desc->data_size) {
+		board->data = vmalloc(high_desc->data_size);
+		if (!board->data)
+			goto err_vfree;
+	} else {
+		 ret = cgeb_call_simple(board, CgebGetDataSize, 0, NULL, &dw);
+		 if (!ret && dw) {
+			board->data = vmalloc(dw);
+			if (!board->data)
+				goto err_vfree;
+		}
+	}
+
+	ret = cgeb_call_simple(board, CgebOpen, 0, NULL, NULL);
+	if (ret)
+		goto err_vfree_data;
+
+	ret = cgeb_map_memory(board);
+	if (ret)
+		goto err_free_map;
+
+	ret = cgeb_call_simple(board, CgebBoardGetInfo, 0, (void*)&pbi, NULL);
+	if (ret)
+		goto err_free_map;
+
+	pr_info("CGEB: Board name: %c%c%c%c\n",
+			pbi->board[0], pbi->board[1],
+			pbi->board[2], pbi->board[3]);
+
+	iounmap(high_desc_virt);
+
+	return board;
+
+err_free_map:
+	cgeb_unmap_memory(board);
+err_vfree_data:
+	vfree(board->data);
+err_vfree:
+	vfree(board->code);
+err_iounmap:
+	iounmap(high_desc_virt);
+err_kfree:
+	kfree(board);
+	return NULL;
+}
+
+static void cgeb_close(struct cgeb_board_data *board)
+{
+	cgeb_call_simple(board, CgebClose, 0, NULL, NULL);
+
+	cgeb_unmap_memory(board);
+
+	vfree(board->data);
+	vfree(board->code);
+}
+
+static unsigned long cgeb_i2c_get_type(struct cgeb_board_data *brd, int unit)
+{
+	struct cgeb_i2c_info *info;
+	int ret;
+
+	ret = cgeb_call_simple(brd, CgebI2CGetInfo, unit, (void *) &info, NULL);
+	if (ret)
+		return ret;
+	if (!info)
+		return -EINVAL;
+	return info->type;
+}
+
+static struct cgeb_board_data *cgeb_board;
+
+static int __init cgeb_init(void)
+{
+	struct cgeb_board_data *board;
+	resource_size_t base;
+	int i, ret;
+	struct cgeb_pdata pdata;
+	u32 i2c_count, watchdog_count;
+	int num_devices = 0;
+
+	for (base = 0xf0000; base >= 0xc0000; base -= 0x10000) {
+		board = cgeb_open(base, 0x10000);
+		if (board)
+			break;
+	}
+
+	if (!board)
+		return -ENODEV;
+
+	cgeb_board = board;
+
+	pdata.board = board;
+
+	cgeb_call_simple(board, CgebI2CCount, 0, NULL, &i2c_count);
+	cgeb_call_simple(board, CgebWDogCount, 0, NULL, &watchdog_count);
+
+	board->num_devices = i2c_count + watchdog_count;
+	board->devices = kzalloc(sizeof(void *) * (board->num_devices),
+			 GFP_KERNEL);
+	if (!board->devices) {
+		ret = -ENOMEM;
+		goto err_out;
+	}
+
+	for (i = 0; i < i2c_count; i++) {
+		ret = cgeb_i2c_get_type(board, i);
+		if (ret != CGEB_I2C_TYPE_PRIMARY)
+			continue;
+
+		 pdata.unit = i;
+
+		 board->devices[num_devices] =
+			platform_device_register_data(NULL, "cgeb-i2c", i,
+					&pdata, sizeof(pdata));
+		 num_devices++;
+	}
+
+	for (i = 0; i < watchdog_count; i++) {
+		board->devices[num_devices] =
+			platform_device_register_data(NULL, "cgeb-watchdog", i,
+					&pdata, sizeof(pdata));
+		pdata.unit = i;
+
+		num_devices++;
+	}
+
+	return 0;
+err_out:
+	cgeb_close(board);
+	kfree(board);
+
+	return ret;
+}
+
+static void __exit cgeb_exit(void)
+{
+	struct cgeb_board_data *board = cgeb_board;
+	int i;
+
+	for (i = 0; i < board->num_devices; i++)
+		if (board->devices[i])
+			platform_device_unregister(board->devices[i]);
+
+	cgeb_close(board);
+
+	kfree(board->devices);
+	kfree(board);
+}
+
+module_init(cgeb_init);
+module_exit(cgeb_exit);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("CGEB driver");
+MODULE_LICENSE("GPL");
diff --git a/include/linux/mfd/congatec-cgeb.h b/include/linux/mfd/congatec-cgeb.h
new file mode 100644
index 000000000000..26f5452286af
--- /dev/null
+++ b/include/linux/mfd/congatec-cgeb.h
@@ -0,0 +1,105 @@
+#ifndef __CONGATEC_CGEB_H
+#define __CONGATEC_CGEB_H
+
+/* CGEB interface functions */
+typedef enum {
+	CgebGetCgebVersion =            0,
+	CgebGetSysBiosVersion =         1,
+	CgebGetVgaBiosVersion =         2,
+	CgebGetDataSize =               3,
+	CgebOpen =                      4,
+	CgebClose =                     5,
+	CgebMapGetMem =                 6,
+	CgebMapChanged =                7,
+	CgebMapGetPorts =               8,
+	CgebDelayUs =                   9,
+	CgebCgbcReadWrite =             10,
+	CgebCgbcSetControl =            11,
+	CgebCgbcGetInfo =               12,
+	CgebCgbcHandleCommand =         13,
+	CgebBoardGetInfo =              14,
+	CgebBoardGetBootCounter =       15,
+	CgebBoardGetRunningTimeMeter =  16,
+	CgebBoardGetBootErrorLog =      17,
+	CgebVgaCount =                  18,
+	CgebVgaGetInfo =                19,
+	CgebVgaGetContrast =            20,
+	CgebVgaSetContrast =            21,
+	CgebVgaGetContrastEnable =      22,
+	CgebVgaSetContrastEnable =      23,
+	CgebVgaGetBacklight =           24,
+	CgebVgaSetBacklight =           25,
+	CgebVgaGetBacklightEnable =     26,
+	CgebVgaSetBacklightEnable =     27,
+	CgebVgaEndDarkBoot =            28,
+	CgebStorageAreaCount =          29,
+	CgebStorageAreaGetInfo =        30,
+	CgebStorageAreaRead =           31,
+	CgebStorageAreaWrite =          32,
+	CgebStorageAreaErase =          33,
+	CgebStorageAreaEraseStatus =    34,
+	CgebI2CCount =                  35,
+	CgebI2CGetInfo =                36,
+	CgebI2CGetAddrList =            37,
+	CgebI2CTransfer =               38,
+	CgebI2CGetFrequency =           39,
+	CgebI2CSetFrequency =           40,
+	CgebIOCount =                   41,
+	CgebIOGetInfo =                 42,
+	CgebIORead =                    43,
+	CgebIOWrite =                   44,
+	CgebIOGetDirection =            45,
+	CgebIOSetDirection =            46,
+	CgebWDogCount =                 47,
+	CgebWDogGetInfo =               48,
+	CgebWDogTrigger =               49,
+	CgebWDogGetConfig =             50,
+	CgebWDogSetConfig =             51,
+	CgebPerformanceGetCurrent =     52,
+	CgebPerformanceSetCurrent =     53,
+	CgebPerformanceGetPolicyCaps =  54,
+	CgebPerformanceGetPolicy =      55,
+	CgebPerformanceSetPolicy =      56,
+	CgebTemperatureCount =          57,
+	CgebTemperatureGetInfo =        58,
+	CgebTemperatureGetCurrent =     59,
+	CgebTemperatureSetLimits =      60,
+	CgebFanCount =                  61,
+	CgebFanGetInfo =                62,
+	CgebFanGetCurrent =             63,
+	CgebFanSetLimits =              64,
+	CgebVoltageCount =              65,
+	CgebVoltageGetInfo =            66,
+	CgebVoltageGetCurrent =         67,
+	CgebVoltageSetLimits =          68,
+	CgebStorageAreaLock =           69,
+	CgebStorageAreaUnlock =         70,
+	CgebStorageAreaIsLocked =       71,
+} cgeb_function_t;
+
+struct cgeb_function_parameters {
+	u32 unit;               /* unit number or type */
+	u32 pars[4];            /* input parameters */
+	u32 rets[2];            /* return parameters */
+	void *iptr;             /* input pointer */
+	void *optr;             /* output pointer */
+};
+
+struct cgeb_board_data;
+
+unsigned int cgeb_call(struct cgeb_board_data *,
+		struct cgeb_function_parameters *, cgeb_function_t);
+
+int cgeb_call_simple(struct cgeb_board_data *,
+		cgeb_function_t, u32,
+		void **, u32 *);
+
+/*
+ * Platform data for child devices
+ */
+struct cgeb_pdata {
+	struct cgeb_board_data *board;
+	int unit;
+};
+
+#endif /* __CONGATEC_CGEB_H */
-- 
2.45.2



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

* [PATCH 3/3] i2c: Add Congatec CGEB I2C driver
  2024-07-18  1:15 [PATCH 0/3] Add support for Congatec CGEB BIOS interface Mary Strodl
  2024-07-18  1:15 ` [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range Mary Strodl
  2024-07-18  1:15 ` [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface Mary Strodl
@ 2024-07-18  1:15 ` Mary Strodl
  2 siblings, 0 replies; 25+ messages in thread
From: Mary Strodl @ 2024-07-18  1:15 UTC (permalink / raw)
  To: linux-kernel
  Cc: akpm, urezki, hch, linux-mm, lee, andi.shyti, linux-i2c, s.hauer,
	christian.gmeiner, Mary Strodl

From: Sascha Hauer <s.hauer@pengutronix.de>

This driver provides a I2C bus driver for the CGEB interface
found on some Congatec x86 modules. No devices are registered
on the bus, the user has to do this via the i2c device /sys
interface.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Signed-off-by: Mary Strodl <mstrodl@csh.rit.edu>
---
 drivers/i2c/busses/Kconfig             |   7 +
 drivers/i2c/busses/Makefile            |   1 +
 drivers/i2c/busses/i2c-congatec-cgeb.c | 187 +++++++++++++++++++++++++
 3 files changed, 195 insertions(+)
 create mode 100644 drivers/i2c/busses/i2c-congatec-cgeb.c

diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
index fe6e8a1bb607..504a0be54f04 100644
--- a/drivers/i2c/busses/Kconfig
+++ b/drivers/i2c/busses/Kconfig
@@ -1261,6 +1261,13 @@ config I2C_RCAR
 	  This driver can also be built as a module.  If so, the module
 	  will be called i2c-rcar.
 
+config I2C_CONGATEC_CGEB
+	tristate "Congatec CGEB I2C driver"
+	depends on MFD_CONGATEC_CGEB
+	help
+	  This driver provides support for the I2C busses accssable via
+	  the Congatec CGEB interface found on Congatec boards.
+
 comment "External I2C/SMBus adapter drivers"
 
 config I2C_DIOLAN_U2C
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
index 78d0561339e5..f4e9fa7542be 100644
--- a/drivers/i2c/busses/Makefile
+++ b/drivers/i2c/busses/Makefile
@@ -128,6 +128,7 @@ obj-$(CONFIG_I2C_XILINX)	+= i2c-xiic.o
 obj-$(CONFIG_I2C_XLP9XX)	+= i2c-xlp9xx.o
 obj-$(CONFIG_I2C_RCAR)		+= i2c-rcar.o
 obj-$(CONFIG_I2C_GXP)		+= i2c-gxp.o
+obj-$(CONFIG_I2C_CONGATEC_CGEB)	+= i2c-congatec-cgeb.o
 
 # External I2C/SMBus adapter drivers
 obj-$(CONFIG_I2C_DIOLAN_U2C)	+= i2c-diolan-u2c.o
diff --git a/drivers/i2c/busses/i2c-congatec-cgeb.c b/drivers/i2c/busses/i2c-congatec-cgeb.c
new file mode 100644
index 000000000000..decaef30ca0a
--- /dev/null
+++ b/drivers/i2c/busses/i2c-congatec-cgeb.c
@@ -0,0 +1,187 @@
+/*
+ * CGEB i2c driver
+ *
+ * (c) 2011 Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/i2c.h>
+#include <linux/mfd/congatec-cgeb.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#define CG_I2C_FLAG_START   0x00080    /* send START condition */
+#define CG_I2C_FLAG_STOP    0x00040    /* send STOP condition */
+#define CG_I2C_FLAG_ALL_ACK 0x08000    /* send ACK on all read bytes */
+#define CG_I2C_FLAG_ALL_NAK 0x04000    /* send NAK on all read bytes */
+
+struct cgeb_i2c_priv {
+	struct cgeb_board_data *board;
+	struct i2c_adapter adapter;
+	int unit;
+};
+
+static u32 cgeb_i2c_func(struct i2c_adapter *adapter)
+{
+	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
+}
+
+static int cgeb_i2c_set_speed(struct cgeb_i2c_priv *priv, int speed)
+{
+	struct cgeb_function_parameters fps;
+
+	memset(&fps, 0, sizeof(fps));
+
+	fps.unit = priv->unit;
+	fps.pars[0] = speed;
+
+	return cgeb_call(priv->board, &fps, CgebI2CSetFrequency);
+}
+
+static int cgeb_i2c_xfer(struct i2c_adapter *adapter,
+		struct i2c_msg *msgs, int num)
+{
+	struct cgeb_function_parameters fps;
+	int i, ret;
+	unsigned long flags = CG_I2C_FLAG_START;
+	struct cgeb_i2c_priv *priv = i2c_get_adapdata(adapter);
+	unsigned long rdlen, wrlen;
+	unsigned char *rdbuf, *wrbuf, *raw_wrbuf;
+	unsigned short lmax = 0;
+
+	/*
+	 * With cgeb the I2C address is part of the write data
+	 * buffer, so allocate a buffer with the length of the
+	 * longest write buffer + 1
+	 */
+	for (i = 0; i < num; i++)
+		if (!(msgs[i].flags & I2C_M_RD))
+			lmax = max(lmax, msgs[i].len);
+
+	raw_wrbuf = kmalloc(lmax + 1, GFP_KERNEL);
+	if (!raw_wrbuf)
+		return -ENOMEM;
+
+	for (i = 0; i < num; i++) {
+		if (msgs[i].flags & I2C_M_RD) {
+			rdbuf = msgs[i].buf;
+			rdlen = msgs[i].len;
+			wrbuf = NULL;
+			wrlen = 0;
+		} else {
+			rdbuf = NULL;
+			rdlen = 0;
+			wrbuf = msgs[i].buf;
+			wrlen = msgs[i].len;
+		}
+
+		raw_wrbuf[0] = msgs[i].addr << 1;
+		if (wrlen)
+			memcpy(&raw_wrbuf[1], wrbuf, wrlen);
+
+		if (msgs[i].flags & I2C_M_RD)
+			raw_wrbuf[0] |= 1;
+
+		if (i == num - 1)
+			flags |= CG_I2C_FLAG_STOP;
+
+		dev_dbg(&adapter->dev,
+				"%s: rd: %p/%ld wr: %p/%ld flags: 0x%08lx %s\n",
+				__func__, rdbuf, rdlen, raw_wrbuf, wrlen + 1,
+				flags,
+				msgs[i].flags & I2C_M_RD ? "READ" : "WRITE");
+
+		memset(&fps, 0, sizeof(fps));
+
+		fps.unit = priv->unit;
+		fps.pars[0] = wrlen + 1;
+		fps.pars[1] = rdlen;
+		fps.pars[2] = flags;
+		fps.iptr = raw_wrbuf;
+		fps.optr = rdbuf;
+
+		ret = cgeb_call(priv->board, &fps, CgebI2CTransfer);
+		if (ret) {
+			ret = -EREMOTEIO;
+			goto out;
+		}
+	}
+
+	ret = num;
+
+out:
+	kfree(raw_wrbuf);
+
+	return ret;
+}
+
+static struct i2c_algorithm cgeb_i2c_algo = {
+	.master_xfer    = cgeb_i2c_xfer,
+	.functionality  = cgeb_i2c_func,
+};
+
+static int cgeb_i2c_probe(struct platform_device *pdev)
+{
+	struct cgeb_i2c_priv *priv;
+	struct cgeb_pdata *pdata = pdev->dev.platform_data;
+	int ret;
+
+	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	strcpy(priv->adapter.name, pdev->name);
+	priv->adapter.owner             = THIS_MODULE;
+	priv->adapter.algo              = &cgeb_i2c_algo;
+	priv->adapter.dev.parent        = &pdev->dev;
+	priv->unit = pdata->unit;
+	priv->board = pdata->board;
+	i2c_set_adapdata(&priv->adapter, priv);
+
+	platform_set_drvdata(pdev, priv);
+
+	ret = cgeb_i2c_set_speed(priv, 400000);
+	if (ret)
+		/* not a critical error, we can continue with the default speed. */
+		dev_warn(&pdev->dev, "Could not set speed to 400KHz\n");
+
+	ret = i2c_add_adapter(&priv->adapter);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "registration failed\n");
+		return ret;
+	}
+
+	dev_info(&pdev->dev, "registered\n");
+
+	return 0;
+};
+
+static int cgeb_i2c_remove(struct platform_device *pdev)
+{
+	struct cgeb_i2c_priv *priv = platform_get_drvdata(pdev);
+
+	i2c_del_adapter(&priv->adapter);
+
+	return 0;
+}
+
+static struct platform_driver cgeb_i2c_driver = {
+	.probe          = cgeb_i2c_probe,
+	.remove         = cgeb_i2c_remove,
+	.driver = {
+		.name   = "cgeb-i2c",
+	},
+};
+module_platform_driver(cgeb_i2c_driver);
+
+MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
+MODULE_DESCRIPTION("cgeb i2c driver");
+MODULE_LICENSE("GPL");
-- 
2.45.2



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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18  1:15 ` [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range Mary Strodl
@ 2024-07-18  2:53   ` Andrew Morton
  2024-07-18 12:29     ` Mary Strodl
  2024-07-18  3:04   ` Christoph Hellwig
  1 sibling, 1 reply; 25+ messages in thread
From: Andrew Morton @ 2024-07-18  2:53 UTC (permalink / raw)
  To: Mary Strodl
  Cc: linux-kernel, urezki, hch, linux-mm, lee, andi.shyti, linux-i2c,
	s.hauer, christian.gmeiner

On Wed, 17 Jul 2024 21:15:02 -0400 Mary Strodl <mstrodl@csh.rit.edu> wrote:

> After the ability to allocate PAGE_KERNEL_EXEC memory was removed
> from __vmalloc

Removed by which commit?

> this seems like the least invasive way to expose
> the capability to drivers that need it.
> 
> Exports __vmalloc_node_range so that drivers can use it.

Why does this driver need a thing which no other driver does?




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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18  1:15 ` [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range Mary Strodl
  2024-07-18  2:53   ` Andrew Morton
@ 2024-07-18  3:04   ` Christoph Hellwig
  2024-07-18 12:40     ` Mary Strodl
  1 sibling, 1 reply; 25+ messages in thread
From: Christoph Hellwig @ 2024-07-18  3:04 UTC (permalink / raw)
  To: Mary Strodl
  Cc: linux-kernel, akpm, urezki, hch, linux-mm, lee, andi.shyti,
	linux-i2c, s.hauer, christian.gmeiner

On Wed, Jul 17, 2024 at 09:15:02PM -0400, Mary Strodl wrote:
> After the ability to allocate PAGE_KERNEL_EXEC memory was removed
> from __vmalloc,

Yes. for a very good reason.

NAK to a driver creating random writable and exectutable memory:

Nacked-by: Christoph Hellwig <hch@lst.de>



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

* Re: [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface
  2024-07-18  1:15 ` [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface Mary Strodl
@ 2024-07-18  3:56   ` kernel test robot
  2024-07-18 14:01   ` kernel test robot
  1 sibling, 0 replies; 25+ messages in thread
From: kernel test robot @ 2024-07-18  3:56 UTC (permalink / raw)
  To: Mary Strodl, linux-kernel
  Cc: oe-kbuild-all, akpm, urezki, hch, linux-mm, lee, andi.shyti,
	linux-i2c, s.hauer, christian.gmeiner, Mary Strodl

Hi Mary,

kernel test robot noticed the following build warnings:

[auto build test WARNING on lee-mfd/for-mfd-next]
[also build test WARNING on lee-mfd/for-mfd-fixes akpm-mm/mm-everything andi-shyti/i2c/i2c-host linus/master v6.10 next-20240717]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Mary-Strodl/mm-vmalloc-export-__vmalloc_node_range/20240718-091816
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
patch link:    https://lore.kernel.org/r/20240718011504.4106163-3-mstrodl%40csh.rit.edu
patch subject: [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface
reproduce: (https://download.01.org/0day-ci/archive/20240718/202407181147.SJ9mOE8q-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407181147.SJ9mOE8q-lkp@intel.com/

versioncheck warnings: (new ones prefixed by >>)
   INFO PATH=/opt/cross/rustc-1.78.0-bindgen-0.65.1/cargo/bin:/opt/cross/clang-18/bin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
   /usr/bin/timeout -k 100 3h /usr/bin/make KCFLAGS= -Wtautological-compare -Wno-error=return-type -Wreturn-type -Wcast-function-type -funsigned-char -Wundef -fstrict-flex-arrays=3 -Wformat-overflow -Wformat-truncation -Wenum-conversion W=1 --keep-going LLVM=1 -j32 ARCH=x86_64 versioncheck
   find ./* \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o \
   	-name '*.[hcS]' -type f -print | sort \
   	| xargs perl -w ./scripts/checkversion.pl
   ./drivers/accessibility/speakup/genmap.c: 13 linux/version.h not needed.
   ./drivers/accessibility/speakup/makemapdata.c: 13 linux/version.h not needed.
>> ./drivers/mfd/congatec-cgeb.c: 25 linux/version.h not needed.
   ./drivers/staging/media/atomisp/include/linux/atomisp.h: 23 linux/version.h not needed.
   ./samples/bpf/spintest.bpf.c: 8 linux/version.h not needed.
   ./samples/trace_events/trace_custom_sched.c: 11 linux/version.h not needed.
   ./sound/soc/codecs/cs42l42.c: 14 linux/version.h not needed.
   ./tools/lib/bpf/bpf_helpers.h: 423: need linux/version.h
   ./tools/testing/selftests/bpf/progs/dev_cgroup.c: 9 linux/version.h not needed.
   ./tools/testing/selftests/bpf/progs/netcnt_prog.c: 3 linux/version.h not needed.
   ./tools/testing/selftests/bpf/progs/test_map_lock.c: 4 linux/version.h not needed.
   ./tools/testing/selftests/bpf/progs/test_send_signal_kern.c: 4 linux/version.h not needed.
   ./tools/testing/selftests/bpf/progs/test_spin_lock.c: 4 linux/version.h not needed.
   ./tools/testing/selftests/bpf/progs/test_tcp_estats.c: 37 linux/version.h not needed.
   ./tools/testing/selftests/wireguard/qemu/init.c: 27 linux/version.h not needed.

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18  2:53   ` Andrew Morton
@ 2024-07-18 12:29     ` Mary Strodl
  0 siblings, 0 replies; 25+ messages in thread
From: Mary Strodl @ 2024-07-18 12:29 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Mary Strodl, linux-kernel, urezki, hch, linux-mm, lee,
	andi.shyti, linux-i2c, s.hauer, christian.gmeiner

On Wed, Jul 17, 2024 at 07:53:23PM -0700, Andrew Morton wrote:
> Removed by which commit?

Thanks. This was removed in:
88dca4ca5a93 mm: remove the pgprot argument to __vmalloc

It was removed because every driver was passing PAGE_KERNEL

> Why does this driver need a thing which no other driver does?

You can	find more information in the manufacturer's docs:
https://www.congatec.com/fileadmin/user_upload/Documents/Manual/CGOSAPI.pdf

In particular, section 1 (page 11) describes how they intend for
it to work.

Basically, they	provide	an x86 blob in the BIOS	that we	copy
into kernelspace and mark executable. Then, we can call into that
blob to access congatec's special hardware.

Thanks again for reviewing my patches!

If there is a better way to do what I'm trying to do, please let
me know. It's possible I'm missing something obvious.


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18  3:04   ` Christoph Hellwig
@ 2024-07-18 12:40     ` Mary Strodl
  2024-07-18 12:45       ` Matthew Wilcox
  0 siblings, 1 reply; 25+ messages in thread
From: Mary Strodl @ 2024-07-18 12:40 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Mary Strodl, linux-kernel, akpm, urezki, linux-mm, lee,
	andi.shyti, linux-i2c, s.hauer, christian.gmeiner

On Wed, Jul 17, 2024 at 08:04:01PM -0700, Christoph Hellwig wrote:
> NAK to a driver creating random writable and exectutable memory:

Is there a better way to do what I'm trying to do? Or some way to
expose this functionality with more guard rails so that it's a
little bit safer?

Thank you for taking time to review my patches!


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18 12:40     ` Mary Strodl
@ 2024-07-18 12:45       ` Matthew Wilcox
  2024-07-18 12:49         ` Christoph Hellwig
  0 siblings, 1 reply; 25+ messages in thread
From: Matthew Wilcox @ 2024-07-18 12:45 UTC (permalink / raw)
  To: Mary Strodl
  Cc: Christoph Hellwig, Mary Strodl, linux-kernel, akpm, urezki,
	linux-mm, lee, andi.shyti, linux-i2c, s.hauer, christian.gmeiner

On Thu, Jul 18, 2024 at 08:40:27AM -0400, Mary Strodl wrote:
> On Wed, Jul 17, 2024 at 08:04:01PM -0700, Christoph Hellwig wrote:
> > NAK to a driver creating random writable and exectutable memory:
> 
> Is there a better way to do what I'm trying to do? Or some way to
> expose this functionality with more guard rails so that it's a
> little bit safer?

No, there is no way to do what you're trying to do.



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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18 12:45       ` Matthew Wilcox
@ 2024-07-18 12:49         ` Christoph Hellwig
  2024-07-18 12:53           ` Matthew Wilcox
  0 siblings, 1 reply; 25+ messages in thread
From: Christoph Hellwig @ 2024-07-18 12:49 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Mary Strodl, Christoph Hellwig, Mary Strodl, linux-kernel, akpm,
	urezki, linux-mm, lee, andi.shyti, linux-i2c, s.hauer,
	christian.gmeiner

On Thu, Jul 18, 2024 at 01:45:11PM +0100, Matthew Wilcox wrote:
> On Thu, Jul 18, 2024 at 08:40:27AM -0400, Mary Strodl wrote:
> > On Wed, Jul 17, 2024 at 08:04:01PM -0700, Christoph Hellwig wrote:
> > > NAK to a driver creating random writable and exectutable memory:
> > 
> > Is there a better way to do what I'm trying to do? Or some way to
> > expose this functionality with more guard rails so that it's a
> > little bit safer?
> 
> No, there is no way to do what you're trying to do.

IFF it is absolutely required to run BIOS provided executable code,
the best way to do that is in a separate userspace process.



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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18 12:49         ` Christoph Hellwig
@ 2024-07-18 12:53           ` Matthew Wilcox
  2024-07-18 13:20             ` Mary Strodl
  0 siblings, 1 reply; 25+ messages in thread
From: Matthew Wilcox @ 2024-07-18 12:53 UTC (permalink / raw)
  To: Christoph Hellwig
  Cc: Mary Strodl, Mary Strodl, linux-kernel, akpm, urezki, linux-mm,
	lee, andi.shyti, linux-i2c, s.hauer, christian.gmeiner

On Thu, Jul 18, 2024 at 05:49:14AM -0700, Christoph Hellwig wrote:
> On Thu, Jul 18, 2024 at 01:45:11PM +0100, Matthew Wilcox wrote:
> > On Thu, Jul 18, 2024 at 08:40:27AM -0400, Mary Strodl wrote:
> > > On Wed, Jul 17, 2024 at 08:04:01PM -0700, Christoph Hellwig wrote:
> > > > NAK to a driver creating random writable and exectutable memory:
> > > 
> > > Is there a better way to do what I'm trying to do? Or some way to
> > > expose this functionality with more guard rails so that it's a
> > > little bit safer?
> > 
> > No, there is no way to do what you're trying to do.
> 
> IFF it is absolutely required to run BIOS provided executable code,
> the best way to do that is in a separate userspace process.

That does work, but I would assume that since this BIOS exists to
communicate with the hardware that it'd need various special privileges
and that running in ring 3 would not work.

Ultimately, better off running the whole thing inside a VM and passing
the device through to the guest.  Or ignoring the BIOS entirely and
implementing direct access to the hardware.  But neither of these
approaches is "a way to do what I'm trying to do", they're entirely
different approaches to making this hardware work.


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18 12:53           ` Matthew Wilcox
@ 2024-07-18 13:20             ` Mary Strodl
  2024-07-18 21:31               ` Andrew Morton
  0 siblings, 1 reply; 25+ messages in thread
From: Mary Strodl @ 2024-07-18 13:20 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Christoph Hellwig, Mary Strodl, linux-kernel, akpm, urezki,
	linux-mm, lee, andi.shyti, linux-i2c, s.hauer, christian.gmeiner

On Thu, Jul 18, 2024 at 01:53:23PM +0100, Matthew Wilcox wrote:
> That does work, but I would assume that since this BIOS exists to
> communicate with the hardware that it'd need various special privileges
> and that running in ring 3 would not work.

Exactly.
 
> Ultimately, better off running the whole thing inside a VM and passing
> the device through to the guest.  Or ignoring the BIOS entirely and
> implementing direct access to the hardware.  But neither of these
> approaches is "a way to do what I'm trying to do", they're entirely
> different approaches to making this hardware work.

If I ran the whole thing inside a VM, I would still need support in the
kernel, right?

As far as I know, there is no documentation on Congatec's side about the
underlying interface. Obviously I could disassemble the blob in the BIOS
and figure it out, but I suspect that will have much less hardware
compatibility and be subject to random breakage if they make a BIOS
update or something. Plus, I would probably run afoul of copyright if I
wrote a driver after doing that.

I'm not really thrilled that this is their design either, but I'm not
sure that there is a better answer...

Thank you!


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

* Re: [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface
  2024-07-18  1:15 ` [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface Mary Strodl
  2024-07-18  3:56   ` kernel test robot
@ 2024-07-18 14:01   ` kernel test robot
  1 sibling, 0 replies; 25+ messages in thread
From: kernel test robot @ 2024-07-18 14:01 UTC (permalink / raw)
  To: Mary Strodl, linux-kernel
  Cc: oe-kbuild-all, akpm, urezki, hch, linux-mm, lee, andi.shyti,
	linux-i2c, s.hauer, christian.gmeiner, Mary Strodl

Hi Mary,

kernel test robot noticed the following build warnings:

[auto build test WARNING on lee-mfd/for-mfd-next]
[also build test WARNING on lee-mfd/for-mfd-fixes akpm-mm/mm-everything andi-shyti/i2c/i2c-host linus/master v6.10 next-20240718]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Mary-Strodl/mm-vmalloc-export-__vmalloc_node_range/20240718-091816
base:   https://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd.git for-mfd-next
patch link:    https://lore.kernel.org/r/20240718011504.4106163-3-mstrodl%40csh.rit.edu
patch subject: [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface
config: i386-allmodconfig (https://download.01.org/0day-ci/archive/20240718/202407182128.dYt4Ud4g-lkp@intel.com/config)
compiler: gcc-13 (Ubuntu 13.2.0-4ubuntu3) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240718/202407182128.dYt4Ud4g-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202407182128.dYt4Ud4g-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/mfd/congatec-cgeb.c: In function 'cgeb_map_memory':
>> drivers/mfd/congatec-cgeb.c:360:52: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
     360 |                                 ioremap_cache((u32)(resource_size_t)pmme->phys,
         |                                                    ^


vim +360 drivers/mfd/congatec-cgeb.c

   334	
   335	static int cgeb_map_memory(struct cgeb_board_data *board)
   336	{
   337		struct cgeb_map_mem_list *pmm;
   338		struct cgeb_map_mem *pmme;
   339		int i;
   340		int ret;
   341	
   342		ret = cgeb_call_simple(board, CgebMapGetMem, 0, (void *)&board->map_mem,
   343				NULL);
   344		if (ret)
   345			return ret;
   346		if (!board->map_mem)
   347			return 0;
   348	
   349		pmm = board->map_mem;
   350		pmme = pmm->entries;
   351	
   352		pr_debug("CGEB: Memory Map with %d entries\n", pmm->count);
   353	
   354		for (i = 0; i < pmm->count; i++, pmme++) {
   355			pr_debug("CGEB: Memory map entry phys=%px, size=%08x\n",
   356					pmme->phys, pmme->size);
   357			if (pmme->phys && pmme->size) {
   358				/* We only want to look at the lower 32 bits */
   359				pmme->virt.off =
 > 360					ioremap_cache((u32)(resource_size_t)pmme->phys,
   361						pmme->size);
   362				if (!pmme->virt.off)
   363					return -ENOMEM;
   364			 } else {
   365				pmme->virt.off = 0;
   366			}
   367	
   368			pmme->virt.seg = (pmme->virt.off) ? board->ds : 0;
   369	
   370			pr_debug("CGEB:   Map phys %p, size %08x, virt %04x:%p\n",
   371				pmme->phys, pmme->size, pmme->virt.seg,
   372				pmme->virt.off);
   373		}
   374	
   375		return cgeb_call_simple(board, CgebMapChanged, 0, NULL, NULL);
   376	}
   377	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18 13:20             ` Mary Strodl
@ 2024-07-18 21:31               ` Andrew Morton
  2024-07-18 21:35                 ` Matthew Wilcox
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Morton @ 2024-07-18 21:31 UTC (permalink / raw)
  To: Mary Strodl
  Cc: Matthew Wilcox, Christoph Hellwig, Mary Strodl, linux-kernel,
	urezki, linux-mm, lee, andi.shyti, linux-i2c, s.hauer,
	christian.gmeiner

On Thu, 18 Jul 2024 09:20:15 -0400 Mary Strodl <mstrodl@freedom.csh.rit.edu> wrote:

> On Thu, Jul 18, 2024 at 01:53:23PM +0100, Matthew Wilcox wrote:
> > That does work, but I would assume that since this BIOS exists to
> > communicate with the hardware that it'd need various special privileges
> > and that running in ring 3 would not work.
> 
> Exactly.
>  
> > Ultimately, better off running the whole thing inside a VM and passing
> > the device through to the guest.  Or ignoring the BIOS entirely and
> > implementing direct access to the hardware.  But neither of these
> > approaches is "a way to do what I'm trying to do", they're entirely
> > different approaches to making this hardware work.
> 
> If I ran the whole thing inside a VM, I would still need support in the
> kernel, right?
> 
> As far as I know, there is no documentation on Congatec's side about the
> underlying interface. Obviously I could disassemble the blob in the BIOS
> and figure it out, but I suspect that will have much less hardware
> compatibility and be subject to random breakage if they make a BIOS
> update or something. Plus, I would probably run afoul of copyright if I
> wrote a driver after doing that.
> 
> I'm not really thrilled that this is their design either, but I'm not
> sure that there is a better answer...
> 

The hardware is weird, but we should try to support it in some fashion.
But without making dangerous functionality more widely available.  So
we're looking for some solution which can be fully contained within
that hardware's driver.

Dumb idea, there will be other ideas: is it practical to take that code
blob out of the BIOS, put it into a kernel module (as a .byte table in
a .s file and suitable C interfacing), compile that up and insmod that
module?  


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18 21:31               ` Andrew Morton
@ 2024-07-18 21:35                 ` Matthew Wilcox
  2024-07-18 21:39                   ` Andrew Morton
  0 siblings, 1 reply; 25+ messages in thread
From: Matthew Wilcox @ 2024-07-18 21:35 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Mary Strodl, Christoph Hellwig, Mary Strodl, linux-kernel,
	urezki, linux-mm, lee, andi.shyti, linux-i2c, s.hauer,
	christian.gmeiner

On Thu, Jul 18, 2024 at 02:31:03PM -0700, Andrew Morton wrote:
> The hardware is weird, but we should try to support it in some fashion.

Why?  It's been around since 2005, and Linux has done perfectly well
without support for it.  What's so compelling about it, as compared to
ohidontknow the nVidia GPU driver where we definitely don't support
taking a binary blob of random x86 code and run it inside the kernel?

> Dumb idea, there will be other ideas: is it practical to take that code
> blob out of the BIOS, put it into a kernel module (as a .byte table in
> a .s file and suitable C interfacing), compile that up and insmod that
> module?  

Have you tried asking someone who cares about security like Kees?
Preferably in person so you can take a picture of the hair on their head
standing straight out and steam coming out of their ears.


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18 21:35                 ` Matthew Wilcox
@ 2024-07-18 21:39                   ` Andrew Morton
  2024-07-19  6:41                     ` Christian Gmeiner
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Morton @ 2024-07-18 21:39 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Mary Strodl, Christoph Hellwig, Mary Strodl, linux-kernel,
	urezki, linux-mm, lee, andi.shyti, linux-i2c, s.hauer,
	christian.gmeiner

On Thu, 18 Jul 2024 22:35:02 +0100 Matthew Wilcox <willy@infradead.org> wrote:

> On Thu, Jul 18, 2024 at 02:31:03PM -0700, Andrew Morton wrote:
> > The hardware is weird, but we should try to support it in some fashion.
> 
> Why?  It's been around since 2005, and Linux has done perfectly well
> without support for it. 

Oh.  I was assuming it was some new thing.  This does weaken the case
a lot.


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-18 21:39                   ` Andrew Morton
@ 2024-07-19  6:41                     ` Christian Gmeiner
  2024-07-19 11:58                       ` Mary Strodl
  0 siblings, 1 reply; 25+ messages in thread
From: Christian Gmeiner @ 2024-07-19  6:41 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Matthew Wilcox, Mary Strodl, Christoph Hellwig, Mary Strodl,
	linux-kernel, urezki, linux-mm, lee, andi.shyti, linux-i2c,
	s.hauer

>
> On Thu, 18 Jul 2024 22:35:02 +0100 Matthew Wilcox <willy@infradead.org> wrote:
>
> > On Thu, Jul 18, 2024 at 02:31:03PM -0700, Andrew Morton wrote:
> > > The hardware is weird, but we should try to support it in some fashion.
> >
> > Why?  It's been around since 2005, and Linux has done perfectly well
> > without support for it.
>
> Oh.  I was assuming it was some new thing.  This does weaken the case
> a lot.

This wonderful interface is used in recent products from them too.
Adding support for it
in an upstream-able way could be still a benefit, as these products
are used in different
industrial environments running on Linux.

-- 
greets
--
Christian Gmeiner, MSc

https://christian-gmeiner.info/privacypolicy


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-19  6:41                     ` Christian Gmeiner
@ 2024-07-19 11:58                       ` Mary Strodl
  2024-07-19 12:42                         ` Matthew Wilcox
  2024-07-19 19:59                         ` Rudolf Marek
  0 siblings, 2 replies; 25+ messages in thread
From: Mary Strodl @ 2024-07-19 11:58 UTC (permalink / raw)
  To: Christian Gmeiner
  Cc: Andrew Morton, Matthew Wilcox, Christoph Hellwig, Mary Strodl,
	linux-kernel, urezki, linux-mm, lee, andi.shyti, linux-i2c,
	s.hauer

On Fri, Jul 19, 2024 at 08:41:04AM +0200, Christian Gmeiner wrote:
> This wonderful interface is used in recent products from them too.
> Adding support for it
> in an upstream-able way could be still a benefit, as these products
> are used in different
> industrial environments running on Linux.

Just seconding this. The hardware we have here (conga-TCA7) was
released in 2021. As far as I know, congatec have been using this
interface for a while and provided a pretty bad out-of-tree driver
for it that needed a proprietary library in userspace to talk to
devices instead of actually registering with the kernel facilities
for i2c, watchdog, backlight, etc.

I think it's valuable functionality to support, but it'll need to
happen safely.

Maybe some of the stuff the driver does right now could be moved into
vmalloc? In other words, we could provide a different function that
allocates an executable page, copies memory into it, then marks it
read-only. Would that do better to alleviate concerns?

Not sure what the restrictions on x86 are, but we could also start
with a writable page, then mark it executable when we un-mark it
writable.

I think this is good discussion, thanks for sharing your thoughts
everybody.


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-19 11:58                       ` Mary Strodl
@ 2024-07-19 12:42                         ` Matthew Wilcox
  2024-07-24  0:00                           ` Andrew Morton
  2024-07-19 19:59                         ` Rudolf Marek
  1 sibling, 1 reply; 25+ messages in thread
From: Matthew Wilcox @ 2024-07-19 12:42 UTC (permalink / raw)
  To: Mary Strodl
  Cc: Christian Gmeiner, Andrew Morton, Christoph Hellwig, Mary Strodl,
	linux-kernel, urezki, linux-mm, lee, andi.shyti, linux-i2c,
	s.hauer

On Fri, Jul 19, 2024 at 07:58:40AM -0400, Mary Strodl wrote:
> Maybe some of the stuff the driver does right now could be moved into
> vmalloc? In other words, we could provide a different function that
> allocates an executable page, copies memory into it, then marks it
> read-only. Would that do better to alleviate concerns?

No.  We are not running arbitrary x86 code.  That is a security
nightmare.


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-19 11:58                       ` Mary Strodl
  2024-07-19 12:42                         ` Matthew Wilcox
@ 2024-07-19 19:59                         ` Rudolf Marek
  2024-07-22 14:54                           ` Mary Strodl
  1 sibling, 1 reply; 25+ messages in thread
From: Rudolf Marek @ 2024-07-19 19:59 UTC (permalink / raw)
  To: Mary Strodl, Christian Gmeiner
  Cc: Andrew Morton, Matthew Wilcox, Christoph Hellwig, Mary Strodl,
	linux-kernel, urezki, linux-mm, lee, andi.shyti, linux-i2c,
	s.hauer

Hi,

Dne 19. 07. 24 v 13:58 Mary Strodl napsal(a):
> I think this is good discussion, thanks for sharing your thoughts
> everybody.

I would suggest to simply run the BIOS code of this interface in usermode. Sort of similar to VM86 VESA stuff.
Last time I looked into this it used STI/CLI/RDMSR/WRMSR and couple of I/O ports and cf8/cfc for PCI.

Thanks,
Rudolf



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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-19 19:59                         ` Rudolf Marek
@ 2024-07-22 14:54                           ` Mary Strodl
  0 siblings, 0 replies; 25+ messages in thread
From: Mary Strodl @ 2024-07-22 14:54 UTC (permalink / raw)
  To: Rudolf Marek
  Cc: Christian Gmeiner, Andrew Morton, Matthew Wilcox,
	Christoph Hellwig, Mary Strodl, linux-kernel, urezki, linux-mm,
	lee, andi.shyti, linux-i2c, s.hauer

On Fri, Jul 19, 2024 at 09:59:37PM +0200, Rudolf Marek wrote:
> I would suggest to simply run the BIOS code of this interface in usermode. Sort of similar to VM86 VESA stuff.
> Last time I looked into this it used STI/CLI/RDMSR/WRMSR and couple of I/O ports and cf8/cfc for PCI.

I took a look at uvesafb (which appears to be what you were talking about) and
it looks like it starts a separate executable and uses some IPC to talk to it.
Is that the best way to do it?

I guess it would look something like:
- driver gets loaded
- driver spawns /sbin/cgeb-helper
- driver uses cn_netlink_send to send the `high_desc` to helper

Then the calls to `board->entry` in the driver get replaced with
`cn_netlink_send` with a `cgeb_fps`.

When the userspace helper gets the message with the `cgeb_fps`, it calls into
the bios code and replies to the driver with send() and passes back cgeb_fps.

From there, a callback registered with cn_add_callback will pick up the message
and call `wake_up_interruptible` to send the message back to the `cgeb_call`
caller.

Is this what you were imagining? Or is there a simpler way to do it?

Where should the code for the userspace helper live? The vesa stuff appeared to
be out of tree.


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-19 12:42                         ` Matthew Wilcox
@ 2024-07-24  0:00                           ` Andrew Morton
  2024-07-24  0:16                             ` Matthew Wilcox
  0 siblings, 1 reply; 25+ messages in thread
From: Andrew Morton @ 2024-07-24  0:00 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Mary Strodl, Christian Gmeiner, Christoph Hellwig, Mary Strodl,
	linux-kernel, urezki, linux-mm, lee, andi.shyti, linux-i2c,
	s.hauer

On Fri, 19 Jul 2024 13:42:40 +0100 Matthew Wilcox <willy@infradead.org> wrote:

> On Fri, Jul 19, 2024 at 07:58:40AM -0400, Mary Strodl wrote:
> > Maybe some of the stuff the driver does right now could be moved into
> > vmalloc? In other words, we could provide a different function that
> > allocates an executable page, copies memory into it, then marks it
> > read-only. Would that do better to alleviate concerns?
> 
> No.  We are not running arbitrary x86 code.  That is a security
> nightmare.

Sure, if such a thing were to be done we'd want it localized within the
driver rather than offered globally.

But if there was some hack within the driver to do this, what problems
might that cause?  What are the scenarios?



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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-24  0:00                           ` Andrew Morton
@ 2024-07-24  0:16                             ` Matthew Wilcox
  2024-07-24  1:36                               ` Christoph Hellwig
  0 siblings, 1 reply; 25+ messages in thread
From: Matthew Wilcox @ 2024-07-24  0:16 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Mary Strodl, Christian Gmeiner, Christoph Hellwig, Mary Strodl,
	linux-kernel, urezki, linux-mm, lee, andi.shyti, linux-i2c,
	s.hauer

On Tue, Jul 23, 2024 at 05:00:43PM -0700, Andrew Morton wrote:
> On Fri, 19 Jul 2024 13:42:40 +0100 Matthew Wilcox <willy@infradead.org> wrote:
> 
> > On Fri, Jul 19, 2024 at 07:58:40AM -0400, Mary Strodl wrote:
> > > Maybe some of the stuff the driver does right now could be moved into
> > > vmalloc? In other words, we could provide a different function that
> > > allocates an executable page, copies memory into it, then marks it
> > > read-only. Would that do better to alleviate concerns?
> > 
> > No.  We are not running arbitrary x86 code.  That is a security
> > nightmare.
> 
> Sure, if such a thing were to be done we'd want it localized within the
> driver rather than offered globally.
> 
> But if there was some hack within the driver to do this, what problems
> might that cause?  What are the scenarios?

That we're running arbitrary x86 code (provided by the manufacturer)
inside the kernel where it can undermine every security guarantee we
provide?


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

* Re: [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range
  2024-07-24  0:16                             ` Matthew Wilcox
@ 2024-07-24  1:36                               ` Christoph Hellwig
  0 siblings, 0 replies; 25+ messages in thread
From: Christoph Hellwig @ 2024-07-24  1:36 UTC (permalink / raw)
  To: Matthew Wilcox
  Cc: Andrew Morton, Mary Strodl, Christian Gmeiner, Christoph Hellwig,
	Mary Strodl, linux-kernel, urezki, linux-mm, lee, andi.shyti,
	linux-i2c, s.hauer

On Wed, Jul 24, 2024 at 01:16:02AM +0100, Matthew Wilcox wrote:
> That we're running arbitrary x86 code (provided by the manufacturer)
> inside the kernel where it can undermine every security guarantee we
> provide?

.. and by exporting the interface allow arbitrary other code including
exploit code to allocate writable and executable memory?


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

end of thread, other threads:[~2024-07-24  1:36 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-07-18  1:15 [PATCH 0/3] Add support for Congatec CGEB BIOS interface Mary Strodl
2024-07-18  1:15 ` [PATCH 1/3] mm: vmalloc: export __vmalloc_node_range Mary Strodl
2024-07-18  2:53   ` Andrew Morton
2024-07-18 12:29     ` Mary Strodl
2024-07-18  3:04   ` Christoph Hellwig
2024-07-18 12:40     ` Mary Strodl
2024-07-18 12:45       ` Matthew Wilcox
2024-07-18 12:49         ` Christoph Hellwig
2024-07-18 12:53           ` Matthew Wilcox
2024-07-18 13:20             ` Mary Strodl
2024-07-18 21:31               ` Andrew Morton
2024-07-18 21:35                 ` Matthew Wilcox
2024-07-18 21:39                   ` Andrew Morton
2024-07-19  6:41                     ` Christian Gmeiner
2024-07-19 11:58                       ` Mary Strodl
2024-07-19 12:42                         ` Matthew Wilcox
2024-07-24  0:00                           ` Andrew Morton
2024-07-24  0:16                             ` Matthew Wilcox
2024-07-24  1:36                               ` Christoph Hellwig
2024-07-19 19:59                         ` Rudolf Marek
2024-07-22 14:54                           ` Mary Strodl
2024-07-18  1:15 ` [PATCH 2/3] x86: Add basic support for the Congatec CGEB BIOS interface Mary Strodl
2024-07-18  3:56   ` kernel test robot
2024-07-18 14:01   ` kernel test robot
2024-07-18  1:15 ` [PATCH 3/3] i2c: Add Congatec CGEB I2C driver Mary Strodl

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox