From mboxrd@z Thu Jan 1 00:00:00 1970 From: Janosch Frank Subject: [RFC/PATCH v2 13/22] s390/mm: Make gmap_read_table EDAT1 compatible Date: Wed, 13 Dec 2017 13:53:24 +0100 Message-ID: <1513169613-13509-14-git-send-email-frankja@linux.vnet.ibm.com> References: <1513169613-13509-1-git-send-email-frankja@linux.vnet.ibm.com> Cc: schwidefsky@de.ibm.com, borntraeger@de.ibm.com, david@redhat.com, dominik.dingel@gmail.com, linux-s390@vger.kernel.org To: kvm@vger.kernel.org Return-path: Received: from mx0b-001b2d01.pphosted.com ([148.163.158.5]:48176 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753141AbdLMMyi (ORCPT ); Wed, 13 Dec 2017 07:54:38 -0500 Received: from pps.filterd (m0098419.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id vBDCs2t0102551 for ; Wed, 13 Dec 2017 07:54:37 -0500 Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com [195.75.94.109]) by mx0b-001b2d01.pphosted.com with ESMTP id 2eu439hm0f-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Wed, 13 Dec 2017 07:54:37 -0500 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Wed, 13 Dec 2017 12:54:35 -0000 In-Reply-To: <1513169613-13509-1-git-send-email-frankja@linux.vnet.ibm.com> Sender: kvm-owner@vger.kernel.org List-ID: For the VSIE we shadow the GMAP/DAT tables that a guest N builds for its N + 1 guest. This means we read the GMAP from the memory of guest N and use the retrieved information to build a shadow version from it which is actually used to run the guest. gmap_read_table is used to retrieve the data from the guest's address space. Unfortunately it currently has no support for reading from huge guests, so let's add that. Signed-off-by: Janosch Frank --- arch/s390/mm/gmap.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/arch/s390/mm/gmap.c b/arch/s390/mm/gmap.c index dabc734..828eadf 100644 --- a/arch/s390/mm/gmap.c +++ b/arch/s390/mm/gmap.c @@ -1201,23 +1201,38 @@ int gmap_read_table(struct gmap *gmap, unsigned long gaddr, unsigned long *val) { unsigned long address, vmaddr; spinlock_t *ptl; + pmd_t *pmdp, pmd; pte_t *ptep, pte; int rc; while (1) { rc = -EAGAIN; - ptep = gmap_pte_op_walk(gmap, gaddr, &ptl); - if (ptep) { - pte = *ptep; - if (pte_present(pte) && (pte_val(pte) & _PAGE_READ)) { - address = pte_val(pte) & PAGE_MASK; - address += gaddr & ~PAGE_MASK; - *val = *(unsigned long *) address; - pte_val(*ptep) |= _PAGE_YOUNG; - /* Do *NOT* clear the _PAGE_INVALID bit! */ - rc = 0; + pmdp = gmap_pmd_op_walk(gmap, gaddr); + if (pmdp) { + if (!pmd_large(*pmdp)) { + ptep = pte_alloc_map_lock(gmap->mm, pmdp, gaddr, &ptl); + if (ptep) { + pte = *ptep; + if (pte_present(pte) && (pte_val(pte) & _PAGE_READ)) { + address = pte_val(pte) & PAGE_MASK; + address += gaddr & ~PAGE_MASK; + *val = *(unsigned long *) address; + pte_val(*ptep) |= _PAGE_YOUNG; + /* Do *NOT* clear the _PAGE_INVALID bit! */ + rc = 0; + } + gmap_pte_op_end(ptl); + } + } else { + pmd = *pmdp; + if (!(pmd_val(pmd) & _SEGMENT_ENTRY_INVALID)) { + address = pmd_val(pmd) & HPAGE_MASK; + address += gaddr & ~HPAGE_MASK; + *val = *(unsigned long *) address; + rc = 0; + } } - gmap_pte_op_end(ptl); + gmap_pmd_op_end(gmap, pmdp); } if (!rc) break; -- 2.7.4