From patchwork Thu Nov 14 10:07:42 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Liju-clr Chen X-Patchwork-Id: 13874916 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D4EFED65C6D for ; Thu, 14 Nov 2024 10:35:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender:List-Subscribe:List-Help :List-Post:List-Archive:List-Unsubscribe:List-Id:Content-Type:MIME-Version: References:In-Reply-To:Message-ID:Date:Subject:CC:To:From:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=GONwmY7pvPVHwGJga8ZRaLBO74qwe7MnnfV4NItAYII=; b=nvz9IqxMI4s+wNtTdufe8JFPbJ P3RiGdlA3+42Wnn2UcmHuc4JHWglN5VDtMv5HK7LSHXc/n+sKSvrxl1c8928x02pGA4O8r4c0RRcF 2WLAtDtMvCSXnY/wW9U5og9nmHKlxNDiXYFE2Ljw9AxV8hVFmq5lw5sO8PPfh+IGjW3znmlTGBCzC hDJUsUsJHCkQrejlUKLdpvBY6LFX/i6TjimyHD/49JfexmIWT2R4ytK7EBzpyxO3orn1tf3XU8Tnp kfhBSQLhr2CthkMimFhEj/VUtjlUVmd21ztZSRkLXWxCiHSJDqgo5MQZxn48uz3FezBnkEqJ0jc3X Qt3NjHVg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98 #2 (Red Hat Linux)) id 1tBXC2-00000009Ypk-3IbC; Thu, 14 Nov 2024 10:35:18 +0000 Received: from mailgw01.mediatek.com ([216.200.240.184]) by bombadil.infradead.org with esmtps (Exim 4.98 #2 (Red Hat Linux)) id 1tBWls-00000009T9j-3Mun; Thu, 14 Nov 2024 10:08:25 +0000 X-UUID: 5853963ca27011ef82ff63e91e7eb18c-20241114 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=GONwmY7pvPVHwGJga8ZRaLBO74qwe7MnnfV4NItAYII=; b=QWl/y8gXzIZDYfxtdF5TZNO8MBozI+m2ne4xZxkuvvSlbNcJuL0vn3DwVoJ1aWeI1JFV6kE0777QiaaXTqNpt0LrJmiCX2babYbHcVh1lAAJcDmJaIQuyk71HPHYznFb7WLMPTRaIes/uZ9PegKBfxOAsfj80G7/E2Sn98yYt1o=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.42,REQID:e09ac5cc-4245-4f18-b023-91bc1c5de35b,IP:0,U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:b0fcdc3,CLOUDID:f46b1307-6ce0-4172-9755-bd2287e50583,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:81|82|102,TC:nil,Content:0,EDM:-3,IP :nil,URL:11|1,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV :0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 0 X-CID-BAS: 0,_,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULN X-UUID: 5853963ca27011ef82ff63e91e7eb18c-20241114 Received: from mtkmbs14n1.mediatek.inc [(172.21.101.75)] by mailgw01.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 261214501; Thu, 14 Nov 2024 03:08:07 -0700 Received: from mtkmbs13n1.mediatek.inc (172.21.101.193) by mtkmbs13n1.mediatek.inc (172.21.101.193) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Thu, 14 Nov 2024 18:08:03 +0800 Received: from mtksdccf07.mediatek.inc (172.21.84.99) by mtkmbs13n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Thu, 14 Nov 2024 18:08:03 +0800 From: Liju-clr Chen To: Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jonathan Corbet , Catalin Marinas , Will Deacon , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , Richard Cochran , Matthias Brugger , AngeloGioacchino Del Regno , Liju-clr Chen , Yingshiuan Pan , Ze-yu Wang CC: , , , , , , , Shawn Hsiao , PeiLun Suei , Chi-shen Yeh , Kevenny Hsieh Subject: [PATCH v13 05/25] virt: geniezone: Add vm support Date: Thu, 14 Nov 2024 18:07:42 +0800 Message-ID: <20241114100802.4116-6-liju-clr.chen@mediatek.com> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20241114100802.4116-1-liju-clr.chen@mediatek.com> References: <20241114100802.4116-1-liju-clr.chen@mediatek.com> MIME-Version: 1.0 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20241114_020817_038404_227A5E81 X-CRM114-Status: GOOD ( 31.16 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org From: Yingshiuan Pan The VM component is responsible for setting up the capability and memory management for the protected VMs. The capability is mainly about the lifecycle control and boot context initialization. Signed-off-by: Yingshiuan Pan Co-developed-by: Jerry Wang Signed-off-by: Jerry Wang Signed-off-by: Yi-De Wu Signed-off-by: Liju Chen --- MAINTAINERS | 1 + arch/arm64/geniezone/gzvm_arch_common.h | 4 ++ arch/arm64/geniezone/vm.c | 27 +++++++ drivers/virt/geniezone/Makefile | 2 +- drivers/virt/geniezone/gzvm_main.c | 15 ++++ drivers/virt/geniezone/gzvm_vm.c | 93 +++++++++++++++++++++++++ include/linux/soc/mediatek/gzvm_drv.h | 29 ++++++++ include/uapi/linux/gzvm.h | 25 +++++++ 8 files changed, 195 insertions(+), 1 deletion(-) create mode 100644 drivers/virt/geniezone/gzvm_vm.c create mode 100644 include/uapi/linux/gzvm.h diff --git a/MAINTAINERS b/MAINTAINERS index 708c13103ec5..e7fd6f6a4350 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9680,6 +9680,7 @@ F: Documentation/virt/geniezone/ F: arch/arm64/geniezone/ F: drivers/virt/geniezone/ F: include/linux/soc/mediatek/gzvm_drv.h +F: include/uapi/linux/gzvm.h GENWQE (IBM Generic Workqueue Card) M: Frank Haverkamp diff --git a/arch/arm64/geniezone/gzvm_arch_common.h b/arch/arm64/geniezone/gzvm_arch_common.h index 660c7cf3fc18..60ee5ed2b39f 100644 --- a/arch/arm64/geniezone/gzvm_arch_common.h +++ b/arch/arm64/geniezone/gzvm_arch_common.h @@ -9,6 +9,8 @@ #include enum { + GZVM_FUNC_CREATE_VM = 0, + GZVM_FUNC_DESTROY_VM = 1, GZVM_FUNC_PROBE = 12, NR_GZVM_FUNC, }; @@ -19,6 +21,8 @@ enum { ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64, \ SMC_ENTITY_MTK, (GZVM_FUNCID_START + (func))) +#define MT_HVC_GZVM_CREATE_VM GZVM_HCALL_ID(GZVM_FUNC_CREATE_VM) +#define MT_HVC_GZVM_DESTROY_VM GZVM_HCALL_ID(GZVM_FUNC_DESTROY_VM) #define MT_HVC_GZVM_PROBE GZVM_HCALL_ID(GZVM_FUNC_PROBE) /** diff --git a/arch/arm64/geniezone/vm.c b/arch/arm64/geniezone/vm.c index daad21b28f6f..8e3c9f872bb1 100644 --- a/arch/arm64/geniezone/vm.c +++ b/arch/arm64/geniezone/vm.c @@ -7,6 +7,7 @@ #include #include +#include #include #include "gzvm_arch_common.h" @@ -70,3 +71,29 @@ int gzvm_arch_probe(struct gzvm_version drv_version, return 0; } + +/** + * gzvm_arch_create_vm() - create vm + * @vm_type: VM type. Only supports Linux VM now. + * + * Return: + * * positive value - VM ID + * * -ENOMEM - Memory not enough for storing VM data + */ +int gzvm_arch_create_vm(unsigned long vm_type) +{ + struct arm_smccc_res res; + int ret; + + ret = gzvm_hypcall_wrapper(MT_HVC_GZVM_CREATE_VM, vm_type, 0, 0, 0, 0, + 0, 0, &res); + return ret ? ret : res.a1; +} + +int gzvm_arch_destroy_vm(u16 vm_id) +{ + struct arm_smccc_res res; + + return gzvm_hypcall_wrapper(MT_HVC_GZVM_DESTROY_VM, vm_id, 0, 0, 0, 0, + 0, 0, &res); +} diff --git a/drivers/virt/geniezone/Makefile b/drivers/virt/geniezone/Makefile index 3a82e5fddf90..25614ea3dea2 100644 --- a/drivers/virt/geniezone/Makefile +++ b/drivers/virt/geniezone/Makefile @@ -6,4 +6,4 @@ GZVM_DIR ?= ../../../drivers/virt/geniezone -gzvm-y := $(GZVM_DIR)/gzvm_main.o +gzvm-y := $(GZVM_DIR)/gzvm_main.o $(GZVM_DIR)/gzvm_vm.o diff --git a/drivers/virt/geniezone/gzvm_main.c b/drivers/virt/geniezone/gzvm_main.c index dc91fd61ba75..02dec63ce48f 100644 --- a/drivers/virt/geniezone/gzvm_main.c +++ b/drivers/virt/geniezone/gzvm_main.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -48,6 +49,19 @@ int gzvm_err_to_errno(unsigned long err) return -EINVAL; } +static long gzvm_dev_ioctl(struct file *filp, unsigned int cmd, + unsigned long user_args) +{ + switch (cmd) { + case GZVM_CREATE_VM: + return gzvm_dev_ioctl_create_vm(&gzvm_drv, user_args); + default: + break; + } + + return -ENOTTY; +} + static int gzvm_dev_open(struct inode *inode, struct file *file) { /* @@ -65,6 +79,7 @@ static int gzvm_dev_release(struct inode *inode, struct file *file) } static const struct file_operations gzvm_chardev_ops = { + .unlocked_ioctl = gzvm_dev_ioctl, .llseek = noop_llseek, .open = gzvm_dev_open, .release = gzvm_dev_release, diff --git a/drivers/virt/geniezone/gzvm_vm.c b/drivers/virt/geniezone/gzvm_vm.c new file mode 100644 index 000000000000..500bc8276d60 --- /dev/null +++ b/drivers/virt/geniezone/gzvm_vm.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static DEFINE_MUTEX(gzvm_list_lock); +static LIST_HEAD(gzvm_list); + +static void gzvm_destroy_vm(struct gzvm *gzvm) +{ + pr_debug("VM-%u is going to be destroyed\n", gzvm->vm_id); + + mutex_lock(&gzvm->lock); + + gzvm_arch_destroy_vm(gzvm->vm_id); + + mutex_lock(&gzvm_list_lock); + list_del(&gzvm->vm_list); + mutex_unlock(&gzvm_list_lock); + + mutex_unlock(&gzvm->lock); + + kfree(gzvm); +} + +static int gzvm_vm_release(struct inode *inode, struct file *filp) +{ + struct gzvm *gzvm = filp->private_data; + + gzvm_destroy_vm(gzvm); + return 0; +} + +static const struct file_operations gzvm_vm_fops = { + .release = gzvm_vm_release, +}; + +static struct gzvm *gzvm_create_vm(struct gzvm_driver *drv, unsigned long vm_type) +{ + int ret; + struct gzvm *gzvm; + + gzvm = kzalloc(sizeof(*gzvm), GFP_KERNEL); + if (!gzvm) + return ERR_PTR(-ENOMEM); + + ret = gzvm_arch_create_vm(vm_type); + if (ret < 0) { + kfree(gzvm); + return ERR_PTR(ret); + } + + gzvm->gzvm_drv = drv; + gzvm->vm_id = ret; + gzvm->mm = current->mm; + mutex_init(&gzvm->lock); + + mutex_lock(&gzvm_list_lock); + list_add(&gzvm->vm_list, &gzvm_list); + mutex_unlock(&gzvm_list_lock); + + pr_debug("VM-%u is created\n", gzvm->vm_id); + + return gzvm; +} + +/** + * gzvm_dev_ioctl_create_vm - Create vm fd + * @vm_type: VM type. Only supports Linux VM now + * @drv: GenieZone driver info to be stored in struct gzvm for future usage + * + * Return: fd of vm, negative if error + */ +int gzvm_dev_ioctl_create_vm(struct gzvm_driver *drv, unsigned long vm_type) +{ + struct gzvm *gzvm; + + gzvm = gzvm_create_vm(drv, vm_type); + if (IS_ERR(gzvm)) + return PTR_ERR(gzvm); + + return anon_inode_getfd("gzvm-vm", &gzvm_vm_fops, gzvm, + O_RDWR | O_CLOEXEC); +} diff --git a/include/linux/soc/mediatek/gzvm_drv.h b/include/linux/soc/mediatek/gzvm_drv.h index 495bf5b8b8e0..70008afaaf61 100644 --- a/include/linux/soc/mediatek/gzvm_drv.h +++ b/include/linux/soc/mediatek/gzvm_drv.h @@ -6,6 +6,10 @@ #ifndef __GZVM_DRV_H__ #define __GZVM_DRV_H__ +#include +#include +#include + /* GZVM version encode */ #define GZVM_DRV_MAJOR_VERSION 16 #define GZVM_DRV_MINOR_VERSION 0 @@ -21,6 +25,8 @@ struct gzvm_driver { struct gzvm_version drv_version; }; +#define INVALID_VM_ID 0xffff + /* * These are the definitions of APIs between GenieZone hypervisor and driver, * there's no need to be visible to uapi. Furthermore, we need GenieZone @@ -32,10 +38,33 @@ struct gzvm_driver { #define ERR_NOT_IMPLEMENTED (-27) #define ERR_FAULT (-40) +/** + * struct gzvm: the following data structures are for data transferring between + * driver and hypervisor, and they're aligned with hypervisor definitions. + * @gzvm_drv: the data structure is used to keep driver's information + * @mm: userspace tied to this vm + * @lock: lock for list_add + * @vm_list: list head for vm list + * @vm_id: vm id + */ +struct gzvm { + struct gzvm_driver *gzvm_drv; + struct mm_struct *mm; + struct mutex lock; + struct list_head vm_list; + u16 vm_id; +}; + +int gzvm_dev_ioctl_create_vm(struct gzvm_driver *drv, unsigned long vm_type); + int gzvm_err_to_errno(unsigned long err); +void gzvm_destroy_all_vms(void); + /* arch-dependant functions */ int gzvm_arch_probe(struct gzvm_version drv_version, struct gzvm_version *hyp_version); +int gzvm_arch_create_vm(unsigned long vm_type); +int gzvm_arch_destroy_vm(u16 vm_id); #endif /* __GZVM_DRV_H__ */ diff --git a/include/uapi/linux/gzvm.h b/include/uapi/linux/gzvm.h new file mode 100644 index 000000000000..c26c7720fab7 --- /dev/null +++ b/include/uapi/linux/gzvm.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +/* + * Copyright (c) 2023 MediaTek Inc. + */ + +/** + * DOC: UAPI of GenieZone Hypervisor + * + * This file declares common data structure shared among user space, + * kernel space, and GenieZone hypervisor. + */ +#ifndef __GZVM_H__ +#define __GZVM_H__ + +#include +#include +#include + +/* GZVM ioctls */ +#define GZVM_IOC_MAGIC 0x92 /* gz */ + +/* ioctls for /dev/gzvm fds */ +#define GZVM_CREATE_VM _IO(GZVM_IOC_MAGIC, 0x01) /* Returns a Geniezone VM fd */ + +#endif /* __GZVM_H__ */