From nobody Sun Nov 9 23:29:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552480979251217.59799305969398; Wed, 13 Mar 2019 05:42:59 -0700 (PDT) Received: from localhost ([127.0.0.1]:43928 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Dj-0002NC-6b for importer@patchew.org; Wed, 13 Mar 2019 08:42:55 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33215) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Bm-0001ET-QY for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:40:56 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h43Bk-0005FI-0X for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:40:54 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59488) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h43Bj-0005DB-LW for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:40:51 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D770D8B94E; Wed, 13 Mar 2019 12:40:50 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-43.ams2.redhat.com [10.36.112.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id E4E341001E70; Wed, 13 Mar 2019 12:40:48 +0000 (UTC) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 13 Mar 2019 13:40:36 +0100 Message-Id: <20190313124042.12855-2-pbonzini@redhat.com> In-Reply-To: <20190313124042.12855-1-pbonzini@redhat.com> References: <20190313124042.12855-1-pbonzini@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Wed, 13 Mar 2019 12:40:50 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 1/7] qemugdb: allow adding support for other coroutine backends X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: fweimer@redhat.com, kwolf@redhat.com, richard.henderson@linaro.org, stefanha@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Split the jmpbuf access to a separate module and dispatch based on which CoroutineXYZ type is defined. Signed-off-by: Paolo Bonzini Reviewed-by: Stefan Hajnoczi --- scripts/qemugdb/coroutine.py | 106 ++++++++------------------ scripts/qemugdb/coroutine_ucontext.py | 69 +++++++++++++++++ 2 files changed, 100 insertions(+), 75 deletions(-) create mode 100644 scripts/qemugdb/coroutine_ucontext.py diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py index 41e079d0e2..db2753d949 100644 --- a/scripts/qemugdb/coroutine.py +++ b/scripts/qemugdb/coroutine.py @@ -1,6 +1,6 @@ #!/usr/bin/python =20 -# GDB debugging support +# GDB debugging support, coroutine dispatch # # Copyright 2012 Red Hat, Inc. and/or its affiliates # @@ -10,82 +10,25 @@ # This work is licensed under the terms of the GNU GPL, version 2 # or later. See the COPYING file in the top-level directory. =20 +from . import coroutine_ucontext import gdb =20 VOID_PTR =3D gdb.lookup_type('void').pointer() +UINTPTR_T =3D gdb.lookup_type('uintptr_t') =20 -def get_fs_base(): - '''Fetch %fs base value using arch_prctl(ARCH_GET_FS). This is - pthread_self().''' - # %rsp - 120 is scratch space according to the SystemV ABI - old =3D gdb.parse_and_eval('*(uint64_t*)($rsp - 120)') - gdb.execute('call (int)arch_prctl(0x1003, $rsp - 120)', False, True) - fs_base =3D gdb.parse_and_eval('*(uint64_t*)($rsp - 120)') - gdb.execute('set *(uint64_t*)($rsp - 120) =3D %s' % old, False, True) - return fs_base - -def pthread_self(): - '''Fetch pthread_self() from the glibc start_thread function.''' - f =3D gdb.newest_frame() - while f.name() !=3D 'start_thread': - f =3D f.older() - if f is None: - return get_fs_base() - - try: - return f.read_var("arg") - except ValueError: - return get_fs_base() - -def get_glibc_pointer_guard(): - '''Fetch glibc pointer guard value''' - fs_base =3D pthread_self() - return gdb.parse_and_eval('*(uint64_t*)((uint64_t)%s + 0x30)' % fs_bas= e) - -def glibc_ptr_demangle(val, pointer_guard): - '''Undo effect of glibc's PTR_MANGLE()''' - return gdb.parse_and_eval('(((uint64_t)%s >> 0x11) | ((uint64_t)%s << = (64 - 0x11))) ^ (uint64_t)%s' % (val, val, pointer_guard)) - -def get_jmpbuf_regs(jmpbuf): - JB_RBX =3D 0 - JB_RBP =3D 1 - JB_R12 =3D 2 - JB_R13 =3D 3 - JB_R14 =3D 4 - JB_R15 =3D 5 - JB_RSP =3D 6 - JB_PC =3D 7 - - pointer_guard =3D get_glibc_pointer_guard() - return {'rbx': jmpbuf[JB_RBX], - 'rbp': glibc_ptr_demangle(jmpbuf[JB_RBP], pointer_guard), - 'rsp': glibc_ptr_demangle(jmpbuf[JB_RSP], pointer_guard), - 'r12': jmpbuf[JB_R12], - 'r13': jmpbuf[JB_R13], - 'r14': jmpbuf[JB_R14], - 'r15': jmpbuf[JB_R15], - 'rip': glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard) } - -def bt_jmpbuf(jmpbuf): - '''Backtrace a jmpbuf''' - regs =3D get_jmpbuf_regs(jmpbuf) - old =3D dict() - - for i in regs: - old[i] =3D gdb.parse_and_eval('(uint64_t)$%s' % i) - - for i in regs: - gdb.execute('set $%s =3D %s' % (i, regs[i])) - - gdb.execute('bt') - - for i in regs: - gdb.execute('set $%s =3D %s' % (i, old[i])) - -def coroutine_to_jmpbuf(co): - coroutine_pointer =3D co.cast(gdb.lookup_type('CoroutineUContext').poi= nter()) - return coroutine_pointer['env']['__jmpbuf'] +backends =3D { + 'CoroutineUContext': coroutine_ucontext +} =20 +def coroutine_backend(): + for k, v in backends.items(): + try: + gdb.lookup_type(k) + except: + continue + return v + + raise Exception('could not find coroutine backend') =20 class CoroutineCommand(gdb.Command): '''Display coroutine backtrace''' @@ -99,18 +42,31 @@ class CoroutineCommand(gdb.Command): gdb.write('usage: qemu coroutine \n') return =20 - bt_jmpbuf(coroutine_to_jmpbuf(gdb.parse_and_eval(argv[0]))) + addr =3D gdb.parse_and_eval(argv[0]) + regs =3D coroutine_backend().get_coroutine_regs(addr) + old =3D dict() + + for i in regs: + old[i] =3D gdb.parse_and_eval('(uint64_t)$%s' % i) + + for i in regs: + gdb.execute('set $%s =3D %s' % (i, regs[i].cast(UINTPTR_T))) + + gdb.execute('bt') + + for i in regs: + gdb.execute('set $%s =3D %s' % (i, old[i].cast(UINTPTR_T))) =20 class CoroutineSPFunction(gdb.Function): def __init__(self): gdb.Function.__init__(self, 'qemu_coroutine_sp') =20 def invoke(self, addr): - return get_jmpbuf_regs(coroutine_to_jmpbuf(addr))['rsp'].cast(VOID= _PTR) + return coroutine_backend().get_coroutine_regs(addr)['rsp'].cast(VO= ID_PTR) =20 class CoroutinePCFunction(gdb.Function): def __init__(self): gdb.Function.__init__(self, 'qemu_coroutine_pc') =20 def invoke(self, addr): - return get_jmpbuf_regs(coroutine_to_jmpbuf(addr))['rip'].cast(VOID= _PTR) + return coroutine_backend().get_coroutine_regs(addr)['rip'].cast(VO= ID_PTR) diff --git a/scripts/qemugdb/coroutine_ucontext.py b/scripts/qemugdb/corout= ine_ucontext.py new file mode 100644 index 0000000000..a2f8c1dbbf --- /dev/null +++ b/scripts/qemugdb/coroutine_ucontext.py @@ -0,0 +1,69 @@ +#!/usr/bin/python + +# GDB debugging support +# +# Copyright 2012 Red Hat, Inc. and/or its affiliates +# +# Authors: +# Avi Kivity +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. + +import gdb + +def get_fs_base(): + '''Fetch %fs base value using arch_prctl(ARCH_GET_FS). This is + pthread_self().''' + # %rsp - 120 is scratch space according to the SystemV ABI + old =3D gdb.parse_and_eval('*(uint64_t*)($rsp - 120)') + gdb.execute('call (int)arch_prctl(0x1003, $rsp - 120)', False, True) + fs_base =3D gdb.parse_and_eval('*(uint64_t*)($rsp - 120)') + gdb.execute('set *(uint64_t*)($rsp - 120) =3D %s' % old, False, True) + return fs_base + +def pthread_self(): + '''Fetch pthread_self() from the glibc start_thread function.''' + f =3D gdb.newest_frame() + while f.name() !=3D 'start_thread': + f =3D f.older() + if f is None: + return get_fs_base() + + try: + return f.read_var("arg") + except ValueError: + return get_fs_base() + +def get_glibc_pointer_guard(): + '''Fetch glibc pointer guard value''' + fs_base =3D pthread_self() + return gdb.parse_and_eval('*(uint64_t*)((uint64_t)%s + 0x30)' % fs_bas= e) + +def glibc_ptr_demangle(val, pointer_guard): + '''Undo effect of glibc's PTR_MANGLE()''' + return gdb.parse_and_eval('(((uint64_t)%s >> 0x11) | ((uint64_t)%s << = (64 - 0x11))) ^ (uint64_t)%s' % (val, val, pointer_guard)) + +def get_jmpbuf_regs(jmpbuf): + JB_RBX =3D 0 + JB_RBP =3D 1 + JB_R12 =3D 2 + JB_R13 =3D 3 + JB_R14 =3D 4 + JB_R15 =3D 5 + JB_RSP =3D 6 + JB_PC =3D 7 + + pointer_guard =3D get_glibc_pointer_guard() + return {'rbx': jmpbuf[JB_RBX], + 'rbp': glibc_ptr_demangle(jmpbuf[JB_RBP], pointer_guard), + 'rsp': glibc_ptr_demangle(jmpbuf[JB_RSP], pointer_guard), + 'r12': jmpbuf[JB_R12], + 'r13': jmpbuf[JB_R13], + 'r14': jmpbuf[JB_R14], + 'r15': jmpbuf[JB_R15], + 'rip': glibc_ptr_demangle(jmpbuf[JB_PC], pointer_guard) } + +def get_coroutine_regs(addr): + co =3D addr.cast(gdb.lookup_type('CoroutineUContext').pointer()) + return get_jmpbuf_regs(co['env']['__jmpbuf']) --=20 2.20.1 From nobody Sun Nov 9 23:29:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552480996821275.3086984506309; Wed, 13 Mar 2019 05:43:16 -0700 (PDT) Received: from localhost ([127.0.0.1]:43930 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Dx-0002Yl-AK for importer@patchew.org; Wed, 13 Mar 2019 08:43:09 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33251) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Bs-0001Ih-SM for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:02 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h43Bo-0005Hi-Vc for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:00 -0400 Received: from mx1.redhat.com ([209.132.183.28]:33702) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h43Bm-0005Fk-QN for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:40:56 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2C26899C1D; Wed, 13 Mar 2019 12:40:53 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-43.ams2.redhat.com [10.36.112.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5C3281001E6F; Wed, 13 Mar 2019 12:40:51 +0000 (UTC) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 13 Mar 2019 13:40:37 +0100 Message-Id: <20190313124042.12855-3-pbonzini@redhat.com> In-Reply-To: <20190313124042.12855-1-pbonzini@redhat.com> References: <20190313124042.12855-1-pbonzini@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Wed, 13 Mar 2019 12:40:53 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 2/7] coroutine: add x86 specific coroutine backend X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: fweimer@redhat.com, kwolf@redhat.com, richard.henderson@linaro.org, stefanha@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This backend is faster (100ns vs 150ns per switch on my laptop), but especially it will be possible to add CET support to it. Unlike the ucontext backend, it does not save any register state; all registers are clobbered in the CO_SWITCH asm, and as a result the compiler automatically saves/restores caller-save registers in qemu_coroutine_switch. This however means that it does not have register mangling, which is nicely provided by glibc to the ucontext backend. Signed-off-by: Paolo Bonzini --- configure | 10 ++ scripts/qemugdb/coroutine.py | 5 +- scripts/qemugdb/coroutine_x86.py | 21 +++ util/Makefile.objs | 1 + util/coroutine-x86.c | 220 +++++++++++++++++++++++++++++++ 5 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 scripts/qemugdb/coroutine_x86.py create mode 100644 util/coroutine-x86.c diff --git a/configure b/configure index cab830a4c9..42a7e479fd 100755 --- a/configure +++ b/configure @@ -5098,6 +5098,8 @@ fi if test "$coroutine" =3D ""; then if test "$mingw32" =3D "yes"; then coroutine=3Dwin32 + elif test "$cpu" =3D "x86_64"; then + coroutine=3Dx86 elif test "$ucontext_works" =3D "yes"; then coroutine=3Ducontext else @@ -5123,6 +5125,14 @@ else error_exit "only the 'windows' coroutine backend is valid for Window= s" fi ;; + x86) + if test "$mingw32" =3D "yes"; then + error_exit "only the 'windows' coroutine backend is valid for Window= s" + fi + if test "$cpu" !=3D "x86_64"; then + error_exit "the 'x86' backend is only valid for x86_64 hosts" + fi + ;; *) error_exit "unknown coroutine backend $coroutine" ;; diff --git a/scripts/qemugdb/coroutine.py b/scripts/qemugdb/coroutine.py index db2753d949..f716db22bb 100644 --- a/scripts/qemugdb/coroutine.py +++ b/scripts/qemugdb/coroutine.py @@ -10,14 +10,15 @@ # This work is licensed under the terms of the GNU GPL, version 2 # or later. See the COPYING file in the top-level directory. =20 -from . import coroutine_ucontext +from . import coroutine_ucontext, coroutine_x86 import gdb =20 VOID_PTR =3D gdb.lookup_type('void').pointer() UINTPTR_T =3D gdb.lookup_type('uintptr_t') =20 backends =3D { - 'CoroutineUContext': coroutine_ucontext + 'CoroutineUContext': coroutine_ucontext, + 'CoroutineX86': coroutine_x86 } =20 def coroutine_backend(): diff --git a/scripts/qemugdb/coroutine_x86.py b/scripts/qemugdb/coroutine_x= 86.py new file mode 100644 index 0000000000..05f830cdb8 --- /dev/null +++ b/scripts/qemugdb/coroutine_x86.py @@ -0,0 +1,21 @@ +#!/usr/bin/python + +# GDB debugging support +# +# Copyright 2019 Red Hat, Inc. +# +# Authors: +# Paolo Bonzini +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. + +import gdb + +U64_PTR =3D gdb.lookup_type('uint64_t').pointer() + +def get_coroutine_regs(addr): + addr =3D addr.cast(gdb.lookup_type('CoroutineX86').pointer()) + rsp =3D addr['sp'].cast(U64_PTR) + return {'rsp': rsp, + 'rip': rsp.dereference()} diff --git a/util/Makefile.objs b/util/Makefile.objs index 835fcd69e2..0808d86a19 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -38,6 +38,7 @@ util-obj-$(CONFIG_MEMBARRIER) +=3D sys_membarrier.o util-obj-y +=3D qemu-coroutine.o qemu-coroutine-lock.o qemu-coroutine-io.o util-obj-y +=3D qemu-coroutine-sleep.o util-obj-y +=3D coroutine-$(CONFIG_COROUTINE_BACKEND).o +coroutine-x86.o-cflags :=3D -mno-red-zone util-obj-y +=3D buffer.o util-obj-y +=3D timed-average.o util-obj-y +=3D base64.o diff --git a/util/coroutine-x86.c b/util/coroutine-x86.c new file mode 100644 index 0000000000..bcb9666700 --- /dev/null +++ b/util/coroutine-x86.c @@ -0,0 +1,220 @@ +/* + * x86-specific coroutine initialization code + * + * Copyright (C) 2006 Anthony Liguori + * Copyright (C) 2011 Kevin Wolf + * Copyright (C) 2019 Paolo Bonzini + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + */ + +#include "qemu/osdep.h" +#include "qemu-common.h" +#include "qemu/coroutine_int.h" + +#ifdef CONFIG_VALGRIND_H +#include +#endif + +#if defined(__SANITIZE_ADDRESS__) || __has_feature(address_sanitizer) +#ifdef CONFIG_ASAN_IFACE_FIBER +#define CONFIG_ASAN 1 +#include +#endif +#endif + +#define COROUTINE_SHADOW_STACK_SIZE 4096 + +typedef struct { + Coroutine base; + void *sp; + + void *stack; + size_t stack_size; + +#ifdef CONFIG_VALGRIND_H + unsigned int valgrind_stack_id; +#endif +} CoroutineX86; + +/** + * Per-thread coroutine bookkeeping + */ +static __thread CoroutineX86 leader; +static __thread Coroutine *current; + +static void finish_switch_fiber(void *fake_stack_save) +{ +#ifdef CONFIG_ASAN + const void *bottom_old; + size_t size_old; + + __sanitizer_finish_switch_fiber(fake_stack_save, &bottom_old, &size_ol= d); + + if (!leader.stack) { + leader.stack =3D (void *)bottom_old; + leader.stack_size =3D size_old; + } +#endif +} + +static void start_switch_fiber(void **fake_stack_save, + const void *bottom, size_t size) +{ +#ifdef CONFIG_ASAN + __sanitizer_start_switch_fiber(fake_stack_save, bottom, size); +#endif +} + +/* + * We hardcode all operands to specific registers so that we can write dow= n all the + * others in the clobber list. Note that action also needs to be hardcode= d so that + * it is the same register in all expansions of this macro. Also, we use = %rdi + * for the coroutine because that is the ABI's first argument register; + * coroutine_trampoline can then retrieve the current coroutine from there. + * + * Note that push and call would clobber the red zone. Makefile.objs comp= iles this + * file with -mno-red-zone. The alternative is to subtract/add 128 bytes = from rsp + * around the switch, with slightly lower cache performance. + */ +#define CO_SWITCH(from, to, action, jump) ({ = \ + int action_ =3D action; = \ + void *from_ =3D from; = \ + void *to_ =3D to; = \ + asm volatile( = \ + ".cfi_remember_state\n" = \ + "pushq %%rbp\n" /* save frame register on sour= ce stack */ \ + ".cfi_adjust_cfa_offset 8\n" = \ + ".cfi_rel_offset %%rbp, 0\n" = \ + "call 1f\n" /* switch continues at label 1= */ \ + "jmp 2f\n" /* switch back continues at la= bel 2 */ \ + = \ + "1: .cfi_adjust_cfa_offset 8\n" = \ + "movq %%rsp, %c[SP](%[FROM])\n" /* save source SP */ = \ + "movq %c[SP](%[TO]), %%rsp\n" /* load destination SP */ = \ + jump "\n" /* coroutine switch */ = \ + = \ + "2: .cfi_adjust_cfa_offset -8\n" = \ + "popq %%rbp\n" = \ + ".cfi_adjust_cfa_offset -8\n" = \ + ".cfi_restore_state\n" = \ + : "+a" (action_), [FROM] "+b" (from_), [TO] "+D" (to_) = \ + : [SP] "i" (offsetof(CoroutineX86, sp)) = \ + : "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11", "r12", "r13", "r1= 4", "r15", \ + "memory"); = \ + action_; = \ +}) + +static void __attribute__((__used__)) coroutine_trampoline(CoroutineX86 *s= elf) +{ + finish_switch_fiber(NULL); + + while (true) { + Coroutine *co =3D &self->base; + qemu_coroutine_switch(co, co->caller, COROUTINE_TERMINATE); + co->entry(co->entry_arg); + } +} + +Coroutine *qemu_coroutine_new(void) +{ + CoroutineX86 *co; + void *fake_stack_save =3D NULL; + + co =3D g_malloc0(sizeof(*co)); + co->stack_size =3D COROUTINE_STACK_SIZE; + co->stack =3D qemu_alloc_stack(&co->stack_size); + co->sp =3D co->stack + co->stack_size; + +#ifdef CONFIG_VALGRIND_H + co->valgrind_stack_id =3D + VALGRIND_STACK_REGISTER(co->stack, co->stack + co->stack_size); +#endif + + /* Immediately enter the coroutine once to pass it its address as the = argument */ + co->base.caller =3D qemu_coroutine_self(); + start_switch_fiber(&fake_stack_save, co->stack, co->stack_size); + CO_SWITCH(current, co, 0, "jmp coroutine_trampoline"); + finish_switch_fiber(fake_stack_save); + co->base.caller =3D NULL; + + return &co->base; +} + +#ifdef CONFIG_VALGRIND_H +#if defined(CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE) && !defined(__clang__) +/* Work around an unused variable in the valgrind.h macro... */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" +#endif +static inline void valgrind_stack_deregister(CoroutineX86 *co) +{ + VALGRIND_STACK_DEREGISTER(co->valgrind_stack_id); +} +#if defined(CONFIG_PRAGMA_DIAGNOSTIC_AVAILABLE) && !defined(__clang__) +#pragma GCC diagnostic pop +#endif +#endif + +void qemu_coroutine_delete(Coroutine *co_) +{ + CoroutineX86 *co =3D DO_UPCAST(CoroutineX86, base, co_); + +#ifdef CONFIG_VALGRIND_H + valgrind_stack_deregister(co); +#endif + + qemu_free_stack(co->stack, co->stack_size); + g_free(co); +} + +/* + * This function is marked noinline to prevent GCC from inlining it + * into coroutine_trampoline(). If we allow it to do that then it + * hoists the code to get the address of the TLS variable "current" + * out of the while() loop. This is an invalid transformation because + * qemu_coroutine_switch() may be called when running thread A but + * return in thread B, and so we might be in a different thread + * context each time round the loop. + */ +CoroutineAction __attribute__((noinline)) +qemu_coroutine_switch(Coroutine *from_, Coroutine *to_, + CoroutineAction action) +{ + CoroutineX86 *from =3D DO_UPCAST(CoroutineX86, base, from_); + CoroutineX86 *to =3D DO_UPCAST(CoroutineX86, base, to_); + void *fake_stack_save =3D NULL; + + current =3D to_; + + start_switch_fiber(action =3D=3D COROUTINE_TERMINATE ? + NULL : &fake_stack_save, to->stack, to->stack_size); + action =3D CO_SWITCH(from, to, action, "ret"); + finish_switch_fiber(fake_stack_save); + + return action; +} + +Coroutine *qemu_coroutine_self(void) +{ + if (!current) { + current =3D &leader.base; + } + return current; +} + +bool qemu_in_coroutine(void) +{ + return current && current->caller; +} --=20 2.20.1 From nobody Sun Nov 9 23:29:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552481164791276.7761229221171; Wed, 13 Mar 2019 05:46:04 -0700 (PDT) Received: from localhost ([127.0.0.1]:43991 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Gk-00059T-Lp for importer@patchew.org; Wed, 13 Mar 2019 08:46:02 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33268) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Bu-0001K4-Qr for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h43Bs-0005JH-SD for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:02 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56340) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h43Bo-0005Gk-TN for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:40:58 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 581EB30FAF16; Wed, 13 Mar 2019 12:40:55 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-43.ams2.redhat.com [10.36.112.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9A4331001E6A; Wed, 13 Mar 2019 12:40:53 +0000 (UTC) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 13 Mar 2019 13:40:38 +0100 Message-Id: <20190313124042.12855-4-pbonzini@redhat.com> In-Reply-To: <20190313124042.12855-1-pbonzini@redhat.com> References: <20190313124042.12855-1-pbonzini@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Wed, 13 Mar 2019 12:40:55 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 3/7] configure: add CET support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: fweimer@redhat.com, kwolf@redhat.com, richard.henderson@linaro.org, stefanha@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" CET requires object files to note which features are supported. The linker will merge them to the set of features that are supported by all object files. The compiler creates these notes when the -fcf-protection option is passed, but we have to blacklist some object files that only support a subset of the full CET feature set. The next patches will improve the situation so that QEMU can be built with full protection. Signed-off-by: Paolo Bonzini --- configure | 27 +++++++++++++++++++++++++++ Makefile.target | 3 +++ util/Makefile.objs | 5 +++++ 3 files changed, 35 insertions(+) diff --git a/configure b/configure index 42a7e479fd..4470fe8e74 100755 --- a/configure +++ b/configure @@ -446,6 +446,7 @@ win_sdk=3D"no" want_tools=3D"yes" libiscsi=3D"" libnfs=3D"" +cet=3D"no" # leave it disabled until we can test performance coroutine=3D"" coroutine_pool=3D"" debug_stack_usage=3D"no" @@ -1246,6 +1247,10 @@ for opt do ;; --with-pkgversion=3D*) pkgversion=3D"$optarg" ;; + --enable-cet) cet=3D"yes" + ;; + --disable-cet) cet=3D"no" + ;; --with-coroutine=3D*) coroutine=3D"$optarg" ;; --disable-coroutine-pool) coroutine_pool=3D"no" @@ -1757,6 +1762,7 @@ disabled with --disable-FEATURE, default is enabled i= f available: lzfse support of lzfse compression library (for reading lzfse-compressed dmg images) seccomp seccomp support + cet Control-flow Enforcement Technology coroutine-pool coroutine freelist (better performance) glusterfs GlusterFS backend tpm TPM support @@ -5074,6 +5080,23 @@ if have_backend "dtrace"; then fi fi =20 +########################################## +# detect CET support in the toolchain + +if test "$cet" !=3D no; then + write_c_skeleton; + if ! compile_prog "-fcf-protection" "" ; then + if test "$cet" =3D yes; then + feature_not_found "cet" 'CET is not supported by your toolchain' + fi + cet=3Dno + fi +fi +if test "$cet" =3D ""; then + cet=3Dyes + QEMU_CFLAGS=3D"-fcf-protection $QEMU_CFLAGS" +fi + ########################################## # check and set a backend for coroutine =20 @@ -6258,6 +6281,7 @@ echo "netmap support $netmap" echo "Linux AIO support $linux_aio" echo "ATTR/XATTR support $attr" echo "Install blobs $blobs" +echo "CET support $cet" echo "KVM support $kvm" echo "HAX support $hax" echo "HVF support $hvf" @@ -6468,6 +6492,9 @@ fi if test "$profiler" =3D "yes" ; then echo "CONFIG_PROFILER=3Dy" >> $config_host_mak fi +if test "$cet" =3D "yes" ; then + echo "CONFIG_CET=3Dy" >> $config_host_mak +fi if test "$slirp" !=3D "no"; then echo "CONFIG_SLIRP=3Dy" >> $config_host_mak echo "CONFIG_SMBD_COMMAND=3D\"$smbd\"" >> $config_host_mak diff --git a/Makefile.target b/Makefile.target index d8048aab8f..fa143d7b4b 100644 --- a/Makefile.target +++ b/Makefile.target @@ -113,6 +113,9 @@ obj-y +=3D exec.o obj-y +=3D accel/ obj-$(CONFIG_TCG) +=3D tcg/tcg.o tcg/tcg-op.o tcg/tcg-op-vec.o tcg/tcg-op-= gvec.o obj-$(CONFIG_TCG) +=3D tcg/tcg-common.o tcg/optimize.o +ifeq ($(CONFIG_CET),y) +tcg/tcg.o-cflags :=3D -fcf-protection=3Dreturn +endif obj-$(CONFIG_TCG_INTERPRETER) +=3D tcg/tci.o obj-$(CONFIG_TCG_INTERPRETER) +=3D disas/tci.o obj-$(CONFIG_TCG) +=3D fpu/softfloat.o diff --git a/util/Makefile.objs b/util/Makefile.objs index 0808d86a19..93a8397aae 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -39,6 +39,11 @@ util-obj-y +=3D qemu-coroutine.o qemu-coroutine-lock.o q= emu-coroutine-io.o util-obj-y +=3D qemu-coroutine-sleep.o util-obj-y +=3D coroutine-$(CONFIG_COROUTINE_BACKEND).o coroutine-x86.o-cflags :=3D -mno-red-zone +ifeq ($(CONFIG_CET),y) +coroutine-sigaltstack.o-cflags :=3D -fcf-protection=3Dbranch +coroutine-ucontext.o-cflags :=3D -fcf-protection=3Dbranch +coroutine-x86.o-cflags +=3D -fcf-protection=3Dbranch +endif util-obj-y +=3D buffer.o util-obj-y +=3D timed-average.o util-obj-y +=3D base64.o --=20 2.20.1 From nobody Sun Nov 9 23:29:57 2025 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552481152895714.0376703055618; Wed, 13 Mar 2019 05:45:52 -0700 (PDT) Received: from localhost ([127.0.0.1]:43989 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43GV-0004yO-O4 for importer@patchew.org; Wed, 13 Mar 2019 08:45:47 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33286) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Bx-0001MJ-FW for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h43Bu-0005LB-PI for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:42626) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h43Bs-0005I1-Ad for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:00 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 86D7A30944E2; Wed, 13 Mar 2019 12:40:57 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-43.ams2.redhat.com [10.36.112.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id C3F5A1001E6F; Wed, 13 Mar 2019 12:40:55 +0000 (UTC) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 13 Mar 2019 13:40:39 +0100 Message-Id: <20190313124042.12855-5-pbonzini@redhat.com> In-Reply-To: <20190313124042.12855-1-pbonzini@redhat.com> References: <20190313124042.12855-1-pbonzini@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.40]); Wed, 13 Mar 2019 12:40:57 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 4/7] tcg: add tcg_out_start X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: fweimer@redhat.com, kwolf@redhat.com, richard.henderson@linaro.org, stefanha@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" This function is called at the beginning of any translation block. We will use it to emit ENDBR32 or ENDBR64 annotations for x86 CET. Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- tcg/aarch64/tcg-target.inc.c | 4 ++++ tcg/arm/tcg-target.inc.c | 4 ++++ tcg/i386/tcg-target.inc.c | 4 ++++ tcg/mips/tcg-target.inc.c | 4 ++++ tcg/ppc/tcg-target.inc.c | 4 ++++ tcg/riscv/tcg-target.inc.c | 4 ++++ tcg/s390/tcg-target.inc.c | 4 ++++ tcg/sparc/tcg-target.inc.c | 4 ++++ tcg/tcg.c | 2 ++ tcg/tci/tcg-target.inc.c | 4 ++++ 10 files changed, 38 insertions(+) diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c index d57f9e500f..885cb48988 100644 --- a/tcg/aarch64/tcg-target.inc.c +++ b/tcg/aarch64/tcg-target.inc.c @@ -2524,6 +2524,10 @@ QEMU_BUILD_BUG_ON(FRAME_SIZE >=3D (1 << 14)); /* We're expecting to use a single ADDI insn. */ QEMU_BUILD_BUG_ON(FRAME_SIZE - PUSH_SIZE > 0xfff); =20 +static inline void tcg_out_start(TCGContext *s) +{ +} + static void tcg_target_qemu_prologue(TCGContext *s) { TCGReg r; diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c index 2245a8aeb9..4b0df86074 100644 --- a/tcg/arm/tcg-target.inc.c +++ b/tcg/arm/tcg-target.inc.c @@ -2270,6 +2270,10 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int c= ount) } } =20 +static inline void tcg_out_start(TCGContext *s) +{ +} + /* Compute frame size via macros, to share between tcg_target_qemu_prologue and tcg_register_jit. */ =20 diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index e0670e5098..781b1faec2 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -3497,6 +3497,10 @@ static const int tcg_target_callee_save_regs[] =3D { + TCG_TARGET_STACK_ALIGN - 1) \ & ~(TCG_TARGET_STACK_ALIGN - 1)) =20 +static inline void tcg_out_start(TCGContext *s) +{ +} + /* Generate global QEMU prologue and epilogue code */ static void tcg_target_qemu_prologue(TCGContext *s) { diff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c index 8a92e916dd..b954166ad1 100644 --- a/tcg/mips/tcg-target.inc.c +++ b/tcg/mips/tcg-target.inc.c @@ -2469,6 +2469,10 @@ static tcg_insn_unit *align_code_ptr(TCGContext *s) return s->code_ptr; } =20 +static inline void tcg_out_start(TCGContext *s) +{ +} + /* Stack frame parameters. */ #define REG_SIZE (TCG_TARGET_REG_BITS / 8) #define SAVE_SIZE ((int)ARRAY_SIZE(tcg_target_callee_save_regs) * REG_SIZ= E) diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c index 773690f1d9..92aae6e77d 100644 --- a/tcg/ppc/tcg-target.inc.c +++ b/tcg/ppc/tcg-target.inc.c @@ -1906,6 +1906,10 @@ static void tcg_out_nop_fill(tcg_insn_unit *p, int c= ount) } } =20 +static inline void tcg_out_start(TCGContext *s) +{ +} + /* Parameters for function call generation, used in tcg.c. */ #define TCG_TARGET_STACK_ALIGN 16 #define TCG_TARGET_EXTEND_ARGS 1 diff --git a/tcg/riscv/tcg-target.inc.c b/tcg/riscv/tcg-target.inc.c index b785f4acb7..04a6aed27d 100644 --- a/tcg/riscv/tcg-target.inc.c +++ b/tcg/riscv/tcg-target.inc.c @@ -1790,6 +1790,10 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOp= code op) } } =20 +static inline void tcg_out_start(TCGContext *s) +{ +} + static const int tcg_target_callee_save_regs[] =3D { TCG_REG_S0, /* used for the global env (TCG_AREG0) */ TCG_REG_S1, diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c index 7db90b3bae..f867d77a36 100644 --- a/tcg/s390/tcg-target.inc.c +++ b/tcg/s390/tcg-target.inc.c @@ -2495,6 +2495,10 @@ static void query_s390_facilities(void) } } =20 +static inline void tcg_out_start(TCGContext *s) +{ +} + static void tcg_target_init(TCGContext *s) { query_s390_facilities(); diff --git a/tcg/sparc/tcg-target.inc.c b/tcg/sparc/tcg-target.inc.c index 7a61839dc1..f795e78153 100644 --- a/tcg/sparc/tcg-target.inc.c +++ b/tcg/sparc/tcg-target.inc.c @@ -1004,6 +1004,10 @@ static void build_trampolines(TCGContext *s) } #endif =20 +static inline void tcg_out_start(TCGContext *s) +{ +} + /* Generate global QEMU prologue and epilogue code */ static void tcg_target_qemu_prologue(TCGContext *s) { diff --git a/tcg/tcg.c b/tcg/tcg.c index 9b2bf7f439..368a3ec5b3 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -100,6 +100,7 @@ static void tcg_register_jit_int(void *buf, size_t size, /* Forward declarations for functions declared and used in tcg-target.inc.= c. */ static const char *target_parse_constraint(TCGArgConstraint *ct, const char *ct_str, TCGType typ= e); +static void tcg_out_start(TCGContext *s); static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg= 1, intptr_t arg2); static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg ar= g); @@ -3926,6 +3927,7 @@ int tcg_gen_code(TCGContext *s, TranslationBlock *tb) #endif =20 num_insns =3D -1; + tcg_out_start(s); QTAILQ_FOREACH(op, &s->ops, link) { TCGOpcode opc =3D op->opc; =20 diff --git a/tcg/tci/tcg-target.inc.c b/tcg/tci/tcg-target.inc.c index 0015a98485..cb90012999 100644 --- a/tcg/tci/tcg-target.inc.c +++ b/tcg/tci/tcg-target.inc.c @@ -889,6 +889,10 @@ static void tcg_target_init(TCGContext *s) CPU_TEMP_BUF_NLONGS * sizeof(long)); } =20 +static inline void tcg_out_start(void) +{ +} + /* Generate global QEMU prologue and epilogue code. */ static inline void tcg_target_qemu_prologue(TCGContext *s) { --=20 2.20.1 From nobody Sun Nov 9 23:29:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552481273153887.442681585375; Wed, 13 Mar 2019 05:47:53 -0700 (PDT) Received: from localhost ([127.0.0.1]:44015 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43IT-0006XE-5Q for importer@patchew.org; Wed, 13 Mar 2019 08:47:49 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33287) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Bx-0001ML-Fd for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h43Bv-0005Lb-Qo for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:05 -0400 Received: from mx1.redhat.com ([209.132.183.28]:23378) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h43Bs-0005Iq-R0 for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:02 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E7EA3C066441; Wed, 13 Mar 2019 12:40:59 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-43.ams2.redhat.com [10.36.112.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id EC6601001E6F; Wed, 13 Mar 2019 12:40:57 +0000 (UTC) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 13 Mar 2019 13:40:40 +0100 Message-Id: <20190313124042.12855-6-pbonzini@redhat.com> In-Reply-To: <20190313124042.12855-1-pbonzini@redhat.com> References: <20190313124042.12855-1-pbonzini@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Wed, 13 Mar 2019 12:40:59 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 5/7] tcg/i386: add support for IBT X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: fweimer@redhat.com, kwolf@redhat.com, richard.henderson@linaro.org, stefanha@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Add endbr annotations before indirect branch targets. This lets QEMU enable IBT even for TCG-enabled builds. Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- Makefile.target | 2 ++ configure | 9 +++++++++ tcg/i386/tcg-target.inc.c | 14 ++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/Makefile.target b/Makefile.target index fa143d7b4b..df413c9b7f 100644 --- a/Makefile.target +++ b/Makefile.target @@ -114,8 +114,10 @@ obj-y +=3D accel/ obj-$(CONFIG_TCG) +=3D tcg/tcg.o tcg/tcg-op.o tcg/tcg-op-vec.o tcg/tcg-op-= gvec.o obj-$(CONFIG_TCG) +=3D tcg/tcg-common.o tcg/optimize.o ifeq ($(CONFIG_CET),y) +ifneq ($(CONFIG_CET_TCG),y) tcg/tcg.o-cflags :=3D -fcf-protection=3Dreturn endif +endif obj-$(CONFIG_TCG_INTERPRETER) +=3D tcg/tci.o obj-$(CONFIG_TCG_INTERPRETER) +=3D disas/tci.o obj-$(CONFIG_TCG) +=3D fpu/softfloat.o diff --git a/configure b/configure index 4470fe8e74..4e553e521b 100755 --- a/configure +++ b/configure @@ -5096,6 +5096,11 @@ if test "$cet" =3D ""; then cet=3Dyes QEMU_CFLAGS=3D"-fcf-protection $QEMU_CFLAGS" fi +if test "$cpu" =3D "x86_64"; then + cet_tcg=3Dyes +else + cet_tcg=3Dno +fi =20 ########################################## # check and set a backend for coroutine @@ -6290,6 +6295,7 @@ echo "TCG support $tcg" if test "$tcg" =3D "yes" ; then echo "TCG debug enabled $debug_tcg" echo "TCG interpreter $tcg_interpreter" + echo "TCG CET support $cet_tcg" fi echo "malloc trim support $malloc_trim" echo "RDMA support $rdma" @@ -6495,6 +6501,9 @@ fi if test "$cet" =3D "yes" ; then echo "CONFIG_CET=3Dy" >> $config_host_mak fi +if test "$cet_tcg" =3D "yes" ; then + echo "CONFIG_CET_TCG=3Dy" >> $config_host_mak +fi if test "$slirp" !=3D "no"; then echo "CONFIG_SLIRP=3Dy" >> $config_host_mak echo "CONFIG_SMBD_COMMAND=3D\"$smbd\"" >> $config_host_mak diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c index 781b1faec2..4d1f80c1b2 100644 --- a/tcg/i386/tcg-target.inc.c +++ b/tcg/i386/tcg-target.inc.c @@ -808,6 +808,17 @@ static inline void tgen_arithr(TCGContext *s, int subo= p, int dest, int src) tcg_out_modrm(s, OPC_ARITH_GvEv + (subop << 3) + ext, dest, src); } =20 +static void tcg_out_endbr(TCGContext *s) +{ +#if defined __CET__ && (__CET__ & 1) +#ifdef __x86_64__ + tcg_out32(s, 0xfa1e0ff3); +#else + tcg_out32(s, 0xfb1e0ff3); +#endif +#endif +} + static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg ar= g) { int rexw =3D 0; @@ -3499,6 +3510,7 @@ static const int tcg_target_callee_save_regs[] =3D { =20 static inline void tcg_out_start(TCGContext *s) { + tcg_out_endbr(s); } =20 /* Generate global QEMU prologue and epilogue code */ @@ -3514,6 +3526,7 @@ static void tcg_target_qemu_prologue(TCGContext *s) CPU_TEMP_BUF_NLONGS * sizeof(long)); =20 /* Save all callee saved registers. */ + tcg_out_endbr(s); for (i =3D 0; i < ARRAY_SIZE(tcg_target_callee_save_regs); i++) { tcg_out_push(s, tcg_target_callee_save_regs[i]); } @@ -3553,6 +3566,7 @@ static void tcg_target_qemu_prologue(TCGContext *s) * and fall through to the rest of the epilogue. */ s->code_gen_epilogue =3D s->code_ptr; + tcg_out_endbr(s); tcg_out_movi(s, TCG_TYPE_REG, TCG_REG_EAX, 0); =20 /* TB epilogue */ --=20 2.20.1 From nobody Sun Nov 9 23:29:57 2025 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552481150156135.44236885111673; Wed, 13 Mar 2019 05:45:50 -0700 (PDT) Received: from localhost ([127.0.0.1]:43966 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43GL-0004kn-KB for importer@patchew.org; Wed, 13 Mar 2019 08:45:37 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33313) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43By-0001Mw-KC for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h43Bx-0005MM-E9 for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:06 -0400 Received: from mx1.redhat.com ([209.132.183.28]:47076) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h43Bv-0005L2-Hb for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:03 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2F27731587B0; Wed, 13 Mar 2019 12:41:02 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-43.ams2.redhat.com [10.36.112.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 61C001001E6A; Wed, 13 Mar 2019 12:41:00 +0000 (UTC) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 13 Mar 2019 13:40:41 +0100 Message-Id: <20190313124042.12855-7-pbonzini@redhat.com> In-Reply-To: <20190313124042.12855-1-pbonzini@redhat.com> References: <20190313124042.12855-1-pbonzini@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Wed, 13 Mar 2019 12:41:02 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 6/7] linux-user: add IBT support to x86 safe-syscall.S X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: fweimer@redhat.com, kwolf@redhat.com, richard.henderson@linaro.org, stefanha@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Because safe-syscall.S does not go through the C compiler, the .note.gnu.property note has to be added manually. Safe syscalls do not involve any indirect branch or stack unwinding, so they are trivially safe for IBT or shadow stacks. Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- linux-user/host/i386/safe-syscall.inc.S | 19 +++++++++++++++++++ linux-user/host/x86_64/safe-syscall.inc.S | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/linux-user/host/i386/safe-syscall.inc.S b/linux-user/host/i386= /safe-syscall.inc.S index 9e58fc6504..6c6d568d62 100644 --- a/linux-user/host/i386/safe-syscall.inc.S +++ b/linux-user/host/i386/safe-syscall.inc.S @@ -98,3 +98,22 @@ safe_syscall_end: .cfi_endproc =20 .size safe_syscall_base, .-safe_syscall_base + + .pushsection ".note.gnu.property", "a" + .p2align 2 + .long 1f - 0f /* name length. */ + .long 4f - 1f /* data length. */ + .long 5 /* NT_GNU_PROPERTY_TYPE_0. */ +0: + .asciz "GNU" /* vendor name. */ + .p2align 2 +1: + /* GNU_PROPERTY_X86_FEATURE_1_AND. */ + .long 0xc0000002 /* pr_type. */ + .long 3f - 2f /* pr_datasz. */ +2: + .long 0x3 /* IBT, SHSTK */ +3: + .p2align 2 +4: + .popsection diff --git a/linux-user/host/x86_64/safe-syscall.inc.S b/linux-user/host/x8= 6_64/safe-syscall.inc.S index f36992daa3..e1a57db338 100644 --- a/linux-user/host/x86_64/safe-syscall.inc.S +++ b/linux-user/host/x86_64/safe-syscall.inc.S @@ -89,3 +89,22 @@ safe_syscall_end: .cfi_endproc =20 .size safe_syscall_base, .-safe_syscall_base + + .pushsection ".note.gnu.property", "a" + .p2align 3 + .long 1f - 0f /* name length. */ + .long 4f - 1f /* data length. */ + .long 5 /* NT_GNU_PROPERTY_TYPE_0. */ +0: + .asciz "GNU" /* vendor name. */ + .p2align 3 +1: + /* GNU_PROPERTY_X86_FEATURE_1_AND. */ + .long 0xc0000002 /* pr_type. */ + .long 3f - 2f /* pr_datasz. */ +2: + .long 0x3 /* IBT, SHSTK */ +3: + .p2align 3 +4: + .popsection --=20 2.20.1 From nobody Sun Nov 9 23:29:57 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552481001988678.7155787088217; Wed, 13 Mar 2019 05:43:21 -0700 (PDT) Received: from localhost ([127.0.0.1]:43932 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43E2-0002d7-SE for importer@patchew.org; Wed, 13 Mar 2019 08:43:14 -0400 Received: from eggs.gnu.org ([209.51.188.92]:33329) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h43Bz-0001N0-PM for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h43By-0005N8-KH for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:07 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56570) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h43Bx-0005Lx-Cv for qemu-devel@nongnu.org; Wed, 13 Mar 2019 08:41:06 -0400 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6C3807C0A8; Wed, 13 Mar 2019 12:41:04 +0000 (UTC) Received: from donizetti.redhat.com (ovpn-112-43.ams2.redhat.com [10.36.112.43]) by smtp.corp.redhat.com (Postfix) with ESMTP id 9D51E1001DE9; Wed, 13 Mar 2019 12:41:02 +0000 (UTC) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 13 Mar 2019 13:40:42 +0100 Message-Id: <20190313124042.12855-8-pbonzini@redhat.com> In-Reply-To: <20190313124042.12855-1-pbonzini@redhat.com> References: <20190313124042.12855-1-pbonzini@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 13 Mar 2019 12:41:04 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH 7/7] coroutine-x86: add CET shadow stack support X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: fweimer@redhat.com, kwolf@redhat.com, richard.henderson@linaro.org, stefanha@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Note that the ABI is not yet part of Linux, so this patch is kinda experimental. Signed-off-by: Paolo Bonzini --- configure | 14 ++++++++ util/Makefile.objs | 1 - util/coroutine-x86.c | 80 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 92 insertions(+), 3 deletions(-) diff --git a/configure b/configure index 4e553e521b..43e2321d3d 100755 --- a/configure +++ b/configure @@ -5090,6 +5090,20 @@ if test "$cet" !=3D no; then feature_not_found "cet" 'CET is not supported by your toolchain' fi cet=3Dno + else + if test $cpu =3D x86_64; then + # only needed by coroutine-x86.c, however it should be rare to have + # CET support in the compiler but not in binutils + cat > $TMPC << EOF +int main(void) { asm("rdsspq %%rax" : : : "rax"); } +EOF + if ! compile_prog "" "" ; then + if test "$cet" =3D yes; then + feature_not_found "cet" 'CET is not supported by your toolchain' + fi + cet=3Dno + fi + fi fi fi if test "$cet" =3D ""; then diff --git a/util/Makefile.objs b/util/Makefile.objs index 93a8397aae..ce1ea310af 100644 --- a/util/Makefile.objs +++ b/util/Makefile.objs @@ -42,7 +42,6 @@ coroutine-x86.o-cflags :=3D -mno-red-zone ifeq ($(CONFIG_CET),y) coroutine-sigaltstack.o-cflags :=3D -fcf-protection=3Dbranch coroutine-ucontext.o-cflags :=3D -fcf-protection=3Dbranch -coroutine-x86.o-cflags +=3D -fcf-protection=3Dbranch endif util-obj-y +=3D buffer.o util-obj-y +=3D timed-average.o diff --git a/util/coroutine-x86.c b/util/coroutine-x86.c index bcb9666700..d55f07dc92 100644 --- a/util/coroutine-x86.c +++ b/util/coroutine-x86.c @@ -22,6 +22,16 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/coroutine_int.h" +#include "qemu/error-report.h" + +#ifdef CONFIG_CET +#include +#include +int arch_prctl(int code, unsigned long addr); +#ifndef ARCH_X86_CET_ALLOC_SHSTK +#define ARCH_X86_CET_ALLOC_SHSTK 0x3004 +#endif +#endif =20 #ifdef CONFIG_VALGRIND_H #include @@ -39,10 +49,14 @@ typedef struct { Coroutine base; void *sp; + void *ssp; =20 void *stack; size_t stack_size; =20 + /* CET shadow stack */ + void *sstack; + size_t sstack_size; #ifdef CONFIG_VALGRIND_H unsigned int valgrind_stack_id; #endif @@ -77,6 +91,30 @@ static void start_switch_fiber(void **fake_stack_save, #endif } =20 +static bool have_cet(void) +{ +#if defined CONFIG_CET + uint64_t ssp; + asm ("xor %0, %0; rdsspq %0\n" : "=3Drm" (ssp)); + return !!ssp; +#else + return 0; +#endif +} + +static void *cet_alloc_sstack(size_t sz) +{ +#if defined CONFIG_CET + uint64_t arg =3D sz; + if (arch_prctl(ARCH_X86_CET_ALLOC_SHSTK, (unsigned long) &arg) < 0) { + abort(); + } + + return (void *)arg; +#else + abort(); +#endif +} /* * We hardcode all operands to specific registers so that we can write dow= n all the * others in the clobber list. Note that action also needs to be hardcode= d so that @@ -87,6 +125,26 @@ static void start_switch_fiber(void **fake_stack_save, * Note that push and call would clobber the red zone. Makefile.objs comp= iles this * file with -mno-red-zone. The alternative is to subtract/add 128 bytes = from rsp * around the switch, with slightly lower cache performance. + * + * The RSTORSSP and SAVEPREVSSP instructions are intricate. In a nutshell= they are: + * + * RSTORSSP(mem): oldSSP =3D SSP + * SSP =3D *mem + * *SSP =3D oldSSP + * + * SAVEPREVSSP: oldSSP =3D shadow_stack_pop() + * *(oldSSP - 8) =3D oldSSP # "push" to old s= hadow stack + * + * Therefore, RSTORSSP(mem) followed by SAVEPREVSSP is the same as + * + * shadow_stack_push(SSP) + * SSP =3D *mem + * shadow_stack_pop() + * + * From the simplified description you can see that co->ssp, being stored = before + * the RSTORSSP+SAVEPREVSSP sequence, points to the top actual entry of th= e shadow + * stack, not to the restore token. Hence we use an offset of -8 in the o= perand + * of rstorssp. */ #define CO_SWITCH(from, to, action, jump) ({ = \ int action_ =3D action; = \ @@ -101,7 +159,15 @@ static void start_switch_fiber(void **fake_stack_save, "jmp 2f\n" /* switch back continues at la= bel 2 */ \ = \ "1: .cfi_adjust_cfa_offset 8\n" = \ - "movq %%rsp, %c[SP](%[FROM])\n" /* save source SP */ = \ + "xor %%rbp, %%rbp\n" /* use old frame pointer as sc= ratch reg */ \ + "rdsspq %%rbp\n" = \ + "test %%rbp, %%rbp\n" /* if CET is on... */ = \ + "jz 9f\n" = \ + "movq %%rbp, %c[SSP](%[FROM])\n" /* ... save source shadow SP, = */ \ + "movq %c[SSP](%[TO]), %%rbp\n" /* restore destination shadow = stack, */ \ + "rstorssp -8(%%rbp)\n" = \ + "saveprevssp\n" /* and save source shadow SP t= oken */ \ + "9: movq %%rsp, %c[SP](%[FROM])\n" /* save source SP */ = \ "movq %c[SP](%[TO]), %%rsp\n" /* load destination SP */ = \ jump "\n" /* coroutine switch */ = \ = \ @@ -110,7 +176,8 @@ static void start_switch_fiber(void **fake_stack_save, ".cfi_adjust_cfa_offset -8\n" = \ ".cfi_restore_state\n" = \ : "+a" (action_), [FROM] "+b" (from_), [TO] "+D" (to_) = \ - : [SP] "i" (offsetof(CoroutineX86, sp)) = \ + : [SP] "i" (offsetof(CoroutineX86, sp)), = \ + [SSP] "i" (offsetof(CoroutineX86, ssp)) = \ : "rcx", "rdx", "rsi", "r8", "r9", "r10", "r11", "r12", "r13", "r1= 4", "r15", \ "memory"); = \ action_; = \ @@ -139,6 +206,12 @@ Coroutine *qemu_coroutine_new(void) co->stack =3D qemu_alloc_stack(&co->stack_size); co->sp =3D co->stack + co->stack_size; =20 + if (have_cet()) { + co->sstack_size =3D COROUTINE_SHADOW_STACK_SIZE; + co->sstack =3D cet_alloc_sstack(co->sstack_size); + co->ssp =3D co->sstack + co->sstack_size; + } + #ifdef CONFIG_VALGRIND_H co->valgrind_stack_id =3D VALGRIND_STACK_REGISTER(co->stack, co->stack + co->stack_size); @@ -178,6 +251,9 @@ void qemu_coroutine_delete(Coroutine *co_) #endif =20 qemu_free_stack(co->stack, co->stack_size); + if (co->sstack) { + munmap(co->sstack, co->sstack_size); + } g_free(co); } =20 --=20 2.20.1