Skip to content

Commit

Permalink
Merge branch 'x86/boot' of git://git.kernel.org/pub/scm/linux/kernel/…
Browse files Browse the repository at this point in the history
…git/tip/tip

Pull x86 boot changes from Peter Anvin:
 "This patchset is a set of cleanups aiming at librarize some of the
  common code from the boot environments.  We currently have three
  different "little environments" (boot, boot/compressed, and
  realmode/rm) in x86, and we are likely to soon get a fourth one
  (kexec/purgatory, which will have to be integrated in the kernel to
  support secure kexec).  This is primarily a cleanup in the
  anticipation of the latter.

  While Vivek implemented this, he ran into some bugs, in particular the
  memcmp implementation for when gcc punts from using the builtin would
  have a misnamed symbol, causing compilation errors if we were ever
  unlucky enough that gcc didn't want to inline the test"

* 'x86/boot' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86, boot: Move memset() definition in compressed/string.c
  x86, boot: Move memcmp() into string.h and string.c
  x86, boot: Move optimized memcpy() 32/64 bit versions to compressed/string.c
  x86, boot: Create a separate string.h file to provide standard string functions
  x86, boot: Undef memcmp before providing a new definition
  • Loading branch information
Linus Torvalds committed Apr 2, 2014
2 parents bb1775c + 0499955 commit 9447dc4
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 62 deletions.
13 changes: 0 additions & 13 deletions arch/x86/boot/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,14 +177,6 @@ static inline void wrgs32(u32 v, addr_t addr)
}

/* Note: these only return true/false, not a signed return value! */
static inline int memcmp(const void *s1, const void *s2, size_t len)
{
u8 diff;
asm("repe; cmpsb; setnz %0"
: "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
return diff;
}

static inline int memcmp_fs(const void *s1, addr_t s2, size_t len)
{
u8 diff;
Expand Down Expand Up @@ -228,11 +220,6 @@ void copy_to_fs(addr_t dst, void *src, size_t len);
void *copy_from_fs(void *dst, addr_t src, size_t len);
void copy_to_gs(addr_t dst, void *src, size_t len);
void *copy_from_gs(void *dst, addr_t src, size_t len);
void *memcpy(void *dst, void *src, size_t len);
void *memset(void *dst, int c, size_t len);

#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
#define memset(d,c,l) __builtin_memset(d,c,l)

/* a20.c */
int enable_a20(void);
Expand Down
51 changes: 8 additions & 43 deletions arch/x86/boot/compressed/misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

#include "misc.h"
#include "../string.h"

/* WARNING!!
* This code is compiled with -fPIC and it is relocated dynamically
Expand Down Expand Up @@ -97,8 +98,14 @@
*/
#define STATIC static

#undef memset
#undef memcpy

/*
* Use a normal definition of memset() from string.c. There are already
* included header files which expect a definition of memset() and by
* the time we define memset macro, it is too late.
*/
#undef memset
#define memzero(s, n) memset((s), 0, (n))


Expand All @@ -109,9 +116,6 @@ static void error(char *m);
*/
struct boot_params *real_mode; /* Pointer to real-mode data */

void *memset(void *s, int c, size_t n);
void *memcpy(void *dest, const void *src, size_t n);

memptr free_mem_ptr;
memptr free_mem_end_ptr;

Expand Down Expand Up @@ -216,45 +220,6 @@ void __putstr(const char *s)
outb(0xff & (pos >> 1), vidport+1);
}

void *memset(void *s, int c, size_t n)
{
int i;
char *ss = s;

for (i = 0; i < n; i++)
ss[i] = c;
return s;
}
#ifdef CONFIG_X86_32
void *memcpy(void *dest, const void *src, size_t n)
{
int d0, d1, d2;
asm volatile(
"rep ; movsl\n\t"
"movl %4,%%ecx\n\t"
"rep ; movsb\n\t"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
: "memory");

return dest;
}
#else
void *memcpy(void *dest, const void *src, size_t n)
{
long d0, d1, d2;
asm volatile(
"rep ; movsq\n\t"
"movq %4,%%rcx\n\t"
"rep ; movsb\n\t"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src)
: "memory");

return dest;
}
#endif

static void error(char *x)
{
error_putstr("\n\n");
Expand Down
46 changes: 40 additions & 6 deletions arch/x86/boot/compressed/string.c
Original file line number Diff line number Diff line change
@@ -1,11 +1,45 @@
#include "misc.h"
#include "../string.c"

/* misc.h might pull in string_32.h which has a macro for memcpy. undef that */
#undef memcpy

int memcmp(const void *s1, const void *s2, size_t len)
#ifdef CONFIG_X86_32
void *memcpy(void *dest, const void *src, size_t n)
{
u8 diff;
asm("repe; cmpsb; setnz %0"
: "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
return diff;
int d0, d1, d2;
asm volatile(
"rep ; movsl\n\t"
"movl %4,%%ecx\n\t"
"rep ; movsb\n\t"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n >> 2), "g" (n & 3), "1" (dest), "2" (src)
: "memory");

return dest;
}
#else
void *memcpy(void *dest, const void *src, size_t n)
{
long d0, d1, d2;
asm volatile(
"rep ; movsq\n\t"
"movq %4,%%rcx\n\t"
"rep ; movsb\n\t"
: "=&c" (d0), "=&D" (d1), "=&S" (d2)
: "0" (n >> 3), "g" (n & 7), "1" (dest), "2" (src)
: "memory");

#include "../string.c"
return dest;
}
#endif

void *memset(void *s, int c, size_t n)
{
int i;
char *ss = s;

for (i = 0; i < n; i++)
ss[i] = c;
return s;
}
1 change: 1 addition & 0 deletions arch/x86/boot/cpucheck.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <asm/processor-flags.h>
#include <asm/required-features.h>
#include <asm/msr-index.h>
#include "string.h"

static u32 err_flags[NCAPINTS];

Expand Down
1 change: 1 addition & 0 deletions arch/x86/boot/edd.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "boot.h"
#include <linux/edd.h>
#include "string.h"

#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)

Expand Down
1 change: 1 addition & 0 deletions arch/x86/boot/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

#include "boot.h"
#include "string.h"

struct boot_params boot_params __attribute__((aligned(16)));

Expand Down
1 change: 1 addition & 0 deletions arch/x86/boot/regs.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/

#include "boot.h"
#include "string.h"

void initregs(struct biosregs *reg)
{
Expand Down
14 changes: 14 additions & 0 deletions arch/x86/boot/string.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,20 @@

#include "boot.h"

/*
* This file gets included in compressed/string.c which might pull in
* string_32.h and which in turn maps memcmp to __builtin_memcmp(). Undo
* that first.
*/
#undef memcmp
int memcmp(const void *s1, const void *s2, size_t len)
{
u8 diff;
asm("repe; cmpsb; setnz %0"
: "=qm" (diff), "+D" (s1), "+S" (s2), "+c" (len));
return diff;
}

int strcmp(const char *str1, const char *str2)
{
const unsigned char *s1 = (const unsigned char *)str1;
Expand Down
21 changes: 21 additions & 0 deletions arch/x86/boot/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef BOOT_STRING_H
#define BOOT_STRING_H

/* Undef any of these macros coming from string_32.h. */
#undef memcpy
#undef memset
#undef memcmp

void *memcpy(void *dst, const void *src, size_t len);
void *memset(void *dst, int c, size_t len);
int memcmp(const void *s1, const void *s2, size_t len);

/*
* Access builtin version by default. If one needs to use optimized version,
* do "undef memcpy" in .c file and link against right string.c
*/
#define memcpy(d,s,l) __builtin_memcpy(d,s,l)
#define memset(d,c,l) __builtin_memset(d,c,l)
#define memcmp __builtin_memcmp

#endif /* BOOT_STRING_H */
1 change: 1 addition & 0 deletions arch/x86/boot/video-vesa.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "boot.h"
#include "video.h"
#include "vesa.h"
#include "string.h"

/* VESA information */
static struct vesa_general_info vginfo;
Expand Down

0 comments on commit 9447dc4

Please sign in to comment.