From nobody Thu Apr 25 18:59:43 2024 Delivered-To: importer@patchew.org Received-SPF: none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) client-ip=80.81.252.135; envelope-from=seabios-bounces@seabios.org; helo=mail.coreboot.org; Authentication-Results: mx.zohomail.com; spf=none (zoho.com: 80.81.252.135 is neither permitted nor denied by domain of seabios.org) smtp.mailfrom=seabios-bounces@seabios.org Return-Path: Received: from mail.coreboot.org (mail.coreboot.org [80.81.252.135]) by mx.zohomail.com with SMTPS id 1514986921633733.0153975927026; Wed, 3 Jan 2018 05:42:01 -0800 (PST) Received: from [127.0.0.1] (helo=ra.coreboot.org) by mail.coreboot.org with esmtp (Exim 4.86_2) (envelope-from ) id 1eWjHs-0007b2-KJ; Wed, 03 Jan 2018 14:40:56 +0100 Received: from mx1.redhat.com ([209.132.183.28]) by mail.coreboot.org with esmtps (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256) (Exim 4.86_2) (envelope-from ) id 1eWjHf-0007ZV-Vl for seabios@seabios.org; Wed, 03 Jan 2018 14:40:54 +0100 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id BCFA4806A4 for ; Wed, 3 Jan 2018 13:41:17 +0000 (UTC) Received: from vitty.brq.redhat.com (unknown [10.43.2.155]) by smtp.corp.redhat.com (Postfix) with ESMTP id 183086F7E1; Wed, 3 Jan 2018 13:41:16 +0000 (UTC) From: Vitaly Kuznetsov To: seabios@seabios.org Date: Wed, 3 Jan 2018 14:41:15 +0100 Message-Id: <20180103134115.13686-1-vkuznets@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 03 Jan 2018 13:41:17 +0000 (UTC) X-Spam-Score: -8.0 (--------) Subject: [SeaBIOS] [PATCH RFC] x86: use volatile asm for read/write{b, w, l} implementations X-BeenThere: seabios@seabios.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: SeaBIOS mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Errors-To: seabios-bounces@seabios.org Sender: "SeaBIOS" X-Duff: Orig. Duff, Duff Lite, Duff Dry, Duff Dark, Raspberry Duff, Lady Duff, Red Duff, Tartar Control Duff X-ZohoMail: RSF_4 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" QEMU/KVM guests running nested on top of Hyper-V fail to boot with virtio-blk-pci disks, the debug log ends with Booting from Hard Disk... call32_smm 0x000edd01 e97a0 handle_smi cmd=3Db5 smbase=3D0x000a0000 vp notify fe007000 (2) -- 0x0 vp read fe005000 (1) -> 0x0 handle_smi cmd=3Db5 smbase=3D0x000a0000 call32_smm done 0x000edd01 0 Booting from 0000:7c00 call32_smm 0x000edd01 e97a4 handle_smi cmd=3Db5 smbase=3D0x000a0000 vp notify fe007000 (2) -- 0x0 In resume (status=3D0) In 32bit resume Attempting a hard reboot ... I bisected the breakage to the following commit: commit f46739b1a819750c63fb5849844d99cc2ab001e8 Author: Kevin O'Connor Date: Tue Feb 2 22:34:27 2016 -0500 virtio: Convert to new PCI BAR helper functions But the commit itself appears to be correct. The problem is in how writew() function compiles into vp_notify(). For example, if we drop 'volatile' qualifier from the current writew() implementation everything starts to work. If we disassemble these two versions (as of f46739b1a) the difference will be: 00000000 : With 'volatile' (current) Without 'volatile' 0: push %ebx 0: push %ebx 1: mov %eax,%ecx 1: mov %eax,%ecx 3: mov 0x1518(%edx),%eax 3: mov 0x1518(%edx),%eax 9: cmpb $0x0,0x2c(%ecx) 9: cmpb $0x0,0x2c(%ecx) d: je 2f d: je 2e f: mov 0x151c(%edx),%edx f: mov 0x151c(%edx),%edx 15: mov 0x28(%ecx),%ebx 18: imul %edx,%ebx 15: imul 0x28(%ecx),%edx 1b: mov 0x8(%ecx),%edx 19: mov 0x8(%ecx),%ebx 1e: add %ebx,%edx 20: cmpb $0x0,0xe(%ecx) 1c: cmpb $0x0,0xe(%ecx) 24: je 2a 20: je 28 22: add %ebx,%edx 26: out %ax,(%dx) 24: out %ax,(%dx) 28: jmp 48 26: jmp 47 2a: mov %ax,(%edx) 28: mov %ax,(%ebx,%edx,1) 2d: jmp 48 2c: jmp 47 2f: lea 0x20(%ecx),%ebx 2e: lea 0x20(%ecx),%ebx 32: cltd 31: cltd 33: push %edx 32: push %edx 34: push %eax 33: push %eax 35: mov $0x2,%ecx 34: mov $0x2,%ecx 3a: mov $0x10,%edx 39: mov $0x10,%edx 3f: mov %ebx,%eax 3e: mov %ebx,%eax 41: call 42 40: call 41 46: pop %eax 45: pop %eax 47: pop %edx 46: pop %edx 48: pop %ebx 47: pop %ebx 49: ret 48: ret My eyes fail to see an obvious compiler flaw here but probably the mov difference (at '2a' old, '28' new) is to blame. Doing some other subtle changes (e.g. adding local variables to the function) help in some cases too. At this point I got a bit lost with my debug so I looked at how Linux does this stuff and it seems we're not using '*(volatile u16) =3D ' there. Rewriting write/read{b,w,l} with volatile asm help. Signed-off-by: Vitaly Kuznetsov --- RFC: This is rather an ongoing debug as I'm not able to point finger at the real culprit yet, I'd be grateful for any help and suggestions. In particular, I don't quite understand why nested virtualization makes a difference here. --- src/x86.h | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/x86.h b/src/x86.h index 53378e9..d45122c 100644 --- a/src/x86.h +++ b/src/x86.h @@ -199,30 +199,27 @@ static inline void smp_wmb(void) { } =20 static inline void writel(void *addr, u32 val) { - barrier(); - *(volatile u32 *)addr =3D val; + asm volatile("movl %0, %1" : : "d"(val), "m"(*(u32 *)addr) : "memory"); } static inline void writew(void *addr, u16 val) { - barrier(); - *(volatile u16 *)addr =3D val; + asm volatile("movw %0, %1" : : "d"(val), "m"(*(u16 *)addr) : "memory"); } static inline void writeb(void *addr, u8 val) { - barrier(); - *(volatile u8 *)addr =3D val; + asm volatile("movb %0, %1" : : "d"(val), "m"(*(u8 *)addr) : "memory"); } static inline u32 readl(const void *addr) { - u32 val =3D *(volatile const u32 *)addr; - barrier(); + u32 val; + asm volatile("movl %1, %0" : "=3Dd"(val) : "m"(*(u32 *)addr) : "memory= "); return val; } static inline u16 readw(const void *addr) { - u16 val =3D *(volatile const u16 *)addr; - barrier(); + u16 val; + asm volatile("movw %1, %0" : "=3Dd"(val) : "m"(*(u16 *)addr) : "memory= "); return val; } static inline u8 readb(const void *addr) { - u8 val =3D *(volatile const u8 *)addr; - barrier(); + u8 val; + asm volatile("movb %1, %0" : "=3Dd"(val) : "m"(*(u8 *)addr) : "memory"= ); return val; } =20 --=20 2.14.3 _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org https://mail.coreboot.org/mailman/listinfo/seabios