From: Corey Minyard <cminyard@mvista.com>
To: Ilya Chichkov <ilya.chichkov.dev@gmail.com>
Cc: "Cédric Le Goater" <clg@redhat.com>,
qemu-devel@nongnu.org,
"Pierrick Bouvier" <pierrick.bouvier@oss.qualcomm.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Daniel P . Berrangé" <berrange@redhat.com>,
"Eric Blake" <eblake@redhat.com>,
"Markus Armbruster" <armbru@redhat.com>,
"Fabiano Rosas" <farosas@suse.de>,
"Laurent Vivier" <lvivier@redhat.com>
Subject: Re: [PATCH v5] hw/i2c: Add remote I2C master with host CUSE bridge
Date: Fri, 24 Jul 2026 08:30:58 -0500 [thread overview]
Message-ID: <amNpErR1oDqsQknD@mail.minyard.net> (raw)
In-Reply-To: <CADgQP8xZo37VqCmqA8fey1_FgJSPi-PQRbDDeuKK-1LGYixYfw@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 9633 bytes --]
On Fri, Jul 24, 2026 at 11:19:17AM +0300, Ilya Chichkov wrote:
> Hi Cédric,
>
> On Wed, 22 Jul 2026 19:42:03 +0200, Cédric Le Goater <clg@redhat.com> wrote:
> > I think a lighter QMP-based approach would serve the same purpose,
> > maybe better, and fit in better in QEMU, without the dependency and
> > maintenance cost:
>
> As Corey and I discussed earlier in the thread, QMP doesn't cover the primary
> motivation for this patch: zero-code transparency for existing host software.
>
> An `i2c-transfer` QMP command would be a great addition for custom scripts,
> but the main goal here is to allow native Linux user-space binaries
> (like i2c-tools,
> lm-sensors) running on the host to talk to QEMU's I2C slaves unmodified, simply
> by opening /dev/i2c-N. Rewriting legacy test suites to speak QMP JSON over a
> socket is often not feasible.
I think what Cédric is saying here is that if you provided a generic
QMP interface that allowed these sorts of operations and wrote an
external program that used said interface to provide a fuse interface,
that would be better. It has a number of advantages:
* You add an interface to QEMU that others can easily use to test
devices.
* You are not tied to QEMU when you want to extend the functions of
the fuse interface.
* It's one less dependency in QEMU. QEMU has a *lot* of dependencies,
and the fewer the better.
The only disadvantage I can think of is that it's one more piece of
software if you are setting this up.
This is not a big piece of software, I agree, but from experience I
think you will be happier with this sort of design in the long run.
It puts you more in control of what you are doing.
And, of course, it makes the QEMU maintainers happier :-).
-corey
>
> > The dependency cost seems high for the use case: libfuse3 + the cuse
> > kernel module pulled into the system emulator build. It's also ~3K
> > lines of new code, three QOM types, FUSE session management, etc.
>
> Regarding dependencies, `libfuse3` is actually not new to the project — it has
> been a supported QEMU dependency for a long time (already used by the block
> layer in `block/export/fuse.c`). Also, just to clarify the diff: the core
> implementation is roughly ~2K lines. The remaining ~900 lines are dedicated
> entirely to qtests and RST documentation.
>
> However, I agree about not polluting the core emulation build with
> Linux-specific
> headers and libfuse3. The maintenance cost must be minimized. To address this,
> I've refactored the architecture for v6 to ensure strict isolation:
>
> - All Linux and FUSE-specific headers are removed from public QEMU headers.
> The internal state structure is now opaque and hidden inside
> remote-i2c-cuse.c.
> - The CUSE backend is isolated behind its own
> CONFIG_REMOTE_I2C_BACKEND_CUSE in Kconfig and meson.build, strictly
> depending on LINUX and fuse3.
>
> On macOS, Windows, or minimalistic builds without libfuse, QEMU will build
> cleanly without pulling in this backend or any of its dependencies.
>
> Would making the CUSE transport a strictly optional, isolated Linux-only backend
> alleviate your concerns regarding the hardware emulation core?
>
> Best regards,
> Ilya
>
> ср, 22 июл. 2026 г. в 20:42, Cédric Le Goater <clg@redhat.com>:
> >
> > On 7/22/26 14:57, Ilya Chichkov wrote:
> > > Add a "remote-i2c-master" device that exposes a QEMU I2C bus to the
> > > host system through a FUSE/CUSE character device. This lets external
> > > host programs and standard i2c-tools interact with I2C slaves emulated
> > > inside QEMU as if they were real devices attached to the host.
> > >
> > > The implementation is split into three layers:
> > >
> > > - A non-blocking finite state machine that drives the QEMU I2C
> > > master. It is pumped by a QEMU Bottom Half and uses virtual timers
> > > to yield during long transfers and to model clock stretching for
> > > asynchronous slaves, so the main loop is never blocked. The FSM
> > > walks IDLE -> ADDR -> SEND/RECV -> WAIT_STRETCH -> END -> FINISHED
> > > and handles NACKs (ENXIO), lost arbitration (EBUSY, with optional
> > > back-off and retry), stretch timeouts, and manual abort/reset.
> > >
> > > - An abstract RemoteI2CBackend QOM base class that decouples the
> > > internal I2C hardware state machine (the frontend) from any
> > > host-specific transport, exposing on_tx_complete and on_tx_error
> > > virtual callbacks.
> > >
> > > - A concrete remote-i2c-backend-cuse backend implementing that
> > > transport over CUSE. It manages the FUSE session and integrates
> > > its file descriptors into QEMU's main AioContext event loop,
> > > translates Linux I2C_RDWR, I2C_SMBUS and I2C_SLAVE ioctls into
> > > generic byte streams for the FSM, and formats responses back into
> > > Linux I2C/SMBus structures for the FUSE driver. SMBus repeated
> > > start is supported for atomic write-then-read operations.
> > >
> > > Example usage:
> > >
> > > -device remote-i2c-master,i2cbus=i2c-bus.0,devname=i2c-33
> > > -object remote-i2c-backend-cuse,id=b0,devname=i2c-33
> > >
> > > This creates /dev/i2c-33 on the host, usable with i2c-tools:
> > >
> > > i2cdetect -y -l
> > > i2cget -y <bus_id> <addr> <reg>
> > >
> > > Acked-by: Markus Armbruster <armbru@redhat.com>
> > > Signed-off-by: Ilya Chichkov <ilya.chichkov.dev@gmail.com>
> > > ---
> > > v2:
> > > - docs/system/devices/remote-i2c-master.rst: Documented concurrent
> > > bus access details and the 'raise-arbitrage-lost' property.
> > > ---
> > > v3:
> > > - qapi/qom.json: Fix RemoteI2CBackendCuseProperties formatting and
> > > expand member documentation (devname, fuse-opts, debug).
> > > - tests/qtest: Add remote-i2c-cuse-test covering capabilities,
> > > functional smoke test, synchronous sensor read/write.
> > > ---
> > > v4:
> > > - qapi: reference the rst doc via :doc:
> > > - qapi: fuse-opts is now ['str'] instead of a space-separated string
> > > - qapi: drop redundant 'debug' property (pass -d via fuse-opts)
> > > ---
> > > v5:
> > > - docs/system/device-emulation.rst: add remote-i2c-master.rst to
> > > the toctree under "Emulated Devices"
> > > - qapi/qom.json: move RemoteI2CBackendCuseProperties definition
> > > before RemoteObjectProperties as requested; change "for usage
> > > information" to "for detailed usage information"
> > > ---
> > > ---
> > > docs/system/device-emulation.rst | 1 +
> > > docs/system/devices/remote-i2c-master.rst | 217 ++++
> > > hw/i2c/Kconfig | 5 +
> > > hw/i2c/meson.build | 6 +
> > > hw/i2c/remote-i2c-backend.c | 30 +
> > > hw/i2c/remote-i2c-cuse.c | 1173 +++++++++++++++++++++
> > > hw/i2c/remote-i2c-fsm.c | 521 +++++++++
> > > hw/i2c/remote-i2c-master.c | 145 +++
> > > hw/i2c/trace-events | 29 +
> > > include/hw/i2c/remote-i2c-backend.h | 70 ++
> > > include/hw/i2c/remote-i2c-cuse.h | 93 ++
> > > include/hw/i2c/remote-i2c-master.h | 77 ++
> > > qapi/qom.json | 29 +
> > > tests/qtest/meson.build | 2 +
> > > tests/qtest/remote-i2c-cuse-test.c | 326 ++++++
> > > 15 files changed, 2724 insertions(+)
> > > create mode 100644 docs/system/devices/remote-i2c-master.rst
> > > create mode 100644 hw/i2c/remote-i2c-backend.c
> > > create mode 100644 hw/i2c/remote-i2c-cuse.c
> > > create mode 100644 hw/i2c/remote-i2c-fsm.c
> > > create mode 100644 hw/i2c/remote-i2c-master.c
> > > create mode 100644 include/hw/i2c/remote-i2c-backend.h
> > > create mode 100644 include/hw/i2c/remote-i2c-cuse.h
> > > create mode 100644 include/hw/i2c/remote-i2c-master.h
> > > create mode 100644 tests/qtest/remote-i2c-cuse-test.c
> >
> > If I understand this proposal correctly, it lets host-side i2c
> > tools talk to emulated I2C devices. The example is i2cdetect/i2cget
> > against a tmp105 on an Aspeed bus.
> >
> > QEMU already has mechanisms for this though. qtest can read/write I2C
> > registers programmatically, QMP can query device state, and the guest
> > OS itself sees the I2C bus natively.
> >
> > The dependency cost seems high for the use case: libfuse3 + the cuse
> > kernel module pulled into the system emulator build. It's also ~3K
> > lines of new code, three QOM types, FUSE session management, etc.
> > The surface area for bugs is large. It's a heavy burden for what it
> > gives.
> >
> > I think a lighter QMP-based approach would serve the same purpose,
> > maybe better, and fit in better in QEMU, without the dependency and
> > maintenance cost:
> >
> > - No host kernel dependency
> > - Works remotely (QMP over socket)
> > - Fits QEMU's existing management model
> > - Much less code
> > - Testable without root or kernel modules
> >
> > Have you considered extending QMP with an I2C transaction command
> > instead? Something like:
> >
> > { 'command': 'i2c-transfer',
> > 'data': { 'bus': 'str',
> > 'address': 'uint8',
> > 'read': 'bool',
> > '*data': ['uint8'],
> > '*length': 'uint16' },
> > 'returns': { '*data': ['uint8'] } }
> >
> >
> > Thanks,
> >
> > C.
> >
[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 3365 bytes --]
next prev parent reply other threads:[~2026-07-24 13:31 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-22 12:57 [PATCH v5] hw/i2c: Add remote I2C master with host CUSE bridge Ilya Chichkov
2026-07-22 17:42 ` Cédric Le Goater
2026-07-24 8:19 ` Ilya Chichkov
2026-07-24 13:30 ` Corey Minyard [this message]
2026-07-24 14:49 ` Ilya Chichkov
2026-07-24 15:15 ` Corey Minyard
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=amNpErR1oDqsQknD@mail.minyard.net \
--to=cminyard@mvista.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=clg@redhat.com \
--cc=eblake@redhat.com \
--cc=farosas@suse.de \
--cc=ilya.chichkov.dev@gmail.com \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=pierrick.bouvier@oss.qualcomm.com \
--cc=qemu-devel@nongnu.org \
/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.