diff options
author | Heiko Carstens <hca@linux.ibm.com> | 2023-07-04 15:47:11 +0200 |
---|---|---|
committer | Heiko Carstens <hca@linux.ibm.com> | 2023-07-24 12:12:22 +0200 |
commit | 83f95671943e6394eda4d20fa9458d4a2ae13c5c (patch) | |
tree | 243c4f037b6824e0f08bd224e453d644ef65e226 /arch/s390/kernel | |
parent | 5ac8c72462cdad56e37981eb2172c5baa1ea40d6 (diff) |
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')
-rw-r--r-- | arch/s390/kernel/diag.c | 24 |
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; |