]> git.zerfleddert.de Git - ms2-kexec/commitdiff
use setup_mm_for_reboot from current kernels, no need for init_mm
authorMichael Gernoth <michael@gernoth.net>
Sun, 22 May 2011 19:55:03 +0000 (21:55 +0200)
committerMichael Gernoth <michael@gernoth.net>
Sun, 22 May 2011 19:55:03 +0000 (21:55 +0200)
Makefile
idmap.c [new file with mode: 0644]

index adf1b83ee536e2850317aa45757f5d54279ddbbb..61a5644125b6584c515f6a5663fb0fb65efec49f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -6,7 +6,7 @@ CROSS_PATH=$(PWD)/../prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/bin
 EXTRA_CFLAGS += -DCONFIG_KEXEC -Wall
 
 obj-m += kexec_load.o
 EXTRA_CFLAGS += -DCONFIG_KEXEC -Wall
 
 obj-m += kexec_load.o
-kexec_load-objs := kexec.o machine_kexec.o mmu.o sys.o core.o relocate_kernel.o \
+kexec_load-objs := kexec.o machine_kexec.o idmap.o sys.o core.o relocate_kernel.o \
        proc-v7.o tlb-v7.o cache-v7.o abort-ev7.o pabort-v7.o copypage-v6.o entry-common.o driver_sys.o
 
 all:
        proc-v7.o tlb-v7.o cache-v7.o abort-ev7.o pabort-v7.o copypage-v6.o entry-common.o driver_sys.o
 
 all:
diff --git a/idmap.c b/idmap.c
new file mode 100644 (file)
index 0000000..e667f74
--- /dev/null
+++ b/idmap.c
@@ -0,0 +1,92 @@
+#include <linux/kernel.h>
+
+#include <asm/cputype.h>
+#include <asm/pgalloc.h>
+#include <asm/pgtable.h>
+
+static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
+       unsigned long prot)
+{
+       pmd_t *pmd = pmd_offset(pud, addr);
+
+       addr = (addr & PMD_MASK) | prot;
+       pmd[0] = __pmd(addr);
+       addr += SECTION_SIZE;
+       pmd[1] = __pmd(addr);
+       flush_pmd_entry(pmd);
+}
+
+static void idmap_add_pud(pgd_t *pgd, unsigned long addr, unsigned long end,
+       unsigned long prot)
+{
+       pud_t *pud = pud_offset(pgd, addr);
+       unsigned long next;
+
+       do {
+               next = pud_addr_end(addr, end);
+               idmap_add_pmd(pud, addr, next, prot);
+       } while (pud++, addr = next, addr != end);
+}
+
+void identity_mapping_add(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+       unsigned long prot, next;
+
+       prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE;
+#if 0
+       if (cpu_architecture() <= CPU_ARCH_ARMv5TEJ && !cpu_is_xscale())
+               prot |= PMD_BIT4;
+#endif
+
+       pgd += pgd_index(addr);
+       do {
+               next = pgd_addr_end(addr, end);
+               idmap_add_pud(pgd, addr, next, prot);
+       } while (pgd++, addr = next, addr != end);
+}
+
+#ifdef CONFIG_SMP
+static void idmap_del_pmd(pud_t *pud, unsigned long addr, unsigned long end)
+{
+       pmd_t *pmd = pmd_offset(pud, addr);
+       pmd_clear(pmd);
+}
+
+static void idmap_del_pud(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+       pud_t *pud = pud_offset(pgd, addr);
+       unsigned long next;
+
+       do {
+               next = pud_addr_end(addr, end);
+               idmap_del_pmd(pud, addr, next);
+       } while (pud++, addr = next, addr != end);
+}
+
+void identity_mapping_del(pgd_t *pgd, unsigned long addr, unsigned long end)
+{
+       unsigned long next;
+
+       pgd += pgd_index(addr);
+       do {
+               next = pgd_addr_end(addr, end);
+               idmap_del_pud(pgd, addr, next);
+       } while (pgd++, addr = next, addr != end);
+}
+#endif
+
+/*
+ * In order to soft-boot, we need to insert a 1:1 mapping in place of
+ * the user-mode pages.  This will then ensure that we have predictable
+ * results when turning the mmu off
+ */
+void setup_mm_for_reboot(char mode)
+{
+       /*
+        * We need to access to user-mode page tables here. For kernel threads
+        * we don't have any user-mode mappings so we use the context that we
+        * "borrowed".
+        */
+       identity_mapping_add(current->active_mm->pgd, 0, TASK_SIZE);
+       local_flush_tlb_all();
+}
Impressum, Datenschutz