From owner-svn-soc-all@FreeBSD.ORG Thu Aug 14 11:45:50 2014 Return-Path: Delivered-To: svn-soc-all@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 834A1E65 for ; Thu, 14 Aug 2014 11:45:50 +0000 (UTC) Received: from socsvn.freebsd.org (socsvn.freebsd.org [IPv6:2001:1900:2254:206a::50:2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 6446029ED for ; Thu, 14 Aug 2014 11:45:50 +0000 (UTC) Received: from socsvn.freebsd.org ([127.0.1.124]) by socsvn.freebsd.org (8.14.9/8.14.9) with ESMTP id s7EBjo2K013312 for ; Thu, 14 Aug 2014 11:45:50 GMT (envelope-from op@FreeBSD.org) Received: (from www@localhost) by socsvn.freebsd.org (8.14.9/8.14.9/Submit) id s7EBjmKG013300 for svn-soc-all@FreeBSD.org; Thu, 14 Aug 2014 11:45:48 GMT (envelope-from op@FreeBSD.org) Date: Thu, 14 Aug 2014 11:45:48 GMT Message-Id: <201408141145.s7EBjmKG013300@socsvn.freebsd.org> X-Authentication-Warning: socsvn.freebsd.org: www set sender to op@FreeBSD.org using -f From: op@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r272397 - in soc2014/op/freebsd-base/sys: kern sys x86/include x86/x86 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-soc-all@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the entire Summer of Code repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Aug 2014 11:45:50 -0000 Author: op Date: Thu Aug 14 11:45:48 2014 New Revision: 272397 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272397 Log: KSP: added variable sized patch support Signed-off-by: Oliver Pinter git: https://github.com/opntr/opBSD/tree/op/gsoc2014/smap+kpatch Modified: soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c soc2014/op/freebsd-base/sys/sys/selfpatch.h soc2014/op/freebsd-base/sys/x86/include/selfpatch-asmacros.h soc2014/op/freebsd-base/sys/x86/include/selfpatch-machdep.h soc2014/op/freebsd-base/sys/x86/x86/selfpatch_machdep.c Modified: soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c ============================================================================== --- soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/kern/kern_selfpatch.c Thu Aug 14 11:45:48 2014 (r272397) @@ -73,6 +73,7 @@ static void lf_close_kernel_text(struct lf_selfpatch *p); static void lf_open_module_text(struct lf_selfpatch *p); static void lf_close_module_text(struct lf_selfpatch *p); +static void lf_pad_with_nop(struct lf_selfpatch *p); bool lf_selfpatch_patch_needed(struct lf_selfpatch *p) @@ -194,13 +195,13 @@ * replace the instructions */ memcpy(p->patchable, p->patch, p->patchable_size); + lf_pad_with_nop(p); if (mod == KSP_MODULE) lf_close_module_text(p); else lf_close_kernel_text(p); - DBG("patched.\n"); return (0); @@ -302,6 +303,33 @@ DBG("caches flushed.\n"); } + +static void +lf_pad_with_nop(struct lf_selfpatch *p) +{ + int i, rem; + char *patchable; + + if (p->patch_size == p->patchable_size) + return; + + if (p->patch_size > p->patchable_size) + panic("%s: patch_size > patchable_size", __func__); + + rem = p->patchable_size - p->patch_size; + patchable = p->patchable + p->patch_size; + + for (i = rem / KSP_MAX_NOPLEN; i > 0; i -= KSP_MAX_NOPLEN) { + memcpy(patchable, + selfpatch_nop_table[KSP_MAX_NOPLEN], + KSP_MAX_NOPLEN); + patchable += KSP_MAX_NOPLEN; + } + + rem %= KSP_MAX_NOPLEN; + memcpy(patchable, selfpatch_nop_table[rem], rem); +} + #ifdef KSP_DEBUG __noinline void lf_selfpatch_selftest(void) Modified: soc2014/op/freebsd-base/sys/sys/selfpatch.h ============================================================================== --- soc2014/op/freebsd-base/sys/sys/selfpatch.h Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/sys/selfpatch.h Thu Aug 14 11:45:48 2014 (r272397) @@ -60,7 +60,7 @@ char *comment; } lf_selfpatch_t; -extern char *selfpatch_nop_table[]; +extern const char *selfpatch_nop_table[]; int lf_selfpatch(linker_file_t lf, int mod); int lf_selfpatch_apply(linker_file_t lf, struct lf_selfpatch *patch, int mod); Modified: soc2014/op/freebsd-base/sys/x86/include/selfpatch-asmacros.h ============================================================================== --- soc2014/op/freebsd-base/sys/x86/include/selfpatch-asmacros.h Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/x86/include/selfpatch-asmacros.h Thu Aug 14 11:45:48 2014 (r272397) @@ -86,6 +86,7 @@ #define KSP_INSTR_NOP8_C KSP_INSTR_INTEL_NOP8_C #define KSP_INSTR_NOP9_C KSP_INSTR_INTEL_NOP9_C +#define KSP_MAX_NOPLEN 9 #define KSP_INSTR_XSAVE_XSAVEOPT(_ARG) \ 0723: \ Modified: soc2014/op/freebsd-base/sys/x86/include/selfpatch-machdep.h ============================================================================== --- soc2014/op/freebsd-base/sys/x86/include/selfpatch-machdep.h Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/x86/include/selfpatch-machdep.h Thu Aug 14 11:45:48 2014 (r272397) @@ -31,8 +31,6 @@ struct lf_selfpatch; -extern char *md_selfpatch_nop_table[]; - bool lf_selfpatch_patch_needed(struct lf_selfpatch *p); #endif /* __X86_SELFPATH_MACHDEP_H__ */ Modified: soc2014/op/freebsd-base/sys/x86/x86/selfpatch_machdep.c ============================================================================== --- soc2014/op/freebsd-base/sys/x86/x86/selfpatch_machdep.c Thu Aug 14 11:42:24 2014 (r272396) +++ soc2014/op/freebsd-base/sys/x86/x86/selfpatch_machdep.c Thu Aug 14 11:45:48 2014 (r272397) @@ -53,3 +53,51 @@ KSP_SELECTOR_END }; +/* + * assembly NOP store + */ +extern const char nop1; +extern const char nop2; +extern const char nop3; +extern const char nop4; +extern const char nop5; +extern const char nop6; +extern const char nop7; +extern const char nop8; +extern const char nop9; + +const char *selfpatch_nop_table[] = { + [0] = (const char *)NULL, + [1] = (const char *)&nop1, + [2] = (const char *)&nop2, + [3] = (const char *)&nop3, + [4] = (const char *)&nop4, + [5] = (const char *)&nop5, + [6] = (const char *)&nop6, + [7] = (const char *)&nop7, + [8] = (const char *)&nop8, + [9] = (const char *)&nop9 +}; + +__asm( +"nop1: \n" +" " KSP_INSTR_NOP1_C " \n" +"nop2: \n" +" " KSP_INSTR_NOP2_C " \n" +"nop3: \n" +" " KSP_INSTR_NOP3_C " \n" +"nop4: \n" +" " KSP_INSTR_NOP4_C " \n" +"nop5: \n" +" " KSP_INSTR_NOP5_C " \n" +"nop6: \n" +" " KSP_INSTR_NOP6_C " \n" +"nop7: \n" +" " KSP_INSTR_NOP7_C " \n" +"nop8: \n" +" " KSP_INSTR_NOP8_C " \n" +"nop9: \n" +" " KSP_INSTR_NOP9_C " \n" +" .p2align 4,0x90 \n" +); +