From patchwork Fri Nov 4 12:32:24 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Milard X-Patchwork-Id: 80843 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp1099619qge; Fri, 4 Nov 2016 04:33:41 -0700 (PDT) X-Received: by 10.200.51.251 with SMTP id d56mr12978714qtb.89.1478259221818; Fri, 04 Nov 2016 04:33:41 -0700 (PDT) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id x34si7278354qtd.82.2016.11.04.04.33.41; Fri, 04 Nov 2016 04:33:41 -0700 (PDT) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 7EB70610DB; Fri, 4 Nov 2016 11:33:41 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 657CE6069E; Fri, 4 Nov 2016 11:33:13 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id C8AE560658; Fri, 4 Nov 2016 11:33:09 +0000 (UTC) Received: from mail-lf0-f45.google.com (mail-lf0-f45.google.com [209.85.215.45]) by lists.linaro.org (Postfix) with ESMTPS id 5A7DE60CC8 for ; Fri, 4 Nov 2016 11:33:08 +0000 (UTC) Received: by mail-lf0-f45.google.com with SMTP id b14so61429288lfg.2 for ; Fri, 04 Nov 2016 04:33:08 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=KQCZm5Gea1/1eXv2cW7c/W2zHMQjgu0VjP6EkFEUm7A=; b=FWxa146sF9HJe+kz8TlgiHzZ+pA48iTcf/OzJmd+zUNdldZZRXA2zl6vr3d++rUSjW PgxXlEijGIq5koCMGoP3n/kaRdsMsZhYSUHrFphUPRQzBbT7hwUa85PaXD+9ZXIRe24g 92ouYzSKEJQaf7yD3M87N45h0bpuIQHxdbKyOXJgamQioCNguqVlbpHQbN2w3wObUTqe pWVusfTcwDXzLiUUH+tGWmLX1sSIolwOgTUjeHT4EwPHaRK35Ono1f/I7E5doiqY2PI/ SHiJP6lt5YtrGarUgKc/Dk/dIK+wpXWFAMutXrpsL3GU39hEBGbF/o1wSDqE2rHUJHzu TwJw== X-Gm-Message-State: ABUngveSGEVwryJys0v2W0eZ3NxDhP7EdEGgRAE0svfwiVJDs77HKFIz5d8gKcwcDm5eSBh5eIY= X-Received: by 10.25.37.134 with SMTP id l128mr4235398lfl.120.1478259187043; Fri, 04 Nov 2016 04:33:07 -0700 (PDT) Received: from erachmi-ericsson.ki.sw.ericsson.se (c-83-233-76-66.cust.bredband2.com. [83.233.76.66]) by smtp.gmail.com with ESMTPSA id d188sm2262242lfe.29.2016.11.04.04.33.06 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 04 Nov 2016 04:33:06 -0700 (PDT) From: Christophe Milard To: mike.holmes@linaro.org, petri.savolainen@nokia.com, bill.fischofer@linaro.org, lng-odp@lists.linaro.org Date: Fri, 4 Nov 2016 13:32:24 +0100 Message-Id: <1478262745-47028-2-git-send-email-christophe.milard@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1478262745-47028-1-git-send-email-christophe.milard@linaro.org> References: <1478262745-47028-1-git-send-email-christophe.milard@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCH 1/2] linux-gen: _ishmphy: adding function for physical address query X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" The function _odp_ishmphy_getphy() is added to query for physical addresses (given a virtual address) This function is meant to be used to populate the physical address of packet segments which are to be used by drivers (without iommu). The function _odp_ishmphy_can_getphy(), also added, return true if _odp_ishmphy_getphy() is able to works (as it requires specific permission) Signed-off-by: Christophe Milard --- platform/linux-generic/_ishmphy.c | 82 ++++++++++++++++++++++ platform/linux-generic/include/_ishmphy_internal.h | 14 ++++ 2 files changed, 96 insertions(+) -- 2.7.4 diff --git a/platform/linux-generic/_ishmphy.c b/platform/linux-generic/_ishmphy.c index 2b2d100..beb213c 100644 --- a/platform/linux-generic/_ishmphy.c +++ b/platform/linux-generic/_ishmphy.c @@ -29,6 +29,7 @@ #include #include #include +#include #include <_ishmphy_internal.h> static void *common_va_address; @@ -38,6 +39,8 @@ static uint64_t common_va_len; #define MAP_ANONYMOUS MAP_ANON #endif +#define PAGEMAP_FILE "/proc/self/pagemap" + /* Book some virtual address space * This function is called at odp_init_global() time to pre-book some * virtual address space inherited by all odpthreads (i.e. descendant @@ -183,3 +186,82 @@ int _odp_ishmphy_unmap(void *start, uint64_t len, int flags) ODP_ERR("_ishmphy_free failure: %s\n", strerror(errno)); return ret; } + +/* + * Get physical address from virtual address addr. + */ +phys_addr_t _odp_ishmphy_getphy(const void *addr) +{ + int page_sz; + int fd; + off_t offset; + int read_bytes; + uint64_t page; + phys_addr_t phys_addr; + + /* get normal page sizes: */ + page_sz = odp_sys_page_size(); + + /* read 8 bytes (uint64_t) at position N*8, where N is addr/page_sz */ + fd = open(PAGEMAP_FILE, O_RDONLY); + if (fd < 0) { + ODP_ERR("cannot open " PAGEMAP_FILE ": %s\n", + strerror(errno)); + return PHYS_ADDR_INVALID; + } + + offset = ((unsigned long)addr / page_sz) * sizeof(uint64_t); + if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { + ODP_ERR("cannot seek " PAGEMAP_FILE ": %s\n", + strerror(errno)); + close(fd); + return PHYS_ADDR_INVALID; + } + + read_bytes = read(fd, &page, sizeof(uint64_t)); + close(fd); + if (read_bytes < 0) { + ODP_ERR("cannot read " PAGEMAP_FILE ": %s\n", + strerror(errno)); + return PHYS_ADDR_INVALID; + } else if (read_bytes != sizeof(uint64_t)) { + ODP_ERR("read %d bytes from " PAGEMAP_FILE " " + "but expected %d:\n", + read_bytes, sizeof(uint64_t)); + return PHYS_ADDR_INVALID; + } + + /* some kernel return PFN zero when permission is denied: */ + if (!(page & 0x7fffffffffffffULL)) + return PHYS_ADDR_INVALID; + + /* + * the pfn (page frame number) are bits 0-54 (see + * pagemap.txt in linux Documentation) + */ + phys_addr = ((page & 0x7fffffffffffffULL) * page_sz) + + ((unsigned long)addr % page_sz); + + return phys_addr; +} + +/* + * check if physical address are readable + * return true if physical addresses can be retrieved. + * Just do a test to see if it works + */ +int _odp_ishmphy_can_getphy(void) +{ + int block_index; + phys_addr_t phy; + + /* allocate a block, locked in memory and try to grab its phy address */ + block_index = _odp_ishm_reserve(NULL, 10, -1, 0, _ODP_ISHM_LOCK, 0); + phy = _odp_ishmphy_getphy((void *)_odp_ishm_address(block_index)); + _odp_ishm_free_by_index(block_index); + + if (phy == PHYS_ADDR_INVALID) + return 0; + + return 1; +} diff --git a/platform/linux-generic/include/_ishmphy_internal.h b/platform/linux-generic/include/_ishmphy_internal.h index 4fe560f..31b154b 100644 --- a/platform/linux-generic/include/_ishmphy_internal.h +++ b/platform/linux-generic/include/_ishmphy_internal.h @@ -13,11 +13,25 @@ extern "C" { #include +typedef uint64_t phys_addr_t; /* Physical address definition. */ +#define PHYS_ADDR_INVALID ((phys_addr_t)-1) + void *_odp_ishmphy_book_va(uintptr_t len, intptr_t align); int _odp_ishmphy_unbook_va(void); void *_odp_ishmphy_map(int fd, void *start, uint64_t size, int flags); int _odp_ishmphy_unmap(void *start, uint64_t len, int flags); +/* + * check if physical address are readable + * return true if physical addresses can be retrieved. + */ +int _odp_ishmphy_can_getphy(void); + +/* + * Get physical address from virtual address addr. + */ +phys_addr_t _odp_ishmphy_getphy(const void *addr); + #ifdef __cplusplus } #endif