Date: Sat, 28 Dec 2013 03:11:09 +0000 (UTC) From: Glen Barber <gjb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r259996 - in user/gjb/hacking/release-embedded: bin/ps etc sys/amd64/vmm/io sys/ia64/ia64 Message-ID: <201312280311.rBS3B9WC064266@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: gjb Date: Sat Dec 28 03:11:09 2013 New Revision: 259996 URL: http://svnweb.freebsd.org/changeset/base/259996 Log: MFH: Tracking commit Sponsored by: The FreeBSD Foundation Modified: user/gjb/hacking/release-embedded/bin/ps/ps.1 user/gjb/hacking/release-embedded/etc/ntp.conf user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic.c user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic.h user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic_priv.h user/gjb/hacking/release-embedded/sys/ia64/ia64/dump_machdep.c Directory Properties: user/gjb/hacking/release-embedded/ (props changed) Modified: user/gjb/hacking/release-embedded/bin/ps/ps.1 ============================================================================== --- user/gjb/hacking/release-embedded/bin/ps/ps.1 Sat Dec 28 03:04:05 2013 (r259995) +++ user/gjb/hacking/release-embedded/bin/ps/ps.1 Sat Dec 28 03:11:09 2013 (r259996) @@ -29,7 +29,7 @@ .\" @(#)ps.1 8.3 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd March 15, 2013 +.Dd December 27, 2013 .Dt PS 1 .Os .Sh NAME @@ -416,8 +416,9 @@ The process has reduced CPU scheduling p .It Li s The process is a session leader. .It Li V -The process is suspended during a -.Xr vfork 2 . +The process' parent is suspended during a +.Xr vfork 2 , +waiting for the process to exec or exit. .It Li W The process is swapped out. .It Li X Modified: user/gjb/hacking/release-embedded/etc/ntp.conf ============================================================================== --- user/gjb/hacking/release-embedded/etc/ntp.conf Sat Dec 28 03:04:05 2013 (r259995) +++ user/gjb/hacking/release-embedded/etc/ntp.conf Sat Dec 28 03:11:09 2013 (r259996) @@ -17,7 +17,7 @@ # users with a static IP and good upstream NTP servers to add a server # to the pool. See http://www.pool.ntp.org/join.html if you are interested. # -# The option `iburst' is used for faster initial synchronisation. +# The option `iburst' is used for faster initial synchronization. # server 0.freebsd.pool.ntp.org iburst server 1.freebsd.pool.ntp.org iburst @@ -35,21 +35,37 @@ server 2.freebsd.pool.ntp.org iburst # server 2.CC.pool.ntp.org iburst # -# Security: Only accept NTP traffic from the following hosts. -# The following configuration example only accepts traffic from the -# above defined servers. +# Security: +# +# By default, only allow time queries and block all other requests +# from unauthenticated clients. +# +# See http://support.ntp.org/bin/view/Support/AccessRestrictions +# for more information. +# +restrict default kod nomodify notrap nopeer noquery +restrict -6 default kod nomodify notrap nopeer noquery +# +# Alternatively, the following rules would block all unauthorized access. +# +#restrict default ignore +#restrict -6 default ignore +# +# In this case, all remote NTP time servers also need to be explicitly +# allowed or they would not be able to exchange time information with +# this server. # # Please note that this example doesn't work for the servers in # the pool.ntp.org domain since they return multiple A records. -# (This is the reason that by default they are commented out) # -#restrict default ignore #restrict 0.pool.ntp.org nomodify nopeer noquery notrap #restrict 1.pool.ntp.org nomodify nopeer noquery notrap #restrict 2.pool.ntp.org nomodify nopeer noquery notrap -#restrict 127.0.0.1 -#restrict -6 ::1 -#restrict 127.127.1.0 +# +# The following settings allow unrestricted access from the localhost +restrict 127.0.0.1 +restrict -6 ::1 +restrict 127.127.1.0 # # If a server loses sync with all upstream servers, NTP clients Modified: user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic.c ============================================================================== --- user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic.c Sat Dec 28 03:04:05 2013 (r259995) +++ user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic.c Sat Dec 28 03:11:09 2013 (r259996) @@ -94,20 +94,14 @@ do { \ #define PRIO(x) ((x) >> 4) #define VLAPIC_VERSION (16) -#define VLAPIC_MAXLVT_ENTRIES (APIC_LVT_CMCI) #define x2apic(vlapic) (((vlapic)->msr_apicbase & APICBASE_X2APIC) ? 1 : 0) /* * The 'vlapic->timer_mtx' is used to provide mutual exclusion between the - * vlapic_callout_handler() and vcpu accesses to the following registers: - * - initial count register aka icr_timer - * - current count register aka ccr_timer - * - divide config register aka dcr_timer + * vlapic_callout_handler() and vcpu accesses to: + * - timer_freq_bt, timer_period_bt, timer_fire_bt * - timer LVT register - * - * Note that the vlapic_callout_handler() does not write to any of these - * registers so they can be safely read from the vcpu context without locking. */ #define VLAPIC_TIMER_LOCK(vlapic) mtx_lock_spin(&((vlapic)->timer_mtx)) #define VLAPIC_TIMER_UNLOCK(vlapic) mtx_unlock_spin(&((vlapic)->timer_mtx)) @@ -217,20 +211,6 @@ vlapic_timer_divisor(uint32_t dcr) } } -static void -vlapic_mask_lvts(struct vlapic *vlapic) -{ - struct LAPIC *lapic = vlapic->apic_page; - - lapic->lvt_cmci |= APIC_LVT_M; - lapic->lvt_timer |= APIC_LVT_M; - lapic->lvt_thermal |= APIC_LVT_M; - lapic->lvt_pcint |= APIC_LVT_M; - lapic->lvt_lint0 |= APIC_LVT_M; - lapic->lvt_lint1 |= APIC_LVT_M; - lapic->lvt_error |= APIC_LVT_M; -} - #if 0 static inline void vlapic_dump_lvt(uint32_t offset, uint32_t *lvt) @@ -273,8 +253,8 @@ vlapic_get_ccr(struct vlapic *vlapic) return (ccr); } -static void -vlapic_set_dcr(struct vlapic *vlapic, uint32_t dcr) +void +vlapic_dcr_write_handler(struct vlapic *vlapic) { struct LAPIC *lapic; int divisor; @@ -282,9 +262,9 @@ vlapic_set_dcr(struct vlapic *vlapic, ui lapic = vlapic->apic_page; VLAPIC_TIMER_LOCK(vlapic); - lapic->dcr_timer = dcr; - divisor = vlapic_timer_divisor(dcr); - VLAPIC_CTR2(vlapic, "vlapic dcr_timer=%#x, divisor=%d", dcr, divisor); + divisor = vlapic_timer_divisor(lapic->dcr_timer); + VLAPIC_CTR2(vlapic, "vlapic dcr_timer=%#x, divisor=%d", + lapic->dcr_timer, divisor); /* * Update the timer frequency and the timer period. @@ -299,8 +279,8 @@ vlapic_set_dcr(struct vlapic *vlapic, ui VLAPIC_TIMER_UNLOCK(vlapic); } -static void -vlapic_update_errors(struct vlapic *vlapic) +void +vlapic_esr_write_handler(struct vlapic *vlapic) { struct LAPIC *lapic; @@ -309,30 +289,6 @@ vlapic_update_errors(struct vlapic *vlap vlapic->esr_pending = 0; } -static void -vlapic_reset(struct vlapic *vlapic) -{ - struct LAPIC *lapic; - - lapic = vlapic->apic_page; - bzero(lapic, sizeof(struct LAPIC)); - - lapic->id = vlapic_get_id(vlapic); - lapic->version = VLAPIC_VERSION; - lapic->version |= (VLAPIC_MAXLVT_ENTRIES << MAXLVTSHIFT); - lapic->dfr = 0xffffffff; - lapic->svr = APIC_SVR_VECTOR; - vlapic_mask_lvts(vlapic); - vlapic_set_dcr(vlapic, 0); - - if (vlapic->vcpuid == 0) - vlapic->boot_state = BS_RUNNING; /* BSP */ - else - vlapic->boot_state = BS_INIT; /* AP */ - - vlapic->svr_last = lapic->svr; -} - void vlapic_set_intr_ready(struct vlapic *vlapic, int vector, bool level) { @@ -391,24 +347,65 @@ vlapic_get_lvtptr(struct vlapic *vlapic, } } +static __inline int +lvt_off_to_idx(uint32_t offset) +{ + int index; + + switch (offset) { + case APIC_OFFSET_CMCI_LVT: + index = APIC_LVT_CMCI; + break; + case APIC_OFFSET_TIMER_LVT: + index = APIC_LVT_TIMER; + break; + case APIC_OFFSET_THERM_LVT: + index = APIC_LVT_THERMAL; + break; + case APIC_OFFSET_PERF_LVT: + index = APIC_LVT_PMC; + break; + case APIC_OFFSET_LINT0_LVT: + index = APIC_LVT_LINT0; + break; + case APIC_OFFSET_LINT1_LVT: + index = APIC_LVT_LINT1; + break; + case APIC_OFFSET_ERROR_LVT: + index = APIC_LVT_ERROR; + break; + default: + index = -1; + break; + } + KASSERT(index >= 0 && index <= VLAPIC_MAXLVT_INDEX, ("lvt_off_to_idx: " + "invalid lvt index %d for offset %#x", index, offset)); + + return (index); +} + static __inline uint32_t vlapic_get_lvt(struct vlapic *vlapic, uint32_t offset) { + int idx; + uint32_t val; - return (*vlapic_get_lvtptr(vlapic, offset)); + idx = lvt_off_to_idx(offset); + val = atomic_load_acq_32(&vlapic->lvt_last[idx]); + return (val); } -static void -vlapic_set_lvt(struct vlapic *vlapic, uint32_t offset, uint32_t val) +void +vlapic_lvt_write_handler(struct vlapic *vlapic, uint32_t offset) { - uint32_t *lvtptr, mask; + uint32_t *lvtptr, mask, val; struct LAPIC *lapic; + int idx; lapic = vlapic->apic_page; lvtptr = vlapic_get_lvtptr(vlapic, offset); - - if (offset == APIC_OFFSET_TIMER_LVT) - VLAPIC_TIMER_LOCK(vlapic); + val = *lvtptr; + idx = lvt_off_to_idx(offset); if (!(lapic->svr & APIC_SVR_ENABLE)) val |= APIC_LVT_M; @@ -427,10 +424,36 @@ vlapic_set_lvt(struct vlapic *vlapic, ui mask |= APIC_LVT_DM; break; } - *lvtptr = val & mask; + val &= mask; + *lvtptr = val; + atomic_store_rel_32(&vlapic->lvt_last[idx], val); +} + +static void +vlapic_mask_lvts(struct vlapic *vlapic) +{ + struct LAPIC *lapic = vlapic->apic_page; + + lapic->lvt_cmci |= APIC_LVT_M; + vlapic_lvt_write_handler(vlapic, APIC_OFFSET_CMCI_LVT); + + lapic->lvt_timer |= APIC_LVT_M; + vlapic_lvt_write_handler(vlapic, APIC_OFFSET_TIMER_LVT); - if (offset == APIC_OFFSET_TIMER_LVT) - VLAPIC_TIMER_UNLOCK(vlapic); + lapic->lvt_thermal |= APIC_LVT_M; + vlapic_lvt_write_handler(vlapic, APIC_OFFSET_THERM_LVT); + + lapic->lvt_pcint |= APIC_LVT_M; + vlapic_lvt_write_handler(vlapic, APIC_OFFSET_PERF_LVT); + + lapic->lvt_lint0 |= APIC_LVT_M; + vlapic_lvt_write_handler(vlapic, APIC_OFFSET_LINT0_LVT); + + lapic->lvt_lint1 |= APIC_LVT_M; + vlapic_lvt_write_handler(vlapic, APIC_OFFSET_LINT1_LVT); + + lapic->lvt_error |= APIC_LVT_M; + vlapic_lvt_write_handler(vlapic, APIC_OFFSET_ERROR_LVT); } static int @@ -651,7 +674,7 @@ vlapic_fire_cmci(struct vlapic *vlapic) } } -static VMM_STAT_ARRAY(LVTS_TRIGGERRED, VLAPIC_MAXLVT_ENTRIES, +static VMM_STAT_ARRAY(LVTS_TRIGGERRED, VLAPIC_MAXLVT_INDEX + 1, "lvts triggered"); int @@ -711,8 +734,6 @@ vlapic_callout_handler(void *arg) callout_deactivate(&vlapic->callout); - KASSERT(vlapic->apic_page->icr_timer != 0, ("timer is disabled")); - vlapic_fire_timer(vlapic); if (vlapic_periodic_timer(vlapic)) { @@ -757,16 +778,17 @@ done: VLAPIC_TIMER_UNLOCK(vlapic); } -static void -vlapic_set_icr_timer(struct vlapic *vlapic, uint32_t icr_timer) +void +vlapic_icrtmr_write_handler(struct vlapic *vlapic) { struct LAPIC *lapic; sbintime_t sbt; + uint32_t icr_timer; VLAPIC_TIMER_LOCK(vlapic); lapic = vlapic->apic_page; - lapic->icr_timer = icr_timer; + icr_timer = lapic->icr_timer; vlapic->timer_period_bt = vlapic->timer_freq_bt; bintime_mul(&vlapic->timer_period_bt, icr_timer); @@ -888,16 +910,22 @@ vlapic_calcdest(struct vm *vm, cpuset_t static VMM_STAT_ARRAY(IPIS_SENT, VM_MAXCPU, "ipis sent to vcpu"); -static int -lapic_process_icr(struct vlapic *vlapic, uint64_t icrval, bool *retu) +int +vlapic_icrlo_write_handler(struct vlapic *vlapic, bool *retu) { int i; bool phys; cpuset_t dmask; + uint64_t icrval; uint32_t dest, vec, mode; struct vlapic *vlapic2; struct vm_exit *vmexit; - + struct LAPIC *lapic; + + lapic = vlapic->apic_page; + lapic->icr_lo &= ~APIC_DELSTAT_PEND; + icrval = ((uint64_t)lapic->icr_hi << 32) | lapic->icr_lo; + if (x2apic(vlapic)) dest = icrval >> 32; else @@ -1088,7 +1116,7 @@ vlapic_svr_write_handler(struct vlapic * */ VLAPIC_CTR0(vlapic, "vlapic is software-enabled"); if (vlapic_periodic_timer(vlapic)) - vlapic_set_icr_timer(vlapic, lapic->icr_timer); + vlapic_icrtmr_write_handler(vlapic); } } } @@ -1155,6 +1183,8 @@ vlapic_read(struct vlapic *vlapic, uint6 break; case APIC_OFFSET_ICR_LOW: *data = lapic->icr_lo; + if (x2apic(vlapic)) + *data |= (uint64_t)lapic->icr_hi << 32; break; case APIC_OFFSET_ICR_HI: *data = lapic->icr_hi; @@ -1162,6 +1192,11 @@ vlapic_read(struct vlapic *vlapic, uint6 case APIC_OFFSET_CMCI_LVT: case APIC_OFFSET_TIMER_LVT ... APIC_OFFSET_ERROR_LVT: *data = vlapic_get_lvt(vlapic, offset); +#ifdef INVARIANTS + reg = vlapic_get_lvtptr(vlapic, offset); + KASSERT(*data == *reg, ("inconsistent lvt value at " + "offset %#lx: %#lx/%#x", offset, *data, *reg)); +#endif break; case APIC_OFFSET_TIMER_ICR: *data = lapic->icr_timer; @@ -1186,6 +1221,7 @@ int vlapic_write(struct vlapic *vlapic, uint64_t offset, uint64_t data, bool *retu) { struct LAPIC *lapic = vlapic->apic_page; + uint32_t *regptr; int retval; KASSERT((offset & 0xf) == 0 && offset < PAGE_SIZE, @@ -1224,32 +1260,32 @@ vlapic_write(struct vlapic *vlapic, uint vlapic_svr_write_handler(vlapic); break; case APIC_OFFSET_ICR_LOW: - if (!x2apic(vlapic)) { - data &= 0xffffffff; - data |= (uint64_t)lapic->icr_hi << 32; - } - retval = lapic_process_icr(vlapic, data, retu); + lapic->icr_lo = data; + if (x2apic(vlapic)) + lapic->icr_hi = data >> 32; + retval = vlapic_icrlo_write_handler(vlapic, retu); break; case APIC_OFFSET_ICR_HI: - if (!x2apic(vlapic)) { - retval = 0; - lapic->icr_hi = data; - } + lapic->icr_hi = data; break; case APIC_OFFSET_CMCI_LVT: case APIC_OFFSET_TIMER_LVT ... APIC_OFFSET_ERROR_LVT: - vlapic_set_lvt(vlapic, offset, data); + regptr = vlapic_get_lvtptr(vlapic, offset); + *regptr = data; + vlapic_lvt_write_handler(vlapic, offset); break; case APIC_OFFSET_TIMER_ICR: - vlapic_set_icr_timer(vlapic, data); + lapic->icr_timer = data; + vlapic_icrtmr_write_handler(vlapic); break; case APIC_OFFSET_TIMER_DCR: - vlapic_set_dcr(vlapic, data); + lapic->dcr_timer = data; + vlapic_dcr_write_handler(vlapic); break; case APIC_OFFSET_ESR: - vlapic_update_errors(vlapic); + vlapic_esr_write_handler(vlapic); break; case APIC_OFFSET_VER: case APIC_OFFSET_APR: @@ -1267,6 +1303,32 @@ vlapic_write(struct vlapic *vlapic, uint return (retval); } +static void +vlapic_reset(struct vlapic *vlapic) +{ + struct LAPIC *lapic; + + lapic = vlapic->apic_page; + bzero(lapic, sizeof(struct LAPIC)); + + lapic->id = vlapic_get_id(vlapic); + lapic->version = VLAPIC_VERSION; + lapic->version |= (VLAPIC_MAXLVT_INDEX << MAXLVTSHIFT); + lapic->dfr = 0xffffffff; + lapic->svr = APIC_SVR_VECTOR; + vlapic_mask_lvts(vlapic); + + lapic->dcr_timer = 0; + vlapic_dcr_write_handler(vlapic); + + if (vlapic->vcpuid == 0) + vlapic->boot_state = BS_RUNNING; /* BSP */ + else + vlapic->boot_state = BS_INIT; /* AP */ + + vlapic->svr_last = lapic->svr; +} + void vlapic_init(struct vlapic *vlapic) { Modified: user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic.h ============================================================================== --- user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic.h Sat Dec 28 03:04:05 2013 (r259995) +++ user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic.h Sat Dec 28 03:11:09 2013 (r259996) @@ -76,4 +76,9 @@ void vlapic_id_write_handler(struct vlap void vlapic_ldr_write_handler(struct vlapic *vlapic); void vlapic_dfr_write_handler(struct vlapic *vlapic); void vlapic_svr_write_handler(struct vlapic *vlapic); +void vlapic_esr_write_handler(struct vlapic *vlapic); +int vlapic_icrlo_write_handler(struct vlapic *vlapic, bool *retu); +void vlapic_icrtmr_write_handler(struct vlapic *vlapic); +void vlapic_dcr_write_handler(struct vlapic *vlapic); +void vlapic_lvt_write_handler(struct vlapic *vlapic, uint32_t offset); #endif /* _VLAPIC_H_ */ Modified: user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic_priv.h ============================================================================== --- user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic_priv.h Sat Dec 28 03:04:05 2013 (r259995) +++ user/gjb/hacking/release-embedded/sys/amd64/vmm/io/vlapic_priv.h Sat Dec 28 03:11:09 2013 (r259996) @@ -29,6 +29,8 @@ #ifndef _VLAPIC_PRIV_H_ #define _VLAPIC_PRIV_H_ +#include <x86/apicreg.h> + /* * APIC Register: Offset Description */ @@ -91,6 +93,8 @@ enum boot_state { */ #define ISRVEC_STK_SIZE (16 + 1) +#define VLAPIC_MAXLVT_INDEX APIC_LVT_CMCI + struct vlapic { struct vm *vm; int vcpuid; @@ -111,12 +115,20 @@ struct vlapic { * The vector on the top of the stack is used to compute the * Processor Priority in conjunction with the TPR. */ - uint8_t isrvec_stk[ISRVEC_STK_SIZE]; - int isrvec_stk_top; + uint8_t isrvec_stk[ISRVEC_STK_SIZE]; + int isrvec_stk_top; + + uint64_t msr_apicbase; + enum boot_state boot_state; - uint64_t msr_apicbase; - enum boot_state boot_state; - uint32_t svr_last; + /* + * Copies of some registers in the virtual APIC page. We do this for + * a couple of different reasons: + * - to be able to detect what changed (e.g. svr_last) + * - to maintain a coherent snapshot of the register (e.g. lvt_last) + */ + uint32_t svr_last; + uint32_t lvt_last[VLAPIC_MAXLVT_INDEX + 1]; }; void vlapic_init(struct vlapic *vlapic); Modified: user/gjb/hacking/release-embedded/sys/ia64/ia64/dump_machdep.c ============================================================================== --- user/gjb/hacking/release-embedded/sys/ia64/ia64/dump_machdep.c Sat Dec 28 03:04:05 2013 (r259995) +++ user/gjb/hacking/release-embedded/sys/ia64/ia64/dump_machdep.c Sat Dec 28 03:11:09 2013 (r259996) @@ -56,7 +56,10 @@ CTASSERT(sizeof(struct kerneldumpheader) #define MD_ALIGN(x) (((off_t)(x) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK) #define DEV_ALIGN(x) (((off_t)(x) + (DEV_BSIZE-1)) & ~(DEV_BSIZE-1)) -typedef int callback_t(struct efi_md*, int, void*); +static int minidump = 0; +TUNABLE_INT("debug.minidump", &minidump); +SYSCTL_INT(_debug, OID_AUTO, minidump, CTLFLAG_RW, &minidump, 0, + "Enable mini crash dumps"); static struct kerneldumpheader kdh; static off_t dumplo, fileofs; @@ -83,7 +86,7 @@ buf_write(struct dumperinfo *di, char *p error = dump_write(di, buffer, 0, dumplo, DEV_BSIZE); if (error) - return error; + return (error); dumplo += DEV_BSIZE; fragsz = 0; } @@ -106,8 +109,14 @@ buf_flush(struct dumperinfo *di) return (error); } +/* + * Physical dump support + */ + +typedef int phys_callback_t(struct efi_md*, int, void*); + static int -cb_dumpdata(struct efi_md *mdp, int seqnr, void *arg) +phys_cb_dumpdata(struct efi_md *mdp, int seqnr, void *arg) { struct dumperinfo *di = (struct dumperinfo*)arg; vm_offset_t pa; @@ -153,7 +162,7 @@ cb_dumpdata(struct efi_md *mdp, int seqn } static int -cb_dumphdr(struct efi_md *mdp, int seqnr, void *arg) +phys_cb_dumphdr(struct efi_md *mdp, int seqnr, void *arg) { struct dumperinfo *di = (struct dumperinfo*)arg; Elf64_Phdr phdr; @@ -175,7 +184,7 @@ cb_dumphdr(struct efi_md *mdp, int seqnr } static int -cb_size(struct efi_md *mdp, int seqnr, void *arg) +phys_cb_size(struct efi_md *mdp, int seqnr, void *arg) { uint64_t *sz = (uint64_t*)arg; @@ -184,7 +193,7 @@ cb_size(struct efi_md *mdp, int seqnr, v } static int -foreach_chunk(callback_t cb, void *arg) +phys_foreach(phys_callback_t cb, void *arg) { struct efi_md *mdp; int error, seqnr; @@ -206,6 +215,31 @@ foreach_chunk(callback_t cb, void *arg) return (seqnr); } +/* + * Virtual dump (aka minidump) support + */ + +static int +virt_size(uint64_t *dumpsize) +{ + + return (0); +} + +static int +virt_dumphdrs(struct dumperinfo *di) +{ + + return (-ENOSYS); +} + +static int +virt_dumpdata(struct dumperinfo *di) +{ + + return (-ENOSYS); +} + void dumpsys(struct dumperinfo *di) { @@ -213,7 +247,7 @@ dumpsys(struct dumperinfo *di) uint64_t dumpsize; off_t hdrgap; size_t hdrsz; - int error; + int error, status; bzero(&ehdr, sizeof(ehdr)); ehdr.e_ident[EI_MAG0] = ELFMAG0; @@ -230,18 +264,25 @@ dumpsys(struct dumperinfo *di) ehdr.e_ident[EI_OSABI] = ELFOSABI_STANDALONE; /* XXX big picture? */ ehdr.e_type = ET_CORE; ehdr.e_machine = EM_IA_64; - ehdr.e_entry = ia64_tpa((uintptr_t)bootinfo); + ehdr.e_entry = (minidump) ? (uintptr_t)bootinfo : + ia64_tpa((uintptr_t)bootinfo); ehdr.e_phoff = sizeof(ehdr); - ehdr.e_flags = EF_IA_64_ABSOLUTE; /* XXX misuse? */ + ehdr.e_flags = (minidump) ? 0 : EF_IA_64_ABSOLUTE; /* XXX misuse? */ ehdr.e_ehsize = sizeof(ehdr); ehdr.e_phentsize = sizeof(Elf64_Phdr); ehdr.e_shentsize = sizeof(Elf64_Shdr); /* Calculate dump size. */ dumpsize = 0L; - ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize); + status = (minidump) ? virt_size(&dumpsize) : + phys_foreach(phys_cb_size, &dumpsize); + if (status < 0) { + error = -status; + goto fail; + } + ehdr.e_phnum = status; hdrsz = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize; - fileofs = MD_ALIGN(hdrsz); + fileofs = (minidump) ? round_page(hdrsz) : MD_ALIGN(hdrsz); dumpsize += fileofs; hdrgap = fileofs - DEV_ALIGN(hdrsz); @@ -270,24 +311,30 @@ dumpsys(struct dumperinfo *di) goto fail; /* Dump program headers */ - error = foreach_chunk(cb_dumphdr, di); - if (error < 0) + status = (minidump) ? virt_dumphdrs(di) : + phys_foreach(phys_cb_dumphdr, di); + if (status < 0) { + error = -status; goto fail; + } buf_flush(di); /* * All headers are written using blocked I/O, so we know the - * current offset is (still) block aligned. Skip the alignement + * current offset is (still) block aligned. Skip the alignment * in the file to have the segment contents aligned at page - * boundary. We cannot use MD_ALIGN on dumplo, because we don't - * care and may very well be unaligned within the dump device. + * boundary. For physical dumps, it's the EFI page size (= 4K). + * For minidumps it's the kernel's page size (= 8K). */ dumplo += hdrgap; /* Dump memory chunks (updates dumplo) */ - error = foreach_chunk(cb_dumpdata, di); - if (error < 0) + status = (minidump) ? virt_dumpdata(di) : + phys_foreach(phys_cb_dumpdata, di); + if (status < 0) { + error = -status; goto fail; + } /* Dump trailer */ error = dump_write(di, &kdh, 0, dumplo, sizeof(kdh)); @@ -300,9 +347,6 @@ dumpsys(struct dumperinfo *di) return; fail: - if (error < 0) - error = -error; - if (error == ECANCELED) printf("\nDump aborted\n"); else
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201312280311.rBS3B9WC064266>