Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F154611593
D3914.id9754.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D3914.id9754.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D3914: Changes to existing kernel functions to support kload
Attached
Detach File
Event Timeline
Log In to Comment