From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754295AbbGPIsr (ORCPT ); Thu, 16 Jul 2015 04:48:47 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33520 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753958AbbGPIsm (ORCPT ); Thu, 16 Jul 2015 04:48:42 -0400 From: Baoquan He To: linux-kernel@vger.kernel.org, ncroxon@redhat.com, dyoung@redhat.com, mhuang@redhat.com Cc: Baoquan He Subject: [RHEL6.8 Patch 16/19] s390/kdump: Allow copy_oldmem_page() copy to virtual memory Date: Thu, 16 Jul 2015 16:47:14 +0800 Message-Id: <1437036437-25408-20-git-send-email-bhe@redhat.com> In-Reply-To: <1437036437-25408-1-git-send-email-bhe@redhat.com> References: <1437036437-25408-1-git-send-email-bhe@redhat.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Resolves: bz1097904 https://bugzilla.redhat.com/show_bug.cgi?id=1097904 This is back ported from upstream. It need be edited manually since several irrelevant commits are not back ported. commit 191a2fa0a8d2bbb64c98f9b1976fcb37ee5eae6b Author: Michael Holzheu Date: Thu Jul 18 12:18:27 2013 +0200 s390/kdump: Allow copy_oldmem_page() copy to virtual memory The kdump mmap patch series (git commit 83086978c63afd7c73e1c) changed the requirements for copy_oldmem_page(). Now this function is used for copying to virtual memory. So implement vmalloc support for the s390 version of copy_oldmem_page(). Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky Signed-off-by: Baoquan He --- arch/s390/kernel/crash_dump.c | 49 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/arch/s390/kernel/crash_dump.c b/arch/s390/kernel/crash_dump.c index b66edb9..0f70217 100644 --- a/arch/s390/kernel/crash_dump.c +++ b/arch/s390/kernel/crash_dump.c @@ -56,6 +56,47 @@ static int __init setup_elfcorehdr(char *arg) early_param("elfcorehdr", setup_elfcorehdr); /* + * Return physical address for virtual address + */ +static inline void *load_real_addr(void *addr) +{ + unsigned long real_addr; + + asm volatile( + " lra %0,0(%1)\n" + " jz 0f\n" + " la %0,0\n" + "0:" + : "=a" (real_addr) : "a" (addr) : "cc"); + return (void *)real_addr; +} + +/* + * Copy up to one page to vmalloc or real memory + */ +static ssize_t copy_page_real(void *buf, void *src, size_t csize) +{ + size_t size; + + if (is_vmalloc_addr(buf)) { + BUG_ON(csize >= PAGE_SIZE); + /* If buf is not page aligned, copy first part */ + size = min(roundup(__pa(buf), PAGE_SIZE) - __pa(buf), csize); + if (size) { + if (memcpy_real(load_real_addr(buf), src, size)) + return -EFAULT; + buf += size; + src += size; + } + /* Copy second part */ + size = csize - size; + return (size) ? memcpy_real(load_real_addr(buf), src, size) : 0; + } else { + return memcpy_real(buf, src, csize); + } +} + +/* * Copy one page from "oldmem" * * For the kdump reserved memory this functions performs a swap operation: @@ -66,6 +107,7 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, size_t csize, unsigned long offset, int userbuf) { unsigned long src; + int rc; if (!csize) return 0; @@ -77,10 +119,11 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, src < OLDMEM_BASE + OLDMEM_SIZE) src -= OLDMEM_BASE; if (userbuf) - copy_to_user_real((void __user *) buf, (void *) src, csize); + rc = copy_to_user_real((void __force __user *) buf, + (void *) src, csize); else - memcpy_real(buf, (void *) src, csize); - return csize; + rc = copy_page_real(buf, (void *) src, csize); + return (rc == 0) ? csize : rc; } /* -- 2.1.0