Re: [RFC v2] MIPS: R5900: Workaround exception NOP execution bug (FLX05)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Maciej,

>  You could use /dev/mem to inspect exception handlers I suppose, but that 
> would be awkward.  It's mostly useful to access MMIO as I described in the 
> message you were kind enough to dig out from the depths of history.
> 
>  For exception handler examination I suggest using /proc/kcore instead, 
> which gives you access to kernel memory via an artificial ELF image, 
> making this a piece of cake.  Like this for example:
> 
> $ gdb -c /proc/kcore
> [...]
> #0  0x00000000 in ?? ()
> (gdb) set architecture mips:isa32r2
> The target architecture is assumed to be mips:isa32r2
> (gdb) x /32i 0x80000000
> 0x80000000:	lui	k1,0x8483
> 0x80000004:	mfc0	k0,c0_badvaddr
> 0x80000008:	lw	k1,-30560(k1)
> 0x8000000c:	srl	k0,k0,0x1a

This was an interesting exercise. I suspect GDB runs out of memory since

	# gdb -q -c /proc/kcore
	[New process 1]
	Segmentation fault

with

	# dmesg | tail -n3
	do_page_fault(): sending SIGSEGV to gdb for invalid read access from 000000a8
	epc = 00953910 in gdb[400000+6d1000]
	ra  = 009538b8 in gdb[400000+6d1000]

to me looks like GDB does a NULL pointer deference (the PS2 has 32 MiB of
RAM, of which 16 MiB is used for a ramdisk in my setup). GDB once could
handle core files remotely, but this capability is apparently now lost:

https://www.redhat.com/archives/crash-utility/2011-December/msg00019.html

One can get a little further by sharing /proc using v9fs to obtain:

	# mipsel-linux-gdb -q -c /mnt/kcore
	[New process 1]
	Core was generated by `ramdisk_size=16384 crtmode=pal1 video=ps2fb:pal,640x480-32 rd_start=0x8063c000'.
	#0  0x00000000 in ?? ()
	(gdb) set architecture mips:5900
	The target architecture is assumed to be mips:5900
	(gdb) x /32i 0x80000000
	   0x80000000:	Cannot access memory at address 0x80000000

In this case I'm wondering whether kcore contains proper ELF headers. What
is the output of readelf for your kcore? I have this:

	ELF Header:
	  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
	  Class:                             ELF32
	  Data:                              2's complement, little endian
	  Version:                           1 (current)
	  OS/ABI:                            UNIX - System V
	  ABI Version:                       0
	  Type:                              CORE (Core file)
	  Machine:                           MIPS R3000
	  Version:                           0x1
	  Entry point address:               0x0
	  Start of program headers:          52 (bytes into file)
	  Start of section headers:          0 (bytes into file)
	  Flags:                             0x0
	  Size of this header:               52 (bytes)
	  Size of program headers:           32 (bytes)
	  Number of program headers:         3
	  Size of section headers:           0 (bytes)
	  Number of section headers:         0
	  Section header string table index: 0
	
	There are no sections in this file.
	
	There are no sections to group in this file.
	
	Program Headers:
	  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
	  NOTE           0x000094 0x00000000 0x00000000 0x0074c 0x00000     0
	  LOAD           0x40001000 0xc0000000 0xffffffff 0x3f7fe000 0x3f7fe000 RWE 0x1000
	  LOAD           0x001000 0x80000000 0x00000000 0x2000000 0x2000000 RWE 0x1000
	
	There is no dynamic section in this file.
	
	There are no relocations in this file.
	
	The decoding of unwind sections for machine type MIPS R3000 is not currently supported.
	
	No version information found in this file.
	
	Displaying notes found at file offset 0x00000094 with length 0x0000074c:
	  Owner                 Data size	Description
	  CORE                 0x00000100	NT_PRSTATUS (prstatus structure)
	  CORE                 0x00000080	NT_PRPSINFO (prpsinfo structure)
	  CORE                 0x00000590	NT_TASKSTRUCT (task structure)

Returning to the more awkward /dev/mem device, the "bad address" error with
for example

	# xxd -s $(( 0x80000000 )) -l 256 /dev/mem
	xxd: /dev/mem: Bad address

is due to drivers/char/mem.c:valid_phys_addr_range which fails on

	return addr + count <= __pa(high_memory);

since

	0x80000000 + 16 <= 0x2000000

is false for CPHYSADDR(0x82000000) in arch/mips/include/asm/page.h:___pa:

	if (!IS_ENABLED(CONFIG_EVA)) {
		/*
		 * We're using the standard MIPS32 legacy memory map, ie.
		 * the address x is going to be in kseg0 or kseg1. We can
		 * handle either case by masking out the desired bits using
		 * CPHYSADDR.
		 */
		return CPHYSADDR(x);
	}

I noticed that /dev/mem is an exception to this comment just above ___pa:

	/*
	 * __pa()/__va() should be used only during mem init.
	 */

Finally, trying to mmap /dev/mem also fails, because

	/* Does it even fit in phys_addr_t? */                                  
	if (offset >> PAGE_SHIFT != vma->vm_pgoff) {                            

in drivers/char/mem.c:mmap_mem computes

	0x00080000 != 0xfff80000

resulting in -EINVAL. Is this the expected behaviour?

Fredrik


[Index of Archives]     [Linux MIPS Home]     [LKML Archive]     [Linux ARM Kernel]     [Linux ARM]     [Linux]     [Git]     [Yosemite News]     [Linux SCSI]     [Linux Hams]

  Powered by Linux