page fault panic in device_get_softc/acpi_pcib_route_interrupt
Nate Lawson
nate at root.org
Thu Jan 6 13:28:43 PST 2005
Pawel Worach wrote:
> John Baldwin wrote:
>>
>> Ok, that might be it. I'll work up a patch to use the relative roots
>> instead. In fact, the patch is very simple. It already used relative
>> lookups when force-attaching the link devices during attach. Pawel,
>> the change is this:
>>
>> --- //depot/vendor/freebsd/src/sys/dev/acpica/acpi_pcib.c
>> 2004/12/27 05:40:30
>> +++ //depot/user/jhb/acpipci/dev/acpica/acpi_pcib.c 2005/01/06
>> 18:40:54
>> @@ -249,7 +249,8 @@
>> /*
>> * We have to find the source device (PCI interrupt link device).
>> */
>> - if (ACPI_FAILURE(AcpiGetHandle(ACPI_ROOT_OBJECT, prt->Source,
>> &lnkdev))) {
>> + if (ACPI_FAILURE(AcpiGetHandle(acpi_get_handle(pcib), prt->Source,
>> + &lnkdev))) {
>> device_printf(pcib, "couldn't find PCI interrupt link device %s\n",
>> prt->Source);
>> goto out;
Yes, I think that's more correct even if it doesn't fix this exact
issue. Most Source references are absolute (\_SB.LNKA) but if it's
relative, the right root to use for the search is the parent of _PRT,
which is the pcib device.
> CURRENT from 16:00 UTC and the patch above seems to result in the same
> thing :(
Sorry to hear that, let's take a look at it.
> Copyright (c) 1992-2005 The FreeBSD Project.
> Copyright (c) 1979, 1980, 1983, 1986, 1988, 1989, 1991, 1992, 1993, 1994
> The Regents of the University of California. All rights reserved.
> FreeBSD 6.0-CURRENT #0: Thu Jan 6 20:31:16 CET 2005
> root at zero:/usr/obj/usr/src/sys/ZERO
> ...
> pcib0: matched entry for 0.15.INTA (src \LPUS:0)
>
>
> Fatal trap 12: page fault while in kernel mode
> cpuid = 0; apic id = 00
> fault virtual address = 0x48
> fault code = supervisor read, page not present
> instruction pointer = 0x8:0xc051f487
> stack pointer = 0x10:0xc0820958
> frame pointer = 0x10:0xc082096c
> code segment = base 0x0, limit 0xfffff, type 0x1b
> = DPL 0, pres 1, def32 1, gran 1
> processor eflags = interrupt enabled, resume, IOPL = 0
> current process = 0 (swapper)
> [thread pid 0 tid 0 ]
> Stopped at device_get_softc+0x7: movl 0x48(%eax),%eax
> db> tr
> Tracing pid 0 tid 0 td 0xc06ef960
> device_get_softc(c07de4a0,c07d99cd,355,c1e841c0,c1e841c0) at
> device_get_softc+0x7
> acpi_pci_link_route_interrupt(0,0,c0820a24,c0820a2c,41) at
> acpi_pci_link_route_interrupt+0x3a
> acpi_pcib_route_interrupt(c1f16d00,c1f8b780,1,c1f7e1f4,1) at
> acpi_pcib_route_interrupt+0x3a1
> acpi_pcib_acpi_route_interrupt(c1f16d00,c1f8b780,1,c06c7f10,c1f8b808) at
> acpi_pcib_acpi_route_interrupt+0x2f
> pci_assign_interrupt_method(c1f16a00,c1f8b780,f,2,24) at
> pci_assign_interrupt_method+0x71
> pci_add_child(c1f16a00,c1f8b800,f,2,80) at pci_add_child+0x207
> pci_add_children(c1f16a00,0,80,c0820b54,c052188f) at pci_add_children+0x123
> acpi_pci_attach(c1f16a00,c1f4484c,c06c14ec,c06aa680,0) at
> acpi_pci_attach+0x86
> device_attach(c1f16a00,c1ed5d80,c0820bdc,c07c538c,c1f16d00) at
> device_attach+0x2c9
> bus_generic_attach(c1f16d00,c07d92a7,0,c0820bcc,0) at
> bus_generic_attach+0x18
> acpi_pcib_attach(c1f16d00,c1f7e1f4,0,c0820c04,c07bff97) at
> acpi_pcib_attach+0xec
> acpi_pcib_acpi_attach(c1f16d00,c1f4384c,c06c14ec,c06aa680,0) at
> acpi_pcib_acpi_attach+0xf9
> device_attach(c1f16d00,2f,c0820cbc,c07c27c4,c1ed5d80) at
> device_attach+0x2c9
> bus_generic_attach(c1ed5d80,2e,2f,c1f7dc28,2e) at bus_generic_attach+0x18
> acpi_attach(c1ed5d80,c1f4604c,c06c14ec,c06aa680,0) at acpi_attach+0x7b4
> device_attach(c1ed5d80,c1f15000,c0820d18,c0679ffa,c1f15000) at
> device_attach+0x2c9
> bus_generic_attach(c1f15000,c1f1504c,c0820d54,c0520839,c1f15000) at
> bus_generic_attach+0x18
John, perhaps this is the problem. pci_add_child is attempting to route
interrupts. However, if the link device is under the PCI bus device, it
may not have a handle/device association yet.
acpi_pci_attach():
/* Add pci children and route interrupts */
pci_add_children(dev, busno, sizeof(struct acpi_pci_devinfo));
/* Whoops, haven't assigned handles for link devices
* under "dev" yet! */
AcpiWalkNamespace(ACPI_TYPE_DEVICE, acpi_get_handle(dev), 1,
acpi_pci_save_handle, dev, NULL);
Pawel, can you send a link to your asl? acpidump -t -d > pawel.asl
I expect we'll see something like this:
Device (PCI0)
Method (_PRT)
[reference to LNK0]
Device (LNK0)
Device (USB0)
My question is why is pci_add_child() routing interrupts? That should
be done in the attach method for the PCI bus, before probing/attaching
children, not when the child devices are being added. I think we'll
have to split this into two separate steps: pci_add_children(), set up
device/handle associations, pci_init_children(). The last function
would do the irq routing.
--
Nate
More information about the freebsd-current
mailing list