Re: [PATCH] python 3.5 compatibility

2020-12-01 Thread Enrico Weigelt, metux IT consult
On 01.12.20 07:33, Markus Armbruster wrote:

> Which has oldstable status.  Good for running the old and stable
> software packaged by it (such as QEMU 2.8), and old (and hopefully
> stable) software of similar vintage.

It's still heavily used out in the field, and officially supported.
But that's just one example.

Perhaps I should add some more details on the situation: I'm using
(specially built) qemu with ptxdist/dkit - not the distro package.
The idea w/ ptxdist is that you just pull the trigger and it builds
everything needed for some project. Qemu is built specifically for
the configured target. Perhaps you've noticed I'm also doing development
of new qemu features - something that one doesn't want to do on old
versions.

> Have you considered upgrading to stable?

This would solve the problem just for me alone, not for others out
there, who're working w/ the BSP. And asking everybody (especially in
enterprise environments) to do a full release upgrade just for one
single tool (qemu) isn't someting that works easily.

If you insist in having python3.6 a hard requirement for qemu, you're
putting me into the situation of having to do lots of backport work
for quite long time (until everybody really did the upgrade). :(

This individual patch wasn't very complicated, but expect even more
(and more tricky cases) on the horizon.


--mtx

-- 
---
Hinweis: unverschlüsselte E-Mails können leicht abgehört und manipuliert
werden ! Für eine vertrauliche Kommunikation senden Sie bitte ihren
GPG/PGP-Schlüssel zu.
---
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
i...@metux.net -- +49-151-27565287



Re: [PATCH] python 3.5 compatibility

2020-11-30 Thread Enrico Weigelt, metux IT consult
On 30.11.20 10:44, Kevin Wolf wrote:

Hi,

> While type hints are valuable documentation, they are more than just
> that. They help to find and prevent avoidable bugs in the code. We are
> actively in the process of adding them to everything in the QAPI
> generator to improve maintainability rather than removing them.

IOW: I'll have to do lots of backporting work, just to keep it running :(


--mtx

-- 
---
Hinweis: unverschlüsselte E-Mails können leicht abgehört und manipuliert
werden ! Für eine vertrauliche Kommunikation senden Sie bitte ihren
GPG/PGP-Schlüssel zu.
---
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
i...@metux.net -- +49-151-27565287



Re: [PATCH] python 3.5 compatibility

2020-11-30 Thread Enrico Weigelt, metux IT consult
On 27.11.20 20:15, Peter Maydell wrote:

Hi,

> Could you say which "stable distros" you have in mind, and whether
> they are covered by our "supported build platforms" policy
> https://www.qemu.org/docs/master/system/build-platforms.html  ?

I'm running on Devuan Ascii.

And packaging python-3.6 just for a few pieces of one application (qemu)
is far too much work.

--mtx

-- 
---
Hinweis: unverschlüsselte E-Mails können leicht abgehört und manipuliert
werden ! Für eine vertrauliche Kommunikation senden Sie bitte ihren
GPG/PGP-Schlüssel zu.
---
Enrico Weigelt, metux IT consult
Free software and Linux embedded engineering
i...@metux.net -- +49-151-27565287



[PATCH] hw: usb: fix break on older kernel headers that miss USBDEVFS_GET_SPEED

2020-11-27 Thread Enrico Weigelt, metux IT consult
Older kernel headers lack the USBDEVFS_GET_SPEED ioctl. Qemu can easily
work without it, but the api version check isn't sufficient. Instead
time consuming bisection, for finding the really correct version, just
change the ifdef to look for the symbol, instead of api version.

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 hw/usb/host-libusb.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index b950501d10..c894a4b148 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -941,7 +941,7 @@ static int usb_host_open(USBHostDevice *s, libusb_device 
*dev, int hostfd)
 usb_host_ep_update(s);
 
 libusb_speed = libusb_get_device_speed(dev);
-#if LIBUSB_API_VERSION >= 0x01000107 && defined(CONFIG_LINUX)
+#ifdef USBDEVFS_GET_SPEED
 if (hostfd && libusb_speed == 0) {
 /*
  * Workaround libusb bug: libusb_get_device_speed() does not
-- 
2.11.0




[PATCH] scripts: minikconf: support config titles

2020-11-27 Thread Enrico Weigelt, metux IT consult
Add support for config option titles, like the real kconfig does.
Even though they're not presented anywhere yet (since minikconf
only acts in the background), it's good to have them supported,
so we can start adding descriptions in the Kconfig files.

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 scripts/minikconf.py | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/scripts/minikconf.py b/scripts/minikconf.py
index bcd91015d3..28c67906cb 100644
--- a/scripts/minikconf.py
+++ b/scripts/minikconf.py
@@ -206,6 +206,7 @@ class KconfigData:
 self.defined_vars = set()
 self.referenced_vars = dict()
 self.clauses = list()
+self.title = None
 
 # semantic analysis -
 
@@ -290,6 +291,9 @@ class KconfigData:
 cond = (cond & var) if cond is not None else var
 self.clauses.append(KconfigData.SelectClause(symbol, cond))
 
+def do_title(self, title):
+self.title = title
+
 def do_imply(self, var, symbol, cond=None):
 # "config X imply Y [if COND]" is the same as
 # "config Y default y if X [&& COND]"
@@ -323,6 +327,7 @@ TOK_BOOL = 15;TOKENS[TOK_BOOL] = '"bool"';
 TOK_IF = 16;  TOKENS[TOK_IF] = '"if"';
 TOK_ID = 17;  TOKENS[TOK_ID] = 'identifier';
 TOK_EOF = 18; TOKENS[TOK_EOF] = 'end of file';
+TOK_QUOTED = 19;  TOKENS[TOK_QUOTED] = 'quoted string';
 
 class KconfigParserError(Exception):
 def __init__(self, parser, msg, tok=None):
@@ -501,6 +506,7 @@ class KconfigParser:
 # property: DEFAULT y_or_n condition
 #   | DEPENDS ON expr
 #   | SELECT var condition
+#   | BOOL "comment"
 #   | BOOL
 def parse_property(self, var):
 if self.tok == TOK_DEFAULT:
@@ -526,6 +532,9 @@ class KconfigParser:
 self.data.do_imply(var, symbol, cond)
 elif self.tok == TOK_BOOL:
 self.get_token()
+if self.tok == TOK_QUOTED:
+self.data.do_title(self.val)
+self.get_token()
 else:
 raise KconfigParserError(self, 'Error in recursive descent?')
 
@@ -645,6 +654,11 @@ class KconfigParser:
 self.cursor = self.src.find('\n', self.cursor)
 self.val = self.src[start:self.cursor]
 return TOK_SOURCE
+elif self.tok == '"':
+start = self.cursor
+self.cursor = self.src.find('"', self.cursor)+1
+self.val = self.src[start:self.cursor]
+return TOK_QUOTED;
 elif self.tok.isalnum():
 # identifier
 while self.src[self.cursor].isalnum() or self.src[self.cursor] == 
'_':
-- 
2.11.0




[PATCH] python 3.5 compatibility

2020-11-27 Thread Enrico Weigelt, metux IT consult
Several stable distros are still on python-3.5, so qemu cannot be
built there, w/o backporting the whole python stack. In order to
make qemu build there, make it running w/ python-3.5. The changes
are mostly removing the new type annotations (which, IMHO, just
serve for documentation purpose) and replacing f-strings by classic
string formatting.

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 configure  |  4 +--
 scripts/block-coroutine-wrapper.py | 56 ++
 scripts/qapi/commands.py   |  2 +-
 scripts/qapi/common.py |  2 +-
 scripts/qapi/events.py |  2 +-
 scripts/qapi/gen.py| 10 +++
 scripts/qapi/main.py   |  6 ++--
 scripts/qapi/schema.py |  2 +-
 scripts/qapi/source.py | 10 +++
 9 files changed, 46 insertions(+), 48 deletions(-)

diff --git a/configure b/configure
index 18c26e0389..e1119929fa 100755
--- a/configure
+++ b/configure
@@ -1866,8 +1866,8 @@ fi
 
 # Note that if the Python conditional here evaluates True we will exit
 # with status 1 which is a shell 'false' value.
-if ! $python -c 'import sys; sys.exit(sys.version_info < (3,6))'; then
-  error_exit "Cannot use '$python', Python >= 3.6 is required." \
+if ! $python -c 'import sys; sys.exit(sys.version_info < (3,5))'; then
+  error_exit "Cannot use '$python', Python >= 3.5 is required." \
   "Use --python=/path/to/python to specify a supported Python."
 fi
 
diff --git a/scripts/block-coroutine-wrapper.py 
b/scripts/block-coroutine-wrapper.py
index 0461fd1c45..a36f7af06f 100644
--- a/scripts/block-coroutine-wrapper.py
+++ b/scripts/block-coroutine-wrapper.py
@@ -32,11 +32,11 @@ def gen_header():
 copyright = re.sub('^.*Copyright', 'Copyright', __doc__, flags=re.DOTALL)
 copyright = re.sub('^(?=.)', ' * ', copyright.strip(), flags=re.MULTILINE)
 copyright = re.sub('^$', ' *', copyright, flags=re.MULTILINE)
-return f"""\
+return """\
 /*
  * File is generated by scripts/block-coroutine-wrapper.py
  *
-{copyright}
+"""+copyright+"""
  */
 
 #include "qemu/osdep.h"
@@ -55,7 +55,7 @@ class ParamDecl:
 def __init__(self, param_decl: str) -> None:
 m = self.param_re.match(param_decl.strip())
 if m is None:
-raise ValueError(f'Wrong parameter declaration: "{param_decl}"')
+raise ValueError('Wrong parameter declaration: '+param_decl)
 self.decl = m.group('decl')
 self.type = m.group('type')
 self.name = m.group('name')
@@ -107,44 +107,42 @@ def gen_wrapper(func: FuncDecl) -> str:
 bs = 'bs' if func.args[0].type == 'BlockDriverState *' else 'child->bs'
 struct_name = snake_to_camel(name)
 
-return f"""\
+return """\
 /*
- * Wrappers for {name}
+ * Wrappers for """+name+"""
  */
 
-typedef struct {struct_name} {{
+typedef struct """+struct_name+""" {
 BdrvPollCo poll_state;
-{ func.gen_block('{decl};') }
-}} {struct_name};
+"""+func.gen_block('{decl};')+"""
+} """+struct_name+""";
 
-static void coroutine_fn {name}_entry(void *opaque)
-{{
-{struct_name} *s = opaque;
+static void coroutine_fn """+name+"""_entry(void *opaque)
+{
+"""+struct_name+""" *s = opaque;
 
-s->poll_state.ret = {name}({ func.gen_list('s->{name}') });
+s->poll_state.ret = """+name+"""("""+func.gen_list('s->{name}')+""");
 s->poll_state.in_progress = false;
 
 aio_wait_kick();
-}}
-
-int {func.name}({ func.gen_list('{decl}') })
-{{
-if (qemu_in_coroutine()) {{
-return {name}({ func.gen_list('{name}') });
-}} else {{
-{struct_name} s = {{
-.poll_state.bs = {bs},
+}
+
+int """+func.name+"""("""+func.gen_list('{decl}')+""")
+{
+if (qemu_in_coroutine()) {
+return """+name+"""("""+func.gen_list('{name}')+""");
+} else {
+"""+struct_name+""" s = {
+.poll_state.bs = """+bs+""",
 .poll_state.in_progress = true,
+"""+func.gen_block('.{name} = {name},')+"""
+};
 
-{ func.gen_block('.{name} = {name},') }
-}};
-
-s.poll_state.co = qemu_coroutine_create({name}_entry, );
+s.poll_state.co = qemu_coroutine_create("""+name+"""_entry, );
 
 return bdrv_poll_co(_state);
-}}
-}}"""
-
+}
+}"&

[PATCH 4/5] standard-headers: virtio-gpio protocol headers

2020-11-27 Thread Enrico Weigelt, metux IT consult
Introduce virtio-gpio protocol headers from Linux kernel.
(work in progress, not mainlined yet)

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 include/standard-headers/linux/virtio_gpio.h | 39 
 include/standard-headers/linux/virtio_ids.h  |  1 +
 2 files changed, 40 insertions(+)
 create mode 100644 include/standard-headers/linux/virtio_gpio.h

diff --git a/include/standard-headers/linux/virtio_gpio.h 
b/include/standard-headers/linux/virtio_gpio.h
new file mode 100644
index 00..d1db0ef1fe
--- /dev/null
+++ b/include/standard-headers/linux/virtio_gpio.h
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+
+#ifndef _LINUX_VIRTIO_GPIO_H
+#define _LINUX_VIRTIO_GPIO_H
+
+#include 
+
+enum virtio_gpio_event_type {
+   // requests from quest to host
+   VIRTIO_GPIO_EV_GUEST_REQUEST= 0x01, // ->request()
+   VIRTIO_GPIO_EV_GUEST_DIRECTION_INPUT= 0x02, // ->direction_input()
+   VIRTIO_GPIO_EV_GUEST_DIRECTION_OUTPUT   = 0x03, // ->direction_output()
+   VIRTIO_GPIO_EV_GUEST_GET_DIRECTION  = 0x04, // ->get_direction()
+   VIRTIO_GPIO_EV_GUEST_GET_VALUE  = 0x05, // ->get_value()
+   VIRTIO_GPIO_EV_GUEST_SET_VALUE  = 0x06, // ->set_value()
+
+   // messages from host to guest
+   VIRTIO_GPIO_EV_HOST_LEVEL   = 0x11, // gpio state changed
+
+   /* mask bit set on host->guest reply */
+   VIRTIO_GPIO_EV_REPLY= 0xF000,
+};
+
+struct virtio_gpio_config {
+   __u8version;
+   __u8reserved0;
+   __u16   num_gpios;
+   __u32   names_size;
+   __u8reserved1[24];
+   __u8name[32];
+};
+
+struct virtio_gpio_event {
+   __le16 type;
+   __le16 pin;
+   __le32 value;
+};
+
+#endif /* _LINUX_VIRTIO_GPIO_H */
diff --git a/include/standard-headers/linux/virtio_ids.h 
b/include/standard-headers/linux/virtio_ids.h
index b052355ac7..053fe59c73 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -48,5 +48,6 @@
 #define VIRTIO_ID_FS   26 /* virtio filesystem */
 #define VIRTIO_ID_PMEM 27 /* virtio pmem */
 #define VIRTIO_ID_MAC80211_HWSIM 29 /* virtio mac80211-hwsim */
+#define VIRTIO_ID_GPIO  30 /* virtio GPIO */
 
 #endif /* _LINUX_VIRTIO_IDS_H */
-- 
2.11.0




[PATCH 5/5] hw: virtio: add virtio-gpio device emulation

2020-11-27 Thread Enrico Weigelt, metux IT consult
Adding a driver for virtio-based GPIOs. The driver connects to
specified gpio backend and routes all requests there.

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 MAINTAINERS |   7 +
 hw/virtio/Kconfig   |   7 +
 hw/virtio/meson.build   |   1 +
 hw/virtio/virtio-gpio.c | 371 
 4 files changed, 386 insertions(+)
 create mode 100644 hw/virtio/virtio-gpio.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d3873121e2..57deed6c20 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2294,6 +2294,13 @@ S: Supported
 F: backends/gpio.c
 F: backends/gpio-builtin.c
 F: include/sysemu/gpio.h
+F: include/standard-headers/linux/virtio_gpio.h
+
+GPIO Virtio backend
+M: Enrico Weigelt, metux IT consult 
+S: Supported
+F: hw/virtio/virtio-gpio.c
+F: include/hw/virtio/virtio-gpio.h
 
 Memory API
 M: Paolo Bonzini 
diff --git a/hw/virtio/Kconfig b/hw/virtio/Kconfig
index 0eda25c4e1..81da1ee763 100644
--- a/hw/virtio/Kconfig
+++ b/hw/virtio/Kconfig
@@ -33,6 +33,13 @@ config VIRTIO_BALLOON
 default y
 depends on VIRTIO
 
+config VIRTIO_GPIO
+bool
+default y
+depends on VIRTIO
+select BACKEND_GPIO
+select BACKEND_GPIO_BUILTIN
+
 config VIRTIO_CRYPTO
 bool
 default y
diff --git a/hw/virtio/meson.build b/hw/virtio/meson.build
index fbff9bc9d4..88577ff812 100644
--- a/hw/virtio/meson.build
+++ b/hw/virtio/meson.build
@@ -25,6 +25,7 @@ virtio_ss.add(when: 'CONFIG_VHOST_USER_VSOCK', if_true: 
files('vhost-user-vsock.
 virtio_ss.add(when: 'CONFIG_VIRTIO_RNG', if_true: files('virtio-rng.c'))
 virtio_ss.add(when: 'CONFIG_VIRTIO_IOMMU', if_true: files('virtio-iommu.c'))
 virtio_ss.add(when: 'CONFIG_VIRTIO_MEM', if_true: files('virtio-mem.c'))
+virtio_ss.add(when: 'CONFIG_VIRTIO_GPIO', if_true: files('virtio-gpio.c'))
 
 virtio_pci_ss = ss.source_set()
 virtio_pci_ss.add(when: 'CONFIG_VHOST_VSOCK', if_true: 
files('vhost-vsock-pci.c'))
diff --git a/hw/virtio/virtio-gpio.c b/hw/virtio/virtio-gpio.c
new file mode 100644
index 00..37e7614c96
--- /dev/null
+++ b/hw/virtio/virtio-gpio.c
@@ -0,0 +1,371 @@
+/*
+ * A virtio device implementing a hardware gpio port.
+ *
+ * Copyright 2020 Enrico Weigelt, metux IT consult 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/iov.h"
+#include "qemu/module.h"
+#include "qemu/timer.h"
+#include "hw/virtio/virtio.h"
+#include "hw/qdev-properties.h"
+#include "sysemu/gpio.h"
+#include "sysemu/runstate.h"
+#include "qom/object.h"
+#include "qom/object_interfaces.h"
+#include "trace.h"
+#include "qemu/error-report.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_gpio.h"
+
+#define WARN(...) warn_report("virtio-gpio: " __VA_ARGS__)
+
+#define TYPE_VIRTIO_GPIO "virtio-gpio-device"
+OBJECT_DECLARE_SIMPLE_TYPE(VirtIOGPIO, VIRTIO_GPIO)
+#define VIRTIO_GPIO_GET_PARENT_CLASS(obj) \
+OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_GPIO)
+
+typedef struct VirtIOGPIO VirtIOGPIO;
+
+struct VirtIOGPIO {
+VirtIODevice parent_obj;
+
+VirtQueue *vq_in;
+VirtQueue *vq_out;
+
+uint32_t num_gpios;
+
+char **gpio_names;
+uint32_t gpio_names_len;
+
+GpioBackend *gpio;
+char *name;
+
+VMChangeStateEntry *vmstate;
+struct virtio_gpio_event reply_buffer;
+
+void *config_buf;
+int config_len;
+};
+
+static bool is_guest_ready(VirtIOGPIO *vgpio)
+{
+VirtIODevice *vdev = VIRTIO_DEVICE(vgpio);
+if (virtio_queue_ready(vgpio->vq_in)
+&& (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {
+return true;
+}
+return false;
+}
+
+static void virtio_gpio_reply(VirtIOGPIO *vgpio, int type, int pin, int value)
+{
+VirtQueueElement *elem;
+size_t len;
+
+if (!virtio_queue_ready(vgpio->vq_out)) {
+WARN("out queue is not ready yet");
+return;
+}
+
+elem = virtqueue_pop(vgpio->vq_out, sizeof(VirtQueueElement));
+if (!elem) {
+WARN("failed to get xmit queue element");
+return;
+}
+
+vgpio->reply_buffer.type = type;
+vgpio->reply_buffer.pin = pin;
+vgpio->reply_buffer.value = value;
+len = iov_from_buf(elem->in_sg, elem->in_num, 0, >reply_buffer,
+   sizeof(struct virtio_gpio_event));
+virtqueue_push(vgpio->vq_out, elem, len);
+g_free(elem);
+virtio_notify(VIRTIO_DEVICE(vgpio), vgpio->vq_out);
+}
+
+static int do_request(VirtIOGPIO *vgpio, struct virtio_gpio_event *reqbuf)
+{
+switch (reqbuf->type) {
+case VIRTIO_GPIO_EV_GUEST_REQUEST:
+return gpio_backend_request(vgpio->gpio, reqbuf->pin);
+case VIRTIO_GPIO_EV_GUEST_DIRECTION_INPUT:
+return gpio_backend_direction_input(vgpio-&

[PATCH] fix .gitignore

2020-11-27 Thread Enrico Weigelt, metux IT consult
Some entries for autogenerated files have been missing in .gitignore.

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index b32bca1315..48ec051c2e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -10,3 +10,5 @@ TAGS
 *~
 *.ast_raw
 *.depend_raw
+config-temp/
+config.log
-- 
2.11.0




[PATCH 1/5] scripts: minikconf: support config titles

2020-11-27 Thread Enrico Weigelt, metux IT consult
Add support for config option titles, like the real kconfig does.
Even though they're not presented anywhere yet (since minikconf
only acts in the background), it's good to have them supported,
so we can start adding descriptions in the Kconfig files.

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 scripts/minikconf.py | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/scripts/minikconf.py b/scripts/minikconf.py
index bcd91015d3..28c67906cb 100644
--- a/scripts/minikconf.py
+++ b/scripts/minikconf.py
@@ -206,6 +206,7 @@ class KconfigData:
 self.defined_vars = set()
 self.referenced_vars = dict()
 self.clauses = list()
+self.title = None
 
 # semantic analysis -
 
@@ -290,6 +291,9 @@ class KconfigData:
 cond = (cond & var) if cond is not None else var
 self.clauses.append(KconfigData.SelectClause(symbol, cond))
 
+def do_title(self, title):
+self.title = title
+
 def do_imply(self, var, symbol, cond=None):
 # "config X imply Y [if COND]" is the same as
 # "config Y default y if X [&& COND]"
@@ -323,6 +327,7 @@ TOK_BOOL = 15;TOKENS[TOK_BOOL] = '"bool"';
 TOK_IF = 16;  TOKENS[TOK_IF] = '"if"';
 TOK_ID = 17;  TOKENS[TOK_ID] = 'identifier';
 TOK_EOF = 18; TOKENS[TOK_EOF] = 'end of file';
+TOK_QUOTED = 19;  TOKENS[TOK_QUOTED] = 'quoted string';
 
 class KconfigParserError(Exception):
 def __init__(self, parser, msg, tok=None):
@@ -501,6 +506,7 @@ class KconfigParser:
 # property: DEFAULT y_or_n condition
 #   | DEPENDS ON expr
 #   | SELECT var condition
+#   | BOOL "comment"
 #   | BOOL
 def parse_property(self, var):
 if self.tok == TOK_DEFAULT:
@@ -526,6 +532,9 @@ class KconfigParser:
 self.data.do_imply(var, symbol, cond)
 elif self.tok == TOK_BOOL:
 self.get_token()
+if self.tok == TOK_QUOTED:
+self.data.do_title(self.val)
+self.get_token()
 else:
 raise KconfigParserError(self, 'Error in recursive descent?')
 
@@ -645,6 +654,11 @@ class KconfigParser:
 self.cursor = self.src.find('\n', self.cursor)
 self.val = self.src[start:self.cursor]
 return TOK_SOURCE
+elif self.tok == '"':
+start = self.cursor
+self.cursor = self.src.find('"', self.cursor)+1
+self.val = self.src[start:self.cursor]
+return TOK_QUOTED;
 elif self.tok.isalnum():
 # identifier
 while self.src[self.cursor].isalnum() or self.src[self.cursor] == 
'_':
-- 
2.11.0




[PATCH 2/5] backends: introduce gpio backend subsystem

2020-11-27 Thread Enrico Weigelt, metux IT consult
Introducing a backend subsys for hardware GPIOs, so we can now
let simulated GPIO devices actually do something, by talking to
pluggable GPIO backends (eg. speaking to host's gpio subsystem,
gpiod, custom simulation, etc).

This patch does not implement any actual gpio backend, nor any
any any hw simulation drivers yet - just the generic infrastructure.

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 MAINTAINERS   |   6 ++
 backends/Kconfig  |   4 +
 backends/gpio.c   | 255 ++
 backends/meson.build  |   1 +
 include/sysemu/gpio.h |  76 +++
 5 files changed, 342 insertions(+)
 create mode 100644 backends/gpio.c
 create mode 100644 include/sysemu/gpio.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 68bc160f41..bfa29a4560 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2288,6 +2288,12 @@ S: Maintained
 F: gdbstub*
 F: gdb-xml/
 
+GPIO Backend API
+M: Enrico Weigelt, metux IT consult 
+S: Supported
+F: backends/gpio.c
+F: include/sysemu/gpio.h
+
 Memory API
 M: Paolo Bonzini 
 S: Supported
diff --git a/backends/Kconfig b/backends/Kconfig
index f35abc1609..2f17189472 100644
--- a/backends/Kconfig
+++ b/backends/Kconfig
@@ -1 +1,5 @@
 source tpm/Kconfig
+
+config BACKEND_GPIO
+bool "Enable GPIO backends"
+default y
diff --git a/backends/gpio.c b/backends/gpio.c
new file mode 100644
index 00..dc539b0791
--- /dev/null
+++ b/backends/gpio.c
@@ -0,0 +1,255 @@
+/*
+ * QEMU GPIO Backend
+ *
+ * Copyright 2020 Enrico Weigelt, metux IT consult 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include 
+#include "qemu/osdep.h"
+#include "sysemu/gpio.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/module.h"
+#include "qom/object_interfaces.h"
+#include "qemu/error-report.h"
+#include "sysemu/gpio.h"
+
+#define GPIO_FORMAT_VALUE   "gpio%d.value"
+#define GPIO_FORMAT_DIRECTION   "gpio%d.direction"
+
+#define BACKEND_OP_HEAD \
+if (!gpio) \
+return -EFAULT;
+
+#define BACKEND_CLASSOP_HEAD(op) \
+GpioBackendClass *klass; \
+BACKEND_OP_HEAD \
+klass = GPIO_BACKEND_GET_CLASS(gpio); \
+if (!klass) \
+return -EFAULT; \
+if (!klass->op) \
+return -EUNATCH;
+
+int gpio_backend_set_notify(GpioBackend *gpio,
+gpio_backend_notify_t proc,
+void *consumer)
+{
+BACKEND_OP_HEAD
+
+gpio->notify_proc = proc;
+gpio->notify_consumer = consumer;
+
+return 0;
+}
+
+int gpio_backend_send_notify(GpioBackend *gpio, int pin, int event, int value)
+{
+BACKEND_OP_HEAD
+
+if (gpio->notify_proc) {
+return gpio->notify_proc(gpio->notify_consumer, pin, event, value);
+}
+
+return 0;
+}
+
+int gpio_backend_request(GpioBackend *gpio, int pin)
+{
+BACKEND_CLASSOP_HEAD(request);
+return klass->request(gpio, pin);
+}
+
+int gpio_backend_set_value(GpioBackend *gpio, int pin, int state)
+{
+BACKEND_CLASSOP_HEAD(set_value);
+return klass->set_value(gpio, pin, state);
+}
+
+int gpio_backend_get_value(GpioBackend *gpio, int pin)
+{
+BACKEND_CLASSOP_HEAD(get_value);
+return klass->get_value(gpio, pin);
+}
+
+int gpio_backend_direction_output(GpioBackend *gpio, int pin, int state)
+{
+BACKEND_CLASSOP_HEAD(direction_output);
+return klass->direction_output(gpio, pin, state);
+}
+
+int gpio_backend_direction_input(GpioBackend *gpio, int pin)
+{
+BACKEND_CLASSOP_HEAD(direction_input);
+return klass->direction_input(gpio, pin);
+}
+
+int gpio_backend_get_direction(GpioBackend *gpio, int pin)
+{
+BACKEND_CLASSOP_HEAD(get_direction);
+return klass->get_direction(gpio, pin);
+}
+
+int gpio_backend_get_ngpio(GpioBackend *gpio)
+{
+BACKEND_CLASSOP_HEAD(get_ngpio);
+return klass->get_ngpio(gpio);
+}
+
+static void getattr_value(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
+{
+int pin;
+int64_t val = 0;
+GpioBackend *gpio = GPIO_BACKEND(obj);
+
+if (sscanf(name, GPIO_FORMAT_VALUE, ) != 1) {
+error_setg(errp,
+  "gpio: getattr_value() illegal property: \"%s\"",
+   name);
+return;
+}
+
+val = gpio_backend_get_value(gpio, pin);
+visit_type_int(v, name, , errp);
+}
+
+static void setattr_value(Object *obj, Visitor *v, const char *name,
+  void *opaque, Error **errp)
+{
+int pin;
+int64_t val = 0;
+GpioBackend *gpio = GPIO_BACKEND(obj);
+
+if (!visit_type_int(v, name, , errp)) {
+return;
+}
+
+if (sscanf(name, GPIO_FORMAT_VALUE, ) != 1) {
+error_setg(errp,
+   "gpio: setattr_value() illegal property: \"%s\"",
+   name);
+return;
+

[PATCH 3/5] backends: gpio: dummy builtin backend

2020-11-27 Thread Enrico Weigelt, metux IT consult
Adding a dummy GPIO backend driver. Essentially stores the states
in memory and gives some debug output. The current state can be
accessed as a string property.

Signed-off-by: Enrico Weigelt, metux IT consult 
---
 MAINTAINERS |   1 +
 backends/Kconfig|   5 ++
 backends/gpio-builtin.c | 137 
 backends/meson.build|   1 +
 include/sysemu/gpio.h   |   2 +
 5 files changed, 146 insertions(+)
 create mode 100644 backends/gpio-builtin.c

diff --git a/MAINTAINERS b/MAINTAINERS
index bfa29a4560..d3873121e2 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2292,6 +2292,7 @@ GPIO Backend API
 M: Enrico Weigelt, metux IT consult 
 S: Supported
 F: backends/gpio.c
+F: backends/gpio-builtin.c
 F: include/sysemu/gpio.h
 
 Memory API
diff --git a/backends/Kconfig b/backends/Kconfig
index 2f17189472..1c8a462b57 100644
--- a/backends/Kconfig
+++ b/backends/Kconfig
@@ -3,3 +3,8 @@ source tpm/Kconfig
 config BACKEND_GPIO
 bool "Enable GPIO backends"
 default y
+
+config BACKEND_GPIO_BUILTIN
+bool "Dummy GPIO backend"
+depends on BACKEND_GPIO
+default y
diff --git a/backends/gpio-builtin.c b/backends/gpio-builtin.c
new file mode 100644
index 00..ac89a88092
--- /dev/null
+++ b/backends/gpio-builtin.c
@@ -0,0 +1,137 @@
+/*
+ * QEMU GPIO Backend - builtin (dummy)
+ *
+ * Copyright 2020 Enrico Weigelt, metux IT consult 
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/gpio.h"
+#include "qemu/main-loop.h"
+#include "qemu/guest-random.h"
+#include "qom/object.h"
+#include "qemu/error-report.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+
+#define MAX_GPIO256
+
+#define WARN(...)   warn_report("gpio-builtin: " __VA_ARGS__)
+
+#define OP_HEAD(name) \
+GpioBuiltin *gpio = GPIO_BUILTIN(obj); \
+if (id >= gpio->num_gpio) { \
+WARN("%s: gpio id %d out of range", name, id); \
+return -ERANGE; \
+}
+
+#define FLAG_DIRECTION_INPUT1
+#define FLAG_LINE_ACTIVE2
+
+OBJECT_DECLARE_SIMPLE_TYPE(GpioBuiltin, GPIO_BUILTIN)
+
+struct GpioBuiltin {
+GpioBackend parent;
+char *states;
+int num_gpio;
+};
+
+static int gpio_builtin_request(GpioBackend *obj, int id)
+{
+OP_HEAD("request");
+return 0;
+}
+
+static int gpio_builtin_set_value(GpioBackend *obj, int id, int state)
+{
+OP_HEAD("set");
+if (state & QEMU_GPIO_LINE_ACTIVE) {
+gpio->states[id] |= FLAG_LINE_ACTIVE;
+} else {
+gpio->states[id] &= ~FLAG_LINE_ACTIVE;
+}
+return 0;
+}
+
+static int gpio_builtin_direction_input(GpioBackend *obj, int id)
+{
+OP_HEAD("direction-input");
+gpio->states[id] |= FLAG_DIRECTION_INPUT;
+return gpio_builtin_set_value(obj, id, 0);
+}
+
+static int gpio_builtin_direction_output(GpioBackend *obj, int id, int state)
+{
+OP_HEAD("direction-output");
+gpio->states[id] &= ~FLAG_DIRECTION_INPUT;
+return gpio_builtin_set_value(obj, id, state);
+}
+
+static int gpio_builtin_get_direction(GpioBackend *obj, int id)
+{
+OP_HEAD("get-direction");
+return (gpio->states[id] & FLAG_DIRECTION_INPUT ?
+QEMU_GPIO_DIRECTION_INPUT : QEMU_GPIO_DIRECTION_OUTPUT);
+}
+
+static int gpio_builtin_get_value(GpioBackend *obj, int id)
+{
+OP_HEAD("get");
+return (gpio->states[id] & FLAG_LINE_ACTIVE ?
+QEMU_GPIO_LINE_ACTIVE : QEMU_GPIO_LINE_INACTIVE);
+}
+
+static void gpio_builtin_instance_init(Object *obj)
+{
+GpioBuiltin *gpio = GPIO_BUILTIN(obj);
+
+gpio->num_gpio = MAX_GPIO;
+gpio->states = g_malloc(gpio->num_gpio + 1);
+memset(gpio->states, 'i', gpio->num_gpio);
+gpio->states[gpio->num_gpio] = 0;
+gpio_backend_register(>parent);
+}
+
+static void gpio_builtin_instance_finalize(Object *obj)
+{
+GpioBuiltin *gpio = GPIO_BUILTIN(obj);
+gpio_backend_unregister(>parent);
+g_free(gpio->states);
+}
+
+static int gpio_builtin_get_ngpio(GpioBackend *obj)
+{
+GpioBuiltin *gpio = GPIO_BUILTIN(obj);
+return gpio->num_gpio;
+}
+
+static void gpio_builtin_class_init(ObjectClass *klass, void *data)
+{
+GpioBackendClass *gpio = GPIO_BACKEND_CLASS(klass);
+
+gpio->name = g_strdup("gpio-builtin");
+gpio->get_value= gpio_builtin_get_value;
+gpio->set_value= gpio_builtin_set_value;
+gpio->get_direction= gpio_builtin_get_direction;
+gpio->direction_input  = gpio_builtin_direction_input;
+gpio->direction_output = gpio_builtin_direction_output;
+gpio->request  = gpio_builtin_request;
+gpio->get_ngpio= gpio_builtin_get_ngpio;
+}
+
+static const TypeInfo gpio_

[Qemu-devel] [Bug 1500265] Re: nested 9p filesystem with security_model=mapped-xattr

2018-08-08 Thread Enrico Weigelt, metux IT consult
Interesting approach. But maybe it should be configurable (eg. specify
the mapping prefix).

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1500265

Title:
  nested 9p filesystem with security_model=mapped-xattr

Status in QEMU:
  New

Bug description:
  I do not know whether this is a bug or a feature request, but on a 9p
  virtfs with security_model=mapped-xattr, access to extended attributes
  starting with "user.virtfs" coming from the guest seem to be silently
  ignored. Would it not be more correct to use some sort of "escaping",
  say map to "user.virtfs.x" on guest to "user.virtfs.virtfs.x" on host
  or something like that, so that the guest can use arbitrary
  attributes.

  In particular, this would allow nested virtual machines to use nested
  9p virtfs with security_model=mapped-xattr.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1500265/+subscriptions



[Qemu-devel] [Bug 1785902] Re: local/9pfs: Too many levels of symbolic links

2018-08-07 Thread Enrico Weigelt, metux IT consult
Turned out that security_model=mapped can't cope with symlinks in the
host file system.

Instead, security_model=passthrough works as expected. OTOH, I'll have
to check, whether this mode already provides a safe chroot, or guest can
escape and damage the host system.

The wiki page needs some more documentation on that:
https://wiki.qemu.org/Documentation/9psetup

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1785902

Title:
  local/9pfs: Too many levels of symbolic links

Status in QEMU:
  New

Bug description:
  Version: 2.9.1

  The primary symptom is resolving symlink fails w/ error "too many
  levels of symbolic links".

  My analysis showed that local_readlink() uses local_open_nofollow() to
  open the file and then tries to read it. local_open_nofollow() then
  tries to open the file w/ O_NOFOLLOW, which obviously fails if the
  requested file is a symlink.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1785902/+subscriptions



[Qemu-devel] [Bug 1785902] [NEW] local/9pfs: Too many levels of symbolic links

2018-08-07 Thread Enrico Weigelt, metux IT consult
Public bug reported:

Version: 2.9.1

The primary symptom is resolving symlink fails w/ error "too many levels
of symbolic links".

My analysis showed that local_readlink() uses local_open_nofollow() to
open the file and then tries to read it. local_open_nofollow() then
tries to open the file w/ O_NOFOLLOW, which obviously fails if the
requested file is a symlink.

** Affects: qemu
 Importance: Undecided
 Status: New

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1785902

Title:
  local/9pfs: Too many levels of symbolic links

Status in QEMU:
  New

Bug description:
  Version: 2.9.1

  The primary symptom is resolving symlink fails w/ error "too many
  levels of symbolic links".

  My analysis showed that local_readlink() uses local_open_nofollow() to
  open the file and then tries to read it. local_open_nofollow() then
  tries to open the file w/ O_NOFOLLOW, which obviously fails if the
  requested file is a symlink.

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1785902/+subscriptions