All of lore.kernel.org
 help / color / mirror / Atom feed
From: Masami Hiramatsu <mhiramat@redhat.com>
To: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Peter Zijlstra <peterz@infradead.org>,
	Nick Piggin <npiggin@suse.de>, akpm <akpm@linux-foundation.org>,
	linux-kernel <linux-kernel@vger.kernel.org>,
	Ingo Molnar <mingo@elte.hu>,
	Ananth N Mavinakayanahalli <ananth@in.ibm.com>,
	Jim Keniston <jkenisto@us.ibm.com>
Subject: Re: irq-disabled vs vmap vs text_poke
Date: Mon, 16 Feb 2009 10:04:43 -0500	[thread overview]
Message-ID: <4999808B.5080505@redhat.com> (raw)
In-Reply-To: <4995E925.3080506@redhat.com>

Masami Hiramatsu wrote:
> Mathieu Desnoyers wrote:
>> * Masami Hiramatsu (mhiramat@redhat.com) wrote:
>>> Mathieu Desnoyers wrote:
>>>>>> text_poke should actually use local_irq_disable/enable rather than
>>>>>> local_irq_save/restore because it _must_ be called with interrupts on.
>>>>> Could you tell me why it must be called with irq on?
>>>>>
>>>> Because it uses vmap, but see below..
>>>>
>>>>>>> Anybody got an idea on how to fix this?
>>>>>> There is probably something wrong with the caller, kprobes, which calls
>>>>>> text_poke with interrupts off.
>>>>> Hmm, kprobe's smoke test caused this problem. Since (un)register_kprobe()
>>>>> may sleep for waiting a mutex, it should not be called with interrupts off.
>>>>> So, it's not text_poke()'s issue nor vmap().
>>>>>
>>>>> BTW, what about using map_vm_area() in text_poke() instead of vmap()?
>>>>> Since text_poke() just maps text pages to alias pages temporarily,
>>>>> I think we don't need to use delayed vunmap().
>>>>>
>>>> As with this patch from you ? Sorry, when it has been initially
>>>> submitted, the discussion turned in a different direction. Please see
>>>> comments inline.
>>> No, sorry for confusing, vm_unmap_ram() is basically same as vunmap().
>>> (The root cause of that bug which I had been reported was not in text_poke())
>>>
>>> Here I said is (maybe) improving text_poke() by using map_vm_area() which
>>> simply maps pages to pre-allocated vm_area. And when unmapping, we just
>>> cleanup pte by unmap_kernel_range().
>>> For pre-allocating vm_area, we can use get_vm_area().
>>>
>>> If we can use kmap for this purpose, it will be better solution.
>>> However, kmap can not be used for making alias pages.
>>>
>>> Thanks,
>>>
>> That sounds clean, and would improve the current way we (mis)use vmap
>> for this tiny mapping. I always felt like I was using a sledgehammer
>> when only a hammer was necessary. :)
>>
>> Do you have a patch that implements this ?
> 
> Sure, however, the patch was not well tested (nor designed :-)),
> because it has been made as a by-product when I tried to solve
> another issue.

Here is the patch which replace v(un)map with (un)map_vm_area.

Signed-off-by: Masami Hiramatsu <mhiramat@redhat.com>
---
  arch/x86/include/asm/alternative.h |    1 +
  arch/x86/kernel/alternative.c      |   25 ++++++++++++++++++++-----
  init/main.c                        |    3 +++
  3 files changed, 24 insertions(+), 5 deletions(-)

Index: linux-2.6/arch/x86/include/asm/alternative.h
===================================================================
--- linux-2.6.orig/arch/x86/include/asm/alternative.h
+++ linux-2.6/arch/x86/include/asm/alternative.h
@@ -177,6 +177,7 @@ extern void add_nops(void *insns, unsign
   * The _early version expects the memory to already be RW.
   */

+extern void text_poke_init(void);
  extern void *text_poke(void *addr, const void *opcode, size_t len);
  extern void *text_poke_early(void *addr, const void *opcode, size_t len);

Index: linux-2.6/arch/x86/kernel/alternative.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/alternative.c
+++ linux-2.6/arch/x86/kernel/alternative.c
@@ -485,6 +485,16 @@ void *text_poke_early(void *addr, const
  	return addr;
  }

+static struct vm_struct *text_poke_area[2];
+static DEFINE_SPINLOCK(text_poke_lock);
+
+void __init text_poke_init(void)
+{
+	text_poke_area[0] = get_vm_area(PAGE_SIZE, VM_ALLOC);
+	text_poke_area[1] = get_vm_area(2 * PAGE_SIZE, VM_ALLOC);
+	BUG_ON(!text_poke_area[0] || !text_poke_area[1]);
+}
+
  /**
   * text_poke - Update instructions on a live kernel
   * @addr: address to modify
@@ -501,8 +511,9 @@ void *__kprobes text_poke(void *addr, co
  	unsigned long flags;
  	char *vaddr;
  	int nr_pages = 2;
-	struct page *pages[2];
-	int i;
+	struct page *pages[2], **pgp = pages;
+	int i, ret;
+	struct vm_struct *vma;

  	if (!core_kernel_text((unsigned long)addr)) {
  		pages[0] = vmalloc_to_page(addr);
@@ -515,12 +526,16 @@ void *__kprobes text_poke(void *addr, co
  	BUG_ON(!pages[0]);
  	if (!pages[1])
  		nr_pages = 1;
-	vaddr = vmap(pages, nr_pages, VM_MAP, PAGE_KERNEL);
-	BUG_ON(!vaddr);
+	spin_lock(&text_poke_lock);
+	vma = text_poke_area[nr_pages-1];
+	ret = map_vm_area(vma, PAGE_KERNEL, &pgp);
+	BUG_ON(ret);
+	vaddr = vma->addr;
  	local_irq_save(flags);
  	memcpy(&vaddr[(unsigned long)addr & ~PAGE_MASK], opcode, len);
  	local_irq_restore(flags);
-	vunmap(vaddr);
+	unmap_kernel_range((unsigned long)vma->addr, (unsigned long)vma->size);
+	spin_unlock(&text_poke_lock);
  	sync_core();
  	/* Could also do a CLFLUSH here to speed up CPU recovery; but
  	   that causes hangs on some VIA CPUs. */
Index: linux-2.6/init/main.c
===================================================================
--- linux-2.6.orig/init/main.c
+++ linux-2.6/init/main.c
@@ -676,6 +676,9 @@ asmlinkage void __init start_kernel(void
  	taskstats_init_early();
  	delayacct_init();

+#ifdef CONFIG_X86
+	text_poke_init();
+#endif
  	check_bugs();

  	acpi_early_init(); /* before LAPIC and SMP init */

-- 
Masami Hiramatsu

Software Engineer
Hitachi Computer Products (America) Inc.
Software Solutions Division

e-mail: mhiramat@redhat.com


  reply	other threads:[~2009-02-16 15:07 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-02-13 12:50 irq-disabled vs vmap vs text_poke Peter Zijlstra
2009-02-13 12:55 ` Nick Piggin
2009-02-13 13:02   ` Peter Zijlstra
2009-02-13 13:04     ` Ingo Molnar
2009-02-13 14:25       ` Mathieu Desnoyers
2009-02-13 14:33         ` Peter Zijlstra
2009-02-13 14:43           ` Mathieu Desnoyers
2009-02-13 18:05             ` Ingo Molnar
2009-02-13 13:05     ` Peter Zijlstra
2009-02-13 13:09       ` Nick Piggin
2009-02-13 14:18 ` Mathieu Desnoyers
2009-02-13 14:28   ` Peter Zijlstra
2009-02-13 16:32   ` Masami Hiramatsu
2009-02-13 16:38     ` Peter Zijlstra
2009-02-13 16:55     ` Mathieu Desnoyers
2009-02-13 18:14       ` Masami Hiramatsu
2009-02-13 18:57         ` Mathieu Desnoyers
2009-02-13 21:41           ` Masami Hiramatsu
2009-02-16 15:04             ` Masami Hiramatsu [this message]
2009-02-16 15:31               ` Nick Piggin
2009-02-16 17:24                 ` Mathieu Desnoyers
2009-02-17  2:00                   ` Masami Hiramatsu
2009-02-17  3:03                     ` Nick Piggin
2009-02-17  8:31                       ` Peter Zijlstra
2009-02-17 17:13                         ` Masami Hiramatsu
2009-02-17 16:48                       ` Masami Hiramatsu
2009-02-17 17:02                         ` Steven Rostedt
2009-02-17 17:18                           ` Mathieu Desnoyers
2009-02-17 17:24                             ` Steven Rostedt
2009-02-17 17:28                               ` Mathieu Desnoyers
2009-02-17 17:48                                 ` Steven Rostedt
2009-02-13 14:27 ` [PATCH] x86: text_poke might sleep Mathieu Desnoyers

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4999808B.5080505@redhat.com \
    --to=mhiramat@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=ananth@in.ibm.com \
    --cc=jkenisto@us.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@polymtl.ca \
    --cc=mingo@elte.hu \
    --cc=npiggin@suse.de \
    --cc=peterz@infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.