Skip to contentSkip to conversation

Dom0 linux 4.0 + devel/for-linus-4.1 branch: p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

PATCH In review Sander Eikelenboom 6 participants 31 messages Apr 13, 2015 – Jun 26, 2015

lore
Share & tools
lore
#0 lore raw

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

--
Sander

I now get a very large number of these at guest with passthrough start:
(XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ee type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ef type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f0 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f1 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f2 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f3 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f4 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f5 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f6 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f7 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f8 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001f9 type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001fa type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001fb type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001fc type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001fd type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001fe type:4 (XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ff type:4 (XEN) [2015-04-12 14:55:20.226] memory_map: error -22 removing dom1 access to [fe200,fe3ff]

But the guest starts after that .. and the device seems to work fine:
(d1) [2015-04-12 14:55:20.230] pci dev 05:0 INTA->IRQ10
(d1) [2015-04-12 14:55:20.246] No RAM in high memory; setting high_mem resource base to 100000000 (d1) [2015-04-12 14:55:20.247] pci dev 03:0 bar 10 size 002000000: 0f0000008
(d1) [2015-04-12 14:55:20.248] pci dev 02:0 bar 14 size 001000000: 0f2000008
(d1) [2015-04-12 14:55:20.250] pci dev 05:0 bar 10 size 000200000: 0f3000004 (XEN) [2015-04-12 14:55:20.250] memory_map:add: dom1 gfn=f3000 mfn=fe200 nr=200 (d1) [2015-04-12 14:55:20.255] pci dev 04:0 bar 30 size 000040000: 0f3200000
(d1) [2015-04-12 14:55:20.257] pci dev 04:0 bar 10 size 000020000: 0f3240000
(d1) [2015-04-12 14:55:20.257] pci dev 03:0 bar 30 size 000010000: 0f3260000
(d1) [2015-04-12 14:55:20.259] pci dev 03:0 bar 14 size 000001000: 0f3270000
(d1) [2015-04-12 14:55:20.260] pci dev 02:0 bar 10 size 000000100: 00000c001
(d1) [2015-04-12 14:55:20.262] pci dev 04:0 bar 14 size 000000040: 00000c101
(d1) [2015-04-12 14:55:20.263] pci dev 01:1 bar 20 size 000000010: 00000c141
(d1) [2015-04-12 14:55:20.266] Multiprocessor initialisation:

(d1) [2015-04-12 14:55:20.286]  - CPU0 ... 48-bit phys ... fixed MTRRs ... var MTRRs [1/8] ... done.
(d1) [2015-04-12 14:55:20.307]  - CPU1 ... 48-bit phys ... fixed MTRRs ... var MTRRs [1/8] ... done.
(d1) [2015-04-12 14:55:20.333]  - CPU2 ... 48-bit phys ... fixed MTRRs ... var MTRRs [1/8] ... done.
(d1) [2015-04-12 14:55:20.359]  - CPU3 ... 48-bit phys ... fixed MTRRs ... var MTRRs [1/8] ... done.

(d1) [2015-04-12 14:55:20.359] Testing HVM environment:
(d1) [2015-04-12 14:55:20.375] - REP INSB across page boundaries ... passed (d1) [2015-04-12 14:55:20.388] - GS base MSRs and SWAPGS ... passed (d1) [2015-04-12 14:55:20.388] Passed 2 of 2 tests
(d1) [2015-04-12 14:55:20.388] Writing SMBIOS tables ...
(d1) [2015-04-12 14:55:20.389] Loading SeaBIOS ...
(d1) [2015-04-12 14:55:20.389] Creating MP tables ...
(d1) [2015-04-12 14:55:20.389] Loading ACPI ...
(d1) [2015-04-12 14:55:20.390] vm86 TSS at fc00a200
(d1) [2015-04-12 14:55:20.391] BIOS map:
(d1) [2015-04-12 14:55:20.391] 10000-100d3: Scratch space
(d1) [2015-04-12 14:55:20.391] c0000-fffff: Main BIOS
(d1) [2015-04-12 14:55:20.391] E820 table:

(d1) [2015-04-12 14:55:20.391]  [00]: 00000000:00000000 - 00000000:000a0000: RAM
(d1) [2015-04-12 14:55:20.391]  HOLE: 00000000:000a0000 - 00000000:000c0000
(d1) [2015-04-12 14:55:20.391]  [01]: 00000000:000c0000 - 00000000:00100000: RESERVED
(d1) [2015-04-12 14:55:20.391]  [02]: 00000000:00100000 - 00000000:3f800000: RAM
(d1) [2015-04-12 14:55:20.391]  HOLE: 00000000:3f800000 - 00000000:fc000000
(d1) [2015-04-12 14:55:20.391]  [03]: 00000000:fc000000 - 00000001:00000000: RESERVED

(d1) [2015-04-12 14:55:20.391] Invoking SeaBIOS ...
(d1) [2015-04-12 14:55:20.393] SeaBIOS (version rel-1.8.0-0-g4c59f5d-20150412_163626-serveerstertje) (d1) [2015-04-12 14:55:20.393]
(d1) [2015-04-12 14:55:20.393] Found Xen hypervisor signature at 40000000
(d1) [2015-04-12 14:55:20.393] Running on QEMU (i440fx)
(d1) [2015-04-12 14:55:20.393] xen: copy e820...
(d1) [2015-04-12 14:55:20.393] Relocating init from 0x000de3f0 to 0x3f7ae880 (size 71360) (d1) [2015-04-12 14:55:20.395] CPU Mhz=3201
(d1) [2015-04-12 14:55:20.398] Found 8 PCI devices (max PCI bus is 00)
(d1) [2015-04-12 14:55:20.398] Allocated Xen hypercall page at 3f7ff000
(d1) [2015-04-12 14:55:20.398] Detected Xen v4.6-unstable
(d1) [2015-04-12 14:55:20.398] xen: copy BIOS tables...
(d1) [2015-04-12 14:55:20.398] Copying SMBIOS entry point from 0x00010010 to 0x000f6570
(d1) [2015-04-12 14:55:20.398] Copying MPTABLE from 0xfc0011b0/fc0011c0 to 0x000f6450
(d1) [2015-04-12 14:55:20.398] Copying PIR from 0x00010030 to 0x000f63d0
(d1) [2015-04-12 14:55:20.398] Copying ACPI RSDP from 0x000100b0 to 0x000f63a0
(d1) [2015-04-12 14:55:20.398] Using pmtimer, ioport 0xb008
(d1) [2015-04-12 14:55:20.398] Scan for VGA option rom
(d1) [2015-04-12 14:55:20.410] Running option rom at c000:0003
(XEN) [2015-04-12 14:55:20.416] stdvga.c:147:d1v0 entering stdvga and caching modes
(d1) [2015-04-12 14:55:20.440] pmm call arg1=0
(d1) [2015-04-12 14:55:20.441] Turning on vga text mode console
(d1) [2015-04-12 14:55:20.496] SeaBIOS (version rel-1.8.0-0-g4c59f5d-20150412_163626-serveerstertje) (d1) [2015-04-12 14:55:20.505] Machine UUID 424ae320-0b9f-4df6-865f-788f5fd31608
(d1) [2015-04-12 14:55:20.505] All threads complete.
(d1) [2015-04-12 14:55:20.506] Found 0 lpt ports
(d1) [2015-04-12 14:55:20.506] Found 1 serial ports
(d1) [2015-04-12 14:55:20.506] ATA controller 1 at 1f0/3f4/0 (irq 14 dev 9)
(d1) [2015-04-12 14:55:20.507] ATA controller 2 at 170/374/0 (irq 15 dev 9)
(d1) [2015-04-12 14:55:20.510] ata0-0: QEMU HARDDISK ATA-7 Hard-Disk (10240 MiBytes)
(d1) [2015-04-12 14:55:20.510] Searching bootorder for: /pci@i0cf8/*@1,1/drive@0/disk@0
(d1) [2015-04-12 14:55:20.511] ata0-1: QEMU HARDDISK ATA-7 Hard-Disk (300 GiBytes)
(d1) [2015-04-12 14:55:20.511] Searching bootorder for: /pci@i0cf8/*@1,1/drive@0/disk@1
(d1) [2015-04-12 14:55:20.608] PS2 keyboard initialized
(d1) [2015-04-12 14:55:20.608] All threads complete.
(d1) [2015-04-12 14:55:20.608] Scan for option roms
(d1) [2015-04-12 14:55:20.627] Running option rom at c980:0003
(d1) [2015-04-12 14:55:20.631] pmm call arg1=1
(d1) [2015-04-12 14:55:20.631] pmm call arg1=0
(d1) [2015-04-12 14:55:20.632] pmm call arg1=1
(d1) [2015-04-12 14:55:20.633] pmm call arg1=0
(d1) [2015-04-12 14:55:20.644] Searching bootorder for: /pci@i0cf8/*@4
(d1) [2015-04-12 14:55:20.644]
(d1) [2015-04-12 14:55:20.648] Press F12 for boot menu.
(d1) [2015-04-12 14:55:20.648]
(d1) [2015-04-12 14:55:23.195] Searching bootorder for: HALT
(d1) [2015-04-12 14:55:23.195] drive 0x000f6350: PCHS=16383/16/63 translation=lba LCHS=1024/255/63 s=20971520 (d1) [2015-04-12 14:55:23.200] drive 0x000f6320: PCHS=16383/16/63 translation=lba LCHS=1024/255/63 s=629145600 (d1) [2015-04-12 14:55:23.200]
(d1) [2015-04-12 14:55:23.200] Space available for UMB: ca800-ef000, f5d90-f6320
(d1) [2015-04-12 14:55:23.200] Returned 258048 bytes of ZoneHigh
(d1) [2015-04-12 14:55:23.201] e820 map has 6 items:

(d1) [2015-04-12 14:55:23.201]   0: 0000000000000000 - 000000000009fc00 = 1 RAM
(d1) [2015-04-12 14:55:23.201]   1: 000000000009fc00 - 00000000000a0000 = 2 RESERVED
(d1) [2015-04-12 14:55:23.201]   2: 00000000000f0000 - 0000000000100000 = 2 RESERVED
(d1) [2015-04-12 14:55:23.201]   3: 0000000000100000 - 000000003f7ff000 = 1 RAM
(d1) [2015-04-12 14:55:23.201]   4: 000000003f7ff000 - 000000003f800000 = 2 RESERVED
(d1) [2015-04-12 14:55:23.201]   5: 00000000fc000000 - 0000000100000000 = 2 RESERVED

(d1) [2015-04-12 14:55:23.204] enter handle_19:
(d1) [2015-04-12 14:55:23.204] NULL
(d1) [2015-04-12 14:55:23.216] Booting from Hard Disk...
(d1) [2015-04-12 14:55:23.217] Booting from 0000:7c00
(XEN) [2015-04-12 14:55:25.446] stdvga.c:151:d1v0 leaving stdvga
(XEN) [2015-04-12 14:55:37.363] stdvga.c:147:d1v0 entering stdvga and caching modes
(XEN) [2015-04-12 14:55:37.918] irq.c:386: Dom1 callback via changed to Direct Vector 0xf3 (XEN) [2015-04-12 14:55:40.484] memory_map:remove: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.491] memory_map:add: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.496] memory_map:remove: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.502] memory_map:add: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.507] memory_map:remove: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.513] memory_map:add: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.518] memory_map:remove: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.524] memory_map:add: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.530] memory_map:remove: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.536] memory_map:add: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.541] memory_map:remove: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.547] memory_map:add: dom1 gfn=f3000 mfn=fe200 nr=200
(XEN) [2015-04-12 14:55:40.565] irq.c:276: Dom1 PCI link 0 changed 5 -> 0
(XEN) [2015-04-12 14:55:40.574] irq.c:276: Dom1 PCI link 1 changed 10 -> 0
(XEN) [2015-04-12 14:55:40.583] irq.c:276: Dom1 PCI link 2 changed 11 -> 0
(XEN) [2015-04-12 14:55:40.592] irq.c:276: Dom1 PCI link 3 changed 5 -> 0
(XEN) [2015-04-12 14:55:41.346] grant_table.c:1305:d1v1 Expanding dom (1) grant table from (4) to (5) frames. (XEN) [2015-04-12 14:57:24.045] grant_table.c:1305:d1v0 Expanding dom (1) grant table from (5) to (6) frames. (XEN) [2015-04-12 14:57:24.051] grant_table.c:311:d0v0 Increased maptrack size to 2 frames (d2) [2015-04-12 14:58:13.556] mapping kernel into physical memory
(d2) [2015-04-12 14:58:13.556] about to get started...

#1 lore raw
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

I think this is qemu incorrectly trying to map GFNs.

David

Quoted 2 lines

I now get a very large number of these at guest with passthrough start:
(XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

#2 lore raw
Quoted 9 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Quoted 7 lines

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

I think this is qemu incorrectly trying to map GFNs.

David

Reverted that specific one, but still get those messages.

--
Sander

Quoted 2 lines
Quoted 2 lines

I now get a very large number of these at guest with passthrough start:
(XEN) [2015-04-12 14:55:20.226] p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

#3 lore raw
Quoted 16 lines · Sander Eikelenboom
Quoted 12 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

Quoted 5 lines
Quoted 3 lines

I think this is qemu incorrectly trying to map GFNs.

David

Reverted that specific one, but still get those messages.

You'll have to bisect it then. Because I don't see any other relevant commits in devel/for-linus-4.1

David

#4 lore raw
Quoted 19 lines · you
Quoted 18 lines · Sander Eikelenboom
Quoted 14 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

I think this is qemu incorrectly trying to map GFNs.

Quoted 8 lines
Quoted 3 lines
Quoted 1 line

David

Reverted that specific one, but still get those messages.

You'll have to bisect it then. Because I don't see any other relevant commits in devel/for-linus-4.1

David

Ok .. hmm first candidate of the bisect also looks interessting:
[628c28eefd6f2cef03b212081b466ae43fd093a3] xen: unify foreign GFN map/unmap for auto-xlated physmap guests

--
Sander

#5 lore raw
Quoted 26 lines · Sander Eikelenboom
Quoted 22 lines · you
Quoted 21 lines · Sander Eikelenboom
Quoted 9 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Quoted 7 lines

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

I think this is qemu incorrectly trying to map GFNs.

David

Reverted that specific one, but still get those messages.

Quoted 7 lines
Quoted 4 lines

You'll have to bisect it then. Because I don't see any other relevant commits in devel/for-linus-4.1

David

Ok .. hmm first candidate of the bisect also looks interessting:
[628c28eefd6f2cef03b212081b466ae43fd093a3] xen: unify foreign GFN map/unmap for auto-xlated physmap guests

Unless your dom0 is PVH, no.

David

#6 lore raw
Quoted 30 lines · you
Quoted 29 lines · Sander Eikelenboom
Quoted 25 lines · you
Quoted 16 lines · Sander Eikelenboom
Quoted 12 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

Quoted 5 lines
Quoted 3 lines

I think this is qemu incorrectly trying to map GFNs.

David

Reverted that specific one, but still get those messages.

You'll have to bisect it then. Because I don't see any other relevant commits in devel/for-linus-4.1

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

David

Ok .. hmm first candidate of the bisect also looks interessting:
[628c28eefd6f2cef03b212081b466ae43fd093a3] xen: unify foreign GFN map/unmap for auto-xlated physmap guests

Unless your dom0 is PVH, no.

David

Nope .. but bisect is underway .. so hopefully we will know it soon enough :-)

#7 lore raw
In reply to David Vrabel
Quoted 30 lines · you
Quoted 29 lines · Sander Eikelenboom
Quoted 25 lines · you
Quoted 16 lines · Sander Eikelenboom
Quoted 12 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

Quoted 5 lines
Quoted 3 lines

I think this is qemu incorrectly trying to map GFNs.

David

Reverted that specific one, but still get those messages.

You'll have to bisect it then. Because I don't see any other relevant commits in devel/for-linus-4.1

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

David

Ok .. hmm first candidate of the bisect also looks interessting:
[628c28eefd6f2cef03b212081b466ae43fd093a3] xen: unify foreign GFN map/unmap for auto-xlated physmap guests

Unless your dom0 is PVH, no.

David

Bisection came back with:

22d8a8938407cb1342af763e937fdf9ee8daf24a is the first bad commit commit 22d8a8938407cb1342af763e937fdf9ee8daf24a

Author: Konrad Rzeszutek Wilk <[email protected]>
Date:   Fri Apr 3 10:28:08 2015 -0400

xen/pciback: Don't disable PCI_COMMAND on PCI device reset.

There is no need for this at all. Worst it means that if the guest tries to write to BARs it could lead (on certain platforms) to PCI SERR errors.

Please note that with af6fc858a35b90e89ea7a7ee58e66628c55c776b "xen-pciback: limit guest control of command register"
a guest is still allowed to enable those control bits (safely), but is not allowed to disable them and that therefore a well behaved frontend which enables things before using them will still function correctly.

This is done via an write to the configuration register 0x4 which triggers on the backend side:
command_write
\- pci_enable_device
\- pci_enable_device_flags
\- do_pci_enable_device
\- pcibios_enable_device
\-pci_enable_resourcess
[which enables the PCI_COMMAND_MEMORY|PCI_COMMAND_IO]

However guests (and drivers) which don't do this could cause problems, including the security issues which XSA-120 sought to address.

Could it be due to the kind of "split brain" relation pciback and qemu have ? (qemu+libxl not setting up things like pcifront does (with event channel and conf space access going through pciback instead of qemu doing things by itself, which also leads to pciback not installing a interrupt handler in dom0 for the devices since that in pciback relies on:
- proper state signaling via xenbus
- setting up an event channel
- doing conf space acces via pciback
)

Is there actually a technical reason why the xen pci passthrough parts in qemu don't act more like pci-front for PV does:
setting up things properly via xenbus, event channel etc, so it would be more similar ?

Or was this more a kind of an oversight when HVM's were introduced ?

--
Sander

#8 lore raw
Quoted 42 lines · Sander Eikelenboom
Quoted 30 lines · you
Quoted 29 lines · Sander Eikelenboom
Quoted 25 lines · you
Quoted 16 lines · Sander Eikelenboom
Quoted 12 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

Quoted 5 lines
Quoted 3 lines

I think this is qemu incorrectly trying to map GFNs.

David

Reverted that specific one, but still get those messages.

You'll have to bisect it then. Because I don't see any other relevant commits in devel/for-linus-4.1

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

David

Ok .. hmm first candidate of the bisect also looks interessting:
[628c28eefd6f2cef03b212081b466ae43fd093a3] xen: unify foreign GFN map/unmap for auto-xlated physmap guests

Unless your dom0 is PVH, no.

David

Quoted 8 lines

Bisection came back with:

22d8a8938407cb1342af763e937fdf9ee8daf24a is the first bad commit commit 22d8a8938407cb1342af763e937fdf9ee8daf24a

Author: Konrad Rzeszutek Wilk <[email protected]>
Date:   Fri Apr 3 10:28:08 2015 -0400

xen/pciback: Don't disable PCI_COMMAND on PCI device reset.

I don't really understand how this could cause the symptoms you reported.

I don't have time to look into this myself so I'm going to drop these two pciback patches for now.

David

#9 lore raw
In reply to Sander Eikelenboom
Quoted 92 lines · Sander Eikelenboom
Quoted 30 lines · you
Quoted 29 lines · Sander Eikelenboom
Quoted 25 lines · you
Quoted 16 lines · Sander Eikelenboom
Quoted 12 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

Quoted 5 lines
Quoted 3 lines

I think this is qemu incorrectly trying to map GFNs.

David

Reverted that specific one, but still get those messages.

You'll have to bisect it then. Because I don't see any other relevant commits in devel/for-linus-4.1

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

David

Ok .. hmm first candidate of the bisect also looks interessting:
[628c28eefd6f2cef03b212081b466ae43fd093a3] xen: unify foreign GFN map/unmap for auto-xlated physmap guests

Unless your dom0 is PVH, no.

David

Bisection came back with:

22d8a8938407cb1342af763e937fdf9ee8daf24a is the first bad commit commit 22d8a8938407cb1342af763e937fdf9ee8daf24a

Author: Konrad Rzeszutek Wilk <[email protected]>
Date:   Fri Apr 3 10:28:08 2015 -0400

xen/pciback: Don't disable PCI_COMMAND on PCI device reset.

There is no need for this at all. Worst it means that if the guest tries to write to BARs it could lead (on certain platforms) to PCI SERR errors.

Please note that with af6fc858a35b90e89ea7a7ee58e66628c55c776b "xen-pciback: limit guest control of command register"
a guest is still allowed to enable those control bits (safely), but is not allowed to disable them and that therefore a well behaved frontend which enables things before using them will still function correctly.

This is done via an write to the configuration register 0x4 which triggers on the backend side:
command_write
\- pci_enable_device
\- pci_enable_device_flags
\- do_pci_enable_device
\- pcibios_enable_device
\-pci_enable_resourcess
[which enables the PCI_COMMAND_MEMORY|PCI_COMMAND_IO]

However guests (and drivers) which don't do this could cause problems, including the security issues which XSA-120 sought to address.

Could it be due to the kind of "split brain" relation pciback and qemu have ? (qemu+libxl not setting up things like pcifront does (with event channel and conf space access going through pciback instead of qemu doing things by itself, which also leads to pciback not installing a interrupt handler in dom0 for the devices since that in pciback relies on:
- proper state signaling via xenbus
- setting up an event channel
- doing conf space acces via pciback
)

Quoted 3 lines

Is there actually a technical reason why the xen pci passthrough parts in qemu don't act more like pci-front for PV does:
setting up things properly via xenbus, event channel etc, so it would be more similar ?

What is your qemu-xen commit id?

With this patch reverted, what is lspci -vvv before you assign to a guest and when hvmloader started?

Thanks!

Quoted 2 lines

Or was this more a kind of an oversight when HVM's were introduced ?

Not sure I understand the question? The XSA126 (http://xenbits.xen.org/xsa/xsa126-qemuu.patch)
has a fix for enabling the proper bits in PCI_COMMAND which xen-pciback
had disabled (which the above Linux patch fixes).

If you have the QEMU patch in you should see a similar issue (I think). Unless the xen-pciback fix causes an previously unused path in libxl (or qemu) to be used (as before when it read the bars from SysFS they were zero). Hmmm.

Could you also attach 'xl -vvvv -d create <g.cfg>' with and without the kernel patch if it is not too much trouble?

If it is - I will do it tomorrow and see if I can see an disreprancy.

Quoted 4 lines

--
Sander

#10 lore raw
Quoted 115 lines · you
Quoted 92 lines · Sander Eikelenboom
Quoted 30 lines · you
Quoted 29 lines · Sander Eikelenboom
Quoted 25 lines · you
Quoted 16 lines · Sander Eikelenboom
Quoted 12 lines · you
Quoted 7 lines · Sander Eikelenboom

Hi David,

I seem to have spotted some trouble with a 4.0 dom0 kernel with the devel/for-linus-4.1 branch pulled on top.

Does this remind you of any specific commits in the devel/for-linus-4.1 branch that could likely be involved that i could try to revert ?

Yes. This will probably be 4e8c0c8c4bf3a (xen/privcmd: improve performance of MMAPBATCH_V2) which makes the kernel try harder to map all GFNs instead of failing on the first one.

Quoted 5 lines
Quoted 3 lines

I think this is qemu incorrectly trying to map GFNs.

David

Reverted that specific one, but still get those messages.

You'll have to bisect it then. Because I don't see any other relevant commits in devel/for-linus-4.1

Quoted 8 lines
Quoted 4 lines
Quoted 1 line

David

Ok .. hmm first candidate of the bisect also looks interessting:
[628c28eefd6f2cef03b212081b466ae43fd093a3] xen: unify foreign GFN map/unmap for auto-xlated physmap guests

Unless your dom0 is PVH, no.

David

Bisection came back with:

22d8a8938407cb1342af763e937fdf9ee8daf24a is the first bad commit commit 22d8a8938407cb1342af763e937fdf9ee8daf24a

Author: Konrad Rzeszutek Wilk <[email protected]>
Date:   Fri Apr 3 10:28:08 2015 -0400

xen/pciback: Don't disable PCI_COMMAND on PCI device reset.

There is no need for this at all. Worst it means that if the guest tries to write to BARs it could lead (on certain platforms) to PCI SERR errors.

Please note that with af6fc858a35b90e89ea7a7ee58e66628c55c776b "xen-pciback: limit guest control of command register"
a guest is still allowed to enable those control bits (safely), but is not allowed to disable them and that therefore a well behaved frontend which enables things before using them will still function correctly.

This is done via an write to the configuration register 0x4 which triggers on the backend side:
command_write
\- pci_enable_device
\- pci_enable_device_flags
\- do_pci_enable_device
\- pcibios_enable_device
\-pci_enable_resourcess
[which enables the PCI_COMMAND_MEMORY|PCI_COMMAND_IO]

However guests (and drivers) which don't do this could cause problems, including the security issues which XSA-120 sought to address.

Could it be due to the kind of "split brain" relation pciback and qemu have ? (qemu+libxl not setting up things like pcifront does (with event channel and conf space access going through pciback instead of qemu doing things by itself, which also leads to pciback not installing a interrupt handler in dom0 for the devices since that in pciback relies on:
- proper state signaling via xenbus
- setting up an event channel
- doing conf space acces via pciback
)

Quoted 3 lines

Is there actually a technical reason why the xen pci passthrough parts in qemu don't act more like pci-front for PV does:
setting up things properly via xenbus, event channel etc, so it would be more similar ?

What is your qemu-xen commit id?

With this patch reverted, what is lspci -vvv before you assign to a guest and when hvmloader started?

Thanks!

Quoted 2 lines

Or was this more a kind of an oversight when HVM's were introduced ?

Not sure I understand the question? The XSA126 (http://xenbits.xen.org/xsa/xsa126-qemuu.patch)
has a fix for enabling the proper bits in PCI_COMMAND which xen-pciback
had disabled (which the above Linux patch fixes).

If you have the QEMU patch in you should see a similar issue (I think). Unless the xen-pciback fix causes an previously unused path in libxl (or qemu) to be used (as before when it read the bars from SysFS they were zero). Hmmm.

Quoted 9 lines

Could you also attach 'xl -vvvv -d create <g.cfg>' with and without the kernel patch if it is not too much trouble?

If it is - I will do it tomorrow and see if I can see an disreprancy.

Quoted 4 lines

--
Sander

Hi Konrad,

xen version is at last changeset 3a28f760508fb35c430edac17a9efde5aff6d1d5 (previous unstable master before the force push which includes 1aeb1156fa43fe2cd2b5003995b20466cd19a622 which causes the trouble reported here:
http://lists.xen.org/archives/html/xen-devel/2015-04/msg01336.html )

qemu-xen is at last changeset 727b998448e852a5e8eb570ac3a259ef62fbdacb plus the revert of 7665d6ba98e20fb05c420de947c1750fd47e5c07 (due to other problem reported here:
http://lists.xen.org/archives/html/xen-devel/2015-04/msg01121.html )

Kernels used:
nokp: Linux v4.0 + stable/for-linus-4.1
kp: nokp + 22d8a8938407cb1342af763e937fdf9ee8daf24a applied.

The device is used for passthrough is: 0a:00.0

--
Sander

Attached are:
kp-lspci-before: lspci -vvv with kernel-patch (bad) before guest start
kp-lspci-during: lspci -vvv with kernel-patch (bad) guest started
nokp-lspci-before: lspci -vvv without kernel-patch (good) before guest start
nokp-lspci-during: lspci -vvv without kernel-patch (good) guest started

kp-xl: xl -vvvv create with kernel-patch (bad)
nokp-xl: xl -vvvv create without kernel-patch (good)

kp-dmesg: xl dmesg output with kernel-patch (bad)
nokp-dmesg: xl dmesg output without kernel-patch (good)

kp-xl-dmesg: xl dmesg output with kernel-patch (bad)
nokp-xl-dmesg: xl dmesg output without kernel-patch (good)

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#11 lore raw
Quoted 11 lines

Hi Konrad,

xen version is at last changeset 3a28f760508fb35c430edac17a9efde5aff6d1d5 (previous unstable master before the force push which includes 1aeb1156fa43fe2cd2b5003995b20466cd19a622 which causes the trouble reported here:
http://lists.xen.org/archives/html/xen-devel/2015-04/msg01336.html )

qemu-xen is at last changeset 727b998448e852a5e8eb570ac3a259ef62fbdacb plus the revert of 7665d6ba98e20fb05c420de947c1750fd47e5c07 (due to other problem reported here:
http://lists.xen.org/archives/html/xen-devel/2015-04/msg01121.html )

You sure? I thought Andrew had an three line patch to fix that:

xen/drivers/passthrough/x86/iommu.c +3 -2
index 9eb8d33..f4ab044 100644
@@ -56,8 +56,9 @@ int arch_iommu_populate_page_table(struct domain *d)
 
     while ( !rc && (page = page_list_remove_head(&d->page_list)) )
     {
-        if ( has_hvm_container_domain(d) ||
-            (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page )
+        if ( (mfn_to_gmfn(d, page_to_mfn(page)) != INVALID_MFN) &&
+            (has_hvm_container_domain(d) ||
+             ((page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page)) )
         {
             BUG_ON(SHARED_M2P(mfn_to_gmfn(d, page_to_mfn(page))));
             rc = hd->platform_ops->map_page(

?

#12 lore raw
Quoted 7 lines · you
Quoted 7 lines

Hi Konrad,

xen version is at last changeset 3a28f760508fb35c430edac17a9efde5aff6d1d5 (previous unstable master before the force push which includes 1aeb1156fa43fe2cd2b5003995b20466cd19a622 which causes the trouble reported here:
http://lists.xen.org/archives/html/xen-devel/2015-04/msg01336.html )

Quoted 6 lines
Quoted 4 lines

qemu-xen is at last changeset 727b998448e852a5e8eb570ac3a259ef62fbdacb plus the revert of 7665d6ba98e20fb05c420de947c1750fd47e5c07 (due to other problem reported here:
http://lists.xen.org/archives/html/xen-devel/2015-04/msg01121.html )

You sure? I thought Andrew had an three line patch to fix that:

Yeah that one helped, but Andrew clearly stated that it's RFC:
"I am not certain that it is the correct way to fix the issue, nor that the ioreq server code is the only way to trigger it. There are several ways to shoot a gfn mapping from the guests physmap.

At least we now understand why it happens. I will defer to others CC'd on this thread for their opinions in the matter."

So my thought was to try to keep this issue as separated as possible from the other two while testing.

xen/drivers/passthrough/x86/iommu.c int arch_iommu_populate_page_table(struct domain *d) · line 59

Quoted 9 lines
xen/drivers/passthrough/x86/iommu.c +0 -1
index 9eb8d33..f4ab044 100644
@@ -56,8 +56,9 @@ int arch_iommu_populate_page_table(struct domain *d)
 
     while ( !rc && (page = page_list_remove_head(&d->page_list)) )
     {
-        if ( has_hvm_container_domain(d) ||

- (page->>u.inuse.type_info & PGT_type_mask) == PGT_writable_page )

Quoted 8 lines
xen/drivers/passthrough/x86/iommu.c +3 -0
+        if ( (mfn_to_gmfn(d, page_to_mfn(page)) != INVALID_MFN) &&
+            (has_hvm_container_domain(d) ||
+             ((page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page)) )
         {
             BUG_ON(SHARED_M2P(mfn_to_gmfn(d, page_to_mfn(page))));
             rc = hd->platform_ops->map_page(

?

#13 lore raw

Is: qemu-xen mishandling upper 64-bit BAR compared to qemu-tradWas:Re: Dom0 linux 4.0 + devel/for-linus-4.1 branch: p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

Quoted 10 lines · Sander Eikelenboom
Quoted 7 lines · you
Quoted 7 lines

Hi Konrad,

xen version is at last changeset 3a28f760508fb35c430edac17a9efde5aff6d1d5 (previous unstable master before the force push which includes 1aeb1156fa43fe2cd2b5003995b20466cd19a622 which causes the trouble reported here:
http://lists.xen.org/archives/html/xen-devel/2015-04/msg01336.html )

Quoted 5 lines
Quoted 4 lines
Quoted 4 lines

qemu-xen is at last changeset 727b998448e852a5e8eb570ac3a259ef62fbdacb plus the revert of 7665d6ba98e20fb05c420de947c1750fd47e5c07 (due to other problem reported here:
http://lists.xen.org/archives/html/xen-devel/2015-04/msg01121.html )

I was able to reproduce this with an older NIC that exposes 64-bit BARs.

The problem is that the XSA120-addendm patch (which does not clear the PCI_COMMAND register anymore), causes an missing functionality in qemu-xen to be exposed. This missing functionality is implemented in qemu-traditional which is why it works there.

The problem is that qemu-xen for any write to the BAR regions updates them to the hypervisor - but only if the real hardware has them enabled (see pci_update_mappings in pci_default_write_config which is called by xen_pt_pci_write_config). Specifically pci_bar_address checks PCI_COMMAND register for PCI_COMMAND_MEMORY. If it is disabled (so no XSA-120 addendum patch), it returns -1 (default value resulting in no changes in the internal structures). If it is enabled, then it updates the d->config space with the value written by the guest. Once xen_pt_pci_write_config is done it syncs up the changes (if there are any) which results in the QEMU calling hypervisor to update the P2M mapping. However

That is, the hvmloader performs for 64-bit BARs two writes of ~0 - to the BARx and BARx+1 to get the full size of PCI device. That means d->config[BARx] is updated to 0xffffff, and since the PCI_COMMAND_MEMORY is set, it actually merges that with the real host value read (so the size of the device), which then later goes through an gauntlet of masking (see xen_pt_bar_reg_write) which picks the right value to return to the guest.
The d->config[BARx] remains unchanged (I think, need to verify).

The next write by hvmloader for the upper BAR (BARx+1) results in d->config[BARx+1] to be updated with 0xffffffff as well. This means we have d->config[BARx] to be 0xfffffff and d->config[BARx+1] to be 0xfffffff (see pci_default_write_config).

pci_update_mappings does not deal in d->config but instead iterates over the PCIIORegion (r->addr and such). It asks pci_bar_address(d, BARx) for the new value, and since this is a 64-bit value, pci_bar_address hands over
d->config[BARx]| d->config[BARx+1] & (Some filtering).

The end result is that we have now 0xffffff000000e or such which r->addr is updated with (the default value was -1).

And then once xen_pt_pci_write_config is done the hypercall is done which tries to update the MFN for the BAR with a new r->addr (0xffffff0000..) which fails.

Prior to the XSA120-addendum patch, none of this would happen because pci_bar_address would always return -1 (uint32_t) for any region and since the default r->addr is -1, we would never do the hypercall.

If you have gotten to this point and are not exactly sure what I am saying - here is a function char to help:

xen_pt_pci_write_config (BARx+1, ~0)

	pci_default_write_config(BARx+1, ~0)
		pci_update_mappings()
			pci_bar_address [for each BAR]
				if (!(cmd & PCI_COMMAND_MEMORY))
					don't update r->addr
				else
					update r->addr with d->config+bar offset (quad read)
	xen_pt_bar_reg_write (BARx+1, ~0)
	if any of the r->addr changed, make the hypercall.

Note that these reads are four bytes read.

The qemu-trad had some extra code to deal with the upper bar by always making r->addr = -1 if anybody ever
wrote -1 to it. That is - ignore whatever the host had and
always make it the default value - so that we would never make the hypercall.

Stefano, thoughts on the fix? Just try doing what qemu-trad did?

#14 lore raw

Is: qemu-xen mishandling upper 64-bit BAR compared to qemu-tradWas:Re: Dom0 linux 4.0 + devel/for-linus-4.1 branch: p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

Quoted 6 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 03:02, <[email protected]> wrote:

The problem is that the XSA120-addendm patch (which does not clear the PCI_COMMAND register anymore), causes an missing functionality in qemu-xen to be exposed. This missing functionality is implemented in qemu-traditional which is why it works there.

Quoted 11 lines

The problem is that qemu-xen for any write to the BAR regions updates them to the hypervisor - but only if the real hardware has them enabled (see pci_update_mappings in pci_default_write_config which is called by xen_pt_pci_write_config). Specifically pci_bar_address checks PCI_COMMAND register for PCI_COMMAND_MEMORY. If it is disabled (so no XSA-120 addendum patch), it returns -1 (default value resulting in no changes in the internal structures). If it is enabled, then it updates the d->config space with the value written by the guest. Once xen_pt_pci_write_config is done it syncs up the changes (if there are any) which results in the QEMU calling hypervisor to update the P2M mapping.

There's one fundamental aspect I'm not understanding here:
pci_update_mappings() / pci_bar_address() look at the guest view (or at least they ought to be), and the virtual command register starts out as zero. Is the bug perhaps that xen_pt_initfn(), after having initialized d->config[] via xen_host_pci_get_block(), leaves the command register at its host view value (rather than updating it alongside reg_entry->data in xen_pt_config_reg_init(), called via xen_pt_config_init()), which would have happened to be zero without that XSA-120 addendum? It is of course concerning that there are two (now clearly mismatching) guest views within qemu (and along those lines I also wonder whether the apparent duplicate maintenance of MSI and MSI-X state, due to pci_default_write_config() calling msi{,x}_write_config(), can do any good, or why the code uses pci_default_write_config() but not pci_default_read_config()).

It looks to me as if there was a halfhearted attempt to utilize infrastructure already available in qemu when these Xen pieces got added, leading to hard to understand issues like the one here. I.e. even if we addressed the initialization value issue above, there would still be two competing emulation layers potentially (and I suppose quite likely) leading to differing register state later on. Hence I wonder how many more issues there are (to come)...

Jan

#15 lore raw

Re: Is: qemu-xen mishandling upper 64-bit BAR compared to qemu-tradWas:Re: Dom0 linux 4.0 + devel/for-linus-4.1 branch: p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

Quoted 18 lines · Jan Beulich
Quoted 6 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 03:02, <[email protected]> wrote:

The problem is that the XSA120-addendm patch (which does not clear the PCI_COMMAND register anymore), causes an missing functionality in qemu-xen to be exposed. This missing functionality is implemented in qemu-traditional which is why it works there.

Quoted 11 lines

The problem is that qemu-xen for any write to the BAR regions updates them to the hypervisor - but only if the real hardware has them enabled (see pci_update_mappings in pci_default_write_config which is called by xen_pt_pci_write_config). Specifically pci_bar_address checks PCI_COMMAND register for PCI_COMMAND_MEMORY. If it is disabled (so no XSA-120 addendum patch), it returns -1 (default value resulting in no changes in the internal structures). If it is enabled, then it updates the d->config space with the value written by the guest. Once xen_pt_pci_write_config is done it syncs up the changes (if there are any) which results in the QEMU calling hypervisor to update the P2M mapping.

Quoted 9 lines

There's one fundamental aspect I'm not understanding here:
pci_update_mappings() / pci_bar_address() look at the guest view (or at least they ought to be), and the virtual command register starts out as zero. Is the bug perhaps that xen_pt_initfn(), after having initialized d->config[] via xen_host_pci_get_block(), leaves the command register at its host view value (rather than updating it alongside reg_entry->data in xen_pt_config_reg_init(), called via xen_pt_config_init()), which would have happened to be zero without that XSA-120 addendum?

It seems to me that Jan is right: setting the PCI_COMMAND register to ~PCI_COMMAND_MEMORY could be done at initialization time. Would that fix the bug?

Quoted 8 lines

It is of course concerning that
there are two (now clearly mismatching) guest views within qemu (and along those lines I also wonder whether the apparent duplicate maintenance of MSI and MSI-X state, due to pci_default_write_config() calling msi{,x}_write_config(), can do any good, or why the code uses pci_default_write_config() but not pci_default_read_config()).

Quoted 8 lines

It looks to me as if there was a halfhearted attempt to utilize infrastructure already available in qemu when these Xen pieces got added, leading to hard to understand issues like the one here. I.e. even if we addressed the initialization value issue above, there would still be two competing emulation layers potentially (and I suppose quite likely) leading to differing register state later on. Hence I wonder how many more issues there are (to come)...

The integration between the existing qemu-traditional code and the upstream QEMU code was hard. I am ready to believe there are more than just a few gaps and I would be happy to take further patches to improve the situation.

In this specific instance, are you referring to d->config, part of PCIDevice, and all the XenPTRegInfo instances? If so, I think the reason for having the latter, is that we need more flexibility, we need individual masks and read and write functions. At the same time we cannot really get rid of d->config.

#16 lore raw

Re: Is: qemu-xen mishandling upper 64-bit BAR compared to qemu-tradWas:Re: Dom0 linux 4.0 + devel/for-linus-4.1 branch: p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

Quoted 30 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 13:13, <[email protected]> wrote:
Quoted 18 lines · Jan Beulich
Quoted 6 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 03:02, <[email protected]> wrote:

The problem is that the XSA120-addendm patch (which does not clear the PCI_COMMAND register anymore), causes an missing functionality in qemu-xen to be exposed. This missing functionality is implemented in qemu-traditional which is why it works there.

Quoted 11 lines

The problem is that qemu-xen for any write to the BAR regions updates them to the hypervisor - but only if the real hardware has them enabled (see pci_update_mappings in pci_default_write_config which is called by xen_pt_pci_write_config). Specifically pci_bar_address checks PCI_COMMAND register for PCI_COMMAND_MEMORY. If it is disabled (so no XSA-120 addendum patch), it returns -1 (default value resulting in no changes in the internal structures). If it is enabled, then it updates the d->config space with the value written by the guest. Once xen_pt_pci_write_config is done it syncs up the changes (if there are any) which results in the QEMU calling hypervisor to update the P2M mapping.

Quoted 9 lines

There's one fundamental aspect I'm not understanding here:
pci_update_mappings() / pci_bar_address() look at the guest view (or at least they ought to be), and the virtual command register starts out as zero. Is the bug perhaps that xen_pt_initfn(), after having initialized d->config[] via xen_host_pci_get_block(), leaves the command register at its host view value (rather than updating it alongside reg_entry->data in xen_pt_config_reg_init(), called via xen_pt_config_init()), which would have happened to be zero without that XSA-120 addendum?

Quoted 3 lines

It seems to me that Jan is right: setting the PCI_COMMAND register to ~PCI_COMMAND_MEMORY could be done at initialization time. Would that fix the bug?

Why ~PCI_COMMAND_MEMORY? Just like in the Xen specific data, this field should start out as zero.

Quoted 22 lines
Quoted 8 lines

It is of course concerning that
there are two (now clearly mismatching) guest views within qemu (and along those lines I also wonder whether the apparent duplicate maintenance of MSI and MSI-X state, due to pci_default_write_config() calling msi{,x}_write_config(), can do any good, or why the code uses pci_default_write_config() but not pci_default_read_config()).

Quoted 8 lines

It looks to me as if there was a halfhearted attempt to utilize infrastructure already available in qemu when these Xen pieces got added, leading to hard to understand issues like the one here. I.e. even if we addressed the initialization value issue above, there would still be two competing emulation layers potentially (and I suppose quite likely) leading to differing register state later on. Hence I wonder how many more issues there are (to come)...

The integration between the existing qemu-traditional code and the upstream QEMU code was hard. I am ready to believe there are more than just a few gaps and I would be happy to take further patches to improve the situation.

Quoted 5 lines

In this specific instance, are you referring to d->config, part of PCIDevice, and all the XenPTRegInfo instances? If so, I think the reason for having the latter, is that we need more flexibility, we need individual masks and read and write functions. At the same time we cannot really get rid of d->config.

I guessed as much, but in that case we should keep the two in sync (i.e. where we apply custom logic we should sync back what we do do d->config[], and at init time we should merge host and emulated state according to ->emu_mask; or maybe XenPTReg shouldn't even have a data field, and instead modifications should go straight to d->config[]). Perhaps a first step ought to be to log all cases where they differ?

Jan

#17 lore raw

Re: Is: qemu-xen mishandling upper 64-bit BAR compared to qemu-tradWas:Re: Dom0 linux 4.0 + devel/for-linus-4.1 branch: p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

Quoted 39 lines · Jan Beulich
Quoted 5 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 13:13, <[email protected]> wrote:
Quoted 3 lines · Jan Beulich
Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 03:02, <[email protected]> wrote:

The problem is that the XSA120-addendm patch (which does not clear the PCI_COMMAND register anymore), causes an missing functionality

in

Quoted 1 line
Quoted 1 line
Quoted 1 line

qemu-xen to be exposed. This missing functionality is implemented

in

Quoted 5 lines
Quoted 5 lines
Quoted 5 lines

qemu-traditional which is why it works there.

The problem is that qemu-xen for any write to the BAR regions updates them to the hypervisor - but only if the real hardware has them enabled (see pci_update_mappings in pci_default_write_config

which

Quoted 1 line
Quoted 1 line
Quoted 1 line

is called by xen_pt_pci_write_config). Specifically

pci_bar_address

Quoted 1 line
Quoted 1 line
Quoted 1 line

checks PCI_COMMAND register for PCI_COMMAND_MEMORY. If it is

disabled

Quoted 1 line
Quoted 1 line
Quoted 1 line

(so no XSA-120 addendum patch), it returns -1 (default value

resulting

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

in no changes in the internal structures). If it is enabled, then it updates the d->config space with the value written by the

guest.

Quoted 1 line
Quoted 1 line
Quoted 1 line

Once xen_pt_pci_write_config is done it syncs up the changes (if

there

Quoted 1 line
Quoted 1 line
Quoted 1 line

are any) which results in the QEMU calling hypervisor to update

the P2M

Quoted 12 lines
Quoted 11 lines
Quoted 1 line

mapping.

There's one fundamental aspect I'm not understanding here:
pci_update_mappings() / pci_bar_address() look at the guest view (or at least they ought to be), and the virtual command register starts out as zero. Is the bug perhaps that xen_pt_initfn(), after having initialized d->config[] via xen_host_pci_get_block(), leaves the command register at its host view value (rather than updating it alongside reg_entry->data in xen_pt_config_reg_init(), called via xen_pt_config_init()), which would have happened to be zero without that XSA-120 addendum?

Quoted 6 lines
Quoted 3 lines

It seems to me that Jan is right: setting the PCI_COMMAND register to ~PCI_COMMAND_MEMORY could be done at initialization time. Would that fix the bug?

Why ~PCI_COMMAND_MEMORY? Just like in the Xen specific data, this field should start out as zero.

It should fix it. I will send out a patch later tonight.

Quoted 32 lines
Quoted 18 lines
Quoted 9 lines

It is of course concerning that
there are two (now clearly mismatching) guest views within qemu (and along those lines I also wonder whether the apparent duplicate maintenance of MSI and MSI-X state, due to pci_default_write_config() calling msi{,x}_write_config(), can do any good, or why the code uses pci_default_write_config() but not pci_default_read_config()).

Quoted 8 lines

It looks to me as if there was a halfhearted attempt to utilize infrastructure already available in qemu when these Xen pieces got added, leading to hard to understand issues like the one here. I.e. even if we addressed the initialization value issue above, there would still be two competing emulation layers potentially (and I suppose quite likely) leading to differing register state later on. Hence I wonder how many more issues there are (to come)...

Quoted 2 lines

The integration between the existing qemu-traditional code and the upstream QEMU code was hard. I am ready to believe there are more

than

Quoted 1 line

just a few gaps and I would be happy to take further patches to

improve

Quoted 4 lines

the situation.

In this specific instance, are you referring to d->config, part of PCIDevice, and all the XenPTRegInfo instances? If so, I think the

reason

Quoted 3 lines

for having the latter, is that we need more flexibility, we need individual masks and read and write functions. At the same time we cannot really get rid of d->config.

Quoted 8 lines

I guessed as much, but in that case we should keep the two in sync (i.e. where we apply custom logic we should sync back what we do do d->config[], and at init time we should merge host and emulated state according to ->emu_mask; or maybe XenPTReg shouldn't even have a data field, and instead modifications should go straight to d->config[]). Perhaps a first step ought to be to log all cases where they differ?

Let me cobble a patch to this effect and see what falls out.

Thank you for the feedback!

Quoted 1 line

Jan

#18 lore raw

PATCH 1/1 xen/pt: Start with emulated PCI_COMMAND set to zero.

In reply to Jan Beulich

From: Konrad Rzeszutek Wilk <[email protected]>

For a passthrough device we maintain a state of emulated registers value contained within d->config. We also consult the host registers (and apply ro and write masks) whenever the guest access the registers. This is done in xen_pt_pci_write_config and xen_pt_pci_read_config.

Also in this picture we call pci_default_write_config which updates the d->config and if the d->config[PCI_COMMAND] register has PCI_COMMAND_MEMORY (or PCI_COMMAND_IO) acts on those changes.

Which is exactly what we do not want to do for 64-bit BARs when the guest just wants to read the size of the BAR.

To get the size of 64-bit memory space BARs, the guest has to calculate ((BAR[x] & 0xFFFFFFF0) + ((BAR[x+1] & 0xFFFFFFFF) << 32)) which means it has to do two writes of ~0 to BARx and BARx+1.

Since (prior to this patch and with XSA120-addendum patch) the PCI_COMMAND register is copied from the host it can have PCI_COMMAND_MEMORY bit set which means that QEMU will try to update the hypervisor's P2M with BARx+1 value to ~0 (0xffffffff) instead of just having xen_pt_pci_write_config and xen_pt_bar_reg_write apply the proper masks and return the size to the guest.

This fixes errors such as these:

(XEN) memory_map:add: dom2 gfn=fffe0 mfn=fbce0 nr=20 (DEBUG) 189 pci dev 04:0 BAR16 wrote ~0.
(DEBUG) 200 pci dev 04:0 BAR16 read 0x0fffe0004.
(XEN) memory_map:remove: dom2 gfn=fffe0 mfn=fbce0 nr=20 (DEBUG) 204 pci dev 04:0 BAR16 wrote 0x0fffe0004.
(DEBUG) 217 pci dev 04:0 BAR16 read upper 0x000000000. (XEN) memory_map:add: dom2 gfn=ffffffff00000 mfn=fbce0 nr=20 (XEN) p2m.c:883:d0v0 p2m_set_entry failed! mfn=ffffffffffffffff rc:-22 (XEN) memory_map:fail: dom2 gfn=ffffffff00000 mfn=fbce0 nr=20 ret:-22 (XEN) memory_map:remove: dom2 gfn=ffffffff00000 mfn=fbce0 nr=20 (XEN) p2m.c:920:d0v0 gfn_to_mfn failed! gfn=ffffffff00000 type:4 (XEN) p2m.c:920:d0v0 gfn_to_mfn failed! gfn=ffffffff00001 type:4 ..
(XEN) memory_map: error -22 removing dom2 access to [fbce0,fbcff] (DEBUG) 222 pci dev 04:0 BAR16 read upper 0x0ffffffff. (XEN) memory_map:remove: dom2 gfn=ffffffff00000 mfn=fbce0 nr=20 (XEN) memory_map: error -22 removing dom2 access to [fbce0,fbcff]

[The DEBUG is to illustate what the hvmloader was doing]

---
 hw/xen/xen_pt.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)
hw/xen/xen_pt.c +3 -1
index 9d2b06b..72f4ca5 100644
@@ -785,7 +785,9 @@ out:
         xen_host_pci_set_word(&s->real_device, PCI_COMMAND,
                               pci_get_word(d->config + PCI_COMMAND) | cmd);
     }
-
+    /* Until the guest enables the device use d->config values which will
+     * inhibit pci_bar_address & pci_update_mappings from triggering updates.*/
+    pci_set_word(d->config + PCI_COMMAND, 0);
     memory_listener_register(&s->memory_listener, &address_space_memory);
     memory_listener_register(&s->io_listener, &address_space_io);
     XEN_PT_LOG(d,
Signature · 1 line
1.8.4.2
#19 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

Quoted 4 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 22:53, <[email protected]> wrote:

hw/xen/xen_pt.c out: · line 793

Quoted 10 lines
hw/xen/xen_pt.c +3 -1
@@ -785,7 +785,9 @@ out:
         xen_host_pci_set_word(&s->real_device, PCI_COMMAND,
                               pci_get_word(d->config + PCI_COMMAND) | cmd);
     }
-
+    /* Until the guest enables the device use d->config values which will
+     * inhibit pci_bar_address & pci_update_mappings from triggering updates.*/
+    pci_set_word(d->config + PCI_COMMAND, 0);
     memory_listener_register(&s->memory_listener, &address_space_memory);
     memory_listener_register(&s->io_listener, &address_space_io);
     XEN_PT_LOG(d,

Well, I can see this as something to be tried out as an experiment, but it looks like you mean this to be a proper submission for inclusion upstream? Or maybe not, considering that qemu-devel wasn't even Cc-ed? In any case - what we need here is a general solution to at least the initialization part of the problem, i.e. all fields we emulate some or all bits for need to have d->config[] updated accordingly (i.e. you need to merge d->config[] and XenPTReg's data field based on the respective XenPTRegInfo's emu_mask, but perhaps simply copying the data field to d->config[] would have the same effect; if it doesn't, we have yet another problem). For the command register this for example means that it is in no way guaranteed that it would end up being zero; its emu_mask however guarantees that the memory and I/O decode bits would start out as zero (which is what you're after).

Jan

#20 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

Quoted 16 lines · you
Quoted 4 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 22:53, <[email protected]> wrote:

hw/xen/xen_pt.c out: · line 793

Quoted 10 lines
hw/xen/xen_pt.c +3 -1
@@ -785,7 +785,9 @@ out:
         xen_host_pci_set_word(&s->real_device, PCI_COMMAND,
                               pci_get_word(d->config + PCI_COMMAND) | cmd);
     }
-
+    /* Until the guest enables the device use d->config values which will
+     * inhibit pci_bar_address & pci_update_mappings from triggering updates.*/
+    pci_set_word(d->config + PCI_COMMAND, 0);
     memory_listener_register(&s->memory_listener, &address_space_memory);
     memory_listener_register(&s->io_listener, &address_space_io);
     XEN_PT_LOG(d,

Well, I can see this as something to be tried out as an experiment,

Quoted 8 lines

but it looks like you mean this to be a proper submission for inclusion upstream? Or maybe not, considering that qemu-devel wasn't even Cc-ed? In any case - what we need here is a general solution to at least the initialization part of the problem, i.e. all fields we emulate some or all bits for need to have d->config[] updated accordingly (i.e. you need to merge d->config[] and XenPTReg's data field based on the respective XenPTRegInfo's emu_mask, but perhaps simply copying the data field to

d->>config[] would have the same effect; if it doesn't, we have

Quoted 4 lines

yet another problem). For the command register this for example means that it is in no way guaranteed that it would end up being zero; its emu_mask however guarantees that the memory and I/O decode bits would start out as zero (which is what you're after).

Just tested this patch together with a dom0 kernel which has the dropped kernel patch from Konrad:
22d8a8938407cb1342af763e937fdf9ee8daf24a xen/pciback: Don't disable PCI_COMMAND on PCI device reset.

And this patch does help to prevent the issue from happening.

--
Sander

Quoted 1 line

Jan

#21 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

Quoted 13 lines · Sander Eikelenboom
Quoted 10 lines · you
Quoted 10 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 22:53, <[email protected]> wrote:
hw/xen/xen_pt.c +2 -1
@@ -785,7 +785,9 @@ out:
         xen_host_pci_set_word(&s->real_device, PCI_COMMAND,
                               pci_get_word(d->config + PCI_COMMAND) | cmd);
     }
-
+    /* Until the guest enables the device use d->config values which will
+     * inhibit pci_bar_address & pci_update_mappings from triggering updates.*/
Quoted 8 lines
Quoted 8 lines

hw/xen/xen_pt.c out: · line 793

Quoted 4 lines
hw/xen/xen_pt.c +1 -0
+    pci_set_word(d->config + PCI_COMMAND, 0);
     memory_listener_register(&s->memory_listener, &address_space_memory);
     memory_listener_register(&s->io_listener, &address_space_io);
     XEN_PT_LOG(d,

Well, I can see this as something to be tried out as an experiment, but it looks like you mean this to be a proper submission for inclusion upstream? Or maybe not, considering that qemu-devel

I needed to make sure that Sander's test-case is indeed fixed with this. And it looks like it is which makes further development of this much simpler since I can reproduce this.

Quoted 11 lines
Quoted 6 lines

wasn't even Cc-ed? In any case - what we need here is a general solution to at least the initialization part of the problem, i.e. all fields we emulate some or all bits for need to have d->config[] updated accordingly (i.e. you need to merge d->config[] and XenPTReg's data field based on the respective XenPTRegInfo's emu_mask, but perhaps simply copying the data field to

d->>config[] would have the same effect; if it doesn't, we have

Quoted 4 lines

yet another problem). For the command register this for example means that it is in no way guaranteed that it would end up being zero; its emu_mask however guarantees that the memory and I/O decode bits would start out as zero (which is what you're after).

Right, I hope :-)

Quoted 5 lines

Just tested this patch together with a dom0 kernel which has the dropped kernel patch from Konrad:
22d8a8938407cb1342af763e937fdf9ee8daf24a xen/pciback: Don't disable PCI_COMMAND on PCI device reset.

And this patch does help to prevent the issue from happening.

Yeeey!

Quoted 8 lines

--
Sander

Quoted 1 line

Jan

#22 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

In reply to Jan Beulich
Quoted 21 lines · Jan Beulich
Quoted 4 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 22:53, <[email protected]> wrote:

hw/xen/xen_pt.c out: · line 793

Quoted 10 lines
hw/xen/xen_pt.c +3 -1
@@ -785,7 +785,9 @@ out:
         xen_host_pci_set_word(&s->real_device, PCI_COMMAND,
                               pci_get_word(d->config + PCI_COMMAND) | cmd);
     }
-
+    /* Until the guest enables the device use d->config values which will
+     * inhibit pci_bar_address & pci_update_mappings from triggering updates.*/
+    pci_set_word(d->config + PCI_COMMAND, 0);
     memory_listener_register(&s->memory_listener, &address_space_memory);
     memory_listener_register(&s->io_listener, &address_space_io);
     XEN_PT_LOG(d,

Well, I can see this as something to be tried out as an experiment, but it looks like you mean this to be a proper submission for inclusion upstream? Or maybe not, considering that qemu-devel wasn't even Cc-ed? In any case - what we need here is a general solution to at least the initialization part of the problem, i.e. all fields we emulate some or all bits for need to have d->config[]

Quoted 8 lines

updated accordingly (i.e. you need to merge d->config[] and XenPTReg's data field based on the respective XenPTRegInfo's emu_mask, but perhaps simply copying the data field to d->config[] would have the same effect; if it doesn't, we have yet another problem). For the command register this for example means that it is in no way guaranteed that it would end up being zero; its emu_mask however guarantees that the memory and I/O decode bits would start out as zero (which is what you're after).

I am not sure I can ask Konrad to come up with a larger general solution when his intent was just to fix this issue. This one liner is OK for that.

Of course it would be great if Konrad wanted to volunteer to submit a patch that updates d->config for all fields, or gets rid of reg->data entirely.

Konrad, what do you think?

#23 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

Quoted 35 lines · Stefano Stabellini
Quoted 21 lines · Jan Beulich
Quoted 4 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 22:53, <[email protected]> wrote:

hw/xen/xen_pt.c out: · line 793

Quoted 10 lines
hw/xen/xen_pt.c +3 -1
@@ -785,7 +785,9 @@ out:
         xen_host_pci_set_word(&s->real_device, PCI_COMMAND,
                               pci_get_word(d->config + PCI_COMMAND) | cmd);
     }
-
+    /* Until the guest enables the device use d->config values which will
+     * inhibit pci_bar_address & pci_update_mappings from triggering updates.*/
+    pci_set_word(d->config + PCI_COMMAND, 0);
     memory_listener_register(&s->memory_listener, &address_space_memory);
     memory_listener_register(&s->io_listener, &address_space_io);
     XEN_PT_LOG(d,

Well, I can see this as something to be tried out as an experiment, but it looks like you mean this to be a proper submission for inclusion upstream? Or maybe not, considering that qemu-devel wasn't even Cc-ed? In any case - what we need here is a general solution to at least the initialization part of the problem, i.e. all fields we emulate some or all bits for need to have d->config[]

Quoted 8 lines

updated accordingly (i.e. you need to merge d->config[] and XenPTReg's data field based on the respective XenPTRegInfo's emu_mask, but perhaps simply copying the data field to d->config[] would have the same effect; if it doesn't, we have yet another problem). For the command register this for example means that it is in no way guaranteed that it would end up being zero; its emu_mask however guarantees that the memory and I/O decode bits would start out as zero (which is what you're after).

I am not sure I can ask Konrad to come up with a larger general solution when his intent was just to fix this issue. This one liner is OK for that.

Quoted 5 lines

Of course it would be great if Konrad wanted to volunteer to submit a patch that updates d->config for all fields, or gets rid of reg->data entirely.

Konrad, what do you think?

You owe me a beer :-)

I will take me some time unless I can find a way to clone myself.

#24 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

In reply to Stefano Stabellini
Quoted 32 lines
Quoted 1 line
Quoted 1 line · On 15.06.15 at 18:19, <[email protected]> wrote:
Quoted 21 lines · Jan Beulich
Quoted 4 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 22:53, <[email protected]> wrote:

hw/xen/xen_pt.c out: · line 793

Quoted 10 lines
hw/xen/xen_pt.c +3 -1
@@ -785,7 +785,9 @@ out:
         xen_host_pci_set_word(&s->real_device, PCI_COMMAND,
                               pci_get_word(d->config + PCI_COMMAND) | cmd);
     }
-
+    /* Until the guest enables the device use d->config values which will
+     * inhibit pci_bar_address & pci_update_mappings from triggering updates.*/
+    pci_set_word(d->config + PCI_COMMAND, 0);
     memory_listener_register(&s->memory_listener, &address_space_memory);
     memory_listener_register(&s->io_listener, &address_space_io);
     XEN_PT_LOG(d,

Well, I can see this as something to be tried out as an experiment, but it looks like you mean this to be a proper submission for inclusion upstream? Or maybe not, considering that qemu-devel wasn't even Cc-ed? In any case - what we need here is a general solution to at least the initialization part of the problem, i.e. all fields we emulate some or all bits for need to have d->config[]

Quoted 8 lines

updated accordingly (i.e. you need to merge d->config[] and XenPTReg's data field based on the respective XenPTRegInfo's emu_mask, but perhaps simply copying the data field to d->config[] would have the same effect; if it doesn't, we have yet another problem). For the command register this for example means that it is in no way guaranteed that it would end up being zero; its emu_mask however guarantees that the memory and I/O decode bits would start out as zero (which is what you're after).

Quoted 3 lines

I am not sure I can ask Konrad to come up with a larger general solution when his intent was just to fix this issue. This one liner is OK for that.

But apart from leaving the same issue around for all other fields the change above is just a hack anyway, going from one incorrect value (the host one) to another incorrect one (constant zero). What I'd consider acceptable as a partial solution would be if at least proper merging was done for this particular field. Yet I suppose once doing that, it's not going to be that much more work to do at least proper init-value merging for all fields. Doing the wider change of eliminating/replacing the data field would indeed seem to go too far for an immediate fix of the issue here.

Jan

#25 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

Quoted 36 lines · Jan Beulich
Quoted 32 lines
Quoted 1 line
Quoted 1 line · On 15.06.15 at 18:19, <[email protected]> wrote:
Quoted 21 lines · Jan Beulich
Quoted 4 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 22:53, <[email protected]> wrote:

hw/xen/xen_pt.c out: · line 793

Quoted 10 lines
hw/xen/xen_pt.c +3 -1
@@ -785,7 +785,9 @@ out:
         xen_host_pci_set_word(&s->real_device, PCI_COMMAND,
                               pci_get_word(d->config + PCI_COMMAND) | cmd);
     }
-
+    /* Until the guest enables the device use d->config values which will
+     * inhibit pci_bar_address & pci_update_mappings from triggering updates.*/
+    pci_set_word(d->config + PCI_COMMAND, 0);
     memory_listener_register(&s->memory_listener, &address_space_memory);
     memory_listener_register(&s->io_listener, &address_space_io);
     XEN_PT_LOG(d,

Well, I can see this as something to be tried out as an experiment, but it looks like you mean this to be a proper submission for inclusion upstream? Or maybe not, considering that qemu-devel wasn't even Cc-ed? In any case - what we need here is a general solution to at least the initialization part of the problem, i.e. all fields we emulate some or all bits for need to have d->config[]

Quoted 8 lines

updated accordingly (i.e. you need to merge d->config[] and XenPTReg's data field based on the respective XenPTRegInfo's emu_mask, but perhaps simply copying the data field to d->config[] would have the same effect; if it doesn't, we have yet another problem). For the command register this for example means that it is in no way guaranteed that it would end up being zero; its emu_mask however guarantees that the memory and I/O decode bits would start out as zero (which is what you're after).

Quoted 3 lines

I am not sure I can ask Konrad to come up with a larger general solution when his intent was just to fix this issue. This one liner is OK for that.

Quoted 9 lines

But apart from leaving the same issue around for all other fields the change above is just a hack anyway, going from one incorrect value (the host one) to another incorrect one (constant zero). What I'd consider acceptable as a partial solution would be if at least proper merging was done for this particular field. Yet I suppose once doing that, it's not going to be that much more work to do at least proper init-value merging for all fields. Doing the wider change of eliminating/replacing the data field would indeed seem to go too far for an immediate fix of the issue here.

While digging in this I realized that some shortcuts and assumptions had been taken (I think I am restating what you two have already realized).

1) The dev.config is (by Xen code) used as the cache of the host configuration devices (which is OK at init right now).

However to sync up the ->data with dev.config (and apply emu_mask) means that it cannot be used as such (the semantics of that have changed).

2). The dev.config is (by the generic code) used as a view of what
the guest should see (cache of guest values).

To make this work, the plan would be:

1). Remove all the dev.config accesses to check host values:

	@@ -728,7 +729,7 @@ static int xen_pt_initfn(PCIDevice *d)
	     }
	 
	     /* Bind interrupt */
	-    if (!s->dev.config[PCI_INTERRUPT_PIN]) {
	+    if (xen_host_pci_get_byte(PCI_INTERRUPT_PIN)) {
		 XEN_PT_LOG(d, "no pin interrupt\n");
		 goto out;
	     }
     And replace them with calls to get the actual host value.

2). Replace all the pci_get_[byte,word,long] (which are wrappers
around dev.config) in the init routines (see get_capability_version and xen_pt_linkctrl_reg_init) with calls to xen_host_pci_[byte,word,long].

In short - replace the calls to get the actual host values.

That would untangle a lot of this and make it a bit saner (I hope).

And after that I can:

3). Rip out ->data and use pci_set_[byte,word,long] or pci_get_[byte,word,long]
to get one unified view of what the guest is suppose to have.

4). Tackle bugs that will creep up because of this. I am not sure what
they are, but surely will hit some. I expect that some of these patches will add debug/more logging to help me tackle this.

5). Reinstate an host cache (if needed) for configuration access to lessen
the amount of reads we do. 'host_cache_config' perhaps?

Anything I missed?

#26 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

Quoted 30 lines
Quoted 1 line
Quoted 1 line · On 24.06.15 at 17:59, <[email protected]> wrote:

While digging in this I realized that some shortcuts and assumptions had been taken (I think I am restating what you two have already realized).

1) The dev.config is (by Xen code) used as the cache of the host configuration devices (which is OK at init right now).

However to sync up the ->data with dev.config (and apply emu_mask) means that it cannot be used as such (the semantics of that have
changed).

2). The dev.config is (by the generic code) used as a view of what
the guest should see (cache of guest values).

To make this work, the plan would be:

1). Remove all the dev.config accesses to check host values:

	@@ -728,7 +729,7 @@ static int xen_pt_initfn(PCIDevice *d)
	     }
	 
	     /* Bind interrupt */
	-    if (!s->dev.config[PCI_INTERRUPT_PIN]) {
	+    if (xen_host_pci_get_byte(PCI_INTERRUPT_PIN)) {
		 XEN_PT_LOG(d, "no pin interrupt\n");
		 goto out;
	     }
     And replace them with calls to get the actual host value.
Quoted 7 lines

2). Replace all the pci_get_[byte,word,long] (which are wrappers
around dev.config) in the init routines (see get_capability_version and xen_pt_linkctrl_reg_init) with calls to xen_host_pci_[byte,word,long].

In short - replace the calls to get the actual host values.

That would untangle a lot of this and make it a bit saner (I hope).

Except that I don't think changing the init-time uses would really be necessary.

Quoted 6 lines

And after that I can:

3). Rip out ->data and use pci_set_[byte,word,long] or
pci_get_[byte,word,long]
to get one unified view of what the guest is suppose to have.

Quoted 6 lines

4). Tackle bugs that will creep up because of this. I am not sure what
they are, but surely will hit some. I expect that some of these patches will add debug/more logging to help me tackle this.

5). Reinstate an host cache (if needed) for configuration access to lessen
the amount of reads we do. 'host_cache_config' perhaps?

Not sure it's a good idea to cache registers that can change behind our back.

Jan

#27 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

Quoted 51 lines · Jan Beulich
Quoted 30 lines
Quoted 1 line
Quoted 1 line · On 24.06.15 at 17:59, <[email protected]> wrote:

While digging in this I realized that some shortcuts and assumptions had been taken (I think I am restating what you two have already realized).

1) The dev.config is (by Xen code) used as the cache of the host configuration devices (which is OK at init right now).

However to sync up the ->data with dev.config (and apply emu_mask) means that it cannot be used as such (the semantics of that have
changed).

2). The dev.config is (by the generic code) used as a view of what
the guest should see (cache of guest values).

To make this work, the plan would be:

1). Remove all the dev.config accesses to check host values:

	@@ -728,7 +729,7 @@ static int xen_pt_initfn(PCIDevice *d)
	     }
	 
	     /* Bind interrupt */
	-    if (!s->dev.config[PCI_INTERRUPT_PIN]) {
	+    if (xen_host_pci_get_byte(PCI_INTERRUPT_PIN)) {
		 XEN_PT_LOG(d, "no pin interrupt\n");
		 goto out;
	     }
     And replace them with calls to get the actual host value.
Quoted 7 lines

2). Replace all the pci_get_[byte,word,long] (which are wrappers
around dev.config) in the init routines (see get_capability_version and xen_pt_linkctrl_reg_init) with calls to xen_host_pci_[byte,word,long].

In short - replace the calls to get the actual host values.

That would untangle a lot of this and make it a bit saner (I hope).

Except that I don't think changing the init-time uses would really be necessary.

Quoted 10 lines

And after that I can:

3). Rip out ->data and use pci_set_[byte,word,long] or
pci_get_[byte,word,long]
to get one unified view of what the guest is suppose to have.

4). Tackle bugs that will creep up because of this. I am not sure what
they are, but surely will hit some. I expect that some of these patches will add debug/more logging to help me tackle this.

Quoted 5 lines
Quoted 2 lines

5). Reinstate an host cache (if needed) for configuration access to lessen
the amount of reads we do. 'host_cache_config' perhaps?

Not sure it's a good idea to cache registers that can change behind our back.

Right. The host cache idea is only good at init time I think.

#28 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

In reply to Jan Beulich
Quoted 34 lines · Jan Beulich
Quoted 34 lines
Quoted 1 line
Quoted 1 line · On 24.06.15 at 17:59, <[email protected]> wrote:

While digging in this I realized that some shortcuts and assumptions had been taken (I think I am restating what you two have already realized).

1) The dev.config is (by Xen code) used as the cache of the host configuration devices (which is OK at init right now).

However to sync up the ->data with dev.config (and apply emu_mask) means that it cannot be used as such (the semantics of that have
changed).

2). The dev.config is (by the generic code) used as a view of what
the guest should see (cache of guest values).

To make this work, the plan would be:

1). Remove all the dev.config accesses to check host values:

	@@ -728,7 +729,7 @@ static int xen_pt_initfn(PCIDevice *d)
	     }
	 
	     /* Bind interrupt */
	-    if (!s->dev.config[PCI_INTERRUPT_PIN]) {
	+    if (xen_host_pci_get_byte(PCI_INTERRUPT_PIN)) {
		 XEN_PT_LOG(d, "no pin interrupt\n");
		 goto out;
	     }
     And replace them with calls to get the actual host value.

2). Replace all the pci_get_[byte,word,long] (which are wrappers
around dev.config) in the init routines (see get_capability_version and xen_pt_linkctrl_reg_init) with calls to xen_host_pci_[byte,word,long].

Quoted 6 lines
Quoted 3 lines

In short - replace the calls to get the actual host values.

That would untangle a lot of this and make it a bit saner (I hope).

Except that I don't think changing the init-time uses would really be necessary.

Ah, but how would we go forward when dev.config is all we have - without any 'data'? We have to stash the init guest values somewhere.

Quoted 19 lines
Quoted 7 lines

And after that I can:

3). Rip out ->data and use pci_set_[byte,word,long] or
pci_get_[byte,word,long]
to get one unified view of what the guest is suppose to have.

Quoted 6 lines

4). Tackle bugs that will creep up because of this. I am not sure what
they are, but surely will hit some. I expect that some of these patches will add debug/more logging to help me tackle this.

5). Reinstate an host cache (if needed) for configuration access to lessen
the amount of reads we do. 'host_cache_config' perhaps?

Not sure it's a good idea to cache registers that can change behind our back.

Jan

#29 lore raw

Re: [PATCH QEMU-XEN] xen/pt: Start with emulated PCI_COMMAND set to zero.

Quoted 38 lines
Quoted 1 line
Quoted 1 line · On 25.06.15 at 19:23, <[email protected]> wrote:
Quoted 36 lines · Jan Beulich
Quoted 36 lines
Quoted 1 line
Quoted 1 line · On 24.06.15 at 17:59, <[email protected]> wrote:

While digging in this I realized that some shortcuts and assumptions had been taken (I think I am restating what you two have already realized).

1) The dev.config is (by Xen code) used as the cache of the host configuration devices (which is OK at init right now).

However to sync up the ->data with dev.config (and apply emu_mask) means that it cannot be used as such (the semantics of that have
changed).

2). The dev.config is (by the generic code) used as a view of what
the guest should see (cache of guest values).

To make this work, the plan would be:

1). Remove all the dev.config accesses to check host values:

	@@ -728,7 +729,7 @@ static int xen_pt_initfn(PCIDevice *d)
	     }
	 
	     /* Bind interrupt */
	-    if (!s->dev.config[PCI_INTERRUPT_PIN]) {
	+    if (xen_host_pci_get_byte(PCI_INTERRUPT_PIN)) {
		 XEN_PT_LOG(d, "no pin interrupt\n");
		 goto out;
	     }
     And replace them with calls to get the actual host value.

2). Replace all the pci_get_[byte,word,long] (which are wrappers
around dev.config) in the init routines (see get_capability_version and xen_pt_linkctrl_reg_init) with calls to xen_host_pci_[byte,word,long].

In short - replace the calls to get the actual host values.

Quoted 7 lines
Quoted 4 lines
Quoted 1 line

That would untangle a lot of this and make it a bit saner (I hope).

Except that I don't think changing the init-time uses would really be necessary.

Ah, but how would we go forward when dev.config is all we have - without any 'data'? We have to stash the init guest values somewhere.

Ah, right - cases like the above would either indeed need the change you suggest, or latching the needed value(s) individually before they may get modified by guest field initialization.

Jan

#30 lore raw

Re: Is: qemu-xen mishandling upper 64-bit BAR compared to qemu-tradWas:Re: Dom0 linux 4.0 + devel/for-linus-4.1 branch: p2m.c:884:d0v0 gfn_to_mfn failed! gfn=ffffffff001ed type:4

In reply to Jan Beulich
Quoted 65 lines · Jan Beulich
Quoted 30 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 13:13, <[email protected]> wrote:
Quoted 18 lines · Jan Beulich
Quoted 6 lines
Quoted 1 line
Quoted 1 line · On 10.06.15 at 03:02, <[email protected]> wrote:

The problem is that the XSA120-addendm patch (which does not clear the PCI_COMMAND register anymore), causes an missing functionality in qemu-xen to be exposed. This missing functionality is implemented in qemu-traditional which is why it works there.

Quoted 11 lines

The problem is that qemu-xen for any write to the BAR regions updates them to the hypervisor - but only if the real hardware has them enabled (see pci_update_mappings in pci_default_write_config which is called by xen_pt_pci_write_config). Specifically pci_bar_address checks PCI_COMMAND register for PCI_COMMAND_MEMORY. If it is disabled (so no XSA-120 addendum patch), it returns -1 (default value resulting in no changes in the internal structures). If it is enabled, then it updates the d->config space with the value written by the guest. Once xen_pt_pci_write_config is done it syncs up the changes (if there are any) which results in the QEMU calling hypervisor to update the P2M mapping.

Quoted 9 lines

There's one fundamental aspect I'm not understanding here:
pci_update_mappings() / pci_bar_address() look at the guest view (or at least they ought to be), and the virtual command register starts out as zero. Is the bug perhaps that xen_pt_initfn(), after having initialized d->config[] via xen_host_pci_get_block(), leaves the command register at its host view value (rather than updating it alongside reg_entry->data in xen_pt_config_reg_init(), called via xen_pt_config_init()), which would have happened to be zero without that XSA-120 addendum?

Quoted 3 lines

It seems to me that Jan is right: setting the PCI_COMMAND register to ~PCI_COMMAND_MEMORY could be done at initialization time. Would that fix the bug?

Why ~PCI_COMMAND_MEMORY? Just like in the Xen specific data, this field should start out as zero.

Quoted 22 lines
Quoted 8 lines

It is of course concerning that
there are two (now clearly mismatching) guest views within qemu (and along those lines I also wonder whether the apparent duplicate maintenance of MSI and MSI-X state, due to pci_default_write_config() calling msi{,x}_write_config(), can do any good, or why the code uses pci_default_write_config() but not pci_default_read_config()).

Quoted 8 lines

It looks to me as if there was a halfhearted attempt to utilize infrastructure already available in qemu when these Xen pieces got added, leading to hard to understand issues like the one here. I.e. even if we addressed the initialization value issue above, there would still be two competing emulation layers potentially (and I suppose quite likely) leading to differing register state later on. Hence I wonder how many more issues there are (to come)...

The integration between the existing qemu-traditional code and the upstream QEMU code was hard. I am ready to believe there are more than just a few gaps and I would be happy to take further patches to improve the situation.

Quoted 5 lines

In this specific instance, are you referring to d->config, part of PCIDevice, and all the XenPTRegInfo instances? If so, I think the reason for having the latter, is that we need more flexibility, we need individual masks and read and write functions. At the same time we cannot really get rid of d->config.

Quoted 7 lines

I guessed as much, but in that case we should keep the two in sync (i.e. where we apply custom logic we should sync back what we do do d->config[], and at init time we should merge host and emulated state according to ->emu_mask; or maybe XenPTReg shouldn't even have a data field, and instead modifications should go straight to d->config[]). Perhaps a first step ought to be to log all cases where they differ?

Yes, I think we could substitute the data field in XenPTReg with a pointer to the right place in d->config. Or we could just get rid of it and introduce a macro to access d->config + reg->offset.