On Fri, Jul 24, 2026 at 05:49:02PM +0300, Ilya Chichkov wrote: > Hi Corey, Cédric, > > On Fri, 24 Jul 2026 08:30:58 -0500, Corey Minyard wrote: > > 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. > > I see your point about keeping the core emulator clean and minimizing > dependencies. > > I am willing to pivot to this architectural direction. I can drop the CUSE > backend from this patch series and instead implement the `i2c-transfer` > QMP command, as Cédric originally suggested. I will handle the CUSE > part externally. > > Before I send v6, are there any other concerns regarding the core FSM > logic, or would replacing CUSE with a QMP backend be sufficient? I didn't see anything, it looked clean and well written to me, but I am not as much of a QEMU expert as others. I kind of happened into this as I know a lot about IPMI and I2C. -corey > > Best regards, > Ilya > > > пт, 24 июл. 2026 г. в 16:31, Corey Minyard : > > > > 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 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 : > > > > > > > > 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 > > > > > > > > > > Acked-by: Markus Armbruster > > > > > Signed-off-by: Ilya Chichkov > > > > > --- > > > > > 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. > > > >