Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 83ace270 authored by Michael Holzheu's avatar Michael Holzheu Committed by Martin Schwidefsky
Browse files

[S390] replace diag10() with diag10_range() function



Currently the diag10() function can only release one page. For exploiters
that have to call diag10 on a contiguous memory region this is suboptimal.
This patch replaces the diag10() function with diag10_range() that is
able to release multiple pages. In addition to that the new function now
allows to release memory with addresses higher than 2047 MiB. This was
due to a restriction of the diagnose implementation under z/VM prior to
release 5.2.

Signed-off-by: default avatarMichael Holzheu <holzheu@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 91d37808
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -9,9 +9,22 @@
#define _ASM_S390_DIAG_H

/*
 * Diagnose 10: Release pages
 * Diagnose 10: Release page range
 */
extern void diag10(unsigned long addr);
static inline void diag10_range(unsigned long start_pfn, unsigned long num_pfn)
{
	unsigned long start_addr, end_addr;

	start_addr = start_pfn << PAGE_SHIFT;
	end_addr = (start_pfn + num_pfn - 1) << PAGE_SHIFT;

	asm volatile(
		"0:	diag	%0,%1,0x10\n"
		"1:\n"
		EX_TABLE(0b, 1b)
		EX_TABLE(1b, 1b)
		: : "a" (start_addr), "a" (end_addr));
}

/*
 * Diagnose 14: Input spool file manipulation
+0 −21
Original line number Diff line number Diff line
@@ -8,27 +8,6 @@
#include <linux/module.h>
#include <asm/diag.h>

/*
 * Diagnose 10: Release pages
 */
void diag10(unsigned long addr)
{
	if (addr >= 0x7ff00000)
		return;
	asm volatile(
#ifdef CONFIG_64BIT
		"	sam31\n"
		"	diag	%0,%0,0x10\n"
		"0:	sam64\n"
#else
		"	diag	%0,%0,0x10\n"
		"0:\n"
#endif
		EX_TABLE(0b, 0b)
		: : "a" (addr));
}
EXPORT_SYMBOL(diag10);

/*
 * Diagnose 14: Input spool file manipulation
 */
+1 −1
Original line number Diff line number Diff line
@@ -91,7 +91,7 @@ static long cmm_alloc_pages(long nr, long *counter,
			} else
				free_page((unsigned long) npa);
		}
		diag10(addr);
		diag10_range(addr >> PAGE_SHIFT, 1);
		pa->pages[pa->index++] = addr;
		(*counter)++;
		spin_unlock(&cmm_lock);