Received: by 2002:ac0:a582:0:0:0:0:0 with SMTP id m2-v6csp499250imm; Wed, 17 Oct 2018 03:51:43 -0700 (PDT) X-Google-Smtp-Source: ACcGV61L7f/sMSuOISaK28HSb4j5UAphrl214SYcHyutv2s6JJK+BVjLdZLVIMRNHVZGHMcP+L9D X-Received: by 2002:a62:22c7:: with SMTP id p68-v6mr26080495pfj.53.1539773503815; Wed, 17 Oct 2018 03:51:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1539773503; cv=none; d=google.com; s=arc-20160816; b=yTSSPy5LC3pgqGFH2ihvTdJHoSHJ8vuE/HFHZudk+D5itnt9wEFm4WcjC/LebphSiV 5En/tel5mr93UVoD02EUy3N7JMUgsmm8XHO6jcM+9EJ7/P/S3YoO+9coUFoCoyHxuPv7 IjIYkQTYRBOBNbs4MoVR8GhxhkJt2b1YQ0Q001PAnAmjldeiLn3vYFivofeTwKYbn3Dd EEbw6vSjywnR3liAf6gzStS5pDZxpDk3adNwAp0+HfSUaSVw9HJ3/NRmG3YCu7DN5wdv wYKnLWKS51PKproLxRrVjBUhKUEytCq0i05/BryIwtwbCs1EM3tvwZAz4ofzwcSuLzse /Ogg== 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=XKGDiYF5qa9JldUTz9azhAGxU6eOx49hju//lwF5plo=; b=iKN0WqTOIHsuvrWHJbDLNOHYX0USwc0mSRvyEzITrOIeIbZS72o3hXF88h3J5aQgyU dRUq57KoHixLcFCuYYN7PB7ljMOj/mvjgo0dLKCeV4y4Q9gXkjX+cjzaCwTWAxWv1T3z wwRgR/lsIdUJMlvlmhwWWSSz/gpJ4xootU9DmnONs/bZsMi+57I78BQMVJbQTtbC7d+N ll4ZQyk9RjE4AJ4mJcMQi/uAf1lDxUl+psqcrfdwqqYcr8MJip3Lstw5+yH350RHJVt7 kqyDuqQMTJyregmh/Cp16G13ikOIBlqCP1K+zV88ZlUpqoa6aijZP/lRMGWxnA28JwNL mWtw== 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 j19-v6si17214790pfh.63.2018.10.17.03.51.28; Wed, 17 Oct 2018 03:51:43 -0700 (PDT) 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 S1727260AbeJQSoU (ORCPT + 99 others); Wed, 17 Oct 2018 14:44:20 -0400 Received: from foss.arm.com ([217.140.101.70]:49658 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726868AbeJQSoU (ORCPT ); Wed, 17 Oct 2018 14:44:20 -0400 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 AB1991596; Wed, 17 Oct 2018 03:49:12 -0700 (PDT) Received: from a75553-lin.blr.arm.com (unknown [10.162.0.175]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id E01993F71D; Wed, 17 Oct 2018 03:49:08 -0700 (PDT) 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 v3 5/7] arm64/kvm: control accessibility of ptrauth key registers Date: Wed, 17 Oct 2018 16:17:58 +0530 Message-Id: <1539773280-4159-6-git-send-email-amit.kachhap@arm.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1539773280-4159-1-git-send-email-amit.kachhap@arm.com> References: <1539773280-4159-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 --- arch/arm64/kvm/sys_regs.c | 42 +++++++++++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 11 deletions(-) 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