Benjamin Herrenschmidt
2018-Aug-05 21:16 UTC
[RFC 0/4] Virtio uses DMA API for all devices
On Sun, 2018-08-05 at 00:29 -0700, Christoph Hellwig wrote:> On Sun, Aug 05, 2018 at 11:10:15AM +1000, Benjamin Herrenschmidt wrote: > > - One you have rejected, which is to have a way for "no-iommu" virtio > > (which still doesn't use an iommu on the qemu side and doesn't need > > to), to be forced to use some custom DMA ops on the VM side. > > > > - One, which sadly has more overhead and will require modifying more > > pieces of the puzzle, which is to make qemu uses an emulated iommu. > > Once we make qemu do that, we can then layer swiotlb on top of the > > emulated iommu on the guest side, and pass that as dma_ops to virtio. > > Or number three: have a a virtio feature bit that tells the VM > to use whatever dma ops the platform thinks are appropinquate for > the bus it pretends to be on. Then set a dma-range that is limited > to your secure memory range (if you really need it to be runtime > enabled only after a device reset that rescans) and use the normal > dma mapping code to bounce buffer.Who would set this bit ? qemu ? Under what circumstances ? What would be the effect of this bit while VIRTIO_F_IOMMU is NOT set, ie, what would qemu do and what would Linux do ? I'm not sure I fully understand your idea. I'm trying to understand because the limitation is not a device side limitation, it's not a qemu limitation, it's actually more of a VM limitation. It has most of its memory pages made inaccessible for security reasons. The platform from a qemu/KVM perspective is almost entirely normal. So I don't understand when would qemu set this bit, or should it be set by the VM at runtime ? Cheers, Ben.
Benjamin Herrenschmidt
2018-Aug-05 21:30 UTC
[RFC 0/4] Virtio uses DMA API for all devices
On Mon, 2018-08-06 at 07:16 +1000, Benjamin Herrenschmidt wrote:> I'm trying to understand because the limitation is not a device side > limitation, it's not a qemu limitation, it's actually more of a VM > limitation. It has most of its memory pages made inaccessible for > security reasons. The platform from a qemu/KVM perspective is almost > entirely normal.In fact this is probably the best image of what's going on: It's a normal VM from a KVM/qemu perspective (and thus virtio). It boots normally, can run firmware, linux, etc... normally, it's not created with any different XML or qemu command line definition etc... It just that once it reaches the kernel with the secure stuff enabled (could be via kexec from a normal kernel), that kernel will "stash away" most of the VM's memory into some secure space that nothing else (not even the hypervisor) can access. It can keep around a pool or two of normal memory for bounce buferring IOs but that's about it. I think that's the clearest way I could find to explain what's going on, and why I'm so resistant on adding things on qemu side. That said, we *can* (and will) notify KVM and qemu of the transition, and we can/will do so after virtio has been instanciated and used by the bootloader, but before it will be used (or even probed) by the secure VM itself, so there's an opportunity to poke at things, either from the VM itself (a quirk poking at virtio config space for example) or from qemu (though I find the idea of iterating all virtio devices from qemu to change a setting rather gross). Cheers, Ben.
On Mon, Aug 06, 2018 at 07:16:47AM +1000, Benjamin Herrenschmidt wrote:> Who would set this bit ? qemu ? Under what circumstances ?I don't really care who sets what. The implementation might not even involved qemu. It is your job to write a coherent interface specification that does not depend on the used components. The hypervisor might be PAPR, Linux + qemu, VMware, Hyperv or something so secret that you'd have to shoot me if you had to tell me. The guest might be Linux, FreeBSD, AIX, OS400 or a Hipster project of the day in Rust. As long as we properly specify the interface it simplify does not matter.> What would be the effect of this bit while VIRTIO_F_IOMMU is NOT set, > ie, what would qemu do and what would Linux do ? I'm not sure I fully > understand your idea.In a perfect would we'd just reuse VIRTIO_F_IOMMU and clarify the description which currently is rather vague but basically captures the use case. Currently is is: VIRTIO_F_IOMMU_PLATFORM(33) This feature indicates that the device is behind an IOMMU that translates bus addresses from the device into physical addresses in memory. If this feature bit is set to 0, then the device emits physical addresses which are not translated further, even though an IOMMU may be present. And I'd change it to something like: VIRTIO_F_PLATFORM_DMA(33) This feature indicates that the device emits platform specific bus addresses that might not be identical to physical address. The translation of physical to bus address is platform speific and defined by the plaform specification for the bus that the virtio device is attached to. If this feature bit is set to 0, then the device emits physical addresses which are not translated further, even if the platform would normally require translations for the bus that the virtio device is attached to. If we can't change the defintion any more we should deprecate the old VIRTIO_F_IOMMU_PLATFORM bit, and require the VIRTIO_F_IOMMU_PLATFORM and VIRTIO_F_PLATFORM_DMA to be not set at the same time.> I'm trying to understand because the limitation is not a device side > limitation, it's not a qemu limitation, it's actually more of a VM > limitation. It has most of its memory pages made inaccessible for > security reasons. The platform from a qemu/KVM perspective is almost > entirely normal.Well, find a way to describe this either in the qemu specification using new feature bits, or by using something like the above.
Benjamin Herrenschmidt
2018-Aug-06 19:52 UTC
[RFC 0/4] Virtio uses DMA API for all devices
On Mon, 2018-08-06 at 02:42 -0700, Christoph Hellwig wrote:> On Mon, Aug 06, 2018 at 07:16:47AM +1000, Benjamin Herrenschmidt wrote: > > Who would set this bit ? qemu ? Under what circumstances ? > > I don't really care who sets what. The implementation might not even > involved qemu. > > It is your job to write a coherent interface specification that does > not depend on the used components. The hypervisor might be PAPR, > Linux + qemu, VMware, Hyperv or something so secret that you'd have > to shoot me if you had to tell me. The guest might be Linux, FreeBSD, > AIX, OS400 or a Hipster project of the day in Rust. As long as we > properly specify the interface it simplify does not matter.That's the point Christoph. The interface is today's interface. It does NOT change. That information is not part of the interface. It's the VM itself that is stashing away its memory in a secret place, and thus needs to do bounce buffering. There is no change to the virtio interface per-se.> > What would be the effect of this bit while VIRTIO_F_IOMMU is NOT set, > > ie, what would qemu do and what would Linux do ? I'm not sure I fully > > understand your idea. > > In a perfect would we'd just reuse VIRTIO_F_IOMMU and clarify the > description which currently is rather vague but basically captures > the use case. Currently is is: > > VIRTIO_F_IOMMU_PLATFORM(33) > This feature indicates that the device is behind an IOMMU that > translates bus addresses from the device into physical addresses in > memory. If this feature bit is set to 0, then the device emits > physical addresses which are not translated further, even though an > IOMMU may be present. > > And I'd change it to something like: > > VIRTIO_F_PLATFORM_DMA(33) > This feature indicates that the device emits platform specific > bus addresses that might not be identical to physical address. > The translation of physical to bus address is platform speific > and defined by the plaform specification for the bus that the virtio > device is attached to. > If this feature bit is set to 0, then the device emits > physical addresses which are not translated further, even if > the platform would normally require translations for the bus that > the virtio device is attached to. > > If we can't change the defintion any more we should deprecate the > old VIRTIO_F_IOMMU_PLATFORM bit, and require the VIRTIO_F_IOMMU_PLATFORM > and VIRTIO_F_PLATFORM_DMA to be not set at the same time.But this doesn't really change our problem does it ? None of what happens in our case is part of the "interface". The suggestion to force the iommu ON was simply that it was a "workaround" as by doing so, we get to override the DMA ops, but that's just a trick. Fundamentally, what we need to solve is pretty much entirely a guest problem.> > I'm trying to understand because the limitation is not a device side > > limitation, it's not a qemu limitation, it's actually more of a VM > > limitation. It has most of its memory pages made inaccessible for > > security reasons. The platform from a qemu/KVM perspective is almost > > entirely normal. > > Well, find a way to describe this either in the qemu specification using > new feature bits, or by using something like the above.But again, why do you want to involve the interface, and thus the hypervisor for something that is essentially what the guest is doign to itself ? It really is something we need to solve locally to the guest, it's not part of the interface. Cheers, Ben.