On 4/6/23 20:17, Xuan Zhuo wrote:
On Thu, 6 Apr 2023 10:20:09 -0700, Guenter Roeck <li...@roeck-us.net> wrote:
Hi,
On Mon, Mar 27, 2023 at 12:05:33PM +0800, Xuan Zhuo wrote:
Added virtqueue_dma_dev() to get DMA device for virtio. Then the
caller can do dma operation in advance. The purpose is to keep memory
mapped across multiple add/get buf operations.
Signed-off-by: Xuan Zhuo <xuanz...@linux.alibaba.com>
Acked-by: Jason Wang <jasow...@redhat.com>
On sparc64, this patch results in
[ 4.364643] Unable to handle kernel NULL pointer dereference
[ 4.365157] tsk->{mm,active_mm}->context = 0000000000000000
[ 4.365394] tsk->{mm,active_mm}->pgd = fffff80000402000
[ 4.365611] \|/ ____ \|/
[ 4.365611] "@'/ .. \`@"
[ 4.365611] /_| \__/ |_\
[ 4.365611] \__U_/
[ 4.366165] swapper/0(1): Oops [#1]
[ 4.366630] CPU: 0 PID: 1 Comm: swapper/0 Tainted: G N
6.3.0-rc5-next-20230405 #1
[ 4.367121] TSTATE: 0000004411001606 TPC: 00000000004375c0 TNPC:
00000000004375c4 Y: 00000002 Tainted: G N
[ 4.367548] TPC: <dma_4u_supported+0x20/0x40>
[ 4.368111] g0: 0000000000000000 g1: 0000000001a93a50 g2: 0000000000000000
g3: 0000000001a96170
[ 4.368439] g4: fffff8000416e9a0 g5: fffff8001dc98000 g6: fffff80004170000
g7: 0000000000000005
[ 4.368769] o0: 0000000000000000 o1: ffffffffffffffff o2: 0000000000000001
o3: fffff800040b78d8
[ 4.369095] o4: 0000000000000000 o5: 0000000000000000 sp: fffff80004172d51
ret_pc: 00000000004375ac
[ 4.369934] RPC: <dma_4u_supported+0xc/0x40>
[ 4.370160] l0: 0000000000000002 l1: 0000000000000002 l2: 0000000000000000
l3: 00000000ffffffff
[ 4.370493] l4: 0000000000000001 l5: 000000000119d2b0 l6: fffff8000416e9a0
l7: 00000000018df000
[ 4.370820] i0: 0000000000000001 i1: ffffffffffffffff i2: fffff80004657758
i3: 000000000125ac00
[ 4.371145] i4: 0000000002362400 i5: 0000000000000000 i6: fffff80004172e01
i7: 000000000050e288
[ 4.371473] I7: <dma_set_mask+0x28/0x80>
[ 4.371683] Call Trace:
[ 4.371864] [<000000000050e288>] dma_set_mask+0x28/0x80
[ 4.372123] [<0000000000a83234>] virtio_dev_probe+0x14/0x400
[ 4.372348] [<0000000000ac7a18>] really_probe+0xb8/0x340
[ 4.372555] [<0000000000ac7d64>] driver_probe_device+0x24/0x120
[ 4.372794] [<0000000000ac8010>] __driver_attach+0x90/0x1a0
[ 4.373012] [<0000000000ac5b4c>] bus_for_each_dev+0x4c/0xa0
[ 4.373226] [<0000000000ac6d80>] bus_add_driver+0x140/0x1e0
[ 4.373440] [<0000000000ac8d94>] driver_register+0x74/0x120
[ 4.373653] [<0000000001b2a690>] virtio_net_driver_init+0x74/0xa8
[ 4.373886] [<0000000000427ee0>] do_one_initcall+0x60/0x340
[ 4.374099] [<0000000001b02f50>] kernel_init_freeable+0x1bc/0x228
[ 4.374330] [<0000000000f37264>] kernel_init+0x18/0x134
[ 4.374534] [<00000000004060e8>] ret_from_fork+0x1c/0x2c
[ 4.374738] [<0000000000000000>] 0x0
[ 4.374981] Disabling lock debugging due to kernel taint
[ 4.375237] Caller[000000000050e288]: dma_set_mask+0x28/0x80
[ 4.375477] Caller[0000000000a83234]: virtio_dev_probe+0x14/0x400
[ 4.375704] Caller[0000000000ac7a18]: really_probe+0xb8/0x340
[ 4.375916] Caller[0000000000ac7d64]: driver_probe_device+0x24/0x120
[ 4.376146] Caller[0000000000ac8010]: __driver_attach+0x90/0x1a0
[ 4.376365] Caller[0000000000ac5b4c]: bus_for_each_dev+0x4c/0xa0
[ 4.376583] Caller[0000000000ac6d80]: bus_add_driver+0x140/0x1e0
[ 4.376805] Caller[0000000000ac8d94]: driver_register+0x74/0x120
[ 4.377025] Caller[0000000001b2a690]: virtio_net_driver_init+0x74/0xa8
[ 4.377262] Caller[0000000000427ee0]: do_one_initcall+0x60/0x340
[ 4.377480] Caller[0000000001b02f50]: kernel_init_freeable+0x1bc/0x228
[ 4.377721] Caller[0000000000f37264]: kernel_init+0x18/0x134
[ 4.377930] Caller[00000000004060e8]: ret_from_fork+0x1c/0x2c
[ 4.378140] Caller[0000000000000000]: 0x0
[ 4.378309] Instruction DUMP:
[ 4.378339] 80a22000
[ 4.378556] 12400006
[ 4.378654] b0102001
[ 4.378746] <c2076658>
[ 4.378838] b0102000
[ 4.378930] 80a04019
[ 4.379022] b1653001
[ 4.379115] 81cfe008
[ 4.379507] 913a2000
[ 4.379617]
[ 4.380504] Kernel panic - not syncing: Attempted to kill init!
exitcode=0x00000009
Reverting it fixes the problem. Bisect log attached.
The reason is that dma_supported() calls dma_4u_supported(), which
expects that dev->archdata.iommu has been initialized. However,
this is not the case for the virtio device. Result is a null pointer
dereference in dma_4u_supported().
static int dma_4u_supported(struct device *dev, u64 device_mask)
{
struct iommu *iommu = dev->archdata.iommu;
if (ali_sound_dma_hack(dev, device_mask))
return 1;
if (device_mask < iommu->dma_addr_mask)
^^^^^^^^^^^^^^^^^^^^ Crash location
return 0;
return 1;
}
sparc64 does not support direct dma?
The virtio is a virtul device based on pci.
Do you know how we should adapt to sparc64?
It isn't exactly common or typical to set dev->dma_mask in driver probe
functions, as your code does, and much less so to do it unconditionally.
I don't know why the virtio driver is different to warrant setting it
there, so I can not answer your question.
Guenter
_______________________________________________
Virtualization mailing list
Virtualization@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/virtualization