From patchwork Wed Jul 10 06:29:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958717 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ApfrPFIO; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJnyn1vSTz20MK for ; Wed, 10 Jul 2024 16:29:53 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQpi-0008D1-Fv; Wed, 10 Jul 2024 02:29:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpb-0008AI-VB for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpZ-0000u6-W2 for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592972; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zysmERLOD7LqFn2JG/XTo8hRSGrS1y0PB/cgSbGIed8=; b=ApfrPFIO83ayI6RbViraM+l3GHDnBm89QAdStO/ZnI8mISl+M8FqUB+nYVEQ4BBdsx9bxT drTEOzZmtR2eFEFCP/LkfYetV4LK6JCWT4aFFmfhtuFsY93vSWVipNuAapZ1DwYp7lu8ar lo0RZ7dVoVnJDv6sAWRMWjRvl6B7g00= Received: from mail-lf1-f71.google.com (mail-lf1-f71.google.com [209.85.167.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-2-ne1ETC2cNqadSX46lAMe4A-1; Wed, 10 Jul 2024 02:29:28 -0400 X-MC-Unique: ne1ETC2cNqadSX46lAMe4A-1 Received: by mail-lf1-f71.google.com with SMTP id 2adb3069b0e04-52e9557e312so1590805e87.0 for ; Tue, 09 Jul 2024 23:29:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592966; x=1721197766; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zysmERLOD7LqFn2JG/XTo8hRSGrS1y0PB/cgSbGIed8=; b=IlA/O6bK34wE6nMHwYZT82J3GvUXXPVBk4F+JTvLhfuY99eSQgy7pt4hCkx7eNLcRW sg38vAPoCAKl0eb8obSKEpZzO+o4v3DGPIoDWIfJ6M5O7PINUKrhJ/RsHllhBv7cjaFL XHWwlZK0t/lcI6B0vg9GRGCnOjNN/16MRZg85dT8EuQOqbSxdN/+nV0C1DBRQ7YC4f23 P8+GaFMjkfJhfJvcEgPj4ZHRc343qWlN4JbFuAkHlEgvqvwJrvLYL5449lft3Q1+zkdh pBsQnDjSKqE0AAqdW3BjVm/adTpRQr9+vP+zRMk/tqNehjtbXUl72iuFKeZw28Bhju3Y Qcuw== X-Gm-Message-State: AOJu0YwKa/kt1rk7U1YOk5a4/pNzaWHmnOCHflBVD3jntHeRu2cmJw5k i2aoE74m0slFsAXr3vBd/a0Z5fe26LWgMTEN1g6CwpGmKaTaZz4/qeNPjJRluq0tbQjED9HAxsj Q/WGWhO5i1qdoFMtE2/E71vghhuAxBtuYbxZTix6XajdSQ296szYhGKorjoJeZNHBQD1Qumh64N CjAhLy4ix9dk5IktUv+KD8aQp34Di5Sr0+vCcu X-Received: by 2002:ac2:4288:0:b0:52c:e121:c927 with SMTP id 2adb3069b0e04-52eb99d6d24mr2346022e87.62.1720592965833; Tue, 09 Jul 2024 23:29:25 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHbYKoehxtbHyVU8PvPvNJOr4IYcSzGJznpnb+AWlb7UDsEwGOR/S1BWAKz4v/wl8kvuxPmKw== X-Received: by 2002:ac2:4288:0:b0:52c:e121:c927 with SMTP id 2adb3069b0e04-52eb99d6d24mr2346008e87.62.1720592965300; Tue, 09 Jul 2024 23:29:25 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4266f736939sm68500425e9.37.2024.07.09.23.29.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:23 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 01/10] target/i386/tcg: Remove SEG_ADDL Date: Wed, 10 Jul 2024 08:29:11 +0200 Message-ID: <20240710062920.73063-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Richard Henderson This truncation is now handled by MMU_*32_IDX. The introduction of MMU_*32_IDX in fact applied correct 32-bit wraparound to 16-bit accesses with a high segment base (e.g. big real mode or vm86 mode), which did not use SEG_ADDL. Signed-off-by: Richard Henderson Link: https://lore.kernel.org/r/20240617161210.4639-3-richard.henderson@linaro.org Signed-off-by: Paolo Bonzini --- target/i386/tcg/seg_helper.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index aee3d19f29b..19d6b41a589 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -579,10 +579,6 @@ int exception_has_error_code(int intno) } while (0) #endif -/* in 64-bit machines, this can overflow. So this segment addition macro - * can be used to trim the value to 32-bit whenever needed */ -#define SEG_ADDL(ssp, sp, sp_mask) ((uint32_t)((ssp) + (sp & (sp_mask)))) - /* XXX: add a is_user flag to have proper security support */ #define PUSHW_RA(ssp, sp, sp_mask, val, ra) \ { \ @@ -593,7 +589,7 @@ int exception_has_error_code(int intno) #define PUSHL_RA(ssp, sp, sp_mask, val, ra) \ { \ sp -= 4; \ - cpu_stl_kernel_ra(env, SEG_ADDL(ssp, sp, sp_mask), (uint32_t)(val), ra); \ + cpu_stl_kernel_ra(env, (ssp) + (sp & (sp_mask)), (val), ra); \ } #define POPW_RA(ssp, sp, sp_mask, val, ra) \ @@ -604,7 +600,7 @@ int exception_has_error_code(int intno) #define POPL_RA(ssp, sp, sp_mask, val, ra) \ { \ - val = (uint32_t)cpu_ldl_kernel_ra(env, SEG_ADDL(ssp, sp, sp_mask), ra); \ + val = (uint32_t)cpu_ldl_kernel_ra(env, (ssp) + (sp & (sp_mask)), ra); \ sp += 4; \ } From patchwork Wed Jul 10 06:29:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958719 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=f1OHI/n+; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJnzb5Jv9z1yNy for ; Wed, 10 Jul 2024 16:30:35 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQpj-0008Da-Kh; Wed, 10 Jul 2024 02:29:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpb-0008AH-VB for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpZ-0000u4-15 for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592972; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rFvMD5cnSal8ruX6+HzjgtU1Y4z0l5Rzbe0xMDe3yYs=; b=f1OHI/n+7hy3LMdwo542+6h5ZbXSdwwGQI982QzHecsImEijf+HpDrfE/uNesf5sRtZmvs tFCxdAQYZl9G3+Tvgb2vmm0Z764xJji6b56WVfKtH5mYkcZDZkH3PM03kBk6WQFw9dwOkC SrcKhYNCA6ydUgC6i+FIVrL1bbLQoJI= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-595-uYbNLWZ7P_KWDNilT74CBQ-1; Wed, 10 Jul 2024 02:29:30 -0400 X-MC-Unique: uYbNLWZ7P_KWDNilT74CBQ-1 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-42796140873so910255e9.2 for ; Tue, 09 Jul 2024 23:29:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592968; x=1721197768; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rFvMD5cnSal8ruX6+HzjgtU1Y4z0l5Rzbe0xMDe3yYs=; b=H9HFKjX4HyAZW5iJt3s3MZKIdp/SsBBSRB+txM2xGEHghU08sD1dvD63d9Qhq+e/Rg tE1GalGFMoolKSPpW8lSrnoEPUZeWlfyr07SaWUs/rRpaIOID90zmaSbvY3Or2PJqc7s MEK8A8Mxy4ZXZLZXJE5M2rK8438a54cM0CKF8z99zqzgyRkIhGtUyWKX95oasMJLEYfB fv8R8nqzkYWXomXfU7kIt8imf1gbcyc3mn8byyzoyYlq8LYfFN3jZQU/w235YlVoFqsT cWUqmbzRul+8eqB1ZqnW7apTbSSS+l2kCChxLaF4mBF+D8UUqyAYrGVQzVXodkRBjmvi tvqA== X-Gm-Message-State: AOJu0YzuQqRQ6//mMEotlYySoX4AxAgjA7wdpFKEs4yu2CB9VNQ7GbZ1 8vnsnfz9BkWt7ckIw4fxCRhFUcqq8AVAPp431nOyw6j8RpiOQem/8kWmLzA8k/mAaWvQRmAK/LY 9P0yNbcclJIgXxXoXt/TGjApoKbPZ/ugyWqoVtNlctZQSS+YpZ9v2vc2lIz0qCMQk0Sq0Ij+QCs 1VkWfJr7wTnXHf03teWVCD6iTx33MBCw//Xv9K X-Received: by 2002:a05:600c:42ca:b0:426:549c:294c with SMTP id 5b1f17b1804b1-426708fa7d0mr34482505e9.35.1720592968356; Tue, 09 Jul 2024 23:29:28 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFE8k1DQhRvtpZmIhZmJOrkKBCfnvvy0HKySRt3RhkqvTxuaybqE+sr2u9sJ2RPWe+vBuGrRQ== X-Received: by 2002:a05:600c:42ca:b0:426:549c:294c with SMTP id 5b1f17b1804b1-426708fa7d0mr34482375e9.35.1720592968095; Tue, 09 Jul 2024 23:29:28 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4267255858asm39484535e9.0.2024.07.09.23.29.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:26 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 02/10] target/i386/tcg: Allow IRET from user mode to user mode with SMAP Date: Wed, 10 Jul 2024 08:29:12 +0200 Message-ID: <20240710062920.73063-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This fixes a bug wherein i386/tcg assumed an interrupt return using the IRET instruction was always returning from kernel mode to either kernel mode or user mode. This assumption is violated when IRET is used as a clever way to restore thread state, as for example in the dotnet runtime. There, IRET returns from user mode to user mode. This bug is that stack accesses from IRET and RETF, as well as accesses to the parameters in a call gate, are normal data accesses using the current CPL. This manifested itself as a page fault in the guest Linux kernel due to SMAP preventing the access. This bug appears to have been in QEMU since the beginning. Analyzed-by: Robert R. Henry Co-developed-by: Robert R. Henry Signed-off-by: Robert R. Henry Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/tcg/seg_helper.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 19d6b41a589..4977a5f5b3a 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -594,13 +594,13 @@ int exception_has_error_code(int intno) #define POPW_RA(ssp, sp, sp_mask, val, ra) \ { \ - val = cpu_lduw_kernel_ra(env, (ssp) + (sp & (sp_mask)), ra); \ + val = cpu_lduw_data_ra(env, (ssp) + (sp & (sp_mask)), ra); \ sp += 2; \ } #define POPL_RA(ssp, sp, sp_mask, val, ra) \ { \ - val = (uint32_t)cpu_ldl_kernel_ra(env, (ssp) + (sp & (sp_mask)), ra); \ + val = (uint32_t)cpu_ldl_data_ra(env, (ssp) + (sp & (sp_mask)), ra); \ sp += 4; \ } @@ -847,7 +847,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, #define POPQ_RA(sp, val, ra) \ { \ - val = cpu_ldq_kernel_ra(env, sp, ra); \ + val = cpu_ldq_data_ra(env, sp, ra); \ sp += 8; \ } @@ -1797,18 +1797,18 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, PUSHL_RA(ssp, sp, sp_mask, env->segs[R_SS].selector, GETPC()); PUSHL_RA(ssp, sp, sp_mask, env->regs[R_ESP], GETPC()); for (i = param_count - 1; i >= 0; i--) { - val = cpu_ldl_kernel_ra(env, old_ssp + - ((env->regs[R_ESP] + i * 4) & - old_sp_mask), GETPC()); + val = cpu_ldl_data_ra(env, + old_ssp + ((env->regs[R_ESP] + i * 4) & old_sp_mask), + GETPC()); PUSHL_RA(ssp, sp, sp_mask, val, GETPC()); } } else { PUSHW_RA(ssp, sp, sp_mask, env->segs[R_SS].selector, GETPC()); PUSHW_RA(ssp, sp, sp_mask, env->regs[R_ESP], GETPC()); for (i = param_count - 1; i >= 0; i--) { - val = cpu_lduw_kernel_ra(env, old_ssp + - ((env->regs[R_ESP] + i * 2) & - old_sp_mask), GETPC()); + val = cpu_lduw_data_ra(env, + old_ssp + ((env->regs[R_ESP] + i * 2) & old_sp_mask), + GETPC()); PUSHW_RA(ssp, sp, sp_mask, val, GETPC()); } } From patchwork Wed Jul 10 06:29:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958718 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=SKpHaBSM; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJnzB3Kbmz1yNy for ; Wed, 10 Jul 2024 16:30:14 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQpk-0008IX-TB; Wed, 10 Jul 2024 02:29:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpe-0008Ck-TN for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:42 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpd-0000uH-JJ for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592975; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zBopGb3I4tvZn2JXrJrqL6k5ycPUsXCyJFN5LtfkPpk=; b=SKpHaBSMFM1/cVYvFPQVE4KilrkV6KRX3Q+s2Zwsu08Dfjkn0NXsvrnDH/WqwmH7RFTrwV N2J+8JefasQOYoHxL1P7lypqJzQZfYJyn6hQlc37D2yiB5fDX7pYpD1O957WeMfqSvLcRX 6ECftZM45NK6OR/1iDoKp/pYRjNRF6s= Received: from mail-lf1-f70.google.com (mail-lf1-f70.google.com [209.85.167.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-279-_KavTdJJNj2KBBVnNmUIAg-1; Wed, 10 Jul 2024 02:29:33 -0400 X-MC-Unique: _KavTdJJNj2KBBVnNmUIAg-1 Received: by mail-lf1-f70.google.com with SMTP id 2adb3069b0e04-52e98c1a9d2so4737300e87.3 for ; Tue, 09 Jul 2024 23:29:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592971; x=1721197771; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=zBopGb3I4tvZn2JXrJrqL6k5ycPUsXCyJFN5LtfkPpk=; b=E0WK295omD22whFJJkYb9s4aUPSsFBMmD5XaUxx9YBULDhf5r/IzqB0Wzh+W3tyXtX ZJmtqFgxNOYPYh12arNMnihxnzxtTfh4zhNy0lVqV1Th0xXajK10ezgj0DOh/0giJHPG FKsSL8RUoAydlevw38dxs4x9OsDd+QLeet6PYgrCfZacgsITU3Fufe27AGBa8QZQV1rK fTZR2gWVGtjKNx/bsOjuImbB77P7rM9J7RWiB82U4+WdJoWVYuoHJ85KsFZURpNi1xxN wzUgvFW+9bWKFS2upVkwQTyvRcN5ZbxhSixdRL7e4hJeNC60ANOBvJzSkzUuL7ub0izP Fa5g== X-Gm-Message-State: AOJu0YyVGljlw/oPkpGE/FQCT+xorqgni39OcMzrxEQTvitoql8PU0Cm QFYTGfm5IFU9bSfC3expBIvbViyV212Qm96bdJp8kZAIHAHXxnZiA7HcXDm53XrZqjV+GTG5bfW Lc8P5WT2ndx0tECeJh8046Y8u2GlUrRs3E6CPomSvd93+AwF2vNH4NHHfgeFZAXojr893wMxcDt sIPBKxZvVngoXDbT1TyVRexMhVrjqcD4MFG80U X-Received: by 2002:a19:8c05:0:b0:52c:d9f8:b033 with SMTP id 2adb3069b0e04-52eb9991345mr2292209e87.3.1720592971078; Tue, 09 Jul 2024 23:29:31 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFLiFVy8ngJbKuOXsc/arS/wjhOAhc/TxReXVbh7N3dFsEbiVyyVT2M57apZNpoD32KrtYF8w== X-Received: by 2002:a19:8c05:0:b0:52c:d9f8:b033 with SMTP id 2adb3069b0e04-52eb9991345mr2292198e87.3.1720592970638; Tue, 09 Jul 2024 23:29:30 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4266e6478d7sm86316955e9.31.2024.07.09.23.29.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:29 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 03/10] target/i386/tcg: use PUSHL/PUSHW for error code Date: Wed, 10 Jul 2024 08:29:13 +0200 Message-ID: <20240710062920.73063-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Do not pre-decrement esp, let the macros subtract the appropriate operand size. Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/tcg/seg_helper.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 4977a5f5b3a..0653bc10936 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -670,22 +670,20 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, } shift = switch_tss(env, intno * 8, e1, e2, SWITCH_TSS_CALL, old_eip); if (has_error_code) { - uint32_t mask; - /* push the error code */ if (env->segs[R_SS].flags & DESC_B_MASK) { - mask = 0xffffffff; + sp_mask = 0xffffffff; } else { - mask = 0xffff; + sp_mask = 0xffff; } - esp = (env->regs[R_ESP] - (2 << shift)) & mask; - ssp = env->segs[R_SS].base + esp; + esp = env->regs[R_ESP]; + ssp = env->segs[R_SS].base; if (shift) { - cpu_stl_kernel(env, ssp, error_code); + PUSHL(ssp, esp, sp_mask, error_code); } else { - cpu_stw_kernel(env, ssp, error_code); + PUSHW(ssp, esp, sp_mask, error_code); } - SET_ESP(esp, mask); + SET_ESP(esp, sp_mask); } return; } From patchwork Wed Jul 10 06:29:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958726 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=jLmN10Jl; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJp181c7Rz1yNy for ; Wed, 10 Jul 2024 16:31:56 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQpl-0008NJ-SS; Wed, 10 Jul 2024 02:29:45 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpi-0008D2-FW for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:43 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpf-0000ua-9K for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592978; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VWTL4VrbXgQj1vr1wUg5bw0Yrmv3ueLbi/7PMgwKSwc=; b=jLmN10JlyMhbEs8WTd9s/RA7TOPw5VuTYUbnVGoWHU3cyqBy6UHN+hHVhFi4GKS/TLV04w QwpSCIvmQZ30YkDo4qmL1al6ZJGEup2G5Xh1GDiBP75bTj0z+23j4RMx2JWqu8/zJxBpM8 3jnXuRfe68wH5ViuOFXok56eMuJ2dhg= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-27-YZ5es4LDPPanEf0pFZm9NA-1; Wed, 10 Jul 2024 02:29:36 -0400 X-MC-Unique: YZ5es4LDPPanEf0pFZm9NA-1 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-42668699453so27364785e9.3 for ; Tue, 09 Jul 2024 23:29:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592974; x=1721197774; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=VWTL4VrbXgQj1vr1wUg5bw0Yrmv3ueLbi/7PMgwKSwc=; b=mwlWuO78YVCYgRYyIMBUs02VF1QdVIh6KRP4RiZDTkLHD+rPQ1Jv5ms9zlxTQL6mbH D4DDokg5HL2r5DLjzNNJ7H6pyRMu2aF8ry40sfjhc7WJrZHqWVWIvRyighcwhPnDJkfQ IVqRp0YUgnHQdD9OD5N/M5kh1TyqdBZOA5FyLFFBaVewGNxsjX9eaUPtwodrCu+oeJmi q+WSEeM69vm2JBLAw9GwioYMbqp3qWfihl4im30tPk+U5YbMwi8gYu/J/plMeQL7euTW Ok/TNscYaigeuWt2CGS43wLA6CUmzK74fPnwja2/32gyFQifsok1mK8TR13jkhT0r1C8 LbwA== X-Gm-Message-State: AOJu0YwmEBkgybpvN8yloWEi8eI/GDTbrW4uIjwrMwKVwUUafnOqhaZ7 G3nq7RnPk02vv6+WFa6Dx0IueuZmw+TeMWMblfYqPb/z0WhGPhDgsXFbML5KXW374Plk+YL4vSk NpXFDMCwRKeEmvt7yvYBoUQ5B1hFVfQfZtIiYAuBtCxw5MALedOCBI9yA3jeURlddIEY9u60SNC ApzvLhS98t/r5rA9ouKnikNSPtwbw2pU1iD5HQ X-Received: by 2002:a05:600c:2109:b0:426:58cb:8ca4 with SMTP id 5b1f17b1804b1-426708f1d36mr35077515e9.37.1720592973996; Tue, 09 Jul 2024 23:29:33 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFKyE8wWern4fIr7F0IWs/THSK8nmSng0k67+PpbTMDzHzmPssX5qnknnqSeczqOa3p1cdjcg== X-Received: by 2002:a05:600c:2109:b0:426:58cb:8ca4 with SMTP id 5b1f17b1804b1-426708f1d36mr35077305e9.37.1720592973298; Tue, 09 Jul 2024 23:29:33 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367cdfab753sm4321191f8f.107.2024.07.09.23.29.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:31 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 04/10] target/i386/tcg: Reorg push/pop within seg_helper.c Date: Wed, 10 Jul 2024 08:29:14 +0200 Message-ID: <20240710062920.73063-5-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Richard Henderson Interrupts and call gates should use accesses with the DPL as the privilege level. While computing the applicable MMU index is easy, the harder thing is how to plumb it in the code. One possibility could be to add a single argument to the PUSH* macros for the privilege level, but this is repetitive and risks confusion between the involved privilege levels. Another possibility is to pass both CPL and DPL, and adjusting both PUSH* and POP* to use specific privilege levels (instead of using cpu_{ld,st}*_data). This makes the code more symmetric. However, a more complicated but much nicer approach is to use a structure to contain the stack parameters, env, unwind return address, and rewrite the macros into functions. The struct provides an easy home for the MMU index as well. Signed-off-by: Richard Henderson Link: https://lore.kernel.org/r/20240617161210.4639-4-richard.henderson@linaro.org Signed-off-by: Paolo Bonzini --- target/i386/tcg/seg_helper.c | 439 +++++++++++++++++++---------------- 1 file changed, 238 insertions(+), 201 deletions(-) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 0653bc10936..6b3de7a2be4 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -579,35 +579,47 @@ int exception_has_error_code(int intno) } while (0) #endif -/* XXX: add a is_user flag to have proper security support */ -#define PUSHW_RA(ssp, sp, sp_mask, val, ra) \ - { \ - sp -= 2; \ - cpu_stw_kernel_ra(env, (ssp) + (sp & (sp_mask)), (val), ra); \ - } +/* XXX: use mmu_index to have proper DPL support */ +typedef struct StackAccess +{ + CPUX86State *env; + uintptr_t ra; + target_ulong ss_base; + target_ulong sp; + target_ulong sp_mask; +} StackAccess; -#define PUSHL_RA(ssp, sp, sp_mask, val, ra) \ - { \ - sp -= 4; \ - cpu_stl_kernel_ra(env, (ssp) + (sp & (sp_mask)), (val), ra); \ - } +static void pushw(StackAccess *sa, uint16_t val) +{ + sa->sp -= 2; + cpu_stw_kernel_ra(sa->env, sa->ss_base + (sa->sp & sa->sp_mask), + val, sa->ra); +} -#define POPW_RA(ssp, sp, sp_mask, val, ra) \ - { \ - val = cpu_lduw_data_ra(env, (ssp) + (sp & (sp_mask)), ra); \ - sp += 2; \ - } +static void pushl(StackAccess *sa, uint32_t val) +{ + sa->sp -= 4; + cpu_stl_kernel_ra(sa->env, sa->ss_base + (sa->sp & sa->sp_mask), + val, sa->ra); +} -#define POPL_RA(ssp, sp, sp_mask, val, ra) \ - { \ - val = (uint32_t)cpu_ldl_data_ra(env, (ssp) + (sp & (sp_mask)), ra); \ - sp += 4; \ - } +static uint16_t popw(StackAccess *sa) +{ + uint16_t ret = cpu_lduw_data_ra(sa->env, + sa->ss_base + (sa->sp & sa->sp_mask), + sa->ra); + sa->sp += 2; + return ret; +} -#define PUSHW(ssp, sp, sp_mask, val) PUSHW_RA(ssp, sp, sp_mask, val, 0) -#define PUSHL(ssp, sp, sp_mask, val) PUSHL_RA(ssp, sp, sp_mask, val, 0) -#define POPW(ssp, sp, sp_mask, val) POPW_RA(ssp, sp, sp_mask, val, 0) -#define POPL(ssp, sp, sp_mask, val) POPL_RA(ssp, sp, sp_mask, val, 0) +static uint32_t popl(StackAccess *sa) +{ + uint32_t ret = cpu_ldl_data_ra(sa->env, + sa->ss_base + (sa->sp & sa->sp_mask), + sa->ra); + sa->sp += 4; + return ret; +} /* protected mode interrupt */ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, @@ -615,12 +627,13 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, int is_hw) { SegmentCache *dt; - target_ulong ptr, ssp; + target_ulong ptr; int type, dpl, selector, ss_dpl, cpl; int has_error_code, new_stack, shift; - uint32_t e1, e2, offset, ss = 0, esp, ss_e1 = 0, ss_e2 = 0; - uint32_t old_eip, sp_mask, eflags; + uint32_t e1, e2, offset, ss = 0, ss_e1 = 0, ss_e2 = 0; + uint32_t old_eip, eflags; int vm86 = env->eflags & VM_MASK; + StackAccess sa; bool set_rf; has_error_code = 0; @@ -662,6 +675,9 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, raise_exception_err(env, EXCP0D_GPF, intno * 8 + 2); } + sa.env = env; + sa.ra = 0; + if (type == 5) { /* task gate */ /* must do that check here to return the correct error code */ @@ -672,18 +688,18 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, if (has_error_code) { /* push the error code */ if (env->segs[R_SS].flags & DESC_B_MASK) { - sp_mask = 0xffffffff; + sa.sp_mask = 0xffffffff; } else { - sp_mask = 0xffff; + sa.sp_mask = 0xffff; } - esp = env->regs[R_ESP]; - ssp = env->segs[R_SS].base; + sa.sp = env->regs[R_ESP]; + sa.ss_base = env->segs[R_SS].base; if (shift) { - PUSHL(ssp, esp, sp_mask, error_code); + pushl(&sa, error_code); } else { - PUSHW(ssp, esp, sp_mask, error_code); + pushw(&sa, error_code); } - SET_ESP(esp, sp_mask); + SET_ESP(sa.sp, sa.sp_mask); } return; } @@ -717,6 +733,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, } if (dpl < cpl) { /* to inner privilege */ + uint32_t esp; get_ss_esp_from_tss(env, &ss, &esp, dpl, 0); if ((ss & 0xfffc) == 0) { raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); @@ -740,17 +757,18 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, raise_exception_err(env, EXCP0A_TSS, ss & 0xfffc); } new_stack = 1; - sp_mask = get_sp_mask(ss_e2); - ssp = get_seg_base(ss_e1, ss_e2); + sa.sp = esp; + sa.sp_mask = get_sp_mask(ss_e2); + sa.ss_base = get_seg_base(ss_e1, ss_e2); } else { /* to same privilege */ if (vm86) { raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); } new_stack = 0; - sp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; - esp = env->regs[R_ESP]; + sa.sp = env->regs[R_ESP]; + sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); + sa.ss_base = env->segs[R_SS].base; } shift = type >> 3; @@ -775,36 +793,36 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, if (shift == 1) { if (new_stack) { if (vm86) { - PUSHL(ssp, esp, sp_mask, env->segs[R_GS].selector); - PUSHL(ssp, esp, sp_mask, env->segs[R_FS].selector); - PUSHL(ssp, esp, sp_mask, env->segs[R_DS].selector); - PUSHL(ssp, esp, sp_mask, env->segs[R_ES].selector); + pushl(&sa, env->segs[R_GS].selector); + pushl(&sa, env->segs[R_FS].selector); + pushl(&sa, env->segs[R_DS].selector); + pushl(&sa, env->segs[R_ES].selector); } - PUSHL(ssp, esp, sp_mask, env->segs[R_SS].selector); - PUSHL(ssp, esp, sp_mask, env->regs[R_ESP]); + pushl(&sa, env->segs[R_SS].selector); + pushl(&sa, env->regs[R_ESP]); } - PUSHL(ssp, esp, sp_mask, eflags); - PUSHL(ssp, esp, sp_mask, env->segs[R_CS].selector); - PUSHL(ssp, esp, sp_mask, old_eip); + pushl(&sa, eflags); + pushl(&sa, env->segs[R_CS].selector); + pushl(&sa, old_eip); if (has_error_code) { - PUSHL(ssp, esp, sp_mask, error_code); + pushl(&sa, error_code); } } else { if (new_stack) { if (vm86) { - PUSHW(ssp, esp, sp_mask, env->segs[R_GS].selector); - PUSHW(ssp, esp, sp_mask, env->segs[R_FS].selector); - PUSHW(ssp, esp, sp_mask, env->segs[R_DS].selector); - PUSHW(ssp, esp, sp_mask, env->segs[R_ES].selector); + pushw(&sa, env->segs[R_GS].selector); + pushw(&sa, env->segs[R_FS].selector); + pushw(&sa, env->segs[R_DS].selector); + pushw(&sa, env->segs[R_ES].selector); } - PUSHW(ssp, esp, sp_mask, env->segs[R_SS].selector); - PUSHW(ssp, esp, sp_mask, env->regs[R_ESP]); + pushw(&sa, env->segs[R_SS].selector); + pushw(&sa, env->regs[R_ESP]); } - PUSHW(ssp, esp, sp_mask, eflags); - PUSHW(ssp, esp, sp_mask, env->segs[R_CS].selector); - PUSHW(ssp, esp, sp_mask, old_eip); + pushw(&sa, eflags); + pushw(&sa, env->segs[R_CS].selector); + pushw(&sa, old_eip); if (has_error_code) { - PUSHW(ssp, esp, sp_mask, error_code); + pushw(&sa, error_code); } } @@ -822,10 +840,10 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, cpu_x86_load_seg_cache(env, R_GS, 0, 0, 0, 0); } ss = (ss & ~3) | dpl; - cpu_x86_load_seg_cache(env, R_SS, ss, - ssp, get_seg_limit(ss_e1, ss_e2), ss_e2); + cpu_x86_load_seg_cache(env, R_SS, ss, sa.ss_base, + get_seg_limit(ss_e1, ss_e2), ss_e2); } - SET_ESP(esp, sp_mask); + SET_ESP(sa.sp, sa.sp_mask); selector = (selector & ~3) | dpl; cpu_x86_load_seg_cache(env, R_CS, selector, @@ -837,20 +855,18 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, #ifdef TARGET_X86_64 -#define PUSHQ_RA(sp, val, ra) \ - { \ - sp -= 8; \ - cpu_stq_kernel_ra(env, sp, (val), ra); \ - } +static void pushq(StackAccess *sa, uint64_t val) +{ + sa->sp -= 8; + cpu_stq_kernel_ra(sa->env, sa->sp, val, sa->ra); +} -#define POPQ_RA(sp, val, ra) \ - { \ - val = cpu_ldq_data_ra(env, sp, ra); \ - sp += 8; \ - } - -#define PUSHQ(sp, val) PUSHQ_RA(sp, val, 0) -#define POPQ(sp, val) POPQ_RA(sp, val, 0) +static uint64_t popq(StackAccess *sa) +{ + uint64_t ret = cpu_ldq_data_ra(sa->env, sa->sp, sa->ra); + sa->sp += 8; + return ret; +} static inline target_ulong get_rsp_from_tss(CPUX86State *env, int level) { @@ -893,8 +909,9 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int, int type, dpl, selector, cpl, ist; int has_error_code, new_stack; uint32_t e1, e2, e3, ss, eflags; - target_ulong old_eip, esp, offset; + target_ulong old_eip, offset; bool set_rf; + StackAccess sa; has_error_code = 0; if (!is_int && !is_hw) { @@ -962,10 +979,15 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int, if (e2 & DESC_C_MASK) { dpl = cpl; } + + sa.env = env; + sa.ra = 0; + sa.sp_mask = -1; + sa.ss_base = 0; if (dpl < cpl || ist != 0) { /* to inner privilege */ new_stack = 1; - esp = get_rsp_from_tss(env, ist != 0 ? ist + 3 : dpl); + sa.sp = get_rsp_from_tss(env, ist != 0 ? ist + 3 : dpl); ss = 0; } else { /* to same privilege */ @@ -973,9 +995,9 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int, raise_exception_err(env, EXCP0D_GPF, selector & 0xfffc); } new_stack = 0; - esp = env->regs[R_ESP]; + sa.sp = env->regs[R_ESP]; } - esp &= ~0xfLL; /* align stack */ + sa.sp &= ~0xfLL; /* align stack */ /* See do_interrupt_protected. */ eflags = cpu_compute_eflags(env); @@ -983,13 +1005,13 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int, eflags |= RF_MASK; } - PUSHQ(esp, env->segs[R_SS].selector); - PUSHQ(esp, env->regs[R_ESP]); - PUSHQ(esp, eflags); - PUSHQ(esp, env->segs[R_CS].selector); - PUSHQ(esp, old_eip); + pushq(&sa, env->segs[R_SS].selector); + pushq(&sa, env->regs[R_ESP]); + pushq(&sa, eflags); + pushq(&sa, env->segs[R_CS].selector); + pushq(&sa, old_eip); if (has_error_code) { - PUSHQ(esp, error_code); + pushq(&sa, error_code); } /* interrupt gate clear IF mask */ @@ -1002,7 +1024,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int, ss = 0 | dpl; cpu_x86_load_seg_cache(env, R_SS, ss, 0, 0, dpl << DESC_DPL_SHIFT); } - env->regs[R_ESP] = esp; + env->regs[R_ESP] = sa.sp; selector = (selector & ~3) | dpl; cpu_x86_load_seg_cache(env, R_CS, selector, @@ -1074,10 +1096,11 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int, int error_code, unsigned int next_eip) { SegmentCache *dt; - target_ulong ptr, ssp; + target_ulong ptr; int selector; - uint32_t offset, esp; + uint32_t offset; uint32_t old_cs, old_eip; + StackAccess sa; /* real mode (simpler!) */ dt = &env->idt; @@ -1087,8 +1110,13 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int, ptr = dt->base + intno * 4; offset = cpu_lduw_kernel(env, ptr); selector = cpu_lduw_kernel(env, ptr + 2); - esp = env->regs[R_ESP]; - ssp = env->segs[R_SS].base; + + sa.env = env; + sa.ra = 0; + sa.sp = env->regs[R_ESP]; + sa.sp_mask = 0xffff; + sa.ss_base = env->segs[R_SS].base; + if (is_int) { old_eip = next_eip; } else { @@ -1096,12 +1124,12 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int, } old_cs = env->segs[R_CS].selector; /* XXX: use SS segment size? */ - PUSHW(ssp, esp, 0xffff, cpu_compute_eflags(env)); - PUSHW(ssp, esp, 0xffff, old_cs); - PUSHW(ssp, esp, 0xffff, old_eip); + pushw(&sa, cpu_compute_eflags(env)); + pushw(&sa, old_cs); + pushw(&sa, old_eip); /* update processor state */ - env->regs[R_ESP] = (env->regs[R_ESP] & ~0xffff) | (esp & 0xffff); + SET_ESP(sa.sp, sa.sp_mask); env->eip = offset; env->segs[R_CS].selector = selector; env->segs[R_CS].base = (selector << 4); @@ -1544,21 +1572,23 @@ void helper_ljmp_protected(CPUX86State *env, int new_cs, target_ulong new_eip, void helper_lcall_real(CPUX86State *env, uint32_t new_cs, uint32_t new_eip, int shift, uint32_t next_eip) { - uint32_t esp, esp_mask; - target_ulong ssp; + StackAccess sa; + + sa.env = env; + sa.ra = GETPC(); + sa.sp = env->regs[R_ESP]; + sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); + sa.ss_base = env->segs[R_SS].base; - esp = env->regs[R_ESP]; - esp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; if (shift) { - PUSHL_RA(ssp, esp, esp_mask, env->segs[R_CS].selector, GETPC()); - PUSHL_RA(ssp, esp, esp_mask, next_eip, GETPC()); + pushl(&sa, env->segs[R_CS].selector); + pushl(&sa, next_eip); } else { - PUSHW_RA(ssp, esp, esp_mask, env->segs[R_CS].selector, GETPC()); - PUSHW_RA(ssp, esp, esp_mask, next_eip, GETPC()); + pushw(&sa, env->segs[R_CS].selector); + pushw(&sa, next_eip); } - SET_ESP(esp, esp_mask); + SET_ESP(sa.sp, sa.sp_mask); env->eip = new_eip; env->segs[R_CS].selector = new_cs; env->segs[R_CS].base = (new_cs << 4); @@ -1570,9 +1600,10 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, { int new_stack, i; uint32_t e1, e2, cpl, dpl, rpl, selector, param_count; - uint32_t ss = 0, ss_e1 = 0, ss_e2 = 0, type, ss_dpl, sp_mask; + uint32_t ss = 0, ss_e1 = 0, ss_e2 = 0, type, ss_dpl; uint32_t val, limit, old_sp_mask; - target_ulong ssp, old_ssp, offset, sp; + target_ulong old_ssp, offset; + StackAccess sa; LOG_PCALL("lcall %04x:" TARGET_FMT_lx " s=%d\n", new_cs, new_eip, shift); LOG_PCALL_STATE(env_cpu(env)); @@ -1584,6 +1615,10 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, } cpl = env->hflags & HF_CPL_MASK; LOG_PCALL("desc=%08x:%08x\n", e1, e2); + + sa.env = env; + sa.ra = GETPC(); + if (e2 & DESC_S_MASK) { if (!(e2 & DESC_CS_MASK)) { raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); @@ -1611,14 +1646,14 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, #ifdef TARGET_X86_64 /* XXX: check 16/32 bit cases in long mode */ if (shift == 2) { - target_ulong rsp; - /* 64 bit case */ - rsp = env->regs[R_ESP]; - PUSHQ_RA(rsp, env->segs[R_CS].selector, GETPC()); - PUSHQ_RA(rsp, next_eip, GETPC()); + sa.sp = env->regs[R_ESP]; + sa.sp_mask = -1; + sa.ss_base = 0; + pushq(&sa, env->segs[R_CS].selector); + pushq(&sa, next_eip); /* from this point, not restartable */ - env->regs[R_ESP] = rsp; + env->regs[R_ESP] = sa.sp; cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, get_seg_base(e1, e2), get_seg_limit(e1, e2), e2); @@ -1626,15 +1661,15 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, } else #endif { - sp = env->regs[R_ESP]; - sp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; + sa.sp = env->regs[R_ESP]; + sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); + sa.ss_base = env->segs[R_SS].base; if (shift) { - PUSHL_RA(ssp, sp, sp_mask, env->segs[R_CS].selector, GETPC()); - PUSHL_RA(ssp, sp, sp_mask, next_eip, GETPC()); + pushl(&sa, env->segs[R_CS].selector); + pushl(&sa, next_eip); } else { - PUSHW_RA(ssp, sp, sp_mask, env->segs[R_CS].selector, GETPC()); - PUSHW_RA(ssp, sp, sp_mask, next_eip, GETPC()); + pushw(&sa, env->segs[R_CS].selector); + pushw(&sa, next_eip); } limit = get_seg_limit(e1, e2); @@ -1642,7 +1677,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); } /* from this point, not restartable */ - SET_ESP(sp, sp_mask); + SET_ESP(sa.sp, sa.sp_mask); cpu_x86_load_seg_cache(env, R_CS, (new_cs & 0xfffc) | cpl, get_seg_base(e1, e2), limit, e2); env->eip = new_eip; @@ -1737,13 +1772,13 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, /* to inner privilege */ #ifdef TARGET_X86_64 if (shift == 2) { - sp = get_rsp_from_tss(env, dpl); ss = dpl; /* SS = NULL selector with RPL = new CPL */ new_stack = 1; - sp_mask = 0; - ssp = 0; /* SS base is always zero in IA-32e mode */ + sa.sp = get_rsp_from_tss(env, dpl); + sa.sp_mask = -1; + sa.ss_base = 0; /* SS base is always zero in IA-32e mode */ LOG_PCALL("new ss:rsp=%04x:%016llx env->regs[R_ESP]=" - TARGET_FMT_lx "\n", ss, sp, env->regs[R_ESP]); + TARGET_FMT_lx "\n", ss, sa.sp, env->regs[R_ESP]); } else #endif { @@ -1752,7 +1787,6 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, LOG_PCALL("new ss:esp=%04x:%08x param_count=%d env->regs[R_ESP]=" TARGET_FMT_lx "\n", ss, sp32, param_count, env->regs[R_ESP]); - sp = sp32; if ((ss & 0xfffc) == 0) { raise_exception_err_ra(env, EXCP0A_TSS, ss & 0xfffc, GETPC()); } @@ -1775,63 +1809,64 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, raise_exception_err_ra(env, EXCP0A_TSS, ss & 0xfffc, GETPC()); } - sp_mask = get_sp_mask(ss_e2); - ssp = get_seg_base(ss_e1, ss_e2); + sa.sp = sp32; + sa.sp_mask = get_sp_mask(ss_e2); + sa.ss_base = get_seg_base(ss_e1, ss_e2); } /* push_size = ((param_count * 2) + 8) << shift; */ - old_sp_mask = get_sp_mask(env->segs[R_SS].flags); old_ssp = env->segs[R_SS].base; + #ifdef TARGET_X86_64 if (shift == 2) { /* XXX: verify if new stack address is canonical */ - PUSHQ_RA(sp, env->segs[R_SS].selector, GETPC()); - PUSHQ_RA(sp, env->regs[R_ESP], GETPC()); + pushq(&sa, env->segs[R_SS].selector); + pushq(&sa, env->regs[R_ESP]); /* parameters aren't supported for 64-bit call gates */ } else #endif if (shift == 1) { - PUSHL_RA(ssp, sp, sp_mask, env->segs[R_SS].selector, GETPC()); - PUSHL_RA(ssp, sp, sp_mask, env->regs[R_ESP], GETPC()); + pushl(&sa, env->segs[R_SS].selector); + pushl(&sa, env->regs[R_ESP]); for (i = param_count - 1; i >= 0; i--) { val = cpu_ldl_data_ra(env, - old_ssp + ((env->regs[R_ESP] + i * 4) & old_sp_mask), - GETPC()); - PUSHL_RA(ssp, sp, sp_mask, val, GETPC()); + old_ssp + ((env->regs[R_ESP] + i * 4) & old_sp_mask), + GETPC()); + pushl(&sa, val); } } else { - PUSHW_RA(ssp, sp, sp_mask, env->segs[R_SS].selector, GETPC()); - PUSHW_RA(ssp, sp, sp_mask, env->regs[R_ESP], GETPC()); + pushw(&sa, env->segs[R_SS].selector); + pushw(&sa, env->regs[R_ESP]); for (i = param_count - 1; i >= 0; i--) { val = cpu_lduw_data_ra(env, - old_ssp + ((env->regs[R_ESP] + i * 2) & old_sp_mask), - GETPC()); - PUSHW_RA(ssp, sp, sp_mask, val, GETPC()); + old_ssp + ((env->regs[R_ESP] + i * 2) & old_sp_mask), + GETPC()); + pushw(&sa, val); } } new_stack = 1; } else { /* to same privilege */ - sp = env->regs[R_ESP]; - sp_mask = get_sp_mask(env->segs[R_SS].flags); - ssp = env->segs[R_SS].base; + sa.sp = env->regs[R_ESP]; + sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); + sa.ss_base = env->segs[R_SS].base; /* push_size = (4 << shift); */ new_stack = 0; } #ifdef TARGET_X86_64 if (shift == 2) { - PUSHQ_RA(sp, env->segs[R_CS].selector, GETPC()); - PUSHQ_RA(sp, next_eip, GETPC()); + pushq(&sa, env->segs[R_CS].selector); + pushq(&sa, next_eip); } else #endif if (shift == 1) { - PUSHL_RA(ssp, sp, sp_mask, env->segs[R_CS].selector, GETPC()); - PUSHL_RA(ssp, sp, sp_mask, next_eip, GETPC()); + pushl(&sa, env->segs[R_CS].selector); + pushl(&sa, next_eip); } else { - PUSHW_RA(ssp, sp, sp_mask, env->segs[R_CS].selector, GETPC()); - PUSHW_RA(ssp, sp, sp_mask, next_eip, GETPC()); + pushw(&sa, env->segs[R_CS].selector); + pushw(&sa, next_eip); } /* from this point, not restartable */ @@ -1845,7 +1880,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, { ss = (ss & ~3) | dpl; cpu_x86_load_seg_cache(env, R_SS, ss, - ssp, + sa.ss_base, get_seg_limit(ss_e1, ss_e2), ss_e2); } @@ -1856,7 +1891,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, get_seg_base(e1, e2), get_seg_limit(e1, e2), e2); - SET_ESP(sp, sp_mask); + SET_ESP(sa.sp, sa.sp_mask); env->eip = offset; } } @@ -1864,26 +1899,28 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, /* real and vm86 mode iret */ void helper_iret_real(CPUX86State *env, int shift) { - uint32_t sp, new_cs, new_eip, new_eflags, sp_mask; - target_ulong ssp; + uint32_t new_cs, new_eip, new_eflags; int eflags_mask; + StackAccess sa; + + sa.env = env; + sa.ra = GETPC(); + sa.sp_mask = 0xffff; /* XXXX: use SS segment size? */ + sa.sp = env->regs[R_ESP]; + sa.ss_base = env->segs[R_SS].base; - sp_mask = 0xffff; /* XXXX: use SS segment size? */ - sp = env->regs[R_ESP]; - ssp = env->segs[R_SS].base; if (shift == 1) { /* 32 bits */ - POPL_RA(ssp, sp, sp_mask, new_eip, GETPC()); - POPL_RA(ssp, sp, sp_mask, new_cs, GETPC()); - new_cs &= 0xffff; - POPL_RA(ssp, sp, sp_mask, new_eflags, GETPC()); + new_eip = popl(&sa); + new_cs = popl(&sa) & 0xffff; + new_eflags = popl(&sa); } else { /* 16 bits */ - POPW_RA(ssp, sp, sp_mask, new_eip, GETPC()); - POPW_RA(ssp, sp, sp_mask, new_cs, GETPC()); - POPW_RA(ssp, sp, sp_mask, new_eflags, GETPC()); + new_eip = popw(&sa); + new_cs = popw(&sa); + new_eflags = popw(&sa); } - env->regs[R_ESP] = (env->regs[R_ESP] & ~sp_mask) | (sp & sp_mask); + SET_ESP(sa.sp, sa.sp_mask); env->segs[R_CS].selector = new_cs; env->segs[R_CS].base = (new_cs << 4); env->eip = new_eip; @@ -1936,47 +1973,49 @@ static inline void helper_ret_protected(CPUX86State *env, int shift, uint32_t new_es, new_ds, new_fs, new_gs; uint32_t e1, e2, ss_e1, ss_e2; int cpl, dpl, rpl, eflags_mask, iopl; - target_ulong ssp, sp, new_eip, new_esp, sp_mask; + target_ulong new_eip, new_esp; + StackAccess sa; + + sa.env = env; + sa.ra = retaddr; #ifdef TARGET_X86_64 if (shift == 2) { - sp_mask = -1; + sa.sp_mask = -1; } else #endif { - sp_mask = get_sp_mask(env->segs[R_SS].flags); + sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); } - sp = env->regs[R_ESP]; - ssp = env->segs[R_SS].base; + sa.sp = env->regs[R_ESP]; + sa.ss_base = env->segs[R_SS].base; new_eflags = 0; /* avoid warning */ #ifdef TARGET_X86_64 if (shift == 2) { - POPQ_RA(sp, new_eip, retaddr); - POPQ_RA(sp, new_cs, retaddr); - new_cs &= 0xffff; + new_eip = popq(&sa); + new_cs = popq(&sa) & 0xffff; if (is_iret) { - POPQ_RA(sp, new_eflags, retaddr); + new_eflags = popq(&sa); } } else #endif { if (shift == 1) { /* 32 bits */ - POPL_RA(ssp, sp, sp_mask, new_eip, retaddr); - POPL_RA(ssp, sp, sp_mask, new_cs, retaddr); - new_cs &= 0xffff; + new_eip = popl(&sa); + new_cs = popl(&sa) & 0xffff; if (is_iret) { - POPL_RA(ssp, sp, sp_mask, new_eflags, retaddr); + new_eflags = popl(&sa); if (new_eflags & VM_MASK) { goto return_to_vm86; } } } else { /* 16 bits */ - POPW_RA(ssp, sp, sp_mask, new_eip, retaddr); - POPW_RA(ssp, sp, sp_mask, new_cs, retaddr); + new_eip = popw(&sa); + new_cs = popw(&sa); if (is_iret) { - POPW_RA(ssp, sp, sp_mask, new_eflags, retaddr); + new_eflags = popw(&sa); } } } @@ -2012,7 +2051,7 @@ static inline void helper_ret_protected(CPUX86State *env, int shift, raise_exception_err_ra(env, EXCP0B_NOSEG, new_cs & 0xfffc, retaddr); } - sp += addend; + sa.sp += addend; if (rpl == cpl && (!(env->hflags & HF_CS64_MASK) || ((env->hflags & HF_CS64_MASK) && !is_iret))) { /* return to same privilege level */ @@ -2024,21 +2063,19 @@ static inline void helper_ret_protected(CPUX86State *env, int shift, /* return to different privilege level */ #ifdef TARGET_X86_64 if (shift == 2) { - POPQ_RA(sp, new_esp, retaddr); - POPQ_RA(sp, new_ss, retaddr); - new_ss &= 0xffff; + new_esp = popq(&sa); + new_ss = popq(&sa) & 0xffff; } else #endif { if (shift == 1) { /* 32 bits */ - POPL_RA(ssp, sp, sp_mask, new_esp, retaddr); - POPL_RA(ssp, sp, sp_mask, new_ss, retaddr); - new_ss &= 0xffff; + new_esp = popl(&sa); + new_ss = popl(&sa) & 0xffff; } else { /* 16 bits */ - POPW_RA(ssp, sp, sp_mask, new_esp, retaddr); - POPW_RA(ssp, sp, sp_mask, new_ss, retaddr); + new_esp = popw(&sa); + new_ss = popw(&sa); } } LOG_PCALL("new ss:esp=%04x:" TARGET_FMT_lx "\n", @@ -2088,14 +2125,14 @@ static inline void helper_ret_protected(CPUX86State *env, int shift, get_seg_base(e1, e2), get_seg_limit(e1, e2), e2); - sp = new_esp; + sa.sp = new_esp; #ifdef TARGET_X86_64 if (env->hflags & HF_CS64_MASK) { - sp_mask = -1; + sa.sp_mask = -1; } else #endif { - sp_mask = get_sp_mask(ss_e2); + sa.sp_mask = get_sp_mask(ss_e2); } /* validate data segments */ @@ -2104,9 +2141,9 @@ static inline void helper_ret_protected(CPUX86State *env, int shift, validate_seg(env, R_FS, rpl); validate_seg(env, R_GS, rpl); - sp += addend; + sa.sp += addend; } - SET_ESP(sp, sp_mask); + SET_ESP(sa.sp, sa.sp_mask); env->eip = new_eip; if (is_iret) { /* NOTE: 'cpl' is the _old_ CPL */ @@ -2126,12 +2163,12 @@ static inline void helper_ret_protected(CPUX86State *env, int shift, return; return_to_vm86: - POPL_RA(ssp, sp, sp_mask, new_esp, retaddr); - POPL_RA(ssp, sp, sp_mask, new_ss, retaddr); - POPL_RA(ssp, sp, sp_mask, new_es, retaddr); - POPL_RA(ssp, sp, sp_mask, new_ds, retaddr); - POPL_RA(ssp, sp, sp_mask, new_fs, retaddr); - POPL_RA(ssp, sp, sp_mask, new_gs, retaddr); + new_esp = popl(&sa); + new_ss = popl(&sa); + new_es = popl(&sa); + new_ds = popl(&sa); + new_fs = popl(&sa); + new_gs = popl(&sa); /* modify processor state */ cpu_load_eflags(env, new_eflags, TF_MASK | AC_MASK | ID_MASK | From patchwork Wed Jul 10 06:29:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958725 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=XVTxqToP; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJp102nhrz1yNy for ; Wed, 10 Jul 2024 16:31:48 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQpm-0008RI-Th; Wed, 10 Jul 2024 02:29:47 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpl-0008Mt-OL for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:45 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpk-0000ur-1S for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:45 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592983; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=yKHaLhM9UAuURgVWP4GssGjRnYIMl9btSsv/NKhFweE=; b=XVTxqToPXrWF3hl7iOhWIpnx1X4yhe6I4oN9N9bUs0wIEwkKvvX7gkvUJcqYWU2cP1Iti2 xr4irxzMaeYVSkhzxqQkEoECPRH/WCc886evJMSvshklJcylvG/AKCBN91aSQHtK9e/aiB t58+U6/499y5yG1w6OjVPBF7rUo65LM= Received: from mail-lj1-f197.google.com (mail-lj1-f197.google.com [209.85.208.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-224-A56q7UioOOaxK9J_ueZ5UA-1; Wed, 10 Jul 2024 02:29:39 -0400 X-MC-Unique: A56q7UioOOaxK9J_ueZ5UA-1 Received: by mail-lj1-f197.google.com with SMTP id 38308e7fff4ca-2ee87d500caso59438401fa.3 for ; Tue, 09 Jul 2024 23:29:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592977; x=1721197777; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yKHaLhM9UAuURgVWP4GssGjRnYIMl9btSsv/NKhFweE=; b=geMZPi8CkSWnCm4iIaE+CCeuPRngZhl2dLqnFHwGtgPnZiT5eB4aCIZyex04b66S0q kVWdBT1TnnvIwfN1864+O07F1Jp3wME8RJgWjP1fga/rHNriI3e1QhpLxbwKP5r0GqG/ a2+cK9HDMuCCcR3UPt3PKr5COy7U5qDde4SE62rTuVq24W/TWVazgUrlpKACftv+XItS z5dWrl8JiVWPnu7UYg46LK1WK3jM2SKzofq5xZ7cuNHpdo7qGpKOYdjwfdZS06SZ8bqj KzbnrPdy8r3nxWhLgiRa9vOuPX0HZoO0H5cRgt2rPXYoAQSGmav/eVh9pS0k+ZkF7KLg e3Qw== X-Gm-Message-State: AOJu0YzvtuLSvrBShAUI4kttNuIt/qA83YjUnXX9JDcvSxwNOdWD3/Hq bHNfJA5IQkr+r6uPwWwhWSUSioQOpwAe9y4SSSjLCEH/Tk/D3CIXs5HwNY+CfbTFie/Yg8YbnrM PibU/zaz16tLZCeCJK+p0uLqdAF1bKssbfudDXUpW39ogaewXSrAnX+2dqPX4XepUBksAR90fnE 4rWcCIjZ6rWItP/RHIha6942e1VZVuS2Kik9Jt X-Received: by 2002:a2e:90c7:0:b0:2ee:4514:aa9a with SMTP id 38308e7fff4ca-2eeb318ab0bmr28900871fa.48.1720592976947; Tue, 09 Jul 2024 23:29:36 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEbrXwaCVR8B7ar+Qt5qj68fyrtyRkOnIvtVS2q+rGh3Er8iLlWYJy2oLW1NIwgx7GoRiakZA== X-Received: by 2002:a2e:90c7:0:b0:2ee:4514:aa9a with SMTP id 38308e7fff4ca-2eeb318ab0bmr28900741fa.48.1720592976556; Tue, 09 Jul 2024 23:29:36 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367cde848e7sm4335496f8f.44.2024.07.09.23.29.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:34 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 05/10] target/i386/tcg: Introduce x86_mmu_index_{kernel_,}pl Date: Wed, 10 Jul 2024 08:29:15 +0200 Message-ID: <20240710062920.73063-6-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Richard Henderson Disconnect mmu index computation from the current pl as stored in env->hflags. Signed-off-by: Richard Henderson Link: https://lore.kernel.org/r/20240617161210.4639-2-richard.henderson@linaro.org Signed-off-by: Paolo Bonzini --- target/i386/cpu.h | 11 ++--------- target/i386/cpu.c | 27 ++++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/target/i386/cpu.h b/target/i386/cpu.h index c43ac01c794..1e121acef54 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -2445,15 +2445,8 @@ static inline bool is_mmu_index_32(int mmu_index) return mmu_index & 1; } -static inline int cpu_mmu_index_kernel(CPUX86State *env) -{ - int mmu_index_32 = (env->hflags & HF_LMA_MASK) ? 0 : 1; - int mmu_index_base = - !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP64_IDX : - ((env->hflags & HF_CPL_MASK) < 3 && (env->eflags & AC_MASK)) ? MMU_KNOSMAP64_IDX : MMU_KSMAP64_IDX; - - return mmu_index_base + mmu_index_32; -} +int x86_mmu_index_pl(CPUX86State *env, unsigned pl); +int cpu_mmu_index_kernel(CPUX86State *env); #define CC_DST (env->cc_dst) #define CC_SRC (env->cc_src) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index c05765eeafc..4688d140c2d 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -8122,18 +8122,39 @@ static bool x86_cpu_has_work(CPUState *cs) return x86_cpu_pending_interrupt(cs, cs->interrupt_request) != 0; } -static int x86_cpu_mmu_index(CPUState *cs, bool ifetch) +int x86_mmu_index_pl(CPUX86State *env, unsigned pl) { - CPUX86State *env = cpu_env(cs); int mmu_index_32 = (env->hflags & HF_CS64_MASK) ? 0 : 1; int mmu_index_base = - (env->hflags & HF_CPL_MASK) == 3 ? MMU_USER64_IDX : + pl == 3 ? MMU_USER64_IDX : !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP64_IDX : (env->eflags & AC_MASK) ? MMU_KNOSMAP64_IDX : MMU_KSMAP64_IDX; return mmu_index_base + mmu_index_32; } +static int x86_cpu_mmu_index(CPUState *cs, bool ifetch) +{ + CPUX86State *env = cpu_env(cs); + return x86_mmu_index_pl(env, env->hflags & HF_CPL_MASK); +} + +static int x86_mmu_index_kernel_pl(CPUX86State *env, unsigned pl) +{ + int mmu_index_32 = (env->hflags & HF_LMA_MASK) ? 0 : 1; + int mmu_index_base = + !(env->hflags & HF_SMAP_MASK) ? MMU_KNOSMAP64_IDX : + (pl < 3 && (env->eflags & AC_MASK) + ? MMU_KNOSMAP64_IDX : MMU_KSMAP64_IDX); + + return mmu_index_base + mmu_index_32; +} + +int cpu_mmu_index_kernel(CPUX86State *env) +{ + return x86_mmu_index_kernel_pl(env, env->hflags & HF_CPL_MASK); +} + static void x86_disas_set_info(CPUState *cs, disassemble_info *info) { X86CPU *cpu = X86_CPU(cs); From patchwork Wed Jul 10 06:29:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958724 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Nc1QlymA; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJp0Q6JQgz1yNy for ; Wed, 10 Jul 2024 16:31:18 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQpo-00009L-IT; Wed, 10 Jul 2024 02:29:48 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpn-0008UB-5x for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:47 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpl-0000uv-HK for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:46 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592983; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Z1qNKNLHYi6Nd/xVugw2OZb8ZRyjnHbwEiVtGU6tBOc=; b=Nc1QlymAQmVGj6XeyYhuiq4ALWAbKqnHP/hWEK2p2OjsA50s1zMX/4uTZdEJsTyn9r6scj 26ewPQK8ctjI7+NvGKqr48cSuitBAzehvNxDJfIBNKnpx+iBq22O66taCoNDFfJe8FA8PY vGCO84Mh227KD2kyzBI7lvNXRW9Y9zY= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-695-ozcy-4VbOYuv48zE1hJzMA-1; Wed, 10 Jul 2024 02:29:42 -0400 X-MC-Unique: ozcy-4VbOYuv48zE1hJzMA-1 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-36785e6c1e6so4046900f8f.3 for ; Tue, 09 Jul 2024 23:29:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592980; x=1721197780; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Z1qNKNLHYi6Nd/xVugw2OZb8ZRyjnHbwEiVtGU6tBOc=; b=jR2qkDWEdrlQdKImfZd5szQYLVsbK4uPMfqU0/Wcnp+uzDyL29UItPFTwmRdx5xc+Q rFKv/HeGw3QNYf7ORB/RubiGIDLyrD7ND5UbSOAVGRUrQm3rDYOXzxg1PgITBXAb/dUZ T/XQExwYPizav0fSrExLs3mfsd+6uhzISPOxu0/miAOXEDpvMAvVs8u61K2YDke12pxs qMPH4v0msP2nvJqU/xvVIZ9USG34Duh89H3f1QjU+V0cShTj7O37usd9I/QjAhXDe79Y mXIehDFZ5BVx71NER6o6rktwjbOZ5SbQYNSGuiPBEr/OHmi0gbjW9wFKB05A4/1IISL0 lnkw== X-Gm-Message-State: AOJu0YyZ3UiZjUPCypkat7jlUlpNPl+rfXmq78h2r/DLroOderz4bCoY ycHQyvibV0SiAyK5HbgCDcWlsg7F9rEwEYIC2iOp9VQ4ECXZmDb6jTLJbqooP4K5jGBtE9wXfpo ujGtx17troagYc/G2AvelhW2Ym2mTsUH4miwjsOdf6KkH/HU5mf0SWMbupOaZSlJRWhDYQENH9v 8/4WsREpxuwyo9COlS8N5XlNs6A/JulNT74iyh X-Received: by 2002:a5d:6da9:0:b0:367:9c9e:714d with SMTP id ffacd0b85a97d-367cea46772mr4119165f8f.11.1720592979873; Tue, 09 Jul 2024 23:29:39 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEcFRQTQuTy1RZ3CdXH+/cRSwoq6jXp5qsG2NsJhWORbnOkHMrHjV0xKYi8x3S+we1LZ2833g== X-Received: by 2002:a5d:6da9:0:b0:367:9c9e:714d with SMTP id ffacd0b85a97d-367cea46772mr4119152f8f.11.1720592979536; Tue, 09 Jul 2024 23:29:39 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367cde7e07fsm4347771f8f.17.2024.07.09.23.29.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:37 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 06/10] target/i386/tcg: Compute MMU index once Date: Wed, 10 Jul 2024 08:29:16 +0200 Message-ID: <20240710062920.73063-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add the MMU index to the StackAccess struct, so that it can be cached or (in the next patch) computed from information that is not in CPUX86State. Co-developed-by: Richard Henderson Signed-off-by: Richard Henderson Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/tcg/seg_helper.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 6b3de7a2be4..07e3667639a 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -587,36 +587,37 @@ typedef struct StackAccess target_ulong ss_base; target_ulong sp; target_ulong sp_mask; + int mmu_index; } StackAccess; static void pushw(StackAccess *sa, uint16_t val) { sa->sp -= 2; - cpu_stw_kernel_ra(sa->env, sa->ss_base + (sa->sp & sa->sp_mask), - val, sa->ra); + cpu_stw_mmuidx_ra(sa->env, sa->ss_base + (sa->sp & sa->sp_mask), + val, sa->mmu_index, sa->ra); } static void pushl(StackAccess *sa, uint32_t val) { sa->sp -= 4; - cpu_stl_kernel_ra(sa->env, sa->ss_base + (sa->sp & sa->sp_mask), - val, sa->ra); + cpu_stl_mmuidx_ra(sa->env, sa->ss_base + (sa->sp & sa->sp_mask), + val, sa->mmu_index, sa->ra); } static uint16_t popw(StackAccess *sa) { - uint16_t ret = cpu_lduw_data_ra(sa->env, - sa->ss_base + (sa->sp & sa->sp_mask), - sa->ra); + uint16_t ret = cpu_lduw_mmuidx_ra(sa->env, + sa->ss_base + (sa->sp & sa->sp_mask), + sa->mmu_index, sa->ra); sa->sp += 2; return ret; } static uint32_t popl(StackAccess *sa) { - uint32_t ret = cpu_ldl_data_ra(sa->env, - sa->ss_base + (sa->sp & sa->sp_mask), - sa->ra); + uint32_t ret = cpu_ldl_mmuidx_ra(sa->env, + sa->ss_base + (sa->sp & sa->sp_mask), + sa->mmu_index, sa->ra); sa->sp += 4; return ret; } @@ -677,6 +678,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, sa.env = env; sa.ra = 0; + sa.mmu_index = cpu_mmu_index_kernel(env); if (type == 5) { /* task gate */ @@ -858,12 +860,12 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, static void pushq(StackAccess *sa, uint64_t val) { sa->sp -= 8; - cpu_stq_kernel_ra(sa->env, sa->sp, val, sa->ra); + cpu_stq_mmuidx_ra(sa->env, sa->sp, val, sa->mmu_index, sa->ra); } static uint64_t popq(StackAccess *sa) { - uint64_t ret = cpu_ldq_data_ra(sa->env, sa->sp, sa->ra); + uint64_t ret = cpu_ldq_mmuidx_ra(sa->env, sa->sp, sa->mmu_index, sa->ra); sa->sp += 8; return ret; } @@ -982,6 +984,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int, sa.env = env; sa.ra = 0; + sa.mmu_index = cpu_mmu_index_kernel(env); sa.sp_mask = -1; sa.ss_base = 0; if (dpl < cpl || ist != 0) { @@ -1116,6 +1119,7 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int, sa.sp = env->regs[R_ESP]; sa.sp_mask = 0xffff; sa.ss_base = env->segs[R_SS].base; + sa.mmu_index = cpu_mmu_index_kernel(env); if (is_int) { old_eip = next_eip; @@ -1579,6 +1583,7 @@ void helper_lcall_real(CPUX86State *env, uint32_t new_cs, uint32_t new_eip, sa.sp = env->regs[R_ESP]; sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); sa.ss_base = env->segs[R_SS].base; + sa.mmu_index = cpu_mmu_index_kernel(env); if (shift) { pushl(&sa, env->segs[R_CS].selector); @@ -1618,6 +1623,7 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, sa.env = env; sa.ra = GETPC(); + sa.mmu_index = cpu_mmu_index_kernel(env); if (e2 & DESC_S_MASK) { if (!(e2 & DESC_CS_MASK)) { @@ -1905,6 +1911,7 @@ void helper_iret_real(CPUX86State *env, int shift) sa.env = env; sa.ra = GETPC(); + sa.mmu_index = x86_mmu_index_pl(env, 0); sa.sp_mask = 0xffff; /* XXXX: use SS segment size? */ sa.sp = env->regs[R_ESP]; sa.ss_base = env->segs[R_SS].base; @@ -1976,8 +1983,11 @@ static inline void helper_ret_protected(CPUX86State *env, int shift, target_ulong new_eip, new_esp; StackAccess sa; + cpl = env->hflags & HF_CPL_MASK; + sa.env = env; sa.ra = retaddr; + sa.mmu_index = x86_mmu_index_pl(env, cpl); #ifdef TARGET_X86_64 if (shift == 2) { @@ -2032,7 +2042,6 @@ static inline void helper_ret_protected(CPUX86State *env, int shift, !(e2 & DESC_CS_MASK)) { raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, retaddr); } - cpl = env->hflags & HF_CPL_MASK; rpl = new_cs & 3; if (rpl < cpl) { raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, retaddr); From patchwork Wed Jul 10 06:29:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958720 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=Y/LVyNTj; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJnzh72R8z1yNy for ; Wed, 10 Jul 2024 16:30:40 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQps-0000OD-1d; Wed, 10 Jul 2024 02:29:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpp-0000Df-Fn for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:49 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpn-0000vF-Ng for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:49 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592987; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vEGqfwScZxwmUn4DuepxdsFQZ9X1/s8dk2WV3PWSmng=; b=Y/LVyNTj/sE3s12XXQkr/2Rg+cnjEokyera0hQyu9qxvi3F7rk1b2zsdlG5eVDcqFZVH9a wShrX/b+IQ+wy/Zt/aX2XpR/jMG8BW79z0S9LRuJWlP6TmLN3gwi12DxisJqHvgE3nbZJP fBMbLCW5aFXkZ8Tnxt3SS2ZPDLL8HDc= Received: from mail-ej1-f71.google.com (mail-ej1-f71.google.com [209.85.218.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-142-aLYBiFpeMHCjyPsNotU8fg-1; Wed, 10 Jul 2024 02:29:44 -0400 X-MC-Unique: aLYBiFpeMHCjyPsNotU8fg-1 Received: by mail-ej1-f71.google.com with SMTP id a640c23a62f3a-a77b2b1d344so401342466b.2 for ; Tue, 09 Jul 2024 23:29:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592982; x=1721197782; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=vEGqfwScZxwmUn4DuepxdsFQZ9X1/s8dk2WV3PWSmng=; b=N6EOvQMj02B0/u+7GdRGBiiWS4Fo27XpZ4jjwnIR8z/S/T5KKyuDsov8hrEk8UgRXF IKWIjqeV7RNigYpMotSD/b3rTrXayKI0M3qe0JzQCEKYxKCFm/Kn53Y8wspaytbP9/My KpC4NG3AgqizBtBZklnCUSLy3kA82ix6LzM76FvYQBKJHVmQGJtLNXVNEXqIzMo1iabv 4iLPqumJdEa25MpZPVUOmbBpLfKeVnuECy4CDevHu0AgKd037vvFXhYRMkiXnptIMwVF RsZ9lp/vACUqHHjSEkN62kOkNeqY1MFfnxBFiFfE0yr9UYHUQaLnvazRQKTUV9P5RRPT FPeQ== X-Gm-Message-State: AOJu0YwJCzzH2Dx1DumTvqKtakaeaPcJz/tHZrDS5LOa6lNqkhLnhet5 hRB2VdzxOSQ37zbKCXOk2x4ikDoUD7B52+IHLxY3ic8Y1kP0YH9eQDG3G2OIGWjXpzhYbpJgx5t KJBV6EbtUss0vhjcm48OeS3ijRsKdgnOPfRlqQKaGDy8GLvFrCSKFHM8RV/Zg/c7Eex7Ay7BxKz tiQBUa+PQNVAtQepm2bbOF3b8Z8NOLf4Dqllcj X-Received: by 2002:a17:906:3396:b0:a77:e2b2:8ef with SMTP id a640c23a62f3a-a780b89f41dmr253505666b.70.1720592982499; Tue, 09 Jul 2024 23:29:42 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFYLd9jG9VYw4d7gAqJJB7JZYu+1dtWyLQcl9kChBpcSsnVuiSbONFF+SXez1K/7lCm4vX4/w== X-Received: by 2002:a17:906:3396:b0:a77:e2b2:8ef with SMTP id a640c23a62f3a-a780b89f41dmr253503766b.70.1720592982021; Tue, 09 Jul 2024 23:29:42 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367cde89108sm4361663f8f.55.2024.07.09.23.29.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:40 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 07/10] target/i386/tcg: Use DPL-level accesses for interrupts and call gates Date: Wed, 10 Jul 2024 08:29:17 +0200 Message-ID: <20240710062920.73063-8-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This fixes a bug wherein i386/tcg assumed an interrupt return using the CALL or JMP instructions were always going from kernel or user mode to kernel mode, when using a call gate. This assumption is violated if the call gate has a DPL that is greater than 0. In addition, the stack accesses should count as explicit, not implicit ("kernel" in QEMU code), so that SMAP is not applied if DPL=3. Analyzed-by: Robert R. Henry Resolves: https://gitlab.com/qemu-project/qemu/-/issues/249 Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/tcg/seg_helper.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 07e3667639a..1430f477c43 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -678,7 +678,7 @@ static void do_interrupt_protected(CPUX86State *env, int intno, int is_int, sa.env = env; sa.ra = 0; - sa.mmu_index = cpu_mmu_index_kernel(env); + sa.mmu_index = x86_mmu_index_pl(env, dpl); if (type == 5) { /* task gate */ @@ -984,7 +984,7 @@ static void do_interrupt64(CPUX86State *env, int intno, int is_int, sa.env = env; sa.ra = 0; - sa.mmu_index = cpu_mmu_index_kernel(env); + sa.mmu_index = x86_mmu_index_pl(env, dpl); sa.sp_mask = -1; sa.ss_base = 0; if (dpl < cpl || ist != 0) { @@ -1119,7 +1119,7 @@ static void do_interrupt_real(CPUX86State *env, int intno, int is_int, sa.sp = env->regs[R_ESP]; sa.sp_mask = 0xffff; sa.ss_base = env->segs[R_SS].base; - sa.mmu_index = cpu_mmu_index_kernel(env); + sa.mmu_index = x86_mmu_index_pl(env, 0); if (is_int) { old_eip = next_eip; @@ -1583,7 +1583,7 @@ void helper_lcall_real(CPUX86State *env, uint32_t new_cs, uint32_t new_eip, sa.sp = env->regs[R_ESP]; sa.sp_mask = get_sp_mask(env->segs[R_SS].flags); sa.ss_base = env->segs[R_SS].base; - sa.mmu_index = cpu_mmu_index_kernel(env); + sa.mmu_index = x86_mmu_index_pl(env, 0); if (shift) { pushl(&sa, env->segs[R_CS].selector); @@ -1619,17 +1619,17 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); } cpl = env->hflags & HF_CPL_MASK; + dpl = (e2 >> DESC_DPL_SHIFT) & 3; LOG_PCALL("desc=%08x:%08x\n", e1, e2); sa.env = env; sa.ra = GETPC(); - sa.mmu_index = cpu_mmu_index_kernel(env); + sa.mmu_index = x86_mmu_index_pl(env, dpl); if (e2 & DESC_S_MASK) { if (!(e2 & DESC_CS_MASK)) { raise_exception_err_ra(env, EXCP0D_GPF, new_cs & 0xfffc, GETPC()); } - dpl = (e2 >> DESC_DPL_SHIFT) & 3; if (e2 & DESC_C_MASK) { /* conforming code segment */ if (dpl > cpl) { @@ -1691,7 +1691,6 @@ void helper_lcall_protected(CPUX86State *env, int new_cs, target_ulong new_eip, } else { /* check gate type */ type = (e2 >> DESC_TYPE_SHIFT) & 0x1f; - dpl = (e2 >> DESC_DPL_SHIFT) & 3; rpl = new_cs & 3; #ifdef TARGET_X86_64 From patchwork Wed Jul 10 06:29:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958722 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=HCTgqwIa; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJp002T5Pz1yNy for ; Wed, 10 Jul 2024 16:30:56 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQpt-0000Vu-45; Wed, 10 Jul 2024 02:29:53 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpq-0000KG-Ux for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:50 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpp-0000vM-JW for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592989; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=8+uzj3RGp8F8f+unwaA1jvsqz4v1x4mS4inV4L7PkF0=; b=HCTgqwIaGFLtcOIDh9gCskI1JWVvJHlukNBkQ69XvN698B3clJaRJzeF6SQj8wooxHaCdX nKUwD1J5kwL9bQCjpdLe2J+rwmcgZRUT3RUZLw2FonQp8QEqANTe0iqAbM7E5Ip/lvhy/P ViBCyll0+xO7epCobjd/D/MOWbtpmb8= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-526-GUkfe6KZOseVRCJ6P12jDg-1; Wed, 10 Jul 2024 02:29:46 -0400 X-MC-Unique: GUkfe6KZOseVRCJ6P12jDg-1 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-42671a6fb9dso9605625e9.3 for ; Tue, 09 Jul 2024 23:29:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592985; x=1721197785; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8+uzj3RGp8F8f+unwaA1jvsqz4v1x4mS4inV4L7PkF0=; b=qerqICDIyxCxgRnzIyPlIVt/pPJ+qfj4olbUYh9ZvpnUAbyUDtTf2Ygp/hCUuYss3E O7o13ha3W2CYUms437ASW8sAji2E5jPrfl8hLlNEizmiOHV6+5uRKLF3dfCVEjFBcpW5 8LQoo9a3mLNesJB59WwFu7JAkhAhZhjPhMVZuchEErt1BvYjDuqQbt2lFwReom78vB8A QUjz0UYzzZLTmiLMXTwBFw6+KCJU/eFyjKyqbHNEeqOe/OEzAo1g8nMwWx/7+mChnHdT ODJWVnh2kM87D7phgz+rYmqOpqpI8jwR05JMqSTeBrTLQAHYgNy74hF6D0y29QfUJ1uA EIBw== X-Gm-Message-State: AOJu0Yw+3OZbpYtVWUgpVqwFgFjnlRGUTmq+YQQz85LvqaPwSqxcBbvK 3ro66YtQ37ZRA016cvKAw7E1Ht2HHnpu2cNf9Ywjei6xrWIU8Kcmsbi10AsE6Q2H4hOD5oJtGt8 hXOhsxpJBiySSDdDq5zmLZdKv/V8FNi/uzTBgPHKlB0q3r2rwNqpFqamNSvEra+JqAma7Q5qBPk zhpQ05+ZFqWWCiUyBCDSTal6TaZxjtq+Rv1Ms+ X-Received: by 2002:a05:600c:206:b0:426:5c36:207c with SMTP id 5b1f17b1804b1-426708f1d6emr35744985e9.25.1720592985155; Tue, 09 Jul 2024 23:29:45 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGbX2XXQ6mm5vIvZT9TxC4xvapGezrW0Jpf6T36H7Ejbr/P5qLxKVM/1tTOSMG47P/yRQvbHg== X-Received: by 2002:a05:600c:206:b0:426:5c36:207c with SMTP id 5b1f17b1804b1-426708f1d6emr35744855e9.25.1720592984849; Tue, 09 Jul 2024 23:29:44 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367cdfb22aasm4373995f8f.117.2024.07.09.23.29.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:43 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 08/10] target/i386/tcg: check for correct busy state before switching to a new task Date: Wed, 10 Jul 2024 08:29:18 +0200 Message-ID: <20240710062920.73063-9-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This step is listed in the Intel manual: "Checks that the new task is available (call, jump, exception, or interrupt) or busy (IRET return)". The AMD manual lists the same operation under the "Preventing recursion" paragraph of "12.3.4 Nesting Tasks", though it is not clear if the processor checks the busy bit in the IRET case. Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/tcg/seg_helper.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 1430f477c43..25af9d4a4ec 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -306,6 +306,11 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, old_tss_limit_max = 43; } + /* new TSS must be busy iff the source is an IRET instruction */ + if (!!(e2 & DESC_TSS_BUSY_MASK) != (source == SWITCH_TSS_IRET)) { + raise_exception_err_ra(env, EXCP0A_TSS, tss_selector & 0xfffc, retaddr); + } + /* read all the registers from the new TSS */ if (type & 8) { /* 32 bit */ From patchwork Wed Jul 10 06:29:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958721 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ayk1tOdQ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJnzj3NSvz20MK for ; Wed, 10 Jul 2024 16:30:41 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQpz-0000uP-2d; Wed, 10 Jul 2024 02:29:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpx-0000ox-NJ for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:57 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpv-0000vh-QC for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592995; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=LOknd05sKwCruykEoyDotoa/EwDe53WiDHzzrB4cdNA=; b=ayk1tOdQzOEOHkStinlkmuGYyY9epuJfCIjpiKxPrOkCwzXceaOVMBghgZBm/YlgYuhOGm 5LJjzOR2ILgcU8C/7Fi2hbqAH+7sOdJFuOAO7sNcDrVRr1Zu10QK8n2HteOnl05u6UQj8a osUAVzqLYAjqK+AoruuIPkJunaMuGWQ= Received: from mail-lj1-f200.google.com (mail-lj1-f200.google.com [209.85.208.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-638-mAlj_skAPoaWJHNAbW251Q-1; Wed, 10 Jul 2024 02:29:51 -0400 X-MC-Unique: mAlj_skAPoaWJHNAbW251Q-1 Received: by mail-lj1-f200.google.com with SMTP id 38308e7fff4ca-2ee87e69b53so63941811fa.0 for ; Tue, 09 Jul 2024 23:29:50 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592988; x=1721197788; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LOknd05sKwCruykEoyDotoa/EwDe53WiDHzzrB4cdNA=; b=AmP9fUin8jVoxxBl9Ap30hjU2sELm35jGtXUL9Rw8cgKHVXvL1RKRah1GDhwoa1Otl lmr6hlcb04KRcjrtFVvojEJdWHtNowoyXwJxPvHbcQZvPgdWkY+jMAsBJHOy12tUvzYW 4Eou7y1Ftz73FCXqlP80U+p1a/LtvyP3rpdwBt1PggpRlSLz2hC7UrwjBjMZPJvk7iuP u6ovWWcluhICtbzbwgJ9KptZLDX2gR0AereWxRH8cwBsxZ0ngAuBNlgFv+aEmF/SDnuy Dxl1ItftRLB4/DlkJr2BxsWnnqrKbhz8Lmm7v+X4EwETZDEvEx1qzNjjVPSjlATYJYef RlwA== X-Gm-Message-State: AOJu0Yz8tSTDhUsFBD4Ui3UGGtxl4fzu5Chyw3mFz13onN2Qc4DOcLVn 57fb6EVwIncGyMzx9IlEDfQJDoErrI/lprHUjQuRa30saC9Y4iWsvL2ha5ik9i5Q2g4ZomuusUM bT4LtMomWej90TBpUDgCSN9JUSUWvUeFhReqKKoNTKx9N8R8UIGGr6kq31wbAk0IqMSC3vsb2cK y6Zru3qtGWd444nzA13Lj17VAEANnNnt7lkQSq X-Received: by 2002:a2e:9ec6:0:b0:2ec:4b00:a746 with SMTP id 38308e7fff4ca-2eeb30bb394mr32864501fa.9.1720592987897; Tue, 09 Jul 2024 23:29:47 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH+t/t9GMGIFZlnMR7HkdoSAWDKWRhJI5tPtWszk1pfiPppcFT6eQyztgrDnuiOvpewNJNIqQ== X-Received: by 2002:a2e:9ec6:0:b0:2ec:4b00:a746 with SMTP id 38308e7fff4ca-2eeb30bb394mr32864341fa.9.1720592987419; Tue, 09 Jul 2024 23:29:47 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367cdfb228csm4325189f8f.114.2024.07.09.23.29.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:46 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 09/10] target/i386/tcg: use X86Access for TSS access Date: Wed, 10 Jul 2024 08:29:19 +0200 Message-ID: <20240710062920.73063-10-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This takes care of probing the vaddr range in advance, and is also faster because it avoids repeated TLB lookups. It also matches the Intel manual better, as it says "Checks that the current (old) TSS, new TSS, and all segment descriptors used in the task switch are paged into system memory"; note however that it's not clear how the processor checks for segment descriptors, and this check is not included in the AMD manual. Signed-off-by: Paolo Bonzini --- target/i386/tcg/seg_helper.c | 101 ++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 50 deletions(-) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 25af9d4a4ec..77f2c65c3cf 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -27,6 +27,7 @@ #include "exec/log.h" #include "helper-tcg.h" #include "seg_helper.h" +#include "access.h" int get_pg_mode(CPUX86State *env) { @@ -250,7 +251,7 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, uint32_t e1, uint32_t e2, int source, uint32_t next_eip, uintptr_t retaddr) { - int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, v1, v2, i; + int tss_limit, tss_limit_max, type, old_tss_limit_max, old_type, i; target_ulong tss_base; uint32_t new_regs[8], new_segs[6]; uint32_t new_eflags, new_eip, new_cr3, new_ldt, new_trap; @@ -258,6 +259,7 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, SegmentCache *dt; int index; target_ulong ptr; + X86Access old, new; type = (e2 >> DESC_TYPE_SHIFT) & 0xf; LOG_PCALL("switch_tss: sel=0x%04x type=%d src=%d\n", tss_selector, type, @@ -311,35 +313,44 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, raise_exception_err_ra(env, EXCP0A_TSS, tss_selector & 0xfffc, retaddr); } + /* X86Access avoids memory exceptions during the task switch */ + access_prepare_mmu(&old, env, env->tr.base, old_tss_limit_max, + MMU_DATA_STORE, cpu_mmu_index_kernel(env), retaddr); + + if (source == SWITCH_TSS_CALL) { + /* Probe for future write of parent task */ + probe_access(env, tss_base, 2, MMU_DATA_STORE, + cpu_mmu_index_kernel(env), retaddr); + } + access_prepare_mmu(&new, env, tss_base, tss_limit, + MMU_DATA_LOAD, cpu_mmu_index_kernel(env), retaddr); + /* read all the registers from the new TSS */ if (type & 8) { /* 32 bit */ - new_cr3 = cpu_ldl_kernel_ra(env, tss_base + 0x1c, retaddr); - new_eip = cpu_ldl_kernel_ra(env, tss_base + 0x20, retaddr); - new_eflags = cpu_ldl_kernel_ra(env, tss_base + 0x24, retaddr); + new_cr3 = access_ldl(&new, tss_base + 0x1c); + new_eip = access_ldl(&new, tss_base + 0x20); + new_eflags = access_ldl(&new, tss_base + 0x24); for (i = 0; i < 8; i++) { - new_regs[i] = cpu_ldl_kernel_ra(env, tss_base + (0x28 + i * 4), - retaddr); + new_regs[i] = access_ldl(&new, tss_base + (0x28 + i * 4)); } for (i = 0; i < 6; i++) { - new_segs[i] = cpu_lduw_kernel_ra(env, tss_base + (0x48 + i * 4), - retaddr); + new_segs[i] = access_ldw(&new, tss_base + (0x48 + i * 4)); } - new_ldt = cpu_lduw_kernel_ra(env, tss_base + 0x60, retaddr); - new_trap = cpu_ldl_kernel_ra(env, tss_base + 0x64, retaddr); + new_ldt = access_ldw(&new, tss_base + 0x60); + new_trap = access_ldl(&new, tss_base + 0x64); } else { /* 16 bit */ new_cr3 = 0; - new_eip = cpu_lduw_kernel_ra(env, tss_base + 0x0e, retaddr); - new_eflags = cpu_lduw_kernel_ra(env, tss_base + 0x10, retaddr); + new_eip = access_ldw(&new, tss_base + 0x0e); + new_eflags = access_ldw(&new, tss_base + 0x10); for (i = 0; i < 8; i++) { - new_regs[i] = cpu_lduw_kernel_ra(env, tss_base + (0x12 + i * 2), retaddr); + new_regs[i] = access_ldw(&new, tss_base + (0x12 + i * 2)); } for (i = 0; i < 4; i++) { - new_segs[i] = cpu_lduw_kernel_ra(env, tss_base + (0x22 + i * 2), - retaddr); + new_segs[i] = access_ldw(&new, tss_base + (0x22 + i * 2)); } - new_ldt = cpu_lduw_kernel_ra(env, tss_base + 0x2a, retaddr); + new_ldt = access_ldw(&new, tss_base + 0x2a); new_segs[R_FS] = 0; new_segs[R_GS] = 0; new_trap = 0; @@ -349,16 +360,6 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, chapters 12.2.5 and 13.2.4 on how to implement TSS Trap bit */ (void)new_trap; - /* NOTE: we must avoid memory exceptions during the task switch, - so we make dummy accesses before */ - /* XXX: it can still fail in some cases, so a bigger hack is - necessary to valid the TLB after having done the accesses */ - - v1 = cpu_ldub_kernel_ra(env, env->tr.base, retaddr); - v2 = cpu_ldub_kernel_ra(env, env->tr.base + old_tss_limit_max, retaddr); - cpu_stb_kernel_ra(env, env->tr.base, v1, retaddr); - cpu_stb_kernel_ra(env, env->tr.base + old_tss_limit_max, v2, retaddr); - /* clear busy bit (it is restartable) */ if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) { tss_set_busy(env, env->tr.selector, 0, retaddr); @@ -371,35 +372,35 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, /* save the current state in the old TSS */ if (old_type & 8) { /* 32 bit */ - cpu_stl_kernel_ra(env, env->tr.base + 0x20, next_eip, retaddr); - cpu_stl_kernel_ra(env, env->tr.base + 0x24, old_eflags, retaddr); - cpu_stl_kernel_ra(env, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX], retaddr); - cpu_stl_kernel_ra(env, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX], retaddr); - cpu_stl_kernel_ra(env, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX], retaddr); - cpu_stl_kernel_ra(env, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX], retaddr); - cpu_stl_kernel_ra(env, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP], retaddr); - cpu_stl_kernel_ra(env, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP], retaddr); - cpu_stl_kernel_ra(env, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI], retaddr); - cpu_stl_kernel_ra(env, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI], retaddr); + access_stl(&old, env->tr.base + 0x20, next_eip); + access_stl(&old, env->tr.base + 0x24, old_eflags); + access_stl(&old, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]); + access_stl(&old, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]); + access_stl(&old, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]); + access_stl(&old, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]); + access_stl(&old, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]); + access_stl(&old, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]); + access_stl(&old, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]); + access_stl(&old, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]); for (i = 0; i < 6; i++) { - cpu_stw_kernel_ra(env, env->tr.base + (0x48 + i * 4), - env->segs[i].selector, retaddr); + access_stw(&old, env->tr.base + (0x48 + i * 4), + env->segs[i].selector); } } else { /* 16 bit */ - cpu_stw_kernel_ra(env, env->tr.base + 0x0e, next_eip, retaddr); - cpu_stw_kernel_ra(env, env->tr.base + 0x10, old_eflags, retaddr); - cpu_stw_kernel_ra(env, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX], retaddr); - cpu_stw_kernel_ra(env, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX], retaddr); - cpu_stw_kernel_ra(env, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX], retaddr); - cpu_stw_kernel_ra(env, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX], retaddr); - cpu_stw_kernel_ra(env, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP], retaddr); - cpu_stw_kernel_ra(env, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP], retaddr); - cpu_stw_kernel_ra(env, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI], retaddr); - cpu_stw_kernel_ra(env, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI], retaddr); + access_stw(&old, env->tr.base + 0x0e, next_eip); + access_stw(&old, env->tr.base + 0x10, old_eflags); + access_stw(&old, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]); + access_stw(&old, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]); + access_stw(&old, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]); + access_stw(&old, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]); + access_stw(&old, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]); + access_stw(&old, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]); + access_stw(&old, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]); + access_stw(&old, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]); for (i = 0; i < 4; i++) { - cpu_stw_kernel_ra(env, env->tr.base + (0x22 + i * 2), - env->segs[i].selector, retaddr); + access_stw(&old, env->tr.base + (0x22 + i * 2), + env->segs[i].selector); } } From patchwork Wed Jul 10 06:29:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 1958723 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=PAL1BvbJ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=patchwork.ozlabs.org) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4WJp0H1Kvjz1yNy for ; Wed, 10 Jul 2024 16:31:11 +1000 (AEST) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sRQq0-000110-NZ; Wed, 10 Jul 2024 02:30:00 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpz-0000wS-Hm for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:59 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sRQpx-0000vn-RH for qemu-devel@nongnu.org; Wed, 10 Jul 2024 02:29:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1720592997; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=1Ql2wQ9TsVXf1SgGfQDPRSm5NqN+wHIJJjqUCwnWnLM=; b=PAL1BvbJoJeEb3IZ9g/rHXe6cPxoCHnHEHHHbTQv5EbeId8sZhzv5qzk3k4RxfcsQEvoFr rjr6THt2cJOhxuwkvPQ5O9I3HcofrZ2rPGlGVzBtF1aTMtXslFHAJtOGFsnqS3IScRbiTu WlTfgQtjZKvPn5p4K0BvMCeiyeyMt9M= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-231-rMBVv1Q7NHKdKnkxgR4H_w-1; Wed, 10 Jul 2024 02:29:53 -0400 X-MC-Unique: rMBVv1Q7NHKdKnkxgR4H_w-1 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-367990b4beeso4038819f8f.2 for ; Tue, 09 Jul 2024 23:29:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720592991; x=1721197791; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1Ql2wQ9TsVXf1SgGfQDPRSm5NqN+wHIJJjqUCwnWnLM=; b=ni8ogAtxN6GfVhfpvp/Gzie7yXFrUfKM/y98DKpFpqSeky1GelurX/uwW9zMUjpbj+ kCt41Kgy67piUHwKizc3zfqS8dC379XBu5UHMR9SloZjNEQ1wBtED6mi0WShlWnzt0jf VG+we104JqC4tqJRRXX3r+B8NlrnOFOxYoXjBSkbdKNsmz/gWtT2NESq6UaVEDfdgxcT g8bdvDu5vk8QZT+QDHMHXph/QdX+MAsDPP2dWrEquptO6pYyx1GdIcm3pDn66VnJJF0c VUtn5wWwCi1s+qX/aDKow5MVz/oVUQ5nTsASXATk/xaxyw3n5Ry83db+sq1xmW7MJywp UtJQ== X-Gm-Message-State: AOJu0Yycdl3/4ZpO3e88h6akeD9/NJGWIRKhA6JvdhjZIF6mefcI89d0 sCwIq3I1+MeG15E8e4PTHFW6aTdcpuLkDfXxCdHhNLMBUhOXm+VheLNUgWKkDn0/9nhzZx8h2ph wjo7UIlygxStL2a4BUNA2MhQ7IoV6h9W5X9BLpWdKIHzvfHpKM7bdtk3Bb2xG8Lt0RG7PNfd+IO s+FRQsI08CRRU46Uw/f3w5k/yCLv4hPafh4UT5 X-Received: by 2002:a5d:68cd:0:b0:367:9d21:22cb with SMTP id ffacd0b85a97d-367cea73551mr2710222f8f.22.1720592991217; Tue, 09 Jul 2024 23:29:51 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFwouR3TO5lOWSmKO2x+OIXS3QBTsbFDmj3fcKeeVcSJ9tc6Hpn0lAFPJtC7bk4zCdIJhL/cA== X-Received: by 2002:a5d:68cd:0:b0:367:9d21:22cb with SMTP id ffacd0b85a97d-367cea73551mr2710212f8f.22.1720592990856; Tue, 09 Jul 2024 23:29:50 -0700 (PDT) Received: from avogadro.local ([151.95.101.29]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-367cde847bdsm4361702f8f.41.2024.07.09.23.29.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 09 Jul 2024 23:29:48 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: rrh.henry@gmail.com, richard.henderson@linaro.org Subject: [PATCH 10/10] target/i386/tcg: save current task state before loading new one Date: Wed, 10 Jul 2024 08:29:20 +0200 Message-ID: <20240710062920.73063-11-pbonzini@redhat.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240710062920.73063-1-pbonzini@redhat.com> References: <20240710062920.73063-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -21 X-Spam_score: -2.2 X-Spam_bar: -- X-Spam_report: (-2.2 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.144, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This is how the steps are ordered in the manual. EFLAGS.NT is overwritten after the fact in the saved image. Signed-off-by: Paolo Bonzini Reviewed-by: Richard Henderson --- target/i386/tcg/seg_helper.c | 85 +++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/target/i386/tcg/seg_helper.c b/target/i386/tcg/seg_helper.c index 77f2c65c3cf..7663e653e84 100644 --- a/target/i386/tcg/seg_helper.c +++ b/target/i386/tcg/seg_helper.c @@ -325,6 +325,42 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, access_prepare_mmu(&new, env, tss_base, tss_limit, MMU_DATA_LOAD, cpu_mmu_index_kernel(env), retaddr); + /* save the current state in the old TSS */ + old_eflags = cpu_compute_eflags(env); + if (old_type & 8) { + /* 32 bit */ + access_stl(&old, env->tr.base + 0x20, next_eip); + access_stl(&old, env->tr.base + 0x24, old_eflags); + access_stl(&old, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]); + access_stl(&old, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]); + access_stl(&old, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]); + access_stl(&old, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]); + access_stl(&old, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]); + access_stl(&old, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]); + access_stl(&old, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]); + access_stl(&old, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]); + for (i = 0; i < 6; i++) { + access_stw(&old, env->tr.base + (0x48 + i * 4), + env->segs[i].selector); + } + } else { + /* 16 bit */ + access_stw(&old, env->tr.base + 0x0e, next_eip); + access_stw(&old, env->tr.base + 0x10, old_eflags); + access_stw(&old, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]); + access_stw(&old, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]); + access_stw(&old, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]); + access_stw(&old, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]); + access_stw(&old, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]); + access_stw(&old, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]); + access_stw(&old, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]); + access_stw(&old, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]); + for (i = 0; i < 4; i++) { + access_stw(&old, env->tr.base + (0x22 + i * 2), + env->segs[i].selector); + } + } + /* read all the registers from the new TSS */ if (type & 8) { /* 32 bit */ @@ -364,49 +400,16 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, if (source == SWITCH_TSS_JMP || source == SWITCH_TSS_IRET) { tss_set_busy(env, env->tr.selector, 0, retaddr); } - old_eflags = cpu_compute_eflags(env); + if (source == SWITCH_TSS_IRET) { old_eflags &= ~NT_MASK; + if (old_type & 8) { + access_stl(&old, env->tr.base + 0x24, old_eflags); + } else { + access_stw(&old, env->tr.base + 0x10, old_eflags); + } } - /* save the current state in the old TSS */ - if (old_type & 8) { - /* 32 bit */ - access_stl(&old, env->tr.base + 0x20, next_eip); - access_stl(&old, env->tr.base + 0x24, old_eflags); - access_stl(&old, env->tr.base + (0x28 + 0 * 4), env->regs[R_EAX]); - access_stl(&old, env->tr.base + (0x28 + 1 * 4), env->regs[R_ECX]); - access_stl(&old, env->tr.base + (0x28 + 2 * 4), env->regs[R_EDX]); - access_stl(&old, env->tr.base + (0x28 + 3 * 4), env->regs[R_EBX]); - access_stl(&old, env->tr.base + (0x28 + 4 * 4), env->regs[R_ESP]); - access_stl(&old, env->tr.base + (0x28 + 5 * 4), env->regs[R_EBP]); - access_stl(&old, env->tr.base + (0x28 + 6 * 4), env->regs[R_ESI]); - access_stl(&old, env->tr.base + (0x28 + 7 * 4), env->regs[R_EDI]); - for (i = 0; i < 6; i++) { - access_stw(&old, env->tr.base + (0x48 + i * 4), - env->segs[i].selector); - } - } else { - /* 16 bit */ - access_stw(&old, env->tr.base + 0x0e, next_eip); - access_stw(&old, env->tr.base + 0x10, old_eflags); - access_stw(&old, env->tr.base + (0x12 + 0 * 2), env->regs[R_EAX]); - access_stw(&old, env->tr.base + (0x12 + 1 * 2), env->regs[R_ECX]); - access_stw(&old, env->tr.base + (0x12 + 2 * 2), env->regs[R_EDX]); - access_stw(&old, env->tr.base + (0x12 + 3 * 2), env->regs[R_EBX]); - access_stw(&old, env->tr.base + (0x12 + 4 * 2), env->regs[R_ESP]); - access_stw(&old, env->tr.base + (0x12 + 5 * 2), env->regs[R_EBP]); - access_stw(&old, env->tr.base + (0x12 + 6 * 2), env->regs[R_ESI]); - access_stw(&old, env->tr.base + (0x12 + 7 * 2), env->regs[R_EDI]); - for (i = 0; i < 4; i++) { - access_stw(&old, env->tr.base + (0x22 + i * 2), - env->segs[i].selector); - } - } - - /* now if an exception occurs, it will occurs in the next task - context */ - if (source == SWITCH_TSS_CALL) { cpu_stw_kernel_ra(env, tss_base, env->tr.selector, retaddr); new_eflags |= NT_MASK; @@ -418,7 +421,9 @@ static int switch_tss_ra(CPUX86State *env, int tss_selector, } /* set the new CPU state */ - /* from this point, any exception which occurs can give problems */ + + /* now if an exception occurs, it will occur in the next task context */ + env->cr[0] |= CR0_TS_MASK; env->hflags |= HF_TS_MASK; env->tr.selector = tss_selector;