qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [RFC] Getting specific device from qdev structs


From: Eduard - Gabriel Munteanu
Subject: [Qemu-devel] [RFC] Getting specific device from qdev structs
Date: Mon, 21 Jun 2010 16:48:59 +0300
User-agent: Mutt/1.5.20 (2009-06-14)

Hi,

I'm working on implementing AMD IOMMU emulation in QEMU/KVM and I'm also
creating an API for address translation and access checking. Ideally,
this API should work with different kinds of devices and IOMMUs. These
operations would typically require specific device information to figure
out which IOMMU is responsible and how it refers to the actual device
(bus-device-function number for example).

At the same time, I need to get this from deep within AIO/DMA code, so
adding specific members in those structures doesn't seem to be the best
way.

So I've been looking for a way to obtain things like a PCIDevice from a
more generic structure (say from hw/qdev.h), e.g. DeviceInfo. Is there
something like that already implemented? My searches turned up nothing.

If not, perhaps something like this would be acceptable?

enum DeviceType {
        DEV_TYPE_PCI,
        DEV_TYPE_ISA,
        [...]
};

struct GenericDevice {
        enum DeviceType type;
        union {
                PCIDevice *pci_dev;
                ISADevice *isa_dev;
                [...]
        };
}; /* 
    * Embed this in DeviceState for example. Make it
    * somehow accesible from AIO/DMA code.
    */

Or some container_of() / DO_UPCAST() magic might do:

struct GenericDevice {
        enum DeviceType type;
        DeviceState     qdev;
}; /* Embed this in PCIDevice and pass a pointer to GenericDevice around. */

struct PCIDevice {
        GenericDevice gdev;
        [...]
}

int iommu_translate(struct GenericDevice *dev, [other args])
{
        PCIDevice *pci_dev;
        ISADevice *isa_dev;

        switch (dev->type) {
        case DEV_TYPE_PCI:
                pci_dev = container_of(dev, PCIDevice, gdev);
                return iommu_pci_translate(pci_dev, [other args]);
        case DEV_TYPE_ISA:
                isa_dev = container_of(dev, ISADevice, gdev);
                return iommu_pci_translate(isa_dev, [other args]);
        [...]
        default:
                break;
        }

        [sensible default]
        return 0;
}

Note we can't actually do any container_of() magic without recording the
type of the container structure somewhere.

What do you think? I'd appreciate some help here. Perhaps there are
other (simpler) ways I didn't think of.


        Thanks,
        Eduard




reply via email to

[Prev in Thread] Current Thread [Next in Thread]