From patchwork Wed Apr 7 18:59:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 12189185 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF8D9C433ED for ; Wed, 7 Apr 2021 18:59:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B293B61246 for ; Wed, 7 Apr 2021 18:59:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S243388AbhDGS7r (ORCPT ); Wed, 7 Apr 2021 14:59:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:21426 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242302AbhDGS7q (ORCPT ); Wed, 7 Apr 2021 14:59:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617821974; 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=iHgFc3x2N5Ea4Wy96VF136gRYci3iHTFc0yTtoimnOw=; b=YaXTiKBVuBga9Q4XBkYwlflV2iVPcA1A0rhngPEbbf7JyZdyd8CXP4FAPq7qawSujO8K7q UD8B8tHotaJYPnBS0LyL3de2u0Be3sa/vXCUsyWUBoAgD+O41n74mK5RmMDAp0E0uzxZ6q 7rEpJrAjZTDXc8f+tSK7o43kN0gGBHI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-395-OvLqyH-IONuMeLrac1iBew-1; Wed, 07 Apr 2021 14:59:30 -0400 X-MC-Unique: OvLqyH-IONuMeLrac1iBew-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id ABF8E107ACC7; Wed, 7 Apr 2021 18:59:29 +0000 (UTC) Received: from kamzik.brq.redhat.com (unknown [10.40.193.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id EE06C6A033; Wed, 7 Apr 2021 18:59:25 +0000 (UTC) From: Andrew Jones To: kvm@vger.kernel.org Cc: alexandru.elisei@arm.com, nikos.nikoleris@arm.com, andre.przywara@arm.com, eric.auger@redhat.com Subject: [PATCH kvm-unit-tests 1/8] arm/arm64: Reorganize cstart assembler Date: Wed, 7 Apr 2021 20:59:11 +0200 Message-Id: <20210407185918.371983-2-drjones@redhat.com> In-Reply-To: <20210407185918.371983-1-drjones@redhat.com> References: <20210407185918.371983-1-drjones@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Move secondary_entry helper functions out of .init and into .text, since secondary_entry isn't run at "init" time. Signed-off-by: Andrew Jones --- arm/cstart.S | 62 +++++++++++++++++++++++++++----------------------- arm/cstart64.S | 22 +++++++++++------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/arm/cstart.S b/arm/cstart.S index d88a98362940..653ab1e8a141 100644 --- a/arm/cstart.S +++ b/arm/cstart.S @@ -96,32 +96,7 @@ start: bl exit b halt - -.macro set_mode_stack mode, stack - add \stack, #S_FRAME_SIZE - msr cpsr_c, #(\mode | PSR_I_BIT | PSR_F_BIT) - isb - mov sp, \stack -.endm - -exceptions_init: - mrc p15, 0, r2, c1, c0, 0 @ read SCTLR - bic r2, #CR_V @ SCTLR.V := 0 - mcr p15, 0, r2, c1, c0, 0 @ write SCTLR - ldr r2, =vector_table - mcr p15, 0, r2, c12, c0, 0 @ write VBAR - - mrs r2, cpsr - - /* first frame reserved for svc mode */ - set_mode_stack UND_MODE, r0 - set_mode_stack ABT_MODE, r0 - set_mode_stack IRQ_MODE, r0 - set_mode_stack FIQ_MODE, r0 - - msr cpsr_cxsf, r2 @ back to svc mode - isb - mov pc, lr +.text enable_vfp: /* Enable full access to CP10 and CP11: */ @@ -133,8 +108,6 @@ enable_vfp: vmsr fpexc, r0 mov pc, lr -.text - .global get_mmu_off get_mmu_off: ldr r0, =auxinfo @@ -235,6 +208,39 @@ asm_mmu_disable: mov pc, lr +/* + * Vectors + */ + +.macro set_mode_stack mode, stack + add \stack, #S_FRAME_SIZE + msr cpsr_c, #(\mode | PSR_I_BIT | PSR_F_BIT) + isb + mov sp, \stack +.endm + +exceptions_init: + mrc p15, 0, r2, c1, c0, 0 @ read SCTLR + bic r2, #CR_V @ SCTLR.V := 0 + mcr p15, 0, r2, c1, c0, 0 @ write SCTLR + ldr r2, =vector_table + mcr p15, 0, r2, c12, c0, 0 @ write VBAR + + mrs r2, cpsr + + /* + * Input r0 is the stack top, which is the exception stacks base + * The first frame is reserved for svc mode + */ + set_mode_stack UND_MODE, r0 + set_mode_stack ABT_MODE, r0 + set_mode_stack IRQ_MODE, r0 + set_mode_stack FIQ_MODE, r0 + + msr cpsr_cxsf, r2 @ back to svc mode + isb + mov pc, lr + /* * Vector stubs * Simplified version of the Linux kernel implementation diff --git a/arm/cstart64.S b/arm/cstart64.S index 0a85338bcdae..d39cf4dfb99c 100644 --- a/arm/cstart64.S +++ b/arm/cstart64.S @@ -89,10 +89,12 @@ start: msr cpacr_el1, x4 /* set up exception handling */ + mov x4, x0 // x0 is the addr of the dtb bl exceptions_init /* complete setup */ - bl setup // x0 is the addr of the dtb + mov x0, x4 // restore the addr of the dtb + bl setup bl get_mmu_off cbnz x0, 1f bl setup_vm @@ -109,13 +111,6 @@ start: bl exit b halt -exceptions_init: - adrp x4, vector_table - add x4, x4, :lo12:vector_table - msr vbar_el1, x4 - isb - ret - .text .globl get_mmu_off @@ -251,6 +246,17 @@ asm_mmu_disable: /* * Vectors + */ + +exceptions_init: + adrp x0, vector_table + add x0, x0, :lo12:vector_table + msr vbar_el1, x0 + isb + ret + +/* + * Vector stubs * Adapted from arch/arm64/kernel/entry.S */ .macro vector_stub, name, vec From patchwork Wed Apr 7 18:59:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 12189187 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1DEBFC433B4 for ; Wed, 7 Apr 2021 18:59:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EA4B961246 for ; Wed, 7 Apr 2021 18:59:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242302AbhDGS7s (ORCPT ); Wed, 7 Apr 2021 14:59:48 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:47020 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229512AbhDGS7r (ORCPT ); Wed, 7 Apr 2021 14:59:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617821976; 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=VX7KgusVBJDZTuoexiV/2l/Nm4sKGRNyiVpIeVJPzlA=; b=N5r0wGCYwfF80arcntuqH24umATYbuzGlvQta8X6R7FkOOHAK9vhCNrR9ac1ttNmmE+nlM uXsSRczjuydmqQv6C44ZgKshfz9Pp6OqcWKgln/EtI7OWM0EHAUrcZMfItVc/PeNyIGDPM 9SwyMyJZB47C6xDMn+uJZuVhz5UotIU= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-164-Ka2tpiFZMmCoPtYOlG84tA-1; Wed, 07 Apr 2021 14:59:35 -0400 X-MC-Unique: Ka2tpiFZMmCoPtYOlG84tA-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0099791271; Wed, 7 Apr 2021 18:59:34 +0000 (UTC) Received: from kamzik.brq.redhat.com (unknown [10.40.193.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2A93060C5C; Wed, 7 Apr 2021 18:59:29 +0000 (UTC) From: Andrew Jones To: kvm@vger.kernel.org Cc: alexandru.elisei@arm.com, nikos.nikoleris@arm.com, andre.przywara@arm.com, eric.auger@redhat.com Subject: [PATCH kvm-unit-tests 2/8] arm/arm64: Move setup_vm into setup Date: Wed, 7 Apr 2021 20:59:12 +0200 Message-Id: <20210407185918.371983-3-drjones@redhat.com> In-Reply-To: <20210407185918.371983-1-drjones@redhat.com> References: <20210407185918.371983-1-drjones@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Consolidate our setup calls to reduce the amount we need to do from init::start. Also remove a couple of pointless comments from setup(). Signed-off-by: Andrew Jones Reviewed-by: Nikos Nikoleris Reviewed-by: Alexandru Elisei --- arm/cstart.S | 6 ------ arm/cstart64.S | 5 ----- lib/arm/setup.c | 7 +++++-- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/arm/cstart.S b/arm/cstart.S index 653ab1e8a141..731f841695ce 100644 --- a/arm/cstart.S +++ b/arm/cstart.S @@ -81,12 +81,7 @@ start: /* complete setup */ pop {r0-r1} bl setup - bl get_mmu_off - cmp r0, #0 - bne 1f - bl setup_vm -1: /* run the test */ ldr r0, =__argc ldr r0, [r0] @@ -108,7 +103,6 @@ enable_vfp: vmsr fpexc, r0 mov pc, lr -.global get_mmu_off get_mmu_off: ldr r0, =auxinfo ldr r0, [r0, #4] diff --git a/arm/cstart64.S b/arm/cstart64.S index d39cf4dfb99c..add60a2b4e74 100644 --- a/arm/cstart64.S +++ b/arm/cstart64.S @@ -95,11 +95,7 @@ start: /* complete setup */ mov x0, x4 // restore the addr of the dtb bl setup - bl get_mmu_off - cbnz x0, 1f - bl setup_vm -1: /* run the test */ adrp x0, __argc ldr w0, [x0, :lo12:__argc] @@ -113,7 +109,6 @@ start: .text -.globl get_mmu_off get_mmu_off: adrp x0, auxinfo ldr x0, [x0, :lo12:auxinfo + 8] diff --git a/lib/arm/setup.c b/lib/arm/setup.c index 751ba980000a..9c16f6004e9f 100644 --- a/lib/arm/setup.c +++ b/lib/arm/setup.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include #include #include @@ -233,7 +235,6 @@ void setup(const void *fdt) freemem += initrd_size; } - /* call init functions */ mem_init(PAGE_ALIGN((unsigned long)freemem)); cpu_init(); @@ -243,7 +244,6 @@ void setup(const void *fdt) /* mem_init must be called before io_init */ io_init(); - /* finish setup */ timer_save_state(); ret = dt_get_bootargs(&bootargs); @@ -256,4 +256,7 @@ void setup(const void *fdt) memcpy(env, initrd, initrd_size); setup_env(env, initrd_size); } + + if (!(auxinfo.flags & AUXINFO_MMU_OFF)) + setup_vm(); } From patchwork Wed Apr 7 18:59:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 12189189 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, UNWANTED_LANGUAGE_BODY autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78447C433B4 for ; Wed, 7 Apr 2021 18:59:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4859B61205 for ; Wed, 7 Apr 2021 18:59:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229512AbhDGS7u (ORCPT ); Wed, 7 Apr 2021 14:59:50 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:21349 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348702AbhDGS7t (ORCPT ); Wed, 7 Apr 2021 14:59:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617821979; 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=6WxyRAp6RNCUYZydrWBy02gx1gkkcvZFYdhfqWAaBn8=; b=SI/Fnl+RytUQ0JIqia+b26t9NRbfzw6eUpI1in5qYq1KkJy6xPWp0YWYOXaWPNaJ/hh1ZQ pCLe3j1TNvEwvB3x3JuZoHVqlyJoxlFaA/QujIyOjIUXcmFJ1y//uyJPHwDEcnhJJhEIEw JMgu8FVhx1bFSYBOJfthoEFjc/Eamdk= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-36-Gp8Vf8ItO8mnHmxdROBKug-1; Wed, 07 Apr 2021 14:59:37 -0400 X-MC-Unique: Gp8Vf8ItO8mnHmxdROBKug-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4EB3191271; Wed, 7 Apr 2021 18:59:36 +0000 (UTC) Received: from kamzik.brq.redhat.com (unknown [10.40.193.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5AD3360CEA; Wed, 7 Apr 2021 18:59:34 +0000 (UTC) From: Andrew Jones To: kvm@vger.kernel.org Cc: alexandru.elisei@arm.com, nikos.nikoleris@arm.com, andre.przywara@arm.com, eric.auger@redhat.com Subject: [PATCH kvm-unit-tests 3/8] pci-testdev: ioremap regions Date: Wed, 7 Apr 2021 20:59:13 +0200 Message-Id: <20210407185918.371983-4-drjones@redhat.com> In-Reply-To: <20210407185918.371983-1-drjones@redhat.com> References: <20210407185918.371983-1-drjones@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Don't assume the physical addresses used with PCI have already been identity mapped. Signed-off-by: Andrew Jones Reviewed-by: Nikos Nikoleris --- lib/pci-host-generic.c | 5 ++--- lib/pci-host-generic.h | 4 ++-- lib/pci-testdev.c | 4 ++++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/pci-host-generic.c b/lib/pci-host-generic.c index 818150dc0a66..de93b8feac39 100644 --- a/lib/pci-host-generic.c +++ b/lib/pci-host-generic.c @@ -122,7 +122,7 @@ static struct pci_host_bridge *pci_dt_probe(void) sizeof(host->addr_space[0]) * nr_addr_spaces); assert(host != NULL); - host->start = base.addr; + host->start = ioremap(base.addr, base.size); host->size = base.size; host->bus = bus; host->bus_max = bus_max; @@ -279,8 +279,7 @@ phys_addr_t pci_host_bridge_get_paddr(u64 pci_addr) static void __iomem *pci_get_dev_conf(struct pci_host_bridge *host, int devfn) { - return (void __iomem *)(unsigned long) - host->start + (devfn << PCI_ECAM_DEVFN_SHIFT); + return (void __iomem *)host->start + (devfn << PCI_ECAM_DEVFN_SHIFT); } u8 pci_config_readb(pcidevaddr_t dev, u8 off) diff --git a/lib/pci-host-generic.h b/lib/pci-host-generic.h index fd30e7c74ed8..0ffe6380ec8f 100644 --- a/lib/pci-host-generic.h +++ b/lib/pci-host-generic.h @@ -18,8 +18,8 @@ struct pci_addr_space { }; struct pci_host_bridge { - phys_addr_t start; - phys_addr_t size; + void __iomem *start; + size_t size; int bus; int bus_max; int nr_addr_spaces; diff --git a/lib/pci-testdev.c b/lib/pci-testdev.c index 039bb44781c1..4f2e5663b2d6 100644 --- a/lib/pci-testdev.c +++ b/lib/pci-testdev.c @@ -185,7 +185,11 @@ int pci_testdev(void) mem = ioremap(addr, PAGE_SIZE); addr = pci_bar_get_addr(&pci_dev, 1); +#if defined(__i386__) || defined(__x86_64__) io = (void *)(unsigned long)addr; +#else + io = ioremap(addr, PAGE_SIZE); +#endif nr_tests += pci_testdev_all(mem, &pci_testdev_mem_ops); nr_tests += pci_testdev_all(io, &pci_testdev_io_ops); From patchwork Wed Apr 7 18:59:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 12189191 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5EC9EC433B4 for ; Wed, 7 Apr 2021 18:59:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 23F9661246 for ; Wed, 7 Apr 2021 18:59:47 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1348702AbhDGS7z (ORCPT ); Wed, 7 Apr 2021 14:59:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:44617 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355483AbhDGS7x (ORCPT ); Wed, 7 Apr 2021 14:59:53 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617821983; 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=vAm/uw1k66ViU/4zNLQwWF6DnNl4wT3Jgnl43W4WIGU=; b=YajUGKTUXn0j+ZQsXXPk6IalJjGFQYys5EUwTWXdZJEmisFVaBMniS+W7bXyJkrRnEy0ba qzkkCQQ/fhcX6OHyyZhUnIeL0eTiN20mVeSOhIeXd1zc2safe/XMSOOD/yq/dbEX81p6Km ZvboE1CID9on7IiUWsbjgM1Ou34Yvyc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-187-nQLN0p3cNb-vJvyV3MIL2Q-1; Wed, 07 Apr 2021 14:59:41 -0400 X-MC-Unique: nQLN0p3cNb-vJvyV3MIL2Q-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 0055991280; Wed, 7 Apr 2021 18:59:40 +0000 (UTC) Received: from kamzik.brq.redhat.com (unknown [10.40.193.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id 196816A038; Wed, 7 Apr 2021 18:59:36 +0000 (UTC) From: Andrew Jones To: kvm@vger.kernel.org Cc: alexandru.elisei@arm.com, nikos.nikoleris@arm.com, andre.przywara@arm.com, eric.auger@redhat.com Subject: [PATCH kvm-unit-tests 4/8] arm/arm64: mmu: Stop mapping an assumed IO region Date: Wed, 7 Apr 2021 20:59:14 +0200 Message-Id: <20210407185918.371983-5-drjones@redhat.com> In-Reply-To: <20210407185918.371983-1-drjones@redhat.com> References: <20210407185918.371983-1-drjones@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org By providing a proper ioremap function, we can just rely on devices calling it for each region they need (as they already do) instead of mapping a big assumed I/O range. The persistent maps weirdness allows us to call setup_vm after io_init. Why don't we just call setup_vm before io_init, I hear you ask? Well, that's because tests like sieve want to start with the MMU off and later call setup_vm, and all the while have working I/O. Some unit tests are just really demanding... Signed-off-by: Andrew Jones Reviewed-by: Nikos Nikoleris --- lib/arm/asm/io.h | 6 ++++ lib/arm/asm/mmu-api.h | 1 + lib/arm/asm/mmu.h | 1 + lib/arm/asm/page.h | 2 ++ lib/arm/mmu.c | 82 ++++++++++++++++++++++++++++++++++++++----- lib/arm64/asm/io.h | 6 ++++ lib/arm64/asm/mmu.h | 1 + lib/arm64/asm/page.h | 2 ++ 8 files changed, 93 insertions(+), 8 deletions(-) diff --git a/lib/arm/asm/io.h b/lib/arm/asm/io.h index ba3b0b2412ad..e4caa6ff5d1e 100644 --- a/lib/arm/asm/io.h +++ b/lib/arm/asm/io.h @@ -77,6 +77,12 @@ static inline void __raw_writel(u32 val, volatile void __iomem *addr) : "r" (val)); } +#define ioremap ioremap +static inline void __iomem *ioremap(phys_addr_t phys_addr, size_t size) +{ + return __ioremap(phys_addr, size); +} + #define virt_to_phys virt_to_phys static inline phys_addr_t virt_to_phys(const volatile void *x) { diff --git a/lib/arm/asm/mmu-api.h b/lib/arm/asm/mmu-api.h index 05fc12b5afb8..b9a5a8f6b3c1 100644 --- a/lib/arm/asm/mmu-api.h +++ b/lib/arm/asm/mmu-api.h @@ -17,6 +17,7 @@ extern void mmu_set_range_sect(pgd_t *pgtable, uintptr_t virt_offset, extern void mmu_set_range_ptes(pgd_t *pgtable, uintptr_t virt_offset, phys_addr_t phys_start, phys_addr_t phys_end, pgprot_t prot); +extern void mmu_set_persistent_maps(pgd_t *pgtable); extern pteval_t *mmu_get_pte(pgd_t *pgtable, uintptr_t vaddr); extern void mmu_clear_user(pgd_t *pgtable, unsigned long vaddr); #endif diff --git a/lib/arm/asm/mmu.h b/lib/arm/asm/mmu.h index 122874b8aebe..d88a4f16df42 100644 --- a/lib/arm/asm/mmu.h +++ b/lib/arm/asm/mmu.h @@ -12,6 +12,7 @@ #define PTE_SHARED L_PTE_SHARED #define PTE_AF PTE_EXT_AF #define PTE_WBWA L_PTE_MT_WRITEALLOC +#define PTE_UNCACHED L_PTE_MT_UNCACHED /* See B3.18.7 TLB maintenance operations */ diff --git a/lib/arm/asm/page.h b/lib/arm/asm/page.h index 1fb5cd26ac66..8eb4a883808e 100644 --- a/lib/arm/asm/page.h +++ b/lib/arm/asm/page.h @@ -47,5 +47,7 @@ typedef struct { pteval_t pgprot; } pgprot_t; extern phys_addr_t __virt_to_phys(unsigned long addr); extern unsigned long __phys_to_virt(phys_addr_t addr); +extern void *__ioremap(phys_addr_t phys_addr, size_t size); + #endif /* !__ASSEMBLY__ */ #endif /* _ASMARM_PAGE_H_ */ diff --git a/lib/arm/mmu.c b/lib/arm/mmu.c index 15eef007f256..a7b7ae51afe3 100644 --- a/lib/arm/mmu.c +++ b/lib/arm/mmu.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "alloc_page.h" #include "vmalloc.h" @@ -21,6 +22,57 @@ extern unsigned long etext; +#define MMU_MAX_PERSISTENT_MAPS 64 + +struct mmu_persistent_map { + uintptr_t virt_offset; + phys_addr_t phys_start; + phys_addr_t phys_end; + pgprot_t prot; + bool sect; +}; + +static struct mmu_persistent_map mmu_persistent_maps[MMU_MAX_PERSISTENT_MAPS]; + +static void +mmu_set_persistent_range(uintptr_t virt_offset, phys_addr_t phys_start, + phys_addr_t phys_end, pgprot_t prot, bool sect) +{ + int i; + + assert(phys_end); + + for (i = 0; i < MMU_MAX_PERSISTENT_MAPS; ++i) { + if (!mmu_persistent_maps[i].phys_end) + break; + } + assert(i < MMU_MAX_PERSISTENT_MAPS); + + mmu_persistent_maps[i] = (struct mmu_persistent_map){ + .virt_offset = virt_offset, + .phys_start = phys_start, + .phys_end = phys_end, + .prot = prot, + .sect = sect, + }; +} + +void mmu_set_persistent_maps(pgd_t *pgtable) +{ + struct mmu_persistent_map *map; + + for (map = &mmu_persistent_maps[0]; map->phys_end; ++map) { + if (map->sect) + mmu_set_range_sect(pgtable, map->virt_offset, + map->phys_start, map->phys_end, + map->prot); + else + mmu_set_range_ptes(pgtable, map->virt_offset, + map->phys_start, map->phys_end, + map->prot); + } +} + pgd_t *mmu_idmap; /* CPU 0 starts with disabled MMU */ @@ -157,7 +209,6 @@ void mmu_set_range_sect(pgd_t *pgtable, uintptr_t virt_offset, void *setup_mmu(phys_addr_t phys_end) { uintptr_t code_end = (uintptr_t)&etext; - struct mem_region *r; /* 0G-1G = I/O, 1G-3G = identity, 3G-4G = vmalloc */ if (phys_end > (3ul << 30)) @@ -172,13 +223,6 @@ void *setup_mmu(phys_addr_t phys_end) mmu_idmap = alloc_page(); - for (r = mem_regions; r->end; ++r) { - if (!(r->flags & MR_F_IO)) - continue; - mmu_set_range_sect(mmu_idmap, r->start, r->start, r->end, - __pgprot(PMD_SECT_UNCACHED | PMD_SECT_USER)); - } - /* armv8 requires code shared between EL1 and EL0 to be read-only */ mmu_set_range_ptes(mmu_idmap, PHYS_OFFSET, PHYS_OFFSET, code_end, @@ -188,10 +232,32 @@ void *setup_mmu(phys_addr_t phys_end) code_end, phys_end, __pgprot(PTE_WBWA | PTE_USER)); + mmu_set_persistent_maps(mmu_idmap); + mmu_enable(mmu_idmap); return mmu_idmap; } +void __iomem *__ioremap(phys_addr_t phys_addr, size_t size) +{ + phys_addr_t paddr_aligned = phys_addr & PAGE_MASK; + phys_addr_t paddr_end = PAGE_ALIGN(phys_addr + size); + pgprot_t prot = __pgprot(PTE_UNCACHED | PTE_USER); + + assert(sizeof(long) == 8 || !(phys_addr >> 32)); + + mmu_set_persistent_range(paddr_aligned, paddr_aligned, paddr_end, + prot, false); + + if (mmu_enabled()) { + pgd_t *pgtable = current_thread_info()->pgtable; + mmu_set_range_ptes(pgtable, paddr_aligned, paddr_aligned, + paddr_end, prot); + } + + return (void __iomem *)(unsigned long)phys_addr; +} + phys_addr_t __virt_to_phys(unsigned long addr) { if (mmu_enabled()) { diff --git a/lib/arm64/asm/io.h b/lib/arm64/asm/io.h index e0a03b250d5b..be19f471c0fa 100644 --- a/lib/arm64/asm/io.h +++ b/lib/arm64/asm/io.h @@ -71,6 +71,12 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) return val; } +#define ioremap ioremap +static inline void __iomem *ioremap(phys_addr_t phys_addr, size_t size) +{ + return __ioremap(phys_addr, size); +} + #define virt_to_phys virt_to_phys static inline phys_addr_t virt_to_phys(const volatile void *x) { diff --git a/lib/arm64/asm/mmu.h b/lib/arm64/asm/mmu.h index 72d75eafc882..72371b2d9fe3 100644 --- a/lib/arm64/asm/mmu.h +++ b/lib/arm64/asm/mmu.h @@ -8,6 +8,7 @@ #include #define PMD_SECT_UNCACHED PMD_ATTRINDX(MT_DEVICE_nGnRE) +#define PTE_UNCACHED PTE_ATTRINDX(MT_DEVICE_nGnRE) #define PTE_WBWA PTE_ATTRINDX(MT_NORMAL) static inline void flush_tlb_all(void) diff --git a/lib/arm64/asm/page.h b/lib/arm64/asm/page.h index ae4484b22114..d0fac6ea563d 100644 --- a/lib/arm64/asm/page.h +++ b/lib/arm64/asm/page.h @@ -72,5 +72,7 @@ typedef struct { pteval_t pgprot; } pgprot_t; extern phys_addr_t __virt_to_phys(unsigned long addr); extern unsigned long __phys_to_virt(phys_addr_t addr); +extern void *__ioremap(phys_addr_t phys_addr, size_t size); + #endif /* !__ASSEMBLY__ */ #endif /* _ASMARM64_PAGE_H_ */ From patchwork Wed Apr 7 18:59:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 12189193 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2978AC433ED for ; Wed, 7 Apr 2021 18:59:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 053E361245 for ; Wed, 7 Apr 2021 18:59:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355525AbhDGTAC (ORCPT ); Wed, 7 Apr 2021 15:00:02 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:50257 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355512AbhDGS77 (ORCPT ); Wed, 7 Apr 2021 14:59:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617821988; 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=U1xkdbI5dHRq6fFNZKzfhYkUvq8CvPIi1fKJ3AV2wbw=; b=CrZwL/eu3hOfChcoiVYOPHN+CrwyealirGZjUHpPDYwXyxLqxgFB4AyWss6SlGQPZz1CXX 1i8MjScZPs0Az22yR0nGCJlC9qYoKjaAzWJD/dfBHitGUN00HUAuh6dNdwSyX67LP61EoZ 2Gnq6Iw4onCN7hsbf1bvc2OrLNFO2Wc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-547-_WYk46P3OMyZKFLZw5Jg1Q-1; Wed, 07 Apr 2021 14:59:46 -0400 X-MC-Unique: _WYk46P3OMyZKFLZw5Jg1Q-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 6EE6C8189C8; Wed, 7 Apr 2021 18:59:45 +0000 (UTC) Received: from kamzik.brq.redhat.com (unknown [10.40.193.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id 65E5F614EF; Wed, 7 Apr 2021 18:59:40 +0000 (UTC) From: Andrew Jones To: kvm@vger.kernel.org Cc: alexandru.elisei@arm.com, nikos.nikoleris@arm.com, andre.przywara@arm.com, eric.auger@redhat.com Subject: [PATCH kvm-unit-tests 5/8] arm/arm64: mmu: Remove memory layout assumptions Date: Wed, 7 Apr 2021 20:59:15 +0200 Message-Id: <20210407185918.371983-6-drjones@redhat.com> In-Reply-To: <20210407185918.371983-1-drjones@redhat.com> References: <20210407185918.371983-1-drjones@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Rather than making too many assumptions about the memory layout in mmu code, just set up the page tables per the memory regions (which means putting all the memory layout assumptions in setup). To ensure we get the right default flags set we need to split the primary region into two regions for code and data. We still only expect the primary regions to be present, but the next patch will remove that assumption too. Signed-off-by: Andrew Jones Reviewed-by: Nikos Nikoleris --- lib/arm/asm/setup.h | 1 + lib/arm/mmu.c | 26 +++++++++++++++----------- lib/arm/setup.c | 22 ++++++++++++++-------- 3 files changed, 30 insertions(+), 19 deletions(-) diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h index c8afb2493f8d..210c14f818fb 100644 --- a/lib/arm/asm/setup.h +++ b/lib/arm/asm/setup.h @@ -15,6 +15,7 @@ extern int nr_cpus; #define MR_F_PRIMARY (1U << 0) #define MR_F_IO (1U << 1) +#define MR_F_CODE (1U << 2) #define MR_F_UNKNOWN (1U << 31) struct mem_region { diff --git a/lib/arm/mmu.c b/lib/arm/mmu.c index a7b7ae51afe3..edd2b9da809b 100644 --- a/lib/arm/mmu.c +++ b/lib/arm/mmu.c @@ -20,8 +20,6 @@ #include -extern unsigned long etext; - #define MMU_MAX_PERSISTENT_MAPS 64 struct mmu_persistent_map { @@ -208,7 +206,7 @@ void mmu_set_range_sect(pgd_t *pgtable, uintptr_t virt_offset, void *setup_mmu(phys_addr_t phys_end) { - uintptr_t code_end = (uintptr_t)&etext; + struct mem_region *r; /* 0G-1G = I/O, 1G-3G = identity, 3G-4G = vmalloc */ if (phys_end > (3ul << 30)) @@ -223,14 +221,20 @@ void *setup_mmu(phys_addr_t phys_end) mmu_idmap = alloc_page(); - /* armv8 requires code shared between EL1 and EL0 to be read-only */ - mmu_set_range_ptes(mmu_idmap, PHYS_OFFSET, - PHYS_OFFSET, code_end, - __pgprot(PTE_WBWA | PTE_RDONLY | PTE_USER)); - - mmu_set_range_ptes(mmu_idmap, code_end, - code_end, phys_end, - __pgprot(PTE_WBWA | PTE_USER)); + for (r = mem_regions; r->end; ++r) { + if (r->flags & MR_F_IO) { + continue; + } else if (r->flags & MR_F_CODE) { + assert_msg(r->flags & MR_F_PRIMARY, "Unexpected code region"); + /* armv8 requires code shared between EL1 and EL0 to be read-only */ + mmu_set_range_ptes(mmu_idmap, r->start, r->start, r->end, + __pgprot(PTE_WBWA | PTE_USER | PTE_RDONLY)); + } else { + assert_msg(r->flags & MR_F_PRIMARY, "Unexpected data region"); + mmu_set_range_ptes(mmu_idmap, r->start, r->start, r->end, + __pgprot(PTE_WBWA | PTE_USER)); + } + } mmu_set_persistent_maps(mmu_idmap); diff --git a/lib/arm/setup.c b/lib/arm/setup.c index 9c16f6004e9f..9da5d24b0be9 100644 --- a/lib/arm/setup.c +++ b/lib/arm/setup.c @@ -31,6 +31,7 @@ #define NR_INITIAL_MEM_REGIONS 16 extern unsigned long stacktop; +extern unsigned long etext; struct timer_state __timer_state; @@ -88,10 +89,12 @@ unsigned int mem_region_get_flags(phys_addr_t paddr) static void mem_init(phys_addr_t freemem_start) { + phys_addr_t code_end = (phys_addr_t)(unsigned long)&etext; struct dt_pbus_reg regs[NR_INITIAL_MEM_REGIONS]; - struct mem_region primary, mem = { + struct mem_region mem = { .start = (phys_addr_t)-1, }; + struct mem_region *primary = NULL; phys_addr_t base, top; int nr_regs, nr_io = 0, i; @@ -110,8 +113,6 @@ static void mem_init(phys_addr_t freemem_start) nr_regs = dt_get_memory_params(regs, NR_INITIAL_MEM_REGIONS - nr_io); assert(nr_regs > 0); - primary = (struct mem_region){ 0 }; - for (i = 0; i < nr_regs; ++i) { struct mem_region *r = &mem_regions[nr_io + i]; @@ -123,7 +124,7 @@ static void mem_init(phys_addr_t freemem_start) */ if (freemem_start >= r->start && freemem_start < r->end) { r->flags |= MR_F_PRIMARY; - primary = *r; + primary = r; } /* @@ -135,13 +136,18 @@ static void mem_init(phys_addr_t freemem_start) if (r->end > mem.end) mem.end = r->end; } - assert(primary.end != 0); + assert(primary); assert(!(mem.start & ~PHYS_MASK) && !((mem.end - 1) & ~PHYS_MASK)); - __phys_offset = primary.start; /* PHYS_OFFSET */ - __phys_end = primary.end; /* PHYS_END */ + __phys_offset = primary->start; /* PHYS_OFFSET */ + __phys_end = primary->end; /* PHYS_END */ + + /* Split the primary region into two regions; code and data */ + mem.start = code_end, mem.end = primary->end, mem.flags = MR_F_PRIMARY; + mem_regions[nr_io + i] = mem; + primary->end = code_end, primary->flags |= MR_F_CODE; - phys_alloc_init(freemem_start, primary.end - freemem_start); + phys_alloc_init(freemem_start, __phys_end - freemem_start); phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES); phys_alloc_get_unused(&base, &top); From patchwork Wed Apr 7 18:59:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 12189195 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9A8EEC433B4 for ; Wed, 7 Apr 2021 18:59:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6F58461205 for ; Wed, 7 Apr 2021 18:59:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355483AbhDGTAE (ORCPT ); Wed, 7 Apr 2021 15:00:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:46816 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355518AbhDGTAB (ORCPT ); Wed, 7 Apr 2021 15:00:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617821990; 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=W3H9pvhGTAkJ6xiexInJDhqfXXsCslpOchcgxFrW6Xc=; b=N1UyTnuwZoplCt6Eaa58OuxFcXlAxNsNE5OC1BArOpDKizUhSTOS4TAz69tnaDtGSf0CWB FEAheKQIGkj3YbC3jSwTzCN7Iriz/YeKmmq07/iDs9RM5VrlEiUuwkA+EU1XzBjgqhTZHl Pbp7oCDBYFJAN2GEvS4nMBbmSZAlwxI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-568-Xodj2DitMQWW6VBs1eKB5A-1; Wed, 07 Apr 2021 14:59:48 -0400 X-MC-Unique: Xodj2DitMQWW6VBs1eKB5A-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 716EB10054F6; Wed, 7 Apr 2021 18:59:47 +0000 (UTC) Received: from kamzik.brq.redhat.com (unknown [10.40.193.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id BFA9860C5C; Wed, 7 Apr 2021 18:59:45 +0000 (UTC) From: Andrew Jones To: kvm@vger.kernel.org Cc: alexandru.elisei@arm.com, nikos.nikoleris@arm.com, andre.przywara@arm.com, eric.auger@redhat.com Subject: [PATCH kvm-unit-tests 6/8] arm/arm64: setup: Consolidate memory layout assumptions Date: Wed, 7 Apr 2021 20:59:16 +0200 Message-Id: <20210407185918.371983-7-drjones@redhat.com> In-Reply-To: <20210407185918.371983-1-drjones@redhat.com> References: <20210407185918.371983-1-drjones@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Keep as much memory layout assumptions as possible in init::start and a single setup function. This prepares us for calling setup() from different start functions which have been linked with different linker scripts. To do this, stacktop is only referenced from init::start, making freemem_start a parameter to setup(). We also split mem_init() into three parts, one that populates the mem regions per the DT, one that populates the mem regions per assumptions, and one that does the mem init. The concept of a primary region is dropped, but we add a sanity check for the absence of memory holes, because we don't know how to deal with them yet. Signed-off-by: Andrew Jones Reviewed-by: Nikos Nikoleris --- arm/cstart.S | 4 +- arm/cstart64.S | 2 + arm/flat.lds | 23 ++++++ lib/arm/asm/setup.h | 8 +-- lib/arm/mmu.c | 2 - lib/arm/setup.c | 165 ++++++++++++++++++++++++-------------------- 6 files changed, 123 insertions(+), 81 deletions(-) diff --git a/arm/cstart.S b/arm/cstart.S index 731f841695ce..14444124c43f 100644 --- a/arm/cstart.S +++ b/arm/cstart.S @@ -80,7 +80,9 @@ start: /* complete setup */ pop {r0-r1} - bl setup + mov r1, #0 + ldr r2, =stacktop @ r1,r2 is the base of free memory + bl setup @ r0 is the addr of the dtb /* run the test */ ldr r0, =__argc diff --git a/arm/cstart64.S b/arm/cstart64.S index add60a2b4e74..434723d4b45d 100644 --- a/arm/cstart64.S +++ b/arm/cstart64.S @@ -94,6 +94,8 @@ start: /* complete setup */ mov x0, x4 // restore the addr of the dtb + adrp x1, stacktop + add x1, x1, :lo12:stacktop // x1 is the base of free memory bl setup /* run the test */ diff --git a/arm/flat.lds b/arm/flat.lds index 6ed377c0eaa0..6fb459efb815 100644 --- a/arm/flat.lds +++ b/arm/flat.lds @@ -1,3 +1,26 @@ +/* + * init::start will pass stacktop to setup() as the base of free memory. + * setup() will then move the FDT and initrd to that base before calling + * mem_init(). With those movements and this linker script, we'll end up + * having the following memory layout: + * + * +----------------------+ <-- top of physical memory + * | | + * ~ ~ + * | | + * +----------------------+ <-- top of initrd + * | | + * +----------------------+ <-- top of FDT + * | | + * +----------------------+ <-- top of cpu0's stack + * | | + * +----------------------+ <-- top of text/data/bss sections + * | | + * | | + * +----------------------+ <-- load address + * | | + * +----------------------+ <-- physical address 0x0 + */ SECTIONS { diff --git a/lib/arm/asm/setup.h b/lib/arm/asm/setup.h index 210c14f818fb..f0e70b119fb0 100644 --- a/lib/arm/asm/setup.h +++ b/lib/arm/asm/setup.h @@ -13,9 +13,8 @@ extern u64 cpus[NR_CPUS]; /* per-cpu IDs (MPIDRs) */ extern int nr_cpus; -#define MR_F_PRIMARY (1U << 0) -#define MR_F_IO (1U << 1) -#define MR_F_CODE (1U << 2) +#define MR_F_IO (1U << 0) +#define MR_F_CODE (1U << 1) #define MR_F_UNKNOWN (1U << 31) struct mem_region { @@ -26,6 +25,7 @@ struct mem_region { extern struct mem_region *mem_regions; extern phys_addr_t __phys_offset, __phys_end; +extern struct mem_region *mem_region_find(phys_addr_t paddr); extern unsigned int mem_region_get_flags(phys_addr_t paddr); #define PHYS_OFFSET (__phys_offset) @@ -35,6 +35,6 @@ extern unsigned int mem_region_get_flags(phys_addr_t paddr); #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) #define SMP_CACHE_BYTES L1_CACHE_BYTES -void setup(const void *fdt); +void setup(const void *fdt, phys_addr_t freemem_start); #endif /* _ASMARM_SETUP_H_ */ diff --git a/lib/arm/mmu.c b/lib/arm/mmu.c index edd2b9da809b..7cff22a12e86 100644 --- a/lib/arm/mmu.c +++ b/lib/arm/mmu.c @@ -225,12 +225,10 @@ void *setup_mmu(phys_addr_t phys_end) if (r->flags & MR_F_IO) { continue; } else if (r->flags & MR_F_CODE) { - assert_msg(r->flags & MR_F_PRIMARY, "Unexpected code region"); /* armv8 requires code shared between EL1 and EL0 to be read-only */ mmu_set_range_ptes(mmu_idmap, r->start, r->start, r->end, __pgprot(PTE_WBWA | PTE_USER | PTE_RDONLY)); } else { - assert_msg(r->flags & MR_F_PRIMARY, "Unexpected data region"); mmu_set_range_ptes(mmu_idmap, r->start, r->start, r->end, __pgprot(PTE_WBWA | PTE_USER)); } diff --git a/lib/arm/setup.c b/lib/arm/setup.c index 9da5d24b0be9..5cda2d919d2b 100644 --- a/lib/arm/setup.c +++ b/lib/arm/setup.c @@ -28,9 +28,9 @@ #include "io.h" -#define NR_INITIAL_MEM_REGIONS 16 +#define MAX_DT_MEM_REGIONS 16 +#define NR_EXTRA_MEM_REGIONS 16 -extern unsigned long stacktop; extern unsigned long etext; struct timer_state __timer_state; @@ -41,7 +41,7 @@ u32 initrd_size; u64 cpus[NR_CPUS] = { [0 ... NR_CPUS-1] = (u64)~0 }; int nr_cpus; -static struct mem_region __initial_mem_regions[NR_INITIAL_MEM_REGIONS + 1]; +static struct mem_region __initial_mem_regions[MAX_DT_MEM_REGIONS + NR_EXTRA_MEM_REGIONS]; struct mem_region *mem_regions = __initial_mem_regions; phys_addr_t __phys_offset, __phys_end; @@ -75,28 +75,62 @@ static void cpu_init(void) set_cpu_online(0, true); } -unsigned int mem_region_get_flags(phys_addr_t paddr) +static int mem_regions_next_index(void) { struct mem_region *r; + int n; - for (r = mem_regions; r->end; ++r) { - if (paddr >= r->start && paddr < r->end) - return r->flags; + for (r = mem_regions, n = 0; r->end; ++r, ++n) + ; + return n; +} + +static void mem_regions_get_dt_regions(void) +{ + struct dt_pbus_reg regs[MAX_DT_MEM_REGIONS]; + int nr_regs, i, n; + + nr_regs = dt_get_memory_params(regs, MAX_DT_MEM_REGIONS); + assert(nr_regs > 0); + + n = mem_regions_next_index(); + + for (i = 0; i < nr_regs; ++i) { + struct mem_region *r = &mem_regions[n + i]; + r->start = regs[i].addr; + r->end = regs[i].addr + regs[i].size; } +} + +struct mem_region *mem_region_find(phys_addr_t paddr) +{ + struct mem_region *r; + + for (r = mem_regions; r->end; ++r) + if (paddr >= r->start && paddr < r->end) + return r; + return NULL; +} - return MR_F_UNKNOWN; +unsigned int mem_region_get_flags(phys_addr_t paddr) +{ + struct mem_region *r = mem_region_find(paddr); + return r ? r->flags : MR_F_UNKNOWN; } -static void mem_init(phys_addr_t freemem_start) +static void mem_regions_add_assumed(void) { phys_addr_t code_end = (phys_addr_t)(unsigned long)&etext; - struct dt_pbus_reg regs[NR_INITIAL_MEM_REGIONS]; - struct mem_region mem = { - .start = (phys_addr_t)-1, - }; - struct mem_region *primary = NULL; - phys_addr_t base, top; - int nr_regs, nr_io = 0, i; + int n = mem_regions_next_index(); + struct mem_region mem = {0}, *r; + + r = mem_region_find(code_end - 1); + assert(r); + + /* Split the region with the code into two regions; code and data */ + mem.start = code_end, mem.end = r->end; + mem_regions[n++] = mem; + r->end = code_end, r->flags = MR_F_CODE; /* * mach-virt I/O regions: @@ -104,50 +138,47 @@ static void mem_init(phys_addr_t freemem_start) * - 512M at 256G (arm64, arm uses highmem=off) * - 512G at 512G (arm64, arm uses highmem=off) */ - mem_regions[nr_io++] = (struct mem_region){ 0, (1ul << 30), MR_F_IO }; + mem_regions[n++] = (struct mem_region){ 0, (1ul << 30), MR_F_IO }; #ifdef __aarch64__ - mem_regions[nr_io++] = (struct mem_region){ (1ul << 38), (1ul << 38) | (1ul << 29), MR_F_IO }; - mem_regions[nr_io++] = (struct mem_region){ (1ul << 39), (1ul << 40), MR_F_IO }; + mem_regions[n++] = (struct mem_region){ (1ul << 38), (1ul << 38) | (1ul << 29), MR_F_IO }; + mem_regions[n++] = (struct mem_region){ (1ul << 39), (1ul << 40), MR_F_IO }; #endif +} - nr_regs = dt_get_memory_params(regs, NR_INITIAL_MEM_REGIONS - nr_io); - assert(nr_regs > 0); - - for (i = 0; i < nr_regs; ++i) { - struct mem_region *r = &mem_regions[nr_io + i]; +static void mem_init(phys_addr_t freemem_start) +{ + phys_addr_t base, top; + struct mem_region *freemem, *r, mem = { + .start = (phys_addr_t)-1, + }; - r->start = regs[i].addr; - r->end = regs[i].addr + regs[i].size; + freemem = mem_region_find(freemem_start); + assert(freemem && !(freemem->flags & (MR_F_IO | MR_F_CODE))); - /* - * pick the region we're in for our primary region - */ - if (freemem_start >= r->start && freemem_start < r->end) { - r->flags |= MR_F_PRIMARY; - primary = r; + for (r = mem_regions; r->end; ++r) { + assert(!(r->start & ~PHYS_MASK) && !((r->end - 1) & ~PHYS_MASK)); + if (!(r->flags & MR_F_IO)) { + if (r->start < mem.start) + mem.start = r->start; + if (r->end > mem.end) + mem.end = r->end; } - - /* - * set the lowest and highest addresses found, - * ignoring potential gaps - */ - if (r->start < mem.start) - mem.start = r->start; - if (r->end > mem.end) - mem.end = r->end; } - assert(primary); - assert(!(mem.start & ~PHYS_MASK) && !((mem.end - 1) & ~PHYS_MASK)); + assert(mem.end); + + /* Check for holes */ + r = mem_region_find(mem.start); + while (r && r->end != mem.end) + r = mem_region_find(r->end); + assert(r); - __phys_offset = primary->start; /* PHYS_OFFSET */ - __phys_end = primary->end; /* PHYS_END */ + /* Ensure our selected freemem region is somewhere in our full range */ + assert(freemem_start >= mem.start && freemem->end <= mem.end); - /* Split the primary region into two regions; code and data */ - mem.start = code_end, mem.end = primary->end, mem.flags = MR_F_PRIMARY; - mem_regions[nr_io + i] = mem; - primary->end = code_end, primary->flags |= MR_F_CODE; + __phys_offset = mem.start; /* PHYS_OFFSET */ + __phys_end = mem.end; /* PHYS_END */ - phys_alloc_init(freemem_start, __phys_end - freemem_start); + phys_alloc_init(freemem_start, freemem->end - freemem_start); phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES); phys_alloc_get_unused(&base, &top); @@ -197,35 +228,17 @@ static void timer_save_state(void) __timer_state.vtimer.irq_flags = fdt32_to_cpu(data[8]); } -void setup(const void *fdt) +void setup(const void *fdt, phys_addr_t freemem_start) { - void *freemem = &stacktop; + void *freemem; const char *bootargs, *tmp; u32 fdt_size; int ret; - /* - * Before calling mem_init we need to move the fdt and initrd - * to safe locations. We move them to construct the memory - * map illustrated below: - * - * +----------------------+ <-- top of physical memory - * | | - * ~ ~ - * | | - * +----------------------+ <-- top of initrd - * | | - * +----------------------+ <-- top of FDT - * | | - * +----------------------+ <-- top of cpu0's stack - * | | - * +----------------------+ <-- top of text/data/bss sections, - * | | see arm/flat.lds - * | | - * +----------------------+ <-- load address - * | | - * +----------------------+ - */ + assert(sizeof(long) == 8 || freemem_start < (3ul << 30)); + freemem = (void *)(unsigned long)freemem_start; + + /* Move the FDT to the base of free memory */ fdt_size = fdt_totalsize(fdt); ret = fdt_move(fdt, freemem, fdt_size); assert(ret == 0); @@ -233,6 +246,7 @@ void setup(const void *fdt) assert(ret == 0); freemem += fdt_size; + /* Move the initrd to the top of the FDT */ ret = dt_get_initrd(&tmp, &initrd_size); assert(ret == 0 || ret == -FDT_ERR_NOTFOUND); if (ret == 0) { @@ -241,7 +255,10 @@ void setup(const void *fdt) freemem += initrd_size; } + mem_regions_get_dt_regions(); + mem_regions_add_assumed(); mem_init(PAGE_ALIGN((unsigned long)freemem)); + cpu_init(); /* cpu_init must be called before thread_info_init */ From patchwork Wed Apr 7 18:59:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 12189197 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B62F2C43460 for ; Wed, 7 Apr 2021 18:59:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8BCE761245 for ; Wed, 7 Apr 2021 18:59:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355519AbhDGTAG (ORCPT ); Wed, 7 Apr 2021 15:00:06 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:53540 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355515AbhDGTAF (ORCPT ); Wed, 7 Apr 2021 15:00:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617821995; 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=1+0Uv4KWM+jkXn6tPNx2tatgsR/a1j8uEfJcMGl7pv8=; b=XY6L2yjN8PR+/vR60/KjJRnJCov4FMHDzDP/M1cBeZZpPTgd/9KNF47uIczJC1ETZV1oCP ARy23QmlYdOS0d8CfenkyAKrcHlgm+VHxEI89geYhaiXLzwLMmTMshlOKU+ccPBCK1RPZE LnE9pc68r7zrMvfGIIwhRZYqIUjC3UY= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-313-diBbI1WkPkKIwhvWHFXdAg-1; Wed, 07 Apr 2021 14:59:52 -0400 X-MC-Unique: diBbI1WkPkKIwhvWHFXdAg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 4F90810054F6; Wed, 7 Apr 2021 18:59:51 +0000 (UTC) Received: from kamzik.brq.redhat.com (unknown [10.40.193.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id C236760CEA; Wed, 7 Apr 2021 18:59:47 +0000 (UTC) From: Andrew Jones To: kvm@vger.kernel.org Cc: alexandru.elisei@arm.com, nikos.nikoleris@arm.com, andre.przywara@arm.com, eric.auger@redhat.com Subject: [PATCH kvm-unit-tests 7/8] chr-testdev: Silently fail init Date: Wed, 7 Apr 2021 20:59:17 +0200 Message-Id: <20210407185918.371983-8-drjones@redhat.com> In-Reply-To: <20210407185918.371983-1-drjones@redhat.com> References: <20210407185918.371983-1-drjones@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org If there's no virtio-console / chr-testdev configured, then the user probably didn't want them. Just silently fail rather than stating the obvious. Signed-off-by: Andrew Jones Reviewed-by: Nikos Nikoleris Reviewed-by: Alexandru Elisei --- lib/chr-testdev.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/chr-testdev.c b/lib/chr-testdev.c index 6890f63c8b29..b3c641a833fe 100644 --- a/lib/chr-testdev.c +++ b/lib/chr-testdev.c @@ -54,11 +54,8 @@ void chr_testdev_init(void) int ret; vcon = virtio_bind(VIRTIO_ID_CONSOLE); - if (vcon == NULL) { - printf("%s: %s: can't find a virtio-console\n", - __func__, TESTDEV_NAME); + if (vcon == NULL) return; - } ret = vcon->config->find_vqs(vcon, 2, vqs, NULL, io_names); if (ret < 0) { From patchwork Wed Apr 7 18:59:18 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Jones X-Patchwork-Id: 12189199 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3D47BC433B4 for ; Wed, 7 Apr 2021 18:59:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1BACF61245 for ; Wed, 7 Apr 2021 18:59:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355524AbhDGTAI (ORCPT ); Wed, 7 Apr 2021 15:00:08 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:46461 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355518AbhDGTAG (ORCPT ); Wed, 7 Apr 2021 15:00:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1617821996; 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=Fq2z9Cciylm7lQWg9/xvcPW8IugFYoqpdT9buVnJ92k=; b=dlNDRmd/xfGozyYXE4WCgR1FduiAOOX83GhWwmmHLUQdMACZTmjaJDGtNfSn3g8klY6Y+I Gz1UQcEg2pGOXhji1+n9f5gLEKS44FzEj6nMhYGhmW18qB6Osw4QMYjoR/afjWE20C7E7t 3hw9bUS13ZhK1jaT4lbujHhyBzNhZvE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-442-9o5buXgANw-Qg_Dcm9DpQg-1; Wed, 07 Apr 2021 14:59:55 -0400 X-MC-Unique: 9o5buXgANw-Qg_Dcm9DpQg-1 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 2C5761006C80; Wed, 7 Apr 2021 18:59:54 +0000 (UTC) Received: from kamzik.brq.redhat.com (unknown [10.40.193.185]) by smtp.corp.redhat.com (Postfix) with ESMTP id A22F660C5C; Wed, 7 Apr 2021 18:59:51 +0000 (UTC) From: Andrew Jones To: kvm@vger.kernel.org Cc: alexandru.elisei@arm.com, nikos.nikoleris@arm.com, andre.przywara@arm.com, eric.auger@redhat.com Subject: [PATCH kvm-unit-tests 8/8] arm/arm64: psci: don't assume method is hvc Date: Wed, 7 Apr 2021 20:59:18 +0200 Message-Id: <20210407185918.371983-9-drjones@redhat.com> In-Reply-To: <20210407185918.371983-1-drjones@redhat.com> References: <20210407185918.371983-1-drjones@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The method can also be smc and it will be when running on bare metal. Signed-off-by: Andrew Jones --- arm/selftest.c | 34 +++++++--------------------------- lib/arm/asm/psci.h | 9 +++++++-- lib/arm/psci.c | 17 +++++++++++++++-- lib/arm/setup.c | 22 ++++++++++++++++++++++ 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/arm/selftest.c b/arm/selftest.c index 4495b161cdd5..9f459ed3d571 100644 --- a/arm/selftest.c +++ b/arm/selftest.c @@ -400,33 +400,13 @@ static void check_vectors(void *arg __unused) exit(report_summary()); } -static bool psci_check(void) +static void psci_print(void) { - const struct fdt_property *method; - int node, len, ver; - - node = fdt_node_offset_by_compatible(dt_fdt(), -1, "arm,psci-0.2"); - if (node < 0) { - printf("PSCI v0.2 compatibility required\n"); - return false; - } - - method = fdt_get_property(dt_fdt(), node, "method", &len); - if (method == NULL) { - printf("bad psci device tree node\n"); - return false; - } - - if (len < 4 || strcmp(method->data, "hvc") != 0) { - printf("psci method must be hvc\n"); - return false; - } - - ver = psci_invoke(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0); - printf("PSCI version %d.%d\n", PSCI_VERSION_MAJOR(ver), - PSCI_VERSION_MINOR(ver)); - - return true; + int ver = psci_invoke(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0); + report_info("PSCI version: %d.%d", PSCI_VERSION_MAJOR(ver), + PSCI_VERSION_MINOR(ver)); + report_info("PSCI method: %s", psci_invoke == psci_invoke_hvc ? + "hvc" : "smc"); } static void cpu_report(void *data __unused) @@ -465,7 +445,7 @@ int main(int argc, char **argv) } else if (strcmp(argv[1], "smp") == 0) { - report(psci_check(), "PSCI version"); + psci_print(); on_cpus(cpu_report, NULL); while (!cpumask_full(&ready)) cpu_relax(); diff --git a/lib/arm/asm/psci.h b/lib/arm/asm/psci.h index 7b956bf5987d..e385ce27f5d1 100644 --- a/lib/arm/asm/psci.h +++ b/lib/arm/asm/psci.h @@ -3,8 +3,13 @@ #include #include -extern int psci_invoke(unsigned long function_id, unsigned long arg0, - unsigned long arg1, unsigned long arg2); +typedef int (*psci_invoke_fn)(unsigned long function_id, unsigned long arg0, + unsigned long arg1, unsigned long arg2); +extern psci_invoke_fn psci_invoke; +extern int psci_invoke_hvc(unsigned long function_id, unsigned long arg0, + unsigned long arg1, unsigned long arg2); +extern int psci_invoke_smc(unsigned long function_id, unsigned long arg0, + unsigned long arg1, unsigned long arg2); extern int psci_cpu_on(unsigned long cpuid, unsigned long entry_point); extern void psci_system_reset(void); extern int cpu_psci_cpu_boot(unsigned int cpu); diff --git a/lib/arm/psci.c b/lib/arm/psci.c index 936c83948b6a..46300f30822c 100644 --- a/lib/arm/psci.c +++ b/lib/arm/psci.c @@ -11,9 +11,11 @@ #include #include +psci_invoke_fn psci_invoke; + __attribute__((noinline)) -int psci_invoke(unsigned long function_id, unsigned long arg0, - unsigned long arg1, unsigned long arg2) +int psci_invoke_hvc(unsigned long function_id, unsigned long arg0, + unsigned long arg1, unsigned long arg2) { asm volatile( "hvc #0" @@ -22,6 +24,17 @@ int psci_invoke(unsigned long function_id, unsigned long arg0, return function_id; } +__attribute__((noinline)) +int psci_invoke_smc(unsigned long function_id, unsigned long arg0, + unsigned long arg1, unsigned long arg2) +{ + asm volatile( + "smc #0" + : "+r" (function_id) + : "r" (arg0), "r" (arg1), "r" (arg2)); + return function_id; +} + int psci_cpu_on(unsigned long cpuid, unsigned long entry_point) { #ifdef __arm__ diff --git a/lib/arm/setup.c b/lib/arm/setup.c index 5cda2d919d2b..e595a9e5a167 100644 --- a/lib/arm/setup.c +++ b/lib/arm/setup.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "io.h" @@ -55,6 +56,26 @@ int mpidr_to_cpu(uint64_t mpidr) return -1; } +static void psci_set_conduit(void) +{ + const void *fdt = dt_fdt(); + const struct fdt_property *method; + int node, len; + + node = fdt_node_offset_by_compatible(fdt, -1, "arm,psci-0.2"); + assert_msg(node >= 0, "PSCI v0.2 compatibility required"); + + method = fdt_get_property(fdt, node, "method", &len); + assert(method != NULL && len == 4); + + if (strcmp(method->data, "hvc") == 0) + psci_invoke = psci_invoke_hvc; + else if (strcmp(method->data, "smc") == 0) + psci_invoke = psci_invoke_smc; + else + assert_msg(false, "Unknown PSCI conduit: %s", method->data); +} + static void cpu_set(int fdtnode __unused, u64 regval, void *info __unused) { int cpu = nr_cpus++; @@ -259,6 +280,7 @@ void setup(const void *fdt, phys_addr_t freemem_start) mem_regions_add_assumed(); mem_init(PAGE_ALIGN((unsigned long)freemem)); + psci_set_conduit(); cpu_init(); /* cpu_init must be called before thread_info_init */