From patchwork Wed Jun 28 21:30:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Henrique Barboza X-Patchwork-Id: 1801291 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ventanamicro.com header.i=@ventanamicro.com header.a=rsa-sha256 header.s=google header.b=f4+ZoF7j; dkim-atps=neutral Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Qrvw16WC4z20Zc for ; Thu, 29 Jun 2023 07:33:37 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1qEcl4-00026p-4m; Wed, 28 Jun 2023 17:31:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1qEcl2-00024P-IX for qemu-devel@nongnu.org; Wed, 28 Jun 2023 17:31:24 -0400 Received: from mail-oo1-xc2d.google.com ([2607:f8b0:4864:20::c2d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1qEcky-000824-Hk for qemu-devel@nongnu.org; Wed, 28 Jun 2023 17:31:24 -0400 Received: by mail-oo1-xc2d.google.com with SMTP id 006d021491bc7-5634db21a78so3153eaf.0 for ; Wed, 28 Jun 2023 14:31:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ventanamicro.com; s=google; t=1687987879; x=1690579879; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=sswYOn7+p4vuez1jQG/odjR1Mcxo50tkghFPEVpBNls=; b=f4+ZoF7jV8Za739pQSj9pWKtBPSAcfT97W7uhtcKHujLydGJRHYI3XAwxcZJkt1rKu uqcMQmwVIXwj3RfLHoPIezp0fn92gjzf4lP6ZhoC3grx0kYz0sxJBsnLXQQ92uSkRjKj JTJq8Dy/DY11k4PIobKf8ZBVJSuubwsp688qsgXyRHzX7ZgF0xluXk5i/JB5Fyh+VcgL 6DziuMjQlq4ns74nNzH7P+JRc4YaB8239vD/r3RZSPchTvsxWikcu4wy5XnpJyTpSv7U 8gVv4biAGh7oETQRtwWK2ITzk50dsVoBPoT9jii57OOn2RLojX4n0UIh2S+65Yqws4HU rPdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687987879; x=1690579879; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=sswYOn7+p4vuez1jQG/odjR1Mcxo50tkghFPEVpBNls=; b=IwVF2zlhJ/kFqYk8qDQnzBIWOtY7dbnYYvmRJQ41xtR/BUcoXaY9b/0rMXrqsglyp8 MxRnnVWnJHYjRBWnL1UqxHOwKzh6favgiCW58wgfEBeNGn6bbXUog9xrjCZ8hTFuSij0 9YvLCjz/HwpV7jxN0Xha7jdMFVTBGAUcN7BiSrL+x6K+IqShvLHW1uIBfOzNEMnGy0Hy Y89SXzwjIUxqlYrv9+S1DwOdEjwOGClLTkuCigDN3hrgm2TwGAnDReFiEr1491jHYVSm 8zeYKtlI29NZB0yueG9sxrcG2pB9zwyLN1gDrAHzi8aFub+MUGomfanHjZuGsyRpwplx X1Tg== X-Gm-Message-State: AC+VfDyqRdlAJaBlAfBd4mV95NuZ9PR4Y8iLuDGADrpH9SAeXwIU/YBa v+559ORgnKD2IXFMJCVG8Q5zioOhBNk/ikqQl1g= X-Google-Smtp-Source: ACHHUZ4pTz87vbAI1TweTiVxITdKieV8/lYK9SE8ky02eAOzQJa5zgBOhlicWF432wKte/q9w9HgiA== X-Received: by 2002:a4a:d6c5:0:b0:565:a8a8:6601 with SMTP id j5-20020a4ad6c5000000b00565a8a86601mr2655850oot.8.1687987879218; Wed, 28 Jun 2023 14:31:19 -0700 (PDT) Received: from grind.dc1.ventanamicro.com (201-69-66-110.dial-up.telesp.net.br. [201.69.66.110]) by smtp.gmail.com with ESMTPSA id y17-20020a4a4511000000b0056084a91c74sm832892ooa.24.2023.06.28.14.31.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 28 Jun 2023 14:31:18 -0700 (PDT) From: Daniel Henrique Barboza To: qemu-devel@nongnu.org Cc: qemu-riscv@nongnu.org, alistair.francis@wdc.com, bmeng@tinylab.org, liweiwei@iscas.ac.cn, zhiwei_liu@linux.alibaba.com, palmer@rivosinc.com, ajones@ventanamicro.com, philmd@linaro.org, Daniel Henrique Barboza Subject: [PATCH v6 06/20] target/riscv: use KVM scratch CPUs to init KVM properties Date: Wed, 28 Jun 2023 18:30:19 -0300 Message-ID: <20230628213033.170315-7-dbarboza@ventanamicro.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230628213033.170315-1-dbarboza@ventanamicro.com> References: <20230628213033.170315-1-dbarboza@ventanamicro.com> MIME-Version: 1.0 Received-SPF: pass client-ip=2607:f8b0:4864:20::c2d; envelope-from=dbarboza@ventanamicro.com; helo=mail-oo1-xc2d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Certain validations, such as the validations done for the machine IDs (mvendorid/marchid/mimpid), are done before starting the CPU. Non-dynamic (named) CPUs tries to match user input with a preset default. As it is today we can't prefetch a KVM default for these cases because we're only able to read/write KVM regs after the vcpu is spinning. Our target/arm friends use a concept called "scratch CPU", which consists of creating a vcpu for doing queries and validations and so on, which is discarded shortly after use [1]. This is a suitable solution for what we need so let's implement it in target/riscv as well. kvm_riscv_init_machine_ids() will be used to do any pre-launch setup for KVM CPUs, via riscv_cpu_add_user_properties(). The function will create a KVM scratch CPU, fetch KVM regs that work as default values for user properties, and then discard the scratch CPU afterwards. We're starting by initializing 'mvendorid'. This concept will be used to init other KVM specific properties in the next patches as well. [1] target/arm/kvm.c, kvm_arm_create_scratch_host_vcpu() Suggested-by: Andrew Jones Signed-off-by: Daniel Henrique Barboza Reviewed-by: Andrew Jones Acked-by: Alistair Francis --- target/riscv/cpu.c | 6 +++ target/riscv/kvm.c | 85 ++++++++++++++++++++++++++++++++++++++++ target/riscv/kvm_riscv.h | 1 + 3 files changed, 92 insertions(+) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 51f055b8be..2485e820f8 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1710,6 +1710,12 @@ static void riscv_cpu_add_user_properties(Object *obj) Property *prop; DeviceState *dev = DEVICE(obj); +#ifndef CONFIG_USER_ONLY + if (kvm_enabled()) { + kvm_riscv_init_user_properties(obj); + } +#endif + riscv_cpu_add_misa_properties(obj); for (prop = riscv_cpu_extensions; prop && prop->name; prop++) { diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c index 0f932a5b96..37f0f70794 100644 --- a/target/riscv/kvm.c +++ b/target/riscv/kvm.c @@ -309,6 +309,91 @@ static void kvm_riscv_put_regs_timer(CPUState *cs) env->kvm_timer_dirty = false; } +typedef struct KVMScratchCPU { + int kvmfd; + int vmfd; + int cpufd; +} KVMScratchCPU; + +/* + * Heavily inspired by kvm_arm_create_scratch_host_vcpu() + * from target/arm/kvm.c. + */ +static bool kvm_riscv_create_scratch_vcpu(KVMScratchCPU *scratch) +{ + int kvmfd = -1, vmfd = -1, cpufd = -1; + + kvmfd = qemu_open_old("/dev/kvm", O_RDWR); + if (kvmfd < 0) { + goto err; + } + do { + vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0); + } while (vmfd == -1 && errno == EINTR); + if (vmfd < 0) { + goto err; + } + cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0); + if (cpufd < 0) { + goto err; + } + + scratch->kvmfd = kvmfd; + scratch->vmfd = vmfd; + scratch->cpufd = cpufd; + + return true; + + err: + if (cpufd >= 0) { + close(cpufd); + } + if (vmfd >= 0) { + close(vmfd); + } + if (kvmfd >= 0) { + close(kvmfd); + } + + return false; +} + +static void kvm_riscv_destroy_scratch_vcpu(KVMScratchCPU *scratch) +{ + close(scratch->cpufd); + close(scratch->vmfd); + close(scratch->kvmfd); +} + +static void kvm_riscv_init_machine_ids(RISCVCPU *cpu, KVMScratchCPU *kvmcpu) +{ + CPURISCVState *env = &cpu->env; + struct kvm_one_reg reg; + int ret; + + reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG, + KVM_REG_RISCV_CONFIG_REG(mvendorid)); + reg.addr = (uint64_t)&cpu->cfg.mvendorid; + ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®); + if (ret != 0) { + error_report("Unable to retrieve mvendorid from host, error %d", ret); + } +} + +void kvm_riscv_init_user_properties(Object *cpu_obj) +{ + RISCVCPU *cpu = RISCV_CPU(cpu_obj); + KVMScratchCPU kvmcpu; + + if (!kvm_riscv_create_scratch_vcpu(&kvmcpu)) { + return; + } + + kvm_riscv_init_machine_ids(cpu, &kvmcpu); + + kvm_riscv_destroy_scratch_vcpu(&kvmcpu); +} + const KVMCapabilityInfo kvm_arch_required_capabilities[] = { KVM_CAP_LAST_INFO }; diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h index ed281bdce0..e3ba935808 100644 --- a/target/riscv/kvm_riscv.h +++ b/target/riscv/kvm_riscv.h @@ -19,6 +19,7 @@ #ifndef QEMU_KVM_RISCV_H #define QEMU_KVM_RISCV_H +void kvm_riscv_init_user_properties(Object *cpu_obj); void kvm_riscv_reset_vcpu(RISCVCPU *cpu); void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level);