From patchwork Thu Dec 3 12:46:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yifei Jiang X-Patchwork-Id: 11948667 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=-16.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT 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 84DA6C8301A for ; Thu, 3 Dec 2020 12:48:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 43A4122245 for ; Thu, 3 Dec 2020 12:48:26 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388233AbgLCMsP (ORCPT ); Thu, 3 Dec 2020 07:48:15 -0500 Received: from szxga04-in.huawei.com ([45.249.212.190]:8238 "EHLO szxga04-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387750AbgLCMsO (ORCPT ); Thu, 3 Dec 2020 07:48:14 -0500 Received: from DGGEMS403-HUB.china.huawei.com (unknown [172.30.72.60]) by szxga04-in.huawei.com (SkyGuard) with ESMTP id 4CmwZn1G9bzkkrX; Thu, 3 Dec 2020 20:46:57 +0800 (CST) Received: from huawei.com (10.174.186.236) by DGGEMS403-HUB.china.huawei.com (10.3.19.203) with Microsoft SMTP Server id 14.3.487.0; Thu, 3 Dec 2020 20:47:24 +0800 From: Yifei Jiang To: , CC: , , , , , , , , , , , , , Yifei Jiang Subject: [PATCH RFC v4 06/15] target/riscv: Support start kernel directly by KVM Date: Thu, 3 Dec 2020 20:46:54 +0800 Message-ID: <20201203124703.168-7-jiangyifei@huawei.com> X-Mailer: git-send-email 2.26.2.windows.1 In-Reply-To: <20201203124703.168-1-jiangyifei@huawei.com> References: <20201203124703.168-1-jiangyifei@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.174.186.236] X-CFilter-Loop: Reflected Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org Get kernel and fdt start address in virt.c, and pass them to KVM when cpu reset. In addition, add kvm_riscv.h to place riscv specific interface. Signed-off-by: Yifei Jiang Signed-off-by: Yipeng Yin --- hw/riscv/virt.c | 8 ++++++++ target/riscv/cpu.c | 4 ++++ target/riscv/cpu.h | 3 +++ target/riscv/kvm.c | 15 +++++++++++++++ target/riscv/kvm_riscv.h | 24 ++++++++++++++++++++++++ 5 files changed, 54 insertions(+) create mode 100644 target/riscv/kvm_riscv.h diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 25cea7aa67..47b7018193 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -42,6 +42,7 @@ #include "sysemu/sysemu.h" #include "hw/pci/pci.h" #include "hw/pci-host/gpex.h" +#include "sysemu/kvm.h" #if defined(TARGET_RISCV32) # define BIOS_FILENAME "opensbi-riscv32-generic-fw_dynamic.bin" @@ -511,6 +512,7 @@ static void virt_machine_init(MachineState *machine) uint64_t kernel_entry; DeviceState *mmio_plic, *virtio_plic, *pcie_plic; int i, j, base_hartid, hart_count; + CPUState *cs; /* Check socket count limit */ if (VIRT_SOCKETS_MAX < riscv_socket_count(machine)) { @@ -660,6 +662,12 @@ static void virt_machine_init(MachineState *machine) virt_memmap[VIRT_MROM].size, kernel_entry, fdt_load_addr, s->fdt); + for (cs = first_cpu; cs; cs = CPU_NEXT(cs)) { + RISCVCPU *riscv_cpu = RISCV_CPU(cs); + riscv_cpu->env.kernel_addr = kernel_entry; + riscv_cpu->env.fdt_addr = fdt_load_addr; + } + /* SiFive Test MMIO device */ sifive_test_create(memmap[VIRT_TEST].base); diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 6a0264fc6b..faee98a58c 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -29,6 +29,7 @@ #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "fpu/softfloat-helpers.h" +#include "kvm_riscv.h" /* RISC-V CPU definitions */ @@ -330,6 +331,9 @@ static void riscv_cpu_reset(DeviceState *dev) cs->exception_index = EXCP_NONE; env->load_res = -1; set_default_nan_mode(1, &env->fp_status); +#ifdef CONFIG_KVM + kvm_riscv_reset_vcpu(cpu); +#endif } static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index c0a326c843..ad1c90f798 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -233,6 +233,9 @@ struct CPURISCVState { /* Fields from here on are preserved across CPU reset. */ QEMUTimer *timer; /* Internal timer */ + + hwaddr kernel_addr; + hwaddr fdt_addr; }; OBJECT_DECLARE_TYPE(RISCVCPU, RISCVCPUClass, diff --git a/target/riscv/kvm.c b/target/riscv/kvm.c index 8b206ce99c..6250ca0c7d 100644 --- a/target/riscv/kvm.c +++ b/target/riscv/kvm.c @@ -37,6 +37,7 @@ #include "hw/irq.h" #include "qemu/log.h" #include "hw/loader.h" +#include "kvm_riscv.h" static __u64 kvm_riscv_reg_id(__u64 type, __u64 idx) { @@ -439,3 +440,17 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run) { return 0; } + +void kvm_riscv_reset_vcpu(RISCVCPU *cpu) +{ + CPURISCVState *env = &cpu->env; + + if (!kvm_enabled()) { + return; + } + env->pc = cpu->env.kernel_addr; + env->gpr[10] = kvm_arch_vcpu_id(CPU(cpu)); /* a0 */ + env->gpr[11] = cpu->env.fdt_addr; /* a1 */ + env->satp = 0; +} + diff --git a/target/riscv/kvm_riscv.h b/target/riscv/kvm_riscv.h new file mode 100644 index 0000000000..f38c82bf59 --- /dev/null +++ b/target/riscv/kvm_riscv.h @@ -0,0 +1,24 @@ +/* + * QEMU KVM support -- RISC-V specific functions. + * + * Copyright (c) 2020 Huawei Technologies Co., Ltd + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2 or later, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program. If not, see . + */ + +#ifndef QEMU_KVM_RISCV_H +#define QEMU_KVM_RISCV_H + +void kvm_riscv_reset_vcpu(RISCVCPU *cpu); + +#endif