aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorChris Wright <chrisw@sous-sol.org>2007-08-18 17:31:41 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-18 18:15:54 -0400
commitd34fda4a84c18402640a1a2342d6e6d9829e6db7 (patch)
treec6da4cdd6c63be258a32635e87b239c570d5f664 /arch
parent18115f45374d19ada218fc013aa5308baf5d283e (diff)
x86: properly initialize temp insn buffer for paravirt patching
With commit ab144f5ec64c42218a555ec1dbde6b60cf2982d6 the patching code now collects the complete new instruction stream into a temp buffer before finally patching in the new insns. In some cases the paravirt patchers will choose to leave the patch site unpatched (length mismatch, clobbers mismatch, etc). This causes the new patching code to copy an uninitialized temp buffer, i.e. garbage, to the callsite. Simply make sure to always initialize the buffer with the original instruction stream. A better fix is to audit all the patchers and return proper length so that apply_paravirt() can skip copies when we leave the patch site untouched. Signed-off-by: Chris Wright <chrisw@sous-sol.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/alternative.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
index 1b66d5c70eaf..9f4ac8b02de4 100644
--- a/arch/i386/kernel/alternative.c
+++ b/arch/i386/kernel/alternative.c
@@ -366,6 +366,8 @@ void apply_paravirt(struct paravirt_patch_site *start,
366 unsigned int used; 366 unsigned int used;
367 367
368 BUG_ON(p->len > MAX_PATCH_LEN); 368 BUG_ON(p->len > MAX_PATCH_LEN);
369 /* prep the buffer with the original instructions */
370 memcpy(insnbuf, p->instr, p->len);
369 used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf, 371 used = paravirt_ops.patch(p->instrtype, p->clobbers, insnbuf,
370 (unsigned long)p->instr, p->len); 372 (unsigned long)p->instr, p->len);
371 373