Commit f725492d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 asm updates from Ingo Molnar:
 "This includes the following changes:

   - cpu_has() cleanups

   - sync_bitops.h modernization to the rmwcc.h facility, similarly to
     bitops.h

   - continued LTO annotations/fixes

   - misc cleanups and smaller cleanups"

* 'x86-asm-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/um/vdso: Drop unnecessary cc-ldoption
  x86/vdso: Rename variable to fix -Wshadow warning
  x86/cpu/amd: Exclude 32bit only assembler from 64bit build
  x86/asm: Mark all top level asm statements as .text
  x86/build/vdso: Add FORCE to the build rule of %.so
  x86/asm: Modernize sync_bitops.h
  x86/mm: Convert some slow-path static_cpu_has() callers to boot_cpu_has()
  x86: Convert some slow-path static_cpu_has() callers to boot_cpu_has()
  x86/asm: Clarify static_cpu_has()'s intended use
  x86/uaccess: Fix implicit cast of __user pointer
  x86/cpufeature: Remove __pure attribute to _static_cpu_has()
parents 80e77644 3855f11d
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -116,7 +116,7 @@ $(obj)/%-x32.o: $(obj)/%.o FORCE
targets += vdsox32.lds $(vobjx32s-y)

$(obj)/%.so: OBJCOPYFLAGS := -S
$(obj)/%.so: $(obj)/%.so.dbg
$(obj)/%.so: $(obj)/%.so.dbg FORCE
	$(call if_changed,objcopy)

$(obj)/vdsox32.so.dbg: $(obj)/vdsox32.lds $(vobjx32s) FORCE
+7 −6
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@

static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
			 void *stripped_addr, size_t stripped_len,
			 FILE *outfile, const char *name)
			 FILE *outfile, const char *image_name)
{
	int found_load = 0;
	unsigned long load_size = -1;  /* Work around bogus warning */
@@ -93,11 +93,12 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
		int k;
		ELF(Sym) *sym = raw_addr + GET_LE(&symtab_hdr->sh_offset) +
			GET_LE(&symtab_hdr->sh_entsize) * i;
		const char *name = raw_addr + GET_LE(&strtab_hdr->sh_offset) +
		const char *sym_name = raw_addr +
				       GET_LE(&strtab_hdr->sh_offset) +
				       GET_LE(&sym->st_name);

		for (k = 0; k < NSYMS; k++) {
			if (!strcmp(name, required_syms[k].name)) {
			if (!strcmp(sym_name, required_syms[k].name)) {
				if (syms[k]) {
					fail("duplicate symbol %s\n",
					     required_syms[k].name);
@@ -134,7 +135,7 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
	if (syms[sym_vvar_start] % 4096)
		fail("vvar_begin must be a multiple of 4096\n");

	if (!name) {
	if (!image_name) {
		fwrite(stripped_addr, stripped_len, 1, outfile);
		return;
	}
@@ -157,7 +158,7 @@ static void BITSFUNC(go)(void *raw_addr, size_t raw_len,
	}
	fprintf(outfile, "\n};\n\n");

	fprintf(outfile, "const struct vdso_image %s = {\n", name);
	fprintf(outfile, "const struct vdso_image %s = {\n", image_name);
	fprintf(outfile, "\t.data = raw_data,\n");
	fprintf(outfile, "\t.size = %lu,\n", mapping_size);
	if (alt_sec) {
+7 −4
Original line number Diff line number Diff line
@@ -156,11 +156,14 @@ extern void clear_cpu_cap(struct cpuinfo_x86 *c, unsigned int bit);
#else

/*
 * Static testing of CPU features.  Used the same as boot_cpu_has().
 * These will statically patch the target code for additional
 * performance.
 * Static testing of CPU features. Used the same as boot_cpu_has(). It
 * statically patches the target code for additional performance. Use
 * static_cpu_has() only in fast paths, where every cycle counts. Which
 * means that the boot_cpu_has() variant is already fast enough for the
 * majority of cases and you should stick to using it as it is generally
 * only two instructions: a RIP-relative MOV and a TEST.
 */
static __always_inline __pure bool _static_cpu_has(u16 bit)
static __always_inline bool _static_cpu_has(u16 bit)
{
	asm_volatile_goto("1: jmp 6f\n"
		 "2:\n"
+3 −4
Original line number Diff line number Diff line
@@ -253,7 +253,7 @@ static inline void copy_xregs_to_kernel_booting(struct xregs_state *xstate)

	WARN_ON(system_state != SYSTEM_BOOTING);

	if (static_cpu_has(X86_FEATURE_XSAVES))
	if (boot_cpu_has(X86_FEATURE_XSAVES))
		XSTATE_OP(XSAVES, xstate, lmask, hmask, err);
	else
		XSTATE_OP(XSAVE, xstate, lmask, hmask, err);
@@ -275,7 +275,7 @@ static inline void copy_kernel_to_xregs_booting(struct xregs_state *xstate)

	WARN_ON(system_state != SYSTEM_BOOTING);

	if (static_cpu_has(X86_FEATURE_XSAVES))
	if (boot_cpu_has(X86_FEATURE_XSAVES))
		XSTATE_OP(XRSTORS, xstate, lmask, hmask, err);
	else
		XSTATE_OP(XRSTOR, xstate, lmask, hmask, err);
@@ -497,8 +497,7 @@ static inline void fpregs_activate(struct fpu *fpu)
 *  - switch_fpu_finish() restores the new state as
 *    necessary.
 */
static inline void
switch_fpu_prepare(struct fpu *old_fpu, int cpu)
static inline void switch_fpu_prepare(struct fpu *old_fpu, int cpu)
{
	if (static_cpu_has(X86_FEATURE_FPU) && old_fpu->initialized) {
		if (!copy_fpregs_to_fpstate(old_fpu))
+9 −22
Original line number Diff line number Diff line
@@ -14,6 +14,8 @@
 * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
 */

#include <asm/rmwcc.h>

#define ADDR (*(volatile long *)addr)

/**
@@ -29,7 +31,7 @@
 */
static inline void sync_set_bit(long nr, volatile unsigned long *addr)
{
	asm volatile("lock; bts %1,%0"
	asm volatile("lock; " __ASM_SIZE(bts) " %1,%0"
		     : "+m" (ADDR)
		     : "Ir" (nr)
		     : "memory");
@@ -47,7 +49,7 @@ static inline void sync_set_bit(long nr, volatile unsigned long *addr)
 */
static inline void sync_clear_bit(long nr, volatile unsigned long *addr)
{
	asm volatile("lock; btr %1,%0"
	asm volatile("lock; " __ASM_SIZE(btr) " %1,%0"
		     : "+m" (ADDR)
		     : "Ir" (nr)
		     : "memory");
@@ -64,7 +66,7 @@ static inline void sync_clear_bit(long nr, volatile unsigned long *addr)
 */
static inline void sync_change_bit(long nr, volatile unsigned long *addr)
{
	asm volatile("lock; btc %1,%0"
	asm volatile("lock; " __ASM_SIZE(btc) " %1,%0"
		     : "+m" (ADDR)
		     : "Ir" (nr)
		     : "memory");
@@ -78,14 +80,9 @@ static inline void sync_change_bit(long nr, volatile unsigned long *addr)
 * This operation is atomic and cannot be reordered.
 * It also implies a memory barrier.
 */
static inline int sync_test_and_set_bit(long nr, volatile unsigned long *addr)
static inline bool sync_test_and_set_bit(long nr, volatile unsigned long *addr)
{
	unsigned char oldbit;

	asm volatile("lock; bts %2,%1\n\tsetc %0"
		     : "=qm" (oldbit), "+m" (ADDR)
		     : "Ir" (nr) : "memory");
	return oldbit;
	return GEN_BINARY_RMWcc("lock; " __ASM_SIZE(bts), *addr, c, "Ir", nr);
}

/**
@@ -98,12 +95,7 @@ static inline int sync_test_and_set_bit(long nr, volatile unsigned long *addr)
 */
static inline int sync_test_and_clear_bit(long nr, volatile unsigned long *addr)
{
	unsigned char oldbit;

	asm volatile("lock; btr %2,%1\n\tsetc %0"
		     : "=qm" (oldbit), "+m" (ADDR)
		     : "Ir" (nr) : "memory");
	return oldbit;
	return GEN_BINARY_RMWcc("lock; " __ASM_SIZE(btr), *addr, c, "Ir", nr);
}

/**
@@ -116,12 +108,7 @@ static inline int sync_test_and_clear_bit(long nr, volatile unsigned long *addr)
 */
static inline int sync_test_and_change_bit(long nr, volatile unsigned long *addr)
{
	unsigned char oldbit;

	asm volatile("lock; btc %2,%1\n\tsetc %0"
		     : "=qm" (oldbit), "+m" (ADDR)
		     : "Ir" (nr) : "memory");
	return oldbit;
	return GEN_BINARY_RMWcc("lock; " __ASM_SIZE(btc), *addr, c, "Ir", nr);
}

#define sync_test_bit(nr, addr) test_bit(nr, addr)
Loading