From patchwork Tue Apr 11 17:42:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver O'Halloran X-Patchwork-Id: 749589 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3w2Zhj5kh3z9sN6 for ; Wed, 12 Apr 2017 04:05:09 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Z6DEtavn"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3w2Zhj2xT3zDq5x for ; Wed, 12 Apr 2017 04:05:09 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Z6DEtavn"; dkim-atps=neutral X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from mail-pg0-x242.google.com (mail-pg0-x242.google.com [IPv6:2607:f8b0:400e:c05::242]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3w2ZCZ75lhzDq8W for ; Wed, 12 Apr 2017 03:43:22 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Z6DEtavn"; dkim-atps=neutral Received: by mail-pg0-x242.google.com with SMTP id 81so671844pgh.3 for ; Tue, 11 Apr 2017 10:43:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=r4JkxDVeU1a7BmNhijyPsgMPnyQ6MWJysop9Zw5gQz0=; b=Z6DEtavnBL8jXqjLVih3RQcrHPU8xEAfr9H41ByfT0tUjfHkvtLYZ+GFcfsxiRdl04 eAfwY5a+7TQ9U08vv0cBe+JmzLtvyUmDe91b3bPTfImndxlFq3zRDmjWiY11Soukyo8S mMHMYXfzpUd4S9szVCFXVbBRRXJJukdtwMmE8HhGRTrya3bHm459S/W+Lp6qv/gOs7HX 1F1QsQpC+m7nZ4VlE5pmok5xH9TnrKcM6FTPinfYCXFHenL4RPBlKCEtZqcuXFHWg+/f KHacB6XVOQncBJTKX4VlkuRAZvGUqy6VtjBABdVL0sc6TZx7CcDArgz/2gPu2UPd3BNI RZxw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=r4JkxDVeU1a7BmNhijyPsgMPnyQ6MWJysop9Zw5gQz0=; b=X1Fp2ullGHQFjUhBd4P17EeX8WI+C+oF4oGtQAl3HDeu9iD+tIxz4PPkYHnmCoteT6 ugu2FfIbhWhQPXnONml+AbSd9t0A/86c2lS1nIgdRvp2eoZ1mQOgLmBXi5pq+x5FB2Ot r3DctcTv0WUUjFsLkS4V5YQ1y3GTFO+40fbvCfK8oEJwNjPJQjhQSN8BdqeB9yn5URc8 D8bYO7Ud9Fb3kKB1sg92/Y8TNbsFzgJJABpWk53265LuwqpZFZ9iiH+aOxHJBIWCuVOq uS+9OjUvItHAgTgPb8tTalOPQRhhyQGjToJiLeA1reqbT86u8wSn38wxNJRFeY43LMqx 48VQ== X-Gm-Message-State: AFeK/H3YM7mfGQd8JhCpEDCik6kf5g0luh4TAzI7hgIQMCs0kP3O05Turn9tXwHsaV1+Nw== X-Received: by 10.98.96.65 with SMTP id u62mr61408603pfb.219.1491932601124; Tue, 11 Apr 2017 10:43:21 -0700 (PDT) Received: from localhost.localdomain ([103.57.0.128]) by smtp.gmail.com with ESMTPSA id r185sm20182582pfr.72.2017.04.11.10.43.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 11 Apr 2017 10:43:20 -0700 (PDT) From: Oliver O'Halloran To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH 9/9] powerpc: Add pmem API support Date: Wed, 12 Apr 2017 03:42:33 +1000 Message-Id: <20170411174233.21902-10-oohall@gmail.com> X-Mailer: git-send-email 2.9.3 In-Reply-To: <20170411174233.21902-1-oohall@gmail.com> References: <20170411174233.21902-1-oohall@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Oliver O'Halloran , arbab@linux.vnet.ibm.com, linux-nvdimm@lists.01.org Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Initial powerpc support for the arch-specific bit of the persistent memory API. Nothing fancy here. Signed-off-by: Oliver O'Halloran --- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/pmem.h | 109 ++++++++++++++++++++++++++++++++++++++++ arch/powerpc/kernel/misc_64.S | 2 +- 3 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/include/asm/pmem.h diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index d7413ed700b8..cf84d0db49ab 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -87,6 +87,7 @@ config PPC select ARCH_HAS_DMA_SET_COHERENT_MASK select ARCH_HAS_ELF_RANDOMIZE select ARCH_HAS_GCOV_PROFILE_ALL + select ARCH_HAS_PMEM_API select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE select ARCH_HAS_SG_CHAIN select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST diff --git a/arch/powerpc/include/asm/pmem.h b/arch/powerpc/include/asm/pmem.h new file mode 100644 index 000000000000..27da9594040f --- /dev/null +++ b/arch/powerpc/include/asm/pmem.h @@ -0,0 +1,109 @@ +/* + * Copyright(c) 2017 IBM Corporation. All rights reserved. + * + * Based on the x86 version. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + */ +#ifndef __ASM_POWERPC_PMEM_H__ +#define __ASM_POWERPC_PMEM_H__ + +#include +#include +#include + +/* + * See include/linux/pmem.h for API documentation + * + * PPC specific notes: + * + * 1. PPC has no non-temporal (cache bypassing) stores so we're stuck with + * doing cache writebacks. + * + * 2. DCBST is a suggestion. DCBF *will* force a writeback. + * + */ + +static inline void arch_wb_cache_pmem(void *addr, size_t size) +{ + unsigned long iaddr = (unsigned long) addr; + + /* NB: contains a barrier */ + flush_inval_dcache_range(iaddr, iaddr + size); +} + +/* invalidate and writeback are functionally identical */ +#define arch_invalidate_pmem arch_wb_cache_pmem + +static inline void arch_memcpy_to_pmem(void *dst, const void *src, size_t n) +{ + int unwritten; + + /* + * We are copying between two kernel buffers, if + * __copy_from_user_inatomic_nocache() returns an error (page + * fault) we would have already reported a general protection fault + * before the WARN+BUG. + * + * XXX: replace this with a hand-rolled memcpy+dcbf + */ + unwritten = __copy_from_user_inatomic(dst, (void __user *) src, n); + if (WARN(unwritten, "%s: fault copying %p <- %p unwritten: %d\n", + __func__, dst, src, unwritten)) + BUG(); + + arch_wb_cache_pmem(dst, n); +} + +static inline int arch_memcpy_from_pmem(void *dst, const void *src, size_t n) +{ + /* + * TODO: We should have most of the infrastructure for MCE handling + * but it needs to be made slightly smarter. + */ + memcpy(dst, src, n); + return 0; +} + +static inline size_t arch_copy_from_iter_pmem(void *addr, size_t bytes, + struct iov_iter *i) +{ + size_t len; + + /* XXX: under what conditions would this return len < size? */ + len = copy_from_iter(addr, bytes, i); + arch_wb_cache_pmem(addr, bytes - len); + + return len; +} + +static inline void arch_clear_pmem(void *addr, size_t size) +{ + void *start = addr; + + /* + * XXX: A hand rolled dcbz+dcbf loop would probably be better. + */ + + if (((uintptr_t) addr & ~PAGE_MASK) == 0) { + while (size >= PAGE_SIZE) { + clear_page(addr); + addr += PAGE_SIZE; + size -= PAGE_SIZE; + } + } + + if (size) + memset(addr, 0, size); + + arch_wb_cache_pmem(start, size); +} + +#endif /* __ASM_POWERPC_PMEM_H__ */ diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index c119044cad0d..1378a8d61faf 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -182,7 +182,7 @@ _GLOBAL(flush_dcache_phys_range) isync blr -_GLOBAL(flush_inval_dcache_range) +_GLOBAL_TOC(flush_inval_dcache_range) ld r10,PPC64_CACHES@toc(r2) lwz r7,DCACHEL1BLOCKSIZE(r10) /* Get dcache block size */ addi r5,r7,-1