Received: by 2002:ab2:6d45:0:b0:1fb:d597:ff75 with SMTP id d5csp172377lqr; Wed, 5 Jun 2024 02:31:39 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCVBhrpDuztP5M0IRLuKW3w3i3D5qQAc4Yf0XFxmMH9I7USwiPFbn4zCD6IkOYRxuDaSKYHtF8uqunUVJVyoMleNZQnSUBiKX1xS5vQzhw== X-Google-Smtp-Source: AGHT+IFEHNwfFTAHVJRXjD8xLgpvi9jDPLddhB4UVbDDCqAfnml1c97uU665t8XD2UfY5Be3NxzH X-Received: by 2002:a17:906:5846:b0:a64:c42f:a99 with SMTP id a640c23a62f3a-a699fa97f93mr114410866b.19.1717579899207; Wed, 05 Jun 2024 02:31:39 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1717579899; cv=pass; d=google.com; s=arc-20160816; b=kR0fWJ4YCHtXB0z2wyyzdr1igv8Fb2Ebo1FNXgE9A9JowTO5RGP/90D9Lt2LyGhz9W E8IjCK1wC8oUieKIcFDJJvplvThlz3FngSNqi3nnCebhgxCxqQwk2T3xhbGPBTxt0zWt BXldm0QwPTqSSnqoqGxY4Em1NeL8D9GepukSb9QJDcQZdo+bdbkN6MMn1buxNUDG8pU7 qHixkOUXDC4IiVFZn3sbu1loXoVCvuMeeIe3beySs2EUAh1C+AgyWveu89LiUGT3Fpdk WzO/IN+S41YEq4mYxhkkKTSFgvcxqh16YVZyRKLT481phVGMlE6ZHvFlHmQLH1bEj3aw damA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=3wx4e8wROhHW2HhW3Rt3caRzX6jA40cpCxYYBvxzUqA=; fh=mU6xl5FN63PgqIKyLHx/u5uRervM0V89cYoVjXl22Bs=; b=ekWdnlEw2MTjR1KrcCGrBiKGP7ZfyaPpW1pnfFm7prw2WLkjyxhXyxqJFYI5nkOiFL R2FO+LNIo2+5Rzsuo+8GiTkfXIPLHD1/feQ2pKcFoQr4N41lEcsZydxdBOylQ7x6SL85 yyfDx1W3TM/A3J5uMgRDJ/3ZgKv7YzclF+ZBuA57SMFTYL5PBVsnmyLWZkRDy8X3n8Ft /ko0oRZ44HbuBTqneoRbZGLy43WmX3LJS+0aRqF1huRXYEu/pmv+WHEX2ph4kBoPCWNZ m2XWVdHqitSu4+vKv+GfkjOmpoyOUAXOaA8C6vsPjx02hYDDUst7ED+fH1X/VwUKvU30 /L2w==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1 spf=pass spfdomain=arm.com dmarc=pass fromdomain=arm.com); spf=pass (google.com: domain of linux-kernel+bounces-202099-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-202099-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from am.mirrors.kernel.org (am.mirrors.kernel.org. [147.75.80.249]) by mx.google.com with ESMTPS id a640c23a62f3a-a68ada8966asi481433466b.1028.2024.06.05.02.31.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 05 Jun 2024 02:31:39 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-202099-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) client-ip=147.75.80.249; Authentication-Results: mx.google.com; arc=pass (i=1 spf=pass spfdomain=arm.com dmarc=pass fromdomain=arm.com); spf=pass (google.com: domain of linux-kernel+bounces-202099-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.80.249 as permitted sender) smtp.mailfrom="linux-kernel+bounces-202099-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by am.mirrors.kernel.org (Postfix) with ESMTPS id BAF8D1F230A7 for ; Wed, 5 Jun 2024 09:31:38 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id F41BF191463; Wed, 5 Jun 2024 09:30:30 +0000 (UTC) Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id D83161946CB; Wed, 5 Jun 2024 09:30:27 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717579830; cv=none; b=aQuB1AZjCyh4zOz54bsn+6AZUy4jKgwhTvYnCQxF9fGV4egGAo1O51KRJoLWYG82VzNDljb3KNkhs1CAyRkHea35RPIiWmAD23HuoLXUhFE9kegbS1BiLjgs2UcyXSne5qzmKoIzxNvLyDxZaukX1eW9Hw7mECCD7BN0tezrfFI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1717579830; c=relaxed/simple; bh=SDyUn4kx6hDKzj28ha22l3vD1vbdQvyJPCpcxph6WH0=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=X8Om+OOiJSVcQJrKzIIBGALJF29kLsB/zz1vAL4x3VY6pfXU4tvCks75vAItG0zKFEp+FAMQ/X/ftK6CAR8MBhPw0nncu/WLGRaBDSqZzR/F4FfDoAODlUJT3DG+vLQ3JDS4HNsJ+iWMIc/Nbd7g8ow31sJtpN/fsy/V15pbxwE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id C67321063; Wed, 5 Jun 2024 02:30:51 -0700 (PDT) Received: from e122027.arm.com (unknown [10.57.39.129]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 7DC5A3F792; Wed, 5 Jun 2024 02:30:23 -0700 (PDT) From: Steven Price To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: Suzuki K Poulose , Catalin Marinas , Marc Zyngier , Will Deacon , James Morse , Oliver Upton , Zenghui Yu , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Joey Gouly , Alexandru Elisei , Christoffer Dall , Fuad Tabba , linux-coco@lists.linux.dev, Ganapatrao Kulkarni , Steven Price Subject: [PATCH v3 02/14] arm64: Detect if in a realm and set RIPAS RAM Date: Wed, 5 Jun 2024 10:29:54 +0100 Message-Id: <20240605093006.145492-3-steven.price@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20240605093006.145492-1-steven.price@arm.com> References: <20240605093006.145492-1-steven.price@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Suzuki K Poulose Detect that the VM is a realm guest by the presence of the RSI interface. If in a realm then all memory needs to be marked as RIPAS RAM initially, the loader may or may not have done this for us. To be sure iterate over all RAM and mark it as such. Any failure is fatal as that implies the RAM regions passed to Linux are incorrect - which would mean failing later when attempting to access non-existent RAM. Signed-off-by: Suzuki K Poulose Co-developed-by: Steven Price Signed-off-by: Steven Price --- Changes since v2: * Use DECLARE_STATIC_KEY_FALSE rather than "extern struct static_key_false". * Rename set_memory_range() to rsi_set_memory_range(). * Downgrade some BUG()s to WARN()s and handle the condition by propagating up the stack. Comment the remaining case that ends in a BUG() to explain why. * Rely on the return from rsi_request_version() rather than checking the version the RMM claims to support. * Rename the generic sounding arm64_setup_memory() to arm64_rsi_setup_memory() and move the call site to setup_arch(). --- arch/arm64/include/asm/rsi.h | 48 +++++++++++++++++++++ arch/arm64/include/asm/rsi_cmds.h | 22 ++++++++++ arch/arm64/kernel/Makefile | 3 +- arch/arm64/kernel/rsi.c | 69 +++++++++++++++++++++++++++++++ arch/arm64/kernel/setup.c | 8 ++++ arch/arm64/mm/init.c | 1 + 6 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/include/asm/rsi.h create mode 100644 arch/arm64/kernel/rsi.c diff --git a/arch/arm64/include/asm/rsi.h b/arch/arm64/include/asm/rsi.h new file mode 100644 index 000000000000..ce2cdb501d84 --- /dev/null +++ b/arch/arm64/include/asm/rsi.h @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 ARM Ltd. + */ + +#ifndef __ASM_RSI_H_ +#define __ASM_RSI_H_ + +#include +#include + +DECLARE_STATIC_KEY_FALSE(rsi_present); + +void __init arm64_rsi_init(void); +void __init arm64_rsi_setup_memory(void); +static inline bool is_realm_world(void) +{ + return static_branch_unlikely(&rsi_present); +} + +static inline int rsi_set_memory_range(phys_addr_t start, phys_addr_t end, + enum ripas state) +{ + unsigned long ret; + phys_addr_t top; + + while (start != end) { + ret = rsi_set_addr_range_state(start, end, state, &top); + if (WARN_ON(ret || top < start || top > end)) + return -EINVAL; + start = top; + } + + return 0; +} + +static inline int rsi_set_memory_range_protected(phys_addr_t start, + phys_addr_t end) +{ + return rsi_set_memory_range(start, end, RSI_RIPAS_RAM); +} + +static inline int rsi_set_memory_range_shared(phys_addr_t start, + phys_addr_t end) +{ + return rsi_set_memory_range(start, end, RSI_RIPAS_EMPTY); +} +#endif diff --git a/arch/arm64/include/asm/rsi_cmds.h b/arch/arm64/include/asm/rsi_cmds.h index ad425c5d6f1b..ab8ad435f10e 100644 --- a/arch/arm64/include/asm/rsi_cmds.h +++ b/arch/arm64/include/asm/rsi_cmds.h @@ -10,6 +10,11 @@ #include +enum ripas { + RSI_RIPAS_EMPTY, + RSI_RIPAS_RAM, +}; + static inline void invoke_rsi_fn_smc_with_res(unsigned long function_id, unsigned long arg0, unsigned long arg1, @@ -44,4 +49,21 @@ static inline unsigned long rsi_get_realm_config(struct realm_config *cfg) return res.a0; } +static inline unsigned long rsi_set_addr_range_state(phys_addr_t start, + phys_addr_t end, + enum ripas state, + phys_addr_t *top) +{ + struct arm_smccc_res res; + + invoke_rsi_fn_smc_with_res(SMC_RSI_IPA_STATE_SET, + start, end, state, RSI_NO_CHANGE_DESTROYED, + &res); + + if (top) + *top = res.a1; + + return res.a0; +} + #endif diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 763824963ed1..a483b916ed11 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -33,7 +33,8 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ return_address.o cpuinfo.o cpu_errata.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o \ - syscall.o proton-pack.o idle.o patching.o pi/ + syscall.o proton-pack.o idle.o patching.o pi/ \ + rsi.o obj-$(CONFIG_COMPAT) += sys32.o signal32.o \ sys_compat.o diff --git a/arch/arm64/kernel/rsi.c b/arch/arm64/kernel/rsi.c new file mode 100644 index 000000000000..3a992bdfd6bb --- /dev/null +++ b/arch/arm64/kernel/rsi.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2023 ARM Ltd. + */ + +#include +#include +#include + +DEFINE_STATIC_KEY_FALSE_RO(rsi_present); +EXPORT_SYMBOL(rsi_present); + +static bool rsi_version_matches(void) +{ + unsigned long ver_lower, ver_higher; + unsigned long ret = rsi_request_version(RSI_ABI_VERSION, + &ver_lower, + &ver_higher); + + if (ret == SMCCC_RET_NOT_SUPPORTED) + return false; + + if (ret != RSI_SUCCESS) { + pr_err("RME: RMM doesn't support RSI version %u.%u. Supported range: %lu.%lu-%lu.%lu\n", + RSI_ABI_VERSION_MAJOR, RSI_ABI_VERSION_MINOR, + RSI_ABI_VERSION_GET_MAJOR(ver_lower), + RSI_ABI_VERSION_GET_MINOR(ver_lower), + RSI_ABI_VERSION_GET_MAJOR(ver_higher), + RSI_ABI_VERSION_GET_MINOR(ver_higher)); + return false; + } + + pr_info("RME: Using RSI version %lu.%lu\n", + RSI_ABI_VERSION_GET_MAJOR(ver_lower), + RSI_ABI_VERSION_GET_MINOR(ver_lower)); + + return true; +} + +void __init arm64_rsi_setup_memory(void) +{ + u64 i; + phys_addr_t start, end; + + if (!is_realm_world()) + return; + + /* + * Iterate over the available memory ranges + * and convert the state to protected memory. + * + * BUG_ON is used because if the attempt to switch the memory to + * protected has failed here, then future accesses to the memory are + * simply going to be reflected as a fault which we can't handle. + * Bailing out early prevents the guest limping on and dieing later. + */ + for_each_mem_range(i, &start, &end) { + BUG_ON(rsi_set_memory_range_protected(start, end)); + } +} + +void __init arm64_rsi_init(void) +{ + if (!rsi_version_matches()) + return; + + static_branch_enable(&rsi_present); +} + diff --git a/arch/arm64/kernel/setup.c b/arch/arm64/kernel/setup.c index a096e2451044..143f87615af0 100644 --- a/arch/arm64/kernel/setup.c +++ b/arch/arm64/kernel/setup.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -293,6 +294,11 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) * cpufeature code and early parameters. */ jump_label_init(); + /* + * Init RSI before early param so that "earlycon" console uses the + * shared alias when in a realm + */ + arm64_rsi_init(); parse_early_param(); dynamic_scs_init(); @@ -328,6 +334,8 @@ void __init __no_sanitize_address setup_arch(char **cmdline_p) arm64_memblock_init(); + arm64_rsi_setup_memory(); + paging_init(); acpi_table_upgrade(); diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 9b5ab6818f7f..9d8d38e3bee2 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include -- 2.34.1