From patchwork Fri Nov 11 14:50:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Milard X-Patchwork-Id: 81833 Delivered-To: patch@linaro.org Received: by 10.182.1.168 with SMTP id 8csp1473042obn; Fri, 11 Nov 2016 05:51:38 -0800 (PST) X-Received: by 10.107.9.155 with SMTP id 27mr11775289ioj.54.1478872298581; Fri, 11 Nov 2016 05:51:38 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id y63si6610750ioi.15.2016.11.11.05.51.38; Fri, 11 Nov 2016 05:51:38 -0800 (PST) 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 1BDE760F02; Fri, 11 Nov 2016 13:51:38 +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=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW, 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 9246560EEF; Fri, 11 Nov 2016 13:51:10 +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 13A0960EBE; Fri, 11 Nov 2016 13:51:08 +0000 (UTC) Received: from mail-lf0-f50.google.com (mail-lf0-f50.google.com [209.85.215.50]) by lists.linaro.org (Postfix) with ESMTPS id 63F2D60EA0 for ; Fri, 11 Nov 2016 13:51:06 +0000 (UTC) Received: by mail-lf0-f50.google.com with SMTP id o141so12837609lff.1 for ; Fri, 11 Nov 2016 05:51:06 -0800 (PST) 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=9eYV5Ql/tJVYwdBiJU2nVztoA5CIYfvZineVYjrJMaY=; b=Lx5QpKVfoZxsqRk9K2RIw5fyfN6trab/tigZmUePfqjFhXAbt2fKjhtPsmTPxhaYhF cGcSi1DZIV54d35aITpXzzuWYS2tvJ5gwKo31Yv6h5NkJjbRFMXZnZbsm6tlFYDwMR8U R6ZPuHqq4N17JxWwMjBxgMA5V2248oJlPKRcnuNTKbzM/+xFLAyGVKWOFqChHgMjOIVd 0fBv6+lBwd4hx2hCyO5Ye0vmeKhRhi4pS2zJaCuoYsCb2mf72BTTEBCstDJ5zXPN2yTs hxWhMhmlkOMAr6DvyN20bW7dy/B9iqvpL1gKJC7WfXi135YuIafxAkbgRn/nk2vbQOHs bdwQ== X-Gm-Message-State: ABUngvcEAsQ/YSVFtwom+NmK6kC2UotKg4EPdB/KAZ0CN9os2Tg2ZN5dS2SimOuxUw128DfqZhk= X-Received: by 10.25.211.136 with SMTP id k130mr1523147lfg.45.1478872265154; Fri, 11 Nov 2016 05:51:05 -0800 (PST) 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 65sm2236774ljb.23.2016.11.11.05.51.04 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 11 Nov 2016 05:51:04 -0800 (PST) From: Christophe Milard To: petri.savolainen@nokia.com, mike.holmes@linaro.org, bill.fischofer@linaro.org, lng-odp@lists.linaro.org Date: Fri, 11 Nov 2016 15:50:28 +0100 Message-Id: <1478875829-35000-2-git-send-email-christophe.milard@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1478875829-35000-1-git-send-email-christophe.milard@linaro.org> References: <1478875829-35000-1-git-send-email-christophe.milard@linaro.org> X-Topics: patch Subject: [lng-odp] [API-NEXT PATCHv2 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_virt_to_phys() 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_virt_to_phys(), also added, return true if _odp_ishmphy_virt_to_phys() 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..8c0f46e 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_virt_to_phys(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_virt_to_phys(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_virt_to_phys((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..2022590 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_virt_to_phys(void); + +/* + * Get physical address from virtual address addr. + */ +phys_addr_t _odp_ishmphy_virt_to_phys(const void *addr); + #ifdef __cplusplus } #endif