Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp3562252imu; Mon, 17 Dec 2018 23:59:14 -0800 (PST) X-Google-Smtp-Source: AFSGD/VpD4Ec0CBCA4bM2PBMgLv1CyG83EI/OtDcKrE7OTsXB+Dk1HfFNOHOmLcld7Pz6hWZiJmm X-Received: by 2002:a62:34c6:: with SMTP id b189mr16154724pfa.229.1545119954306; Mon, 17 Dec 2018 23:59:14 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1545119954; cv=none; d=google.com; s=arc-20160816; b=Z9JzKizG/7M/mimTsTnIUUyEw8mQ+Qp8eySY3SXHH/zT5xU3DW6QcIQFz7+RZaPp4T OGWV/XTe+imoFv/npxoKAYcyR6fJJfvS4jLazFLlJhfEf+ywt0E5dKmI8SM74HpvqFCe F9/a1G3gngW+iunlUj+QMIMzu6nnLBvmKRYk5ouFlKIxOcr1igE+LDNiAjVfgUKMwf3n cLR/61MXTbOjyuK/XgQEmiCNRfOL8FqsgIToj0L8uT6LSHqDrnLhIioSz3U3j7PYnL7J U0Fz3m0lPO1yH1ZKsG3ddk9zwW0UU7ftpvm9rrk2iisIgFFzYGKrci/tm8Yq36vAVfEL ykDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=eQ7u43qB/eWwoyjuh6iFwsHRb3rgp/adhTZcBNg64Q0=; b=dO8m3yzpImryXgLJXkeKrpmJ4g+ZPCEoHdrDxJZVlniZMhh+J+TkFKZh059xRNhfaA K14SZqiQpie9CDZUY+LctCjYBsIursw+rPj00kghQBB0gjfRi+UWqyJCe2Ma8BwvBP5B DOhuZtyMV7S9kUsK4EzCvirAVmV1h5LXztW0aMnk1jwKelC0s+LANbwdqlnVjRzHDcDj 7TWBoZhNA67T06dvkhvk0qouEO4/31PXyuuHdg5SetDfxchSmBDcxDiOheE6ikMk6RVb wyej6dS7qc17pLfLpRQ2EFgZHp8+fPcsX6Q3jtdHpgXuWOib7XetG5E2QXLWE6a2QwYB 7RwQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id u69si13784411pfj.219.2018.12.17.23.58.58; Mon, 17 Dec 2018 23:59:14 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726743AbeLRH5m (ORCPT + 99 others); Tue, 18 Dec 2018 02:57:42 -0500 Received: from foss.arm.com ([217.140.101.70]:39806 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726368AbeLRH5l (ORCPT ); Tue, 18 Dec 2018 02:57:41 -0500 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9401B80D; Mon, 17 Dec 2018 23:57:40 -0800 (PST) Received: from a75553-lin.blr.arm.com (a75553-lin.blr.arm.com [10.162.0.175]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id BFACE3F575; Mon, 17 Dec 2018 23:57:36 -0800 (PST) From: Amit Daniel Kachhap To: linux-arm-kernel@lists.infradead.org Cc: Christoffer Dall , Marc Zyngier , Catalin Marinas , Will Deacon , Andrew Jones , Dave Martin , Ramana Radhakrishnan , kvmarm@lists.cs.columbia.edu, Kristina Martsenko , linux-kernel@vger.kernel.org, Amit Daniel Kachhap , Mark Rutland Subject: [PATCH v4 5/6] arm64/kvm: control accessibility of ptrauth key registers Date: Tue, 18 Dec 2018 13:26:49 +0530 Message-Id: <1545119810-12182-6-git-send-email-amit.kachhap@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1545119810-12182-1-git-send-email-amit.kachhap@arm.com> References: <1545119810-12182-1-git-send-email-amit.kachhap@arm.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org According to userspace settings, ptrauth key registers are conditionally present in guest system register list based on user specified flag KVM_ARM_VCPU_PTRAUTH. Signed-off-by: Amit Daniel Kachhap Cc: Mark Rutland Cc: Christoffer Dall Cc: Marc Zyngier Cc: kvmarm@lists.cs.columbia.edu --- Documentation/arm64/pointer-authentication.txt | 3 +- arch/arm64/kvm/sys_regs.c | 42 +++++++++++++++++++------- 2 files changed, 33 insertions(+), 12 deletions(-) diff --git a/Documentation/arm64/pointer-authentication.txt b/Documentation/arm64/pointer-authentication.txt index a65dca2..729055a 100644 --- a/Documentation/arm64/pointer-authentication.txt +++ b/Documentation/arm64/pointer-authentication.txt @@ -94,4 +94,5 @@ in KVM guests and attempted use of the feature will result in an UNDEFINED exception being injected into the guest. Additionally, when KVM_ARM_VCPU_PTRAUTH is not set then KVM will mask the -feature bits from ID_AA64ISAR1_EL1. +feature bits from ID_AA64ISAR1_EL1 and pointer authentication key registers +are hidden from userspace. diff --git a/arch/arm64/kvm/sys_regs.c b/arch/arm64/kvm/sys_regs.c index ce6144a..09302b2 100644 --- a/arch/arm64/kvm/sys_regs.c +++ b/arch/arm64/kvm/sys_regs.c @@ -1343,12 +1343,6 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_TTBR1_EL1), access_vm_reg, reset_unknown, TTBR1_EL1 }, { SYS_DESC(SYS_TCR_EL1), access_vm_reg, reset_val, TCR_EL1, 0 }, - PTRAUTH_KEY(APIA), - PTRAUTH_KEY(APIB), - PTRAUTH_KEY(APDA), - PTRAUTH_KEY(APDB), - PTRAUTH_KEY(APGA), - { SYS_DESC(SYS_AFSR0_EL1), access_vm_reg, reset_unknown, AFSR0_EL1 }, { SYS_DESC(SYS_AFSR1_EL1), access_vm_reg, reset_unknown, AFSR1_EL1 }, { SYS_DESC(SYS_ESR_EL1), access_vm_reg, reset_unknown, ESR_EL1 }, @@ -1500,6 +1494,14 @@ static const struct sys_reg_desc sys_reg_descs[] = { { SYS_DESC(SYS_FPEXC32_EL2), NULL, reset_val, FPEXC32_EL2, 0x70 }, }; +static const struct sys_reg_desc ptrauth_reg_descs[] = { + PTRAUTH_KEY(APIA), + PTRAUTH_KEY(APIB), + PTRAUTH_KEY(APDA), + PTRAUTH_KEY(APDB), + PTRAUTH_KEY(APGA), +}; + static bool trap_dbgidr(struct kvm_vcpu *vcpu, struct sys_reg_params *p, const struct sys_reg_desc *r) @@ -2100,6 +2102,8 @@ static int emulate_sys_reg(struct kvm_vcpu *vcpu, r = find_reg(params, table, num); if (!r) r = find_reg(params, sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); + if (!r && kvm_arm_vcpu_ptrauth_allowed(vcpu)) + r = find_reg(params, ptrauth_reg_descs, ARRAY_SIZE(ptrauth_reg_descs)); if (likely(r)) { perform_access(vcpu, params, r); @@ -2213,6 +2217,8 @@ static const struct sys_reg_desc *index_to_sys_reg_desc(struct kvm_vcpu *vcpu, r = find_reg_by_id(id, ¶ms, table, num); if (!r) r = find_reg(¶ms, sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); + if (!r && kvm_arm_vcpu_ptrauth_allowed(vcpu)) + r = find_reg(¶ms, ptrauth_reg_descs, ARRAY_SIZE(ptrauth_reg_descs)); /* Not saved in the sys_reg array and not otherwise accessible? */ if (r && !(r->reg || r->get_user)) @@ -2494,18 +2500,22 @@ static int walk_one_sys_reg(const struct sys_reg_desc *rd, } /* Assumed ordered tables, see kvm_sys_reg_table_init. */ -static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 __user *uind) +static int walk_sys_regs(struct kvm_vcpu *vcpu, u64 __user *uind, + const struct sys_reg_desc *desc, unsigned int len) { const struct sys_reg_desc *i1, *i2, *end1, *end2; unsigned int total = 0; size_t num; int err; + if (desc == ptrauth_reg_descs && !kvm_arm_vcpu_ptrauth_allowed(vcpu)) + return total; + /* We check for duplicates here, to allow arch-specific overrides. */ i1 = get_target_table(vcpu->arch.target, true, &num); end1 = i1 + num; - i2 = sys_reg_descs; - end2 = sys_reg_descs + ARRAY_SIZE(sys_reg_descs); + i2 = desc; + end2 = desc + len; BUG_ON(i1 == end1 || i2 == end2); @@ -2533,7 +2543,10 @@ unsigned long kvm_arm_num_sys_reg_descs(struct kvm_vcpu *vcpu) { return ARRAY_SIZE(invariant_sys_regs) + num_demux_regs() - + walk_sys_regs(vcpu, (u64 __user *)NULL); + + walk_sys_regs(vcpu, (u64 __user *)NULL, sys_reg_descs, + ARRAY_SIZE(sys_reg_descs)) + + walk_sys_regs(vcpu, (u64 __user *)NULL, ptrauth_reg_descs, + ARRAY_SIZE(ptrauth_reg_descs)); } int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) @@ -2548,7 +2561,12 @@ int kvm_arm_copy_sys_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) uindices++; } - err = walk_sys_regs(vcpu, uindices); + err = walk_sys_regs(vcpu, uindices, sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); + if (err < 0) + return err; + uindices += err; + + err = walk_sys_regs(vcpu, uindices, ptrauth_reg_descs, ARRAY_SIZE(ptrauth_reg_descs)); if (err < 0) return err; uindices += err; @@ -2582,6 +2600,7 @@ void kvm_sys_reg_table_init(void) BUG_ON(check_sysreg_table(cp15_regs, ARRAY_SIZE(cp15_regs))); BUG_ON(check_sysreg_table(cp15_64_regs, ARRAY_SIZE(cp15_64_regs))); BUG_ON(check_sysreg_table(invariant_sys_regs, ARRAY_SIZE(invariant_sys_regs))); + BUG_ON(check_sysreg_table(ptrauth_reg_descs, ARRAY_SIZE(ptrauth_reg_descs))); /* We abuse the reset function to overwrite the table itself. */ for (i = 0; i < ARRAY_SIZE(invariant_sys_regs); i++) @@ -2623,6 +2642,7 @@ void kvm_reset_sys_regs(struct kvm_vcpu *vcpu) /* Generic chip reset first (so target could override). */ reset_sys_reg_descs(vcpu, sys_reg_descs, ARRAY_SIZE(sys_reg_descs)); + reset_sys_reg_descs(vcpu, ptrauth_reg_descs, ARRAY_SIZE(ptrauth_reg_descs)); table = get_target_table(vcpu->arch.target, true, &num); reset_sys_reg_descs(vcpu, table, num); -- 2.7.4