summarylogtreecommitdiffstats
path: root/openonload-201606-bug64486-63982.patch
blob: 93df45fbd0ba9e7c8e36bc15df08d2301291cda4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
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 14:32:18.640463000 +0100
@@ -367,29 +367,42 @@
 {
   unsigned long result = 0;
   unsigned char *p, *pend;
-  unsigned int *idtbase;
+  unsigned int *idtbase = NULL;
   unsigned char idt[10];
 
 #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. */
+  idtbase = efrm_find_ksym("do_syscall_32_irqs_off");
+  /* Linux-4.6: */
+  if( idtbase == NULL )
+    idtbase = efrm_find_ksym("do_int80_syscall_32");
+#endif
+
+  if( idtbase == NULL ) {
+    /* linux<4.4: get ia32_sys_call_table variable from asm code at
+     * linux/arch/x86/entry/entry_64_compat.S. */
+    __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 {
+    p = (void *)idtbase;
+  }
   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-08-15 14:47:01.461718000 +0100
+++ openonload-201606_patched/src/include/onload/version.h	2016-08-15 14:47:23.538636000 +0100
@@ -29,7 +29,7 @@
 
 
 #ifndef ONLOAD_VERSION
-# define ONLOAD_VERSION "201606"
+# define ONLOAD_VERSION "201606-p64486_63982"
 #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 14:32:28.140994000 +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;
 }