diff options
Diffstat (limited to 'openonload-201606-bug64486-63982-ilog2-no_KALLSYMS_ALL.patch')
-rw-r--r-- | openonload-201606-bug64486-63982-ilog2-no_KALLSYMS_ALL.patch | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/openonload-201606-bug64486-63982-ilog2-no_KALLSYMS_ALL.patch b/openonload-201606-bug64486-63982-ilog2-no_KALLSYMS_ALL.patch new file mode 100644 index 000000000000..9015aab27489 --- /dev/null +++ b/openonload-201606-bug64486-63982-ilog2-no_KALLSYMS_ALL.patch @@ -0,0 +1,135 @@ +diff -ur openonload-201606/src/driver/linux_onload/x86_linux_trampoline.c openonload-201606_patched/src/driver/linux_onload/x86_linux_trampoline.c +--- openonload-201606/src/driver/linux_onload/x86_linux_trampoline.c 2016-06-30 11:42:18.000000000 +0100 ++++ openonload-201606_patched/src/driver/linux_onload/x86_linux_trampoline.c 2016-08-15 16:24:49.526866000 +0100 +@@ -290,19 +290,22 @@ + */ + static void **find_syscall_table(void) + { +- unsigned long *idtbase = NULL; +- unsigned char *p, *end, idt[6]; ++ unsigned char *p = NULL; ++ unsigned char *end; + void **result = NULL; + + #ifdef ERFM_HAVE_NEW_KALLSYMS + /* Linux-4.4 & 4.5: */ +- idtbase = efrm_find_ksym("do_syscall_32_irqs_on"); ++ p = efrm_find_ksym("do_syscall_32_irqs_on"); + /* Linux-4.6: */ +- if( idtbase == NULL ) +- idtbase = efrm_find_ksym("do_int80_syscall_32"); ++ if( p == NULL ) ++ p = efrm_find_ksym("do_int80_syscall_32"); + #endif + +- if( idtbase == NULL ) { ++ if( p == NULL ) { ++ unsigned long *idtbase; ++ unsigned char idt[6]; ++ + __asm__("sidt %0" : "=m"(idt)); + idtbase = (unsigned long *)(idt[2] | (idt[3] << 8) | (idt[4] << 16) + | (idt[5] << 24)); +@@ -311,9 +314,6 @@ + p = (unsigned char *)((idtbase[0x80*2] & 0xffff) + | (idtbase[0x80*2+1] & 0xffff0000)); + } +- else { +- p = (void *)idtbase; +- } + TRAMP_DEBUG("int 0x80 entry point at %p", p); + end = p + 1024 - 7; + while (p < end) { +@@ -366,30 +366,45 @@ + static void **find_ia32_syscall_table(void) + { + unsigned long result = 0; +- unsigned char *p, *pend; +- unsigned int *idtbase; +- unsigned char idt[10]; ++ unsigned char *p = NULL; ++ unsigned char *pend; + + #ifdef ERFM_HAVE_NEW_KALLSYMS +- void *addr; +- ++#if 0 ++ /* It works with CONFIG_KALLSYMS_ALL=y only. */ + /* Linux>=4.2: ia32_sys_call_table is not a local variable any more, so +- * we can use kallsyms to find it. */ ++ * we can use kallsyms to find it if CONFIG_KALLSYMS_ALL=y. */ ++ void *addr; + addr = efrm_find_ksym("ia32_sys_call_table"); + if( addr != NULL ) + return addr; + #endif + +- /* linux<4.4: ia32_sys_call_table is an internal variable in +- * linux/arch/x86/entry/entry_64_compat.S, and we can parse this asm +- * code. */ +- __asm__("sidt %0" : "=m"(idt)); +- idtbase = *(unsigned int **)(&idt[2]); +- TRAMP_DEBUG("idt base=%p, entry 0x80=%08x,%08x,%08x", idtbase, +- idtbase[0x80*4], idtbase[0x80*4+1], idtbase[0x80*4+2]); +- result = (idtbase[0x80*4] & 0xffff) | (idtbase[0x80*4+1] & 0xffff0000) +- | ((unsigned long)idtbase[0x80*4+2] << 32); +- p = (unsigned char *)result; ++ /* Linux-4.4 & 4.5: do_syscall_32_irqs_off is a function, so it does not ++ * require CONFIG_KALLSYMS_ALL=y. */ ++ p = efrm_find_ksym("do_syscall_32_irqs_off"); ++ /* Linux-4.6: */ ++ if( p == NULL ) ++ p = efrm_find_ksym("do_int80_syscall_32"); ++#endif ++ ++ if( p == NULL ) { ++ /* linux<4.4: get ia32_sys_call_table variable from asm code at ++ * linux/arch/x86/entry/entry_64_compat.S. */ ++ unsigned int *idtbase; ++ unsigned char idt[10]; ++ ++ __asm__("sidt %0" : "=m"(idt)); ++ idtbase = *(unsigned int **)(&idt[2]); ++ TRAMP_DEBUG("idt base=%p, entry 0x80=%08x,%08x,%08x", idtbase, ++ idtbase[0x80*4], idtbase[0x80*4+1], idtbase[0x80*4+2]); ++ result = (idtbase[0x80*4] & 0xffff) | (idtbase[0x80*4+1] & 0xffff0000) ++ | ((unsigned long)idtbase[0x80*4+2] << 32); ++ p = (unsigned char *)result; ++ } ++ else { ++ result = (unsigned long)p; ++ } + TRAMP_DEBUG("int 0x80 entry point at %p", p); + pend = p + 1024 - 7; + while (p < pend) { +diff -ur openonload-201606/src/include/onload/version.h openonload-201606_patched/src/include/onload/version.h +--- openonload-201606/src/include/onload/version.h 2016-06-30 11:42:26.000000000 +0100 ++++ openonload-201606_patched/src/include/onload/version.h 2016-08-15 16:28:05.299169000 +0100 +@@ -29,7 +29,7 @@ + + + #ifndef ONLOAD_VERSION +-# define ONLOAD_VERSION "201606" ++# define ONLOAD_VERSION "201606-p63982-p64486" + #endif + + #define ONLOAD_PRODUCT "OpenOnload" +diff -ur openonload-201606/src/lib/efrm/vi_resource_alloc.c openonload-201606_patched/src/lib/efrm/vi_resource_alloc.c +--- openonload-201606/src/lib/efrm/vi_resource_alloc.c 2016-06-30 11:42:13.000000000 +0100 ++++ openonload-201606_patched/src/lib/efrm/vi_resource_alloc.c 2016-08-15 16:27:44.743189000 +0100 +@@ -1432,6 +1432,15 @@ + + qso->q_len_entries = n_q_entries; + qso->q_len_bytes = efrm_vi_q_bytes(virs, q_type, n_q_entries); ++ ++ /* This value should always be positive, but if we don't check for this ++ * explicitly, some compilers will assume that undefined logarithms ++ * can be taken in get_order() and will generate code that won't link. ++ * See bug63982. */ ++ EFRM_ASSERT(qso->q_len_bytes > 0); ++ if (qso->q_len_bytes <= 0) ++ return -EINVAL; ++ + qso->q_len_page_order = get_order(qso->q_len_bytes); + return 0; + } |