Re: page fault panic in device_get_softc/acpi_pcib_route_interrupt

From: Nate Lawson <nate_at_root.org>
Date: Thu, 06 Jan 2005 13:28:27 -0800
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
>> _at__at_ -249,7 +249,8 _at__at_
>>      /*
>>       * 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
Received on Thu Jan 06 2005 - 20:28:43 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:25 UTC