NetBSD-Bugs archive

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

Re: port-x68k/51663 (crash dump related bugs in x68k/machdep.c)



The following reply was made to PR port-x68k/51663; it has been noted by GNATS.

From: Rin Okuyama <rokuyama%rk.phys.keio.ac.jp@localhost>
To: gnats-bugs%NetBSD.org@localhost, tsutsui%NetBSD.org@localhost
Cc: 
Subject: Re: port-x68k/51663 (crash dump related bugs in x68k/machdep.c)
Date: Mon, 28 Nov 2016 22:38:39 +0900

 Let me explain a little more.
 
 cpu_kcore_hdr.un._m68k.ram_segs[i].{start,size} describe start address
 and size of the i-th segment of physical memory.
 
 On the kernel side, dumpsys(9) dumps their contents:
 
 https://nxr.netbsd.org/source/xref/src/sys/arch/x68k/x68k/machdep.c#702
    702  void
    703  dumpsys(void)
    704  {
    ...
    717          seg = 0;
    ...
    750          for (pg = 0; pg < dumpsize; pg++) {
    ...
    762                  while (maddr >=
    763                      (m->ram_segs[seg].start + m->ram_segs[seg].size)) {
    764                          if (++seg >= M68K_NPHYS_RAM_SEGS ||
    765                              m->ram_segs[seg].size == 0) {
    766                                  error = EINVAL;         /* XXX ?? */
    767                                  goto bad;
    768                          }
    769                          maddr = m->ram_segs[seg].start;
    770                  }
    771                  pmap_enter(pmap_kernel(), (vaddr_t)vmmap, maddr,
    772                      VM_PROT_READ, VM_PROT_READ|PMAP_WIRED);
    773                  pmap_update(pmap_kernel());
    774
    775                  error = (*dump)(dumpdev, blkno, vmmap, PAGE_SIZE);
    776   bad:
    777                  switch (error) {
    778                  case 0:
    779                          maddr += PAGE_SIZE;
    780                          blkno += btodb(PAGE_SIZE);
    781                          break;
    ...
    806                  }
    807          }
    808          printf("succeeded\n");
    809  }
 
 On the userland side, libkvm converts physical address into offset of
 a crash dump:
 
 https://nxr.netbsd.org/source/xref/src/lib/libkvm/kvm_m68k_cmn.c#158
    158  /*
    159   * Translate a physical address to a file-offset in the crash dump.
    160   */
    161  off_t
    162  _kvm_cmn_pa2off(kvm_t *kd, u_long pa)
    163  {
    164          cpu_kcore_hdr_t *h = kd->cpu_data;
    165          struct m68k_kcore_hdr *m = &h->un._m68k;
    166          phys_ram_seg_t *rsp;
    167          off_t off;
    168          int i;
    169
    170          off = 0;
    171          rsp = m->ram_segs;
    172          for (i = 0; i < M68K_NPHYS_RAM_SEGS && rsp[i].size != 0; i++) {
    173                  if (pa >= rsp[i].start &&
    174                      pa < (rsp[i].start + rsp[i].size)) {
    175                          pa -= rsp[i].start;
    176                          break;
    177                  }
    178                  off += rsp[i].size;
    179          }
    180          return (kd->dump_off + off + pa);
    181  }
 
 (This function silently returns bogus offset when invalid address is
 passed. This is a dangerous behavior and should be fixed later.)
 
 cpu_kcore_hdr.un._m68k.ram_segs[0] must cover whole the base memory,
 including areas not registered into the free list of UVM. This is
 because there are global variables and msgbuf below and above the region
 managed by UVM.
 
 On the other hand, regions in extended memory not managed by UVM can
 probably be excluded from ram_segs[i] (i >= 1). However, in my patch,
 such regions are also included for the reasons explained before.
 


Home | Main Index | Thread Index | Old Index