Date: Tue, 11 Oct 2011 08:39:20 -0600 (MDT) From: Ian Lepore <freebsd@damnhippie.dyndns.org> To: FreeBSD-gnats-submit@FreeBSD.org Subject: arm/161492: [patch] ARM thread-data/RAS page is not properly initialized Message-ID: <201110111439.p9BEdKIb052251@revolution.hippie.lan> Resent-Message-ID: <201110111500.p9BF0HA7016979@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 161492 >Category: arm >Synopsis: [patch] ARM thread-data/RAS page is not properly initialized >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-arm >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Oct 11 15:00:16 UTC 2011 >Closed-Date: >Last-Modified: >Originator: Ian Lepore <freebsd@damnhippie.dyndns.org> >Release: FreeBSD 8.2-RC3 arm >Organization: none >Environment: FreeBSD tflex 8.2-STABLE FreeBSD 8.2-STABLE #29: Tue Oct 11 13:32:35 UTC 2011 root@revolution.hippie.lan:/usr/obj/arm/usr/src/sys/TFLEX arm >Description: The global page that holds ARM_TP_ADDRESS and the RAS start/end addresses is allocated using the VM_ALLOC_ZERO flag, but that flag only indicates a preference for a pre-zeroed page if one is available, it doesn't guarantee the returned page has been zeroed. It appears that often (perhaps always?) there are no pre-zeroed pages available early in startup, and the page will contain random values. Some combinations of these random values may be misinterpreted by the RAS code in PUSHFRAMEINSVC, causing it to use the garbage value from RAS_START when returning from the first trap/interrupt, typically causing a panic due to supervisor-mode access fault. >How-To-Repeat: Naturally a failure scenario based on inopportune values of random data is pretty rare and hard to repeat. >Fix: This patch zeroes the page if necessary after allocating it, and also initializes ARM_RAS_END to 0xffffffff, since that's one of the preconditions of the RAS scheme when no atomic sequence is running. --- machdep.c.diff begins here --- --- src/sys/arm/arm/machdep.c.orig Tue Jun 21 12:50:26 2011 -0600 +++ src/sys/arm/arm/machdep.c Tue Oct 11 08:10:43 2011 -0600 @@ -308,10 +308,14 @@ cpu_startup(void *dummy) #ifdef ARM_CACHE_LOCK_ENABLE pmap_kenter_user(ARM_TP_ADDRESS, ARM_TP_ADDRESS); arm_lock_cache_line(ARM_TP_ADDRESS); + bzero((void*)ARM_TP_ADDRESS, PAGE_SIZE); #else m = vm_page_alloc(NULL, 0, VM_ALLOC_NOOBJ | VM_ALLOC_ZERO); pmap_kenter_user(ARM_TP_ADDRESS, VM_PAGE_TO_PHYS(m)); + if ((m->flags & PG_ZERO) == 0) + bzero((void*)ARM_TP_ADDRESS, PAGE_SIZE); #endif + *(uint32_t *)ARM_RAS_END = 0xffffffff; } SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); --- arm.machdep.c.diff ends here --- >Release-Note: >Audit-Trail: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201110111439.p9BEdKIb052251>