From: Volodymyr Babchuk <Volodymyr_Babchuk@epam.com>
To: "linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>
Subject: Write to srvio_numvfs triggers kernel panic
Date: Wed, 4 May 2022 19:56:01 +0000 [thread overview]
Message-ID: <87a6bxm5vm.fsf@epam.com> (raw)
Hello,
I have encountered issue when PCI code tries to use both fields in
union {
struct pci_sriov *sriov; /* PF: SR-IOV info */
struct pci_dev *physfn; /* VF: related PF */
};
(which are part of struct pci_dev) at the same time.
Symptoms are following:
# echo 1 > /sys/bus/pci/devices/0000:01:00.0/sriov_numvfs
pci 0000:01:00.2: reg 0x20c: [mem 0x30018000-0x3001ffff 64bit]
pci 0000:01:00.2: VF(n) BAR0 space: [mem 0x30018000-0x30117fff 64bit] (contains BAR0 for 32 VFs)
Unable to handle kernel paging request at virtual address 0001000200000010
Mem abort info:
ESR = 0x96000004
EC = 0x25: DABT (current EL), IL = 32 bits
SET = 0, FnV = 0
EA = 0, S1PTW = 0
Data abort info:
ISV = 0, ISS = 0x00000004
CM = 0, WnR = 0
[0001000200000010] address between user and kernel address ranges
Internal error: Oops: 96000004 [#1] PREEMPT SMP
Modules linked in: xt_MASQUERADE iptable_nat nf_nat nf_conntrack nf_defrag_ipv6
nf_defrag_ipv4 libcrc32c iptable_filter crct10dif_ce nvme nvme_core at24
pci_endpoint_test bridge pdrv_genirq ip_tables x_tables ipv6
CPU: 3 PID: 287 Comm: sh Not tainted 5.10.41-lorc+ #233
Hardware name: XENVM-4.17 (DT)
pstate: 60400005 (nZCv daif +PAN -UAO -TCO BTYPE=--)
pc : pcie_aspm_get_link+0x90/0xcc
lr : pcie_aspm_get_link+0x8c/0xcc
sp : ffff8000130d39c0
x29: ffff8000130d39c0 x28: 00000000000001a4
x27: 00000000ffffee4b x26: ffff80001164f560
x25: 0000000000000000 x24: 0000000000000000
x23: ffff80001164f660 x22: 0000000000000000
x23: ffff80001164f660 x22: 0000000000000000
x21: ffff000003f08000 x20: ffff800010db37d8
x19: ffff000004b8e780 x18: ffffffffffffffff
x17: 0000000000000000 x16: 00000000deadbeef
x15: ffff8000930d36c7 x14: 0000000000000006
x13: ffff8000115c2710 x12: 000000000000081c
x11: 00000000000002b4 x10: ffff8000115c2710
x9 : ffff8000115c2710 x8 : 00000000ffffefff
x7 : ffff80001161a710 x6 : ffff80001161a710
x5 : ffff00003fdad900 x4 : 0000000000000000
x3 : 0000000000000000 x2 : 0000000000000000
x1 : ffff000003c51c80 x0 : 0001000200000000
Call trace:
pcie_aspm_get_link+0x90/0xcc
aspm_ctrl_attrs_are_visible+0x30/0xc0
internal_create_group+0xd0/0x3cc
internal_create_groups.part.0+0x4c/0xc0
sysfs_create_groups+0x20/0x34
device_add+0x2b4/0x760
pci_device_add+0x814/0x854
pci_iov_add_virtfn+0x240/0x2f0
sriov_enable+0x1f8/0x474
pci_sriov_configure_simple+0x38/0x90
sriov_numvfs_store+0xa4/0x1a0
dev_attr_store+0x1c/0x30
sysfs_kf_write+0x48/0x60
kernfs_fop_write_iter+0x118/0x1ac
new_sync_write+0xe8/0x184
vfs_write+0x23c/0x2a0
ksys_write+0x68/0xf4
__arm64_sys_write+0x20/0x2c
el0_svc_common.constprop.0+0x78/0x1a0
do_el0_svc+0x28/0x94
el0_svc+0x14/0x20
el0_sync_handler+0xa4/0x130
el0_sync+0x180/0x1c0
Code: d0002120 9133e000 97ffef8e f9400a60 (f9400813)
Debugging showed the following:
pci_iov_add_virtfn() allocates new struct pci_dev:
virtfn = pci_alloc_dev(bus);
and sets physfn:
virtfn->is_virtfn = 1;
virtfn->physfn = pci_dev_get(dev);
then we will get into sriov_init() via the following call path:
pci_device_add(virtfn, virtfn->bus);
pci_init_capabilities(dev);
pci_iov_init(dev);
sriov_init(dev, pos);
sriov_init() overwrites value in the union:
dev->sriov = iov; <<<<<---- There
dev->is_physfn = 1;
Next, we will get into function that causes panic:
pci_device_add(virtfn, virtfn->bus);
device_add(&dev->dev)
sysfs_create_groups()
internal_create_group()
aspm_ctrl_attrs_are_visible()
pcie_aspm_get_link()
pci_upstream_bridge()
pci_physfn()
which is
static inline struct pci_dev *pci_physfn(struct pci_dev *dev)
{
#ifdef CONFIG_PCI_IOV
if (dev->is_virtfn)
dev = dev->physfn;
#endif
return dev;
}
as is_virtfn == 1 and dev->physfn was overwritten via write to
dev->sriov, pci_physfn() will return pointer to struct pci_sriov
allocated by sriov_init(). And then pci_upstream_bridge() will
cause panic by acessing it as if it were pointer to struct pci_dev
I encountered this issue on ARM64, Linux 5.10.41. Tried to test
on master branch, but it is quite difficult to rebase platform
code on the master. But I compared all relevant parts of PCI code
and didn't found any differences.
Looks like I am missing following, because how SR-IOV can be so broken?
But what exactly?
--
Volodymyr Babchuk at EPAM
next reply other threads:[~2022-05-04 21:27 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-05-04 19:56 Volodymyr Babchuk [this message]
2022-05-06 20:17 ` Write to srvio_numvfs triggers kernel panic Bjorn Helgaas
2022-05-07 1:34 ` Jason Gunthorpe
2022-05-07 10:25 ` Volodymyr Babchuk
2022-05-08 11:19 ` Leon Romanovsky
2022-05-09 18:22 ` Keith Busch
2022-05-07 10:22 ` Volodymyr Babchuk
2022-05-07 15:41 ` Bjorn Helgaas
2022-05-08 11:07 ` Volodymyr Babchuk
2022-05-09 16:49 ` Bjorn Helgaas
2022-05-09 16:58 ` Alex Williamson
2022-05-10 6:39 ` Christoph Hellwig
2022-05-10 17:37 ` Bjorn Helgaas
2022-05-12 7:18 ` Volodymyr Babchuk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87a6bxm5vm.fsf@epam.com \
--to=volodymyr_babchuk@epam.com \
--cc=linux-pci@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.