Received: by 2002:a05:6a10:206:0:0:0:0 with SMTP id 6csp384117pxj; Fri, 7 May 2021 10:40:10 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxA/duOx1zw/MvPog0B2ZLb9dB6TwvHwcjm7Whu/2VVW5gXoaonP8bDTrVCwWTiW4NTVY3a X-Received: by 2002:aa7:d915:: with SMTP id a21mr13206939edr.357.1620409210735; Fri, 07 May 2021 10:40:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1620409210; cv=none; d=google.com; s=arc-20160816; b=jNhMU2dWUy/4NZqUWlOsyux0GdEkWsXH4Xbyf4F0I7OapczfTmwevrBCsgaEKYt4QA oh3rRYhJ2ZRLjmbAzHZCfkYY2KUDFNvB69HrP7fTVO+SoRTAyp3HwAi2IC4pL8in81Mx LLBePKmkEEcb4KZorkccHFlCBXn7eiyesNOIrH4ubwpOXZTUrH6sdhgEYbJo3K0qqOiu JMgk7lzhDtTGx08bm6CKJMhAPV/5MsJBAZlmqFYRenvIBEZudV78WOziyw5qNHDi8/P6 V/m0zN2P52SxuipciK0TyS1NqMea2j3YxjALfvKjdBxAa97S1EYej2wZ2mllIUD8yyDC CNhQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:references:mime-version :message-id:in-reply-to:date:reply-to:dkim-signature; bh=nXbsQzZRKADxmz3jPQyGk2mwipulmK8ydHFPEpTQQXY=; b=TBbQ/5+AYaJsVRLUvwPOewlyf7nv9r8E9weojuxFXR2rnAvWqaP+aPR9vx0CLXPz4E QbSzAUuuSxlwngBGTGvq3Rpy46Vd3OFAx0Brer1eEJ96hCuzrEcplnHuzwnFApSz/Jzh UXkukSuOSeT2zSOn1pzCrszsQvpPU6X+G9lyefF5Y3i5bt88If9ziHCna/XLyS+OEHar kmmcynK1pFI1O7jMccSpqrmqlvvEgharCY3G0fWoVHAeQ+W3Uym0hwBimKT0hAW3ltSI s9OVzignl2k5szgCJIyugPfCTjInZAUznblD5n31PBoh4A4/yoxnIsi/usxON9sPCRNQ 4ikw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=cZAvPBhN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id n17si5473387ejj.409.2021.05.07.10.39.47; Fri, 07 May 2021 10:40:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20161025 header.b=cZAvPBhN; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238480AbhEGRBC (ORCPT + 99 others); Fri, 7 May 2021 13:01:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33642 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S238462AbhEGRA7 (ORCPT ); Fri, 7 May 2021 13:00:59 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 89457C06138A for ; Fri, 7 May 2021 09:59:58 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id a3-20020a2580430000b02904f7a1a09012so10744898ybn.3 for ; Fri, 07 May 2021 09:59:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=reply-to:date:in-reply-to:message-id:mime-version:references :subject:from:to:cc; bh=nXbsQzZRKADxmz3jPQyGk2mwipulmK8ydHFPEpTQQXY=; b=cZAvPBhNqujbaGxJlK4D8mIW+Swf1BC4L7PwZB3GQ7JVWWxdeAIL3qOpHbD1N7+IDP tlcRAsw/mMjLviNrHz0tBXTi1JaNLfNk8c+7bk9+0nD6VUhcdBo88t7lHPuldYqc+OP0 U17N9Sf8vPB2ez0F3tKHgHTGKEuCK5D6KPo26i3BaiXYrC9bKDjH76kSLoXyWhJOB5BR Y0vh1d9xhzxQLAnuh6E9lnuowGCPTtBhYd5K7Nbu7a10Nq8InGHZVUwUzrTcxak9TjPW YCa1Cy35GJsLR09nU0UHI+GD9Vf3JnTOxzrSetvQ3vn0dWxX03VZvc2vsqlz2az75D6r LERw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:reply-to:date:in-reply-to:message-id :mime-version:references:subject:from:to:cc; bh=nXbsQzZRKADxmz3jPQyGk2mwipulmK8ydHFPEpTQQXY=; b=RsEKU0ehBvPj3maXx6s8RnIhxgPSBeqEyzFbO/KJCYWlhDcomuoGwaWe7Pbxl5xdfp IOBXCWU2INnO8288IkTjJN3D19P8w+c4i6UGZK/jGMIPQIHQmvVvONLgW+qiYUDNYbJJ Wmh3EzttRDNDTC8LW45VjRiJFfhm379k9mW9fXLFgRDt2JQBxnrkt5N8w/L48PtRZaQW w6flW5c6dLCE5PuNubPAtyi/opilh8Q5N4joNJVYvhe+K7c3nL8GDfJKtHqtEjUN/LgN HmJV9Q0O4Od+Z2BN27digM9hOW0ibJhfTBs8z7mXPEQkUSPE5qH2gTsKPoioWQJKG3wF Dn7Q== X-Gm-Message-State: AOAM531HJsxXKH2Yj2nEVRt3lB5UBRhyPWgUcx+Ogu+f6BXgOeMqfUIv fl72fMDqXSJx1+PyT96qKgyWZ174rnA= X-Received: from seanjc798194.pdx.corp.google.com ([2620:15c:f:10:7352:5279:7518:418f]) (user=seanjc job=sendgmr) by 2002:a25:30d5:: with SMTP id w204mr14454275ybw.416.1620406797719; Fri, 07 May 2021 09:59:57 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 7 May 2021 09:59:47 -0700 In-Reply-To: <20210507165947.2502412-1-seanjc@google.com> Message-Id: <20210507165947.2502412-3-seanjc@google.com> Mime-Version: 1.0 References: <20210507165947.2502412-1-seanjc@google.com> X-Mailer: git-send-email 2.31.1.607.g51e8a6a459-goog Subject: [PATCH 2/2] KVM: x86: Allow userspace to update tracked sregs for protected guests From: Sean Christopherson To: Paolo Bonzini Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Peter Gonda , Maxim Levitsky Content-Type: text/plain; charset="UTF-8" Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Allow userspace to set CR0, CR4, CR8, and EFER via KVM_SET_SREGS for protected guests, e.g. for SEV-ES guests with an encrypted VMSA. KVM tracks the aforementioned registers by trapping guest writes, and also exposes the values to userspace via KVM_GET_SREGS. Skipping the regs in KVM_SET_SREGS prevents userspace from updating KVM's CPU model to match the known hardware state. Fixes: 5265713a0737 ("KVM: x86: Update __get_sregs() / __set_sregs() to support SEV-ES") Reported-by: Peter Gonda Cc: stable@vger.kernel.org Cc: Maxim Levitsky Signed-off-by: Sean Christopherson --- arch/x86/kvm/x86.c | 73 ++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 3bf52ba5f2bb..1b7d0e97c82b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -9963,21 +9963,25 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) if (kvm_set_apic_base(vcpu, &apic_base_msr)) goto out; - if (vcpu->arch.guest_state_protected) - goto skip_protected_regs; + if (!vcpu->arch.guest_state_protected) { + dt.size = sregs->idt.limit; + dt.address = sregs->idt.base; + static_call(kvm_x86_set_idt)(vcpu, &dt); + dt.size = sregs->gdt.limit; + dt.address = sregs->gdt.base; + static_call(kvm_x86_set_gdt)(vcpu, &dt); - dt.size = sregs->idt.limit; - dt.address = sregs->idt.base; - static_call(kvm_x86_set_idt)(vcpu, &dt); - dt.size = sregs->gdt.limit; - dt.address = sregs->gdt.base; - static_call(kvm_x86_set_gdt)(vcpu, &dt); - - vcpu->arch.cr2 = sregs->cr2; - mmu_reset_needed |= kvm_read_cr3(vcpu) != sregs->cr3; - vcpu->arch.cr3 = sregs->cr3; - kvm_register_mark_available(vcpu, VCPU_EXREG_CR3); + vcpu->arch.cr2 = sregs->cr2; + mmu_reset_needed |= kvm_read_cr3(vcpu) != sregs->cr3; + vcpu->arch.cr3 = sregs->cr3; + kvm_register_mark_available(vcpu, VCPU_EXREG_CR3); + } + /* + * Writes to CR0, CR4, CR8, and EFER are trapped (after the instruction + * completes) for SEV-EV guests, thus userspace is allowed to set them + * so that KVM's model can be updated to mirror hardware state. + */ kvm_set_cr8(vcpu, sregs->cr8); mmu_reset_needed |= vcpu->arch.efer != sregs->efer; @@ -9990,35 +9994,42 @@ static int __set_sregs(struct kvm_vcpu *vcpu, struct kvm_sregs *sregs) mmu_reset_needed |= kvm_read_cr4(vcpu) != sregs->cr4; static_call(kvm_x86_set_cr4)(vcpu, sregs->cr4); - idx = srcu_read_lock(&vcpu->kvm->srcu); - if (is_pae_paging(vcpu)) { + /* + * PDPTEs, like regular PTEs, are always encrypted, thus reading them + * will return garbage. Shadow paging, including nested NPT, isn't + * compatible with protected guests, so ignoring the PDPTEs is a-ok. + */ + if (!vcpu->arch.guest_state_protected && is_pae_paging(vcpu)) { + idx = srcu_read_lock(&vcpu->kvm->srcu); load_pdptrs(vcpu, vcpu->arch.walk_mmu, kvm_read_cr3(vcpu)); + srcu_read_unlock(&vcpu->kvm->srcu, idx); + mmu_reset_needed = 1; } - srcu_read_unlock(&vcpu->kvm->srcu, idx); if (mmu_reset_needed) kvm_mmu_reset_context(vcpu); - kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); - kvm_set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); - kvm_set_segment(vcpu, &sregs->es, VCPU_SREG_ES); - kvm_set_segment(vcpu, &sregs->fs, VCPU_SREG_FS); - kvm_set_segment(vcpu, &sregs->gs, VCPU_SREG_GS); - kvm_set_segment(vcpu, &sregs->ss, VCPU_SREG_SS); + if (!vcpu->arch.guest_state_protected) { + kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS); + kvm_set_segment(vcpu, &sregs->ds, VCPU_SREG_DS); + kvm_set_segment(vcpu, &sregs->es, VCPU_SREG_ES); + kvm_set_segment(vcpu, &sregs->fs, VCPU_SREG_FS); + kvm_set_segment(vcpu, &sregs->gs, VCPU_SREG_GS); + kvm_set_segment(vcpu, &sregs->ss, VCPU_SREG_SS); - kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); - kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); + kvm_set_segment(vcpu, &sregs->tr, VCPU_SREG_TR); + kvm_set_segment(vcpu, &sregs->ldt, VCPU_SREG_LDTR); - update_cr8_intercept(vcpu); + update_cr8_intercept(vcpu); - /* Older userspace won't unhalt the vcpu on reset. */ - if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 && - sregs->cs.selector == 0xf000 && sregs->cs.base == 0xffff0000 && - !is_protmode(vcpu)) - vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; + /* Older userspace won't unhalt the vcpu on reset. */ + if (kvm_vcpu_is_bsp(vcpu) && kvm_rip_read(vcpu) == 0xfff0 && + sregs->cs.selector == 0xf000 && + sregs->cs.base == 0xffff0000 && !is_protmode(vcpu)) + vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; + } -skip_protected_regs: max_bits = KVM_NR_INTERRUPTS; pending_vec = find_first_bit( (const unsigned long *)sregs->interrupt_bitmap, max_bits); -- 2.31.1.607.g51e8a6a459-goog