From patchwork Sun Mar 19 03:37:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "buddy.zhang" X-Patchwork-Id: 13180203 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48EA7C6FD1F for ; Sun, 19 Mar 2023 03:38:25 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 42192900003; Sat, 18 Mar 2023 23:38:24 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 3D198900002; Sat, 18 Mar 2023 23:38:24 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 29895900003; Sat, 18 Mar 2023 23:38:24 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 16F50900002 for ; Sat, 18 Mar 2023 23:38:24 -0400 (EDT) Received: from smtpin23.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id CE993C0C64 for ; Sun, 19 Mar 2023 03:38:23 +0000 (UTC) X-FDA: 80584240086.23.BEB8AAE Received: from bg4.exmail.qq.com (bg4.exmail.qq.com [43.155.65.254]) by imf02.hostedemail.com (Postfix) with ESMTP id 02A6980009 for ; Sun, 19 Mar 2023 03:38:20 +0000 (UTC) Authentication-Results: imf02.hostedemail.com; dkim=none; dmarc=none; spf=pass (imf02.hostedemail.com: domain of buddy.zhang@biscuitos.cn designates 43.155.65.254 as permitted sender) smtp.mailfrom=buddy.zhang@biscuitos.cn ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1679197102; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:references; bh=bVAW11hgQC9h7W44+MxZRIw+h31KyH8WsDkVPgyNse8=; b=at4pGqZ/YEOLzTifGJp6c2yujuuenEnxPuFtd/U+wbib+vg075YPyU7baFiTj3Sa1nbCUp bWDC2QVMCegaM5w9RxN3U8aF1n6RAZdzTai2EffPRfTmywg7fV/vutDx4kscxdy5dkrbJz VRH6YuOte9zfwnlpDIFYSfToPxXBw+w= ARC-Authentication-Results: i=1; imf02.hostedemail.com; dkim=none; dmarc=none; spf=pass (imf02.hostedemail.com: domain of buddy.zhang@biscuitos.cn designates 43.155.65.254 as permitted sender) smtp.mailfrom=buddy.zhang@biscuitos.cn ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1679197102; a=rsa-sha256; cv=none; b=8A+fDs9DQmMTVi99GtwQiMaNYGJdBlu4u9rtPMe2M07ong6ks9q1P+hjj2muQHT9wbjaGu ewuxRe8ZYYpFmrj/+WKEj93pQotdZLmosZ3IdXGaqEYldxw1IIGUaUOXOgHxps2b1AO18D ypR5ZyTuyTu67wuo+/ikxiYJxaRL4S4= X-QQ-mid: bizesmtp87t1679197076tawonyos Received: from localhost.localdomain ( [60.186.52.194]) by bizesmtp.qq.com (ESMTP) with id ; Sun, 19 Mar 2023 11:37:52 +0800 (CST) X-QQ-SSF: 01000000006000101000B00A0000000 X-QQ-FEAT: PXtIlpCZyqct4D9A6UijQTb/of6mMAcUFFGfIr9JXjdhBQPb6LhUTp6o5fZpi zPo0BEnuM3Vrq7aTWcaITofmY07dr+PAk/rGBrE82G7CvJjxC0BNcAv96c9+YFsAP5iH+91 0wcOlPG1Cj8kJObOJiJyBOoOboJQ68dxkhblpS5CLpnmtIbtPi8ACMQE270ZUJSpqUZe+xr A8Yf8+rvCbqnGHPyV71H8GD3bIdYn6J+bm8LUSq0nKLuaJVl0o63gRnX+uQVrCzFdk84nfW Kxw27yyJcDAyhx1VzQCm8FqwRJVCbxK32SxFTaGMr1fuCNnr4ez+6PmqPj/ALcdg52yf1/3 zBcW2y3 X-QQ-GoodBg: 0 From: "buddy.zhang" To: akpm@linux-foundation.org Cc: linux-mm@kvack.org, linux-kernel@vger.kernel.org, "buddy.zhang" Subject: [PATCH] mm: Keep memory type same on DEVMEM Page-Fault Date: Sun, 19 Mar 2023 11:37:50 +0800 Message-Id: <20230319033750.475200-1-buddy.zhang@biscuitos.cn> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:biscuitos.cn:qybglogicsvr:qybglogicsvr2 X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: 02A6980009 X-Stat-Signature: kid94rd4i6uq6c951u1hj3anckydm6b1 X-HE-Tag: 1679197100-82496 X-HE-Meta: U2FsdGVkX1+bBlSS8FHNNOculdRmsFk8dWw2RIWXTcXFvm2JHIewQiK5M3FeqPnF1jL4A3zNK4pl1Pz3ula6NAXYEG2lESp/IYP1rfT8fA9N7D41cdjz80UsEJ3VqxEuplA/QGXfegNkjUrIi01P5EjPsm+YPe/R+HzmFb9yGZcc7fatjBTQgSJchZfc+Kq1guXeZFYjzsxpbqrhMFMrKwlL2vvZS6Iv8XUsDNp6kATsfBiUcgZFgHUJEgSaVV1uyLgaQddc+NKEiwsn8y/rcsiVc3ZOv/BQ2Hql1iBB50HfPhFBL2lzcNIICdyR2eShg9ONB5WD9WjxsHYgmu3z/pGE3HcyEpybsFoUIEfc9GBk8KaiA82wy1N5/7gQwMqz4CiCTgPOwk2QCJz+bxySt4YlaEGj6X1yDDDQIiFNBF+rTteGY5T8orH+P0kCUFb+wygfKM3WFR+M43v1g1vk5WaM5wJ5K2KXn/mv2rsjpK/QPolb8u6DdIqPcA+RkYiAO6SdFgL9Y11fvG0rwcrMXWd0q2Wxz6e3zU/f1meCaEzJPD1R7c36vJWQy2gvJ8yX/aQtA1Ak3t1eHOWWKn7beTuB0HnYqWft/oMKlKXBy97qFbiktQXIZbKaM0/86cUgdUrw3+fZIXNTfZKp0gUNIxNVi2KbaB59s9ydvHPYutZCGtacwXsW1YF0H+/jXj+TtMA8iva5eEeMYMBUNpnT0i7HFD+0BlFP9PxQWHV49r8kqKXhsjfAjLn7EdIpSfqWSFsd5NKUxD4cuTIqlABswA5BPzw93+LimrAKTtDKHZVfreA8k1sfNr98pRmo+J7NswVEEHqZpAlrBbvWnC06Q2OrlHdK+Q2wotwK+ZnS0SaGY3+5bff3IPOxWgHCiy6LDAIoRjspVGcI+RGrpqYJMfEiyfpqsrvrmIOu0O9rowToXzIBAvfo+WU6ljRjYfxRYuas7LNC0CcSFiWeVmu WkUpRxlk T0Fy/NbFWlnjONsH3AgFZoW9YAlsGONMtbIxRzTzVEBBqHA2YShiMqtmi0tNopIk8TON8ZpxcmRmsSMY= 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: On X86 architecture, supports memory type on Page-table, such as PTE is PAT/PCD/PWD, which can setup up Memory Type as WC/WB/WT/UC etc. Then, Virtual address from userspace or kernel space can map to same physical page, if each page table has different memory type, then it's confused to have more memory type for same physical page. On DEVMEM, the 'remap_pfn_range()' keep memory type same on different mapping. But if it happen on Page-Fault route, such as code: 19 static vm_fault_t vm_fault(struct vm_fault *vmf) 20 { 21 struct vm_area_struct *vma = vmf->vma; 22 unsigned long address = vmf->address; 23 struct page *fault_page; 24 unsigned long pfn; 25 int r; 26 27 /* Allocate Page as DEVMEM */ 28 fault_page = alloc_page(GFP_KERNEL); 29 if (!fault_page) { 30 printk("ERROR: NO Free Memory from DEVMEM.\n"); 31 r = -ENOMEM; 32 goto err_alloc; 33 } 34 pfn = page_to_pfn(fault_page); 35 36 /* Clear PAT Attribute */ 37 pgprot_val(vma->vm_page_prot) &= ~(_PAGE_PCD | _PAGE_PWT | _PAGE_PAT); 38 39 /* Change Memory Type for Direct-Mapping Area */ 40 arch_io_reserve_memtype_wc(PFN_PHYS(pfn), PAGE_SIZE); 41 pgprot_val(vma->vm_page_prot) |= cachemode2protval(_PAGE_CACHE_MODE_WT); 42 43 /* Establish pte and INC _mapcount for page */ 44 vm_flags_set(vma, VM_MIXEDMAP); 45 if (vm_insert_page(vma, address, fault_page)) 46 return -EAGAIN; 47 48 /* Add refcount for page */ 49 atomic_inc(&fault_page->_refcount); 50 /* bind fault page */ 51 vmf->page = fault_page; 52 53 return 0; 54 55 err_alloc: 56 return r; 57 } 58 59 static const struct vm_operations_struct BiscuitOS_vm_ops = { 60 .fault = vm_fault, 61 }; 62 63 static int BiscuitOS_mmap(struct file *filp, struct vm_area_struct *vma) 64 { 65 /* setup vm_ops */ 66 vma->vm_ops = &BiscuitOS_vm_ops; 67 68 return 0; 69 } If invoke arch_io_reserve_memtype_wc() on Line-40, and modify memory type as WC for Direct-Mapping area, and then setup meory type as WT on Line-41, then invoke 'vm_insert_page()' to create mapping, so you can see: | <----- Usespace -----> | <- Kernel space -> | ----+------+---+-------------+---+---+------------+-- | | | | | | | ----+------+---+-------------+---+---+------------+-- WT| |WC o-------o o--------o WT| |WC V V -------------------+--------+------------------------ | DEVMEM | -------------------+--------+------------------------ Physical Address Space For this case, OS should check memory type before mapping on 'vm_insert_page()', and keep memory type same, so add check on function: 07 int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, 08 struct page *page) 09 { 10 if (addr < vma->vm_start || addr >= vma->vm_end) 11 return -EFAULT; 12 if (!page_count(page)) 13 return -EINVAL; 14 if (!(vma->vm_flags & VM_MIXEDMAP)) { 15 BUG_ON(mmap_read_trylock(vma->vm_mm)); 16 BUG_ON(vma->vm_flags & VM_PFNMAP); 17 vm_flags_set(vma, VM_MIXEDMAP); 18 } 19 if (track_pfn_remap(vma, &vma->vm_page_prot, 20 page_to_pfn(page), addr, PAGE_SIZE)) 21 return -EINVAL; 22 return insert_page(vma, addr, page, vma->vm_page_prot); 23 } And line 19 to 21, when mapping different memory type on this route, the 'track_pfn_remap()' will notify error and change request as current, e.g. x86/PAT: APP:88 map pfn RAM range req write-through for [mem 0x025c1000-0x025c1fff], got write-combining And then, we can keep memory type same on Page-fault route for DEVMEM, the end: | <----- Usespace -----> | <- Kernel space -> | ----+------+---+-------------+---+---+------------+-- | | | | | | | ----+------+---+-------------+---+---+------------+-- WT| |WC o---(X)----o----------o |WC V -------------------+--------+------------------------ | DEVMEM | -------------------+--------+------------------------ Signed-off-by: buddy.zhang@biscuitos.cn --- mm/memory.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mm/memory.c b/mm/memory.c index f456f3b5049c..ed3d09f513f1 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1989,6 +1989,9 @@ int vm_insert_page(struct vm_area_struct *vma, unsigned long addr, BUG_ON(vma->vm_flags & VM_PFNMAP); vm_flags_set(vma, VM_MIXEDMAP); } + if (track_pfn_remap(vma, &vma->vm_page_prot, + page_to_pfn(page), addr, PAGE_SIZE)) + return -EINVAL; return insert_page(vma, addr, page, vma->vm_page_prot); } EXPORT_SYMBOL(vm_insert_page);