[Crash-utility] Re: [Patch] Fix dev -p command for systems withvirtual devices

Dave Anderson anderson at redhat.com
Fri Dec 22 19:20:55 UTC 2006


Dave Anderson wrote:

> Rachita Kothiyal wrote:
>
> > Hi Dave
> >
> > Running 'dev -p' command on PowerPC systems with virtual devices (ie
> > no real PCI devices) fails with the following message:
> >
> > dev: invalid kernel virtual address: 98  type: "pci bus number"
> >
> > It should instead report that there are no _real_ PCI devices to list.
> > The following patch addresses this issue. Currently it just prints a
> > message letting the user know of the absence of pci devices, but it
> > might be a good idea to list down the virtual devices present in the
> > system in such cases. I am working on a patch for that too, probably
> > will discuss that on another thread.
> >
> > Please provide your comments/suggestions.
> >
> > Thanks
> > Rachita
>
> Hi Rachita,
>
> Yep -- in fact I see that the same thing happens on xen kernels
> as well.  I'll test your patch out on a few other architectures, and
> if all goes well, I'll queue it for the next release.
>
> Thanks again,
>   Dave
>
> >
> >
> >  On PowerPC machines configured with virtual devices(VIO) it is possible
> >  that there are no _real_ PCI devices. Hence it is reasonable that 'dev -p'
> >  would not list anything. This patch identifies such cases and displays a
> >  message appropriately.
> >
> > Signed-off-by: Rachita Kothiyal <rachita at in.ibm.com>
> > ---
> >
> >  dev.c |   30 +++++++++++++++++++++++++++---
> >  1 files changed, 27 insertions(+), 3 deletions(-)
> >
> > diff -puN dev.c~fix-vio-pci-device dev.c
> > --- crash-4.0-3.9/dev.c~fix-vio-pci-device      2006-12-22 13:32:02.737262096 +0530
> > +++ crash-4.0-3.9-rachita/dev.c 2006-12-22 13:48:44.984897296 +0530
> > @@ -1955,13 +1955,11 @@ do_pci(void)
> >         unsigned int      class;
> >         unsigned short    device, vendor;
> >         unsigned char     busno;
> > -       ulong             *devlist, bus, devfn, tmp;
> > +       ulong             *devlist, bus, devfn, tmp, prev, next;
> >         char              buf1[BUFSIZE];
> >         char              buf2[BUFSIZE];
> >         char              buf3[BUFSIZE];
> >
> > -       fprintf(fp, "%s BU:SL.FN CLASS: VENDOR-DEVICE\n",
> > -               mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "PCI_DEV"));
> >
> >         BZERO(&pcilist_data, sizeof(struct list_data));
> >
> > @@ -1972,11 +1970,34 @@ do_pci(void)
> >                          FAULT_ON_ERROR);
> >                  pcilist_data.end = symbol_value("pci_devices");
> >                  pcilist_data.list_head_offset = OFFSET(pci_dev_global_list);
> > +               readmem(symbol_value("pci_devices") + OFFSET(list_head_prev),
> > +                       KVADDR, &prev, sizeof(void *), "list head prev",
> > +                       FAULT_ON_ERROR);
> > +                /*
> > +                * Check if this system does not have any PCI devices.
> > +                * Possible on PowerPC machines with VIO configured.
> > +                */
> > +               if ((pcilist_data.start == pcilist_data.end) &&
> > +                  (prev == pcilist_data.end)) {
> > +                       fprintf(fp, "No PCI devices found on this system.\n");
> > +                       return;
> > +               }
> >
> >         } else {
> >                 get_symbol_data("pci_devices", sizeof(void *),
> >                                 &pcilist_data.start);
> >                 pcilist_data.member_offset = OFFSET(pci_dev_next);
> > +                /*
> > +                * Check if this system does not have any PCI devices.
> > +                * Possible on PowerPC machines with VIO configured.
> > +                */
> > +               readmem(pcilist_data.start + pcilist_data.member_offset,
> > +                       KVADDR, &next, sizeof(void *), "pci dev next",
> > +                       FAULT_ON_ERROR);
> > +               if (!next) {
> > +                       fprintf(fp, "No PCI devices found on this system.\n");
> > +                       return;
> > +               }
> >         }
> >
> >         hq_open();
> > @@ -1985,6 +2006,9 @@ do_pci(void)
> >         devcnt = retrieve_list(devlist, devcnt);
> >         hq_close();
> >
> > +       fprintf(fp, "%s BU:SL.FN CLASS: VENDOR-DEVICE\n",
> > +               mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "PCI_DEV"));
> > +
> >         for (i = 0; i < devcnt; i++) {
> >
> >                 /*
> > _
>

Hi Rachita,

Found a few other quirks -- kernels that don't have the "pci_device"
symbol at all, and another 2.6.7-era kernel compiled with gcc 3.4.1
that didn't have debuginfo data for the pci_dev structure.

Here's what I'm going with to cover all bases.

Thanks,
   Dave

-------------- next part --------------
Index: dev.c
===================================================================
RCS file: /nfs/projects/cvs/crash/dev.c,v
retrieving revision 1.13
diff -u -r1.13 dev.c
--- dev.c	23 Nov 2005 16:09:44 -0000	1.13
+++ dev.c	22 Dec 2006 18:48:25 -0000
@@ -1955,35 +1955,53 @@
 	unsigned int      class;
 	unsigned short    device, vendor;
 	unsigned char     busno;
-	ulong             *devlist, bus, devfn, tmp;
+	ulong             *devlist, bus, devfn, prev, next;
 	char 		  buf1[BUFSIZE];
 	char 		  buf2[BUFSIZE];
 	char 		  buf3[BUFSIZE];
 
-	fprintf(fp, "%s BU:SL.FN CLASS: VENDOR-DEVICE\n",
-		mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "PCI_DEV"));
+	if (!symbol_exists("pci_devices"))
+		error(FATAL, "no PCI devices found on this system.\n");
 
 	BZERO(&pcilist_data, sizeof(struct list_data));
 
 	if (VALID_MEMBER(pci_dev_global_list)) {
-                get_symbol_data("pci_devices", sizeof(void *), &tmp);
-                readmem(tmp + OFFSET(list_head_next), KVADDR,
-                        &pcilist_data.start, sizeof(void *), "pci devices",
-                        FAULT_ON_ERROR);
+                get_symbol_data("pci_devices", sizeof(void *), &pcilist_data.start);
                 pcilist_data.end = symbol_value("pci_devices");
                 pcilist_data.list_head_offset = OFFSET(pci_dev_global_list);
+		readmem(symbol_value("pci_devices") + OFFSET(list_head_prev),
+			KVADDR, &prev, sizeof(void *), "list head prev",
+			FAULT_ON_ERROR);
+                /*
+		 * Check if this system does not have any PCI devices.
+		 */
+		if ((pcilist_data.start == pcilist_data.end) &&
+ 		   (prev == pcilist_data.end))
+			error(FATAL, "no PCI devices found on this system.\n");
 
-	} else {
+	} else if (VALID_MEMBER(pci_dev_next)) {
 		get_symbol_data("pci_devices", sizeof(void *),
 				&pcilist_data.start);
 		pcilist_data.member_offset = OFFSET(pci_dev_next);
-	} 
+                /*
+		 * Check if this system does not have any PCI devices.
+		 */
+		readmem(pcilist_data.start + pcilist_data.member_offset,
+			KVADDR, &next, sizeof(void *), "pci dev next",
+			FAULT_ON_ERROR);
+		if (!next)
+			error(FATAL, "no PCI devices found on this system.\n");
+	} else 
+		option_not_supported('p');
 
 	hq_open();
 	devcnt = do_list(&pcilist_data);
 	devlist = (ulong *)GETBUF(devcnt * sizeof(ulong));
 	devcnt = retrieve_list(devlist, devcnt);
 	hq_close();
+
+	fprintf(fp, "%s BU:SL.FN CLASS: VENDOR-DEVICE\n",
+		mkstring(buf1, VADDR_PRLEN, CENTER|LJUST, "PCI_DEV"));
 
 	for (i = 0; i < devcnt; i++) {
 


More information about the Crash-utility mailing list