1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
Length restrictions for fw_cfg_dma_transfer?
For me, this takes close to 3 minutes at 100% CPU:
echo "outl 0x518 0x9596ffff" | ./i386-softmmu/qemu-system-i386 -M q35 -m 32 -nographic -accel qtest -monitor none -serial none -qtest stdio
#0 phys_page_find (d=0x606000035d80, addr=136728041144404) at /exec.c:338
#1 address_space_lookup_region (d=0x606000035d80, addr=136728041144404, resolve_subpage=true) at /exec.c:363
#2 address_space_translate_internal (d=0x606000035d80, addr=136728041144404, xlat=0x7fff1fc0d070, plen=0x7fff1fc0d090, resolve_subpage=true) at /exec.c:382
#3 flatview_do_translate (fv=0x606000035d20, addr=136728041144404, xlat=0x7fff1fc0d070, plen_out=0x7fff1fc0d090, page_mask_out=0x0, is_write=true, is_mmio=true, target_as=0x7fff1fc0ce10, attrs=...)
pment/qemu/exec.c:520
#4 flatview_translate (fv=0x606000035d20, addr=136728041144404, xlat=0x7fff1fc0d070, plen=0x7fff1fc0d090, is_write=true, attrs=...) at /exec.c:586
#5 flatview_write_continue (fv=0x606000035d20, addr=136728041144404, attrs=..., ptr=0x7fff1fc0d660, len=172, addr1=136728041144400, l=172, mr=0x557fd54e77e0 <io_mem_unassigned>)
pment/qemu/exec.c:3160
#6 flatview_write (fv=0x606000035d20, addr=136728041144064, attrs=..., buf=0x7fff1fc0d660, len=512) at /exec.c:3177
#7 address_space_write (as=0x557fd54e7a00 <address_space_memory>, addr=136728041144064, attrs=..., buf=0x7fff1fc0d660, len=512) at /exec.c:3271
#8 dma_memory_set (as=0x557fd54e7a00 <address_space_memory>, addr=136728041144064, c=0 '\000', len=1378422272) at /dma-helpers.c:31
#9 fw_cfg_dma_transfer (s=0x61a000001e80) at /hw/nvram/fw_cfg.c:400
#10 fw_cfg_dma_mem_write (opaque=0x61a000001e80, addr=4, value=4294940309, size=4) at /hw/nvram/fw_cfg.c:467
#11 memory_region_write_accessor (mr=0x61a000002200, addr=4, value=0x7fff1fc0e3d0, size=4, shift=0, mask=4294967295, attrs=...) at /memory.c:483
#12 access_with_adjusted_size (addr=4, value=0x7fff1fc0e3d0, size=4, access_size_min=1, access_size_max=8, access_fn=0x557fd2288c80 <memory_region_write_accessor>, mr=0x61a000002200, attrs=...)
pment/qemu/memory.c:539
#13 memory_region_dispatch_write (mr=0x61a000002200, addr=4, data=4294940309, op=MO_32, attrs=...) at /memory.c:1476
#14 flatview_write_continue (fv=0x606000035f00, addr=1304, attrs=..., ptr=0x7fff1fc0ec40, len=4, addr1=4, l=4, mr=0x61a000002200) at /exec.c:3137
#15 flatview_write (fv=0x606000035f00, addr=1304, attrs=..., buf=0x7fff1fc0ec40, len=4) at /exec.c:3177
#16 address_space_write (as=0x557fd54e7bc0 <address_space_io>, addr=1304, attrs=..., buf=0x7fff1fc0ec40, len=4) at /exec.c:3271
It looks like fw_cfg_dma_transfer gets the address(136728041144064) and length(1378422272) for the read from the value provided as input 4294940309 (0xFFFF9695) which lands in pcbios. Should there be any limits on the length of guest-memory that fw_cfg should populate?
Found by libfuzzer
On 5/24/20 6:12 AM, Alexander Bulekov wrote:
> Public bug reported:
>
> For me, this takes close to 3 minutes at 100% CPU:
> echo "outl 0x518 0x9596ffff" | ./i386-softmmu/qemu-system-i386 -M q35 -m 32 -nographic -accel qtest -monitor none -serial none -qtest stdio
>
> #0 phys_page_find (d=0x606000035d80, addr=136728041144404) at /exec.c:338
> #1 address_space_lookup_region (d=0x606000035d80, addr=136728041144404, resolve_subpage=true) at /exec.c:363
> #2 address_space_translate_internal (d=0x606000035d80, addr=136728041144404, xlat=0x7fff1fc0d070, plen=0x7fff1fc0d090, resolve_subpage=true) at /exec.c:382
> #3 flatview_do_translate (fv=0x606000035d20, addr=136728041144404, xlat=0x7fff1fc0d070, plen_out=0x7fff1fc0d090, page_mask_out=0x0, is_write=true, is_mmio=true, target_as=0x7fff1fc0ce10, attrs=...)
> pment/qemu/exec.c:520
> #4 flatview_translate (fv=0x606000035d20, addr=136728041144404, xlat=0x7fff1fc0d070, plen=0x7fff1fc0d090, is_write=true, attrs=...) at /exec.c:586
> #5 flatview_write_continue (fv=0x606000035d20, addr=136728041144404, attrs=..., ptr=0x7fff1fc0d660, len=172, addr1=136728041144400, l=172, mr=0x557fd54e77e0 <io_mem_unassigned>)
> pment/qemu/exec.c:3160
> #6 flatview_write (fv=0x606000035d20, addr=136728041144064, attrs=..., buf=0x7fff1fc0d660, len=512) at /exec.c:3177
> #7 address_space_write (as=0x557fd54e7a00 <address_space_memory>, addr=136728041144064, attrs=..., buf=0x7fff1fc0d660, len=512) at /exec.c:3271
> #8 dma_memory_set (as=0x557fd54e7a00 <address_space_memory>, addr=136728041144064, c=0 '\000', len=1378422272) at /dma-helpers.c:31
> #9 fw_cfg_dma_transfer (s=0x61a000001e80) at /hw/nvram/fw_cfg.c:400
> #10 fw_cfg_dma_mem_write (opaque=0x61a000001e80, addr=4, value=4294940309, size=4) at /hw/nvram/fw_cfg.c:467
> #11 memory_region_write_accessor (mr=0x61a000002200, addr=4, value=0x7fff1fc0e3d0, size=4, shift=0, mask=4294967295, attrs=...) at /memory.c:483
> #12 access_with_adjusted_size (addr=4, value=0x7fff1fc0e3d0, size=4, access_size_min=1, access_size_max=8, access_fn=0x557fd2288c80 <memory_region_write_accessor>, mr=0x61a000002200, attrs=...)
> pment/qemu/memory.c:539
> #13 memory_region_dispatch_write (mr=0x61a000002200, addr=4, data=4294940309, op=MO_32, attrs=...) at /memory.c:1476
> #14 flatview_write_continue (fv=0x606000035f00, addr=1304, attrs=..., ptr=0x7fff1fc0ec40, len=4, addr1=4, l=4, mr=0x61a000002200) at /exec.c:3137
> #15 flatview_write (fv=0x606000035f00, addr=1304, attrs=..., buf=0x7fff1fc0ec40, len=4) at /exec.c:3177
> #16 address_space_write (as=0x557fd54e7bc0 <address_space_io>, addr=1304, attrs=..., buf=0x7fff1fc0ec40, len=4) at /exec.c:3271
>
>
> It looks like fw_cfg_dma_transfer gets the address(136728041144064) and length(1378422272) for the read from the value provided as input 4294940309 (0xFFFF9695) which lands in pcbios. Should there be any limits on the length of guest-memory that fw_cfg should populate?
It looks to me a normal behavior for a DMA device. DMA devices have a
different address space view than the CPUs.
Also note the fw_cfg is a generic device, not restricted to the x86 arch.
Maybe this function could use dma_memory_valid() to skip unassigned regions?
On Sun, 24 May 2020 at 11:30, Philippe Mathieu-Daudé <email address hidden> wrote:
> It looks to me a normal behavior for a DMA device. DMA devices have a
> different address space view than the CPUs.
> Also note the fw_cfg is a generic device, not restricted to the x86 arch.
In an ideal world all our DMA devices would use some kind of common
framework or design pattern so they didn't hog all the CPU
and/or spend minutes with the BQL held if the guest requests
an enormous-sized DMA. In practice many of them just have
a simple "loop until the DMA transfer is complete" implementation...
thanks
-- PMM
On 5/24/20 3:40 PM, Peter Maydell wrote:
> On Sun, 24 May 2020 at 11:30, Philippe Mathieu-Daudé <email address hidden> wrote:
>> It looks to me a normal behavior for a DMA device. DMA devices have a
>> different address space view than the CPUs.
>> Also note the fw_cfg is a generic device, not restricted to the x86 arch.
>
> In an ideal world all our DMA devices would use some kind of common
> framework or design pattern so they didn't hog all the CPU
> and/or spend minutes with the BQL held if the guest requests
> an enormous-sized DMA. In practice many of them just have
> a simple "loop until the DMA transfer is complete" implementation...
Is this framework already implemented in the hidden dma-helpers.c?
Apparently this file was written for BlockBackend, but the code seems
rather generic.
On 24/05/2020 14:40, Peter Maydell wrote:
> On Sun, 24 May 2020 at 11:30, Philippe Mathieu-Daudé <email address hidden> wrote:
>> It looks to me a normal behavior for a DMA device. DMA devices have a
>> different address space view than the CPUs.
>> Also note the fw_cfg is a generic device, not restricted to the x86 arch.
>
> In an ideal world all our DMA devices would use some kind of common
> framework or design pattern so they didn't hog all the CPU
> and/or spend minutes with the BQL held if the guest requests
> an enormous-sized DMA. In practice many of them just have
> a simple "loop until the DMA transfer is complete" implementation...
One of the problems with the PPC Mac DBDMA emulation is that the controller is
effectively a mini-CPU that runs its own programs for transferring data to/from memory.
Currently this is done as a QEMU BH which means for larger transfers the emulated CPU
can be paused for a not insignificant amount of time until the program performing the
transfer finishes. I've always wondered if this should be running in a separate
thread to reduce its impact.
ATB,
Mark.
Can you still reproduce this problem with the current git version of QEMU? ... for me, the command now returns immediately.
This no longer causes timeout/excessive CPU usage for me. Probably fixed
Ok, thanks for checking! Closing now.
|