Received: by 2002:ac0:946b:0:0:0:0:0 with SMTP id j40csp788417imj; Fri, 15 Feb 2019 06:51:48 -0800 (PST) X-Google-Smtp-Source: AHgI3IYt1tGIDCNlPYIvCNxM4xlLjhNUhaMed67+KIbPbdOL2WfWG5rL1KCXlM6XC/ndHp5/EYYj X-Received: by 2002:a17:902:8697:: with SMTP id g23mr1239496plo.30.1550242308579; Fri, 15 Feb 2019 06:51:48 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550242308; cv=none; d=google.com; s=arc-20160816; b=x917T6bdBCZ45lB336etq975zUjyskHNci8DfauKsA89Nf+QqKRwZpv00bLCPFjcKo PM0lsgs1IQqHvBHuFU9i/eo9fzgpsN+TfJjqBV/frFUJZYhbXBHmDoTU5PCRKcYvnuLR /qwKqj9qWmuWIxusaUp9/ZqYQ4cLZwBVncQDR3f3rRQzLPMi0h6n+lvltDEvObgkem+1 E1pOGWHzLIeaB7Zu3lpunEsS9FXiC++kqyCHE7yby6uEF96A/2BSnzG+Qd8XQs6oxOF+ nJ9SkOoNBPJpNQ3jj+GZY/b7NrweIhmdOXA26AB+vNj7PeMAvZ1F7eSEHP5XDLWANxV3 bLlw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=PIhCInLYkKfopLNTLqTqlYAD8zSX8J/apxh2X1ISq4E=; b=mJvz7RW7OCL5INNoOhNB/85q9Tql4rrCzzOxSJA4KxtaPJ/m8K5p91kTtCxUX1JDwj D1WITnKG1ifTwC+zlqy1cXJUsqMitjq8O2/t2D09CNvjMGUILp8uh29UwQCy8eSfUEbH avN+jwFZ5hCJJJIPEMNSI3dXvJZ7nfNLuTvOLinTj59EFcF9XAtDs95efvj+nqfzvX8d ScvVYL3WCZGF4dF2+UyjogvMmDm1R1H931OXAafkve4OJhvD/Bf/AYkn2SLWlCTgTIcV Fqepd4jr6CMmgKiWupO+/z+X0yy7vfbfagScuJQ/znbv2XCloL1vu6eO5dgvbMTAyHmD YAGA== 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 b61si6090409plb.70.2019.02.15.06.51.31; Fri, 15 Feb 2019 06:51:48 -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 S1730315AbfBOEAh (ORCPT + 99 others); Thu, 14 Feb 2019 23:00:37 -0500 Received: from foss.arm.com ([217.140.101.70]:54424 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726192AbfBOEAh (ORCPT ); Thu, 14 Feb 2019 23:00:37 -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 47382A78; Thu, 14 Feb 2019 20:00:36 -0800 (PST) Received: from [10.162.0.144] (a075553-lin.blr.arm.com [10.162.0.144]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 72D183F557; Thu, 14 Feb 2019 20:00:33 -0800 (PST) Subject: Re: [PATCH v5 3/5] arm64/kvm: context-switch ptrauth register To: Kristina Martsenko , James Morse Cc: linux-arm-kernel@lists.infradead.org, Marc Zyngier , Catalin Marinas , Will Deacon , kvmarm@lists.cs.columbia.edu, Ramana Radhakrishnan , Dave Martin , linux-kernel@vger.kernel.org References: <1548658727-14271-1-git-send-email-amit.kachhap@arm.com> <1548658727-14271-4-git-send-email-amit.kachhap@arm.com> <9d4b5ac7-9d89-b6a0-cfa2-4eab81ff157a@arm.com> From: Amit Daniel Kachhap Message-ID: <7a7f0b78-19b6-3953-fdce-4d173b2d69b9@arm.com> Date: Fri, 15 Feb 2019 09:30:30 +0530 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.4.0 MIME-Version: 1.0 In-Reply-To: <9d4b5ac7-9d89-b6a0-cfa2-4eab81ff157a@arm.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On 2/13/19 11:05 PM, Kristina Martsenko wrote: > On 31/01/2019 16:25, James Morse wrote: >> Hi Amit, >> >> On 28/01/2019 06:58, Amit Daniel Kachhap wrote: >>> When pointer authentication is supported, a guest may wish to use it. >>> This patch adds the necessary KVM infrastructure for this to work, with >>> a semi-lazy context switch of the pointer auth state. > > [...] > >>> +void __no_ptrauth __hyp_text __ptrauth_switch_to_guest(struct kvm_vcpu *vcpu, >>> + struct kvm_cpu_context *host_ctxt, >>> + struct kvm_cpu_context *guest_ctxt) >>> +{ >>> + if (!__ptrauth_is_enabled(vcpu)) >>> + return; >>> + >> >>> + ptrauth_keys_store((struct ptrauth_keys *) &host_ctxt->sys_regs[APIAKEYLO_EL1]); >> >> We can't cast part of an array to a structure like this. What happens if the >> compiler inserts padding in struct-ptrauth_keys, or the struct randomization >> thing gets hold of it: https://lwn.net/Articles/722293/ >> >> If we want to use the helpers that take a struct-ptrauth_keys, we need to keep >> the keys in a struct-ptrauth_keys. To do this we'd need to provide accessors so >> that GET_ONE_REG() of APIAKEYLO_EL1 comes from the struct-ptrauth_keys, instead >> of the sys_reg array. > > If I've understood correctly, the idea is to have a struct ptrauth_keys > in struct kvm_vcpu_arch, instead of having the keys in the > kvm_cpu_context->sys_regs array. This is to avoid having similar code in > __ptrauth_key_install/ptrauth_keys_switch and > __ptrauth_restore_key/__ptrauth_restore_state, and so that future > patches (that add pointer auth in the kernel) would only need to update > one place instead of two. Yes your observation is correct. > > But it also means we'll have to special case pointer auth in > kvm_arm_sys_reg_set_reg/kvm_arm_sys_reg_get_reg and kvm_vcpu_arch. Is it > worth it? I'd prefer to keep the slight code duplication but avoid the > special casing. In my local implementation I implemented above by separating ptrauth registers from sys registers but if I use the new way suggested by Dave [1] then those things are not possible as reg ID is used for matching entries. So I will stick to the single sys_reg list for next iteration using [1]. [1]: https://lore.kernel.org/linux-arm-kernel/1547757219-19439-11-git-send-email-Dave.Martin@arm.com/ > >> >> >> Wouldn't the host keys be available somewhere else? (they must get transfer to >> secondary CPUs somehow). Can we skip the save step when switching from the host? >> >> >>> + ptrauth_keys_switch((struct ptrauth_keys *) &guest_ctxt->sys_regs[APIAKEYLO_EL1]); >>> +} >> > > [...] > >> >>> diff --git a/arch/arm64/kvm/hyp/switch.c b/arch/arm64/kvm/hyp/switch.c >>> index 03b36f1..301d332 100644 >>> --- a/arch/arm64/kvm/hyp/switch.c >>> +++ b/arch/arm64/kvm/hyp/switch.c >>> @@ -483,6 +483,8 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) >>> sysreg_restore_guest_state_vhe(guest_ctxt); >>> __debug_switch_to_guest(vcpu); >>> >>> + __ptrauth_switch_to_guest(vcpu, host_ctxt, guest_ctxt); >>> + >>> __set_guest_arch_workaround_state(vcpu); >>> >>> do { >>> @@ -494,6 +496,8 @@ int kvm_vcpu_run_vhe(struct kvm_vcpu *vcpu) >>> >>> __set_host_arch_workaround_state(vcpu); >>> >>> + __ptrauth_switch_to_host(vcpu, host_ctxt, guest_ctxt); >>> + >>> sysreg_save_guest_state_vhe(guest_ctxt); >>> >>> __deactivate_traps(vcpu); >> >> ...This makes me nervous... >> >> __guest_enter() is a function that (might) change the keys, then we change them >> again here. We can't have any signed return address between these two points. I >> don't trust the compiler not to generate any. >> >> ~ >> >> I had a chat with some friendly compiler folk... because there are two identical >> sequences in kvm_vcpu_run_vhe() and __kvm_vcpu_run_nvhe(), the compiler could >> move the common code to a function it then calls. Apparently this is called >> 'function outlining'. >> >> If the compiler does this, and the guest changes the keys, I think we would fail >> the return address check. >> >> Painting the whole thing with no_prauth would solve this, but this code then >> becomes a target. >> Because the compiler can't anticipate the keys changing, we ought to treat them >> the same way we do the callee saved registers, stack-pointer etc, and >> save/restore them in the __guest_enter() assembly code. >> >> (we can still keep the save/restore in C, but call it from assembly so we know >> nothing new is going on the stack). > > I agree that this should be called from assembly if we were building the > kernel with pointer auth. But as we are not doing that yet in this > series, can't we keep the calls in kvm_vcpu_run_vhe for now? Well if we keep them in kvm_vcpu_run_vhe then there is not much issue also in calling those C functions from assembly guest_enter/guest_exit. It works fine in my local implementation. This will also save code churning again when kernel ptrauth support is added. The only extra change required to be done is to assign attribute _noptrauth to those functions. I will add these comments properly in function description. > > In general I would prefer if the keys were switched in > kvm_arch_vcpu_load/put for now, since the keys are currently only used > in userspace. Once in-kernel pointer auth support comes along, it can > move the switch into kvm_vcpu_run_vhe or __guest_enter/__guest_exit as > required. Yes it is possible but then there are other benefits in doing this way. It will be always ptrauth registers save/restore if inside kvm_arch_vcpu_load/put even if userspace does not use it. The current way does save/restore dynamically when userspace uses ptrauth instructions by trapping first time. Some discussion happened on it earlier between Mark and Cristopher and they seem to agree on it [2]. [2]: https://lore.kernel.org/lkml/20180409125818.GE10904@cbox/ Thanks, Amit D > > Thanks, > Kristina >