svn commit: r259996 - in user/gjb/hacking/release-embedded: bin/ps etc sys/amd64/vmm/io sys/ia64/ia64
Glen Barber
gjb at FreeBSD.org
Sat Dec 28 03:11:10 UTC 2013
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
More information about the svn-src-user
mailing list