mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-02-17 07:07:26 +07:00
[PATCH] i386: generic cmpxchg
- Make cmpxchg generally available on the i386 platform. - Provide emulation of cmpxchg suitable for uniprocessor if built and run on 386. From: Christoph Lameter <clameter@sgi.com> - Cut down patch and small style changes. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Christoph Lameter <clameter@sgi.com> Cc: "Paul E. McKenney" <paulmck@us.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
parent
dbdf65b1b7
commit
53e86b91b7
@ -6,6 +6,7 @@
|
|||||||
#include <linux/bitops.h>
|
#include <linux/bitops.h>
|
||||||
#include <linux/smp.h>
|
#include <linux/smp.h>
|
||||||
#include <linux/thread_info.h>
|
#include <linux/thread_info.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/msr.h>
|
#include <asm/msr.h>
|
||||||
@ -264,5 +265,52 @@ __init int intel_cpu_init(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_X86_CMPXCHG
|
||||||
|
unsigned long cmpxchg_386_u8(volatile void *ptr, u8 old, u8 new)
|
||||||
|
{
|
||||||
|
u8 prev;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
/* Poor man's cmpxchg for 386. Unsuitable for SMP */
|
||||||
|
local_irq_save(flags);
|
||||||
|
prev = *(u8 *)ptr;
|
||||||
|
if (prev == old)
|
||||||
|
*(u8 *)ptr = new;
|
||||||
|
local_irq_restore(flags);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cmpxchg_386_u8);
|
||||||
|
|
||||||
|
unsigned long cmpxchg_386_u16(volatile void *ptr, u16 old, u16 new)
|
||||||
|
{
|
||||||
|
u16 prev;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
/* Poor man's cmpxchg for 386. Unsuitable for SMP */
|
||||||
|
local_irq_save(flags);
|
||||||
|
prev = *(u16 *)ptr;
|
||||||
|
if (prev == old)
|
||||||
|
*(u16 *)ptr = new;
|
||||||
|
local_irq_restore(flags);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cmpxchg_386_u16);
|
||||||
|
|
||||||
|
unsigned long cmpxchg_386_u32(volatile void *ptr, u32 old, u32 new)
|
||||||
|
{
|
||||||
|
u32 prev;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
/* Poor man's cmpxchg for 386. Unsuitable for SMP */
|
||||||
|
local_irq_save(flags);
|
||||||
|
prev = *(u32 *)ptr;
|
||||||
|
if (prev == old)
|
||||||
|
*(u32 *)ptr = new;
|
||||||
|
local_irq_restore(flags);
|
||||||
|
return prev;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cmpxchg_386_u32);
|
||||||
|
#endif
|
||||||
|
|
||||||
// arch_initcall(intel_cpu_init);
|
// arch_initcall(intel_cpu_init);
|
||||||
|
|
||||||
|
@ -263,6 +263,10 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz
|
|||||||
|
|
||||||
#ifdef CONFIG_X86_CMPXCHG
|
#ifdef CONFIG_X86_CMPXCHG
|
||||||
#define __HAVE_ARCH_CMPXCHG 1
|
#define __HAVE_ARCH_CMPXCHG 1
|
||||||
|
#define cmpxchg(ptr,o,n)\
|
||||||
|
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
|
||||||
|
(unsigned long)(n),sizeof(*(ptr))))
|
||||||
|
#endif
|
||||||
|
|
||||||
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
||||||
unsigned long new, int size)
|
unsigned long new, int size)
|
||||||
@ -291,10 +295,42 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
|
|||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define cmpxchg(ptr,o,n)\
|
#ifndef CONFIG_X86_CMPXCHG
|
||||||
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
|
/*
|
||||||
(unsigned long)(n),sizeof(*(ptr))))
|
* Building a kernel capable running on 80386. It may be necessary to
|
||||||
|
* simulate the cmpxchg on the 80386 CPU. For that purpose we define
|
||||||
|
* a function for each of the sizes we support.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern unsigned long cmpxchg_386_u8(volatile void *, u8, u8);
|
||||||
|
extern unsigned long cmpxchg_386_u16(volatile void *, u16, u16);
|
||||||
|
extern unsigned long cmpxchg_386_u32(volatile void *, u32, u32);
|
||||||
|
|
||||||
|
static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old,
|
||||||
|
unsigned long new, int size)
|
||||||
|
{
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
return cmpxchg_386_u8(ptr, old, new);
|
||||||
|
case 2:
|
||||||
|
return cmpxchg_386_u16(ptr, old, new);
|
||||||
|
case 4:
|
||||||
|
return cmpxchg_386_u32(ptr, old, new);
|
||||||
|
}
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define cmpxchg(ptr,o,n) \
|
||||||
|
({ \
|
||||||
|
__typeof__(*(ptr)) __ret; \
|
||||||
|
if (likely(boot_cpu_data.x86 > 3)) \
|
||||||
|
__ret = __cmpxchg((ptr), (unsigned long)(o), \
|
||||||
|
(unsigned long)(n), sizeof(*(ptr))); \
|
||||||
|
else \
|
||||||
|
__ret = cmpxchg_386((ptr), (unsigned long)(o), \
|
||||||
|
(unsigned long)(n), sizeof(*(ptr))); \
|
||||||
|
__ret; \
|
||||||
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_X86_CMPXCHG64
|
#ifdef CONFIG_X86_CMPXCHG64
|
||||||
|
Loading…
Reference in New Issue
Block a user