From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Google-Smtp-Source: AH8x2248JX+rNJ+N8zzgkR4/30vudDR19a0zbFzxYu8m1MXzeR/wt/Cmo03UnOYf2eq5YDZVOzwk ARC-Seal: i=1; a=rsa-sha256; t=1516841836; cv=none; d=google.com; s=arc-20160816; b=qSOcc+m0x7wWzWenZHHZf4VCNE8yThUrV0Jf3Vctj5rC7dzkvqvu8MFpcoRRGmrO6P QGNhyfPhTuAT9PYbDJyku/p9I2qWEI9V40zJYj0QpvHmN5kBxhDQ/UaY2WaHqbtXrXJr 3jM/TMFaNXyGUFURPbcU6pVkqs1rr7tIiaIIuLn+mTLfIuut/JmGHwS9jhH0SFt7hvRE Y/9Z6t/z7LdDkxVZ3Gew2vjohFepwFqCnMSYDZbkKraBM/M84zTNccnUC1sKAwcXsPcb Hii6jgukM5reNaYLsVv211wDMztKiWNq0r2P9Ao0Fv0PEGuL1SHzJlmnbHVuER/SFSW9 QiBA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=wq+LWPWREMPWTha0KuLU0ctpl8oyI66DKfy3rV43WUM=; b=s5lZbl4y4zvITLtzOPFojFOihvV1HoO6FFeZKOto2fsCOUTQT5pH34y2tnbg9A0GPN VIYJsDb8PAMLjCAhNHArTfkcO0BNokkrvq5ypEpTeRFq8SqVfkyAsA8Rsgyc4CDQsALA pPfu9Pm8y2E7sG9r6ITRzhdW8qrYqDpBunEbf3XPMaR9RXyiMXPAZkqfLfgK8U+op8nd LoUVV2aZisvkfnWExay+0fz6T2dxStwTDJfSvYvjLO3tjQzes35hMQg9pRI8IDIL0/PR pTz8iBQeWo/XdymFTVcFLHotl31blhMSg5NlyxU/2WGEHrnbXkF0IdIVD8BAZH78QmRj YRmA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of tim.c.chen@linux.intel.com designates 192.55.52.43 as permitted sender) smtp.mailfrom=tim.c.chen@linux.intel.com Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of tim.c.chen@linux.intel.com designates 192.55.52.43 as permitted sender) smtp.mailfrom=tim.c.chen@linux.intel.com X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.46,409,1511856000"; d="scan'208";a="22116104" From: Tim Chen To: linux-kernel@vger.kernel.org Cc: Tim Chen , KarimAllah Ahmed , Andi Kleen , Andrea Arcangeli , Andy Lutomirski , Arjan van de Ven , Ashok Raj , Asit Mallick , Borislav Petkov , Dan Williams , Dave Hansen , David Woodhouse , Greg Kroah-Hartman , "H . Peter Anvin" , Ingo Molnar , Janakarajan Natarajan , Joerg Roedel , Jun Nakajima , Laura Abbott , Linus Torvalds , Masami Hiramatsu , Paolo Bonzini , Peter Zijlstra , rkrcmar@redhat.com, Thomas Gleixner , Tom Lendacky , x86@kernel.org Subject: [RFC PATCH 2/2] x86/ibpb: Prevent missed IBPB flush Date: Wed, 24 Jan 2018 16:36:42 -0800 Message-Id: <332d3ac8a7018b98d8182ec86b5fc41239c667c6.1516840211.git.tim.c.chen@linux.intel.com> X-Mailer: git-send-email 2.9.4 In-Reply-To: References: In-Reply-To: References: X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: =?utf-8?q?1590523945343890139?= X-GMAIL-MSGID: =?utf-8?q?1590523945343890139?= X-Mailing-List: linux-kernel@vger.kernel.org List-ID: It is possible that the last uesr mm that we recorded for a cpu was released, and a new mm with identical address was allocated when we check it again. We could skip IBPB flush here for the process with the new mm. It is a difficult to exploit case as we have to exit() a process on a cpu, free the mm, and fork() the victim to use the mm pointer on that cpu. The exploiter needs the old mm to get recycled to the newly forked process and no other processes run on the target cpu. Nevertheless, the patch below is one way to close this hole by adding a ref count to prevent the last user mm from being released. It does add ref counting overhead, and extra memory cost of keeping an mm (though not the VMAs and most of page tables) around longer than we will otherwise need to. Any better solutions are welcomed. Suggested-by: Dave Hansen Signed-off-by: Tim Chen --- arch/x86/mm/tlb.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/arch/x86/mm/tlb.c b/arch/x86/mm/tlb.c index 86ed07f..3bdaa10 100644 --- a/arch/x86/mm/tlb.c +++ b/arch/x86/mm/tlb.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -291,8 +292,17 @@ void switch_mm_irqs_off(struct mm_struct *prev, struct mm_struct *next, trace_tlb_flush_rcuidle(TLB_FLUSH_ON_TASK_SWITCH, 0); } - if (next != &init_mm && next != last) + if (next != &init_mm && next != last) { + if (last != NULL) + mmdrop(last); + /* + * Keep 'next' allocated until we switch to another mm. + * This keeps us from missing a flush of the branch predictors + * if 'next' gets freed and reallocated. + */ + mmgrab(next); this_cpu_write(cpu_tlbstate.last_usr_mm, next); + } this_cpu_write(cpu_tlbstate.loaded_mm, next); this_cpu_write(cpu_tlbstate.loaded_mm_asid, new_asid); } @@ -370,6 +380,7 @@ void initialize_tlbstate_and_flush(void) write_cr3(build_cr3(mm->pgd, 0)); /* Reinitialize tlbstate. */ + this_cpu_write(cpu_tlbstate.last_usr_mm, NULL); this_cpu_write(cpu_tlbstate.loaded_mm_asid, 0); this_cpu_write(cpu_tlbstate.next_asid, 1); this_cpu_write(cpu_tlbstate.ctxs[0].ctx_id, mm->context.ctx_id); -- 2.9.4