Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 20 Dec 2013 11:29:40 -0800
From:      Peter Wemm <peter@wemm.org>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        "freebsd-stable@freebsd.org" <freebsd-stable@freebsd.org>
Subject:   Re: 10.0 BETA 3 with redports kernel panic
Message-ID:  <CAGE5yCos5xGu7w24A6QSRDEPbfRNsjmHSvnpUE2Dvr1PUW2T8w@mail.gmail.com>
In-Reply-To: <20131220162254.GT59496@kib.kiev.ua>
References:  <20131217120019.GD59496@kib.kiev.ua> <1387285472.2372.2.camel@powernoodle.corp.yahoo.com> <1387473915.2494.0.camel@powernoodle.corp.yahoo.com> <20131219180833.GN59496@kib.kiev.ua> <1387479064.2494.5.camel@powernoodle.corp.yahoo.com> <CAGE5yCqhmRSM6oyw=FRZq59LniLsYaN%2BEog=GEPn3-ruuQk9EQ@mail.gmail.com> <CAGE5yCp9msPAy4HZ4TGRXws%2BxjLQ8iChbPQGj539qHJKhq2UJQ@mail.gmail.com> <1387492541.27693.5.camel@powernoodle.corp.yahoo.com> <20131220094835.GR59496@kib.kiev.ua> <1387554355.1491.4.camel@powernoodle.corp.yahoo.com> <20131220162254.GT59496@kib.kiev.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Dec 20, 2013 at 8:22 AM, Konstantin Belousov
<kostikbel@gmail.com> wrote:
> On Fri, Dec 20, 2013 at 07:45:55AM -0800, Sean Bruno wrote:
>> With this change to pmap.c we blow up in keg_alloc_slab() now:
>>
>> FreeBSD clang version 3.3 (tags/RELEASE_33/final 183502) 20130610
>> kernel trap 12 with interrupts disabled
>>
>>
>> Fatal trap 12: page fault while in kernel mode
>> cpuid = 0; apic id = 00
>> fault virtual address = 0x8
>> fault code            = supervisor write data, page not present
>> instruction pointer   = 0x20:0xffffffff80b2602a
>> stack pointer         = 0x28:0xffffffff81a90a50
>> frame pointer         = 0x28:0xffffffff81a90ac0
>> code segment          = base 0x0, limit 0xfffff, type 0x1b
>>                       = DPL 0, pres 1, long 1, def32 0, gran 1
>> processor eflags      = resume, IOPL = 0
>> current process               = 0 ()
>> [ thread pid 0 tid 0 ]
>> Stopped at      keg_alloc_slab+0x13a:   movq    %r13,0x8(%rax)
>> db> whe
>> Tracing pid 0 tid 0 td 0xffffffff81527500
>> keg_alloc_slab() at keg_alloc_slab+0x13a/frame 0xffffffff81a90ac0
>> keg_fetch_slab() at keg_fetch_slab+0x152/frame 0xffffffff81a90b10
>> zone_fetch_slab() at zone_fetch_slab+0x7e/frame 0xffffffff81a90b50
>> zone_import() at zone_import+0x3c/frame 0xffffffff81a90b90
>> uma_zalloc_arg() at uma_zalloc_arg+0x33e/frame 0xffffffff81a90c10
>> malloc() at malloc+0x6a/frame 0xffffffff81a90c60
>> init_dynamic_kenv() at init_dynamic_kenv+0x8d/frame 0xffffffff81a90c90
>> mi_startup() at mi_startup+0x118/frame 0xffffffff81a90cb0
>> btext() at btext+0x2c
>> db> bt
>> Tracing pid 0 tid 0 td 0xffffffff81527500
>> keg_alloc_slab() at keg_alloc_slab+0x13a/frame 0xffffffff81a90ac0
>> keg_fetch_slab() at keg_fetch_slab+0x152/frame 0xffffffff81a90b10
>> zone_fetch_slab() at zone_fetch_slab+0x7e/frame 0xffffffff81a90b50
>> zone_import() at zone_import+0x3c/frame 0xffffffff81a90b90
>> uma_zalloc_arg() at uma_zalloc_arg+0x33e/frame 0xffffffff81a90c10
>> malloc() at malloc+0x6a/frame 0xffffffff81a90c60
>> init_dynamic_kenv() at init_dynamic_kenv+0x8d/frame 0xffffffff81a90c90
>> mi_startup() at mi_startup+0x118/frame 0xffffffff81a90cb0
>> btext() at btext+0x2c
>>
>
> This could be related, indeed.
>
> Lets limit the impact to the /dev/{,k}mem only.  Please try this.
>
> diff --git a/sys/amd64/amd64/mem.c b/sys/amd64/amd64/mem.c
> index abbbb21..2a9b7c1 100644
> --- a/sys/amd64/amd64/mem.c
> +++ b/sys/amd64/amd64/mem.c
> @@ -98,7 +98,11 @@ memrw(struct cdev *dev, struct uio *uio, int flags)
>  kmemphys:
>                         o = v & PAGE_MASK;
>                         c = min(uio->uio_resid, (u_int)(PAGE_SIZE - o));
> -                       error = uiomove((void *)PHYS_TO_DMAP(v), (int)c, uio);
> +                       v = PHYS_TO_DMAP(v);
> +                       if (v < DMAP_MIN_ADDRESS || v >= dmaplimit ||
> +                           pmap_kextract(v) == 0)
> +                               return (EFAULT);
> +                       error = uiomove((void *)v, (int)c, uio);
>                         continue;
>                 }
>                 else if (dev2unit(dev) == CDEV_MINOR_KMEM) {
> diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c
> index 014020b..13404b0 100644
> --- a/sys/amd64/amd64/pmap.c
> +++ b/sys/amd64/amd64/pmap.c
> @@ -321,7 +321,7 @@ SYSCTL_INT(_machdep, OID_AUTO, nkpt, CTLFLAG_RD, &nkpt, 0,
>      "Number of kernel page table pages allocated on bootup");
>
>  static int ndmpdp;
> -static vm_paddr_t dmaplimit;
> +vm_paddr_t dmaplimit;
>  vm_offset_t kernel_vm_end = VM_MIN_KERNEL_ADDRESS;
>  pt_entry_t pg_nx;
>
> diff --git a/sys/amd64/include/pmap.h b/sys/amd64/include/pmap.h
> index 3918282..e83e07e 100644
> --- a/sys/amd64/include/pmap.h
> +++ b/sys/amd64/include/pmap.h
> @@ -369,6 +369,7 @@ extern vm_paddr_t phys_avail[];
>  extern vm_paddr_t dump_avail[];
>  extern vm_offset_t virtual_avail;
>  extern vm_offset_t virtual_end;
> +extern vm_paddr_t dmaplimit;
>
>  #define        pmap_page_get_memattr(m)        ((vm_memattr_t)(m)->md.pat_mode)
>  #define        pmap_page_is_write_mapped(m)    (((m)->aflags & PGA_WRITEABLE) != 0)

The reason why the dmaplimit change originally exploded was becase
dmaplimit is set to zero for the duration of while we're running on
the page tables given to us by the loader.  I believe initializing
dmaplimit to DMAP_MAX_ADDRESS rather than zero would have solved the
original explosions.

There's far more rotten things here though. :(
-- 
Peter Wemm - peter@wemm.org; peter@FreeBSD.org; peter@yahoo-inc.com; KI6FJV
Yes, I know, gmail sucks now. If you see this then I forgot. Habits
are hard to break.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAGE5yCos5xGu7w24A6QSRDEPbfRNsjmHSvnpUE2Dvr1PUW2T8w>