Compare commits

...
Author SHA1 Message Date
Jan Andres 9cbb077f8d Fix NULL pointer dereference in eventfd read call
Starting with commit 12aceb89b0bc ("eventfd: convert to f_op->read_iter()")
in 5.8-rc1, 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. We can do that safely for
kernel 4.14 and newer (older versions have different arguments of
kernel_read() and kernel_write()).
2020-09-19 21:58:43 +02:00
Jan Andres 4e40ef62ee 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 commit cca98e9f8b5e
("mm: enforce that vmap can't map pages executable") in 5.8-rc1.

Emulate previous behavior of vmap() by using alloc_vm_area() and
explicitly setting the PTE.
2020-09-19 21:58:43 +02:00
Michal Kubecek 11bf1a7d96 vmmon: include <asm/irq_vectors.h> explicitly
After mainline commit 13c01139b171 ("x86/headers: Remove APIC headers from
<asm/smp.h>") in 5.9-rc1, APIC headers are no longer included via
<asm/smp.h> so that linux/hostif.c will lack the definition of
SPURIOUS_APIC_VECTOR.

Include <asm/irq_vectors.h> in linux/hostif.c explicitly to avoid that.
2020-08-20 11:17:17 +02:00
Michal Kubecek f3b55e5bca vmmon: handle change of vmstat slab counters to bytes
Mainline commit d42f3245c7e2 ("mm: memcg: convert vmstat slab counters to
bytes") in kernel 5.9-rc1 changed vmstat accounting of slab to byte
counters. Unfortunately there doesn't seem to be any obvious way to check
for this change except version check.
2020-08-20 10:20:07 +02:00
+31 -1
View File
@@ -47,7 +47,9 @@
#include <asm/asm.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/tlbflush.h>
#include <asm/uaccess.h>
#include <asm/irq_vectors.h>
#include <linux/capability.h>
#include <linux/kthread.h>
#include <linux/wait.h>
@@ -623,7 +625,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
}
@@ -1529,8 +1548,11 @@ HostIF_EstimateLockedPageLimit(const VMDriver* vm, // IN
#else
lockedPages += global_page_state(NR_PAGETABLE);
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 9, 0)
/* NR_SLAB_* converted to byte counters in 5.9 */
lockedPages += global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
/* NR_SLAB_* moved from zone to node in 4.13. */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
lockedPages += global_node_page_state(NR_SLAB_UNRECLAIMABLE);
#else
lockedPages += global_page_state(NR_SLAB_UNRECLAIMABLE);
@@ -2239,7 +2261,11 @@ HostIF_SemaphoreWait(VMDriver *vm, // IN:
* reading no bytes (EAGAIN - non blocking fd) or sizeof(uint64).
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 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;
@@ -2352,7 +2378,11 @@ HostIF_SemaphoreSignal(uint64 *args) // IN:
* it be present.
*/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 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;