Page MenuHomeFreeBSD

D3914.id9754.diff
No OneTemporary

D3914.id9754.diff

Index: sys/amd64/include/intr_machdep.h
===================================================================
--- sys/amd64/include/intr_machdep.h
+++ sys/amd64/include/intr_machdep.h
@@ -173,6 +173,7 @@
int intr_register_source(struct intsrc *isrc);
int intr_remove_handler(void *cookie);
void intr_resume(bool suspend_cancelled);
+int intr_clear_all_handlers(void);
void intr_suspend(void);
void intr_reprogram(void);
void intrcnt_add(const char *name, u_long **countp);
Index: sys/kern/kern_module.c
===================================================================
--- sys/kern/kern_module.c
+++ sys/kern/kern_module.c
@@ -64,6 +64,7 @@
struct sx modules_sx;
static int nextid = 1;
static void module_shutdown(void *, int);
+void kload_module_shutdown(void);
static int
modevent_nop(module_t mod, int what, void *arg)
@@ -107,6 +108,12 @@
}
void
+kload_module_shutdown(void) {
+ module_shutdown(NULL, 0);
+}
+
+
+void
module_register_init(const void *arg)
{
const moduledata_t *data = (const moduledata_t *)arg;
Index: sys/kern/kern_shutdown.c
===================================================================
--- sys/kern/kern_shutdown.c
+++ sys/kern/kern_shutdown.c
@@ -318,6 +318,14 @@
{
static int once = 0;
+ /*
+ * Do not use kload if we're coming to this code via panic
+ */
+ if (panicstr == NULL)
+ howto |= RB_KLOAD; /* if kload is setup and ready */
+ else
+ howto &= ~RB_KLOAD; /* do not use kload in panic situations */
+
#if defined(SMP)
/*
* Bind us to CPU 0 so that all shutdown code runs there. Some
Index: sys/sys/eventhandler.h
===================================================================
--- sys/sys/eventhandler.h
+++ sys/sys/eventhandler.h
@@ -173,6 +173,7 @@
#define SHUTDOWN_PRI_FIRST EVENTHANDLER_PRI_FIRST
#define SHUTDOWN_PRI_DEFAULT EVENTHANDLER_PRI_ANY
#define SHUTDOWN_PRI_LAST EVENTHANDLER_PRI_LAST
+#define SHUTDOWN_PRI_KLOAD EVENTHANDLER_PRI_LAST - 100
EVENTHANDLER_DECLARE(shutdown_pre_sync, shutdown_fn); /* before fs sync */
EVENTHANDLER_DECLARE(shutdown_post_sync, shutdown_fn); /* after fs sync */
Index: sys/sys/reboot.h
===================================================================
--- sys/sys/reboot.h
+++ sys/sys/reboot.h
@@ -60,6 +60,7 @@
#define RB_RESERVED2 0x80000 /* reserved for internal use of boot blocks */
#define RB_PAUSE 0x100000 /* pause after each output line during probe */
#define RB_REROOT 0x200000 /* unmount the rootfs and mount it again */
+#define RB_KLOAD 0x400000 /* reboot using kload'ed kernel image */
#define RB_MULTIPLE 0x20000000 /* use multiple consoles */
#define RB_BOOTINFO 0x80000000 /* have `struct bootinfo *' arg */
Index: sys/x86/include/apicvar.h
===================================================================
--- sys/x86/include/apicvar.h
+++ sys/x86/include/apicvar.h
@@ -457,6 +457,7 @@
void lapic_handle_timer(struct trapframe *frame);
void xen_intr_handle_upcall(struct trapframe *frame);
void hv_vector_handler(struct trapframe *frame);
+void lapic_clear_lapic(u_int);
extern int x2apic_mode;
extern int lapic_eoi_suppression;
Index: sys/x86/x86/intr_machdep.c
===================================================================
--- sys/x86/x86/intr_machdep.c
+++ sys/x86/x86/intr_machdep.c
@@ -194,6 +194,25 @@
}
int
+intr_clear_all_handlers(void)
+{
+ struct intsrc *isrc;
+ int i;
+
+ printf("%s\n", __func__);
+ mtx_lock(&intr_table_lock);
+ for (i = 0; i < NUM_IO_INTS; i++) {
+ isrc = interrupt_sources[i];
+ if (isrc != NULL) {
+ isrc->is_pic->pic_disable_source(isrc, PIC_EOI);
+ isrc->is_pic->pic_disable_intr(isrc);
+ }
+ }
+ mtx_unlock(&intr_table_lock);
+ return 0;
+}
+
+int
intr_remove_handler(void *cookie)
{
struct intsrc *isrc;
Index: sys/x86/x86/local_apic.c
===================================================================
--- sys/x86/x86/local_apic.c
+++ sys/x86/x86/local_apic.c
@@ -561,6 +561,62 @@
intr_restore(saveintr);
}
+void
+lapic_clear_lapic(u_int disable) {
+
+ struct lapic *la;
+ la = &lapics[lapic_id()];
+
+ uint32_t value;
+
+ if (bootverbose)
+ printf("%s lapic_id(%d) cpu(%d) la %p lapic_map %p\n",__FUNCTION__,
+ lapic_id(), PCPU_GET(cpuid), la, lapic_map);
+
+ /*
+ * Fist we set the mask bit to keep and new interrupts from
+ * arriving but allowing any pending interrupts to finish
+ * *THEN* set the registers to default values
+ * If the interrupts are not allowed to clear a kload'ed / booted
+ * kernel will see the old interrupts before the appropriate handlers
+ * are in place and trigger a panic.
+ */
+#ifdef notyet
+ /* this seems to be causing APIC error in the new kernel */
+ value = lapic_read32(LAPIC_LVT_ERROR);
+ value |= APIC_LVT_M;
+ lapic_write32(LAPIC_LVT_ERROR, value);
+#endif
+
+ value = lapic_read32(LAPIC_LVT_TIMER);
+ value |= APIC_LVT_M;
+ lapic_write32(LAPIC_LVT_TIMER, value);
+
+ value = lapic_read32(LAPIC_LVT_LINT0);
+ value |= APIC_LVT_M;
+ lapic_write32(LAPIC_LVT_LINT0, value);
+
+ value = lapic_read32(LAPIC_LVT_LINT1);
+ value |= APIC_LVT_M;
+ lapic_write32(LAPIC_LVT_LINT1, value);
+
+ value = lapic_read32(LAPIC_LVT_PCINT);
+ value |= APIC_LVT_M;
+ lapic_write32(LAPIC_LVT_PCINT, value);
+
+ /* Program timer LVT and setup handler. */
+ lapic_write32(LAPIC_LVT_TIMER, APIC_LVTT_M); /* masked */
+ lapic_write32(LAPIC_LVT_LINT0, APIC_LVT_M); /* masked */
+ lapic_write32(LAPIC_LVT_LINT1, APIC_LVT_M); /* masked */
+ //lapic_write32(LAPIC_LVT_PCINT, APIC_LVT_M); /* masked */
+
+ if (disable) {
+ if (bootverbose)
+ printf("lapic disable\n");
+ lapic_disable();
+ }
+}
+
static void
native_lapic_setup(int boot)
{
@@ -1145,7 +1201,20 @@
lapic_write32(LAPIC_ESR, 0);
esr = lapic_read32(LAPIC_ESR);
- printf("CPU%d: local APIC error 0x%x\n", PCPU_GET(cpuid), esr);
+ printf("CPU%d: local APIC error 0x%x\t", PCPU_GET(cpuid), esr);
+ if (esr & APIC_ESR_SEND_CS_ERROR)
+ printf("send_cs_error\n");
+ if (esr & APIC_ESR_RECEIVE_CS_ERROR)
+ printf("receive_cs_error\n");
+ if (esr & APIC_ESR_SEND_ACCEPT)
+ printf("send_accept\n");
+ if (esr & APIC_ESR_RECEIVE_ACCEPT)
+ printf("receive_accept\n");
+ if (esr & APIC_ESR_SEND_ILLEGAL_VECTOR)
+ printf("send_illegal_vector\n");
+ if (esr & APIC_ESR_ILLEGAL_REGISTER)
+ printf("illegal_register\n");
+
lapic_eoi();
}
Index: sys/x86/x86/mp_x86.c
===================================================================
--- sys/x86/x86/mp_x86.c
+++ sys/x86/x86/mp_x86.c
@@ -35,6 +35,7 @@
#include "opt_pmap.h"
#include "opt_sched.h"
#include "opt_smp.h"
+#include "opt_kload.h"
#include <sys/param.h>
#include <sys/systm.h>
@@ -90,6 +91,13 @@
extern struct pcpu __pcpu[];
+#ifdef KLOAD
+/* page table setup by kload so we can set the APs to a known page table */
+extern pt_entry_t kload_pgtbl;
+#else
+static pt_entry_t kload_pgtbl = 0;
+#endif
+
/* AP uses this during bootstrap. Do not staticize. */
char *bootSTK;
int bootAP;
@@ -1014,6 +1022,9 @@
mtx_assert(&smp_ipi_mtx, MA_NOTOWNED);
+ lapic_clear_lapic(1 /* disable lapic */);
+ /* shutdown interrupts to the cpu and then set the mask as stopped */
+
cpu = PCPU_GET(cpuid);
if (savectx(&susppcbs[cpu]->sp_pcb)) {
#ifdef __amd64__
@@ -1038,6 +1049,29 @@
CPU_CLR_ATOMIC(cpu, &suspended_cpus);
}
+ if (kload_pgtbl) {
+ /*
+ * Set the pagetable to boot capable PT in case this is
+ * kload suspend. If a normal suspend resume we restore
+ * the originnal page table
+ */
+ (void)intr_disable();
+ load_cr3(kload_pgtbl);
+
+ /* Disable PGE. */
+ load_cr4(rcr4() & ~CR4_PGE);
+
+ /* Disable caches (CD = 1, NW = 0) and paging*/
+ load_cr0((rcr0() & ~CR0_NW) | CR0_CD | CR0_PG);
+
+ /* Flushes caches and TLBs. */
+ wbinvd();
+ invltlb();
+
+ halt();
+
+ }
+
/* Wait for resume */
while (!CPU_ISSET(cpu, &started_cpus))
ia32_pause();
Index: sys/x86/x86/nexus.c
===================================================================
--- sys/x86/x86/nexus.c
+++ sys/x86/x86/nexus.c
@@ -59,6 +59,7 @@
#include <machine/intr_machdep.h>
#include <sys/rman.h>
#include <sys/interrupt.h>
+#include <sys/sysctl.h>
#include <machine/vmparam.h>
#include <vm/vm.h>
@@ -677,6 +678,38 @@
}
static int
+smap_hdlr(SYSCTL_HANDLER_ARGS)
+{
+ /*
+ SYSCTL_HANDLER_ARGS
+ struct sysctl_oid *oidp, void *arg1,
+ intptr_t arg2, struct sysctl_req *req
+ */
+ struct bios_smap *smapbase;
+ caddr_t kmdp;
+ uint32_t smapsize = 0;
+
+ /* Retrieve the system memory map from the loader. */
+ kmdp = preload_search_by_type("elf kernel");
+ if (kmdp == NULL)
+ kmdp = preload_search_by_type(ELF_KERN_STR);
+ if (kmdp != NULL) {
+ smapbase = (struct bios_smap *)preload_search_info(kmdp,
+ MODINFO_METADATA | MODINFOMD_SMAP);
+ } else {
+ smapbase = NULL;
+ goto out;
+ }
+
+ smapsize = *((u_int32_t *)smapbase - 1);
+out:
+ return (sysctl_handle_opaque(oidp, smapbase, smapsize, req));
+}
+SYSCTL_PROC(_hw, OID_AUTO, smap, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE,
+ 0, sizeof(struct bios_smap), smap_hdlr, "S,smap",
+ "Bios System Map");
+
+static int
ram_attach(device_t dev)
{
struct bios_smap *smapbase, *smap, *smapend;

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 30, 1:15 AM (3 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32424442
Default Alt Text
D3914.id9754.diff (8 KB)

Event Timeline