From patchwork Mon Aug 12 14:13:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 1971637 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=uPCFUKQm; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=infradead.org header.i=@infradead.org header.a=rsa-sha256 header.s=desiato.20200630 header.b=jxBTHNfm; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=linux.dev header.i=@linux.dev header.a=rsa-sha256 header.s=key1 header.b=sPkIH0pc; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=kvm-riscv-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WjJ3y3NFyz1yYC for ; Tue, 13 Aug 2024 01:15:26 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=1kyjQpH6wGyIqsZaKlbnUVZjDuAIygY27+iF2wQSg54=; b=uPCFUKQmP2d76W ofwoflUD7ZP/tET+dSnHNhWzfcmttqtfq8q4gA2JerNxAUvldzmJk2vAb5X6N4GWgJ9MhjPwNrGxh NsyHphPdXp27tssfJjKMLu+4IZm7JpYTSHvcN8qRGQvVTIQ10ToFRwukdFtpTCqJMDXyYrSziIQnV uoh/4FhR89P0WPKnrPqk9ylOzAHN6BR1zutp4LnDZ/cn/RuO6ZyMNcawQbHJXUAZlta7LhfCiqLR9 KG/eyf5+7SjNzxwcvszNV8Qgndg0lWRWn060lKO04qlav5aHONUbZ9p2AjdfwaJnzf6Ao5KKwnsrz zf7Itx9AESplHqesLrJg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdWlZ-00000000hpq-0dts; Mon, 12 Aug 2024 15:15:25 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdVoQ-00000000Y6w-19AW for kvm-riscv@bombadil.infradead.org; Mon, 12 Aug 2024 14:14:18 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=uxDUAgwyU7LZpMoLOtgb1JYYiYJmCsjV9g+S3q6q5t0=; b=jxBTHNfmurPZKMoRks9ZV+bn88 8xA7M1fM4OzPbEsa+xezMkGydGVZwrxBD3dvMcFMpQMACQnuqPFbNJFr/qMteQYKNSzvC0eas3Edb IXHIoOr1PaQzMzOQayhDUE4OWmO7OnfgX9FNbFaeaC5N/VhfOU9pW6hhXnvtJiC07rS1cQLiGBBI8 2gxJxqKZKJedo7NwmJXWSroJqdGId+rMuMqABYeC1O3dpeOE2njUhcqsabrzufg1avKqMp1JIj8hb Lj4jNODJyol20Gk7N9hZAOPpM6r6eeumR3KFENkisFDS93RC7F6kLaMMv8prP9/DZZfF9oBIQ8tRv 9sSFts0w==; Received: from out-174.mta1.migadu.com ([2001:41d0:203:375::ae]) by desiato.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1sdVoM-00000007a8F-0yPQ for kvm-riscv@lists.infradead.org; Mon, 12 Aug 2024 14:14:17 +0000 X-Report-Abuse: Please report any abuse attempt to abuse@migadu.com and include these headers. DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.dev; s=key1; t=1723472051; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=uxDUAgwyU7LZpMoLOtgb1JYYiYJmCsjV9g+S3q6q5t0=; b=sPkIH0pcIOYjgfqFJqLk8SM0SHovIHM6PcSps5yh4S0ocoeZvccTjSpAzHg86UmEhgTjMF u0OW3de8vGFvbKuKFE8DVaCGZADAD2TFTyusNSBNBJHA2Nnq1zfxWRWYAZWg7nwKeZyJgG zXzKFYACpgKZBDahttngtYEpqa/WLZM= From: Andrew Jones To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org Cc: atishp@rivosinc.com, cade.richard@berkeley.edu, jamestiotio@gmail.com Subject: [kvm-unit-tests PATCH 4/4] riscv: sbi: dbcn: Add high address tests Date: Mon, 12 Aug 2024 16:13:59 +0200 Message-ID: <20240812141354.119889-10-andrew.jones@linux.dev> In-Reply-To: <20240812141354.119889-6-andrew.jones@linux.dev> References: <20240812141354.119889-6-andrew.jones@linux.dev> MIME-Version: 1.0 X-Migadu-Flow: FLOW_OUT X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240812_151414_433249_33607EFC X-CRM114-Status: GOOD ( 17.66 ) X-Spam-Score: -0.2 (/) X-Spam-Report: Spam detection software, running on the system "desiato.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: On platforms where we have high memory (above 4G) such as on the QEMU virt machine model with over 2G of RAM configured, then we can test DBCN with addresses above 4G on 32-bit and on both 32-bit and [...] Content analysis details: (-0.2 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature -0.0 T_SCC_BODY_TEXT_LINE No description available. X-BeenThere: kvm-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kvm-riscv" Errors-To: kvm-riscv-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org On platforms where we have high memory (above 4G) such as on the QEMU virt machine model with over 2G of RAM configured, then we can test DBCN with addresses above 4G on 32-bit and on both 32-bit and 64-bit we can try crossing page boundaries both below 4G and from below 4G into 4G. Add those tests along with a bit of refactoring and the introduction of a couple helpers to find and check high addresses. Signed-off-by: Andrew Jones --- riscv/sbi.c | 134 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 116 insertions(+), 18 deletions(-) diff --git a/riscv/sbi.c b/riscv/sbi.c index 3f7ca6a78cfc..4f1e65dd3be6 100644 --- a/riscv/sbi.c +++ b/riscv/sbi.c @@ -5,18 +5,25 @@ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones */ #include +#include #include +#include #include +#include +#include #include #include #include #include #include +#include #include #include #include #include +#define HIGH_ADDR_BOUNDARY ((phys_addr_t)1 << 32) + static void help(void) { puts("Test SBI\n"); @@ -46,6 +53,25 @@ static void split_phys_addr(phys_addr_t paddr, unsigned long *hi, unsigned long *hi = (unsigned long)(paddr >> 32); } +static bool check_addr(phys_addr_t start, phys_addr_t size) +{ + struct mem_region *r = memregions_find(start); + return r && r->end - start >= size && r->flags == MR_F_UNUSED; +} + +static phys_addr_t get_highest_addr(void) +{ + phys_addr_t highest_end = 0; + struct mem_region *r; + + for (r = mem_regions; r->end; ++r) { + if (r->end > highest_end) + highest_end = r->end; + } + + return highest_end - 1; +} + static bool env_or_skip(const char *env) { if (!getenv(env)) { @@ -266,16 +292,60 @@ static void check_time(void) #define DBCN_WRITE_TEST_STRING "DBCN_WRITE_TEST_STRING\n" #define DBCN_WRITE_BYTE_TEST_BYTE (u8)'a' +static void dbcn_write_test(const char *s, unsigned long num_bytes) +{ + unsigned long base_addr_lo, base_addr_hi; + phys_addr_t paddr = virt_to_phys((void *)s); + int num_calls = 0; + struct sbiret ret; + + split_phys_addr(paddr, &base_addr_hi, &base_addr_lo); + + do { + ret = __dbcn_sbi_ecall(SBI_EXT_DBCN_CONSOLE_WRITE, num_bytes, base_addr_lo, base_addr_hi); + num_bytes -= ret.value; + paddr += ret.value; + split_phys_addr(paddr, &base_addr_hi, &base_addr_lo); + num_calls++; + } while (num_bytes != 0 && ret.error == SBI_SUCCESS); + + report(ret.error == SBI_SUCCESS, "write success (error=%ld)", ret.error); + report_info("%d sbi calls made", num_calls); +} + +static void dbcn_high_write_test(const char *s, unsigned long num_bytes, + phys_addr_t page_addr, size_t page_offset) +{ + int nr_pages = page_offset ? 2 : 1; + void *vaddr; + + if (page_addr != PAGE_ALIGN(page_addr) || page_addr + PAGE_SIZE < HIGH_ADDR_BOUNDARY || + !check_addr(page_addr, nr_pages * PAGE_SIZE)) { + report_skip("Memory above 4G required"); + return; + } + + vaddr = alloc_vpages(nr_pages); + + for (int i = 0; i < nr_pages; ++i) + install_page(current_pgtable(), page_addr + i * PAGE_SIZE, vaddr + i * PAGE_SIZE); + memcpy(vaddr + page_offset, DBCN_WRITE_TEST_STRING, num_bytes); + dbcn_write_test(vaddr + page_offset, num_bytes); +} + /* * Only the write functionality is tested here. There's no easy way to * non-interactively test the read functionality. */ static void check_dbcn(void) { - unsigned long num_bytes, base_addr_lo, base_addr_hi; + unsigned long num_bytes = strlen(DBCN_WRITE_TEST_STRING); + unsigned long base_addr_lo, base_addr_hi; + bool do_invalid_addr = false; phys_addr_t paddr; - int num_calls = 0; struct sbiret ret; + const char *tmp; + char *buf; report_prefix_push("dbcn"); @@ -286,33 +356,61 @@ static void check_dbcn(void) return; } - num_bytes = strlen(DBCN_WRITE_TEST_STRING); - paddr = virt_to_phys((void *)&DBCN_WRITE_TEST_STRING); - split_phys_addr(paddr, &base_addr_hi, &base_addr_lo); - report_prefix_push("write"); - do { - ret = __dbcn_sbi_ecall(SBI_EXT_DBCN_CONSOLE_WRITE, num_bytes, base_addr_lo, base_addr_hi); - num_bytes -= ret.value; - paddr += ret.value; - split_phys_addr(paddr, &base_addr_hi, &base_addr_lo); - num_calls++; - } while (num_bytes != 0 && ret.error == SBI_SUCCESS); + dbcn_write_test(DBCN_WRITE_TEST_STRING, num_bytes); - report(ret.error == SBI_SUCCESS, "write success (error=%ld)", ret.error); - report_info("%d sbi calls made", num_calls); + assert(num_bytes < PAGE_SIZE); + + report_prefix_push("page boundary"); + buf = alloc_pages(1); + memcpy(&buf[PAGE_SIZE - num_bytes / 2], DBCN_WRITE_TEST_STRING, num_bytes); + dbcn_write_test(&buf[PAGE_SIZE - num_bytes / 2], num_bytes); + report_prefix_pop(); + + report_prefix_push("high boundary"); + tmp = getenv("SBI_DBCN_SKIP_HIGH_BOUNDARY"); + if (!tmp || atol(tmp) == 0) + dbcn_high_write_test(DBCN_WRITE_TEST_STRING, num_bytes, + HIGH_ADDR_BOUNDARY - PAGE_SIZE, PAGE_SIZE - num_bytes / 2); + else + report_skip("user disabled"); + report_prefix_pop(); + + if (__riscv_xlen == 32) { + report_prefix_push("high page"); + tmp = getenv("SBI_DBCN_SKIP_HIGH_PAGE"); + if (!tmp || atol(tmp) == 0) { + paddr = HIGH_ADDR_BOUNDARY; + tmp = getenv("HIGH_PAGE"); + if (tmp) + paddr = strtoull(tmp, NULL, 0); + dbcn_high_write_test(DBCN_WRITE_TEST_STRING, num_bytes, paddr, 0); + } else { + report_skip("user disabled"); + } + report_prefix_pop(); + } /* Bytes are read from memory and written to the console */ - if (env_or_skip("INVALID_ADDR")) { + report_prefix_push("invalid parameter"); + tmp = getenv("INVALID_ADDR_AUTO"); + if (tmp && atol(tmp) == 1) { + paddr = get_highest_addr() + 1; + do_invalid_addr = true; + } else if (env_or_skip("INVALID_ADDR")) { paddr = strtoull(getenv("INVALID_ADDR"), NULL, 0); + do_invalid_addr = true; + } + + if (do_invalid_addr) { split_phys_addr(paddr, &base_addr_hi, &base_addr_lo); ret = __dbcn_sbi_ecall(SBI_EXT_DBCN_CONSOLE_WRITE, 1, base_addr_lo, base_addr_hi); - report(ret.error == SBI_ERR_INVALID_PARAM, "invalid parameter: address (error=%ld)", ret.error); + report(ret.error == SBI_ERR_INVALID_PARAM, "address (error=%ld)", ret.error); } - report_prefix_pop(); + report_prefix_pop(); report_prefix_push("write_byte"); puts("DBCN_WRITE TEST CHAR: ");