From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 71EA3C3F2D3 for ; Fri, 28 Feb 2020 15:43:39 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 1963E246A0 for ; Fri, 28 Feb 2020 15:43:39 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1963E246A0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.ibm.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 51EC46B000A; Fri, 28 Feb 2020 10:43:37 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 45A926B000C; Fri, 28 Feb 2020 10:43:37 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 34A306B000D; Fri, 28 Feb 2020 10:43:37 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0214.hostedemail.com [216.40.44.214]) by kanga.kvack.org (Postfix) with ESMTP id 0F5726B000A for ; Fri, 28 Feb 2020 10:43:37 -0500 (EST) Received: from smtpin23.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay05.hostedemail.com (Postfix) with ESMTP id 1F86C181AEF39 for ; Fri, 28 Feb 2020 15:43:36 +0000 (UTC) X-FDA: 76539955632.23.wind35_599b115c8f04c X-HE-Tag: wind35_599b115c8f04c X-Filterd-Recvd-Size: 7783 Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by imf14.hostedemail.com (Postfix) with ESMTP for ; Fri, 28 Feb 2020 15:43:35 +0000 (UTC) Received: from pps.filterd (m0127361.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 01SFcX8G118343 for ; Fri, 28 Feb 2020 10:43:35 -0500 Received: from e06smtp01.uk.ibm.com (e06smtp01.uk.ibm.com [195.75.94.97]) by mx0a-001b2d01.pphosted.com with ESMTP id 2yepy3ry86-1 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=NOT) for ; Fri, 28 Feb 2020 10:43:34 -0500 Received: from localhost by e06smtp01.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Fri, 28 Feb 2020 15:43:32 -0000 Received: from b06cxnps3075.portsmouth.uk.ibm.com (9.149.109.195) by e06smtp01.uk.ibm.com (192.168.101.131) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; (version=TLSv1/SSLv3 cipher=AES256-GCM-SHA384 bits=256/256) Fri, 28 Feb 2020 15:43:28 -0000 Received: from d06av26.portsmouth.uk.ibm.com (d06av26.portsmouth.uk.ibm.com [9.149.105.62]) by b06cxnps3075.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 01SFhRAV58523828 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Fri, 28 Feb 2020 15:43:27 GMT Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id E81EAAE057; Fri, 28 Feb 2020 15:43:26 +0000 (GMT) Received: from d06av26.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2E1CDAE045; Fri, 28 Feb 2020 15:43:26 +0000 (GMT) Received: from p-imbrenda.emea.ibm.com (unknown [9.145.11.131]) by d06av26.portsmouth.uk.ibm.com (Postfix) with ESMTP; Fri, 28 Feb 2020 15:43:26 +0000 (GMT) From: Claudio Imbrenda To: linux-next@vger.kernel.org, akpm@linux-foundation.org Cc: borntraeger@de.ibm.com, david@redhat.com, aarcange@redhat.com, linux-mm@kvack.org, frankja@linux.ibm.com, sfr@canb.auug.org.au, jhubbard@nvidia.com, linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org, Will Deacon Subject: [RFC v1 2/2] mm/gup/writeback: add callbacks for inaccessible pages Date: Fri, 28 Feb 2020 16:43:22 +0100 X-Mailer: git-send-email 2.24.1 In-Reply-To: <20200228154322.329228-1-imbrenda@linux.ibm.com> References: <20200228154322.329228-1-imbrenda@linux.ibm.com> MIME-Version: 1.0 X-TM-AS-GCONF: 00 x-cbid: 20022815-4275-0000-0000-000003A6660C X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 20022815-4276-0000-0000-000038BAFBE1 Message-Id: <20200228154322.329228-4-imbrenda@linux.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138,18.0.572 definitions=2020-02-28_04:2020-02-28,2020-02-28 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 suspectscore=2 mlxscore=0 spamscore=0 phishscore=0 adultscore=0 impostorscore=0 bulkscore=0 clxscore=1015 malwarescore=0 mlxlogscore=550 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2001150001 definitions=main-2002280124 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: With the introduction of protected KVM guests on s390 there is now a concept of inaccessible pages. These pages need to be made accessible before the host can access them. While cpu accesses will trigger a fault that can be resolved, I/O accesses will just fail. We need to add a callback into architecture code for places that will do I/O, namely when writeback is started or when a page reference is taken. This is not only to enable paging, file backing etc, it is also necessary to protect the host against a malicious user space. For example a bad QEMU could simply start direct I/O on such protected memory. We do not want userspace to be able to trigger I/O errors and thus we the logic is "whenever somebody accesses that page (gup) or does I/O, make sure that this page can be accessed". When the guest tries to access that page we will wait in the page fault handler for writeback to have finished and for the page_ref to be the expected value. On s390x the function is not supposed to fail, so it is ok to use a WARN_ON on failure. If we ever need some more finegrained handling we can tackle this when we know the details. Signed-off-by: Claudio Imbrenda Acked-by: Will Deacon Reviewed-by: David Hildenbrand Reviewed-by: Christian Borntraeger Signed-off-by: Christian Borntraeger --- include/linux/gfp.h | 6 ++++++ mm/gup.c | 19 ++++++++++++++++--- mm/page-writeback.c | 5 +++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/include/linux/gfp.h b/include/linux/gfp.h index e5b817cb86e7..be2754841369 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h @@ -485,6 +485,12 @@ static inline void arch_free_page(struct page *page,= int order) { } #ifndef HAVE_ARCH_ALLOC_PAGE static inline void arch_alloc_page(struct page *page, int order) { } #endif +#ifndef HAVE_ARCH_MAKE_PAGE_ACCESSIBLE +static inline int arch_make_page_accessible(struct page *page) +{ + return 0; +} +#endif =20 struct page * __alloc_pages_nodemask(gfp_t gfp_mask, unsigned int order, int preferred= _nid, diff --git a/mm/gup.c b/mm/gup.c index 0b9a806898f3..86fff6e4e4f3 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -391,6 +391,7 @@ static struct page *follow_page_pte(struct vm_area_st= ruct *vma, struct page *page; spinlock_t *ptl; pte_t *ptep, pte; + int ret; =20 /* FOLL_GET and FOLL_PIN are mutually exclusive. */ if (WARN_ON_ONCE((flags & (FOLL_PIN | FOLL_GET)) =3D=3D @@ -449,8 +450,6 @@ static struct page *follow_page_pte(struct vm_area_st= ruct *vma, if (is_zero_pfn(pte_pfn(pte))) { page =3D pte_page(pte); } else { - int ret; - ret =3D follow_pfn_pte(vma, address, ptep, flags); page =3D ERR_PTR(ret); goto out; @@ -458,7 +457,6 @@ static struct page *follow_page_pte(struct vm_area_st= ruct *vma, } =20 if (flags & FOLL_SPLIT && PageTransCompound(page)) { - int ret; get_page(page); pte_unmap_unlock(ptep, ptl); lock_page(page); @@ -475,6 +473,14 @@ static struct page *follow_page_pte(struct vm_area_s= truct *vma, page =3D ERR_PTR(-ENOMEM); goto out; } + if (flags & FOLL_PIN) { + ret =3D arch_make_page_accessible(page); + if (ret) { + unpin_user_page(page); + page =3D ERR_PTR(ret); + goto out; + } + } if (flags & FOLL_TOUCH) { if ((flags & FOLL_WRITE) && !pte_dirty(pte) && !PageDirty(page)) @@ -2143,6 +2149,13 @@ static int gup_pte_range(pmd_t pmd, unsigned long = addr, unsigned long end, =20 VM_BUG_ON_PAGE(compound_head(page) !=3D head, page); =20 + if (flags & FOLL_PIN) { + ret =3D arch_make_page_accessible(page); + if (ret) { + unpin_user_page(page); + goto pte_unmap; + } + } SetPageReferenced(page); pages[*nr] =3D page; (*nr)++; diff --git a/mm/page-writeback.c b/mm/page-writeback.c index ab5a3cee8ad3..8384be5a2758 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c @@ -2807,6 +2807,11 @@ int __test_set_page_writeback(struct page *page, b= ool keep_write) inc_zone_page_state(page, NR_ZONE_WRITE_PENDING); } unlock_page_memcg(page); + /* + * If writeback has been triggered on a page that cannot be made + * accessible, it is too late. + */ + WARN_ON(arch_make_page_accessible(page)); return ret; =20 } --=20 2.24.1