From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Ruslan Ruslichenko <ruslichenko.r@gmail.com>
Cc: qemu-devel@nongnu.org, qemu-arm@nongnu.org,
peter.maydell@linaro.org, artem_mygaiev@epam.com,
volodymyr_babchuk@epam.com, takahiro.nakata.wr@renesas.com,
"Edgar E . Iglesias" <edgar.iglesias@gmail.com>,
francisco.iglesias@amd.com, Ruslan_Ruslichenko@epam.com,
"Edgar E . Iglesias" <edgar.iglesias@amd.com>
Subject: Re: [PATCH 08/29] hw/core: Setup Remote Port I/O channels
Date: Thu, 5 Feb 2026 20:28:20 +0000 [thread overview]
Message-ID: <aYT9ZMNk7stEXhHB@redhat.com> (raw)
In-Reply-To: <20260205195824.2610192-9-ruslichenko.r@gmail.com>
On Thu, Feb 05, 2026 at 08:58:03PM +0100, Ruslan Ruslichenko wrote:
> From: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
>
> Add initialization of communication channels with
> remote peer.
>
> This includes character device backend, which can be
> configured based on QOM properties or automatic socket
> creation based on the machine path. The patch also
> initializes the signaling event pipes.
>
> Signed-off-by: Edgar E. Iglesias <edgar.iglesias@amd.com>
> Signed-off-by: Takahiro Nakata <takahiro.nakata.wr@renesas.com>
> Signed-off-by: Ruslan Ruslichenko <Ruslan_Ruslichenko@epam.com>
> ---
> hw/core/remote-port.c | 187 ++++++++++++++++++++++++++++++++++
> include/hw/core/remote-port.h | 16 +++
> 2 files changed, 203 insertions(+)
>
> diff --git a/hw/core/remote-port.c b/hw/core/remote-port.c
> index c909a825f3..5154c1bc2a 100644
> --- a/hw/core/remote-port.c
> +++ b/hw/core/remote-port.c
> @@ -52,6 +52,58 @@
> #define REMOTE_PORT_CLASS(klass) \
> OBJECT_CLASS_CHECK(RemotePortClass, (klass), TYPE_REMOTE_PORT)
>
> +static char *rp_sanitize_prefix(RemotePort *s)
> +{
> + char *sanitized_name;
> + char *c;
> +
> + sanitized_name = g_strdup(s->prefix);
> + for (c = sanitized_name; *c != '\0'; c++) {
> + if (*c == '/') {
> + *c = '_';
> + }
> + }
> + return sanitized_name;
> +}
> +
> +static char *rp_autocreate_chardesc(RemotePort *s, bool server)
> +{
> + char *prefix;
> + char *chardesc;
> + int r;
> +
> + prefix = rp_sanitize_prefix(s);
> + r = asprintf(&chardesc, "unix:%s/qemu-rport-%s%s",
> + machine_path, prefix, server ? ",wait,server" : "");
> + assert(r > 0);
> + free(prefix);
> + return chardesc;
> +}
> +
> +static Chardev *rp_autocreate_chardev(RemotePort *s, char *name)
> +{
> + Chardev *chr = NULL;
> + char *chardesc;
> + char *s_path;
> + int r;
> +
> + r = asprintf(&s_path, "%s/qemu-rport-%s", machine_path,
> + rp_sanitize_prefix(s));
> + assert(r > 0);
> + if (g_file_test(s_path, G_FILE_TEST_EXISTS)) {
> + chardesc = rp_autocreate_chardesc(s, false);
> + chr = qemu_chr_new_noreplay(name, chardesc, false, NULL);
> + free(chardesc);
> + }
> + free(s_path);
> +
> + if (!chr) {
> + chardesc = rp_autocreate_chardesc(s, true);
> + chr = qemu_chr_new_noreplay(name, chardesc, false, NULL);
> + free(chardesc);
> + }
> + return chr;
> +}
>
> static void rp_reset(DeviceState *dev)
> {
> @@ -66,6 +118,127 @@ static void rp_reset(DeviceState *dev)
>
> static void rp_realize(DeviceState *dev, Error **errp)
> {
> + RemotePort *s = REMOTE_PORT(dev);
> + int r;
> + Error *err = NULL;
> +
> + s->prefix = object_get_canonical_path(OBJECT(dev));
> +
> + if (!qemu_chr_fe_get_driver(&s->chr)) {
> + char *name;
> + Chardev *chr = NULL;
> + static int nr;
> +
> + r = asprintf(&name, "rport%d", nr);
> + nr++;
> + assert(r > 0);
> +
> + if (s->chrdev_id) {
> + chr = qemu_chr_find(s->chrdev_id);
> + }
> +
> + if (chr) {
> + /* Found the chardev via commandline */
> + } else if (s->chardesc) {
> + chr = qemu_chr_new(name, s->chardesc, NULL);
> + } else {
> + if (!machine_path) {
> + error_report("%s: Missing chardesc prop."
> + " Forgot -machine-path?",
> + s->prefix);
> + exit(EXIT_FAILURE);
> + }
> + chr = rp_autocreate_chardev(s, name);
> + }
Having three different ways to configure the chardev rather
feels like overkill. IMHO it should be sufficient to just
accept thue chardev ID as a mandatory argument, and not
attempt to create chardevs from this code. That would
in turn seem to avoid the need for the -machine-path arg
to exist ?
> +#ifdef _WIN32
> + /*
> + * Create a socket connection between two sockets. We auto-bind
> + * and read out the port selected by the kernel.
> + */
> + {
> + char *name;
> + SocketAddress *sock;
> + int port;
> + int listen_sk;
> +
> + sock = socket_parse("127.0.0.1:0", &error_abort);
> + listen_sk = socket_listen(sock, 1, &error_abort);
Please avoid introducing new usage of low level sockets APIs. The higher
level QIOChannelSocket APIs is preferred, that said.....
> +
> + if (s->event.pipe.read < 0) {
> + perror("socket read");
> + exit(EXIT_FAILURE);
> + }
> +
> + {
> + struct sockaddr_in saddr;
> + socklen_t slen = sizeof saddr;
> + int r;
> +
> + r = getsockname(listen_sk, (struct sockaddr *) &saddr, &slen);
> + if (r < 0) {
> + perror("getsockname");
> + exit(EXIT_FAILURE);
> + }
> + port = htons(saddr.sin_port);
> + }
> +
> + name = g_strdup_printf("127.0.0.1:%d", port);
> + s->event.pipe.write = inet_connect(name, &error_abort);
> + g_free(name);
> + if (s->event.pipe.write < 0) {
> + perror("socket write");
> + exit(EXIT_FAILURE);
> + }
> +
> + for (;;) {
> + struct sockaddr_in saddr;
> + socklen_t slen = sizeof saddr;
> + int fd;
> +
> + slen = sizeof(saddr);
> + fd = qemu_accept(listen_sk, (struct sockaddr *)&saddr, &slen);
> + if (fd < 0 && errno != EINTR) {
> + close(listen_sk);
> + return;
> + } else if (fd >= 0) {
> + close(listen_sk);
> + s->event.pipe.read = fd;
> + break;
> + }
> + }
> +
> + if (!qemu_set_blocking(s->event.pipe.read, false, &err)) {
> + error_report("%s: Unable to set non-block for internal pipes",
> + s->prefix);
> + exit(EXIT_FAILURE);
> + }
> + }
> +#else
> + if (!g_unix_open_pipe(s->event.pipes, FD_CLOEXEC, NULL)) {
> + error_report("%s: Unable to create remort-port internal pipes",
> + s->prefix);
> + exit(EXIT_FAILURE);
> + }
> +
> + if (!qemu_set_blocking(s->event.pipe.read, false, &err)) {
> + error_report("%s: Unable to set non-block for internal pipes",
> + s->prefix);
> + exit(EXIT_FAILURE);
> + }
> +
> +#endif
... I can't help thinking we have this code "self event pipe" design
somewhere else in QEMU. Ideally we would have a helper API for this
task and avoid OS conditional code in this device impl.
> }
>
> static void rp_unrealize(DeviceState *dev)
> @@ -73,6 +246,13 @@ static void rp_unrealize(DeviceState *dev)
> RemotePort *s = REMOTE_PORT(dev);
>
> s->finalizing = true;
> +
> + info_report("%s: Wait for remote-port to disconnect", s->prefix);
> + qemu_chr_fe_disconnect(&s->chr);
> +
> + close(s->event.pipe.read);
> + close(s->event.pipe.write);
> + object_unparent(OBJECT(s->chrdev));
> }
>
> static const VMStateDescription vmstate_rp = {
> @@ -84,6 +264,12 @@ static const VMStateDescription vmstate_rp = {
> }
> };
>
> +static Property rp_properties[] = {
> + DEFINE_PROP_CHR("chardev", RemotePort, chr),
> + DEFINE_PROP_STRING("chardesc", RemotePort, chardesc),
> + DEFINE_PROP_STRING("chrdev-id", RemotePort, chrdev_id),
> +};
This really feels lik
> +
> static void rp_prop_allow_set_link(const Object *obj, const char *name,
> Object *val, Error **errp)
> {
> @@ -112,6 +298,7 @@ static void rp_class_init(ObjectClass *klass, const void *data)
> dc->realize = rp_realize;
> dc->unrealize = rp_unrealize;
> dc->vmsd = &vmstate_rp;
> + device_class_set_props_n(dc, rp_properties, ARRAY_SIZE(rp_properties));
> }
>
> static const TypeInfo rp_info = {
> diff --git a/include/hw/core/remote-port.h b/include/hw/core/remote-port.h
> index db71071c8e..0f40018cdb 100644
> --- a/include/hw/core/remote-port.h
> +++ b/include/hw/core/remote-port.h
> @@ -56,8 +56,24 @@ typedef struct RemotePortDeviceClass {
> struct RemotePort {
> DeviceState parent;
>
> + union {
> + int pipes[2];
> + struct {
> + int read;
> + int write;
> + } pipe;
> + } event;
> + Chardev *chrdev;
> + CharFrontend chr;
> bool finalizing;
>
> + char *chardesc;
> + char *chrdev_id;
> +
> + const char *prefix;
> + const char *remote_prefix;
> +
> + uint32_t current_id;
> bool reset_done;
>
> #define REMOTE_PORT_MAX_DEVS 1024
> --
> 2.43.0
>
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2026-02-05 20:28 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-05 19:57 [PATCH 00/29] hw/core: Introduce Remote Port Co-simulation Protocol Ruslan Ruslichenko
2026-02-05 19:57 ` [PATCH 01/29] hw/core: Add Remote Port protocol packet definition Ruslan Ruslichenko
2026-02-05 20:38 ` Daniel P. Berrangé
2026-02-06 17:45 ` Ruslan Ruslichenko
2026-02-06 18:06 ` Daniel P. Berrangé
2026-02-05 19:57 ` [PATCH 02/29] hw/core: Add Remote Port header helpers Ruslan Ruslichenko
2026-02-05 19:57 ` [PATCH 03/29] hw/core: Add Remote Port session state and hello protocol Ruslan Ruslichenko
2026-02-05 19:57 ` [PATCH 04/29] hw/core: Implement Remote Port bus access helpers Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 05/29] hw/core: Implement Remote Port irq, sync and ATS helpers Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 06/29] system/vl: Introduce -machine-path command line option Ruslan Ruslichenko
2026-02-05 20:17 ` Daniel P. Berrangé
2026-02-05 19:58 ` [PATCH 07/29] hw/core: Add Remote Port object skeleton Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 08/29] hw/core: Setup Remote Port I/O channels Ruslan Ruslichenko
2026-02-05 20:28 ` Daniel P. Berrangé [this message]
2026-02-06 17:33 ` Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 09/29] hw/core: Add Remote Port protocol thread and handshake Ruslan Ruslichenko
2026-02-05 20:29 ` Daniel P. Berrangé
2026-02-06 17:38 ` Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 10/29] hw/core: Implement Remote Port packet dispatch logic Ruslan Ruslichenko
2026-02-05 20:32 ` Daniel P. Berrangé
2026-02-05 19:58 ` [PATCH 11/29] hw/core: Implement Remote Port response handling Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 12/29] hw/core: Implement Remote Port time synchronization Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 13/29] system/memory: Introduce unified MemoryTransaction and .access callback Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 14/29] hw/core: Add Remote Port Memory Master object skeleton Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 15/29] hw/core: Implement Remote Port Memory Master bus transactions Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 16/29] system/physmem: Add ats_do_translate helper Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 17/29] hw/core: Add Remote Port ATS device skeleton Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 18/29] hw/core: Implement Remote Port ATS logic and cache management Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 19/29] hw/core: Add Remote Port memory slave device Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 20/29] hw/core: Add Remote Port GPIO/Interrupt bridge Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 21/29] hw/core: Add Remote Port Stream device Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 22/29] hw/core: Add Remote Port files to build Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 23/29] system: Introduce -sync-quantum command line option Ruslan Ruslichenko
2026-02-05 20:40 ` Daniel P. Berrangé
2026-02-06 17:57 ` Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 24/29] hw/core: Add FDT support to Remote Port GPIO Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 25/29] hw/core: Add FDT support to Remote Port memory master Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 26/29] hw/core: Add Remote Port connection support to fdt-generic Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 27/29] hw/core: Support IOMMU translation for Remote Port memory slave Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 28/29] hw/core: Add Remote Port attachment helpers Ruslan Ruslichenko
2026-02-05 19:58 ` [PATCH 29/29] hw/core: Add ATS support to Remote Port memory slave Ruslan Ruslichenko
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aYT9ZMNk7stEXhHB@redhat.com \
--to=berrange@redhat.com \
--cc=Ruslan_Ruslichenko@epam.com \
--cc=artem_mygaiev@epam.com \
--cc=edgar.iglesias@amd.com \
--cc=edgar.iglesias@gmail.com \
--cc=francisco.iglesias@amd.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=ruslichenko.r@gmail.com \
--cc=takahiro.nakata.wr@renesas.com \
--cc=volodymyr_babchuk@epam.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.