Skip to contentSkip to conversation

I-pipe: x86 port

PATCH In review Philippe Gerum 2 participants 3 messages Jun 17, 2005 – Jun 21, 2005

lore
Share & tools
lore
#0 lore raw

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 cpu
 	unsigned 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 ma
 			apic_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.
#1 lore raw

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

#2 lore raw
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.