From patchwork Wed Jan 22 01:58:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bobby Eshleman X-Patchwork-Id: 11345011 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 10ACE1398 for ; Wed, 22 Jan 2020 05:15:14 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E14152465B for ; Wed, 22 Jan 2020 05:15:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Vbqa9Hle" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E14152465B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iu8L9-000583-3a; Wed, 22 Jan 2020 05:14:07 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iu5Kd-00068a-4n for xen-devel@lists.xenproject.org; Wed, 22 Jan 2020 02:01:23 +0000 X-Inumbo-ID: 01c14e60-3cbb-11ea-9fd7-bc764e2007e4 Received: from mail-yw1-xc43.google.com (unknown [2607:f8b0:4864:20::c43]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 01c14e60-3cbb-11ea-9fd7-bc764e2007e4; Wed, 22 Jan 2020 02:00:47 +0000 (UTC) Received: by mail-yw1-xc43.google.com with SMTP id v126so2481422ywc.10 for ; Tue, 21 Jan 2020 18:00:47 -0800 (PST) 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 :mime-version:content-transfer-encoding; bh=tVeW5GY1jFWlO2G9XHobSpgwoDZA3lnMYQkqKBzkx3Q=; b=Vbqa9HleQrDyGPECtEfpgh84mR1AQabPUxOKxYuc8lPkuIjKw+jI/+y/ZVRh2hqqHJ Y9LXfBqNREwf5gECz8uy4UnouwElrxZdPtQFlsn/4ETxko0ENyJd32bxOXK9slCvA5Vf 8CYXajhnCWkC8Or13Z9E9PSLqc4HA7pMgWQ8vUDJ4ChG7qqUDBRk2syQPiEobURTjSwS 03uNEmgErI32tUjSldamYzh3rvGGtdXkKsIC4jo9p/wL3Q3QgX499jB9oqNJwxrVACBG a/eARvdMtbDnrhbgbH+uwjaXW+F/Itgu1CaL/LWeT1VUqsspWH0U32exXHgKMNy2w8gZ AsUw== 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:mime-version:content-transfer-encoding; bh=tVeW5GY1jFWlO2G9XHobSpgwoDZA3lnMYQkqKBzkx3Q=; b=BxJVQMRkx7rqZ4G/N0wc4ezB5uWdxWnG0CpmJT899iGNvKGBwZPsMQBJSxOoe2Zj1D U0YtNxAw/v36r+JyLopmlURg+kRGpXjJ+G59Y4sYl2CNT9eX3Ip9Vmp4UVU7Rcl/9Zsk CJSdntEaWQ5HEmTrRQHKup3vKeevydy5pMGX4reaZVYyTtH2KMW2XObyFvKzbMdGGd0a 8GhOXUfQ9hfv/vVoZqQ1KldGDo+TlrampCBkv/CvuZrRb0DaT8JCywi+XngdiwErdi9O VoP5tlDZdRF42EoCWGz9rbpWPSKcBnxUPjeRtj/Fhghl3Z5YufUU7dPPIqhU4Md1K1KL uq5A== X-Gm-Message-State: APjAAAVPxnRbXikQvPXlsH6NblibtGHcZbQ/N3F7dvTpJcdXu4Spn5Y+ UP1IC88vFqlIiNZfSL/C6gvfcWGh/AEMGQ== X-Google-Smtp-Source: APXvYqzhjOb12wNiNHgyzt+CGioFUk9q1vNs0ERns2IbS7PaVD7wSSKT1mfzAc2KL28xXvWbGCiVZg== X-Received: by 2002:a81:758a:: with SMTP id q132mr5634042ywc.162.1579658446233; Tue, 21 Jan 2020 18:00:46 -0800 (PST) Received: from bobbye-pc.knology.net ([216.186.244.35]) by smtp.gmail.com with ESMTPSA id q185sm17504248ywh.61.2020.01.21.18.00.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 21 Jan 2020 18:00:45 -0800 (PST) From: Bobby Eshleman To: xen-devel@lists.xenproject.org Date: Tue, 21 Jan 2020 19:58:50 -0600 Message-Id: <3681ad921f88a931dd99a1f69d940d4991d7db11.1579615303.git.bobbyeshleman@gmail.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: References: MIME-Version: 1.0 X-Mailman-Approved-At: Wed, 22 Jan 2020 05:14:01 +0000 Subject: [Xen-devel] [RFC XEN PATCH 11/23] riscv: Add guestcopy.c X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Bobby Eshleman , Stefano Stabellini , Julien Grall , Wei Liu , Konrad Rzeszutek Wilk , George Dunlap , Andrew Cooper , Ian Jackson , Bobby Eshleman , Dan Robertson , Alistair Francis Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" From: Alistair Francis Signed-off-by: Alistair Francis --- xen/arch/riscv/guestcopy.c | 158 +++++++++++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 xen/arch/riscv/guestcopy.c diff --git a/xen/arch/riscv/guestcopy.c b/xen/arch/riscv/guestcopy.c new file mode 100644 index 0000000000..c2f7700eab --- /dev/null +++ b/xen/arch/riscv/guestcopy.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include +#include +#include + +#define COPY_flush_dcache (1U << 0) +#define COPY_from_guest (0U << 1) +#define COPY_to_guest (1U << 1) +#define COPY_ipa (0U << 2) +#define COPY_linear (1U << 2) + +typedef union +{ + struct + { + struct vcpu *v; + } gva; + + struct + { + struct domain *d; + } gpa; +} copy_info_t; + +#define GVA_INFO(vcpu) ((copy_info_t) { .gva = { vcpu } }) +#define GPA_INFO(domain) ((copy_info_t) { .gpa = { domain } }) + +static struct page_info *translate_get_page(copy_info_t info, uint64_t addr, + bool linear, bool write) +{ + p2m_type_t p2mt; + struct page_info *page; + + page = get_page_from_gfn(info.gpa.d, paddr_to_pfn(addr), &p2mt, P2M_ALLOC); + + if ( !page ) + return NULL; + + if ( !p2m_is_ram(p2mt) ) + { + put_page(page); + return NULL; + } + + return page; +} + +static unsigned long copy_guest(void *buf, uint64_t addr, unsigned int len, + copy_info_t info, unsigned int flags) +{ + /* XXX needs to handle faults */ + unsigned offset = addr & ~PAGE_MASK; + + BUILD_BUG_ON((sizeof(addr)) < sizeof(vaddr_t)); + BUILD_BUG_ON((sizeof(addr)) < sizeof(paddr_t)); + + while ( len ) + { + void *p; + unsigned size = min(len, (unsigned)PAGE_SIZE - offset); + struct page_info *page; + + page = translate_get_page(info, addr, flags & COPY_linear, + flags & COPY_to_guest); + if ( page == NULL ) + return len; + + p = __map_domain_page(page); + p += offset; + if ( flags & COPY_to_guest ) + { + /* + * buf will be NULL when the caller request to zero the + * guest memory. + */ + if ( buf ) + memcpy(p, buf, size); + else + memset(p, 0, size); + } + else + memcpy(buf, p, size); + + if ( flags & COPY_flush_dcache ) + clean_dcache_va_range(p, size); + + unmap_domain_page(p - offset); + put_page(page); + len -= size; + buf += size; + addr += size; + /* + * After the first iteration, guest virtual address is correctly + * aligned to PAGE_SIZE. + */ + offset = 0; + } + + return 0; +} + +unsigned long raw_copy_to_guest(void *to, const void *from, unsigned len) +{ + return copy_guest((void *)from, (vaddr_t)to, len, + GVA_INFO(current), COPY_to_guest | COPY_linear); +} + +unsigned long raw_copy_to_guest_flush_dcache(void *to, const void *from, + unsigned len) +{ + return copy_guest((void *)from, (vaddr_t)to, len, GVA_INFO(current), + COPY_to_guest | COPY_flush_dcache | COPY_linear); +} + +unsigned long raw_clear_guest(void *to, unsigned len) +{ + return copy_guest(NULL, (vaddr_t)to, len, GVA_INFO(current), + COPY_to_guest | COPY_linear); +} + +unsigned long raw_copy_from_guest(void *to, const void __user *from, unsigned len) +{ + return copy_guest(to, (vaddr_t)from, len, GVA_INFO(current), + COPY_from_guest | COPY_linear); +} + +unsigned long copy_to_guest_phys_flush_dcache(struct domain *d, + paddr_t gpa, + void *buf, + unsigned int len) +{ + return copy_guest(buf, gpa, len, GPA_INFO(d), + COPY_to_guest | COPY_ipa | COPY_flush_dcache); +} + +int access_guest_memory_by_ipa(struct domain *d, paddr_t gpa, void *buf, + uint32_t size, bool is_write) +{ + unsigned long left; + int flags = COPY_ipa; + + flags |= is_write ? COPY_to_guest : COPY_from_guest; + + left = copy_guest(buf, gpa, size, GPA_INFO(d), flags); + + return (!left) ? 0 : -EINVAL; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */