summaryrefslogtreecommitdiff
path: root/arch/s390/kernel/diag.c
diff options
context:
space:
mode:
authorHeiko Carstens <hca@linux.ibm.com>2023-07-04 16:47:11 +0300
committerHeiko Carstens <hca@linux.ibm.com>2023-07-24 13:12:22 +0300
commit83f95671943e6394eda4d20fa9458d4a2ae13c5c (patch)
tree243c4f037b6824e0f08bd224e453d644ef65e226 /arch/s390/kernel/diag.c
parent5ac8c72462cdad56e37981eb2172c5baa1ea40d6 (diff)
downloadlinux-83f95671943e6394eda4d20fa9458d4a2ae13c5c.tar.xz
s390/hypfs: simplify memory allocation
Simplify memory allocation for diagnose 204 memory buffer: - allocate with __vmalloc_node() to enure page alignment - allocate real / physical memory area also within vmalloc area and handle vmalloc to real / physical address translation within diag204(). Acked-by: Alexander Gordeev <agordeev@linux.ibm.com> Reviewed-by: Mete Durlu <meted@linux.ibm.com> Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Diffstat (limited to 'arch/s390/kernel/diag.c')
-rw-r--r--arch/s390/kernel/diag.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c
index f3a0f39cbd6c..f287713baf6d 100644
--- a/arch/s390/kernel/diag.c
+++ b/arch/s390/kernel/diag.c
@@ -11,6 +11,7 @@
#include <linux/cpu.h>
#include <linux/seq_file.h>
#include <linux/debugfs.h>
+#include <linux/vmalloc.h>
#include <asm/asm-extable.h>
#include <asm/diag.h>
#include <asm/trace/diag.h>
@@ -168,11 +169,30 @@ static inline int __diag204(unsigned long *subcode, unsigned long size, void *ad
return rp.odd;
}
+/**
+ * diag204() - Issue diagnose 204 call.
+ * @subcode: Subcode of diagnose 204 to be executed.
+ * @size: Size of area in pages which @area points to, if given.
+ * @addr: Vmalloc'ed memory area where the result is written to.
+ *
+ * Execute diagnose 204 with the given subcode and write the result to the
+ * memory area specified with @addr. For subcodes which do not write a
+ * result to memory both @size and @addr must be zero. If @addr is
+ * specified it must be page aligned and must have been allocated with
+ * vmalloc(). Conversion to real / physical addresses will be handled by
+ * this function if required.
+ */
int diag204(unsigned long subcode, unsigned long size, void *addr)
{
- diag_stat_inc(DIAG_STAT_X204);
+ if (addr) {
+ if (WARN_ON_ONCE(!is_vmalloc_addr(addr)))
+ return -1;
+ if (WARN_ON_ONCE(!IS_ALIGNED((unsigned long)addr, PAGE_SIZE)))
+ return -1;
+ }
if ((subcode & DIAG204_SUBCODE_MASK) == DIAG204_SUBC_STIB4)
- addr = (void *)__pa(addr);
+ addr = (void *)pfn_to_phys(vmalloc_to_pfn(addr));
+ diag_stat_inc(DIAG_STAT_X204);
size = __diag204(&subcode, size, addr);
if (subcode)
return -1;