summarylogtreecommitdiffstats
path: root/vmmon.patch
blob: d435cee23c6ea8beb000d34566dece50fada9276 (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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
--- a/vmmon/Makefile
+++ b/vmmon/Makefile
@@ -43,7 +43,11 @@ INCLUDE      += -I$(SRCROOT)/shared
 endif
 
 
+ifdef KVERSION
+VM_UNAME = $(KVERSION)
+else
 VM_UNAME = $(shell uname -r)
+endif
 
 # Header directory for the running kernel
 ifdef LINUXINCLUDE
@@ -137,7 +137,7 @@
 endif
 
 # Add Spectre options when available
-CC_OPTS += $(call vm_check_gcc,-mindirect-branch=thunk -mindirect-branch-register,)
+CC_OPTS += $(call vm_check_gcc,-mindirect-branch-register,)
 
 include $(SRCROOT)/Makefile.kernel
 
From 2da85cbe6d9c0bc5c7c2008748bd12e70ce0f310 Mon Sep 17 00:00:00 2001
From: Jan Andres <jandres@gmx.net>
Date: Fri, 4 Sep 2020 10:53:10 +0200
Subject: [PATCH] Fix NX bit handling for Linux 5.8+

Do not use vmap() to map the cross page, it needs to be executable and
vmap() unconditionally sets the NX bit starting with 5.8.x.

Emulate previous behavior of vmap() by using alloc_vm_area() and
explicitly setting the PTE.
---
 vmmon-only/linux/hostif.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/vmmon-only/linux/hostif.c b/vmmon-only/linux/hostif.c
index 3a48505..ec6856a 100644
--- a/vmmon-only/linux/hostif.c
+++ b/vmmon-only/linux/hostif.c
@@ -47,6 +47,7 @@
 #include <asm/asm.h>
 #include <asm/io.h>
 #include <asm/page.h>
+#include <asm/tlbflush.h>
 #include <asm/uaccess.h>
 #include <linux/capability.h>
 #include <linux/kthread.h>
@@ -634,7 +635,24 @@ HostIF_FastClockUnlock(int callerID) // IN
 static void *
 MapCrossPage(struct page *p)  // IN:
 {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)
    return vmap(&p, 1, VM_MAP, VM_PAGE_KERNEL_EXEC);
+#else
+   /* Starting with 5.8, vmap() always sets the NX bit, but the cross
+    * page needs to be executable. */
+   pte_t *ptes[1];
+   struct vm_struct *area = alloc_vm_area(1UL << PAGE_SHIFT, ptes);
+   if (area == NULL)
+      return NULL;
+
+   set_pte(ptes[0], mk_pte(p, VM_PAGE_KERNEL_EXEC));
+
+   preempt_disable();
+   __flush_tlb_all();
+   preempt_enable();
+
+   return area->addr;
+#endif
 }
 
 
From c71e377757f20dc78a99d42a127124bb2c49e865 Mon Sep 17 00:00:00 2001
From: Jan Andres <jandres@gmx.net>
Date: Fri, 4 Sep 2020 10:59:19 +0200
Subject: [PATCH] Fix NULL pointer dereference in eventfd read call

Starting with 5.8, the "read" function pointer in eventfd's
file_operations is NULL, "read_iter" is available instead.

Use kernel_read() and kernel_write() instead of directly calling the
function pointers to handle this correctly.
---
 vmmon-only/linux/hostif.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/vmmon-only/linux/hostif.c b/vmmon-only/linux/hostif.c
index ec6856a..4a7afb1 100644
--- a/vmmon-only/linux/hostif.c
+++ b/vmmon-only/linux/hostif.c
@@ -2609,7 +2609,11 @@ HostIF_SemaphoreWait(VMDriver *vm,   // IN:
     * reading no bytes (EAGAIN - non blocking fd) or sizeof(uint64).
     */
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
+   res = kernel_read(file, (char *) &value, sizeof value, &file->f_pos);
+#else
    res = file->f_op->read(file, (char *) &value, sizeof value, &file->f_pos);
+#endif
 
    if (res == sizeof value) {
       res = MX_WAITNORMAL;
@@ -2726,7 +2730,11 @@ HostIF_SemaphoreSignal(uint64 *args)  // IN:
     * it be present.
     */
 
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
+   res = kernel_write(file, (char *) &value, sizeof value, &file->f_pos);
+#else
    res = file->f_op->write(file, (char *) &value, sizeof value, &file->f_pos);
+#endif
 
    if (res == sizeof value) {
       res = MX_WAITNORMAL;