Janusz Dziedzic | 2 Nov 2007 16:24
Picon

evbarm, new board, start_init function USRSTACK problem

Hello,

Two weeks ago I've started with my board and NetBSD.

Now I have problem with start_init function. I don't know that is a UVM problem or I don't understand everything correctly.



    /*
     * Need just enough stack to hold the faked-up "execve()" arguments.
     */
    addr = (vaddr_t)STACK_ALLOC(USRSTACK, PAGE_SIZE);    // is 0xBFFFF000
   
    /* should this add maping ( 0xBFFFF000 <---> Physical_Memory)  to pagetable? */
    if (uvm_map(&p->p_vmspace->vm_map, &addr, PAGE_SIZE,
                    NULL, UVM_UNKNOWN_OFFSET, 0,
                    UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_COPY,
            UVM_ADV_NORMAL,
                    UVM_FLAG_FIXED|UVM_FLAG_OVERLAY|UVM_FLAG_COPYONW)) != 0)
        panic("init: couldn't allocate argument space");
    p->p_vmspace->vm_maxsaddr = (void *)STACK_MAX(addr, PAGE_SIZE);

    ipx = 0;

   ....
   /* here I have data abort, because 0xBFFFFFFD is not mapped in MMU page table */
   (void)copyout((void *)flags, arg1, i);

  So should I map this address in machdep file or where can I find problem?


Additional information:
http://valhalla.bofh.pl/~l4mer/userstack.PNG           // from Lauterbach - useful
http://valhalla.bofh.pl/~l4mer/beast.txt                   // console output
http://valhalla.bofh.pl/~l4mer/beast_machdep.c      // machdep fiele
http://valhalla.bofh.pl/~l4mer/beast_start.S            // startup file


KERNEL_BASE_PHYS=0x00200000
KERNEL_BASE_VIRT=0xc0200000


BR
--
Janusz

Todd Poynor | 7 Nov 2007 01:09

UVM permissions check for ARM_SYNC_ICACHE syscall

The ARM_SYNC_ICACHE syscall will invalidate any I cache (and clean and
invalidate any D cache) ranges requested by userspace, including
kernel virtual addresses.  It may be possible for a rogue program to
cause some mischief by invalidating modifications made by the kernel.

The suggested patch below fails the arm_sync_icache() with EINVAL if
the address range is not fully mapped writeable to the process.  Any
suggestions appreciated. -- Todd

Index: netbsd/src/sys/arch/arm/arm32/sys_machdep.c
===================================================================
--- netbsd.orig/src/sys/arch/arm/arm32/sys_machdep.c
+++ netbsd/src/sys/arch/arm/arm32/sys_machdep.c
 <at>  <at>  -66,11 +66,26  <at>  <at>  arm32_sync_icache(p, args, retval)
  	register_t *retval;
  {
  	struct arm_sync_icache_args ua;
+	struct vmspace *vm;
  	int error;
+	int rv;

  	if ((error = copyin(args, &ua, sizeof(ua))) != 0)
  		return (error);

+	if ((error = proc_vmspace_getref(p, &vm)) != 0)
+		return (error);
+
+	vm_map_lock(&vm->vm_map);
+	rv = uvm_map_checkprot(&vm->vm_map, ua.addr, ua.addr + ua.len,
+			       VM_PROT_WRITE);
+	vm_map_unlock(&vm->vm_map);
+	uvmspace_free(vm);
+
+	if (rv == 0) {
+		return EINVAL;
+	}
+
  	cpu_icache_sync_range(ua.addr, ua.len);

  	*retval = 0;

Todd Poynor | 8 Nov 2007 01:58

ARM1136 panic on arm32_sync_icache()

A program containing the following fragment can crash an ARM1136 system 
with a Data Abort in the kernel:

	struct arm_sync_icache_args a;

	a.addr = malloc(PAGE_SIZE * 3);
	a.len = PAGE_SIZE * 3;
	sysarch(ARM_SYNC_ICACHE, &a);

The ARMv6 Virtually Indexed Physically Tagged cache maintenance system 
control coprocessor instructions that invalidate lines based on Modified 
Virtual Addresses throw Data Abort exceptions for virtual addresses not 
mapped in the PTE.  On previous VIVT cache revisions of the 
architecture, a PTE lookup was not necessary, and so callers that synced 
cache lines in pages not actually written did not incur this problem.

One workaround is to have the syscall version invalidate the entire 
cache (another popular UNIX variant does this a lot due to ARM1136 
errata).  Or invalidate based on set/way (which at 4KB ways means 
invalidating a whole lotta cache).  Or figure out the cause of the 
kernel Data Abort and either send the process a SIGSEGV or skip faulting 
instructions (or fix up address range and restart for MCRR range 
instructions).

I'll send a patch for one of those options if nobody raises any 
objections or alternate suggestions.  Thanks,

--

-- 
Todd

Matt Thomas | 8 Nov 2007 04:49

Re: ARM1136 panic on arm32_sync_icache()


On Nov 7, 2007, at 4:58 PM, Todd Poynor wrote:

> A program containing the following fragment can crash an ARM1136  
> system with a Data Abort in the kernel:
>
> 	struct arm_sync_icache_args a;
>
> 	a.addr = malloc(PAGE_SIZE * 3);
> 	a.len = PAGE_SIZE * 3;
> 	sysarch(ARM_SYNC_ICACHE, &a);
>
> The ARMv6 Virtually Indexed Physically Tagged cache maintenance  
> system control coprocessor instructions that invalidate lines based  
> on Modified Virtual Addresses throw Data Abort exceptions for  
> virtual addresses not mapped in the PTE.  On previous VIVT cache  
> revisions of the architecture, a PTE lookup was not necessary, and  
> so callers that synced cache lines in pages not actually written  
> did not incur this problem.
>
> One workaround is to have the syscall version invalidate the entire  
> cache (another popular UNIX variant does this a lot due to ARM1136  
> errata).  Or invalidate based on set/way (which at 4KB ways means  
> invalidating a whole lotta cache).  Or figure out the cause of the  
> kernel Data Abort and either send the process a SIGSEGV or skip  
> faulting instructions (or fix up address range and restart for MCRR  
> range instructions).
>
> I'll send a patch for one of those options if nobody raises any  
> objections or alternate suggestions.  Thanks,

I prefer the of onfault since this error shouldn't normally happen.

Todd Poynor | 9 Nov 2007 02:22

Re: ARM1136 panic on arm32_sync_icache()

Matt Thomas wrote:
> On Nov 7, 2007, at 4:58 PM, Todd Poynor wrote:
...
>> The ARMv6 Virtually Indexed Physically Tagged cache maintenance system 
>> control coprocessor instructions that invalidate lines based on 
>> Modified Virtual Addresses throw Data Abort exceptions for virtual 
>> addresses not mapped in the PTE. ...
> 
> I prefer the of onfault since this error shouldn't normally happen.

Here's a patch against -current (but only tested on -4.0rc3) that adds a 
"safe" wrapper around cpu_icache_sync_range via pcb_onfault and returns 
zero or EFAULT to the caller.  Some notes on questionable stuff I 
wrestled with follow.

The wrapper is added to arch/arm/arm32/locore.S as a handy place to put 
it within the arm32/ family.  This might not be the best place for a 
cpufunc thing, but it needs some assym.h symbols only generated for 
arm32.  The protototype is added to arch/arm/include/cpufunc.h, although 
it is arm32-only.  (It would be nice to have fault catchers in C and do 
this in arch/arm/arm32/sys_machdep.c with a setjmp-style call.)

The wrapper knows the called routine doesn't mess with sp or r4.

--

-- 
Todd

Matt Thomas | 9 Nov 2007 02:53

Re: ARM1136 panic on arm32_sync_icache()


On Nov 8, 2007, at 5:22 PM, Todd Poynor wrote:

> Matt Thomas wrote:
>> On Nov 7, 2007, at 4:58 PM, Todd Poynor wrote:
> ...
>>> The ARMv6 Virtually Indexed Physically Tagged cache maintenance  
>>> system control coprocessor instructions that invalidate lines  
>>> based on Modified Virtual Addresses throw Data Abort exceptions  
>>> for virtual addresses not mapped in the PTE. ...
>> I prefer the of onfault since this error shouldn't normally happen.
>
> Here's a patch against -current (but only tested on -4.0rc3) that  
> adds a "safe" wrapper around cpu_icache_sync_range via pcb_onfault  
> and returns zero or EFAULT to the caller.  Some notes on  
> questionable stuff I wrestled with follow.
>
> The wrapper is added to arch/arm/arm32/locore.S as a handy place to  
> put it within the arm32/ family.  This might not be the best place  
> for a cpufunc thing, but it needs some assym.h symbols only  
> generated for arm32.  The protototype is added to arch/arm/include/ 
> cpufunc.h, although it is arm32-only.  (It would be nice to have  
> fault catchers in C and do this in arch/arm/arm32/sys_machdep.c  
> with a setjmp-style call.)
>
> The wrapper knows the called routine doesn't mess with sp or r4.
>
>
> -- 
> Todd
>
> Index: netbsd-current-11082007/src/sys/arch/arm/arm32/genassym.cf
> ===================================================================
> --- netbsd-current-11082007.orig/src/sys/arch/arm/arm32/genassym.cf
> +++ netbsd-current-11082007/src/sys/arch/arm/arm32/genassym.cf
>  <at>  <at>  -130,6 +130,7  <at>  <at>  define	TRAPFRAMESIZE		sizeof(struct trap
>
>  define	CF_IDCACHE_WBINV_ALL	offsetof(struct cpu_functions,  
> cf_idcache_wbinv_all)
>  define	CF_DCACHE_WB_RANGE	offsetof(struct cpu_functions,  
> cf_dcache_wb_range)
> +define  CF_ICACHE_SYNC_RANGE    offsetof(struct cpu_functions,  
> cf_icache_sync_range)
>  define	CF_TLB_FLUSHID_SE	offsetof(struct cpu_functions,  
> cf_tlb_flushID_SE)
>  define	CF_CONTEXT_SWITCH	offsetof(struct cpu_functions,  
> cf_context_switch)
>  define	CF_SLEEP		offsetof(struct cpu_functions, cf_sleep)
> Index: netbsd-current-11082007/src/sys/arch/arm/arm32/locore.S
> ===================================================================
> --- netbsd-current-11082007.orig/src/sys/arch/arm/arm32/locore.S
> +++ netbsd-current-11082007/src/sys/arch/arm/arm32/locore.S
>  <at>  <at>  -212,5 +212,39  <at>  <at>  _C_LABEL(esym):	.word	_C_LABEL(end)
>  ENTRY_NP(abort)
>  	b	_C_LABEL(abort)
>
> +#ifdef MULTIPROCESSOR
> +.Lcpu_info:
> +        .word   _C_LABEL(cpu_info)
> +#else
> +.Lcurpcb:
> +        .word   _C_LABEL(curpcb)
> +#endif
> +
> +ENTRY(cpufunc_safe_icache_sync_range)
> +	stmfd	sp!, {lr}
	stmfd  sp!, {r4, lr}
> +#ifdef MULTIPROCESSOR
> +	/* XXX Probably not appropriate for non-Hydra SMPs */
> +	stmfd   sp!, {r0-r1}
> +	bl      _C_LABEL(cpu_number)
> +	ldr     r4, .Lcpu_info
> +	ldr     r4, [r4, r0, lsl #2]
> +	ldr     r4, [r4, #CI_CURPCB]
> +	ldmfd   sp!, {r0-r1}
> +#else
> +	ldr     r4, .Lcurpcb
> +	ldr     r4, [r4]
> +#endif
> +	adr     r3, .Licache_sync_fault
> +	str     r3, [r4, #PCB_ONFAULT]
> +	ldr	r2, .Lcpufuncs
> +	mov	lr, pc

For a call, the stack should be 8-byte aligned.

> +	ldr	pc, [r2, #CF_ICACHE_SYNC_RANGE]
> +	mov     r0, #0x00000000
	str r0, [r4, #PCB_ONFAULT]

> +	ldmfd	sp!, {pc}
	ldmfd sp!, {r4, pc}
> +
> +.Licache_sync_fault:
> +	mov     r1, #0x00000000
> +	str     r1, [r4, #PCB_ONFAULT]
> +	ldmfd	sp!, {pc}
	ldmfd sp!, {r4, pc}

I think these r1's should be r0.

>  /* End of locore.S */
> Index: netbsd-current-11082007/src/sys/arch/arm/arm32/sys_machdep.c
> ===================================================================
> --- netbsd-current-11082007.orig/src/sys/arch/arm/arm32/sys_machdep.c
> +++ netbsd-current-11082007/src/sys/arch/arm/arm32/sys_machdep.c
>  <at>  <at>  -70,10 +70,8  <at>  <at>  arm32_sync_icache(p, args, retval)
>  	if ((error = copyin(args, &ua, sizeof(ua))) != 0)
>  		return (error);
>
> -	cpu_icache_sync_range(ua.addr, ua.len);
> -
> -	*retval = 0;
> -	return(0);
> +	*retval = cpufunc_safe_icache_sync_range(ua.addr, ua.len);
> +	return(*retval);

retval should stay 0.  0 should be returned.
>  }
>
>  static int
> Index: netbsd-current-11082007/src/sys/arch/arm/include/cpufunc.h
> ===================================================================
> --- netbsd-current-11082007.orig/src/sys/arch/arm/include/cpufunc.h
> +++ netbsd-current-11082007/src/sys/arch/arm/include/cpufunc.h
>  <at>  <at>  -211,6 +211,7  <at>  <at>  u_int	cpufunc_control		(u_int, u_int);
>  void	cpufunc_domains		(u_int);
>  u_int	cpufunc_faultstatus	(void);
>  u_int	cpufunc_faultaddress	(void);
> +int	cpufunc_safe_icache_sync_range(vaddr_t, vsize_t);
>
>  #ifdef CPU_ARM2
>  u_int	arm2_id			(void);
>

Nick Hudson | 29 Nov 2007 11:52

Re: Test kernels

[cc: port-arm added. others deleted]

On Wednesday 28 November 2007 21:06:18 Andrew Doran wrote:
> On Mon, Nov 26, 2007 at 07:27:58PM +0000, Andrew Doran wrote:
> > I have test kernels for the following architectures. These are for
> > changes to interrupt handling, and I'll be merging them into -current
> > soon.
>
> Thanks to everyone who has helped so far. I have put another set of kernels
> at the URL below. Any takers?
>
> arm:	cats, iyonix, netwinder, shark
[non-arm stuff deleted]

cats works.

>
> 	http://www.hairylemon.org/~ad/netbsd/softint/
>
> Thanks,
> Andrew

Nick

Izumi Tsutsui | 29 Nov 2007 17:00
Picon
Gravatar

Re: Test kernels

ad <at> NetBSD.org wrote:

> Thanks to everyone who has helped so far. I have put another set of kernels
> at the URL below. Any takers?
> 
> arm:	cats, iyonix, netwinder, shark
> m68k:	hp300, luna68k, mac68k, mvme68k, news68k, next68k
 :
> 	http://www.hairylemon.org/~ad/netbsd/softint/

- shark.bz2 on FUNAI's DNARD works.
  (BTW it's better to put a.out kernel binary for shark)
- news68k.bz2 on NWS-1750 (68030) also works.
- hp300.bz2 on HP 9000/382 (68040) hangs during scsi probe:

---
 :
spc0 at dio0 scode 14 ipl 4: 98265A SCSI, 32-bit DMA, SCSI ID 7
scsibus0 at spc0: 8 targets, 8 luns per target
le0 at dio0 scode 21 ipl 5: address 08:00:09:18:d8:d2
le0: 8 receive buffers, 2 transmit buffers
WARNING: select code size unknown for id = 0x39 secid = 0x10
device id = 0x39 secid = 0x10 at dio0 scode 132 ipl 3 not configured
WARNING: select code size unknown for id = 0x39 secid = 0x10
device id = 0x39 secid = 0x10 at dio0 scode 133 ipl 3 not configured
nhpib3 at dio0 scode 134 ipl 3: 98624A HP-IB
hpibbus3 at nhpib3
nhpib4 at dio0 scode 135 ipl 3: 98624A HP-IB
hpibbus4 at nhpib4
interrupt levels: vm = 3
Kernelized RAIDframe activated
scsibus0: waiting 2 seconds for devices to settle...
sd0 at scsibus0 target 0 lun 0: <CONNER, CFP1080S, 4040> disk fixed

 [hangs here, sending break]

Stopped in pid 0.2 (system) at  netbsd:cpu_Debugger+0x6:        unlk    a6
db> tr
cpu_Debugger(0,5,2832b8,262e00,1ea9f2) + 6
comintr(1739800,2058,12c89c,2f45e00,2f2ffa8) + 562
intr_dispatch(74) + 52
intrhand(2f45e00) + a
lwp_trampoline() + e
db> 
---

where
>> sd0: 1030 MB, 3658 cyl, 6 head, 96 sec, 512 bytes/sect x 2110812 sectors
>> sd0: async, 8-bit transfers
these lines should appear.
"interrupt levels: vm = 3" means bad spl value?

---
Izumi Tsutsui


Gmane