From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pf0-x243.google.com (mail-pf0-x243.google.com [IPv6:2607:f8b0:400e:c00::243]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 2B9A121EB88E6 for ; Sat, 2 Sep 2017 19:09:36 -0700 (PDT) Received: by mail-pf0-x243.google.com with SMTP id g13so2336272pfm.2 for ; Sat, 02 Sep 2017 19:12:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=XpktA1QnwhUesxVoQTx+Z7SVXwHuj8XZ+fmjoHBENOs=; b=LCNfzW03Yw5YjeoqvUT39mUUKjxijMwobDDGKPfLEGRsXPeFDmIw/MJcHgXscxnH6G G9TOg+FGvSCpZM1pAB73/HXOg/8aF7CrkefgqlCkmX0kwHBP+d+jPw4Gb/B+icSRtWR3 oEAp0YghbxHsvle5r4rzQjun5ZTp6aAHH8CsWGqtx8Xl++IgRl0KHVd9ra+ha7euldmC QOohp/KKirXNnO73hMA58zXQdKi2GLcZUBPZi85SRWK75fC5I5Vz7/qFZ3dYulTf+Jmb 8aRRPuMZm/7LJE0nI0/NbbqAKFw99w6sUvRTmo/4TQ/PSy3n+IGYrjY8oom3hHH+3sn1 mHDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=XpktA1QnwhUesxVoQTx+Z7SVXwHuj8XZ+fmjoHBENOs=; b=hfuquPvvKKqNenpbAw37W37/Yef5FiGoYOx7JKT97OquxyEk5dMlo4PBD6v2lDiZ+y qr6ogKKAi0EthULY8Gj/DzQvwFzaSwNmWLpl3EpB06HUrLD8SFjVFo0YfaDM1tQAX7nq 9O5p4VX19Y89bUTSTHdH+cv++3o1YSGbmWIffIU5c00Q/vOibBIjlOCV1zrbHii6JqgT 0d6P1Cwrm9JBcQkXiKUrRu0rZFrTsIoLCts4SUMwbcW6WGDAGs7fYQdcCnWoUqepTNdr Tsb+2DF+lMi6dO6qt42jvTuPRx8ciOBU92KlbNxXPqPEfNmlDgnGiWqdHfB7qVzW5U7H H3Tw== X-Gm-Message-State: AHPjjUjRC9NLxxdAAbWZYe/W5ojyCDvWvqr8cjzAjmqNwtj+fiztzWmI oXemPpWchSHxh4O5Lv8= X-Google-Smtp-Source: ADKCNb6kHt9RivHk/VgCzsBLCPARi2kKrrUsmIpTKwlL03bF8AWKgz1RMBFdpgyssKvJyBL7720LpQ== X-Received: by 10.98.52.67 with SMTP id b64mr7380172pfa.231.1504404740696; Sat, 02 Sep 2017 19:12:20 -0700 (PDT) Received: from localhost.localdomain ([153.34.197.203]) by smtp.gmail.com with ESMTPSA id o10sm4932009pgq.68.2017.09.02.19.12.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sat, 02 Sep 2017 19:12:20 -0700 (PDT) From: Ge Song X-Google-Original-From: Ge Song To: edk2-devel@lists.01.org Cc: Jordan Justen , Laszlo Ersek , Ard Biesheuvel Date: Sun, 3 Sep 2017 10:12:14 +0800 Message-Id: <20170903021214.11516-2-ge.song@hxt-semitech.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170903021214.11516-1-ge.song@hxt-semitech.com> References: <20170903021214.11516-1-ge.song@hxt-semitech.com> MIME-Version: 1.0 Subject: [PATCH v1 1/1] OvmfPkg/SecMain: Fix stack switching to permanent memory fail X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 03 Sep 2017 02:09:36 -0000 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In earlier PEI stage, temporary memory(Cache As Ram) is employed as stack and heap. We move them to the new room and do some relocation fixup when permanent memory becomes available. TemporaryRamMigration() is responsible for switching the stack. In the begining of the TemporaryRamMigration(), Ebp/Rbp is populated with content of Esp/Rsp and used as frame pointer, after the execution of SetJump/LongJump, stack migrates to new position while the context keeps unchanged. But when TemporaryRamMigration() exits, Esp/Rsp is filled with the content of Ebp/Rbp to destroy this stack frame. The result is, stack switches back to previous temporary momery. More detailed information: > TemporaryRamMigration (PeiServices=0x817790, > TemporaryMemoryBase=8454144, PermanentMemoryBase=469016576, > CopySize=32768) > at /home/bird/src/edk2/OvmfPkg/Sec/SecMain.c:938 > 938 LongJump (&JumpBuffer, (UINTN)-1); > (gdb) info registers > rax 0x1bf4d3b0 469029808 > rbx 0x810248 8454728 > rcx 0x8173e8 8483816 > rdx 0x8173b0 8483760 > rsi 0x1bf4a000 469016576 > rdi 0x8000 32768 > rbp 0x817520 0x817520 > rsp 0x8173b0 0x8173b0 > r8 0x0 0 > ... > rip 0xfffcd409 0xfffcd409 > eflags 0x2 [ ] > cs 0x18 24 > ss 0x8 8 > ... After execution of LongJump: > 943 return EFI_SUCCESS; > (gdb) info registers > rax 0x0 0 > rbx 0x810248 8454728 > rcx 0x0 0 > rdx 0xffffffffffffffff -1 > rsi 0x1bf4a000 469016576 > rdi 0x8000 32768 > rbp 0x817520 0x817520 > rsp 0x1bf4d3b0 0x1bf4d3b0 > r8 0x0 0 > ... > rip 0xfffcd42a 0xfffcd42a > eflags 0x86 [ PF SF ] > cs 0x18 24 > ss 0x8 8 > ... We can find rsp has changed to new permanent memory When leaving TemporaryRamMigration(), the stack swithes back to previous temporary memory: > (gdb) finish > Run till exit from #0 TemporaryRamMigration (PeiServices=0x817790, > TemporaryMemoryBase=8454144, PermanentMemoryBase=469016576, > CopySize=32768) > at /home/bird/src/edk2/OvmfPkg/Sec/SecMain.c:943 > PeiCheckAndSwitchStack (SecCoreData=0x1bf4df78, Private=0x1bf4d788) at > /home/bird/src/edk2/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c:806 > 806 PeiCore (SecCoreData, NULL, Private); > Value returned is $1 = 0 > (gdb) info registers > rax 0x0 0 > rbx 0x810248 8454728 > rcx 0x0 0 > rdx 0xffffffffffffffff -1 > rsi 0x1bf4a000 469016576 > rdi 0x8000 32768 > rbp 0x817630 0x817630 > rsp 0x817530 0x817530 > r8 0x0 0 > ... > rip 0x828135 0x828135 > eflags 0x86 [ PF SF ] > cs 0x18 24 > ss 0x8 8 > ... > (gdb) disassemble /r > Dump of assembler code for function TemporaryRamMigration: > 0x00000000fffcd29c <+0>: 55 push %rbp > 0x00000000fffcd29d <+1>: 48 89 e5 mov %rsp,%rbp > 0x00000000fffcd2a0 <+4>: 48 81 ec 70 01 00 00 sub > $0x170,%rsp > ... > ... > 0x00000000fffcd425 <+393>: e8 80 10 00 00 callq 0xfffce4aa > > => 0x00000000fffcd42a <+398>: b8 00 00 00 00 mov $0x0,%eax > 0x00000000fffcd42f <+403>: c9 leaveq > 0x00000000fffcd430 <+404>: c3 retq > End of assembler dump. See the description of leave(opcode: c9), from Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 2A "Releases the stack frame set up by an earlier ENTER instruction. The LEAVE instruction copies the frame pointer (in the EBP register) into the stack pointer register (ESP), which releases the stack space allocated to the stack frame. The old frame pointer (the frame pointer for the calling procedure that was saved by the ENTER instruction) is then popped from the stack into the EBP register, restoring the calling procedure’s stack frame." To solve this, update Ebp/Rbp too when Esp/Rsp is updated Cc: Jordan Justen Cc: Laszlo Ersek Cc: Ard Biesheuvel Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ge Song --- OvmfPkg/Sec/SecMain.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c index e1993ec347b5..f7fec3d8c03b 100644 --- a/OvmfPkg/Sec/SecMain.c +++ b/OvmfPkg/Sec/SecMain.c @@ -931,9 +931,11 @@ TemporaryRamMigration ( if (SetJump (&JumpBuffer) == 0) { #if defined (MDE_CPU_IA32) JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset; + JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset; #endif #if defined (MDE_CPU_X64) JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset; + JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset; #endif LongJump (&JumpBuffer, (UINTN)-1); } -- 2.11.0