From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752185AbcHHXGZ (ORCPT ); Mon, 8 Aug 2016 19:06:25 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56500 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750929AbcHHXGY (ORCPT ); Mon, 8 Aug 2016 19:06:24 -0400 Date: Mon, 8 Aug 2016 18:06:20 -0500 From: Josh Poimboeuf To: Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" Cc: x86@kernel.org, linux-kernel@vger.kernel.org, Andy Lutomirski , Linus Torvalds , Steven Rostedt , Brian Gerst , Kees Cook , Peter Zijlstra , Frederic Weisbecker , Byungchul Park Subject: Re: [PATCH v2 36/44] x86/entry/unwind: encode pt_regs pointer in frame pointer Message-ID: <20160808230620.npfarppkfhozjvzj@treble> References: <39c49ee952529d473f682cc03d105a66a060dd22.1470345772.git.jpoimboe@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <39c49ee952529d473f682cc03d105a66a060dd22.1470345772.git.jpoimboe@redhat.com> User-Agent: Mutt/1.6.0.1 (2016-04-01) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Mon, 08 Aug 2016 23:06:23 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Aug 04, 2016 at 05:22:32PM -0500, Josh Poimboeuf wrote: > With frame pointers, when a task is interrupted, its stack is no longer > completely reliable because the function could have been interrupted > before it had a chance to save the previous frame pointer on the stack. > So the caller of the interrupted function could get skipped by a stack > trace. > > This is problematic for live patching, which needs to know whether a > stack trace of a sleeping task can be relied upon. There's currently no > way to detect if a sleeping task was interrupted by a page fault > exception or preemption before it went to sleep. > > Another issue is that when dumping the stack of an interrupted task, the > unwinder has no way of knowing where the saved pt_regs registers are, so > it can't print them. > > This solves those issues by encoding the pt_regs pointer in the frame > pointer on entry from an interrupt or an exception. The frame pointer > unwinder is also updated to decode it. > > Suggested-by: Andy Lutomirski > Signed-off-by: Josh Poimboeuf When doing some testing on x86_32, I realized there's a flaw here in the unwinder's pt_regs detection, when an interrupt hits when we're already in the entry code. For example, a page fault can be interrupted by an irq, after the page fault entry code encoded the frame pointer, but before it had a chance to call into the C handler. In that case, regs->bp itself is encoded, and the current "pt_regs aren't real frames" design falls apart because there can actually be more than one set of pt_regs per "frame". So the unwinder gets confused and stops walking the stack too early. So really the unwinder needs to consider each pt_regs as a frame in and of itself. Which of course Andy already suggested before, but I stupidly shot it down. Working on that for v3. -- Josh