Page MenuHomeFreeBSD

D3914.id9760.diff
No OneTemporary

D3914.id9760.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
@@ -63,7 +63,6 @@
static TAILQ_HEAD(modulelist, module) modules;
struct sx modules_sx;
static int nextid = 1;
-static void module_shutdown(void *, int);
static int
modevent_nop(module_t mod, int what, void *arg)
@@ -91,7 +90,7 @@
SYSINIT(module, SI_SUB_KLD, SI_ORDER_FIRST, module_init, 0);
-static void
+void
module_shutdown(void *arg1, int arg2)
{
module_t mod;
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/kload.h
===================================================================
--- sys/sys/kload.h
+++ sys/sys/kload.h
@@ -85,7 +85,6 @@
*/
pt_entry_t * kload_build_page_table(void);
void setup_freebsd_gdt(uint64_t *);
-void kload_module_shutdown(void);
/*
* defined in <arch>/kload_exec.S
Index: sys/sys/module.h
===================================================================
--- sys/sys/module.h
+++ sys/sys/module.h
@@ -179,6 +179,7 @@
const char * module_getname(module_t);
void module_setspecific(module_t, modspecific_t *);
struct linker_file *module_file(module_t);
+void module_shutdown(void *arg1, int arg2);
#ifdef MOD_DEBUG
extern int mod_debug;
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
@@ -456,6 +456,7 @@
void lapic_handle_intr(int vector, struct trapframe *frame);
void lapic_handle_timer(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,24 @@
}
int
+intr_clear_all_handlers(void)
+{
+ struct intsrc *isrc;
+ int i;
+
+ 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)
{
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,12 @@
mtx_assert(&smp_ipi_mtx, MA_NOTOWNED);
+ /*
+ * shutdown interrupts to the cpu
+ * and then set the mask as stopped
+ */
+ lapic_clear_lapic(1 /* disable lapic */);
+
cpu = PCPU_GET(cpuid);
if (savectx(&susppcbs[cpu]->sp_pcb)) {
#ifdef __amd64__
@@ -1038,6 +1052,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>

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 29, 6:33 PM (15 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32376020
Default Alt Text
D3914.id9760.diff (7 KB)

Event Timeline