From 7a71cef780404e8c90d23b1131142e158d94354b Mon Sep 17 00:00:00 2001 From: "bibo,mao" Date: Sat, 21 Oct 2006 18:37:02 +0200 Subject: [PATCH] x86-64: x86_64 add NX mask for PTE entry If function change_page_attr_addr calls revert_page to revert to original pte value, mk_pte_phys does not mask NX bit. If NX bit is set on no NX hardware supported x86_64 machine, there is will be RSVD type page fault and system will crash. This patch adds NX mask bit for PTE entry. Signed-off-by: bibo,mao Signed-off-by: Andi Kleen --- include/asm-x86_64/pgtable.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 6899e770b173..0555c1c4d8fa 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -366,6 +366,7 @@ static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { pte_t pte; pte_val(pte) = physpage | pgprot_val(pgprot); + pte_val(pte) &= __supported_pte_mask; return pte; } -- cgit v1.2.3 From e70ea8c09db0e25ab58f84ba7f393e5c9125a8ee Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Sat, 21 Oct 2006 18:37:03 +0200 Subject: [PATCH] x86-64: Revert timer routing behaviour back to 2.6.16 state By default route the 8254 over the 8259 and only disable it on ATI boards where this causes double timer interrupts. This should unbreak some Nvidia boards where the timer doesn't seem to tick of it isn't enabled in the 8259. At least one VIA board also seemed to have a little trouble with the disabled 8259. For 2.6.20 we'll try both dynamically without black listing, but I think for .19 this is the safer approach because it has been already well tested in earlier kernels. This also makes the x86-64 behaviour the same as i386. Command line options can change all this of course. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/early-quirks.c | 9 +++++---- arch/x86_64/kernel/io_apic.c | 2 +- include/asm-x86_64/proto.h | 2 ++ 3 files changed, 8 insertions(+), 5 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index 208e38a372c1..2b1245d86258 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -61,10 +61,11 @@ static void nvidia_bugs(void) static void ati_bugs(void) { -#if 1 /* for testing */ - printk("ATI board detected\n"); -#endif - /* No bugs right now */ + if (timer_over_8254 == 1) { + timer_over_8254 = 0; + printk(KERN_INFO + "ATI board detected. Disabling timer routing over 8254.\n"); + } } struct chipset { diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 8a9a357875b7..b000017e4b5d 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -57,7 +57,7 @@ static int no_timer_check; static int disable_timer_pin_1 __initdata; -int timer_over_8254 __initdata = 0; +int timer_over_8254 __initdata = 1; /* Where if anywhere is the i8259 connect in external int mode */ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index c181fef786e4..e72cfcdf5344 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -122,6 +122,8 @@ extern int fix_aperture; extern int reboot_force; extern int notsc_setup(char *); +extern int timer_over_8254; + extern int gsi_irq_sharing(int gsi); extern void smp_local_timer_interrupt(void); -- cgit v1.2.3 From 70a0a5357db20c291d46c04011d646d5d84c868c Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Wed, 25 Oct 2006 01:00:23 +0200 Subject: [PATCH] x86-64: Only look at per_cpu data for online cpus. When I generalized __assign_irq_vector I failed to pay attention to what happens when you access a per cpu data structure for a cpu that is not online. It is an undefined case making any code that does it have undefined behavior as well. The code still needs to be able to allocate a vector across cpus that are not online to properly handle combinations like lowest priority interrupt delivery and cpu_hotplug. Not that we can do that today but the infrastructure shouldn't prevent it. So this patch updates the places where we touch per cpu data to only touch online cpus, it makes cpu vector allocation an atomic operation with respect to cpu hotplug, and it updates the cpu start code to properly initialize vector_irq so we don't have inconsistencies. Signed-off-by: Eric W. Biederman Signed-off-by: Andi Kleen --- arch/x86_64/kernel/io_apic.c | 42 +++++++++++++++++++++++++++++++++++++----- arch/x86_64/kernel/smpboot.c | 7 ++++++- include/asm-x86_64/hw_irq.h | 2 ++ 3 files changed, 45 insertions(+), 6 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index 0e89ae7e7b22..fe429e5d6b29 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -63,7 +63,7 @@ int timer_over_8254 __initdata = 1; static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); -static DEFINE_SPINLOCK(vector_lock); +DEFINE_SPINLOCK(vector_lock); /* * # of IRQ routing registers @@ -618,6 +618,9 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) BUG_ON((unsigned)irq >= NR_IRQ_VECTORS); + /* Only try and allocate irqs on cpus that are present */ + cpus_and(mask, mask, cpu_online_map); + if (irq_vector[irq] > 0) old_vector = irq_vector[irq]; if (old_vector > 0) { @@ -627,11 +630,12 @@ static int __assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) } for_each_cpu_mask(cpu, mask) { - cpumask_t domain; + cpumask_t domain, new_mask; int new_cpu; int vector, offset; domain = vector_allocation_domain(cpu); + cpus_and(new_mask, domain, cpu_online_map); vector = current_vector; offset = current_offset; @@ -646,18 +650,20 @@ next: continue; if (vector == IA32_SYSCALL_VECTOR) goto next; - for_each_cpu_mask(new_cpu, domain) + for_each_cpu_mask(new_cpu, new_mask) if (per_cpu(vector_irq, new_cpu)[vector] != -1) goto next; /* Found one! */ current_vector = vector; current_offset = offset; if (old_vector >= 0) { + cpumask_t old_mask; int old_cpu; - for_each_cpu_mask(old_cpu, irq_domain[irq]) + cpus_and(old_mask, irq_domain[irq], cpu_online_map); + for_each_cpu_mask(old_cpu, old_mask) per_cpu(vector_irq, old_cpu)[old_vector] = -1; } - for_each_cpu_mask(new_cpu, domain) + for_each_cpu_mask(new_cpu, new_mask) per_cpu(vector_irq, new_cpu)[vector] = irq; irq_vector[irq] = vector; irq_domain[irq] = domain; @@ -678,6 +684,32 @@ static int assign_irq_vector(int irq, cpumask_t mask, cpumask_t *result) return vector; } +void __setup_vector_irq(int cpu) +{ + /* Initialize vector_irq on a new cpu */ + /* This function must be called with vector_lock held */ + unsigned long flags; + int irq, vector; + + + /* Mark the inuse vectors */ + for (irq = 0; irq < NR_IRQ_VECTORS; ++irq) { + if (!cpu_isset(cpu, irq_domain[irq])) + continue; + vector = irq_vector[irq]; + per_cpu(vector_irq, cpu)[vector] = irq; + } + /* Mark the free vectors */ + for (vector = 0; vector < NR_VECTORS; ++vector) { + irq = per_cpu(vector_irq, cpu)[vector]; + if (irq < 0) + continue; + if (!cpu_isset(cpu, irq_domain[irq])) + per_cpu(vector_irq, cpu)[vector] = -1; + } +} + + extern void (*interrupt[NR_IRQS])(void); static struct irq_chip ioapic_chip; diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 7b7a6870288a..62c2e747af58 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -581,12 +581,16 @@ void __cpuinit start_secondary(void) * smp_call_function(). */ lock_ipi_call_lock(); + spin_lock(&vector_lock); + /* Setup the per cpu irq handling data structures */ + __setup_vector_irq(smp_processor_id()); /* * Allow the master to continue. */ cpu_set(smp_processor_id(), cpu_online_map); per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE; + spin_unlock(&vector_lock); unlock_ipi_call_lock(); cpu_idle(); @@ -799,7 +803,6 @@ static int __cpuinit do_boot_cpu(int cpu, int apicid) cpu, node); } - alternatives_smp_switch(1); c_idle.idle = get_idle_for_cpu(cpu); @@ -1246,8 +1249,10 @@ int __cpu_disable(void) local_irq_disable(); remove_siblinginfo(cpu); + spin_lock(&vector_lock); /* It's now safe to remove this processor from the online map */ cpu_clear(cpu, cpu_online_map); + spin_unlock(&vector_lock); remove_cpu_from_maps(); fixup_irqs(cpu_online_map); return 0; diff --git a/include/asm-x86_64/hw_irq.h b/include/asm-x86_64/hw_irq.h index 792dd52fcd70..179cce755aa7 100644 --- a/include/asm-x86_64/hw_irq.h +++ b/include/asm-x86_64/hw_irq.h @@ -76,6 +76,8 @@ #ifndef __ASSEMBLY__ typedef int vector_irq_t[NR_VECTORS]; DECLARE_PER_CPU(vector_irq_t, vector_irq); +extern void __setup_vector_irq(int cpu); +extern spinlock_t vector_lock; /* * Various low-level irq details needed by irq.c, process.c, -- cgit v1.2.3 From 6c0ffb9d2fd987c79c6cbb81c3f3011c63749b1a Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 8 Nov 2006 10:23:03 -0800 Subject: x86-64: clean up io-apic accesses This is just commit 130fe05dbc0114609cfef9815c0c5580b42decfa ported to x86-64, for all the same reasons. It cleans up the IO-APIC accesses in order to then fix the ordering issues. We move the accessor functions (that were only used by io_apic.c) out of a header file, and use proper memory-mapped accesses rather than making up our own "volatile" pointers. Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/io_apic.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ include/asm-x86_64/io_apic.h | 34 -------------------------------- 2 files changed, 46 insertions(+), 34 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index fe429e5d6b29..96e02d845716 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -88,6 +88,52 @@ static struct irq_pin_list { short apic, pin, next; } irq_2_pin[PIN_MAP_SIZE]; +struct io_apic { + unsigned int index; + unsigned int unused[3]; + unsigned int data; +}; + +static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx) +{ + return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx) + + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK); +} + +static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(reg, &io_apic->index); + return readl(&io_apic->data); +} + +static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(reg, &io_apic->index); + writel(value, &io_apic->data); +} + +/* + * Re-write a value: to be used for read-modify-write + * cycles where the read already set up the index register. + */ +static inline void io_apic_modify(unsigned int apic, unsigned int value) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + writel(value, &io_apic->data); +} + +/* + * Synchronize the IO-APIC and the CPU by doing + * a dummy read from the IO-APIC + */ +static inline void io_apic_sync(unsigned int apic) +{ + struct io_apic __iomem *io_apic = io_apic_base(apic); + readl(&io_apic->data); +} + #define __DO_ACTION(R, ACTION, FINAL) \ \ { \ diff --git a/include/asm-x86_64/io_apic.h b/include/asm-x86_64/io_apic.h index 171ec2dc8c04..561ecbfd4cb5 100644 --- a/include/asm-x86_64/io_apic.h +++ b/include/asm-x86_64/io_apic.h @@ -12,10 +12,6 @@ #define APIC_MISMATCH_DEBUG -#define IO_APIC_BASE(idx) \ - ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \ - + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK))) - /* * The structure of the IO-APIC: */ @@ -119,36 +115,6 @@ extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; /* non-0 if default (table-less) MP configuration */ extern int mpc_default_type; -static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) -{ - *IO_APIC_BASE(apic) = reg; - return *(IO_APIC_BASE(apic)+4); -} - -static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) -{ - *IO_APIC_BASE(apic) = reg; - *(IO_APIC_BASE(apic)+4) = value; -} - -/* - * Re-write a value: to be used for read-modify-write - * cycles where the read already set up the index register. - */ -static inline void io_apic_modify(unsigned int apic, unsigned int value) -{ - *(IO_APIC_BASE(apic)+4) = value; -} - -/* - * Synchronize the IO-APIC and the CPU by doing - * a dummy read from the IO-APIC - */ -static inline void io_apic_sync(unsigned int apic) -{ - (void) *(IO_APIC_BASE(apic)+4); -} - /* 1 if "noapic" boot option passed */ extern int skip_ioapic_setup; -- cgit v1.2.3 From fa18f477d0987c011cce047a7c3cd1284f547a14 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86: Add acpi_user_timer_override option for Asus boards Timer overrides are normally disabled on Nvidia board because they are commonly wrong, except on new ones with HPET support. Unfortunately there are quite some Asus boards around that don't have HPET, but need a timer override. We don't know yet how to handle this transparently, but at least add a command line option to force the timer override and let them boot. Cc: len.brown@intel.com Signed-off-by: Andi Kleen --- Documentation/kernel-parameters.txt | 4 ++++ arch/i386/kernel/acpi/boot.c | 8 ++++++++ arch/i386/kernel/acpi/earlyquirk.c | 8 +++++++- arch/x86_64/kernel/early-quirks.c | 8 ++++++++ include/asm-i386/acpi.h | 1 + include/asm-x86_64/acpi.h | 1 + 6 files changed, 29 insertions(+), 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index dd00fd556a60..67473849f20e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -164,6 +164,10 @@ and is between 256 and 4096 characters. It is defined in the file acpi_skip_timer_override [HW,ACPI] Recognize and ignore IRQ0/pin2 Interrupt Override. For broken nForce2 BIOS resulting in XT-PIC timer. + acpi_use_timer_override [HW,ACPI} + Use timer override. For some broken Nvidia NF5 boards + that require a timer override, but don't have + HPET acpi_dbg_layer= [HW,ACPI] Format: diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 22e4c466e5a3..d12fb97a5337 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c @@ -82,6 +82,7 @@ EXPORT_SYMBOL(acpi_strict); acpi_interrupt_flags acpi_sci_flags __initdata; int acpi_sci_override_gsi __initdata; int acpi_skip_timer_override __initdata; +int acpi_use_timer_override __initdata; #ifdef CONFIG_X86_LOCAL_APIC static u64 acpi_lapic_addr __initdata = APIC_DEFAULT_PHYS_BASE; @@ -1300,6 +1301,13 @@ static int __init parse_acpi_skip_timer_override(char *arg) return 0; } early_param("acpi_skip_timer_override", parse_acpi_skip_timer_override); + +static int __init parse_acpi_use_timer_override(char *arg) +{ + acpi_use_timer_override = 1; + return 0; +} +early_param("acpi_use_timer_override", parse_acpi_use_timer_override); #endif /* CONFIG_X86_IO_APIC */ static int __init setup_acpi_sci(char *s) diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index fe799b11ac0a..c9841692bb7c 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -27,11 +27,17 @@ static int __init check_bridge(int vendor, int device) #ifdef CONFIG_ACPI /* According to Nvidia all timer overrides are bogus unless HPET is enabled. */ - if (vendor == PCI_VENDOR_ID_NVIDIA) { + if (!acpi_use_timer_override && vendor == PCI_VENDOR_ID_NVIDIA) { nvidia_hpet_detected = 0; acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { acpi_skip_timer_override = 1; + printk(KERN_INFO "Nvidia board " + "detected. Ignoring ACPI " + "timer override.\n"); + printk(KERN_INFO "If you got timer trouble " + "try acpi_use_timer_override\n"); + } } #endif diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index 2b1245d86258..68273bff58cc 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -45,7 +45,13 @@ static void nvidia_bugs(void) /* * All timer overrides on Nvidia are * wrong unless HPET is enabled. + * Unfortunately that's not true on many Asus boards. + * We don't know yet how to detect this automatically, but + * at least allow a command line override. */ + if (acpi_use_timer_override) + return; + nvidia_hpet_detected = 0; acpi_table_parse(ACPI_HPET, nvidia_hpet_check); if (nvidia_hpet_detected == 0) { @@ -53,6 +59,8 @@ static void nvidia_bugs(void) printk(KERN_INFO "Nvidia board " "detected. Ignoring ACPI " "timer override.\n"); + printk(KERN_INFO "If you got timer trouble " + "try acpi_use_timer_override\n"); } #endif /* RED-PEN skip them on mptables too? */ diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h index 6016632d032f..c80b3a94511a 100644 --- a/include/asm-i386/acpi.h +++ b/include/asm-i386/acpi.h @@ -132,6 +132,7 @@ extern int acpi_gsi_to_irq(u32 gsi, unsigned int *irq); #ifdef CONFIG_X86_IO_APIC extern int acpi_skip_timer_override; +extern int acpi_use_timer_override; #endif static inline void acpi_noirq_set(void) { acpi_noirq = 1; } diff --git a/include/asm-x86_64/acpi.h b/include/asm-x86_64/acpi.h index ed59aa4c6ff9..9d1916e59c04 100644 --- a/include/asm-x86_64/acpi.h +++ b/include/asm-x86_64/acpi.h @@ -163,6 +163,7 @@ extern u8 x86_acpiid_to_apicid[]; #define ARCH_HAS_POWER_INIT 1 extern int acpi_skip_timer_override; +extern int acpi_use_timer_override; #endif /*__KERNEL__*/ -- cgit v1.2.3 From 8c131af1db510793f87dc43edbc8950a35370df3 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86-64: Fix vgetcpu when CONFIG_HOTPLUG_CPU is disabled The vgetcpu per CPU initialization previously relied on CPU hotplug events for all CPUs to initialize the per CPU state. That only worked only on kernels with CONFIG_HOTPLUG_CPU enabled. On the others some CPUs didn't get their state initialized properly and vgetcpu wouldn't work. Change the initialization sequence to instead run in a normal initcall (which runs after the normal CPU bootup) and initialize all running CPUs there. Later hotplug CPUs are still handled with an hotplug notifier. This actually simplifies the code somewhat. Signed-off-by: Andi Kleen --- arch/x86_64/kernel/smp.c | 3 +-- arch/x86_64/kernel/time.c | 11 ----------- arch/x86_64/kernel/vsyscall.c | 45 ++++++++++++++++++++++++------------------- include/asm-x86_64/vsyscall.h | 2 -- 4 files changed, 26 insertions(+), 35 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/smp.c b/arch/x86_64/kernel/smp.c index 4f67697f5036..9f74c883568c 100644 --- a/arch/x86_64/kernel/smp.c +++ b/arch/x86_64/kernel/smp.c @@ -376,9 +376,8 @@ int smp_call_function_single (int cpu, void (*func) (void *info), void *info, /* prevent preemption and reschedule on another processor */ int me = get_cpu(); if (cpu == me) { - WARN_ON(1); put_cpu(); - return -EBUSY; + return 0; } spin_lock_bh(&call_lock); __smp_call_function_single(cpu, func, info, nonatomic, wait); diff --git a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c index 88722f11ca13..e3ef544d2cfb 100644 --- a/arch/x86_64/kernel/time.c +++ b/arch/x86_64/kernel/time.c @@ -876,15 +876,6 @@ static struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL }; -static int __cpuinit -time_cpu_notifier(struct notifier_block *nb, unsigned long action, void *hcpu) -{ - unsigned cpu = (unsigned long) hcpu; - if (action == CPU_ONLINE) - vsyscall_set_cpu(cpu); - return NOTIFY_DONE; -} - void __init time_init(void) { if (nohpet) @@ -925,8 +916,6 @@ void __init time_init(void) vxtime.last_tsc = get_cycles_sync(); set_cyc2ns_scale(cpu_khz); setup_irq(0, &irq0); - hotcpu_notifier(time_cpu_notifier, 0); - time_cpu_notifier(NULL, CPU_ONLINE, (void *)(long)smp_processor_id()); #ifndef CONFIG_SMP time_init_gtod(); diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index a98b460af6a1..a730bacecb0b 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -27,6 +27,9 @@ #include #include #include +#include +#include +#include #include #include @@ -243,32 +246,17 @@ static ctl_table kernel_root_table2[] = { #endif -static void __cpuinit write_rdtscp_cb(void *info) -{ - write_rdtscp_aux((unsigned long)info); -} - -void __cpuinit vsyscall_set_cpu(int cpu) +/* Assume __initcall executes before all user space. Hopefully kmod + doesn't violate that. We'll find out if it does. */ +static void __cpuinit vsyscall_set_cpu(int cpu) { unsigned long *d; unsigned long node = 0; #ifdef CONFIG_NUMA node = cpu_to_node[cpu]; #endif - if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) { - void *info = (void *)((node << 12) | cpu); - /* Can happen on preemptive kernel */ - if (get_cpu() == cpu) - write_rdtscp_cb(info); -#ifdef CONFIG_SMP - else { - /* the notifier is unfortunately not executed on the - target CPU */ - smp_call_function_single(cpu,write_rdtscp_cb,info,0,1); - } -#endif - put_cpu(); - } + if (cpu_has(&cpu_data[cpu], X86_FEATURE_RDTSCP)) + write_rdtscp_aux((node << 12) | cpu); /* Store cpu number in limit so that it can be loaded quickly in user space in vgetcpu. @@ -280,6 +268,21 @@ void __cpuinit vsyscall_set_cpu(int cpu) *d |= (node >> 4) << 48; } +static void __cpuinit cpu_vsyscall_init(void *arg) +{ + /* preemption should be already off */ + vsyscall_set_cpu(raw_smp_processor_id()); +} + +static int __cpuinit +cpu_vsyscall_notifier(struct notifier_block *n, unsigned long action, void *arg) +{ + long cpu = (long)arg; + if (action == CPU_ONLINE) + smp_call_function_single(cpu, cpu_vsyscall_init, NULL, 0, 1); + return NOTIFY_DONE; +} + static void __init map_vsyscall(void) { extern char __vsyscall_0; @@ -299,6 +302,8 @@ static int __init vsyscall_init(void) #ifdef CONFIG_SYSCTL register_sysctl_table(kernel_root_table2, 0); #endif + on_each_cpu(cpu_vsyscall_init, NULL, 0, 1); + hotcpu_notifier(cpu_vsyscall_notifier, 0); return 0; } diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h index fd452fc2c037..01d1c17e2849 100644 --- a/include/asm-x86_64/vsyscall.h +++ b/include/asm-x86_64/vsyscall.h @@ -59,8 +59,6 @@ extern seqlock_t xtime_lock; extern int sysctl_vsyscall; -extern void vsyscall_set_cpu(int cpu); - #define ARCH_HAVE_XTIME_LOCK 1 #endif /* __KERNEL__ */ -- cgit v1.2.3 From 9446868b5383eb87f76b2d4389dea4bb968a6657 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Tue, 14 Nov 2006 16:57:46 +0100 Subject: [PATCH] x86-64: Fix race in exit_idle When another interrupt happens in exit_idle the exit idle notifier could be called an incorrect number of times. Add a test_and_clear_bit_pda and use it handle the bit atomically against interrupts to avoid this. Pointed out by Stephane Eranian Signed-off-by: Andi Kleen --- arch/x86_64/kernel/process.c | 3 +-- include/asm-x86_64/pda.h | 9 +++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 49f7fac6229e..f6226055d53d 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -88,9 +88,8 @@ void enter_idle(void) static void __exit_idle(void) { - if (read_pda(isidle) == 0) + if (test_and_clear_bit_pda(0, isidle) == 0) return; - write_pda(isidle, 0); atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL); } diff --git a/include/asm-x86_64/pda.h b/include/asm-x86_64/pda.h index 14996d962bac..5642634843c4 100644 --- a/include/asm-x86_64/pda.h +++ b/include/asm-x86_64/pda.h @@ -109,6 +109,15 @@ extern struct x8664_pda _proxy_pda; #define sub_pda(field,val) pda_to_op("sub",field,val) #define or_pda(field,val) pda_to_op("or",field,val) +/* This is not atomic against other CPUs -- CPU preemption needs to be off */ +#define test_and_clear_bit_pda(bit,field) ({ \ + int old__; \ + asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \ + : "=r" (old__), "+m" (_proxy_pda.field) \ + : "dIr" (bit), "i" (pda_offset(field)) : "memory"); \ + old__; \ +}) + #endif #define PDA_STACKOFFSET (5*8) -- cgit v1.2.3 From c6dbaef22a2f78700e242915a13218dd780c89ff Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:18:39 +1100 Subject: Driver core: add dev_archdata to struct device Add arch specific dev_archdata to struct device Adds an arch specific struct dev_arch to struct device. This enables architecture to add specific fields to every device in the system, like DMA operation pointers, NUMA node ID, firmware specific data, etc... Signed-off-by: Benjamin Herrenschmidt Acked-by: Andi Kleen Acked-By: David Howells Signed-off-by: Greg Kroah-Hartman --- include/asm-alpha/device.h | 7 +++++++ include/asm-arm/device.h | 7 +++++++ include/asm-arm26/device.h | 7 +++++++ include/asm-avr32/device.h | 7 +++++++ include/asm-cris/device.h | 7 +++++++ include/asm-frv/device.h | 7 +++++++ include/asm-generic/device.h | 12 ++++++++++++ include/asm-h8300/device.h | 7 +++++++ include/asm-i386/device.h | 7 +++++++ include/asm-ia64/device.h | 7 +++++++ include/asm-m32r/device.h | 7 +++++++ include/asm-m68k/device.h | 7 +++++++ include/asm-m68knommu/device.h | 7 +++++++ include/asm-mips/device.h | 7 +++++++ include/asm-parisc/device.h | 7 +++++++ include/asm-powerpc/device.h | 7 +++++++ include/asm-ppc/device.h | 7 +++++++ include/asm-s390/device.h | 7 +++++++ include/asm-sh/device.h | 7 +++++++ include/asm-sh64/device.h | 7 +++++++ include/asm-sparc/device.h | 7 +++++++ include/asm-sparc64/device.h | 7 +++++++ include/asm-um/device.h | 7 +++++++ include/asm-v850/device.h | 7 +++++++ include/asm-x86_64/device.h | 7 +++++++ include/asm-xtensa/device.h | 7 +++++++ include/linux/device.h | 3 +++ 27 files changed, 190 insertions(+) create mode 100644 include/asm-alpha/device.h create mode 100644 include/asm-arm/device.h create mode 100644 include/asm-arm26/device.h create mode 100644 include/asm-avr32/device.h create mode 100644 include/asm-cris/device.h create mode 100644 include/asm-frv/device.h create mode 100644 include/asm-generic/device.h create mode 100644 include/asm-h8300/device.h create mode 100644 include/asm-i386/device.h create mode 100644 include/asm-ia64/device.h create mode 100644 include/asm-m32r/device.h create mode 100644 include/asm-m68k/device.h create mode 100644 include/asm-m68knommu/device.h create mode 100644 include/asm-mips/device.h create mode 100644 include/asm-parisc/device.h create mode 100644 include/asm-powerpc/device.h create mode 100644 include/asm-ppc/device.h create mode 100644 include/asm-s390/device.h create mode 100644 include/asm-sh/device.h create mode 100644 include/asm-sh64/device.h create mode 100644 include/asm-sparc/device.h create mode 100644 include/asm-sparc64/device.h create mode 100644 include/asm-um/device.h create mode 100644 include/asm-v850/device.h create mode 100644 include/asm-x86_64/device.h create mode 100644 include/asm-xtensa/device.h (limited to 'include/asm-x86_64') diff --git a/include/asm-alpha/device.h b/include/asm-alpha/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-alpha/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-arm/device.h b/include/asm-arm/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-arm/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-arm26/device.h b/include/asm-arm26/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-arm26/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-avr32/device.h b/include/asm-avr32/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-avr32/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-cris/device.h b/include/asm-cris/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-cris/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-frv/device.h b/include/asm-frv/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-frv/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-generic/device.h b/include/asm-generic/device.h new file mode 100644 index 000000000000..c17c9600f220 --- /dev/null +++ b/include/asm-generic/device.h @@ -0,0 +1,12 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#ifndef _ASM_GENERIC_DEVICE_H +#define _ASM_GENERIC_DEVICE_H + +struct dev_archdata { +}; + +#endif /* _ASM_GENERIC_DEVICE_H */ diff --git a/include/asm-h8300/device.h b/include/asm-h8300/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-h8300/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-i386/device.h b/include/asm-i386/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-i386/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-ia64/device.h b/include/asm-ia64/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-ia64/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-m32r/device.h b/include/asm-m32r/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-m32r/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-m68k/device.h b/include/asm-m68k/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-m68k/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-m68knommu/device.h b/include/asm-m68knommu/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-m68knommu/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-mips/device.h b/include/asm-mips/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-mips/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-parisc/device.h b/include/asm-parisc/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-parisc/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-powerpc/device.h b/include/asm-powerpc/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-powerpc/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-ppc/device.h b/include/asm-ppc/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-ppc/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-s390/device.h b/include/asm-s390/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-s390/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-sh/device.h b/include/asm-sh/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-sh/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-sh64/device.h b/include/asm-sh64/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-sh64/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-sparc/device.h b/include/asm-sparc/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-sparc/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-sparc64/device.h b/include/asm-sparc64/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-sparc64/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-um/device.h b/include/asm-um/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-um/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-v850/device.h b/include/asm-v850/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-v850/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-x86_64/device.h b/include/asm-x86_64/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-x86_64/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/asm-xtensa/device.h b/include/asm-xtensa/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/include/asm-xtensa/device.h @@ -0,0 +1,7 @@ +/* + * Arch specific extensions to struct device + * + * This file is released under the GPLv2 + */ +#include + diff --git a/include/linux/device.h b/include/linux/device.h index 00b29e0c5ce0..5b54d756cd54 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -21,6 +21,7 @@ #include #include #include +#include #define DEVICE_NAME_SIZE 50 #define DEVICE_NAME_HALF __stringify(20) /* Less than half to accommodate slop */ @@ -383,6 +384,8 @@ struct device { struct dma_coherent_mem *dma_mem; /* internal for coherent mem override */ + /* arch specific additions */ + struct dev_archdata archdata; /* class_device migration path */ struct list_head node; -- cgit v1.2.3 From 465ae641e4a3e5028aa9c85d3843259aa28a22ce Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Sat, 11 Nov 2006 17:18:42 +1100 Subject: ACPI: Change ACPI to use dev_archdata instead of firmware_data Change ACPI to use dev_archdata instead of firmware_data This patch changes ACPI to use the new dev_archdata on i386, x86_64 and ia64 (is there any other arch using ACPI ?) to store it's acpi_handle. It also removes the firmware_data field from struct device as this was the only user. Only build-tested on x86 Signed-off-by: Benjamin Herrenschmidt Cc: Len Brown Signed-off-by: Greg Kroah-Hartman --- drivers/acpi/glue.c | 20 +++++++++++--------- include/acpi/acpi_bus.h | 2 +- include/asm-i386/device.h | 10 +++++++++- include/asm-ia64/device.h | 10 +++++++++- include/asm-x86_64/device.h | 10 +++++++++- include/linux/device.h | 2 -- 6 files changed, 39 insertions(+), 15 deletions(-) (limited to 'include/asm-x86_64') diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c index 10f160dc75b1..a2f46d587d55 100644 --- a/drivers/acpi/glue.c +++ b/drivers/acpi/glue.c @@ -267,9 +267,9 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) { acpi_status status; - if (dev->firmware_data) { + if (dev->archdata.acpi_handle) { printk(KERN_WARNING PREFIX - "Drivers changed 'firmware_data' for %s\n", dev->bus_id); + "Drivers changed 'acpi_handle' for %s\n", dev->bus_id); return -EINVAL; } get_device(dev); @@ -278,25 +278,26 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle) put_device(dev); return -EINVAL; } - dev->firmware_data = handle; + dev->archdata.acpi_handle = handle; return 0; } static int acpi_unbind_one(struct device *dev) { - if (!dev->firmware_data) + if (!dev->archdata.acpi_handle) return 0; - if (dev == acpi_get_physical_device(dev->firmware_data)) { + if (dev == acpi_get_physical_device(dev->archdata.acpi_handle)) { /* acpi_get_physical_device increase refcnt by one */ put_device(dev); - acpi_detach_data(dev->firmware_data, acpi_glue_data_handler); - dev->firmware_data = NULL; + acpi_detach_data(dev->archdata.acpi_handle, + acpi_glue_data_handler); + dev->archdata.acpi_handle = NULL; /* acpi_bind_one increase refcnt by one */ put_device(dev); } else { printk(KERN_ERR PREFIX - "Oops, 'firmware_data' corrupt for %s\n", dev->bus_id); + "Oops, 'acpi_handle' corrupt for %s\n", dev->bus_id); } return 0; } @@ -328,7 +329,8 @@ static int acpi_platform_notify(struct device *dev) if (!ret) { struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - acpi_get_name(dev->firmware_data, ACPI_FULL_PATHNAME, &buffer); + acpi_get_name(dev->archdata.acpi_handle, + ACPI_FULL_PATHNAME, &buffer); DBG("Device %s -> %s\n", dev->bus_id, (char *)buffer.pointer); kfree(buffer.pointer); } else diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index f338e40bd544..fdd10953b2b6 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -357,7 +357,7 @@ struct device *acpi_get_physical_device(acpi_handle); /* helper */ acpi_handle acpi_get_child(acpi_handle, acpi_integer); acpi_handle acpi_get_pci_rootbridge_handle(unsigned int, unsigned int); -#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->firmware_data)) +#define DEVICE_ACPI_HANDLE(dev) ((acpi_handle)((dev)->archdata.acpi_handle)) #endif /* CONFIG_ACPI */ diff --git a/include/asm-i386/device.h b/include/asm-i386/device.h index d8f9872b0e2d..849604c70e6b 100644 --- a/include/asm-i386/device.h +++ b/include/asm-i386/device.h @@ -3,5 +3,13 @@ * * This file is released under the GPLv2 */ -#include +#ifndef _ASM_I386_DEVICE_H +#define _ASM_I386_DEVICE_H +struct dev_archdata { +#ifdef CONFIG_ACPI + void *acpi_handle; +#endif +}; + +#endif /* _ASM_I386_DEVICE_H */ diff --git a/include/asm-ia64/device.h b/include/asm-ia64/device.h index d8f9872b0e2d..3db6daf7f251 100644 --- a/include/asm-ia64/device.h +++ b/include/asm-ia64/device.h @@ -3,5 +3,13 @@ * * This file is released under the GPLv2 */ -#include +#ifndef _ASM_IA64_DEVICE_H +#define _ASM_IA64_DEVICE_H +struct dev_archdata { +#ifdef CONFIG_ACPI + void *acpi_handle; +#endif +}; + +#endif /* _ASM_IA64_DEVICE_H */ diff --git a/include/asm-x86_64/device.h b/include/asm-x86_64/device.h index d8f9872b0e2d..3afa03f33a36 100644 --- a/include/asm-x86_64/device.h +++ b/include/asm-x86_64/device.h @@ -3,5 +3,13 @@ * * This file is released under the GPLv2 */ -#include +#ifndef _ASM_X86_64_DEVICE_H +#define _ASM_X86_64_DEVICE_H +struct dev_archdata { +#ifdef CONFIG_ACPI + void *acpi_handle; +#endif +}; + +#endif /* _ASM_X86_64_DEVICE_H */ diff --git a/include/linux/device.h b/include/linux/device.h index 5b54d756cd54..2d9dc358c027 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -369,8 +369,6 @@ struct device { void *driver_data; /* data private to the driver */ void *platform_data; /* Platform specific data, device core doesn't touch it */ - void *firmware_data; /* Firmware specific data (e.g. ACPI, - BIOS data),reserved for device core*/ struct dev_pm_info power; u64 *dma_mask; /* dma mask (if dma'able device) */ -- cgit v1.2.3 From a4f89fb7c072b8592b296c2ba216269c0c96db43 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 14 Nov 2006 21:20:08 -0800 Subject: [NET]: X86_64 checksum annotations and cleanups. * sanitize prototypes, annotate * usual ntohs->shift Signed-off-by: Al Viro Signed-off-by: David S. Miller --- arch/x86_64/lib/csum-partial.c | 7 +++--- arch/x86_64/lib/csum-wrappers.c | 37 ++++++++++++++++------------ include/asm-x86_64/checksum.h | 54 +++++++++++++++++++++-------------------- 3 files changed, 53 insertions(+), 45 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/lib/csum-partial.c b/arch/x86_64/lib/csum-partial.c index c493735218da..06ae630de82b 100644 --- a/arch/x86_64/lib/csum-partial.c +++ b/arch/x86_64/lib/csum-partial.c @@ -132,9 +132,10 @@ static __force_inline unsigned do_csum(const unsigned char *buff, unsigned len) * * it's best to have buff aligned on a 64-bit boundary */ -unsigned csum_partial(const unsigned char *buff, unsigned len, unsigned sum) +__wsum csum_partial(const void *buff, int len, __wsum sum) { - return add32_with_carry(do_csum(buff, len), sum); + return (__force __wsum)add32_with_carry(do_csum(buff, len), + (__force u32)sum); } EXPORT_SYMBOL(csum_partial); @@ -143,7 +144,7 @@ EXPORT_SYMBOL(csum_partial); * this routine is used for miscellaneous IP-like checksums, mainly * in icmp.c */ -unsigned short ip_compute_csum(unsigned char * buff, int len) +__sum16 ip_compute_csum(const void *buff, int len) { return csum_fold(csum_partial(buff,len,0)); } diff --git a/arch/x86_64/lib/csum-wrappers.c b/arch/x86_64/lib/csum-wrappers.c index b1320ec58428..fd42a4a095fc 100644 --- a/arch/x86_64/lib/csum-wrappers.c +++ b/arch/x86_64/lib/csum-wrappers.c @@ -18,9 +18,9 @@ * Returns an 32bit unfolded checksum of the buffer. * src and dst are best aligned to 64bits. */ -unsigned int -csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, - int len, unsigned int isum, int *errp) +__wsum +csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum isum, int *errp) { might_sleep(); *errp = 0; @@ -34,17 +34,19 @@ csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, if (unlikely((unsigned long)src & 6)) { while (((unsigned long)src & 6) && len >= 2) { __u16 val16; - *errp = __get_user(val16, (__u16 __user *)src); + *errp = __get_user(val16, (const __u16 __user *)src); if (*errp) return isum; *(__u16 *)dst = val16; - isum = add32_with_carry(isum, val16); + isum = (__force __wsum)add32_with_carry( + (__force unsigned)isum, val16); src += 2; dst += 2; len -= 2; } } - isum = csum_partial_copy_generic((__force void *)src,dst,len,isum,errp,NULL); + isum = csum_partial_copy_generic((__force const void *)src, + dst, len, isum, errp, NULL); if (likely(*errp == 0)) return isum; } @@ -66,9 +68,9 @@ EXPORT_SYMBOL(csum_partial_copy_from_user); * Returns an 32bit unfolded checksum of the buffer. * src and dst are best aligned to 64bits. */ -unsigned int -csum_partial_copy_to_user(unsigned const char *src, unsigned char __user *dst, - int len, unsigned int isum, int *errp) +__wsum +csum_partial_copy_to_user(const void *src, void __user *dst, + int len, __wsum isum, int *errp) { might_sleep(); if (unlikely(!access_ok(VERIFY_WRITE, dst, len))) { @@ -79,7 +81,8 @@ csum_partial_copy_to_user(unsigned const char *src, unsigned char __user *dst, if (unlikely((unsigned long)dst & 6)) { while (((unsigned long)dst & 6) && len >= 2) { __u16 val16 = *(__u16 *)src; - isum = add32_with_carry(isum, val16); + isum = (__force __wsum)add32_with_carry( + (__force unsigned)isum, val16); *errp = __put_user(val16, (__u16 __user *)dst); if (*errp) return isum; @@ -104,19 +107,21 @@ EXPORT_SYMBOL(csum_partial_copy_to_user); * * Returns an 32bit unfolded checksum of the buffer. */ -unsigned int -csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, unsigned int sum) +__wsum +csum_partial_copy_nocheck(const void *src, void *dst, int len, __wsum sum) { return csum_partial_copy_generic(src,dst,len,sum,NULL,NULL); } EXPORT_SYMBOL(csum_partial_copy_nocheck); -unsigned short csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, - __u32 len, unsigned short proto, unsigned int sum) +__sum16 csum_ipv6_magic(const struct in6_addr *saddr, + const struct in6_addr *daddr, + __u32 len, unsigned short proto, __wsum sum) { __u64 rest, sum64; - rest = (__u64)htonl(len) + (__u64)htons(proto) + (__u64)sum; + rest = (__force __u64)htonl(len) + (__force __u64)htons(proto) + + (__force __u64)sum; asm(" addq (%[saddr]),%[sum]\n" " adcq 8(%[saddr]),%[sum]\n" " adcq (%[daddr]),%[sum]\n" @@ -124,7 +129,7 @@ unsigned short csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, " adcq $0,%[sum]\n" : [sum] "=r" (sum64) : "[sum]" (rest),[saddr] "r" (saddr), [daddr] "r" (daddr)); - return csum_fold(add32_with_carry(sum64 & 0xffffffff, sum64>>32)); + return csum_fold((__force __wsum)add32_with_carry(sum64 & 0xffffffff, sum64>>32)); } EXPORT_SYMBOL(csum_ipv6_magic); diff --git a/include/asm-x86_64/checksum.h b/include/asm-x86_64/checksum.h index 989469e8e0b7..419fe88a0342 100644 --- a/include/asm-x86_64/checksum.h +++ b/include/asm-x86_64/checksum.h @@ -19,15 +19,16 @@ * the last step before putting a checksum into a packet. * Make sure not to mix with 64bit checksums. */ -static inline unsigned int csum_fold(unsigned int sum) +static inline __sum16 csum_fold(__wsum sum) { __asm__( " addl %1,%0\n" " adcl $0xffff,%0" : "=r" (sum) - : "r" (sum << 16), "0" (sum & 0xffff0000) + : "r" ((__force u32)sum << 16), + "0" ((__force u32)sum & 0xffff0000) ); - return (~sum) >> 16; + return (__force __sum16)(~(__force u32)sum >> 16); } /* @@ -43,7 +44,7 @@ static inline unsigned int csum_fold(unsigned int sum) * iph: ipv4 header * ihl: length of header / 4 */ -static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) +static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) { unsigned int sum; @@ -70,7 +71,7 @@ static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) : "=r" (sum), "=r" (iph), "=r" (ihl) : "1" (iph), "2" (ihl) : "memory"); - return(sum); + return (__force __sum16)sum; } /** @@ -84,16 +85,17 @@ static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) * Returns the pseudo header checksum the input data. Result is * 32bit unfolded. */ -static inline unsigned long -csum_tcpudp_nofold(unsigned saddr, unsigned daddr, unsigned short len, - unsigned short proto, unsigned int sum) +static inline __wsum +csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len, + unsigned short proto, __wsum sum) { asm(" addl %1, %0\n" " adcl %2, %0\n" " adcl %3, %0\n" " adcl $0, %0\n" : "=r" (sum) - : "g" (daddr), "g" (saddr), "g" ((ntohs(len)<<16)+proto*256), "0" (sum)); + : "g" (daddr), "g" (saddr), + "g" ((len + proto)<<8), "0" (sum)); return sum; } @@ -109,9 +111,9 @@ csum_tcpudp_nofold(unsigned saddr, unsigned daddr, unsigned short len, * Returns the 16bit pseudo header checksum the input data already * complemented and ready to be filled in. */ -static inline unsigned short int -csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, - unsigned short len, unsigned short proto, unsigned int sum) +static inline __sum16 +csum_tcpudp_magic(__be32 saddr, __be32 daddr, + unsigned short len, unsigned short proto, __wsum sum) { return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); } @@ -126,25 +128,25 @@ csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, * Before filling it in it needs to be csum_fold()'ed. * buff should be aligned to a 64bit boundary if possible. */ -extern unsigned int csum_partial(const unsigned char *buff, unsigned len, unsigned int sum); +extern __wsum csum_partial(const void *buff, int len, __wsum sum); #define _HAVE_ARCH_COPY_AND_CSUM_FROM_USER 1 #define HAVE_CSUM_COPY_USER 1 /* Do not call this directly. Use the wrappers below */ -extern unsigned long csum_partial_copy_generic(const unsigned char *src, const unsigned char *dst, - unsigned len, - unsigned sum, +extern __wsum csum_partial_copy_generic(const void *src, const void *dst, + int len, + __wsum sum, int *src_err_ptr, int *dst_err_ptr); -extern unsigned int csum_partial_copy_from_user(const unsigned char __user *src, unsigned char *dst, - int len, unsigned int isum, int *errp); -extern unsigned int csum_partial_copy_to_user(const unsigned char *src, unsigned char __user *dst, - int len, unsigned int isum, int *errp); -extern unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, int len, - unsigned int sum); +extern __wsum csum_partial_copy_from_user(const void __user *src, void *dst, + int len, __wsum isum, int *errp); +extern __wsum csum_partial_copy_to_user(const void *src, void __user *dst, + int len, __wsum isum, int *errp); +extern __wsum csum_partial_copy_nocheck(const void *src, void *dst, int len, + __wsum sum); /* Old names. To be removed. */ #define csum_and_copy_to_user csum_partial_copy_to_user @@ -158,7 +160,7 @@ extern unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned * Returns the 16bit folded/inverted checksum of the passed buffer. * Ready to fill in. */ -extern unsigned short ip_compute_csum(unsigned char * buff, int len); +extern __sum16 ip_compute_csum(const void *buff, int len); /** * csum_ipv6_magic - Compute checksum of an IPv6 pseudo header. @@ -176,9 +178,9 @@ extern unsigned short ip_compute_csum(unsigned char * buff, int len); struct in6_addr; #define _HAVE_ARCH_IPV6_CSUM 1 -extern unsigned short -csum_ipv6_magic(struct in6_addr *saddr, struct in6_addr *daddr, - __u32 len, unsigned short proto, unsigned int sum); +extern __sum16 +csum_ipv6_magic(const struct in6_addr *saddr, const struct in6_addr *daddr, + __u32 len, unsigned short proto, __wsum sum); static inline unsigned add32_with_carry(unsigned a, unsigned b) { -- cgit v1.2.3 From f6a570333e554b48ad589e7137c77c57809eee81 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 18 Oct 2006 01:47:25 -0400 Subject: [PATCH] severing module.h->sched.h Signed-off-by: Al Viro --- arch/i386/kernel/alternative.c | 1 + arch/i386/kernel/cpu/mcheck/therm_throt.c | 1 + drivers/base/cpu.c | 1 + drivers/hwmon/abituguru.c | 1 + drivers/leds/ledtrig-ide-disk.c | 1 + drivers/leds/ledtrig-timer.c | 1 + drivers/pci/access.c | 1 + drivers/scsi/scsi_transport_sas.c | 1 + drivers/w1/slaves/w1_therm.c | 1 + include/asm-x86_64/elf.h | 1 - include/linux/acct.h | 1 + include/linux/module.h | 13 +------------ include/scsi/libiscsi.h | 2 ++ kernel/latency.c | 1 + kernel/module.c | 15 ++++++++++++++- lib/random32.c | 1 + 16 files changed, 29 insertions(+), 14 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 583c238e17fb..535f9794fba1 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -1,4 +1,5 @@ #include +#include #include #include #include diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/i386/kernel/cpu/mcheck/therm_throt.c index 2d8703b7ce65..bad8b4420709 100644 --- a/arch/i386/kernel/cpu/mcheck/therm_throt.c +++ b/arch/i386/kernel/cpu/mcheck/therm_throt.c @@ -20,6 +20,7 @@ #include #include #include +#include #include /* How long to wait between reporting thermal events */ diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4bef76a2f3f2..1f745f12f94e 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c index e5cb0fdab9b1..b1dc63e4ac7b 100644 --- a/drivers/hwmon/abituguru.c +++ b/drivers/hwmon/abituguru.c @@ -21,6 +21,7 @@ etc voltage & frequency control is not supported! */ #include +#include #include #include #include diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c index fa651886ab4f..54b155c7026f 100644 --- a/drivers/leds/ledtrig-ide-disk.c +++ b/drivers/leds/ledtrig-ide-disk.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c index 29a8818a32ec..d756bdb01c59 100644 --- a/drivers/leds/ledtrig-timer.c +++ b/drivers/leds/ledtrig-timer.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include diff --git a/drivers/pci/access.c b/drivers/pci/access.c index 73a58c73d526..fc405f0165d9 100644 --- a/drivers/pci/access.c +++ b/drivers/pci/access.c @@ -1,5 +1,6 @@ #include #include +#include #include #include diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index b5b0c2cba96b..5c0b75bbfa10 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -25,6 +25,7 @@ #include #include +#include #include #include #include diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 5372cfcbd054..b022fffd8c51 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include diff --git a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h index a406fcb1e924..6d24ea7c4d9d 100644 --- a/include/asm-x86_64/elf.h +++ b/include/asm-x86_64/elf.h @@ -45,7 +45,6 @@ typedef struct user_i387_struct elf_fpregset_t; #ifdef __KERNEL__ #include -#include /* * This is used to ensure we don't load something for the wrong architecture. diff --git a/include/linux/acct.h b/include/linux/acct.h index 0496d1f09952..302eb727ecb8 100644 --- a/include/linux/acct.h +++ b/include/linux/acct.h @@ -119,6 +119,7 @@ struct acct_v3 #ifdef CONFIG_BSD_PROCESS_ACCT struct vfsmount; struct super_block; +struct pacct_struct; extern void acct_auto_close_mnt(struct vfsmount *m); extern void acct_auto_close(struct super_block *sb); extern void acct_init_pacct(struct pacct_struct *pacct); diff --git a/include/linux/module.h b/include/linux/module.h index 9258ffd8a7f0..d33df2408e05 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -6,7 +6,6 @@ * Rewritten by Richard Henderson Dec 1996 * Rewritten again by Rusty Russell, 2002 */ -#include #include #include #include @@ -411,17 +410,7 @@ static inline int try_module_get(struct module *module) return ret; } -static inline void module_put(struct module *module) -{ - if (module) { - unsigned int cpu = get_cpu(); - local_dec(&module->ref[cpu].count); - /* Maybe they're waiting for us to drop reference? */ - if (unlikely(!module_is_live(module))) - wake_up_process(module->waiter); - put_cpu(); - } -} +extern void module_put(struct module *module); #else /*!CONFIG_MODULE_UNLOAD*/ static inline int try_module_get(struct module *module) diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 61eebec00a7b..ea0816d4904d 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -25,6 +25,8 @@ #include #include +#include +#include #include #include diff --git a/kernel/latency.c b/kernel/latency.c index 258f2555abbc..e63fcacb61a7 100644 --- a/kernel/latency.c +++ b/kernel/latency.c @@ -36,6 +36,7 @@ #include #include #include +#include #include struct latency_info { diff --git a/kernel/module.c b/kernel/module.c index 45e01cb60101..e2d09d604ca0 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -34,10 +34,10 @@ #include #include #include +#include #include #include #include -#include #include #include #include @@ -790,6 +790,19 @@ static struct module_attribute refcnt = { .show = show_refcnt, }; +void module_put(struct module *module) +{ + if (module) { + unsigned int cpu = get_cpu(); + local_dec(&module->ref[cpu].count); + /* Maybe they're waiting for us to drop reference? */ + if (unlikely(!module_is_live(module))) + wake_up_process(module->waiter); + put_cpu(); + } +} +EXPORT_SYMBOL(module_put); + #else /* !CONFIG_MODULE_UNLOAD */ static void print_unload_info(struct seq_file *m, struct module *mod) { diff --git a/lib/random32.c b/lib/random32.c index 4a15ce51cea7..ec7f81d3fb18 100644 --- a/lib/random32.c +++ b/lib/random32.c @@ -36,6 +36,7 @@ #include #include #include +#include #include struct rnd_state { -- cgit v1.2.3 From b07e4ecd4d380ad697c54d729cb653d027077c99 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 19 Oct 2006 10:29:02 -0400 Subject: [PATCH] severing uaccess.h -> sched.h Signed-off-by: Al Viro --- include/asm-x86_64/uaccess.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h index 19f99178fe83..d5dbc87274f8 100644 --- a/include/asm-x86_64/uaccess.h +++ b/include/asm-x86_64/uaccess.h @@ -6,7 +6,6 @@ */ #include #include -#include #include #include -- cgit v1.2.3 From e62438630ca37539c8cc1553710bbfaa3cf960a7 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Mon, 4 Dec 2006 03:38:31 -0700 Subject: [PATCH] Centralise definitions of sector_t and blkcnt_t CONFIG_LBD and CONFIG_LSF are spread into asm/types.h for no particularly good reason. Centralising the definition in linux/types.h means that arch maintainers don't need to bother adding it, as well as fixing the problem with x86-64 users being asked to make a decision that has absolutely no effect. The H8/300 porters seem particularly confused since I'm not aware of any microcontrollers that need to support 2TB filesystems. Signed-off-by: Matthew Wilcox Signed-off-by: Linus Torvalds --- block/Kconfig | 6 ++---- include/asm-avr32/types.h | 5 ----- include/asm-h8300/types.h | 6 ------ include/asm-i386/types.h | 10 ---------- include/asm-mips/types.h | 10 ---------- include/asm-powerpc/types.h | 10 ---------- include/asm-s390/types.h | 10 ---------- include/asm-sh/types.h | 10 ---------- include/asm-x86_64/types.h | 3 --- include/linux/types.h | 14 +++++++++----- 10 files changed, 11 insertions(+), 73 deletions(-) (limited to 'include/asm-x86_64') diff --git a/block/Kconfig b/block/Kconfig index 83766a6bdee2..a50f48111647 100644 --- a/block/Kconfig +++ b/block/Kconfig @@ -19,11 +19,9 @@ config BLOCK if BLOCK -#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64 -#for instance. config LBD bool "Support for Large Block Devices" - depends on X86 || (MIPS && 32BIT) || PPC32 || (S390 && !64BIT) || SUPERH || UML + depends on !64BIT help Say Y here if you want to attach large (bigger than 2TB) discs to your machine, or if you want to have a raid or loopback device @@ -44,7 +42,7 @@ config BLK_DEV_IO_TRACE config LSF bool "Support for Large Single Files" - depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML + depends on !64BIT help Say Y here if you want to be able to handle very large files (bigger than 2TB), otherwise say N. diff --git a/include/asm-avr32/types.h b/include/asm-avr32/types.h index 3f47db9675af..2bff153a32ed 100644 --- a/include/asm-avr32/types.h +++ b/include/asm-avr32/types.h @@ -57,11 +57,6 @@ typedef unsigned long long u64; typedef u32 dma_addr_t; -#ifdef CONFIG_LBD -typedef u64 sector_t; -#define HAVE_SECTOR_T -#endif - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-h8300/types.h b/include/asm-h8300/types.h index da2402b86540..2a8b1b2be782 100644 --- a/include/asm-h8300/types.h +++ b/include/asm-h8300/types.h @@ -55,12 +55,6 @@ typedef unsigned long long u64; typedef u32 dma_addr_t; -#define HAVE_SECTOR_T -typedef u64 sector_t; - -#define HAVE_BLKCNT_T -typedef u64 blkcnt_t; - #endif /* __KERNEL__ */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-i386/types.h b/include/asm-i386/types.h index 4b4b295ccdb9..ad0a55bd782f 100644 --- a/include/asm-i386/types.h +++ b/include/asm-i386/types.h @@ -57,16 +57,6 @@ typedef u32 dma_addr_t; #endif typedef u64 dma64_addr_t; -#ifdef CONFIG_LBD -typedef u64 sector_t; -#define HAVE_SECTOR_T -#endif - -#ifdef CONFIG_LSF -typedef u64 blkcnt_t; -#define HAVE_BLKCNT_T -#endif - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h index 2b52e180c6f2..63a13c5bd832 100644 --- a/include/asm-mips/types.h +++ b/include/asm-mips/types.h @@ -93,16 +93,6 @@ typedef unsigned long long phys_t; typedef unsigned long phys_t; #endif -#ifdef CONFIG_LBD -typedef u64 sector_t; -#define HAVE_SECTOR_T -#endif - -#ifdef CONFIG_LSF -typedef u64 blkcnt_t; -#define HAVE_BLKCNT_T -#endif - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-powerpc/types.h b/include/asm-powerpc/types.h index d6fb56b80453..3b363757a2bb 100644 --- a/include/asm-powerpc/types.h +++ b/include/asm-powerpc/types.h @@ -97,16 +97,6 @@ typedef struct { unsigned long env; } func_descr_t; -#ifdef CONFIG_LBD -typedef u64 sector_t; -#define HAVE_SECTOR_T -#endif - -#ifdef CONFIG_LSF -typedef u64 blkcnt_t; -#define HAVE_BLKCNT_T -#endif - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h index ae2951cc83ac..fc5d7cf19324 100644 --- a/include/asm-s390/types.h +++ b/include/asm-s390/types.h @@ -87,16 +87,6 @@ typedef union { } subreg; } register_pair; -#ifdef CONFIG_LBD -typedef u64 sector_t; -#define HAVE_SECTOR_T -#endif - -#ifdef CONFIG_LSF -typedef u64 blkcnt_t; -#define HAVE_BLKCNT_T -#endif - #endif /* ! __s390x__ */ #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-sh/types.h b/include/asm-sh/types.h index 3c09dd4ca31c..fd00dbb82f84 100644 --- a/include/asm-sh/types.h +++ b/include/asm-sh/types.h @@ -52,16 +52,6 @@ typedef unsigned long long u64; typedef u32 dma_addr_t; -#ifdef CONFIG_LBD -typedef u64 sector_t; -#define HAVE_SECTOR_T -#endif - -#ifdef CONFIG_LSF -typedef u64 blkcnt_t; -#define HAVE_BLKCNT_T -#endif - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/asm-x86_64/types.h b/include/asm-x86_64/types.h index c86c2e6793e2..2d4491aae281 100644 --- a/include/asm-x86_64/types.h +++ b/include/asm-x86_64/types.h @@ -48,9 +48,6 @@ typedef unsigned long long u64; typedef u64 dma64_addr_t; typedef u64 dma_addr_t; -typedef u64 sector_t; -#define HAVE_SECTOR_T - #endif /* __ASSEMBLY__ */ #endif /* __KERNEL__ */ diff --git a/include/linux/types.h b/include/linux/types.h index 745c409ebbb5..0351bf2fac85 100644 --- a/include/linux/types.h +++ b/include/linux/types.h @@ -136,15 +136,19 @@ typedef __s64 int64_t; * * Linux always considers sectors to be 512 bytes long independently * of the devices real block size. - * - * If required, asm/types.h can override it and define - * HAVE_SECTOR_T */ -#ifndef HAVE_SECTOR_T +#ifdef CONFIG_LBD +typedef u64 sector_t; +#else typedef unsigned long sector_t; #endif -#ifndef HAVE_BLKCNT_T +/* + * The type of the inode's block count. + */ +#ifdef CONFIG_LSF +typedef u64 blkcnt_t; +#else typedef unsigned long blkcnt_t; #endif -- cgit v1.2.3 From 16afea0255cf6963eb924d4334cdb5acb9074581 Mon Sep 17 00:00:00 2001 From: Art Haas Date: Wed, 6 Dec 2006 14:45:53 -0600 Subject: [PATCH] Remove 'volatile' from spinlock_types This is a resubmission of patches originally created by Ingo Molnar. The link below is the initial (?) posting of the patch. http://marc.theaimsgroup.com/?l=linux-kernel&m=115217423929806&w=2 Remove 'volatile' from spinlock_types as it causes GCC to generate bad code (see link) and locking should be used on kernel data. Signed-off-by: Art Haas Signed-off-by: Linus Torvalds --- include/asm-i386/spinlock_types.h | 4 ++-- include/asm-x86_64/spinlock_types.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-i386/spinlock_types.h b/include/asm-i386/spinlock_types.h index 59efe849f351..4da9345c1500 100644 --- a/include/asm-i386/spinlock_types.h +++ b/include/asm-i386/spinlock_types.h @@ -6,13 +6,13 @@ #endif typedef struct { - volatile unsigned int slock; + unsigned int slock; } raw_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 1 } typedef struct { - volatile unsigned int lock; + unsigned int lock; } raw_rwlock_t; #define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } diff --git a/include/asm-x86_64/spinlock_types.h b/include/asm-x86_64/spinlock_types.h index 59efe849f351..4da9345c1500 100644 --- a/include/asm-x86_64/spinlock_types.h +++ b/include/asm-x86_64/spinlock_types.h @@ -6,13 +6,13 @@ #endif typedef struct { - volatile unsigned int slock; + unsigned int slock; } raw_spinlock_t; #define __RAW_SPIN_LOCK_UNLOCKED { 1 } typedef struct { - volatile unsigned int lock; + unsigned int lock; } raw_rwlock_t; #define __RAW_RW_LOCK_UNLOCKED { RW_LOCK_BIAS } -- cgit v1.2.3 From f9e9dcb38f5106fa8cdac04a9e967d5487f1cd20 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 6 Dec 2006 14:42:57 -0800 Subject: x86[-64]:Remove 'volatile' from atomic_t Any code that relies on the volatile would be a bug waiting to happen anyway. Don't encourage people to think that putting 'volatile' on data structures somehow fixes problems. We should always use proper locking (and other serialization) techniques. Signed-off-by: Linus Torvalds --- include/asm-i386/atomic.h | 2 +- include/asm-x86_64/atomic.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h index 51a166242522..a6c024e2506f 100644 --- a/include/asm-i386/atomic.h +++ b/include/asm-i386/atomic.h @@ -14,7 +14,7 @@ * on us. We need to use _exactly_ the address the user gave us, * not some alias that contains the same information. */ -typedef struct { volatile int counter; } atomic_t; +typedef struct { int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h index 007e88d6d43f..93849f7abc24 100644 --- a/include/asm-x86_64/atomic.h +++ b/include/asm-x86_64/atomic.h @@ -21,7 +21,7 @@ * on us. We need to use _exactly_ the address the user gave us, * not some alias that contains the same information. */ -typedef struct { volatile int counter; } atomic_t; +typedef struct { int counter; } atomic_t; #define ATOMIC_INIT(i) { (i) } -- cgit v1.2.3 From 87e1652c7863b9ae406ff37f33c7ec2bb494d7b1 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] x86-64: Don't keep interrupts disabled while spinning in spinlocks Follows i386. Based on patch from some folks at Google (MikeW, Edward G.?), but completely redone by AK. Signed-off-by: Andi Kleen --- include/asm-x86_64/spinlock.h | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/spinlock.h b/include/asm-x86_64/spinlock.h index 05ef097ba55b..88bf981e73cf 100644 --- a/include/asm-x86_64/spinlock.h +++ b/include/asm-x86_64/spinlock.h @@ -36,7 +36,34 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock) "2:\t" : "=m" (lock->slock) : : "memory"); } -#define __raw_spin_lock_flags(lock, flags) __raw_spin_lock(lock) +/* + * Same as __raw_spin_lock, but reenable interrupts during spinning. + */ +#ifndef CONFIG_PROVE_LOCKING +static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long flags) +{ + asm volatile( + "\n1:\t" + LOCK_PREFIX " ; decl %0\n\t" + "jns 5f\n" + "testl $0x200, %1\n\t" /* interrupts were disabled? */ + "jz 4f\n\t" + "sti\n" + "3:\t" + "rep;nop\n\t" + "cmpl $0, %0\n\t" + "jle 3b\n\t" + "cli\n\t" + "jmp 1b\n" + "4:\t" + "rep;nop\n\t" + "cmpl $0, %0\n\t" + "jg 1b\n\t" + "jmp 4b\n" + "5:\n\t" + : "+m" (lock->slock) : "r" ((unsigned)flags) : "memory"); +} +#endif static inline int __raw_spin_trylock(raw_spinlock_t *lock) { -- cgit v1.2.3 From bd1d599518bf11992cc6d5b0df08da4a2b7b0db5 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Dec 2006 02:14:00 +0100 Subject: [PATCH] x86-64: x86_64 rename X86_FEATURE_DTES to X86_FEATURE_DS Here is a patch (used by perfmon2) that renamed X86_FEATURE_DTES to X86_FEATURE_DS to match Intel's documentation for the Debug Store save area. The patch also adds cpu_has_ds. changelog: - rename X86_FEATURE_DTES to X86_FEATURE_DS to match documentation - adds cpu_has_ds to test for X86_FEATURE_DS Signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- include/asm-x86_64/cpufeature.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h index ee792faaca01..65eb39e8f3cc 100644 --- a/include/asm-x86_64/cpufeature.h +++ b/include/asm-x86_64/cpufeature.h @@ -29,7 +29,7 @@ #define X86_FEATURE_PSE36 (0*32+17) /* 36-bit PSEs */ #define X86_FEATURE_PN (0*32+18) /* Processor serial number */ #define X86_FEATURE_CLFLSH (0*32+19) /* Supports the CLFLUSH instruction */ -#define X86_FEATURE_DTES (0*32+21) /* Debug Trace Store */ +#define X86_FEATURE_DS (0*32+21) /* Debug Store */ #define X86_FEATURE_ACPI (0*32+22) /* ACPI via MSR */ #define X86_FEATURE_MMX (0*32+23) /* Multimedia Extensions */ #define X86_FEATURE_FXSR (0*32+24) /* FXSAVE and FXRSTOR instructions (fast save and restore */ @@ -112,5 +112,6 @@ #define cpu_has_cyrix_arr 0 #define cpu_has_centaur_mcr 0 #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) +#define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) #endif /* __ASM_X8664_CPUFEATURE_H */ -- cgit v1.2.3 From 36b2a8d5aff4cb3ee83d5e40447a8f073bcfe2fb Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] x86-64: add X86_FEATURE_PEBS and detection Here is a patch (used by perfmon2) to detect the presence of the Precise Event Based Sampling (PEBS) feature for Intel 64-bit processors. The patch also adds the cpu_has_pebs macro. changelog: - adds X86_FEATURE_PEBS - adds cpu_has_pebs to test for X86_FEATURE_PEBS Signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- arch/x86_64/kernel/setup.c | 7 +++++++ include/asm-x86_64/cpufeature.h | 2 ++ 2 files changed, 9 insertions(+) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index fc944b5e8f4a..619af2e2fa26 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -835,6 +835,13 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) set_bit(X86_FEATURE_ARCH_PERFMON, &c->x86_capability); } + if (cpu_has_ds) { + unsigned int l1, l2; + rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); + if (!(l1 & (1<<12))) + set_bit(X86_FEATURE_PEBS, c->x86_capability); + } + n = c->extended_cpuid_level; if (n >= 0x80000008) { unsigned eax = cpuid_eax(0x80000008); diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h index 65eb39e8f3cc..d280384807ef 100644 --- a/include/asm-x86_64/cpufeature.h +++ b/include/asm-x86_64/cpufeature.h @@ -68,6 +68,7 @@ #define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */ #define X86_FEATURE_UP (3*32+8) /* SMP kernel running on UP */ #define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */ +#define X86_FEATURE_PEBS (3*32+10) /* Precise-Event Based Sampling */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ @@ -113,5 +114,6 @@ #define cpu_has_centaur_mcr 0 #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) #define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) +#define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) #endif /* __ASM_X8664_CPUFEATURE_H */ -- cgit v1.2.3 From d8cebe65ea5179e3293c38427d71f4d73c795d39 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] x86-64: remove duplicated cpu_mask_to_apicid in x86_64 smp.h inline function cpu_mask_to_apicid in smp.h is duplicated with macro in mach_apic.h. Signed-off-by: Yinghai Lu Signed-off-by: Andi Kleen --- include/asm-x86_64/smp.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index d6b7c057edba..7ae7e7d89d16 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -82,11 +82,6 @@ extern u8 x86_cpu_to_apicid[NR_CPUS]; /* physical ID */ extern u8 x86_cpu_to_log_apicid[NR_CPUS]; extern u8 bios_cpu_apicid[]; -static inline unsigned int cpu_mask_to_apicid(cpumask_t cpumask) -{ - return cpus_addr(cpumask)[0]; -} - static inline int cpu_present_to_apicid(int mps_cpu) { if (mps_cpu < NR_CPUS) -- cgit v1.2.3 From bb81a09e55eaf7e5f798468ab971469b6f66a259 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Thu, 7 Dec 2006 02:14:01 +0100 Subject: [PATCH] x86: all cpu backtrace When a spinlock lockup occurs, arrange for the NMI code to emit an all-cpu backtrace, so we get to see which CPU is holding the lock, and where. Cc: Andi Kleen Cc: Ingo Molnar Cc: Badari Pulavarty Signed-off-by: Andrew Morton Signed-off-by: Andi Kleen --- arch/i386/kernel/nmi.c | 26 ++++++++++++++++++++++++++ arch/x86_64/kernel/nmi.c | 29 ++++++++++++++++++++++++++++- include/asm-i386/nmi.h | 8 ++++++++ include/asm-x86_64/nmi.h | 3 +++ include/linux/nmi.h | 5 +++++ lib/spinlock_debug.c | 4 ++++ 6 files changed, 74 insertions(+), 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c index eaafe233a5da..171194ccb7bc 100644 --- a/arch/i386/kernel/nmi.c +++ b/arch/i386/kernel/nmi.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,8 @@ int nmi_watchdog_enabled; static DEFINE_PER_CPU(unsigned long, perfctr_nmi_owner); static DEFINE_PER_CPU(unsigned long, evntsel_nmi_owner[3]); +static cpumask_t backtrace_mask = CPU_MASK_NONE; + /* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) */ @@ -907,6 +910,16 @@ __kprobes int nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) touched = 1; } + if (cpu_isset(cpu, backtrace_mask)) { + static DEFINE_SPINLOCK(lock); /* Serialise the printks */ + + spin_lock(&lock); + printk("NMI backtrace for cpu %d\n", cpu); + dump_stack(); + spin_unlock(&lock); + cpu_clear(cpu, backtrace_mask); + } + sum = per_cpu(irq_stat, cpu).apic_timer_irqs; /* if the apic timer isn't firing, this cpu isn't doing much */ @@ -1033,6 +1046,19 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, #endif +void __trigger_all_cpu_backtrace(void) +{ + int i; + + backtrace_mask = cpu_online_map; + /* Wait for up to 10 seconds for all CPUs to do the backtrace */ + for (i = 0; i < 10 * 1000; i++) { + if (cpus_empty(backtrace_mask)) + break; + mdelay(1); + } +} + EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); diff --git a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c index 7af9cb3e2d99..27e95e7922c1 100644 --- a/arch/x86_64/kernel/nmi.c +++ b/arch/x86_64/kernel/nmi.c @@ -12,14 +12,15 @@ * Mikael Pettersson : PM converted to driver model. Disable/enable API. */ +#include #include #include #include #include #include -#include #include #include +#include #include #include @@ -41,6 +42,8 @@ int panic_on_unrecovered_nmi; static DEFINE_PER_CPU(unsigned, perfctr_nmi_owner); static DEFINE_PER_CPU(unsigned, evntsel_nmi_owner[2]); +static cpumask_t backtrace_mask = CPU_MASK_NONE; + /* this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. It will be the max for all platforms (for now) */ @@ -782,6 +785,7 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) { int sum; int touched = 0; + int cpu = smp_processor_id(); struct nmi_watchdog_ctlblk *wd = &__get_cpu_var(nmi_watchdog_ctlblk); u64 dummy; int rc=0; @@ -799,6 +803,16 @@ int __kprobes nmi_watchdog_tick(struct pt_regs * regs, unsigned reason) touched = 1; } + if (cpu_isset(cpu, backtrace_mask)) { + static DEFINE_SPINLOCK(lock); /* Serialise the printks */ + + spin_lock(&lock); + printk("NMI backtrace for cpu %d\n", cpu); + dump_stack(); + spin_unlock(&lock); + cpu_clear(cpu, backtrace_mask); + } + #ifdef CONFIG_X86_MCE /* Could check oops_in_progress here too, but it's safer not too */ @@ -931,6 +945,19 @@ int proc_nmi_enabled(struct ctl_table *table, int write, struct file *file, #endif +void __trigger_all_cpu_backtrace(void) +{ + int i; + + backtrace_mask = cpu_online_map; + /* Wait for up to 10 seconds for all CPUs to do the backtrace */ + for (i = 0; i < 10 * 1000; i++) { + if (cpus_empty(backtrace_mask)) + break; + mdelay(1); + } +} + EXPORT_SYMBOL(nmi_active); EXPORT_SYMBOL(nmi_watchdog); EXPORT_SYMBOL(avail_to_resrv_perfctr_nmi); diff --git a/include/asm-i386/nmi.h b/include/asm-i386/nmi.h index 269d315719ca..b04333ea6f31 100644 --- a/include/asm-i386/nmi.h +++ b/include/asm-i386/nmi.h @@ -5,6 +5,9 @@ #define ASM_NMI_H #include +#include + +#ifdef ARCH_HAS_NMI_WATCHDOG /** * do_nmi_callback @@ -42,4 +45,9 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, void __user *, size_t *, loff_t *); extern int unknown_nmi_panic; +void __trigger_all_cpu_backtrace(void); +#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() + +#endif + #endif /* ASM_NMI_H */ diff --git a/include/asm-x86_64/nmi.h b/include/asm-x86_64/nmi.h index f367d4014b42..72375e7d32a8 100644 --- a/include/asm-x86_64/nmi.h +++ b/include/asm-x86_64/nmi.h @@ -77,4 +77,7 @@ extern int proc_nmi_enabled(struct ctl_table *, int , struct file *, extern int unknown_nmi_panic; +void __trigger_all_cpu_backtrace(void); +#define trigger_all_cpu_backtrace() __trigger_all_cpu_backtrace() + #endif /* ASM_NMI_H */ diff --git a/include/linux/nmi.h b/include/linux/nmi.h index e16904e28c3a..acb4ed130247 100644 --- a/include/linux/nmi.h +++ b/include/linux/nmi.h @@ -15,9 +15,14 @@ * disables interrupts for a long time. This call is stateless. */ #ifdef ARCH_HAS_NMI_WATCHDOG +#include extern void touch_nmi_watchdog(void); #else # define touch_nmi_watchdog() touch_softlockup_watchdog() #endif +#ifndef trigger_all_cpu_backtrace +#define trigger_all_cpu_backtrace() do { } while (0) +#endif + #endif diff --git a/lib/spinlock_debug.c b/lib/spinlock_debug.c index b6c4f898197c..479fd462eaa9 100644 --- a/lib/spinlock_debug.c +++ b/lib/spinlock_debug.c @@ -7,6 +7,7 @@ */ #include +#include #include #include #include @@ -117,6 +118,9 @@ static void __spin_lock_debug(spinlock_t *lock) raw_smp_processor_id(), current->comm, current->pid, lock); dump_stack(); +#ifdef CONFIG_SMP + trigger_all_cpu_backtrace(); +#endif } } } -- cgit v1.2.3 From 86efef50cfff9905c4e4ec64f3d3d3b299226674 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Dec 2006 02:14:02 +0100 Subject: [PATCH] x86-64: x86-64 add Intel Core related PMU MSRs definitions Add o the x86-64 tree a bunch of MSRs related to performance monitoring for the processors based on Intel Core microarchitecture. It also adds some architectural MSRs for PEBS. A similar patch for i386 will follow. changelog: - add Intel Precise-Event Based sampling (PEBS) related MSR - add Intel Data Save (DS) Area related MSR - add Intel Core microarchitecure performance counter MSRs Signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- include/asm-x86_64/msr.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h index 37e194169fac..a745c5008a60 100644 --- a/include/asm-x86_64/msr.h +++ b/include/asm-x86_64/msr.h @@ -210,6 +210,10 @@ static inline unsigned int cpuid_edx(unsigned int op) #define MSR_IA32_LASTINTFROMIP 0x1dd #define MSR_IA32_LASTINTTOIP 0x1de +#define MSR_IA32_PEBS_ENABLE 0x3f1 +#define MSR_IA32_DS_AREA 0x600 +#define MSR_IA32_PERF_CAPABILITIES 0x345 + #define MSR_MTRRfix64K_00000 0x250 #define MSR_MTRRfix16K_80000 0x258 #define MSR_MTRRfix16K_A0000 0x259 @@ -407,4 +411,13 @@ static inline unsigned int cpuid_edx(unsigned int op) #define MSR_P4_U2L_ESCR0 0x3b0 #define MSR_P4_U2L_ESCR1 0x3b1 +/* Intel Core-based CPU performance counters */ +#define MSR_CORE_PERF_FIXED_CTR0 0x309 +#define MSR_CORE_PERF_FIXED_CTR1 0x30a +#define MSR_CORE_PERF_FIXED_CTR2 0x30b +#define MSR_CORE_PERF_FIXED_CTR_CTRL 0x38d +#define MSR_CORE_PERF_GLOBAL_STATUS 0x38e +#define MSR_CORE_PERF_GLOBAL_CTRL 0x38f +#define MSR_CORE_PERF_GLOBAL_OVF_CTRL 0x390 + #endif -- cgit v1.2.3 From 249e83fe839a13b5dc94285daeeaf70f6e54d930 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Thu, 7 Dec 2006 02:14:04 +0100 Subject: [PATCH] x86-64: Extract segment descriptor definitions for use outside Code that wants to use struct desc_struct cannot do so on i386 because desc.h contains other code that will only compile on x86_64. So extract the structure definitions into a asm-x86_64/desc_defs.h. Signed-off-by: Avi Kivity Signed-off-by: Andi Kleen include/asm-x86_64/desc.h | 53 ------------------------------- include/asm-x86_64/desc_defs.h | 69 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 52 deletions(-) --- include/asm-x86_64/desc.h | 53 +------------------------------- include/asm-x86_64/desc_defs.h | 69 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 52 deletions(-) create mode 100644 include/asm-x86_64/desc_defs.h (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/desc.h b/include/asm-x86_64/desc.h index eb7723a46790..913d6ac00033 100644 --- a/include/asm-x86_64/desc.h +++ b/include/asm-x86_64/desc.h @@ -9,64 +9,13 @@ #include #include +#include #include #include -// 8 byte segment descriptor -struct desc_struct { - u16 limit0; - u16 base0; - unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1; - unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 : 8; -} __attribute__((packed)); - -struct n_desc_struct { - unsigned int a,b; -}; - extern struct desc_struct cpu_gdt_table[GDT_ENTRIES]; -enum { - GATE_INTERRUPT = 0xE, - GATE_TRAP = 0xF, - GATE_CALL = 0xC, -}; - -// 16byte gate -struct gate_struct { - u16 offset_low; - u16 segment; - unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; - u16 offset_middle; - u32 offset_high; - u32 zero1; -} __attribute__((packed)); - -#define PTR_LOW(x) ((unsigned long)(x) & 0xFFFF) -#define PTR_MIDDLE(x) (((unsigned long)(x) >> 16) & 0xFFFF) -#define PTR_HIGH(x) ((unsigned long)(x) >> 32) - -enum { - DESC_TSS = 0x9, - DESC_LDT = 0x2, -}; - -// LDT or TSS descriptor in the GDT. 16 bytes. -struct ldttss_desc { - u16 limit0; - u16 base0; - unsigned base1 : 8, type : 5, dpl : 2, p : 1; - unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; - u32 base3; - u32 zero1; -} __attribute__((packed)); - -struct desc_ptr { - unsigned short size; - unsigned long address; -} __attribute__((packed)) ; - #define load_TR_desc() asm volatile("ltr %w0"::"r" (GDT_ENTRY_TSS*8)) #define load_LDT_desc() asm volatile("lldt %w0"::"r" (GDT_ENTRY_LDT*8)) #define clear_LDT() asm volatile("lldt %w0"::"r" (0)) diff --git a/include/asm-x86_64/desc_defs.h b/include/asm-x86_64/desc_defs.h new file mode 100644 index 000000000000..089004070099 --- /dev/null +++ b/include/asm-x86_64/desc_defs.h @@ -0,0 +1,69 @@ +/* Written 2000 by Andi Kleen */ +#ifndef __ARCH_DESC_DEFS_H +#define __ARCH_DESC_DEFS_H + +/* + * Segment descriptor structure definitions, usable from both x86_64 and i386 + * archs. + */ + +#ifndef __ASSEMBLY__ + +#include + +// 8 byte segment descriptor +struct desc_struct { + u16 limit0; + u16 base0; + unsigned base1 : 8, type : 4, s : 1, dpl : 2, p : 1; + unsigned limit : 4, avl : 1, l : 1, d : 1, g : 1, base2 : 8; +} __attribute__((packed)); + +struct n_desc_struct { + unsigned int a,b; +}; + +enum { + GATE_INTERRUPT = 0xE, + GATE_TRAP = 0xF, + GATE_CALL = 0xC, +}; + +// 16byte gate +struct gate_struct { + u16 offset_low; + u16 segment; + unsigned ist : 3, zero0 : 5, type : 5, dpl : 2, p : 1; + u16 offset_middle; + u32 offset_high; + u32 zero1; +} __attribute__((packed)); + +#define PTR_LOW(x) ((unsigned long)(x) & 0xFFFF) +#define PTR_MIDDLE(x) (((unsigned long)(x) >> 16) & 0xFFFF) +#define PTR_HIGH(x) ((unsigned long)(x) >> 32) + +enum { + DESC_TSS = 0x9, + DESC_LDT = 0x2, +}; + +// LDT or TSS descriptor in the GDT. 16 bytes. +struct ldttss_desc { + u16 limit0; + u16 base0; + unsigned base1 : 8, type : 5, dpl : 2, p : 1; + unsigned limit1 : 4, zero0 : 3, g : 1, base2 : 8; + u32 base3; + u32 zero1; +} __attribute__((packed)); + +struct desc_ptr { + unsigned short size; + unsigned long address; +} __attribute__((packed)) ; + + +#endif /* !__ASSEMBLY__ */ + +#endif -- cgit v1.2.3 From b34e90b8f0f30151349134f87b5dc6ef75a5218c Mon Sep 17 00:00:00 2001 From: Laurent Vivier Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] Calgary: use BIOS supplied BBARs and topology information Find the BBAR register address of each Calgary using the "Extended BIOS Data Area" rather than calculating it ourselves. Also get the bus topology (what PHB each bus is on) from Calgary rather than calculating it ourselves. This patch fixes http://bugzilla.kernel.org/show_bug.cgi?id=7407. Signed-off-by: Laurent Vivier Signed-off-by: Muli Ben-Yehuda Signed-off-by: Jon Mason Signed-off-by: Andi Kleen --- arch/x86_64/kernel/pci-calgary.c | 161 ++++++++++++++++++++++++++++++--------- include/asm-x86_64/rio.h | 76 ++++++++++++++++++ 2 files changed, 201 insertions(+), 36 deletions(-) create mode 100644 include/asm-x86_64/rio.h (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index f53b581dfd0b..afc0a53505f1 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -41,6 +41,7 @@ #include #include #include +#include #define PCI_DEVICE_ID_IBM_CALGARY 0x02a1 #define PCI_VENDOR_DEVICE_ID_CALGARY \ @@ -115,14 +116,35 @@ static const unsigned long phb_offsets[] = { 0xB000 /* PHB3 */ }; +/* PHB debug registers */ + +static const unsigned long phb_debug_offsets[] = { + 0x4000 /* PHB 0 DEBUG */, + 0x5000 /* PHB 1 DEBUG */, + 0x6000 /* PHB 2 DEBUG */, + 0x7000 /* PHB 3 DEBUG */ +}; + +/* + * STUFF register for each debug PHB, + * byte 1 = start bus number, byte 2 = end bus number + */ + +#define PHB_DEBUG_STUFF_OFFSET 0x0020 + unsigned int specified_table_size = TCE_TABLE_SIZE_UNSPECIFIED; static int translate_empty_slots __read_mostly = 0; static int calgary_detected __read_mostly = 0; +static struct rio_table_hdr *rio_table_hdr __initdata; +static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; +static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; + struct calgary_bus_info { void *tce_space; unsigned char translation_disabled; signed char phbid; + void __iomem *bbar; }; static struct calgary_bus_info bus_info[MAX_PHB_BUS_NUM] = { { NULL, 0, 0 }, }; @@ -475,6 +497,11 @@ static struct dma_mapping_ops calgary_dma_ops = { .unmap_sg = calgary_unmap_sg, }; +static inline void __iomem * busno_to_bbar(unsigned char num) +{ + return bus_info[num].bbar; +} + static inline int busno_to_phbid(unsigned char num) { return bus_info[num].phbid; @@ -828,31 +855,9 @@ static void __init calgary_disable_translation(struct pci_dev *dev) del_timer_sync(&tbl->watchdog_timer); } -static inline unsigned int __init locate_register_space(struct pci_dev *dev) +static inline void __iomem * __init locate_register_space(struct pci_dev *dev) { - int rionodeid; - u32 address; - - /* - * Each Calgary has four busses. The first four busses (first Calgary) - * have RIO node ID 2, then the next four (second Calgary) have RIO - * node ID 3, the next four (third Calgary) have node ID 2 again, etc. - * We use a gross hack - relying on the dev->bus->number ordering, - * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1, - * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the - * second (id 3), and then it repeats modulo 14. - */ - rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2; - /* - * register space address calculation as follows: - * FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase) - * ChassisBase is always zero for x366/x260/x460 - * RioNodeId is 2 for first Calgary, 3 for second Calgary - */ - address = START_ADDRESS - - (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) + - (0x100000) * (rionodeid - CHASSIS_BASE); - return address; + return busno_to_bbar(dev->bus->number); } static void __init calgary_init_one_nontraslated(struct pci_dev *dev) @@ -864,15 +869,12 @@ static void __init calgary_init_one_nontraslated(struct pci_dev *dev) static int __init calgary_init_one(struct pci_dev *dev) { - u32 address; void __iomem *bbar; int ret; BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); - address = locate_register_space(dev); - /* map entire 1MB of Calgary config space */ - bbar = ioremap_nocache(address, 1024 * 1024); + bbar = locate_register_space(dev); if (!bbar) { ret = -ENODATA; goto done; @@ -898,6 +900,35 @@ static int __init calgary_init(void) { int ret = -ENODEV; struct pci_dev *dev = NULL; + int rio, phb, bus; + void __iomem *bbar; + void __iomem *target; + u8 start_bus, end_bus; + u32 val; + + for (rio = 0; rio < rio_table_hdr->num_rio_dev; rio++) { + + if ( (rio_devs[rio]->type != COMPAT_CALGARY) && + (rio_devs[rio]->type != ALT_CALGARY) ) + continue; + + /* map entire 1MB of Calgary config space */ + bbar = ioremap_nocache(rio_devs[rio]->BBAR, 1024 * 1024); + + for (phb = 0; phb < PHBS_PER_CALGARY; phb++) { + + target = calgary_reg(bbar, phb_debug_offsets[phb] | + PHB_DEBUG_STUFF_OFFSET); + val = be32_to_cpu(readl(target)); + start_bus = (u8)((val & 0x00FF0000) >> 16); + end_bus = (u8)((val & 0x0000FF00) >> 8); + for (bus = start_bus; bus <= end_bus; bus++) { + bus_info[bus].bbar = bbar; + bus_info[bus].phbid = phb; + } + } + } + do { dev = pci_get_device(PCI_VENDOR_ID_IBM, @@ -962,13 +993,55 @@ static inline int __init determine_tce_table_size(u64 ram) return ret; } +static int __init build_detail_arrays(void) +{ + unsigned long ptr; + int i, scal_detail_size, rio_detail_size; + + if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){ + printk(KERN_WARNING + "Calgary: MAX_NUMNODES too low! Defined as %d, " + "but system has %d nodes.\n", + MAX_NUMNODES, rio_table_hdr->num_scal_dev); + return -ENODEV; + } + + switch (rio_table_hdr->version){ + default: + printk(KERN_WARNING + "Calgary: Invalid Rio Grande Table Version: %d\n", + rio_table_hdr->version); + return -ENODEV; + case 2: + scal_detail_size = 11; + rio_detail_size = 13; + break; + case 3: + scal_detail_size = 12; + rio_detail_size = 15; + break; + } + + ptr = ((unsigned long)rio_table_hdr) + 3; + for (i = 0; i < rio_table_hdr->num_scal_dev; + i++, ptr += scal_detail_size) + scal_devs[i] = (struct scal_detail *)ptr; + + for (i = 0; i < rio_table_hdr->num_rio_dev; + i++, ptr += rio_detail_size) + rio_devs[i] = (struct rio_detail *)ptr; + + return 0; +} + void __init detect_calgary(void) { u32 val; int bus; void *tbl; int calgary_found = 0; - int phb = -1; + unsigned long ptr; + int offset; /* * if the user specified iommu=off or iommu=soft or we found @@ -980,6 +1053,29 @@ void __init detect_calgary(void) if (!early_pci_allowed()) return; + ptr = (unsigned long)phys_to_virt(get_bios_ebda()); + + rio_table_hdr = NULL; + offset = 0x180; + while (offset) { + /* The block id is stored in the 2nd word */ + if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){ + /* set the pointer past the offset & block id */ + rio_table_hdr = (struct rio_table_hdr *)(ptr+offset+4); + break; + } + /* The next offset is stored in the 1st word. 0 means no more */ + offset = *((unsigned short *)(ptr + offset)); + } + if (!rio_table_hdr){ + printk(KERN_ERR "Calgary: Unable to locate " + "Rio Grande Table in EBDA - bailing!\n"); + return; + } + + if (build_detail_arrays()) + return; + specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { @@ -990,12 +1086,6 @@ void __init detect_calgary(void) if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) continue; - /* - * There are 4 PHBs per Calgary chip. Set phb to which phb (0-3) - * it is connected to releative to the clagary chip. - */ - phb = (phb + 1) % PHBS_PER_CALGARY; - if (info->translation_disabled) continue; @@ -1010,7 +1100,6 @@ void __init detect_calgary(void) if (!tbl) goto cleanup; info->tce_space = tbl; - info->phbid = phb; calgary_found = 1; break; } diff --git a/include/asm-x86_64/rio.h b/include/asm-x86_64/rio.h new file mode 100644 index 000000000000..1f315c39d76e --- /dev/null +++ b/include/asm-x86_64/rio.h @@ -0,0 +1,76 @@ +/* + * Derived from include/asm-i386/mach-summit/mach_mpparse.h + * and include/asm-i386/mach-default/bios_ebda.h + * + * Author: Laurent Vivier + * + */ + +#ifndef __ASM_RIO_H +#define __ASM_RIO_H + +#define RIO_TABLE_VERSION 3 + +struct rio_table_hdr { + u8 version; /* Version number of this data structure */ + u8 num_scal_dev; /* # of Scalability devices */ + u8 num_rio_dev; /* # of RIO I/O devices */ +} __attribute__((packed)); + +struct scal_detail { + u8 node_id; /* Scalability Node ID */ + u32 CBAR; /* Address of 1MB register space */ + u8 port0node; /* Node ID port connected to: 0xFF=None */ + u8 port0port; /* Port num port connected to: 0,1,2, or */ + /* 0xFF=None */ + u8 port1node; /* Node ID port connected to: 0xFF = None */ + u8 port1port; /* Port num port connected to: 0,1,2, or */ + /* 0xFF=None */ + u8 port2node; /* Node ID port connected to: 0xFF = None */ + u8 port2port; /* Port num port connected to: 0,1,2, or */ + /* 0xFF=None */ + u8 chassis_num; /* 1 based Chassis number (1 = boot node) */ +} __attribute__((packed)); + +struct rio_detail { + u8 node_id; /* RIO Node ID */ + u32 BBAR; /* Address of 1MB register space */ + u8 type; /* Type of device */ + u8 owner_id; /* Node ID of Hurricane that owns this */ + /* node */ + u8 port0node; /* Node ID port connected to: 0xFF=None */ + u8 port0port; /* Port num port connected to: 0,1,2, or */ + /* 0xFF=None */ + u8 port1node; /* Node ID port connected to: 0xFF=None */ + u8 port1port; /* Port num port connected to: 0,1,2, or */ + /* 0xFF=None */ + u8 first_slot; /* Lowest slot number below this Calgary */ + u8 status; /* Bit 0 = 1 : the XAPIC is used */ + /* = 0 : the XAPIC is not used, ie: */ + /* ints fwded to another XAPIC */ + /* Bits1:7 Reserved */ + u8 WP_index; /* instance index - lower ones have */ + /* lower slot numbers/PCI bus numbers */ + u8 chassis_num; /* 1 based Chassis number */ +} __attribute__((packed)); + +enum { + HURR_SCALABILTY = 0, /* Hurricane Scalability info */ + HURR_RIOIB = 2, /* Hurricane RIOIB info */ + COMPAT_CALGARY = 4, /* Compatibility Calgary */ + ALT_CALGARY = 5, /* Second Planar Calgary */ +}; + +/* + * there is a real-mode segmented pointer pointing to the + * 4K EBDA area at 0x40E. + */ + +static inline unsigned long get_bios_ebda(void) +{ + unsigned long address= *(unsigned short *)phys_to_virt(0x40Eul); + address <<= 4; + return address; +} + +#endif /* __ASM_RIO_H */ -- cgit v1.2.3 From eae93755540bae18aff46b8a0e621b5d65bd5380 Mon Sep 17 00:00:00 2001 From: Muli Ben-Yehuda Date: Thu, 7 Dec 2006 02:14:06 +0100 Subject: [PATCH] Calgary: check BBAR ioremap success when ioremapping This patch cleans up the previous "Use BIOS supplied BBAR information" patch. Mostly stylistic clenaups, but also check for ioremap failure when we ioremap the BBAR rather than when trying to use it. Signed-off-by: Muli Ben-Yehuda Signed-off-by: Jon Mason Signed-off-by: Andi Kleen Acked-by: Laurent Vivier --- arch/x86_64/kernel/pci-calgary.c | 85 +++++++++++++++++++++++----------------- include/asm-x86_64/rio.h | 8 ++-- 2 files changed, 52 insertions(+), 41 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index afc0a53505f1..8a1e4f35bc3c 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -138,7 +138,7 @@ static int calgary_detected __read_mostly = 0; static struct rio_table_hdr *rio_table_hdr __initdata; static struct scal_detail *scal_devs[MAX_NUMNODES] __initdata; -static struct rio_detail *rio_devs[MAX_NUMNODES*4] __initdata; +static struct rio_detail *rio_devs[MAX_NUMNODES * 4] __initdata; struct calgary_bus_info { void *tce_space; @@ -855,11 +855,6 @@ static void __init calgary_disable_translation(struct pci_dev *dev) del_timer_sync(&tbl->watchdog_timer); } -static inline void __iomem * __init locate_register_space(struct pci_dev *dev) -{ - return busno_to_bbar(dev->bus->number); -} - static void __init calgary_init_one_nontraslated(struct pci_dev *dev) { pci_dev_get(dev); @@ -874,15 +869,10 @@ static int __init calgary_init_one(struct pci_dev *dev) BUG_ON(dev->bus->number >= MAX_PHB_BUS_NUM); - bbar = locate_register_space(dev); - if (!bbar) { - ret = -ENODATA; - goto done; - } - + bbar = busno_to_bbar(dev->bus->number); ret = calgary_setup_tar(dev, bbar); if (ret) - goto iounmap; + goto done; pci_dev_get(dev); dev->bus->self = dev; @@ -890,38 +880,39 @@ static int __init calgary_init_one(struct pci_dev *dev) return 0; -iounmap: - iounmap(bbar); done: return ret; } -static int __init calgary_init(void) +static int __init calgary_locate_bbars(void) { - int ret = -ENODEV; - struct pci_dev *dev = NULL; - int rio, phb, bus; + int ret; + int rioidx, phb, bus; void __iomem *bbar; void __iomem *target; + unsigned long offset; u8 start_bus, end_bus; u32 val; - for (rio = 0; rio < rio_table_hdr->num_rio_dev; rio++) { + ret = -ENODATA; + for (rioidx = 0; rioidx < rio_table_hdr->num_rio_dev; rioidx++) { + struct rio_detail *rio = rio_devs[rioidx]; - if ( (rio_devs[rio]->type != COMPAT_CALGARY) && - (rio_devs[rio]->type != ALT_CALGARY) ) + if ((rio->type != COMPAT_CALGARY) && (rio->type != ALT_CALGARY)) continue; /* map entire 1MB of Calgary config space */ - bbar = ioremap_nocache(rio_devs[rio]->BBAR, 1024 * 1024); + bbar = ioremap_nocache(rio->BBAR, 1024 * 1024); + if (!bbar) + goto error; for (phb = 0; phb < PHBS_PER_CALGARY; phb++) { + offset = phb_debug_offsets[phb] | PHB_DEBUG_STUFF_OFFSET; + target = calgary_reg(bbar, offset); - target = calgary_reg(bbar, phb_debug_offsets[phb] | - PHB_DEBUG_STUFF_OFFSET); val = be32_to_cpu(readl(target)); start_bus = (u8)((val & 0x00FF0000) >> 16); - end_bus = (u8)((val & 0x0000FF00) >> 8); + end_bus = (u8)((val & 0x0000FF00) >> 8); for (bus = start_bus; bus <= end_bus; bus++) { bus_info[bus].bbar = bbar; bus_info[bus].phbid = phb; @@ -929,6 +920,25 @@ static int __init calgary_init(void) } } + return 0; + +error: + /* scan bus_info and iounmap any bbars we previously ioremap'd */ + for (bus = 0; bus < ARRAY_SIZE(bus_info); bus++) + if (bus_info[bus].bbar) + iounmap(bus_info[bus].bbar); + + return ret; +} + +static int __init calgary_init(void) +{ + int ret; + struct pci_dev *dev = NULL; + + ret = calgary_locate_bbars(); + if (ret) + return ret; do { dev = pci_get_device(PCI_VENDOR_ID_IBM, @@ -1000,18 +1010,13 @@ static int __init build_detail_arrays(void) if (rio_table_hdr->num_scal_dev > MAX_NUMNODES){ printk(KERN_WARNING - "Calgary: MAX_NUMNODES too low! Defined as %d, " + "Calgary: MAX_NUMNODES too low! Defined as %d, " "but system has %d nodes.\n", MAX_NUMNODES, rio_table_hdr->num_scal_dev); return -ENODEV; } switch (rio_table_hdr->version){ - default: - printk(KERN_WARNING - "Calgary: Invalid Rio Grande Table Version: %d\n", - rio_table_hdr->version); - return -ENODEV; case 2: scal_detail_size = 11; rio_detail_size = 13; @@ -1020,6 +1025,11 @@ static int __init build_detail_arrays(void) scal_detail_size = 12; rio_detail_size = 15; break; + default: + printk(KERN_WARNING + "Calgary: Invalid Rio Grande Table Version: %d\n", + rio_table_hdr->version); + return -EPROTO; } ptr = ((unsigned long)rio_table_hdr) + 3; @@ -1042,6 +1052,7 @@ void __init detect_calgary(void) int calgary_found = 0; unsigned long ptr; int offset; + int ret; /* * if the user specified iommu=off or iommu=soft or we found @@ -1061,27 +1072,29 @@ void __init detect_calgary(void) /* The block id is stored in the 2nd word */ if (*((unsigned short *)(ptr + offset + 2)) == 0x4752){ /* set the pointer past the offset & block id */ - rio_table_hdr = (struct rio_table_hdr *)(ptr+offset+4); + rio_table_hdr = (struct rio_table_hdr *)(ptr + offset + 4); break; } /* The next offset is stored in the 1st word. 0 means no more */ offset = *((unsigned short *)(ptr + offset)); } - if (!rio_table_hdr){ + if (!rio_table_hdr) { printk(KERN_ERR "Calgary: Unable to locate " "Rio Grande Table in EBDA - bailing!\n"); return; } - if (build_detail_arrays()) + ret = build_detail_arrays(); + if (ret) { + printk(KERN_ERR "Calgary: build_detail_arrays ret %d\n", ret); return; + } specified_table_size = determine_tce_table_size(end_pfn * PAGE_SIZE); for (bus = 0; bus < MAX_PHB_BUS_NUM; bus++) { int dev; struct calgary_bus_info *info = &bus_info[bus]; - info->phbid = -1; if (read_pci_config(bus, 0, 0, 0) != PCI_VENDOR_DEVICE_ID_CALGARY) continue; diff --git a/include/asm-x86_64/rio.h b/include/asm-x86_64/rio.h index 1f315c39d76e..c7350f6d2015 100644 --- a/include/asm-x86_64/rio.h +++ b/include/asm-x86_64/rio.h @@ -3,7 +3,6 @@ * and include/asm-i386/mach-default/bios_ebda.h * * Author: Laurent Vivier - * */ #ifndef __ASM_RIO_H @@ -19,7 +18,7 @@ struct rio_table_hdr { struct scal_detail { u8 node_id; /* Scalability Node ID */ - u32 CBAR; /* Address of 1MB register space */ + u32 CBAR; /* Address of 1MB register space */ u8 port0node; /* Node ID port connected to: 0xFF=None */ u8 port0port; /* Port num port connected to: 0,1,2, or */ /* 0xFF=None */ @@ -34,7 +33,7 @@ struct scal_detail { struct rio_detail { u8 node_id; /* RIO Node ID */ - u32 BBAR; /* Address of 1MB register space */ + u32 BBAR; /* Address of 1MB register space */ u8 type; /* Type of device */ u8 owner_id; /* Node ID of Hurricane that owns this */ /* node */ @@ -65,10 +64,9 @@ enum { * there is a real-mode segmented pointer pointing to the * 4K EBDA area at 0x40E. */ - static inline unsigned long get_bios_ebda(void) { - unsigned long address= *(unsigned short *)phys_to_virt(0x40Eul); + unsigned long address = *(unsigned short *)phys_to_virt(0x40EUL); address <<= 4; return address; } -- cgit v1.2.3 From bff6547bb6a4e82c399d74e7fba78b12d2f162ed Mon Sep 17 00:00:00 2001 From: Muli Ben-Yehuda Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] Calgary: allow compiling Calgary in but not using it by default This patch makes it possible to compile Calgary in but not use it by default. In this mode, use 'iommu=calgary' to activate it. Signed-off-by: Muli Ben-Yehuda Signed-off-by: Jon Mason Signed-off-by: Andi Kleen --- Documentation/x86_64/boot-options.txt | 3 ++- arch/x86_64/Kconfig | 11 +++++++++++ arch/x86_64/kernel/pci-calgary.c | 9 +++++++++ arch/x86_64/kernel/pci-dma.c | 5 +++++ include/asm-x86_64/calgary.h | 2 ++ 5 files changed, 29 insertions(+), 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/Documentation/x86_64/boot-options.txt b/Documentation/x86_64/boot-options.txt index ab9b1c046c00..dbdcaf68e3ea 100644 --- a/Documentation/x86_64/boot-options.txt +++ b/Documentation/x86_64/boot-options.txt @@ -179,7 +179,7 @@ PCI IOMMU iommu=[size][,noagp][,off][,force][,noforce][,leak][,memaper[=order]][,merge] - [,forcesac][,fullflush][,nomerge][,noaperture] + [,forcesac][,fullflush][,nomerge][,noaperture][,calgary] size set size of iommu (in bytes) noagp don't initialize the AGP driver and use full aperture. off don't use the IOMMU @@ -200,6 +200,7 @@ IOMMU buffering. nodac Forbid DMA >4GB panic Always panic when IOMMU overflows + calgary Use the Calgary IOMMU if it is available swiotlb=pages[,force] diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 010d2265f1cf..5cb509dbffe4 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -455,6 +455,17 @@ config CALGARY_IOMMU Normally the kernel will make the right choice by itself. If unsure, say Y. +config CALGARY_IOMMU_ENABLED_BY_DEFAULT + bool "Should Calgary be enabled by default?" + default y + depends on CALGARY_IOMMU + help + Should Calgary be enabled by default? if you choose 'y', Calgary + will be used (if it exists). If you choose 'n', Calgary will not be + used even if it exists. If you choose 'n' and would like to use + Calgary anyway, pass 'iommu=calgary' on the kernel command line. + If unsure, say Y. + # need this always selected by IOMMU for the VIA workaround config SWIOTLB bool diff --git a/arch/x86_64/kernel/pci-calgary.c b/arch/x86_64/kernel/pci-calgary.c index 8a1e4f35bc3c..0ddf29dae7e0 100644 --- a/arch/x86_64/kernel/pci-calgary.c +++ b/arch/x86_64/kernel/pci-calgary.c @@ -43,6 +43,12 @@ #include #include +#ifdef CONFIG_CALGARY_IOMMU_ENABLED_BY_DEFAULT +int use_calgary __read_mostly = 1; +#else +int use_calgary __read_mostly = 0; +#endif /* CONFIG_CALGARY_DEFAULT_ENABLED */ + #define PCI_DEVICE_ID_IBM_CALGARY 0x02a1 #define PCI_VENDOR_DEVICE_ID_CALGARY \ (PCI_VENDOR_ID_IBM | PCI_DEVICE_ID_IBM_CALGARY << 16) @@ -1061,6 +1067,9 @@ void __init detect_calgary(void) if (swiotlb || no_iommu || iommu_detected) return; + if (!use_calgary) + return; + if (!early_pci_allowed()) return; diff --git a/arch/x86_64/kernel/pci-dma.c b/arch/x86_64/kernel/pci-dma.c index f8d857453f8a..683b7a5c1ab3 100644 --- a/arch/x86_64/kernel/pci-dma.c +++ b/arch/x86_64/kernel/pci-dma.c @@ -296,6 +296,11 @@ __init int iommu_setup(char *p) gart_parse_options(p); #endif +#ifdef CONFIG_CALGARY_IOMMU + if (!strncmp(p, "calgary", 7)) + use_calgary = 1; +#endif /* CONFIG_CALGARY_IOMMU */ + p += strcspn(p, ","); if (*p == ',') ++p; diff --git a/include/asm-x86_64/calgary.h b/include/asm-x86_64/calgary.h index 6b93f5a3a5c8..7ee900645719 100644 --- a/include/asm-x86_64/calgary.h +++ b/include/asm-x86_64/calgary.h @@ -51,6 +51,8 @@ struct iommu_table { #define TCE_TABLE_SIZE_4M 6 #define TCE_TABLE_SIZE_8M 7 +extern int use_calgary; + #ifdef CONFIG_CALGARY_IOMMU extern int calgary_iommu_init(void); extern void detect_calgary(void); -- cgit v1.2.3 From b9a8d94a47f8a41766f6f7944adfb1d641349903 Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] x86-64: Make x86_64 udelay() round up instead of down. Port two patches from i386 to x86_64 delay.c to make sure all rounding is done upward instead of downward. There is no sign in commit messages that the mismatch was done on purpose, and "delay() guarantees sleeping at least for the specified time" is still a valid rule IMHO. The original x86 patches are both from pre-GIT era, i.e.: "[PATCH] round up in __udelay()" in commit 54c7e1f5cc6771ff644d7bc21a2b829308bd126f "[PATCH] add 1 in __const_udelay()" in commit 42c77a9801b8877d8b90f65f75db758822a0bccc (both commits are from converted BK repository to x86_64). AK: fixed gcc warning linux/arch/x86_64/lib/delay.c:43: warning: suggest parentheses around + or - inside shift (did this actually work?) Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andi Kleen --- arch/x86_64/lib/delay.c | 4 ++-- include/asm-x86_64/delay.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/lib/delay.c b/arch/x86_64/lib/delay.c index 50be90975d04..2dbebd308347 100644 --- a/arch/x86_64/lib/delay.c +++ b/arch/x86_64/lib/delay.c @@ -40,13 +40,13 @@ EXPORT_SYMBOL(__delay); inline void __const_udelay(unsigned long xloops) { - __delay((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32); + __delay(((xloops * HZ * cpu_data[raw_smp_processor_id()].loops_per_jiffy) >> 32) + 1); } EXPORT_SYMBOL(__const_udelay); void __udelay(unsigned long usecs) { - __const_udelay(usecs * 0x000010c6); /* 2**32 / 1000000 */ + __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */ } EXPORT_SYMBOL(__udelay); diff --git a/include/asm-x86_64/delay.h b/include/asm-x86_64/delay.h index 65f64acc5319..40146f611ccb 100644 --- a/include/asm-x86_64/delay.h +++ b/include/asm-x86_64/delay.h @@ -16,7 +16,7 @@ extern void __const_udelay(unsigned long usecs); extern void __delay(unsigned long loops); #define udelay(n) (__builtin_constant_p(n) ? \ - ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c6ul)) : \ + ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ __udelay(n)) #define ndelay(n) (__builtin_constant_p(n) ? \ -- cgit v1.2.3 From e6536c1262c56d302e749ab1b44fdb0b9786327d Mon Sep 17 00:00:00 2001 From: Paolo 'Blaisorblade' Giarrusso Date: Thu, 7 Dec 2006 02:14:07 +0100 Subject: [PATCH] x86: comment magic constants in delay.h For both i386 and x86_64, copy from arch/$ARCH/lib/delay.c comments about the used magic constants, plus a few other niceties. Signed-off-by: Paolo 'Blaisorblade' Giarrusso Signed-off-by: Andi Kleen include/asm-i386/delay.h | 5 ++++- include/asm-x86_64/delay.h | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) --- include/asm-i386/delay.h | 5 ++++- include/asm-x86_64/delay.h | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-i386/delay.h b/include/asm-i386/delay.h index b1c7650dc7b9..9ae5e3782ed8 100644 --- a/include/asm-i386/delay.h +++ b/include/asm-i386/delay.h @@ -7,6 +7,7 @@ * Delay routines calling functions in arch/i386/lib/delay.c */ +/* Undefined functions to get compile-time errors */ extern void __bad_udelay(void); extern void __bad_ndelay(void); @@ -15,10 +16,12 @@ extern void __ndelay(unsigned long nsecs); extern void __const_udelay(unsigned long usecs); extern void __delay(unsigned long loops); +/* 0x10c7 is 2**32 / 1000000 (rounded up) */ #define udelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ __udelay(n)) - + +/* 0x5 is 2**32 / 1000000000 (rounded up) */ #define ndelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ __ndelay(n)) diff --git a/include/asm-x86_64/delay.h b/include/asm-x86_64/delay.h index 40146f611ccb..c2669f1f5529 100644 --- a/include/asm-x86_64/delay.h +++ b/include/asm-x86_64/delay.h @@ -7,18 +7,21 @@ * Delay routines calling functions in arch/x86_64/lib/delay.c */ +/* Undefined functions to get compile-time errors */ extern void __bad_udelay(void); extern void __bad_ndelay(void); extern void __udelay(unsigned long usecs); -extern void __ndelay(unsigned long usecs); +extern void __ndelay(unsigned long nsecs); extern void __const_udelay(unsigned long usecs); extern void __delay(unsigned long loops); +/* 0x10c7 is 2**32 / 1000000 (rounded up) */ #define udelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_udelay() : __const_udelay((n) * 0x10c7ul)) : \ __udelay(n)) +/* 0x5 is 2**32 / 1000000000 (rounded up) */ #define ndelay(n) (__builtin_constant_p(n) ? \ ((n) > 20000 ? __bad_ndelay() : __const_udelay((n) * 5ul)) : \ __ndelay(n)) -- cgit v1.2.3 From 139ec7c416248b9ea227d21839235344edfee1e0 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 7 Dec 2006 02:14:08 +0100 Subject: [PATCH] paravirt: Patch inline replacements for paravirt intercepts It turns out that the most called ops, by several orders of magnitude, are the interrupt manipulation ops. These are obvious candidates for patching, so mark them up and create infrastructure for it. The method used is that the ops structure has a patch function, which is called for each place which needs to be patched: this returns a number of instructions (the rest are NOP-padded). Usually we can spare a register (%eax) for the binary patched code to use, but in a couple of critical places in entry.S we can't: we make the clobbers explicit at the call site, and manually clobber the allowed registers in debug mode as an extra check. And: Don't abuse CONFIG_DEBUG_KERNEL, add CONFIG_DEBUG_PARAVIRT. And: AK: Fix warnings in x86-64 alternative.c build And: AK: Fix compilation with defconfig And: ^From: Andrew Morton Some binutlises still like to emit references to __stop_parainstructions and __start_parainstructions. And: AK: Fix warnings about unused variables when PARAVIRT is disabled. Signed-off-by: Rusty Russell Signed-off-by: Jeremy Fitzhardinge Signed-off-by: Chris Wright Signed-off-by: Zachary Amsden Signed-off-by: Andi Kleen Signed-off-by: Andrew Morton --- arch/i386/Kconfig.debug | 10 ++ arch/i386/kernel/alternative.c | 63 ++++++++++--- arch/i386/kernel/entry.S | 39 +++++--- arch/i386/kernel/module.c | 11 ++- arch/i386/kernel/paravirt.c | 44 +++++++++ arch/i386/kernel/vmlinux.lds.S | 6 ++ include/asm-i386/alternative.h | 13 ++- include/asm-i386/desc.h | 41 ++++---- include/asm-i386/irqflags.h | 4 +- include/asm-i386/paravirt.h | 189 ++++++++++++++++++++++++++++++------- include/asm-i386/processor.h | 198 +++++++++++++++++++-------------------- include/asm-i386/spinlock.h | 15 ++- include/asm-x86_64/alternative.h | 12 +++ scripts/mod/modpost.c | 2 + 14 files changed, 459 insertions(+), 188 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug index b31c0802e1cc..f68cc6f215f8 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/i386/Kconfig.debug @@ -85,4 +85,14 @@ config DOUBLEFAULT option saves about 4k and might cause you much additional grey hair. +config DEBUG_PARAVIRT + bool "Enable some paravirtualization debugging" + default y + depends on PARAVIRT && DEBUG_KERNEL + help + Currently deliberately clobbers regs which are allowed to be + clobbered in inlined paravirt hooks, even in native mode. + If turning this off solves a problem, then DISABLE_INTERRUPTS() or + ENABLE_INTERRUPTS() is lying about what registers can be clobbered. + endmenu diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c index 535f9794fba1..9eca21b49f6b 100644 --- a/arch/i386/kernel/alternative.c +++ b/arch/i386/kernel/alternative.c @@ -124,6 +124,20 @@ static unsigned char** find_nop_table(void) #endif /* CONFIG_X86_64 */ +static void nop_out(void *insns, unsigned int len) +{ + unsigned char **noptable = find_nop_table(); + + while (len > 0) { + unsigned int noplen = len; + if (noplen > ASM_NOP_MAX) + noplen = ASM_NOP_MAX; + memcpy(insns, noptable[noplen], noplen); + insns += noplen; + len -= noplen; + } +} + extern struct alt_instr __alt_instructions[], __alt_instructions_end[]; extern struct alt_instr __smp_alt_instructions[], __smp_alt_instructions_end[]; extern u8 *__smp_locks[], *__smp_locks_end[]; @@ -138,10 +152,9 @@ extern u8 __smp_alt_begin[], __smp_alt_end[]; void apply_alternatives(struct alt_instr *start, struct alt_instr *end) { - unsigned char **noptable = find_nop_table(); struct alt_instr *a; u8 *instr; - int diff, i, k; + int diff; DPRINTK("%s: alt table %p -> %p\n", __FUNCTION__, start, end); for (a = start; a < end; a++) { @@ -159,13 +172,7 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end) #endif memcpy(instr, a->replacement, a->replacementlen); diff = a->instrlen - a->replacementlen; - /* Pad the rest with nops */ - for (i = a->replacementlen; diff > 0; diff -= k, i += k) { - k = diff; - if (k > ASM_NOP_MAX) - k = ASM_NOP_MAX; - memcpy(a->instr + i, noptable[k], k); - } + nop_out(instr + a->replacementlen, diff); } } @@ -209,7 +216,6 @@ static void alternatives_smp_lock(u8 **start, u8 **end, u8 *text, u8 *text_end) static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end) { - unsigned char **noptable = find_nop_table(); u8 **ptr; for (ptr = start; ptr < end; ptr++) { @@ -217,7 +223,7 @@ static void alternatives_smp_unlock(u8 **start, u8 **end, u8 *text, u8 *text_end continue; if (*ptr > text_end) continue; - **ptr = noptable[1][0]; + nop_out(*ptr, 1); }; } @@ -343,6 +349,40 @@ void alternatives_smp_switch(int smp) #endif +#ifdef CONFIG_PARAVIRT +void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) +{ + struct paravirt_patch *p; + + for (p = start; p < end; p++) { + unsigned int used; + + used = paravirt_ops.patch(p->instrtype, p->clobbers, p->instr, + p->len); +#ifdef CONFIG_DEBUG_PARAVIRT + { + int i; + /* Deliberately clobber regs using "not %reg" to find bugs. */ + for (i = 0; i < 3; i++) { + if (p->len - used >= 2 && (p->clobbers & (1 << i))) { + memcpy(p->instr + used, "\xf7\xd0", 2); + p->instr[used+1] |= i; + used += 2; + } + } + } +#endif + /* Pad the rest with nops */ + nop_out(p->instr + used, p->len - used); + } + + /* Sync to be conservative, in case we patched following instructions */ + sync_core(); +} +extern struct paravirt_patch __start_parainstructions[], + __stop_parainstructions[]; +#endif /* CONFIG_PARAVIRT */ + void __init alternative_instructions(void) { unsigned long flags; @@ -390,5 +430,6 @@ void __init alternative_instructions(void) alternatives_smp_switch(0); } #endif + apply_paravirt(__start_parainstructions, __stop_parainstructions); local_irq_restore(flags); } diff --git a/arch/i386/kernel/entry.S b/arch/i386/kernel/entry.S index d274612e05cd..de34b7fed3c1 100644 --- a/arch/i386/kernel/entry.S +++ b/arch/i386/kernel/entry.S @@ -53,6 +53,19 @@ #include #include "irq_vectors.h" +/* + * We use macros for low-level operations which need to be overridden + * for paravirtualization. The following will never clobber any registers: + * INTERRUPT_RETURN (aka. "iret") + * GET_CR0_INTO_EAX (aka. "movl %cr0, %eax") + * ENABLE_INTERRUPTS_SYSEXIT (aka "sti; sysexit"). + * + * For DISABLE_INTERRUPTS/ENABLE_INTERRUPTS (aka "cli"/"sti"), you must + * specify what registers can be overwritten (CLBR_NONE, CLBR_EAX/EDX/ECX/ANY). + * Allowing a register to be clobbered can shrink the paravirt replacement + * enough to patch inline, increasing performance. + */ + #define nr_syscalls ((syscall_table_size)/4) CF_MASK = 0x00000001 @@ -63,9 +76,9 @@ NT_MASK = 0x00004000 VM_MASK = 0x00020000 #ifdef CONFIG_PREEMPT -#define preempt_stop DISABLE_INTERRUPTS; TRACE_IRQS_OFF +#define preempt_stop(clobbers) DISABLE_INTERRUPTS(clobbers); TRACE_IRQS_OFF #else -#define preempt_stop +#define preempt_stop(clobbers) #define resume_kernel restore_nocheck #endif @@ -226,7 +239,7 @@ ENTRY(ret_from_fork) ALIGN RING0_PTREGS_FRAME ret_from_exception: - preempt_stop + preempt_stop(CLBR_ANY) ret_from_intr: GET_THREAD_INFO(%ebp) check_userspace: @@ -237,7 +250,7 @@ check_userspace: jb resume_kernel # not returning to v8086 or userspace ENTRY(resume_userspace) - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx @@ -248,7 +261,7 @@ ENTRY(resume_userspace) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) - DISABLE_INTERRUPTS + DISABLE_INTERRUPTS(CLBR_ANY) cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_nocheck need_resched: @@ -277,7 +290,7 @@ sysenter_past_esp: * No need to follow this irqs on/off section: the syscall * disabled irqs and here we enable it straight after entry: */ - ENABLE_INTERRUPTS + ENABLE_INTERRUPTS(CLBR_NONE) pushl $(__USER_DS) CFI_ADJUST_CFA_OFFSET 4 /*CFI_REL_OFFSET ss, 0*/ @@ -322,7 +335,7 @@ sysenter_past_esp: jae syscall_badsys call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) - DISABLE_INTERRUPTS + DISABLE_INTERRUPTS(CLBR_ECX|CLBR_EDX) TRACE_IRQS_OFF movl TI_flags(%ebp), %ecx testw $_TIF_ALLWORK_MASK, %cx @@ -364,7 +377,7 @@ syscall_call: call *sys_call_table(,%eax,4) movl %eax,PT_EAX(%esp) # store the return value syscall_exit: - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -393,7 +406,7 @@ restore_nocheck_notrace: .section .fixup,"ax" iret_exc: TRACE_IRQS_ON - ENABLE_INTERRUPTS + ENABLE_INTERRUPTS(CLBR_NONE) pushl $0 # no error code pushl $do_iret_error jmp error_code @@ -436,7 +449,7 @@ ldt_ss: CFI_ADJUST_CFA_OFFSET 4 pushl %eax CFI_ADJUST_CFA_OFFSET 4 - DISABLE_INTERRUPTS + DISABLE_INTERRUPTS(CLBR_EAX) TRACE_IRQS_OFF lss (%esp), %esp CFI_ADJUST_CFA_OFFSET -8 @@ -451,7 +464,7 @@ work_pending: jz work_notifysig work_resched: call schedule - DISABLE_INTERRUPTS # make sure we don't miss an interrupt + DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret TRACE_IRQS_OFF @@ -509,7 +522,7 @@ syscall_exit_work: testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl jz work_pending TRACE_IRQS_ON - ENABLE_INTERRUPTS # could let do_syscall_trace() call + ENABLE_INTERRUPTS(CLBR_ANY) # could let do_syscall_trace() call # schedule() instead movl %esp, %eax movl $1, %edx @@ -693,7 +706,7 @@ ENTRY(device_not_available) GET_CR0_INTO_EAX testl $0x4, %eax # EM (math emulation bit) jne device_not_available_emulate - preempt_stop + preempt_stop(CLBR_ANY) call math_state_restore jmp ret_from_exception device_not_available_emulate: diff --git a/arch/i386/kernel/module.c b/arch/i386/kernel/module.c index 470cf97e7cd3..d7d9c8b23f72 100644 --- a/arch/i386/kernel/module.c +++ b/arch/i386/kernel/module.c @@ -108,7 +108,8 @@ int module_finalize(const Elf_Ehdr *hdr, const Elf_Shdr *sechdrs, struct module *me) { - const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL; + const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL, + *para = NULL; char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) { @@ -118,6 +119,8 @@ int module_finalize(const Elf_Ehdr *hdr, alt = s; if (!strcmp(".smp_locks", secstrings + s->sh_name)) locks= s; + if (!strcmp(".parainstructions", secstrings + s->sh_name)) + para = s; } if (alt) { @@ -132,6 +135,12 @@ int module_finalize(const Elf_Ehdr *hdr, lseg, lseg + locks->sh_size, tseg, tseg + text->sh_size); } + + if (para) { + void *pseg = (void *)para->sh_addr; + apply_paravirt(pseg, pseg + para->sh_size); + } + return 0; } diff --git a/arch/i386/kernel/paravirt.c b/arch/i386/kernel/paravirt.c index 478192cd4b90..d46460426446 100644 --- a/arch/i386/kernel/paravirt.c +++ b/arch/i386/kernel/paravirt.c @@ -45,6 +45,49 @@ char *memory_setup(void) return paravirt_ops.memory_setup(); } +/* Simple instruction patching code. */ +#define DEF_NATIVE(name, code) \ + extern const char start_##name[], end_##name[]; \ + asm("start_" #name ": " code "; end_" #name ":") +DEF_NATIVE(cli, "cli"); +DEF_NATIVE(sti, "sti"); +DEF_NATIVE(popf, "push %eax; popf"); +DEF_NATIVE(pushf, "pushf; pop %eax"); +DEF_NATIVE(pushf_cli, "pushf; pop %eax; cli"); +DEF_NATIVE(iret, "iret"); +DEF_NATIVE(sti_sysexit, "sti; sysexit"); + +static const struct native_insns +{ + const char *start, *end; +} native_insns[] = { + [PARAVIRT_IRQ_DISABLE] = { start_cli, end_cli }, + [PARAVIRT_IRQ_ENABLE] = { start_sti, end_sti }, + [PARAVIRT_RESTORE_FLAGS] = { start_popf, end_popf }, + [PARAVIRT_SAVE_FLAGS] = { start_pushf, end_pushf }, + [PARAVIRT_SAVE_FLAGS_IRQ_DISABLE] = { start_pushf_cli, end_pushf_cli }, + [PARAVIRT_INTERRUPT_RETURN] = { start_iret, end_iret }, + [PARAVIRT_STI_SYSEXIT] = { start_sti_sysexit, end_sti_sysexit }, +}; + +static unsigned native_patch(u8 type, u16 clobbers, void *insns, unsigned len) +{ + unsigned int insn_len; + + /* Don't touch it if we don't have a replacement */ + if (type >= ARRAY_SIZE(native_insns) || !native_insns[type].start) + return len; + + insn_len = native_insns[type].end - native_insns[type].start; + + /* Similarly if we can't fit replacement. */ + if (len < insn_len) + return len; + + memcpy(insns, native_insns[type].start, insn_len); + return insn_len; +} + static fastcall unsigned long native_get_debugreg(int regno) { unsigned long val = 0; /* Damn you, gcc! */ @@ -349,6 +392,7 @@ struct paravirt_ops paravirt_ops = { .paravirt_enabled = 0, .kernel_rpl = 0, + .patch = native_patch, .banner = default_banner, .arch_setup = native_nop, .memory_setup = machine_specific_memory_setup, diff --git a/arch/i386/kernel/vmlinux.lds.S b/arch/i386/kernel/vmlinux.lds.S index 6860f20aa579..5c69cf0e5944 100644 --- a/arch/i386/kernel/vmlinux.lds.S +++ b/arch/i386/kernel/vmlinux.lds.S @@ -165,6 +165,12 @@ SECTIONS .altinstr_replacement : AT(ADDR(.altinstr_replacement) - LOAD_OFFSET) { *(.altinstr_replacement) } + . = ALIGN(4); + __start_parainstructions = .; + .parainstructions : AT(ADDR(.parainstructions) - LOAD_OFFSET) { + *(.parainstructions) + } + __stop_parainstructions = .; /* .exit.text is discard at runtime, not link time, to deal with references from .altinstructions and .eh_frame */ .exit.text : AT(ADDR(.exit.text) - LOAD_OFFSET) { *(.exit.text) } diff --git a/include/asm-i386/alternative.h b/include/asm-i386/alternative.h index b01a7ec409ce..b8fa9557c532 100644 --- a/include/asm-i386/alternative.h +++ b/include/asm-i386/alternative.h @@ -4,7 +4,7 @@ #ifdef __KERNEL__ #include - +#include #include struct alt_instr { @@ -118,4 +118,15 @@ static inline void alternatives_smp_switch(int smp) {} #define LOCK_PREFIX "" #endif +struct paravirt_patch; +#ifdef CONFIG_PARAVIRT +void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end); +#else +static inline void +apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) +{} +#define __start_parainstructions NULL +#define __stop_parainstructions NULL +#endif + #endif /* _I386_ALTERNATIVE_H */ diff --git a/include/asm-i386/desc.h b/include/asm-i386/desc.h index f19820f0834f..f398cc456448 100644 --- a/include/asm-i386/desc.h +++ b/include/asm-i386/desc.h @@ -81,31 +81,15 @@ static inline void load_TLS(struct thread_struct *t, unsigned int cpu) #undef C } -static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b) -{ - __u32 *lp = (__u32 *)((char *)dt + entry*8); - *lp = entry_a; - *(lp+1) = entry_b; -} - #define write_ldt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) #define write_gdt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) #define write_idt_entry(dt, entry, a, b) write_dt_entry(dt, entry, a, b) -static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) -{ - __u32 a, b; - pack_gate(&a, &b, (unsigned long)addr, seg, type, 0); - write_idt_entry(idt_table, gate, a, b); -} - -static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) +static inline void write_dt_entry(void *dt, int entry, __u32 entry_a, __u32 entry_b) { - __u32 a, b; - pack_descriptor(&a, &b, (unsigned long)addr, - offsetof(struct tss_struct, __cacheline_filler) - 1, - DESCTYPE_TSS, 0); - write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); + __u32 *lp = (__u32 *)((char *)dt + entry*8); + *lp = entry_a; + *(lp+1) = entry_b; } #define set_ldt native_set_ldt @@ -128,6 +112,23 @@ static inline fastcall void native_set_ldt(const void *addr, } } +static inline void _set_gate(int gate, unsigned int type, void *addr, unsigned short seg) +{ + __u32 a, b; + pack_gate(&a, &b, (unsigned long)addr, seg, type, 0); + write_idt_entry(idt_table, gate, a, b); +} + +static inline void __set_tss_desc(unsigned int cpu, unsigned int entry, const void *addr) +{ + __u32 a, b; + pack_descriptor(&a, &b, (unsigned long)addr, + offsetof(struct tss_struct, __cacheline_filler) - 1, + DESCTYPE_TSS, 0); + write_gdt_entry(get_cpu_gdt_table(cpu), entry, a, b); +} + + #define set_tss_desc(cpu,addr) __set_tss_desc(cpu, GDT_ENTRY_TSS, addr) #define LDT_entry_a(info) \ diff --git a/include/asm-i386/irqflags.h b/include/asm-i386/irqflags.h index 9ce01f3fb7bc..17b18cf4fe9d 100644 --- a/include/asm-i386/irqflags.h +++ b/include/asm-i386/irqflags.h @@ -79,8 +79,8 @@ static inline unsigned long __raw_local_irq_save(void) } #else -#define DISABLE_INTERRUPTS cli -#define ENABLE_INTERRUPTS sti +#define DISABLE_INTERRUPTS(clobbers) cli +#define ENABLE_INTERRUPTS(clobbers) sti #define ENABLE_INTERRUPTS_SYSEXIT sti; sysexit #define INTERRUPT_RETURN iret #define GET_CR0_INTO_EAX movl %cr0, %eax diff --git a/include/asm-i386/paravirt.h b/include/asm-i386/paravirt.h index a7551a44686f..081194751ade 100644 --- a/include/asm-i386/paravirt.h +++ b/include/asm-i386/paravirt.h @@ -3,8 +3,26 @@ /* Various instructions on x86 need to be replaced for * para-virtualization: those hooks are defined here. */ #include +#include #ifdef CONFIG_PARAVIRT +/* These are the most performance critical ops, so we want to be able to patch + * callers */ +#define PARAVIRT_IRQ_DISABLE 0 +#define PARAVIRT_IRQ_ENABLE 1 +#define PARAVIRT_RESTORE_FLAGS 2 +#define PARAVIRT_SAVE_FLAGS 3 +#define PARAVIRT_SAVE_FLAGS_IRQ_DISABLE 4 +#define PARAVIRT_INTERRUPT_RETURN 5 +#define PARAVIRT_STI_SYSEXIT 6 + +/* Bitmask of what can be clobbered: usually at least eax. */ +#define CLBR_NONE 0x0 +#define CLBR_EAX 0x1 +#define CLBR_ECX 0x2 +#define CLBR_EDX 0x4 +#define CLBR_ANY 0x7 + #ifndef __ASSEMBLY__ struct thread_struct; struct Xgt_desc_struct; @@ -15,6 +33,15 @@ struct paravirt_ops int paravirt_enabled; const char *name; + /* + * Patch may replace one of the defined code sequences with arbitrary + * code, subject to the same register constraints. This generally + * means the code is not free to clobber any registers other than EAX. + * The patch function should return the number of bytes of code + * generated, as we nop pad the rest in generic code. + */ + unsigned (*patch)(u8 type, u16 clobber, void *firstinsn, unsigned len); + void (*arch_setup)(void); char *(*memory_setup)(void); void (*init_IRQ)(void); @@ -147,35 +174,6 @@ static inline void __cpuid(unsigned int *eax, unsigned int *ebx, #define read_cr4_safe(x) paravirt_ops.read_cr4_safe() #define write_cr4(x) paravirt_ops.write_cr4(x) -static inline unsigned long __raw_local_save_flags(void) -{ - return paravirt_ops.save_fl(); -} - -static inline void raw_local_irq_restore(unsigned long flags) -{ - return paravirt_ops.restore_fl(flags); -} - -static inline void raw_local_irq_disable(void) -{ - paravirt_ops.irq_disable(); -} - -static inline void raw_local_irq_enable(void) -{ - paravirt_ops.irq_enable(); -} - -static inline unsigned long __raw_local_irq_save(void) -{ - unsigned long flags = paravirt_ops.save_fl(); - - paravirt_ops.irq_disable(); - - return flags; -} - static inline void raw_safe_halt(void) { paravirt_ops.safe_halt(); @@ -267,15 +265,134 @@ static inline void slow_down_io(void) { #endif } -#define CLI_STRING "pushl %eax; pushl %ecx; pushl %edx; call *paravirt_ops+PARAVIRT_irq_disable; popl %edx; popl %ecx; popl %eax" -#define STI_STRING "pushl %eax; pushl %ecx; pushl %edx; call *paravirt_ops+PARAVIRT_irq_enable; popl %edx; popl %ecx; popl %eax" +/* These all sit in the .parainstructions section to tell us what to patch. */ +struct paravirt_patch { + u8 *instr; /* original instructions */ + u8 instrtype; /* type of this instruction */ + u8 len; /* length of original instruction */ + u16 clobbers; /* what registers you may clobber */ +}; + +#define paravirt_alt(insn_string, typenum, clobber) \ + "771:\n\t" insn_string "\n" "772:\n" \ + ".pushsection .parainstructions,\"a\"\n" \ + " .long 771b\n" \ + " .byte " __stringify(typenum) "\n" \ + " .byte 772b-771b\n" \ + " .short " __stringify(clobber) "\n" \ + ".popsection" + +static inline unsigned long __raw_local_save_flags(void) +{ + unsigned long f; + + __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" + "call *%1;" + "popl %%edx; popl %%ecx", + PARAVIRT_SAVE_FLAGS, CLBR_NONE) + : "=a"(f): "m"(paravirt_ops.save_fl) + : "memory", "cc"); + return f; +} + +static inline void raw_local_irq_restore(unsigned long f) +{ + __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" + "call *%1;" + "popl %%edx; popl %%ecx", + PARAVIRT_RESTORE_FLAGS, CLBR_EAX) + : "=a"(f) : "m" (paravirt_ops.restore_fl), "0"(f) + : "memory", "cc"); +} + +static inline void raw_local_irq_disable(void) +{ + __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" + "call *%0;" + "popl %%edx; popl %%ecx", + PARAVIRT_IRQ_DISABLE, CLBR_EAX) + : : "m" (paravirt_ops.irq_disable) + : "memory", "eax", "cc"); +} + +static inline void raw_local_irq_enable(void) +{ + __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" + "call *%0;" + "popl %%edx; popl %%ecx", + PARAVIRT_IRQ_ENABLE, CLBR_EAX) + : : "m" (paravirt_ops.irq_enable) + : "memory", "eax", "cc"); +} + +static inline unsigned long __raw_local_irq_save(void) +{ + unsigned long f; + + __asm__ __volatile__(paravirt_alt( "pushl %%ecx; pushl %%edx;" + "call *%1; pushl %%eax;" + "call *%2; popl %%eax;" + "popl %%edx; popl %%ecx", + PARAVIRT_SAVE_FLAGS_IRQ_DISABLE, + CLBR_NONE) + : "=a"(f) + : "m" (paravirt_ops.save_fl), + "m" (paravirt_ops.irq_disable) + : "memory", "cc"); + return f; +} + +#define CLI_STRING paravirt_alt("pushl %%ecx; pushl %%edx;" \ + "call *paravirt_ops+%c[irq_disable];" \ + "popl %%edx; popl %%ecx", \ + PARAVIRT_IRQ_DISABLE, CLBR_EAX) + +#define STI_STRING paravirt_alt("pushl %%ecx; pushl %%edx;" \ + "call *paravirt_ops+%c[irq_enable];" \ + "popl %%edx; popl %%ecx", \ + PARAVIRT_IRQ_ENABLE, CLBR_EAX) +#define CLI_STI_CLOBBERS , "%eax" +#define CLI_STI_INPUT_ARGS \ + , \ + [irq_disable] "i" (offsetof(struct paravirt_ops, irq_disable)), \ + [irq_enable] "i" (offsetof(struct paravirt_ops, irq_enable)) + #else /* __ASSEMBLY__ */ -#define INTERRUPT_RETURN jmp *%cs:paravirt_ops+PARAVIRT_iret -#define DISABLE_INTERRUPTS pushl %eax; pushl %ecx; pushl %edx; call *paravirt_ops+PARAVIRT_irq_disable; popl %edx; popl %ecx; popl %eax -#define ENABLE_INTERRUPTS pushl %eax; pushl %ecx; pushl %edx; call *%cs:paravirt_ops+PARAVIRT_irq_enable; popl %edx; popl %ecx; popl %eax -#define ENABLE_INTERRUPTS_SYSEXIT jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit -#define GET_CR0_INTO_EAX call *paravirt_ops+PARAVIRT_read_cr0 +#define PARA_PATCH(ptype, clobbers, ops) \ +771:; \ + ops; \ +772:; \ + .pushsection .parainstructions,"a"; \ + .long 771b; \ + .byte ptype; \ + .byte 772b-771b; \ + .short clobbers; \ + .popsection + +#define INTERRUPT_RETURN \ + PARA_PATCH(PARAVIRT_INTERRUPT_RETURN, CLBR_ANY, \ + jmp *%cs:paravirt_ops+PARAVIRT_iret) + +#define DISABLE_INTERRUPTS(clobbers) \ + PARA_PATCH(PARAVIRT_IRQ_DISABLE, clobbers, \ + pushl %ecx; pushl %edx; \ + call *paravirt_ops+PARAVIRT_irq_disable; \ + popl %edx; popl %ecx) \ + +#define ENABLE_INTERRUPTS(clobbers) \ + PARA_PATCH(PARAVIRT_IRQ_ENABLE, clobbers, \ + pushl %ecx; pushl %edx; \ + call *%cs:paravirt_ops+PARAVIRT_irq_enable; \ + popl %edx; popl %ecx) + +#define ENABLE_INTERRUPTS_SYSEXIT \ + PARA_PATCH(PARAVIRT_STI_SYSEXIT, CLBR_ANY, \ + jmp *%cs:paravirt_ops+PARAVIRT_irq_enable_sysexit) + +#define GET_CR0_INTO_EAX \ + call *paravirt_ops+PARAVIRT_read_cr0 + #endif /* __ASSEMBLY__ */ #endif /* CONFIG_PARAVIRT */ #endif /* __ASM_PARAVIRT_H */ diff --git a/include/asm-i386/processor.h b/include/asm-i386/processor.h index 6c2c4457be0a..5f0418d0078c 100644 --- a/include/asm-i386/processor.h +++ b/include/asm-i386/processor.h @@ -156,59 +156,6 @@ static inline fastcall void native_cpuid(unsigned int *eax, unsigned int *ebx, : "0" (*eax), "2" (*ecx)); } -/* - * Generic CPUID function - * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx - * resulting in stale register contents being returned. - */ -static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) -{ - *eax = op; - *ecx = 0; - __cpuid(eax, ebx, ecx, edx); -} - -/* Some CPUID calls want 'count' to be placed in ecx */ -static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, - int *edx) -{ - *eax = op; - *ecx = count; - __cpuid(eax, ebx, ecx, edx); -} - -/* - * CPUID functions returning a single datum - */ -static inline unsigned int cpuid_eax(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return eax; -} -static inline unsigned int cpuid_ebx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return ebx; -} -static inline unsigned int cpuid_ecx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return ecx; -} -static inline unsigned int cpuid_edx(unsigned int op) -{ - unsigned int eax, ebx, ecx, edx; - - cpuid(op, &eax, &ebx, &ecx, &edx); - return edx; -} - #define load_cr3(pgdir) write_cr3(__pa(pgdir)) /* @@ -491,22 +438,6 @@ struct thread_struct { .io_bitmap = { [ 0 ... IO_BITMAP_LONGS] = ~0 }, \ } -#ifdef CONFIG_PARAVIRT -#include -#else -#define paravirt_enabled() 0 -#define __cpuid native_cpuid - -static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) -{ - tss->esp0 = thread->esp0; - /* This can only happen when SEP is enabled, no need to test "SEP"arately */ - if (unlikely(tss->ss1 != thread->sysenter_cs)) { - tss->ss1 = thread->sysenter_cs; - wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); - } -} - #define start_thread(regs, new_eip, new_esp) do { \ __asm__("movl %0,%%fs": :"r" (0)); \ regs->xgs = 0; \ @@ -519,36 +450,6 @@ static inline void load_esp0(struct tss_struct *tss, struct thread_struct *threa regs->esp = new_esp; \ } while (0) -/* - * These special macros can be used to get or set a debugging register - */ -#define get_debugreg(var, register) \ - __asm__("movl %%db" #register ", %0" \ - :"=r" (var)) -#define set_debugreg(value, register) \ - __asm__("movl %0,%%db" #register \ - : /* no output */ \ - :"r" (value)) - -#define set_iopl_mask native_set_iopl_mask -#endif /* CONFIG_PARAVIRT */ - -/* - * Set IOPL bits in EFLAGS from given mask - */ -static fastcall inline void native_set_iopl_mask(unsigned mask) -{ - unsigned int reg; - __asm__ __volatile__ ("pushfl;" - "popl %0;" - "andl %1, %0;" - "orl %2, %0;" - "pushl %0;" - "popfl" - : "=&r" (reg) - : "i" (~X86_EFLAGS_IOPL), "r" (mask)); -} - /* Forward declaration, a strange C thing */ struct task_struct; struct mm_struct; @@ -640,6 +541,105 @@ static inline void rep_nop(void) #define cpu_relax() rep_nop() +#ifdef CONFIG_PARAVIRT +#include +#else +#define paravirt_enabled() 0 +#define __cpuid native_cpuid + +static inline void load_esp0(struct tss_struct *tss, struct thread_struct *thread) +{ + tss->esp0 = thread->esp0; + /* This can only happen when SEP is enabled, no need to test "SEP"arately */ + if (unlikely(tss->ss1 != thread->sysenter_cs)) { + tss->ss1 = thread->sysenter_cs; + wrmsr(MSR_IA32_SYSENTER_CS, thread->sysenter_cs, 0); + } +} + +/* + * These special macros can be used to get or set a debugging register + */ +#define get_debugreg(var, register) \ + __asm__("movl %%db" #register ", %0" \ + :"=r" (var)) +#define set_debugreg(value, register) \ + __asm__("movl %0,%%db" #register \ + : /* no output */ \ + :"r" (value)) + +#define set_iopl_mask native_set_iopl_mask +#endif /* CONFIG_PARAVIRT */ + +/* + * Set IOPL bits in EFLAGS from given mask + */ +static fastcall inline void native_set_iopl_mask(unsigned mask) +{ + unsigned int reg; + __asm__ __volatile__ ("pushfl;" + "popl %0;" + "andl %1, %0;" + "orl %2, %0;" + "pushl %0;" + "popfl" + : "=&r" (reg) + : "i" (~X86_EFLAGS_IOPL), "r" (mask)); +} + +/* + * Generic CPUID function + * clear %ecx since some cpus (Cyrix MII) do not set or clear %ecx + * resulting in stale register contents being returned. + */ +static inline void cpuid(unsigned int op, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) +{ + *eax = op; + *ecx = 0; + __cpuid(eax, ebx, ecx, edx); +} + +/* Some CPUID calls want 'count' to be placed in ecx */ +static inline void cpuid_count(int op, int count, int *eax, int *ebx, int *ecx, + int *edx) +{ + *eax = op; + *ecx = count; + __cpuid(eax, ebx, ecx, edx); +} + +/* + * CPUID functions returning a single datum + */ +static inline unsigned int cpuid_eax(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return eax; +} +static inline unsigned int cpuid_ebx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return ebx; +} +static inline unsigned int cpuid_ecx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return ecx; +} +static inline unsigned int cpuid_edx(unsigned int op) +{ + unsigned int eax, ebx, ecx, edx; + + cpuid(op, &eax, &ebx, &ecx, &edx); + return edx; +} + /* generic versions from gas */ #define GENERIC_NOP1 ".byte 0x90\n" #define GENERIC_NOP2 ".byte 0x89,0xf6\n" diff --git a/include/asm-i386/spinlock.h b/include/asm-i386/spinlock.h index dea60709db29..d3bcebed60ca 100644 --- a/include/asm-i386/spinlock.h +++ b/include/asm-i386/spinlock.h @@ -12,6 +12,8 @@ #else #define CLI_STRING "cli" #define STI_STRING "sti" +#define CLI_STI_CLOBBERS +#define CLI_STI_INPUT_ARGS #endif /* CONFIG_PARAVIRT */ /* @@ -57,25 +59,28 @@ static inline void __raw_spin_lock_flags(raw_spinlock_t *lock, unsigned long fla { asm volatile( "\n1:\t" - LOCK_PREFIX " ; decb %0\n\t" + LOCK_PREFIX " ; decb %[slock]\n\t" "jns 5f\n" "2:\t" - "testl $0x200, %1\n\t" + "testl $0x200, %[flags]\n\t" "jz 4f\n\t" STI_STRING "\n" "3:\t" "rep;nop\n\t" - "cmpb $0, %0\n\t" + "cmpb $0, %[slock]\n\t" "jle 3b\n\t" CLI_STRING "\n\t" "jmp 1b\n" "4:\t" "rep;nop\n\t" - "cmpb $0, %0\n\t" + "cmpb $0, %[slock]\n\t" "jg 1b\n\t" "jmp 4b\n" "5:\n\t" - : "+m" (lock->slock) : "r" (flags) : "memory"); + : [slock] "+m" (lock->slock) + : [flags] "r" (flags) + CLI_STI_INPUT_ARGS + : "memory" CLI_STI_CLOBBERS); } #endif diff --git a/include/asm-x86_64/alternative.h b/include/asm-x86_64/alternative.h index a584826cc570..a6657b4f3e0e 100644 --- a/include/asm-x86_64/alternative.h +++ b/include/asm-x86_64/alternative.h @@ -4,6 +4,7 @@ #ifdef __KERNEL__ #include +#include #include struct alt_instr { @@ -133,4 +134,15 @@ static inline void alternatives_smp_switch(int smp) {} #define LOCK_PREFIX "" #endif +struct paravirt_patch; +#ifdef CONFIG_PARAVIRT +void apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end); +#else +static inline void +apply_paravirt(struct paravirt_patch *start, struct paravirt_patch *end) +{} +#define __start_parainstructions NULL +#define __stop_parainstructions NULL +#endif + #endif /* _X86_64_ALTERNATIVE_H */ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 2e1141623147..ac0a58222992 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -911,6 +911,7 @@ static int init_section_ref_ok(const char *name) ".toc1", /* used by ppc64 */ ".stab", ".rodata", + ".parainstructions", ".text.lock", "__bug_table", /* used by powerpc for BUG() */ ".pci_fixup_header", @@ -931,6 +932,7 @@ static int init_section_ref_ok(const char *name) ".altinstructions", ".eh_frame", ".debug", + ".parainstructions", NULL }; /* part of section name */ -- cgit v1.2.3 From 103efcd9aac1de4da6a1477f2f3b9fcf35273a18 Mon Sep 17 00:00:00 2001 From: Ernie Petrides Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] x86-64: fix perms/range of vsyscall vma in /proc/*/maps The final line of /proc//maps on x86_64 for native 64-bit tasks shows an incorrect ending address and incorrect permissions. There is only a single page mapped in this vsyscall region, and it is accessible for both read and execute. The patch below fixes this. (Since 32-bit-compat tasks have a real vma with correct perms/range, no change is necessary for that scenario.) Before the patch, a "cat /proc/self/maps | tail -1" shows this: ffffffffff600000-ffffffffffe00000 ---p 00000000 [...] After the patch, this is the output: ffffffffff600000-ffffffffff601000 r-xp 00000000 [...] Signed-off-by: Ernie Petrides Signed-off-by: Andi Kleen --- arch/x86_64/kernel/vsyscall.c | 1 + arch/x86_64/mm/init.c | 7 ++++--- include/asm-x86_64/vsyscall.h | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 92546c1526f1..c3de9a09cd9f 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -290,6 +290,7 @@ static void __init map_vsyscall(void) extern char __vsyscall_0; unsigned long physaddr_page0 = __pa_symbol(&__vsyscall_0); + /* Note that VSYSCALL_MAPPED_PAGES must agree with the code below. */ __set_fixmap(VSYSCALL_FIRST_PAGE, physaddr_page0, PAGE_KERNEL_VSYSCALL); } diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c index 4c0c00ef3ca7..2968b90ef8ad 100644 --- a/arch/x86_64/mm/init.c +++ b/arch/x86_64/mm/init.c @@ -730,14 +730,15 @@ static __init int x8664_sysctl_init(void) __initcall(x8664_sysctl_init); #endif -/* A pseudo VMAs to allow ptrace access for the vsyscall page. This only +/* A pseudo VMA to allow ptrace access for the vsyscall page. This only covers the 64bit vsyscall page now. 32bit has a real VMA now and does not need special handling anymore. */ static struct vm_area_struct gate_vma = { .vm_start = VSYSCALL_START, - .vm_end = VSYSCALL_END, - .vm_page_prot = PAGE_READONLY + .vm_end = VSYSCALL_START + (VSYSCALL_MAPPED_PAGES << PAGE_SHIFT), + .vm_page_prot = PAGE_READONLY_EXEC, + .vm_flags = VM_READ | VM_EXEC }; struct vm_area_struct *get_gate_vma(struct task_struct *tsk) diff --git a/include/asm-x86_64/vsyscall.h b/include/asm-x86_64/vsyscall.h index 01d1c17e2849..05cb8dd200de 100644 --- a/include/asm-x86_64/vsyscall.h +++ b/include/asm-x86_64/vsyscall.h @@ -10,6 +10,7 @@ enum vsyscall_num { #define VSYSCALL_START (-10UL << 20) #define VSYSCALL_SIZE 1024 #define VSYSCALL_END (-2UL << 20) +#define VSYSCALL_MAPPED_PAGES 1 #define VSYSCALL_ADDR(vsyscall_nr) (VSYSCALL_START+VSYSCALL_SIZE*(vsyscall_nr)) #ifdef __KERNEL__ -- cgit v1.2.3 From 4a1c42275078f48b90428cdb062f5220d79ec9da Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] x86-64: remove prototype of free_bootmem_generic() The function doesn't exist (anymore). Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- include/asm-x86_64/proto.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index e72cfcdf5344..21fa5afa232e 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -61,7 +61,6 @@ extern void numa_initmem_init(unsigned long start_pfn, unsigned long end_pfn); extern unsigned long numa_free_all_bootmem(void); extern void reserve_bootmem_generic(unsigned long phys, unsigned len); -extern void free_bootmem_generic(unsigned long phys, unsigned len); extern void load_gs_index(unsigned gs); -- cgit v1.2.3 From eab724e5df17af0ed0dac03da8f75aa336c31206 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:09 +0100 Subject: [PATCH] x86-64: adjust pmd_bad() Make pmd_bad() symmetrical to pgd_bad() and pud_bad(). At once, simplify them all. TBD: tighten down the checks again as suggested by Hugh D. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- include/asm-x86_64/pgtable.h | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/pgtable.h b/include/asm-x86_64/pgtable.h index 0555c1c4d8fa..59901c690a0d 100644 --- a/include/asm-x86_64/pgtable.h +++ b/include/asm-x86_64/pgtable.h @@ -221,20 +221,19 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long #define __S110 PAGE_SHARED_EXEC #define __S111 PAGE_SHARED_EXEC -static inline unsigned long pgd_bad(pgd_t pgd) -{ - unsigned long val = pgd_val(pgd); - val &= ~PTE_MASK; - val &= ~(_PAGE_USER | _PAGE_DIRTY); - return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED); -} +static inline unsigned long pgd_bad(pgd_t pgd) +{ + return pgd_val(pgd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); +} static inline unsigned long pud_bad(pud_t pud) { - unsigned long val = pud_val(pud); - val &= ~PTE_MASK; - val &= ~(_PAGE_USER | _PAGE_DIRTY); - return val & ~(_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED); + return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); +} + +static inline unsigned long pmd_bad(pmd_t pmd) +{ + return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); } #define pte_none(x) (!pte_val(x)) @@ -347,7 +346,6 @@ static inline int pmd_large(pmd_t pte) { #define pmd_none(x) (!pmd_val(x)) #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) #define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0) -#define pmd_bad(x) ((pmd_val(x) & (~PTE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE ) #define pfn_pmd(nr,prot) (__pmd(((nr) << PAGE_SHIFT) | pgprot_val(prot))) #define pmd_pfn(x) ((pmd_val(x) & __PHYSICAL_MASK) >> PAGE_SHIFT) -- cgit v1.2.3 From 274e1bbdeeaf16e71418f11f5f305ab26061f2c2 Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] x86: add write_pci_config_byte() to direct PCI access routines Mechanism of selecting physical mode in genapic when cpu hotplug is enabled on x86_64, broke the quirk(quirk_intel_irqbalance()) introduced for working around the transposing interrupt message errata in E7520/E7320/E7525 (revision ID 0x9 and below. errata #23 in http://download.intel.com/design/chipsets/specupdt/30304203.pdf). This errata requires the mode to be in logical flat, so that interrupts can be directed to more than one cpu(and thus use hardware IRQ balancing enabled by BIOS on these platforms). Following four patches fixes this by moving the quirk to early quirk and forcing the x86_64 genapic selection to logical flat on these platforms. Thanks to Shaohua for pointing out the breakage. This patch: Add write_pci_config_byte() to direct PCI access routines Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton --- arch/i386/pci/early.c | 7 +++++++ include/asm-x86_64/pci-direct.h | 1 + 2 files changed, 8 insertions(+) (limited to 'include/asm-x86_64') diff --git a/arch/i386/pci/early.c b/arch/i386/pci/early.c index 713d6c866cae..42df4b6606df 100644 --- a/arch/i386/pci/early.c +++ b/arch/i386/pci/early.c @@ -45,6 +45,13 @@ void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, outl(val, 0xcfc); } +void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val) +{ + PDprintk("%x writing to %x: %x\n", slot, offset, val); + outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8); + outb(val, 0xcfc); +} + int early_pci_allowed(void) { return (pci_probe & (PCI_PROBE_CONF1|PCI_PROBE_NOEARLY)) == diff --git a/include/asm-x86_64/pci-direct.h b/include/asm-x86_64/pci-direct.h index eba9cb471df3..6823fa4f1afa 100644 --- a/include/asm-x86_64/pci-direct.h +++ b/include/asm-x86_64/pci-direct.h @@ -10,6 +10,7 @@ extern u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset); extern u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset); extern u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset); extern void write_pci_config(u8 bus, u8 slot, u8 func, u8 offset, u32 val); +extern void write_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset, u8 val); extern int early_pci_allowed(void); -- cgit v1.2.3 From 9899f826fc90beba4f78083f6230e06cbe1050c9 Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] x86-64: add genapic_force Add genapic_force. Used by the next Intel quirks patch. Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton --- arch/x86_64/kernel/genapic.c | 9 ++++++++- include/asm-x86_64/genapic.h | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/genapic.c b/arch/x86_64/kernel/genapic.c index 8e78a75d1866..b007433f96bb 100644 --- a/arch/x86_64/kernel/genapic.c +++ b/arch/x86_64/kernel/genapic.c @@ -33,7 +33,7 @@ extern struct genapic apic_flat; extern struct genapic apic_physflat; struct genapic *genapic = &apic_flat; - +struct genapic *genapic_force; /* * Check the APIC IDs in bios_cpu_apicid and choose the APIC mode. @@ -46,6 +46,13 @@ void __init clustered_apic_check(void) u8 cluster_cnt[NUM_APIC_CLUSTERS]; int max_apic = 0; + /* genapic selection can be forced because of certain quirks. + */ + if (genapic_force) { + genapic = genapic_force; + goto print; + } + #if defined(CONFIG_ACPI) /* * Some x86_64 machines use physical APIC mode regardless of how many diff --git a/include/asm-x86_64/genapic.h b/include/asm-x86_64/genapic.h index a0e9a4b93484..b80f4bb5f273 100644 --- a/include/asm-x86_64/genapic.h +++ b/include/asm-x86_64/genapic.h @@ -30,6 +30,6 @@ struct genapic { }; -extern struct genapic *genapic; +extern struct genapic *genapic, *genapic_force, apic_flat; #endif -- cgit v1.2.3 From b0d0a4ba45760b10ecee9035ed45b442c1a6cc84 Mon Sep 17 00:00:00 2001 From: "Siddha, Suresh B" Date: Thu, 7 Dec 2006 02:14:10 +0100 Subject: [PATCH] x86: fix the irqbalance quirk for E7320/E7520/E7525 Move the irqbalance quirks for E7320/E7520/E7525(Errata 23 in http://download.intel.com/design/chipsets/specupdt/30304203.pdf) to early quirks. And add a PCI quirk for these platforms to check(which happens very late during the boot) if the APIC routing is indeed set to default flat mode. This fixes the breakage(in x86_64) of this quirk due to cpu hotplug which selects physical mode instead of the logical flat(as needed for this errata workaround). Signed-off-by: Suresh Siddha Signed-off-by: Andi Kleen Cc: Andi Kleen Cc: "Li, Shaohua" Signed-off-by: Andrew Morton --- arch/i386/kernel/acpi/earlyquirk.c | 21 +++++++++++++++++ arch/i386/kernel/quirks.c | 46 +++++++++++++++++++++++++++++--------- arch/i386/kernel/smpboot.c | 7 ++++++ arch/x86_64/kernel/early-quirks.c | 13 +++++++++++ arch/x86_64/kernel/smpboot.c | 8 +++++++ include/asm-i386/genapic.h | 2 +- include/asm-i386/irq.h | 2 ++ include/asm-x86_64/proto.h | 1 + 8 files changed, 88 insertions(+), 12 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/i386/kernel/acpi/earlyquirk.c b/arch/i386/kernel/acpi/earlyquirk.c index c9841692bb7c..4b60af7f91dd 100644 --- a/arch/i386/kernel/acpi/earlyquirk.c +++ b/arch/i386/kernel/acpi/earlyquirk.c @@ -10,6 +10,7 @@ #include #include #include +#include #ifdef CONFIG_ACPI @@ -49,6 +50,24 @@ static int __init check_bridge(int vendor, int device) return 0; } +static void check_intel(void) +{ + u16 vendor, device; + + vendor = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID); + + if (vendor != PCI_VENDOR_ID_INTEL) + return; + + device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); +#ifdef CONFIG_SMP + if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || + device == PCI_DEVICE_ID_INTEL_E7520_MCH || + device == PCI_DEVICE_ID_INTEL_E7525_MCH) + quirk_intel_irqbalance(); +#endif +} + void __init check_acpi_pci(void) { int num, slot, func; @@ -60,6 +79,8 @@ void __init check_acpi_pci(void) if (!early_pci_allowed()) return; + check_intel(); + /* Poor man's PCI discovery */ for (num = 0; num < 32; num++) { for (slot = 0; slot < 32; slot++) { diff --git a/arch/i386/kernel/quirks.c b/arch/i386/kernel/quirks.c index 9f6ab1789bb0..a01320a7b636 100644 --- a/arch/i386/kernel/quirks.c +++ b/arch/i386/kernel/quirks.c @@ -3,10 +3,23 @@ */ #include #include +#include +#include +#include #if defined(CONFIG_X86_IO_APIC) && defined(CONFIG_SMP) && defined(CONFIG_PCI) +static void __devinit verify_quirk_intel_irqbalance(struct pci_dev *dev) +{ +#ifdef CONFIG_X86_64 + if (genapic != &apic_flat) + panic("APIC mode must be flat on this system\n"); +#elif defined(CONFIG_X86_GENERICARCH) + if (genapic != &apic_default) + panic("APIC mode must be default(flat) on this system. Use apic=default\n"); +#endif +} -static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) +void __init quirk_intel_irqbalance(void) { u8 config, rev; u32 word; @@ -16,18 +29,18 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) * based platforms. * Disable SW irqbalance/affinity on those platforms. */ - pci_read_config_byte(dev, PCI_CLASS_REVISION, &rev); + rev = read_pci_config_byte(0, 0, 0, PCI_CLASS_REVISION); if (rev > 0x9) return; printk(KERN_INFO "Intel E7520/7320/7525 detected."); - /* enable access to config space*/ - pci_read_config_byte(dev, 0xf4, &config); - pci_write_config_byte(dev, 0xf4, config|0x2); + /* enable access to config space */ + config = read_pci_config_byte(0, 0, 0, 0xf4); + write_pci_config_byte(0, 0, 0, 0xf4, config|0x2); /* read xTPR register */ - raw_pci_ops->read(0, 0, 0x40, 0x4c, 2, &word); + word = read_pci_config_16(0, 0, 0x40, 0x4c); if (!(word & (1 << 13))) { printk(KERN_INFO "Disabling irq balancing and affinity\n"); @@ -37,14 +50,25 @@ static void __devinit quirk_intel_irqbalance(struct pci_dev *dev) noirqdebug_setup(""); #ifdef CONFIG_PROC_FS no_irq_affinity = 1; +#endif +#ifdef CONFIG_HOTPLUG_CPU + printk(KERN_INFO "Disabling cpu hotplug control\n"); + enable_cpu_hotplug = 0; +#endif +#ifdef CONFIG_X86_64 + /* force the genapic selection to flat mode so that + * interrupts can be redirected to more than one CPU. + */ + genapic_force = &apic_flat; #endif } - /* put back the original value for config space*/ + /* put back the original value for config space */ if (!(config & 0x2)) - pci_write_config_byte(dev, 0xf4, config); + write_pci_config_byte(0, 0, 0, 0xf4, config); } -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, quirk_intel_irqbalance); -DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7320_MCH, verify_quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7525_MCH, verify_quirk_intel_irqbalance); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_E7520_MCH, verify_quirk_intel_irqbalance); + #endif diff --git a/arch/i386/kernel/smpboot.c b/arch/i386/kernel/smpboot.c index cd7de9c9654b..346f27f4c79f 100644 --- a/arch/i386/kernel/smpboot.c +++ b/arch/i386/kernel/smpboot.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -1482,6 +1483,12 @@ int __devinit __cpu_up(unsigned int cpu) cpu_set(cpu, smp_commenced_mask); while (!cpu_isset(cpu, cpu_online_map)) cpu_relax(); + +#ifdef CONFIG_X86_GENERICARCH + if (num_online_cpus() > 8 && genapic == &apic_default) + panic("Default flat APIC routing can't be used with > 8 cpus\n"); +#endif + return 0; } diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c index fb0c6da41b7e..829698f6d049 100644 --- a/arch/x86_64/kernel/early-quirks.c +++ b/arch/x86_64/kernel/early-quirks.c @@ -71,6 +71,18 @@ static void ati_bugs(void) { } +static void intel_bugs(void) +{ + u16 device = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID); + +#ifdef CONFIG_SMP + if (device == PCI_DEVICE_ID_INTEL_E7320_MCH || + device == PCI_DEVICE_ID_INTEL_E7520_MCH || + device == PCI_DEVICE_ID_INTEL_E7525_MCH) + quirk_intel_irqbalance(); +#endif +} + struct chipset { u16 vendor; void (*f)(void); @@ -80,6 +92,7 @@ static struct chipset early_qrk[] = { { PCI_VENDOR_ID_NVIDIA, nvidia_bugs }, { PCI_VENDOR_ID_VIA, via_bugs }, { PCI_VENDOR_ID_ATI, ati_bugs }, + { PCI_VENDOR_ID_INTEL, intel_bugs}, {} }; diff --git a/arch/x86_64/kernel/smpboot.c b/arch/x86_64/kernel/smpboot.c index 62c2e747af58..4c161c208d5b 100644 --- a/arch/x86_64/kernel/smpboot.c +++ b/arch/x86_64/kernel/smpboot.c @@ -60,6 +60,7 @@ #include #include #include +#include /* Number of siblings per CPU package */ int smp_num_siblings = 1; @@ -1167,6 +1168,13 @@ int __cpuinit __cpu_up(unsigned int cpu) while (!cpu_isset(cpu, cpu_online_map)) cpu_relax(); + + if (num_online_cpus() > 8 && genapic == &apic_flat) { + printk(KERN_WARNING + "flat APIC routing can't be used with > 8 cpus\n"); + BUG(); + } + err = 0; return err; diff --git a/include/asm-i386/genapic.h b/include/asm-i386/genapic.h index 8ffbb0f07457..fd2be593b06e 100644 --- a/include/asm-i386/genapic.h +++ b/include/asm-i386/genapic.h @@ -122,6 +122,6 @@ struct genapic { APICFUNC(phys_pkg_id) \ } -extern struct genapic *genapic; +extern struct genapic *genapic, apic_default; #endif diff --git a/include/asm-i386/irq.h b/include/asm-i386/irq.h index 9e15ce0006eb..11761cdaae19 100644 --- a/include/asm-i386/irq.h +++ b/include/asm-i386/irq.h @@ -37,6 +37,8 @@ static __inline__ int irq_canonicalize(int irq) extern int irqbalance_disable(char *str); #endif +extern void quirk_intel_irqbalance(void); + #ifdef CONFIG_HOTPLUG_CPU extern void fixup_irqs(cpumask_t map); #endif diff --git a/include/asm-x86_64/proto.h b/include/asm-x86_64/proto.h index 21fa5afa232e..6d324b838972 100644 --- a/include/asm-x86_64/proto.h +++ b/include/asm-x86_64/proto.h @@ -87,6 +87,7 @@ extern void syscall32_cpu_init(void); extern void setup_node_bootmem(int nodeid, unsigned long start, unsigned long end); extern void early_quirks(void); +extern void quirk_intel_irqbalance(void); extern void check_efer(void); extern int unhandled_signal(struct task_struct *tsk, int sig); -- cgit v1.2.3 From ee58fad51a2a767cb2567706ace967705233d881 Mon Sep 17 00:00:00 2001 From: Stephane Eranian Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] x86-64: x86-64 add Intel BTS cpufeature bit and detection (take 2) Here is a small patch for x86-64 which adds a cpufeature flag and detection code for Intel's Branch Trace Store (BTS) feature. This feature can be found on Intel P4 and Core 2 processors among others. It can also be used by perfmon. changelog: - add CPU_FEATURE_BTS - add Branch Trace Store detection signed-off-by: stephane eranian Signed-off-by: Andi Kleen --- arch/x86_64/kernel/setup.c | 2 ++ include/asm-x86_64/cpufeature.h | 2 ++ 2 files changed, 4 insertions(+) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index 619af2e2fa26..a570c81c8316 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c @@ -838,6 +838,8 @@ static void __cpuinit init_intel(struct cpuinfo_x86 *c) if (cpu_has_ds) { unsigned int l1, l2; rdmsr(MSR_IA32_MISC_ENABLE, l1, l2); + if (!(l1 & (1<<11))) + set_bit(X86_FEATURE_BTS, c->x86_capability); if (!(l1 & (1<<12))) set_bit(X86_FEATURE_PEBS, c->x86_capability); } diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h index d280384807ef..0b3c686139f1 100644 --- a/include/asm-x86_64/cpufeature.h +++ b/include/asm-x86_64/cpufeature.h @@ -69,6 +69,7 @@ #define X86_FEATURE_UP (3*32+8) /* SMP kernel running on UP */ #define X86_FEATURE_ARCH_PERFMON (3*32+9) /* Intel Architectural PerfMon */ #define X86_FEATURE_PEBS (3*32+10) /* Precise-Event Based Sampling */ +#define X86_FEATURE_BTS (3*32+11) /* Branch Trace Store */ /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ @@ -115,5 +116,6 @@ #define cpu_has_clflush boot_cpu_has(X86_FEATURE_CLFLSH) #define cpu_has_ds boot_cpu_has(X86_FEATURE_DS) #define cpu_has_pebs boot_cpu_has(X86_FEATURE_PEBS) +#define cpu_has_bts boot_cpu_has(X86_FEATURE_BTS) #endif /* __ASM_X8664_CPUFEATURE_H */ -- cgit v1.2.3 From c7a3392e9e53e43c44a971de3dd480a8e2788e75 Mon Sep 17 00:00:00 2001 From: Wink Saville Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] x86-64: Fix comments for MSR_FS_BASE and MSR_GS_BASE. The comments for MSR_FS_BASE & MSR_GS_BASE were transposed. Signed-off-by: Wink Saville Signed-off-by: Andi Kleen --- include/asm-x86_64/msr.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/msr.h b/include/asm-x86_64/msr.h index a745c5008a60..952783d35c7b 100644 --- a/include/asm-x86_64/msr.h +++ b/include/asm-x86_64/msr.h @@ -169,8 +169,8 @@ static inline unsigned int cpuid_edx(unsigned int op) #define MSR_LSTAR 0xc0000082 /* long mode SYSCALL target */ #define MSR_CSTAR 0xc0000083 /* compatibility mode SYSCALL target */ #define MSR_SYSCALL_MASK 0xc0000084 /* EFLAGS mask for syscall */ -#define MSR_FS_BASE 0xc0000100 /* 64bit GS base */ -#define MSR_GS_BASE 0xc0000101 /* 64bit FS base */ +#define MSR_FS_BASE 0xc0000100 /* 64bit FS base */ +#define MSR_GS_BASE 0xc0000101 /* 64bit GS base */ #define MSR_KERNEL_GS_BASE 0xc0000102 /* SwapGS GS shadow (or USER_GS from kernel) */ /* EFER bits: */ #define _EFER_SCE 0 /* SYSCALL/SYSRET */ -- cgit v1.2.3 From 0741f4d207a644482d7a040f05cd264c98cf7ee8 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert <76306.1226@compuserve.com> Date: Thu, 7 Dec 2006 02:14:11 +0100 Subject: [PATCH] x86: add sysctl for kstack_depth_to_print Add sysctl for kstack_depth_to_print. This lets users change the amount of raw stack data printed in dump_stack() without having to reboot. Signed-off-by: Chuck Ebbert <76306.1226@compuserve.com> Signed-off-by: Andi Kleen --- Documentation/sysctl/kernel.txt | 8 ++++++++ arch/i386/kernel/traps.c | 2 +- arch/x86_64/kernel/traps.c | 2 +- include/asm-x86_64/stacktrace.h | 2 ++ kernel/sysctl.c | 9 +++++++++ 5 files changed, 21 insertions(+), 2 deletions(-) (limited to 'include/asm-x86_64') diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 0bc7f1e3c9e6..5922e84d9133 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -27,6 +27,7 @@ show up in /proc/sys/kernel: - hotplug - java-appletviewer [ binfmt_java, obsolete ] - java-interpreter [ binfmt_java, obsolete ] +- kstack_depth_to_print [ X86 only ] - l2cr [ PPC only ] - modprobe ==> Documentation/kmod.txt - msgmax @@ -170,6 +171,13 @@ This flag controls the L2 cache of G3 processor boards. If ============================================================== +kstack_depth_to_print: (X86 only) + +Controls the number of words to print when dumping the raw +kernel stack. + +============================================================== + osrelease, ostype & version: # cat osrelease diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 7b2f9f022089..1d48a75fa338 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -91,7 +91,7 @@ asmlinkage void alignment_check(void); asmlinkage void spurious_interrupt_bug(void); asmlinkage void machine_check(void); -static int kstack_depth_to_print = 24; +int kstack_depth_to_print = 24; #ifdef CONFIG_STACK_UNWIND static int call_trace = 1; #else diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 264db33476ab..75ceccee178c 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -108,7 +108,7 @@ static inline void preempt_conditional_cli(struct pt_regs *regs) preempt_enable_no_resched(); } -static int kstack_depth_to_print = 12; +int kstack_depth_to_print = 12; #ifdef CONFIG_STACK_UNWIND static int call_trace = 1; #else diff --git a/include/asm-x86_64/stacktrace.h b/include/asm-x86_64/stacktrace.h index 5eb9799bef76..6f0b54594307 100644 --- a/include/asm-x86_64/stacktrace.h +++ b/include/asm-x86_64/stacktrace.h @@ -1,6 +1,8 @@ #ifndef _ASM_STACKTRACE_H #define _ASM_STACKTRACE_H 1 +extern int kstack_depth_to_print; + /* Generic stack tracer with callbacks */ struct stacktrace_ops { diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 09e569f4792b..6fc5e17086f4 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -54,6 +54,7 @@ extern int proc_nr_files(ctl_table *table, int write, struct file *filp, #ifdef CONFIG_X86 #include +#include #endif #if defined(CONFIG_SYSCTL) @@ -707,6 +708,14 @@ static ctl_table kern_table[] = { .mode = 0444, .proc_handler = &proc_dointvec, }, + { + .ctl_name = CTL_UNNUMBERED, + .procname = "kstack_depth_to_print", + .data = &kstack_depth_to_print, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec, + }, #endif #if defined(CONFIG_MMU) { -- cgit v1.2.3 From 359ad0d4015a9ab39243f2ebc4eb07915bd618b2 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] unwinder: more sanity checks in Dwarf2 unwinder Tighten the requirements on both input to and output from the Dwarf2 unwinder. Signed-off-by: Jan Beulich Signed-off-by: Andi Kleen --- arch/i386/kernel/traps.c | 7 +++++++ arch/x86_64/kernel/traps.c | 7 +++++++ include/asm-i386/unwind.h | 12 ++++-------- include/asm-x86_64/unwind.h | 8 ++------ kernel/unwind.c | 16 +++++++++++++++- 5 files changed, 35 insertions(+), 15 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/i386/kernel/traps.c b/arch/i386/kernel/traps.c index 86d8476be4fe..c447807e2a45 100644 --- a/arch/i386/kernel/traps.c +++ b/arch/i386/kernel/traps.c @@ -161,12 +161,19 @@ dump_trace_unwind(struct unwind_frame_info *info, void *data) { struct ops_and_data *oad = (struct ops_and_data *)data; int n = 0; + unsigned long sp = UNW_SP(info); + if (arch_unw_user_mode(info)) + return -1; while (unwind(info) == 0 && UNW_PC(info)) { n++; oad->ops->address(oad->data, UNW_PC(info)); if (arch_unw_user_mode(info)) break; + if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) + && sp > UNW_SP(info)) + break; + sp = UNW_SP(info); } return n; } diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 9864d195c408..4fdd162f0bef 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -225,12 +225,19 @@ static int dump_trace_unwind(struct unwind_frame_info *info, void *context) { struct ops_and_data *oad = (struct ops_and_data *)context; int n = 0; + unsigned long sp = UNW_SP(info); + if (arch_unw_user_mode(info)) + return -1; while (unwind(info) == 0 && UNW_PC(info)) { n++; oad->ops->address(oad->data, UNW_PC(info)); if (arch_unw_user_mode(info)) break; + if ((sp & ~(PAGE_SIZE - 1)) == (UNW_SP(info) & ~(PAGE_SIZE - 1)) + && sp > UNW_SP(info)) + break; + sp = UNW_SP(info); } return n; } diff --git a/include/asm-i386/unwind.h b/include/asm-i386/unwind.h index 601fc67bd775..aa2c931e30db 100644 --- a/include/asm-i386/unwind.h +++ b/include/asm-i386/unwind.h @@ -79,17 +79,13 @@ extern asmlinkage int arch_unwind_init_running(struct unwind_frame_info *, void *arg), void *arg); -static inline int arch_unw_user_mode(const struct unwind_frame_info *info) +static inline int arch_unw_user_mode(/*const*/ struct unwind_frame_info *info) { -#if 0 /* This can only work when selector register and EFLAGS saves/restores - are properly annotated (and tracked in UNW_REGISTER_INFO). */ - return user_mode_vm(&info->regs); -#else - return info->regs.eip < PAGE_OFFSET + return user_mode_vm(&info->regs) + || info->regs.eip < PAGE_OFFSET || (info->regs.eip >= __fix_to_virt(FIX_VDSO) - && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE) + && info->regs.eip < __fix_to_virt(FIX_VDSO) + PAGE_SIZE) || info->regs.esp < PAGE_OFFSET; -#endif } #else diff --git a/include/asm-x86_64/unwind.h b/include/asm-x86_64/unwind.h index 2e7ff10fd775..2f6349e48717 100644 --- a/include/asm-x86_64/unwind.h +++ b/include/asm-x86_64/unwind.h @@ -87,14 +87,10 @@ extern int arch_unwind_init_running(struct unwind_frame_info *, static inline int arch_unw_user_mode(const struct unwind_frame_info *info) { -#if 0 /* This can only work when selector register saves/restores - are properly annotated (and tracked in UNW_REGISTER_INFO). */ - return user_mode(&info->regs); -#else - return (long)info->regs.rip >= 0 + return user_mode(&info->regs) + || (long)info->regs.rip >= 0 || (info->regs.rip >= VSYSCALL_START && info->regs.rip < VSYSCALL_END) || (long)info->regs.rsp >= 0; -#endif } #else diff --git a/kernel/unwind.c b/kernel/unwind.c index af48168a3afb..7e721f104105 100644 --- a/kernel/unwind.c +++ b/kernel/unwind.c @@ -95,6 +95,7 @@ static const struct { typedef unsigned long uleb128_t; typedef signed long sleb128_t; +#define sleb128abs __builtin_labs static struct unwind_table { struct { @@ -787,7 +788,7 @@ int unwind(struct unwind_frame_info *frame) #define FRAME_REG(r, t) (((t *)frame)[reg_info[r].offs]) const u32 *fde = NULL, *cie = NULL; const u8 *ptr = NULL, *end = NULL; - unsigned long pc = UNW_PC(frame) - frame->call_frame; + unsigned long pc = UNW_PC(frame) - frame->call_frame, sp; unsigned long startLoc = 0, endLoc = 0, cfa; unsigned i; signed ptrType = -1; @@ -936,6 +937,9 @@ int unwind(struct unwind_frame_info *frame) state.dataAlign = get_sleb128(&ptr, end); if (state.codeAlign == 0 || state.dataAlign == 0 || ptr >= end) cie = NULL; + else if (UNW_PC(frame) % state.codeAlign + || UNW_SP(frame) % sleb128abs(state.dataAlign)) + return -EPERM; else { retAddrReg = state.version <= 1 ? *ptr++ : get_uleb128(&ptr, end); /* skip augmentation */ @@ -968,6 +972,8 @@ int unwind(struct unwind_frame_info *frame) #ifdef CONFIG_FRAME_POINTER unsigned long top, bottom; + if ((UNW_SP(frame) | UNW_FP(frame)) % sizeof(unsigned long)) + return -EPERM; top = STACK_TOP(frame->task); bottom = STACK_BOTTOM(frame->task); # if FRAME_RETADDR_OFFSET < 0 @@ -1018,6 +1024,7 @@ int unwind(struct unwind_frame_info *frame) || state.regs[retAddrReg].where == Nowhere || state.cfa.reg >= ARRAY_SIZE(reg_info) || reg_info[state.cfa.reg].width != sizeof(unsigned long) + || FRAME_REG(state.cfa.reg, unsigned long) % sizeof(unsigned long) || state.cfa.offs % sizeof(unsigned long)) return -EIO; /* update frame */ @@ -1038,6 +1045,8 @@ int unwind(struct unwind_frame_info *frame) #else # define CASES CASE(8); CASE(16); CASE(32); CASE(64) #endif + pc = UNW_PC(frame); + sp = UNW_SP(frame); for (i = 0; i < ARRAY_SIZE(state.regs); ++i) { if (REG_INVALID(i)) { if (state.regs[i].where == Nowhere) @@ -1118,6 +1127,11 @@ int unwind(struct unwind_frame_info *frame) } } + if (UNW_PC(frame) % state.codeAlign + || UNW_SP(frame) % sleb128abs(state.dataAlign) + || (pc == UNW_PC(frame) && sp == UNW_SP(frame))) + return -EIO; + return 0; #undef CASES #undef FRAME_REG -- cgit v1.2.3 From d331e739f5ad2aaa9d8553891ba6ca823bdbce37 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: Fix interrupt race in idle callback (3rd try) Idle callbacks has some races when enter_idle() sets isidle and subsequent interrupts that can happen on that CPU, before CPU goes to idle. Due to this, an IDLE_END can get called before IDLE_START. To avoid these races, disable interrupts before enter_idle and make sure that all idle routines do not enable interrupts before entering idle. Note that poll_idle() still has a this race as it has to enable interrupts before going to idle. But, all other idle routines have the race fixed. Signed-off-by: Venkatesh Pallipadi Signed-off-by: Andi Kleen --- arch/x86_64/kernel/process.c | 19 +++++++++++++++++-- include/asm-x86_64/processor.h | 8 ++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 0b7b4caa4f74..a418ee4c8c62 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c @@ -127,6 +127,7 @@ static void default_idle(void) */ static void poll_idle (void) { + local_irq_enable(); cpu_relax(); } @@ -208,6 +209,12 @@ void cpu_idle (void) idle = default_idle; if (cpu_is_offline(smp_processor_id())) play_dead(); + /* + * Idle routines should keep interrupts disabled + * from here on, until they go to idle. + * Otherwise, idle callbacks can misfire. + */ + local_irq_disable(); enter_idle(); idle(); /* In many cases the interrupt that ended idle @@ -245,8 +252,16 @@ void mwait_idle_with_hints(unsigned long eax, unsigned long ecx) /* Default MONITOR/MWAIT with no hints, used for default C1 state */ static void mwait_idle(void) { - local_irq_enable(); - mwait_idle_with_hints(0,0); + if (!need_resched()) { + __monitor((void *)¤t_thread_info()->flags, 0, 0); + smp_mb(); + if (!need_resched()) + __sti_mwait(0, 0); + else + local_irq_enable(); + } else { + local_irq_enable(); + } } void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) diff --git a/include/asm-x86_64/processor.h b/include/asm-x86_64/processor.h index cef17e0f828c..76552d72804c 100644 --- a/include/asm-x86_64/processor.h +++ b/include/asm-x86_64/processor.h @@ -475,6 +475,14 @@ static inline void __mwait(unsigned long eax, unsigned long ecx) : :"a" (eax), "c" (ecx)); } +static inline void __sti_mwait(unsigned long eax, unsigned long ecx) +{ + /* "mwait %eax,%ecx;" */ + asm volatile( + "sti; .byte 0x0f,0x01,0xc9;" + : :"a" (eax), "c" (ecx)); +} + extern void mwait_idle_with_hints(unsigned long eax, unsigned long ecx); #define stack_current() \ -- cgit v1.2.3 From 9ee4016888f1b226d7bb9a10ddb782868f658b31 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: include/asm-x86_64/cpufeature.h isn't a userspace header Nothing in include/asm-x86_64/cpufeature.h is part of the userspace<->kernel interface. Signed-off-by: Adrian Bunk Signed-off-by: Andi Kleen --- include/asm-x86_64/Kbuild | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/Kbuild b/include/asm-x86_64/Kbuild index 1ee9b07f3fe6..6c455b4068c0 100644 --- a/include/asm-x86_64/Kbuild +++ b/include/asm-x86_64/Kbuild @@ -6,7 +6,6 @@ ALTARCHDEF := defined __i386__ header-y += boot.h header-y += bootsetup.h -header-y += cpufeature.h header-y += debugreg.h header-y += ldt.h header-y += msr.h -- cgit v1.2.3 From 9dc452ba2d47f376987a99c0819833af0b46cc3f Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Thu, 7 Dec 2006 02:14:13 +0100 Subject: [PATCH] x86-64: Fix constraints in atomic_add_return() Following i386 from Duncan Sands Signed-off-by: Andi Kleen --- include/asm-x86_64/atomic.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h index 007e88d6d43f..626d3715fbb5 100644 --- a/include/asm-x86_64/atomic.h +++ b/include/asm-x86_64/atomic.h @@ -189,9 +189,9 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) { int __i = i; __asm__ __volatile__( - LOCK_PREFIX "xaddl %0, %1;" - :"=r"(i) - :"m"(v->counter), "0"(i)); + LOCK_PREFIX "xaddl %0, %1" + :"+r" (i), "+m" (v->counter) + : : "memory"); return i + __i; } -- cgit v1.2.3 From a866374aecc90c7d90619727ccd851ac096b2fc7 Mon Sep 17 00:00:00 2001 From: Peter Zijlstra Date: Wed, 6 Dec 2006 20:32:20 -0800 Subject: [PATCH] mm: pagefault_{disable,enable}() Introduce pagefault_{disable,enable}() and use these where previously we did manual preempt increments/decrements to make the pagefault handler do the atomic thing. Currently they still rely on the increased preempt count, but do not rely on the disabled preemption, this might go away in the future. (NOTE: the extra barrier() in pagefault_disable might fix some holes on machines which have too many registers for their own good) [heiko.carstens@de.ibm.com: s390 fix] Signed-off-by: Peter Zijlstra Acked-by: Nick Piggin Cc: Martin Schwidefsky Signed-off-by: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/frv/kernel/futex.c | 4 ++-- arch/i386/mm/highmem.c | 10 ++++------ arch/mips/mm/highmem.c | 10 ++++------ arch/s390/lib/uaccess_std.c | 6 +++--- arch/sparc/mm/highmem.c | 8 +++----- include/asm-frv/highmem.h | 5 ++--- include/asm-generic/futex.h | 4 ++-- include/asm-i386/futex.h | 4 ++-- include/asm-ia64/futex.h | 4 ++-- include/asm-mips/futex.h | 4 ++-- include/asm-parisc/futex.h | 4 ++-- include/asm-powerpc/futex.h | 4 ++-- include/asm-ppc/highmem.h | 8 +++----- include/asm-sparc64/futex.h | 4 ++-- include/asm-x86_64/futex.h | 4 ++-- include/linux/uaccess.h | 39 +++++++++++++++++++++++++++++++++++++-- kernel/futex.c | 28 ++++++++++++++-------------- 17 files changed, 88 insertions(+), 62 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/frv/kernel/futex.c b/arch/frv/kernel/futex.c index eae874a970c6..53dc5ed1ebda 100644 --- a/arch/frv/kernel/futex.c +++ b/arch/frv/kernel/futex.c @@ -200,7 +200,7 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) if (!access_ok(VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -223,7 +223,7 @@ int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) break; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/arch/i386/mm/highmem.c b/arch/i386/mm/highmem.c index f9f647cdbc7b..178bbfe6cbac 100644 --- a/arch/i386/mm/highmem.c +++ b/arch/i386/mm/highmem.c @@ -32,7 +32,7 @@ void *kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - inc_preempt_count(); + pagefault_disable(); if (!PageHighMem(page)) return page_address(page); @@ -52,8 +52,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) #ifdef CONFIG_DEBUG_HIGHMEM if (vaddr >= PAGE_OFFSET && vaddr < (unsigned long)high_memory) { - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); return; } @@ -68,8 +67,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) */ kpte_clear_flush(kmap_pte-idx, vaddr); - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } /* This is the same as kmap_atomic() but can map memory that doesn't @@ -80,7 +78,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) enum fixed_addresses idx; unsigned long vaddr; - inc_preempt_count(); + pagefault_disable(); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 99ebf3ccc222..675502ada5a2 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c @@ -39,7 +39,7 @@ void *__kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - inc_preempt_count(); + pagefault_disable(); if (!PageHighMem(page)) return page_address(page); @@ -62,8 +62,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) enum fixed_addresses idx = type + KM_TYPE_NR*smp_processor_id(); if (vaddr < FIXADDR_START) { // FIXME - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); return; } @@ -78,8 +77,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) local_flush_tlb_one(vaddr); #endif - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } #ifndef CONFIG_LIMITED_DMA @@ -92,7 +90,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) enum fixed_addresses idx; unsigned long vaddr; - inc_preempt_count(); + pagefault_disable(); idx = type + KM_TYPE_NR*smp_processor_id(); vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c index 2d549ed2e113..bbaca66fa293 100644 --- a/arch/s390/lib/uaccess_std.c +++ b/arch/s390/lib/uaccess_std.c @@ -11,7 +11,7 @@ #include #include -#include +#include #include #ifndef __s390x__ @@ -258,7 +258,7 @@ int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old) { int oldval = 0, newval, ret; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -284,7 +284,7 @@ int futex_atomic_op(int op, int __user *uaddr, int oparg, int *old) default: ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); *old = oldval; return ret; } diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c index 4d8ed9c65182..01fc6c254292 100644 --- a/arch/sparc/mm/highmem.c +++ b/arch/sparc/mm/highmem.c @@ -35,7 +35,7 @@ void *kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - inc_preempt_count(); + pagefault_disable(); if (!PageHighMem(page)) return page_address(page); @@ -70,8 +70,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) unsigned long idx = type + KM_TYPE_NR*smp_processor_id(); if (vaddr < FIXADDR_START) { // FIXME - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); return; } @@ -97,8 +96,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type) #endif #endif - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } /* We may be fed a pagetable here by ptep_to_xxx and others. */ diff --git a/include/asm-frv/highmem.h b/include/asm-frv/highmem.h index 0f390f41f816..ff4d6cdeb152 100644 --- a/include/asm-frv/highmem.h +++ b/include/asm-frv/highmem.h @@ -115,7 +115,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) { unsigned long paddr; - inc_preempt_count(); + pagefault_disable(); paddr = page_to_phys(page); switch (type) { @@ -170,8 +170,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) default: BUG(); } - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } #endif /* !__ASSEMBLY__ */ diff --git a/include/asm-generic/futex.h b/include/asm-generic/futex.h index df893c160318..f422df0956a2 100644 --- a/include/asm-generic/futex.h +++ b/include/asm-generic/futex.h @@ -21,7 +21,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -33,7 +33,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/include/asm-i386/futex.h b/include/asm-i386/futex.h index 946d97cfea23..438ef0ec7101 100644 --- a/include/asm-i386/futex.h +++ b/include/asm-i386/futex.h @@ -56,7 +56,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); if (op == FUTEX_OP_SET) __futex_atomic_op1("xchgl %0, %2", ret, oldval, uaddr, oparg); @@ -88,7 +88,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) } } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/include/asm-ia64/futex.h b/include/asm-ia64/futex.h index 07d77f3a8cbe..8a98a2654139 100644 --- a/include/asm-ia64/futex.h +++ b/include/asm-ia64/futex.h @@ -59,7 +59,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -83,7 +83,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h index 927a216bd530..47e5679c2353 100644 --- a/include/asm-mips/futex.h +++ b/include/asm-mips/futex.h @@ -88,7 +88,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -115,7 +115,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/include/asm-parisc/futex.h b/include/asm-parisc/futex.h index d84bbb283fd1..dbee6e60aa81 100644 --- a/include/asm-parisc/futex.h +++ b/include/asm-parisc/futex.h @@ -21,7 +21,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -33,7 +33,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/include/asm-powerpc/futex.h b/include/asm-powerpc/futex.h index 936422e54891..3f3673fd3ff3 100644 --- a/include/asm-powerpc/futex.h +++ b/include/asm-powerpc/futex.h @@ -43,7 +43,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -65,7 +65,7 @@ static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/include/asm-ppc/highmem.h b/include/asm-ppc/highmem.h index 1d2c4ef81c22..f7b21ee302b4 100644 --- a/include/asm-ppc/highmem.h +++ b/include/asm-ppc/highmem.h @@ -79,7 +79,7 @@ static inline void *kmap_atomic(struct page *page, enum km_type type) unsigned long vaddr; /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */ - inc_preempt_count(); + pagefault_disable(); if (!PageHighMem(page)) return page_address(page); @@ -101,8 +101,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) unsigned int idx = type + KM_TYPE_NR*smp_processor_id(); if (vaddr < KMAP_FIX_BEGIN) { // FIXME - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); return; } @@ -115,8 +114,7 @@ static inline void kunmap_atomic(void *kvaddr, enum km_type type) pte_clear(&init_mm, vaddr, kmap_pte+idx); flush_tlb_page(NULL, vaddr); #endif - dec_preempt_count(); - preempt_check_resched(); + pagefault_enable(); } static inline struct page *kmap_atomic_to_page(void *ptr) diff --git a/include/asm-sparc64/futex.h b/include/asm-sparc64/futex.h index 7392fc4a954e..876312fe82cc 100644 --- a/include/asm-sparc64/futex.h +++ b/include/asm-sparc64/futex.h @@ -45,7 +45,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) oparg = 1 << oparg; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -67,7 +67,7 @@ static inline int futex_atomic_op_inuser(int encoded_op, int __user *uaddr) ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/include/asm-x86_64/futex.h b/include/asm-x86_64/futex.h index 9804bf07b092..5cdfb08013c3 100644 --- a/include/asm-x86_64/futex.h +++ b/include/asm-x86_64/futex.h @@ -55,7 +55,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) return -EFAULT; - inc_preempt_count(); + pagefault_disable(); switch (op) { case FUTEX_OP_SET: @@ -78,7 +78,7 @@ futex_atomic_op_inuser (int encoded_op, int __user *uaddr) ret = -ENOSYS; } - dec_preempt_count(); + pagefault_enable(); if (!ret) { switch (cmp) { diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h index a48d7f11c7be..67918c22339c 100644 --- a/include/linux/uaccess.h +++ b/include/linux/uaccess.h @@ -1,8 +1,43 @@ #ifndef __LINUX_UACCESS_H__ #define __LINUX_UACCESS_H__ +#include #include +/* + * These routines enable/disable the pagefault handler in that + * it will not take any locks and go straight to the fixup table. + * + * They have great resemblance to the preempt_disable/enable calls + * and in fact they are identical; this is because currently there is + * no other way to make the pagefault handlers do this. So we do + * disable preemption but we don't necessarily care about that. + */ +static inline void pagefault_disable(void) +{ + inc_preempt_count(); + /* + * make sure to have issued the store before a pagefault + * can hit. + */ + barrier(); +} + +static inline void pagefault_enable(void) +{ + /* + * make sure to issue those last loads/stores before enabling + * the pagefault handler again. + */ + barrier(); + dec_preempt_count(); + /* + * make sure we do.. + */ + barrier(); + preempt_check_resched(); +} + #ifndef ARCH_HAS_NOCACHE_UACCESS static inline unsigned long __copy_from_user_inatomic_nocache(void *to, @@ -35,9 +70,9 @@ static inline unsigned long __copy_from_user_nocache(void *to, ({ \ long ret; \ \ - inc_preempt_count(); \ + pagefault_disable(); \ ret = __get_user(retval, addr); \ - dec_preempt_count(); \ + pagefault_enable(); \ ret; \ }) diff --git a/kernel/futex.c b/kernel/futex.c index 93ef30ba209f..af7b81cbde30 100644 --- a/kernel/futex.c +++ b/kernel/futex.c @@ -282,9 +282,9 @@ static inline int get_futex_value_locked(u32 *dest, u32 __user *from) { int ret; - inc_preempt_count(); + pagefault_disable(); ret = __copy_from_user_inatomic(dest, from, sizeof(u32)); - dec_preempt_count(); + pagefault_enable(); return ret ? -EFAULT : 0; } @@ -585,9 +585,9 @@ static int wake_futex_pi(u32 __user *uaddr, u32 uval, struct futex_q *this) if (!(uval & FUTEX_OWNER_DIED)) { newval = FUTEX_WAITERS | new_owner->pid; - inc_preempt_count(); + pagefault_disable(); curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); - dec_preempt_count(); + pagefault_enable(); if (curval == -EFAULT) return -EFAULT; if (curval != uval) @@ -618,9 +618,9 @@ static int unlock_futex_pi(u32 __user *uaddr, u32 uval) * There is no waiter, so we unlock the futex. The owner died * bit has not to be preserved here. We are the owner: */ - inc_preempt_count(); + pagefault_disable(); oldval = futex_atomic_cmpxchg_inatomic(uaddr, uval, 0); - dec_preempt_count(); + pagefault_enable(); if (oldval == -EFAULT) return oldval; @@ -1158,9 +1158,9 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, */ newval = current->pid; - inc_preempt_count(); + pagefault_disable(); curval = futex_atomic_cmpxchg_inatomic(uaddr, 0, newval); - dec_preempt_count(); + pagefault_enable(); if (unlikely(curval == -EFAULT)) goto uaddr_faulted; @@ -1183,9 +1183,9 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, uval = curval; newval = uval | FUTEX_WAITERS; - inc_preempt_count(); + pagefault_disable(); curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); - dec_preempt_count(); + pagefault_enable(); if (unlikely(curval == -EFAULT)) goto uaddr_faulted; @@ -1215,10 +1215,10 @@ static int futex_lock_pi(u32 __user *uaddr, int detect, unsigned long sec, newval = current->pid | FUTEX_OWNER_DIED | FUTEX_WAITERS; - inc_preempt_count(); + pagefault_disable(); curval = futex_atomic_cmpxchg_inatomic(uaddr, uval, newval); - dec_preempt_count(); + pagefault_enable(); if (unlikely(curval == -EFAULT)) goto uaddr_faulted; @@ -1390,9 +1390,9 @@ retry_locked: * anyone else up: */ if (!(uval & FUTEX_OWNER_DIED)) { - inc_preempt_count(); + pagefault_disable(); uval = futex_atomic_cmpxchg_inatomic(uaddr, current->pid, 0); - dec_preempt_count(); + pagefault_enable(); } if (unlikely(uval == -EFAULT)) -- cgit v1.2.3 From f5738ceed46782aea7663d62cb6398eb05fc4ce0 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Wed, 6 Dec 2006 20:37:29 -0800 Subject: [PATCH] remove kernel syscalls The last thing we agreed on was to remove the macros entirely for 2.6.19, on all architectures. Unfortunately, I think nobody actually _did_ that, so they are still there. [akpm@osdl.org: x86_64 fix] Cc: David Woodhouse Cc: Greg Schafer Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/kernel/vsyscall.c | 1 + include/asm-alpha/unistd.h | 182 ---------------------------- include/asm-arm/unistd.h | 150 ----------------------- include/asm-arm26/unistd.h | 133 --------------------- include/asm-frv/unistd.h | 119 ------------------- include/asm-h8300/unistd.h | 166 -------------------------- include/asm-i386/unistd.h | 98 --------------- include/asm-m32r/unistd.h | 111 ----------------- include/asm-m68k/unistd.h | 97 --------------- include/asm-m68knommu/unistd.h | 150 ----------------------- include/asm-mips/unistd.h | 262 ----------------------------------------- include/asm-powerpc/unistd.h | 109 ----------------- include/asm-s390/unistd.h | 154 ------------------------ include/asm-sh/unistd.h | 137 --------------------- include/asm-sh64/unistd.h | 142 ---------------------- include/asm-sparc/unistd.h | 130 -------------------- include/asm-sparc64/unistd.h | 118 ------------------- include/asm-v850/unistd.h | 160 ------------------------- include/asm-x86_64/unistd.h | 99 ---------------- include/asm-xtensa/unistd.h | 184 ----------------------------- 20 files changed, 1 insertion(+), 2701 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/kernel/vsyscall.c b/arch/x86_64/kernel/vsyscall.c index 92546c1526f1..630036c06c75 100644 --- a/arch/x86_64/kernel/vsyscall.c +++ b/arch/x86_64/kernel/vsyscall.c @@ -42,6 +42,7 @@ #include #define __vsyscall(nr) __attribute__ ((unused,__section__(".vsyscall_" #nr))) +#define __syscall_clobber "r11","rcx","memory" int __sysctl_vsyscall __section_sysctl_vsyscall = 1; seqlock_t __xtime_lock __section_xtime_lock = SEQLOCK_UNLOCKED; diff --git a/include/asm-alpha/unistd.h b/include/asm-alpha/unistd.h index 2cabbd465c0c..84313d14e780 100644 --- a/include/asm-alpha/unistd.h +++ b/include/asm-alpha/unistd.h @@ -387,188 +387,6 @@ #define NR_SYSCALLS 447 -#if defined(__GNUC__) - -#define _syscall_return(type) \ - return (_sc_err ? errno = _sc_ret, _sc_ret = -1L : 0), (type) _sc_ret - -#define _syscall_clobbers \ - "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", \ - "$22", "$23", "$24", "$25", "$27", "$28" \ - -#define _syscall0(type, name) \ -type name(void) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_19 __asm__("$19"); \ - \ - _sc_0 = __NR_##name; \ - __asm__("callsys # %0 %1 %2" \ - : "=r"(_sc_0), "=r"(_sc_19) \ - : "0"(_sc_0) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; \ - } \ - _syscall_return(type); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_16 __asm__("$16"); \ - register long _sc_19 __asm__("$19"); \ - \ - _sc_0 = __NR_##name; \ - _sc_16 = (long) (arg1); \ - __asm__("callsys # %0 %1 %2 %3" \ - : "=r"(_sc_0), "=r"(_sc_19) \ - : "0"(_sc_0), "r"(_sc_16) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; \ - } \ - _syscall_return(type); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_16 __asm__("$16"); \ - register long _sc_17 __asm__("$17"); \ - register long _sc_19 __asm__("$19"); \ - \ - _sc_0 = __NR_##name; \ - _sc_16 = (long) (arg1); \ - _sc_17 = (long) (arg2); \ - __asm__("callsys # %0 %1 %2 %3 %4" \ - : "=r"(_sc_0), "=r"(_sc_19) \ - : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; \ - } \ - _syscall_return(type); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_16 __asm__("$16"); \ - register long _sc_17 __asm__("$17"); \ - register long _sc_18 __asm__("$18"); \ - register long _sc_19 __asm__("$19"); \ - \ - _sc_0 = __NR_##name; \ - _sc_16 = (long) (arg1); \ - _sc_17 = (long) (arg2); \ - _sc_18 = (long) (arg3); \ - __asm__("callsys # %0 %1 %2 %3 %4 %5" \ - : "=r"(_sc_0), "=r"(_sc_19) \ - : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \ - "r"(_sc_18) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; \ - } \ - _syscall_return(type); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_16 __asm__("$16"); \ - register long _sc_17 __asm__("$17"); \ - register long _sc_18 __asm__("$18"); \ - register long _sc_19 __asm__("$19"); \ - \ - _sc_0 = __NR_##name; \ - _sc_16 = (long) (arg1); \ - _sc_17 = (long) (arg2); \ - _sc_18 = (long) (arg3); \ - _sc_19 = (long) (arg4); \ - __asm__("callsys # %0 %1 %2 %3 %4 %5 %6" \ - : "=r"(_sc_0), "=r"(_sc_19) \ - : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \ - "r"(_sc_18), "1"(_sc_19) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; \ - } \ - _syscall_return(type); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_16 __asm__("$16"); \ - register long _sc_17 __asm__("$17"); \ - register long _sc_18 __asm__("$18"); \ - register long _sc_19 __asm__("$19"); \ - register long _sc_20 __asm__("$20"); \ - \ - _sc_0 = __NR_##name; \ - _sc_16 = (long) (arg1); \ - _sc_17 = (long) (arg2); \ - _sc_18 = (long) (arg3); \ - _sc_19 = (long) (arg4); \ - _sc_20 = (long) (arg5); \ - __asm__("callsys # %0 %1 %2 %3 %4 %5 %6 %7" \ - : "=r"(_sc_0), "=r"(_sc_19) \ - : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \ - "r"(_sc_18), "1"(_sc_19), "r"(_sc_20) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; \ - } \ - _syscall_return(type); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6)\ -{ \ - long _sc_ret, _sc_err; \ - { \ - register long _sc_0 __asm__("$0"); \ - register long _sc_16 __asm__("$16"); \ - register long _sc_17 __asm__("$17"); \ - register long _sc_18 __asm__("$18"); \ - register long _sc_19 __asm__("$19"); \ - register long _sc_20 __asm__("$20"); \ - register long _sc_21 __asm__("$21"); \ - \ - _sc_0 = __NR_##name; \ - _sc_16 = (long) (arg1); \ - _sc_17 = (long) (arg2); \ - _sc_18 = (long) (arg3); \ - _sc_19 = (long) (arg4); \ - _sc_20 = (long) (arg5); \ - _sc_21 = (long) (arg6); \ - __asm__("callsys # %0 %1 %2 %3 %4 %5 %6 %7 %8" \ - : "=r"(_sc_0), "=r"(_sc_19) \ - : "0"(_sc_0), "r"(_sc_16), "r"(_sc_17), \ - "r"(_sc_18), "1"(_sc_19), "r"(_sc_20), "r"(_sc_21) \ - : _syscall_clobbers); \ - _sc_ret = _sc_0, _sc_err = _sc_19; \ - } \ - _syscall_return(type); \ -} - -#endif /* __GNUC__ */ - #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h index 14a87eec5a2d..d44c629d8424 100644 --- a/include/asm-arm/unistd.h +++ b/include/asm-arm/unistd.h @@ -377,156 +377,6 @@ #endif #ifdef __KERNEL__ -#include -#include - -#define __sys2(x) #x -#define __sys1(x) __sys2(x) - -#ifndef __syscall -#if defined(__thumb__) || defined(__ARM_EABI__) -#define __SYS_REG(name) register long __sysreg __asm__("r7") = __NR_##name; -#define __SYS_REG_LIST(regs...) "r" (__sysreg) , ##regs -#define __syscall(name) "swi\t0" -#else -#define __SYS_REG(name) -#define __SYS_REG_LIST(regs...) regs -#define __syscall(name) "swi\t" __sys1(__NR_##name) "" -#endif -#endif - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - errno = -(res); \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#define _syscall0(type,name) \ -type name(void) { \ - __SYS_REG(name) \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : __SYS_REG_LIST() \ - : "memory" ); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) { \ - __SYS_REG(name) \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : __SYS_REG_LIST( "0" (__r0) ) \ - : "memory" ); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) { \ - __SYS_REG(name) \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : __SYS_REG_LIST( "0" (__r0), "r" (__r1) ) \ - : "memory" ); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) { \ - __SYS_REG(name) \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __r2 __asm__("r2") = (long)arg3; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2) ) \ - : "memory" ); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - __SYS_REG(name) \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __r2 __asm__("r2") = (long)arg3; \ - register long __r3 __asm__("r3") = (long)arg4; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), "r" (__r3) ) \ - : "memory" ); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ - __SYS_REG(name) \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __r2 __asm__("r2") = (long)arg3; \ - register long __r3 __asm__("r3") = (long)arg4; \ - register long __r4 __asm__("r4") = (long)arg5; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ - "r" (__r3), "r" (__r4) ) \ - : "memory" ); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \ - __SYS_REG(name) \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __r2 __asm__("r2") = (long)arg3; \ - register long __r3 __asm__("r3") = (long)arg4; \ - register long __r4 __asm__("r4") = (long)arg5; \ - register long __r5 __asm__("r5") = (long)arg6; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : __SYS_REG_LIST( "0" (__r0), "r" (__r1), "r" (__r2), \ - "r" (__r3), "r" (__r4), "r" (__r5) ) \ - : "memory" ); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_STAT64 diff --git a/include/asm-arm26/unistd.h b/include/asm-arm26/unistd.h index 25a5eead85be..4c3b919177e5 100644 --- a/include/asm-arm26/unistd.h +++ b/include/asm-arm26/unistd.h @@ -311,139 +311,6 @@ #define __ARM_NR_usr26 (__ARM_NR_BASE+3) #ifdef __KERNEL__ -#include -#include - -#define __sys2(x) #x -#define __sys1(x) __sys2(x) - -#ifndef __syscall -#define __syscall(name) "swi\t" __sys1(__NR_##name) "" -#endif - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)-MAX_ERRNO) { \ - errno = -(res); \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#define _syscall0(type,name) \ -type name(void) { \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : \ - : "lr"); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) { \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : "r" (__r0) \ - : "lr"); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) { \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : "r" (__r0),"r" (__r1) \ - : "lr"); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) { \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __r2 __asm__("r2") = (long)arg3; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : "r" (__r0),"r" (__r1),"r" (__r2) \ - : "lr"); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4)\ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __r2 __asm__("r2") = (long)arg3; \ - register long __r3 __asm__("r3") = (long)arg4; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3) \ - : "lr"); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) { \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __r2 __asm__("r2") = (long)arg3; \ - register long __r3 __asm__("r3") = (long)arg4; \ - register long __r4 __asm__("r4") = (long)arg5; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3),"r" (__r4) \ - : "lr"); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) { \ - register long __r0 __asm__("r0") = (long)arg1; \ - register long __r1 __asm__("r1") = (long)arg2; \ - register long __r2 __asm__("r2") = (long)arg3; \ - register long __r3 __asm__("r3") = (long)arg4; \ - register long __r4 __asm__("r4") = (long)arg5; \ - register long __r5 __asm__("r5") = (long)arg6; \ - register long __res_r0 __asm__("r0"); \ - long __res; \ - __asm__ __volatile__ ( \ - __syscall(name) \ - : "=r" (__res_r0) \ - : "r" (__r0),"r" (__r1),"r" (__r2),"r" (__r3), "r" (__r4),"r" (__r5) \ - : "lr"); \ - __res = __res_r0; \ - __syscall_return(type,__res); \ -} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-frv/unistd.h b/include/asm-frv/unistd.h index 725e854928cf..584c0417ae4d 100644 --- a/include/asm-frv/unistd.h +++ b/include/asm-frv/unistd.h @@ -320,125 +320,6 @@ #ifdef __KERNEL__ #define NR_syscalls 310 -#include - -/* - * process the return value of a syscall, consigning it to one of two possible fates - * - user-visible error numbers are in the range -1 - -4095: see - */ -#undef __syscall_return -#define __syscall_return(type, res) \ -do { \ - unsigned long __sr2 = (res); \ - if (__builtin_expect(__sr2 >= (unsigned long)(-MAX_ERRNO), 0)) { \ - errno = (-__sr2); \ - __sr2 = ~0UL; \ - } \ - return (type) __sr2; \ -} while (0) - -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ - -#undef _syscall0 -#define _syscall0(type,name) \ -type name(void) \ -{ \ - register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ - register unsigned long __sc0 __asm__ ("gr8"); \ - __asm__ __volatile__ ("tira gr0,#0" \ - : "=r" (__sc0) \ - : "r" (__scnum)); \ - __syscall_return(type, __sc0); \ -} - -#undef _syscall1 -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ - register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ - __asm__ __volatile__ ("tira gr0,#0" \ - : "+r" (__sc0) \ - : "r" (__scnum)); \ - __syscall_return(type, __sc0); \ -} - -#undef _syscall2 -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ - register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ - register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ - register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ - __asm__ __volatile__ ("tira gr0,#0" \ - : "+r" (__sc0) \ - : "r" (__scnum), "r" (__sc1)); \ - __syscall_return(type, __sc0); \ -} - -#undef _syscall3 -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ - register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ - register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ - register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ - register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \ - __asm__ __volatile__ ("tira gr0,#0" \ - : "+r" (__sc0) \ - : "r" (__scnum), "r" (__sc1), "r" (__sc2)); \ - __syscall_return(type, __sc0); \ -} - -#undef _syscall4 -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ - register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ - register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ - register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \ - register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \ - __asm__ __volatile__ ("tira gr0,#0" \ - : "+r" (__sc0) \ - : "r" (__scnum), "r" (__sc1), "r" (__sc2), "r" (__sc3)); \ - __syscall_return(type, __sc0); \ -} - -#undef _syscall5 -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ - register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ - register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ - register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ - register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \ - register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \ - register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5; \ - __asm__ __volatile__ ("tira gr0,#0" \ - : "+r" (__sc0) \ - : "r" (__scnum), "r" (__sc1), "r" (__sc2), \ - "r" (__sc3), "r" (__sc4)); \ - __syscall_return(type, __sc0); \ -} - -#undef _syscall6 -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5, type6, arg6) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ - register unsigned long __scnum __asm__ ("gr7") = (__NR_##name); \ - register unsigned long __sc0 __asm__ ("gr8") = (unsigned long) arg1; \ - register unsigned long __sc1 __asm__ ("gr9") = (unsigned long) arg2; \ - register unsigned long __sc2 __asm__ ("gr10") = (unsigned long) arg3; \ - register unsigned long __sc3 __asm__ ("gr11") = (unsigned long) arg4; \ - register unsigned long __sc4 __asm__ ("gr12") = (unsigned long) arg5; \ - register unsigned long __sc5 __asm__ ("gr13") = (unsigned long) arg6; \ - __asm__ __volatile__ ("tira gr0,#0" \ - : "+r" (__sc0) \ - : "r" (__scnum), "r" (__sc1), "r" (__sc2), \ - "r" (__sc3), "r" (__sc4), "r" (__sc5)); \ - __syscall_return(type, __sc0); \ -} #define __ARCH_WANT_IPC_PARSE_VERSION /* #define __ARCH_WANT_OLD_READDIR */ diff --git a/include/asm-h8300/unistd.h b/include/asm-h8300/unistd.h index 747788d629ae..7ddd414f8d16 100644 --- a/include/asm-h8300/unistd.h +++ b/include/asm-h8300/unistd.h @@ -295,172 +295,6 @@ #ifdef __KERNEL__ #define NR_syscalls 289 -#include - -/* user-visible error numbers are in the range -1 - -MAX_ERRNO: see - */ - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - /* avoid using res which is declared to be in register d0; \ - errno might expand to a function call and clobber it. */ \ - int __err = -(res); \ - errno = __err; \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#define _syscall0(type, name) \ -type name(void) \ -{ \ - register long __res __asm__("er0"); \ - __asm__ __volatile__ ("mov.l %1,er0\n\t" \ - "trapa #0\n\t" \ - : "=r" (__res) \ - : "g" (__NR_##name) \ - : "cc", "memory"); \ - __syscall_return(type, __res); \ -} - -#define _syscall1(type, name, atype, a) \ -type name(atype a) \ -{ \ - register long __res __asm__("er0"); \ - register long _a __asm__("er1"); \ - _a = (long)a; \ - __asm__ __volatile__ ("mov.l %1,er0\n\t" \ - "trapa #0\n\t" \ - : "=r" (__res) \ - : "g" (__NR_##name), \ - "g" (_a) \ - : "cc", "memory"); \ - __syscall_return(type, __res); \ -} - -#define _syscall2(type, name, atype, a, btype, b) \ -type name(atype a, btype b) \ -{ \ - register long __res __asm__("er0"); \ - register long _a __asm__("er1"); \ - register long _b __asm__("er2"); \ - _a = (long)a; \ - _b = (long)b; \ - __asm__ __volatile__ ("mov.l %1,er0\n\t" \ - "trapa #0\n\t" \ - : "=r" (__res) \ - : "g" (__NR_##name), \ - "g" (_a), \ - "g" (_b) \ - : "cc", "memory"); \ - __syscall_return(type, __res); \ -} - -#define _syscall3(type, name, atype, a, btype, b, ctype, c) \ -type name(atype a, btype b, ctype c) \ -{ \ - register long __res __asm__("er0"); \ - register long _a __asm__("er1"); \ - register long _b __asm__("er2"); \ - register long _c __asm__("er3"); \ - _a = (long)a; \ - _b = (long)b; \ - _c = (long)c; \ - __asm__ __volatile__ ("mov.l %1,er0\n\t" \ - "trapa #0\n\t" \ - : "=r" (__res) \ - : "g" (__NR_##name), \ - "g" (_a), \ - "g" (_b), \ - "g" (_c) \ - : "cc", "memory"); \ - __syscall_return(type, __res); \ -} - -#define _syscall4(type, name, atype, a, btype, b, \ - ctype, c, dtype, d) \ -type name(atype a, btype b, ctype c, dtype d) \ -{ \ - register long __res __asm__("er0"); \ - register long _a __asm__("er1"); \ - register long _b __asm__("er2"); \ - register long _c __asm__("er3"); \ - register long _d __asm__("er4"); \ - _a = (long)a; \ - _b = (long)b; \ - _c = (long)c; \ - _d = (long)d; \ - __asm__ __volatile__ ("mov.l %1,er0\n\t" \ - "trapa #0\n\t" \ - : "=r" (__res) \ - : "g" (__NR_##name), \ - "g" (_a), \ - "g" (_b), \ - "g" (_c), \ - "g" (_d) \ - : "cc", "memory"); \ - __syscall_return(type, __res); \ -} - -#define _syscall5(type, name, atype, a, btype, b, \ - ctype, c, dtype, d, etype, e) \ -type name(atype a, btype b, ctype c, dtype d, etype e) \ -{ \ - register long __res __asm__("er0"); \ - register long _a __asm__("er1"); \ - register long _b __asm__("er2"); \ - register long _c __asm__("er3"); \ - register long _d __asm__("er4"); \ - register long _e __asm__("er5"); \ - _a = (long)a; \ - _b = (long)b; \ - _c = (long)c; \ - _d = (long)d; \ - _e = (long)e; \ - __asm__ __volatile__ ("mov.l %1,er0\n\t" \ - "trapa #0\n\t" \ - : "=r" (__res) \ - : "g" (__NR_##name), \ - "g" (_a), \ - "g" (_b), \ - "g" (_c), \ - "g" (_d), \ - "g" (_e) \ - : "cc", "memory"); \ - __syscall_return(type, __res); \ -} - -#define _syscall6(type, name, atype, a, btype, b, \ - ctype, c, dtype, d, etype, e, ftype, f) \ -type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \ -{ \ - register long __res __asm__("er0"); \ - register long _a __asm__("er1"); \ - register long _b __asm__("er2"); \ - register long _c __asm__("er3"); \ - register long _d __asm__("er4"); \ - register long _e __asm__("er5"); \ - register long _f __asm__("er6"); \ - _a = (long)a; \ - _b = (long)b; \ - _c = (long)c; \ - _d = (long)d; \ - _e = (long)e; \ - _f = (long)f; \ - __asm__ __volatile__ ("mov.l %1,er0\n\t" \ - "trapa #0\n\t" \ - : "=r" (__res) \ - : "g" (__NR_##name), \ - "g" (_a), \ - "g" (_b), \ - "g" (_c), \ - "g" (_d), \ - "g" (_e) \ - "g" (_f) \ - : "cc", "memory"); \ - __syscall_return(type, __res); \ -} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index beeeaf6b054a..833fa1704ff9 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h @@ -329,104 +329,6 @@ #ifdef __KERNEL__ #define NR_syscalls 320 -#include - -/* - * user-visible error numbers are in the range -1 - -MAX_ERRNO: see - * - */ -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - errno = -(res); \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ -long __res; \ -__asm__ volatile ("int $0x80" \ - : "=a" (__res) \ - : "0" (__NR_##name)); \ -__syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -long __res; \ -__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"ri" ((long)(arg1)) : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -long __res; \ -__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)) \ - : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ - "d" ((long)(arg3)) : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -long __res; \ -__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; int $0x80 ; pop %%ebx" \ - : "=a" (__res) \ - : "0" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ - "d" ((long)(arg3)),"S" ((long)(arg4)) : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -__asm__ volatile ("push %%ebx ; movl %2,%%ebx ; movl %1,%%eax ; " \ - "int $0x80 ; pop %%ebx" \ - : "=a" (__res) \ - : "i" (__NR_##name),"ri" ((long)(arg1)),"c" ((long)(arg2)), \ - "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \ - : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ -long __res; \ - struct { long __a1; long __a6; } __s = { (long)arg1, (long)arg6 }; \ -__asm__ volatile ("push %%ebp ; push %%ebx ; movl 4(%2),%%ebp ; " \ - "movl 0(%2),%%ebx ; movl %1,%%eax ; int $0x80 ; " \ - "pop %%ebx ; pop %%ebp" \ - : "=a" (__res) \ - : "i" (__NR_##name),"0" ((long)(&__s)),"c" ((long)(arg2)), \ - "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5)) \ - : "memory"); \ -__syscall_return(type,__res); \ -} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-m32r/unistd.h b/include/asm-m32r/unistd.h index 95aa34298d82..5b66bd3c6ed6 100644 --- a/include/asm-m32r/unistd.h +++ b/include/asm-m32r/unistd.h @@ -296,117 +296,6 @@ #ifdef __KERNEL__ #define NR_syscalls 285 -#include - -/* user-visible error numbers are in the range -1 - -MAX_ERRNO: see - * - */ - -#include /* SYSCALL_* */ - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - /* Avoid using "res" which is declared to be in register r0; \ - errno might expand to a function call and clobber it. */ \ - int __err = -(res); \ - errno = __err; \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#define _syscall0(type,name) \ -type name(void) \ -{ \ -register long __scno __asm__ ("r7") = __NR_##name; \ -register long __res __asm__("r0"); \ -__asm__ __volatile__ (\ - "trap #" SYSCALL_VECTOR "|| nop"\ - : "=r" (__res) \ - : "r" (__scno) \ - : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -register long __scno __asm__ ("r7") = __NR_##name; \ -register long __res __asm__ ("r0") = (long)(arg1); \ -__asm__ __volatile__ (\ - "trap #" SYSCALL_VECTOR "|| nop"\ - : "=r" (__res) \ - : "r" (__scno), "0" (__res) \ - : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -register long __scno __asm__ ("r7") = __NR_##name; \ -register long __arg2 __asm__ ("r1") = (long)(arg2); \ -register long __res __asm__ ("r0") = (long)(arg1); \ -__asm__ __volatile__ (\ - "trap #" SYSCALL_VECTOR "|| nop"\ - : "=r" (__res) \ - : "r" (__scno), "0" (__res), "r" (__arg2) \ - : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -register long __scno __asm__ ("r7") = __NR_##name; \ -register long __arg3 __asm__ ("r2") = (long)(arg3); \ -register long __arg2 __asm__ ("r1") = (long)(arg2); \ -register long __res __asm__ ("r0") = (long)(arg1); \ -__asm__ __volatile__ (\ - "trap #" SYSCALL_VECTOR "|| nop"\ - : "=r" (__res) \ - : "r" (__scno), "0" (__res), "r" (__arg2), \ - "r" (__arg3) \ - : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name(type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ -{ \ -register long __scno __asm__ ("r7") = __NR_##name; \ -register long __arg4 __asm__ ("r3") = (long)(arg4); \ -register long __arg3 __asm__ ("r2") = (long)(arg3); \ -register long __arg2 __asm__ ("r1") = (long)(arg2); \ -register long __res __asm__ ("r0") = (long)(arg1); \ -__asm__ __volatile__ (\ - "trap #" SYSCALL_VECTOR "|| nop"\ - : "=r" (__res) \ - : "r" (__scno), "0" (__res), "r" (__arg2), \ - "r" (__arg3), "r" (__arg4) \ - : "memory"); \ -__syscall_return(type,__res); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name(type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -register long __scno __asm__ ("r7") = __NR_##name; \ -register long __arg5 __asm__ ("r4") = (long)(arg5); \ -register long __arg4 __asm__ ("r3") = (long)(arg4); \ -register long __arg3 __asm__ ("r2") = (long)(arg3); \ -register long __arg2 __asm__ ("r1") = (long)(arg2); \ -register long __res __asm__ ("r0") = (long)(arg1); \ -__asm__ __volatile__ (\ - "trap #" SYSCALL_VECTOR "|| nop"\ - : "=r" (__res) \ - : "r" (__scno), "0" (__res), "r" (__arg2), \ - "r" (__arg3), "r" (__arg4), "r" (__arg5) \ - : "memory"); \ -__syscall_return(type,__res); \ -} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_STAT64 diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h index ad4348058c66..fdbb60e6a0d4 100644 --- a/include/asm-m68k/unistd.h +++ b/include/asm-m68k/unistd.h @@ -317,103 +317,6 @@ #ifdef __KERNEL__ #define NR_syscalls 311 -#include - -/* user-visible error numbers are in the range -1 - -MAX_ERRNO: see - */ - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - /* avoid using res which is declared to be in register d0; \ - errno might expand to a function call and clobber it. */ \ - int __err = -(res); \ - errno = __err; \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#define _syscall0(type,name) \ -type name(void) \ -{ \ -register long __res __asm__ ("%d0") = __NR_##name; \ -__asm__ __volatile__ ("trap #0" \ - : "+d" (__res) ); \ -__syscall_return(type,__res); \ -} - -#define _syscall1(type,name,atype,a) \ -type name(atype a) \ -{ \ -register long __res __asm__ ("%d0") = __NR_##name; \ -register long __a __asm__ ("%d1") = (long)(a); \ -__asm__ __volatile__ ("trap #0" \ - : "+d" (__res) \ - : "d" (__a) ); \ -__syscall_return(type,__res); \ -} - -#define _syscall2(type,name,atype,a,btype,b) \ -type name(atype a,btype b) \ -{ \ -register long __res __asm__ ("%d0") = __NR_##name; \ -register long __a __asm__ ("%d1") = (long)(a); \ -register long __b __asm__ ("%d2") = (long)(b); \ -__asm__ __volatile__ ("trap #0" \ - : "+d" (__res) \ - : "d" (__a), "d" (__b) \ - ); \ -__syscall_return(type,__res); \ -} - -#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ -type name(atype a,btype b,ctype c) \ -{ \ -register long __res __asm__ ("%d0") = __NR_##name; \ -register long __a __asm__ ("%d1") = (long)(a); \ -register long __b __asm__ ("%d2") = (long)(b); \ -register long __c __asm__ ("%d3") = (long)(c); \ -__asm__ __volatile__ ("trap #0" \ - : "+d" (__res) \ - : "d" (__a), "d" (__b), \ - "d" (__c) \ - ); \ -__syscall_return(type,__res); \ -} - -#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ -type name (atype a, btype b, ctype c, dtype d) \ -{ \ -register long __res __asm__ ("%d0") = __NR_##name; \ -register long __a __asm__ ("%d1") = (long)(a); \ -register long __b __asm__ ("%d2") = (long)(b); \ -register long __c __asm__ ("%d3") = (long)(c); \ -register long __d __asm__ ("%d4") = (long)(d); \ -__asm__ __volatile__ ("trap #0" \ - : "+d" (__res) \ - : "d" (__a), "d" (__b), \ - "d" (__c), "d" (__d) \ - ); \ -__syscall_return(type,__res); \ -} - -#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ -type name (atype a,btype b,ctype c,dtype d,etype e) \ -{ \ -register long __res __asm__ ("%d0") = __NR_##name; \ -register long __a __asm__ ("%d1") = (long)(a); \ -register long __b __asm__ ("%d2") = (long)(b); \ -register long __c __asm__ ("%d3") = (long)(c); \ -register long __d __asm__ ("%d4") = (long)(d); \ -register long __e __asm__ ("%d5") = (long)(e); \ -__asm__ __volatile__ ("trap #0" \ - : "+d" (__res) \ - : "d" (__a), "d" (__b), \ - "d" (__c), "d" (__d), "d" (__e) \ - ); \ -__syscall_return(type,__res); \ -} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-m68knommu/unistd.h b/include/asm-m68knommu/unistd.h index ebaf03197114..82e03195f325 100644 --- a/include/asm-m68knommu/unistd.h +++ b/include/asm-m68knommu/unistd.h @@ -318,156 +318,6 @@ #ifdef __KERNEL__ #define NR_syscalls 311 -#include - -/* user-visible error numbers are in the range -1 - -MAX_ERRNO: see - */ - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - /* avoid using res which is declared to be in register d0; \ - errno might expand to a function call and clobber it. */ \ - int __err = -(res); \ - errno = __err; \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#define _syscall0(type, name) \ -type name(void) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name) \ - : "cc", "%d0"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - errno = -__res; \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall1(type, name, atype, a) \ -type name(atype a) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "g" ((long)a) \ - : "cc", "%d0", "%d1"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - errno = -__res; \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall2(type, name, atype, a, btype, b) \ -type name(atype a, btype b) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %3, %%d2\n\t" \ - "movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "a" ((long)a), \ - "g" ((long)b) \ - : "cc", "%d0", "%d1", "%d2"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - errno = -__res; \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall3(type, name, atype, a, btype, b, ctype, c) \ -type name(atype a, btype b, ctype c) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %4, %%d3\n\t" \ - "movel %3, %%d2\n\t" \ - "movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "a" ((long)a), \ - "a" ((long)b), \ - "g" ((long)c) \ - : "cc", "%d0", "%d1", "%d2", "%d3"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - errno = -__res; \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \ -type name(atype a, btype b, ctype c, dtype d) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %5, %%d4\n\t" \ - "movel %4, %%d3\n\t" \ - "movel %3, %%d2\n\t" \ - "movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "a" ((long)a), \ - "a" ((long)b), \ - "a" ((long)c), \ - "g" ((long)d) \ - : "cc", "%d0", "%d1", "%d2", "%d3", \ - "%d4"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - errno = -__res; \ - __res = -1; \ - } \ - return (type)__res; \ -} - -#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e) \ -type name(atype a, btype b, ctype c, dtype d, etype e) \ -{ \ - long __res; \ - __asm__ __volatile__ ("movel %6, %%d5\n\t" \ - "movel %5, %%d4\n\t" \ - "movel %4, %%d3\n\t" \ - "movel %3, %%d2\n\t" \ - "movel %2, %%d1\n\t" \ - "movel %1, %%d0\n\t" \ - "trap #0\n\t" \ - "movel %%d0, %0" \ - : "=g" (__res) \ - : "i" (__NR_##name), \ - "a" ((long)a), \ - "a" ((long)b), \ - "a" ((long)c), \ - "a" ((long)d), \ - "g" ((long)e) \ - : "cc", "%d0", "%d1", "%d2", "%d3", \ - "%d4", "%d5"); \ - if ((unsigned long)(__res) >= (unsigned long)(-125)) { \ - errno = -__res; \ - __res = -1; \ - } \ - return (type)__res; \ -} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index ec56aa52f669..696cff39a1d3 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -933,268 +933,6 @@ #ifndef __ASSEMBLY__ -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ - register unsigned long __a3 asm("$7"); \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "li\t$2, %2\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "=r" (__a3) \ - : "i" (__NR_##name) \ - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -/* - * DANGER: This macro isn't usable for the pipe(2) call - * which has a unusual return convention. - */ -#define _syscall1(type,name,atype,a) \ -type name(atype a) \ -{ \ - register unsigned long __a0 asm("$4") = (unsigned long) a; \ - register unsigned long __a3 asm("$7"); \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "li\t$2, %3\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "=r" (__a3) \ - : "r" (__a0), "i" (__NR_##name) \ - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -#define _syscall2(type,name,atype,a,btype,b) \ -type name(atype a, btype b) \ -{ \ - register unsigned long __a0 asm("$4") = (unsigned long) a; \ - register unsigned long __a1 asm("$5") = (unsigned long) b; \ - register unsigned long __a3 asm("$7"); \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "li\t$2, %4\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "=r" (__a3) \ - : "r" (__a0), "r" (__a1), "i" (__NR_##name) \ - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -#define _syscall3(type,name,atype,a,btype,b,ctype,c) \ -type name(atype a, btype b, ctype c) \ -{ \ - register unsigned long __a0 asm("$4") = (unsigned long) a; \ - register unsigned long __a1 asm("$5") = (unsigned long) b; \ - register unsigned long __a2 asm("$6") = (unsigned long) c; \ - register unsigned long __a3 asm("$7"); \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "li\t$2, %5\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "=r" (__a3) \ - : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -#define _syscall4(type,name,atype,a,btype,b,ctype,c,dtype,d) \ -type name(atype a, btype b, ctype c, dtype d) \ -{ \ - register unsigned long __a0 asm("$4") = (unsigned long) a; \ - register unsigned long __a1 asm("$5") = (unsigned long) b; \ - register unsigned long __a2 asm("$6") = (unsigned long) c; \ - register unsigned long __a3 asm("$7") = (unsigned long) d; \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "li\t$2, %5\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "+r" (__a3) \ - : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name) \ - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -#if (_MIPS_SIM == _MIPS_SIM_ABI32) - -/* - * Using those means your brain needs more than an oil change ;-) - */ - -#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ -type name(atype a, btype b, ctype c, dtype d, etype e) \ -{ \ - register unsigned long __a0 asm("$4") = (unsigned long) a; \ - register unsigned long __a1 asm("$5") = (unsigned long) b; \ - register unsigned long __a2 asm("$6") = (unsigned long) c; \ - register unsigned long __a3 asm("$7") = (unsigned long) d; \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "lw\t$2, %6\n\t" \ - "subu\t$29, 32\n\t" \ - "sw\t$2, 16($29)\n\t" \ - "li\t$2, %5\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "addiu\t$29, 32\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "+r" (__a3) \ - : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ - "m" ((unsigned long)e) \ - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ -type name(atype a, btype b, ctype c, dtype d, etype e, ftype f) \ -{ \ - register unsigned long __a0 asm("$4") = (unsigned long) a; \ - register unsigned long __a1 asm("$5") = (unsigned long) b; \ - register unsigned long __a2 asm("$6") = (unsigned long) c; \ - register unsigned long __a3 asm("$7") = (unsigned long) d; \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "lw\t$2, %6\n\t" \ - "lw\t$8, %7\n\t" \ - "subu\t$29, 32\n\t" \ - "sw\t$2, 16($29)\n\t" \ - "sw\t$8, 20($29)\n\t" \ - "li\t$2, %5\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - "addiu\t$29, 32\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "+r" (__a3) \ - : "r" (__a0), "r" (__a1), "r" (__a2), "i" (__NR_##name), \ - "m" ((unsigned long)e), "m" ((unsigned long)f) \ - : "$2", "$8", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -#endif /* (_MIPS_SIM == _MIPS_SIM_ABI32) */ - -#if (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) - -#define _syscall5(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e) \ -type name (atype a,btype b,ctype c,dtype d,etype e) \ -{ \ - register unsigned long __a0 asm("$4") = (unsigned long) a; \ - register unsigned long __a1 asm("$5") = (unsigned long) b; \ - register unsigned long __a2 asm("$6") = (unsigned long) c; \ - register unsigned long __a3 asm("$7") = (unsigned long) d; \ - register unsigned long __a4 asm("$8") = (unsigned long) e; \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "li\t$2, %6\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "+r" (__a3) \ - : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "i" (__NR_##name) \ - : "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -#define _syscall6(type,name,atype,a,btype,b,ctype,c,dtype,d,etype,e,ftype,f) \ -type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \ -{ \ - register unsigned long __a0 asm("$4") = (unsigned long) a; \ - register unsigned long __a1 asm("$5") = (unsigned long) b; \ - register unsigned long __a2 asm("$6") = (unsigned long) c; \ - register unsigned long __a3 asm("$7") = (unsigned long) d; \ - register unsigned long __a4 asm("$8") = (unsigned long) e; \ - register unsigned long __a5 asm("$9") = (unsigned long) f; \ - unsigned long __v0; \ - \ - __asm__ volatile ( \ - ".set\tnoreorder\n\t" \ - "li\t$2, %7\t\t\t# " #name "\n\t" \ - "syscall\n\t" \ - "move\t%0, $2\n\t" \ - ".set\treorder" \ - : "=&r" (__v0), "+r" (__a3) \ - : "r" (__a0), "r" (__a1), "r" (__a2), "r" (__a4), "r" (__a5), \ - "i" (__NR_##name) \ - : "$2", "$9", "$10", "$11", "$12", "$13", "$14", "$15", "$24", \ - "memory"); \ - \ - if (__a3 == 0) \ - return (type) __v0; \ - errno = __v0; \ - return (type) -1; \ -} - -#endif /* (_MIPS_SIM == _MIPS_SIM_NABI32) || (_MIPS_SIM == _MIPS_SIM_ABI64) */ - - #define __ARCH_OMIT_COMPAT_SYS_GETDENTS64 #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index 04b6c17cc59b..0ae954e3d258 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h @@ -334,115 +334,6 @@ #ifndef __ASSEMBLY__ -/* On powerpc a system call basically clobbers the same registers like a - * function call, with the exception of LR (which is needed for the - * "sc; bnslr" sequence) and CR (where only CR0.SO is clobbered to signal - * an error return status). - */ - -#define __syscall_nr(nr, type, name, args...) \ - unsigned long __sc_ret, __sc_err; \ - { \ - register unsigned long __sc_0 __asm__ ("r0"); \ - register unsigned long __sc_3 __asm__ ("r3"); \ - register unsigned long __sc_4 __asm__ ("r4"); \ - register unsigned long __sc_5 __asm__ ("r5"); \ - register unsigned long __sc_6 __asm__ ("r6"); \ - register unsigned long __sc_7 __asm__ ("r7"); \ - register unsigned long __sc_8 __asm__ ("r8"); \ - \ - __sc_loadargs_##nr(name, args); \ - __asm__ __volatile__ \ - ("sc \n\t" \ - "mfcr %0 " \ - : "=&r" (__sc_0), \ - "=&r" (__sc_3), "=&r" (__sc_4), \ - "=&r" (__sc_5), "=&r" (__sc_6), \ - "=&r" (__sc_7), "=&r" (__sc_8) \ - : __sc_asm_input_##nr \ - : "cr0", "ctr", "memory", \ - "r9", "r10","r11", "r12"); \ - __sc_ret = __sc_3; \ - __sc_err = __sc_0; \ - } \ - if (__sc_err & 0x10000000) \ - { \ - errno = __sc_ret; \ - __sc_ret = -1; \ - } \ - return (type) __sc_ret - -#define __sc_loadargs_0(name, dummy...) \ - __sc_0 = __NR_##name -#define __sc_loadargs_1(name, arg1) \ - __sc_loadargs_0(name); \ - __sc_3 = (unsigned long) (arg1) -#define __sc_loadargs_2(name, arg1, arg2) \ - __sc_loadargs_1(name, arg1); \ - __sc_4 = (unsigned long) (arg2) -#define __sc_loadargs_3(name, arg1, arg2, arg3) \ - __sc_loadargs_2(name, arg1, arg2); \ - __sc_5 = (unsigned long) (arg3) -#define __sc_loadargs_4(name, arg1, arg2, arg3, arg4) \ - __sc_loadargs_3(name, arg1, arg2, arg3); \ - __sc_6 = (unsigned long) (arg4) -#define __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5) \ - __sc_loadargs_4(name, arg1, arg2, arg3, arg4); \ - __sc_7 = (unsigned long) (arg5) -#define __sc_loadargs_6(name, arg1, arg2, arg3, arg4, arg5, arg6) \ - __sc_loadargs_5(name, arg1, arg2, arg3, arg4, arg5); \ - __sc_8 = (unsigned long) (arg6) - -#define __sc_asm_input_0 "0" (__sc_0) -#define __sc_asm_input_1 __sc_asm_input_0, "1" (__sc_3) -#define __sc_asm_input_2 __sc_asm_input_1, "2" (__sc_4) -#define __sc_asm_input_3 __sc_asm_input_2, "3" (__sc_5) -#define __sc_asm_input_4 __sc_asm_input_3, "4" (__sc_6) -#define __sc_asm_input_5 __sc_asm_input_4, "5" (__sc_7) -#define __sc_asm_input_6 __sc_asm_input_5, "6" (__sc_8) - -#define _syscall0(type,name) \ -type name(void) \ -{ \ - __syscall_nr(0, type, name); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ - __syscall_nr(1, type, name, arg1); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1, type2 arg2) \ -{ \ - __syscall_nr(2, type, name, arg1, arg2); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1, type2 arg2, type3 arg3) \ -{ \ - __syscall_nr(3, type, name, arg1, arg2, arg3); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ - __syscall_nr(4, type, name, arg1, arg2, arg3, arg4); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ - __syscall_nr(5, type, name, arg1, arg2, arg3, arg4, arg5); \ -} -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ - __syscall_nr(6, type, name, arg1, arg2, arg3, arg4, arg5, arg6); \ -} - - #include #include #include diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h index 71d3c21b84f0..fb6fef97d739 100644 --- a/include/asm-s390/unistd.h +++ b/include/asm-s390/unistd.h @@ -345,160 +345,6 @@ #ifdef __KERNEL__ -#include - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - errno = -(res); \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#define _svc_clobber "1", "cc", "memory" - -#define _syscall0(type,name) \ -type name(void) { \ - register long __svcres asm("2"); \ - long __res; \ - asm volatile( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name) \ - : _svc_clobber); \ - __res = __svcres; \ - __syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) { \ - register type1 __arg1 asm("2") = arg1; \ - register long __svcres asm("2"); \ - long __res; \ - asm volatile( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1) \ - : _svc_clobber); \ - __res = __svcres; \ - __syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1, type2 arg2) { \ - register type1 __arg1 asm("2") = arg1; \ - register type2 __arg2 asm("3") = arg2; \ - register long __svcres asm("2"); \ - long __res; \ - asm volatile( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1), \ - "d" (__arg2) \ - : _svc_clobber ); \ - __res = __svcres; \ - __syscall_return(type,__res); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1, type2 arg2, type3 arg3) { \ - register type1 __arg1 asm("2") = arg1; \ - register type2 __arg2 asm("3") = arg2; \ - register type3 __arg3 asm("4") = arg3; \ - register long __svcres asm("2"); \ - long __res; \ - asm volatile( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1), \ - "d" (__arg2), \ - "d" (__arg3) \ - : _svc_clobber); \ - __res = __svcres; \ - __syscall_return(type,__res); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3, \ - type4,name4) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ - register type1 __arg1 asm("2") = arg1; \ - register type2 __arg2 asm("3") = arg2; \ - register type3 __arg3 asm("4") = arg3; \ - register type4 __arg4 asm("5") = arg4; \ - register long __svcres asm("2"); \ - long __res; \ - asm volatile( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1), \ - "d" (__arg2), \ - "d" (__arg3), \ - "d" (__arg4) \ - : _svc_clobber); \ - __res = __svcres; \ - __syscall_return(type,__res); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3, \ - type4,name4,type5,name5) \ -type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ - type5 arg5) { \ - register type1 __arg1 asm("2") = arg1; \ - register type2 __arg2 asm("3") = arg2; \ - register type3 __arg3 asm("4") = arg3; \ - register type4 __arg4 asm("5") = arg4; \ - register type5 __arg5 asm("6") = arg5; \ - register long __svcres asm("2"); \ - long __res; \ - asm volatile( \ - " .if %1 < 256\n" \ - " svc %b1\n" \ - " .else\n" \ - " la %%r1,%1\n" \ - " svc 0\n" \ - " .endif" \ - : "=d" (__svcres) \ - : "i" (__NR_##name), \ - "0" (__arg1), \ - "d" (__arg2), \ - "d" (__arg3), \ - "d" (__arg4), \ - "d" (__arg5) \ - : _svc_clobber); \ - __res = __svcres; \ - __syscall_return(type,__res); \ -} - #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_SYS_ALARM diff --git a/include/asm-sh/unistd.h b/include/asm-sh/unistd.h index 0cae1d248761..f982073dc6c6 100644 --- a/include/asm-sh/unistd.h +++ b/include/asm-sh/unistd.h @@ -332,143 +332,6 @@ #ifdef __KERNEL__ -#include - -/* user-visible error numbers are in the range -1 - -MAX_ERRNO: - * see */ - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - /* Avoid using "res" which is declared to be in register r0; \ - errno might expand to a function call and clobber it. */ \ - int __err = -(res); \ - errno = __err; \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - -#if defined(__sh2__) || defined(__SH2E__) || defined(__SH2A__) -#define SYSCALL_ARG0 "trapa #0x20" -#define SYSCALL_ARG1 "trapa #0x21" -#define SYSCALL_ARG2 "trapa #0x22" -#define SYSCALL_ARG3 "trapa #0x23" -#define SYSCALL_ARG4 "trapa #0x24" -#define SYSCALL_ARG5 "trapa #0x25" -#define SYSCALL_ARG6 "trapa #0x26" -#else -#define SYSCALL_ARG0 "trapa #0x10" -#define SYSCALL_ARG1 "trapa #0x11" -#define SYSCALL_ARG2 "trapa #0x12" -#define SYSCALL_ARG3 "trapa #0x13" -#define SYSCALL_ARG4 "trapa #0x14" -#define SYSCALL_ARG5 "trapa #0x15" -#define SYSCALL_ARG6 "trapa #0x16" -#endif - -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -__asm__ __volatile__ (SYSCALL_ARG0 \ - : "=z" (__sc0) \ - : "0" (__sc0) \ - : "memory" ); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -__asm__ __volatile__ (SYSCALL_ARG1 \ - : "=z" (__sc0) \ - : "0" (__sc0), "r" (__sc4) \ - : "memory"); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -__asm__ __volatile__ (SYSCALL_ARG2 \ - : "=z" (__sc0) \ - : "0" (__sc0), "r" (__sc4), "r" (__sc5) \ - : "memory"); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -register long __sc6 __asm__ ("r6") = (long) arg3; \ -__asm__ __volatile__ (SYSCALL_ARG3 \ - : "=z" (__sc0) \ - : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6) \ - : "memory"); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -register long __sc0 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -register long __sc6 __asm__ ("r6") = (long) arg3; \ -register long __sc7 __asm__ ("r7") = (long) arg4; \ -__asm__ __volatile__ (SYSCALL_ARG4 \ - : "=z" (__sc0) \ - : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), \ - "r" (__sc7) \ - : "memory" ); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ -register long __sc3 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -register long __sc6 __asm__ ("r6") = (long) arg3; \ -register long __sc7 __asm__ ("r7") = (long) arg4; \ -register long __sc0 __asm__ ("r0") = (long) arg5; \ -__asm__ __volatile__ (SYSCALL_ARG5 \ - : "=z" (__sc0) \ - : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \ - "r" (__sc3) \ - : "memory" ); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ -register long __sc3 __asm__ ("r3") = __NR_##name; \ -register long __sc4 __asm__ ("r4") = (long) arg1; \ -register long __sc5 __asm__ ("r5") = (long) arg2; \ -register long __sc6 __asm__ ("r6") = (long) arg3; \ -register long __sc7 __asm__ ("r7") = (long) arg4; \ -register long __sc0 __asm__ ("r0") = (long) arg5; \ -register long __sc1 __asm__ ("r1") = (long) arg6; \ -__asm__ __volatile__ (SYSCALL_ARG6 \ - : "=z" (__sc0) \ - : "0" (__sc0), "r" (__sc4), "r" (__sc5), "r" (__sc6), "r" (__sc7), \ - "r" (__sc3), "r" (__sc1) \ - : "memory" ); \ -__syscall_return(type,__sc0); \ -} - #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT diff --git a/include/asm-sh64/unistd.h b/include/asm-sh64/unistd.h index ee7828b27ad1..1f38a7aacaaf 100644 --- a/include/asm-sh64/unistd.h +++ b/include/asm-sh64/unistd.h @@ -347,148 +347,6 @@ #ifdef __KERNEL__ #define NR_syscalls 321 -#include - -/* user-visible error numbers are in the range -1 - -MAX_ERRNO: - * see */ - -#define __syscall_return(type, res) \ -do { \ - /* Note: when returning from kernel the return value is in r9 \ - ** This prevents conflicts between return value and arg1 \ - ** when dispatching signal handler, in other words makes \ - ** life easier in the system call epilogue (see entry.S) \ - */ \ - register unsigned long __sr2 __asm__ ("r2") = res; \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - errno = -(res); \ - __sr2 = -1; \ - } \ - return (type) (__sr2); \ -} while (0) - -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ - -#define _syscall0(type,name) \ -type name(void) \ -{ \ -register unsigned long __sc0 __asm__ ("r9") = ((0x10 << 16) | __NR_##name); \ -__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "()" \ - : "=r" (__sc0) \ - : "r" (__sc0) ); \ -__syscall_return(type,__sc0); \ -} - - /* - * The apparent spurious "dummy" assembler comment is *needed*, - * as without it, the compiler treats the arg variables - * as no longer live just before the asm. The compiler can - * then optimize the storage into any registers it wishes. - * The additional dummy statement forces the compiler to put - * the arguments into the correct registers before the TRAPA. - */ -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -register unsigned long __sc0 __asm__ ("r9") = ((0x11 << 16) | __NR_##name); \ -register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ -__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2)" \ - : "=r" (__sc0) \ - : "r" (__sc0), "r" (__sc2)); \ -__asm__ __volatile__ ("!dummy %0 %1" \ - : \ - : "r" (__sc0), "r" (__sc2)); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -register unsigned long __sc0 __asm__ ("r9") = ((0x12 << 16) | __NR_##name); \ -register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ -register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ -__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3)" \ - : "=r" (__sc0) \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3) ); \ -__asm__ __volatile__ ("!dummy %0 %1 %2" \ - : \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3) ); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -register unsigned long __sc0 __asm__ ("r9") = ((0x13 << 16) | __NR_##name); \ -register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ -register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ -register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3; \ -__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3,%4)" \ - : "=r" (__sc0) \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) ); \ -__asm__ __volatile__ ("!dummy %0 %1 %2 %3" \ - : \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4) ); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -register unsigned long __sc0 __asm__ ("r9") = ((0x14 << 16) | __NR_##name); \ -register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ -register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ -register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3; \ -register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4; \ -__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3,%4,%5)" \ - : "=r" (__sc0) \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5) );\ -__asm__ __volatile__ ("!dummy %0 %1 %2 %3 %4" \ - : \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5) );\ -__syscall_return(type,__sc0); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5) \ -{ \ -register unsigned long __sc0 __asm__ ("r9") = ((0x15 << 16) | __NR_##name); \ -register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ -register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ -register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3; \ -register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4; \ -register unsigned long __sc6 __asm__ ("r6") = (unsigned long) arg5; \ -__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3,%4,%5,%6)" \ - : "=r" (__sc0) \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \ - "r" (__sc6)); \ -__asm__ __volatile__ ("!dummy %0 %1 %2 %3 %4 %5" \ - : \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \ - "r" (__sc6)); \ -__syscall_return(type,__sc0); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5, type6, arg6) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6) \ -{ \ -register unsigned long __sc0 __asm__ ("r9") = ((0x16 << 16) | __NR_##name); \ -register unsigned long __sc2 __asm__ ("r2") = (unsigned long) arg1; \ -register unsigned long __sc3 __asm__ ("r3") = (unsigned long) arg2; \ -register unsigned long __sc4 __asm__ ("r4") = (unsigned long) arg3; \ -register unsigned long __sc5 __asm__ ("r5") = (unsigned long) arg4; \ -register unsigned long __sc6 __asm__ ("r6") = (unsigned long) arg5; \ -register unsigned long __sc7 __asm__ ("r7") = (unsigned long) arg6; \ -__asm__ __volatile__ ("trapa %1 !\t\t\t" #name "(%2,%3,%4,%5,%6,%7)" \ - : "=r" (__sc0) \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \ - "r" (__sc6), "r" (__sc7)); \ -__asm__ __volatile__ ("!dummy %0 %1 %2 %3 %4 %5 %6" \ - : \ - : "r" (__sc0), "r" (__sc2), "r" (__sc3), "r" (__sc4), "r" (__sc5), \ - "r" (__sc6), "r" (__sc7)); \ -__syscall_return(type,__sc0); \ -} #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index f7827fa4cd5e..d5b2f8053b3b 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h @@ -329,136 +329,6 @@ * find a free slot in the 0-302 range. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res)\ - : "r" (__g1) \ - : "o0", "cc"); \ -if (__res < -255 || __res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res>=0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -register long __o3 __asm__ ("o3") = (long)(arg4); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res>=0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -register long __o3 __asm__ ("o3") = (long)(arg4); \ -register long __o4 __asm__ ("o4") = (long)(arg5); \ -__asm__ __volatile__ ("t 0x10\n\t" \ - "bcc 1f\n\t" \ - "mov %%o0, %0\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "1:\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \ - : "cc"); \ -if (__res < -255 || __res>=0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 63669dad0d72..47047536f261 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h @@ -332,124 +332,6 @@ * find a free slot in the 0-302 range. */ -#define _syscall0(type,name) \ -type name(void) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -__asm__ __volatile__ ("t 0x6d\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "movcc %%xcc, %%o0, %0\n\t" \ - : "=r" (__res)\ - : "r" (__g1) \ - : "o0", "cc"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -__asm__ __volatile__ ("t 0x6d\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "movcc %%xcc, %%o0, %0\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__g1) \ - : "cc"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -__asm__ __volatile__ ("t 0x6d\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "movcc %%xcc, %%o0, %0\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__g1) \ - : "cc"); \ -if (__res >= 0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -__asm__ __volatile__ ("t 0x6d\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "movcc %%xcc, %%o0, %0\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__g1) \ - : "cc"); \ -if (__res>=0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -register long __o3 __asm__ ("o3") = (long)(arg4); \ -__asm__ __volatile__ ("t 0x6d\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "movcc %%xcc, %%o0, %0\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__g1) \ - : "cc"); \ -if (__res>=0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -register long __g1 __asm__ ("g1") = __NR_##name; \ -register long __o0 __asm__ ("o0") = (long)(arg1); \ -register long __o1 __asm__ ("o1") = (long)(arg2); \ -register long __o2 __asm__ ("o2") = (long)(arg3); \ -register long __o3 __asm__ ("o3") = (long)(arg4); \ -register long __o4 __asm__ ("o4") = (long)(arg5); \ -__asm__ __volatile__ ("t 0x6d\n\t" \ - "sub %%g0, %%o0, %0\n\t" \ - "movcc %%xcc, %%o0, %0\n\t" \ - : "=r" (__res), "=&r" (__o0) \ - : "1" (__o0), "r" (__o1), "r" (__o2), "r" (__o3), "r" (__o4), "r" (__g1) \ - : "cc"); \ -if (__res>=0) \ - return (type) __res; \ -errno = -__res; \ -return -1; \ -} - /* sysconf options, for SunOS compatibility */ #define _SC_ARG_MAX 1 #define _SC_CHILD_MAX 2 diff --git a/include/asm-v850/unistd.h b/include/asm-v850/unistd.h index 737401e7d3ad..2241ed45ecfe 100644 --- a/include/asm-v850/unistd.h +++ b/include/asm-v850/unistd.h @@ -204,168 +204,8 @@ #define __NR_gettid 201 #define __NR_tkill 202 - -/* Syscall protocol: - Syscall number in r12, args in r6-r9, r13-r14 - Return value in r10 - Trap 0 for `short' syscalls, where all the args can fit in function - call argument registers, and trap 1 when there are additional args in - r13-r14. */ - -#define SYSCALL_NUM "r12" -#define SYSCALL_ARG0 "r6" -#define SYSCALL_ARG1 "r7" -#define SYSCALL_ARG2 "r8" -#define SYSCALL_ARG3 "r9" -#define SYSCALL_ARG4 "r13" -#define SYSCALL_ARG5 "r14" -#define SYSCALL_RET "r10" - -#define SYSCALL_SHORT_TRAP "0" -#define SYSCALL_LONG_TRAP "1" - -/* Registers clobbered by any syscall. This _doesn't_ include the syscall - number (r12) or the `extended arg' registers (r13, r14), even though - they are actually clobbered too (this is because gcc's `asm' statement - doesn't allow a clobber to be used as an input or output). */ -#define SYSCALL_CLOBBERS "r1", "r5", "r11", "r15", "r16", \ - "r17", "r18", "r19" - -/* Registers clobbered by a `short' syscall. This includes all clobbers - except the syscall number (r12). */ -#define SYSCALL_SHORT_CLOBBERS SYSCALL_CLOBBERS, "r13", "r14" - #ifdef __KERNEL__ -#include -#include - -#define __syscall_return(type, res) \ - do { \ - /* user-visible error numbers are in the range -1 - -MAX_ERRNO: \ - see */ \ - if (__builtin_expect ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO), 0)) { \ - errno = -(res); \ - res = -1; \ - } \ - return (type) (res); \ - } while (0) - - -#define _syscall0(type, name) \ -type name (void) \ -{ \ - register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ - register unsigned long __ret __asm__ (SYSCALL_RET); \ - __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ - : "=r" (__ret), "=r" (__syscall) \ - : "1" (__syscall) \ - : SYSCALL_SHORT_CLOBBERS); \ - __syscall_return (type, __ret); \ -} - -#define _syscall1(type, name, atype, a) \ -type name (atype a) \ -{ \ - register atype __a __asm__ (SYSCALL_ARG0) = a; \ - register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ - register unsigned long __ret __asm__ (SYSCALL_RET); \ - __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ - : "=r" (__ret), "=r" (__syscall) \ - : "1" (__syscall), "r" (__a) \ - : SYSCALL_SHORT_CLOBBERS); \ - __syscall_return (type, __ret); \ -} - -#define _syscall2(type, name, atype, a, btype, b) \ -type name (atype a, btype b) \ -{ \ - register atype __a __asm__ (SYSCALL_ARG0) = a; \ - register btype __b __asm__ (SYSCALL_ARG1) = b; \ - register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ - register unsigned long __ret __asm__ (SYSCALL_RET); \ - __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ - : "=r" (__ret), "=r" (__syscall) \ - : "1" (__syscall), "r" (__a), "r" (__b) \ - : SYSCALL_SHORT_CLOBBERS); \ - __syscall_return (type, __ret); \ -} - -#define _syscall3(type, name, atype, a, btype, b, ctype, c) \ -type name (atype a, btype b, ctype c) \ -{ \ - register atype __a __asm__ (SYSCALL_ARG0) = a; \ - register btype __b __asm__ (SYSCALL_ARG1) = b; \ - register ctype __c __asm__ (SYSCALL_ARG2) = c; \ - register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ - register unsigned long __ret __asm__ (SYSCALL_RET); \ - __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ - : "=r" (__ret), "=r" (__syscall) \ - : "1" (__syscall), "r" (__a), "r" (__b), "r" (__c) \ - : SYSCALL_SHORT_CLOBBERS); \ - __syscall_return (type, __ret); \ -} - -#define _syscall4(type, name, atype, a, btype, b, ctype, c, dtype, d) \ -type name (atype a, btype b, ctype c, dtype d) \ -{ \ - register atype __a __asm__ (SYSCALL_ARG0) = a; \ - register btype __b __asm__ (SYSCALL_ARG1) = b; \ - register ctype __c __asm__ (SYSCALL_ARG2) = c; \ - register dtype __d __asm__ (SYSCALL_ARG3) = d; \ - register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ - register unsigned long __ret __asm__ (SYSCALL_RET); \ - __asm__ __volatile__ ("trap " SYSCALL_SHORT_TRAP \ - : "=r" (__ret), "=r" (__syscall) \ - : "1" (__syscall), \ - "r" (__a), "r" (__b), "r" (__c), "r" (__d) \ - : SYSCALL_SHORT_CLOBBERS); \ - __syscall_return (type, __ret); \ -} - -#define _syscall5(type, name, atype, a, btype, b, ctype, c, dtype, d, etype,e)\ -type name (atype a, btype b, ctype c, dtype d, etype e) \ -{ \ - register atype __a __asm__ (SYSCALL_ARG0) = a; \ - register btype __b __asm__ (SYSCALL_ARG1) = b; \ - register ctype __c __asm__ (SYSCALL_ARG2) = c; \ - register dtype __d __asm__ (SYSCALL_ARG3) = d; \ - register etype __e __asm__ (SYSCALL_ARG4) = e; \ - register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ - register unsigned long __ret __asm__ (SYSCALL_RET); \ - __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \ - : "=r" (__ret), "=r" (__syscall), "=r" (__e) \ - : "1" (__syscall), \ - "r" (__a), "r" (__b), "r" (__c), "r" (__d), "2" (__e) \ - : SYSCALL_CLOBBERS); \ - __syscall_return (type, __ret); \ -} - -#define __SYSCALL6_TRAP(syscall, ret, a, b, c, d, e, f) \ - __asm__ __volatile__ ("trap " SYSCALL_LONG_TRAP \ - : "=r" (ret), "=r" (syscall), \ - "=r" (e), "=r" (f) \ - : "1" (syscall), \ - "r" (a), "r" (b), "r" (c), "r" (d), \ - "2" (e), "3" (f) \ - : SYSCALL_CLOBBERS); - -#define _syscall6(type, name, atype, a, btype, b, ctype, c, dtype, d, etype, e, ftype, f) \ -type name (atype a, btype b, ctype c, dtype d, etype e, ftype f) \ -{ \ - register atype __a __asm__ (SYSCALL_ARG0) = a; \ - register btype __b __asm__ (SYSCALL_ARG1) = b; \ - register ctype __c __asm__ (SYSCALL_ARG2) = c; \ - register dtype __d __asm__ (SYSCALL_ARG3) = d; \ - register etype __e __asm__ (SYSCALL_ARG4) = e; \ - register etype __f __asm__ (SYSCALL_ARG5) = f; \ - register unsigned long __syscall __asm__ (SYSCALL_NUM) = __NR_##name; \ - register unsigned long __ret __asm__ (SYSCALL_RET); \ - __SYSCALL6_TRAP(__syscall, __ret, __a, __b, __c, __d, __e, __f); \ - __syscall_return (type, __ret); \ -} - - #define __ARCH_WANT_IPC_PARSE_VERSION #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_STAT64 diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index 777288eb7e75..c5f596e71faa 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h @@ -622,25 +622,7 @@ __SYSCALL(__NR_move_pages, sys_move_pages) #define __NR_syscall_max __NR_move_pages -#ifdef __KERNEL__ -#include -#endif - #ifndef __NO_STUBS - -/* user-visible error numbers are in the range -1 - -MAX_ERRNO */ - -#define __syscall_clobber "r11","rcx","memory" - -#define __syscall_return(type, res) \ -do { \ - if ((unsigned long)(res) >= (unsigned long)(-MAX_ERRNO)) { \ - errno = -(res); \ - res = -1; \ - } \ - return (type) (res); \ -} while (0) - #define __ARCH_WANT_OLD_READDIR #define __ARCH_WANT_OLD_STAT #define __ARCH_WANT_SYS_ALARM @@ -664,87 +646,6 @@ do { \ #define __ARCH_WANT_SYS_TIME #define __ARCH_WANT_COMPAT_SYS_TIME -#define __syscall "syscall" - -#define _syscall0(type,name) \ -type name(void) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name) : __syscall_clobber ); \ -__syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type1,arg1) \ -type name(type1 arg1) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" ((long)(arg1)) : __syscall_clobber ); \ -__syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type1,arg1,type2,arg2) \ -type name(type1 arg1,type2 arg2) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)) : __syscall_clobber ); \ -__syscall_return(type,__res); \ -} - -#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -__asm__ volatile (__syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ - "d" ((long)(arg3)) : __syscall_clobber); \ -__syscall_return(type,__res); \ -} - -#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ -{ \ -long __res; \ -__asm__ volatile ("movq %5,%%r10 ;" __syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ - "d" ((long)(arg3)),"g" ((long)(arg4)) : __syscall_clobber,"r10" ); \ -__syscall_return(type,__res); \ -} - -#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; " __syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ - "d" ((long)(arg3)),"g" ((long)(arg4)),"g" ((long)(arg5)) : \ - __syscall_clobber,"r8","r10" ); \ -__syscall_return(type,__res); \ -} - -#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ - type5,arg5,type6,arg6) \ -type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5,type6 arg6) \ -{ \ -long __res; \ -__asm__ volatile ("movq %5,%%r10 ; movq %6,%%r8 ; movq %7,%%r9 ; " __syscall \ - : "=a" (__res) \ - : "0" (__NR_##name),"D" ((long)(arg1)),"S" ((long)(arg2)), \ - "d" ((long)(arg3)), "g" ((long)(arg4)), "g" ((long)(arg5)), \ - "g" ((long)(arg6)) : \ - __syscall_clobber,"r8","r10","r9" ); \ -__syscall_return(type,__res); \ -} - #ifdef __KERNEL__ #ifndef __ASSEMBLY__ diff --git a/include/asm-xtensa/unistd.h b/include/asm-xtensa/unistd.h index 411f810a55c6..2e1a1b997e7d 100644 --- a/include/asm-xtensa/unistd.h +++ b/include/asm-xtensa/unistd.h @@ -218,190 +218,6 @@ #define SYSXTENSA_COUNT 5 /* count of syscall0 functions*/ -#ifdef __KERNEL__ -#include - -#define __syscall_return(type, res) return ((type)(res)) - -/* Tensilica's xt-xcc compiler is much more agressive at code - * optimization than gcc. Multiple __asm__ statements are - * insufficient for xt-xcc because subsequent optimization passes - * (beyond the front-end that knows of __asm__ statements and other - * such GNU Extensions to C) can modify the register selection for - * containment of C variables. - * - * xt-xcc cannot modify the contents of a single __asm__ statement, so - * we create single-asm versions of the syscall macros that are - * suitable and optimal for both xt-xcc and gcc. - * - * Linux takes system-call arguments in registers. The following - * design is optimized for user-land apps (e.g., glibc) which - * typically have a function wrapper around the "syscall" assembly - * instruction. It satisfies the Xtensa ABI while minizing argument - * shifting. - * - * The Xtensa ABI and software conventions require the system-call - * number in a2. If an argument exists in a2, we move it to the next - * available register. Note that for improved efficiency, we do NOT - * shift all parameters down one register to maintain the original - * order. - * - * At best case (zero arguments), we just write the syscall number to - * a2. At worst case (1 to 6 arguments), we move the argument in a2 - * to the next available register, then write the syscall number to - * a2. - * - * For clarity, the following truth table enumerates all possibilities. - * - * arguments syscall number arg0, arg1, arg2, arg3, arg4, arg5 - * --------- -------------- ---------------------------------- - * 0 a2 - * 1 a2 a3 - * 2 a2 a4, a3 - * 3 a2 a5, a3, a4 - * 4 a2 a6, a3, a4, a5 - * 5 a2 a7, a3, a4, a5, a6 - * 6 a2 a8, a3, a4, a5, a6, a7 - */ - -#define _syscall0(type,name) \ -type name(void) \ -{ \ -long __res; \ -__asm__ __volatile__ ( \ - " movi a2, %1 \n" \ - " syscall \n" \ - " mov %0, a2 \n" \ - : "=a" (__res) \ - : "i" (__NR_##name) \ - : "a2" \ - ); \ -__syscall_return(type,__res); \ -} - -#define _syscall1(type,name,type0,arg0) \ -type name(type0 arg0) \ -{ \ -long __res; \ -__asm__ __volatile__ ( \ - " mov a3, %2 \n" \ - " movi a2, %1 \n" \ - " syscall \n" \ - " mov %0, a2 \n" \ - : "=a" (__res) \ - : "i" (__NR_##name), "a" (arg0) \ - : "a2", "a3" \ - ); \ -__syscall_return(type,__res); \ -} - -#define _syscall2(type,name,type0,arg0,type1,arg1) \ -type name(type0 arg0,type1 arg1) \ -{ \ -long __res; \ -__asm__ __volatile__ ( \ - " mov a4, %2 \n" \ - " mov a3, %3 \n" \ - " movi a2, %1 \n" \ - " syscall \n" \ - " mov %0, a2 \n" \ - : "=a" (__res) \ - : "i" (__NR_##name), "a" (arg0), "a" (arg1) \ - : "a2", "a3", "a4" \ - ); \ -__syscall_return(type,__res); \ -} - -#define _syscall3(type,name,type0,arg0,type1,arg1,type2,arg2) \ -type name(type0 arg0,type1 arg1,type2 arg2) \ -{ \ -long __res; \ -__asm__ __volatile__ ( \ - " mov a5, %2 \n" \ - " mov a4, %4 \n" \ - " mov a3, %3 \n" \ - " movi a2, %1 \n" \ - " syscall \n" \ - " mov %0, a2 \n" \ - : "=a" (__res) \ - : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2) \ - : "a2", "a3", "a4", "a5" \ - ); \ -__syscall_return(type,__res); \ -} - -#define _syscall4(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3) \ -type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3) \ -{ \ -long __res; \ -__asm__ __volatile__ ( \ - " mov a6, %2 \n" \ - " mov a5, %5 \n" \ - " mov a4, %4 \n" \ - " mov a3, %3 \n" \ - " movi a2, %1 \n" \ - " syscall \n" \ - " mov %0, a2 \n" \ - : "=a" (__res) \ - : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), "a" (arg3) \ - : "a2", "a3", "a4", "a5", "a6" \ - ); \ -__syscall_return(type,__res); \ -} - -/* Note that we save and restore the a7 frame pointer. - * Including a7 in the clobber list doesn't do what you'd expect. - */ -#define _syscall5(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ -type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4) \ -{ \ -long __res; \ -__asm__ __volatile__ ( \ - " mov a9, a7 \n" \ - " mov a7, %2 \n" \ - " mov a6, %6 \n" \ - " mov a5, %5 \n" \ - " mov a4, %4 \n" \ - " mov a3, %3 \n" \ - " movi a2, %1 \n" \ - " syscall \n" \ - " mov a7, a9 \n" \ - " mov %0, a2 \n" \ - : "=a" (__res) \ - : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \ - "a" (arg3), "a" (arg4) \ - : "a2", "a3", "a4", "a5", "a6", "a9" \ - ); \ -__syscall_return(type,__res); \ -} - -/* Note that we save and restore the a7 frame pointer. - * Including a7 in the clobber list doesn't do what you'd expect. - */ -#define _syscall6(type,name,type0,arg0,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \ -type name(type0 arg0,type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ -{ \ -long __res; \ -__asm__ __volatile__ ( \ - " mov a9, a7 \n" \ - " mov a8, %2 \n" \ - " mov a7, %7 \n" \ - " mov a6, %6 \n" \ - " mov a5, %5 \n" \ - " mov a4, %4 \n" \ - " mov a3, %3 \n" \ - " movi a2, %1 \n" \ - " syscall \n" \ - " mov a7, a9 \n" \ - " mov %0, a2 \n" \ - : "=a" (__res) \ - : "i" (__NR_##name), "a" (arg0), "a" (arg1), "a" (arg2), \ - "a" (arg3), "a" (arg4), "a" (arg5) \ - : "a2", "a3", "a4", "a5", "a6", "a8", "a9" \ - ); \ -__syscall_return(type,__res); \ -} - /* * "Conditional" syscalls * -- cgit v1.2.3 From 83df8db9e62129975fab6d800fb381faf0dfee74 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 6 Dec 2006 20:38:14 -0800 Subject: [PATCH] declare smp_call_function_single in generic code smp_call_function_single() needs to be visible in non-SMP builds, to fix: arch/x86_64/kernel/vsyscall.c:283: warning: implicit declaration of function 'smp_call_function_single' Signed-off-by: Randy Dunlap Cc: Ingo Molnar Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-x86_64/smp.h | 7 ------- include/linux/smp.h | 7 +++++++ 2 files changed, 7 insertions(+), 7 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/smp.h b/include/asm-x86_64/smp.h index d6b7c057edba..f1bdd500d7ac 100644 --- a/include/asm-x86_64/smp.h +++ b/include/asm-x86_64/smp.h @@ -118,13 +118,6 @@ static __inline int logical_smp_processor_id(void) #define cpu_physical_id(cpu) x86_cpu_to_apicid[cpu] #else #define cpu_physical_id(cpu) boot_cpu_id -static inline int smp_call_function_single(int cpuid, void (*func) (void *info), - void *info, int retry, int wait) -{ - /* Disable interrupts here? */ - func(info); - return 0; -} #endif /* !CONFIG_SMP */ #endif diff --git a/include/linux/smp.h b/include/linux/smp.h index 51649987f691..7ba23ec8211b 100644 --- a/include/linux/smp.h +++ b/include/linux/smp.h @@ -99,6 +99,13 @@ static inline int up_smp_call_function(void) static inline void smp_send_reschedule(int cpu) { } #define num_booting_cpus() 1 #define smp_prepare_boot_cpu() do {} while (0) +static inline int smp_call_function_single(int cpuid, void (*func) (void *info), + void *info, int retry, int wait) +{ + /* Disable interrupts here? */ + func(info); + return 0; +} #endif /* !SMP */ -- cgit v1.2.3 From f67637ee4b5d90d41160d755b9a8cca18c394586 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 6 Dec 2006 20:38:54 -0800 Subject: [PATCH] Add struct dev pointer to dma_is_consistent() dma_is_consistent() is ill-designed in that it does not have a struct device pointer argument which makes proper support for systems that consist of a mix of coherent and non-coherent DMA devices hard. Change dma_is_consistent to take a struct device pointer as first argument and fix the sole caller to pass it. Signed-off-by: Ralf Baechle Cc: James Bottomley Cc: "David S. Miller" Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/DMA-API.txt | 6 +++--- arch/mips/mm/dma-coherent.c | 2 +- arch/mips/mm/dma-ip27.c | 2 +- arch/mips/mm/dma-ip32.c | 2 +- arch/mips/mm/dma-noncoherent.c | 2 +- drivers/scsi/53c700.c | 2 +- include/asm-alpha/dma-mapping.h | 2 +- include/asm-arm/dma-mapping.h | 2 +- include/asm-avr32/dma-mapping.h | 2 +- include/asm-cris/dma-mapping.h | 2 +- include/asm-frv/dma-mapping.h | 2 +- include/asm-generic/dma-mapping.h | 2 +- include/asm-i386/dma-mapping.h | 2 +- include/asm-ia64/dma-mapping.h | 2 +- include/asm-m68k/dma-mapping.h | 2 +- include/asm-mips/dma-mapping.h | 2 +- include/asm-parisc/dma-mapping.h | 2 +- include/asm-powerpc/dma-mapping.h | 4 ++-- include/asm-sparc64/dma-mapping.h | 2 +- include/asm-um/dma-mapping.h | 2 +- include/asm-x86_64/dma-mapping.h | 2 +- include/asm-xtensa/dma-mapping.h | 2 +- 22 files changed, 25 insertions(+), 25 deletions(-) (limited to 'include/asm-x86_64') diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 8621a064f7e1..3dc1f9125caf 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -431,10 +431,10 @@ be identical to those passed in (and returned by dma_alloc_noncoherent()). int -dma_is_consistent(dma_addr_t dma_handle) +dma_is_consistent(struct device *dev, dma_addr_t dma_handle) -returns true if the memory pointed to by the dma_handle is actually -consistent. +returns true if the device dev is performing consistent DMA on the memory +area pointed to by the dma_handle. int dma_get_cache_alignment(void) diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c index 7fa5fd16e46b..18bc83e577c1 100644 --- a/arch/mips/mm/dma-coherent.c +++ b/arch/mips/mm/dma-coherent.c @@ -190,7 +190,7 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(dma_addr_t dma_addr) +int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c index 8da19fd22ac6..8e9a5a8f5d65 100644 --- a/arch/mips/mm/dma-ip27.c +++ b/arch/mips/mm/dma-ip27.c @@ -197,7 +197,7 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(dma_addr_t dma_addr) +int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c index ec54ed0d26ff..08720a42100f 100644 --- a/arch/mips/mm/dma-ip32.c +++ b/arch/mips/mm/dma-ip32.c @@ -363,7 +363,7 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(dma_addr_t dma_addr) +int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index 2eeffe5c2a3a..4a3efc633373 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c @@ -299,7 +299,7 @@ int dma_supported(struct device *dev, u64 mask) EXPORT_SYMBOL(dma_supported); -int dma_is_consistent(dma_addr_t dma_addr) +int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index 335a25540c08..acee062cd6f6 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -313,7 +313,7 @@ NCR_700_detect(struct scsi_host_template *tpnt, hostdata->status = memory + STATUS_OFFSET; /* all of these offsets are L1_CACHE_BYTES separated. It is fatal * if this isn't sufficient separation to avoid dma flushing issues */ - BUG_ON(!dma_is_consistent(pScript) && L1_CACHE_BYTES < dma_get_cache_alignment()); + BUG_ON(!dma_is_consistent(hostdata->dev, pScript) && L1_CACHE_BYTES < dma_get_cache_alignment()); hostdata->slots = (struct NCR_700_command_slot *)(memory + SLOTS_OFFSET); hostdata->dev = dev; diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h index b9ff4d8cb33a..b274bf6317c7 100644 --- a/include/asm-alpha/dma-mapping.h +++ b/include/asm-alpha/dma-mapping.h @@ -51,7 +51,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(dev) (1) +#define dma_is_consistent(d, h) (1) int dma_set_mask(struct device *dev, u64 mask); diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h index 666617711c81..9bc46b486afb 100644 --- a/include/asm-arm/dma-mapping.h +++ b/include/asm-arm/dma-mapping.h @@ -48,7 +48,7 @@ static inline int dma_get_cache_alignment(void) return 32; } -static inline int dma_is_consistent(dma_addr_t handle) +static inline int dma_is_consistent(struct device *dev, dma_addr_t handle) { return !!arch_is_coherent(); } diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h index 4c40cb41cdf8..44630be2ee22 100644 --- a/include/asm-avr32/dma-mapping.h +++ b/include/asm-avr32/dma-mapping.h @@ -307,7 +307,7 @@ dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -static inline int dma_is_consistent(dma_addr_t dma_addr) +static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 1; } diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h index cbf1a98f0129..af704fdd3d0d 100644 --- a/include/asm-cris/dma-mapping.h +++ b/include/asm-cris/dma-mapping.h @@ -156,7 +156,7 @@ dma_get_cache_alignment(void) return (1 << INTERNODE_CACHE_SHIFT); } -#define dma_is_consistent(d) (1) +#define dma_is_consistent(d, h) (1) static inline void dma_cache_sync(void *vaddr, size_t size, diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h index e9fc1d47797e..7b97fc785f72 100644 --- a/include/asm-frv/dma-mapping.h +++ b/include/asm-frv/dma-mapping.h @@ -172,7 +172,7 @@ int dma_get_cache_alignment(void) return 1 << L1_CACHE_SHIFT; } -#define dma_is_consistent(d) (1) +#define dma_is_consistent(d, h) (1) static inline void dma_cache_sync(void *vaddr, size_t size, diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h index b541e48cc545..b9be3fc344c7 100644 --- a/include/asm-generic/dma-mapping.h +++ b/include/asm-generic/dma-mapping.h @@ -266,7 +266,7 @@ dma_error(dma_addr_t dma_addr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d) (1) +#define dma_is_consistent(d, h) (1) static inline int dma_get_cache_alignment(void) diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h index 81999a3ebe7c..7da64c9f1738 100644 --- a/include/asm-i386/dma-mapping.h +++ b/include/asm-i386/dma-mapping.h @@ -156,7 +156,7 @@ dma_get_cache_alignment(void) return (1 << INTERNODE_CACHE_SHIFT); } -#define dma_is_consistent(d) (1) +#define dma_is_consistent(d, h) (1) static inline void dma_cache_sync(void *vaddr, size_t size, diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h index 99a8f8e1218c..4b075bc032ec 100644 --- a/include/asm-ia64/dma-mapping.h +++ b/include/asm-ia64/dma-mapping.h @@ -59,6 +59,6 @@ dma_cache_sync (void *vaddr, size_t size, enum dma_data_direction dir) mb(); } -#define dma_is_consistent(dma_handle) (1) /* all we do is coherent memory... */ +#define dma_is_consistent(d, h) (1) /* all we do is coherent memory... */ #endif /* _ASM_IA64_DMA_MAPPING_H */ diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h index d90d841d3dfd..efc89c12f837 100644 --- a/include/asm-m68k/dma-mapping.h +++ b/include/asm-m68k/dma-mapping.h @@ -21,7 +21,7 @@ static inline int dma_get_cache_alignment(void) return 1 << L1_CACHE_SHIFT; } -static inline int dma_is_consistent(dma_addr_t dma_addr) +static inline int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return 0; } diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index 43288634c38a..e17f70d7b702 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h @@ -63,7 +63,7 @@ dma_get_cache_alignment(void) return 128; } -extern int dma_is_consistent(dma_addr_t dma_addr); +extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr); extern void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction); diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h index 1e387e1dad30..c40d48afdc52 100644 --- a/include/asm-parisc/dma-mapping.h +++ b/include/asm-parisc/dma-mapping.h @@ -191,7 +191,7 @@ dma_get_cache_alignment(void) } static inline int -dma_is_consistent(dma_addr_t dma_addr) +dma_is_consistent(struct device *dev, dma_addr_t dma_addr) { return (hppa_dma_ops->dma_sync_single_for_cpu == NULL); } diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index 7e38b5fddada..3cf635b53b88 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -342,9 +342,9 @@ static inline int dma_mapping_error(dma_addr_t dma_addr) #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) #ifdef CONFIG_NOT_COHERENT_CACHE -#define dma_is_consistent(d) (0) +#define dma_is_consistent(d, h) (0) #else -#define dma_is_consistent(d) (1) +#define dma_is_consistent(d, h) (1) #endif static inline int dma_get_cache_alignment(void) diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h index 27c46fbeebd6..5fe0072f3f82 100644 --- a/include/asm-sparc64/dma-mapping.h +++ b/include/asm-sparc64/dma-mapping.h @@ -181,7 +181,7 @@ dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t siz #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d) (1) +#define dma_is_consistent(d, h) (1) static inline int dma_get_cache_alignment(void) diff --git a/include/asm-um/dma-mapping.h b/include/asm-um/dma-mapping.h index babd29895114..defb5b8307de 100644 --- a/include/asm-um/dma-mapping.h +++ b/include/asm-um/dma-mapping.h @@ -94,7 +94,7 @@ dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems, #define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) #define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) -#define dma_is_consistent(d) (1) +#define dma_is_consistent(d, h) (1) static inline int dma_get_cache_alignment(void) diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h index 10174b110a5c..c8cc4887fba6 100644 --- a/include/asm-x86_64/dma-mapping.h +++ b/include/asm-x86_64/dma-mapping.h @@ -180,7 +180,7 @@ static inline int dma_get_cache_alignment(void) return boot_cpu_data.x86_clflush_size; } -#define dma_is_consistent(h) 1 +#define dma_is_consistent(d, h) 1 extern int dma_set_mask(struct device *dev, u64 mask); diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h index c39c91dfcc69..827d1dfd9e1d 100644 --- a/include/asm-xtensa/dma-mapping.h +++ b/include/asm-xtensa/dma-mapping.h @@ -170,7 +170,7 @@ dma_get_cache_alignment(void) return L1_CACHE_BYTES; } -#define dma_is_consistent(d) (1) +#define dma_is_consistent(d, h) (1) static inline void dma_cache_sync(void *vaddr, size_t size, -- cgit v1.2.3 From d3fa72e4556ec1f04e46a0d561d9e785ecaa173d Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 6 Dec 2006 20:38:56 -0800 Subject: [PATCH] Pass struct dev pointer to dma_cache_sync() Pass struct dev pointer to dma_cache_sync() dma_cache_sync() is ill-designed in that it does not have a struct device pointer argument which makes proper support for systems that consist of a mix of coherent and non-coherent DMA devices hard. Change dma_cache_sync to take a struct device pointer as first argument and fix all its callers to pass it. Signed-off-by: Ralf Baechle Cc: James Bottomley Cc: "David S. Miller" Cc: Greg KH Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- Documentation/DMA-API.txt | 2 +- arch/avr32/mm/dma-coherent.c | 2 +- arch/mips/mm/dma-coherent.c | 2 +- arch/mips/mm/dma-ip27.c | 2 +- arch/mips/mm/dma-ip32.c | 3 +- arch/mips/mm/dma-noncoherent.c | 3 +- drivers/net/lasi_82596.c | 94 +++++++++++++++++++-------------------- drivers/scsi/53c700.c | 80 ++++++++++++++++++--------------- drivers/scsi/53c700.h | 16 +++---- drivers/serial/mpsc.c | 22 ++++----- include/asm-alpha/dma-mapping.h | 2 +- include/asm-avr32/dma-mapping.h | 3 +- include/asm-cris/dma-mapping.h | 2 +- include/asm-frv/dma-mapping.h | 2 +- include/asm-generic/dma-mapping.h | 2 +- include/asm-i386/dma-mapping.h | 2 +- include/asm-ia64/dma-mapping.h | 3 +- include/asm-m68k/dma-mapping.h | 2 +- include/asm-mips/dma-mapping.h | 2 +- include/asm-parisc/dma-mapping.h | 2 +- include/asm-powerpc/dma-mapping.h | 2 +- include/asm-sh/dma-mapping.h | 2 +- include/asm-sh64/dma-mapping.h | 2 +- include/asm-sparc64/dma-mapping.h | 2 +- include/asm-um/dma-mapping.h | 2 +- include/asm-x86_64/dma-mapping.h | 3 +- include/asm-xtensa/dma-mapping.h | 2 +- 27 files changed, 137 insertions(+), 126 deletions(-) (limited to 'include/asm-x86_64') diff --git a/Documentation/DMA-API.txt b/Documentation/DMA-API.txt index 3dc1f9125caf..805db4b2cba6 100644 --- a/Documentation/DMA-API.txt +++ b/Documentation/DMA-API.txt @@ -459,7 +459,7 @@ anything like this. You must also be extra careful about accessing memory you intend to sync partially. void -dma_cache_sync(void *vaddr, size_t size, +dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) Do a partial sync of memory that was allocated by diff --git a/arch/avr32/mm/dma-coherent.c b/arch/avr32/mm/dma-coherent.c index 44ab8a7bdae2..b68d669f823d 100644 --- a/arch/avr32/mm/dma-coherent.c +++ b/arch/avr32/mm/dma-coherent.c @@ -11,7 +11,7 @@ #include #include -void dma_cache_sync(void *vaddr, size_t size, int direction) +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, int direction) { /* * No need to sync an uncached area diff --git a/arch/mips/mm/dma-coherent.c b/arch/mips/mm/dma-coherent.c index 18bc83e577c1..5697c6e250a3 100644 --- a/arch/mips/mm/dma-coherent.c +++ b/arch/mips/mm/dma-coherent.c @@ -197,7 +197,7 @@ int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(void *vaddr, size_t size, +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); diff --git a/arch/mips/mm/dma-ip27.c b/arch/mips/mm/dma-ip27.c index 8e9a5a8f5d65..f088344db465 100644 --- a/arch/mips/mm/dma-ip27.c +++ b/arch/mips/mm/dma-ip27.c @@ -204,7 +204,7 @@ int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(void *vaddr, size_t size, +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); diff --git a/arch/mips/mm/dma-ip32.c b/arch/mips/mm/dma-ip32.c index 08720a42100f..b42b6f7456e6 100644 --- a/arch/mips/mm/dma-ip32.c +++ b/arch/mips/mm/dma-ip32.c @@ -370,7 +370,8 @@ int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction direction) { if (direction == DMA_NONE) return; diff --git a/arch/mips/mm/dma-noncoherent.c b/arch/mips/mm/dma-noncoherent.c index 4a3efc633373..8cecef0957c3 100644 --- a/arch/mips/mm/dma-noncoherent.c +++ b/arch/mips/mm/dma-noncoherent.c @@ -306,7 +306,8 @@ int dma_is_consistent(struct device *dev, dma_addr_t dma_addr) EXPORT_SYMBOL(dma_is_consistent); -void dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction direction) +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction direction) { if (direction == DMA_NONE) return; diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index f4d815bca643..ea392f2a5aa2 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -119,14 +119,14 @@ #define DEB(x,y) if (i596_debug & (x)) { y; } -#define CHECK_WBACK(addr,len) \ - do { dma_cache_sync((void *)addr, len, DMA_TO_DEVICE); } while (0) +#define CHECK_WBACK(priv, addr,len) \ + do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_TO_DEVICE); } while (0) -#define CHECK_INV(addr,len) \ - do { dma_cache_sync((void *)addr, len, DMA_FROM_DEVICE); } while(0) +#define CHECK_INV(priv, addr,len) \ + do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_FROM_DEVICE); } while(0) -#define CHECK_WBACK_INV(addr,len) \ - do { dma_cache_sync((void *)addr, len, DMA_BIDIRECTIONAL); } while (0) +#define CHECK_WBACK_INV(priv, addr,len) \ + do { dma_cache_sync((priv)->dev, (void *)addr, len, DMA_BIDIRECTIONAL); } while (0) #define PA_I82596_RESET 0 /* Offsets relative to LASI-LAN-Addr.*/ @@ -449,10 +449,10 @@ static inline void MPU_PORT(struct net_device *dev, int c, dma_addr_t x) static inline int wait_istat(struct net_device *dev, struct i596_private *lp, int delcnt, char *str) { - CHECK_INV(&(lp->iscp), sizeof(struct i596_iscp)); + CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp)); while (--delcnt && lp->iscp.stat) { udelay(10); - CHECK_INV(&(lp->iscp), sizeof(struct i596_iscp)); + CHECK_INV(lp, &(lp->iscp), sizeof(struct i596_iscp)); } if (!delcnt) { printk("%s: %s, iscp.stat %04x, didn't clear\n", @@ -466,10 +466,10 @@ static inline int wait_istat(struct net_device *dev, struct i596_private *lp, in static inline int wait_cmd(struct net_device *dev, struct i596_private *lp, int delcnt, char *str) { - CHECK_INV(&(lp->scb), sizeof(struct i596_scb)); + CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); while (--delcnt && lp->scb.command) { udelay(10); - CHECK_INV(&(lp->scb), sizeof(struct i596_scb)); + CHECK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); } if (!delcnt) { printk("%s: %s, status %4.4x, cmd %4.4x.\n", @@ -522,7 +522,7 @@ static void i596_display_data(struct net_device *dev) rbd, rbd->count, rbd->b_next, rbd->b_data, rbd->size); rbd = rbd->v_next; } while (rbd != lp->rbd_head); - CHECK_INV(lp, sizeof(struct i596_private)); + CHECK_INV(lp, lp, sizeof(struct i596_private)); } @@ -592,7 +592,7 @@ static inline void init_rx_bufs(struct net_device *dev) rfd->b_next = WSWAPrfd(virt_to_dma(lp,lp->rfds)); rfd->cmd = CMD_EOL|CMD_FLEX; - CHECK_WBACK_INV(lp, sizeof(struct i596_private)); + CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private)); } static inline void remove_rx_bufs(struct net_device *dev) @@ -629,7 +629,7 @@ static void rebuild_rx_bufs(struct net_device *dev) lp->rbd_head = lp->rbds; lp->rfds[0].rbd = WSWAPrbd(virt_to_dma(lp,lp->rbds)); - CHECK_WBACK_INV(lp, sizeof(struct i596_private)); + CHECK_WBACK_INV(lp, lp, sizeof(struct i596_private)); } @@ -663,8 +663,8 @@ static int init_i596_mem(struct net_device *dev) DEB(DEB_INIT, printk("%s: starting i82596.\n", dev->name)); - CHECK_WBACK(&(lp->scp), sizeof(struct i596_scp)); - CHECK_WBACK(&(lp->iscp), sizeof(struct i596_iscp)); + CHECK_WBACK(lp, &(lp->scp), sizeof(struct i596_scp)); + CHECK_WBACK(lp, &(lp->iscp), sizeof(struct i596_iscp)); MPU_PORT(dev, PORT_ALTSCP, virt_to_dma(lp,&lp->scp)); @@ -678,25 +678,25 @@ static int init_i596_mem(struct net_device *dev) rebuild_rx_bufs(dev); lp->scb.command = 0; - CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); enable_irq(dev->irq); /* enable IRQs from LAN */ DEB(DEB_INIT, printk("%s: queuing CmdConfigure\n", dev->name)); memcpy(lp->cf_cmd.i596_config, init_setup, 14); lp->cf_cmd.cmd.command = CmdConfigure; - CHECK_WBACK(&(lp->cf_cmd), sizeof(struct cf_cmd)); + CHECK_WBACK(lp, &(lp->cf_cmd), sizeof(struct cf_cmd)); i596_add_cmd(dev, &lp->cf_cmd.cmd); DEB(DEB_INIT, printk("%s: queuing CmdSASetup\n", dev->name)); memcpy(lp->sa_cmd.eth_addr, dev->dev_addr, 6); lp->sa_cmd.cmd.command = CmdSASetup; - CHECK_WBACK(&(lp->sa_cmd), sizeof(struct sa_cmd)); + CHECK_WBACK(lp, &(lp->sa_cmd), sizeof(struct sa_cmd)); i596_add_cmd(dev, &lp->sa_cmd.cmd); DEB(DEB_INIT, printk("%s: queuing CmdTDR\n", dev->name)); lp->tdr_cmd.cmd.command = CmdTDR; - CHECK_WBACK(&(lp->tdr_cmd), sizeof(struct tdr_cmd)); + CHECK_WBACK(lp, &(lp->tdr_cmd), sizeof(struct tdr_cmd)); i596_add_cmd(dev, &lp->tdr_cmd.cmd); spin_lock_irqsave (&lp->lock, flags); @@ -708,7 +708,7 @@ static int init_i596_mem(struct net_device *dev) DEB(DEB_INIT, printk("%s: Issuing RX_START\n", dev->name)); lp->scb.command = RX_START; lp->scb.rfd = WSWAPrfd(virt_to_dma(lp,lp->rfds)); - CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); CA(dev); @@ -740,13 +740,13 @@ static inline int i596_rx(struct net_device *dev) rfd = lp->rfd_head; /* Ref next frame to check */ - CHECK_INV(rfd, sizeof(struct i596_rfd)); + CHECK_INV(lp, rfd, sizeof(struct i596_rfd)); while ((rfd->stat) & STAT_C) { /* Loop while complete frames */ if (rfd->rbd == I596_NULL) rbd = NULL; else if (rfd->rbd == lp->rbd_head->b_addr) { rbd = lp->rbd_head; - CHECK_INV(rbd, sizeof(struct i596_rbd)); + CHECK_INV(lp, rbd, sizeof(struct i596_rbd)); } else { printk("%s: rbd chain broken!\n", dev->name); @@ -790,7 +790,7 @@ static inline int i596_rx(struct net_device *dev) dma_addr = dma_map_single(lp->dev, newskb->data, PKT_BUF_SZ, DMA_FROM_DEVICE); rbd->v_data = newskb->data; rbd->b_data = WSWAPchar(dma_addr); - CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); + CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd)); } else skb = dev_alloc_skb(pkt_len + 2); @@ -842,7 +842,7 @@ memory_squeeze: if (rbd != NULL && (rbd->count & 0x4000)) { rbd->count = 0; lp->rbd_head = rbd->v_next; - CHECK_WBACK_INV(rbd, sizeof(struct i596_rbd)); + CHECK_WBACK_INV(lp, rbd, sizeof(struct i596_rbd)); } /* Tidy the frame descriptor, marking it as end of list */ @@ -860,10 +860,10 @@ memory_squeeze: lp->scb.rfd = rfd->b_next; lp->rfd_head = rfd->v_next; - CHECK_WBACK_INV(rfd->v_prev, sizeof(struct i596_rfd)); - CHECK_WBACK_INV(rfd, sizeof(struct i596_rfd)); + CHECK_WBACK_INV(lp, rfd->v_prev, sizeof(struct i596_rfd)); + CHECK_WBACK_INV(lp, rfd, sizeof(struct i596_rfd)); rfd = lp->rfd_head; - CHECK_INV(rfd, sizeof(struct i596_rfd)); + CHECK_INV(lp, rfd, sizeof(struct i596_rfd)); } DEB(DEB_RXFRAME, printk("frames %d\n", frames)); @@ -902,12 +902,12 @@ static inline void i596_cleanup_cmd(struct net_device *dev, struct i596_private ptr->v_next = NULL; ptr->b_next = I596_NULL; } - CHECK_WBACK_INV(ptr, sizeof(struct i596_cmd)); + CHECK_WBACK_INV(lp, ptr, sizeof(struct i596_cmd)); } wait_cmd(dev, lp, 100, "i596_cleanup_cmd timed out"); lp->scb.cmd = I596_NULL; - CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); } @@ -925,7 +925,7 @@ static inline void i596_reset(struct net_device *dev, struct i596_private *lp) /* FIXME: this command might cause an lpmc */ lp->scb.command = CUC_ABORT | RX_ABORT; - CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); CA(dev); /* wait for shutdown */ @@ -951,20 +951,20 @@ static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd) cmd->command |= (CMD_EOL | CMD_INTR); cmd->v_next = NULL; cmd->b_next = I596_NULL; - CHECK_WBACK(cmd, sizeof(struct i596_cmd)); + CHECK_WBACK(lp, cmd, sizeof(struct i596_cmd)); spin_lock_irqsave (&lp->lock, flags); if (lp->cmd_head != NULL) { lp->cmd_tail->v_next = cmd; lp->cmd_tail->b_next = WSWAPcmd(virt_to_dma(lp,&cmd->status)); - CHECK_WBACK(lp->cmd_tail, sizeof(struct i596_cmd)); + CHECK_WBACK(lp, lp->cmd_tail, sizeof(struct i596_cmd)); } else { lp->cmd_head = cmd; wait_cmd(dev, lp, 100, "i596_add_cmd timed out"); lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&cmd->status)); lp->scb.command = CUC_START; - CHECK_WBACK(&(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK(lp, &(lp->scb), sizeof(struct i596_scb)); CA(dev); } lp->cmd_tail = cmd; @@ -998,12 +998,12 @@ static int i596_test(struct net_device *dev) data = virt_to_dma(lp,tint); tint[1] = -1; - CHECK_WBACK(tint,PAGE_SIZE); + CHECK_WBACK(lp, tint, PAGE_SIZE); MPU_PORT(dev, 1, data); for(data = 1000000; data; data--) { - CHECK_INV(tint,PAGE_SIZE); + CHECK_INV(lp, tint, PAGE_SIZE); if(tint[1] != -1) break; @@ -1061,7 +1061,7 @@ static void i596_tx_timeout (struct net_device *dev) /* Issue a channel attention signal */ DEB(DEB_ERRORS, printk("Kicking board.\n")); lp->scb.command = CUC_START | RX_START; - CHECK_WBACK_INV(&(lp->scb), sizeof(struct i596_scb)); + CHECK_WBACK_INV(lp, &(lp->scb), sizeof(struct i596_scb)); CA (dev); lp->last_restart = lp->stats.tx_packets; } @@ -1118,8 +1118,8 @@ static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev) tbd->data = WSWAPchar(tx_cmd->dma_addr); DEB(DEB_TXADDR,print_eth(skb->data, "tx-queued")); - CHECK_WBACK_INV(tx_cmd, sizeof(struct tx_cmd)); - CHECK_WBACK_INV(tbd, sizeof(struct i596_tbd)); + CHECK_WBACK_INV(lp, tx_cmd, sizeof(struct tx_cmd)); + CHECK_WBACK_INV(lp, tbd, sizeof(struct i596_tbd)); i596_add_cmd(dev, &tx_cmd->cmd); lp->stats.tx_packets++; @@ -1228,7 +1228,7 @@ static int __devinit i82596_probe(struct net_device *dev, lp->dma_addr = dma_addr; lp->dev = gen_dev; - CHECK_WBACK_INV(dev->mem_start, sizeof(struct i596_private)); + CHECK_WBACK_INV(lp, dev->mem_start, sizeof(struct i596_private)); i = register_netdev(dev); if (i) { @@ -1295,7 +1295,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) DEB(DEB_INTS, printk("%s: i596 interrupt command unit inactive %x.\n", dev->name, status & 0x0700)); while (lp->cmd_head != NULL) { - CHECK_INV(lp->cmd_head, sizeof(struct i596_cmd)); + CHECK_INV(lp, lp->cmd_head, sizeof(struct i596_cmd)); if (!(lp->cmd_head->status & STAT_C)) break; @@ -1358,7 +1358,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) } ptr->v_next = NULL; ptr->b_next = I596_NULL; - CHECK_WBACK(ptr, sizeof(struct i596_cmd)); + CHECK_WBACK(lp, ptr, sizeof(struct i596_cmd)); lp->last_cmd = jiffies; } @@ -1372,13 +1372,13 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) ptr->command &= 0x1fff; ptr = ptr->v_next; - CHECK_WBACK_INV(prev, sizeof(struct i596_cmd)); + CHECK_WBACK_INV(lp, prev, sizeof(struct i596_cmd)); } if ((lp->cmd_head != NULL)) ack_cmd |= CUC_START; lp->scb.cmd = WSWAPcmd(virt_to_dma(lp,&lp->cmd_head->status)); - CHECK_WBACK_INV(&lp->scb, sizeof(struct i596_scb)); + CHECK_WBACK_INV(lp, &lp->scb, sizeof(struct i596_scb)); } if ((status & 0x1000) || (status & 0x4000)) { if ((status & 0x4000)) @@ -1397,7 +1397,7 @@ static irqreturn_t i596_interrupt(int irq, void *dev_id) } wait_cmd(dev, lp, 100, "i596 interrupt, timeout"); lp->scb.command = ack_cmd; - CHECK_WBACK(&lp->scb, sizeof(struct i596_scb)); + CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb)); /* DANGER: I suspect that some kind of interrupt acknowledgement aside from acking the 82596 might be needed @@ -1426,7 +1426,7 @@ static int i596_close(struct net_device *dev) wait_cmd(dev, lp, 100, "close1 timed out"); lp->scb.command = CUC_ABORT | RX_ABORT; - CHECK_WBACK(&lp->scb, sizeof(struct i596_scb)); + CHECK_WBACK(lp, &lp->scb, sizeof(struct i596_scb)); CA(dev); @@ -1486,7 +1486,7 @@ static void set_multicast_list(struct net_device *dev) dev->name); else { lp->cf_cmd.cmd.command = CmdConfigure; - CHECK_WBACK_INV(&lp->cf_cmd, sizeof(struct cf_cmd)); + CHECK_WBACK_INV(lp, &lp->cf_cmd, sizeof(struct cf_cmd)); i596_add_cmd(dev, &lp->cf_cmd.cmd); } } @@ -1514,7 +1514,7 @@ static void set_multicast_list(struct net_device *dev) DEB(DEB_MULTI, printk("%s: Adding address %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, cp[0],cp[1],cp[2],cp[3],cp[4],cp[5])); } - CHECK_WBACK_INV(&lp->mc_cmd, sizeof(struct mc_cmd)); + CHECK_WBACK_INV(lp, &lp->mc_cmd, sizeof(struct mc_cmd)); i596_add_cmd(dev, &cmd->cmd); } } diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index acee062cd6f6..68103e508db7 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -362,11 +362,11 @@ NCR_700_detect(struct scsi_host_template *tpnt, for (j = 0; j < PATCHES; j++) script[LABELPATCHES[j]] = bS_to_host(pScript + SCRIPT[LABELPATCHES[j]]); /* now patch up fixed addresses. */ - script_patch_32(script, MessageLocation, + script_patch_32(hostdata->dev, script, MessageLocation, pScript + MSGOUT_OFFSET); - script_patch_32(script, StatusAddress, + script_patch_32(hostdata->dev, script, StatusAddress, pScript + STATUS_OFFSET); - script_patch_32(script, ReceiveMsgAddress, + script_patch_32(hostdata->dev, script, ReceiveMsgAddress, pScript + MSGIN_OFFSET); hostdata->script = script; @@ -821,8 +821,9 @@ process_extended_message(struct Scsi_Host *host, shost_printk(KERN_WARNING, host, "Unexpected SDTR msg\n"); hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); - script_patch_16(hostdata->script, MessageCount, 1); + dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE); + script_patch_16(hostdata->dev, hostdata->script, + MessageCount, 1); /* SendMsgOut returns, so set up the return * address */ resume_offset = hostdata->pScript + Ent_SendMessageWithATN; @@ -833,8 +834,9 @@ process_extended_message(struct Scsi_Host *host, printk(KERN_INFO "scsi%d: (%d:%d), Unsolicited WDTR after CMD, Rejecting\n", host->host_no, pun, lun); hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); - script_patch_16(hostdata->script, MessageCount, 1); + dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE); + script_patch_16(hostdata->dev, hostdata->script, MessageCount, + 1); resume_offset = hostdata->pScript + Ent_SendMessageWithATN; break; @@ -847,8 +849,9 @@ process_extended_message(struct Scsi_Host *host, printk("\n"); /* just reject it */ hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); - script_patch_16(hostdata->script, MessageCount, 1); + dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE); + script_patch_16(hostdata->dev, hostdata->script, MessageCount, + 1); /* SendMsgOut returns, so set up the return * address */ resume_offset = hostdata->pScript + Ent_SendMessageWithATN; @@ -929,8 +932,9 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata printk("\n"); /* just reject it */ hostdata->msgout[0] = A_REJECT_MSG; - dma_cache_sync(hostdata->msgout, 1, DMA_TO_DEVICE); - script_patch_16(hostdata->script, MessageCount, 1); + dma_cache_sync(hostdata->dev, hostdata->msgout, 1, DMA_TO_DEVICE); + script_patch_16(hostdata->dev, hostdata->script, MessageCount, + 1); /* SendMsgOut returns, so set up the return * address */ resume_offset = hostdata->pScript + Ent_SendMessageWithATN; @@ -939,7 +943,7 @@ process_message(struct Scsi_Host *host, struct NCR_700_Host_Parameters *hostdata } NCR_700_writel(temp, host, TEMP_REG); /* set us up to receive another message */ - dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE); + dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE); return resume_offset; } @@ -1019,9 +1023,9 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, slot->SG[1].ins = bS_to_host(SCRIPT_RETURN); slot->SG[1].pAddr = 0; slot->resume_offset = hostdata->pScript; - dma_cache_sync(slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE); - dma_cache_sync(SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); - + dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG[0])*2, DMA_TO_DEVICE); + dma_cache_sync(hostdata->dev, SCp->sense_buffer, sizeof(SCp->sense_buffer), DMA_FROM_DEVICE); + /* queue the command for reissue */ slot->state = NCR_700_SLOT_QUEUED; slot->flags = NCR_700_FLAG_AUTOSENSE; @@ -1136,11 +1140,12 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, hostdata->cmd = slot->cmnd; /* re-patch for this command */ - script_patch_32_abs(hostdata->script, CommandAddress, - slot->pCmd); - script_patch_16(hostdata->script, + script_patch_32_abs(hostdata->dev, hostdata->script, + CommandAddress, slot->pCmd); + script_patch_16(hostdata->dev, hostdata->script, CommandCount, slot->cmnd->cmd_len); - script_patch_32_abs(hostdata->script, SGScriptStartAddress, + script_patch_32_abs(hostdata->dev, hostdata->script, + SGScriptStartAddress, to32bit(&slot->pSG[0].ins)); /* Note: setting SXFER only works if we're @@ -1150,13 +1155,13 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, * should therefore always clear ACK */ NCR_700_writeb(NCR_700_get_SXFER(hostdata->cmd->device), host, SXFER_REG); - dma_cache_sync(hostdata->msgin, + dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE); - dma_cache_sync(hostdata->msgout, + dma_cache_sync(hostdata->dev, hostdata->msgout, MSG_ARRAY_SIZE, DMA_TO_DEVICE); /* I'm just being paranoid here, the command should * already have been flushed from the cache */ - dma_cache_sync(slot->cmnd->cmnd, + dma_cache_sync(hostdata->dev, slot->cmnd->cmnd, slot->cmnd->cmd_len, DMA_TO_DEVICE); @@ -1220,7 +1225,7 @@ process_script_interrupt(__u32 dsps, __u32 dsp, struct scsi_cmnd *SCp, hostdata->reselection_id = reselection_id; /* just in case we have a stale simple tag message, clear it */ hostdata->msgin[1] = 0; - dma_cache_sync(hostdata->msgin, + dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL); if(hostdata->tag_negotiated & (1<pScript + Ent_GetReselectionWithTag; @@ -1336,7 +1341,7 @@ process_selection(struct Scsi_Host *host, __u32 dsp) hostdata->cmd = NULL; /* clear any stale simple tag message */ hostdata->msgin[1] = 0; - dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, + dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_BIDIRECTIONAL); if(id == 0xff) { @@ -1433,29 +1438,30 @@ NCR_700_start_command(struct scsi_cmnd *SCp) NCR_700_set_flag(SCp->device, NCR_700_DEV_BEGIN_SYNC_NEGOTIATION); } - script_patch_16(hostdata->script, MessageCount, count); + script_patch_16(hostdata->dev, hostdata->script, MessageCount, count); - script_patch_ID(hostdata->script, + script_patch_ID(hostdata->dev, hostdata->script, Device_ID, 1<script, CommandAddress, + script_patch_32_abs(hostdata->dev, hostdata->script, CommandAddress, slot->pCmd); - script_patch_16(hostdata->script, CommandCount, SCp->cmd_len); + script_patch_16(hostdata->dev, hostdata->script, CommandCount, + SCp->cmd_len); /* finally plumb the beginning of the SG list into the script * */ - script_patch_32_abs(hostdata->script, SGScriptStartAddress, - to32bit(&slot->pSG[0].ins)); + script_patch_32_abs(hostdata->dev, hostdata->script, + SGScriptStartAddress, to32bit(&slot->pSG[0].ins)); NCR_700_clear_fifo(SCp->device->host); if(slot->resume_offset == 0) slot->resume_offset = hostdata->pScript; /* now perform all the writebacks and invalidates */ - dma_cache_sync(hostdata->msgout, count, DMA_TO_DEVICE); - dma_cache_sync(hostdata->msgin, MSG_ARRAY_SIZE, + dma_cache_sync(hostdata->dev, hostdata->msgout, count, DMA_TO_DEVICE); + dma_cache_sync(hostdata->dev, hostdata->msgin, MSG_ARRAY_SIZE, DMA_FROM_DEVICE); - dma_cache_sync(SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE); - dma_cache_sync(hostdata->status, 1, DMA_FROM_DEVICE); + dma_cache_sync(hostdata->dev, SCp->cmnd, SCp->cmd_len, DMA_TO_DEVICE); + dma_cache_sync(hostdata->dev, hostdata->status, 1, DMA_FROM_DEVICE); /* set the synchronous period/offset */ NCR_700_writeb(NCR_700_get_SXFER(SCp->device), @@ -1631,7 +1637,7 @@ NCR_700_intr(int irq, void *dev_id) slot->SG[i].ins = bS_to_host(SCRIPT_NOP); slot->SG[i].pAddr = 0; } - dma_cache_sync(slot->SG, sizeof(slot->SG), DMA_TO_DEVICE); + dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE); /* and pretend we disconnected after * the command phase */ resume_offset = hostdata->pScript + Ent_MsgInDuringData; @@ -1897,9 +1903,9 @@ NCR_700_queuecommand(struct scsi_cmnd *SCp, void (*done)(struct scsi_cmnd *)) } slot->SG[i].ins = bS_to_host(SCRIPT_RETURN); slot->SG[i].pAddr = 0; - dma_cache_sync(slot->SG, sizeof(slot->SG), DMA_TO_DEVICE); + dma_cache_sync(hostdata->dev, slot->SG, sizeof(slot->SG), DMA_TO_DEVICE); DEBUG((" SETTING %08lx to %x\n", - (&slot->pSG[i].ins), + (&slot->pSG[i].ins), slot->SG[i].ins)); } slot->resume_offset = 0; diff --git a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h index f5c3caf344a7..f38822db4210 100644 --- a/drivers/scsi/53c700.h +++ b/drivers/scsi/53c700.h @@ -415,31 +415,31 @@ struct NCR_700_Host_Parameters { #define NCR_710_MIN_XFERP 0 #define NCR_700_MIN_PERIOD 25 /* for SDTR message, 100ns */ -#define script_patch_32(script, symbol, value) \ +#define script_patch_32(dev, script, symbol, value) \ { \ int i; \ for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \ __u32 val = bS_to_cpu((script)[A_##symbol##_used[i]]) + value; \ (script)[A_##symbol##_used[i]] = bS_to_host(val); \ - dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ + dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ DEBUG((" script, patching %s at %d to 0x%lx\n", \ #symbol, A_##symbol##_used[i], (value))); \ } \ } -#define script_patch_32_abs(script, symbol, value) \ +#define script_patch_32_abs(dev, script, symbol, value) \ { \ int i; \ for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \ (script)[A_##symbol##_used[i]] = bS_to_host(value); \ - dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ + dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ DEBUG((" script, patching %s at %d to 0x%lx\n", \ #symbol, A_##symbol##_used[i], (value))); \ } \ } /* Used for patching the SCSI ID in the SELECT instruction */ -#define script_patch_ID(script, symbol, value) \ +#define script_patch_ID(dev, script, symbol, value) \ { \ int i; \ for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \ @@ -447,13 +447,13 @@ struct NCR_700_Host_Parameters { val &= 0xff00ffff; \ val |= ((value) & 0xff) << 16; \ (script)[A_##symbol##_used[i]] = bS_to_host(val); \ - dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ + dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ DEBUG((" script, patching ID field %s at %d to 0x%x\n", \ #symbol, A_##symbol##_used[i], val)); \ } \ } -#define script_patch_16(script, symbol, value) \ +#define script_patch_16(dev, script, symbol, value) \ { \ int i; \ for(i=0; i< (sizeof(A_##symbol##_used) / sizeof(__u32)); i++) { \ @@ -461,7 +461,7 @@ struct NCR_700_Host_Parameters { val &= 0xffff0000; \ val |= ((value) & 0xffff); \ (script)[A_##symbol##_used[i]] = bS_to_host(val); \ - dma_cache_sync(&(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ + dma_cache_sync((dev), &(script)[A_##symbol##_used[i]], 4, DMA_TO_DEVICE); \ DEBUG((" script, patching short field %s at %d to 0x%x\n", \ #symbol, A_##symbol##_used[i], val)); \ } \ diff --git a/drivers/serial/mpsc.c b/drivers/serial/mpsc.c index 8eea69f29989..29823bd60fb0 100644 --- a/drivers/serial/mpsc.c +++ b/drivers/serial/mpsc.c @@ -555,7 +555,7 @@ mpsc_sdma_start_tx(struct mpsc_port_info *pi) if (!mpsc_sdma_tx_active(pi)) { txre = (struct mpsc_tx_desc *)(pi->txr + (pi->txr_tail * MPSC_TXRE_SIZE)); - dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)txre, @@ -931,7 +931,7 @@ mpsc_init_rings(struct mpsc_port_info *pi) } txre->link = cpu_to_be32(pi->txr_p); /* Wrap last back to first */ - dma_cache_sync((void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE, + dma_cache_sync(pi->port.dev, (void *) pi->dma_region, MPSC_DMA_ALLOC_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ @@ -1005,7 +1005,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi) rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn*MPSC_RXRE_SIZE)); - dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)rxre, @@ -1029,7 +1029,7 @@ mpsc_rx_intr(struct mpsc_port_info *pi) } bp = pi->rxb + (pi->rxr_posn * MPSC_RXBE_SIZE); - dma_cache_sync((void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync(pi->port.dev, (void *) bp, MPSC_RXBE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)bp, @@ -1098,7 +1098,7 @@ next_frame: SDMA_DESC_CMDSTAT_F | SDMA_DESC_CMDSTAT_L); wmb(); - dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL); + dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)rxre, @@ -1109,7 +1109,7 @@ next_frame: pi->rxr_posn = (pi->rxr_posn + 1) & (MPSC_RXR_ENTRIES - 1); rxre = (struct mpsc_rx_desc *)(pi->rxr + (pi->rxr_posn * MPSC_RXRE_SIZE)); - dma_cache_sync((void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync(pi->port.dev, (void *)rxre, MPSC_RXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)rxre, @@ -1143,7 +1143,7 @@ mpsc_setup_tx_desc(struct mpsc_port_info *pi, u32 count, u32 intr) SDMA_DESC_CMDSTAT_EI : 0)); wmb(); - dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL); + dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)txre, @@ -1192,7 +1192,7 @@ mpsc_copy_tx_data(struct mpsc_port_info *pi) else /* All tx data copied into ring bufs */ return; - dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); + dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)bp, @@ -1217,7 +1217,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi) txre = (struct mpsc_tx_desc *)(pi->txr + (pi->txr_tail * MPSC_TXRE_SIZE)); - dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); + dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ invalidate_dcache_range((ulong)txre, @@ -1235,7 +1235,7 @@ mpsc_tx_intr(struct mpsc_port_info *pi) txre = (struct mpsc_tx_desc *)(pi->txr + (pi->txr_tail * MPSC_TXRE_SIZE)); - dma_cache_sync((void *) txre, MPSC_TXRE_SIZE, + dma_cache_sync(pi->port.dev, (void *) txre, MPSC_TXRE_SIZE, DMA_FROM_DEVICE); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ @@ -1652,7 +1652,7 @@ mpsc_console_write(struct console *co, const char *s, uint count) count--; } - dma_cache_sync((void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); + dma_cache_sync(pi->port.dev, (void *) bp, MPSC_TXBE_SIZE, DMA_BIDIRECTIONAL); #if defined(CONFIG_PPC32) && !defined(CONFIG_NOT_COHERENT_CACHE) if (pi->cache_mgmt) /* GT642[46]0 Res #COMM-2 */ flush_dcache_range((ulong)bp, diff --git a/include/asm-alpha/dma-mapping.h b/include/asm-alpha/dma-mapping.h index b274bf6317c7..57e09f5e3424 100644 --- a/include/asm-alpha/dma-mapping.h +++ b/include/asm-alpha/dma-mapping.h @@ -60,7 +60,7 @@ int dma_set_mask(struct device *dev, u64 mask); #define dma_sync_single_range(dev, addr, off, size, dir) do { } while (0) #define dma_sync_sg_for_cpu(dev, sg, nents, dir) do { } while (0) #define dma_sync_sg_for_device(dev, sg, nents, dir) do { } while (0) -#define dma_cache_sync(va, size, dir) do { } while (0) +#define dma_cache_sync(dev, va, size, dir) do { } while (0) #define dma_get_cache_alignment() L1_CACHE_BYTES diff --git a/include/asm-avr32/dma-mapping.h b/include/asm-avr32/dma-mapping.h index 44630be2ee22..0580b5d62bba 100644 --- a/include/asm-avr32/dma-mapping.h +++ b/include/asm-avr32/dma-mapping.h @@ -8,7 +8,8 @@ #include #include -extern void dma_cache_sync(void *vaddr, size_t size, int direction); +extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, + int direction); /* * Return whether the given device DMA address mask can be supported diff --git a/include/asm-cris/dma-mapping.h b/include/asm-cris/dma-mapping.h index af704fdd3d0d..662cea70152d 100644 --- a/include/asm-cris/dma-mapping.h +++ b/include/asm-cris/dma-mapping.h @@ -159,7 +159,7 @@ dma_get_cache_alignment(void) #define dma_is_consistent(d, h) (1) static inline void -dma_cache_sync(void *vaddr, size_t size, +dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { } diff --git a/include/asm-frv/dma-mapping.h b/include/asm-frv/dma-mapping.h index 7b97fc785f72..bcb2df68496e 100644 --- a/include/asm-frv/dma-mapping.h +++ b/include/asm-frv/dma-mapping.h @@ -175,7 +175,7 @@ int dma_get_cache_alignment(void) #define dma_is_consistent(d, h) (1) static inline -void dma_cache_sync(void *vaddr, size_t size, +void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { flush_write_buffers(); diff --git a/include/asm-generic/dma-mapping.h b/include/asm-generic/dma-mapping.h index b9be3fc344c7..783ab9944d70 100644 --- a/include/asm-generic/dma-mapping.h +++ b/include/asm-generic/dma-mapping.h @@ -295,7 +295,7 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, } static inline void -dma_cache_sync(void *vaddr, size_t size, +dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { /* could define this in terms of the dma_cache ... operations, diff --git a/include/asm-i386/dma-mapping.h b/include/asm-i386/dma-mapping.h index 7da64c9f1738..183eebeebbdc 100644 --- a/include/asm-i386/dma-mapping.h +++ b/include/asm-i386/dma-mapping.h @@ -159,7 +159,7 @@ dma_get_cache_alignment(void) #define dma_is_consistent(d, h) (1) static inline void -dma_cache_sync(void *vaddr, size_t size, +dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { flush_write_buffers(); diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h index 4b075bc032ec..ebd5887f4b1a 100644 --- a/include/asm-ia64/dma-mapping.h +++ b/include/asm-ia64/dma-mapping.h @@ -50,7 +50,8 @@ dma_set_mask (struct device *dev, u64 mask) extern int dma_get_cache_alignment(void); static inline void -dma_cache_sync (void *vaddr, size_t size, enum dma_data_direction dir) +dma_cache_sync (struct device *dev, void *vaddr, size_t size, + enum dma_data_direction dir) { /* * IA-64 is cache-coherent, so this is mostly a no-op. However, we do need to diff --git a/include/asm-m68k/dma-mapping.h b/include/asm-m68k/dma-mapping.h index efc89c12f837..00259ed6fc95 100644 --- a/include/asm-m68k/dma-mapping.h +++ b/include/asm-m68k/dma-mapping.h @@ -41,7 +41,7 @@ static inline void dma_free_noncoherent(struct device *dev, size_t size, { dma_free_coherent(dev, size, addr, handle); } -static inline void dma_cache_sync(void *vaddr, size_t size, +static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction dir) { /* we use coherent allocation, so not much to do here. */ diff --git a/include/asm-mips/dma-mapping.h b/include/asm-mips/dma-mapping.h index e17f70d7b702..236d1a467cc7 100644 --- a/include/asm-mips/dma-mapping.h +++ b/include/asm-mips/dma-mapping.h @@ -65,7 +65,7 @@ dma_get_cache_alignment(void) extern int dma_is_consistent(struct device *dev, dma_addr_t dma_addr); -extern void dma_cache_sync(void *vaddr, size_t size, +extern void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction); #define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h index c40d48afdc52..66f0b408c669 100644 --- a/include/asm-parisc/dma-mapping.h +++ b/include/asm-parisc/dma-mapping.h @@ -197,7 +197,7 @@ dma_is_consistent(struct device *dev, dma_addr_t dma_addr) } static inline void -dma_cache_sync(void *vaddr, size_t size, +dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { if(hppa_dma_ops->dma_sync_single_for_cpu) diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h index 3cf635b53b88..7c7de87bd8ae 100644 --- a/include/asm-powerpc/dma-mapping.h +++ b/include/asm-powerpc/dma-mapping.h @@ -378,7 +378,7 @@ static inline void dma_sync_single_range_for_device(struct device *dev, dma_sync_single_for_device(dev, dma_handle, offset + size, direction); } -static inline void dma_cache_sync(void *vaddr, size_t size, +static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { BUG_ON(direction == DMA_NONE); diff --git a/include/asm-sh/dma-mapping.h b/include/asm-sh/dma-mapping.h index 56cd4b977232..37ab0c131a4d 100644 --- a/include/asm-sh/dma-mapping.h +++ b/include/asm-sh/dma-mapping.h @@ -53,7 +53,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, consistent_free(vaddr, size); } -static inline void dma_cache_sync(void *vaddr, size_t size, +static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction dir) { consistent_sync(vaddr, size, (int)dir); diff --git a/include/asm-sh64/dma-mapping.h b/include/asm-sh64/dma-mapping.h index 68e27a8fca31..5efe906c59f7 100644 --- a/include/asm-sh64/dma-mapping.h +++ b/include/asm-sh64/dma-mapping.h @@ -35,7 +35,7 @@ static inline void dma_free_coherent(struct device *dev, size_t size, consistent_free(NULL, size, vaddr, dma_handle); } -static inline void dma_cache_sync(void *vaddr, size_t size, +static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction dir) { dma_cache_wback_inv((unsigned long)vaddr, size); diff --git a/include/asm-sparc64/dma-mapping.h b/include/asm-sparc64/dma-mapping.h index 5fe0072f3f82..2f858a2df94a 100644 --- a/include/asm-sparc64/dma-mapping.h +++ b/include/asm-sparc64/dma-mapping.h @@ -210,7 +210,7 @@ dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle, } static inline void -dma_cache_sync(void *vaddr, size_t size, +dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { /* could define this in terms of the dma_cache ... operations, diff --git a/include/asm-um/dma-mapping.h b/include/asm-um/dma-mapping.h index defb5b8307de..f0ee4fb55911 100644 --- a/include/asm-um/dma-mapping.h +++ b/include/asm-um/dma-mapping.h @@ -112,7 +112,7 @@ dma_sync_single_range(struct device *dev, dma_addr_t dma_handle, } static inline void -dma_cache_sync(void *vaddr, size_t size, +dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { BUG(); diff --git a/include/asm-x86_64/dma-mapping.h b/include/asm-x86_64/dma-mapping.h index c8cc4887fba6..be9ec6890723 100644 --- a/include/asm-x86_64/dma-mapping.h +++ b/include/asm-x86_64/dma-mapping.h @@ -185,7 +185,8 @@ static inline int dma_get_cache_alignment(void) extern int dma_set_mask(struct device *dev, u64 mask); static inline void -dma_cache_sync(void *vaddr, size_t size, enum dma_data_direction dir) +dma_cache_sync(struct device *dev, void *vaddr, size_t size, + enum dma_data_direction dir) { flush_write_buffers(); } diff --git a/include/asm-xtensa/dma-mapping.h b/include/asm-xtensa/dma-mapping.h index 827d1dfd9e1d..82b03b3a2ee6 100644 --- a/include/asm-xtensa/dma-mapping.h +++ b/include/asm-xtensa/dma-mapping.h @@ -173,7 +173,7 @@ dma_get_cache_alignment(void) #define dma_is_consistent(d, h) (1) static inline void -dma_cache_sync(void *vaddr, size_t size, +dma_cache_sync(struct device *dev, void *vaddr, size_t size, enum dma_data_direction direction) { consistent_sync(vaddr, size, direction); -- cgit v1.2.3 From 7d1362c0d05b8543807ab403ac8ce813cab41fa4 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Wed, 6 Dec 2006 20:40:38 -0800 Subject: [PATCH] cleanup asm/setup.h userspace visibility Make the contents of the userspace asm/setup.h header consistent on all architectures: - export setup.h to userspace on all architectures - export only COMMAND_LINE_SIZE to userspace - frv: move COMMAND_LINE_SIZE from param.h - i386: remove duplicate COMMAND_LINE_SIZE from param.h - arm: - export ATAGs to userspace - change u8/u16/u32 to __u8/__u16/__u32 Signed-off-by: Adrian Bunk Acked-by: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-arm/setup.h | 104 ++++++++++++++++++++++------------------- include/asm-arm26/setup.h | 4 ++ include/asm-avr32/setup.h | 4 ++ include/asm-frv/param.h | 1 - include/asm-frv/setup.h | 6 +++ include/asm-generic/Kbuild.asm | 1 + include/asm-i386/Kbuild | 1 - include/asm-i386/param.h | 1 - include/asm-i386/setup.h | 6 ++- include/asm-ia64/Kbuild | 1 - include/asm-m32r/setup.h | 9 +++- include/asm-m68k/setup.h | 6 ++- include/asm-m68knommu/setup.h | 5 ++ include/asm-mips/setup.h | 2 - include/asm-powerpc/setup.h | 3 -- include/asm-s390/setup.h | 3 +- include/asm-sh/setup.h | 6 ++- include/asm-sh64/setup.h | 6 +++ include/asm-x86_64/Kbuild | 1 - 19 files changed, 102 insertions(+), 68 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-arm/setup.h b/include/asm-arm/setup.h index aa4b5782f0c9..e5407392afca 100644 --- a/include/asm-arm/setup.h +++ b/include/asm-arm/setup.h @@ -14,55 +14,57 @@ #ifndef __ASMARM_SETUP_H #define __ASMARM_SETUP_H +#include + #define COMMAND_LINE_SIZE 1024 /* The list ends with an ATAG_NONE node. */ #define ATAG_NONE 0x00000000 struct tag_header { - u32 size; - u32 tag; + __u32 size; + __u32 tag; }; /* The list must start with an ATAG_CORE node */ #define ATAG_CORE 0x54410001 struct tag_core { - u32 flags; /* bit 0 = read-only */ - u32 pagesize; - u32 rootdev; + __u32 flags; /* bit 0 = read-only */ + __u32 pagesize; + __u32 rootdev; }; /* it is allowed to have multiple ATAG_MEM nodes */ #define ATAG_MEM 0x54410002 struct tag_mem32 { - u32 size; - u32 start; /* physical start address */ + __u32 size; + __u32 start; /* physical start address */ }; /* VGA text type displays */ #define ATAG_VIDEOTEXT 0x54410003 struct tag_videotext { - u8 x; - u8 y; - u16 video_page; - u8 video_mode; - u8 video_cols; - u16 video_ega_bx; - u8 video_lines; - u8 video_isvga; - u16 video_points; + __u8 x; + __u8 y; + __u16 video_page; + __u8 video_mode; + __u8 video_cols; + __u16 video_ega_bx; + __u8 video_lines; + __u8 video_isvga; + __u16 video_points; }; /* describes how the ramdisk will be used in kernel */ #define ATAG_RAMDISK 0x54410004 struct tag_ramdisk { - u32 flags; /* bit 0 = load, bit 1 = prompt */ - u32 size; /* decompressed ramdisk size in _kilo_ bytes */ - u32 start; /* starting block of floppy-based RAM disk image */ + __u32 flags; /* bit 0 = load, bit 1 = prompt */ + __u32 size; /* decompressed ramdisk size in _kilo_ bytes */ + __u32 start; /* starting block of floppy-based RAM disk image */ }; /* describes where the compressed ramdisk image lives (virtual address) */ @@ -76,23 +78,23 @@ struct tag_ramdisk { #define ATAG_INITRD2 0x54420005 struct tag_initrd { - u32 start; /* physical start address */ - u32 size; /* size of compressed ramdisk image in bytes */ + __u32 start; /* physical start address */ + __u32 size; /* size of compressed ramdisk image in bytes */ }; /* board serial number. "64 bits should be enough for everybody" */ #define ATAG_SERIAL 0x54410006 struct tag_serialnr { - u32 low; - u32 high; + __u32 low; + __u32 high; }; /* board revision */ #define ATAG_REVISION 0x54410007 struct tag_revision { - u32 rev; + __u32 rev; }; /* initial values for vesafb-type framebuffers. see struct screen_info @@ -101,20 +103,20 @@ struct tag_revision { #define ATAG_VIDEOLFB 0x54410008 struct tag_videolfb { - u16 lfb_width; - u16 lfb_height; - u16 lfb_depth; - u16 lfb_linelength; - u32 lfb_base; - u32 lfb_size; - u8 red_size; - u8 red_pos; - u8 green_size; - u8 green_pos; - u8 blue_size; - u8 blue_pos; - u8 rsvd_size; - u8 rsvd_pos; + __u16 lfb_width; + __u16 lfb_height; + __u16 lfb_depth; + __u16 lfb_linelength; + __u32 lfb_base; + __u32 lfb_size; + __u8 red_size; + __u8 red_pos; + __u8 green_size; + __u8 green_pos; + __u8 blue_size; + __u8 blue_pos; + __u8 rsvd_size; + __u8 rsvd_pos; }; /* command line: \0 terminated string */ @@ -128,17 +130,17 @@ struct tag_cmdline { #define ATAG_ACORN 0x41000101 struct tag_acorn { - u32 memc_control_reg; - u32 vram_pages; - u8 sounddefault; - u8 adfsdrives; + __u32 memc_control_reg; + __u32 vram_pages; + __u8 sounddefault; + __u8 adfsdrives; }; /* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */ #define ATAG_MEMCLK 0x41000402 struct tag_memclk { - u32 fmemclk; + __u32 fmemclk; }; struct tag { @@ -167,24 +169,26 @@ struct tag { }; struct tagtable { - u32 tag; + __u32 tag; int (*parse)(const struct tag *); }; -#define __tag __attribute_used__ __attribute__((__section__(".taglist.init"))) -#define __tagtable(tag, fn) \ -static struct tagtable __tagtable_##fn __tag = { tag, fn } - #define tag_member_present(tag,member) \ ((unsigned long)(&((struct tag *)0L)->member + 1) \ <= (tag)->hdr.size * 4) -#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size)) +#define tag_next(t) ((struct tag *)((__u32 *)(t) + (t)->hdr.size)) #define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) #define for_each_tag(t,base) \ for (t = base; t->hdr.size; t = tag_next(t)) +#ifdef __KERNEL__ + +#define __tag __attribute_used__ __attribute__((__section__(".taglist.init"))) +#define __tagtable(tag, fn) \ +static struct tagtable __tagtable_##fn __tag = { tag, fn } + /* * Memory map description */ @@ -217,4 +221,6 @@ struct early_params { static struct early_params __early_##fn __attribute_used__ \ __attribute__((__section__(".early_param.init"))) = { name, fn } +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-arm26/setup.h b/include/asm-arm26/setup.h index 6348931be65d..1a867b4e8d53 100644 --- a/include/asm-arm26/setup.h +++ b/include/asm-arm26/setup.h @@ -16,6 +16,8 @@ #define COMMAND_LINE_SIZE 1024 +#ifdef __KERNEL__ + /* The list ends with an ATAG_NONE node. */ #define ATAG_NONE 0x00000000 @@ -202,4 +204,6 @@ struct meminfo { extern struct meminfo meminfo; +#endif /* __KERNEL__ */ + #endif diff --git a/include/asm-avr32/setup.h b/include/asm-avr32/setup.h index 10193da4113b..0a5224245e44 100644 --- a/include/asm-avr32/setup.h +++ b/include/asm-avr32/setup.h @@ -13,6 +13,8 @@ #define COMMAND_LINE_SIZE 256 +#ifdef __KERNEL__ + /* Magic number indicating that a tag table is present */ #define ATAG_MAGIC 0xa2a25441 @@ -138,4 +140,6 @@ void chip_enable_sdram(void); #endif /* !__ASSEMBLY__ */ +#endif /* __KERNEL__ */ + #endif /* __ASM_AVR32_SETUP_H__ */ diff --git a/include/asm-frv/param.h b/include/asm-frv/param.h index 168381ebb41a..365653b1726c 100644 --- a/include/asm-frv/param.h +++ b/include/asm-frv/param.h @@ -18,6 +18,5 @@ #endif #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#define COMMAND_LINE_SIZE 512 #endif /* _ASM_PARAM_H */ diff --git a/include/asm-frv/setup.h b/include/asm-frv/setup.h index 0d293b9a5857..afd787ceede6 100644 --- a/include/asm-frv/setup.h +++ b/include/asm-frv/setup.h @@ -12,6 +12,10 @@ #ifndef _ASM_SETUP_H #define _ASM_SETUP_H +#define COMMAND_LINE_SIZE 512 + +#ifdef __KERNEL__ + #include #ifndef __ASSEMBLY__ @@ -22,4 +26,6 @@ extern unsigned long __initdata num_mappedpages; #endif /* !__ASSEMBLY__ */ +#endif /* __KERNEL__ */ + #endif /* _ASM_SETUP_H */ diff --git a/include/asm-generic/Kbuild.asm b/include/asm-generic/Kbuild.asm index a84c3d88a189..a37e95fe58d6 100644 --- a/include/asm-generic/Kbuild.asm +++ b/include/asm-generic/Kbuild.asm @@ -14,6 +14,7 @@ unifdef-y += posix_types.h unifdef-y += ptrace.h unifdef-y += resource.h unifdef-y += sembuf.h +unifdef-y += setup.h unifdef-y += shmbuf.h unifdef-y += sigcontext.h unifdef-y += siginfo.h diff --git a/include/asm-i386/Kbuild b/include/asm-i386/Kbuild index 147e4ac1ebf0..5ae93afc67e1 100644 --- a/include/asm-i386/Kbuild +++ b/include/asm-i386/Kbuild @@ -7,5 +7,4 @@ header-y += ptrace-abi.h header-y += ucontext.h unifdef-y += mtrr.h -unifdef-y += setup.h unifdef-y += vm86.h diff --git a/include/asm-i386/param.h b/include/asm-i386/param.h index 745dc5bd0fbc..21b32466fcdc 100644 --- a/include/asm-i386/param.h +++ b/include/asm-i386/param.h @@ -18,6 +18,5 @@ #endif #define MAXHOSTNAMELEN 64 /* max length of hostname */ -#define COMMAND_LINE_SIZE 256 #endif diff --git a/include/asm-i386/setup.h b/include/asm-i386/setup.h index 2734909eff84..c5b504bfbaad 100644 --- a/include/asm-i386/setup.h +++ b/include/asm-i386/setup.h @@ -6,6 +6,8 @@ #ifndef _i386_SETUP_H #define _i386_SETUP_H +#define COMMAND_LINE_SIZE 256 + #ifdef __KERNEL__ #include @@ -14,10 +16,8 @@ */ #define MAXMEM_PFN PFN_DOWN(MAXMEM) #define MAX_NONPAE_PFN (1 << 20) -#endif #define PARAM_SIZE 4096 -#define COMMAND_LINE_SIZE 256 #define OLD_CL_MAGIC_ADDR 0x90020 #define OLD_CL_MAGIC 0xA33F @@ -78,4 +78,6 @@ void __init add_memory_region(unsigned long long start, #endif /* __ASSEMBLY__ */ +#endif /* __KERNEL__ */ + #endif /* _i386_SETUP_H */ diff --git a/include/asm-ia64/Kbuild b/include/asm-ia64/Kbuild index 15818a18bc52..4a1e48b9f403 100644 --- a/include/asm-ia64/Kbuild +++ b/include/asm-ia64/Kbuild @@ -10,7 +10,6 @@ header-y += intrinsics.h header-y += perfmon_default_smpl.h header-y += ptrace_offsets.h header-y += rse.h -header-y += setup.h header-y += ucontext.h unifdef-y += perfmon.h diff --git a/include/asm-m32r/setup.h b/include/asm-m32r/setup.h index 52f4fa29abfc..6a0b32202d4e 100644 --- a/include/asm-m32r/setup.h +++ b/include/asm-m32r/setup.h @@ -1,6 +1,11 @@ /* * This is set up by the setup-routine at boot-time */ + +#define COMMAND_LINE_SIZE 512 + +#ifdef __KERNEL__ + #define PARAM ((unsigned char *)empty_zero_page) #define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) @@ -18,8 +23,6 @@ #define SCREEN_INFO (*(struct screen_info *) (PARAM+0x200)) -#define COMMAND_LINE_SIZE (512) - #define RAMDISK_IMAGE_START_MASK (0x07FF) #define RAMDISK_PROMPT_FLAG (0x8000) #define RAMDISK_LOAD_FLAG (0x4000) @@ -27,3 +30,5 @@ extern unsigned long memory_start; extern unsigned long memory_end; +#endif /* __KERNEL__ */ + diff --git a/include/asm-m68k/setup.h b/include/asm-m68k/setup.h index 7facc9a46e74..2a8853cd6554 100644 --- a/include/asm-m68k/setup.h +++ b/include/asm-m68k/setup.h @@ -41,8 +41,12 @@ #define MACH_Q40 10 #define MACH_SUN3X 11 +#define COMMAND_LINE_SIZE 256 + #ifdef __KERNEL__ +#define CL_SIZE COMMAND_LINE_SIZE + #ifndef __ASSEMBLY__ extern unsigned long m68k_machtype; #endif /* !__ASSEMBLY__ */ @@ -355,8 +359,6 @@ extern int m68k_is040or060; */ #define NUM_MEMINFO 4 -#define CL_SIZE 256 -#define COMMAND_LINE_SIZE CL_SIZE #ifndef __ASSEMBLY__ struct mem_info { diff --git a/include/asm-m68knommu/setup.h b/include/asm-m68knommu/setup.h index d2b0fcce41b2..fb86bb2a6078 100644 --- a/include/asm-m68knommu/setup.h +++ b/include/asm-m68knommu/setup.h @@ -1,5 +1,10 @@ +#ifdef __KERNEL__ + #include /* We have a bigger command line buffer. */ #undef COMMAND_LINE_SIZE + +#endif /* __KERNEL__ */ + #define COMMAND_LINE_SIZE 512 diff --git a/include/asm-mips/setup.h b/include/asm-mips/setup.h index 737fa4a6912e..70009a902639 100644 --- a/include/asm-mips/setup.h +++ b/include/asm-mips/setup.h @@ -1,8 +1,6 @@ -#ifdef __KERNEL__ #ifndef _MIPS_SETUP_H #define _MIPS_SETUP_H #define COMMAND_LINE_SIZE 256 #endif /* __SETUP_H */ -#endif /* __KERNEL__ */ diff --git a/include/asm-powerpc/setup.h b/include/asm-powerpc/setup.h index 3d9740aae018..817fac0a0714 100644 --- a/include/asm-powerpc/setup.h +++ b/include/asm-powerpc/setup.h @@ -1,9 +1,6 @@ #ifndef _ASM_POWERPC_SETUP_H #define _ASM_POWERPC_SETUP_H -#ifdef __KERNEL__ - #define COMMAND_LINE_SIZE 512 -#endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_SETUP_H */ diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h index 7664bacdd832..9574fe80a046 100644 --- a/include/asm-s390/setup.h +++ b/include/asm-s390/setup.h @@ -8,12 +8,13 @@ #ifndef _ASM_S390_SETUP_H #define _ASM_S390_SETUP_H +#define COMMAND_LINE_SIZE 896 + #ifdef __KERNEL__ #include #define PARMAREA 0x10400 -#define COMMAND_LINE_SIZE 896 #define MEMORY_CHUNKS 16 /* max 0x7fff */ #define IPL_PARMBLOCK_ORIGIN 0x2000 diff --git a/include/asm-sh/setup.h b/include/asm-sh/setup.h index 34ca8a7f06ba..1583c6b7bdaa 100644 --- a/include/asm-sh/setup.h +++ b/include/asm-sh/setup.h @@ -1,10 +1,12 @@ -#ifdef __KERNEL__ #ifndef _SH_SETUP_H #define _SH_SETUP_H #define COMMAND_LINE_SIZE 256 +#ifdef __KERNEL__ + int setup_early_printk(char *); -#endif /* _SH_SETUP_H */ #endif /* __KERNEL__ */ + +#endif /* _SH_SETUP_H */ diff --git a/include/asm-sh64/setup.h b/include/asm-sh64/setup.h index ebd42eb1b709..5b07b14c2927 100644 --- a/include/asm-sh64/setup.h +++ b/include/asm-sh64/setup.h @@ -1,6 +1,10 @@ #ifndef __ASM_SH64_SETUP_H #define __ASM_SH64_SETUP_H +#define COMMAND_LINE_SIZE 256 + +#ifdef __KERNEL__ + #define PARAM ((unsigned char *)empty_zero_page) #define MOUNT_ROOT_RDONLY (*(unsigned long *) (PARAM+0x000)) #define RAMDISK_FLAGS (*(unsigned long *) (PARAM+0x004)) @@ -12,5 +16,7 @@ #define COMMAND_LINE ((char *) (PARAM+256)) #define COMMAND_LINE_SIZE 256 +#endif /* __KERNEL__ */ + #endif /* __ASM_SH64_SETUP_H */ diff --git a/include/asm-x86_64/Kbuild b/include/asm-x86_64/Kbuild index 1ee9b07f3fe6..763521358fb8 100644 --- a/include/asm-x86_64/Kbuild +++ b/include/asm-x86_64/Kbuild @@ -12,7 +12,6 @@ header-y += ldt.h header-y += msr.h header-y += prctl.h header-y += ptrace-abi.h -header-y += setup.h header-y += sigcontext32.h header-y += ucontext.h header-y += vsyscall32.h -- cgit v1.2.3 From c31a0bf3e1bc581676618db7492f18798fd0a73f Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Fri, 8 Dec 2006 02:36:22 -0800 Subject: [PATCH] Generic BUG for x86-64 This makes x86-64 use the generic BUG machinery. The main advantage in using the generic BUG machinery for x86-64 is that the inlined overhead of BUG is just the ud2a instruction; the file+line information are no longer inlined into the instruction stream. This reduces cache pollution. Signed-off-by: Jeremy Fitzhardinge Cc: Andi Kleen Cc: Hugh Dickens Cc: Michael Ellerman Cc: Paul Mackerras Cc: Benjamin Herrenschmidt Cc: Rusty Russell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/x86_64/Kconfig | 5 +++++ arch/x86_64/kernel/module.c | 5 ++++- arch/x86_64/kernel/traps.c | 36 +++++++++++--------------------- arch/x86_64/kernel/vmlinux.lds.S | 2 ++ include/asm-x86_64/bug.h | 44 ++++++++++++++++++++-------------------- 5 files changed, 45 insertions(+), 47 deletions(-) (limited to 'include/asm-x86_64') diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index bfbb9bcae123..3254a616c69e 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -96,6 +96,11 @@ config AUDIT_ARCH bool default y +config GENERIC_BUG + bool + default y + depends on BUG + source "init/Kconfig" diff --git a/arch/x86_64/kernel/module.c b/arch/x86_64/kernel/module.c index 9d0958ff547f..a888e67f5874 100644 --- a/arch/x86_64/kernel/module.c +++ b/arch/x86_64/kernel/module.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -173,10 +174,12 @@ int module_finalize(const Elf_Ehdr *hdr, lseg, lseg + locks->sh_size, tseg, tseg + text->sh_size); } - return 0; + + return module_bug_finalize(hdr, sechdrs, me); } void module_arch_cleanup(struct module *mod) { alternatives_smp_module_del(mod); + module_bug_cleanup(mod); } diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index a1641ffdffcf..b54ccc07f379 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -524,30 +525,15 @@ bad: printk("\n"); } -void handle_BUG(struct pt_regs *regs) -{ - struct bug_frame f; - long len; - const char *prefix = ""; +int is_valid_bugaddr(unsigned long rip) +{ + unsigned short ud2; - if (user_mode(regs)) - return; - if (__copy_from_user(&f, (const void __user *) regs->rip, - sizeof(struct bug_frame))) - return; - if (f.filename >= 0 || - f.ud2[0] != 0x0f || f.ud2[1] != 0x0b) - return; - len = __strnlen_user((char *)(long)f.filename, PATH_MAX) - 1; - if (len < 0 || len >= PATH_MAX) - f.filename = (int)(long)"unmapped filename"; - else if (len > 50) { - f.filename += len - 50; - prefix = "..."; - } - printk("----------- [cut here ] --------- [please bite here ] ---------\n"); - printk(KERN_ALERT "Kernel BUG at %s%.50s:%d\n", prefix, (char *)(long)f.filename, f.line); -} + if (__copy_from_user(&ud2, (const void __user *) rip, sizeof(ud2))) + return 0; + + return ud2 == 0x0b0f; +} #ifdef CONFIG_BUG void out_of_line_bug(void) @@ -627,7 +613,9 @@ void die(const char * str, struct pt_regs * regs, long err) { unsigned long flags = oops_begin(); - handle_BUG(regs); + if (!user_mode(regs)) + report_bug(regs->rip); + __die(str, regs, err); oops_end(flags); do_exit(SIGSEGV); diff --git a/arch/x86_64/kernel/vmlinux.lds.S b/arch/x86_64/kernel/vmlinux.lds.S index 6a1f8f491e5d..6c417788c54b 100644 --- a/arch/x86_64/kernel/vmlinux.lds.S +++ b/arch/x86_64/kernel/vmlinux.lds.S @@ -51,6 +51,8 @@ SECTIONS RODATA + BUG_TABLE + . = ALIGN(PAGE_SIZE); /* Align data segment to page size boundary */ /* Data */ .data : AT(ADDR(.data) - LOAD_OFFSET) { diff --git a/include/asm-x86_64/bug.h b/include/asm-x86_64/bug.h index 80ac1fe966ac..682606414913 100644 --- a/include/asm-x86_64/bug.h +++ b/include/asm-x86_64/bug.h @@ -1,30 +1,30 @@ #ifndef __ASM_X8664_BUG_H #define __ASM_X8664_BUG_H 1 -#include - -/* - * Tell the user there is some problem. The exception handler decodes - * this frame. - */ -struct bug_frame { - unsigned char ud2[2]; - unsigned char push; - signed int filename; - unsigned char ret; - unsigned short line; -} __attribute__((packed)); - #ifdef CONFIG_BUG #define HAVE_ARCH_BUG -/* We turn the bug frame into valid instructions to not confuse - the disassembler. Thanks to Jan Beulich & Suresh Siddha - for nice instruction selection. - The magic numbers generate mov $64bitimm,%eax ; ret $offset. */ -#define BUG() \ - asm volatile( \ - "ud2 ; pushq $%c1 ; ret $%c0" :: \ - "i"(__LINE__), "i" (__FILE__)) + +#ifdef CONFIG_DEBUG_BUGVERBOSE +#define BUG() \ + do { \ + asm volatile("1:\tud2\n" \ + ".pushsection __bug_table,\"a\"\n" \ + "2:\t.quad 1b, %c0\n" \ + "\t.word %c1, 0\n" \ + "\t.org 2b+%c2\n" \ + ".popsection" \ + : : "i" (__FILE__), "i" (__LINE__), \ + "i" (sizeof(struct bug_entry))); \ + for(;;) ; \ + } while(0) +#else +#define BUG() \ + do { \ + asm volatile("ud2"); \ + for(;;) ; \ + } while(0) +#endif + void out_of_line_bug(void); #else static inline void out_of_line_bug(void) { } -- cgit v1.2.3 From be90038a24c814dc98bc5a813f41855779000018 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 8 Dec 2006 02:38:43 -0800 Subject: [PATCH] tty: preparatory structures for termios revamp In order to sort out our struct termios and add proper speed control we need to separate the kernel and user termios structures. Glibc is fine but the other libraries rely on the kernel exported struct termios and we need to extend this without breaking the ABI/API To do so we add a struct ktermios which is the kernel view of a termios structure and overlaps the struct termios with extra fields on the end for now. (That limitation will go away in later patches). Some platforms (eg alpha) planned ahead and thus use the same struct for both, others did not. This just adds the structures but does not use them, it seems a sensible splitting point for bisect if there are compile failures (not that I expect them) Signed-off-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/net/wireless/strip.c | 2 +- include/asm-alpha/termbits.h | 13 +++++++++++++ include/asm-arm/termbits.h | 12 ++++++++++++ include/asm-arm26/termbits.h | 12 ++++++++++++ include/asm-avr32/termbits.h | 11 +++++++++++ include/asm-cris/termbits.h | 11 +++++++++++ include/asm-frv/termbits.h | 11 +++++++++++ include/asm-h8300/termbits.h | 11 +++++++++++ include/asm-i386/termbits.h | 11 +++++++++++ include/asm-ia64/termbits.h | 11 +++++++++++ include/asm-m32r/termbits.h | 11 +++++++++++ include/asm-m68k/termbits.h | 11 +++++++++++ include/asm-mips/termbits.h | 11 +++++++++++ include/asm-parisc/termbits.h | 11 +++++++++++ include/asm-powerpc/termbits.h | 13 +++++++++++++ include/asm-s390/termbits.h | 11 +++++++++++ include/asm-sh/termbits.h | 11 +++++++++++ include/asm-sparc/termbits.h | 12 ++++++++++++ include/asm-sparc64/termbits.h | 12 ++++++++++++ include/asm-v850/termbits.h | 11 +++++++++++ include/asm-x86_64/termbits.h | 11 +++++++++++ 21 files changed, 229 insertions(+), 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c index 337c692f6fd6..ce3a8bac66ff 100644 --- a/drivers/net/wireless/strip.c +++ b/drivers/net/wireless/strip.c @@ -798,7 +798,7 @@ static unsigned int get_baud(struct tty_struct *tty) */ static void set_baud(struct tty_struct *tty, unsigned int baudcode) { - struct termios old_termios = *(tty->termios); + struct ktermios old_termios = *(tty->termios); tty->termios->c_cflag &= ~CBAUD; /* Clear the old baud setting */ tty->termios->c_cflag |= baudcode; /* Set the new baud setting */ tty->driver->set_termios(tty, &old_termios); diff --git a/include/asm-alpha/termbits.h b/include/asm-alpha/termbits.h index 5541101b58ae..ad854a4a3af6 100644 --- a/include/asm-alpha/termbits.h +++ b/include/asm-alpha/termbits.h @@ -25,6 +25,19 @@ struct termios { speed_t c_ospeed; /* output speed */ }; +/* Alpha has matching termios and ktermios */ + +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t c_line; /* line discipline (== c_cc[19]) */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VEOF 0 #define VEOL 1 diff --git a/include/asm-arm/termbits.h b/include/asm-arm/termbits.h index bbc6e1d24d3f..a3f4fe1742d0 100644 --- a/include/asm-arm/termbits.h +++ b/include/asm-arm/termbits.h @@ -15,6 +15,18 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-arm26/termbits.h b/include/asm-arm26/termbits.h index bbc6e1d24d3f..a3f4fe1742d0 100644 --- a/include/asm-arm26/termbits.h +++ b/include/asm-arm26/termbits.h @@ -15,6 +15,18 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-avr32/termbits.h b/include/asm-avr32/termbits.h index 9dc6eacafa33..c215fafdae4d 100644 --- a/include/asm-avr32/termbits.h +++ b/include/asm-avr32/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-cris/termbits.h b/include/asm-cris/termbits.h index be0836d2f282..8d8cec225fe1 100644 --- a/include/asm-cris/termbits.h +++ b/include/asm-cris/termbits.h @@ -19,6 +19,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-frv/termbits.h b/include/asm-frv/termbits.h index 74f20d6e292f..2d6d389cff49 100644 --- a/include/asm-frv/termbits.h +++ b/include/asm-frv/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-h8300/termbits.h b/include/asm-h8300/termbits.h index fa69ae00eda3..6a1f4d3807b4 100644 --- a/include/asm-h8300/termbits.h +++ b/include/asm-h8300/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-i386/termbits.h b/include/asm-i386/termbits.h index 72c10e3190f8..12baf1d6343f 100644 --- a/include/asm-i386/termbits.h +++ b/include/asm-i386/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-ia64/termbits.h b/include/asm-ia64/termbits.h index b9e843f7dc42..4531a511bde5 100644 --- a/include/asm-ia64/termbits.h +++ b/include/asm-ia64/termbits.h @@ -26,6 +26,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-m32r/termbits.h b/include/asm-m32r/termbits.h index 5ace3702df75..faf2bd0504c1 100644 --- a/include/asm-m32r/termbits.h +++ b/include/asm-m32r/termbits.h @@ -19,6 +19,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-m68k/termbits.h b/include/asm-m68k/termbits.h index e9eec3eb0718..a194092240fb 100644 --- a/include/asm-m68k/termbits.h +++ b/include/asm-m68k/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-mips/termbits.h b/include/asm-mips/termbits.h index b62ec7c521cc..0bbe07b42a07 100644 --- a/include/asm-mips/termbits.h +++ b/include/asm-mips/termbits.h @@ -30,6 +30,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 /* Interrupt character [ISIG]. */ #define VQUIT 1 /* Quit character [ISIG]. */ diff --git a/include/asm-parisc/termbits.h b/include/asm-parisc/termbits.h index 372b634892c9..a46e299a9391 100644 --- a/include/asm-parisc/termbits.h +++ b/include/asm-parisc/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-powerpc/termbits.h b/include/asm-powerpc/termbits.h index 6d533b07aaf5..b572f21b32c4 100644 --- a/include/asm-powerpc/termbits.h +++ b/include/asm-powerpc/termbits.h @@ -30,6 +30,19 @@ struct termios { speed_t c_ospeed; /* output speed */ }; +/* For PowerPC the termios and ktermios are the same */ + +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-s390/termbits.h b/include/asm-s390/termbits.h index eb3f8bfabf61..585c78a6e407 100644 --- a/include/asm-s390/termbits.h +++ b/include/asm-s390/termbits.h @@ -25,6 +25,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-sh/termbits.h b/include/asm-sh/termbits.h index 4f9822a8e7b4..f1b7b46f4e9a 100644 --- a/include/asm-sh/termbits.h +++ b/include/asm-sh/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-sparc/termbits.h b/include/asm-sparc/termbits.h index 1794d71134b7..5eb00a105d7c 100644 --- a/include/asm-sparc/termbits.h +++ b/include/asm-sparc/termbits.h @@ -31,6 +31,18 @@ struct termios { #endif }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t _x_cc[2]; /* We need them to hold vmin/vtime */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-sparc64/termbits.h b/include/asm-sparc64/termbits.h index b07715273ed4..705cd44b4173 100644 --- a/include/asm-sparc64/termbits.h +++ b/include/asm-sparc64/termbits.h @@ -33,6 +33,18 @@ struct termios { #endif }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + cc_t _x_cc[2]; /* We need them to hold vmin/vtime */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-v850/termbits.h b/include/asm-v850/termbits.h index 212d4e279263..f3b433032089 100644 --- a/include/asm-v850/termbits.h +++ b/include/asm-v850/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 diff --git a/include/asm-x86_64/termbits.h b/include/asm-x86_64/termbits.h index bd950946e52c..f31918cea510 100644 --- a/include/asm-x86_64/termbits.h +++ b/include/asm-x86_64/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct ktermios { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + /* c_cc characters */ #define VINTR 0 #define VQUIT 1 -- cgit v1.2.3 From 592ee3a5e5e2a981ef2829a0380093006d045661 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 8 Dec 2006 02:38:48 -0800 Subject: [PATCH] termios: Enable new style termios ioctls on x86-64 This turns on the split input/output speed features and arbitary baud rate handling for the x86-64 platform. Nothing should break if you use existing standard speeds. If you use the new speed stuff then you may see some drivers failing to report the speed changes properly in error cases. This will be worked on further. For the working cases this all seems happy. I'll post a test suite used to test the basic stuff as well. Patches for i386 will follow when I get a moment but are basically the same. If people could patch/test-suite other architectures and submit them that would be great. Signed-off-by: Alan Cox Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-x86_64/ioctls.h | 4 ++++ include/asm-x86_64/termbits.h | 16 +++++++++++++++- include/asm-x86_64/termios.h | 6 ++++-- 3 files changed, 23 insertions(+), 3 deletions(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-x86_64/ioctls.h b/include/asm-x86_64/ioctls.h index 62caf8b6e4e1..3fc0b15a0d7e 100644 --- a/include/asm-x86_64/ioctls.h +++ b/include/asm-x86_64/ioctls.h @@ -46,6 +46,10 @@ #define TIOCSBRK 0x5427 /* BSD compatibility */ #define TIOCCBRK 0x5428 /* BSD compatibility */ #define TIOCGSID 0x5429 /* Return the session ID of FD */ +#define TCGETS2 _IOR('T',0x2A, struct termios2) +#define TCSETS2 _IOW('T',0x2B, struct termios2) +#define TCSETSW2 _IOW('T',0x2C, struct termios2) +#define TCSETSF2 _IOW('T',0x2D, struct termios2) #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ diff --git a/include/asm-x86_64/termbits.h b/include/asm-x86_64/termbits.h index f31918cea510..6cfc3bb10c1a 100644 --- a/include/asm-x86_64/termbits.h +++ b/include/asm-x86_64/termbits.h @@ -17,6 +17,17 @@ struct termios { cc_t c_cc[NCCS]; /* control characters */ }; +struct termios2 { + tcflag_t c_iflag; /* input mode flags */ + tcflag_t c_oflag; /* output mode flags */ + tcflag_t c_cflag; /* control mode flags */ + tcflag_t c_lflag; /* local mode flags */ + cc_t c_line; /* line discipline */ + cc_t c_cc[NCCS]; /* control characters */ + speed_t c_ispeed; /* input speed */ + speed_t c_ospeed; /* output speed */ +}; + struct ktermios { tcflag_t c_iflag; /* input mode flags */ tcflag_t c_oflag; /* output mode flags */ @@ -129,6 +140,7 @@ struct ktermios { #define HUPCL 0002000 #define CLOCAL 0004000 #define CBAUDEX 0010000 +#define BOTHER 0010000 /* non standard rate */ #define B57600 0010001 #define B115200 0010002 #define B230400 0010003 @@ -144,10 +156,12 @@ struct ktermios { #define B3000000 0010015 #define B3500000 0010016 #define B4000000 0010017 -#define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CIBAUD 002003600000 /* input baud rate */ #define CMSPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ +#define IBSHIFT 8 /* Shift from CBAUD to CIBAUD */ + /* c_lflag bits */ #define ISIG 0000001 #define ICANON 0000002 diff --git a/include/asm-x86_64/termios.h b/include/asm-x86_64/termios.h index 041a91f7ddfb..443b225537f0 100644 --- a/include/asm-x86_64/termios.h +++ b/include/asm-x86_64/termios.h @@ -98,8 +98,10 @@ struct termio { copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ }) -#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) -#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) +#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) #endif /* __KERNEL__ */ -- cgit v1.2.3 From 08c183f31bdbb709f177f6d3110d5f288ea33933 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Sun, 10 Dec 2006 02:20:29 -0800 Subject: [PATCH] sched: add option to serialize load balancing Large sched domains can be very expensive to scan. Add an option SD_SERIALIZE to the sched domain flags. If that flag is set then we make sure that no other such domain is being balanced. [akpm@osdl.org: build fix] Signed-off-by: Christoph Lameter Cc: Peter Williams Cc: Nick Piggin Cc: Christoph Lameter Cc: "Siddha, Suresh B" Cc: "Chen, Kenneth W" Acked-by: Ingo Molnar Cc: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-i386/topology.h | 1 + include/asm-ia64/topology.h | 1 + include/asm-powerpc/topology.h | 1 + include/asm-x86_64/topology.h | 1 + include/linux/sched.h | 1 + include/linux/topology.h | 3 ++- kernel/sched.c | 9 +++++++++ 7 files changed, 16 insertions(+), 1 deletion(-) (limited to 'include/asm-x86_64') diff --git a/include/asm-i386/topology.h b/include/asm-i386/topology.h index 978d09596130..ac58580ad664 100644 --- a/include/asm-i386/topology.h +++ b/include/asm-i386/topology.h @@ -89,6 +89,7 @@ static inline int node_to_first_cpu(int node) .flags = SD_LOAD_BALANCE \ | SD_BALANCE_EXEC \ | SD_BALANCE_FORK \ + | SD_SERIALIZE \ | SD_WAKE_BALANCE, \ .last_balance = jiffies, \ .balance_interval = 1, \ diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h index a6e38565ab4c..22ed6749557e 100644 --- a/include/asm-ia64/topology.h +++ b/include/asm-ia64/topology.h @@ -101,6 +101,7 @@ void build_cpu_to_node_map(void); .flags = SD_LOAD_BALANCE \ | SD_BALANCE_EXEC \ | SD_BALANCE_FORK \ + | SD_SERIALIZE \ | SD_WAKE_BALANCE, \ .last_balance = jiffies, \ .balance_interval = 64, \ diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h index 50c014007de7..6610495f5f16 100644 --- a/include/asm-powerpc/topology.h +++ b/include/asm-powerpc/topology.h @@ -66,6 +66,7 @@ static inline int pcibus_to_node(struct pci_bus *bus) | SD_BALANCE_EXEC \ | SD_BALANCE_NEWIDLE \ | SD_WAKE_IDLE \ + | SD_SERIALIZE \ | SD_WAKE_BALANCE, \ .last_balance = jiffies, \ .balance_interval = 1, \ diff --git a/include/asm-x86_64/topology.h b/include/asm-x86_64/topology.h index 5c8f49280dbc..2facec5914d2 100644 --- a/include/asm-x86_64/topology.h +++ b/include/asm-x86_64/topology.h @@ -47,6 +47,7 @@ extern int __node_distance(int, int); .flags = SD_LOAD_BALANCE \ | SD_BALANCE_FORK \ | SD_BALANCE_EXEC \ + | SD_SERIALIZE \ | SD_WAKE_BALANCE, \ .last_balance = jiffies, \ .balance_interval = 1, \ diff --git a/include/linux/sched.h b/include/linux/sched.h index 1208feab46e0..ea92e5c89089 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -648,6 +648,7 @@ enum idle_type #define SD_SHARE_CPUPOWER 128 /* Domain members share cpu power */ #define SD_POWERSAVINGS_BALANCE 256 /* Balance for power savings */ #define SD_SHARE_PKG_RESOURCES 512 /* Domain members share cpu pkg resources */ +#define SD_SERIALIZE 1024 /* Only a single load balancing instance */ #define BALANCE_FOR_MC_POWER \ (sched_smt_power_savings ? SD_POWERSAVINGS_BALANCE : 0) diff --git a/include/linux/topology.h b/include/linux/topology.h index b93bb6cc6cc2..6c5a6e6e813b 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h @@ -194,7 +194,8 @@ .wake_idx = 0, /* unused */ \ .forkexec_idx = 0, /* unused */ \ .per_cpu_gain = 100, \ - .flags = SD_LOAD_BALANCE, \ + .flags = SD_LOAD_BALANCE \ + | SD_SERIALIZE, \ .last_balance = jiffies, \ .balance_interval = 64, \ .nr_balance_failed = 0, \ diff --git a/kernel/sched.c b/kernel/sched.c index 0a4a26b21f69..2b2b780939c9 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2880,6 +2880,7 @@ static void update_load(struct rq *this_rq) * * Balancing parameters are set up in arch_init_sched_domains. */ +static DEFINE_SPINLOCK(balancing); static void run_rebalance_domains(struct softirq_action *h) { @@ -2909,6 +2910,11 @@ static void run_rebalance_domains(struct softirq_action *h) if (unlikely(!interval)) interval = 1; + if (sd->flags & SD_SERIALIZE) { + if (!spin_trylock(&balancing)) + goto out; + } + if (time_after_eq(jiffies, sd->last_balance + interval)) { if (load_balance(this_cpu, this_rq, sd, idle)) { /* @@ -2920,6 +2926,9 @@ static void run_rebalance_domains(struct softirq_action *h) } sd->last_balance = jiffies; } + if (sd->flags & SD_SERIALIZE) + spin_unlock(&balancing); +out: if (time_after(next_balance, sd->last_balance + interval)) next_balance = sd->last_balance + interval; } -- cgit v1.2.3