* 64 bit s390 and 2.4.0-test11 (was Memory management bug)
@ 2000-12-07 13:15 schwidefsky
0 siblings, 0 replies; only message in thread
From: schwidefsky @ 2000-12-07 13:15 UTC (permalink / raw)
To: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1960 bytes --]
Hi,
good news (at least for us): linux on the 64 bit S/390 (aka zServer)
is now running pretty stable. Our implementation of ptep_get_and_clear
didn't clear the pte if the invalid bit was already set. But a swapped
page has the invalid bit set too and in that case we didn't clear the
pte. That did cause the BUG() in swap_state.c:60.
With this new backend in mind I'd like to suggest two small changes
for the common code.
1) move establish_pte to the architecture dependent folders. Our
implementation looks like this:
static inline void ptep_invalidate_and_flush(pte_t *ptep, unsigned long
addr)
{
if (!(pte_val(*ptep) & _PAGE_INVALID))
__asm__ __volatile__ ("ipte %0,%1" : : "a" (ptep), "a"
(addr));
}
static inline void establish_pte(struct vm_area_struct * vma,
unsigned long address,
pte_t *page_table, pte_t entry)
{
ptep_invalidate_and_flush(page_table, address);
set_pte(page_table, entry);
}
The question I face at the moment is: where is the right place in
include/asm for establish_pte. I added it to include/asm-generic/pgtable.h
and include/asm-i386/pgtable.h but I now face the problem that the
default implementation has a call to flush_tlb_page and that is defined
in pgalloc.h. I added an #include <asm/pgalloc.h> but I fear that this
could
cause compile errors. For details see establish_pte.diff.
2) add a check for EI_CLASS in the binfmt_elf loader. We will use the
same EM_S390 for 31 bit and 64 bit binaries. The distinction is done
by means of the EI_CLASS byte in the ELF header. See binfmt_elf.diff
blue skies,
Martin
Linux/390 Design & Development, IBM Deutschland Entwicklung GmbH
Schönaicherstr. 220, D-71032 Böblingen, Telefon: 49 - (0)7031 - 16-2247
E-Mail: schwidefsky@de.ibm.com
(See attached file: establish_pte.diff)(See attached file: binfmt_elf.diff)
[-- Attachment #2: establish_pte.diff --]
[-- Type: application/octet-stream, Size: 2700 bytes --]
diff -u -r --new-file linux-2.4.0-test11/include/asm-generic/pgtable.h linux-2.4.0-test11-establish_pte/include/asm-generic/pgtable.h
--- linux-2.4.0-test11/include/asm-generic/pgtable.h Fri Oct 20 00:51:16 2000
+++ linux-2.4.0-test11-establish_pte/include/asm-generic/pgtable.h Wed Dec 6 20:52:00 2000
@@ -1,6 +1,8 @@
#ifndef _ASM_GENERIC_PGTABLE_H
#define _ASM_GENERIC_PGTABLE_H
+#include <asm/pgalloc.h>
+
static inline int ptep_test_and_clear_young(pte_t *ptep)
{
pte_t pte = *ptep;
@@ -40,4 +40,17 @@
#define pte_same(A,B) (pte_val(A) == pte_val(B))
+/*
+ * Establish a new mapping:
+ * - flush the old one
+ * - update the page tables
+ * - inform the TLB about the new one
+ */
+static inline void establish_pte(struct vm_area_struct * vma, unsigned long address, pte_t *page_table, pte_t entry)
+{
+ set_pte(page_table, entry);
+ flush_tlb_page(vma, address);
+ update_mmu_cache(vma, address, entry);
+}
+
#endif /* _ASM_GENERIC_PGTABLE_H */
diff -u -r --new-file linux-2.4.0-test11/include/asm-i386/pgtable.h linux-2.4.0-test11-establish_pte/include/asm-i386/pgtable.h
--- linux-2.4.0-test11/include/asm-i386/pgtable.h Sun Nov 19 05:56:59 2000
+++ linux-2.4.0-test11-establish_pte/include/asm-i386/pgtable.h Wed Dec 6 20:53:43 2000
@@ -287,6 +287,20 @@
static inline void ptep_mkdirty(pte_t *ptep) { set_bit(_PAGE_BIT_RW, ptep); }
/*
+ * Establish a new mapping:
+ * - flush the old one
+ * - update the page tables
+ * - inform the TLB about the new one
+ */
+static inline void establish_pte(struct vm_area_struct * vma, unsigned long address, pte_t *page_table, pte_t entry)
+{
+ set_pte(page_table, entry);
+ if (vma->vm_mm == current->active_mm)
+ __flush_tlb_one(addr);
+ update_mmu_cache(vma, address, entry);
+}
+
+/*
* Conversion functions: convert a page and protection to a page entry,
* and a page entry and page directory to the page they refer to.
*/
diff -u -r --new-file linux-2.4.0-test11/mm/memory.c linux-2.4.0-test11-establish_pte/mm/memory.c
--- linux-2.4.0-test11/mm/memory.c Wed Nov 1 16:45:09 2000
+++ linux-2.4.0-test11-establish_pte/mm/memory.c Wed Dec 6 20:52:00 2000
@@ -773,19 +773,6 @@
return error;
}
-/*
- * Establish a new mapping:
- * - flush the old one
- * - update the page tables
- * - inform the TLB about the new one
- */
-static inline void establish_pte(struct vm_area_struct * vma, unsigned long address, pte_t *page_table, pte_t entry)
-{
- set_pte(page_table, entry);
- flush_tlb_page(vma, address);
- update_mmu_cache(vma, address, entry);
-}
-
static inline void break_cow(struct vm_area_struct * vma, struct page * old_page, struct page * new_page, unsigned long address,
pte_t *page_table)
{
[-- Attachment #3: binfmt_elf.diff --]
[-- Type: application/octet-stream, Size: 724 bytes --]
diff -u -r --new-file linux-2.4.0-test11/fs/binfmt_elf.c linux-2.4.0-test11-establish_pte/fs/binfmt_elf.c
--- linux-2.4.0-test11/fs/binfmt_elf.c Fri Oct 27 20:04:43 2000
+++ linux-2.4.0-test11-establish_pte/fs/binfmt_elf.c Wed Dec 6 20:52:00 2000
@@ -247,6 +247,8 @@
goto out;
if (!elf_check_arch(interp_elf_ex))
goto out;
+ if (interp_elf_ex->e_ident[EI_CLASS] != ELF_CLASS)
+ goto out;
if (!interpreter->f_op->mmap)
goto out;
@@ -422,6 +424,8 @@
if (elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN)
goto out;
if (!elf_check_arch(&elf_ex))
+ goto out;
+ if (elf_ex.e_ident[EI_CLASS] != ELF_CLASS)
goto out;
if (!bprm->file->f_op||!bprm->file->f_op->mmap)
goto out;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2000-12-07 14:23 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-12-07 13:15 64 bit s390 and 2.4.0-test11 (was Memory management bug) schwidefsky
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®