From patchwork Thu Nov 10 12:30:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Beulich X-Patchwork-Id: 9421015 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id EF98E60484 for ; Thu, 10 Nov 2016 12:33:36 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id DE7B52926B for ; Thu, 10 Nov 2016 12:33:36 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id D1BD729495; Thu, 10 Nov 2016 12:33:36 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 21C0D2926B for ; Thu, 10 Nov 2016 12:33:36 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1c4oUx-00007q-IK; Thu, 10 Nov 2016 12:30:31 +0000 Received: from mail6.bemta6.messagelabs.com ([193.109.254.103]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1c4oUw-00007j-BM for xen-devel@lists.xenproject.org; Thu, 10 Nov 2016 12:30:30 +0000 Received: from [193.109.254.147] by server-7.bemta-6.messagelabs.com id E5/94-21485-56864285; Thu, 10 Nov 2016 12:30:29 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFlrGIsWRWlGSWpSXmKPExsXS6fjDSzclQyX C4MsMRYvvWyYzOTB6HP5whSWAMYo1My8pvyKBNWPfqztsBctDKi68fMTWwPjZsYuRk0NIIE/i 7o0JLCA2r4CdRNP1H2wgtoSAocTT99fBbBYBVYlPB1uYQWw2AXWJtmfbWbsYOThEBAwkzh1N6 mLk4mAWmM4ocW73VLB6YQFXiT9T+8FqeAUEJf7uEAYJMwONn3N3GuMERq5ZCJlZSDIQtpbEw1 +3WCBsbYllC18zg5QzC0hLLP/HARG2lJh0/yQbqhIQ20Wi+dRLlgWMHKsYNYpTi8pSi3SNjPS SijLTM0pyEzNzdA0NzPRyU4uLE9NTcxKTivWS83M3MQLDjwEIdjCumR94iFGSg0lJlHdHgEqE EF9SfkplRmJxRnxRaU5q8SFGGQ4OJQnevWlAOcGi1PTUirTMHGAkwKQlOHiURHgng6R5iwsSc 4sz0yFSpxgVpcR514MkBEASGaV5cG2w6LvEKCslzMsIdIgQT0FqUW5mCar8K0ZxDkYlYd6bIF N4MvNK4Ka/AlrMBLR4RhzY4pJEhJRUA+OC9qYl7Mxu62UEFe/keJ2pvO9ZOOOQ+YVtU5wv2v9 RfsMxe3/onRsL7AWqZMN2BsnlrfJ141z1/qyUvW3QLZGNvqcqFcJ7HzuKHTlVp/Qq5MfW/RJr Cj9P+CW3xSj02cQ1Ej0LVBasONDDaxFQfrNv/kIRDS525sS9x/K6yoIv9ajstnHpWaHEUpyRa KjFXFScCAArvI0luQIAAA== X-Env-Sender: JBeulich@suse.com X-Msg-Ref: server-8.tower-27.messagelabs.com!1478781026!60697308!1 X-Originating-IP: [137.65.248.74] X-SpamReason: No, hits=0.5 required=7.0 tests=BODY_RANDOM_LONG X-StarScan-Received: X-StarScan-Version: 9.0.16; banners=-,-,- X-VirusChecked: Checked Received: (qmail 17024 invoked from network); 10 Nov 2016 12:30:27 -0000 Received: from prv-mh.provo.novell.com (HELO prv-mh.provo.novell.com) (137.65.248.74) by server-8.tower-27.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 10 Nov 2016 12:30:27 -0000 Received: from INET-PRV-MTA by prv-mh.provo.novell.com with Novell_GroupWise; Thu, 10 Nov 2016 05:30:25 -0700 Message-Id: <58247671020000780011DA5A@prv-mh.provo.novell.com> X-Mailer: Novell GroupWise Internet Agent 14.2.1 Date: Thu, 10 Nov 2016 05:30:25 -0700 From: "Jan Beulich" To: "xen-devel" Mime-Version: 1.0 Cc: Andrew Cooper , Paul Durrant , Wei Liu , Tim Deegan Subject: [Xen-devel] [PATCH] x86: always supply .cpuid() handler to x86_emulate() X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP With us incremementally adding proper CPUID checks to x86_emulate() (see commit de05bd965a ["x86emul: correct {,F}CMOV and F{,U}COMI{,P} emulation"]) it is no longer appropriate to invoke the function with that hook being NULL, as long as respective instructions may get used in that case. Signed-off-by: Jan Beulich Reviewed-by: Paul Durrant Reviewed-by: Andrew Cooper --- I've noticed the problem first with a not yet submitted patch checking cx8 (PV 32-bit kernels occasionally use cmpxchg8b for page table accesses), and I think we don't strictly need the change here for 4.8, but then again it may be better to handle this properly right away. x86: always supply .cpuid() handler to x86_emulate() With us incremementally adding proper CPUID checks to x86_emulate() (see commit de05bd965a ["x86emul: correct {,F}CMOV and F{,U}COMI{,P} emulation"]) it is no longer appropriate to invoke the function with that hook being NULL, as long as respective instructions may get used in that case. Signed-off-by: Jan Beulich --- I've noticed the problem first with a not yet submitted patch checking cx8 (PV 32-bit kernels occasionally use cmpxchg8b for page table accesses), and I think we don't strictly need the change here for 4.8, but then again it may be better to handle this properly right away. --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -1542,7 +1542,7 @@ static int hvmemul_wbinvd( return X86EMUL_OKAY; } -static int hvmemul_cpuid( +int hvmemul_cpuid( unsigned int *eax, unsigned int *ebx, unsigned int *ecx, @@ -1892,11 +1892,13 @@ int hvm_emulate_one_mmio(unsigned long m .read = x86emul_unhandleable_rw, .insn_fetch = hvmemul_insn_fetch, .write = mmcfg_intercept_write, + .cpuid = hvmemul_cpuid, }; static const struct x86_emulate_ops hvm_ro_emulate_ops_mmio = { .read = x86emul_unhandleable_rw, .insn_fetch = hvmemul_insn_fetch, - .write = mmio_ro_emulated_write + .write = mmio_ro_emulated_write, + .cpuid = hvmemul_cpuid, }; struct mmio_ro_emulate_ctxt mmio_ro_ctxt = { .cr2 = gla }; struct hvm_emulate_ctxt ctxt; --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -5327,6 +5327,7 @@ static const struct x86_emulate_ops ptwr .insn_fetch = ptwr_emulated_read, .write = ptwr_emulated_write, .cmpxchg = ptwr_emulated_cmpxchg, + .cpuid = pv_emul_cpuid, }; /* Write page fault handler: check if guest is trying to modify a PTE. */ @@ -5414,6 +5415,7 @@ static const struct x86_emulate_ops mmio .read = x86emul_unhandleable_rw, .insn_fetch = ptwr_emulated_read, .write = mmio_ro_emulated_write, + .cpuid = pv_emul_cpuid, }; int mmcfg_intercept_write( @@ -5451,6 +5453,7 @@ static const struct x86_emulate_ops mmcf .read = x86emul_unhandleable_rw, .insn_fetch = ptwr_emulated_read, .write = mmcfg_intercept_write, + .cpuid = pv_emul_cpuid, }; /* Check if guest is trying to modify a r/o MMIO page. */ --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -306,6 +306,7 @@ static const struct x86_emulate_ops hvm_ .insn_fetch = hvm_emulate_insn_fetch, .write = hvm_emulate_write, .cmpxchg = hvm_emulate_cmpxchg, + .cpuid = hvmemul_cpuid, }; static int @@ -374,6 +375,7 @@ static const struct x86_emulate_ops pv_s .insn_fetch = pv_emulate_read, .write = pv_emulate_write, .cmpxchg = pv_emulate_cmpxchg, + .cpuid = pv_emul_cpuid, }; const struct x86_emulate_ops *shadow_init_emulation( --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -2755,6 +2755,24 @@ static int priv_op_write_msr(unsigned in return X86EMUL_UNHANDLEABLE; } +int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx, struct x86_emulate_ctxt *ctxt) +{ + struct cpu_user_regs regs = *ctxt->regs; + + regs._eax = *eax; + regs._ecx = *ecx; + + pv_cpuid(®s); + + *eax = regs._eax; + *ebx = regs._ebx; + *ecx = regs._ecx; + *edx = regs._edx; + + return X86EMUL_OKAY; +} + /* Instruction fetch with error handling. */ #define insn_fetch(type, base, eip, limit) \ ({ unsigned long _rc, _ptr = (base) + (eip); \ --- a/xen/include/asm-x86/hvm/emulate.h +++ b/xen/include/asm-x86/hvm/emulate.h @@ -60,6 +60,12 @@ void hvm_emulate_init( unsigned int insn_bytes); void hvm_emulate_writeback( struct hvm_emulate_ctxt *hvmemul_ctxt); +int hvmemul_cpuid( + unsigned int *eax, + unsigned int *ebx, + unsigned int *ecx, + unsigned int *edx, + struct x86_emulate_ctxt *ctxt); struct segment_register *hvmemul_get_seg_reg( enum x86_segment seg, struct hvm_emulate_ctxt *hvmemul_ctxt); --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -504,6 +504,8 @@ extern int mmcfg_intercept_write(enum x8 void *p_data, unsigned int bytes, struct x86_emulate_ctxt *ctxt); +int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx, struct x86_emulate_ctxt *ctxt); int ptwr_do_page_fault(struct vcpu *, unsigned long, struct cpu_user_regs *); --- a/xen/arch/x86/hvm/emulate.c +++ b/xen/arch/x86/hvm/emulate.c @@ -1542,7 +1542,7 @@ static int hvmemul_wbinvd( return X86EMUL_OKAY; } -static int hvmemul_cpuid( +int hvmemul_cpuid( unsigned int *eax, unsigned int *ebx, unsigned int *ecx, @@ -1892,11 +1892,13 @@ int hvm_emulate_one_mmio(unsigned long m .read = x86emul_unhandleable_rw, .insn_fetch = hvmemul_insn_fetch, .write = mmcfg_intercept_write, + .cpuid = hvmemul_cpuid, }; static const struct x86_emulate_ops hvm_ro_emulate_ops_mmio = { .read = x86emul_unhandleable_rw, .insn_fetch = hvmemul_insn_fetch, - .write = mmio_ro_emulated_write + .write = mmio_ro_emulated_write, + .cpuid = hvmemul_cpuid, }; struct mmio_ro_emulate_ctxt mmio_ro_ctxt = { .cr2 = gla }; struct hvm_emulate_ctxt ctxt; --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -5327,6 +5327,7 @@ static const struct x86_emulate_ops ptwr .insn_fetch = ptwr_emulated_read, .write = ptwr_emulated_write, .cmpxchg = ptwr_emulated_cmpxchg, + .cpuid = pv_emul_cpuid, }; /* Write page fault handler: check if guest is trying to modify a PTE. */ @@ -5414,6 +5415,7 @@ static const struct x86_emulate_ops mmio .read = x86emul_unhandleable_rw, .insn_fetch = ptwr_emulated_read, .write = mmio_ro_emulated_write, + .cpuid = pv_emul_cpuid, }; int mmcfg_intercept_write( @@ -5451,6 +5453,7 @@ static const struct x86_emulate_ops mmcf .read = x86emul_unhandleable_rw, .insn_fetch = ptwr_emulated_read, .write = mmcfg_intercept_write, + .cpuid = pv_emul_cpuid, }; /* Check if guest is trying to modify a r/o MMIO page. */ --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -306,6 +306,7 @@ static const struct x86_emulate_ops hvm_ .insn_fetch = hvm_emulate_insn_fetch, .write = hvm_emulate_write, .cmpxchg = hvm_emulate_cmpxchg, + .cpuid = hvmemul_cpuid, }; static int @@ -374,6 +375,7 @@ static const struct x86_emulate_ops pv_s .insn_fetch = pv_emulate_read, .write = pv_emulate_write, .cmpxchg = pv_emulate_cmpxchg, + .cpuid = pv_emul_cpuid, }; const struct x86_emulate_ops *shadow_init_emulation( --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -2755,6 +2755,24 @@ static int priv_op_write_msr(unsigned in return X86EMUL_UNHANDLEABLE; } +int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx, struct x86_emulate_ctxt *ctxt) +{ + struct cpu_user_regs regs = *ctxt->regs; + + regs._eax = *eax; + regs._ecx = *ecx; + + pv_cpuid(®s); + + *eax = regs._eax; + *ebx = regs._ebx; + *ecx = regs._ecx; + *edx = regs._edx; + + return X86EMUL_OKAY; +} + /* Instruction fetch with error handling. */ #define insn_fetch(type, base, eip, limit) \ ({ unsigned long _rc, _ptr = (base) + (eip); \ --- a/xen/include/asm-x86/hvm/emulate.h +++ b/xen/include/asm-x86/hvm/emulate.h @@ -60,6 +60,12 @@ void hvm_emulate_init( unsigned int insn_bytes); void hvm_emulate_writeback( struct hvm_emulate_ctxt *hvmemul_ctxt); +int hvmemul_cpuid( + unsigned int *eax, + unsigned int *ebx, + unsigned int *ecx, + unsigned int *edx, + struct x86_emulate_ctxt *ctxt); struct segment_register *hvmemul_get_seg_reg( enum x86_segment seg, struct hvm_emulate_ctxt *hvmemul_ctxt); --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -504,6 +504,8 @@ extern int mmcfg_intercept_write(enum x8 void *p_data, unsigned int bytes, struct x86_emulate_ctxt *ctxt); +int pv_emul_cpuid(unsigned int *eax, unsigned int *ebx, unsigned int *ecx, + unsigned int *edx, struct x86_emulate_ctxt *ctxt); int ptwr_do_page_fault(struct vcpu *, unsigned long, struct cpu_user_regs *);