Re: virtio capabilities
On Wed, Dec 18, 2019 at 04:19:57PM +1100, Alexey Kardashevskiy wrote: > > > On 13/12/2019 19:36, Michael S. Tsirkin wrote: > > On Fri, Dec 13, 2019 at 07:29:40PM +1100, Alexey Kardashevskiy wrote: > >> > >> > >> On 13/12/2019 18:24, Michael S. Tsirkin wrote: > >>> On Fri, Dec 13, 2019 at 05:05:05PM +1100, Alexey Kardashevskiy wrote: > Hi! > > I am having an issue with capabilities (hopefully the chunk formatting > won't break). > > The problem is that when virtio_pci_find_capability() reads > pci_find_capability(dev, PCI_CAP_ID_VNDR), 0 is returned; if repeated, > it returns a valid number (0x84). Timing seems to matter. pci_cfg_read > trace shows that that first time read does not reach QEMU but others do > reach QEMU and return what is expected. > > How to debug this, any quick ideas? > The config space is not a MMIO BAR > or KVM memory slot or anything like this, right? :) Thanks, > >>> > >>> Depends on the platform. > >>> > >>> E.g. on x86, when using cf8/cfc pair, if guest doesn't > >> > >> > >> Is there an easy way to tell if it is this "cf8/cfc" case? > >> > >> I have these bars, is any of them related to cf8/cfc? Thanks, > >> > >> root@le-dbg:~# (qemu) info mtree -f > >> FlatView #0 > >> AS "memory", root: system > >> AS "cpu-memory-0", root: system > >> Root memory region: system > >> - (prio 0, ram): ppc_spapr.ram kvm > >> 20008000-2000802f (prio 0, i/o): msix-table > >> 20008800-20008807 (prio 0, i/o): msix-pba > >> 2100-21000fff (prio 0, i/o): virtio-pci-common > >> 21001000-21001fff (prio 0, i/o): virtio-pci-isr > >> 21002000-21002fff (prio 0, i/o): virtio-pci-device > >> 21003000-21003fff (prio 0, i/o): virtio-pci-notify > >> > > > > > > No, you want stuff in hw/ppc/spapr_pci.c > > > The problem was with our firmware, fixing that now. > > Out of curiosity. I do not see cf8/cfc on x86 either, or I just do not > recognize those, what is this cf8/cfc? E.g. i440fx: static void i440fx_pcihost_realize(DeviceState *dev, Error **errp) { PCIHostState *s = PCI_HOST_BRIDGE(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); sysbus_add_io(sbd, 0xcf8, >conf_mem); sysbus_init_ioports(sbd, 0xcf8, 4); sysbus_add_io(sbd, 0xcfc, >data_mem); sysbus_init_ioports(sbd, 0xcfc, 4); /* register i440fx 0xcf8 port as coalesced pio */ memory_region_set_flush_coalesced(>data_mem); memory_region_add_coalescing(>conf_mem, 0, 4); } > Thanks, > > FlatView #2 > > AS "memory", root: system > > AS "cpu-memory-0", root: system > > AS "piix3-ide", root: bus master container > > AS "virtio-net-pci", root: bus master container > > Root memory region: system > > -000b (prio 0, ram): pc.ram kvm > > 000c-000c0fff (prio 0, rom): pc.ram > @000c kvm > 000c1000-000c3fff (prio 0, ram): pc.ram > @000c1000 kvm > 000c4000-000e7fff (prio 0, rom): pc.ram > @000c4000 kvm > 000e8000-000e (prio 0, ram): pc.ram > @000e8000 kvm > 000f-000f (prio 0, rom): pc.ram > @000f kvm > 0010-7fff (prio 0, ram): pc.ram > @0010 kvm > febc-febc002f (prio 0, i/o): msix-table > > febc0800-febc0807 (prio 0, i/o): msix-pba > > febfc000-febfcfff (prio 0, i/o): virtio-pci-common > > febfd000-febfdfff (prio 0, i/o): virtio-pci-isr > > febfe000-febfefff (prio 0, i/o): virtio-pci-device > > febff000-febf (prio 0, i/o): virtio-pci-notify > > fec0-fec00fff (prio 0, i/o): kvm-ioapic > > fed0-fed003ff (prio 0, i/o): hpet > > fee0-feef (prio 4096, i/o): kvm-apic-msi > > fffc- (prio 0, rom): pc.bios kvm > > > > -- > Alexey
Re: virtio capabilities
On 13/12/2019 19:36, Michael S. Tsirkin wrote: > On Fri, Dec 13, 2019 at 07:29:40PM +1100, Alexey Kardashevskiy wrote: >> >> >> On 13/12/2019 18:24, Michael S. Tsirkin wrote: >>> On Fri, Dec 13, 2019 at 05:05:05PM +1100, Alexey Kardashevskiy wrote: Hi! I am having an issue with capabilities (hopefully the chunk formatting won't break). The problem is that when virtio_pci_find_capability() reads pci_find_capability(dev, PCI_CAP_ID_VNDR), 0 is returned; if repeated, it returns a valid number (0x84). Timing seems to matter. pci_cfg_read trace shows that that first time read does not reach QEMU but others do reach QEMU and return what is expected. How to debug this, any quick ideas? The config space is not a MMIO BAR or KVM memory slot or anything like this, right? :) Thanks, >>> >>> Depends on the platform. >>> >>> E.g. on x86, when using cf8/cfc pair, if guest doesn't >> >> >> Is there an easy way to tell if it is this "cf8/cfc" case? >> >> I have these bars, is any of them related to cf8/cfc? Thanks, >> >> root@le-dbg:~# (qemu) info mtree -f >> FlatView #0 >> AS "memory", root: system >> AS "cpu-memory-0", root: system >> Root memory region: system >> - (prio 0, ram): ppc_spapr.ram kvm >> 20008000-2000802f (prio 0, i/o): msix-table >> 20008800-20008807 (prio 0, i/o): msix-pba >> 2100-21000fff (prio 0, i/o): virtio-pci-common >> 21001000-21001fff (prio 0, i/o): virtio-pci-isr >> 21002000-21002fff (prio 0, i/o): virtio-pci-device >> 21003000-21003fff (prio 0, i/o): virtio-pci-notify >> > > > No, you want stuff in hw/ppc/spapr_pci.c The problem was with our firmware, fixing that now. Out of curiosity. I do not see cf8/cfc on x86 either, or I just do not recognize those, what is this cf8/cfc? Thanks, FlatView #2 AS "memory", root: system AS "cpu-memory-0", root: system AS "piix3-ide", root: bus master container AS "virtio-net-pci", root: bus master container Root memory region: system -000b (prio 0, ram): pc.ram kvm 000c-000c0fff (prio 0, rom): pc.ram @000c kvm 000c1000-000c3fff (prio 0, ram): pc.ram @000c1000 kvm 000c4000-000e7fff (prio 0, rom): pc.ram @000c4000 kvm 000e8000-000e (prio 0, ram): pc.ram @000e8000 kvm 000f-000f (prio 0, rom): pc.ram @000f kvm 0010-7fff (prio 0, ram): pc.ram @0010 kvm febc-febc002f (prio 0, i/o): msix-table febc0800-febc0807 (prio 0, i/o): msix-pba febfc000-febfcfff (prio 0, i/o): virtio-pci-common febfd000-febfdfff (prio 0, i/o): virtio-pci-isr febfe000-febfefff (prio 0, i/o): virtio-pci-device febff000-febf (prio 0, i/o): virtio-pci-notify fec0-fec00fff (prio 0, i/o): kvm-ioapic fed0-fed003ff (prio 0, i/o): hpet fee0-feef (prio 4096, i/o): kvm-apic-msi fffc- (prio 0, rom): pc.bios kvm -- Alexey
Re: virtio capabilities
On Fri, Dec 13, 2019 at 07:29:40PM +1100, Alexey Kardashevskiy wrote: > > > On 13/12/2019 18:24, Michael S. Tsirkin wrote: > > On Fri, Dec 13, 2019 at 05:05:05PM +1100, Alexey Kardashevskiy wrote: > >> Hi! > >> > >> I am having an issue with capabilities (hopefully the chunk formatting > >> won't break). > >> > >> The problem is that when virtio_pci_find_capability() reads > >> pci_find_capability(dev, PCI_CAP_ID_VNDR), 0 is returned; if repeated, > >> it returns a valid number (0x84). Timing seems to matter. pci_cfg_read > >> trace shows that that first time read does not reach QEMU but others do > >> reach QEMU and return what is expected. > >> > >> How to debug this, any quick ideas? > >> The config space is not a MMIO BAR > >> or KVM memory slot or anything like this, right? :) Thanks, > > > > Depends on the platform. > > > > E.g. on x86, when using cf8/cfc pair, if guest doesn't > > > Is there an easy way to tell if it is this "cf8/cfc" case? > > I have these bars, is any of them related to cf8/cfc? Thanks, > > root@le-dbg:~# (qemu) info mtree -f > FlatView #0 > AS "memory", root: system > AS "cpu-memory-0", root: system > Root memory region: system > - (prio 0, ram): ppc_spapr.ram kvm > 20008000-2000802f (prio 0, i/o): msix-table > 20008800-20008807 (prio 0, i/o): msix-pba > 2100-21000fff (prio 0, i/o): virtio-pci-common > 21001000-21001fff (prio 0, i/o): virtio-pci-isr > 21002000-21002fff (prio 0, i/o): virtio-pci-device > 21003000-21003fff (prio 0, i/o): virtio-pci-notify > No, you want stuff in hw/ppc/spapr_pci.c > > > > have a lock around programming the pair of registers, > > then one access can conflict with another one. > > > > When using express it's MMIO so shouldn't be a problem. > > > >> > >> [3.489492] ___K___ (0) virtio_pci_modern_probe 642 > >> [3.489697] ___K___ (0) virtio_pci_find_capability 492: FIND a cap > >> [3.490070] ___K___ (0) virtio_pci_find_capability 494: cap is at 0 > >> [3.490335] ___K___ (0) virtio_pci_find_capability 492: FIND a cap > >> 10909@1576216763.643271:pci_cfg_read virtio-net-pci 00:0 @0x6 -> 0x10 > >> 10909@1576216763.643431:pci_cfg_read virtio-net-pci 00:0 @0x34 -> 0x98 > >> 10909@1576216763.643591:pci_cfg_read virtio-net-pci 00:0 @0x98 -> 0x8411 > >> 10909@1576216763.643747:pci_cfg_read virtio-net-pci 00:0 @0x84 -> 0x7009 > >> [3.491264] ___K___ (0) virtio_pci_find_capability 494: cap is at 132 > >> 10909@1576216763.644140:pci_cfg_read virtio-net-pci 00:0 @0x87 -> 0x5 > >> 10909@1576216763.644287:pci_cfg_read virtio-net-pci 00:0 @0x88 -> 0x0 > >> [3.491803] ___K___ (0) virtio_pci_find_capability 506: 5 0 > >> 10909@1576216763.644632:pci_cfg_read virtio-net-pci 00:0 @0x85 -> 0x70 > >> 10909@1576216763.644786:pci_cfg_read virtio-net-pci 00:0 @0x70 -> 0x6009 > >> 10909@1576216763.644942:pci_cfg_read virtio-net-pci 00:0 @0x73 -> 0x2 > >> 10909@1576216763.645092:pci_cfg_read virtio-net-pci 00:0 @0x74 -> 0x4 > >> [3.492607] ___K___ (0) virtio_pci_find_capability 506: 2 4 > >> > >> > >> > >> > >> > >> diff --git a/drivers/virtio/virtio_pci_modern.c > >> b/drivers/virtio/virtio_pci_modern.c > >> index 7abcc50838b8..85b2a7ce96e9 100644 > >> --- a/drivers/virtio/virtio_pci_modern.c > >> +++ b/drivers/virtio/virtio_pci_modern.c > >> @@ -486,9 +486,14 @@ static const struct virtio_config_ops > >> virtio_pci_config_ops = { > >> static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 > >> cfg_type, > >> u32 ioresource_types, int > >> *bars) > >> { > >> - int pos; > >> + int pos = 0;// = pci_find_capability(dev, PCI_CAP_ID_VNDR); > >> > >> - for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); > >> + while (!pos) { > >> + pr_err("___K___ (%u) %s %u: FIND a cap\n", > >> smp_processor_id(), __func__, __LINE__); > >> + pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); > >> + pr_err("___K___ (%u) %s %u: cap is at %d\n", > >> smp_processor_id(), __func__, __LINE__, pos); > >> + } > >> + for (; > >> pos > 0; > >> pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) { > >> u8 type, bar; > >> > >> > >> -- > >> Alexey > > > > -- > Alexey
Re: virtio capabilities
On 13/12/2019 18:24, Michael S. Tsirkin wrote: > On Fri, Dec 13, 2019 at 05:05:05PM +1100, Alexey Kardashevskiy wrote: >> Hi! >> >> I am having an issue with capabilities (hopefully the chunk formatting >> won't break). >> >> The problem is that when virtio_pci_find_capability() reads >> pci_find_capability(dev, PCI_CAP_ID_VNDR), 0 is returned; if repeated, >> it returns a valid number (0x84). Timing seems to matter. pci_cfg_read >> trace shows that that first time read does not reach QEMU but others do >> reach QEMU and return what is expected. >> >> How to debug this, any quick ideas? >> The config space is not a MMIO BAR >> or KVM memory slot or anything like this, right? :) Thanks, > > Depends on the platform. > > E.g. on x86, when using cf8/cfc pair, if guest doesn't Is there an easy way to tell if it is this "cf8/cfc" case? I have these bars, is any of them related to cf8/cfc? Thanks, root@le-dbg:~# (qemu) info mtree -f FlatView #0 AS "memory", root: system AS "cpu-memory-0", root: system Root memory region: system - (prio 0, ram): ppc_spapr.ram kvm 20008000-2000802f (prio 0, i/o): msix-table 20008800-20008807 (prio 0, i/o): msix-pba 2100-21000fff (prio 0, i/o): virtio-pci-common 21001000-21001fff (prio 0, i/o): virtio-pci-isr 21002000-21002fff (prio 0, i/o): virtio-pci-device 21003000-21003fff (prio 0, i/o): virtio-pci-notify > have a lock around programming the pair of registers, > then one access can conflict with another one. > > When using express it's MMIO so shouldn't be a problem. > >> >> [3.489492] ___K___ (0) virtio_pci_modern_probe 642 >> [3.489697] ___K___ (0) virtio_pci_find_capability 492: FIND a cap >> [3.490070] ___K___ (0) virtio_pci_find_capability 494: cap is at 0 >> [3.490335] ___K___ (0) virtio_pci_find_capability 492: FIND a cap >> 10909@1576216763.643271:pci_cfg_read virtio-net-pci 00:0 @0x6 -> 0x10 >> 10909@1576216763.643431:pci_cfg_read virtio-net-pci 00:0 @0x34 -> 0x98 >> 10909@1576216763.643591:pci_cfg_read virtio-net-pci 00:0 @0x98 -> 0x8411 >> 10909@1576216763.643747:pci_cfg_read virtio-net-pci 00:0 @0x84 -> 0x7009 >> [3.491264] ___K___ (0) virtio_pci_find_capability 494: cap is at 132 >> 10909@1576216763.644140:pci_cfg_read virtio-net-pci 00:0 @0x87 -> 0x5 >> 10909@1576216763.644287:pci_cfg_read virtio-net-pci 00:0 @0x88 -> 0x0 >> [3.491803] ___K___ (0) virtio_pci_find_capability 506: 5 0 >> 10909@1576216763.644632:pci_cfg_read virtio-net-pci 00:0 @0x85 -> 0x70 >> 10909@1576216763.644786:pci_cfg_read virtio-net-pci 00:0 @0x70 -> 0x6009 >> 10909@1576216763.644942:pci_cfg_read virtio-net-pci 00:0 @0x73 -> 0x2 >> 10909@1576216763.645092:pci_cfg_read virtio-net-pci 00:0 @0x74 -> 0x4 >> [3.492607] ___K___ (0) virtio_pci_find_capability 506: 2 4 >> >> >> >> >> >> diff --git a/drivers/virtio/virtio_pci_modern.c >> b/drivers/virtio/virtio_pci_modern.c >> index 7abcc50838b8..85b2a7ce96e9 100644 >> --- a/drivers/virtio/virtio_pci_modern.c >> +++ b/drivers/virtio/virtio_pci_modern.c >> @@ -486,9 +486,14 @@ static const struct virtio_config_ops >> virtio_pci_config_ops = { >> static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 >> cfg_type, >> u32 ioresource_types, int >> *bars) >> { >> - int pos; >> + int pos = 0;// = pci_find_capability(dev, PCI_CAP_ID_VNDR); >> >> - for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); >> + while (!pos) { >> + pr_err("___K___ (%u) %s %u: FIND a cap\n", >> smp_processor_id(), __func__, __LINE__); >> + pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); >> + pr_err("___K___ (%u) %s %u: cap is at %d\n", >> smp_processor_id(), __func__, __LINE__, pos); >> + } >> + for (; >> pos > 0; >> pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) { >> u8 type, bar; >> >> >> -- >> Alexey > -- Alexey
Re: virtio capabilities
On Fri, Dec 13, 2019 at 05:05:05PM +1100, Alexey Kardashevskiy wrote: > Hi! > > I am having an issue with capabilities (hopefully the chunk formatting > won't break). > > The problem is that when virtio_pci_find_capability() reads > pci_find_capability(dev, PCI_CAP_ID_VNDR), 0 is returned; if repeated, > it returns a valid number (0x84). Timing seems to matter. pci_cfg_read > trace shows that that first time read does not reach QEMU but others do > reach QEMU and return what is expected. > > How to debug this, any quick ideas? > The config space is not a MMIO BAR > or KVM memory slot or anything like this, right? :) Thanks, Depends on the platform. E.g. on x86, when using cf8/cfc pair, if guest doesn't have a lock around programming the pair of registers, then one access can conflict with another one. When using express it's MMIO so shouldn't be a problem. > > [3.489492] ___K___ (0) virtio_pci_modern_probe 642 > [3.489697] ___K___ (0) virtio_pci_find_capability 492: FIND a cap > [3.490070] ___K___ (0) virtio_pci_find_capability 494: cap is at 0 > [3.490335] ___K___ (0) virtio_pci_find_capability 492: FIND a cap > 10909@1576216763.643271:pci_cfg_read virtio-net-pci 00:0 @0x6 -> 0x10 > 10909@1576216763.643431:pci_cfg_read virtio-net-pci 00:0 @0x34 -> 0x98 > 10909@1576216763.643591:pci_cfg_read virtio-net-pci 00:0 @0x98 -> 0x8411 > 10909@1576216763.643747:pci_cfg_read virtio-net-pci 00:0 @0x84 -> 0x7009 > [3.491264] ___K___ (0) virtio_pci_find_capability 494: cap is at 132 > 10909@1576216763.644140:pci_cfg_read virtio-net-pci 00:0 @0x87 -> 0x5 > 10909@1576216763.644287:pci_cfg_read virtio-net-pci 00:0 @0x88 -> 0x0 > [3.491803] ___K___ (0) virtio_pci_find_capability 506: 5 0 > 10909@1576216763.644632:pci_cfg_read virtio-net-pci 00:0 @0x85 -> 0x70 > 10909@1576216763.644786:pci_cfg_read virtio-net-pci 00:0 @0x70 -> 0x6009 > 10909@1576216763.644942:pci_cfg_read virtio-net-pci 00:0 @0x73 -> 0x2 > 10909@1576216763.645092:pci_cfg_read virtio-net-pci 00:0 @0x74 -> 0x4 > [3.492607] ___K___ (0) virtio_pci_find_capability 506: 2 4 > > > > > > diff --git a/drivers/virtio/virtio_pci_modern.c > b/drivers/virtio/virtio_pci_modern.c > index 7abcc50838b8..85b2a7ce96e9 100644 > --- a/drivers/virtio/virtio_pci_modern.c > +++ b/drivers/virtio/virtio_pci_modern.c > @@ -486,9 +486,14 @@ static const struct virtio_config_ops > virtio_pci_config_ops = { > static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 > cfg_type, > u32 ioresource_types, int > *bars) > { > - int pos; > + int pos = 0;// = pci_find_capability(dev, PCI_CAP_ID_VNDR); > > - for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); > + while (!pos) { > + pr_err("___K___ (%u) %s %u: FIND a cap\n", > smp_processor_id(), __func__, __LINE__); > + pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); > + pr_err("___K___ (%u) %s %u: cap is at %d\n", > smp_processor_id(), __func__, __LINE__, pos); > + } > + for (; > pos > 0; > pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) { > u8 type, bar; > > > -- > Alexey
virtio capabilities
Hi! I am having an issue with capabilities (hopefully the chunk formatting won't break). The problem is that when virtio_pci_find_capability() reads pci_find_capability(dev, PCI_CAP_ID_VNDR), 0 is returned; if repeated, it returns a valid number (0x84). Timing seems to matter. pci_cfg_read trace shows that that first time read does not reach QEMU but others do reach QEMU and return what is expected. How to debug this, any quick ideas? The config space is not a MMIO BAR or KVM memory slot or anything like this, right? :) Thanks, [3.489492] ___K___ (0) virtio_pci_modern_probe 642 [3.489697] ___K___ (0) virtio_pci_find_capability 492: FIND a cap [3.490070] ___K___ (0) virtio_pci_find_capability 494: cap is at 0 [3.490335] ___K___ (0) virtio_pci_find_capability 492: FIND a cap 10909@1576216763.643271:pci_cfg_read virtio-net-pci 00:0 @0x6 -> 0x10 10909@1576216763.643431:pci_cfg_read virtio-net-pci 00:0 @0x34 -> 0x98 10909@1576216763.643591:pci_cfg_read virtio-net-pci 00:0 @0x98 -> 0x8411 10909@1576216763.643747:pci_cfg_read virtio-net-pci 00:0 @0x84 -> 0x7009 [3.491264] ___K___ (0) virtio_pci_find_capability 494: cap is at 132 10909@1576216763.644140:pci_cfg_read virtio-net-pci 00:0 @0x87 -> 0x5 10909@1576216763.644287:pci_cfg_read virtio-net-pci 00:0 @0x88 -> 0x0 [3.491803] ___K___ (0) virtio_pci_find_capability 506: 5 0 10909@1576216763.644632:pci_cfg_read virtio-net-pci 00:0 @0x85 -> 0x70 10909@1576216763.644786:pci_cfg_read virtio-net-pci 00:0 @0x70 -> 0x6009 10909@1576216763.644942:pci_cfg_read virtio-net-pci 00:0 @0x73 -> 0x2 10909@1576216763.645092:pci_cfg_read virtio-net-pci 00:0 @0x74 -> 0x4 [3.492607] ___K___ (0) virtio_pci_find_capability 506: 2 4 diff --git a/drivers/virtio/virtio_pci_modern.c b/drivers/virtio/virtio_pci_modern.c index 7abcc50838b8..85b2a7ce96e9 100644 --- a/drivers/virtio/virtio_pci_modern.c +++ b/drivers/virtio/virtio_pci_modern.c @@ -486,9 +486,14 @@ static const struct virtio_config_ops virtio_pci_config_ops = { static inline int virtio_pci_find_capability(struct pci_dev *dev, u8 cfg_type, u32 ioresource_types, int *bars) { - int pos; + int pos = 0;// = pci_find_capability(dev, PCI_CAP_ID_VNDR); - for (pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); + while (!pos) { + pr_err("___K___ (%u) %s %u: FIND a cap\n", smp_processor_id(), __func__, __LINE__); + pos = pci_find_capability(dev, PCI_CAP_ID_VNDR); + pr_err("___K___ (%u) %s %u: cap is at %d\n", smp_processor_id(), __func__, __LINE__, pos); + } + for (; pos > 0; pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_VNDR)) { u8 type, bar; -- Alexey
Re: [Qemu-devel] [PATCH v2 07/22] virtio: find version 1.0 virtio capabilities
Hi, Yes, seabios always allocates both mem and io. What if it can't? E.g. too many devices. First tries to move 64bit bars above 64g. Guess we better should exclude virtio devices here (like we do for xhci already). Failing that it'll panic. cheers, Gerd
Re: [Qemu-devel] [PATCH v2 07/22] virtio: find version 1.0 virtio capabilities
On Wed, Jul 01, 2015 at 02:49:54PM +0200, Gerd Hoffmann wrote: Hi, Yes, seabios always allocates both mem and io. What if it can't? E.g. too many devices. First tries to move 64bit bars above 64g. Guess we better should exclude virtio devices here (like we do for xhci already). Why? You can use config capability. Failing that it'll panic. cheers, Gerd IO can't well go above 4G :) So eventually we'll make these express devices. For express the spec explicitly says devices must still work if IO is disabled. At that point maybe teaching bios to disable IO and keep working will have value. -- MST
Re: [Qemu-devel] [PATCH v2 07/22] virtio: find version 1.0 virtio capabilities
On Wed, Jul 01, 2015 at 02:24:02PM +0200, Gerd Hoffmann wrote: Hi, Hmm this seems to violate this rule in the spec: The driver SHOULD use the first instance of each virtio structure type they can support. can support here means that bios was able to allocate it during enumeration. For example there could be both IO and memory, in this order you need to check that IO/memory got enabled (in theory, also that they are within parent bridge's windows - used by some guests, but seabios doesn't disable memmory/io in this strange way). Yes, seabios always allocates both mem and io. What if it can't? E.g. too many devices. So this incremental fix ... @@ -234,7 +234,7 @@ void vp_init_simple(struct vp_device *vp, struct pci_device *pci) vp_cap = NULL; break; } -if (vp_cap) { +if (vp_cap !vp_cap-cap) { vp_cap-cap = cap; vp_cap-bar = pci_config_readb(pci-bdf, cap + offsetof(struct virtio_pci_cap, bar)); ... makes seabios use the first not the last and should do the trick, right? cheers, Gerd
Re: [Qemu-devel] [PATCH v2 07/22] virtio: find version 1.0 virtio capabilities
Hi, Hmm this seems to violate this rule in the spec: The driver SHOULD use the first instance of each virtio structure type they can support. can support here means that bios was able to allocate it during enumeration. For example there could be both IO and memory, in this order you need to check that IO/memory got enabled (in theory, also that they are within parent bridge's windows - used by some guests, but seabios doesn't disable memmory/io in this strange way). Yes, seabios always allocates both mem and io. So this incremental fix ... @@ -234,7 +234,7 @@ void vp_init_simple(struct vp_device *vp, struct pci_device *pci) vp_cap = NULL; break; } -if (vp_cap) { +if (vp_cap !vp_cap-cap) { vp_cap-cap = cap; vp_cap-bar = pci_config_readb(pci-bdf, cap + offsetof(struct virtio_pci_cap, bar)); ... makes seabios use the first not the last and should do the trick, right? cheers, Gerd
Re: [Qemu-devel] [PATCH v2 07/22] virtio: find version 1.0 virtio capabilities
On Tue, Jun 30, 2015 at 10:38:58AM +0200, Gerd Hoffmann wrote: virtio 1.0 specifies the location of the various virtio regions using pci capabilities. Look them up and store the results. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- src/hw/virtio-pci.c | 55 + src/hw/virtio-pci.h | 8 2 files changed, 63 insertions(+) diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c index 4971021..0acf65f 100644 --- a/src/hw/virtio-pci.c +++ b/src/hw/virtio-pci.c @@ -88,6 +88,61 @@ fail: struct vp_device *vp_init_simple(struct pci_device *pci) { struct vp_device *vp = malloc_high(sizeof(*vp)); +u8 cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, 0); +struct vp_cap *vp_cap; +u32 addr, offset; +u8 type; + +memset(vp, 0, sizeof(*vp)); +while (cap != 0) { +type = pci_config_readb(pci-bdf, cap + +offsetof(struct virtio_pci_cap, cfg_type)); +switch (type) { +case VIRTIO_PCI_CAP_COMMON_CFG: +vp_cap = vp-common; +break; +case VIRTIO_PCI_CAP_NOTIFY_CFG: +vp_cap = vp-notify; +break; +case VIRTIO_PCI_CAP_ISR_CFG: +vp_cap = vp-isr; +break; +case VIRTIO_PCI_CAP_DEVICE_CFG: +vp_cap = vp-device; +break; +default: +vp_cap = NULL; +break; +} +if (vp_cap) { +vp_cap-cap = cap; +vp_cap-bar = pci_config_readb(pci-bdf, cap + + offsetof(struct virtio_pci_cap, bar)); +offset = pci_config_readl(pci-bdf, cap + + offsetof(struct virtio_pci_cap, offset)); +addr = pci_config_readl(pci-bdf, PCI_BASE_ADDRESS_0 + 4 * vp_cap-bar); +if (addr PCI_BASE_ADDRESS_SPACE_IO) { +vp_cap-is_io = 1; +addr = PCI_BASE_ADDRESS_IO_MASK; +} else { +vp_cap-is_io = 0; +addr = PCI_BASE_ADDRESS_MEM_MASK; +} +vp_cap-addr = addr + offset; +dprintf(3, pci dev %x:%x virtio cap at 0x%x type %d +bar %d at 0x%08x off +0x%04x [%s]\n, +pci_bdf_to_bus(pci-bdf), pci_bdf_to_dev(pci-bdf), +vp_cap-cap, type, vp_cap-bar, addr, offset, +vp_cap-is_io ? io : mmio); +} + +cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, cap); +} + +if (vp-common.cap vp-notify.cap vp-isr.cap vp-device.cap) { +dprintf(1, pci dev %x:%x supports virtio 1.0\n, +pci_bdf_to_bus(pci-bdf), pci_bdf_to_dev(pci-bdf)); +} vp-ioaddr = pci_config_readl(pci-bdf, PCI_BASE_ADDRESS_0) PCI_BASE_ADDRESS_IO_MASK; Hmm this seems to violate this rule in the spec: The driver SHOULD use the first instance of each virtio structure type they can support. can support here means that bios was able to allocate it during enumeration. For example there could be both IO and memory, in this order you need to check that IO/memory got enabled (in theory, also that they are within parent bridge's windows - used by some guests, but seabios doesn't disable memmory/io in this strange way). diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h index bc2eb05..0f57ca8 100644 --- a/src/hw/virtio-pci.h +++ b/src/hw/virtio-pci.h @@ -115,8 +115,16 @@ typedef struct virtio_pci_isr { /* --- driver structs --- */ +struct vp_cap { +u32 addr; +u8 cap; +u8 bar; +u8 is_io; +}; + struct vp_device { unsigned int ioaddr; +struct vp_cap common, notify, isr, device; }; static inline u32 vp_get_features(struct vp_device *vp) -- 1.8.3.1
[Qemu-devel] [PATCH v3 07/25] virtio: find version 1.0 virtio capabilities
virtio 1.0 specifies the location of the various virtio regions using pci capabilities. Look them up and store the results. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- src/hw/virtio-pci.c | 56 + src/hw/virtio-pci.h | 8 2 files changed, 64 insertions(+) diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c index 9428d04..58f3d39 100644 --- a/src/hw/virtio-pci.c +++ b/src/hw/virtio-pci.c @@ -87,6 +87,62 @@ fail: void vp_init_simple(struct vp_device *vp, struct pci_device *pci) { +u8 cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, 0); +struct vp_cap *vp_cap; +u32 addr, offset; +u8 type; + +memset(vp, 0, sizeof(*vp)); +while (cap != 0) { +type = pci_config_readb(pci-bdf, cap + +offsetof(struct virtio_pci_cap, cfg_type)); +switch (type) { +case VIRTIO_PCI_CAP_COMMON_CFG: +vp_cap = vp-common; +break; +case VIRTIO_PCI_CAP_NOTIFY_CFG: +vp_cap = vp-notify; +break; +case VIRTIO_PCI_CAP_ISR_CFG: +vp_cap = vp-isr; +break; +case VIRTIO_PCI_CAP_DEVICE_CFG: +vp_cap = vp-device; +break; +default: +vp_cap = NULL; +break; +} +if (vp_cap !vp_cap-cap) { +vp_cap-cap = cap; +vp_cap-bar = pci_config_readb(pci-bdf, cap + + offsetof(struct virtio_pci_cap, bar)); +offset = pci_config_readl(pci-bdf, cap + + offsetof(struct virtio_pci_cap, offset)); +addr = pci_config_readl(pci-bdf, PCI_BASE_ADDRESS_0 + 4 * vp_cap-bar); +if (addr PCI_BASE_ADDRESS_SPACE_IO) { +vp_cap-is_io = 1; +addr = PCI_BASE_ADDRESS_IO_MASK; +} else { +vp_cap-is_io = 0; +addr = PCI_BASE_ADDRESS_MEM_MASK; +} +vp_cap-addr = addr + offset; +dprintf(3, pci dev %x:%x virtio cap at 0x%x type %d +bar %d at 0x%08x off +0x%04x [%s]\n, +pci_bdf_to_bus(pci-bdf), pci_bdf_to_dev(pci-bdf), +vp_cap-cap, type, vp_cap-bar, addr, offset, +vp_cap-is_io ? io : mmio); +} + +cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, cap); +} + +if (vp-common.cap vp-notify.cap vp-isr.cap vp-device.cap) { +dprintf(1, pci dev %x:%x supports virtio 1.0\n, +pci_bdf_to_bus(pci-bdf), pci_bdf_to_dev(pci-bdf)); +} + vp-ioaddr = pci_config_readl(pci-bdf, PCI_BASE_ADDRESS_0) PCI_BASE_ADDRESS_IO_MASK; diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h index 42e2b7f..467c02f 100644 --- a/src/hw/virtio-pci.h +++ b/src/hw/virtio-pci.h @@ -115,8 +115,16 @@ typedef struct virtio_pci_isr { /* --- driver structs --- */ +struct vp_cap { +u32 addr; +u8 cap; +u8 bar; +u8 is_io; +}; + struct vp_device { unsigned int ioaddr; +struct vp_cap common, notify, isr, device; }; static inline u32 vp_get_features(struct vp_device *vp) -- 1.8.3.1
[Qemu-devel] [PATCH v2 07/22] virtio: find version 1.0 virtio capabilities
virtio 1.0 specifies the location of the various virtio regions using pci capabilities. Look them up and store the results. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- src/hw/virtio-pci.c | 55 + src/hw/virtio-pci.h | 8 2 files changed, 63 insertions(+) diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c index 4971021..0acf65f 100644 --- a/src/hw/virtio-pci.c +++ b/src/hw/virtio-pci.c @@ -88,6 +88,61 @@ fail: struct vp_device *vp_init_simple(struct pci_device *pci) { struct vp_device *vp = malloc_high(sizeof(*vp)); +u8 cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, 0); +struct vp_cap *vp_cap; +u32 addr, offset; +u8 type; + +memset(vp, 0, sizeof(*vp)); +while (cap != 0) { +type = pci_config_readb(pci-bdf, cap + +offsetof(struct virtio_pci_cap, cfg_type)); +switch (type) { +case VIRTIO_PCI_CAP_COMMON_CFG: +vp_cap = vp-common; +break; +case VIRTIO_PCI_CAP_NOTIFY_CFG: +vp_cap = vp-notify; +break; +case VIRTIO_PCI_CAP_ISR_CFG: +vp_cap = vp-isr; +break; +case VIRTIO_PCI_CAP_DEVICE_CFG: +vp_cap = vp-device; +break; +default: +vp_cap = NULL; +break; +} +if (vp_cap) { +vp_cap-cap = cap; +vp_cap-bar = pci_config_readb(pci-bdf, cap + + offsetof(struct virtio_pci_cap, bar)); +offset = pci_config_readl(pci-bdf, cap + + offsetof(struct virtio_pci_cap, offset)); +addr = pci_config_readl(pci-bdf, PCI_BASE_ADDRESS_0 + 4 * vp_cap-bar); +if (addr PCI_BASE_ADDRESS_SPACE_IO) { +vp_cap-is_io = 1; +addr = PCI_BASE_ADDRESS_IO_MASK; +} else { +vp_cap-is_io = 0; +addr = PCI_BASE_ADDRESS_MEM_MASK; +} +vp_cap-addr = addr + offset; +dprintf(3, pci dev %x:%x virtio cap at 0x%x type %d +bar %d at 0x%08x off +0x%04x [%s]\n, +pci_bdf_to_bus(pci-bdf), pci_bdf_to_dev(pci-bdf), +vp_cap-cap, type, vp_cap-bar, addr, offset, +vp_cap-is_io ? io : mmio); +} + +cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, cap); +} + +if (vp-common.cap vp-notify.cap vp-isr.cap vp-device.cap) { +dprintf(1, pci dev %x:%x supports virtio 1.0\n, +pci_bdf_to_bus(pci-bdf), pci_bdf_to_dev(pci-bdf)); +} vp-ioaddr = pci_config_readl(pci-bdf, PCI_BASE_ADDRESS_0) PCI_BASE_ADDRESS_IO_MASK; diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h index bc2eb05..0f57ca8 100644 --- a/src/hw/virtio-pci.h +++ b/src/hw/virtio-pci.h @@ -115,8 +115,16 @@ typedef struct virtio_pci_isr { /* --- driver structs --- */ +struct vp_cap { +u32 addr; +u8 cap; +u8 bar; +u8 is_io; +}; + struct vp_device { unsigned int ioaddr; +struct vp_cap common, notify, isr, device; }; static inline u32 vp_get_features(struct vp_device *vp) -- 1.8.3.1
[Qemu-devel] [PATCH 06/18] virtio: find version 1.0 virtio capabilities
virtio 1.0 specifies the location of the various virtio regions using pci capabilities. Look them up and store the results. Signed-off-by: Gerd Hoffmann kra...@redhat.com --- src/hw/virtio-pci.c | 55 + src/hw/virtio-pci.h | 8 2 files changed, 63 insertions(+) diff --git a/src/hw/virtio-pci.c b/src/hw/virtio-pci.c index ed5bfcb..2abe601 100644 --- a/src/hw/virtio-pci.c +++ b/src/hw/virtio-pci.c @@ -88,6 +88,61 @@ fail: struct vp_device *vp_init_simple(struct pci_device *pci) { struct vp_device *vp = malloc_low(sizeof(*vp)); +u8 cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, 0); +struct vp_cap *vp_cap; +u32 addr, offset; +u8 type; + +memset(vp, 0, sizeof(*vp)); +while (cap != 0) { +type = pci_config_readb(pci-bdf, cap + +offsetof(struct virtio_pci_cap, cfg_type)); +switch (type) { +case VIRTIO_PCI_CAP_COMMON_CFG: +vp_cap = vp-common; +break; +case VIRTIO_PCI_CAP_NOTIFY_CFG: +vp_cap = vp-notify; +break; +case VIRTIO_PCI_CAP_ISR_CFG: +vp_cap = vp-isr; +break; +case VIRTIO_PCI_CAP_DEVICE_CFG: +vp_cap = vp-device; +break; +default: +vp_cap = NULL; +break; +} +if (vp_cap) { +vp_cap-cap = cap; +vp_cap-bar = pci_config_readb(pci-bdf, cap + + offsetof(struct virtio_pci_cap, bar)); +offset = pci_config_readl(pci-bdf, cap + + offsetof(struct virtio_pci_cap, offset)); +addr = pci_config_readl(pci-bdf, PCI_BASE_ADDRESS_0 + 4 * vp_cap-bar); +if (addr PCI_BASE_ADDRESS_SPACE_IO) { +vp_cap-is_io = 1; +addr = PCI_BASE_ADDRESS_IO_MASK; +} else { +vp_cap-is_io = 0; +addr = PCI_BASE_ADDRESS_MEM_MASK; +} +vp_cap-addr = addr + offset; +dprintf(3, pci dev %x:%x virtio cap at 0x%x type %d +bar %d at 0x%08x off +0x%04x [%s]\n, +pci_bdf_to_bus(pci-bdf), pci_bdf_to_dev(pci-bdf), +vp_cap-cap, type, vp_cap-bar, addr, offset, +vp_cap-is_io ? io : mmio); +} + +cap = pci_find_capability(pci, PCI_CAP_ID_VNDR, cap); +} + +if (vp-common.cap vp-notify.cap vp-isr.cap vp-device.cap) { +dprintf(1, pci dev %x:%x supports virtio 1.0\n, +pci_bdf_to_bus(pci-bdf), pci_bdf_to_dev(pci-bdf)); +} vp-ioaddr = pci_config_readl(pci-bdf, PCI_BASE_ADDRESS_0) PCI_BASE_ADDRESS_IO_MASK; diff --git a/src/hw/virtio-pci.h b/src/hw/virtio-pci.h index e6f9c0b..893a7dd 100644 --- a/src/hw/virtio-pci.h +++ b/src/hw/virtio-pci.h @@ -99,8 +99,16 @@ typedef struct virtio_pci_isr { } virtio_pci_isr; +struct vp_cap { +u32 addr; +u8 cap; +u8 bar; +u8 is_io; +}; + struct vp_device { unsigned int ioaddr; +struct vp_cap common, notify, isr, device; }; static inline u32 vp_get_features(struct vp_device *vp) -- 1.8.3.1