- Various asmlinkage fixes to mark all symbols used from
assembler visible.
- Some inline assembler fixes to avoid direct references
to non global symbols
- Move the global register variable for sp to inline
assembler. This fixes both LTO and apparently clang/LLVM too.
-Andi
From: Andi Kleen <[email protected]>
The paravirt patching code assumes that it can reference a
local assembler label between two different top level assembler
statements. This does not work with LTO
where the assembler code may end up in different assembler files.
Replace it with extern / global /asm linkage labels.
This also removes one redundant copy of the macro.
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Andi Kleen <[email protected]>
---
arch/x86/include/asm/paravirt_types.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index aab8f67..7549b8b 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -388,10 +388,11 @@ extern struct pv_lock_ops pv_lock_ops;
_paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
/* Simple instruction patching code. */
-#define DEF_NATIVE(ops, name, code) \
- extern const char start_##ops##_##name[] __visible, \
- end_##ops##_##name[] __visible; \
- asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
+#define NATIVE_LABEL(a,x,b) "\n\t.globl " a #x "_" #b "\n" a #x "_" #b ":\n\t"
+
+#define DEF_NATIVE(ops, name, code) \
+ __visible extern const char start_##ops##_##name[], end_##ops##_##name[]; \
+ asm(NATIVE_LABEL("start_", ops, name) code NATIVE_LABEL("end_", ops, name))
unsigned paravirt_patch_nop(void);
unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
--
1.8.3.1
From: Andi Kleen <[email protected]>
Tell the compiler that the inline assembler statement
references lguest_entry.
This fixes compile problems with LTO where the variable
and the assembler code may end up in different files.
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Andi Kleen <[email protected]>
---
drivers/lguest/x86/core.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
index 5169239..922a1ac 100644
--- a/drivers/lguest/x86/core.c
+++ b/drivers/lguest/x86/core.c
@@ -157,7 +157,7 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
* stack, then the address of this call. This stack layout happens to
* exactly match the stack layout created by an interrupt...
*/
- asm volatile("pushf; lcall *lguest_entry"
+ asm volatile("pushf; lcall *%4"
/*
* This is how we tell GCC that %eax ("a") and %ebx ("b")
* are changed by this routine. The "=" means output.
@@ -169,7 +169,9 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
* physical address of the Guest's top-level page
* directory.
*/
- : "0"(pages), "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir))
+ : "0"(pages),
+ "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)),
+ "m"(lguest_entry)
/*
* We tell gcc that all these registers could change,
* which means we don't have to save and restore them in
--
1.8.3.1
From: Andi Kleen <[email protected]>
These functions are called from inline assembler stubs, thus
need to be global and visible.
Cc: [email protected]
Cc: [email protected]
Cc: Raghavendra K T <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
---
arch/x86/kernel/kvm.c | 2 +-
arch/x86/xen/spinlock.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index a0e2a8a..5d10bb5 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -673,7 +673,7 @@ static cpumask_t waiting_cpus;
/* Track spinlock on which a cpu is waiting */
static DEFINE_PER_CPU(struct kvm_lock_waiting, klock_waiting);
-static void kvm_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
+__visible void kvm_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
{
struct kvm_lock_waiting *w;
int cpu;
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index be6b860..3ab9309 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -106,7 +106,7 @@ static DEFINE_PER_CPU(struct xen_lock_waiting, lock_waiting);
static cpumask_t waiting_cpus;
static bool xen_pvspin = true;
-static void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
+__visible void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
{
int irq = __this_cpu_read(lock_kicker_irq);
struct xen_lock_waiting *w = &__get_cpu_var(lock_waiting);
--
1.8.3.1
From: Andi Kleen <[email protected]>
The paravirt thunks use a hack of using a static reference to a static
function to reference that function from the top level statement.
This assumes that gcc always generates static function names in a specific
format, which is not necessarily true.
Simply make these functions global and asmlinkage or __visible. This way the
static __used variables are not needed and everything works.
Functions with arguments are __visible to keep the register calling
convention on 32bit.
Changed in paravirt and in all users (Xen and vsmp)
v2: Use __visible for functions with arguments
Cc: [email protected]
Cc: Ido Yariv <[email protected]>
Cc: [email protected]
Signed-off-by: Andi Kleen <[email protected]>
---
arch/x86/include/asm/paravirt.h | 2 +-
arch/x86/kernel/vsmp_64.c | 8 ++++----
arch/x86/xen/irq.c | 8 ++++----
arch/x86/xen/mmu.c | 16 ++++++++--------
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 401f350..cd6e161 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -781,9 +781,9 @@ static __always_inline void __ticket_unlock_kick(struct arch_spinlock *lock,
*/
#define PV_CALLEE_SAVE_REGS_THUNK(func) \
extern typeof(func) __raw_callee_save_##func; \
- static void *__##func##__ __used = func; \
\
asm(".pushsection .text;" \
+ ".globl __raw_callee_save_" #func " ; " \
"__raw_callee_save_" #func ": " \
PV_SAVE_ALL_CALLER_REGS \
"call " #func ";" \
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index 992f890..f6584a9 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -33,7 +33,7 @@
* and vice versa.
*/
-static unsigned long vsmp_save_fl(void)
+asmlinkage unsigned long vsmp_save_fl(void)
{
unsigned long flags = native_save_fl();
@@ -43,7 +43,7 @@ static unsigned long vsmp_save_fl(void)
}
PV_CALLEE_SAVE_REGS_THUNK(vsmp_save_fl);
-static void vsmp_restore_fl(unsigned long flags)
+__visible void vsmp_restore_fl(unsigned long flags)
{
if (flags & X86_EFLAGS_IF)
flags &= ~X86_EFLAGS_AC;
@@ -53,7 +53,7 @@ static void vsmp_restore_fl(unsigned long flags)
}
PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl);
-static void vsmp_irq_disable(void)
+asmlinkage void vsmp_irq_disable(void)
{
unsigned long flags = native_save_fl();
@@ -61,7 +61,7 @@ static void vsmp_irq_disable(void)
}
PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable);
-static void vsmp_irq_enable(void)
+asmlinkage void vsmp_irq_enable(void)
{
unsigned long flags = native_save_fl();
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 0da7f86..f56c23b 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -22,7 +22,7 @@ void xen_force_evtchn_callback(void)
(void)HYPERVISOR_xen_version(0, NULL);
}
-static unsigned long xen_save_fl(void)
+asmlinkage unsigned long xen_save_fl(void)
{
struct vcpu_info *vcpu;
unsigned long flags;
@@ -40,7 +40,7 @@ static unsigned long xen_save_fl(void)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl);
-static void xen_restore_fl(unsigned long flags)
+__visible void xen_restore_fl(unsigned long flags)
{
struct vcpu_info *vcpu;
@@ -62,7 +62,7 @@ static void xen_restore_fl(unsigned long flags)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl);
-static void xen_irq_disable(void)
+asmlinkage void xen_irq_disable(void)
{
/* There's a one instruction preempt window here. We need to
make sure we're don't switch CPUs between getting the vcpu
@@ -73,7 +73,7 @@ static void xen_irq_disable(void)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
-static void xen_irq_enable(void)
+asmlinkage void xen_irq_enable(void)
{
struct vcpu_info *vcpu;
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index fdc3ba2..f59bd87 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -431,7 +431,7 @@ static pteval_t iomap_pte(pteval_t val)
return val;
}
-static pteval_t xen_pte_val(pte_t pte)
+__visible pteval_t xen_pte_val(pte_t pte)
{
pteval_t pteval = pte.pte;
#if 0
@@ -448,7 +448,7 @@ static pteval_t xen_pte_val(pte_t pte)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val);
-static pgdval_t xen_pgd_val(pgd_t pgd)
+__visible pgdval_t xen_pgd_val(pgd_t pgd)
{
return pte_mfn_to_pfn(pgd.pgd);
}
@@ -479,7 +479,7 @@ void xen_set_pat(u64 pat)
WARN_ON(pat != 0x0007010600070106ull);
}
-static pte_t xen_make_pte(pteval_t pte)
+__visible pte_t xen_make_pte(pteval_t pte)
{
phys_addr_t addr = (pte & PTE_PFN_MASK);
#if 0
@@ -514,14 +514,14 @@ static pte_t xen_make_pte(pteval_t pte)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte);
-static pgd_t xen_make_pgd(pgdval_t pgd)
+__visible pgd_t xen_make_pgd(pgdval_t pgd)
{
pgd = pte_pfn_to_mfn(pgd);
return native_make_pgd(pgd);
}
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pgd);
-static pmdval_t xen_pmd_val(pmd_t pmd)
+__visible pmdval_t xen_pmd_val(pmd_t pmd)
{
return pte_mfn_to_pfn(pmd.pmd);
}
@@ -580,7 +580,7 @@ static void xen_pmd_clear(pmd_t *pmdp)
}
#endif /* CONFIG_X86_PAE */
-static pmd_t xen_make_pmd(pmdval_t pmd)
+__visible pmd_t xen_make_pmd(pmdval_t pmd)
{
pmd = pte_pfn_to_mfn(pmd);
return native_make_pmd(pmd);
@@ -588,13 +588,13 @@ static pmd_t xen_make_pmd(pmdval_t pmd)
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pmd);
#if PAGETABLE_LEVELS == 4
-static pudval_t xen_pud_val(pud_t pud)
+__visible pudval_t xen_pud_val(pud_t pud)
{
return pte_mfn_to_pfn(pud.pud);
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pud_val);
-static pud_t xen_make_pud(pudval_t pud)
+__visible pud_t xen_make_pud(pudval_t pud)
{
pud = pte_pfn_to_mfn(pud);
--
1.8.3.1
From: Andi Kleen <[email protected]>
LTO requires consistent types of symbols over all files.
So "nmi" cannot be declared as a char [] here, need to use the
correct function type.
Cc: [email protected]
Signed-off-by: Andi Kleen <[email protected]>
---
arch/x86/xen/setup.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 09f3059..a55ff2f 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -34,7 +34,7 @@
extern const char xen_hypervisor_callback[];
extern const char xen_failsafe_callback[];
#ifdef CONFIG_X86_64
-extern const char nmi[];
+extern asmlinkage void nmi(void);
#endif
extern void xen_sysenter_target(void);
extern void xen_syscall_target(void);
@@ -559,7 +559,7 @@ void xen_enable_syscall(void)
void __cpuinit xen_enable_nmi(void)
{
#ifdef CONFIG_X86_64
- if (register_callback(CALLBACKTYPE_nmi, nmi))
+ if (register_callback(CALLBACKTYPE_nmi, (char *)nmi))
BUG();
#endif
}
--
1.8.3.1
From: Andi Kleen <[email protected]>
- Make the C code used by the paravirt stubs visible
- Since they have to be global now, give them a more unique
name.
Cc: [email protected]
Cc: [email protected]
Signed-off-by: Andi Kleen <[email protected]>
---
arch/x86/lguest/boot.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index bdf8532..ad1fb5f 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -233,13 +233,13 @@ static void lguest_end_context_switch(struct task_struct *next)
* flags word contains all kind of stuff, but in practice Linux only cares
* about the interrupt flag. Our "save_flags()" just returns that.
*/
-static unsigned long save_fl(void)
+asmlinkage unsigned long lguest_save_fl(void)
{
return lguest_data.irq_enabled;
}
/* Interrupts go off... */
-static void irq_disable(void)
+asmlinkage void lguest_irq_disable(void)
{
lguest_data.irq_enabled = 0;
}
@@ -253,8 +253,8 @@ static void irq_disable(void)
* PV_CALLEE_SAVE_REGS_THUNK(), which pushes %eax onto the stack, calls the
* C function, then restores it.
*/
-PV_CALLEE_SAVE_REGS_THUNK(save_fl);
-PV_CALLEE_SAVE_REGS_THUNK(irq_disable);
+PV_CALLEE_SAVE_REGS_THUNK(lguest_save_fl);
+PV_CALLEE_SAVE_REGS_THUNK(lguest_irq_disable);
/*:*/
/* These are in i386_head.S */
@@ -1291,9 +1291,9 @@ __init void lguest_init(void)
*/
/* Interrupt-related operations */
- pv_irq_ops.save_fl = PV_CALLEE_SAVE(save_fl);
+ pv_irq_ops.save_fl = PV_CALLEE_SAVE(lguest_save_fl);
pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(lg_restore_fl);
- pv_irq_ops.irq_disable = PV_CALLEE_SAVE(irq_disable);
+ pv_irq_ops.irq_disable = PV_CALLEE_SAVE(lguest_irq_disable);
pv_irq_ops.irq_enable = __PV_IS_CALLEE_SAVE(lg_irq_enable);
pv_irq_ops.safe_halt = lguest_safe_halt;
--
1.8.3.1
From: Andi Kleen <[email protected]>
LTO in gcc 4.6/47. has trouble with global register variables. They were used
to read the stack pointer. Use a simple inline assembler statement with
a mov instead.
This also helps LLVM/clang, who do not support global register
variables.
v2: More general asm constraint. Fix description (Jan Beulich)
Cc: [email protected]
Signed-off-by: Andi Kleen <[email protected]>
---
arch/x86/include/asm/thread_info.h | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 2781119..ffda484 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -166,9 +166,11 @@ struct thread_info {
*/
#ifndef __ASSEMBLY__
-
-/* how to get the current stack pointer from C */
-register unsigned long current_stack_pointer asm("esp") __used;
+#define current_stack_pointer ({ \
+ unsigned long sp; \
+ asm("mov %%esp,%0" : "=g" (sp)); \
+ sp; \
+})
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
--
1.8.3.1
Andi Kleen <[email protected]> writes:
> From: Andi Kleen <[email protected]>
>
> - Make the C code used by the paravirt stubs visible
> - Since they have to be global now, give them a more unique
> name.
>
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Andi Kleen <[email protected]>
Acked-by: Rusty Russell <[email protected]>
Cheers,
Rusty.
> ---
> arch/x86/lguest/boot.c | 12 ++++++------
> 1 file changed, 6 insertions(+), 6 deletions(-)
>
> diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
> index bdf8532..ad1fb5f 100644
> --- a/arch/x86/lguest/boot.c
> +++ b/arch/x86/lguest/boot.c
> @@ -233,13 +233,13 @@ static void lguest_end_context_switch(struct task_struct *next)
> * flags word contains all kind of stuff, but in practice Linux only cares
> * about the interrupt flag. Our "save_flags()" just returns that.
> */
> -static unsigned long save_fl(void)
> +asmlinkage unsigned long lguest_save_fl(void)
> {
> return lguest_data.irq_enabled;
> }
>
> /* Interrupts go off... */
> -static void irq_disable(void)
> +asmlinkage void lguest_irq_disable(void)
> {
> lguest_data.irq_enabled = 0;
> }
> @@ -253,8 +253,8 @@ static void irq_disable(void)
> * PV_CALLEE_SAVE_REGS_THUNK(), which pushes %eax onto the stack, calls the
> * C function, then restores it.
> */
> -PV_CALLEE_SAVE_REGS_THUNK(save_fl);
> -PV_CALLEE_SAVE_REGS_THUNK(irq_disable);
> +PV_CALLEE_SAVE_REGS_THUNK(lguest_save_fl);
> +PV_CALLEE_SAVE_REGS_THUNK(lguest_irq_disable);
> /*:*/
>
> /* These are in i386_head.S */
> @@ -1291,9 +1291,9 @@ __init void lguest_init(void)
> */
>
> /* Interrupt-related operations */
> - pv_irq_ops.save_fl = PV_CALLEE_SAVE(save_fl);
> + pv_irq_ops.save_fl = PV_CALLEE_SAVE(lguest_save_fl);
> pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(lg_restore_fl);
> - pv_irq_ops.irq_disable = PV_CALLEE_SAVE(irq_disable);
> + pv_irq_ops.irq_disable = PV_CALLEE_SAVE(lguest_irq_disable);
> pv_irq_ops.irq_enable = __PV_IS_CALLEE_SAVE(lg_irq_enable);
> pv_irq_ops.safe_halt = lguest_safe_halt;
>
> --
> 1.8.3.1
Andi Kleen <[email protected]> writes:
> From: Andi Kleen <[email protected]>
>
> Tell the compiler that the inline assembler statement
> references lguest_entry.
>
> This fixes compile problems with LTO where the variable
> and the assembler code may end up in different files.
>
> Cc: [email protected]
> Cc: [email protected]
> Signed-off-by: Andi Kleen <[email protected]>
Great, thanks. Might as well keep this with the others:
Acked-by: Rusty Russell <[email protected]>
Tested-by: Rusty Russell <[email protected]>
Cheers,
Rusty.
> ---
> drivers/lguest/x86/core.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c
> index 5169239..922a1ac 100644
> --- a/drivers/lguest/x86/core.c
> +++ b/drivers/lguest/x86/core.c
> @@ -157,7 +157,7 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
> * stack, then the address of this call. This stack layout happens to
> * exactly match the stack layout created by an interrupt...
> */
> - asm volatile("pushf; lcall *lguest_entry"
> + asm volatile("pushf; lcall *%4"
> /*
> * This is how we tell GCC that %eax ("a") and %ebx ("b")
> * are changed by this routine. The "=" means output.
> @@ -169,7 +169,9 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
> * physical address of the Guest's top-level page
> * directory.
> */
> - : "0"(pages), "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir))
> + : "0"(pages),
> + "1"(__pa(cpu->lg->pgdirs[cpu->cpu_pgd].pgdir)),
> + "m"(lguest_entry)
> /*
> * We tell gcc that all these registers could change,
> * which means we don't have to save and restore them in
> --
> 1.8.3.1
On Tue, Oct 22, 2013 at 09:07:58AM -0700, Andi Kleen wrote:
> From: Andi Kleen <[email protected]>
>
> These functions are called from inline assembler stubs, thus
> need to be global and visible.
>
> Cc: [email protected]
> Cc: [email protected]
> Cc: Raghavendra K T <[email protected]>
> Signed-off-by: Andi Kleen <[email protected]>
Acked-by: Gleb Natapov <[email protected]>
> ---
> arch/x86/kernel/kvm.c | 2 +-
> arch/x86/xen/spinlock.c | 2 +-
> 2 files changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
> index a0e2a8a..5d10bb5 100644
> --- a/arch/x86/kernel/kvm.c
> +++ b/arch/x86/kernel/kvm.c
> @@ -673,7 +673,7 @@ static cpumask_t waiting_cpus;
> /* Track spinlock on which a cpu is waiting */
> static DEFINE_PER_CPU(struct kvm_lock_waiting, klock_waiting);
>
> -static void kvm_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
> +__visible void kvm_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
> {
> struct kvm_lock_waiting *w;
> int cpu;
> diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
> index be6b860..3ab9309 100644
> --- a/arch/x86/xen/spinlock.c
> +++ b/arch/x86/xen/spinlock.c
> @@ -106,7 +106,7 @@ static DEFINE_PER_CPU(struct xen_lock_waiting, lock_waiting);
> static cpumask_t waiting_cpus;
>
> static bool xen_pvspin = true;
> -static void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
> +__visible void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
> {
> int irq = __this_cpu_read(lock_kicker_irq);
> struct xen_lock_waiting *w = &__get_cpu_var(lock_waiting);
> --
> 1.8.3.1
--
Gleb.
Commit-ID: 9549b9b3479323a1ad6ae83eae8e98aa765994f0
Gitweb: http://git.kernel.org/tip/9549b9b3479323a1ad6ae83eae8e98aa765994f0
Author: Andi Kleen <[email protected]>
AuthorDate: Tue, 22 Oct 2013 09:07:54 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 29 Jan 2014 22:17:17 -0800
x86, asmlinkage, lguest: Fix C functions used by inline assembler
- Make the C code used by the paravirt stubs visible
- Since they have to be global now, give them a more unique
name.
Cc: Rusty Russell <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/lguest/boot.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c
index bdf8532..ad1fb5f 100644
--- a/arch/x86/lguest/boot.c
+++ b/arch/x86/lguest/boot.c
@@ -233,13 +233,13 @@ static void lguest_end_context_switch(struct task_struct *next)
* flags word contains all kind of stuff, but in practice Linux only cares
* about the interrupt flag. Our "save_flags()" just returns that.
*/
-static unsigned long save_fl(void)
+asmlinkage unsigned long lguest_save_fl(void)
{
return lguest_data.irq_enabled;
}
/* Interrupts go off... */
-static void irq_disable(void)
+asmlinkage void lguest_irq_disable(void)
{
lguest_data.irq_enabled = 0;
}
@@ -253,8 +253,8 @@ static void irq_disable(void)
* PV_CALLEE_SAVE_REGS_THUNK(), which pushes %eax onto the stack, calls the
* C function, then restores it.
*/
-PV_CALLEE_SAVE_REGS_THUNK(save_fl);
-PV_CALLEE_SAVE_REGS_THUNK(irq_disable);
+PV_CALLEE_SAVE_REGS_THUNK(lguest_save_fl);
+PV_CALLEE_SAVE_REGS_THUNK(lguest_irq_disable);
/*:*/
/* These are in i386_head.S */
@@ -1291,9 +1291,9 @@ __init void lguest_init(void)
*/
/* Interrupt-related operations */
- pv_irq_ops.save_fl = PV_CALLEE_SAVE(save_fl);
+ pv_irq_ops.save_fl = PV_CALLEE_SAVE(lguest_save_fl);
pv_irq_ops.restore_fl = __PV_IS_CALLEE_SAVE(lg_restore_fl);
- pv_irq_ops.irq_disable = PV_CALLEE_SAVE(irq_disable);
+ pv_irq_ops.irq_disable = PV_CALLEE_SAVE(lguest_irq_disable);
pv_irq_ops.irq_enable = __PV_IS_CALLEE_SAVE(lg_irq_enable);
pv_irq_ops.safe_halt = lguest_safe_halt;
Commit-ID: dff38e3e93bbc10653a232f68077e5d031624464
Gitweb: http://git.kernel.org/tip/dff38e3e93bbc10653a232f68077e5d031624464
Author: Andi Kleen <[email protected]>
AuthorDate: Tue, 22 Oct 2013 09:07:57 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 29 Jan 2014 22:17:17 -0800
x86: Use inline assembler instead of global register variable to get sp
LTO in gcc 4.6/47. has trouble with global register variables. They were used
to read the stack pointer. Use a simple inline assembler statement with
a mov instead.
This also helps LLVM/clang, which does not support global register
variables.
[ hpa: Ideally this should become a builtin in both gcc and clang. ]
v2: More general asm constraint. Fix description (Jan Beulich)
Signed-off-by: Andi Kleen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/thread_info.h | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index 3ba3de4..e1940c0 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -163,9 +163,11 @@ struct thread_info {
*/
#ifndef __ASSEMBLY__
-
-/* how to get the current stack pointer from C */
-register unsigned long current_stack_pointer asm("esp") __used;
+#define current_stack_pointer ({ \
+ unsigned long sp; \
+ asm("mov %%esp,%0" : "=g" (sp)); \
+ sp; \
+})
/* how to get the thread information struct from C */
static inline struct thread_info *current_thread_info(void)
Commit-ID: dd41f818e581bc8244d34d594e20331fcb835524
Gitweb: http://git.kernel.org/tip/dd41f818e581bc8244d34d594e20331fcb835524
Author: Andi Kleen <[email protected]>
AuthorDate: Tue, 22 Oct 2013 09:07:58 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 29 Jan 2014 22:17:18 -0800
x86, asmlinkage, xen, kvm: Make {xen,kvm}_lock_spinning global and visible
These functions are called from inline assembler stubs, thus
need to be global and visible.
Cc: Konrad Rzeszutek Wilk <[email protected]>
Cc: Gleb Natapov <[email protected]>
Cc: Raghavendra K T <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/kernel/kvm.c | 2 +-
arch/x86/xen/spinlock.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 6dd802c..cd1b362 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -673,7 +673,7 @@ static cpumask_t waiting_cpus;
/* Track spinlock on which a cpu is waiting */
static DEFINE_PER_CPU(struct kvm_lock_waiting, klock_waiting);
-static void kvm_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
+__visible void kvm_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
{
struct kvm_lock_waiting *w;
int cpu;
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 0e36cde..581521c 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -106,7 +106,7 @@ static DEFINE_PER_CPU(struct xen_lock_waiting, lock_waiting);
static cpumask_t waiting_cpus;
static bool xen_pvspin = true;
-static void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
+__visible void xen_lock_spinning(struct arch_spinlock *lock, __ticket_t want)
{
int irq = __this_cpu_read(lock_kicker_irq);
struct xen_lock_waiting *w = &__get_cpu_var(lock_waiting);
Commit-ID: 07ba06d9d293d3c0a512f1cb9189645c6e0424e2
Gitweb: http://git.kernel.org/tip/07ba06d9d293d3c0a512f1cb9189645c6e0424e2
Author: Andi Kleen <[email protected]>
AuthorDate: Tue, 22 Oct 2013 09:07:59 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 29 Jan 2014 22:17:18 -0800
x86, asmlinkage, xen: Fix type of NMI
LTO requires consistent types of symbols over all files.
So "nmi" cannot be declared as a char [] here, need to use the
correct function type.
Cc: Konrad Rzeszutek Wilk <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/xen/setup.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/x86/xen/setup.c b/arch/x86/xen/setup.c
index 68c054f..518ab4a 100644
--- a/arch/x86/xen/setup.c
+++ b/arch/x86/xen/setup.c
@@ -34,7 +34,7 @@
extern const char xen_hypervisor_callback[];
extern const char xen_failsafe_callback[];
#ifdef CONFIG_X86_64
-extern const char nmi[];
+extern asmlinkage void nmi(void);
#endif
extern void xen_sysenter_target(void);
extern void xen_syscall_target(void);
@@ -559,7 +559,7 @@ void xen_enable_syscall(void)
void xen_enable_nmi(void)
{
#ifdef CONFIG_X86_64
- if (register_callback(CALLBACKTYPE_nmi, nmi))
+ if (register_callback(CALLBACKTYPE_nmi, (char *)nmi))
BUG();
#endif
}
Commit-ID: 824a2870098fa5364d49d4cd5a1f41544d9f6c65
Gitweb: http://git.kernel.org/tip/824a2870098fa5364d49d4cd5a1f41544d9f6c65
Author: Andi Kleen <[email protected]>
AuthorDate: Tue, 22 Oct 2013 09:07:55 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 29 Jan 2014 22:17:17 -0800
x86, asmlinkage, paravirt: Don't rely on local assembler labels
The paravirt patching code assumes that it can reference a
local assembler label between two different top level assembler
statements. This does not work with LTO
where the assembler code may end up in different assembler files.
Replace it with extern / global /asm linkage labels.
This also removes one redundant copy of the macro.
Cc: Jeremy Fitzhardinge <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/paravirt_types.h | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/arch/x86/include/asm/paravirt_types.h b/arch/x86/include/asm/paravirt_types.h
index aab8f67..7549b8b 100644
--- a/arch/x86/include/asm/paravirt_types.h
+++ b/arch/x86/include/asm/paravirt_types.h
@@ -388,10 +388,11 @@ extern struct pv_lock_ops pv_lock_ops;
_paravirt_alt(insn_string, "%c[paravirt_typenum]", "%c[paravirt_clobber]")
/* Simple instruction patching code. */
-#define DEF_NATIVE(ops, name, code) \
- extern const char start_##ops##_##name[] __visible, \
- end_##ops##_##name[] __visible; \
- asm("start_" #ops "_" #name ": " code "; end_" #ops "_" #name ":")
+#define NATIVE_LABEL(a,x,b) "\n\t.globl " a #x "_" #b "\n" a #x "_" #b ":\n\t"
+
+#define DEF_NATIVE(ops, name, code) \
+ __visible extern const char start_##ops##_##name[], end_##ops##_##name[]; \
+ asm(NATIVE_LABEL("start_", ops, name) code NATIVE_LABEL("end_", ops, name))
unsigned paravirt_patch_nop(void);
unsigned paravirt_patch_ident_32(void *insnbuf, unsigned len);
Commit-ID: a2e7f0e3a4f0f23fe4cd8cc22da547872f0170bb
Gitweb: http://git.kernel.org/tip/a2e7f0e3a4f0f23fe4cd8cc22da547872f0170bb
Author: Andi Kleen <[email protected]>
AuthorDate: Tue, 22 Oct 2013 09:07:56 -0700
Committer: H. Peter Anvin <[email protected]>
CommitDate: Wed, 29 Jan 2014 22:17:17 -0800
x86, asmlinkage, paravirt: Make paravirt thunks global
The paravirt thunks use a hack of using a static reference to a static
function to reference that function from the top level statement.
This assumes that gcc always generates static function names in a specific
format, which is not necessarily true.
Simply make these functions global and asmlinkage or __visible. This way the
static __used variables are not needed and everything works.
Functions with arguments are __visible to keep the register calling
convention on 32bit.
Changed in paravirt and in all users (Xen and vsmp)
v2: Use __visible for functions with arguments
Cc: Jeremy Fitzhardinge <[email protected]>
Cc: Ido Yariv <[email protected]>
Signed-off-by: Andi Kleen <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: H. Peter Anvin <[email protected]>
---
arch/x86/include/asm/paravirt.h | 2 +-
arch/x86/kernel/vsmp_64.c | 8 ++++----
arch/x86/xen/irq.c | 8 ++++----
arch/x86/xen/mmu.c | 16 ++++++++--------
4 files changed, 17 insertions(+), 17 deletions(-)
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index 401f350..cd6e161 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -781,9 +781,9 @@ static __always_inline void __ticket_unlock_kick(struct arch_spinlock *lock,
*/
#define PV_CALLEE_SAVE_REGS_THUNK(func) \
extern typeof(func) __raw_callee_save_##func; \
- static void *__##func##__ __used = func; \
\
asm(".pushsection .text;" \
+ ".globl __raw_callee_save_" #func " ; " \
"__raw_callee_save_" #func ": " \
PV_SAVE_ALL_CALLER_REGS \
"call " #func ";" \
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c
index 992f890..f6584a9 100644
--- a/arch/x86/kernel/vsmp_64.c
+++ b/arch/x86/kernel/vsmp_64.c
@@ -33,7 +33,7 @@
* and vice versa.
*/
-static unsigned long vsmp_save_fl(void)
+asmlinkage unsigned long vsmp_save_fl(void)
{
unsigned long flags = native_save_fl();
@@ -43,7 +43,7 @@ static unsigned long vsmp_save_fl(void)
}
PV_CALLEE_SAVE_REGS_THUNK(vsmp_save_fl);
-static void vsmp_restore_fl(unsigned long flags)
+__visible void vsmp_restore_fl(unsigned long flags)
{
if (flags & X86_EFLAGS_IF)
flags &= ~X86_EFLAGS_AC;
@@ -53,7 +53,7 @@ static void vsmp_restore_fl(unsigned long flags)
}
PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl);
-static void vsmp_irq_disable(void)
+asmlinkage void vsmp_irq_disable(void)
{
unsigned long flags = native_save_fl();
@@ -61,7 +61,7 @@ static void vsmp_irq_disable(void)
}
PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable);
-static void vsmp_irq_enable(void)
+asmlinkage void vsmp_irq_enable(void)
{
unsigned long flags = native_save_fl();
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index 0da7f86..f56c23b 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -22,7 +22,7 @@ void xen_force_evtchn_callback(void)
(void)HYPERVISOR_xen_version(0, NULL);
}
-static unsigned long xen_save_fl(void)
+asmlinkage unsigned long xen_save_fl(void)
{
struct vcpu_info *vcpu;
unsigned long flags;
@@ -40,7 +40,7 @@ static unsigned long xen_save_fl(void)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_save_fl);
-static void xen_restore_fl(unsigned long flags)
+__visible void xen_restore_fl(unsigned long flags)
{
struct vcpu_info *vcpu;
@@ -62,7 +62,7 @@ static void xen_restore_fl(unsigned long flags)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl);
-static void xen_irq_disable(void)
+asmlinkage void xen_irq_disable(void)
{
/* There's a one instruction preempt window here. We need to
make sure we're don't switch CPUs between getting the vcpu
@@ -73,7 +73,7 @@ static void xen_irq_disable(void)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable);
-static void xen_irq_enable(void)
+asmlinkage void xen_irq_enable(void)
{
struct vcpu_info *vcpu;
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index ce563be..648512c 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -431,7 +431,7 @@ static pteval_t iomap_pte(pteval_t val)
return val;
}
-static pteval_t xen_pte_val(pte_t pte)
+__visible pteval_t xen_pte_val(pte_t pte)
{
pteval_t pteval = pte.pte;
#if 0
@@ -448,7 +448,7 @@ static pteval_t xen_pte_val(pte_t pte)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pte_val);
-static pgdval_t xen_pgd_val(pgd_t pgd)
+__visible pgdval_t xen_pgd_val(pgd_t pgd)
{
return pte_mfn_to_pfn(pgd.pgd);
}
@@ -479,7 +479,7 @@ void xen_set_pat(u64 pat)
WARN_ON(pat != 0x0007010600070106ull);
}
-static pte_t xen_make_pte(pteval_t pte)
+__visible pte_t xen_make_pte(pteval_t pte)
{
phys_addr_t addr = (pte & PTE_PFN_MASK);
#if 0
@@ -514,14 +514,14 @@ static pte_t xen_make_pte(pteval_t pte)
}
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pte);
-static pgd_t xen_make_pgd(pgdval_t pgd)
+__visible pgd_t xen_make_pgd(pgdval_t pgd)
{
pgd = pte_pfn_to_mfn(pgd);
return native_make_pgd(pgd);
}
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pgd);
-static pmdval_t xen_pmd_val(pmd_t pmd)
+__visible pmdval_t xen_pmd_val(pmd_t pmd)
{
return pte_mfn_to_pfn(pmd.pmd);
}
@@ -580,7 +580,7 @@ static void xen_pmd_clear(pmd_t *pmdp)
}
#endif /* CONFIG_X86_PAE */
-static pmd_t xen_make_pmd(pmdval_t pmd)
+__visible pmd_t xen_make_pmd(pmdval_t pmd)
{
pmd = pte_pfn_to_mfn(pmd);
return native_make_pmd(pmd);
@@ -588,13 +588,13 @@ static pmd_t xen_make_pmd(pmdval_t pmd)
PV_CALLEE_SAVE_REGS_THUNK(xen_make_pmd);
#if PAGETABLE_LEVELS == 4
-static pudval_t xen_pud_val(pud_t pud)
+__visible pudval_t xen_pud_val(pud_t pud)
{
return pte_mfn_to_pfn(pud.pud);
}
PV_CALLEE_SAVE_REGS_THUNK(xen_pud_val);
-static pud_t xen_make_pud(pudval_t pud)
+__visible pud_t xen_make_pud(pudval_t pud)
{
pud = pte_pfn_to_mfn(pud);