From mboxrd@z Thu Jan 1 00:00:00 1970 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 3320FEE49A5 for ; Mon, 21 Aug 2023 21:23:23 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:From:Subject:Message-ID: References:Mime-Version:In-Reply-To:Date:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=kkQAbO8rroYAl5mQdwnOdz/XzP06PDv3H+jLhwppNWQ=; b=ADT9j1U3R22xgDeCC1yk2greiJ WejVVjAUyByXTEMaviHhpOH9xMIObqz4vi1anca1qtoQoJb+QCnXXiVNIarCY3yNOvI1p4sqiPRnw bLT01hyen/DmM6PAO3pIL+STOCy/uRHY9yIbsdsgAiHbcguBtI0PZ3ecN2cnctwy8rn+coYiex9yd flzMnHkTTUQkFl6H4lvcRFnnX7tmAbMrC8eec6VfgGSDs9DnADMUvwy/2wizyDPNRhWY/COSIudQ1 LpDlzPsM+OfI7HxVh2kPtw5xCu5ZOnE6lH1gIxrFsEaJpxFgggGnfCNnmzmOVo49OIp1/x0tNKEvh fPkc7Qdw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qYCMU-00EiG7-1r; Mon, 21 Aug 2023 21:22:58 +0000 Received: from mail-pf1-x44a.google.com ([2607:f8b0:4864:20::44a]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qYCMM-00EiCy-2p for linux-arm-kernel@lists.infradead.org; Mon, 21 Aug 2023 21:22:52 +0000 Received: by mail-pf1-x44a.google.com with SMTP id d2e1a72fcca58-68a4075f42fso2016952b3a.3 for ; Mon, 21 Aug 2023 14:22:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1692652969; x=1693257769; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=2B7Qy6Kw5j/nTo/++b4jHC7ZtOMGC89Nxbhsckocxfk=; b=bJhawE4Uhw56ASBDjFYeOUlLqMZlQeCKQIJ7UYtdJOCDTJd68Ir9e9VfvRLfnTgX6H VLShYlvLVCw1aq4fZu3uTxVWGWpQhT/H9tK0L0FX9+6SuZTdn35543bhQtizWC3xXzyd lBqn+TNEyxr4YAHP5PGaYKvUst+Thd0/VOBSPWvgl6XyTD8ud+pwSCb2MjENzFhN3CJ9 ualZc/+6TGm2R3NBNYPsvpxrEVvndkOhqWQvdYkuBQg9zr9y9CkoAgM4XrEFzYCK+tTA q5zeXbOCB2GKlHamZFmpTdLZYyDFc8BGf9uRieUSWHRr+Bs5X9HJyAjNacuj2q3hbGpD LFWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692652969; x=1693257769; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=2B7Qy6Kw5j/nTo/++b4jHC7ZtOMGC89Nxbhsckocxfk=; b=DVKcIbe0zQ//G0fYWLmdtUMp1jxju5zgLoJS7f068gmhtw5ycTWs4EfByy9z8S8w2m A5VuGYmAscT+JaymdFTmnOKdmMQpSk/pWKoaDB6OLyICZdNngFaLw7WQsAJ3hZ39aRXV 7KsMXw9qApggGv8AphQ+0GSM+3jgYFgtgOTvMlKiT8dpGbJQeQB1zITxnFNEai84dY+Z hvaWN1IpMXX93zIbdNZJY7OuNkaB9SyXu8NrDX3jQzXVaLx5IfwD2zrP+J/paAL+f9Vp NRAJU1gHm9s2tdxcbdf3HhyYBEHCtb+2sdWnLIeWPxc3rVvv4WxPTVa8gB3ZfcSQmLLJ tVVg== X-Gm-Message-State: AOJu0Yw5a6cJOK4IgkWRZ/AJ56i4z35LB1U6wHWzGcnZgdVUhynSLUqS dIYdJOeBEmoQVvB9JPStUCa5ND66kmTG6yYNMw== X-Google-Smtp-Source: AGHT+IFSEGdu2t4zwctottOZyfhvKMdc+9pCmvEQUmekmWTsy2kBSMFlsqmqWUe4mc3/Ykgfegb5kfjn1Y36WAIpIw== X-Received: from jgzg.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:1acf]) (user=jingzhangos job=sendgmr) by 2002:a05:6a00:2d87:b0:67e:86c0:6bd3 with SMTP id fb7-20020a056a002d8700b0067e86c06bd3mr4675455pfb.1.1692652968987; Mon, 21 Aug 2023 14:22:48 -0700 (PDT) Date: Mon, 21 Aug 2023 14:22:33 -0700 In-Reply-To: <20230821212243.491660-1-jingzhangos@google.com> Mime-Version: 1.0 References: <20230821212243.491660-1-jingzhangos@google.com> X-Mailer: git-send-email 2.42.0.rc1.204.g551eb34607-goog Message-ID: <20230821212243.491660-2-jingzhangos@google.com> Subject: [PATCH v9 01/11] KVM: arm64: Allow userspace to get the writable masks for feature ID registers From: Jing Zhang To: KVM , KVMARM , ARMLinux , Marc Zyngier , Oliver Upton Cc: Will Deacon , Paolo Bonzini , James Morse , Alexandru Elisei , Suzuki K Poulose , Fuad Tabba , Reiji Watanabe , Raghavendra Rao Ananta , Suraj Jitindar Singh , Cornelia Huck , Shaoqin Huang , Jing Zhang X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230821_142250_913375_02E88C9D X-CRM114-Status: GOOD ( 23.37 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Add a VM ioctl to allow userspace to get writable masks for feature ID registers in below system register space: op0 = 3, op1 = {0, 1, 3}, CRn = 0, CRm = {0 - 7}, op2 = {0 - 7} This is used to support mix-and-match userspace and kernels for writable ID registers, where userspace may want to know upfront whether it can actually tweak the contents of an idreg or not. Suggested-by: Marc Zyngier Suggested-by: Cornelia Huck Signed-off-by: Jing Zhang --- arch/arm64/include/asm/kvm_host.h | 2 ++ arch/arm64/include/uapi/asm/kvm.h | 26 ++++++++++++++ arch/arm64/kvm/arm.c | 7 ++++ arch/arm64/kvm/sys_regs.c | 57 +++++++++++++++++++++++++++++++ include/uapi/linux/kvm.h | 1 + 5 files changed, 93 insertions(+) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h index d3dd05bbfe23..a328d362df5a 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -1074,6 +1074,8 @@ int kvm_vm_ioctl_mte_copy_tags(struct kvm *kvm, struct kvm_arm_copy_mte_tags *copy_tags); int kvm_vm_ioctl_set_counter_offset(struct kvm *kvm, struct kvm_arm_counter_offset *offset); +int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, + struct reg_mask_range *range); /* Guest/host FPSIMD coordination helpers */ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu); diff --git a/arch/arm64/include/uapi/asm/kvm.h b/arch/arm64/include/uapi/asm/kvm.h index f7ddd73a8c0f..7a21bbb8a0f7 100644 --- a/arch/arm64/include/uapi/asm/kvm.h +++ b/arch/arm64/include/uapi/asm/kvm.h @@ -505,6 +505,32 @@ struct kvm_smccc_filter { #define KVM_HYPERCALL_EXIT_SMC (1U << 0) #define KVM_HYPERCALL_EXIT_16BIT (1U << 1) +/* Get feature ID registers userspace writable mask. */ +/* + * From DDI0487J.a, D19.2.66 ("ID_AA64MMFR2_EL1, AArch64 Memory Model + * Feature Register 2"): + * + * "The Feature ID space is defined as the System register space in + * AArch64 with op0==3, op1=={0, 1, 3}, CRn==0, CRm=={0-7}, + * op2=={0-7}." + * + * This covers all R/O registers that indicate anything useful feature + * wise, including the ID registers. + */ +#define ARM64_FEATURE_ID_SPACE_IDX(op0, op1, crn, crm, op2) \ + ({ \ + __u64 __op1 = (op1) & 3; \ + __op1 -= (__op1 == 3); \ + (__op1 << 6 | ((crm) & 7) << 3 | (op2)); \ + }) + +#define ARM64_FEATURE_ID_SPACE_SIZE (3 * 8 * 8) + +struct reg_mask_range { + __u64 addr; /* Pointer to mask array */ + __u64 reserved[7]; +}; + #endif #endif /* __ARM_KVM_H__ */ diff --git a/arch/arm64/kvm/arm.c b/arch/arm64/kvm/arm.c index d1cb298a58a0..cfb5e9ef43c4 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -1630,6 +1630,13 @@ int kvm_arch_vm_ioctl(struct file *filp, unsigned int ioctl, unsigned long arg) return kvm_vm_set_attr(kvm, &attr); } + case KVM_ARM_GET_REG_WRITABLE_MASKS: { + struct reg_mask_range range; + + if (copy_from_user(&range, argp, sizeof(range))) + return -EFAULT; + return kvm_vm_ioctl_get_reg_writable_masks(kvm, &range); + } default: return -EINVAL; } diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index 2ca2973abe66..216905840c92 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -3560,6 +3560,63 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) return write_demux_regids(uindices); } +#define ARM64_FEATURE_ID_SPACE_INDEX(r) \ + ARM64_FEATURE_ID_SPACE_IDX(sys_reg_Op0(r), \ + sys_reg_Op1(r), \ + sys_reg_CRn(r), \ + sys_reg_CRm(r), \ + sys_reg_Op2(r)) + +static bool is_feature_id_reg(u32 encoding) +{ + return (sys_reg_Op0(encoding) == 3 && + (sys_reg_Op1(encoding) < 2 || sys_reg_Op1(encoding) == 3) && + sys_reg_CRn(encoding) == 0 && + sys_reg_CRm(encoding) <= 7); +} + +int kvm_vm_ioctl_get_reg_writable_masks(struct kvm *kvm, struct reg_mask_range *range) +{ + const void *zero_page = page_to_virt(ZERO_PAGE(0)); + u64 __user *masks = (u64 __user *)range->addr; + + /* Only feature id range is supported, reserved[7] must be zero. */ + if (memcmp(range->reserved, zero_page, sizeof(range->reserved))) + return -EINVAL; + + /* Wipe the whole thing first */ + if (clear_user(masks, ARM64_FEATURE_ID_SPACE_SIZE * sizeof(__u64))) + return -EFAULT; + + for (int i = 0; i < ARRAY_SIZE(sys_reg_descs); i++) { + const struct sys_reg_desc *reg = &sys_reg_descs[i]; + u32 encoding = reg_to_encoding(reg); + u64 val; + + if (!is_feature_id_reg(encoding) || !reg->set_user) + continue; + + /* + * For ID registers, we return the writable mask. Other feature + * registers return a full 64bit mask. That's not necessary + * compliant with a given revision of the architecture, but the + * RES0/RES1 definitions allow us to do that. + */ + if (is_id_reg(encoding)) { + if (!reg->val) + continue; + val = reg->val; + } else { + val = ~0UL; + } + + if (put_user(val, (masks + ARM64_FEATURE_ID_SPACE_INDEX(encoding)))) + return -EFAULT; + } + + return 0; +} + int __init kvm_sys_reg_table_init(void) { struct sys_reg_params params; diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index f089ab290978..424b6d00440b 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -1555,6 +1555,7 @@ struct kvm_s390_ucas_mapping { #define KVM_ARM_MTE_COPY_TAGS _IOR(KVMIO, 0xb4, struct kvm_arm_copy_mte_tags) /* Available with KVM_CAP_COUNTER_OFFSET */ #define KVM_ARM_SET_COUNTER_OFFSET _IOW(KVMIO, 0xb5, struct kvm_arm_counter_offset) +#define KVM_ARM_GET_REG_WRITABLE_MASKS _IOR(KVMIO, 0xb6, struct reg_mask_range) /* ioctl for vm fd */ #define KVM_CREATE_DEVICE _IOWR(KVMIO, 0xe0, struct kvm_create_device) -- 2.42.0.rc1.204.g551eb34607-goog _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel