4224 lines
110 KiB
Diff
Executable File
4224 lines
110 KiB
Diff
Executable File
Colinux base
|
|
|
|
|
|
Index: linux-2.6.33-source/CREDITS
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/CREDITS
|
|
+++ linux-2.6.33-source/CREDITS
|
|
@@ -16,6 +16,13 @@
|
|
S: (ask for current address)
|
|
S: Finland
|
|
|
|
+N: Dan Aloni
|
|
+E: da-x@colinux.org
|
|
+W: http://www.colinux.org
|
|
+D: Cooperative Linux
|
|
+D: Various kernel patches
|
|
+S: Israel
|
|
+
|
|
N: Dragos Acostachioaie
|
|
E: dragos@iname.com
|
|
W: http://www.arbornet.org/~dragos
|
|
Index: linux-2.6.33-source/Makefile
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/Makefile
|
|
+++ linux-2.6.33-source/Makefile
|
|
@@ -312,7 +312,11 @@
|
|
|
|
AS = $(CROSS_COMPILE)as
|
|
LD = $(CROSS_COMPILE)ld
|
|
+ifeq ($(GCCTRACE),Y)
|
|
+CC = $(COLINUX_ROOT)/bin/tracewrapper.py $(CROSS_COMPILE)gcc
|
|
+else
|
|
CC = $(CROSS_COMPILE)gcc
|
|
+endif
|
|
CPP = $(CC) -E
|
|
AR = $(CROSS_COMPILE)ar
|
|
NM = $(CROSS_COMPILE)nm
|
|
Index: linux-2.6.33-source/arch/x86/Kconfig
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/Kconfig
|
|
+++ linux-2.6.33-source/arch/x86/Kconfig
|
|
@@ -42,7 +42,7 @@
|
|
select HAVE_KVM
|
|
select HAVE_ARCH_KGDB
|
|
select HAVE_ARCH_TRACEHOOK
|
|
- select HAVE_GENERIC_DMA_COHERENT if X86_32
|
|
+ select HAVE_GENERIC_DMA_COHERENT if (X86_32 && !COOPERATIVE)
|
|
select HAVE_EFFICIENT_UNALIGNED_ACCESS
|
|
select USER_STACKTRACE_SUPPORT
|
|
select HAVE_DMA_API_DEBUG
|
|
@@ -71,6 +71,7 @@
|
|
|
|
config GENERIC_CMOS_UPDATE
|
|
def_bool y
|
|
+ depends on !COOPERATIVE
|
|
|
|
config CLOCKSOURCE_WATCHDOG
|
|
def_bool y
|
|
@@ -96,12 +97,14 @@
|
|
|
|
config ZONE_DMA
|
|
def_bool y
|
|
+ depends on HAVE_DMA
|
|
|
|
config SBUS
|
|
bool
|
|
|
|
config GENERIC_ISA_DMA
|
|
def_bool y
|
|
+ depends on HAVE_DMA
|
|
|
|
config GENERIC_IOMAP
|
|
def_bool y
|
|
@@ -194,6 +197,8 @@
|
|
|
|
config GENERIC_HARDIRQS_NO__DO_IRQ
|
|
def_bool y
|
|
+# FIXME: Use generic_handle_irq() instead __do_IRQ()
|
|
+ depends on !COOPERATIVE
|
|
|
|
config GENERIC_IRQ_PROBE
|
|
bool
|
|
@@ -241,6 +246,7 @@
|
|
|
|
config SMP
|
|
bool "Symmetric multi-processing support"
|
|
+ depends on !COOPERATIVE
|
|
---help---
|
|
This enables support for systems with more than one CPU. If you have
|
|
a system with only one CPU, like most personal computers, say N. If
|
|
@@ -592,6 +598,7 @@
|
|
config HPET_TIMER
|
|
def_bool X86_64
|
|
prompt "HPET Timer Support" if X86_32
|
|
+ depends on !COOPERATIVE
|
|
---help---
|
|
Use the IA-PC HPET (High Precision Event Timer) to manage
|
|
time in preference to the PIT and RTC, if a HPET is
|
|
@@ -617,6 +624,7 @@
|
|
config DMI
|
|
default y
|
|
bool "Enable DMI scanning" if EMBEDDED
|
|
+ depends on !COOPERATIVE
|
|
---help---
|
|
Enabled scanning of DMI to identify machine quirks. Say Y
|
|
here unless you have verified that your setup is not
|
|
@@ -780,6 +788,10 @@
|
|
to use it. If you say Y here even though your machine doesn't have
|
|
an IO-APIC, then the kernel will still run with no slowdown at all.
|
|
|
|
+config X86_UP_COPIC
|
|
+ bool 'Cooperative PIC (COPIC) support'
|
|
+ depends on COOPERATIVE
|
|
+
|
|
config X86_LOCAL_APIC
|
|
def_bool y
|
|
depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
|
|
@@ -894,6 +906,7 @@
|
|
|
|
config I8K
|
|
tristate "Dell laptop support"
|
|
+ depends on !COOPERATIVE
|
|
---help---
|
|
This adds a driver to safely access the System Management Mode
|
|
of the CPU on the Dell Inspiron 8000. The System Management Mode
|
|
@@ -915,6 +928,7 @@
|
|
config X86_REBOOTFIXUPS
|
|
bool "Enable X86 board specific fixups for reboot"
|
|
depends on X86_32
|
|
+ depends on !COOPERATIVE
|
|
---help---
|
|
This enables chipset and/or board specific fixups to be done
|
|
in order to get reboot to work correctly. This is only needed on
|
|
@@ -994,6 +1008,7 @@
|
|
default HIGHMEM4G if !X86_NUMAQ
|
|
default HIGHMEM64G if X86_NUMAQ
|
|
depends on X86_32
|
|
+ depends on !COOPERATIVE
|
|
|
|
config NOHIGHMEM
|
|
bool "off"
|
|
@@ -1100,6 +1115,7 @@
|
|
config X86_PAE
|
|
bool "PAE (Physical Address Extension) Support"
|
|
depends on X86_32 && !HIGHMEM4G
|
|
+ depends on !COOPERATIVE
|
|
---help---
|
|
PAE is required for NX support, and furthermore enables
|
|
larger swapspace support for non-overcommit purposes. It
|
|
@@ -1230,6 +1246,7 @@
|
|
config ARCH_SPARSEMEM_ENABLE
|
|
def_bool y
|
|
depends on X86_64 || NUMA || (EXPERIMENTAL && X86_32) || X86_32_NON_STANDARD
|
|
+ depends on !COOPERATIVE
|
|
select SPARSEMEM_STATIC if X86_32
|
|
select SPARSEMEM_VMEMMAP_ENABLE if X86_64
|
|
|
|
@@ -1336,6 +1353,7 @@
|
|
config MTRR
|
|
bool
|
|
default y
|
|
+ depends on !COOPERATIVE
|
|
prompt "MTRR (Memory Type Range Register) support" if EMBEDDED
|
|
---help---
|
|
On Intel P6 family processors (Pentium Pro, Pentium II and later)
|
|
@@ -1470,6 +1488,7 @@
|
|
|
|
config KEXEC
|
|
bool "kexec system call"
|
|
+ depends on !COOPERATIVE
|
|
---help---
|
|
kexec is a system call that implements the ability to shutdown your
|
|
current kernel, and to start another kernel. It is like a reboot
|
|
@@ -1603,6 +1622,26 @@
|
|
automatically on SMP systems. )
|
|
Say N if you want to disable CPU hotplug.
|
|
|
|
+config COOPERATIVE
|
|
+ bool 'Cooperative Mode'
|
|
+ default y
|
|
+
|
|
+config COLINUX_STATS
|
|
+ bool 'Cooperative Linux stats'
|
|
+ depends on COOPERATIVE
|
|
+ default y
|
|
+ help
|
|
+ OS switch counters readable in /proc/colinux/stats.
|
|
+
|
|
+# FIXME: IOMEM should disabled, but was needed by keyboard and Serial device
|
|
+#config NO_IOMEM
|
|
+# depends on COOPERATIVE
|
|
+# def_bool y
|
|
+
|
|
+config NO_DMA
|
|
+ def_bool y
|
|
+ depends on COOPERATIVE
|
|
+
|
|
config COMPAT_VDSO
|
|
def_bool y
|
|
prompt "Compat VDSO support"
|
|
@@ -1676,6 +1715,7 @@
|
|
depends on NUMA
|
|
|
|
menu "Power management and ACPI options"
|
|
+ depends on !COOPERATIVE
|
|
|
|
config ARCH_HIBERNATION_HEADER
|
|
def_bool y
|
|
Index: linux-2.6.33-source/arch/x86/Kconfig.cpu
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/Kconfig.cpu
|
|
+++ linux-2.6.33-source/arch/x86/Kconfig.cpu
|
|
@@ -392,7 +392,7 @@
|
|
|
|
config X86_TSC
|
|
def_bool y
|
|
- depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) && !X86_NUMAQ) || X86_64
|
|
+ depends on ((MWINCHIP3D || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MVIAC7 || MGEODEGX1 || MGEODE_LX || MCORE2 || MATOM) && !X86_NUMAQ && !COOPERATIVE) || X86_64
|
|
|
|
config X86_CMPXCHG64
|
|
def_bool y
|
|
Index: linux-2.6.33-source/arch/x86/kernel/Makefile
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/Makefile
|
|
+++ linux-2.6.33-source/arch/x86/kernel/Makefile
|
|
@@ -2,7 +2,11 @@
|
|
# Makefile for the linux kernel.
|
|
#
|
|
|
|
-extra-y := head_$(BITS).o head$(BITS).o head.o init_task.o vmlinux.lds
|
|
+extra-y := head_$(BITS).o
|
|
+ifndef CONFIG_COOPERATIVE
|
|
+extra-y += head$(BITS).o head.o
|
|
+endif
|
|
+extra-y += init_task.o vmlinux.lds
|
|
|
|
CPPFLAGS_vmlinux.lds += -U$(UTS_MACHINE)
|
|
|
|
@@ -31,17 +35,24 @@
|
|
|
|
obj-y := process_$(BITS).o signal.o entry_$(BITS).o
|
|
obj-y += traps.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
|
|
-obj-y += time.o ioport.o ldt.o dumpstack.o
|
|
-obj-y += setup.o x86_init.o i8259.o irqinit.o
|
|
+obj-y += ldt.o dumpstack.o
|
|
+obj-y += setup.o irqinit.o
|
|
obj-$(CONFIG_X86_VISWS) += visws_quirks.o
|
|
+ifndef CONFIG_COOPERATIVE
|
|
obj-$(CONFIG_X86_32) += probe_roms_32.o
|
|
+endif
|
|
obj-$(CONFIG_X86_32) += sys_i386_32.o i386_ksyms_32.o
|
|
obj-$(CONFIG_X86_64) += sys_x86_64.o x8664_ksyms_64.o
|
|
obj-$(CONFIG_X86_64) += syscall_64.o vsyscall_64.o
|
|
-obj-y += bootflag.o e820.o
|
|
-obj-y += pci-dma.o quirks.o i8237.o topology.o kdebugfs.o
|
|
-obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
|
|
+ifndef CONFIG_COOPERATIVE
|
|
+obj-y += bootflag.o
|
|
+endif
|
|
+obj-$(CONFIG_HAS_DMA) += pci-dma.o pci-nommu.o
|
|
+obj-y += quirks.o i8237.o topology.o kdebugfs.o
|
|
+obj-y += alternative.o hw_breakpoint.o
|
|
+ifndef CONFIG_COOPERATIVE
|
|
obj-y += tsc.o io_delay.o rtc.o
|
|
+endif
|
|
|
|
obj-$(CONFIG_X86_TRAMPOLINE) += trampoline.o
|
|
obj-y += process.o
|
|
@@ -57,11 +68,12 @@
|
|
obj-y += cpu/
|
|
obj-y += acpi/
|
|
obj-$(CONFIG_SFI) += sfi.o
|
|
-obj-y += reboot.o
|
|
obj-$(CONFIG_MCA) += mca_32.o
|
|
obj-$(CONFIG_X86_MSR) += msr.o
|
|
obj-$(CONFIG_X86_CPUID) += cpuid.o
|
|
+ifndef CONFIG_COOPERATIVE
|
|
obj-$(CONFIG_PCI) += early-quirks.o
|
|
+endif
|
|
apm-y := apm_32.o
|
|
obj-$(CONFIG_APM) += apm.o
|
|
obj-$(CONFIG_SMP) += smp.o
|
|
@@ -130,3 +142,19 @@
|
|
obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o
|
|
obj-y += vsmp_64.o
|
|
endif
|
|
+
|
|
+###
|
|
+# coLinux specific files
|
|
+ifdef CONFIG_COOPERATIVE
|
|
+obj-y += cooperative.o
|
|
+obj-y += timer_cooperative.o
|
|
+obj-y += ioport_cooperative.o i8259_cooperative.o
|
|
+obj-y += reboot_cooperative.o
|
|
+obj-y += x86_init_cooperative.o
|
|
+else
|
|
+obj-y += i8253.o i8259.o
|
|
+obj-y += time.o ioport.o
|
|
+obj-y += e820.o
|
|
+obj-y += reboot.o
|
|
+obj-y += x86_init.o
|
|
+endif
|
|
Index: linux-2.6.33-source/arch/x86/kernel/cooperative.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/arch/x86/kernel/cooperative.c
|
|
@@ -0,0 +1,221 @@
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/interrupt.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/reboot.h>
|
|
+
|
|
+#include <linux/cooperative_internal.h>
|
|
+#include <asm/cooperative_internal.h>
|
|
+#include <asm/cpu.h>
|
|
+#include <asm/processor.h>
|
|
+#include <asm/desc.h>
|
|
+#include <asm/mmu_context.h>
|
|
+#include <asm/debugreg.h>
|
|
+#include <asm/i387.h>
|
|
+
|
|
+CO_TRACE_STOP;
|
|
+
|
|
+#ifdef ENABLE_PASSAGE_HOLDING_CHECK
|
|
+int co_passage_page_holding_count = 0;
|
|
+#endif
|
|
+bool co_host_fpu_saved = 0;
|
|
+char co_host_fpu[0x200] __attribute__ ((__aligned__(16)));
|
|
+
|
|
+static void __init co_early_cpu_init(void)
|
|
+{
|
|
+ /*
|
|
+ * On the first switch to Linux we must set up a valid TR because
|
|
+ * the passage page code assumes such one exists. This is basically
|
|
+ * copied code from cpu_init().
|
|
+ *
|
|
+ * P.S this is protected by CO_TRACE_STOP so that we don't
|
|
+ * have a monitor context switch.
|
|
+ */
|
|
+ struct task_struct *me;
|
|
+ struct tss_struct *t;
|
|
+ int cpu;
|
|
+ int i;
|
|
+ struct desc_struct *gdt;
|
|
+
|
|
+ cpu = stack_smp_processor_id();
|
|
+ t = &per_cpu(init_tss, cpu);
|
|
+
|
|
+ me = current;
|
|
+
|
|
+ write_cr4(mmu_cr4_features);
|
|
+
|
|
+ /*
|
|
+ * Initialize the per-CPU GDT with the boot GDT,
|
|
+ * and set up the GDT descriptor:
|
|
+ */
|
|
+
|
|
+ switch_to_new_gdt(cpu);
|
|
+ loadsegment(fs, 0);
|
|
+
|
|
+ load_idt(&idt_descr);
|
|
+
|
|
+ memset(me->thread.tls_array, 0, GDT_ENTRY_TLS_ENTRIES * 8);
|
|
+
|
|
+ /*
|
|
+ * Delete NT
|
|
+ */
|
|
+ __asm__("pushfl ; andl $0xffffbfff,(%esp) ; popfl");
|
|
+
|
|
+ t->x86_tss.io_bitmap_base = offsetof(struct tss_struct, io_bitmap);
|
|
+
|
|
+ /*
|
|
+ * <= is required because the CPU will access up to
|
|
+ * 8 bits beyond the end of the IO permission bitmap.
|
|
+ */
|
|
+ for (i = 0; i <= IO_BITMAP_LONGS; i++)
|
|
+ t->io_bitmap[i] = ~0UL;
|
|
+
|
|
+ atomic_inc(&init_mm.mm_count);
|
|
+ me->active_mm = &init_mm;
|
|
+ enter_lazy_tlb(&init_mm, me);
|
|
+
|
|
+ load_sp0(t, ¤t->thread);
|
|
+ set_tss_desc(cpu, t);
|
|
+ gdt = get_cpu_gdt_table(cpu);
|
|
+ gdt[GDT_ENTRY_TSS].b &= 0xfffffdff;
|
|
+
|
|
+ load_TR_desc();
|
|
+ load_LDT(&init_mm.context);
|
|
+
|
|
+ /* Clear %gs. */
|
|
+ asm volatile ("mov %0, %%gs" : : "r" (0));
|
|
+}
|
|
+
|
|
+/*
|
|
+ * 'co_start' is the first Linux code that runs in the
|
|
+ * coLinux kernel context. It receives %ecx which contains the
|
|
+ * address of the passage page. The passage page code sets %ecx
|
|
+ * to this value in its context restore part.
|
|
+ */
|
|
+
|
|
+void __init co_start(void)
|
|
+{
|
|
+ co_early_cpu_init();
|
|
+ co_start_kernel();
|
|
+}
|
|
+
|
|
+static void co_switch_wrapper_protected(void)
|
|
+{
|
|
+ kernel_fpu_begin();
|
|
+
|
|
+ if (co_host_fpu_saved) {
|
|
+ CO_FPU_RESTORE(co_host_fpu);
|
|
+ co_host_fpu_saved = 0;
|
|
+ }
|
|
+
|
|
+ /* And switch... */
|
|
+ co_switch();
|
|
+
|
|
+ kernel_fpu_end();
|
|
+}
|
|
+
|
|
+void co_switch_wrapper(void)
|
|
+{
|
|
+ /* taken from irq.c: debugging check for stack overflow */
|
|
+ long esp;
|
|
+
|
|
+ __asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (THREAD_SIZE - 1));
|
|
+ if (unlikely(esp < (sizeof(struct thread_info) + STACK_WARN))) {
|
|
+ printk("co_switch_wrapper: stack overflow: %ld\n", esp - sizeof(struct thread_info));
|
|
+ co_terminate(CO_TERMINATE_STACK_OVERFLOW);
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_COLINUX_STATS
|
|
+ co_proc_counts.switches[co_passage_page->operation]++;
|
|
+#endif
|
|
+ co_switch_wrapper_protected();
|
|
+}
|
|
+
|
|
+void co_debug(const char *fmt, ...)
|
|
+{
|
|
+}
|
|
+
|
|
+#define MAX_TRACE_POINTS 1024
|
|
+
|
|
+typedef struct {
|
|
+ unsigned char *code;
|
|
+ unsigned char original_byte;
|
|
+ int off;
|
|
+} co_tracepoint_t;
|
|
+
|
|
+co_tracepoint_t tracepoints[MAX_TRACE_POINTS];
|
|
+static int active_tracepoints = 0;
|
|
+
|
|
+void co_kernel_breakpoint(struct pt_regs * regs)
|
|
+{
|
|
+ int i = 0;
|
|
+ unsigned char *code = (unsigned char *)regs->ip;
|
|
+ if (!code)
|
|
+ return;
|
|
+
|
|
+ code--;
|
|
+ for (i=0; i < active_tracepoints; i++) {
|
|
+ if (tracepoints[i].code == code) {
|
|
+ co_debug("TRACEPOINT: %p", code);
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (i == active_tracepoints) {
|
|
+ /* Bad, we don't know this tracepoint */
|
|
+ co_terminate(CO_TERMINATE_INVALID_OPERATION);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ *tracepoints[i].code = tracepoints[i].original_byte;
|
|
+ regs->flags |= (1 << 8); /* Enable TF */
|
|
+ regs->ip = (unsigned long)code;
|
|
+ tracepoints[i].off = 1;
|
|
+}
|
|
+
|
|
+void co_kernel_set_breakpoints(void)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i=0; i < active_tracepoints; i++)
|
|
+ if (tracepoints[i].code && tracepoints[i].off) {
|
|
+ *tracepoints[i].code = 0xcc;
|
|
+ tracepoints[i].off = 0;
|
|
+ }
|
|
+}
|
|
+
|
|
+int co_kernel_debug(struct pt_regs *regs, long error_code, unsigned int condition)
|
|
+{
|
|
+ /* if not a single step trap */
|
|
+ if (!(condition & DR_STEP))
|
|
+ return 0;
|
|
+
|
|
+ /* if userspace */
|
|
+ if (regs->cs & 3)
|
|
+ return 0;
|
|
+
|
|
+ regs->flags &= ~(1 << 8); /* Disable TF */
|
|
+
|
|
+ co_kernel_set_breakpoints();
|
|
+
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+void co_kernel_tracepoint_add(unsigned char *code)
|
|
+{
|
|
+ if (active_tracepoints >= MAX_TRACE_POINTS)
|
|
+ return;
|
|
+
|
|
+ tracepoints[active_tracepoints].code = code;
|
|
+ tracepoints[active_tracepoints].original_byte = *code;
|
|
+ tracepoints[active_tracepoints].off = 0;
|
|
+ active_tracepoints++;
|
|
+ *code = 0xcc;
|
|
+}
|
|
+
|
|
+co_arch_info_t co_arch_info = {
|
|
+ .kernel_cs = __KERNEL_CS,
|
|
+ .kernel_ds = __KERNEL_DS,
|
|
+};
|
|
+
|
|
+CO_TRACE_CONTINUE;
|
|
Index: linux-2.6.33-source/arch/x86/kernel/entry_32.S
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/entry_32.S
|
|
+++ linux-2.6.33-source/arch/x86/kernel/entry_32.S
|
|
@@ -864,7 +864,11 @@
|
|
SAVE_ALL
|
|
TRACE_IRQS_OFF
|
|
movl %esp,%eax
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ call proxy_interrupt_handler
|
|
+#else
|
|
call do_IRQ
|
|
+#endif
|
|
jmp ret_from_intr
|
|
ENDPROC(common_interrupt)
|
|
CFI_ENDPROC
|
|
@@ -917,6 +921,9 @@
|
|
CFI_ADJUST_CFA_OFFSET 4
|
|
pushl $do_device_not_available
|
|
CFI_ADJUST_CFA_OFFSET 4
|
|
+#if defined(CONFIG_COOPERATIVE)
|
|
+ DISABLE_INTERRUPTS(CLBR_NONE) # FIXME: Need we this realy?
|
|
+#endif
|
|
jmp error_code
|
|
CFI_ENDPROC
|
|
END(device_not_available)
|
|
Index: linux-2.6.33-source/arch/x86/kernel/head_32.S
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/head_32.S
|
|
+++ linux-2.6.33-source/arch/x86/kernel/head_32.S
|
|
@@ -359,6 +359,7 @@
|
|
*/
|
|
call setup_idt
|
|
|
|
+ENTRY(co_arch_start_kernel)
|
|
checkCPUtype:
|
|
|
|
movl $-1,X86_CPUID # -1 for no CPUID initially
|
|
@@ -567,6 +568,10 @@
|
|
#endif
|
|
call dump_stack
|
|
hlt_loop:
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ movl $2,%eax /* CO_TERMINATE_PANIC */
|
|
+ call co_terminate
|
|
+#endif
|
|
hlt
|
|
jmp hlt_loop
|
|
|
|
@@ -607,7 +612,11 @@
|
|
__REFDATA
|
|
.align 4
|
|
ENTRY(initial_code)
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ .long start_kernel
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
.long i386_start_kernel
|
|
+#endif
|
|
|
|
/*
|
|
* BSS section
|
|
@@ -655,7 +664,7 @@
|
|
|
|
.data
|
|
ENTRY(stack_start)
|
|
- .long init_thread_union+THREAD_SIZE
|
|
+ .long init_thread_union+THREAD_SIZE-100
|
|
.long __BOOT_DS
|
|
|
|
ready: .byte 0
|
|
Index: linux-2.6.33-source/arch/x86/kernel/setup.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/setup.c
|
|
+++ linux-2.6.33-source/arch/x86/kernel/setup.c
|
|
@@ -49,6 +49,7 @@
|
|
#include <asm/pci-direct.h>
|
|
#include <linux/init_ohci1394_dma.h>
|
|
#include <linux/kvm_para.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
|
|
#include <linux/errno.h>
|
|
#include <linux/kernel.h>
|
|
@@ -299,8 +300,10 @@
|
|
|
|
static void __init reserve_brk(void)
|
|
{
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
if (_brk_end > _brk_start)
|
|
reserve_early(__pa(_brk_start), __pa(_brk_end), "BRK");
|
|
+#endif
|
|
|
|
/* Mark brk area as locked down and no longer taking any
|
|
new allocations */
|
|
@@ -309,6 +312,7 @@
|
|
|
|
#ifdef CONFIG_BLK_DEV_INITRD
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
#define MAX_MAP_CHUNK (NR_FIX_BTMAPS << PAGE_SHIFT)
|
|
static void __init relocate_initrd(void)
|
|
{
|
|
@@ -371,9 +375,20 @@
|
|
ramdisk_image, ramdisk_image + ramdisk_size - 1,
|
|
ramdisk_here, ramdisk_here + ramdisk_size - 1);
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
static void __init reserve_initrd(void)
|
|
{
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ if (co_boot_params.co_initrd != NULL) {
|
|
+ initrd_start = (unsigned long)co_boot_params.co_initrd;
|
|
+ initrd_end = (unsigned long)co_boot_params.co_initrd + co_boot_params.co_initrd_size;
|
|
+ printk(KERN_INFO "initrd enabled: 0x%lx-0x%lx size: 0x%08lx\n",
|
|
+ initrd_start, initrd_end, co_boot_params.co_initrd_size);
|
|
+
|
|
+ reserve_bootmem(virt_to_phys(co_boot_params.co_initrd), co_boot_params.co_initrd_size, BOOTMEM_DEFAULT);
|
|
+ }
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
u64 ramdisk_image = boot_params.hdr.ramdisk_image;
|
|
u64 ramdisk_size = boot_params.hdr.ramdisk_size;
|
|
u64 ramdisk_end = ramdisk_image + ramdisk_size;
|
|
@@ -410,6 +425,7 @@
|
|
relocate_initrd();
|
|
|
|
free_early(ramdisk_image, ramdisk_end);
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
}
|
|
#else
|
|
static void __init reserve_initrd(void)
|
|
@@ -417,6 +433,7 @@
|
|
}
|
|
#endif /* CONFIG_BLK_DEV_INITRD */
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static void __init parse_setup_data(void)
|
|
{
|
|
struct setup_data *data;
|
|
@@ -482,6 +499,7 @@
|
|
early_iounmap(data, sizeof(*data));
|
|
}
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
/*
|
|
* --------- Crashkernel reservation ------------------------------
|
|
@@ -549,6 +567,7 @@
|
|
}
|
|
#endif
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static struct resource standard_io_resources[] = {
|
|
{ .name = "dma1", .start = 0x00, .end = 0x1f,
|
|
.flags = IORESOURCE_BUSY | IORESOURCE_IO },
|
|
@@ -581,6 +600,7 @@
|
|
request_resource(&ioport_resource, &standard_io_resources[i]);
|
|
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
/*
|
|
* Note: elfcorehdr_addr is not just limited to vmcore. It is also used by
|
|
@@ -618,6 +638,7 @@
|
|
}
|
|
#endif
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
/* List of systems that have known low memory corruption BIOS problems */
|
|
static struct dmi_system_id __initdata bad_bios_dmi_table[] = {
|
|
#ifdef CONFIG_X86_RESERVE_LOW_64K
|
|
@@ -677,6 +698,7 @@
|
|
#endif
|
|
{}
|
|
};
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
/*
|
|
* Determine if we were loaded by an EFI loader. If so, then we have also been
|
|
@@ -751,10 +773,12 @@
|
|
|
|
x86_init.oem.arch_setup();
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
setup_memory_map();
|
|
parse_setup_data();
|
|
/* update the e820_saved too */
|
|
e820_reserve_setup_data();
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
copy_edd();
|
|
|
|
@@ -772,6 +796,9 @@
|
|
bss_resource.start = virt_to_phys(&__bss_start);
|
|
bss_resource.end = virt_to_phys(&__bss_stop)-1;
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ strlcpy(boot_command_line, co_boot_params.co_boot_parameters, COMMAND_LINE_SIZE);
|
|
+#endif
|
|
#ifdef CONFIG_CMDLINE_BOOL
|
|
#ifdef CONFIG_CMDLINE_OVERRIDE
|
|
strlcpy(boot_command_line, builtin_cmdline, COMMAND_LINE_SIZE);
|
|
@@ -804,8 +831,10 @@
|
|
/* Must be before kernel pagetables are setup */
|
|
vmi_activate();
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
/* after early param, so could get panic from serial */
|
|
reserve_early_setup_data();
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
if (acpi_mps_check()) {
|
|
#ifdef CONFIG_X86_LOCAL_APIC
|
|
@@ -814,16 +843,19 @@
|
|
setup_clear_cpu_cap(X86_FEATURE_APIC);
|
|
}
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
#ifdef CONFIG_PCI
|
|
if (pci_early_dump_regs)
|
|
early_dump_pci_devices();
|
|
#endif
|
|
|
|
finish_e820_parsing();
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
if (efi_enabled)
|
|
efi_init();
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
dmi_scan_machine();
|
|
|
|
dmi_check_system(bad_bios_dmi_table);
|
|
@@ -835,13 +867,16 @@
|
|
init_hypervisor_platform();
|
|
|
|
x86_init.resources.probe_roms();
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
/* after parse_early_param, so could debug it */
|
|
insert_resource(&iomem_resource, &code_resource);
|
|
insert_resource(&iomem_resource, &data_resource);
|
|
insert_resource(&iomem_resource, &bss_resource);
|
|
|
|
-
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ max_pfn = co_boot_params.co_memory_size >> PAGE_SHIFT;
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
#ifdef CONFIG_X86_32
|
|
if (ppro_with_ram_bug()) {
|
|
e820_update_range(0x70000000ULL, 0x40000ULL, E820_RAM,
|
|
@@ -866,6 +901,7 @@
|
|
mtrr_bp_init();
|
|
if (mtrr_trim_uncached_memory(max_pfn))
|
|
max_pfn = e820_end_of_ram_pfn();
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
|
|
#ifdef CONFIG_X86_32
|
|
/* max_low_pfn get updated here */
|
|
@@ -933,8 +969,6 @@
|
|
init_ohci1394_dma_on_all_controllers();
|
|
#endif
|
|
|
|
- reserve_initrd();
|
|
-
|
|
reserve_crashkernel();
|
|
|
|
vsmp_init();
|
|
@@ -961,6 +995,7 @@
|
|
#endif
|
|
|
|
initmem_init(0, max_pfn, acpi, k8);
|
|
+ reserve_initrd();
|
|
|
|
#ifdef CONFIG_X86_64
|
|
/*
|
|
@@ -1018,15 +1053,21 @@
|
|
|
|
kvm_guest_init();
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
e820_reserve_resources();
|
|
e820_mark_nosave_regions(max_low_pfn);
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
x86_init.resources.reserve_resources();
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
e820_setup_gap();
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
#ifdef CONFIG_VT
|
|
-#if defined(CONFIG_VGA_CONSOLE)
|
|
+#ifdef CONFIG_COOPERATIVE_CONSOLE
|
|
+ conswitchp = &colinux_con;
|
|
+#elif defined(CONFIG_VGA_CONSOLE)
|
|
if (!efi_enabled || (efi_mem_type(0xa0000) != EFI_CONVENTIONAL_MEMORY))
|
|
conswitchp = &vga_con;
|
|
#elif defined(CONFIG_DUMMY_CONSOLE)
|
|
@@ -1040,6 +1081,7 @@
|
|
|
|
#ifdef CONFIG_X86_32
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static struct resource video_ram_resource = {
|
|
.name = "Video RAM area",
|
|
.start = 0xa0000,
|
|
@@ -1052,5 +1094,6 @@
|
|
request_resource(&iomem_resource, &video_ram_resource);
|
|
reserve_standard_io_resources();
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
#endif /* CONFIG_X86_32 */
|
|
Index: linux-2.6.33-source/arch/x86/kernel/traps.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/traps.c
|
|
+++ linux-2.6.33-source/arch/x86/kernel/traps.c
|
|
@@ -30,6 +30,7 @@
|
|
#include <linux/mm.h>
|
|
#include <linux/smp.h>
|
|
#include <linux/io.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
|
|
#ifdef CONFIG_EISA
|
|
#include <linux/ioport.h>
|
|
@@ -56,6 +57,7 @@
|
|
#include <asm/mce.h>
|
|
|
|
#include <asm/mach_traps.h>
|
|
+#include <asm/cooperative_internal.h>
|
|
|
|
#ifdef CONFIG_X86_64
|
|
#include <asm/x86_init.h>
|
|
@@ -172,6 +174,10 @@
|
|
return;
|
|
|
|
kernel_trap:
|
|
+ if (cooperative_mode_enabled() && trapnr == 3) {
|
|
+ co_kernel_breakpoint(regs);
|
|
+ return;
|
|
+ }
|
|
if (!fixup_exception(regs)) {
|
|
tsk->thread.error_code = error_code;
|
|
tsk->thread.trap_no = trapnr;
|
|
@@ -308,6 +314,7 @@
|
|
die("general protection fault", regs, error_code);
|
|
}
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static notrace __kprobes void
|
|
mem_parity_error(unsigned char reason, struct pt_regs *regs)
|
|
{
|
|
@@ -431,6 +438,7 @@
|
|
reassert_nmi();
|
|
#endif
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
dotraplinkage notrace __kprobes void
|
|
do_nmi(struct pt_regs *regs, long error_code)
|
|
@@ -439,8 +447,10 @@
|
|
|
|
inc_irq_stat(__nmi_count);
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
if (!ignore_nmis)
|
|
default_do_nmi(regs);
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
nmi_exit();
|
|
}
|
|
@@ -558,6 +568,10 @@
|
|
/* Store the virtualized DR6 value */
|
|
tsk->thread.debugreg6 = dr6;
|
|
|
|
+ if (cooperative_mode_enabled() &&
|
|
+ co_kernel_debug(regs, error_code, dr6))
|
|
+ return;
|
|
+
|
|
if (notify_die(DIE_DEBUG, "debug", regs, PTR_ERR(&dr6), error_code,
|
|
SIGTRAP) == NOTIFY_STOP)
|
|
return;
|
|
@@ -833,6 +847,13 @@
|
|
|
|
clts(); /* Allow maths ops (or we recurse) */
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ if (!co_host_fpu_saved) {
|
|
+ CO_FPU_SAVE(co_host_fpu);
|
|
+ co_host_fpu_saved = 1;
|
|
+ }
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
+
|
|
__math_state_restore();
|
|
}
|
|
EXPORT_SYMBOL_GPL(math_state_restore);
|
|
Index: linux-2.6.33-source/arch/x86/mm/fault.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/mm/fault.c
|
|
+++ linux-2.6.33-source/arch/x86/mm/fault.c
|
|
@@ -317,7 +317,7 @@
|
|
goto out;
|
|
|
|
pte = pte_offset_kernel(pmd, address);
|
|
- printk("*pte = %0*Lx ", sizeof(*pte) * 2, (u64)pte_val(*pte));
|
|
+ printk("*pte = %0*Lx ", sizeof(*pte) * 2, (u64)CO_P_TO_PP(pte_val(*pte)));
|
|
out:
|
|
printk("\n");
|
|
}
|
|
Index: linux-2.6.33-source/arch/x86/mm/init_32.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/mm/init_32.c
|
|
+++ linux-2.6.33-source/arch/x86/mm/init_32.c
|
|
@@ -27,6 +27,7 @@
|
|
#include <linux/bootmem.h>
|
|
#include <linux/slab.h>
|
|
#include <linux/proc_fs.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
#include <linux/memory_hotplug.h>
|
|
#include <linux/initrd.h>
|
|
#include <linux/cpumask.h>
|
|
@@ -54,10 +55,15 @@
|
|
|
|
unsigned long highstart_pfn, highend_pfn;
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static noinline int do_test_wp_bit(void);
|
|
+#endif
|
|
|
|
bool __read_mostly __vmalloc_start_set = false;
|
|
|
|
+/* colinux start_va */
|
|
+static long co_start_va = 0;
|
|
+
|
|
static __init void *alloc_low_page(void)
|
|
{
|
|
unsigned long pfn = e820_table_end++;
|
|
@@ -121,7 +127,7 @@
|
|
page_table = (pte_t *)alloc_low_page();
|
|
|
|
paravirt_alloc_pte(&init_mm, __pa(page_table) >> PAGE_SHIFT);
|
|
- set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
|
|
+ set_pmd(pmd, __pmd(CO_PP_TO_P(__pa(page_table)) | _PAGE_TABLE));
|
|
BUG_ON(page_table != pte_offset_kernel(pmd, 0));
|
|
}
|
|
|
|
@@ -223,6 +229,7 @@
|
|
}
|
|
}
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static inline int is_kernel_text(unsigned long addr)
|
|
{
|
|
if (addr >= PAGE_OFFSET && addr <= (unsigned long)__init_end)
|
|
@@ -370,6 +377,7 @@
|
|
}
|
|
return 0;
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
pte_t *kmap_pte;
|
|
pgprot_t kmap_prot;
|
|
@@ -471,6 +479,7 @@
|
|
|
|
void __init native_pagetable_setup_start(pgd_t *base)
|
|
{
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
unsigned long pfn, va;
|
|
pgd_t *pgd;
|
|
pud_t *pud;
|
|
@@ -499,6 +508,7 @@
|
|
pte_clear(NULL, va, pte);
|
|
}
|
|
paravirt_alloc_pmd(&init_mm, __pa(base) >> PAGE_SHIFT);
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
}
|
|
|
|
void __init native_pagetable_setup_done(pgd_t *base)
|
|
@@ -717,7 +727,18 @@
|
|
num_physpages = highend_pfn;
|
|
high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
|
|
#else
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ /* Allocate boot memory from host */
|
|
+ max_low_pfn = max_pfn = co_boot_params.co_memory_size >> PAGE_SHIFT;
|
|
+ min_low_pfn = PFN_UP(__pa((unsigned long)&_end)) + 0x10;
|
|
+ co_start_va = (unsigned long)__va(min_low_pfn << PAGE_SHIFT);
|
|
+ co_alloc_pages(co_start_va, 0x20);
|
|
+
|
|
+ /* Add single region without check via e820_find_active_region */
|
|
+ add_active_range(0, 0, max_low_pfn);
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
e820_register_active_regions(0, 0, max_low_pfn);
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
sparse_memory_present_with_active_regions(0);
|
|
num_physpages = max_low_pfn;
|
|
high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
|
|
@@ -738,8 +759,10 @@
|
|
{
|
|
unsigned long max_zone_pfns[MAX_NR_ZONES];
|
|
memset(max_zone_pfns, 0, sizeof(max_zone_pfns));
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
max_zone_pfns[ZONE_DMA] =
|
|
virt_to_phys((char *)MAX_DMA_ADDRESS) >> PAGE_SHIFT;
|
|
+#endif
|
|
max_zone_pfns[ZONE_NORMAL] = max_low_pfn;
|
|
#ifdef CONFIG_HIGHMEM
|
|
max_zone_pfns[ZONE_HIGHMEM] = highend_pfn;
|
|
@@ -748,6 +771,7 @@
|
|
free_area_init_nodes(max_zone_pfns);
|
|
}
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static unsigned long __init setup_node_bootmem(int nodeid,
|
|
unsigned long start_pfn,
|
|
unsigned long end_pfn,
|
|
@@ -768,25 +792,40 @@
|
|
|
|
return bootmap + bootmap_size;
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
void __init setup_bootmem_allocator(void)
|
|
{
|
|
- int nodeid;
|
|
- unsigned long bootmap_size, bootmap;
|
|
/*
|
|
* Initialize the boot-time allocator (with low memory only):
|
|
*/
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ unsigned long bootmap_size;
|
|
+
|
|
+ bootmap_size = init_bootmem(min_low_pfn, max_low_pfn);
|
|
+ {
|
|
+ unsigned long bootmem_end = co_start_va + bootmap_size + (0x10 << PAGE_SHIFT);
|
|
+ unsigned long physical_end = __PAGE_OFFSET + (max_low_pfn << PAGE_SHIFT);
|
|
+
|
|
+ free_bootmem(__pa(bootmem_end), physical_end - bootmem_end);
|
|
+ }
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
+ int nodeid;
|
|
+ unsigned long bootmap_size, bootmap;
|
|
+
|
|
bootmap_size = bootmem_bootmap_pages(max_low_pfn)<<PAGE_SHIFT;
|
|
bootmap = find_e820_area(0, max_pfn_mapped<<PAGE_SHIFT, bootmap_size,
|
|
PAGE_SIZE);
|
|
if (bootmap == -1L)
|
|
panic("Cannot find bootmem map of size %ld\n", bootmap_size);
|
|
reserve_early(bootmap, bootmap + bootmap_size, "BOOTMAP");
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
|
|
printk(KERN_INFO " mapped low ram: 0 - %08lx\n",
|
|
max_pfn_mapped<<PAGE_SHIFT);
|
|
printk(KERN_INFO " low ram: 0 - %08lx\n", max_low_pfn<<PAGE_SHIFT);
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
for_each_online_node(nodeid) {
|
|
unsigned long start_pfn, end_pfn;
|
|
|
|
@@ -804,6 +843,7 @@
|
|
bootmap = setup_node_bootmem(nodeid, start_pfn, end_pfn,
|
|
bootmap);
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
after_bootmem = 1;
|
|
}
|
|
@@ -836,6 +876,7 @@
|
|
* black magic jumps to work around some nasty CPU bugs, but fortunately the
|
|
* switch to using exceptions got rid of all that.
|
|
*/
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static void __init test_wp_bit(void)
|
|
{
|
|
printk(KERN_INFO
|
|
@@ -856,13 +897,16 @@
|
|
printk(KERN_CONT "Ok.\n");
|
|
}
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
void __init mem_init(void)
|
|
{
|
|
int codesize, reservedpages, datasize, initsize;
|
|
int tmp;
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
pci_iommu_alloc();
|
|
+#endif
|
|
|
|
#ifdef CONFIG_FLATMEM
|
|
BUG_ON(!mem_map);
|
|
@@ -895,15 +939,15 @@
|
|
totalhigh_pages << (PAGE_SHIFT-10));
|
|
|
|
printk(KERN_INFO "virtual kernel memory layout:\n"
|
|
- " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
|
|
+ " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
|
|
#ifdef CONFIG_HIGHMEM
|
|
- " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
|
|
+ " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n"
|
|
#endif
|
|
- " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n"
|
|
- " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
|
|
- " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
|
|
- " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
|
|
- " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ " colinux : 0x%08lx - 0x%08lx (%4ld MB)\n"
|
|
+#endif
|
|
+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n",
|
|
+
|
|
FIXADDR_START, FIXADDR_TOP,
|
|
(FIXADDR_TOP - FIXADDR_START) >> 10,
|
|
|
|
@@ -911,9 +955,19 @@
|
|
PKMAP_BASE, PKMAP_BASE+LAST_PKMAP*PAGE_SIZE,
|
|
(LAST_PKMAP*PAGE_SIZE) >> 10,
|
|
#endif
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ CO_VPTR_BASE_START, CO_VPTR_BASE_END,
|
|
+ (CO_VPTR_BASE_END - CO_VPTR_BASE_START) >> 20,
|
|
+#endif
|
|
|
|
VMALLOC_START, VMALLOC_END,
|
|
- (VMALLOC_END - VMALLOC_START) >> 20,
|
|
+ (VMALLOC_END - VMALLOC_START) >> 20);
|
|
+
|
|
+ printk(KERN_INFO
|
|
+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n"
|
|
+ " .init : 0x%08lx - 0x%08lx (%4ld kB)\n"
|
|
+ " .data : 0x%08lx - 0x%08lx (%4ld kB)\n"
|
|
+ " .text : 0x%08lx - 0x%08lx (%4ld kB)\n",
|
|
|
|
(unsigned long)__va(0), (unsigned long)high_memory,
|
|
((unsigned long)high_memory - (unsigned long)__va(0)) >> 20,
|
|
@@ -946,11 +1000,19 @@
|
|
BUG_ON(PKMAP_BASE + LAST_PKMAP*PAGE_SIZE > FIXADDR_START);
|
|
BUG_ON(VMALLOC_END > PKMAP_BASE);
|
|
#endif
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ BUG_ON(CO_VPTR_BASE_END > FIXADDR_START);
|
|
+ BUG_ON(VMALLOC_END > CO_VPTR_BASE_START);
|
|
+ if (VMALLOC_START > VMALLOC_END)
|
|
+ panic("LOWMEM overlaps vmalloc. Decrease total memory with 'mem=...'!");
|
|
+#endif
|
|
BUG_ON(VMALLOC_START >= VMALLOC_END);
|
|
BUG_ON((unsigned long)high_memory > VMALLOC_START);
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
if (boot_cpu_data.wp_works_ok < 0)
|
|
test_wp_bit();
|
|
+#endif
|
|
|
|
save_pg_dir();
|
|
zap_low_mappings(true);
|
|
@@ -972,6 +1034,7 @@
|
|
* This function cannot be __init, since exceptions don't work in that
|
|
* section. Put this after the callers, so that it cannot be inlined.
|
|
*/
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static noinline int do_test_wp_bit(void)
|
|
{
|
|
char tmp_reg;
|
|
@@ -991,6 +1054,7 @@
|
|
|
|
return flag;
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
#ifdef CONFIG_DEBUG_RODATA
|
|
const int rodata_test_data = 0xC3;
|
|
Index: linux-2.6.33-source/arch/x86/mm/init.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/mm/init.c
|
|
+++ linux-2.6.33-source/arch/x86/mm/init.c
|
|
@@ -28,6 +28,7 @@
|
|
#endif
|
|
;
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static void __init find_early_table_space(unsigned long end, int use_pse,
|
|
int use_gbpages)
|
|
{
|
|
@@ -86,6 +87,7 @@
|
|
printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n",
|
|
end, e820_table_start << PAGE_SHIFT, e820_table_top << PAGE_SHIFT);
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
struct map_range {
|
|
unsigned long start;
|
|
@@ -146,6 +148,7 @@
|
|
use_gbpages = direct_gbpages;
|
|
#endif
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
/* Enable PSE if available */
|
|
if (cpu_has_pse)
|
|
set_in_cr4(X86_CR4_PSE);
|
|
@@ -160,6 +163,7 @@
|
|
page_size_mask |= 1 << PG_LEVEL_1G;
|
|
if (use_pse)
|
|
page_size_mask |= 1 << PG_LEVEL_2M;
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
memset(mr, 0, sizeof(mr));
|
|
nr_range = 0;
|
|
@@ -256,6 +260,9 @@
|
|
(mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":(
|
|
(mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k"));
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ ret = end;
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
/*
|
|
* Find space for the kernel direct mapping tables.
|
|
*
|
|
@@ -310,6 +317,7 @@
|
|
|
|
if (!after_bootmem)
|
|
early_memtest(start, end);
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
|
|
return ret >> PAGE_SHIFT;
|
|
}
|
|
@@ -349,16 +357,20 @@
|
|
* create a kernel page fault:
|
|
*/
|
|
#ifdef CONFIG_DEBUG_PAGEALLOC
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n",
|
|
begin, PAGE_ALIGN(end));
|
|
set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
#else
|
|
/*
|
|
* We just marked the kernel text read only above, now that
|
|
* we are going to free part of that, we need to make that
|
|
* writeable first.
|
|
*/
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
set_memory_rw(begin, (end - begin) >> PAGE_SHIFT);
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
printk(KERN_INFO "Freeing %s: %luk freed\n", what, (end - begin) >> 10);
|
|
|
|
Index: linux-2.6.33-source/arch/x86/mm/pageattr.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/mm/pageattr.c
|
|
+++ linux-2.6.33-source/arch/x86/mm/pageattr.c
|
|
@@ -1122,6 +1122,8 @@
|
|
}
|
|
EXPORT_SYMBOL(set_memory_nx);
|
|
|
|
+// FIXME: Make it usable. Flags must change on host too
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
int set_memory_ro(unsigned long addr, int numpages)
|
|
{
|
|
return change_page_attr_clear(&addr, numpages, __pgprot(_PAGE_RW), 0);
|
|
@@ -1138,6 +1140,7 @@
|
|
{
|
|
return change_page_attr_clear(&addr, numpages, __pgprot(_PAGE_PRESENT), 0);
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
int set_memory_4k(unsigned long addr, int numpages)
|
|
{
|
|
@@ -1234,6 +1237,7 @@
|
|
}
|
|
EXPORT_SYMBOL(set_pages_nx);
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
int set_pages_ro(struct page *page, int numpages)
|
|
{
|
|
unsigned long addr = (unsigned long)page_address(page);
|
|
@@ -1247,6 +1251,7 @@
|
|
|
|
return set_memory_rw(addr, numpages);
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
#ifdef CONFIG_DEBUG_PAGEALLOC
|
|
|
|
Index: linux-2.6.33-source/arch/x86/mm/ioremap.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/mm/ioremap.c
|
|
+++ linux-2.6.33-source/arch/x86/mm/ioremap.c
|
|
@@ -13,6 +13,7 @@
|
|
#include <linux/slab.h>
|
|
#include <linux/vmalloc.h>
|
|
#include <linux/mmiotrace.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
|
|
#include <asm/cacheflush.h>
|
|
#include <asm/e820.h>
|
|
@@ -26,8 +27,10 @@
|
|
|
|
int page_is_ram(unsigned long pagenr)
|
|
{
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
resource_size_t addr, end;
|
|
int i;
|
|
+#endif
|
|
|
|
/*
|
|
* A special case is the first 4Kb of memory;
|
|
@@ -45,6 +48,7 @@
|
|
pagenr < (BIOS_END >> PAGE_SHIFT))
|
|
return 0;
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
for (i = 0; i < e820.nr_map; i++) {
|
|
/*
|
|
* Not usable memory:
|
|
@@ -58,6 +62,7 @@
|
|
if ((pagenr >= addr) && (pagenr < end))
|
|
return 1;
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
return 0;
|
|
}
|
|
|
|
@@ -87,6 +92,7 @@
|
|
return err;
|
|
}
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
/*
|
|
* Remap an arbitrary physical address space into the kernel virtual
|
|
* address space. Needed when the kernel wants to access high addresses
|
|
@@ -216,6 +222,7 @@
|
|
free_memtype(phys_addr, phys_addr + size);
|
|
return NULL;
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
/**
|
|
* ioremap_nocache - map bus memory into CPU space
|
|
@@ -240,6 +247,11 @@
|
|
*/
|
|
void __iomem *ioremap_nocache(resource_size_t phys_addr, unsigned long size)
|
|
{
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ panic("ioremap_nocache %zu:%lu\n", phys_addr, size);
|
|
+ return NULL;
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
+
|
|
/*
|
|
* Ideally, this should be:
|
|
* pat_enabled ? _PAGE_CACHE_UC : _PAGE_CACHE_UC_MINUS;
|
|
@@ -251,6 +263,7 @@
|
|
|
|
return __ioremap_caller(phys_addr, size, val,
|
|
__builtin_return_address(0));
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
}
|
|
EXPORT_SYMBOL(ioremap_nocache);
|
|
|
|
@@ -266,26 +279,41 @@
|
|
*/
|
|
void __iomem *ioremap_wc(resource_size_t phys_addr, unsigned long size)
|
|
{
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ panic("ioremap_wc %zu:%lu\n", phys_addr, size);
|
|
+ return NULL;
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
if (pat_enabled)
|
|
return __ioremap_caller(phys_addr, size, _PAGE_CACHE_WC,
|
|
__builtin_return_address(0));
|
|
else
|
|
return ioremap_nocache(phys_addr, size);
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
}
|
|
EXPORT_SYMBOL(ioremap_wc);
|
|
|
|
void __iomem *ioremap_cache(resource_size_t phys_addr, unsigned long size)
|
|
{
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ panic("ioremap_cache %zu:%lu\n", phys_addr, size);
|
|
+ return NULL;
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
return __ioremap_caller(phys_addr, size, _PAGE_CACHE_WB,
|
|
__builtin_return_address(0));
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
}
|
|
EXPORT_SYMBOL(ioremap_cache);
|
|
|
|
void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
|
|
unsigned long prot_val)
|
|
{
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ panic("ioremap_prot %zu:%lu\n", phys_addr, size);
|
|
+ return NULL;
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
return __ioremap_caller(phys_addr, size, (prot_val & _PAGE_CACHE_MASK),
|
|
__builtin_return_address(0));
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
}
|
|
EXPORT_SYMBOL(ioremap_prot);
|
|
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/bug.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/bug.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/bug.h
|
|
@@ -4,6 +4,10 @@
|
|
#ifdef CONFIG_BUG
|
|
#define HAVE_ARCH_BUG
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+extern void co_terminate_bug(int code, int line, const char *file);
|
|
+#define BUG() do { co_terminate_bug(0, __LINE__, __FILE__); } while(0)
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
|
|
|
#ifdef CONFIG_X86_32
|
|
@@ -34,6 +38,7 @@
|
|
#endif
|
|
|
|
#endif /* !CONFIG_BUG */
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
|
|
#include <asm-generic/bug.h>
|
|
#endif /* _ASM_X86_BUG_H */
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/cooperative.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/cooperative.h
|
|
@@ -0,0 +1,205 @@
|
|
+/*
|
|
+ * linux/include/asm/cooperative.h
|
|
+ *
|
|
+ * Copyright (C) 2004 Dan Aloni
|
|
+ *
|
|
+ * This file defines the lower level interfaces between the Cooperative Linux
|
|
+ * kernel and the host OS driver. It's for both external inclusion from the
|
|
+ * and internal inclusion in the kernel sources.
|
|
+ */
|
|
+
|
|
+#ifndef __LINUX_ASM_COOPERATIVE_H__
|
|
+#define __LINUX_ASM_COOPERATIVE_H__
|
|
+
|
|
+typedef struct {
|
|
+ unsigned short size;
|
|
+ struct x86_idt_entry *table;
|
|
+} __attribute__((packed)) x86_idt_t;
|
|
+
|
|
+typedef struct {
|
|
+ unsigned short limit;
|
|
+ struct x86_dt_entry *base;
|
|
+} __attribute__((packed)) x86_gdt_t;
|
|
+
|
|
+typedef struct {
|
|
+ unsigned char border2[0x4];
|
|
+
|
|
+ unsigned long cs;
|
|
+ #define CO_ARCH_STATE_STACK_CS "0x04"
|
|
+
|
|
+ unsigned long ds;
|
|
+ #define CO_ARCH_STATE_STACK_DS "0x08"
|
|
+
|
|
+ unsigned long es;
|
|
+ #define CO_ARCH_STATE_STACK_ES "0x0C"
|
|
+
|
|
+ unsigned long cr3;
|
|
+ #define CO_ARCH_STATE_STACK_CR3 "0x10"
|
|
+
|
|
+ unsigned long cr4;
|
|
+ #define CO_ARCH_STATE_STACK_CR4 "0x14"
|
|
+
|
|
+ unsigned long cr2;
|
|
+ #define CO_ARCH_STATE_STACK_CR2 "0x18"
|
|
+
|
|
+ unsigned long cr0;
|
|
+ #define CO_ARCH_STATE_STACK_CR0 "0x1C"
|
|
+
|
|
+ x86_gdt_t gdt;
|
|
+ #define CO_ARCH_STATE_STACK_GDT "0x20"
|
|
+
|
|
+ unsigned long fs;
|
|
+ #define CO_ARCH_STATE_STACK_FS "0x26"
|
|
+
|
|
+ unsigned long gs;
|
|
+ #define CO_ARCH_STATE_STACK_GS "0x2A"
|
|
+
|
|
+ unsigned short ldt;
|
|
+ #define CO_ARCH_STATE_STACK_LDT "0x2E"
|
|
+
|
|
+ x86_idt_t idt;
|
|
+ #define CO_ARCH_STATE_STACK_IDT "0x30"
|
|
+
|
|
+ unsigned short tr;
|
|
+ #define CO_ARCH_STATE_STACK_TR "0x36"
|
|
+
|
|
+ unsigned long return_eip;
|
|
+ #define CO_ARCH_STATE_STACK_RETURN_EIP "0x38"
|
|
+
|
|
+ unsigned long flags;
|
|
+ #define CO_ARCH_STATE_STACK_FLAGS "0x3C"
|
|
+
|
|
+ unsigned long esp;
|
|
+ #define CO_ARCH_STATE_STACK_ESP "0x40"
|
|
+
|
|
+ unsigned long ss;
|
|
+ #define CO_ARCH_STATE_STACK_SS "0x44"
|
|
+
|
|
+ unsigned long dr0;
|
|
+ #define CO_ARCH_STATE_STACK_DR0 "0x48"
|
|
+
|
|
+ unsigned long dr1;
|
|
+ #define CO_ARCH_STATE_STACK_DR1 "0x4C"
|
|
+
|
|
+ unsigned long dr2;
|
|
+ #define CO_ARCH_STATE_STACK_DR2 "0x50"
|
|
+
|
|
+ unsigned long dr3;
|
|
+ #define CO_ARCH_STATE_STACK_DR3 "0x54"
|
|
+
|
|
+ unsigned long dr6;
|
|
+ #define CO_ARCH_STATE_STACK_DR6 "0x58"
|
|
+
|
|
+ unsigned long dr7;
|
|
+ #define CO_ARCH_STATE_STACK_DR7 "0x5C"
|
|
+
|
|
+ union {
|
|
+ unsigned long temp_cr3;
|
|
+ unsigned long other_map;
|
|
+ } __attribute__((packed));
|
|
+ #define CO_ARCH_STATE_STACK_TEMP_CR3 "0x60"
|
|
+ #define CO_ARCH_STATE_STACK_OTHERMAP "0x60"
|
|
+
|
|
+ unsigned long relocate_eip;
|
|
+ #define CO_ARCH_STATE_STACK_RELOCATE_EIP "0x64"
|
|
+
|
|
+ unsigned long pad1;
|
|
+ #define CO_ARCH_STATE_STACK_RELOCATE_EIP_AFTER "0x68"
|
|
+
|
|
+ unsigned long va;
|
|
+ #define CO_ARCH_STATE_STACK_VA "0x6C"
|
|
+
|
|
+ unsigned long sysenter_cs;
|
|
+ #define CO_ARCH_STATE_SYSENTER_CS "0x70"
|
|
+
|
|
+ unsigned long sysenter_esp;
|
|
+ #define CO_ARCH_STATE_SYSENTER_ESP "0x74"
|
|
+
|
|
+ unsigned long sysenter_eip;
|
|
+ #define CO_ARCH_STATE_SYSENTER_EIP "0x78"
|
|
+} __attribute__((packed)) co_arch_state_stack_t;
|
|
+
|
|
+#define CO_MAX_PARAM_SIZE 0x400
|
|
+
|
|
+typedef struct co_arch_passage_page_normal_address_space {
|
|
+ unsigned long pgd[0x400];
|
|
+ unsigned long pte[2][0x400];
|
|
+} co_arch_passage_page_normal_address_space_t;
|
|
+
|
|
+typedef struct co_arch_passage_page_pae_address_space {
|
|
+ unsigned long long main[0x200];
|
|
+ unsigned long long pgd[2][0x200];
|
|
+ unsigned long long pte[2][0x200];
|
|
+} co_arch_passage_page_pae_address_space_t;
|
|
+
|
|
+typedef struct co_arch_passage_page {
|
|
+ union {
|
|
+ struct {
|
|
+ union {
|
|
+ struct {
|
|
+ union {
|
|
+ unsigned long self_physical_address;
|
|
+ unsigned long temp_pgd_physical;
|
|
+ } __attribute__((packed));
|
|
+ unsigned long dr0;
|
|
+ unsigned long dr1;
|
|
+ unsigned long dr2;
|
|
+ unsigned long dr3;
|
|
+ unsigned long dr6;
|
|
+ unsigned long dr7;
|
|
+ unsigned char code[0x260];
|
|
+ } __attribute__((packed));
|
|
+ unsigned char pad[0x280]; /* Be careful! see NOTE below */
|
|
+ } __attribute__((packed));
|
|
+
|
|
+ /* Machine states */
|
|
+
|
|
+ /*
|
|
+ * NOTE: *_state fields must be aligned at 16 bytes boundary since
|
|
+ * the fxsave/fxload instructions expect an aligned arugment.
|
|
+ */
|
|
+
|
|
+ co_arch_state_stack_t host_state;
|
|
+ co_arch_state_stack_t linuxvm_state;
|
|
+
|
|
+ /* Control parameters */
|
|
+ unsigned long operation;
|
|
+ unsigned long params[];
|
|
+ } __attribute__((packed));
|
|
+ unsigned char first_page[0x1000];
|
|
+ };
|
|
+
|
|
+ /* page tables for passage address spaces */
|
|
+ union {
|
|
+ co_arch_passage_page_normal_address_space_t guest_normal;
|
|
+ co_arch_passage_page_normal_address_space_t temp_space;
|
|
+ } __attribute__((packed));
|
|
+ union {
|
|
+ co_arch_passage_page_normal_address_space_t host_normal;
|
|
+ co_arch_passage_page_pae_address_space_t host_pae;
|
|
+ } __attribute__((packed));
|
|
+} co_arch_passage_page_t;
|
|
+
|
|
+/*
|
|
+ * Address space layout:
|
|
+ */
|
|
+
|
|
+#define CO_VPTR_BASE (0xffc00000UL)
|
|
+#define CO_VPTR_PHYSICAL_TO_PSEUDO_PFN_MAP (CO_VPTR_BASE - 0x1000000UL)
|
|
+#define CO_VPTR_PSEUDO_RAM_PAGE_TABLES (CO_VPTR_BASE - 0x1100000UL)
|
|
+#define CO_VPTR_PASSAGE_PAGE (CO_VPTR_BASE - 0x1101000UL)
|
|
+#define CO_VPTR_IO_AREA_SIZE (0x10000UL)
|
|
+#define CO_VPTR_IO_AREA_START (CO_VPTR_BASE - 0x1200000UL)
|
|
+#define CO_VPTR_SELF_MAP (CO_VPTR_BASE - 0x1400000UL)
|
|
+
|
|
+#define CO_VPTR_BASE_START CO_VPTR_SELF_MAP
|
|
+#define CO_VPTR_BASE_END CO_VPTR_BASE
|
|
+
|
|
+#define CO_LOWMEMORY_MAX_MB 984
|
|
+
|
|
+typedef struct {
|
|
+ unsigned long kernel_cs;
|
|
+ unsigned long kernel_ds;
|
|
+} __attribute__((packed)) co_arch_info_t;
|
|
+
|
|
+#endif
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/cooperative_internal.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/cooperative_internal.h
|
|
@@ -0,0 +1,53 @@
|
|
+/*
|
|
+ * linux/include/asm/cooperative_internal.h
|
|
+ *
|
|
+ * Copyright (C) 2004 Dan Aloni
|
|
+ */
|
|
+
|
|
+#ifndef __LINUX_ASM_COOPERATIVE_INTERNAL_H__
|
|
+#define __LINUX_ASM_COOPERATIVE_INTERNAL_H__
|
|
+
|
|
+#include <asm/ptrace.h>
|
|
+
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+
|
|
+extern bool co_host_fpu_saved;
|
|
+extern char co_host_fpu[0x200];
|
|
+
|
|
+extern void co_kernel_breakpoint(struct pt_regs * regs);
|
|
+extern int co_kernel_debug(struct pt_regs * regs, long error_code, unsigned int condition);
|
|
+
|
|
+#define CO_FPU_SAVE(x) \
|
|
+do \
|
|
+{ \
|
|
+ if (cpu_has_fxsr) \
|
|
+ asm("fxsave " #x " ; fnclex"); \
|
|
+ else \
|
|
+ asm("fnsave " #x " ; fwait"); \
|
|
+} \
|
|
+while (0)
|
|
+
|
|
+#define CO_FPU_RESTORE(x) \
|
|
+do \
|
|
+{ \
|
|
+ if (cpu_has_fxsr) \
|
|
+ asm("fxrstor " #x); \
|
|
+ else \
|
|
+ asm("frstor " #x); \
|
|
+} \
|
|
+while (0)
|
|
+
|
|
+#else
|
|
+
|
|
+static inline void co_kernel_breakpoint(struct pt_regs * regs)
|
|
+{
|
|
+}
|
|
+
|
|
+static inline int co_kernel_debug(struct pt_regs * regs, long error_code, unsigned int condition)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#endif
|
|
+
|
|
+#endif
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/dma.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/dma.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/dma.h
|
|
@@ -287,6 +287,7 @@
|
|
*
|
|
* Assumes DMA flip-flop is clear.
|
|
*/
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
static inline int get_dma_residue(unsigned int dmanr)
|
|
{
|
|
unsigned int io_port;
|
|
@@ -301,6 +302,7 @@
|
|
|
|
return (dmanr <= 3) ? count : (count << 1);
|
|
}
|
|
+#endif
|
|
|
|
|
|
/* These are in kernel/dma.c: */
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/irq_vectors.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/irq_vectors.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/irq_vectors.h
|
|
@@ -67,6 +67,18 @@
|
|
#define IRQ14_VECTOR (IRQ0_VECTOR + 14)
|
|
#define IRQ15_VECTOR (IRQ0_VECTOR + 15)
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+#define TIMER_IRQ 0
|
|
+#define KEYBOARD_IRQ 1
|
|
+#define SERIAL_IRQ 3
|
|
+#define SOUND_IRQ 5
|
|
+#define POWER_IRQ 9
|
|
+#define NETWORK_IRQ 10
|
|
+#define SCSI_IRQ 11
|
|
+#define MOUSE_IRQ 12
|
|
+#define BLOCKDEV_IRQ 15
|
|
+#endif
|
|
+
|
|
/*
|
|
* Special IRQ vectors used by the SMP architecture, 0xf0-0xff
|
|
*
|
|
@@ -157,7 +169,9 @@
|
|
#define CPU_VECTOR_LIMIT ( 8 * NR_CPUS )
|
|
#define IO_APIC_VECTOR_LIMIT ( 32 * MAX_IO_APICS )
|
|
|
|
-#ifdef CONFIG_X86_IO_APIC
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+# define NR_IRQS (NR_VECTORS - FIRST_EXTERNAL_VECTOR)
|
|
+#elif defined(CONFIG_X86_IO_APIC)
|
|
# ifdef CONFIG_SPARSE_IRQ
|
|
# define NR_IRQS \
|
|
(CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ? \
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/mc146818rtc.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/mc146818rtc.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/mc146818rtc.h
|
|
@@ -87,6 +87,8 @@
|
|
#define current_lock_cmos_reg() 0
|
|
#endif
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
+
|
|
/*
|
|
* The yet supported machines all access the RTC index register via
|
|
* an ISA port access but the way to access the date register differs ...
|
|
@@ -99,6 +101,11 @@
|
|
extern int mach_set_rtc_mmss(unsigned long nowtime);
|
|
extern unsigned long mach_get_cmos_time(void);
|
|
|
|
+#else
|
|
+#define CMOS_READ(addr) (0)
|
|
+#define CMOS_WRITE(val, addr) do {} while(0)
|
|
+#endif
|
|
+
|
|
#define RTC_IRQ 8
|
|
|
|
#endif /* _ASM_X86_MC146818RTC_H */
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/page.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/page.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/page.h
|
|
@@ -14,6 +14,7 @@
|
|
#endif /* CONFIG_X86_64 */
|
|
|
|
#ifndef __ASSEMBLY__
|
|
+#include <asm/cooperative.h>
|
|
|
|
struct page;
|
|
|
|
@@ -53,6 +54,20 @@
|
|
extern bool __virt_addr_valid(unsigned long kaddr);
|
|
#define virt_addr_valid(kaddr) __virt_addr_valid((unsigned long) (kaddr))
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+#define CO_PA(pfn) (((unsigned long *)CO_VPTR_PSEUDO_RAM_PAGE_TABLES)[pfn])
|
|
+#define CO_VA_PFN(pa) (((unsigned long *)CO_VPTR_PHYSICAL_TO_PSEUDO_PFN_MAP)[((pa) >> PAGE_SHIFT)])
|
|
+#define CO_PFN_PP_TO_P(pfn) (CO_PA(pfn) >> PAGE_SHIFT)
|
|
+#define CO_PFN_P_TO_PP(pfn) (CO_VA_PFN(pfn << PAGE_SHIFT))
|
|
+#define CO_PP_TO_P(pa) ((CO_PFN_PP_TO_P(pa >> PAGE_SHIFT) << PAGE_SHIFT) | (pa & ~PAGE_MASK))
|
|
+#define CO_P_TO_PP(pa) ((CO_PFN_P_TO_PP(pa >> PAGE_SHIFT) << PAGE_SHIFT) | (pa & ~PAGE_MASK))
|
|
+#else
|
|
+#define CO_PFN_P_TO_PP(pfn) pfn
|
|
+#define CO_PFN_PP_TO_P(pfn) pfn
|
|
+#define CO_PP_TO_P(pa) pa
|
|
+#define CO_P_TO_PP(pa) pa
|
|
+#endif
|
|
+
|
|
#endif /* __ASSEMBLY__ */
|
|
|
|
#include <asm-generic/memory_model.h>
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/pgtable-2level.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/pgtable-2level.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/pgtable-2level.h
|
|
@@ -1,6 +1,8 @@
|
|
#ifndef _ASM_X86_PGTABLE_2LEVEL_H
|
|
#define _ASM_X86_PGTABLE_2LEVEL_H
|
|
|
|
+#include <asm/cooperative.h>
|
|
+
|
|
#define pte_ERROR(e) \
|
|
printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, (e).pte_low)
|
|
#define pgd_ERROR(e) \
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/pgtable.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/pgtable.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/pgtable.h
|
|
@@ -124,7 +124,7 @@
|
|
|
|
static inline unsigned long pte_pfn(pte_t pte)
|
|
{
|
|
- return (pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT;
|
|
+ return CO_PFN_P_TO_PP((pte_val(pte) & PTE_PFN_MASK) >> PAGE_SHIFT);
|
|
}
|
|
|
|
static inline unsigned long pmd_pfn(pmd_t pmd)
|
|
@@ -230,13 +230,13 @@
|
|
|
|
static inline pte_t pfn_pte(unsigned long page_nr, pgprot_t pgprot)
|
|
{
|
|
- return __pte(((phys_addr_t)page_nr << PAGE_SHIFT) |
|
|
+ return __pte(((phys_addr_t)CO_PFN_PP_TO_P(page_nr) << PAGE_SHIFT) |
|
|
massage_pgprot(pgprot));
|
|
}
|
|
|
|
static inline pmd_t pfn_pmd(unsigned long page_nr, pgprot_t pgprot)
|
|
{
|
|
- return __pmd(((phys_addr_t)page_nr << PAGE_SHIFT) |
|
|
+ return __pmd(((phys_addr_t)CO_PFN_PP_TO_P(page_nr) << PAGE_SHIFT) |
|
|
massage_pgprot(pgprot));
|
|
}
|
|
|
|
@@ -341,14 +341,14 @@
|
|
|
|
static inline unsigned long pmd_page_vaddr(pmd_t pmd)
|
|
{
|
|
- return (unsigned long)__va(pmd_val(pmd) & PTE_PFN_MASK);
|
|
+ return (unsigned long)__va(CO_P_TO_PP(pmd_val(pmd)) & PTE_PFN_MASK);
|
|
}
|
|
|
|
/*
|
|
* Currently stuck as a macro due to indirect forward reference to
|
|
* linux/mmzone.h's __section_mem_map_addr() definition:
|
|
*/
|
|
-#define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT)
|
|
+#define pmd_page(pmd) pfn_to_page(CO_P_TO_PP(pmd_val(pmd)) >> PAGE_SHIFT)
|
|
|
|
/*
|
|
* the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/processor.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/processor.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/processor.h
|
|
@@ -243,6 +243,7 @@
|
|
} __attribute__((packed)) ____cacheline_aligned;
|
|
#endif
|
|
|
|
+#ifdef __KERNEL__
|
|
/*
|
|
* IO-bitmap sizes:
|
|
*/
|
|
@@ -677,6 +678,7 @@
|
|
|
|
return eax;
|
|
}
|
|
+#endif /* __KERNEL__ */
|
|
|
|
static inline unsigned int cpuid_ebx(unsigned int op)
|
|
{
|
|
Index: linux-2.6.33-source/include/linux/cooperative.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/include/linux/cooperative.h
|
|
@@ -0,0 +1,399 @@
|
|
+/*
|
|
+ * linux/include/linux/cooperative.h
|
|
+ *
|
|
+ * Copyright (C) 2004 Dan Aloni
|
|
+ *
|
|
+ * This file defines the interfaces between the Cooperative Linux kernel
|
|
+ * and the host OS driver. It's for both external inclusion from the
|
|
+ * and internal inclusion in the kernel sources.
|
|
+ */
|
|
+
|
|
+#ifndef __LINUX_COOPERATIVE_H__
|
|
+#define __LINUX_COOPERATIVE_H__
|
|
+
|
|
+#ifdef __KERNEL__
|
|
+#ifndef CO_KERNEL
|
|
+#define CO_COLINUX_KERNEL
|
|
+#define CO_KERNEL
|
|
+#endif
|
|
+#endif
|
|
+
|
|
+#include <asm/cooperative.h>
|
|
+
|
|
+#define CO_LINUX_API_VERSION 14
|
|
+
|
|
+#pragma pack(0)
|
|
+
|
|
+#define CO_BOOTPARAM_STRING_LENGTH 0x100
|
|
+
|
|
+typedef enum {
|
|
+ CO_OPERATION_EMPTY=0,
|
|
+ CO_OPERATION_START,
|
|
+ CO_OPERATION_IDLE,
|
|
+ CO_OPERATION_TERMINATE,
|
|
+ CO_OPERATION_MESSAGE_TO_MONITOR,
|
|
+ CO_OPERATION_MESSAGE_FROM_MONITOR,
|
|
+ CO_OPERATION_FORWARD_INTERRUPT,
|
|
+ CO_OPERATION_DEVICE,
|
|
+ CO_OPERATION_GET_TIME,
|
|
+ CO_OPERATION_DEBUG_LINE,
|
|
+ CO_OPERATION_GET_HIGH_PREC_TIME,
|
|
+ CO_OPERATION_TRACE_POINT,
|
|
+ CO_OPERATION_FREE_PAGES,
|
|
+ CO_OPERATION_ALLOC_PAGES,
|
|
+ CO_OPERATION_PRINTK_unused,
|
|
+ CO_OPERATION_GETPP,
|
|
+ CO_OPERATION_MAX /* Must be last entry all times */
|
|
+} co_operation_t;
|
|
+
|
|
+#define CO_MODULE_MAX_CONET 16
|
|
+#define CO_MODULE_MAX_COBD 32
|
|
+#define CO_MODULE_MAX_COFS 32
|
|
+#define CO_MODULE_MAX_SERIAL 32
|
|
+#define CO_MODULE_MAX_COSCSI 32
|
|
+#define CO_MODULE_MAX_COVIDEO 2
|
|
+#define CO_MODULE_MAX_COAUDIO 2
|
|
+
|
|
+typedef enum {
|
|
+ CO_MODULE_LINUX,
|
|
+ CO_MODULE_MONITOR,
|
|
+ CO_MODULE_DAEMON,
|
|
+ CO_MODULE_IDLE,
|
|
+ CO_MODULE_KERNEL_SWITCH,
|
|
+ CO_MODULE_USER_SWITCH,
|
|
+ CO_MODULE_CONSOLE,
|
|
+ CO_MODULE_PRINTK,
|
|
+
|
|
+ CO_MODULE_CONET0,
|
|
+ CO_MODULE_CONET_END=CO_MODULE_CONET0+CO_MODULE_MAX_CONET-1,
|
|
+
|
|
+ CO_MODULE_COBD0,
|
|
+ CO_MODULE_COBD_END=CO_MODULE_COBD0+CO_MODULE_MAX_COBD-1,
|
|
+
|
|
+ CO_MODULE_COFS0,
|
|
+ CO_MODULE_COFS_END=CO_MODULE_COFS0+CO_MODULE_MAX_COFS-1,
|
|
+
|
|
+ CO_MODULE_SERIAL0,
|
|
+ CO_MODULE_SERIAL_END=CO_MODULE_SERIAL0+CO_MODULE_MAX_SERIAL-1,
|
|
+
|
|
+ CO_MODULE_COSCSI0,
|
|
+ CO_MODULE_COSCSI_END=CO_MODULE_COSCSI0+CO_MODULE_MAX_COSCSI-1,
|
|
+
|
|
+ CO_MODULE_COVIDEO0,
|
|
+ CO_MODULE_COVIDEO_END=CO_MODULE_COVIDEO0+CO_MODULE_MAX_COVIDEO-1,
|
|
+
|
|
+ CO_MODULE_COAUDIO0,
|
|
+ CO_MODULE_COAUDIO_END=CO_MODULE_COAUDIO0+CO_MODULE_MAX_COAUDIO-1,
|
|
+ CO_MODULES_MAX,
|
|
+} co_module_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_PRIORITY_DISCARDABLE=0,
|
|
+ CO_PRIORITY_IMPORTANT,
|
|
+} co_priority_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_MESSAGE_TYPE_STRING=0,
|
|
+ CO_MESSAGE_TYPE_OTHER=1,
|
|
+} co_message_type_t;
|
|
+
|
|
+typedef struct {
|
|
+ co_module_t from;
|
|
+ co_module_t to;
|
|
+ co_priority_t priority;
|
|
+ co_message_type_t type;
|
|
+ unsigned long size;
|
|
+ unsigned char data[0];
|
|
+} __attribute__((packed)) co_message_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_DEVICE_BLOCK=0,
|
|
+ CO_DEVICE_CONSOLE,
|
|
+ CO_DEVICE_KEYBOARD,
|
|
+ CO_DEVICE_NETWORK,
|
|
+ CO_DEVICE_TIMER,
|
|
+ CO_DEVICE_POWER,
|
|
+ CO_DEVICE_SERIAL,
|
|
+ CO_DEVICE_FILESYSTEM,
|
|
+
|
|
+ CO_DEVICE_MOUSE,
|
|
+ CO_DEVICE_SCSI,
|
|
+ CO_DEVICE_VIDEO,
|
|
+ CO_DEVICE_AUDIO,
|
|
+ CO_DEVICE_PCI,
|
|
+
|
|
+ CO_DEVICES_TOTAL,
|
|
+} co_device_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_KBD_SCANCODE_RAW=0,
|
|
+ CO_KBD_SCANCODE_ASCII
|
|
+} mode_data_from_keyboard_t;
|
|
+
|
|
+typedef struct {
|
|
+ unsigned char code;
|
|
+ mode_data_from_keyboard_t mode;
|
|
+} __attribute__((packed)) co_scan_code_t;
|
|
+
|
|
+#define CO_MOUSE_MAX_X 2048
|
|
+#define CO_MOUSE_MAX_Y 2048
|
|
+
|
|
+typedef struct {
|
|
+ unsigned btns;
|
|
+ unsigned abs_x;
|
|
+ unsigned abs_y;
|
|
+ int rel_z;
|
|
+} __attribute__((packed)) co_mouse_data_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_LINUX_MESSAGE_POWER_ALT_CTRL_DEL=0,
|
|
+ CO_LINUX_MESSAGE_POWER_SHUTDOWN,
|
|
+ CO_LINUX_MESSAGE_POWER_OFF,
|
|
+} co_linux_message_power_type_t;
|
|
+
|
|
+typedef struct {
|
|
+ co_linux_message_power_type_t type;
|
|
+} __attribute__((packed)) co_linux_message_power_t;
|
|
+
|
|
+typedef struct {
|
|
+ unsigned long tick_count;
|
|
+} __attribute__((packed)) co_linux_message_idle_t;
|
|
+
|
|
+typedef struct {
|
|
+ co_device_t device;
|
|
+ unsigned int unit;
|
|
+ unsigned long size;
|
|
+ char data[];
|
|
+} __attribute__((packed)) co_linux_message_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_TERMINATE_END=0,
|
|
+ CO_TERMINATE_REBOOT,
|
|
+ CO_TERMINATE_POWEROFF,
|
|
+ CO_TERMINATE_PANIC,
|
|
+ CO_TERMINATE_HALT,
|
|
+ CO_TERMINATE_FORCED_OFF,
|
|
+ CO_TERMINATE_FORCED_END,
|
|
+ CO_TERMINATE_INVALID_OPERATION,
|
|
+ CO_TERMINATE_STACK_OVERFLOW,
|
|
+ CO_TERMINATE_BUG,
|
|
+ CO_TERMINATE_VMXE,
|
|
+} co_termination_reason_t;
|
|
+
|
|
+#ifdef CO_KERNEL
|
|
+
|
|
+#ifndef asmlinkage
|
|
+#define asmlinkage __attribute__((regparm(0)))
|
|
+#endif
|
|
+
|
|
+typedef void asmlinkage (*co_switcher_t)(co_arch_passage_page_t *page,
|
|
+ void *from,
|
|
+ void *to);
|
|
+
|
|
+#define co_passage_page_func_low(_from_,_to_) \
|
|
+ (((co_switcher_t)(co_passage_page->code)) \
|
|
+ (co_passage_page, \
|
|
+ &_from_.border2, \
|
|
+ &_to_.border2))
|
|
+
|
|
+# ifdef CO_COLINUX_KERNEL
|
|
+# define co_passage_page ((co_arch_passage_page_t *)(CO_VPTR_PASSAGE_PAGE))
|
|
+# define co_current (co_passage_page->linuxvm_state)
|
|
+# define co_other (co_passage_page->host_state)
|
|
+# else
|
|
+# define co_passage_page (cmon->passage_page)
|
|
+# define co_other (co_passage_page->linuxvm_state)
|
|
+# define co_current (co_passage_page->host_state)
|
|
+# endif
|
|
+
|
|
+# define co_switch() co_passage_page_func_low(co_current, co_other)
|
|
+
|
|
+#endif /* CO_KERNEL */
|
|
+
|
|
+/*
|
|
+ * Defines operations on various virtual devices.
|
|
+ */
|
|
+
|
|
+typedef enum {
|
|
+ CO_OPERATION_CONSOLE_STARTUP=0,
|
|
+ CO_OPERATION_CONSOLE_INIT=1,
|
|
+ CO_OPERATION_CONSOLE_DEINIT,
|
|
+ CO_OPERATION_CONSOLE_CLEAR,
|
|
+ CO_OPERATION_CONSOLE_PUTC,
|
|
+ CO_OPERATION_CONSOLE_PUTCS,
|
|
+ CO_OPERATION_CONSOLE_CURSOR_DRAW,
|
|
+ CO_OPERATION_CONSOLE_CURSOR_ERASE,
|
|
+ CO_OPERATION_CONSOLE_CURSOR_MOVE,
|
|
+ CO_OPERATION_CONSOLE_SCROLL_UP,
|
|
+ CO_OPERATION_CONSOLE_SCROLL_DOWN,
|
|
+ CO_OPERATION_CONSOLE_BMOVE,
|
|
+ CO_OPERATION_CONSOLE_SWITCH,
|
|
+ CO_OPERATION_CONSOLE_BLANK,
|
|
+ CO_OPERATION_CONSOLE_FONT_OP,
|
|
+ CO_OPERATION_CONSOLE_SET_PALETTE,
|
|
+ CO_OPERATION_CONSOLE_SCROLLDELTA,
|
|
+ CO_OPERATION_CONSOLE_SET_ORIGIN,
|
|
+ CO_OPERATION_CONSOLE_SAVE_SCREEN,
|
|
+ CO_OPERATION_CONSOLE_INVERT_REGION,
|
|
+ CO_OPERATION_CONSOLE_CONFIG,
|
|
+ CO_OPERATION_CONSOLE_INIT_SCROLLBUFFER,
|
|
+} co_operation_console_t;
|
|
+
|
|
+
|
|
+typedef char co_console_code;
|
|
+typedef unsigned short co_console_character;
|
|
+typedef unsigned short co_console_unit;
|
|
+
|
|
+typedef struct {
|
|
+ co_console_unit x;
|
|
+ co_console_unit y;
|
|
+ co_console_unit height;
|
|
+} __attribute__((packed)) co_cursor_pos_t;
|
|
+
|
|
+typedef struct {
|
|
+ co_operation_console_t type;
|
|
+ union {
|
|
+ struct {
|
|
+ co_console_unit top;
|
|
+ co_console_unit bottom;
|
|
+ co_console_unit lines;
|
|
+ co_console_character charattr;
|
|
+ } scroll;
|
|
+ struct {
|
|
+ co_console_unit y;
|
|
+ co_console_unit x;
|
|
+ co_console_unit count;
|
|
+ co_console_character data[];
|
|
+ } putcs;
|
|
+ struct {
|
|
+ co_console_unit x;
|
|
+ co_console_unit y;
|
|
+ co_console_character charattr;
|
|
+ } putc;
|
|
+ struct {
|
|
+ co_console_unit top;
|
|
+ co_console_unit left;
|
|
+ co_console_unit bottom;
|
|
+ co_console_unit right;
|
|
+ co_console_character charattr;
|
|
+ } clear;
|
|
+ struct {
|
|
+ co_console_unit y;
|
|
+ co_console_unit x;
|
|
+ co_console_unit count;
|
|
+ } invert;
|
|
+ struct {
|
|
+ co_console_unit row;
|
|
+ co_console_unit column;
|
|
+ co_console_unit top;
|
|
+ co_console_unit left;
|
|
+ co_console_unit bottom;
|
|
+ co_console_unit right;
|
|
+ } bmove;
|
|
+ struct {
|
|
+ co_console_unit rows;
|
|
+ co_console_unit cols;
|
|
+ co_console_unit attr;
|
|
+ } config;
|
|
+ co_cursor_pos_t cursor;
|
|
+ };
|
|
+} __attribute__((packed)) co_console_message_t;
|
|
+
|
|
+typedef struct {
|
|
+ unsigned long messages_waiting;
|
|
+ unsigned char buffer[];
|
|
+} co_io_buffer_t;
|
|
+
|
|
+typedef struct {
|
|
+ unsigned long index;
|
|
+ unsigned long flags;
|
|
+ unsigned long func;
|
|
+ unsigned long pid;
|
|
+} __attribute__((packed)) co_trace_point_info_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_BLOCK_OPEN=0,
|
|
+ CO_BLOCK_STAT,
|
|
+ CO_BLOCK_READ,
|
|
+ CO_BLOCK_WRITE,
|
|
+ CO_BLOCK_CLOSE,
|
|
+ CO_BLOCK_GET_ALIAS,
|
|
+} co_block_request_type_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_BLOCK_REQUEST_RETCODE_OK=0,
|
|
+ CO_BLOCK_REQUEST_RETCODE_ERROR=-1,
|
|
+} co_block_request_retcode_t;
|
|
+
|
|
+typedef enum {
|
|
+ CO_NETWORK_GET_MAC=0,
|
|
+} co_network_request_type_t;
|
|
+
|
|
+#ifdef CO_KERNEL
|
|
+/* If we are compiling kernel code (Linux or Host Driver) */
|
|
+# ifdef CO_COLINUX_KERNEL
|
|
+/* Inside Linux, vm_ptr_t considered a valid pointer in its virtual address space */
|
|
+typedef void *vm_ptr_t;
|
|
+# else
|
|
+/* But inside the host, the type is considered not to be a pointer in its own address space */
|
|
+typedef unsigned long vm_ptr_t;
|
|
+# endif
|
|
+
|
|
+typedef struct {
|
|
+ co_block_request_type_t type;
|
|
+ long rc;
|
|
+ union {
|
|
+ struct {
|
|
+ unsigned long long offset;
|
|
+ unsigned long long size;
|
|
+ unsigned long long disk_size;
|
|
+ vm_ptr_t address;
|
|
+ void * irq_request;
|
|
+ int async;
|
|
+ };
|
|
+ struct {
|
|
+ char alias[20];
|
|
+ };
|
|
+ };
|
|
+} __attribute__((packed)) co_block_request_t;
|
|
+
|
|
+typedef struct {
|
|
+ void * irq_request;
|
|
+ int uptodate;
|
|
+} __attribute__((packed)) co_block_intr_t;
|
|
+
|
|
+typedef struct {
|
|
+ co_network_request_type_t type;
|
|
+ unsigned int unit;
|
|
+ char mac_address[6];
|
|
+ char _pad[2];
|
|
+ int result;
|
|
+} __attribute__((packed)) co_network_request_t;
|
|
+
|
|
+#endif /* CO_KERNEL */
|
|
+
|
|
+typedef struct {
|
|
+ unsigned long api_version;
|
|
+ unsigned long compiler_major;
|
|
+ unsigned long compiler_minor;
|
|
+ unsigned long compiler_abi;
|
|
+} __attribute__((packed)) co_info_t;
|
|
+
|
|
+typedef struct {
|
|
+ unsigned long co_core_end;
|
|
+ unsigned long co_memory_size;
|
|
+ void *co_initrd;
|
|
+ unsigned long co_initrd_size;
|
|
+ unsigned long co_cpu_khz;
|
|
+ unsigned long filler[5]; // compatible old api: empty 5,6,7,8,9
|
|
+ char co_boot_parameters[CO_BOOTPARAM_STRING_LENGTH]; // params[10]
|
|
+} __attribute__((packed)) co_boot_params_t;
|
|
+
|
|
+#ifndef COLINUX_TRACE
|
|
+#define CO_TRACE_STOP
|
|
+#define CO_TRACE_CONTINUE
|
|
+#endif
|
|
+
|
|
+#pragma pack()
|
|
+
|
|
+#endif
|
|
Index: linux-2.6.33-source/include/linux/cooperative_internal.h
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/include/linux/cooperative_internal.h
|
|
@@ -0,0 +1,143 @@
|
|
+/*
|
|
+ * linux/include/linux/cooperative_internal.h
|
|
+ *
|
|
+ * Copyright (C) 2004 Dan Aloni
|
|
+ *
|
|
+ * This header gathers the functions and variables in Cooperative Mode
|
|
+ * when CONFIG_COOPERATIVE is defined.
|
|
+ */
|
|
+#ifndef __LINUX_COOPERATIVE_LINUX_H__
|
|
+#define __LINUX_COOPERATIVE_LINUX_H__
|
|
+
|
|
+#include <linux/cooperative.h>
|
|
+#include <linux/list.h>
|
|
+#include <asm/ptrace.h>
|
|
+
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+
|
|
+#define ENABLE_PASSAGE_HOLDING_CHECK
|
|
+
|
|
+typedef struct {
|
|
+ struct list_head node;
|
|
+ co_message_t msg;
|
|
+} co_message_node_t;
|
|
+
|
|
+extern co_boot_params_t co_boot_params;
|
|
+#ifdef ENABLE_PASSAGE_HOLDING_CHECK
|
|
+extern int co_passage_page_holding_count;
|
|
+#endif
|
|
+
|
|
+#ifdef CONFIG_COLINUX_STATS
|
|
+typedef struct co_proc_counts {
|
|
+ unsigned long switches[CO_OPERATION_MAX];
|
|
+} co_proc_counts_t;
|
|
+
|
|
+extern co_proc_counts_t co_proc_counts;
|
|
+#endif
|
|
+
|
|
+#define co_io_buffer ((co_io_buffer_t *)CO_VPTR_IO_AREA_START)
|
|
+#define cooperative_mode_enabled() 1
|
|
+
|
|
+extern void co_debug(const char *fmt, ...)
|
|
+ __attribute__ ((format (printf, 1, 2)));
|
|
+extern void co_printk(const char *line, int size);
|
|
+
|
|
+extern void co_switch_wrapper(void);
|
|
+extern void co_callback(struct pt_regs *regs);
|
|
+extern void co_idle_processor(void);
|
|
+NORET_TYPE void co_terminate(co_termination_reason_t reason) ATTRIB_NORET;
|
|
+NORET_TYPE void co_terminate_panic(const char *text, int len) ATTRIB_NORET;
|
|
+NORET_TYPE void co_terminate_bug(int code, int line, const char *file) ATTRIB_NORET;
|
|
+extern void co_free_pages(unsigned long vaddr, int pages);
|
|
+extern int co_alloc_pages(unsigned long vaddr, int pages);
|
|
+extern void co_start_kernel(void);
|
|
+extern void co_arch_start_kernel(void);
|
|
+
|
|
+extern void co_send_message(co_module_t from,
|
|
+ co_module_t to,
|
|
+ co_priority_t priority,
|
|
+ co_message_type_t type,
|
|
+ unsigned long size,
|
|
+ const char *data);
|
|
+
|
|
+extern int co_get_message(co_message_node_t **message, co_device_t device);
|
|
+static inline void co_free_message(co_message_node_t *message)
|
|
+{
|
|
+ kfree(message);
|
|
+}
|
|
+
|
|
+extern void *co_map_buffer(void *, int);
|
|
+
|
|
+static inline void co_passage_page_ref_up(void)
|
|
+{
|
|
+#ifdef ENABLE_PASSAGE_HOLDING_CHECK
|
|
+ co_passage_page_holding_count++;
|
|
+#endif
|
|
+}
|
|
+
|
|
+static inline void co_passage_page_ref_down(void)
|
|
+{
|
|
+#ifdef ENABLE_PASSAGE_HOLDING_CHECK
|
|
+ co_passage_page_holding_count--;
|
|
+#endif
|
|
+}
|
|
+
|
|
+static inline int co_passage_page_held(void)
|
|
+{
|
|
+#ifdef ENABLE_PASSAGE_HOLDING_CHECK
|
|
+ return co_passage_page_holding_count;
|
|
+#else
|
|
+ return 0;
|
|
+#endif
|
|
+}
|
|
+
|
|
+static inline void co_passage_page_acquire(unsigned long *flags)
|
|
+{
|
|
+ local_irq_save(*flags);
|
|
+ co_passage_page_ref_up();
|
|
+}
|
|
+
|
|
+static inline void co_passage_page_release(unsigned long flags)
|
|
+{
|
|
+ co_passage_page_ref_down();
|
|
+ local_irq_restore(flags);
|
|
+}
|
|
+
|
|
+#ifdef ENABLE_PASSAGE_HOLDING_CHECK
|
|
+#define co_passage_page_assert_valid() do { \
|
|
+ BUG_ON(co_passage_page_held()); \
|
|
+} while (0)
|
|
+#else
|
|
+#define co_passage_page_assert_valid() /* nothing */
|
|
+#endif
|
|
+
|
|
+static inline co_message_t *co_send_message_save(unsigned long *flags)
|
|
+{
|
|
+ co_passage_page_assert_valid();
|
|
+ co_passage_page_acquire(flags);
|
|
+
|
|
+ if (co_io_buffer->messages_waiting) {
|
|
+ co_passage_page_release(*flags);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ co_passage_page->operation = CO_OPERATION_MESSAGE_TO_MONITOR;
|
|
+ co_io_buffer->messages_waiting = 1;
|
|
+ return ((co_message_t *)co_io_buffer->buffer);
|
|
+}
|
|
+
|
|
+static inline void co_send_message_restore(unsigned long flags)
|
|
+{
|
|
+ co_switch_wrapper();
|
|
+ co_passage_page_release(flags);
|
|
+}
|
|
+
|
|
+#else
|
|
+
|
|
+#define co_printk(line, size) do {} while (0)
|
|
+#define co_terminate(reason) do {} while (0)
|
|
+#define cooperative_mode_enabled() 0
|
|
+
|
|
+#endif
|
|
+
|
|
+#endif
|
|
Index: linux-2.6.33-source/kernel/Makefile
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/kernel/Makefile
|
|
+++ linux-2.6.33-source/kernel/Makefile
|
|
@@ -85,6 +85,7 @@
|
|
obj-$(CONFIG_TREE_RCU_TRACE) += rcutree_trace.o
|
|
obj-$(CONFIG_TINY_RCU) += rcutiny.o
|
|
obj-$(CONFIG_RELAY) += relay.o
|
|
+obj-$(CONFIG_COOPERATIVE) += cooperative.o
|
|
obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
|
|
obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
|
|
obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
|
|
Index: linux-2.6.33-source/kernel/cooperative.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/kernel/cooperative.c
|
|
@@ -0,0 +1,442 @@
|
|
+/*
|
|
+ * linux/kernel/cooperative.c
|
|
+ *
|
|
+ * Cooperative mode (coLinux) support routines.
|
|
+ *
|
|
+ * Dan Aloni <da-x@colinux.org>, 2003-2004 (C).
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/module.h>
|
|
+#include <linux/string.h>
|
|
+#include <linux/interrupt.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/slab.h>
|
|
+#include <linux/proc_fs.h>
|
|
+#include <linux/irq.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
+
|
|
+CO_TRACE_STOP;
|
|
+
|
|
+co_boot_params_t co_boot_params;
|
|
+
|
|
+typedef struct {
|
|
+ struct list_head list;
|
|
+ int num_messages;
|
|
+} co_message_queue_t;
|
|
+
|
|
+int co_messages_active = 0;
|
|
+co_message_queue_t co_outgoing_messages;
|
|
+co_message_queue_t co_incoming_messages;
|
|
+co_message_queue_t *co_incoming_queued_messages;
|
|
+
|
|
+#ifdef CONFIG_COLINUX_STATS
|
|
+co_proc_counts_t co_proc_counts;
|
|
+#endif
|
|
+
|
|
+void __init co_start_kernel(void)
|
|
+{
|
|
+ memcpy(&co_boot_params, co_passage_page->params, sizeof(co_boot_params));
|
|
+ co_arch_start_kernel();
|
|
+}
|
|
+
|
|
+void co_send_message(co_module_t from,
|
|
+ co_module_t to,
|
|
+ co_priority_t priority,
|
|
+ co_message_type_t type,
|
|
+ unsigned long size,
|
|
+ const char *data)
|
|
+{
|
|
+ unsigned long flags;
|
|
+ co_message_t *buffer;
|
|
+
|
|
+ BUG_ON((sizeof(co_message_t) + size) > CO_VPTR_IO_AREA_SIZE - sizeof(co_io_buffer_t));
|
|
+
|
|
+ buffer = co_send_message_save(&flags);
|
|
+ if (!buffer)
|
|
+ return;
|
|
+
|
|
+ buffer->from = from;
|
|
+ buffer->to = to;
|
|
+ buffer->priority = priority;
|
|
+ buffer->type = type;
|
|
+ buffer->size = size;
|
|
+ memcpy(buffer->data, data, size);
|
|
+
|
|
+ co_send_message_restore(flags);
|
|
+}
|
|
+
|
|
+static void co_message_add_to_incoming(co_message_t *message, unsigned long size)
|
|
+{
|
|
+ co_message_node_t *message_copy;
|
|
+
|
|
+ message_copy = kmalloc(size + sizeof(co_message_node_t) - sizeof(co_message_t),
|
|
+ GFP_ATOMIC);
|
|
+ if (!message_copy)
|
|
+ return;
|
|
+
|
|
+ memcpy(&message_copy->msg, message, size);
|
|
+ list_add_tail(&message_copy->node, &co_incoming_messages.list);
|
|
+}
|
|
+
|
|
+static void co_handle_jiffies(long count)
|
|
+{
|
|
+ if (count > HZ) {
|
|
+ long secs = count / HZ;
|
|
+
|
|
+ /* 'warp_clock' for long distances */
|
|
+ write_seqlock(&xtime_lock);
|
|
+ xtime.tv_sec += secs;
|
|
+ count -= (secs * HZ);
|
|
+ update_xtime_cache(0);
|
|
+ write_sequnlock(&xtime_lock);
|
|
+ clock_was_set();
|
|
+ }
|
|
+
|
|
+ while (count > 0) {
|
|
+ irq_enter();
|
|
+ __do_IRQ(TIMER_IRQ);
|
|
+ irq_exit();
|
|
+ count--;
|
|
+ }
|
|
+}
|
|
+
|
|
+/* called with disabled interrupts */
|
|
+static void co_handle_incoming_message(co_message_node_t *node_message)
|
|
+{
|
|
+ co_linux_message_t *message;
|
|
+ co_message_queue_t *queue;
|
|
+ int irq;
|
|
+
|
|
+ message = (co_linux_message_t *)&node_message->msg.data;
|
|
+ switch (message->device) {
|
|
+ case CO_DEVICE_POWER: irq = POWER_IRQ; break;
|
|
+ case CO_DEVICE_KEYBOARD: irq = KEYBOARD_IRQ; break;
|
|
+#ifdef CONFIG_CONET_COOPERATIVE
|
|
+ case CO_DEVICE_NETWORK: irq = NETWORK_IRQ; break;
|
|
+#endif
|
|
+#ifdef CONFIG_SERIAL_COOPERATIVE
|
|
+ case CO_DEVICE_SERIAL: irq = SERIAL_IRQ; break;
|
|
+#endif
|
|
+ case CO_DEVICE_SCSI: irq = SCSI_IRQ; break;
|
|
+ case CO_DEVICE_MOUSE: irq = MOUSE_IRQ; break;
|
|
+ case CO_DEVICE_BLOCK: irq = BLOCKDEV_IRQ; break;
|
|
+ default:
|
|
+ BUG_ON((unsigned long)message->device >= (unsigned long)CO_DEVICES_TOTAL);
|
|
+ co_free_message(node_message);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ /* Add to the queue */
|
|
+ queue = &co_incoming_queued_messages[message->device];
|
|
+ list_add(&node_message->node, &queue->list);
|
|
+ queue->num_messages++;
|
|
+
|
|
+ irq_enter();
|
|
+ __do_IRQ(irq);
|
|
+ irq_exit();
|
|
+}
|
|
+
|
|
+static void co_handle_incoming_messages(void)
|
|
+{
|
|
+ if (!co_messages_active)
|
|
+ return;
|
|
+
|
|
+ /*
|
|
+ * Pop a message from the incoming queue.
|
|
+ */
|
|
+ while (!list_empty(&co_incoming_messages.list)) {
|
|
+ co_message_node_t *message;
|
|
+
|
|
+ message = list_entry(co_incoming_messages.list.next,
|
|
+ co_message_node_t, node);
|
|
+ BUG_ON((unsigned long)message->msg.from >= (unsigned long)CO_MODULES_MAX);
|
|
+ BUG_ON((unsigned long)message->msg.to >= (unsigned long)CO_MODULES_MAX);
|
|
+ list_del(&message->node);
|
|
+
|
|
+ /*
|
|
+ * Let the interrupt routine of the arch dependant code
|
|
+ * handle the message, and be responsible to free it.
|
|
+ */
|
|
+ co_handle_incoming_message(message);
|
|
+ }
|
|
+}
|
|
+
|
|
+void co_callback(struct pt_regs *regs)
|
|
+{
|
|
+ long io_size;
|
|
+ unsigned long new_jiffies;
|
|
+ struct pt_regs null_regs;
|
|
+
|
|
+ BUG_ON(!irqs_disabled());
|
|
+ if (co_passage_page->operation != CO_OPERATION_MESSAGE_FROM_MONITOR) {
|
|
+ co_passage_page_ref_down();
|
|
+ return;
|
|
+ }
|
|
+
|
|
+#ifdef CONFIG_COLINUX_STATS
|
|
+ co_proc_counts.switches[CO_OPERATION_MESSAGE_FROM_MONITOR]++;
|
|
+#endif
|
|
+ io_size = co_passage_page->params[0];
|
|
+ new_jiffies = co_passage_page->params[1];
|
|
+
|
|
+ if (co_messages_active && io_size > 0 && io_size <= CO_VPTR_IO_AREA_SIZE) {
|
|
+ static unsigned char temp_storage[CO_VPTR_IO_AREA_SIZE];
|
|
+ unsigned char *io_buffer = temp_storage;
|
|
+ unsigned char *io_buffer_end = &temp_storage[io_size];
|
|
+
|
|
+ /* Copy into temp, because kmalloc calls host to mapping pages */
|
|
+ memcpy(temp_storage, co_io_buffer->buffer, io_size);
|
|
+ co_io_buffer->messages_waiting = 0;
|
|
+ co_passage_page_ref_down();
|
|
+
|
|
+ while (io_buffer < io_buffer_end) {
|
|
+ co_message_t *message = (co_message_t *)io_buffer;
|
|
+ co_linux_message_t *linux_message = (co_linux_message_t *)message->data;
|
|
+ unsigned long size = message->size + sizeof(*message);
|
|
+
|
|
+ BUG_ON((unsigned long)message->from >= (unsigned long)CO_MODULES_MAX);
|
|
+ BUG_ON((unsigned long)message->to >= (unsigned long)CO_MODULES_MAX);
|
|
+ BUG_ON((unsigned long)linux_message->device >= (unsigned long)CO_DEVICES_TOTAL);
|
|
+
|
|
+ co_message_add_to_incoming(message, size);
|
|
+ io_buffer += size;
|
|
+ }
|
|
+ } else {
|
|
+ co_io_buffer->messages_waiting = 0;
|
|
+ co_passage_page_ref_down();
|
|
+ }
|
|
+
|
|
+ memset (&null_regs, 0, sizeof(null_regs));
|
|
+
|
|
+ /* Have only, if from proxy_interrupt_handler(), needs for user_mode() */
|
|
+ if (regs)
|
|
+ null_regs.cs = regs->cs;
|
|
+ set_irq_regs(&null_regs);
|
|
+
|
|
+ co_handle_jiffies(new_jiffies);
|
|
+ co_handle_incoming_messages();
|
|
+}
|
|
+
|
|
+void co_idle_processor(void)
|
|
+{
|
|
+ co_passage_page_assert_valid();
|
|
+ local_irq_disable();
|
|
+ co_passage_page_ref_up();
|
|
+ co_passage_page->operation = CO_OPERATION_IDLE;
|
|
+ co_switch_wrapper();
|
|
+ co_callback(NULL);
|
|
+ local_irq_enable();
|
|
+}
|
|
+
|
|
+void co_printk(const char *line, int size)
|
|
+{
|
|
+ unsigned long flags;
|
|
+ co_message_t *co_message;
|
|
+
|
|
+ co_message = co_send_message_save(&flags);
|
|
+ if (co_message) {
|
|
+ co_message->from = CO_MODULE_LINUX;
|
|
+ co_message->to = CO_MODULE_PRINTK;
|
|
+ co_message->priority = CO_PRIORITY_DISCARDABLE;
|
|
+ co_message->type = CO_MESSAGE_TYPE_STRING;
|
|
+ if (size > 200)
|
|
+ size = 200;
|
|
+ co_message->size = size + 1;
|
|
+ memcpy(co_message->data, line, size);
|
|
+ co_message->data[size] = '\0';
|
|
+ co_send_message_restore(flags);
|
|
+ }
|
|
+}
|
|
+
|
|
+NORET_TYPE void co_terminate_panic(const char *text, int len)
|
|
+{
|
|
+ unsigned long flags;
|
|
+
|
|
+ co_passage_page_acquire(&flags);
|
|
+ co_passage_page->operation = CO_OPERATION_TERMINATE;
|
|
+ co_passage_page->params[0] = CO_TERMINATE_PANIC;
|
|
+ co_passage_page->params[1] = 0;
|
|
+ co_passage_page->params[2] = 0;
|
|
+ co_passage_page->params[3] = len;
|
|
+ memcpy((char *)&co_passage_page->params[4], text, len+1);
|
|
+ co_switch_wrapper();
|
|
+ while(1);
|
|
+}
|
|
+
|
|
+NORET_TYPE void co_terminate_bug(int code, int line, const char *file)
|
|
+{
|
|
+ unsigned long flags;
|
|
+
|
|
+ co_passage_page_acquire(&flags);
|
|
+ co_passage_page->operation = CO_OPERATION_TERMINATE;
|
|
+ co_passage_page->params[0] = CO_TERMINATE_BUG;
|
|
+ co_passage_page->params[1] = code;
|
|
+ co_passage_page->params[2] = line;
|
|
+ co_passage_page->params[3] = strlen(file);
|
|
+ strcpy((char *)&co_passage_page->params[4], file);
|
|
+ co_switch_wrapper();
|
|
+ while(1);
|
|
+}
|
|
+NORET_TYPE EXPORT_SYMBOL(co_terminate_bug);
|
|
+
|
|
+void co_terminate(co_termination_reason_t reason)
|
|
+{
|
|
+ unsigned long flags;
|
|
+
|
|
+ co_passage_page_acquire(&flags);
|
|
+ co_passage_page->operation = CO_OPERATION_TERMINATE;
|
|
+ co_passage_page->params[0] = reason;
|
|
+ co_passage_page->params[3] = 0; /* len */
|
|
+ co_switch_wrapper();
|
|
+ while(1);
|
|
+}
|
|
+EXPORT_SYMBOL(co_terminate);
|
|
+
|
|
+int co_get_message(co_message_node_t **message, co_device_t device)
|
|
+{
|
|
+ co_message_queue_t *queue;
|
|
+ co_message_node_t *node;
|
|
+ unsigned long flags;
|
|
+
|
|
+ if (!co_messages_active)
|
|
+ return 0;
|
|
+
|
|
+ local_irq_save(flags);
|
|
+ queue = &co_incoming_queued_messages[device];
|
|
+ if (list_empty(&queue->list)) {
|
|
+ local_irq_restore(flags);
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ node = list_entry(queue->list.prev, co_message_node_t, node);
|
|
+ list_del(&node->node);
|
|
+ queue->num_messages--;
|
|
+ local_irq_restore(flags);
|
|
+
|
|
+ *message = node;
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+co_info_t co_info = {
|
|
+ .api_version = CO_LINUX_API_VERSION,
|
|
+ .compiler_major = __GNUC__,
|
|
+ .compiler_minor = __GNUC_MINOR__,
|
|
+ .compiler_abi = __GXX_ABI_VERSION,
|
|
+};
|
|
+
|
|
+static int __init initcall_message_queues(void)
|
|
+{
|
|
+ int queue_index;
|
|
+
|
|
+ INIT_LIST_HEAD(&co_outgoing_messages.list);
|
|
+ INIT_LIST_HEAD(&co_incoming_messages.list);
|
|
+
|
|
+ co_incoming_queued_messages =
|
|
+ kmalloc(sizeof(co_message_queue_t) * CO_DEVICES_TOTAL, GFP_KERNEL);
|
|
+ if (!co_incoming_queued_messages)
|
|
+ panic("unable to allocate message queues\n");
|
|
+
|
|
+ for (queue_index=0; queue_index < CO_DEVICES_TOTAL; queue_index++) {
|
|
+ co_message_queue_t *queue = &co_incoming_queued_messages[queue_index];
|
|
+ queue->num_messages = 0;
|
|
+ INIT_LIST_HEAD(&queue->list);
|
|
+ }
|
|
+
|
|
+ co_messages_active = 1;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+
|
|
+void co_free_pages(unsigned long vaddr, int pages)
|
|
+{
|
|
+ unsigned long flags;
|
|
+
|
|
+ co_passage_page_acquire(&flags);
|
|
+ co_passage_page->operation = CO_OPERATION_FREE_PAGES;
|
|
+ co_passage_page->params[0] = vaddr;
|
|
+ co_passage_page->params[1] = pages;
|
|
+ co_switch_wrapper();
|
|
+ co_passage_page_release(flags);
|
|
+}
|
|
+
|
|
+int co_alloc_pages(unsigned long vaddr, int size)
|
|
+{
|
|
+ unsigned long flags;
|
|
+ long result;
|
|
+
|
|
+ co_passage_page_acquire(&flags);
|
|
+ co_passage_page->operation = CO_OPERATION_ALLOC_PAGES;
|
|
+ co_passage_page->params[0] = vaddr;
|
|
+ co_passage_page->params[1] = size;
|
|
+ co_switch_wrapper();
|
|
+ result = (long)co_passage_page->params[4];
|
|
+ co_passage_page_release(flags);
|
|
+
|
|
+ if (result < 0)
|
|
+ return -ENOMEM;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+__initcall(initcall_message_queues);
|
|
+
|
|
+#ifdef CONFIG_COLINUX_STATS
|
|
+static int co_guest_read_status(char *page, char **start, off_t off, int count, int *eof, void *clear)
|
|
+{
|
|
+ co_proc_counts_t hold;
|
|
+ int len;
|
|
+
|
|
+ local_irq_disable();
|
|
+ hold = co_proc_counts;
|
|
+ if (clear)
|
|
+ memset(&co_proc_counts, 0, sizeof(co_proc_counts));
|
|
+ local_irq_enable();
|
|
+
|
|
+ len = sprintf(page, "idle:\t%lu\n"
|
|
+ "msgto:\t%lu\n"
|
|
+ "mfrom:\t%lu\n"
|
|
+ "intr:\t%lu\n"
|
|
+ "dev:\t%lu\n"
|
|
+ "time:\t%lu\n"
|
|
+ "hpt:\t%lu\n"
|
|
+ "free:\t%lu\n"
|
|
+ "alloc:\t%lu\n"
|
|
+ "getpp:\t%lu\n",
|
|
+ hold.switches[CO_OPERATION_IDLE],
|
|
+ hold.switches[CO_OPERATION_MESSAGE_TO_MONITOR],
|
|
+ hold.switches[CO_OPERATION_MESSAGE_FROM_MONITOR],
|
|
+ hold.switches[CO_OPERATION_FORWARD_INTERRUPT],
|
|
+ hold.switches[CO_OPERATION_DEVICE],
|
|
+ hold.switches[CO_OPERATION_GET_TIME],
|
|
+ hold.switches[CO_OPERATION_GET_HIGH_PREC_TIME],
|
|
+ hold.switches[CO_OPERATION_FREE_PAGES],
|
|
+ hold.switches[CO_OPERATION_ALLOC_PAGES],
|
|
+ hold.switches[CO_OPERATION_GETPP]);
|
|
+
|
|
+ return len;
|
|
+}
|
|
+
|
|
+static __init int co_create_proc_stats(void)
|
|
+{
|
|
+ struct proc_dir_entry *co_guest_dir;
|
|
+
|
|
+ co_guest_dir = proc_mkdir("colinux", NULL);
|
|
+ if(co_guest_dir) {
|
|
+ create_proc_read_entry("stats",
|
|
+ 0444, co_guest_dir,
|
|
+ co_guest_read_status, NULL);
|
|
+ create_proc_read_entry("stats_clear",
|
|
+ 0444, co_guest_dir,
|
|
+ co_guest_read_status, (void*)1);
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+__initcall(co_create_proc_stats);
|
|
+#endif /* CONFIG_COLINUX_STATS */
|
|
+
|
|
+CO_TRACE_CONTINUE;
|
|
Index: linux-2.6.33-source/kernel/panic.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/kernel/panic.c
|
|
+++ linux-2.6.33-source/kernel/panic.c
|
|
@@ -23,6 +23,7 @@
|
|
#include <linux/init.h>
|
|
#include <linux/nmi.h>
|
|
#include <linux/dmi.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
|
|
int panic_on_oops;
|
|
static unsigned long tainted_mask;
|
|
@@ -68,7 +69,7 @@
|
|
|
|
bust_spinlocks(1);
|
|
va_start(args, fmt);
|
|
- vsnprintf(buf, sizeof(buf), fmt, args);
|
|
+ i = vsnprintf(buf, sizeof(buf), fmt, args);
|
|
va_end(args);
|
|
printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
|
|
#ifdef CONFIG_DEBUG_BUGVERBOSE
|
|
@@ -84,6 +85,9 @@
|
|
|
|
kmsg_dump(KMSG_DUMP_PANIC);
|
|
|
|
+ if (cooperative_mode_enabled())
|
|
+ co_terminate_panic(buf, i);
|
|
+
|
|
/*
|
|
* Note smp_send_stop is the usual smp shutdown function, which
|
|
* unfortunately means it may not be hardened to work in a panic
|
|
Index: linux-2.6.33-source/kernel/printk.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/kernel/printk.c
|
|
+++ linux-2.6.33-source/kernel/printk.c
|
|
@@ -51,6 +51,8 @@
|
|
{
|
|
}
|
|
|
|
+#include <linux/cooperative_internal.h>
|
|
+
|
|
#define __LOG_BUF_LEN (1 << CONFIG_LOG_BUF_SHIFT)
|
|
|
|
/* printk's without a loglevel use this.. */
|
|
@@ -740,6 +742,8 @@
|
|
}
|
|
}
|
|
|
|
+ co_printk(printk_buf, printed_len);
|
|
+
|
|
/*
|
|
* Copy the output into log_buf. If the caller didn't provide
|
|
* appropriate log level tags, we insert them here
|
|
Index: linux-2.6.33-source/mm/bootmem.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/mm/bootmem.c
|
|
+++ linux-2.6.33-source/mm/bootmem.c
|
|
@@ -12,6 +12,7 @@
|
|
#include <linux/pfn.h>
|
|
#include <linux/bootmem.h>
|
|
#include <linux/module.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
#include <linux/kmemleak.h>
|
|
|
|
#include <asm/bug.h>
|
|
@@ -544,6 +545,21 @@
|
|
|
|
region = phys_to_virt(PFN_PHYS(bdata->node_min_pfn) +
|
|
start_off);
|
|
+
|
|
+ if (cooperative_mode_enabled()) {
|
|
+ unsigned long alloc_address = (unsigned long)region;
|
|
+ unsigned long alloc_size = size;
|
|
+
|
|
+ alloc_size += (alloc_address & (~PAGE_MASK));
|
|
+ alloc_address &= PAGE_MASK;
|
|
+ alloc_size = (alloc_size + PAGE_SIZE - 1) >> PAGE_SHIFT;
|
|
+
|
|
+ if (co_alloc_pages(alloc_address, alloc_size)) {
|
|
+ free_bootmem((unsigned long)region, size);
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
memset(region, 0, size);
|
|
/*
|
|
* The min_count is set to 0 so that bootmem allocated blocks
|
|
Index: linux-2.6.33-source/mm/page_alloc.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/mm/page_alloc.c
|
|
+++ linux-2.6.33-source/mm/page_alloc.c
|
|
@@ -49,6 +49,7 @@
|
|
#include <linux/debugobjects.h>
|
|
#include <linux/kmemleak.h>
|
|
#include <linux/memory.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
#include <trace/events/kmem.h>
|
|
|
|
#include <asm/tlbflush.h>
|
|
@@ -338,6 +339,34 @@
|
|
return bad;
|
|
}
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+static int co_persistent_alloc_pages(unsigned long address, int size)
|
|
+{
|
|
+ int result, retries_left;
|
|
+
|
|
+ for (retries_left = 10; retries_left > 0; retries_left--) {
|
|
+ result = co_alloc_pages(address, size);
|
|
+ if (result) {
|
|
+ unsigned long cache_size;
|
|
+ /*
|
|
+ * Whoops, we have allocated too much of the
|
|
+ * host OS's memory, time to free some cache.
|
|
+ */
|
|
+ cache_size = global_page_state(NR_FILE_PAGES)-total_swapcache_pages;
|
|
+ cache_size /= 2;
|
|
+ if (cache_size < size*2)
|
|
+ cache_size = size*2;
|
|
+ shrink_all_memory(cache_size);
|
|
+ } else {
|
|
+ return 0;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ WARN_ON(result != 0);
|
|
+ return result;
|
|
+}
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
+
|
|
static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags)
|
|
{
|
|
int i;
|
|
@@ -453,6 +482,11 @@
|
|
{
|
|
unsigned long page_idx;
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ co_free_pages((unsigned long)page_address(page), 1 << order);
|
|
+ ClearPageCoHostMapped(page);
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
+
|
|
if (unlikely(PageCompound(page)))
|
|
if (unlikely(destroy_compound_page(page, order)))
|
|
return;
|
|
@@ -692,6 +726,12 @@
|
|
return 1;
|
|
}
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ if (!TestSetPageCoHostMapped(page))
|
|
+ if (co_persistent_alloc_pages((unsigned long)page_address(page), 1 << order))
|
|
+ return 1;
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
+
|
|
set_page_private(page, 0);
|
|
set_page_refcounted(page);
|
|
|
|
@@ -1237,6 +1277,7 @@
|
|
VM_BUG_ON(bad_range(zone, page));
|
|
if (prep_new_page(page, order, gfp_flags))
|
|
goto again;
|
|
+
|
|
return page;
|
|
|
|
failed:
|
|
@@ -1918,7 +1959,7 @@
|
|
dump_stack();
|
|
show_mem();
|
|
}
|
|
- return page;
|
|
+ return NULL;
|
|
got_pg:
|
|
if (kmemcheck_enabled)
|
|
kmemcheck_pagealloc_alloc(page, order, gfp_mask);
|
|
Index: linux-2.6.33-source/mm/vmscan.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/mm/vmscan.c
|
|
+++ linux-2.6.33-source/mm/vmscan.c
|
|
@@ -2332,7 +2332,7 @@
|
|
return nr;
|
|
}
|
|
|
|
-#ifdef CONFIG_HIBERNATION
|
|
+#if defined(CONFIG_HIBERNATION) || defined(CONFIG_COOPERATIVE)
|
|
/*
|
|
* Try to free `nr_to_reclaim' of memory, system-wide, and return the number of
|
|
* freed pages.
|
|
Index: linux-2.6.33-source/drivers/char/mem.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/drivers/char/mem.c
|
|
+++ linux-2.6.33-source/drivers/char/mem.c
|
|
@@ -22,6 +22,7 @@
|
|
#include <linux/device.h>
|
|
#include <linux/highmem.h>
|
|
#include <linux/crash_dump.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
#include <linux/backing-dev.h>
|
|
#include <linux/bootmem.h>
|
|
#include <linux/splice.h>
|
|
@@ -130,6 +131,9 @@
|
|
ssize_t read, sz;
|
|
char *ptr;
|
|
|
|
+ if (cooperative_mode_enabled())
|
|
+ return -ENOMEM;
|
|
+
|
|
if (!valid_phys_addr_range(p, count))
|
|
return -EFAULT;
|
|
read = 0;
|
|
@@ -188,6 +192,9 @@
|
|
unsigned long copied;
|
|
void *ptr;
|
|
|
|
+ if (cooperative_mode_enabled())
|
|
+ return -ENOMEM;
|
|
+
|
|
if (!valid_phys_addr_range(p, count))
|
|
return -EFAULT;
|
|
|
|
@@ -298,6 +305,9 @@
|
|
{
|
|
size_t size = vma->vm_end - vma->vm_start;
|
|
|
|
+ if (cooperative_mode_enabled())
|
|
+ return -EFAULT;
|
|
+
|
|
if (!valid_mmap_phys_addr_range(vma->vm_pgoff, size))
|
|
return -EINVAL;
|
|
|
|
@@ -333,6 +343,9 @@
|
|
{
|
|
unsigned long pfn;
|
|
|
|
+ if (cooperative_mode_enabled())
|
|
+ return -EFAULT;
|
|
+
|
|
/* Turn a kernel-virtual address into a physical page frame */
|
|
pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT;
|
|
|
|
@@ -397,6 +410,9 @@
|
|
char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */
|
|
int err = 0;
|
|
|
|
+ if (cooperative_mode_enabled())
|
|
+ return -ENOMEM;
|
|
+
|
|
read = 0;
|
|
if (p < (unsigned long) high_memory) {
|
|
low_count = count;
|
|
@@ -527,6 +543,9 @@
|
|
char * kbuf; /* k-addr because vwrite() takes vmlist_lock rwlock */
|
|
int err = 0;
|
|
|
|
+ if (cooperative_mode_enabled())
|
|
+ return -ENOMEM;
|
|
+
|
|
if (p < (unsigned long) high_memory) {
|
|
unsigned long to_write = min_t(unsigned long, count,
|
|
(unsigned long)high_memory - p);
|
|
Index: linux-2.6.33-source/arch/x86/kernel/cpu/bugs.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/cpu/bugs.c
|
|
+++ linux-2.6.33-source/arch/x86/kernel/cpu/bugs.c
|
|
@@ -25,6 +25,8 @@
|
|
|
|
__setup("no-hlt", no_halt);
|
|
|
|
+// Ignore, if have no emulation compiled in
|
|
+#ifdef CONFIG_MATH_EMULATION
|
|
static int __init no_387(char *s)
|
|
{
|
|
boot_cpu_data.hard_math = 0;
|
|
@@ -33,6 +35,7 @@
|
|
}
|
|
|
|
__setup("no387", no_387);
|
|
+#endif
|
|
|
|
static double __initdata x = 4195835.0;
|
|
static double __initdata y = 3145727.0;
|
|
Index: linux-2.6.33-source/arch/x86/kernel/reboot_cooperative.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/arch/x86/kernel/reboot_cooperative.c
|
|
@@ -0,0 +1,133 @@
|
|
+/*
|
|
+ * linux/arch/x86/kernel/reboot_cooperative.c
|
|
+ */
|
|
+
|
|
+#include <linux/module.h>
|
|
+#include <linux/reboot.h>
|
|
+#include <linux/kthread.h>
|
|
+#include <linux/syscalls.h>
|
|
+#include <linux/interrupt.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
+
|
|
+/* sys_reboot needs this dummy. */
|
|
+void (*pm_power_off)(void);
|
|
+
|
|
+/*
|
|
+ * This is a hack to make ctrl_alt_del work as a poweroff, so the OS can be
|
|
+ * notified, unmount and sync everything.
|
|
+ */
|
|
+static int co_powering_off;
|
|
+
|
|
+static int co_powerd(void *__unused)
|
|
+{
|
|
+ extern char * envp_init[];
|
|
+ static char *const argv_shutdown[]= { "/sbin/shutdown", "-h", "now", NULL };
|
|
+ static char *const argv_halt[]= { "/sbin/halt", NULL };
|
|
+
|
|
+ if (kernel_execve(argv_shutdown[0], argv_shutdown, envp_init) >= 0)
|
|
+ return 0;
|
|
+ printk(KERN_INFO "%s spawn failed\n", argv_shutdown[0]);
|
|
+
|
|
+ if (kernel_execve(argv_halt[0], argv_halt, envp_init) >= 0)
|
|
+ return 0;
|
|
+ printk(KERN_INFO "%s spawn failed\n", argv_halt[0]);
|
|
+
|
|
+ printk(KERN_INFO "Fallback into reboot and power off\n");
|
|
+ co_powering_off++;
|
|
+ ctrl_alt_del();
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static void deferred_shutdown(struct work_struct *dummy)
|
|
+{
|
|
+ kthread_run(co_powerd, NULL, "copowerd");
|
|
+}
|
|
+
|
|
+/*
|
|
+ * This function will call from interrupt context.
|
|
+ */
|
|
+static void co_shedule_shutdown(void)
|
|
+{
|
|
+ static DECLARE_WORK(shutdown_work, deferred_shutdown);
|
|
+
|
|
+ schedule_work(&shutdown_work);
|
|
+}
|
|
+
|
|
+
|
|
+static void co_machine_restart(void)
|
|
+{
|
|
+ co_terminate(CO_TERMINATE_REBOOT);
|
|
+}
|
|
+
|
|
+void machine_power_off(void)
|
|
+{
|
|
+ co_terminate(CO_TERMINATE_POWEROFF);
|
|
+}
|
|
+
|
|
+void machine_shutdown(void)
|
|
+{
|
|
+ co_terminate(CO_TERMINATE_HALT);
|
|
+}
|
|
+
|
|
+void machine_emergency_restart(void)
|
|
+{
|
|
+ co_machine_restart();
|
|
+}
|
|
+
|
|
+void machine_restart(char *cmd)
|
|
+{
|
|
+ if (co_powering_off)
|
|
+ machine_power_off();
|
|
+ else
|
|
+ co_machine_restart();
|
|
+}
|
|
+
|
|
+void machine_halt(void)
|
|
+{
|
|
+ co_terminate(CO_TERMINATE_HALT);
|
|
+}
|
|
+
|
|
+static irqreturn_t power_interrupt(int irq, void *dev_id)
|
|
+{
|
|
+ co_message_node_t *node_message;
|
|
+
|
|
+ if (co_get_message(&node_message, CO_DEVICE_POWER)) {
|
|
+ co_linux_message_t *message;
|
|
+ co_linux_message_power_t *type;
|
|
+
|
|
+ message = (co_linux_message_t *)&node_message->msg.data;
|
|
+ type = (co_linux_message_power_t *)message->data;
|
|
+ switch (type->type) {
|
|
+ case CO_LINUX_MESSAGE_POWER_ALT_CTRL_DEL:
|
|
+ ctrl_alt_del();
|
|
+ break;
|
|
+ case CO_LINUX_MESSAGE_POWER_SHUTDOWN:
|
|
+ co_shedule_shutdown();
|
|
+ break;
|
|
+ case CO_LINUX_MESSAGE_POWER_OFF:
|
|
+ machine_power_off();
|
|
+ break;
|
|
+ default:
|
|
+ printk(KERN_ERR "power interrupt: buggy type %d\n", type->type);
|
|
+ }
|
|
+ co_free_message(node_message);
|
|
+ }
|
|
+
|
|
+ return IRQ_HANDLED;
|
|
+}
|
|
+
|
|
+static int __init co_power_init(void)
|
|
+{
|
|
+ int rc;
|
|
+
|
|
+ rc = request_irq(POWER_IRQ, &power_interrupt, IRQF_SAMPLE_RANDOM, "power", NULL);
|
|
+ if (rc) {
|
|
+ printk(KERN_ERR "POWER: unable to get irq %d", POWER_IRQ);
|
|
+ return rc;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+__initcall(co_power_init);
|
|
Index: linux-2.6.33-source/arch/x86/kernel/i8259_cooperative.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/arch/x86/kernel/i8259_cooperative.c
|
|
@@ -0,0 +1,103 @@
|
|
+/*
|
|
+ * linux/arch/x86/kernel/i8259_cooperative.c
|
|
+ */
|
|
+
|
|
+#include <linux/interrupt.h>
|
|
+#include <linux/init.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
+
|
|
+#include <asm/irq.h>
|
|
+#include <asm/desc.h>
|
|
+
|
|
+CO_TRACE_STOP;
|
|
+
|
|
+/* Function must have the same prototype as do_IRQ() */
|
|
+unsigned int /*__irq_entry*/ proxy_interrupt_handler(struct pt_regs *regs)
|
|
+{
|
|
+ /* high bit used in ret_from_ code */
|
|
+ unsigned vector = ~regs->orig_ax;
|
|
+
|
|
+ co_passage_page_assert_valid();
|
|
+ co_passage_page_ref_up();
|
|
+ co_passage_page->operation = CO_OPERATION_FORWARD_INTERRUPT;
|
|
+ co_passage_page->params[0] = vector; /* IRQ vector */
|
|
+ co_passage_page->host_state.flags &= ~(1 << 9); /* Turn IF off */
|
|
+ co_switch_wrapper();
|
|
+ co_callback(regs);
|
|
+ return 1;
|
|
+}
|
|
+
|
|
+CO_TRACE_CONTINUE;
|
|
+
|
|
+/*
|
|
+ * Not like you have any other choice other than using
|
|
+ * COPIC in Cooperative mode.
|
|
+ */
|
|
+
|
|
+static void end_COPIC_irq(unsigned int irq)
|
|
+{
|
|
+}
|
|
+
|
|
+static void mask_and_ack_COPIC(unsigned int irq)
|
|
+{
|
|
+}
|
|
+
|
|
+static unsigned int startup_COPIC_irq(unsigned int irq)
|
|
+{
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+#define shutdown_COPIC_irq disable_COPIC_irq
|
|
+
|
|
+static void disable_COPIC_irq(unsigned int irq)
|
|
+{
|
|
+}
|
|
+
|
|
+static void enable_COPIC_irq(unsigned int irq)
|
|
+{
|
|
+}
|
|
+
|
|
+static struct irq_chip co_pic_irq_chip = {
|
|
+ .name = "COPIC",
|
|
+ .startup = startup_COPIC_irq,
|
|
+ .shutdown = shutdown_COPIC_irq,
|
|
+ .enable = enable_COPIC_irq,
|
|
+ .disable = disable_COPIC_irq,
|
|
+ .mask_ack = mask_and_ack_COPIC,
|
|
+ .end = end_COPIC_irq,
|
|
+ .set_affinity = NULL
|
|
+};
|
|
+
|
|
+void __init init_ISA_irqs (void)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ printk("Setting proxy interrupt vectors (0..%d)\n", NR_IRQS-1);
|
|
+ for (i = 0; i < NR_IRQS; i++) {
|
|
+ irq_desc[i].status = IRQ_DISABLED;
|
|
+ irq_desc[i].action = NULL;
|
|
+ irq_desc[i].depth = 1;
|
|
+
|
|
+ set_irq_chip_and_handler_name(i, &co_pic_irq_chip, handle_simple_irq, "CO");
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
+void __init init_IRQ(void)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ /* all the set up before the call gates are initialised */
|
|
+ init_ISA_irqs();
|
|
+
|
|
+ /*
|
|
+ * Cover the whole vector space, no vector can escape us.
|
|
+ */
|
|
+ for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {
|
|
+ int vector = FIRST_EXTERNAL_VECTOR + i;
|
|
+ if (i >= NR_IRQS)
|
|
+ break;
|
|
+ if (vector != SYSCALL_VECTOR)
|
|
+ set_intr_gate(vector, interrupt[i]);
|
|
+ }
|
|
+}
|
|
Index: linux-2.6.33-source/arch/x86/kernel/ioport_cooperative.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/arch/x86/kernel/ioport_cooperative.c
|
|
@@ -0,0 +1,15 @@
|
|
+/*
|
|
+ * linux/arch/x86/kernel/ioport_cooperative.c
|
|
+ */
|
|
+
|
|
+#include <linux/syscalls.h>
|
|
+
|
|
+asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
|
+{
|
|
+ return -EPERM;
|
|
+}
|
|
+
|
|
+asmlinkage long sys_iopl(unsigned long unused)
|
|
+{
|
|
+ return -EPERM;
|
|
+}
|
|
Index: linux-2.6.33-source/lib/iomap.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/lib/iomap.c
|
|
+++ linux-2.6.33-source/lib/iomap.c
|
|
@@ -58,6 +58,7 @@
|
|
bad_io_access(port, #is_pio ); \
|
|
} while (0)
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
#ifndef pio_read16be
|
|
#define pio_read16be(port) swab16(inw(port))
|
|
#define pio_read32be(port) swab32(inl(port))
|
|
@@ -223,6 +224,7 @@
|
|
EXPORT_SYMBOL(iowrite8_rep);
|
|
EXPORT_SYMBOL(iowrite16_rep);
|
|
EXPORT_SYMBOL(iowrite32_rep);
|
|
+#endif
|
|
|
|
/* Create a virtual mapping cookie for an IO port range */
|
|
void __iomem *ioport_map(unsigned long port, unsigned int nr)
|
|
Index: linux-2.6.33-source/drivers/char/Kconfig
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/drivers/char/Kconfig
|
|
+++ linux-2.6.33-source/drivers/char/Kconfig
|
|
@@ -1100,6 +1100,7 @@
|
|
config DEVPORT
|
|
bool
|
|
depends on !M68K
|
|
+ depends on !COOPERATIVE
|
|
depends on ISA || PCI
|
|
default y
|
|
|
|
Index: linux-2.6.33-source/drivers/crypto/Kconfig
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/drivers/crypto/Kconfig
|
|
+++ linux-2.6.33-source/drivers/crypto/Kconfig
|
|
@@ -52,6 +52,7 @@
|
|
config CRYPTO_DEV_GEODE
|
|
tristate "Support for the Geode LX AES engine"
|
|
depends on X86_32 && PCI
|
|
+ depends on !COOPERATIVE
|
|
select CRYPTO_ALGAPI
|
|
select CRYPTO_BLKCIPHER
|
|
help
|
|
Index: linux-2.6.33-source/drivers/usb/Kconfig
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/drivers/usb/Kconfig
|
|
+++ linux-2.6.33-source/drivers/usb/Kconfig
|
|
@@ -17,6 +17,7 @@
|
|
# NOTE: SL-811 option should be board-specific ...
|
|
config USB_ARCH_HAS_HCD
|
|
boolean
|
|
+ depends on !COOPERATIVE
|
|
default y if USB_ARCH_HAS_OHCI
|
|
default y if USB_ARCH_HAS_EHCI
|
|
default y if PCMCIA && !M32R # sl811_cs
|
|
@@ -27,6 +28,7 @@
|
|
# many non-PCI SOC chips embed OHCI
|
|
config USB_ARCH_HAS_OHCI
|
|
boolean
|
|
+ depends on !COOPERATIVE
|
|
# ARM:
|
|
default y if SA1111
|
|
default y if ARCH_OMAP
|
|
@@ -55,6 +57,7 @@
|
|
# some non-PCI hcds implement EHCI
|
|
config USB_ARCH_HAS_EHCI
|
|
boolean
|
|
+ depends on !COOPERATIVE
|
|
default y if PPC_83xx
|
|
default y if SOC_AU1200
|
|
default y if ARCH_IXP4XX
|
|
Index: linux-2.6.33-source/arch/x86/mm/comap.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/arch/x86/mm/comap.c
|
|
@@ -0,0 +1,130 @@
|
|
+
|
|
+/*
|
|
+ * This source code is a part of coLinux source package.
|
|
+ *
|
|
+ * Copyright (C) 2008 Steve Shoecraft <sshoecraft@earthlink.net>
|
|
+ *
|
|
+ * The code is licensed under the GPL. See the COPYING file in
|
|
+ * the root directory.
|
|
+ *
|
|
+ */
|
|
+
|
|
+#include <linux/kernel.h>
|
|
+#include <linux/mm.h>
|
|
+#include <linux/vmalloc.h>
|
|
+#include <linux/sched.h>
|
|
+
|
|
+#include <linux/cooperative.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
+
|
|
+static unsigned long *get_pp(void *host_buffer, int size) {
|
|
+ unsigned long *pp, flags;
|
|
+ int npages,pp_size,rc;
|
|
+
|
|
+ /* Get # of pages */
|
|
+ npages = size >> PAGE_SHIFT;
|
|
+ if ((npages * PAGE_SIZE) < size) npages++;
|
|
+
|
|
+ /* Alloc mem for phys pages */
|
|
+ pp_size = npages * sizeof(unsigned long);
|
|
+ pp = kmalloc(pp_size, GFP_KERNEL);
|
|
+ if (!pp) {
|
|
+ printk(KERN_ERR "co_map_buffer: error allocating memory for physical pages!\n");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ /* Request physical pages from the host */
|
|
+ co_passage_page_assert_valid();
|
|
+ co_passage_page_acquire(&flags);
|
|
+ co_passage_page->operation = CO_OPERATION_GETPP;
|
|
+ co_passage_page->params[0] = (unsigned long) pp;
|
|
+ co_passage_page->params[1] = (unsigned long) host_buffer;
|
|
+ co_passage_page->params[2] = size;
|
|
+ co_switch_wrapper();
|
|
+ rc = co_passage_page->params[0];
|
|
+ co_passage_page_release(flags);
|
|
+ if (rc) {
|
|
+ printk(KERN_ERR "co_map_buffer: error getting physical pages from host!\n");
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
+ return pp;
|
|
+}
|
|
+
|
|
+#define VM_OPTS VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_PFNMAP | VM_RAND_READ
|
|
+
|
|
+void *co_map_buffer(void *host_buffer, int size) {
|
|
+ unsigned long addr, *pp, *pd, *pt, pa;
|
|
+ struct vm_struct *area;
|
|
+ void *buffer;
|
|
+ int i,npages,pd_index,pt_index;
|
|
+
|
|
+ /* Get the physical pages for the host buffer */
|
|
+ pp = get_pp(host_buffer, size);
|
|
+ if (!pp) return 0;
|
|
+
|
|
+ /* Get an area of virtual memory */
|
|
+ area = get_vm_area(size, VM_OPTS);
|
|
+ buffer = area->addr;
|
|
+
|
|
+ npages = size >> PAGE_SHIFT;
|
|
+
|
|
+ addr = (unsigned long) buffer;
|
|
+ pd = (unsigned long *) init_mm.pgd;
|
|
+ while(npages) {
|
|
+ /* Get pt */
|
|
+ pd_index = pgd_index(addr);
|
|
+ if (pd[pd_index] != 0) {
|
|
+ pa = pd[pd_index] & PAGE_MASK;
|
|
+ pt = __va(CO_P_TO_PP(pa));
|
|
+ } else {
|
|
+ pt = (unsigned long *) kmalloc(PAGE_SIZE, GFP_KERNEL);
|
|
+ if (!pt) {
|
|
+ printk(KERN_ERR "co_map_buffer: unable to alloc new pt entry!\n");
|
|
+ return 0;
|
|
+ }
|
|
+ memset(pt, 0, PAGE_SIZE);
|
|
+ pa = CO_PP_TO_P(__pa(pt)) | _PAGE_TABLE;
|
|
+ pd[pd_index] = pa;
|
|
+ }
|
|
+
|
|
+ /* Fill pt */
|
|
+ pt_index = pte_index(addr);
|
|
+ for(i=pt_index; i < 1024; i++) {
|
|
+ if (!npages) break;
|
|
+ BUG_ON(pt[i] != 0);
|
|
+ pt[i] = *pp | _PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_DIRTY | _PAGE_ACCESSED;
|
|
+ pp++;
|
|
+ addr += PAGE_SIZE;
|
|
+ npages--;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return buffer;
|
|
+}
|
|
+
|
|
+#if 0
|
|
+void dump_pt(void *buf, int size) {
|
|
+ unsigned long addr, *pd, *pt;
|
|
+ int x, pd_index, pt_index, npages;
|
|
+
|
|
+ npages = size >> PAGE_SHIFT;
|
|
+
|
|
+ addr = (unsigned long) buf;
|
|
+ pd = (unsigned long *) __va(read_cr3());
|
|
+ printk(KERN_INFO "pd: %p\n", pd);
|
|
+ while(npages) {
|
|
+ pd_index = pgd_index(addr);
|
|
+ printk(KERN_INFO "pd[%04d]: %lx\n", pd_index, pd[pd_index]);
|
|
+ BUG_ON(pd[pd_index] == 0);
|
|
+ pt = __va(CO_P_TO_PP(pd[pd_index] & PAGE_MASK));
|
|
+ pt_index = pte_index(addr);
|
|
+ for(x=pt_index; x < 1024; x++) {
|
|
+ if (!npages) break;
|
|
+ printk(KERN_INFO "%04d: pt[%04d]: %08lx\n", npages, x, pt[x]);
|
|
+ addr += PAGE_SIZE;
|
|
+ npages--;
|
|
+ }
|
|
+ }
|
|
+}
|
|
+#endif
|
|
Index: linux-2.6.33-source/arch/x86/kernel/vmlinux.lds.S
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/vmlinux.lds.S
|
|
+++ linux-2.6.33-source/arch/x86/kernel/vmlinux.lds.S
|
|
@@ -101,6 +101,7 @@
|
|
#endif
|
|
. = ALIGN(8);
|
|
_stext = .;
|
|
+ _kernel_start = .; /* coLinux kernel entry */
|
|
TEXT_TEXT
|
|
SCHED_TEXT
|
|
LOCK_TEXT
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/fixmap.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/fixmap.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/fixmap.h
|
|
@@ -25,6 +25,7 @@
|
|
#else
|
|
#include <asm/vsyscall.h>
|
|
#endif
|
|
+#include <asm/cooperative.h>
|
|
|
|
/*
|
|
* We can't declare FIXADDR_TOP as variable for x86_64 because vsyscall
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/io_32.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/io_32.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/io_32.h
|
|
@@ -102,10 +102,18 @@
|
|
|
|
#endif /* __KERNEL__ */
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+static inline void native_io_delay(void)
|
|
+{
|
|
+ asm volatile("jmp 1f; 1: jmp 1f; 1:" : : : "memory");
|
|
+}
|
|
+static inline void io_delay_init(void) {}
|
|
+#else
|
|
extern void native_io_delay(void);
|
|
|
|
extern int io_delay_type;
|
|
extern void io_delay_init(void);
|
|
+#endif
|
|
|
|
#if defined(CONFIG_PARAVIRT)
|
|
#include <asm/paravirt.h>
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/mmzone_32.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/mmzone_32.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/mmzone_32.h
|
|
@@ -7,6 +7,7 @@
|
|
#define _ASM_X86_MMZONE_32_H
|
|
|
|
#include <asm/smp.h>
|
|
+#include <asm/cooperative.h>
|
|
|
|
#ifdef CONFIG_NUMA
|
|
extern struct pglist_data *node_data[];
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/pgtable_32.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/pgtable_32.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/pgtable_32.h
|
|
@@ -17,6 +17,7 @@
|
|
#include <asm/fixmap.h>
|
|
#include <linux/threads.h>
|
|
#include <asm/paravirt.h>
|
|
+#include <asm/cooperative.h>
|
|
|
|
#include <linux/bitops.h>
|
|
#include <linux/slab.h>
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/pgtable_32_types.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/pgtable_32_types.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/pgtable_32_types.h
|
|
@@ -42,6 +42,8 @@
|
|
|
|
#ifdef CONFIG_HIGHMEM
|
|
# define VMALLOC_END (PKMAP_BASE - 2 * PAGE_SIZE)
|
|
+#elif defined(CONFIG_COOPERATIVE)
|
|
+# define VMALLOC_END (CO_VPTR_BASE_START - 2 * PAGE_SIZE)
|
|
#else
|
|
# define VMALLOC_END (FIXADDR_START - 2 * PAGE_SIZE)
|
|
#endif
|
|
Index: linux-2.6.33-source/kernel/sysctl.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/kernel/sysctl.c
|
|
+++ linux-2.6.33-source/kernel/sysctl.c
|
|
@@ -105,7 +105,7 @@
|
|
static int __maybe_unused two = 2;
|
|
static unsigned long one_ul = 1;
|
|
static int one_hundred = 100;
|
|
-#ifdef CONFIG_PRINTK
|
|
+#if defined(CONFIG_PRINTK) && !defined(CONFIG_COOPERATIVE)
|
|
static int ten_thousand = 10000;
|
|
#endif
|
|
|
|
@@ -675,6 +675,7 @@
|
|
.mode = 0644,
|
|
.proc_handler = proc_dointvec,
|
|
},
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
{
|
|
.procname = "printk_delay",
|
|
.data = &printk_delay_msec,
|
|
@@ -684,6 +685,7 @@
|
|
.extra1 = &zero,
|
|
.extra2 = &ten_thousand,
|
|
},
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
#endif
|
|
{
|
|
.procname = "ngroups_max",
|
|
@@ -744,6 +746,7 @@
|
|
.mode = 0644,
|
|
.proc_handler = proc_dointvec,
|
|
},
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
{
|
|
.procname = "io_delay_type",
|
|
.data = &io_delay_type,
|
|
@@ -751,6 +754,7 @@
|
|
.mode = 0644,
|
|
.proc_handler = proc_dointvec,
|
|
},
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
#endif
|
|
#if defined(CONFIG_MMU)
|
|
{
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/system.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/system.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/system.h
|
|
@@ -6,6 +6,7 @@
|
|
#include <asm/cpufeature.h>
|
|
#include <asm/cmpxchg.h>
|
|
#include <asm/nops.h>
|
|
+#include <asm/page.h>
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/irqflags.h>
|
|
@@ -309,8 +310,22 @@
|
|
#define write_cr0(x) (native_write_cr0(x))
|
|
#define read_cr2() (native_read_cr2())
|
|
#define write_cr2(x) (native_write_cr2(x))
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+
|
|
+static inline unsigned long read_cr3(void)
|
|
+{
|
|
+ return CO_P_TO_PP(native_read_cr3());
|
|
+}
|
|
+
|
|
+static inline void write_cr3(unsigned long val)
|
|
+{
|
|
+ native_write_cr3(CO_PP_TO_P(val));
|
|
+}
|
|
+
|
|
+#else
|
|
#define read_cr3() (native_read_cr3())
|
|
#define write_cr3(x) (native_write_cr3(x))
|
|
+#endif
|
|
#define read_cr4() (native_read_cr4())
|
|
#define read_cr4_safe() (native_read_cr4_safe())
|
|
#define write_cr4(x) (native_write_cr4(x))
|
|
Index: linux-2.6.33-source/arch/x86/power/hibernate_32.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/power/hibernate_32.c
|
|
+++ linux-2.6.33-source/arch/x86/power/hibernate_32.c
|
|
@@ -65,7 +65,7 @@
|
|
if (!page_table)
|
|
return NULL;
|
|
|
|
- set_pmd(pmd, __pmd(__pa(page_table) | _PAGE_TABLE));
|
|
+ set_pmd(pmd, __pmd(CO_PP_TO_P(__pa(page_table)) | _PAGE_TABLE));
|
|
|
|
BUG_ON(page_table != pte_offset_kernel(pmd, 0));
|
|
|
|
Index: linux-2.6.33-source/arch/x86/kernel/i8237.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/i8237.c
|
|
+++ linux-2.6.33-source/arch/x86/kernel/i8237.c
|
|
@@ -23,6 +23,7 @@
|
|
|
|
static int i8237A_resume(struct sys_device *dev)
|
|
{
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
unsigned long flags;
|
|
int i;
|
|
|
|
@@ -41,6 +42,7 @@
|
|
enable_dma(4);
|
|
|
|
release_dma_lock(flags);
|
|
+#endif
|
|
|
|
return 0;
|
|
}
|
|
Index: linux-2.6.33-source/arch/x86/mm/Makefile
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/mm/Makefile
|
|
+++ linux-2.6.33-source/arch/x86/mm/Makefile
|
|
@@ -25,4 +25,6 @@
|
|
obj-$(CONFIG_K8_NUMA) += k8topology_64.o
|
|
obj-$(CONFIG_ACPI_NUMA) += srat_$(BITS).o
|
|
|
|
+obj-$(CONFIG_COOPERATIVE) += comap.o
|
|
+
|
|
obj-$(CONFIG_MEMTEST) += memtest.o
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/pgalloc.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/pgalloc.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/pgalloc.h
|
|
@@ -4,6 +4,7 @@
|
|
#include <linux/threads.h>
|
|
#include <linux/mm.h> /* for struct page */
|
|
#include <linux/pagemap.h>
|
|
+#include <asm/cooperative.h>
|
|
|
|
static inline int __paravirt_pgd_alloc(struct mm_struct *mm) { return 0; }
|
|
|
|
@@ -63,7 +64,7 @@
|
|
pmd_t *pmd, pte_t *pte)
|
|
{
|
|
paravirt_alloc_pte(mm, __pa(pte) >> PAGE_SHIFT);
|
|
- set_pmd(pmd, __pmd(__pa(pte) | _PAGE_TABLE));
|
|
+ set_pmd(pmd, __pmd(CO_PP_TO_P(__pa(pte)) | _PAGE_TABLE));
|
|
}
|
|
|
|
static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
|
|
@@ -72,7 +73,7 @@
|
|
unsigned long pfn = page_to_pfn(pte);
|
|
|
|
paravirt_alloc_pte(mm, pfn);
|
|
- set_pmd(pmd, __pmd(((pteval_t)pfn << PAGE_SHIFT) | _PAGE_TABLE));
|
|
+ set_pmd(pmd, __pmd(((pteval_t)CO_PFN_PP_TO_P(pfn) << PAGE_SHIFT) | _PAGE_TABLE));
|
|
}
|
|
|
|
#define pmd_pgtable(pmd) pmd_page(pmd)
|
|
Index: linux-2.6.33-source/arch/x86/kernel/process.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/process.c
|
|
+++ linux-2.6.33-source/arch/x86/kernel/process.c
|
|
@@ -12,6 +12,7 @@
|
|
#include <linux/user-return-notifier.h>
|
|
#include <linux/dmi.h>
|
|
#include <linux/utsname.h>
|
|
+#include <linux/cooperative_internal.h>
|
|
#include <trace/events/power.h>
|
|
#include <linux/hw_breakpoint.h>
|
|
#include <asm/system.h>
|
|
@@ -357,6 +358,12 @@
|
|
}
|
|
#endif
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c)
|
|
+{
|
|
+ pm_idle = co_idle_processor;
|
|
+}
|
|
+#else /* CONFIG_COOPERATIVE */
|
|
/*
|
|
* We use this if we don't have any better
|
|
* idle routine..
|
|
@@ -682,6 +689,7 @@
|
|
return 0;
|
|
}
|
|
early_param("idle", idle_setup);
|
|
+#endif /* CONFIG_COOPERATIVE */
|
|
|
|
unsigned long arch_align_stack(unsigned long sp)
|
|
{
|
|
Index: linux-2.6.33-source/arch/x86/kvm/Kconfig
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kvm/Kconfig
|
|
+++ linux-2.6.33-source/arch/x86/kvm/Kconfig
|
|
@@ -6,7 +6,7 @@
|
|
|
|
menuconfig VIRTUALIZATION
|
|
bool "Virtualization"
|
|
- depends on HAVE_KVM || X86
|
|
+ depends on (HAVE_KVM || X86) && !COOPERATIVE
|
|
default y
|
|
---help---
|
|
Say Y here to get to see options for using your Linux host to run other
|
|
Index: linux-2.6.33-source/arch/x86/include/asm/io.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/include/asm/io.h
|
|
+++ linux-2.6.33-source/arch/x86/include/asm/io.h
|
|
@@ -167,7 +167,12 @@
|
|
*/
|
|
static inline void __iomem *ioremap(resource_size_t offset, unsigned long size)
|
|
{
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ panic("ioremap %ld:%ld\n", (long)offset, size);
|
|
+ return NULL;
|
|
+#else
|
|
return ioremap_nocache(offset, size);
|
|
+#endif
|
|
}
|
|
|
|
extern void iounmap(volatile void __iomem *addr);
|
|
Index: linux-2.6.33-source/arch/x86/kernel/irqinit.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/irqinit.c
|
|
+++ linux-2.6.33-source/arch/x86/kernel/irqinit.c
|
|
@@ -43,6 +43,7 @@
|
|
* (these are usually mapped into the 0x30-0xff vector range)
|
|
*/
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
#ifdef CONFIG_X86_32
|
|
/*
|
|
* Note that on a 486, we don't want to do a SIGFPE on an irq13
|
|
@@ -82,6 +83,7 @@
|
|
.handler = no_action,
|
|
.name = "cascade",
|
|
};
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
|
|
DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
|
|
[0 ... IRQ0_VECTOR - 1] = -1,
|
|
@@ -116,6 +118,7 @@
|
|
return 0;
|
|
}
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
void __init init_ISA_irqs(void)
|
|
{
|
|
int i;
|
|
@@ -249,3 +252,4 @@
|
|
irq_ctx_init(smp_processor_id());
|
|
#endif
|
|
}
|
|
+#endif /* !CONFIG_COOPERATIVE */
|
|
Index: linux-2.6.33-source/arch/x86/Makefile
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/Makefile
|
|
+++ linux-2.6.33-source/arch/x86/Makefile
|
|
@@ -116,8 +116,10 @@
|
|
# Kernel objects
|
|
|
|
head-y := arch/x86/kernel/head_$(BITS).o
|
|
+ifndef CONFIG_COOPERATIVE
|
|
head-y += arch/x86/kernel/head$(BITS).o
|
|
head-y += arch/x86/kernel/head.o
|
|
+endif
|
|
head-y += arch/x86/kernel/init_task.o
|
|
|
|
libs-y += arch/x86/lib/
|
|
Index: linux-2.6.33-source/arch/x86/kernel/x86_init_cooperative.c
|
|
===================================================================
|
|
--- /dev/null
|
|
+++ linux-2.6.33-source/arch/x86/kernel/x86_init_cooperative.c
|
|
@@ -0,0 +1,94 @@
|
|
+/*
|
|
+ * Copyright (C) 2009 Thomas Gleixner <tglx@linutronix.de>
|
|
+ *
|
|
+ * For licencing details see kernel-base/COPYING
|
|
+ */
|
|
+#include <linux/init.h>
|
|
+#include <linux/kernel.h>
|
|
+
|
|
+#include <asm/bios_ebda.h>
|
|
+#include <asm/paravirt.h>
|
|
+#include <asm/mpspec.h>
|
|
+#include <asm/setup.h>
|
|
+#include <asm/apic.h>
|
|
+#include <asm/e820.h>
|
|
+#include <asm/time.h>
|
|
+#include <asm/irq.h>
|
|
+#include <asm/pat.h>
|
|
+#include <asm/tsc.h>
|
|
+#include <asm/iommu.h>
|
|
+
|
|
+void __cpuinit x86_init_noop(void) { }
|
|
+void __init x86_init_uint_noop(unsigned int unused) { }
|
|
+void __init x86_init_pgd_noop(pgd_t *unused) { }
|
|
+int __init iommu_init_noop(void) { return 0; }
|
|
+void iommu_shutdown_noop(void) { }
|
|
+
|
|
+static void __init reserve_standard_io_resources_noop(void) { }
|
|
+static unsigned long mach_get_cmos_time_noop(void) { return 0; }
|
|
+static int mach_set_rtc_mmss_noop(unsigned long unused) { return 0; }
|
|
+static void __init hpet_time_init_noop(void) { }
|
|
+static void __init native_init_IRQ_noop(void) { }
|
|
+static char *__init default_machine_specific_memory_setup_noop(void) { return "CO-dummy"; }
|
|
+static unsigned long native_calibrate_tsc_noop(void) { return 0; }
|
|
+
|
|
+/*
|
|
+ * The platform setup functions are preset with the default functions
|
|
+ * for standard PC hardware.
|
|
+ */
|
|
+struct x86_init_ops x86_init __initdata = {
|
|
+
|
|
+ .resources = {
|
|
+ .probe_roms = x86_init_noop,
|
|
+ .reserve_resources = reserve_standard_io_resources_noop,
|
|
+ .memory_setup = default_machine_specific_memory_setup_noop,
|
|
+ },
|
|
+
|
|
+ .mpparse = {
|
|
+ .mpc_record = x86_init_uint_noop,
|
|
+ .setup_ioapic_ids = x86_init_noop,
|
|
+ .mpc_apic_id = default_mpc_apic_id,
|
|
+ .smp_read_mpc_oem = default_smp_read_mpc_oem,
|
|
+ .mpc_oem_bus_info = default_mpc_oem_bus_info,
|
|
+ .find_smp_config = default_find_smp_config,
|
|
+ .get_smp_config = default_get_smp_config,
|
|
+ },
|
|
+
|
|
+ .irqs = {
|
|
+ .pre_vector_init = init_ISA_irqs,
|
|
+ .intr_init = native_init_IRQ_noop,
|
|
+ .trap_init = x86_init_noop,
|
|
+ },
|
|
+
|
|
+ .oem = {
|
|
+ .arch_setup = x86_init_noop,
|
|
+ .banner = default_banner,
|
|
+ },
|
|
+
|
|
+ .paging = {
|
|
+ .pagetable_setup_start = native_pagetable_setup_start,
|
|
+ .pagetable_setup_done = native_pagetable_setup_done,
|
|
+ },
|
|
+
|
|
+ .timers = {
|
|
+ .setup_percpu_clockev = setup_boot_APIC_clock,
|
|
+ .tsc_pre_init = x86_init_noop,
|
|
+ .timer_init = hpet_time_init_noop,
|
|
+ },
|
|
+
|
|
+ .iommu = {
|
|
+ .iommu_init = iommu_init_noop,
|
|
+ },
|
|
+};
|
|
+
|
|
+struct x86_cpuinit_ops x86_cpuinit __cpuinitdata = {
|
|
+ .setup_percpu_clockev = setup_secondary_APIC_clock,
|
|
+};
|
|
+
|
|
+struct x86_platform_ops x86_platform = {
|
|
+ .calibrate_tsc = native_calibrate_tsc_noop,
|
|
+ .get_wallclock = mach_get_cmos_time_noop,
|
|
+ .set_wallclock = mach_set_rtc_mmss_noop,
|
|
+ .iommu_shutdown = iommu_shutdown_noop,
|
|
+ .is_untracked_pat_range = is_ISA_range,
|
|
+};
|
|
Index: linux-2.6.33-source/arch/x86/kernel/cpu/Makefile
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/cpu/Makefile
|
|
+++ linux-2.6.33-source/arch/x86/kernel/cpu/Makefile
|
|
@@ -14,7 +14,10 @@
|
|
|
|
obj-y := intel_cacheinfo.o addon_cpuid_features.o
|
|
obj-y += proc.o capflags.o powerflags.o common.o
|
|
-obj-y += vmware.o hypervisor.o sched.o
|
|
+ifndef CONFIG_COOPERATIVE
|
|
+obj-y += vmware.o hypervisor.o
|
|
+endif
|
|
+obj-y += sched.o
|
|
|
|
obj-$(CONFIG_X86_32) += bugs.o cmpxchg.o
|
|
obj-$(CONFIG_X86_64) += bugs_64.o
|
|
Index: linux-2.6.33-source/arch/x86/kernel/cpu/common.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/cpu/common.c
|
|
+++ linux-2.6.33-source/arch/x86/kernel/cpu/common.c
|
|
@@ -818,7 +818,9 @@
|
|
detect_ht(c);
|
|
#endif
|
|
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
init_hypervisor(c);
|
|
+#endif
|
|
|
|
/*
|
|
* Clear/Set all flags overriden by options, need do it
|
|
@@ -864,7 +866,9 @@
|
|
void __init identify_boot_cpu(void)
|
|
{
|
|
identify_cpu(&boot_cpu_data);
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
init_c1e_mask();
|
|
+#endif
|
|
#ifdef CONFIG_X86_32
|
|
sysenter_setup();
|
|
enable_sep_cpu();
|
|
Index: linux-2.6.33-source/include/linux/page-flags.h
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/include/linux/page-flags.h
|
|
+++ linux-2.6.33-source/include/linux/page-flags.h
|
|
@@ -110,6 +110,11 @@
|
|
#endif
|
|
__NR_PAGEFLAGS,
|
|
|
|
+/* coLinux flag should not clear by PAGE_FLAGS_CHECK_AT_PREP */
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+ PG_co_host_mapped, /* Page is mapped on coLinux host */
|
|
+#endif
|
|
+
|
|
/* Filesystems */
|
|
PG_checked = PG_owner_priv_1,
|
|
|
|
@@ -284,6 +289,11 @@
|
|
|
|
u64 stable_page_flags(struct page *page);
|
|
|
|
+#ifdef CONFIG_COOPERATIVE
|
|
+CLEARPAGEFLAG(CoHostMapped, co_host_mapped)
|
|
+TESTSETFLAG(CoHostMapped, co_host_mapped)
|
|
+#endif
|
|
+
|
|
static inline int PageUptodate(struct page *page)
|
|
{
|
|
int ret = test_bit(PG_uptodate, &(page)->flags);
|
|
Index: linux-2.6.33-source/arch/x86/kernel/cpu/intel.c
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/arch/x86/kernel/cpu/intel.c
|
|
+++ linux-2.6.33-source/arch/x86/kernel/cpu/intel.c
|
|
@@ -91,7 +91,9 @@
|
|
if (c->x86_power & (1 << 8)) {
|
|
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
|
|
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
|
|
+#ifndef CONFIG_COOPERATIVE
|
|
if (!check_tsc_unstable())
|
|
+#endif
|
|
sched_clock_stable = 1;
|
|
}
|
|
|
|
Index: linux-2.6.33-source/scripts/mkmakefile
|
|
===================================================================
|
|
--- linux-2.6.33-source.orig/scripts/mkmakefile
|
|
+++ linux-2.6.33-source/scripts/mkmakefile
|
|
@@ -44,7 +44,10 @@
|
|
|
|
Makefile:;
|
|
|
|
-\$(all) %/: all
|
|
+\$(all): all
|
|
+ @:
|
|
+
|
|
+%/: all
|
|
@:
|
|
|
|
EOF
|