From patchwork Tue May 13 14:55:41 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 4168421 Return-Path: X-Original-To: patchwork-kvm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4EED7BFF02 for ; Tue, 13 May 2014 14:56:51 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6DAEB20127 for ; Tue, 13 May 2014 14:56:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 75252200ED for ; Tue, 13 May 2014 14:56:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964924AbaEMO4q (ORCPT ); Tue, 13 May 2014 10:56:46 -0400 Received: from mail-ee0-f45.google.com ([74.125.83.45]:42133 "EHLO mail-ee0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S964874AbaEMO4C (ORCPT ); Tue, 13 May 2014 10:56:02 -0400 Received: by mail-ee0-f45.google.com with SMTP id d49so513818eek.4 for ; Tue, 13 May 2014 07:56:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references; bh=mP1tdquPxq2nr6ErvBfstE2Dus3QN3yrro2K3nGM71M=; b=KqHIUbwQIaV77e+0qg/ao4fK3evRXhrTtPJnHzCVVLNHSAPbeOxztrLQYmCFVwDtJI J87+Qsvw/zTdypnJ9CXu7JF36Jcg+c0/0embeeFVRiHXQaqxOYTWbFnPgUFqZpSA5sU8 WJ/RjyZvmLFRzwtQGDlHwORw9UiTMWSI3l4PZsEyUpUvCTcoTlR10RCSVhTt7Y2RjJjJ O6pYUeKJpsycxX8Cfz+lb1gX2h6Ax8JdmCGi/NG/UultWLXvUvjXBFJvKDz77q/q4FBT z7f1BeF9CzsUzkXfPw/DApiASBS2Wpc+j9uGr4FgHITb+wr2g8WrT43/3sWlYkIxM+OS 0bNA== X-Received: by 10.14.202.134 with SMTP id d6mr3894389eeo.92.1399992960912; Tue, 13 May 2014 07:56:00 -0700 (PDT) Received: from playground.station (net-37-117-141-58.cust.vodafonedsl.it. [37.117.141.58]) by mx.google.com with ESMTPSA id l3sm40720216eeo.43.2014.05.13.07.55.59 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 13 May 2014 07:56:00 -0700 (PDT) From: Paolo Bonzini To: linux-kernel@vger.kernel.org Cc: jan.kiszka@siemens.com, kvm@vger.kernel.org, gleb@kernel.org, avi.kivity@gmail.com Subject: [PATCH 5/5] KVM: x86: add capability to get/set CPL Date: Tue, 13 May 2014 16:55:41 +0200 Message-Id: <1399992941-11600-6-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1399992941-11600-1-git-send-email-pbonzini@redhat.com> References: <1399992941-11600-1-git-send-email-pbonzini@redhat.com> Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Until now, KVM used to assume that CS.RPL could always be used as the CPL value when KVM_SET_SREGS is called. Unfortunately this is not the case. If userspace decides to call KVM_GET_SREGS/KVM_SET_SREGS exactly after CR0.PE has been set to 1, but before the long jump that reloads CS, the CPL will be reset to bits 0-1 of CS (aka CS.RPL). This can work or not, depending on the placement of the code that transitions to protected mode. If CS.RPL != 0 the emulator will see CS.RPL != CS.DPL (the DPL will always be zero) and fail to fetch the next instruction of the transition code. To trigger this using QEMU, it is enough to send "info cpus" continuously while running iPXE (which places its code for real->protected mode in the EBDA). iPXE does a lot of transitions, and the guest will crash very quickly. Signed-off-by: Paolo Bonzini --- arch/x86/include/asm/kvm_host.h | 2 ++ arch/x86/kvm/x86.c | 7 ++++++- include/uapi/linux/kvm.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 0bc2d91c8a97..5a85423f4e65 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -574,6 +574,8 @@ struct kvm_arch { struct mutex apic_map_lock; struct kvm_apic_map *apic_map; + bool set_cpl; + unsigned int tss_addr; struct page *apic_access_page; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ca0a1d38fa51..94c6c77e7a9f 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2656,6 +2656,7 @@ int kvm_dev_ioctl_check_extension(long ext) case KVM_CAP_HYPERV_TIME: case KVM_CAP_IOAPIC_POLARITY_IGNORED: case KVM_CAP_ENABLE_CAP_VM: + case KVM_CAP_X86_CPL: #ifdef CONFIG_KVM_DEVICE_ASSIGNMENT case KVM_CAP_ASSIGN_DEV_IRQ: case KVM_CAP_PCI_2_3: @@ -3682,6 +3683,10 @@ static int kvm_vm_ioctl_enable_cap(struct kvm *kvm, struct kvm_enable_cap *cap) return -EINVAL; switch (cap->cap) { + case KVM_CAP_X86_CPL: + kvm->arch.set_cpl = 1; + r = 0; + break; default: r = -EINVAL; break; @@ -6678,7 +6683,7 @@ int kvm_arch_vcpu_ioctl_set_sregs(struct kvm_vcpu *vcpu, pr_debug("Set back pending irq %d\n", pending_vec); } - kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS, false); + kvm_set_segment(vcpu, &sregs->cs, VCPU_SREG_CS, vcpu->kvm->arch.set_cpl); kvm_set_segment(vcpu, &sregs->ds, VCPU_SREG_DS, false); kvm_set_segment(vcpu, &sregs->es, VCPU_SREG_ES, false); kvm_set_segment(vcpu, &sregs->fs, VCPU_SREG_FS, false); diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h index 2b83cf35437a..4bcf34aa1b3b 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -748,6 +748,7 @@ struct kvm_ppc_smmu_info { #define KVM_CAP_S390_IRQCHIP 99 #define KVM_CAP_IOEVENTFD_NO_LENGTH 100 #define KVM_CAP_VM_ATTRIBUTES 101 +#define KVM_CAP_X86_CPL 102 #ifdef KVM_CAP_IRQ_ROUTING