From patchwork Wed Jan 29 14:45:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 11356291 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2D3EA138C for ; Wed, 29 Jan 2020 14:46:37 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0905B206F0 for ; Wed, 29 Jan 2020 14:46:36 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="dUTP4h2Q" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0905B206F0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iwob6-0007Fs-BO; Wed, 29 Jan 2020 14:45:40 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iwob5-0007Fc-3r for xen-devel@lists.xenproject.org; Wed, 29 Jan 2020 14:45:39 +0000 X-Inumbo-ID: 0158b60c-42a6-11ea-ad98-bc764e2007e4 Received: from esa6.hc3370-68.iphmx.com (unknown [216.71.155.175]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 0158b60c-42a6-11ea-ad98-bc764e2007e4; Wed, 29 Jan 2020 14:45:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1580309134; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ESNEET6I+PO0EuyrahfL5uaji1n0hG5COBYrVolw4cU=; b=dUTP4h2QCKBIsv68T2pyR3H/QMXDmsOqcoduuYAvyMeQyoMxKjh07kTz ZcBCCZbs7xja3vOnN6+//+Hd1cmMWMkvPwR8y0LQxu75/Pi6cHwJKT6+/ 41wNxavU2RucHUsi1/g5TPahR4N/E+7ZyG4shh8h1qjcjcqFqFkYYSje5 M=; Authentication-Results: esa6.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=roger.pau@citrix.com; spf=Pass smtp.mailfrom=roger.pau@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of roger.pau@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa6.hc3370-68.iphmx.com: domain of roger.pau@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa6.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa6.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: pDpPKsUMAZy5AcEhetZF+rZDtgeb3T6SFIKHeKI6LJOFbJYQr3nOzDZXsWe2dsFSaTEgsl8s45 6EhounZ7330ogbTODPSaASq8rAAI2G2fdCvG5069eIJHQdGWQhmCrloqvC8tKje5+1T+l9D0KC ieqsyHIyrO28zzPDL7HnvP/+hHV5sxplVWLGd3FnKYHIwrxXxXVxoLrL9YNBqq+I6F4Aw5iEgp YS9KSi+NvM1GyFacZ6DXJb1z2vBBndt4GYQfEf+onjgDbuvZy9Tjedz2Nwuzgcx1qDNT4Tq0Py RjI= X-SBRS: 2.7 X-MesageID: 12056470 X-Ironport-Server: esa6.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.70,378,1574139600"; d="scan'208";a="12056470" From: Roger Pau Monne To: Date: Wed, 29 Jan 2020 15:45:13 +0100 Message-ID: <20200129144514.96686-2-roger.pau@citrix.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200129144514.96686-1-roger.pau@citrix.com> References: <20200129144514.96686-1-roger.pau@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v2 1/2] nvmx: implement support for MSR bitmaps X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Tian , Jun Nakajima , Wei Liu , Andrew Cooper , Roger Pau Monne Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Current implementation of nested VMX has a half baked handling of MSR bitmaps for the L1 VMM: it maps the L1 VMM provided MSR bitmap, but doesn't actually load it into the nested vmcs, and thus the nested guest vmcs ends up using the same MSR bitmap as the L1 VMM. This is wrong as there's no assurance that the set of features enabled for the L1 vmcs are the same that L1 itself is going to use in the nested vmcs, and thus can lead to misconfigurations. For example L1 vmcs can use x2APIC virtualization and virtual interrupt delivery, and thus some x2APIC MSRs won't be trapped so that they can be handled directly by the hardware using virtualization extensions. On the other hand, the nested vmcs created by L1 VMM might not use any of such features, so using a MSR bitmap that doesn't trap accesses to the x2APIC MSRs will be leaking them to the underlying hardware. Fix this by crafting a merged MSR bitmap between the one used by L1 and the nested guest. Signed-off-by: Roger Pau Monné --- This seems better than what's done currently, but TBH there's a lot of work to be done in nvmx in order to make it functional and secure that I'm not sure whether building on top of the current implementation is something sane to do, or it would be better to start from scratch and re-implement nvmx to just support the minimum required set of VTx features in a sane and safe way. --- Changes since v1: - Split the x2APIC MSR fix into a separate patch. - Move setting MSR_BITMAP vmcs field into load_vvmcs_host_state for virtual vmexit. - Allocate memory with MEMF_no_owner. - Use tabs to align comment of the nestedvmx struct field. --- xen/arch/x86/hvm/vmx/vvmx.c | 63 ++++++++++++++++++++++++++++-- xen/include/asm-x86/hvm/vmx/vvmx.h | 3 +- 2 files changed, 62 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index 47eee1e5b9..c35b4bab84 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -128,6 +128,16 @@ int nvmx_vcpu_initialise(struct vcpu *v) unmap_domain_page(vw); } + if ( cpu_has_vmx_msr_bitmap ) + { + nvmx->msr_merged = alloc_domheap_page(d, MEMF_no_owner); + if ( !nvmx->msr_merged ) + { + gdprintk(XENLOG_ERR, "nest: allocation for MSR bitmap failed\n"); + return -ENOMEM; + } + } + nvmx->ept.enabled = 0; nvmx->guest_vpid = 0; nvmx->vmxon_region_pa = INVALID_PADDR; @@ -182,6 +192,11 @@ void nvmx_vcpu_destroy(struct vcpu *v) free_domheap_page(v->arch.hvm.vmx.vmwrite_bitmap); v->arch.hvm.vmx.vmwrite_bitmap = NULL; } + if ( nvmx->msr_merged ) + { + free_domheap_page(nvmx->msr_merged); + nvmx->msr_merged = NULL; + } } void nvmx_domain_relinquish_resources(struct domain *d) @@ -548,6 +563,37 @@ unsigned long *_shadow_io_bitmap(struct vcpu *v) return nestedhvm_vcpu_iomap_get(port80, portED); } +static void update_msrbitmap(struct vcpu *v) +{ + struct nestedvmx *nvmx = &vcpu_2_nvmx(v); + struct vmx_msr_bitmap *msr_bitmap; + unsigned int msr; + + ASSERT(__n2_exec_control(v) & CPU_BASED_ACTIVATE_MSR_BITMAP); + + if ( !nvmx->msrbitmap ) + return; + + msr_bitmap = __map_domain_page(nvmx->msr_merged); + + bitmap_or(msr_bitmap->read_low, nvmx->msrbitmap->read_low, + v->arch.hvm.vmx.msr_bitmap->read_low, + sizeof(msr_bitmap->read_low) * 8); + bitmap_or(msr_bitmap->read_high, nvmx->msrbitmap->read_high, + v->arch.hvm.vmx.msr_bitmap->read_high, + sizeof(msr_bitmap->read_high) * 8); + bitmap_or(msr_bitmap->write_low, nvmx->msrbitmap->write_low, + v->arch.hvm.vmx.msr_bitmap->write_low, + sizeof(msr_bitmap->write_low) * 8); + bitmap_or(msr_bitmap->write_high, nvmx->msrbitmap->write_high, + v->arch.hvm.vmx.msr_bitmap->write_high, + sizeof(msr_bitmap->write_high) * 8); + + unmap_domain_page(msr_bitmap); + + __vmwrite(MSR_BITMAP, page_to_maddr(nvmx->msr_merged)); +} + void nvmx_update_exec_control(struct vcpu *v, u32 host_cntrl) { u32 pio_cntrl = (CPU_BASED_ACTIVATE_IO_BITMAP @@ -558,10 +604,15 @@ void nvmx_update_exec_control(struct vcpu *v, u32 host_cntrl) shadow_cntrl = __n2_exec_control(v); pio_cntrl &= shadow_cntrl; /* Enforce the removed features */ - shadow_cntrl &= ~(CPU_BASED_ACTIVATE_MSR_BITMAP - | CPU_BASED_ACTIVATE_IO_BITMAP + shadow_cntrl &= ~(CPU_BASED_ACTIVATE_IO_BITMAP | CPU_BASED_UNCOND_IO_EXITING); - shadow_cntrl |= host_cntrl; + /* + * Do NOT enforce the MSR bitmap currently used by L1, as certain hardware + * virtualization features require specific MSR bitmap settings, but + * without the guest also using these same features the bitmap could be + * leaking through unwanted MSR accesses. + */ + shadow_cntrl |= (host_cntrl & ~CPU_BASED_ACTIVATE_MSR_BITMAP); if ( pio_cntrl == CPU_BASED_UNCOND_IO_EXITING ) { /* L1 VMM intercepts all I/O instructions */ shadow_cntrl |= CPU_BASED_UNCOND_IO_EXITING; @@ -584,6 +635,9 @@ void nvmx_update_exec_control(struct vcpu *v, u32 host_cntrl) __vmwrite(IO_BITMAP_B, virt_to_maddr(bitmap) + PAGE_SIZE); } + if ( shadow_cntrl & CPU_BASED_ACTIVATE_MSR_BITMAP ) + update_msrbitmap(v); + /* TODO: change L0 intr window to MTF or NMI window */ __vmwrite(CPU_BASED_VM_EXEC_CONTROL, shadow_cntrl); } @@ -1278,6 +1332,9 @@ static void load_vvmcs_host_state(struct vcpu *v) hvm_set_tsc_offset(v, v->arch.hvm.cache_tsc_offset, 0); set_vvmcs(v, VM_ENTRY_INTR_INFO, 0); + + if ( v->arch.hvm.vmx.exec_control & CPU_BASED_ACTIVATE_MSR_BITMAP ) + __vmwrite(MSR_BITMAP, virt_to_maddr(v->arch.hvm.vmx.msr_bitmap)); } static void sync_exception_state(struct vcpu *v) diff --git a/xen/include/asm-x86/hvm/vmx/vvmx.h b/xen/include/asm-x86/hvm/vmx/vvmx.h index 6b9c4ae0b2..c8d5600fdd 100644 --- a/xen/include/asm-x86/hvm/vmx/vvmx.h +++ b/xen/include/asm-x86/hvm/vmx/vvmx.h @@ -37,7 +37,8 @@ struct nestedvmx { */ paddr_t vmxon_region_pa; void *iobitmap[2]; /* map (va) of L1 guest I/O bitmap */ - void *msrbitmap; /* map (va) of L1 guest MSR bitmap */ + struct vmx_msr_bitmap *msrbitmap; /* map (va) of L1 guest MSR bitmap */ + struct page_info *msr_merged; /* merged L1 and L1 guest MSR bitmap */ /* deferred nested interrupt */ struct { unsigned long intr_info; From patchwork Wed Jan 29 14:45:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Roger_Pau_Monn=C3=A9?= X-Patchwork-Id: 11356293 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3565E159A for ; Wed, 29 Jan 2020 14:46:40 +0000 (UTC) Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 124D3206F0 for ; Wed, 29 Jan 2020 14:46:40 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (1024-bit key) header.d=citrix.com header.i=@citrix.com header.b="DVbGAiIc" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 124D3206F0 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=citrix.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=xen-devel-bounces@lists.xenproject.org Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iwobB-0007Ha-Mf; Wed, 29 Jan 2020 14:45:45 +0000 Received: from us1-rack-iad1.inumbo.com ([172.99.69.81]) by lists.xenproject.org with esmtp (Exim 4.89) (envelope-from ) id 1iwobA-0007H8-4T for xen-devel@lists.xenproject.org; Wed, 29 Jan 2020 14:45:44 +0000 X-Inumbo-ID: 027d97d2-42a6-11ea-b211-bc764e2007e4 Received: from esa2.hc3370-68.iphmx.com (unknown [216.71.145.153]) by us1-rack-iad1.inumbo.com (Halon) with ESMTPS id 027d97d2-42a6-11ea-b211-bc764e2007e4; Wed, 29 Jan 2020 14:45:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=citrix.com; s=securemail; t=1580309137; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=aTx9zYJ42cXd+ovOU1wPK7fiBk28ZOmSha7iU7SLwHg=; b=DVbGAiIcpubKKlNc9ABQvNZ/5ki592ilbEtby2IzI6VOlE2jDICJo9bs HrXx7f/Oa3wZtN8jPXpSU08MGa7wuWhIRR0pFP8CXbZKe1Q2kXtVP9PAC wUZLe6pvslQw/pVHXi9svXHd3ghGOz9htM7+Evw203XDxXdAHZQEOSRTJ Y=; Authentication-Results: esa2.hc3370-68.iphmx.com; dkim=none (message not signed) header.i=none; spf=None smtp.pra=roger.pau@citrix.com; spf=Pass smtp.mailfrom=roger.pau@citrix.com; spf=None smtp.helo=postmaster@mail.citrix.com Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of roger.pau@citrix.com) identity=pra; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible Received-SPF: Pass (esa2.hc3370-68.iphmx.com: domain of roger.pau@citrix.com designates 162.221.158.21 as permitted sender) identity=mailfrom; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="roger.pau@citrix.com"; x-conformance=sidf_compatible; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:209.167.231.154 ip4:178.63.86.133 ip4:195.66.111.40/30 ip4:85.115.9.32/28 ip4:199.102.83.4 ip4:192.28.146.160 ip4:192.28.146.107 ip4:216.52.6.88 ip4:216.52.6.188 ip4:162.221.158.21 ip4:162.221.156.83 ip4:168.245.78.127 ~all" Received-SPF: None (esa2.hc3370-68.iphmx.com: no sender authenticity information available from domain of postmaster@mail.citrix.com) identity=helo; client-ip=162.221.158.21; receiver=esa2.hc3370-68.iphmx.com; envelope-from="roger.pau@citrix.com"; x-sender="postmaster@mail.citrix.com"; x-conformance=sidf_compatible IronPort-SDR: BVU0H13PlxrLQdayLcY6I3StyS+HvCZ28CgG5gbndq0yP5VSwGFOLyWWxkqlic0homvtyeUVuV PNG0UmJGKj5AGOTSbjJJWXqyYT086acfCuxWDSUy68QUzqix3p226HTLvO5owiDqEqipVWtRnJ Lj5hnFOz1hpANy59FpWVSzT+hVocuvwqXHYiM15zIa03dIPN9CCZIqnw0ZMenumPczZTiQ1v22 hmaKBy9akSadVJDzbWo3PEuBPM87NSWn+mpykpsf90IJDf7W9H9tIdJYr9MqQ9tbfBIRs2ZeAs 5rg= X-SBRS: 2.7 X-MesageID: 11633377 X-Ironport-Server: esa2.hc3370-68.iphmx.com X-Remote-IP: 162.221.158.21 X-Policy: $RELAYED X-IronPort-AV: E=Sophos;i="5.70,378,1574139600"; d="scan'208";a="11633377" From: Roger Pau Monne To: Date: Wed, 29 Jan 2020 15:45:14 +0100 Message-ID: <20200129144514.96686-3-roger.pau@citrix.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200129144514.96686-1-roger.pau@citrix.com> References: <20200129144514.96686-1-roger.pau@citrix.com> MIME-Version: 1.0 Subject: [Xen-devel] [PATCH v2 2/2] nvmx: always trap accesses to x2APIC MSRs X-BeenThere: xen-devel@lists.xenproject.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Cc: Kevin Tian , Jun Nakajima , Wei Liu , Andrew Cooper , Roger Pau Monne Errors-To: xen-devel-bounces@lists.xenproject.org Sender: "Xen-devel" Nested VMX doesn't expose support for SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE, SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY or SECONDARY_EXEC_APIC_REGISTER_VIRT, and hence the x2APIC MSRs should always be trapped in the nested guest MSR bitmap, or else a nested guest could access the hardware x2APIC MSRs given certain conditions. Accessing the hardware MSRs could be achieved by forcing the L0 Xen to use SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE and SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY or SECONDARY_EXEC_APIC_REGISTER_VIRT (if supported), and then creating a L2 guest with a MSR bitmap that doesn't trap accesses to the x2APIC MSR range. Then OR'ing both L0 and L1 MSR bitmaps would result in a bitmap that doesn't trap certain x2APIC MSRs and a VMCS that doesn't have SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE and SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY or SECONDARY_EXEC_APIC_REGISTER_VIRT set either. Fix this by making sure x2APIC MSRs are always trapped in the nested MSR bitmap. Signed-off-by: Roger Pau Monné Reviewed-by: Kevin Tian --- Changes since v1: - New in this version (split from #1 patch). - Use non-locked set_bit. --- xen/arch/x86/hvm/vmx/vvmx.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/xen/arch/x86/hvm/vmx/vvmx.c b/xen/arch/x86/hvm/vmx/vvmx.c index c35b4bab84..69dd4cf6ea 100644 --- a/xen/arch/x86/hvm/vmx/vvmx.c +++ b/xen/arch/x86/hvm/vmx/vvmx.c @@ -589,6 +589,16 @@ static void update_msrbitmap(struct vcpu *v) v->arch.hvm.vmx.msr_bitmap->write_high, sizeof(msr_bitmap->write_high) * 8); + /* + * Nested VMX doesn't support any x2APIC hardware virtualization, so + * make sure all the x2APIC MSRs are trapped. + */ + for ( msr = MSR_X2APIC_FIRST; msr <= MSR_X2APIC_FIRST + 0xff; msr++ ) + { + __set_bit(msr, msr_bitmap->read_low); + __set_bit(msr, msr_bitmap->write_low); + } + unmap_domain_page(msr_bitmap); __vmwrite(MSR_BITMAP, page_to_maddr(nvmx->msr_merged));