I-pipe: x86 port
PATCH 2/2 I-pipe: x86 port
diffstat:
arch/i386/Kconfig | 3 arch/i386/kernel/Makefile | 1 arch/i386/kernel/apic.c | 8 arch/i386/kernel/entry.S | 87 +++- arch/i386/kernel/i386_ksyms.c | 19 arch/i386/kernel/i8259.c | 31 + arch/i386/kernel/io_apic.c | 90 ++++ arch/i386/kernel/ipipe.c | 646 +++++++++++++++++++++++++++++++ arch/i386/kernel/process.c | 1 arch/i386/kernel/smp.c | 29 + arch/i386/kernel/time.c | 5 arch/i386/kernel/traps.c | 8 arch/i386/mm/fault.c | 2 arch/i386/mm/ioremap.c | 2 include/asm-i386/apic.h | 6 include/asm-i386/io_apic.h | 4 include/asm-i386/ipipe.h | 308 ++++++++++++++ include/asm-i386/mach-default/do_timer.h | 5 include/asm-i386/mach-visws/do_timer.h | 5 include/asm-i386/pgalloc.h | 23 + include/asm-i386/spinlock.h | 4 include/asm-i386/system.h | 31 + ipipe/x86.c | 577 +++++++++++++++++++++++++++ 23 files changed, 1868 insertions(+), 27 deletions(-)
arch/i386/Kconfig +2 -1
@@ -534,6 +534,8 @@ config PREEMPT_BKL Say Y here if you are building a kernel for a desktop system. Say N if you are unsure. +source "ipipe/Kconfig" + config X86_UP_APIC bool "Local APIC support on uniprocessors" depends on !SMP && !(X86_VISWS || X86_VOYAGER)
@@ -941,7 +943,6 @@ config SECCOMP endmenu - menu "Power management options (ACPI, APM)" depends on !X86_VOYAGER
arch/i386/kernel/Makefile +1 -0
@@ -11,6 +11,7 @@ obj-y := process.o semaphore.o signal.o obj-y += cpu/ obj-y += timers/ +obj-$(CONFIG_IPIPE_CORE) += ipipe.o obj-$(CONFIG_ACPI_BOOT) += acpi/ obj-$(CONFIG_X86_BIOS_REBOOT) += reboot.o obj-$(CONFIG_MCA) += mca.o
arch/i386/kernel/apic.c +6 -2
@@ -62,7 +62,7 @@ void ack_bad_irq(unsigned int irq)* unexpected vectors occur) that might lock up the APIC * completely. */ -ack_APIC_irq (); +__ack_APIC_irq (); }void __init apic_intr_init (void )
@@ -1161,6 +1161,10 @@ inline void smp_local_timer_interrupt(st fastcall void smp_apic_timer_interrupt(struct pt_regs *regs) {int cpu =smp_processor_id (); +#ifdef CONFIG_IPIPE_CORE +if (ipipe_running) + regs = __ipipe_tick_regs + cpu; +#endif /* CONFIG_IPIPE_CORE */ /* * the NMI deadlock-detector uses this.
@@ -1197,7 +1201,7 @@ fastcall void smp_spurious_interrupt(str*/ v =apic_read (APIC_ISR + ((SPURIOUS_APIC_VECTOR & ~0x1f ) >>1 ));if (v & (1 << (SPURIOUS_APIC_VECTOR &0x1f ))) -ack_APIC_irq (); +__ack_APIC_irq ();/* see sw-dev-man vol 3, chapter 7.4.13.5 */ printk(KERN_INFO "spurious APIC interrupt on CPU#%d, should never
happen.\n",
arch/i386/kernel/entry.S +23 -6
@@ -75,11 +75,27 @@ DF_MASK = 0x00000400 NT_MASK = 0x00004000 VM_MASK = 0x00020000 +#ifdef CONFIG_IPIPE_CORE +#define CLI call __ipipe_stall_root +#define STI call __ipipe_unstall_root +#define FIXUP_ROOT_IF call __ipipe_if_fixup_root ; movl ORIG_EAX(%esp),%eax +#define EMULATE_ROOT_IRET call __ipipe_unstall_iret_root ; movl EAX(%esp),%eax +#define TEST_PREEMPTIBLE(regs) call __ipipe_kpreempt_root ; testl %eax,%eax +#define restore_nocheck .ipipe_unstall_and_restore_nocheck +#else /* !CONFIG_IPIPE_CORE */ +#define CLI cli +#define STI sti +#define FIXUP_ROOT_IF +#define EMULATE_ROOT_IRET +#define TEST_PREEMPTIBLE(regs) testl $IF_MASK,EFLAGS(regs) +#define restore_nmi restore_all +#endif /* CONFIG_IPIPE_CORE */ + #ifdef CONFIG_PREEMPT -#define preempt_stop cli +#define preempt_stop CLI #else #define preempt_stop -#define resume_kernel restore_nocheck +#define resume_kernel restore_nocheck #endif #define SAVE_ALL \
@@ -141,14 +157,14 @@ ENTRY(ret_from_fork) ALIGN ret_from_exception: preempt_stop -ret_from_intr: +ENTRY(ret_from_intr) GET_THREAD_INFO(%ebp) movl EFLAGS(%esp), %eax # mix EFLAGS and CS movb CS(%esp), %al testl $(VM_MASK | 3), %eax jz resume_kernel ENTRY(resume_userspace) - cli # make sure we don't miss an interrupt + CLI # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx
@@ -159,14 +175,14 @@ ENTRY(resume_userspace) #ifdef CONFIG_PREEMPT ENTRY(resume_kernel) - cli + CLI cmpl $0,TI_preempt_count(%ebp) # non-zero preempt_count ? jnz restore_nocheck need_resched: movl TI_flags(%ebp), %ecx # need_resched set ? testb $_TIF_NEED_RESCHED, %cl jz restore_all - testl $IF_MASK,EFLAGS(%esp) # interrupts off (exception path) ? + TEST_PREEMPTIBLE(%esp) # interrupts off (exception path) ? jz restore_all call preempt_schedule_irq jmp need_resched
@@ -200,6 +216,7 @@ sysenter_past_esp: pushl %eax SAVE_ALL + FIXUP_ROOT_IF GET_THREAD_INFO(%ebp) /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not
testb */
@@ -209,11 +226,12 @@ sysenter_past_esp:
jae syscall_badsys
call *sys_call_table(,%eax,4)
movl %eax,EAX(%esp)
- cli
+ CLI
movl TI_flags(%ebp), %ecx
testw $_TIF_ALLWORK_MASK, %cx
jne syscall_exit_work
/* if something modifies registers it must also disable sysexit */
+ EMULATE_ROOT_IRET
movl EIP(%esp), %edx
movl OLDESP(%esp), %ecx
xorl %ebp,%ebp
@@ -225,6 +243,7 @@ sysenter_past_esp:
ENTRY(system_call)
pushl %eax # save orig_eax
SAVE_ALL
+ FIXUP_ROOT_IF
GET_THREAD_INFO(%ebp)
# system call tracing in operation /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ @@ -236,7 +255,7 @@ syscall_call: call *sys_call_table(,%eax,4) movl %eax,EAX(%esp) # store the return value syscall_exit: - cli # make sure we don't miss an interrupt + CLI # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx @@ -253,7 +272,15 @@ restore_all: andl $(VM_MASK | (4 << 8) | 3), %eax cmpl $((4 << 8) | 3), %eax je ldt_ss # returning to user-space with LDT SS +#ifdef CONFIG_IPIPE_CORE +.ipipe_unstall_and_restore_nocheck: + call __ipipe_unstall_iret_root +restore_nmi: + # FIXME: we need to check for a return to + # user-space on a 16bit stack even in the NMI case +#else /* !CONFIG_IPIPE_CORE */ restore_nocheck: +#endif /* CONFIG_IPIPE_CORE */ RESTORE_REGS addl $4, %esp 1: iret @@ -301,7 +328,7 @@ work_pending: jz work_notifysig work_resched: call schedule - cli # make sure we don't miss an interrupt + CLI # make sure we don't miss an interrupt # setting need_resched or sigpending # between sampling and the iret movl TI_flags(%ebp), %ecx @@ -348,7 +375,7 @@ syscall_trace_entry: syscall_exit_work: testb $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SINGLESTEP), %cl jz work_pending - sti # could let do_syscall_trace() call + STI # could let do_syscall_trace() call # schedule() instead movl %esp, %eax movl $1, %edx @@ -399,7 +426,11 @@ ENTRY(interrupt)
vector=0
ENTRY(irq_entries_start)
+#ifdef CONFIG_IPIPE_CORE
+.rept 224
+#else
.rept NR_IRQS
+#endif
ALIGN
1: pushl $vector-256
jmp common_interrupt
@@ -424,6 +455,36 @@ ENTRY(name) \
call smp_/**/name; \
jmp ret_from_intr;
+#ifdef CONFIG_IPIPE_CORE
+
+.data
+ENTRY(__ipipe_irq_trampolines)
+.text
+
+vector=0
+ENTRY(__ipipe_irq_entries)
+.rept 224
+ ALIGN
+1: pushl $vector-256
+ jmp __ipipe_irq_common
+.data
+ .long 1b
+.text
+vector=vector+1
+.endr
+
+ ALIGN
+__ipipe_irq_common:
+ SAVE_ALL
+ call __ipipe_handle_irq
+ testl %eax,%eax
+ jnz ret_from_intr
+ RESTORE_REGS
+ addl $4, %esp
+ iret
+
+#endif /* CONFIG_IPIPE_CORE */
+
/* The include is where all of the SMP etc. interrupts come from */ #include "entry_arch.h"
@@ -455,6 +516,7 @@ error_code:
movl %ecx, %es
movl %esp,%eax # pt_regs pointer
call *%edi
+ FIXUP_ROOT_IF
jmp ret_from_exception
ENTRY(coprocessor_error)
@@ -470,6 +532,7 @@ ENTRY(simd_coprocessor_error)
ENTRY(device_not_available)
pushl $-1 # mark this as an int
SAVE_ALL
+ FIXUP_ROOT_IF
movl %cr0, %eax
testl $0x4, %eax # EM (math emulation bit)
jne device_not_available_emulate
@@ -511,6 +574,7 @@ ENTRY(debug)
debug_stack_correct:
pushl $-1 # mark this as an int
SAVE_ALL
+ FIXUP_ROOT_IF
xorl %edx,%edx # error code 0
movl %esp,%eax # pt_regs pointer
call do_debug
@@ -549,7 +613,7 @@ nmi_stack_correct:
xorl %edx,%edx # zero error code
movl %esp,%eax # pt_regs pointer
call do_nmi
- jmp restore_all
+ jmp restore_nmi
nmi_stack_fixup:
FIX_STACK(12,nmi_stack_correct, 1)
@@ -591,6 +655,7 @@ nmi_16bit_stack:
ENTRY(int3)
pushl $-1 # mark this as an int
SAVE_ALL
+ FIXUP_ROOT_IF
xorl %edx,%edx # zero error code
movl %esp,%eax # pt_regs pointer
call do_int3
arch/i386/kernel/i386_ksyms.c +19 -0
@@ -36,6 +36,25 @@extern void dump_thread (struct pt_regs *,struct user *);extern spinlock_t rtc_lock; +#ifdef CONFIG_IPIPE_CORE +#ifdef CONFIG_IPIPE_MODULE +extern int __ipipe_irq_trampolines; +EXPORT_SYMBOL (__ipipe_irq_trampolines); +#ifdef CONFIG_X86_LOCAL_APIC +extern int using_apic_timer; +EXPORT_SYMBOL (using_apic_timer); +#endif /* CONFIG_X86_LOCAL_APIC */ +extern struct desc_struct idt_table[]; +EXPORT_SYMBOL (idt_table); +#ifdef CONFIG_X86_IO_APIC +EXPORT_SYMBOL (io_apic_irqs); +EXPORT_SYMBOL (irq_vector); +#endif /* CONFIG_X86_IO_APIC */ +#endif /* CONFIG_IPIPE_MODULE */ +extern irq_desc_t irq_desc[]; +EXPORT_SYMBOL (irq_desc); +#endif /* CONFIG_IPIPE_CORE */ +/* This is definitely a GPL-only symbol */ EXPORT_SYMBOL_GPL (cpu_gdt_table);
arch/i386/kernel/i8259.c +31 -0
@@ -170,6 +170,36 @@ static inline int i8259A_irq_real(unsign*/ static void mask_and_ack_8259A (unsigned int irq) { +#ifdef CONFIG_IPIPE_CORE +unsigned int irqmask =1 << irq; + +spin_lock (&i8259A_lock); + +if (cached_irq_mask & irqmask) + goto spurious_8259A_irq; + +if (irq ==0 ) { +/* Fast timer ack -- don't mask +(unless supposedly spurious) */ +outb (0x20 ,PIC_MASTER_CMD ); +spin_unlock (&i8259A_lock); +return ; + } + + cached_irq_mask |= irqmask; + +handle_real_irq: +if (irq &8 ) { +outb (cached_slave_mask,PIC_SLAVE_IMR ); +outb (0x60 +(irq&7 ),PIC_SLAVE_CMD );/* 'Specific EOI' to slave */ +outb (0x60 +PIC_CASCADE_IR ,PIC_MASTER_CMD );/* 'Specific EOI' to master-IRQ2 */ + }else { +outb (cached_master_mask,PIC_MASTER_IMR ); +outb (0x60 +irq,PIC_MASTER_CMD );/* 'Specific EOI to master */ + } +spin_unlock (&i8259A_lock); +return ; +#else /* !CONFIG_IPIPE_CORE */ unsigned int irqmask =1 << irq;unsigned long flags;
@@ -206,6 +236,7 @@ handle_real_irq: }spin_unlock_irqrestore (&i8259A_lock, flags);return ; +#endif /* CONFIG_IPIPE_CORE */ spurious_8259A_irq:/*
arch/i386/kernel/io_apic.c +89 -1
120 lines not on this page · raw message
arch/i386/kernel/ipipe.c +646 -0
646 lines not on this page · raw message
arch/i386/kernel/process.c +1 -0
@@ -161,6 +161,7 @@ void cpu_idle (void) idle = default_idle;__get_cpu_var (irq_stat).idle_timestamp = jiffies; +ipipe_suspend_domain ();idle (); }schedule ();
arch/i386/kernel/smp.c +9 -4
@@ -131,6 +131,9 @@ void __send_IPI_shortcut(unsigned int sh* to the APIC. */ unsigned int cfg; +unsigned long flags; + +local_irq_save_hw_cond (flags);/* * Wait for idle.
@@ -146,6 +149,8 @@ void __send_IPI_shortcut(unsigned int sh* Send the IPI. The write to APIC_ICR fires this off. */ apic_write_around (APIC_ICR , cfg); + +local_irq_restore_hw_cond (flags); } void fastcall send_IPI_self(int vector)
@@ -162,7 +167,7 @@ void send_IPI_mask_bitmask(cpumask_t cpuunsigned long cfg;unsigned long flags; -local_irq_save (flags); +local_irq_save_hw (flags);/* * Wait for idle.
@@ -185,7 +190,7 @@ void send_IPI_mask_bitmask(cpumask_t cpu*/ apic_write_around (APIC_ICR , cfg); -local_irq_restore (flags); +local_irq_restore_hw (flags); }void send_IPI_mask_sequence (cpumask_t mask,int vector)
@@ -199,7 +204,7 @@ void send_IPI_mask_sequence(cpumask_t ma* should be modified to do 1 message per cluster ID - mbligh */ -local_irq_save (flags); +local_irq_save_hw (flags);for (query_cpu =0 ; query_cpu <NR_CPUS ; ++query_cpu) {if (cpu_isset (query_cpu, mask)) {
@@ -226,7 +231,7 @@ void send_IPI_mask_sequence(cpumask_t maapic_write_around (APIC_ICR , cfg); } } -local_irq_restore (flags); +local_irq_restore_hw (flags); }#include <mach_ipi.h> /* must come after the send_IPI functions above
for inlining */
@@ -310,7 +315,9 @@ static inline void leave_mm (unsigned lo
fastcall void smp_invalidate_interrupt(struct pt_regs *regs) {
- unsigned long cpu;
+ unsigned long cpu, flags;
+
+ local_irq_save_hw_cond(flags);
cpu = get_cpu();
@@ -340,6 +347,7 @@ fastcall void smp_invalidate_interrupt(s
smp_mb__after_clear_bit();
out:
put_cpu_no_resched();
+ local_irq_restore_hw_cond(flags);
}
static void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
@@ -400,14 +408,19 @@ void flush_tlb_current_task(void)
{
struct mm_struct *mm = current->mm;
cpumask_t cpu_mask;
+ unsigned long flags;
preempt_disable();
+ local_irq_save_hw_cond(flags);
+
cpu_mask = mm->cpu_vm_mask;
cpu_clear(smp_processor_id(), cpu_mask);
local_flush_tlb();
if (!cpus_empty(cpu_mask))
flush_tlb_others(cpu_mask, mm, FLUSH_ALL);
+
+ local_irq_restore_hw_cond(flags);
preempt_enable();
}
@@ -435,8 +448,11 @@ void flush_tlb_page(struct vm_area_struc
{
struct mm_struct *mm = vma->vm_mm; cpumask_t cpu_mask;
+ unsigned long flags;
preempt_disable();
+ local_irq_save_hw_cond(flags);
+
cpu_mask = mm->cpu_vm_mask;
cpu_clear(smp_processor_id(), cpu_mask);
@@ -447,6 +463,8 @@ void flush_tlb_page(struct vm_area_struc
leave_mm(smp_processor_id());
}
+ local_irq_restore_hw_cond(flags);
+
if (!cpus_empty(cpu_mask))
flush_tlb_others(cpu_mask, mm, va);
@@ -609,4 +627,3 @@ fastcall void smp_call_function_interrup
atomic_inc(&call_data->finished);
}
}
-
arch/i386/kernel/time.c +3 -2
@@ -258,11 +258,12 @@ static inline void do_timer_interrupt(in* This will also deassert NMI lines for the watchdog if run * on an 82489DX-based system. */ -spin_lock (&i8259A_lock); +unsigned long flags; +spin_lock_irqsave_hw_cond (&i8259A_lock,flags);outb (0x0c ,PIC_MASTER_OCW3 );/* Ack the IRQ; AEOI will end it automatically. */ inb (PIC_MASTER_POLL ); - spin_unlock(&i8259A_lock); + spin_unlock_irqrestore_hw_cond(&i8259A_lock,flags); }#endif
arch/i386/kernel/traps.c +8 -0
@@ -226,6 +226,11 @@ void show_registers(struct pt_regs *regs regs->esi, regs->edi, regs->ebp, esp);printk ("ds: %04x es: %04x ss: %04x\n" , regs->xds &0xffff , regs->xes &0xffff , ss); +#ifdef CONFIG_IPIPE_CORE +if (ipipe_current_domain != ipipe_root_domain) +printk ("I-pipe domain %s" ,ipipe_current_domain->name); + else +#endif /* CONFIG_IPIPE_CORE */ printk ("Process %s (pid: %d, threadinfo=%p task=%p)" , current->comm, current->pid,current_thread_info (), current);/*
@@ -946,12 +951,15 @@ asmlinkage void math_state_restore(struc {struct thread_info *thread =current_thread_info ();struct task_struct *tsk = thread->task; +unsigned long flags; +local_irq_save_hw_cond (flags);clts ();/* Allow maths ops (or we recurse) */ if (!tsk_used_math (tsk))init_fpu (tsk);restore_fpu (tsk); thread->status |=TS_USEDFPU ;/* So we fnsave on switch_to() */ +local_irq_restore_hw_cond (flags); }#ifndef CONFIG_MATH_EMULATION
arch/i386/mm/fault.c +2 -0
@@ -224,6 +224,8 @@ fastcall void do_page_fault(struct pt_re/* get the address */ __asm__("movl %%cr2,%0" :"=r" (address)); +local_irq_enable_hw_cond (); +if (notify_die (DIE_PAGE_FAULT ,"page fault" , regs, error_code,14 ,SIGSEGV ) ==NOTIFY_STOP )return ;
arch/i386/mm/ioremap.c +2 -0
@@ -16,6 +16,7 @@#include <asm/cacheflush.h> #include <asm/tlbflush.h> #include <asm/pgtable.h> +#include <asm/pgalloc.h> #define ISA_START_ADDRESS 0xa0000#define ISA_END_ADDRESS 0x100000
@@ -92,6 +93,7 @@ static int ioremap_page_range(unsigned l err =ioremap_pud_range (pgd, addr, next, phys_addr+addr, flags);if (err)break ; +set_pgdir (addr, *pgd); }while (pgd++, addr = next, addr != end);spin_unlock (&init_mm.page_table_lock);flush_tlb_all ();
include/asm-i386/apic.h +6 -0
@@ -69,7 +69,13 @@ int get_physical_broadcast(void);# define apic_write_around (x,y) apic_write_atomic((x),(y))#endif +#ifdef CONFIG_IPIPE_CORE +#define ack_APIC_irq () do { if (!ipipe_running) __ack_APIC_irq(); } while(0) +static inline void __ack_APIC_irq(void) +#else /* !CONFIG_IPIPE_CORE */ +#define __ack_APIC_irq () ack_APIC_irq() static inline void ack_APIC_irq(void) +#endif /* CONFIG_IPIPE_CORE */ {/* * ack_APIC_irq() actually gets compiled as a single instruction:
include/asm-i386/io_apic.h +1 -0
@@ -16,7 +16,9 @@#ifdef CONFIG_PCI_MSI static inline int use_pci_vector (void ) {return 1 ;}static inline void disable_edge_ioapic_vector (unsigned int vector) { } +#ifndef CONFIG_IPIPE_CORE static inline void mask_and_ack_level_ioapic_vector(unsigned int
vector) { }
+#endif /* !CONFIG_IPIPE_CORE */
static inline void end_edge_ioapic_vector (unsigned int vector) { }
#define startup_level_ioapic startup_level_ioapic_vector
#define shutdown_level_ioapic mask_IO_APIC_vector
@@ -35,7 +37,9 @@ static inline void end_edge_ioapic_vecto
#else
static inline int use_pci_vector(void) {return 0;}
static inline void disable_edge_ioapic_irq(unsigned int irq) { }
+#ifndef CONFIG_IPIPE_CORE
static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { }
+#endif /* !CONFIG_IPIPE_CORE */
static inline void end_edge_ioapic_irq (unsigned int irq) { }
#define startup_level_ioapic startup_level_ioapic_irq
#define shutdown_level_ioapic mask_IO_APIC_irq
include/asm-i386/ipipe.h +308 -0
308 lines not on this page · raw message
include/asm-i386/mach-default/do_timer.h 2005-06-15 17:35:32.000000000 +0200 renamed from include/asm-i386/mach-default/do_timer.h +3 -2
@@ -49,14 +49,15 @@ static inline void do_timer_interrupt_ho static inline int do_timer_overflow(int count) { int i; + unsigned long flags; - spin_lock(&i8259A_lock); + spin_lock_irqsave_hw_cond(&i8259A_lock, flags); /* * This is tricky when I/O APICs are used; * see do_timer_interrupt(). */ i = inb(0x20); - spin_unlock(&i8259A_lock); + spin_unlock_irqrestore_hw_cond(&i8259A_lock, flags); /* assumption about timer being IRQ0 */ if (i & 0x01) {
include/asm-i386/mach-visws/do_timer.h 2005-06-15 17:35:32.000000000 +0200 renamed from include/asm-i386/mach-visws/do_timer.h +3 -2
@@ -28,14 +28,15 @@ static inline void do_timer_interrupt_ho static inline int do_timer_overflow(int count) { int i; + unsigned long flags; - spin_lock(&i8259A_lock); + spin_lock_irqsave_hw_cond(&i8259A_lock, flags); /* * This is tricky when I/O APICs are used; * see do_timer_interrupt(). */ i = inb(0x20); - spin_unlock(&i8259A_lock); + spin_unlock_irqrestore_hw_cond(&i8259A_lock, flags); /* assumption about timer being IRQ0 */ if (i & 0x01) {
include/asm-i386/pgalloc.h +23 -0
@@ -47,4 +47,27 @@ static inline void pte_free(struct page#define check_pgt_cache () do { } while (0) +static inline void set_pgdir (unsigned long address,pgd_t entry) +{ +#ifdef CONFIG_IPIPE_CORE +struct task_struct * p; +struct page *page; +pgd_t *pgd; + +read_lock (&tasklist_lock); + +for_each_process (p) { +if (p->mm) + *pgd_offset (p->mm,address) = entry; + } + +read_unlock (&tasklist_lock); + +for (page = pgd_list; page; page = (struct page *)page->index) { + pgd = (pgd_t *)page_address (page); + pgd[address >>PGDIR_SHIFT ] = entry; + } +#endif /* CONFIG_IPIPE_CORE */ +} +#endif /* _I386_PGALLOC_H */
include/asm-i386/spinlock.h +4 -0
@@ -57,6 +57,9 @@ typedef struct {"jmp 1b\n" \ "3:\n\t" +#ifdef CONFIG_IPIPE_CORE +#define spin_lock_string_flags spin_lock_string +#else /* !CONFIG_IPIPE_CORE */ #define spin_lock_string_flags \ "\n1:\t" \ "lock ; decb %0\n\t" \
@@ -72,6 +75,7 @@ typedef struct {"cli\n\t" \"jmp 1b\n" \ "4:\n\t" +#endif /* CONFIG_IPIPE_CORE */ /* * This works. Despite all the confusion.
include/asm-i386/system.h +29 -0
@@ -441,6 +441,35 @@ struct alt_instr {#define set_wmb (var, value) do { var = value; wmb(); } while (0)/* interrupt control.. */ +#ifdef CONFIG_IPIPE_CORE + +#include <linux/linkage.h> + +void __ipipe_stall_root (void ); + +void __ipipe_unstall_root (void ); + +unsigned long __ipipe_test_root (void ); + +unsigned long __ipipe_test_and_stall_root (void ); + +void fastcall __ipipe_restore_root(unsigned long flags); + +#define local_save_flags (x) ((x) = __ipipe_test_root()) +#define local_irq_save (x) ((x) = __ipipe_test_and_stall_root()) +#define local_irq_restore (x) __ipipe_restore_root(x) +#define local_irq_disable () __ipipe_stall_root() +#define local_irq_enable () __ipipe_unstall_root() + +#define irqs_disabled () __ipipe_test_root() + +#define safe_halt () do { \ + __ipipe_unstall_root(); \ + __asm__ __volatile__("sti; hlt": : :"memory"); \ +} while(0) + +#else /* !CONFIG_IPIPE_CORE */ +#define local_save_flags (x) do { typecheck(unsigned long,x); __asm__
__volatile__("pushfl ; popl %0":"=g" (x): /* no input */); } while (0)
#define local_irq_restore(x) do { typecheck(unsigned long,x); __asm____volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory", "cc"); } while (0)
#define local_irq_disable() __asm__ __volatile__("cli": : :"memory")
@@ -458,6 +487,8 @@ struct alt_instr {
/* For spinlocks etc */
#define local_irq_save(x) __asm__ __volatile__("pushfl ; popl %0 ;
cli":"=g" (x): /* no input */ :"memory")
+#endif /* CONFIG_IPIPE_CORE */
+
/*
* disable hlt during certain critical i/o operations */
ipipe/x86.c +577 -0
577 lines not on this page · raw message
Signature · 1 line
Philippe.
include/asm-i386/system.h struct alt_instr { · line 464
Quoted 7 lines · Philippe Gerum
include/asm-i386/system.h +7
-0+#define local_save_flags (x) ((x) = __ipipe_test_root()) +#define local_irq_save (x) ((x) = __ipipe_test_and_stall_root()) +#define local_irq_restore (x) __ipipe_restore_root(x) +#define local_irq_disable () __ipipe_stall_root() +#define local_irq_enable () __ipipe_unstall_root() + +#define irqs_disabled () __ipipe_test_root()
If you want to integrate with newer RT patches , (I'm not sure which one this is on) .. You could modify the above so that it uses the soft irq's off flags . So if linux is in a soft irq disable than it's equal to a stall on the ipipe ..
Daniel
Quoted 15 lines · Daniel Walker
include/asm-i386/system.h struct alt_instr { · line 464
Quoted 7 lines · Philippe Gerum
include/asm-i386/system.h +7
-0+#define local_save_flags (x) ((x) = __ipipe_test_root()) +#define local_irq_save (x) ((x) = __ipipe_test_and_stall_root()) +#define local_irq_restore (x) __ipipe_restore_root(x) +#define local_irq_disable () __ipipe_stall_root() +#define local_irq_enable () __ipipe_unstall_root() + +#define irqs_disabled () __ipipe_test_root()If you want to integrate with newer RT patches , (I'm not sure which one this is on) ..
This patch only inherits the basic conditionals for integrating with PREEMPT_RT from a recent Adeos combo experimenting the issue w/ 0.7.44-03, but there is indeed more to do for completing the integration with recent PREEMPT_RT patches.
You could modify the above so that it uses the soft irq's
Quoted 3 lines
off flags . So if linux is in a soft irq disable than it's equal to a stall on the ipipe ..
Ack. I will provide a newer combo patch using PREEMPT_RT's virtualized local_irq_disable for the root domain. Thanks for the hint.
Signature · 1 line
Philippe.