From: Ingo Molnar I've attached a 'blind' port of the prot bits of fremap to ia64. I've compiled it with a cross-compiler but otherwise it's untested. (and it's very likely i got the pte bits wrong - but it's roughly OK.) This should at least make ia64 compile. Anyone who tests this should also try the attached fremap testcode. (the testcode is x86 but ought to run fine in ia64's emulation layer.) If it runs through and finishes with all OK's printed then the code works fine. I've updated the syscall slots too. /* * Copyright (C) Ingo Molnar, 2002 */ #include #include #include #include #include #include #include #include #include #include #include #include #ifdef __s390__ #define __NR_sys_remap_file_pages 265 #elif __ia64__ #define __NR_sys_remap_file_pages 1259 #elif __i386__ #define __NR_sys_remap_file_pages 280 #else #error "define __NR_sys_remap_file_pages for your architecture" #endif _syscall5(int, sys_remap_file_pages, unsigned long, start, unsigned long, len, unsigned long, prot, unsigned long, pgoff, int, flags); #define PAGE_SIZE 4096 #define PAGE_WORDS (PAGE_SIZE/sizeof(int)) #define CACHE_PAGES 1024 #define CACHE_SIZE (CACHE_PAGES*PAGE_SIZE) #define WINDOW_PAGES 16 #define WINDOW_SIZE (WINDOW_PAGES*PAGE_SIZE) #define WINDOW_START 0x48000000 #define PROT (PROT_READ|PROT_WRITE) #if 0 #define PROT2 (PROT_READ|PROT_WRITE) #define PROT3 (PROT_READ|PROT_WRITE) #else #define PROT2 (PROT_READ) #define PROT3 (PROT_READ) #endif static char cache_contents [CACHE_SIZE]; int main(int argc, char **argv) { unsigned int *data = NULL; int i, j, fd, offset = 30; char *ptr, filename[100]; sys_remap_file_pages(-1, -1, -1, -1, -1); sprintf(filename, "/tmp/cache%d", getpid()); fd = open(filename, O_RDWR|O_CREAT|O_TRUNC,S_IRWXU); if (fd < 0) { perror("death"); printf("could not open cachefile!\n"); exit(1); } for (i = 0; i < CACHE_PAGES; i++) { int *page = (int *) (cache_contents + i*PAGE_SIZE); for (j = 0; j < PAGE_WORDS; j++) page[j] = i; } if (write(fd, cache_contents, CACHE_SIZE) != CACHE_SIZE) { perror("death"); printf("could not write cachefile!\n"); exit(1); } close(fd); // chmod(filename, S_IRUSR); fd = open(filename, O_RDWR,S_IRWXU); ptr = mmap(0, WINDOW_SIZE, PROT, MAP_SHARED // | MAP_POPULATE , fd, 0); if (ptr == MAP_FAILED) { printf("mmap() failed, ptr = %p!\n", ptr); exit(1); } sys_remap_file_pages((unsigned int)ptr, 0x1000, PROT2, 0, 0); data = (int *) ptr; printf("data mapping: %p\n", data); printf("mapping pages in reverse order via remap_file_pages():\n"); again: for (i = 0; i < WINDOW_PAGES; i += 2) { int *page = data + i*(PAGE_SIZE/sizeof(int)); ptr = (char*)sys_remap_file_pages( (unsigned long)page, PAGE_SIZE * 2, PROT3, (WINDOW_PAGES-i+offset), 0); if (ptr) { printf("mmap() of page %d failed, ptr = %p!\n", i, ptr); exit(1); } printf("remapped page %d to %p.\n", i, page); } // sleep(5); printf("page contents:\n"); for (i = 0; i < WINDOW_PAGES; i++) { int index = i*(PAGE_SIZE/sizeof(int)); printf(".. data[%d] (page %d/%p): %d - ", index, i, data + index, data[index]); fflush(stdout); /* * Double-check the correctness of the mapping: */ if (i & 1) { if (data[index] != WINDOW_PAGES-i+offset+2) { printf("hm, mapped incorrect data!\n"); exit(1); } data[index] = WINDOW_PAGES-i+offset+2; } else { if (data[index] != WINDOW_PAGES-i+offset) { printf("hm, mapped incorrect data!\n"); exit(1); } data[index] = WINDOW_PAGES-i+offset; } printf("OK.\n"); } if (--offset >= 0) { goto again; } // for (;;) sleep(1); return 0; } --- 25-akpm/arch/ia64/ia32/ia32_entry.S | 9 ++++++++- 25-akpm/arch/ia64/kernel/entry.S | 4 ++-- 25-akpm/include/asm-ia64/ia32.h | 2 +- 25-akpm/include/asm-ia64/mman.h | 1 + 25-akpm/include/asm-ia64/pgtable.h | 17 +++++++++++++---- 5 files changed, 25 insertions(+), 8 deletions(-) diff -puN arch/ia64/ia32/ia32_entry.S~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 arch/ia64/ia32/ia32_entry.S --- 25/arch/ia64/ia32/ia32_entry.S~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 Tue Mar 30 16:08:09 2004 +++ 25-akpm/arch/ia64/ia32/ia32_entry.S Tue Mar 30 16:08:09 2004 @@ -465,7 +465,7 @@ ia32_syscall_table: data8 sys_epoll_create data8 sys32_epoll_ctl /* 255 */ data8 sys32_epoll_wait - data8 sys_remap_file_pages + data8 old_remap_file_pages data8 sys_set_tid_address data8 sys32_timer_create data8 compat_timer_settime /* 260 */ @@ -484,5 +484,12 @@ ia32_syscall_table: data8 sys_ni_syscall data8 sys_ni_syscall + data8 sys_ni_syscall /* 275 */ + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_ni_syscall + data8 sys_remap_file_pages /* 280 */ + // guard against failures to increase IA32_NR_syscalls .org ia32_syscall_table + 8*IA32_NR_syscalls diff -puN arch/ia64/kernel/entry.S~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 arch/ia64/kernel/entry.S --- 25/arch/ia64/kernel/entry.S~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 Tue Mar 30 16:08:09 2004 +++ 25-akpm/arch/ia64/kernel/entry.S Tue Mar 30 16:08:09 2004 @@ -1367,7 +1367,7 @@ sys_call_table: data8 sys_ni_syscall /* was: ia64_oldfstat */ data8 sys_vhangup data8 sys_lchown - data8 sys_remap_file_pages // 1125 + data8 old_remap_file_pages // 1125 data8 sys_wait4 data8 sys_sysinfo data8 sys_clone @@ -1501,7 +1501,7 @@ sys_call_table: data8 sys_clock_nanosleep data8 sys_fstatfs64 data8 sys_statfs64 - data8 sys_ni_syscall + data8 sys_remap_file_pages data8 sys_ni_syscall // 1260 data8 sys_ni_syscall data8 sys_ni_syscall diff -puN include/asm-ia64/mman.h~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 include/asm-ia64/mman.h --- 25/include/asm-ia64/mman.h~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 Tue Mar 30 16:08:09 2004 +++ 25-akpm/include/asm-ia64/mman.h Tue Mar 30 16:08:09 2004 @@ -30,6 +30,7 @@ #define MAP_NORESERVE 0x04000 /* don't check for reservations */ #define MAP_POPULATE 0x08000 /* populate (prefault) pagetables */ #define MAP_NONBLOCK 0x10000 /* do not block on IO */ +#define MAP_INHERIT 0x20000 /* inherit prot of underlying vma */ #define MS_ASYNC 1 /* sync memory asynchronously */ #define MS_INVALIDATE 2 /* invalidate the caches */ diff -puN include/asm-ia64/pgtable.h~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 include/asm-ia64/pgtable.h --- 25/include/asm-ia64/pgtable.h~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 Tue Mar 30 16:08:09 2004 +++ 25-akpm/include/asm-ia64/pgtable.h Tue Mar 30 16:08:09 2004 @@ -434,7 +434,8 @@ extern void paging_init (void); * Format of file pte: * bit 0 : present bit (must be zero) * bit 1 : _PAGE_FILE (must be one) - * bits 2-62: file_offset/PAGE_SIZE + * bit 2 : _PAGE_AR_RW + * bits 3-62: file_offset/PAGE_SIZE * bit 63 : _PAGE_PROTNONE bit */ #define __swp_type(entry) (((entry).val >> 2) & 0x7f) @@ -443,9 +444,17 @@ extern void paging_init (void); #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) -#define PTE_FILE_MAX_BITS 61 -#define pte_to_pgoff(pte) ((pte_val(pte) << 1) >> 3) -#define pgoff_to_pte(off) ((pte_t) { ((off) << 2) | _PAGE_FILE }) +#define PTE_FILE_MAX_BITS 59 +#define pte_to_pgoff(pte) ((pte_val(pte) << 1) >> 4) + +#define pte_to_pgprot(pte) \ + __pgprot((pte_val(pte) & (_PAGE_AR_RW | _PAGE_PROTNONE)) \ + | ((pte_val(pte) & _PAGE_PROTNONE) ? 0 : \ + (__ACCESS_BITS | _PAGE_PL_3))) + +#define pgoff_prot_to_pte(off, prot) \ + ((pte_t) { _PAGE_FILE + \ + (pgprot_val(prot) & (_PAGE_AR_RW | _PAGE_PROTNONE)) + (off) }) #define io_remap_page_range remap_page_range /* XXX is this right? */ diff -puN include/asm-ia64/ia32.h~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 include/asm-ia64/ia32.h --- 25/include/asm-ia64/ia32.h~remap-file-pages-prot-ia64-2.6.4-rc2-mm1-A0 Tue Mar 30 16:08:09 2004 +++ 25-akpm/include/asm-ia64/ia32.h Tue Mar 30 16:08:09 2004 @@ -6,7 +6,7 @@ #include #include -#define IA32_NR_syscalls 275 /* length of syscall table */ +#define IA32_NR_syscalls 281 /* length of syscall table */ #ifndef __ASSEMBLY__ _