public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
@ 2005-11-09 13:54 Jan Beulich
  2005-11-09 13:56 ` [PATCH 1/39] NLKD - an alternative kallsyms approach Jan Beulich
                   ` (2 more replies)
  0 siblings, 3 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 13:54 UTC (permalink / raw)
  To: linux-kernel

The following patch set represents the Novell Linux Kernel Debugger,
stripped off of its original low-level exception handling framework.

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 1/39] NLKD - an alternative kallsyms approach
  2005-11-09 13:54 [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jan Beulich
@ 2005-11-09 13:56 ` Jan Beulich
  2005-11-09 13:57   ` [PATCH 2/39] NLKD - an alternative early ioremap approach Jan Beulich
  2005-11-09 16:50   ` [PATCH 1/39] NLKD - an alternative kallsyms approach Randy.Dunlap
  2005-11-09 16:59 ` [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jeff Garzik
       [not found] ` <437214E4.76F0.0078.0@novell.com>
  2 siblings, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 13:56 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1091 bytes --]

This patch provides an alternative to the pre-exisiting kallsyms code.
That code, from a kernel debugger perspective at least, suffers from
incomplete information, making it impossible to
(a) disambiguate multiple static functions of the same name (in
different source files),
(b) determine a complete set of attributes for a symbol (namely, the
symbol's size, but also its type, which gets converted to an nm-like
one-character representation), and
(c) retain full section information

This new approach basically makes handling core kernel and module
symbols the same, by retrieving the kernel's section, symbol, and
string tables rather than parsing the system map.

At once it adds the functionality to strip unneeded symbols from
modules, which results in non-neglectable space savings for typical
distributions (which large amounts of modules). Note that with certain
recent, but broken binutils versions (2.16.90*, 2.16.91* up to
and including 2.16.91.0.3) this can only be built without
CONFIG_MODVERSIONS.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-kallsyms.patch --]
[-- Type: application/octet-stream, Size: 68058 bytes --]

This patch provides an alternative to the pre-exisiting kallsyms code.
That code, from a kernel debugger perspective at least, suffers from
incomplete information, making it impossible to
(a) disambiguate multiple static functions of the same name (in
different source files),
(b) determine a complete set of attributes for a symbol (namely, the
symbol's size, but also its type, which gets converted to an nm-like
one-character representation), and
(c) retain full section information

This new approach basically makes handling core kernel and module
symbols the same, by retrieving the kernel's section, symbol, and
string tables rather than parsing the system map.

At once it adds the functionality to strip unneeded symbols from
modules, which results in non-neglectable space savings for typical
distributions (which large amounts of modules). Note that with certain
recent, but broken binutils versions (2.16.90*, 2.16.91* up to
and including 2.16.91.0.3) this can only be built without
CONFIG_MODVERSIONS.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

--- 2.6.14/Makefile	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/Makefile	2005-11-04 16:20:57.000000000 +0100
@@ -160,15 +160,19 @@ LOCALVERSION = $(subst $(space),, \
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)$(LOCALVERSION)
 
+HOSTARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+				   -e s/arm.*/arm/ -e s/sa110/arm/ \
+				   -e s/s390x/s390/ -e s/parisc64/parisc/ )
+
 # SUBARCH tells the usermode build what the underlying arch is.  That is set
 # first, and if a usermode build is happening, the "ARCH=um" on the command
 # line overrides the setting of ARCH below.  If a native build is happening,
 # then ARCH is assigned, getting whatever value it gets normally, and 
 # SUBARCH is subsequently ignored.
 
-SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
-				  -e s/arm.*/arm/ -e s/sa110/arm/ \
-				  -e s/s390x/s390/ -e s/parisc64/parisc/ )
+ifeq ($(SUBARCH),)
+SUBARCH         := $(if $(filter-out um,$(ARCH)),$(ARCH),$(HOSTARCH))
+endif
 
 # Cross compiling and selecting different set of gcc/bin-utils
 # ---------------------------------------------------------------------------
@@ -327,6 +331,7 @@ NM		= $(CROSS_COMPILE)nm
 STRIP		= $(CROSS_COMPILE)strip
 OBJCOPY		= $(CROSS_COMPILE)objcopy
 OBJDUMP		= $(CROSS_COMPILE)objdump
+READELF		= $(CROSS_COMPILE)readelf
 AWK		= awk
 GENKSYMS	= scripts/genksyms/genksyms
 DEPMOD		= /sbin/depmod
@@ -729,24 +734,108 @@ endef
 
 # Generate .S file with all kernel symbols
 quiet_cmd_kallsyms = KSYM    $@
-      cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
-                     $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
 
-.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
+ifdef CONFIG_KALLSYMS_TRADITIONAL
+
+cmd_kallsyms = { test $* -eq 0 || $(NM) -n $<; } | $(KALLSYMS) $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) >$@
+
+kallsyms-strip-ext :=
+
+else
+
+cmd_kallsyms = { test $* -eq 0 || $(NM) -n $<; } | $(KALLSYMS) -$$(expr $* + 1) >$@
+
+kallsyms-strip-src := $(if $(CONFIG_KALLSYMS_STRIP_GENERATED),$(srctree)/$(KALLSYMS))
+kallsyms-strip-src += $(if $(CONFIG_KALLSYMS_STRIP_GENERATED),$(wildcard $(srctree)/arch/$(ARCH)/kallsyms))
+kallsyms-strip-src += $(if $(CONFIG_KALLSYMS_ALL),,.tmp_data)
+kallsyms-strip-src := $(strip $(kallsyms-strip-src))
+kallsyms-strip-ext := $(if $(kallsyms-strip-src),.stripped)
+
+quiet_cmd_ktab = KTAB    $@
+define cmd_ktab
+	if [ $* -eq 0 ]; then \
+		echo "placeholder" >$@; \
+	else \
+		rm -f $@; \
+		$(READELF) -SW $< | while read idx name type addr offs size more; do \
+			if [ "$(suffix $@)" = "$$name" ]; then \
+				tail -c+$$((0x$$offs+1)) <$< | head -c $$((0x$$size)) >$@; \
+				break; \
+			fi; \
+		done; \
+		test -s $@; \
+	fi
+endef
+
+quiet_cmd_kshdr = KSHDR   $@
+define cmd_kshdr
+	if [ $* -eq 0 ]; then \
+		echo "placeholder" >$@; \
+	else \
+		nsect= ;: grab this from the first decimal number; \
+		osect= ;: grab this from the first hexadecimal number; \
+		for i in $$($(READELF) -S $< | egrep '^[^]\[()]*$$'); \
+		do \
+			test -z "$$nsect" && nsect=$$(echo $${i%:*} | egrep '^[[:digit:]]+$$'); \
+			test -z "$$osect" && osect=$$(echo $${i%:*} | egrep '^0[xX][[:xdigit:]]+$$'); \
+		done; \
+		zsect= ;: grab this from the last number that is followed by a unit specification; \
+		for i in $$($(READELF) -h $< | egrep ':[[:space:]]+[[:digit:]]+[[:space:]]+\(.*\)'); \
+		do \
+			val=$$(echo $$i | egrep '^([[:digit:]]+|0[xX][[:xdigit:]]+)$$'); \
+			test -n "$$val" && zsect=$$val; \
+		done; \
+		tail -c+$$((osect+1)) <$< | head -c $$((nsect*zsect)) >$@; \
+	fi
+endef
+
+quiet_cmd_kstrip = STRIP   $<
+cmd_kstrip = $(OBJCOPY) $(addprefix --strip-symbols ,$(filter %.strip,$^)) -w $< $@
+
+.tmp_kallsyms%.symtab: .tmp_vmlinux%$(kallsyms-strip-ext)
+	$(call cmd,ktab)
+
+.tmp_kallsyms%.strtab: .tmp_vmlinux%$(kallsyms-strip-ext)
+	$(call cmd,ktab)
+
+.tmp_kallsyms%.sections: .tmp_vmlinux%$(kallsyms-strip-ext)
+	$(call cmd,kshdr)
+
+.tmp_kallsyms%.shstrtab: .tmp_vmlinux%$(kallsyms-strip-ext)
+	$(call cmd,ktab)
+
+.tmp_vmlinux%.stripped: .tmp_vmlinux% $(addsuffix .strip,$(kallsyms-strip-src)) $(objtree)/include/linux/autoconf.h
+	$(call cmd,kstrip)
+
+.tmp_data.strip: .tmp_vmlinux1 $(objtree)/include/linux/autoconf.h
+	$(Q)$(NM) $< | sed -n 's,[[:xdigit:]]\+[[:space:]]\+[^tT][[:space:]]\+\(.*\),\1,p' \
+		| while read i; do case $$i in \
+			$(addsuffix $(close);;, \
+				$(shell cat $(addsuffix .strip,$(filter $(srctree)/%,$(kallsyms-strip-src))) /dev/null \
+				        | sed 's,\([;|&<>()$$\\]\),\\\1,g')) \
+			*) echo $$i;; \
+		esac; done >$@
+
+endif # CONFIG_KALLSYMS_TRADITIONAL
+
+$(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): AFLAGS+=-Wa,--strip-local-absolute
+$(foreach n,0 1 2 3,.tmp_kallsyms$(n).o): %.o: %.S $(if $(CONFIG_KALLSYMS_TRADITIONAL),,%.symtab %.strtab %.sections %.shstrtab) scripts FORCE
 	$(call if_changed_dep,as_o_S)
 
-.tmp_kallsyms%.S: .tmp_vmlinux% $(KALLSYMS)
+.tmp_kallsyms%.S: .tmp_vmlinux%$(kallsyms-strip-ext) $(KALLSYMS) $(objtree)/include/linux/autoconf.h
 	$(call cmd,kallsyms)
 
-# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
-.tmp_vmlinux1: $(vmlinux-lds) $(vmlinux-all) FORCE
-	$(call if_changed_rule,ksym_ld)
+.tmp_vmlinux0$(kallsyms-strip-ext):
+	$(Q)echo "placeholder" >$@
 
-.tmp_vmlinux2: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms1.o FORCE
-	$(call if_changed,vmlinux__)
+.tmp_vmlinux1: .tmp_kallsyms0.o
+.tmp_vmlinux2: .tmp_kallsyms1.o
+.tmp_vmlinux3: .tmp_kallsyms2.o
 
-.tmp_vmlinux3: $(vmlinux-lds) $(vmlinux-all) .tmp_kallsyms2.o FORCE
-	$(call if_changed,vmlinux__)
+.tmp_vmlinux%: LDFLAGS_vmlinux += -S
+# .tmp_vmlinux1 must be complete except kallsyms, so update vmlinux version
+.tmp_vmlinux%: $(vmlinux-lds) $(vmlinux-all) FORCE
+	$(if $(filter 1,$*),$(call if_changed_rule,ksym_ld),$(call if_changed,vmlinux__))
 
 # Needs to visit scripts/ before $(KALLSYMS) can be used.
 $(KALLSYMS): scripts ;
@@ -980,7 +1069,7 @@ endif # CONFIG_MODULES
 # Directories & files removed with 'make clean'
 CLEAN_DIRS  += $(MODVERDIR)
 CLEAN_FILES +=	vmlinux System.map \
-                .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
+                .tmp_data* .tmp_kallsyms* .tmp_version .tmp_vmlinux* .tmp_System.map
 
 # Directories & files removed with 'make mrproper'
 MRPROPER_DIRS  += include/config include2
--- 2.6.14/arch/alpha/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/alpha/defconfig	2005-09-07 12:36:02.000000000 +0200
@@ -32,6 +32,7 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
--- 2.6.14/arch/frv/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/frv/defconfig	2005-09-07 12:34:09.000000000 +0200
@@ -33,6 +33,7 @@ CONFIG_SYSCTL=y
 # CONFIG_IKCONFIG is not set
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_PRINTK=y
--- 2.6.14/arch/i386/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/i386/defconfig	2005-09-07 12:32:14.000000000 +0200
@@ -28,6 +28,8 @@ CONFIG_HOTPLUG=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_IOSCHED_NOOP=y
--- 2.6.14/arch/i386/kernel/entry.S	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/i386/kernel/entry.S	2005-11-04 16:45:13.000000000 +0100
@@ -129,6 +129,7 @@ ENTRY(ret_from_fork)
 	GET_THREAD_INFO(%ebp)
 	popl %eax
 	jmp syscall_exit
+END(ret_from_fork)
 
 /*
  * Return to user mode is not as complex as all this looks,
@@ -156,6 +157,7 @@ ENTRY(resume_userspace)
 					# int/exception return?
 	jne work_pending
 	jmp restore_all
+END(ret_from_exception)
 
 #ifdef CONFIG_PREEMPT
 ENTRY(resume_kernel)
@@ -170,6 +172,7 @@ need_resched:
 	jz restore_all
 	call preempt_schedule_irq
 	jmp need_resched
+END(resume_kernel)
 #endif
 
 /* SYSENTER_RETURN points to after the "sysenter" instruction in
@@ -219,6 +222,7 @@ sysenter_past_esp:
 	xorl %ebp,%ebp
 	sti
 	sysexit
+ENDPROC(sysenter_entry)
 
 
 	# system call handler stub
@@ -293,6 +297,7 @@ ldt_ss:
 	.align 4
 	.long 1b,iret_exc
 .previous
+ENDPROC(system_call)
 
 	# perform work that needs to be done immediately before resumption
 	ALIGN
@@ -330,6 +335,7 @@ work_notifysig_v86:
 	xorl %edx, %edx
 	call do_notify_resume
 	jmp resume_userspace
+END(work_pending)
 
 	# perform syscall exit tracing
 	ALIGN
@@ -345,6 +351,7 @@ syscall_trace_entry:
 	cmpl $(nr_syscalls), %eax
 	jnae syscall_call
 	jmp syscall_exit
+END(syscall_trace_entry)
 
 	# perform syscall exit tracing
 	ALIGN
@@ -357,6 +364,7 @@ syscall_exit_work:
 	movl $1, %edx
 	call do_syscall_trace
 	jmp resume_userspace
+END(syscall_exit_work)
 
 	ALIGN
 syscall_fault:
@@ -365,11 +373,13 @@ syscall_fault:
 	GET_THREAD_INFO(%ebp)
 	movl $-EFAULT,EAX(%esp)
 	jmp resume_userspace
+END(syscall_fault)
 
 	ALIGN
 syscall_badsys:
 	movl $-ENOSYS,EAX(%esp)
 	jmp resume_userspace
+END(syscall_badsys)
 
 #define FIXUP_ESPFIX_STACK \
 	movl %esp, %eax; \
@@ -398,19 +408,24 @@ syscall_badsys:
  */
 .data
 ENTRY(interrupt)
-.text
+.previous
 
-vector=0
 ENTRY(irq_entries_start)
+vector=0
 .rept NR_IRQS
 	ALIGN
 1:	pushl $vector-256
 	jmp common_interrupt
-.data
+ .data
 	.long 1b
-.text
-vector=vector+1
+ .previous
+ vector=vector+1
 .endr
+END(irq_entries_start)
+
+.data
+END(interrupt)
+.previous
 
 	ALIGN
 common_interrupt:
@@ -418,6 +433,7 @@ common_interrupt:
 	movl %esp,%eax
 	call do_IRQ
 	jmp ret_from_intr
+ENDPROC(common_interrupt)
 
 #define BUILD_INTERRUPT(name, nr)	\
 ENTRY(name)				\
@@ -425,7 +441,8 @@ ENTRY(name)				\
 	SAVE_ALL			\
 	movl %esp,%eax;			\
 	call smp_/**/name;		\
-	jmp ret_from_intr;
+	jmp ret_from_intr;	\
+ENDPROC(name)
 
 /* The include is where all of the SMP etc. interrupts come from */
 #include "entry_arch.h"
@@ -433,6 +450,7 @@ ENTRY(name)				\
 ENTRY(divide_error)
 	pushl $0			# no error code
 	pushl $do_divide_error
+END(divide_error)
 	ALIGN
 error_code:
 	pushl %ds
@@ -459,16 +477,19 @@ error_code:
 	movl %esp,%eax			# pt_regs pointer
 	call *%edi
 	jmp ret_from_exception
+ENDPROC(error_code)
 
 ENTRY(coprocessor_error)
 	pushl $0
 	pushl $do_coprocessor_error
 	jmp error_code
+END(coprocessor_error)
 
 ENTRY(simd_coprocessor_error)
 	pushl $0
 	pushl $do_simd_coprocessor_error
 	jmp error_code
+END(simd_coprocessor_error)
 
 ENTRY(device_not_available)
 	pushl $-1			# mark this as an int
@@ -484,6 +505,7 @@ device_not_available_emulate:
 	call math_emulate
 	addl $4, %esp
 	jmp ret_from_exception
+END(device_not_available)
 
 /*
  * Debug traps and NMI can happen at the one SYSENTER instruction
@@ -518,6 +540,7 @@ debug_stack_correct:
 	movl %esp,%eax			# pt_regs pointer
 	call do_debug
 	jmp ret_from_exception
+END(debug)
 	.previous .text
 /*
  * NMI is doubly nasty. It can happen _while_ we're handling
@@ -590,6 +613,7 @@ nmi_16bit_stack:
 	.align 4
 	.long 1b,iret_exc
 .previous
+ENDPROC(nmi)
 
 KPROBE_ENTRY(int3)
 	pushl $-1			# mark this as an int
@@ -598,52 +622,63 @@ KPROBE_ENTRY(int3)
 	movl %esp,%eax		# pt_regs pointer
 	call do_int3
 	jmp ret_from_exception
+END(int3)
 	.previous .text
 
 ENTRY(overflow)
 	pushl $0
 	pushl $do_overflow
 	jmp error_code
+END(overflow)
 
 ENTRY(bounds)
 	pushl $0
 	pushl $do_bounds
 	jmp error_code
+END(bounds)
 
 ENTRY(invalid_op)
 	pushl $0
 	pushl $do_invalid_op
 	jmp error_code
+END(invalid_op)
 
 ENTRY(coprocessor_segment_overrun)
 	pushl $0
 	pushl $do_coprocessor_segment_overrun
 	jmp error_code
+END(coprocessor_segment_overrun)
 
 ENTRY(invalid_TSS)
 	pushl $do_invalid_TSS
 	jmp error_code
+END(invalid_TSS)
 
 ENTRY(segment_not_present)
 	pushl $do_segment_not_present
 	jmp error_code
+END(segment_not_present)
 
 ENTRY(stack_segment)
 	pushl $do_stack_segment
 	jmp error_code
+END(stack_segment)
 
 KPROBE_ENTRY(general_protection)
 	pushl $do_general_protection
 	jmp error_code
+END(general_protection)
 	.previous .text
 
 ENTRY(alignment_check)
 	pushl $do_alignment_check
 	jmp error_code
+END(alignment_check)
 
 KPROBE_ENTRY(page_fault)
 	pushl $do_page_fault
 	jmp error_code
+END(page_fault)
 	.previous .text
 
 #ifdef CONFIG_X86_MCE
@@ -651,12 +686,14 @@ ENTRY(machine_check)
 	pushl $0
 	pushl machine_check_vector
 	jmp error_code
+END(machine_check)
 #endif
 
 ENTRY(spurious_interrupt_bug)
 	pushl $0
 	pushl $do_spurious_interrupt_bug
 	jmp error_code
+END(spurious_interrupt_bug)
 
 #include "syscall_table.S"
 
--- 2.6.14/arch/ia64/Makefile	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/ia64/Makefile	2005-09-07 11:52:28.000000000 +0200
@@ -9,7 +9,6 @@
 #
 
 NM := $(CROSS_COMPILE)nm -B
-READELF := $(CROSS_COMPILE)readelf
 
 export AWK
 
--- 2.6.14/arch/ia64/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/ia64/defconfig	2005-09-07 12:34:27.000000000 +0200
@@ -29,6 +29,7 @@ CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_PRINTK=y
--- 2.6.14/arch/m68k/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/m68k/defconfig	2005-09-07 12:34:56.000000000 +0200
@@ -32,6 +32,7 @@ CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_PRINTK=y
 CONFIG_BUG=y
--- 2.6.14/arch/mips/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/mips/defconfig	2005-09-07 12:35:22.000000000 +0200
@@ -32,6 +32,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_EMBEDDED=y
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
--- 2.6.14/arch/ppc64/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/ppc64/defconfig	2005-09-07 12:36:57.000000000 +0200
@@ -41,6 +41,7 @@ CONFIG_CPUSETS=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_PRINTK=y
--- 2.6.14/arch/s390/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/s390/defconfig	2005-09-07 12:35:46.000000000 +0200
@@ -37,6 +37,7 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_PRINTK=y
--- 2.6.14/arch/sparc/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/sparc/defconfig	2005-09-07 12:37:27.000000000 +0200
@@ -28,7 +28,9 @@ CONFIG_LOG_BUF_SHIFT=14
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 # CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_IOSCHED_NOOP=y
--- 2.6.14/arch/sparc64/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/sparc64/defconfig	2005-09-07 12:37:48.000000000 +0200
@@ -30,6 +30,7 @@ CONFIG_KOBJECT_UEVENT=y
 # CONFIG_IKCONFIG is not set
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 # CONFIG_KALLSYMS_ALL is not set
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_FUTEX=y
--- 2.6.14/arch/um/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/um/defconfig	2005-09-07 12:33:51.000000000 +0200
@@ -70,6 +70,7 @@ CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 # CONFIG_KALLSYMS_ALL is not set
 CONFIG_KALLSYMS_EXTRA_PASS=y
 CONFIG_PRINTK=y
--- 2.6.14/arch/x86_64/defconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/x86_64/defconfig	2005-09-07 12:38:00.000000000 +0200
@@ -43,6 +43,7 @@ CONFIG_IKCONFIG_PROC=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_EMBEDDED is not set
 CONFIG_KALLSYMS=y
+CONFIG_KALLSYMS_TRADITIONAL=y
 CONFIG_KALLSYMS_ALL=y
 # CONFIG_KALLSYMS_EXTRA_PASS is not set
 CONFIG_PRINTK=y
--- 2.6.14/arch/x86_64/kernel/entry.S	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/arch/x86_64/kernel/entry.S	2005-11-07 14:56:02.000000000 +0100
@@ -153,6 +153,7 @@ rff_trace:
 	GET_THREAD_INFO(%rcx)	
 	jmp rff_action
 	CFI_ENDPROC
+END(ret_from_fork)
 
 /*
  * System call entry. Upto 6 arguments in registers are supported.
@@ -281,6 +282,7 @@ tracesys:			 
 	RESTORE_REST
 	jmp ret_from_sys_call
 	CFI_ENDPROC
+END(system_call)
 		
 /* 
  * Syscall return path ending with IRET.
@@ -359,6 +361,7 @@ int_restore_rest:
 	cli
 	jmp int_with_check
 	CFI_ENDPROC
+END(int_ret_from_sys_call)
 		
 /* 
  * Certain special system calls that need to save a complete full stack frame.
@@ -370,6 +373,7 @@ int_restore_rest:
 	leaq	\func(%rip),%rax
 	leaq    -ARGOFFSET+8(%rsp),\arg /* 8 for return address */
 	jmp	ptregscall_common
+END(\label)
 	.endm
 
 	CFI_STARTPROC
@@ -399,6 +403,7 @@ ENTRY(ptregscall_common)
 	CFI_REL_OFFSET rip, 0
 	ret
 	CFI_ENDPROC
+END(ptregscall_common)
 	
 ENTRY(stub_execve)
 	CFI_STARTPROC
@@ -429,6 +434,7 @@ exec_32bit:
 	RESTORE_REST
 	jmp int_ret_from_sys_call
 	CFI_ENDPROC
+END(stub_execve)
 	
 /*
  * sigreturn is special because it needs to restore all registers on return.
@@ -446,6 +452,7 @@ ENTRY(stub_rt_sigreturn)
 	RESTORE_REST
 	jmp int_ret_from_sys_call
 	CFI_ENDPROC
+END(stub_rt_sigreturn)
 
 /*
  * initial frame state for interrupts and exceptions
@@ -596,6 +603,7 @@ retint_kernel:	
 	jmp exit_intr
 #endif	
 	CFI_ENDPROC
+END(common_interrupt)
 	
 /*
  * APIC interrupts.
@@ -611,14 +619,17 @@ retint_kernel:	
 
 ENTRY(thermal_interrupt)
 	apicinterrupt THERMAL_APIC_VECTOR,smp_thermal_interrupt
+END(thermal_interrupt)
 
 #ifdef CONFIG_SMP	
 ENTRY(reschedule_interrupt)
 	apicinterrupt RESCHEDULE_VECTOR,smp_reschedule_interrupt
+END(reschedule_interrupt)
 
 	.macro INVALIDATE_ENTRY num
 ENTRY(invalidate_interrupt\num)
 	apicinterrupt INVALIDATE_TLB_VECTOR_START+\num,smp_invalidate_interrupt	
+END(invalidate_interrupt\num)
 	.endm
 
 	INVALIDATE_ENTRY 0
@@ -632,17 +643,21 @@ ENTRY(invalidate_interrupt\num)
 
 ENTRY(call_function_interrupt)
 	apicinterrupt CALL_FUNCTION_VECTOR,smp_call_function_interrupt
+END(call_function_interrupt)
 #endif
 
 #ifdef CONFIG_X86_LOCAL_APIC	
 ENTRY(apic_timer_interrupt)
 	apicinterrupt LOCAL_TIMER_VECTOR,smp_apic_timer_interrupt
+END(apic_timer_interrupt)
 
 ENTRY(error_interrupt)
 	apicinterrupt ERROR_APIC_VECTOR,smp_error_interrupt
+END(error_interrupt)
 
 ENTRY(spurious_interrupt)
 	apicinterrupt SPURIOUS_APIC_VECTOR,smp_spurious_interrupt
+END(spurious_interrupt)
 #endif
 				
 /*
@@ -770,6 +785,7 @@ error_kernelspace:
 	cmpq $gs_change,RIP(%rsp)
         je   error_swapgs
 	jmp  error_sti
+END(error_entry)
 	
        /* Reload gs selector with exception handling */
        /* edi:  new selector */ 
@@ -787,6 +803,7 @@ gs_change:     
 	CFI_ADJUST_CFA_OFFSET -8
         ret
 	CFI_ENDPROC
+ENDPROC(load_gs_index)
        
         .section __ex_table,"a"
         .align 8
@@ -840,7 +857,7 @@ ENTRY(kernel_thread)
 	UNFAKE_STACK_FRAME
 	ret
 	CFI_ENDPROC
-
+ENDPROC(kernel_thread)
 	
 child_rip:
 	/*
@@ -853,6 +870,7 @@ child_rip:
 	# exit
 	xorl %edi, %edi
 	call do_exit
+ENDPROC(child_rip)
 
 /*
  * execve(). This function needs to use IRET, not SYSRET, to set up all state properly.
@@ -882,19 +900,24 @@ ENTRY(execve)
 	UNFAKE_STACK_FRAME
 	ret
 	CFI_ENDPROC
+ENDPROC(execve)
 
 KPROBE_ENTRY(page_fault)
 	errorentry do_page_fault
+END(page_fault)
 	.previous .text
 
 ENTRY(coprocessor_error)
 	zeroentry do_coprocessor_error
+END(coprocessor_error)
 
 ENTRY(simd_coprocessor_error)
 	zeroentry do_simd_coprocessor_error	
+END(simd_coprocessor_error)
 
 ENTRY(device_not_available)
 	zeroentry math_state_restore
+END(device_not_available)
 
 	/* runs on exception stack */
 KPROBE_ENTRY(debug)
@@ -904,6 +927,7 @@ KPROBE_ENTRY(debug)
 	paranoidentry do_debug
 	jmp paranoid_exit
 	CFI_ENDPROC
+END(debug)
 	.previous .text
 
 	/* runs on exception stack */	
@@ -954,25 +978,32 @@ paranoid_schedule:
 	cli
 	jmp paranoid_userspace
 	CFI_ENDPROC
+END(nmi)
 
 KPROBE_ENTRY(int3)
 	zeroentry do_int3	
+END(int3)
 	.previous .text
 
 ENTRY(overflow)
 	zeroentry do_overflow
+END(overflow)
 
 ENTRY(bounds)
 	zeroentry do_bounds
+END(bounds)
 
 ENTRY(invalid_op)
 	zeroentry do_invalid_op	
+END(invalid_op)
 
 ENTRY(coprocessor_segment_overrun)
 	zeroentry do_coprocessor_segment_overrun
+END(coprocessor_segment_overrun)
 
 ENTRY(reserved)
 	zeroentry do_reserved
+END(reserved)
 
 	/* runs on exception stack */
 ENTRY(double_fault)
@@ -980,12 +1011,15 @@ ENTRY(double_fault)
 	paranoidentry do_double_fault
 	jmp paranoid_exit
 	CFI_ENDPROC
+END(double_fault)
 
 ENTRY(invalid_TSS)
 	errorentry do_invalid_TSS
+END(invalid_TSS)
 
 ENTRY(segment_not_present)
 	errorentry do_segment_not_present
+END(segment_not_present)
 
 	/* runs on exception stack */
 ENTRY(stack_segment)
@@ -993,19 +1027,24 @@ ENTRY(stack_segment)
 	paranoidentry do_stack_segment
 	jmp paranoid_exit
 	CFI_ENDPROC
+END(stack_segment)
 
 KPROBE_ENTRY(general_protection)
 	errorentry do_general_protection
+END(general_protection)
 	.previous .text
 
 ENTRY(alignment_check)
 	errorentry do_alignment_check
+END(alignment_check)
 
 ENTRY(divide_error)
 	zeroentry do_divide_error
+END(divide_error)
 
 ENTRY(spurious_interrupt_bug)
 	zeroentry do_spurious_interrupt_bug
+END(spurious_interrupt_bug)
 
 #ifdef CONFIG_X86_MCE
 	/* runs on exception stack */
@@ -1016,10 +1055,12 @@ ENTRY(machine_check)
 	paranoidentry do_machine_check
 	jmp paranoid_exit
 	CFI_ENDPROC
+END(machine_check)
 #endif
 
 ENTRY(call_debug)
        zeroentry do_call_debug
+END(call_debug)
 
 ENTRY(call_softirq)
 	CFI_STARTPROC
@@ -1038,3 +1079,4 @@ ENTRY(call_softirq)
 	CFI_ADJUST_CFA_OFFSET -8
 	ret
 	CFI_ENDPROC
+ENDPROC(call_softirq)
--- 2.6.14/include/linux/kallsyms.h	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/include/linux/kallsyms.h	2005-11-04 16:19:34.000000000 +0100
@@ -19,6 +19,25 @@ const char *kallsyms_lookup(unsigned lon
 			    unsigned long *offset,
 			    char **modname, char *namebuf);
 
+#ifdef CONFIG_MODULES
+
+#if defined(Elf_Shdr) && defined(Elf_Sym)
+char kallsyms_elf_type(const Elf_Sym *sym,
+		       const Elf_Shdr *sechdrs,
+		       const char *secstrings);
+#endif
+
+struct module;
+void module_init_done(struct module *);
+
+unsigned long kallsyms_find_symname(struct module *, const char *);
+
+const char *kallsyms_get_ksymbol(struct module *,
+                                 unsigned long addr,
+                                 unsigned long *size,
+                                 unsigned long *offset);
+#endif
+
 /* Replace "%s" in format with address, if found */
 extern void __print_symbol(const char *fmt, unsigned long address);
 
@@ -64,4 +83,12 @@ do {						\
 	__print_symbol(fmt, addr);		\
 } while(0)
 
+#if defined(CONFIG_KALLSYMS) && !defined(CONFIG_KALLSYMS_TRADITIONAL)
+void kallsyms_early_init(void);
+void kallsyms_init_done(void);
+#else
+#define kallsyms_early_init() ((void)0)
+#define kallsyms_init_done() ((void)0)
+#endif
+
 #endif /*_LINUX_KALLSYMS_H*/
--- 2.6.14/include/linux/linkage.h	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/include/linux/linkage.h	2005-11-07 10:44:38.000000000 +0100
@@ -39,6 +39,16 @@
   ALIGN; \
   name:
 
+#ifdef CONFIG_KALLSYMS
+#define ENDPROC(name) \
+  .type name, @function; \
+  END(name)
+#define END(name) \
+  .size name, .-name
+#else
+#define ENDPROC(name)
+#define END(name)
+#endif
 
 #endif
 
--- 2.6.14/include/linux/module.h	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/include/linux/module.h	2005-11-04 16:19:34.000000000 +0100
@@ -301,7 +301,14 @@ struct module
 	/* We keep the symbol and string tables for kallsyms. */
 	Elf_Sym *symtab;
 	unsigned long num_symtab;
-	char *strtab;
+	const char *strtab;
+
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+	/* And also the sections and their string table. */
+	Elf_Shdr *sections;
+	unsigned long num_sections;
+	const char *shstrtab;
+# endif
 
 	/* Section attributes */
 	struct module_sect_attrs *sect_attrs;
--- 2.6.14/init/Kconfig	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/init/Kconfig	2005-11-07 10:51:19.000000000 +0100
@@ -272,9 +272,19 @@ config KALLSYMS
 	   symbolic stack backtraces. This increases the size of the kernel
 	   somewhat, as all symbols have to be loaded into the kernel image.
 
+config KALLSYMS_TRADITIONAL
+	bool "Traditional kallsyms symbol table format"
+	depends on KALLSYMS
+	default !MODULES
+	help
+	  Say N here if you want the kernel symbol table to be consistent with
+	  that loadable modules use (i.e. the ELF symbol table extracted from
+	  the kernel binary).
+
 config KALLSYMS_ALL
 	bool "Include all symbols in kallsyms"
 	depends on DEBUG_KERNEL && KALLSYMS
+	default DEBUG_KERNEL
 	help
 	   Normally kallsyms only contains the symbols of functions, for nicer
 	   OOPS messages.  Some debuggers can use kallsyms for other
@@ -283,6 +293,13 @@ config KALLSYMS_ALL
 
 	   Say N.
 
+config KALLSYMS_STRIP_GENERATED
+	bool "Strip machine generated symbols from kallsyms" if KALLSYMS_ALL
+	depends on KALLSYMS && !KALLSYMS_TRADITIONAL
+	default y
+	help
+	  Say N if you want kallsyms to retain even machine generated symbols.
+ 
 config KALLSYMS_EXTRA_PASS
 	bool "Do an extra kallsyms pass"
 	depends on KALLSYMS
--- 2.6.14/init/main.c	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/init/main.c	2005-11-07 10:53:53.000000000 +0100
@@ -481,6 +481,7 @@ asmlinkage void __init start_kernel(void
 		   &unknown_bootoption);
 	sort_main_extable();
 	trap_init();
+	kallsyms_early_init();
 	rcu_init();
 	init_IRQ();
 	pidhash_init();
@@ -708,6 +709,7 @@ static int init(void * unused)
 	 * we're essentially up and running. Get rid of the
 	 * initmem segments and start the user-mode stuff..
 	 */
+	kallsyms_init_done();
 	free_initmem();
 	unlock_kernel();
 	system_state = SYSTEM_RUNNING;
--- 2.6.14/kernel/kallsyms.c	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/kernel/kallsyms.c	2005-11-08 12:22:46.000000000 +0100
@@ -11,8 +11,8 @@
  *      Changed the compression method from stem compression to "table lookup"
  *      compression (see scripts/kallsyms.c for a more complete description)
  */
-#include <linux/kallsyms.h>
 #include <linux/module.h>
+#include <linux/kallsyms.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
 #include <linux/fs.h>
@@ -28,15 +28,42 @@
 #define all_var 0
 #endif
 
-/* These will be re-linked against their real values during the second link stage */
-extern unsigned long kallsyms_addresses[] __attribute__((weak));
-extern unsigned long kallsyms_num_syms __attribute__((weak,section("data")));
-extern u8 kallsyms_names[] __attribute__((weak));
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
+extern const unsigned long kallsyms_addresses[];
+extern const unsigned long kallsyms_num_syms __attribute__((section("data")));
+extern const u8 kallsyms_names[];
+
+extern const u8 kallsyms_token_table[];
+extern const u16 kallsyms_token_index[];
 
-extern u8 kallsyms_token_table[] __attribute__((weak));
-extern u16 kallsyms_token_index[] __attribute__((weak));
+extern const unsigned long kallsyms_markers[];
+#else
+extern Elf_Shdr kallsyms_sections[];
+extern Elf_Sym kallsyms_symtab[];
+extern const char kallsyms_shstrtab[], kallsyms_strtab[];
+# ifdef CONFIG_MODULES
+struct module kallsyms_kernel_module = {
+	.module_core = _text,
+	.module_init = __init_begin,
+	.symtab = kallsyms_symtab,
+	.strtab = kallsyms_strtab,
+	.sections = kallsyms_sections,
+	.shstrtab = kallsyms_shstrtab
+};
+# else
+const void*const kallsyms_module_core = _text;
+const void*const kallsyms_module_init = __init_begin;
+size_t kallsyms_core_size = 0, kallsyms_init_size = 0;
+static size_t kallsyms_core_text_size, kallsyms_init_text_size;
+size_t kallsyms_num_sections = 0, kallsyms_num_symtab = 0;
+#  define KALLSYMS_VAR(mod, var) kallsyms_##var
+# endif
+# define kallsyms_num_syms KALLSYMS_VAR(&kallsyms_kernel_module, num_symtab)
+#endif
 
-extern unsigned long kallsyms_markers[] __attribute__((weak));
+#ifdef CONFIG_MODULES
+# define KALLSYMS_VAR(mod, var) (mod)->var
+#endif
 
 static inline int is_kernel_inittext(unsigned long addr)
 {
@@ -68,12 +95,36 @@ static inline int is_kernel(unsigned lon
 	return in_gate_area_no_task(addr);
 }
 
+static inline int within(unsigned long addr, const void *start, unsigned long size)
+{
+	return ((void *)addr >= start && (void *)addr < start + size);
+}
+
+#if defined(CONFIG_MODULES) || !defined(CONFIG_KALLSYMS_TRADITIONAL)
+# ifndef CONFIG_MODULES
+static inline
+#  define kallsyms_find_symname(m, n) kallsyms_find_symname(n)
+# endif
+unsigned long kallsyms_find_symname(
+	struct module *mod,
+	const char *name)
+{
+	unsigned long i;
+
+	for (i = 0; i < KALLSYMS_VAR(mod, num_symtab); i++)
+		if (strcmp(name, KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name) == 0)
+			return KALLSYMS_VAR(mod, symtab)[i].st_value;
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
 /* expand a compressed symbol data into the resulting uncompressed string,
    given the offset to where the symbol is in the compressed stream */
 static unsigned int kallsyms_expand_symbol(unsigned int off, char *result)
 {
 	int len, skipped_first = 0;
-	u8 *tptr, *data;
+	const u8 *tptr, *data;
 
 	/* get the compressed symbol length from the first symbol byte */
 	data = &kallsyms_names[off];
@@ -121,7 +172,7 @@ static char kallsyms_get_symbol_type(uns
  * kallsyms array */
 static unsigned int get_symbol_offset(unsigned long pos)
 {
-	u8 *name;
+	const u8 *name;
 	int i;
 
 	/* use the closest marker we have. We have markers every 256 positions,
@@ -137,10 +188,12 @@ static unsigned int get_symbol_offset(un
 
 	return name - kallsyms_names;
 }
+#endif
 
 /* Lookup the address for this symbol. Returns 0 if not found. */
 unsigned long kallsyms_lookup_name(const char *name)
 {
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
 	char namebuf[KSYM_NAME_LEN+1];
 	unsigned long i;
 	unsigned int off;
@@ -151,10 +204,78 @@ unsigned long kallsyms_lookup_name(const
 		if (strcmp(namebuf, name) == 0)
 			return kallsyms_addresses[i];
 	}
+#else
+	unsigned long kaddr = kallsyms_find_symname(&kallsyms_kernel_module, name);
+
+	if (kaddr)
+		return kaddr;
+#endif
 	return module_kallsyms_lookup_name(name);
 }
 EXPORT_SYMBOL_GPL(kallsyms_lookup_name);
 
+#if defined(CONFIG_MODULES) || !defined(CONFIG_KALLSYMS_TRADITIONAL)
+/*
+ * This ignores the intensely annoying "mapping symbols" found
+ * in ARM ELF files: $a, $t and $d.
+ */
+static inline int is_arm_mapping_symbol(const char *str)
+{
+#ifdef CONFIG_ARM
+	return str[0] == '$' && strchr("atd", str[1])
+	       && (str[2] == '\0' || str[2] == '.');
+#else
+	return 0;
+#endif
+}
+
+# ifndef CONFIG_MODULES
+static inline
+#  define kallsyms_get_ksymbol(m, a, s, o) kallsyms_get_ksymbol(a, s, o)
+# endif
+const char *kallsyms_get_ksymbol(struct module *mod,
+			       unsigned long addr,
+			       unsigned long *size,
+			       unsigned long *offset)
+{
+	unsigned long i, best = 0;
+	unsigned long nextval;
+
+	/* At worse, next value is at end of module */
+	if (within(addr, KALLSYMS_VAR(mod, module_init), KALLSYMS_VAR(mod, init_size)))
+		nextval = (unsigned long)KALLSYMS_VAR(mod, module_init) + KALLSYMS_VAR(mod, init_text_size);
+	else
+		nextval = (unsigned long)KALLSYMS_VAR(mod, module_core) + KALLSYMS_VAR(mod, core_text_size);
+
+	/* Scan for closest preceeding symbol, and next symbol. (ELF
+           starts real symbols at 1). */
+	for (i = 1; i < KALLSYMS_VAR(mod, num_symtab); i++) {
+		if (KALLSYMS_VAR(mod, symtab)[i].st_shndx == SHN_UNDEF)
+			continue;
+
+		/* We ignore unnamed symbols: they're uninformative
+		 * and inserted at a whim. */
+		if (KALLSYMS_VAR(mod, symtab)[i].st_value <= addr
+		    && KALLSYMS_VAR(mod, symtab)[i].st_value > KALLSYMS_VAR(mod, symtab)[best].st_value
+		    && *(KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name) != '\0'
+		    && !is_arm_mapping_symbol(KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name))
+			best = i;
+		if (KALLSYMS_VAR(mod, symtab)[i].st_value > addr
+		    && KALLSYMS_VAR(mod, symtab)[i].st_value < nextval
+		    && *(KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name) != '\0'
+		    && !is_arm_mapping_symbol(KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[i].st_name))
+			nextval = KALLSYMS_VAR(mod, symtab)[i].st_value;
+	}
+
+	if (!best)
+		return NULL;
+
+	*size = nextval - KALLSYMS_VAR(mod, symtab)[best].st_value;
+	*offset = addr - KALLSYMS_VAR(mod, symtab)[best].st_value;
+	return KALLSYMS_VAR(mod, strtab) + KALLSYMS_VAR(mod, symtab)[best].st_name;
+}
+#endif
+
 /*
  * Lookup an address
  * - modname is set to NULL if it's in the kernel
@@ -167,18 +288,18 @@ const char *kallsyms_lookup(unsigned lon
 			    unsigned long *offset,
 			    char **modname, char *namebuf)
 {
-	unsigned long i, low, high, mid;
 	const char *msym;
 
-	/* This kernel should never had been booted. */
-	BUG_ON(!kallsyms_addresses);
-
 	namebuf[KSYM_NAME_LEN] = 0;
 	namebuf[0] = 0;
 
-	if ((all_var && is_kernel(addr)) ||
-	    (!all_var && (is_kernel_text(addr) || is_kernel_inittext(addr) ||
-				is_kernel_extratext(addr)))) {
+	if (all_var
+	    ? is_kernel(addr)
+	    : is_kernel_text(addr)
+	      || is_kernel_inittext(addr)
+	      || is_kernel_extratext(addr)) {
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
+		unsigned long i, low, high, mid;
 		unsigned long symbol_end = 0;
 
 		/* do a binary search on the sorted kallsyms_addresses array */
@@ -219,6 +340,10 @@ const char *kallsyms_lookup(unsigned lon
 		*modname = NULL;
 		*offset = addr - kallsyms_addresses[low];
 		return namebuf;
+#else
+		*modname = NULL;
+		return kallsyms_get_ksymbol(&kallsyms_kernel_module, addr, symbolsize, offset);
+#endif
 	}
 
 	/* see if it's in a module */
@@ -236,30 +361,46 @@ void __print_symbol(const char *fmt, uns
 	const char *name;
 	unsigned long offset, size;
 	char namebuf[KSYM_NAME_LEN+1];
-	char buffer[sizeof("%s+%#lx/%#lx [%s]") + KSYM_NAME_LEN +
-		    2*(BITS_PER_LONG*3/10) + MODULE_NAME_LEN + 1];
 
 	name = kallsyms_lookup(address, &size, &offset, &modname, namebuf);
 
-	if (!name)
-		sprintf(buffer, "0x%lx", address);
-	else {
-		if (modname)
-			sprintf(buffer, "%s+%#lx/%#lx [%s]", name, offset,
-				size, modname);
-		else
-			sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
+	if (!name) {
+		char addrstr[sizeof("0x%lx") + (BITS_PER_LONG*3/10)];
+
+		sprintf(addrstr, "0x%lx", address);
+		printk(fmt, addrstr);
+		return;
+	}
+
+	if (modname) {
+		/* This is pretty small. */
+		char buffer[sizeof("%s+%#lx/%#lx [%s]")
+			   + strlen(name) + 2*(BITS_PER_LONG*3/10)
+			   + strlen(modname)];
+
+		sprintf(buffer, "%s+%#lx/%#lx [%s]",
+			name, offset, size, modname);
+		printk(fmt, buffer);
+	} else {
+		char buffer[sizeof("%s+%#lx/%#lx")
+			   + strlen(name) + 2*(BITS_PER_LONG*3/10)];
+
+		sprintf(buffer, "%s+%#lx/%#lx", name, offset, size);
+		printk(fmt, buffer);
 	}
-	printk(fmt, buffer);
 }
 
 /* To avoid using get_symbol_offset for every symbol, we carry prefix along. */
 struct kallsym_iter
 {
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
 	loff_t pos;
+#endif
 	struct module *owner;
 	unsigned long value;
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
 	unsigned int nameoff; /* If iterating in core kernel symbols */
+#endif
 	char type;
 	char name[KSYM_NAME_LEN+1];
 };
@@ -271,9 +412,9 @@ static void upcase_if_global(struct kall
 		iter->type += 'A' - 'a';
 }
 
-static int get_ksymbol_mod(struct kallsym_iter *iter)
+static int get_ksymbol_mod(struct kallsym_iter *iter, loff_t pos)
 {
-	iter->owner = module_get_kallsym(iter->pos - kallsyms_num_syms,
+	iter->owner = module_get_kallsym(pos,
 					 &iter->value,
 					 &iter->type, iter->name);
 	if (iter->owner == NULL)
@@ -283,6 +424,7 @@ static int get_ksymbol_mod(struct kallsy
 	return 1;
 }
 
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
 /* Returns space to next name. */
 static unsigned long get_ksymbol_core(struct kallsym_iter *iter)
 {
@@ -304,26 +446,87 @@ static void reset_iter(struct kallsym_it
 	iter->nameoff = get_symbol_offset(new_pos);
 	iter->pos = new_pos;
 }
+#else
+# define reset_iter(iter, new_pos) ((void)((iter)->name[0] = '\0'))
+#endif
 
 /* Returns false if pos at or past end of file. */
 static int update_iter(struct kallsym_iter *iter, loff_t pos)
 {
 	/* Module symbols can be accessed randomly. */
-	if (pos >= kallsyms_num_syms) {
-		iter->pos = pos;
-		return get_ksymbol_mod(iter);
-	}
+	if (pos >= kallsyms_num_syms)
+		return get_ksymbol_mod(iter, pos - kallsyms_num_syms);
 	
+#ifdef CONFIG_KALLSYMS_TRADITIONAL
 	/* If we're not on the desired position, reset to new position. */
 	if (pos != iter->pos)
 		reset_iter(iter, pos);
 
 	iter->nameoff += get_ksymbol_core(iter);
 	iter->pos++;
+#else
+	iter->owner = NULL;
+	iter->value = KALLSYMS_VAR(&kallsyms_kernel_module, symtab)[pos].st_value;
+	iter->type = KALLSYMS_VAR(&kallsyms_kernel_module, symtab)[pos].st_other;
+	strncpy(iter->name,
+		KALLSYMS_VAR(&kallsyms_kernel_module, strtab) + KALLSYMS_VAR(&kallsyms_kernel_module, symtab)[pos].st_name,
+		127);
+	upcase_if_global(iter);
+#endif
 
 	return 1;
 }
 
+#if defined(CONFIG_MODULES) || !defined(CONFIG_KALLSYMS_TRADITIONAL)
+# ifndef ARCH_SHF_SMALL
+#  define ARCH_SHF_SMALL 0
+# endif
+/* As per nm */
+# ifndef CONFIG_MODULES
+static inline __init
+# endif
+char kallsyms_elf_type(const Elf_Sym *sym,
+		     const Elf_Shdr *sechdrs,
+		     const char *secstrings)
+{
+	if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
+		if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
+			return 'v';
+		else
+			return 'w';
+	}
+	if (sym->st_shndx == SHN_UNDEF)
+		return 'U';
+	if (sym->st_shndx == SHN_ABS)
+		return 'a';
+	if (sym->st_shndx >= SHN_LORESERVE)
+		return '?';
+	if (sechdrs) {
+		if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
+			return 't';
+		if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC
+		    && sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
+			if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
+				return 'r';
+			else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
+				return 'g';
+			else
+				return 'd';
+		}
+		if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
+			if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
+				return 's';
+			else
+				return 'b';
+		}
+		if (strncmp(secstrings + sechdrs[sym->st_shndx].sh_name,
+			    ".debug", strlen(".debug")) == 0)
+			return 'n';
+	}
+	return '?';
+}
+#endif
+
 static void *s_next(struct seq_file *m, void *p, loff_t *pos)
 {
 	(*pos)++;
@@ -417,4 +620,73 @@ static int __init kallsyms_init(void)
 }
 __initcall(kallsyms_init);
 
+
+#ifndef CONFIG_KALLSYMS_TRADITIONAL
+
+extern const size_t kallsyms_size_sections, kallsyms_size_symtab;
+extern const size_t kallsyms_size_shstrtab, kallsyms_size_strtab;
+
+void __init kallsyms_early_init() {
+	Elf_Shdr*section;
+	Elf_Sym*symbol;
+
+	KALLSYMS_VAR(&kallsyms_kernel_module, core_size) = _end - _text;
+	KALLSYMS_VAR(&kallsyms_kernel_module, core_text_size) = _etext - _stext;
+	KALLSYMS_VAR(&kallsyms_kernel_module, init_size) = __init_end - __init_begin;
+	KALLSYMS_VAR(&kallsyms_kernel_module, init_text_size) = _einittext - _sinittext;
+
+	BUG_ON(kallsyms_size_sections <= sizeof(*kallsyms_sections));
+	BUG_ON(kallsyms_size_sections % sizeof(*kallsyms_sections));
+	BUG_ON(kallsyms_size_shstrtab <= 0);
+	BUG_ON(*kallsyms_shstrtab);
+	BUG_ON(kallsyms_shstrtab[kallsyms_size_shstrtab - 1]);
+	for(section = kallsyms_sections + 1; (unsigned long)section < (unsigned long)kallsyms_sections + kallsyms_size_sections; ++section)
+		if(section->sh_name >= kallsyms_size_shstrtab)
+			section->sh_name = 0;
+	KALLSYMS_VAR(&kallsyms_kernel_module, num_sections) = kallsyms_size_sections / sizeof(*kallsyms_sections);
+
+	BUG_ON(kallsyms_size_symtab <= sizeof(*kallsyms_symtab));
+	BUG_ON(kallsyms_size_symtab % sizeof(*kallsyms_symtab));
+	BUG_ON(kallsyms_size_strtab <= 0);
+	BUG_ON(*kallsyms_strtab);
+	BUG_ON(kallsyms_strtab[kallsyms_size_strtab - 1]);
+	for(symbol = kallsyms_symtab + 1; (unsigned long)symbol < (unsigned long)kallsyms_symtab + kallsyms_size_symtab; ++symbol) {
+		if(symbol->st_name >= kallsyms_size_strtab)
+			symbol->st_name = 0;
+		symbol->st_other = kallsyms_elf_type(symbol, kallsyms_sections, kallsyms_shstrtab);
+	}
+	KALLSYMS_VAR(&kallsyms_kernel_module, num_symtab) = kallsyms_size_symtab / sizeof(*kallsyms_symtab);
+}
+
+
+void __init kallsyms_init_done() {
+# ifdef CONFIG_MODULES
+	module_init_done(&kallsyms_kernel_module);
+# else
+	Elf_Shdr*section;
+	const Elf_Sym*src;
+	Elf_Sym*dst;
+
+	for(section = kallsyms_sections + 1; (unsigned long)section < (unsigned long)kallsyms_sections + kallsyms_size_sections; ++section)
+		if(section->sh_addr >= (unsigned long)__init_begin
+		   && (section->sh_size
+		       ? section->sh_addr + section->sh_size - 1
+		       : section->sh_addr) < (unsigned long)__init_end)
+			section->sh_addr = 0;
+	for(src = dst = kallsyms_symtab + 1; (unsigned long)src < (unsigned long)kallsyms_symtab + kallsyms_size_symtab; ++src) {
+		if(!src->st_shndx || !src->st_name)
+			continue;
+		if(src->st_shndx < kallsyms_num_sections
+		   && !kallsyms_sections[src->st_shndx].sh_addr)
+			continue;
+		if(src != dst)
+			*dst = *src;
+		++dst;
+	}
+	kallsyms_num_symtab = dst - kallsyms_symtab;
+# endif
+}
+
+#endif /* CONFIG_KALLSYMS_TRADITIONAL */
+
 EXPORT_SYMBOL(__print_symbol);
--- 2.6.14/kernel/module.c	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/kernel/module.c	2005-11-04 16:19:34.000000000 +0100
@@ -37,6 +37,7 @@
 #include <linux/stop_machine.h>
 #include <linux/device.h>
 #include <linux/string.h>
+#include <linux/kallsyms.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
 #include <asm/cacheflush.h>
@@ -1163,6 +1164,8 @@ static int __unlink_module(void *_mod)
 	return 0;
 }
 
+static void cleanup_kallsyms(struct module *);
+
 /* Free a module, remove from lists, etc (must hold module mutex). */
 static void free_module(struct module *mod)
 {
@@ -1177,6 +1180,8 @@ static void free_module(struct module *m
 	/* Module unload stuff */
 	module_unload_free(mod);
 
+	cleanup_kallsyms(mod);
+
 	/* This may be NULL, but that's OK */
 	module_free(mod, mod->module_init);
 	kfree(mod->args);
@@ -1425,49 +1430,9 @@ int is_exported(const char *name, const 
 	return 0;
 }
 
-/* As per nm */
-static char elf_type(const Elf_Sym *sym,
-		     Elf_Shdr *sechdrs,
-		     const char *secstrings,
-		     struct module *mod)
-{
-	if (ELF_ST_BIND(sym->st_info) == STB_WEAK) {
-		if (ELF_ST_TYPE(sym->st_info) == STT_OBJECT)
-			return 'v';
-		else
-			return 'w';
-	}
-	if (sym->st_shndx == SHN_UNDEF)
-		return 'U';
-	if (sym->st_shndx == SHN_ABS)
-		return 'a';
-	if (sym->st_shndx >= SHN_LORESERVE)
-		return '?';
-	if (sechdrs[sym->st_shndx].sh_flags & SHF_EXECINSTR)
-		return 't';
-	if (sechdrs[sym->st_shndx].sh_flags & SHF_ALLOC
-	    && sechdrs[sym->st_shndx].sh_type != SHT_NOBITS) {
-		if (!(sechdrs[sym->st_shndx].sh_flags & SHF_WRITE))
-			return 'r';
-		else if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
-			return 'g';
-		else
-			return 'd';
-	}
-	if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
-		if (sechdrs[sym->st_shndx].sh_flags & ARCH_SHF_SMALL)
-			return 's';
-		else
-			return 'b';
-	}
-	if (strncmp(secstrings + sechdrs[sym->st_shndx].sh_name,
-		    ".debug", strlen(".debug")) == 0)
-		return 'n';
-	return '?';
-}
-
 static void add_kallsyms(struct module *mod,
-			 Elf_Shdr *sechdrs,
+			 const Elf_Ehdr *hdr,
+			 const Elf_Shdr *sechdrs,
 			 unsigned int symindex,
 			 unsigned int strindex,
 			 const char *secstrings)
@@ -1476,23 +1441,125 @@ static void add_kallsyms(struct module *
 
 	mod->symtab = (void *)sechdrs[symindex].sh_addr;
 	mod->num_symtab = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
-	mod->strtab = (void *)sechdrs[strindex].sh_addr;
+	mod->strtab = (const void *)sechdrs[strindex].sh_addr;
+
+	if (mod->num_symtab > 1
+	    && sechdrs[strindex].sh_size > 0
+	    && !*mod->strtab
+	    && !mod->strtab[sechdrs[strindex].sh_size - 1]) {
+		/* Set types up while we still have access to sections. */
+		for (i = 1; i < mod->num_symtab; i++) {
+			if (mod->symtab[i].st_name >= sechdrs[strindex].sh_size)
+				mod->symtab[i].st_name = 0;
+			mod->symtab[i].st_other
+				= kallsyms_elf_type(&mod->symtab[i], sechdrs, secstrings);
+		}
+	}
+	else {
+		mod->symtab = NULL;
+		mod->num_symtab = 0;
+		mod->strtab = NULL;
+	}
 
-	/* Set types up while we still have access to sections. */
-	for (i = 0; i < mod->num_symtab; i++)
-		mod->symtab[i].st_info
-			= elf_type(&mod->symtab[i], sechdrs, secstrings, mod);
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+	if (hdr->e_shnum > 1
+	    && sechdrs[hdr->e_shstrndx].sh_size > 0
+	    && !*secstrings
+	    && !secstrings[sechdrs[hdr->e_shstrndx].sh_size - 1]) {
+		if (hdr->e_shnum < PAGE_SIZE / sizeof(*sechdrs))
+			mod->sections = kmalloc(hdr->e_shnum * sizeof(*sechdrs), GFP_KERNEL);
+		else
+			mod->sections = vmalloc(hdr->e_shnum * sizeof(*sechdrs));
+	}
+	else
+		mod->sections = NULL;
+	if (mod->sections) {
+		mod->num_sections = hdr->e_shnum;
+		memset(mod->sections, 0, sizeof(*mod->sections));
+		mod->shstrtab = (const void *)sechdrs[hdr->e_shstrndx].sh_addr;
+		for (i = 1; i < mod->num_sections; ++i) {
+			mod->sections[i] = sechdrs[i];
+			if (mod->sections[i].sh_name >= sechdrs[hdr->e_shstrndx].sh_size)
+				mod->sections[i].sh_name = 0;
+			if (!(mod->sections[i].sh_flags & SHF_ALLOC))
+				mod->sections[i].sh_addr = 0;
+		}
+	}
+	else {
+		mod->num_sections = 0;
+		mod->shstrtab = NULL;
+	}
+#endif
+}
+
+static void cleanup_kallsyms(struct module *mod)
+{
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+	if (mod->num_sections) {
+		if (mod->num_sections < PAGE_SIZE / sizeof(*mod->sections))
+			kfree(mod->sections);
+		else
+			vfree(mod->sections);
+		mod->num_sections = 0;
+	}
+# endif
+	mod->num_symtab = 0;
 }
 #else
 static inline void add_kallsyms(struct module *mod,
-				Elf_Shdr *sechdrs,
+				const Elf_Ehdr *hdr,
+				const Elf_Shdr *sechdrs,
 				unsigned int symindex,
 				unsigned int strindex,
 				const char *secstrings)
 {
 }
+
+static inline void cleanup_kallsyms(struct module *mod)
+{
+}
 #endif /* CONFIG_KALLSYMS */
 
+#ifndef CONFIG_KALLSYMS
+static inline
+#endif
+void module_init_done(struct module *mod)
+{
+#ifdef CONFIG_KALLSYMS
+	if (mod->init_size) {
+		const Elf_Sym*src;
+		Elf_Sym*dst;
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+		Elf_Shdr*section;
+
+		for(section = mod->sections + 1; section < mod->sections + mod->num_sections; ++section)
+			if(section->sh_entsize & INIT_OFFSET_MASK)
+				section->sh_addr = 0;
+# endif
+		for(src = dst = mod->symtab + 1; src < mod->symtab + mod->num_symtab; ++src) {
+			if(!src->st_shndx || !src->st_name)
+				continue;
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+			if(src->st_shndx < mod->num_sections
+			   && !mod->sections[src->st_shndx].sh_addr)
+				continue;
+# else
+			if(src->st_value >= (unsigned long)mod->module_init
+			   && src->st_value < (unsigned long)mod->module_init + mod->init_size)
+				continue;
+# endif
+			if(src != dst)
+				*dst = *src;
+			++dst;
+		}
+		mod->num_symtab = dst - mod->symtab;
+	}
+#endif
+	mod->module_init = NULL;
+	mod->init_size = 0;
+	mod->init_text_size = 0;
+}
+
 /* Allocate and load the module: note that size of section 0 is always
    zero, and we rely on this for optional sections. */
 static struct module *load_module(void __user *umod,
@@ -1531,7 +1598,8 @@ static struct module *load_module(void _
 	if (memcmp(hdr->e_ident, ELFMAG, 4) != 0
 	    || hdr->e_type != ET_REL
 	    || !elf_check_arch(hdr)
-	    || hdr->e_shentsize != sizeof(*sechdrs)) {
+	    || hdr->e_shentsize != sizeof(*sechdrs)
+	    || !hdr->e_shstrndx) {
 		err = -ENOEXEC;
 		goto free_hdr;
 	}
@@ -1555,6 +1623,10 @@ static struct module *load_module(void _
 
 		/* Internal symbols and strings. */
 		if (sechdrs[i].sh_type == SHT_SYMTAB) {
+			if (symindex) {
+				err = -ENOEXEC;
+				goto free_hdr;
+			}
 			symindex = i;
 			strindex = sechdrs[i].sh_link;
 			strtab = (char *)hdr + sechdrs[strindex].sh_offset;
@@ -1566,6 +1638,11 @@ static struct module *load_module(void _
 #endif
 	}
 
+	if (!symindex || !strindex) {
+		err = -ENOEXEC;
+		goto free_hdr;
+	}
+
 	modindex = find_sec(hdr, sechdrs, secstrings,
 			    ".gnu.linkonce.this_module");
 	if (!modindex) {
@@ -1597,9 +1674,14 @@ static struct module *load_module(void _
 	/* Don't keep modinfo section */
 	sechdrs[infoindex].sh_flags &= ~(unsigned long)SHF_ALLOC;
 #ifdef CONFIG_KALLSYMS
+	mod->num_symtab = 0;
 	/* Keep symbol and string tables for decoding later. */
 	sechdrs[symindex].sh_flags |= SHF_ALLOC;
 	sechdrs[strindex].sh_flags |= SHF_ALLOC;
+# ifndef CONFIG_KALLSYMS_TRADITIONAL
+	mod->num_sections = 0;
+	sechdrs[hdr->e_shstrndx].sh_flags |= SHF_ALLOC;
+# endif
 #endif
 
 	/* Check module struct version now, before we try to use module. */
@@ -1775,7 +1857,7 @@ static struct module *load_module(void _
 	percpu_modcopy(mod->percpu, (void *)sechdrs[pcpuindex].sh_addr,
 		       sechdrs[pcpuindex].sh_size);
 
-	add_kallsyms(mod, sechdrs, symindex, strindex, secstrings);
+	add_kallsyms(mod, hdr, sechdrs, symindex, strindex, secstrings);
 
 	err = module_finalize(hdr, sechdrs, mod);
 	if (err < 0)
@@ -1843,6 +1925,7 @@ static struct module *load_module(void _
 	module_arch_cleanup(mod);
  cleanup:
 	module_unload_free(mod);
+	cleanup_kallsyms(mod);
 	module_free(mod, mod->module_init);
  free_core:
 	module_free(mod, mod->module_core);
@@ -1934,9 +2017,7 @@ sys_init_module(void __user *umod,
 	/* Drop initial reference. */
 	module_put(mod);
 	module_free(mod, mod->module_init);
-	mod->module_init = NULL;
-	mod->init_size = 0;
-	mod->init_text_size = 0;
+	module_init_done(mod);
 	up(&module_mutex);
 
 	return 0;
@@ -1948,58 +2029,6 @@ static inline int within(unsigned long a
 }
 
 #ifdef CONFIG_KALLSYMS
-/*
- * This ignores the intensely annoying "mapping symbols" found
- * in ARM ELF files: $a, $t and $d.
- */
-static inline int is_arm_mapping_symbol(const char *str)
-{
-	return str[0] == '$' && strchr("atd", str[1]) 
-	       && (str[2] == '\0' || str[2] == '.');
-}
-
-static const char *get_ksymbol(struct module *mod,
-			       unsigned long addr,
-			       unsigned long *size,
-			       unsigned long *offset)
-{
-	unsigned int i, best = 0;
-	unsigned long nextval;
-
-	/* At worse, next value is at end of module */
-	if (within(addr, mod->module_init, mod->init_size))
-		nextval = (unsigned long)mod->module_init+mod->init_text_size;
-	else 
-		nextval = (unsigned long)mod->module_core+mod->core_text_size;
-
-	/* Scan for closest preceeding symbol, and next symbol. (ELF
-           starts real symbols at 1). */
-	for (i = 1; i < mod->num_symtab; i++) {
-		if (mod->symtab[i].st_shndx == SHN_UNDEF)
-			continue;
-
-		/* We ignore unnamed symbols: they're uninformative
-		 * and inserted at a whim. */
-		if (mod->symtab[i].st_value <= addr
-		    && mod->symtab[i].st_value > mod->symtab[best].st_value
-		    && *(mod->strtab + mod->symtab[i].st_name) != '\0'
-		    && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
-			best = i;
-		if (mod->symtab[i].st_value > addr
-		    && mod->symtab[i].st_value < nextval
-		    && *(mod->strtab + mod->symtab[i].st_name) != '\0'
-		    && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name))
-			nextval = mod->symtab[i].st_value;
-	}
-
-	if (!best)
-		return NULL;
-
-	*size = nextval - mod->symtab[best].st_value;
-	*offset = addr - mod->symtab[best].st_value;
-	return mod->strtab + mod->symtab[best].st_name;
-}
-
 /* For kallsyms to ask for address resolution.  NULL means not found.
    We don't lock, as this is used for oops resolution and races are a
    lesser concern. */
@@ -2014,7 +2043,7 @@ const char *module_address_lookup(unsign
 		if (within(addr, mod->module_init, mod->init_size)
 		    || within(addr, mod->module_core, mod->core_size)) {
 			*modname = mod->name;
-			return get_ksymbol(mod, addr, size, offset);
+			return kallsyms_get_ksymbol(mod, addr, size, offset);
 		}
 	}
 	return NULL;
@@ -2031,7 +2060,7 @@ struct module *module_get_kallsym(unsign
 	list_for_each_entry(mod, &modules, list) {
 		if (symnum < mod->num_symtab) {
 			*value = mod->symtab[symnum].st_value;
-			*type = mod->symtab[symnum].st_info;
+			*type = mod->symtab[symnum].st_other;
 			strncpy(namebuf,
 				mod->strtab + mod->symtab[symnum].st_name,
 				127);
@@ -2044,16 +2073,6 @@ struct module *module_get_kallsym(unsign
 	return NULL;
 }
 
-static unsigned long mod_find_symname(struct module *mod, const char *name)
-{
-	unsigned int i;
-
-	for (i = 0; i < mod->num_symtab; i++)
-		if (strcmp(name, mod->strtab+mod->symtab[i].st_name) == 0)
-			return mod->symtab[i].st_value;
-	return 0;
-}
-
 /* Look for this name: can be of form module:name. */
 unsigned long module_kallsyms_lookup_name(const char *name)
 {
@@ -2065,11 +2084,11 @@ unsigned long module_kallsyms_lookup_nam
 	if ((colon = strchr(name, ':')) != NULL) {
 		*colon = '\0';
 		if ((mod = find_module(name)) != NULL)
-			ret = mod_find_symname(mod, colon+1);
+			ret = kallsyms_find_symname(mod, colon+1);
 		*colon = ':';
 	} else {
 		list_for_each_entry(mod, &modules, list)
-			if ((ret = mod_find_symname(mod, name)) != 0)
+			if ((ret = kallsyms_find_symname(mod, name)) != 0)
 				break;
 	}
 	return ret;
--- 2.6.14/scripts/Kbuild.include	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Kbuild.include	2005-11-07 11:12:52.000000000 +0100
@@ -5,6 +5,8 @@
 comma   := ,
 empty   :=
 space   := $(empty) $(empty)
+open    := (
+close   := )
 
 ###
 # The temporary file to save gcc -MD generated dependencies must not
--- 2.6.14/scripts/Makefile	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Makefile	2005-11-04 16:19:35.000000000 +0100
@@ -8,6 +8,7 @@
 # conmakehash:	 Create arrays for initializing the kernel console tables
 
 hostprogs-$(CONFIG_KALLSYMS)     += kallsyms
+HOSTCFLAGS_kallsyms.o := -D ARCH_$(SUBARCH)
 hostprogs-$(CONFIG_LOGO)         += pnmtologo
 hostprogs-$(CONFIG_VT)           += conmakehash
 hostprogs-$(CONFIG_PROM_CONSOLE) += conmakehash
--- 2.6.14/scripts/Makefile.build	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Makefile.build	2005-11-08 12:29:46.000000000 +0100
@@ -156,23 +156,26 @@ else
 #   are done.
 # o otherwise, we calculate symbol versions using the good old
 #   genksyms on the preprocessed source and postprocess them in a way
-#   that they are usable as a linker script
-# o generate <file>.o from .tmp_<file>.o using the linker to
-#   replace the unresolved symbols __crc_exported_symbol with
-#   the actual value of the checksum generated by genksyms
+#   that they are usable as assembly source
+# o recompile <file>.o from <file>.c forcing inclusion of assembler
+#   directives defining the actual values of __crc_*, followed by
+#   objcopy-ing them to force these symbols to be local to permit
+#   stripping them during the final module linking stage.
 
 cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
 cmd_modversions =							\
 	if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then	\
-		$(CPP) -D__GENKSYMS__ $(c_flags) $<			\
-		| $(GENKSYMS)						\
-		> $(@D)/.tmp_$(@F:.o=.ver);				\
-									\
-		$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) 		\
-			-T $(@D)/.tmp_$(@F:.o=.ver);			\
-		rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver);	\
+		if $(CPP) -D__GENKSYMS__ $(c_flags) $<			\
+		   | $(GENKSYMS) -a > $(@D)/.tmp_$(@F:.o=.ver)		\
+		   && $(CC) $(c_flags) -c -w -include $(@D)/.tmp_$(@F:.o=.ver) -o $@ $< \
+		   && $(OBJCOPY) -L '__crc_*' -w $@; then		\
+			rm -f $(@D)/.tmp_$(@F);				\
+		else							\
+			rm -f $@; exit 1;				\
+		fi;							\
 	else								\
 		mv -f $(@D)/.tmp_$(@F) $@;				\
+		rm -f $(@D)/.tmp_$(@F:.o=.ver);				\
 	fi;
 endif
 
@@ -183,6 +186,12 @@ define rule_cc_o_c
 	$(cmd_cc_o_c);							  \
 	$(cmd_modversions)						  \
 	scripts/basic/fixdep $(depfile) $@ '$(subst ','\'',$(cmd_cc_o_c))' > $(@D)/.$(@F).tmp;  \
+	if [ -r $(@D)/.tmp_$(@F:.o=.ver) ]; then			  \
+		echo >> $(@D)/.$(@F).tmp;				  \
+		echo '$@: $(GENKSYMS)' >> $(@D)/.$(@F).tmp;		  \
+		echo '$(GENKSYMS):: ;' >> $(@D)/.$(@F).tmp;		  \
+		rm $(@D)/.tmp_$(@F:.o=.ver);				  \
+	fi;								  \
 	rm -f $(depfile);						  \
 	mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
 endef
--- 2.6.14/scripts/Makefile.modinst	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Makefile.modinst	2005-11-04 16:19:35.000000000 +0100
@@ -17,7 +17,8 @@ __modinst: $(modules)
 	@:
 
 quiet_cmd_modules_install = INSTALL $@
-      cmd_modules_install = mkdir -p $(2); cp $@ $(2)
+      cmd_modules_install = mkdir -p $(2); \
+			    cp $(firstword $(wildcard $@s) $@) $(2)/$(basename $(@F)).ko
 
 # Modules built outside the kernel source tree go into extra by default
 INSTALL_MOD_DIR ?= extra
--- 2.6.14/scripts/Makefile.modpost	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/Makefile.modpost	2005-11-04 16:19:35.000000000 +0100
@@ -41,9 +41,33 @@ include scripts/Makefile.lib
 
 symverfile := $(objtree)/Module.symvers
 
+ifdef CONFIG_KALLSYMS
+
+ifdef CONFIG_KALLSYMS_TRADITIONAL
+
+kallsyms-strip-src :=
+
+else
+
+kallsyms-strip-src := $(if $(CONFIG_KALLSYMS_STRIP_GENERATED),$(srctree)/scripts/kallsyms.strip)
+kallsyms-strip-src += $(if $(CONFIG_KALLSYMS_STRIP_GENERATED),$(wildcard $(srctree)/arch/$(ARCH)/kallsyms.strip))
+# binutils up to at least 2.15 do not permit stripping symbols by name while
+# retaining those that are needed by relocations...
+# kallsyms-strip-src += $(if $(CONFIG_KALLSYMS_ALL),,data)
+
+endif
+
+ko := $(if $(strip $(kallsyms-strip-src)),.kos,.ko)
+
+else
+
+ko := .kos
+
+endif
+
 # Step 1), find all modules listed in $(MODVERDIR)/
 __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
-modules   := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
+modules   := $(patsubst %.o,%$(ko), $(wildcard $(__modules:.ko=.o)))
 
 _modpost: $(modules)
 
@@ -58,12 +82,12 @@ quiet_cmd_modpost = MODPOST
 	$(filter-out FORCE,$^)
 
 .PHONY: __modpost
-__modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE
+__modpost: $(wildcard vmlinux) $(modules:$(ko)=.o) FORCE
 	$(call cmd,modpost)
 
 # Declare generated files as targets for modpost
 $(symverfile):         __modpost ;
-$(modules:.ko=.mod.c): __modpost ;
+$(modules:$(ko)=.mod.c): __modpost ;
 
 
 # Step 5), compile all *.mod.c files
@@ -75,19 +99,51 @@ quiet_cmd_cc_o_c = CC      $@
       cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE)	\
 		   -c -o $@ $<
 
-$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
+$(modules:$(ko)=.mod.o): %.mod.o: %.mod.c FORCE
 	$(call if_changed_dep,cc_o_c)
 
-targets += $(modules:.ko=.mod.o)
+targets += $(modules:$(ko)=.mod.o)
 
 # Step 6), final link of the modules
 quiet_cmd_ld_ko_o = LD [M]  $@
       cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ 		\
 			  $(filter-out FORCE,$^)
 
-$(modules): %.ko :%.o %.mod.o FORCE
+ifeq ($(ko),.ko)
+
+$(modules): %.ko: %.o %.mod.o FORCE
+	$(Q)rm -f $@s
+	$(call if_changed,ld_ko_o)
+
+else
+
+$(patsubst %$(ko),%.ko,$(modules)): %.ko: %.o %.mod.o FORCE
 	$(call if_changed,ld_ko_o)
 
+# Step 7), strip as many symbols from the modules as feasible
+quiet_cmd_strip_kos_ko = STRIP   $<
+ifdef CONFIG_KALLSYMS
+cmd_strip_kos_ko = $(OBJCOPY) --strip-debug $(addprefix --strip-symbols ,$(filter %.strip,$^)) -w $< $@
+else
+cmd_strip_kos_ko = $(OBJCOPY) --strip-debug --strip-unneeded $< $@
+endif
+
+%$(ko): %.ko $(filter %.strip,$(kallsyms-strip-src)) $(if $(filter data,$(kallsyms-strip-src)),.data_%.strip) FORCE
+	$(call if_changed,strip_kos_ko)
+
+.PRECIOUS: .data_%.strip
+.data_%.strip: %.ko .config
+	$(Q)$(NM) $< | sed -n 's,[[:xdigit:]]\+[[:space:]]\+[^tT][[:space:]]\+\(.*\),\1,p' \
+		| while read i; do case $$i in \
+			$(addsuffix $(close);;,$(shell cat $(filter $(srctree)/%,$(kallsyms-strip-src)) \
+				| sed 's,\([;|&<>()$$\\]\),\\\1,g')) \
+			*) echo $$i;; \
+		esac; done >$@
+
+targets += $(patsubst %$(ko),%.ko,$(modules))
+
+endif
+
 targets += $(modules)
 
 
--- 2.6.14/scripts/genksyms/genksyms.c	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/genksyms/genksyms.c	2005-11-04 16:19:35.000000000 +0100
@@ -43,7 +43,7 @@ FILE *debugfile;
 int cur_line = 1;
 char *cur_filename, *output_directory;
 
-int flag_debug, flag_dump_defs, flag_warnings;
+int flag_debug, flag_dump_defs, flag_warnings, flag_inline_asm;
 
 static int errors;
 static int nsyms;
@@ -457,8 +457,16 @@ export_symbol(const char *name)
       if (flag_dump_defs)
 	fputs(">\n", debugfile);
 
-      /* Used as a linker script. */
-      printf("__crc_%s = 0x%08lx ;\n", name, crc);
+      if (!flag_inline_asm)
+	{
+	  /* Used as a linker script. */
+	  printf("__crc_%s = 0x%08lx ;\n", name, crc);
+	}
+      else
+	{
+	  /* Used as inline assembly. */
+	  printf("__asm__(\".equiv __crc_%s, 0x%08lx\");\n", name, crc);
+	}
     }
 }
 
@@ -529,6 +537,7 @@ main(int argc, char **argv)
 
 #ifdef __GNU_LIBRARY__
   struct option long_opts[] = {
+    {"asm", 0, 0, 'a'},
     {"debug", 0, 0, 'd'},
     {"warnings", 0, 0, 'w'},
     {"quiet", 0, 0, 'q'},
@@ -538,13 +547,16 @@ main(int argc, char **argv)
     {0, 0, 0, 0}
   };
 
-  while ((o = getopt_long(argc, argv, "dwqVDk:p:",
+  while ((o = getopt_long(argc, argv, "adwqVDk:p:",
 			  &long_opts[0], NULL)) != EOF)
 #else  /* __GNU_LIBRARY__ */
-  while ((o = getopt(argc, argv, "dwqVDk:p:")) != EOF)
+  while ((o = getopt(argc, argv, "adwqVDk:p:")) != EOF)
 #endif /* __GNU_LIBRARY__ */
     switch (o)
       {
+      case 'a':
+	flag_inline_asm = 1;
+	break;
       case 'd':
 	flag_debug++;
 	break;
--- 2.6.14/scripts/kallsyms.c	2005-10-28 02:02:08.000000000 +0200
+++ 2.6.14-kallsyms/scripts/kallsyms.c	2005-11-07 11:55:11.000000000 +0100
@@ -30,6 +30,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
+#include <limits.h>
 
 #define KSYM_NAME_LEN		127
 
@@ -43,6 +44,7 @@ struct sym_entry {
 
 static struct sym_entry *table;
 static unsigned int table_size, table_cnt;
+static long stage;
 static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext;
 static int all_symbols = 0;
 static char symbol_prefix_char = '\0';
@@ -56,7 +58,7 @@ unsigned char best_table_len[256];
 
 static void usage(void)
 {
-	fprintf(stderr, "Usage: kallsyms [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n");
+	fprintf(stderr, "Usage: kallsyms [stage] [--all-symbols] [--symbol-prefix=<prefix char>] < in.map > out.S\n");
 	exit(1);
 }
 
@@ -66,8 +68,12 @@ static void usage(void)
  */
 static inline int is_arm_mapping_symbol(const char *str)
 {
+#if defined(ARCH_arm) || defined(ARCH_arm26)
 	return str[0] == '$' && strchr("atd", str[1])
 	       && (str[2] == '\0' || str[2] == '.');
+#else
+	return 0;
+#endif
 }
 
 static int read_symbol(FILE *in, struct sym_entry *s)
@@ -138,13 +144,6 @@ static int symbol_valid(struct sym_entry
 	 * specified so exclude them to get a stable symbol list.
 	 */
 	static char *special_symbols[] = {
-		"kallsyms_addresses",
-		"kallsyms_num_syms",
-		"kallsyms_names",
-		"kallsyms_markers",
-		"kallsyms_token_table",
-		"kallsyms_token_index",
-
 	/* Exclude linker generated symbols which vary between passes */
 		"_SDA_BASE_",		/* ppc */
 		"_SDA2_BASE_",		/* ppc */
@@ -176,7 +175,8 @@ static int symbol_valid(struct sym_entry
 	}
 
 	/* Exclude symbols which vary between passes. */
-	if (strstr((char *)s->sym + offset, "_compiled."))
+	if (strstr((char *)s->sym + offset, "_compiled.")
+	    || strncmp((char *)s->sym + offset, "__compound_literal.", 19) == 0)
 		return 0;
 
 	for (i = 0; special_symbols[i]; i++)
@@ -258,7 +258,42 @@ static void write_src(void)
 	printf("#define ALGN .align 4\n");
 	printf("#endif\n");
 
-	printf(".data\n");
+	printf(".section .rodata, \"a\"\n");
+
+	if (stage) {
+		static struct {
+			const char*name;
+			unsigned writeable:1;
+			unsigned aligned:1;
+		} const what[] = {
+			{"sections", 1, 1},
+			{"symtab",   1, 1},
+			{"strtab",   0, 0},
+			{"shstrtab", 0, 0}
+		};
+
+		for (i = 0; i < sizeof(what)/sizeof(*what); ++i) {
+			if (what[i].writeable)
+				printf(".data\n");
+			printf(".globl kallsyms_%s, kallsyms_size_%s\n", what[i].name, what[i].name);
+			if (what[i].aligned)
+				printf("\tALGN\n");
+			printf("kallsyms_%s:\n", what[i].name);
+			printf(".incbin \".tmp_kallsyms%ld.%s\"\n", labs(stage) - 1, what[i].name);
+			printf(".equ __kallsyms_size_%s, . - kallsyms_%s\n", what[i].name, what[i].name);
+			if (what[i].writeable)
+				printf(".previous\n");
+			printf("\n");
+		}
+		printf("\tALGN\n");
+		for (i = 0; i < sizeof(what)/sizeof(*what); ++i) {
+			printf("kallsyms_size_%s:\n", what[i].name);
+			printf("\tPTR\t__kallsyms_size_%s\n", what[i].name);
+		}
+		printf("\n");
+	}
+	if (stage < 0)
+		return;
 
 	output_label("kallsyms_addresses");
 	for (i = 0; i < table_cnt; i++) {
@@ -472,25 +507,28 @@ static void optimize_token_table(void)
 
 int main(int argc, char **argv)
 {
-	if (argc >= 2) {
-		int i;
-		for (i = 1; i < argc; i++) {
-			if(strcmp(argv[i], "--all-symbols") == 0)
-				all_symbols = 1;
-			else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) {
-				char *p = &argv[i][16];
-				/* skip quote */
-				if ((*p == '"' && *(p+2) == '"') || (*p == '\'' && *(p+2) == '\''))
-					p++;
-				symbol_prefix_char = *p;
-			} else
-				usage();
-		}
-	} else if (argc != 1)
-		usage();
+	int i;
+
+	for (i = 1; i < argc; i++) {
+		if(strcmp(argv[i], "--all-symbols") == 0)
+			all_symbols = 1;
+		else if (strncmp(argv[i], "--symbol-prefix=", 16) == 0) {
+			char *p = &argv[i][16];
+
+			/* skip quote */
+			if ((*p == '"' || *p == '\'') && p[2] == *p)
+				p++;
+			symbol_prefix_char = *p;
+		} else if ((stage = strtol(argv[i], argv + i, 0)) == 0
+		           || stage >= LONG_MAX
+		           || stage <= LONG_MIN
+		           || *argv[i])
+			usage();
+	}
 
 	read_map(stdin);
-	optimize_token_table();
+	if (stage >= 0 && table_cnt)
+		optimize_token_table();
 	write_src();
 
 	return 0;
--- 2.6.14/scripts/kallsyms.strip	1970-01-01 01:00:00.000000000 +0100
+++ 2.6.14-kallsyms/scripts/kallsyms.strip	2005-03-21 16:34:09.000000000 +0100
@@ -0,0 +1,18 @@
+<*>
+__compound_literal[$.][0-9]*
+__crc_[a-zA-Z_]*
+__exitcall_[a-zA-Z_]*
+__func__[$.][0-9]*
+__FUNCTION__[$.][0-9]*
+gcc[0-9]_compiled[$.]
+__initcall_[a-zA-Z_]*
+__kcrctab_[a-zA-Z_]*
+__kstrtab_[a-zA-Z_]*
+__ksymtab_[a-zA-Z_]*
+__mod_[a-zA-Z_]*[0-9]
+__module_depends
+__param_[a-zA-Z_]*
+__pci_fixup_[A-Z]*
+__PRETTY_FUNCTION__[$.][0-9]*
+__setup_[a-zA-Z_0-9]*
+____versions

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 2/39] NLKD - an alternative early ioremap approach
  2005-11-09 13:56 ` [PATCH 1/39] NLKD - an alternative kallsyms approach Jan Beulich
@ 2005-11-09 13:57   ` Jan Beulich
  2005-11-09 13:58     ` [PATCH 3/39] NLKD - early/late CPU up/down notification Jan Beulich
  2005-11-11 10:06     ` [PATCH 2/39] NLKD - an alternative early ioremap approach Pavel Machek
  2005-11-09 16:50   ` [PATCH 1/39] NLKD - an alternative kallsyms approach Randy.Dunlap
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 13:57 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 359 bytes --]

An alternative to (on i386) boot-time ioremap approaches, which is more
architecture independent (though arch dependent code needs adjustments
if this is to be made use of, which with this patch only happens for
i386 and x86_64) and doesn't require alternative boot-time interfaces.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-early-ioremap.patch --]
[-- Type: application/octet-stream, Size: 8196 bytes --]

An alternative to (on i386) boot-time ioremap approaches, which is more
architecture independent (though arch dependent code needs adjustments
if this is to be made use of, which with this patch only happens for
i386 and x86_64) and doesn't require alternative boot-time interfaces.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/i386/kernel/setup.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/setup.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/setup.c	2005-11-04 16:19:33.000000000 +0100
@@ -1127,6 +1127,9 @@ static unsigned long __init setup_memory
 	}
 	printk(KERN_NOTICE "%ldMB HIGHMEM available.\n",
 		pages_to_mb(highend_pfn - highstart_pfn));
+	high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
+#else
+	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
 #endif
 	printk(KERN_NOTICE "%ldMB LOWMEM available.\n",
 			pages_to_mb(max_low_pfn));
Index: 2.6.14-nlkd/arch/i386/mm/init.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/mm/init.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/mm/init.c	2005-11-04 16:19:33.000000000 +0100
@@ -560,12 +560,6 @@ void __init mem_init(void)
  
 	set_max_mapnr_init();
 
-#ifdef CONFIG_HIGHMEM
-	high_memory = (void *) __va(highstart_pfn * PAGE_SIZE - 1) + 1;
-#else
-	high_memory = (void *) __va(max_low_pfn * PAGE_SIZE - 1) + 1;
-#endif
-
 	/* this will put all low memory onto the freelists */
 	totalram_pages += free_all_bootmem();
 
Index: 2.6.14-nlkd/arch/i386/mm/ioremap.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/mm/ioremap.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/mm/ioremap.c	2005-11-04 16:19:33.000000000 +0100
@@ -257,7 +257,8 @@ void iounmap(volatile void __iomem *addr
 	} 
 out_unlock:
 	write_unlock(&vmlist_lock);
-	kfree(p); 
+	if (p)
+		free_vm_area(p);
 }
 EXPORT_SYMBOL(iounmap);
 
Index: 2.6.14-nlkd/arch/i386/mm/pgtable.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/mm/pgtable.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/mm/pgtable.c	2005-11-04 16:19:33.000000000 +0100
@@ -11,6 +11,7 @@
 #include <linux/smp.h>
 #include <linux/highmem.h>
 #include <linux/slab.h>
+#include <linux/bootmem.h>
 #include <linux/pagemap.h>
 #include <linux/spinlock.h>
 
@@ -148,7 +149,9 @@ void __set_fixmap (enum fixed_addresses 
 
 pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address)
 {
-	return (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
+	if (likely(totalram_pages))
+		return (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
+	return alloc_bootmem_pages(PAGE_SIZE);
 }
 
 struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address)
Index: 2.6.14-nlkd/arch/x86_64/kernel/setup.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/setup.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/setup.c	2005-11-04 16:19:33.000000000 +0100
@@ -566,6 +566,7 @@ void __init setup_arch(char **cmdline_p)
 	 * we are rounding upwards:
 	 */
 	end_pfn = e820_end_of_ram();
+	high_memory = (void *)__va(end_pfn * PAGE_SIZE - 1) + 1;
 
 	check_efer();
 
Index: 2.6.14-nlkd/arch/x86_64/mm/init.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/mm/init.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/mm/init.c	2005-11-04 16:19:33.000000000 +0100
@@ -400,7 +400,6 @@ void __init mem_init(void)
 	max_low_pfn = end_pfn;
 	max_pfn = end_pfn;
 	num_physpages = end_pfn;
-	high_memory = (void *) __va(end_pfn * PAGE_SIZE);
 
 	/* clear the zero-page */
 	memset(empty_zero_page, 0, PAGE_SIZE);
Index: 2.6.14-nlkd/arch/x86_64/mm/ioremap.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/mm/ioremap.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/mm/ioremap.c	2005-11-04 16:19:33.000000000 +0100
@@ -266,5 +266,6 @@ void iounmap(volatile void __iomem *addr
 	else if (p->flags >> 20)
 		ioremap_change_attr(p->phys_addr, p->size, 0);
 	write_unlock(&vmlist_lock);
-	kfree(p); 
+	if(p)
+		free_vm_area(p);
 }
Index: 2.6.14-nlkd/include/linux/vmalloc.h
===================================================================
--- 2.6.14-nlkd.orig/include/linux/vmalloc.h	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/include/linux/vmalloc.h	2005-11-04 16:19:34.000000000 +0100
@@ -8,6 +8,7 @@
 #define VM_IOREMAP	0x00000001	/* ioremap() and friends */
 #define VM_ALLOC	0x00000002	/* vmalloc() */
 #define VM_MAP		0x00000004	/* vmap()ed pages */
+#define VM_BOOTMEM	0x00000008	/* allocated from bootmem */
 /* bits [20..32] reserved for arch specific ioremap internals */
 
 /*
@@ -50,6 +51,7 @@ extern struct vm_struct *__get_vm_area(u
 					unsigned long start, unsigned long end);
 extern struct vm_struct *remove_vm_area(void *addr);
 extern struct vm_struct *__remove_vm_area(void *addr);
+extern void free_vm_area(struct vm_struct *area);
 extern int map_vm_area(struct vm_struct *area, pgprot_t prot,
 			struct page ***pages);
 extern void unmap_vm_area(struct vm_struct *area);
Index: 2.6.14-nlkd/mm/page_alloc.c
===================================================================
--- 2.6.14-nlkd.orig/mm/page_alloc.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/mm/page_alloc.c	2005-11-04 16:19:35.000000000 +0100
@@ -992,6 +992,15 @@ fastcall unsigned long get_zeroed_page(g
 {
 	struct page * page;
 
+	if (unlikely(!totalram_pages)) {
+		/* This exists solely for page table allocation; pages
+		   allocated this way must never be freed! */
+		void *address = alloc_bootmem_pages(PAGE_SIZE);
+
+		clear_page(address);
+		return (unsigned long) address;
+	}
+
 	/*
 	 * get_zeroed_page() returns a 32-bit address, which cannot represent
 	 * a highmem page
Index: 2.6.14-nlkd/mm/vmalloc.c
===================================================================
--- 2.6.14-nlkd.orig/mm/vmalloc.c	2005-11-09 10:40:18.000000000 +0100
+++ 2.6.14-nlkd/mm/vmalloc.c	2005-11-04 16:19:35.000000000 +0100
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/highmem.h>
 #include <linux/slab.h>
+#include <linux/bootmem.h>
 #include <linux/spinlock.h>
 #include <linux/interrupt.h>
 
@@ -177,20 +178,24 @@ struct vm_struct *__get_vm_area(unsigned
 	}
 	addr = ALIGN(start, align);
 	size = PAGE_ALIGN(size);
-
-	area = kmalloc(sizeof(*area), GFP_KERNEL);
-	if (unlikely(!area))
-		return NULL;
-
-	if (unlikely(!size)) {
-		kfree (area);
+	if (unlikely(!size))
 		return NULL;
-	}
-
 	/*
 	 * We always allocate a guard page.
 	 */
 	size += PAGE_SIZE;
+	if (unlikely(!size))
+		return NULL;
+
+	BUG_ON(flags & VM_BOOTMEM);
+	if (likely(malloc_sizes->cs_cachep))
+		area = kmalloc(sizeof(*area), GFP_KERNEL);
+	else {
+		area = alloc_bootmem(sizeof(*area));
+		flags |= VM_BOOTMEM;
+	}
+	if (unlikely(!area))
+		return NULL;
 
 	write_lock(&vmlist_lock);
 	for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
@@ -225,7 +230,7 @@ found:
 
 out:
 	write_unlock(&vmlist_lock);
-	kfree(area);
+	free_vm_area(area);
 	if (printk_ratelimit())
 		printk(KERN_WARNING "allocation failed: out of vmalloc space - use vmalloc=<size> to increase size.\n");
 	return NULL;
@@ -286,6 +291,14 @@ struct vm_struct *remove_vm_area(void *a
 	return v;
 }
 
+void free_vm_area(struct vm_struct *area)
+{
+	if (likely(!(area->flags & VM_BOOTMEM)))
+		kfree(area);
+	else if (!malloc_sizes->cs_cachep)
+		free_bootmem(virt_to_phys(area), sizeof(*area));
+}
+
 void __vunmap(void *addr, int deallocate_pages)
 {
 	struct vm_struct *area;
@@ -322,7 +335,7 @@ void __vunmap(void *addr, int deallocate
 			kfree(area->pages);
 	}
 
-	kfree(area);
+	free_vm_area(area);
 	return;
 }
 
@@ -412,7 +425,7 @@ void *__vmalloc_area(struct vm_struct *a
 	area->pages = pages;
 	if (!area->pages) {
 		remove_vm_area(area->addr);
-		kfree(area);
+		free_vm_area(area);
 		return NULL;
 	}
 	memset(area->pages, 0, array_size);

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-09 13:57   ` [PATCH 2/39] NLKD - an alternative early ioremap approach Jan Beulich
@ 2005-11-09 13:58     ` Jan Beulich
  2005-11-09 13:59       ` [PATCH 4/39] NLKD/i386 " Jan Beulich
                         ` (3 more replies)
  2005-11-11 10:06     ` [PATCH 2/39] NLKD - an alternative early ioremap approach Pavel Machek
  1 sibling, 4 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 13:58 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 225 bytes --]

A mechanism to allow debuggers to learn about starting/dying CPUs as
early/late as possible. Arch-dependent changes for i386 and x86_64
will follow.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-notify-cpu.patch --]
[-- Type: application/octet-stream, Size: 2254 bytes --]

A mechanism to allow debuggers to learn about starting/dying CPUs as
early/late as possible. Arch-dependent changes for i386 and x86_64
will follow.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/include/linux/cpu.h
===================================================================
--- 2.6.14-nlkd.orig/include/linux/cpu.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/linux/cpu.h	2005-11-04 16:19:34.000000000 +0100
@@ -42,6 +42,10 @@ struct notifier_block;
 extern int register_cpu_notifier(struct notifier_block *nb);
 extern void unregister_cpu_notifier(struct notifier_block *nb);
 
+#ifndef MODULE
+extern int cpu_notify(unsigned long);
+#endif
+
 int cpu_up(unsigned int cpu);
 
 #else
Index: 2.6.14-nlkd/include/linux/notifier.h
===================================================================
--- 2.6.14-nlkd.orig/include/linux/notifier.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/linux/notifier.h	2005-11-04 16:19:34.000000000 +0100
@@ -65,12 +65,14 @@ extern int notifier_call_chain(struct no
 
 #define NETLINK_URELEASE	0x0001	/* Unicast netlink socket released */
 
+#define CPU_ALIVE		0x0001 /* current CPU is alive */
 #define CPU_ONLINE		0x0002 /* CPU (unsigned)v is up */
 #define CPU_UP_PREPARE		0x0003 /* CPU (unsigned)v coming up */
 #define CPU_UP_CANCELED		0x0004 /* CPU (unsigned)v NOT coming up */
 #define CPU_DOWN_PREPARE	0x0005 /* CPU (unsigned)v going down */
 #define CPU_DOWN_FAILED		0x0006 /* CPU (unsigned)v NOT going down */
 #define CPU_DEAD		0x0007 /* CPU (unsigned)v dead */
+#define CPU_DYING		0x0008 /* current CPU dying */
 
 #endif /* __KERNEL__ */
 #endif /* _LINUX_NOTIFIER_H */
Index: 2.6.14-nlkd/kernel/cpu.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/cpu.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/kernel/cpu.c	2005-11-04 16:19:34.000000000 +0100
@@ -41,6 +41,12 @@ void unregister_cpu_notifier(struct noti
 }
 EXPORT_SYMBOL(unregister_cpu_notifier);
 
+int cpu_notify(unsigned long event)
+{
+	return notifier_call_chain(&cpu_chain, event,
+	                           (void *)(long)smp_processor_id());
+}
+
 #ifdef CONFIG_HOTPLUG_CPU
 static inline void check_for_tasks(int cpu)
 {

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 4/39] NLKD/i386 - early/late CPU up/down notification
  2005-11-09 13:58     ` [PATCH 3/39] NLKD - early/late CPU up/down notification Jan Beulich
@ 2005-11-09 13:59       ` Jan Beulich
  2005-11-09 14:01       ` [PATCH 5/39] NLKD/x86-64 " Jan Beulich
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 13:59 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 197 bytes --]

i386-specific part of the new mechanism to allow debuggers to learn
about starting/dying CPUs as early/late as possible.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-notify-cpu-i386.patch --]
[-- Type: application/octet-stream, Size: 882 bytes --]

i386-specific part of the new mechanism to allow debuggers to learn
about starting/dying CPUs as early/late as possible.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/i386/kernel/smpboot.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/smpboot.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/smpboot.c	2005-11-04 16:19:33.000000000 +0100
@@ -486,6 +486,7 @@ static void __devinit start_secondary(vo
 	smp_callin();
 	while (!cpu_isset(smp_processor_id(), smp_commenced_mask))
 		rep_nop();
+	cpu_notify(CPU_ALIVE);
 	setup_secondary_APIC_clock();
 	if (nmi_watchdog == NMI_IO_APIC) {
 		disable_8259A_irq(0);
@@ -970,6 +971,7 @@ void cpu_exit_clear(void)
 	int cpu = raw_smp_processor_id();
 
 	idle_task_exit();
+	cpu_notify(CPU_DYING);
 
 	cpucount --;
 	cpu_uninit();

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 5/39] NLKD/x86-64 - early/late CPU up/down notification
  2005-11-09 13:58     ` [PATCH 3/39] NLKD - early/late CPU up/down notification Jan Beulich
  2005-11-09 13:59       ` [PATCH 4/39] NLKD/i386 " Jan Beulich
@ 2005-11-09 14:01       ` Jan Beulich
  2005-11-10 13:10         ` Andi Kleen
  2005-11-09 14:01       ` [PATCH 6/39] NLKD - early panic notification Jan Beulich
  2005-11-09 16:45       ` [PATCH 3/39] NLKD - early/late CPU up/down notification Greg KH
  3 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:01 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 190 bytes --]

x86_64-specific part of the new mechanism to allow debuggers to learn
about starting/dying CPUs as early/late as possible.

From: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-notify-cpu-x86_64.patch --]
[-- Type: application/octet-stream, Size: 1362 bytes --]

x86_64-specific part of the new mechanism to allow debuggers to learn
about starting/dying CPUs as early/late as possible.

From: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/x86_64/kernel/process.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/process.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/process.c	2005-11-04 16:19:33.000000000 +0100
@@ -164,6 +164,7 @@ DECLARE_PER_CPU(int, cpu_state);
 static inline void play_dead(void)
 {
 	idle_task_exit();
+	cpu_notify(CPU_DYING);
 	wbinvd();
 	mb();
 	/* Ack it */
Index: 2.6.14-nlkd/arch/x86_64/kernel/smpboot.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/smpboot.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/smpboot.c	2005-11-04 16:19:33.000000000 +0100
@@ -40,7 +40,7 @@
 
 #include <linux/config.h>
 #include <linux/init.h>
-
+#include <linux/cpu.h>
 #include <linux/mm.h>
 #include <linux/kernel_stat.h>
 #include <linux/smp_lock.h>
@@ -479,6 +479,8 @@ void __cpuinit start_secondary(void)
 	/* otherwise gcc will move up the smp_processor_id before the cpu_init */
 	barrier();
 
+	cpu_notify(CPU_ALIVE);
+
 	Dprintk("cpu %d: setting up apic clock\n", smp_processor_id()); 	
 	setup_secondary_APIC_clock();
 

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 6/39] NLKD - early panic notification
  2005-11-09 13:58     ` [PATCH 3/39] NLKD - early/late CPU up/down notification Jan Beulich
  2005-11-09 13:59       ` [PATCH 4/39] NLKD/i386 " Jan Beulich
  2005-11-09 14:01       ` [PATCH 5/39] NLKD/x86-64 " Jan Beulich
@ 2005-11-09 14:01       ` Jan Beulich
  2005-11-09 14:02         ` [PATCH 7/39] NLKD - task create/destroy notification Jan Beulich
  2005-11-09 16:50         ` [PATCH 6/39] NLKD - early panic notification Greg KH
  2005-11-09 16:45       ` [PATCH 3/39] NLKD - early/late CPU up/down notification Greg KH
  3 siblings, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:01 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 140 bytes --]

A mechanism to allow debuggers to intercept panic events early.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-notify-prepanic.patch --]
[-- Type: application/octet-stream, Size: 1469 bytes --]

A mechanism to allow debuggers to intercept panic events early.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/include/linux/kernel.h
===================================================================
--- 2.6.14-nlkd.orig/include/linux/kernel.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/linux/kernel.h	2005-11-04 16:19:34.000000000 +0100
@@ -86,6 +86,7 @@ extern int cond_resched(void);
 	})
 
 extern struct notifier_block *panic_notifier_list;
+extern struct notifier_block *prepanic_notifier_list;
 extern long (*panic_blink)(long time);
 NORET_TYPE void panic(const char * fmt, ...)
 	__attribute__ ((NORET_AND format (printf, 1, 2)));
Index: 2.6.14-nlkd/kernel/panic.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/panic.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/kernel/panic.c	2005-11-04 16:19:34.000000000 +0100
@@ -27,8 +27,10 @@ int tainted;
 EXPORT_SYMBOL(panic_timeout);
 
 struct notifier_block *panic_notifier_list;
+struct notifier_block *prepanic_notifier_list;
 
 EXPORT_SYMBOL(panic_notifier_list);
+EXPORT_SYMBOL(prepanic_notifier_list);
 
 static int __init panic_setup(char *str)
 {
@@ -76,6 +78,7 @@ NORET_TYPE void panic(const char * fmt, 
 	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 	printk(KERN_EMERG "Kernel panic - not syncing: %s\n",buf);
+	notifier_call_chain(&prepanic_notifier_list, 0, buf);
 	bust_spinlocks(0);
 
 	/*

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 7/39] NLKD - task create/destroy notification
  2005-11-09 14:01       ` [PATCH 6/39] NLKD - early panic notification Jan Beulich
@ 2005-11-09 14:02         ` Jan Beulich
  2005-11-09 14:03           ` [PATCH 8/39] NLKD - rmmod notification Jan Beulich
  2005-11-09 16:50         ` [PATCH 6/39] NLKD - early panic notification Greg KH
  1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:02 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 144 bytes --]

A mechanism to allow debuggers to learn about starting/dying tasks.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-notify-task.patch --]
[-- Type: application/octet-stream, Size: 2004 bytes --]

A mechanism to allow debuggers to learn about starting/dying tasks.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/include/linux/sched.h
===================================================================
--- 2.6.14-nlkd.orig/include/linux/sched.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/linux/sched.h	2005-11-04 16:19:34.000000000 +0100
@@ -34,6 +34,7 @@
 #include <linux/percpu.h>
 #include <linux/topology.h>
 #include <linux/seccomp.h>
+#include <linux/notifier.h>
 
 #include <linux/auxvec.h>	/* For AT_VECTOR_SIZE */
 
@@ -1109,6 +1110,11 @@ extern int do_execve(char *, char __user
 extern long do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
 task_t *fork_idle(int);
 
+#define TASK_NEW 1
+#define TASK_DELETE 2
+
+extern struct notifier_block *task_notifier_list;
+
 extern void set_task_comm(struct task_struct *tsk, char *from);
 extern void get_task_comm(char *to, struct task_struct *tsk);
 
Index: 2.6.14-nlkd/kernel/fork.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/fork.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/kernel/fork.c	2005-11-04 16:19:34.000000000 +0100
@@ -64,6 +64,9 @@ DEFINE_PER_CPU(unsigned long, process_co
 
 EXPORT_SYMBOL(tasklist_lock);
 
+struct notifier_block *task_notifier_list = NULL;
+EXPORT_SYMBOL(task_notifier_list);
+
 int nr_processes(void)
 {
 	int cpu;
@@ -108,6 +111,8 @@ EXPORT_SYMBOL(free_task);
 
 void __put_task_struct(struct task_struct *tsk)
 {
+	notifier_call_chain(&task_notifier_list, TASK_DELETE, tsk);
+
 	WARN_ON(!(tsk->exit_state & (EXIT_DEAD | EXIT_ZOMBIE)));
 	WARN_ON(atomic_read(&tsk->usage));
 	WARN_ON(tsk == current);
@@ -1279,6 +1284,8 @@ long do_fork(unsigned long clone_flags,
 			set_tsk_thread_flag(p, TIF_SIGPENDING);
 		}
 
+		notifier_call_chain(&task_notifier_list, TASK_NEW, p);
+
 		if (!(clone_flags & CLONE_STOPPED))
 			wake_up_new_task(p, clone_flags);
 		else

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 8/39] NLKD - rmmod notification
  2005-11-09 14:02         ` [PATCH 7/39] NLKD - task create/destroy notification Jan Beulich
@ 2005-11-09 14:03           ` Jan Beulich
  2005-11-09 14:04             ` [PATCH 9/39] NLKD - hotkey notification Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:03 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 199 bytes --]

Debugging and maintenance support code occasionally needs to know not
only of module insertions, but also module removals.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-notify-rmmod.patch --]
[-- Type: application/octet-stream, Size: 1282 bytes --]

Debugging and maintenance support code occasionally needs to know not
only of module insertions, but also module removals.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/kernel/module.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/module.c	2005-11-04 16:19:34.000000000 +0100
+++ 2.6.14-nlkd/kernel/module.c	2005-11-04 16:19:34.000000000 +0100
@@ -1169,6 +1169,10 @@ static void cleanup_kallsyms(struct modu
 /* Free a module, remove from lists, etc (must hold module mutex). */
 static void free_module(struct module *mod)
 {
+	down(&notify_mutex);
+	notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod);
+	up(&notify_mutex);
+
 	/* Delete from various lists */
 	stop_machine_run(__unlink_module, mod, NR_CPUS);
 	remove_sect_attrs(mod);
@@ -1999,9 +2003,13 @@ sys_init_module(void __user *umod,
                    buggy refcounters. */
 		mod->state = MODULE_STATE_GOING;
 		synchronize_sched();
-		if (mod->unsafe)
+		if (mod->unsafe) {
 			printk(KERN_ERR "%s: module is now stuck!\n",
 			       mod->name);
+			down(&notify_mutex);
+			notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod);
+			up(&notify_mutex);
+		}
 		else {
 			module_put(mod);
 			down(&module_mutex);

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 9/39] NLKD - hotkey notification
  2005-11-09 14:03           ` [PATCH 8/39] NLKD - rmmod notification Jan Beulich
@ 2005-11-09 14:04             ` Jan Beulich
  2005-11-09 14:05               ` [PATCH 10/39] NLKD - console layout change notification Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:04 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 198 bytes --]

A mechanism to allow debuggers to trigger on a certain hotkey
(combination). Derived (generalized) from similar KDB work.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-notify-keyboard.patch --]
[-- Type: application/octet-stream, Size: 2137 bytes --]

A mechanism to allow debuggers to trigger on a certain hotkey
(combination). Derived (generalized) from similar KDB work.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/drivers/char/keyboard.c
===================================================================
--- 2.6.14-nlkd.orig/drivers/char/keyboard.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/drivers/char/keyboard.c	2005-11-07 09:39:05.000000000 +0100
@@ -39,6 +39,7 @@
 #include <linux/vt_kern.h>
 #include <linux/sysrq.h>
 #include <linux/input.h>
+#include <linux/kdebug.h>
 
 static void kbd_disconnect(struct input_handle *handle);
 extern void ctrl_alt_del(void);
@@ -153,6 +154,9 @@ static int sysrq_down;
 #endif
 static int sysrq_alt;
 
+struct notifier_block *kdebug_chain = NULL;
+EXPORT_SYMBOL(kdebug_chain);
+
 /*
  * Translation of scancodes to keycodes. We set them on only the first attached
  * keyboard - for per-keyboard setting, /dev/input/event is more useful.
@@ -1052,6 +1056,11 @@ static void kbd_keycode(unsigned int key
 
 	rep = (down == 2);
 
+	if (notify_kdebug(KDEBUG_KEYBOARD,
+	                  keycode | ((long)!down << (BITS_PER_LONG - 1)),
+	                  regs) == NOTIFY_STOP)
+		return;
+
 #ifdef CONFIG_MAC_EMUMOUSEBTN
 	if (mac_hid_mouse_emulate_buttons(1, keycode, down))
 		return;
Index: 2.6.14-nlkd/include/linux/kdebug.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/linux/kdebug.h	2005-11-09 10:25:16.000000000 +0100
@@ -0,0 +1,27 @@
+#ifndef _KDEBUG_H
+#define _KDEBUG_H
+
+/*
+ * This notifier is to replace hardcoded entries in e.g. the keyboard
+ * driver used by kernel debuggers.
+ */
+#include <linux/notifier.h>
+
+struct pt_regs;
+
+struct kdebug_args {
+	struct pt_regs *regs;
+	long data;
+};
+
+extern struct notifier_block *kdebug_chain;
+
+#define KDEBUG_KEYBOARD 1
+
+static inline int notify_kdebug(unsigned long event, long data, struct pt_regs *regs)
+{
+	struct kdebug_args args = { .regs=regs, .data = data };
+	return notifier_call_chain(&kdebug_chain, event, &args);
+}
+
+#endif

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 10/39] NLKD - console layout change notification
  2005-11-09 14:04             ` [PATCH 9/39] NLKD - hotkey notification Jan Beulich
@ 2005-11-09 14:05               ` Jan Beulich
  2005-11-09 14:06                 ` [PATCH 11/39] NLKD - time adjustment Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:05 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 192 bytes --]

A mechanism to allow (local) debuggers to learn about changes to the
console layout, to adapt their internal state.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-notify-console.patch --]
[-- Type: application/octet-stream, Size: 8873 bytes --]

A mechanism to allow (local) debuggers to learn about changes to the
console layout, to adapt their internal state.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/drivers/video/console/fbcon.c
===================================================================
--- 2.6.14-nlkd.orig/drivers/video/console/fbcon.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/drivers/video/console/fbcon.c	2005-11-07 12:09:42.000000000 +0100
@@ -107,7 +107,7 @@ enum {
 };
 
 struct display fb_display[MAX_NR_CONSOLES];
-static signed char con2fb_map[MAX_NR_CONSOLES];
+signed char con2fb_map[MAX_NR_CONSOLES];
 static signed char con2fb_map_boot[MAX_NR_CONSOLES];
 static int logo_height;
 static int logo_lines;
@@ -211,6 +211,16 @@ static inline int fbcon_is_inactive(stru
 		vc->vc_mode != KD_TEXT || ops->graphics);
 }
 
+static inline int fbcon_set_par(struct fb_info *info)
+{
+	if (info->fbops->fb_set_par) {
+		if (fb_notify_clients(FB_EVENT_PRE_MODE_CHANGE, info, &info->var) == NOTIFY_BAD)
+			return -EINVAL;
+		info->fbops->fb_set_par(info);
+	}
+	return 0;
+}
+
 static inline int get_color(struct vc_data *vc, struct fb_info *info,
 	      u16 c, int is_fg)
 {
@@ -623,15 +633,19 @@ static int con2fb_release_oldinfo(struct
 	return err;
 }
 
-static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
+static int con2fb_init_display(struct vc_data *vc, struct fb_info *info,
 				int unit, int show_logo)
 {
 	struct fbcon_ops *ops = info->fbcon_par;
 
 	ops->currcon = fg_console;
 
-	if (info->fbops->fb_set_par && !(ops->flags & FBCON_FLAGS_INIT))
-		info->fbops->fb_set_par(info);
+	if (!(ops->flags & FBCON_FLAGS_INIT)) {
+		int err = fbcon_set_par(info);
+
+		if (err)
+			return err;
+	}
 
 	ops->flags |= FBCON_FLAGS_INIT;
 	ops->graphics = 0;
@@ -652,6 +666,7 @@ static void con2fb_init_display(struct v
 	}
 
 	update_screen(vc_cons[fg_console].d);
+	return 0;
 }
 
 /**
@@ -708,7 +723,7 @@ static int set_con2fb_map(int unit, int 
  		if (!found)
  			fbcon_add_cursor_timer(info);
  		con2fb_map_boot[unit] = newidx;
- 		con2fb_init_display(vc, info, unit, show_logo);
+ 		err = con2fb_init_display(vc, info, unit, show_logo);
 	}
 
 	release_console_sem();
@@ -980,9 +995,8 @@ static void fbcon_init(struct vc_data *v
 	 * We need to do it in fbcon_init() to prevent screen corruption.
 	 */
 	if (CON_IS_VISIBLE(vc)) {
-		if (info->fbops->fb_set_par &&
-		    !(ops->flags & FBCON_FLAGS_INIT))
-			info->fbops->fb_set_par(info);
+		if (!(ops->flags & FBCON_FLAGS_INIT) && fbcon_set_par(info) != 0)
+			return;
 		ops->flags |= FBCON_FLAGS_INIT;
 	}
 
@@ -1988,8 +2002,8 @@ static int fbcon_switch(struct vc_data *
 	fb_set_var(info, &var);
 
 	if (old_info != NULL && old_info != info) {
-		if (info->fbops->fb_set_par)
-			info->fbops->fb_set_par(info);
+		if (fbcon_set_par(info) != 0)
+			return 0;
 		fbcon_del_cursor_timer(old_info);
 		fbcon_add_cursor_timer(info);
 	}
@@ -2848,6 +2862,12 @@ static const struct consw fb_con = {
 	.con_resize             = fbcon_resize,
 };
 
+int is_fb_con(const struct consw *con)
+{
+	return con == &fb_con;
+}
+EXPORT_SYMBOL(is_fb_con);
+
 static struct notifier_block fbcon_event_notifier = {
 	.notifier_call	= fbcon_event_notify,
 };
@@ -2892,4 +2912,6 @@ module_exit(fb_console_exit);
 
 #endif
 
+EXPORT_SYMBOL(con2fb_map);
+
 MODULE_LICENSE("GPL");
Index: 2.6.14-nlkd/drivers/video/console/fbcon.h
===================================================================
--- 2.6.14-nlkd.orig/drivers/video/console/fbcon.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/drivers/video/console/fbcon.h	2005-11-07 10:07:01.000000000 +0100
@@ -168,4 +168,7 @@ extern void fbcon_set_tileops(struct vc_
 #endif
 extern void fbcon_set_bitops(struct fbcon_ops *ops);
 
+extern int is_fb_con(const struct consw *);
+extern signed char con2fb_map[];
+
 #endif /* _VIDEO_FBCON_H */
Index: 2.6.14-nlkd/drivers/video/console/vgacon.c
===================================================================
--- 2.6.14-nlkd.orig/drivers/video/console/vgacon.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/drivers/video/console/vgacon.c	2005-11-04 16:19:34.000000000 +0100
@@ -114,6 +114,8 @@ static int 		vga_video_font_height;
 static int 		vga_scan_lines;
 static unsigned int 	vga_rolled_over = 0;
 
+static struct notifier_block *vga_notifier_list;
+
 static int __init no_scroll(char *str)
 {
 	/*
@@ -962,6 +964,9 @@ static int vgacon_adjust_height(struct v
 	outb_p(fsr, vga_video_port_val);
 	outb_p(0x12, vga_video_port_reg);	/* Vertical display limit */
 	outb_p(vde, vga_video_port_val);
+	notifier_call_chain(&vga_notifier_list,
+			    VGACON_EVENT_PRE_ADJUST_HEIGHT | (vga_font_is_default ? VGACON_MC_DEFAULT_FONT : 0),
+			    (void*)(long)rows);
 	spin_unlock_irq(&vga_lock);
 
 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
@@ -1185,4 +1190,16 @@ const struct consw vga_con = {
 	.con_invert_region = vgacon_invert_region,
 };
 
+int vgacon_register_client(struct notifier_block *nb)
+{
+	return notifier_chain_register(&vga_notifier_list, nb);
+}
+EXPORT_SYMBOL(vgacon_register_client);
+
+int vgacon_unregister_client(struct notifier_block *nb)
+{
+	return notifier_chain_unregister(&vga_notifier_list, nb);
+}
+EXPORT_SYMBOL(vgacon_unregister_client);
+
 MODULE_LICENSE("GPL");
Index: 2.6.14-nlkd/drivers/video/fbmem.c
===================================================================
--- 2.6.14-nlkd.orig/drivers/video/fbmem.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/drivers/video/fbmem.c	2005-11-07 10:11:34.000000000 +0100
@@ -673,8 +673,17 @@ fb_set_var(struct fb_info *info, struct 
 
 		if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
 			struct fb_videomode mode;
+			struct fb_event event;
 			int err = 0;
 
+			event.info = info;
+			event.data = var;
+			if (notifier_call_chain(&fb_notifier_list,
+						FB_EVENT_PRE_MODE_CHANGE,
+						&event) == NOTIFY_BAD)
+				return -EINVAL;
+
+
 			info->var = *var;
 			if (info->fbops->fb_set_par)
 				info->fbops->fb_set_par(info);
@@ -690,7 +699,6 @@ fb_set_var(struct fb_info *info, struct 
 				err = fb_add_videomode(&mode, &info->modelist);
 
 			if (!err && (flags & FBINFO_MISC_USEREVENT)) {
-				struct fb_event event;
 				int evnt = (var->activate & FB_ACTIVATE_ALL) ?
 					FB_EVENT_MODE_CHANGE_ALL :
 					FB_EVENT_MODE_CHANGE;
@@ -1117,6 +1125,21 @@ int fb_unregister_client(struct notifier
 }
 
 /**
+ *	fb_notify_clients - notify all clients
+ *	@what: event type
+ *	@info: framebuffer affected
+ *	@data: event specific data
+ */
+int fb_notify_clients(unsigned long what, struct fb_info *info, void *data)
+{
+	struct fb_event event;
+
+	event.info = info;
+	event.data = data;
+	return notifier_call_chain(&fb_notifier_list, what, &event);
+}
+
+/**
  *	fb_set_suspend - low level driver signals suspend
  *	@info: framebuffer affected
  *	@state: 0 = resuming, !=0 = suspending
@@ -1321,6 +1344,7 @@ EXPORT_SYMBOL(fb_get_buffer_offset);
 EXPORT_SYMBOL(fb_set_suspend);
 EXPORT_SYMBOL(fb_register_client);
 EXPORT_SYMBOL(fb_unregister_client);
+EXPORT_SYMBOL(fb_notify_clients);
 EXPORT_SYMBOL(fb_get_options);
 EXPORT_SYMBOL(fb_new_modelist);
 
Index: 2.6.14-nlkd/include/linux/fb.h
===================================================================
--- 2.6.14-nlkd.orig/include/linux/fb.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/linux/fb.h	2005-11-09 10:28:14.000000000 +0100
@@ -475,6 +475,8 @@ struct fb_cursor_user {
  * Register/unregister for framebuffer events
  */
 
+/*	The resolution of the passed in fb_info is about to change */
+#define FB_EVENT_PRE_MODE_CHANGE	0x00
 /*	The resolution of the passed in fb_info about to change */ 
 #define FB_EVENT_MODE_CHANGE		0x01
 /*	The display on this fb_info is beeing suspended, no access to the
@@ -509,6 +511,7 @@ struct fb_event {
 
 extern int fb_register_client(struct notifier_block *nb);
 extern int fb_unregister_client(struct notifier_block *nb);
+extern int fb_notify_clients(unsigned long, struct fb_info *, void *);
 
 /*
  * Pixmap structure definition
Index: 2.6.14-nlkd/include/video/vga.h
===================================================================
--- 2.6.14-nlkd.orig/include/video/vga.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/video/vga.h	2005-11-04 16:19:34.000000000 +0100
@@ -19,6 +19,7 @@
 
 #include <linux/config.h>
 #include <linux/types.h>
+#include <linux/notifier.h>
 #include <asm/io.h>
 #ifndef CONFIG_AMIGA
 #include <asm/vga.h>
@@ -479,4 +480,12 @@ static inline void vga_mm_wattr (void __
         vga_mm_w (regbase, VGA_ATT_W, val);
 }
 
+#define VGACON_EVENT_PRE_ADJUST_HEIGHT 0x01
+
+#define VGACON_EVENT_FLAGS_MASK 0xff000000
+#define VGACON_MC_DEFAULT_FONT 0x80000000
+
+int vgacon_register_client(struct notifier_block *);
+int vgacon_unregister_client(struct notifier_block *);
+
 #endif /* __linux_video_vga_h__ */

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 11/39] NLKD - time adjustment
  2005-11-09 14:05               ` [PATCH 10/39] NLKD - console layout change notification Jan Beulich
@ 2005-11-09 14:06                 ` Jan Beulich
  2005-11-09 14:06                   ` [PATCH 12/39] NLKD/i386 " Jan Beulich
                                     ` (3 more replies)
  0 siblings, 4 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:06 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 328 bytes --]

Generic part of an interface to allow debuggers to update time after
having halted the system for perhaps extended periods of time. This
generally requires arch-dependent changes, too, unless the arch-
dependent time handling is already overflow-safe.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-time.patch --]
[-- Type: application/octet-stream, Size: 2095 bytes --]

Generic part of an interface to allow debuggers to update time after
having halted the system for perhaps extended periods of time. This
generally requires arch-dependent changes, too, unless the arch-
dependent time handling is already overflow-safe.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/include/linux/jiffies.h
===================================================================
--- 2.6.14-nlkd.orig/include/linux/jiffies.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/linux/jiffies.h	2005-11-04 16:19:34.000000000 +0100
@@ -83,6 +83,11 @@
  */
 extern u64 __jiffy_data jiffies_64;
 extern unsigned long volatile __jiffy_data jiffies;
+#ifndef CONFIG_DEBUG_KERNEL
+# define debugger_jiffies 0
+#else
+extern u64 debugger_jiffies;
+#endif
 
 #if (BITS_PER_LONG < 64)
 u64 get_jiffies_64(void);
Index: 2.6.14-nlkd/kernel/timer.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/timer.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/kernel/timer.c	2005-11-07 15:20:27.000000000 +0100
@@ -46,6 +46,10 @@ static void time_interpolator_update(lon
 #define time_interpolator_update(x)
 #endif
 
+#ifdef CONFIG_DEBUG_KERNEL
+u64 debugger_jiffies;
+#endif
+
 /*
  * per-CPU timer vector definitions:
  */
@@ -935,6 +939,28 @@ static inline void update_times(void)
 	ticks = jiffies - wall_jiffies;
 	if (ticks) {
 		wall_jiffies += ticks;
+#ifndef debugger_jiffies
+		if (ticks > 1
+		    && debugger_jiffies
+		    && jiffies_64 - debugger_jiffies > 1) {
+			u64 nsec64 = (u64)(ticks - 1) * tick_nsec;
+			unsigned long nsec = do_div(nsec64, NSEC_PER_SEC);
+			unsigned long sec = nsec64;
+
+			if (sec > 0
+			    && xtime.tv_nsec + nsec + tick_nsec < NSEC_PER_SEC) {
+				/* Make sure xtime.tv_nsec exceeds a second when
+				   checked (in update_wall_time). */
+				sec--;
+				nsec += NSEC_PER_SEC;
+			}
+			xtime.tv_sec += sec;
+			xtime.tv_nsec += nsec;
+			touch_softlockup_watchdog();
+			ticks = 1;
+		}
+		debugger_jiffies = 0;
+#endif
 		update_wall_time(ticks);
 	}
 	calc_load(ticks);

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 12/39] NLKD/i386 - time adjustment
  2005-11-09 14:06                 ` [PATCH 11/39] NLKD - time adjustment Jan Beulich
@ 2005-11-09 14:06                   ` Jan Beulich
  2005-11-09 19:10                     ` George Anzinger
  2005-11-09 14:08                   ` [PATCH 13/39] NLKD/x86-64 " Jan Beulich
                                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:06 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 263 bytes --]

Since i386 time handling is not overflow-safe, these are the
adjustments needed for allowing debuggers to update time after
having halted the system for perhaps extended periods of time.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-time-i386.patch --]
[-- Type: application/octet-stream, Size: 12073 bytes --]

Since i386 time handling is not overflow-safe, these are the
adjustments needed for allowing debuggers to update time after
having halted the system for perhaps extended periods of time.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/i386/kernel/timers/common.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/timers/common.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/timers/common.c	2005-11-04 16:19:33.000000000 +0100
@@ -149,7 +149,7 @@ unsigned long read_timer_tsc(void)
 
 
 /* calculate cpu_khz */
-void init_cpu_khz(void)
+unsigned long init_cpu_khz(void)
 {
 	if (cpu_has_tsc) {
 		unsigned long tsc_quotient = calibrate_tsc();
@@ -166,7 +166,9 @@ void init_cpu_khz(void)
 				printk("Detected %u.%03u MHz processor.\n",
 					cpu_khz / 1000, cpu_khz % 1000);
 			}
+			return tsc_quotient;
 		}
 	}
+	return 0;
 }
 
Index: 2.6.14-nlkd/arch/i386/kernel/timers/timer_hpet.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/timers/timer_hpet.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/timers/timer_hpet.c	2005-11-04 16:19:33.000000000 +0100
@@ -99,7 +99,7 @@ static unsigned long get_offset_hpet(voi
 static void mark_offset_hpet(void)
 {
 	unsigned long long this_offset, last_offset;
-	unsigned long offset;
+	unsigned long offset, lost_ticks = 0;
 
 	write_seqlock(&monotonic_lock);
 	last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
@@ -109,14 +109,34 @@ static void mark_offset_hpet(void)
 		offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
 	else
 		offset = hpet_readl(HPET_COUNTER);
-	if (unlikely(((offset - hpet_last) >= (2*hpet_tick)) && (hpet_last != 0))) {
-		int lost_ticks = ((offset - hpet_last) / hpet_tick) - 1;
-		jiffies_64 += lost_ticks;
+	this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+	if (unlikely(debugger_jiffies)) {
+		unsigned long long delta = this_offset - last_offset;
+		unsigned long lo, hi, lo1;
+
+#ifndef CONFIG_SMP
+		/* When the TSC gets reset during AP startup, the code below would
+		   incorrectly think we lost a huge amount of ticks. */
+		if (unlikely((long long)delta < 0))
+			delta = this_offset;
+#endif
+		ASM_MUL64_REG(hi /* dummy */, lo1, tsc_hpet_quotient, (unsigned long)delta);
+		ASM_MUL64_REG(lo, hi, tsc_hpet_quotient, (unsigned long)(delta >> 32));
+		__asm__("addl %3, %1\n\t"
+		        "adcl $0, %2"
+		        : "=A" (delta)
+		        : "a" (lo), "d" (hi), "rm" (lo1)
+		        : "flags");
+		do_div(delta, hpet_tick);
+		lost_ticks = delta;
 	}
+	else if (unlikely(((offset - hpet_last) >= (2*hpet_tick)) && (hpet_last != 0)))
+		lost_ticks = ((offset - hpet_last) / hpet_tick);
+	if (lost_ticks)
+		jiffies_64 += lost_ticks - 1;
 	hpet_last = offset;
 
 	/* update the monotonic base value */
-	this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
 	monotonic_base += cycles_2_ns(this_offset - last_offset);
 	write_sequnlock(&monotonic_lock);
 }
Index: 2.6.14-nlkd/arch/i386/kernel/timers/timer_pm.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/timers/timer_pm.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/timers/timer_pm.c	2005-11-04 16:19:33.000000000 +0100
@@ -42,6 +42,10 @@ static u32 offset_delay;
 
 static unsigned long long monotonic_base;
 static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
+#ifndef debugger_jiffies
+static unsigned long tsc_quotient;
+static u64 tsc_offset;
+#endif
 
 #define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
 
@@ -127,6 +131,9 @@ pm_good:
 	if (verify_pmtmr_rate() != 0)
 		return -ENODEV;
 
+#ifndef debugger_jiffies
+	tsc_quotient =
+#endif
 	init_cpu_khz();
 	return 0;
 }
@@ -151,6 +158,11 @@ static inline u32 cyc2us(u32 cycles)
 static void mark_offset_pmtmr(void)
 {
 	u32 lost, delta, last_offset;
+#ifdef debugger_jiffies
+# define delta64 delta
+#else
+	u64 delta64, last_tsc_offset = tsc_offset;
+#endif
 	static int first_run = 1;
 	last_offset = offset_tick;
 
@@ -158,21 +170,60 @@ static void mark_offset_pmtmr(void)
 
 	offset_tick = read_pmtmr();
 
-	/* calculate tick interval */
-	delta = (offset_tick - last_offset) & ACPI_PM_MASK;
+#ifndef debugger_jiffies
+	rdtscll(tsc_offset);
 
-	/* convert to usecs */
-	delta = cyc2us(delta);
+	if (likely(!debugger_jiffies)) {
+#endif
+
+		/* calculate tick interval */
+		delta = (offset_tick - last_offset) & ACPI_PM_MASK;
+
+		/* convert to usecs */
+		delta = cyc2us(delta);
+
+#ifndef debugger_jiffies
+		delta64 = delta;
+	}
+	else {
+# ifdef CONFIG_SMP
+		/* When the TSC gets reset during AP startup, the code below would
+		   incorrectly think we lost a huge amount of ticks. */
+		if (unlikely((long long)(tsc_offset - last_tsc_offset) < 0))
+			delta64 = tsc_offset;
+		else
+# endif
+			delta64 = tsc_offset - last_tsc_offset;
+		__asm__("mull %2"
+			: "=a" (lost /* just a dummy */),
+			  "=d" (delta)
+			: "rm" (tsc_quotient),
+			  "0" ((unsigned long)delta64));
+		__asm__("mull %1"
+			: "=A" (delta64)
+			: "rm" (tsc_quotient),
+			  "a" ((unsigned long)(delta64 >> 32)));
+		delta64 += delta;
+		delta = (u32)delta64 ? (u32)delta64 - 1 : (offset_delay = 0);
+	}
+#endif
 
 	/* update the monotonic base value */
 	monotonic_base += delta * NSEC_PER_USEC;
 	write_sequnlock(&monotonic_lock);
 
 	/* convert to ticks */
-	delta += offset_delay;
-	lost = delta / (USEC_PER_SEC / HZ);
-	offset_delay = delta % (USEC_PER_SEC / HZ);
-
+	if (likely(delta == delta64)) {
+		delta += offset_delay;
+		lost = delta / (USEC_PER_SEC / HZ);
+		offset_delay = delta % (USEC_PER_SEC / HZ);
+	}
+	else {
+		do_div(delta64, USEC_PER_SEC / HZ);
+		lost = delta64;
+		offset_delay = 0;
+	}
+#undef delta64
 
 	/* compensate for lost ticks */
 	if (lost >= 2)
Index: 2.6.14-nlkd/arch/i386/kernel/timers/timer_tsc.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/timers/timer_tsc.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/timers/timer_tsc.c	2005-11-04 16:19:33.000000000 +0100
@@ -38,11 +38,21 @@ int tsc_disable __devinitdata = 0;
 
 static int use_tsc;
 /* Number of usecs that the last interrupt was delayed */
-static int delay_at_last_interrupt;
+static unsigned long delay_at_last_interrupt;
 
 static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
 static unsigned long last_tsc_high; /* msb 32 bits of Time Stamp Counter */
 static unsigned long long monotonic_base;
+#ifdef CONFIG_HPET_TIMER
+#ifdef CONFIG_DEBUG_KERNEL
+static unsigned long tsc_hpet_quotient;		/* convert tsc to hpet clks */
+#define TSC_HPET_QUOTIENT_PTR (&tsc_hpet_quotient)
+#else
+#define tsc_hpet_quotient 0
+#define TSC_HPET_QUOTIENT_PTR NULL
+#endif
+#endif
+
 static seqlock_t monotonic_lock = SEQLOCK_UNLOCKED;
 
 /* convert from cycles(64bits) => nanoseconds (64bits)
@@ -170,7 +180,7 @@ static void delay_tsc(unsigned long loop
 static void mark_offset_tsc_hpet(void)
 {
 	unsigned long long this_offset, last_offset;
- 	unsigned long offset, temp, hpet_current;
+ 	unsigned long offset, temp, hpet_current, lost_ticks = 0;
 
 	write_seqlock(&monotonic_lock);
 	last_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
@@ -190,15 +200,33 @@ static void mark_offset_tsc_hpet(void)
 	rdtsc(last_tsc_low, last_tsc_high);
 
 	/* lost tick compensation */
+	this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
 	offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
-	if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0))) {
-		int lost_ticks = (offset - hpet_last) / hpet_tick;
-		jiffies_64 += lost_ticks;
+	if (unlikely(debugger_jiffies)) {
+		unsigned long long delta = this_offset - last_offset;
+
+		if (likely((long long)delta > 0)) {
+			unsigned long lo, hi, lo1;
+			unsigned long long full;
+
+			ASM_MUL64_REG(temp, lo1, tsc_hpet_quotient, (unsigned long)delta);
+			ASM_MUL64_REG(lo, hi, tsc_hpet_quotient, (unsigned long)(delta >> 32));
+			__asm__("addl %3, %1\n\t"
+			        "adcl $0, %2"
+			        : "=A" (full)
+			        : "a" (lo), "d" (hi), "rm" (lo1)
+			        : "flags");
+			do_div(full, hpet_tick);
+			lost_ticks = full;
+		}
 	}
+	else if (unlikely(((offset - hpet_last) > hpet_tick) && (hpet_last != 0)))
+		lost_ticks = (offset - hpet_last) / hpet_tick;
+	if (lost_ticks)
+		jiffies_64 += lost_ticks - 1;
 	hpet_last = hpet_current;
 
 	/* update the monotonic base value */
-	this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
 	monotonic_base += cycles_2_ns(this_offset - last_offset);
 	write_sequnlock(&monotonic_lock);
 
@@ -342,7 +370,6 @@ EXPORT_SYMBOL(recalibrate_cpu_khz);
 static void mark_offset_tsc(void)
 {
 	unsigned long lost,delay;
-	unsigned long delta = last_tsc_low;
 	int count;
 	int countmp;
 	static int count1 = 0;
@@ -400,25 +427,55 @@ static void mark_offset_tsc(void)
 		}
 	}
 
+	this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
+
 	/* lost tick compensation */
-	delta = last_tsc_low - delta;
-	{
+	if (likely(!debugger_jiffies)) {
+		unsigned long delta = last_tsc_low - (unsigned long)last_offset;
 		register unsigned long eax, edx;
+
 		eax = delta;
 		__asm__("mull %2"
 		:"=a" (eax), "=d" (edx)
 		:"rm" (fast_gettimeoffset_quotient),
 		 "0" (eax));
 		delta = edx;
+		delta += delay_at_last_interrupt;
+		lost = delta / (USEC_PER_SEC / HZ);
+		delay = delta % (USEC_PER_SEC / HZ);
+	}
+	else {
+		unsigned long long delta;
+		unsigned long delta_low;
+
+#ifdef CONFIG_SMP
+		/* When the TSC gets reset during AP startup, the code below would
+		   incorrectly think we lost a huge amount of ticks. */
+		if (unlikely((long long)(this_offset - last_offset) < 0))
+			delta = this_offset;
+		else
+#endif
+			delta = this_offset - last_offset;
+
+		__asm__("mull %2"
+			: "=a" (lost /* just a dummy */),
+			  "=d" (delta_low)
+			: "rm" (fast_gettimeoffset_quotient),
+			  "0" ((unsigned long)delta));
+		__asm__("mull %1"
+			: "=A" (delta)
+			: "rm" (fast_gettimeoffset_quotient),
+			  "a" ((unsigned long)(delta >> 32)));
+		delta += delta_low;
+		delta += delay_at_last_interrupt;
+		delay = do_div(delta, USEC_PER_SEC / HZ);
+		lost = delta;
 	}
-	delta += delay_at_last_interrupt;
-	lost = delta/(1000000/HZ);
-	delay = delta%(1000000/HZ);
 	if (lost >= 2) {
 		jiffies_64 += lost-1;
 
 		/* sanity check to ensure we're not always losing ticks */
-		if (lost_count++ > 100) {
+		if (!debugger_jiffies && lost_count++ > 100) {
 			printk(KERN_WARNING "Losing too many ticks!\n");
 			printk(KERN_WARNING "TSC cannot be used as a timesource.  \n");
 			printk(KERN_WARNING "Possible reasons for this are:\n");
@@ -435,7 +492,6 @@ static void mark_offset_tsc(void)
 	} else
 		lost_count = 0;
 	/* update the monotonic base value */
-	this_offset = ((unsigned long long)last_tsc_high<<32)|last_tsc_low;
 	monotonic_base += cycles_2_ns(this_offset - last_offset);
 	write_sequnlock(&monotonic_lock);
 
@@ -499,7 +555,7 @@ static int __init init_tsc(char* overrid
 		if (is_hpet_enabled() && hpet_use_timer) {
 			unsigned long result, remain;
 			printk("Using TSC for gettimeofday\n");
-			tsc_quotient = calibrate_tsc_hpet(NULL);
+			tsc_quotient = calibrate_tsc_hpet(TSC_HPET_QUOTIENT_PTR);
 			timer_tsc.mark_offset = &mark_offset_tsc_hpet;
 			/*
 			 * Math to calculate hpet to usec multiplier
Index: 2.6.14-nlkd/include/asm-i386/timer.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-i386/timer.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/asm-i386/timer.h	2005-11-04 16:19:34.000000000 +0100
@@ -57,7 +57,7 @@ extern struct init_timer_opts timer_cycl
 
 extern unsigned long calibrate_tsc(void);
 extern unsigned long read_timer_tsc(void);
-extern void init_cpu_khz(void);
+extern unsigned long init_cpu_khz(void);
 extern int recalibrate_cpu_khz(void);
 #ifdef CONFIG_HPET_TIMER
 extern struct init_timer_opts timer_hpet_init;

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-09 14:06                 ` [PATCH 11/39] NLKD - time adjustment Jan Beulich
  2005-11-09 14:06                   ` [PATCH 12/39] NLKD/i386 " Jan Beulich
@ 2005-11-09 14:08                   ` Jan Beulich
  2005-11-09 14:13                     ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Jan Beulich
  2005-11-10 13:19                     ` [PATCH 13/39] NLKD/x86-64 - time adjustment Andi Kleen
  2005-11-09 14:09                   ` [PATCH 14/39] NLKD - kernel trace buffer access Jan Beulich
  2005-11-09 18:51                   ` [PATCH 11/39] NLKD - time adjustment George Anzinger
  3 siblings, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:08 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 394 bytes --]

Since x86-64 time handling is not overflow-safe, these are the
adjustments needed for allowing debuggers to update time after
having halted the system for perhaps extended periods of time.

Note that this depends on the HPET definitions adjustments, which
aren't in 2.6.14, but have supposedly been merged already into 2.6.15.

From: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-time-x86_64.patch --]
[-- Type: application/octet-stream, Size: 14844 bytes --]

Since x86-64 time handling is not overflow-safe, these are the
adjustments needed for allowing debuggers to update time after
having halted the system for perhaps extended periods of time.

Note that this depends on the HPET definitions adjustments, which
aren't in 2.6.14, but have supposedly been merged already into 2.6.15.

From: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/x86_64/kernel/pmtimer.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/pmtimer.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/pmtimer.c	2005-11-04 16:19:33.000000000 +0100
@@ -52,22 +52,53 @@ int pmtimer_mark_offset(void)
 {
 	static int first_run = 1;
 	unsigned long tsc;
-	u32 lost;
-
+	u32 lost, delta;
 	u32 tick = inl(pmtmr_ioport);
-	u32 delta;
+#ifdef debugger_jiffies
+# define delta64 delta
+#else
+	u64 delta64;
+#endif
+
+	rdtscll(tsc);
 
-	delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK);
+	if (likely(!debugger_jiffies)) {
+		delta = cyc2us((tick - last_pmtmr_tick) & ACPI_PM_MASK);
+#ifndef delta64
+		delta64 = delta;
+	}
+	else {
+# ifdef CONFIG_SMP
+		/* When the TSC gets reset during AP startup, the code below would
+		   incorrectly think we lost a huge amount of ticks. */
+		if (unlikely((long long)(tsc - vxtime.last_tsc) < 0))
+			delta64 = tsc;
+		else
+# endif
+			delta64 = tsc - vxtime.last_tsc;
+		__asm__("mulq %1\n\t"
+		        "shrdq $32, %%rdx, %0"
+		        : "+a" (delta64)
+		        : "rm" (vxtime.tsc_quot)
+		        : "rdx");
+		delta = (u32)delta64 ? (u32)delta64 - 1 : (offset_delay = 0);
+#endif
+	}
 
 	last_pmtmr_tick = tick;
 	monotonic_base += delta * NSEC_PER_USEC;
 
-	delta += offset_delay;
-
-	lost = delta / (USEC_PER_SEC / HZ);
-	offset_delay = delta % (USEC_PER_SEC / HZ);
+	if (likely(delta == delta64)) {
+		delta += offset_delay;
+		lost = delta / (USEC_PER_SEC / HZ);
+		offset_delay = delta % (USEC_PER_SEC / HZ);
+	}
+	else {
+		lost = (u32)(delta64 / (USEC_PER_SEC / HZ));
+		offset_delay = 0;
+	}
+#undef delta64
 
-	rdtscll(tsc);
 	vxtime.last_tsc = tsc - offset_delay * cpu_khz;
 
 	/* don't calculate delay for first run,
Index: 2.6.14-nlkd/arch/x86_64/kernel/time.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/time.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/time.c	2005-11-04 16:19:33.000000000 +0100
@@ -58,6 +58,12 @@ DEFINE_SPINLOCK(i8253_lock);
 static int nohpet __initdata = 0;
 static int notsc __initdata = 0;
 
+#ifndef CONFIG_DEBUG_KERNEL
+# define hpet64 0
+#else
+static int hpet64 = -1;
+#endif
+
 #undef HPET_HACK_ENABLE_DANGEROUS
 
 unsigned int cpu_khz;					/* TSC clocks / usec, not used here */
@@ -65,7 +71,7 @@ static unsigned long hpet_period;			/* f
 unsigned long hpet_tick;				/* HPET clocks / interrupt */
 static int hpet_use_timer;
 unsigned long vxtime_hz = PIT_TICK_RATE;
-int report_lost_ticks;				/* command line option */
+static int report_lost_ticks;				/* command line option */
 unsigned long long monotonic_base;
 
 struct vxtime_data __vxtime __section_vxtime;	/* for vsyscalls */
@@ -75,6 +81,19 @@ unsigned long __wall_jiffies __section_w
 struct timespec __xtime __section_xtime;
 struct timezone __sys_tz __section_sys_tz;
 
+static unsigned int cyc2ns_scale;
+#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
+
+static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
+{
+	cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
+}
+
+static inline unsigned long long cycles_2_ns(unsigned long long cyc)
+{
+	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
+}
+
 static inline void rdtscll_sync(unsigned long *tsc)
 {
 #ifdef CONFIG_SMP
@@ -365,7 +384,14 @@ static irqreturn_t timer_interrupt(int i
 {
 	static unsigned long rtc_update = 0;
 	unsigned long tsc;
-	int delay, offset = 0, lost = 0;
+	unsigned int delay;
+#ifdef hpet64
+	int
+#else
+	long
+# define last last64
+#endif
+		offset = 0, lost = 0;
 
 /*
  * Here we are in the timer irq handler. We have irqs locally disabled (so we
@@ -384,8 +410,14 @@ static irqreturn_t timer_interrupt(int i
 		 * we can more accurately know the counter value
 		 * when the timer interrupt occured.
 		 */
+		unsigned int hi1 = hpet64 > 0 ? hpet_readl(HPET_COUNTER+4) : 0;
+
 		offset = hpet_readl(HPET_T0_CMP) - hpet_tick;
 		delay = hpet_readl(HPET_COUNTER) - offset;
+		if (hpet64 > 0)
+			offset += (long)(offset >= 0 ? hi1 : hpet_readl(HPET_COUNTER+4)) << 32;
+		else
+			offset = (unsigned int)offset;
 	} else {
 		spin_lock(&i8253_lock);
 		outb_p(0x00, 0x43);
@@ -398,21 +430,66 @@ static irqreturn_t timer_interrupt(int i
 	rdtscll_sync(&tsc);
 
 	if (vxtime.mode == VXTIME_HPET) {
-		if (offset - vxtime.last > hpet_tick) {
-			lost = (offset - vxtime.last) / hpet_tick - 1;
+		if (hpet64 > 0) {
+			unsigned long delta = offset - vxtime.last;
+
+			if (delta > hpet_tick)
+				lost = delta / hpet_tick - 1;
+			monotonic_base += delta * (NSEC_PER_SEC/HZ) / hpet_tick;
 		}
+		else if (likely(!debugger_jiffies)) {
+			unsigned int delta = offset - vxtime.last;
+
+			if (delta > hpet_tick)
+				lost = delta / hpet_tick - 1;
+			monotonic_base += delta * (NSEC_PER_SEC/HZ) / hpet_tick;
+		}
+		else {
+			unsigned long delta;
+
+#ifdef CONFIG_SMP
+			/* When the TSC gets reset during AP startup, the code below would
+			   incorrectly think we lost a huge amount of ticks. */
+			if(unlikely((long)(tsc - vxtime.last_tsc) < 0))
+				delta = tsc;
+			else
+#endif
+				delta = tsc - vxtime.last_tsc;
+			delta = cycles_2_ns(delta);
 
-		monotonic_base += 
-			(offset - vxtime.last)*(NSEC_PER_SEC/HZ) / hpet_tick;
+			if (delta > NSEC_PER_SEC/HZ)
+				lost = delta / (NSEC_PER_SEC/HZ) - 1;
+			monotonic_base += delta;
+		}
 
 		vxtime.last = offset;
+#ifndef debugger_jiffies
+		vxtime.last_tsc = tsc;
+#endif
 #ifdef CONFIG_X86_PM_TIMER
 	} else if (vxtime.mode == VXTIME_PMTMR) {
 		lost = pmtimer_mark_offset();
 #endif
 	} else {
-		offset = (((tsc - vxtime.last_tsc) *
-			   vxtime.tsc_quot) >> 32) - (USEC_PER_SEC / HZ);
+		long delta;
+
+		if (likely(!debugger_jiffies))
+			delta = ((tsc - vxtime.last_tsc) * vxtime.tsc_quot) >> 32;
+		else {
+			delta = tsc - vxtime.last_tsc;
+#ifdef CONFIG_SMP
+			/* When the TSC gets reset during AP startup, the code below would
+			   incorrectly think we lost a huge amount of ticks. */
+			if (delta < 0)
+				delta = tsc;
+#endif
+			__asm__("mulq %1\n\t"
+			        "shrdq $32, %%rdx, %0"
+			        : "+a" (delta)
+			        : "rm" (vxtime.tsc_quot)
+			        : "rdx");
+		}
+		offset = delta - (USEC_PER_SEC / HZ);
 
 		if (offset < 0)
 			offset = 0;
@@ -426,16 +503,31 @@ static irqreturn_t timer_interrupt(int i
 
 		vxtime.last_tsc = tsc - vxtime.quot * delay / vxtime.tsc_quot;
 
-		if ((((tsc - vxtime.last_tsc) *
-		      vxtime.tsc_quot) >> 32) < offset)
-			vxtime.last_tsc = tsc -
-				(((long) offset << 32) / vxtime.tsc_quot) - 1;
+		if (delta < offset) {
+			if (likely(!debugger_jiffies))
+				vxtime.last_tsc = tsc -
+					(((long) offset << 32) / vxtime.tsc_quot) - 1;
+			else {
+				unsigned long temp;
+
+				/* This division cannot overflow because the dividend was the
+				   result of a multiplication with the divisor. */
+				__asm__("divq %3"
+					: "=a" (delta),
+					  "=d" (temp)
+					: "A" ((__uint128_t)(unsigned long)offset << 32),
+					  "rm" (vxtime.tsc_quot));
+				vxtime.last_tsc = tsc - delta - 1;
+			}
+		}
 	}
 
 	if (lost > 0) {
-		handle_lost_ticks(lost, regs);
+		if (!debugger_jiffies)
+			handle_lost_ticks(lost, regs);
 		jiffies += lost;
 	}
+#undef last
 
 /*
  * Do the timer stuff.
@@ -478,19 +570,6 @@ static irqreturn_t timer_interrupt(int i
 	return IRQ_HANDLED;
 }
 
-static unsigned int cyc2ns_scale;
-#define CYC2NS_SCALE_FACTOR 10 /* 2^10, carefully chosen */
-
-static inline void set_cyc2ns_scale(unsigned long cpu_mhz)
-{
-	cyc2ns_scale = (1000 << CYC2NS_SCALE_FACTOR)/cpu_mhz;
-}
-
-static inline unsigned long long cycles_2_ns(unsigned long long cyc)
-{
-	return (cyc * cyc2ns_scale) >> CYC2NS_SCALE_FACTOR;
-}
-
 unsigned long long sched_clock(void)
 {
 	unsigned long a = 0;
@@ -791,7 +870,7 @@ static __init int late_hpet_init(void)
 fs_initcall(late_hpet_init);
 #endif
 
-static int hpet_timer_stop_set_go(unsigned long tick)
+static int hpet_timer_stop_set_go(unsigned long tick, unsigned n)
 {
 	unsigned int cfg;
 
@@ -802,8 +881,47 @@ static int hpet_timer_stop_set_go(unsign
 	cfg = hpet_readl(HPET_CFG);
 	cfg &= ~(HPET_CFG_ENABLE | HPET_CFG_LEGACY);
 	hpet_writel(cfg, HPET_CFG);
-	hpet_writel(0, HPET_COUNTER);
-	hpet_writel(0, HPET_COUNTER + 4);
+
+#ifndef hpet64
+	if (hpet64 && n > 0) {
+/*
+ * Unfortunately at least the ICH6 HPET runs its main counter in 32-bit mode
+ * when timer 0 is not run in 64-bit mode. Thus we need to check here whether
+ * the main counter remains in 64-bit mode when all 64-bit capable counters
+ * have been set to 32-bit mode. An alternative would be to run timer 0 in
+ * 64-bit mode while reading only its low 32 bits, but this requires that
+ * there be no 32-bit writers of the comparator or increment registers, which
+ * (given the global visibility of hpet_{read,write}{l,q}) cannot be
+ * guaranteed.
+ */
+		unsigned i;
+
+		/* Disable counters and set them to 32-bit mode. */
+		for (i = 0; i <= n; ++i)
+			hpet_writel(HPET_Tn_CFG(i), HPET_TN_32BIT);
+
+		/* Set main counter so it will immediately overflow and enable it */
+		hpet_writeq(0xffffffff, HPET_COUNTER);
+		hpet_writel(cfg | HPET_CFG_ENABLE, HPET_CFG);
+
+		/* Wait for it to overflow 32 bits. */
+		while (!(hpet_readl(HPET_COUNTER) + 1))
+			;
+
+		/* Disable main counter again. */
+		hpet_writel(cfg, HPET_CFG);
+
+		/* Check whether the high part changed. */
+		if (!hpet_readl(HPET_COUNTER + 4))
+			hpet64 = 0;
+
+		/* Perhaps this should generally be done? */
+		for (i = 0; i <= n; ++i)
+			hpet_writel(HPET_Tn_CFG(i), 0);
+	}
+#endif
+
+	hpet_writeq(0, HPET_COUNTER);
 
 /*
  * Set up timer 0, as periodic with first interrupt to happen at hpet_tick,
@@ -812,8 +930,8 @@ static int hpet_timer_stop_set_go(unsign
 	if (hpet_use_timer) {
 		hpet_writel(HPET_TN_ENABLE | HPET_TN_PERIODIC | HPET_TN_SETVAL |
 		    HPET_TN_32BIT, HPET_T0_CFG);
-		hpet_writel(hpet_tick, HPET_T0_CMP);
-		hpet_writel(hpet_tick, HPET_T0_CMP); /* AK: why twice? */
+		hpet_writeq(hpet_tick, HPET_T0_CMP); /* set comparator */
+		hpet_writeq(hpet_tick, HPET_T0_CMP); /* set increment */
 		cfg |= HPET_CFG_LEGACY;
 	}
 /*
@@ -841,7 +959,9 @@ static int hpet_init(void)
 
 	id = hpet_readl(HPET_ID);
 
-	if (!(id & HPET_ID_VENDOR) || !(id & HPET_ID_NUMBER))
+	if (!(id + 1)
+	    || !(id & HPET_ID_VENDOR)
+	    || !(id & HPET_ID_NUMBER))
 		return -1;
 
 	hpet_period = hpet_readl(HPET_PERIOD);
@@ -853,12 +973,17 @@ static int hpet_init(void)
 
 	hpet_use_timer = (id & HPET_ID_LEGSUP);
 
-	return hpet_timer_stop_set_go(hpet_tick);
+#ifndef hpet64
+	if (hpet64 && (!hpet_use_timer || !(id & HPET_ID_64BIT)))
+		hpet64 = 0;
+#endif
+
+	return hpet_timer_stop_set_go(hpet_tick, (id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT);
 }
 
 static int hpet_reenable(void)
 {
-	return hpet_timer_stop_set_go(hpet_tick);
+	return hpet_timer_stop_set_go(hpet_tick, 0);
 }
 
 void __init pit_init(void)
@@ -889,16 +1014,42 @@ void __init time_init(void)
 	char *timename;
 
 #ifdef HPET_HACK_ENABLE_DANGEROUS
-        if (!vxtime.hpet_address) {
+	if (!vxtime.hpet_address && !nohpet) {
 		printk(KERN_WARNING "time.c: WARNING: Enabling HPET base "
 		       "manually!\n");
-                outl(0x800038a0, 0xcf8);
-                outl(0xff000001, 0xcfc);
-                outl(0x800038a0, 0xcf8);
-                vxtime.hpet_address = inl(0xcfc) & 0xfffffffe;
-		printk(KERN_WARNING "time.c: WARNING: Enabled HPET "
-		       "at %#lx.\n", vxtime.hpet_address);
-        }
+		outl(0x80003800, 0xcf8);
+		if (inw(0xcfc) == 0x1022) {
+			outl(0x800038a0, 0xcf8);
+			outl(inl(0xcfc) | 0x00000001, 0xcfc);
+			vxtime.hpet_address = inl(0xcfc) & 0xfffffc00;
+		}
+		outl(0x8000f800, 0xcf8);
+		if (inw(0xcfc) == 0x8086) {
+			switch(inl(0xcfc) >> 16) {
+			case 0x24d0: // ICH5
+				outl(0x8000f8d0, 0xcf8);
+				outl(inl(0xcfc) | 0x00020000, 0xcfc);
+				vxtime.hpet_address = 0xfed00000 | ((inl(0xcfc) >> 3) & 0x00003000);
+				break;
+			case 0x2640: // ICH6/ICH6R
+			case 0x2641: // ICH6-M
+			case 0x26B8: // ICH7/ICH7R
+				outl(0x8000f8f0, 0xcf8);
+				outl(inl(0xcfc) | 0x00000001, 0xcfc);
+				vxtime.hpet_address = inl(0xcfc) & 0xffffc000;
+				if (vxtime.hpet_address) {
+					set_fixmap_nocache(FIX_HPET_BASE, vxtime.hpet_address + 0x3000);
+					hpet_writel(hpet_readl(0x404) | 0x80, 0x404);
+					vxtime.hpet_address = 0xfed00000 | ((hpet_readl(0x404) & 0x00000003) << 12);
+					__set_fixmap(FIX_HPET_BASE, 0, __pgprot(0));
+				}
+				break;
+			}
+		}
+		if (vxtime.hpet_address)
+			printk(KERN_WARNING "time.c: WARNING: Enabled HPET "
+			       "at %#lx.\n", vxtime.hpet_address);
+	}
 #endif
 	if (nohpet)
 		vxtime.hpet_address = 0;
@@ -974,8 +1125,16 @@ void __init time_init_gtod(void)
 	if (unsynchronized_tsc())
 		notsc = 1;
 	if (vxtime.hpet_address && notsc) {
+		unsigned int hi1 = hpet64 ? hpet_readl(HPET_COUNTER+4) : 0;
+
 		timetype = hpet_use_timer ? "HPET" : "PIT/HPET";
 		vxtime.last = hpet_readl(HPET_T0_CMP) - hpet_tick;
+#ifndef hpet64
+		if (hpet64) {
+			vxtime.last64 += (long)(vxtime.last >= 0 ? hi1 : hpet_readl(HPET_COUNTER+4)) << 32;
+			hpet64 = 1;
+		}
+#endif
 		vxtime.mode = VXTIME_HPET;
 		do_gettimeoffset = do_gettimeoffset_hpet;
 #ifdef CONFIG_X86_PM_TIMER
@@ -1295,6 +1454,15 @@ static int __init nohpet_setup(char *s) 
 
 __setup("nohpet", nohpet_setup);
 
+#ifndef hpet64
+static int __init nohpet64_setup(char *s)
+{
+	hpet64 = 0;
+	return 0;
+}
+
+__setup("nohpet64", nohpet64_setup);
+#endif
 
 static int __init notsc_setup(char *s)
 {
Index: 2.6.14-nlkd/include/asm-x86_64/vsyscall.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/vsyscall.h	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/vsyscall.h	2005-11-07 10:39:05.000000000 +0100
@@ -29,7 +29,10 @@ enum vsyscall_num {
 
 struct vxtime_data {
 	long hpet_address;	/* HPET base address */
-	int last;
+	union {
+		int last;
+		long last64;
+	};
 	unsigned long last_tsc;
 	long quot;
 	long tsc_quot;
@@ -37,7 +40,9 @@ struct vxtime_data {
 };
 
 #define hpet_readl(a)           readl((void *)fix_to_virt(FIX_HPET_BASE) + a)
+#define hpet_readq(a)           readq((void *)fix_to_virt(FIX_HPET_BASE) + a)
 #define hpet_writel(d,a)        writel(d, (void *)fix_to_virt(FIX_HPET_BASE) + a)
+#define hpet_writeq(d,a)        writeq(d, (void *)fix_to_virt(FIX_HPET_BASE) + a)
 
 /* vsyscall space (readonly) */
 extern struct vxtime_data __vxtime;

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 14/39] NLKD - kernel trace buffer access
  2005-11-09 14:06                 ` [PATCH 11/39] NLKD - time adjustment Jan Beulich
  2005-11-09 14:06                   ` [PATCH 12/39] NLKD/i386 " Jan Beulich
  2005-11-09 14:08                   ` [PATCH 13/39] NLKD/x86-64 " Jan Beulich
@ 2005-11-09 14:09                   ` Jan Beulich
  2005-11-09 14:09                     ` [PATCH 15/39] NLKD - early pseudo-fs Jan Beulich
  2005-11-10  5:44                     ` [PATCH 14/39] NLKD - kernel trace buffer access Keith Owens
  2005-11-09 18:51                   ` [PATCH 11/39] NLKD - time adjustment George Anzinger
  3 siblings, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:09 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 151 bytes --]

Debug extension implementation for NLKD to access the kernel trace
buffer.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-printk.patch --]
[-- Type: application/octet-stream, Size: 4993 bytes --]

Debug extension implementation for NLKD to access the kernel trace
buffer.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/kernel/printk.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/printk.c	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/kernel/printk.c	2005-11-04 16:19:34.000000000 +0100
@@ -1032,3 +1032,190 @@ int printk_ratelimit(void)
 				printk_ratelimit_burst);
 }
 EXPORT_SYMBOL(printk_ratelimit);
+
+#if defined(CONFIG_PRINTK) && defined(CONFIG_NLKD)
+# include <linux/ctype.h>
+# include <linux/nlkd.h>
+
+static int match(unsigned long start, unsigned long end, const char *pattern, size_t len)
+{
+	unsigned long stop;
+
+	start &= LOG_BUF_MASK;
+	stop = end &= LOG_BUF_MASK;
+	if (stop < start)
+		stop = log_buf_len;
+	for (;;) {
+		const char *p;
+
+		while (((end - start) & LOG_BUF_MASK) >= len
+		       && (p = memchr(log_buf + start, *pattern, stop - start)) != NULL) {
+			unsigned long where = p - log_buf;
+
+			if (len > stop - where
+			    ? !memcmp(p, pattern, stop - where)
+			      && !memcmp(p + (stop - where),
+			                 pattern + (stop - where),
+			                 len - (stop - where))
+			    : !memcmp(p, pattern, len))
+					return 1;
+			start = where + 1;
+		}
+		if (end >= start)
+			return 0;
+		start = 0;
+		stop = end;
+	}
+}
+
+static void do_mgrep(const char *pattern, long skip, long count)
+{
+	int backward = 1;
+	unsigned long line, cur;
+	size_t len = pattern ? strlen(pattern) : 0;
+
+	if (count == 0)
+		count = 5;
+	else if (count < 0) {
+		count = -count;
+		backward = 0;
+	}
+	if (skip < 0) {
+		skip = -skip;
+		backward = 0;
+	}
+#define LOG_IDX_MATCH(idx1, idx2) (!(((idx1) ^ (idx2)) & LOG_BUF_MASK))
+	if (backward) {
+		/* Search from end.  */
+		int end;
+
+		skip += count - 1;
+		line = log_end;
+		do {
+			for (cur = line - 1; !LOG_IDX_MATCH(cur, log_end) && LOG_BUF(cur) && LOG_BUF(cur) == '\n'; --cur)
+				;
+			for (; !(end = LOG_IDX_MATCH(cur, log_end) || !LOG_BUF(cur)) && LOG_BUF(cur) != '\n'; --cur)
+				;
+			if (len && !match(cur + 1, line, pattern, len))
+				++skip;
+			line = cur + 1;
+		} while (skip-- && !end);
+		if (++skip < count)
+			count -= skip;
+		else
+			count = 0;
+	}
+	else {
+		/* Search from start.  */
+		for (cur = LOG_BUF(log_end) ? log_end : 0; line = cur, skip; --skip) {
+			while (LOG_BUF(cur) != '\n')
+				if (!LOG_BUF(cur) || LOG_IDX_MATCH(++cur, log_end))
+					return;
+			while (LOG_BUF(cur) == '\n')
+				if (!LOG_BUF(cur) || LOG_IDX_MATCH(++cur, log_end))
+					return;
+			if (len && !match(line, cur, pattern, len))
+				++skip;
+		}
+	}
+	while (count) {
+		for (cur = line; LOG_BUF(cur) && LOG_BUF(cur) != '\n'; ++cur)
+			if (LOG_IDX_MATCH(cur + 1, 0)) {
+				for (cur = 0; LOG_BUF(cur) && LOG_BUF(cur) != '\n'; ++cur)
+					if (LOG_IDX_MATCH(cur + 1, line))
+						break;
+				break;
+			}
+		if(!len || match(line, cur, pattern, len)) {
+			if (cur < line) {
+				nlkdExtPrintf("%.*s", log_buf_len - (int)(line & LOG_BUF_MASK), &LOG_BUF(line));
+				nlkdExtPrintf("%.*s\n", (int)cur, log_buf);
+			}
+			else
+				nlkdExtPrintf("%.*s\n", (int)(cur - line), &LOG_BUF(line));
+			--count;
+		}
+		if (LOG_BUF(cur) != '\n')
+			break;
+		for (line = cur + 1; LOG_BUF(line) == '\n'; ++line)
+			;
+	}
+#undef LOG_IDX_MATCH
+}
+
+static char *skipComma(char *s) {
+	while (*s && isspace(*s))
+		++s;
+	if (*s == ';' || *s == ',')
+		++s;
+	while (*s && isspace(*s))
+		++s;
+	return s;
+}
+
+/*
+ * !dmesg [[<# to skip>;]<# of lines>]
+ */
+static void dbgxt_dmesg(void *pattern, const char *command) {
+	long skip = 0, count = 0;
+
+	if (!command)
+		return;
+	if (!pattern && *command == '?') {
+		nlkdExtOutputString("dmesg [[<# to skip>] <# of entries>]");
+		return;
+	}
+	if (*command) {
+		char *tail;
+
+		skip = simple_strtol(command, &tail, 0);
+		if (*(tail = skipComma(tail)))
+			count = simple_strtol(tail, NULL, 0);
+		else {
+			count = skip;
+			skip = 0;
+		}
+	}
+	do_mgrep(pattern, skip, count);
+}
+
+/*
+ * !mgrep <match string> [[<# to skip>];<# of lines>]
+ */
+static void dbgxt_mgrep(void *unused, const char *command) {
+	if (!command)
+		return;
+	if (!strcmp(command, "?")) {
+		nlkdExtOutputString("mgrep <match> [[<# to skip>] <# of entries>]");
+		return;
+	}
+	if (*command) {
+		char pattern[256], *dst;
+		char quote = strchr("\"\'", *command) != NULL ? *command++ : 0;
+
+		for (dst = pattern; *command && (quote ? *command != quote : !isspace(*command)); ++command)
+			if(dst < pattern + ARRAY_SIZE(pattern) - 1)
+				*dst++ = *command;
+		*dst = 0;
+		if (*command)
+			++command;
+		while (*command && isspace(*command))
+			++command;
+		dbgxt_dmesg((void *)pattern, command);
+	}
+}
+
+static THIS_MODULE_ID(printkModuleId);
+NLKD_EXTENSION(dmesg,
+	dbgxt_dmesg,
+	NULL,
+	printkModuleId,
+	"Display trace buffer records",
+	0);
+NLKD_EXTENSION(mgrep,
+	dbgxt_mgrep,
+	NULL,
+	printkModuleId,
+	"Grep trace buffer records",
+	0);
+#endif

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 15/39] NLKD - early pseudo-fs
  2005-11-09 14:09                   ` [PATCH 14/39] NLKD - kernel trace buffer access Jan Beulich
@ 2005-11-09 14:09                     ` Jan Beulich
  2005-11-09 14:11                       ` [PATCH 16/39] NLKD - core adjustments Jan Beulich
  2005-11-09 14:29                       ` [PATCH 15/39] NLKD - early pseudo-fs Al Viro
  2005-11-10  5:44                     ` [PATCH 14/39] NLKD - kernel trace buffer access Keith Owens
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:09 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 624 bytes --]

While for limited amounts of configuration information the kernel
command line may be suitable, it isn't when it comes to significant
amounts of configurable entities that need to be set before the full
kernel infrastructure is available. This patch adds functionality to
pass one or more configuration files through the initrd, but without
requiring knowledge of the actual structure (including compression) of
it; the file(s) is/are attached to the end of the already built
initrd (which obviously depends on external scripts not provided
here).

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-early-pseudo-fs.patch --]
[-- Type: application/octet-stream, Size: 9822 bytes --]

While for limited amounts of configuration information the kernel
command line may be suitable, it isn't when it comes to significant
amounts of configurable entities that need to be set before the full
kernel infrastructure is available. This patch adds functionality to
pass one or more configuration files through the initrd, but without
requiring knowledge of the actual structure (including compression) of
it; the file(s) is/are attached to the end of the already built
initrd (which obviously depends on external scripts not provided
here).

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/include/linux/epfs.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/linux/epfs.h	2005-06-27 12:48:32.000000000 +0200
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ *
+ *   File Name:      epfs.h
+ *   Created by:     Jan Beulich
+ *   Date created:   28Apr2005
+ *
+ *   %version:       2 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 04:48:22 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2005 Novell, Inc. All Rights Reserved.                      *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+#ifndef _LINUX_EPFS_H
+
+#include <linux/config.h>
+#include <linux/errno.h>
+#include <linux/types.h>
+
+#if defined(CONFIG_EARLY_PSEUDO_FS) && !defined(MODULE)
+# define EPFS_DECLARE(proto, retval) proto;
+#else
+# define EPFS_DECLARE(proto, retval) static inline proto { return retval; }
+#endif
+
+EPFS_DECLARE(int epfs_open(const char *name), -ENOSYS)
+EPFS_DECLARE(size_t epfs_get_size(int fd), ~(size_t)0)
+EPFS_DECLARE(size_t epfs_read(int fd, size_t pos, void *buf, size_t size), ~(size_t)0)
+EPFS_DECLARE(int epfs_close(int fd), -ENOSYS)
+
+#undef EPFS_DECLARE
+
+#endif /* _LINUX_EPFS_H */
Index: 2.6.14-nlkd/init/Kconfig
===================================================================
--- 2.6.14-nlkd.orig/init/Kconfig	2005-11-09 10:19:35.000000000 +0100
+++ 2.6.14-nlkd/init/Kconfig	2005-11-07 10:51:19.000000000 +0100
@@ -340,6 +340,16 @@ config BASE_FULL
 	  kernel data structures. This saves memory on small machines,
 	  but may reduce performance.
 
+config EARLY_PSEUDO_FS
+	bool "Early pseudo file system support"
+	depends on BLK_DEV_INITRD
+	---help---
+	  This pseudo file system allows access to certain (configuration)
+	  files before any real file system is available. A matching mkinitrd
+	  or similar script is required to actually make use of this.
+
+	  If unsure, say N.
+
 config FUTEX
 	bool "Enable futex support" if EMBEDDED
 	default y
Index: 2.6.14-nlkd/init/Makefile
===================================================================
--- 2.6.14-nlkd.orig/init/Makefile	2005-11-09 10:40:17.000000000 +0100
+++ 2.6.14-nlkd/init/Makefile	2005-11-04 16:19:34.000000000 +0100
@@ -4,6 +4,7 @@
 
 obj-y				:= main.o version.o mounts.o initramfs.o
 obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
+obj-$(CONFIG_EARLY_PSEUDO_FS)	+= epfs.o
 
 mounts-y			:= do_mounts.o
 mounts-$(CONFIG_DEVFS_FS)	+= do_mounts_devfs.o
Index: 2.6.14-nlkd/init/epfs.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/init/epfs.c	2005-06-27 16:02:28.000000000 +0200
@@ -0,0 +1,151 @@
+/*****************************************************************************
+ *
+ *   File Name:      epfs.c
+ *   Created by:     Jan Beulich
+ *   Date created:   28Apr2005
+ *
+ *   %version:       2 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 08:02:17 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2005 Novell, Inc. All Rights Reserved.                      *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+#include <linux/epfs.h>
+#include <linux/init.h>
+#include <linux/initrd.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+static inline int __init check_sys(void)
+{
+	return initrd_start && initrd_end > initrd_start;
+}
+
+static const char *__init find(const char *target, int *fd)
+{
+	const char *const start = (char *)initrd_start;
+	const char *ptr = (char *)initrd_end - 1;
+	const char *found = NULL;
+	size_t prev;
+
+	/* check initial link */
+	if (*ptr) {
+		*fd = -ENOSYS;
+		return NULL;
+	}
+	while (--ptr > start)
+		if ((*ptr < '0' || *ptr > '9') && (*ptr < 'A' || *ptr > 'F'))
+			break;
+	if (ptr <= start || *ptr) {
+		*fd = -ENOSYS;
+		return NULL;
+	}
+	if (target)
+		*fd = 0;
+	/* scan list */
+	for (prev = ptr - start; ; ) {
+		char *tail;
+		const size_t cur = simple_strtoul(ptr + 1, &tail, 16);
+		const char *const name = start + cur;
+		size_t size;
+
+		if (!*tail && !cur)
+			break;
+		if (*tail
+		    || cur <= 0
+		    || cur >= prev
+		    || *name != '/'
+		    || (tail = memchr(name, 0, prev - cur)) == NULL
+		    || (ptr = memchr(tail + 1, 0, (prev - cur) - (tail + 1 - name))) == NULL
+		    || (size = simple_strtoul(tail + 1, &tail, 16), tail != ptr)
+		    || (tail = memchr(ptr + 1, 0, (prev - cur) - (ptr + 1 - name))) == NULL
+		    || size + (tail + 1 - name) != prev - cur) {
+			*fd = -ENOSYS;
+			break;
+		}
+		if (!found) {
+			if (target) {
+				++*fd;
+				if(!strcmp(target, name))
+					found = name;
+			}
+			else if (!--*fd)
+				found = name;
+		}
+		prev = cur;
+	}
+	return found;
+}
+
+int __init epfs_open(const char *name)
+{
+	int fd;
+
+	if (!check_sys())
+		return -ENOSYS;
+	if (!name)
+		return -EINVAL;
+	if (!find(name, &fd))
+		return -ENOENT;
+	return fd;
+}
+
+size_t __init epfs_get_size(int fd)
+{
+	const char *start;
+
+	if (!check_sys() || !(start = find(NULL, &fd)))
+		return ~(size_t)0;
+	return simple_strtoul(start + strlen(start) + 1, NULL, 16);
+}
+
+size_t __init epfs_read(int fd, size_t pos, void *buf, size_t len)
+{
+	const char *start;
+	size_t size;
+
+	if (!check_sys() || !(start = find(NULL, &fd)))
+		return ~(size_t)0;
+	size = simple_strtoul(start += strlen(start) + 1, NULL, 16);
+	if (pos >= size)
+		return 0;
+	if (len > size - pos)
+		len = size - pos;
+	start += strlen(start) + 1; /* skip size */
+	start += strlen(start) + 1; /* skip link */
+	memcpy(buf, start + pos, len);
+	return size;
+}
+
+int __init epfs_close(int fd)
+{
+	if (!check_sys())
+		return -ENOSYS;
+	if (!find(NULL, &fd))
+		return -EINVAL;
+	return 0;
+}

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 16/39] NLKD - core adjustments
  2005-11-09 14:09                     ` [PATCH 15/39] NLKD - early pseudo-fs Jan Beulich
@ 2005-11-09 14:11                       ` Jan Beulich
  2005-11-09 14:11                         ` [PATCH 17/39] NLKD/i386 " Jan Beulich
  2005-11-09 14:18                         ` [PATCH 22/39] NLKD - core Jan Beulich
  2005-11-09 14:29                       ` [PATCH 15/39] NLKD - early pseudo-fs Al Viro
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:11 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 124 bytes --]

The core NLKD adjustments to pre-existing code.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd.patch --]
[-- Type: application/octet-stream, Size: 7333 bytes --]

The core NLKD adjustments to pre-existing code.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/include/asm-generic/bug.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-generic/bug.h	2005-11-09 10:40:16.000000000 +0100
+++ 2.6.14-nlkd/include/asm-generic/bug.h	2005-11-04 16:19:34.000000000 +0100
@@ -5,6 +5,44 @@
 #include <linux/config.h>
 
 #ifdef CONFIG_BUG
+
+# ifdef CONFIG_NLKD
+
+#  ifndef _LINUX_NLKD_H
+#   define _LINUX_NLKD_H
+#   include <linux/nlkd.h>
+#   undef _LINUX_NLKD_H
+#  endif
+
+#  ifdef HAVE_ARCH_BUG
+#   undef BUG
+#  else
+#   define HAVE_ARCH_BUG
+#  endif
+#  define BUG() nlkdAssert("BUG", __FILE__, __PRETTY_FUNCTION__, __LINE__)
+
+#  ifdef HAVE_ARCH_BUG_ON
+#   undef BUG_ON
+#  else
+#   define HAVE_ARCH_BUG_ON
+#  endif
+#  define BUG_ON(condition) (unlikely(condition) \
+		? nlkdAssert("!(" #condition ")", __FILE__, __PRETTY_FUNCTION__, __LINE__) \
+		: (void)0)
+
+#  ifdef HAVE_ARCH_WARN_ON
+#   undef WARN_ON
+#  else
+#   define HAVE_ARCH_WARN_ON
+#  endif
+#  define WARN_ON(condition) (unlikely(condition) \
+		? printk("Badness in %s at %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__), \
+		  dump_stack(), \
+		  nlkdDebugEvent(DEBUG_EVENT_MESSAGE, #condition) \
+		: (void)0)
+
+# endif /* CONFIG_NLKD */
+
 #ifndef HAVE_ARCH_BUG
 #define BUG() do { \
 	printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
Index: 2.6.14-nlkd/include/linux/sched.h
===================================================================
--- 2.6.14-nlkd.orig/include/linux/sched.h	2005-11-04 16:19:34.000000000 +0100
+++ 2.6.14-nlkd/include/linux/sched.h	2005-11-04 16:19:34.000000000 +0100
@@ -298,6 +298,10 @@ struct mm_struct {
 	/* Architecture-specific MM context */
 	mm_context_t context;
 
+#ifdef CONFIG_NLKD
+	struct cdeBPStruct_s *bpList;
+#endif
+
 	/* Token based thrashing protection. */
 	unsigned long swap_token_time;
 	char recent_pagein;
@@ -681,6 +685,10 @@ struct task_struct {
 
 	struct mm_struct *mm, *active_mm;
 
+#ifdef CONFIG_NLKD
+	struct cdeBPStruct_s *bpList;
+#endif
+
 /* task state */
 	struct linux_binfmt *binfmt;
 	long exit_state;
@@ -689,6 +697,9 @@ struct task_struct {
 	/* ??? */
 	unsigned long personality;
 	unsigned did_exec:1;
+#ifdef CONFIG_NLKD
+	unsigned kstep:1;         /* kernel-debugger single stepping this task */
+#endif
 	pid_t pid;
 	pid_t tgid;
 	/* 
Index: 2.6.14-nlkd/init/Kconfig
===================================================================
--- 2.6.14-nlkd.orig/init/Kconfig	2005-11-07 10:51:19.000000000 +0100
+++ 2.6.14-nlkd/init/Kconfig	2005-11-07 10:51:19.000000000 +0100
@@ -275,7 +275,7 @@ config KALLSYMS
 config KALLSYMS_TRADITIONAL
 	bool "Traditional kallsyms symbol table format"
 	depends on KALLSYMS
-	default !MODULES
+	default !MODULES && !NLKD
 	help
 	  Say N here if you want the kernel symbol table to be consistent with
 	  that loadable modules use (i.e. the ELF symbol table extracted from
Index: 2.6.14-nlkd/init/main.c
===================================================================
--- 2.6.14-nlkd.orig/init/main.c	2005-11-07 10:53:53.000000000 +0100
+++ 2.6.14-nlkd/init/main.c	2005-11-07 10:53:53.000000000 +0100
@@ -47,6 +47,7 @@
 #include <linux/rmap.h>
 #include <linux/mempolicy.h>
 #include <linux/key.h>
+#include <linux/nlkd.h>
 #include <net/sock.h>
 
 #include <asm/io.h>
@@ -482,6 +483,7 @@ asmlinkage void __init start_kernel(void
 	sort_main_extable();
 	trap_init();
 	kallsyms_early_init();
+	nlkd_init();
 	rcu_init();
 	init_IRQ();
 	pidhash_init();
@@ -709,6 +711,7 @@ static int init(void * unused)
 	 * we're essentially up and running. Get rid of the
 	 * initmem segments and start the user-mode stuff..
 	 */
+	nlkd_init_done();
 	kallsyms_init_done();
 	free_initmem();
 	unlock_kernel();
Index: 2.6.14-nlkd/kernel/exit.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/exit.c	2005-11-09 10:40:16.000000000 +0100
+++ 2.6.14-nlkd/kernel/exit.c	2005-11-04 16:19:34.000000000 +0100
@@ -28,6 +28,7 @@
 #include <linux/cpuset.h>
 #include <linux/syscalls.h>
 #include <linux/signal.h>
+#include <linux/nlkd.h>
 
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
@@ -794,6 +795,7 @@ fastcall NORET_TYPE void do_exit(long co
 	struct task_struct *tsk = current;
 	int group_dead;
 
+	bp_list_clear(tsk);
 	profile_task_exit(tsk);
 
 	WARN_ON(atomic_read(&tsk->fs_excl));
Index: 2.6.14-nlkd/kernel/fork.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/fork.c	2005-11-04 16:19:34.000000000 +0100
+++ 2.6.14-nlkd/kernel/fork.c	2005-11-04 16:19:34.000000000 +0100
@@ -42,6 +42,7 @@
 #include <linux/profile.h>
 #include <linux/rmap.h>
 #include <linux/acct.h>
+#include <linux/nlkd.h>
 
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
@@ -337,6 +338,9 @@ static struct mm_struct * mm_init(struct
 
 	if (likely(!mm_alloc_pgd(mm))) {
 		mm->def_flags = 0;
+#if defined(CONFIG_CDE) || defined(CONFIG_CDE_MODULE)
+		mm->bpList = NULL;
+#endif
 		return mm;
 	}
 	free_mm(mm);
@@ -377,6 +381,7 @@ void fastcall __mmdrop(struct mm_struct 
 void mmput(struct mm_struct *mm)
 {
 	if (atomic_dec_and_test(&mm->mm_users)) {
+		bp_list_clear(mm);
 		exit_aio(mm);
 		exit_mmap(mm);
 		if (!list_empty(&mm->mmlist)) {
Index: 2.6.14-nlkd/kernel/power/swsusp.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/power/swsusp.c	2005-11-09 10:40:16.000000000 +0100
+++ 2.6.14-nlkd/kernel/power/swsusp.c	2005-11-04 16:19:34.000000000 +0100
@@ -67,6 +67,7 @@
 #include <linux/highmem.h>
 #include <linux/bio.h>
 #include <linux/mount.h>
+#include <linux/nlkd.h>
 
 #include <asm/uaccess.h>
 #include <asm/mmu_context.h>
@@ -1044,6 +1045,7 @@ int swsusp_suspend(void)
 	/* Restore control flow magically appears here */
 	restore_processor_state();
 	BUG_ON (nr_copy_pages_check != nr_copy_pages);
+	bp_load();
 	restore_highmem();
 	device_power_up();
 	local_irq_enable();
@@ -1064,6 +1066,7 @@ int swsusp_resume(void)
          */
 	BUG_ON(!error);
 	restore_processor_state();
+	bp_load();
 	restore_highmem();
 	touch_softlockup_watchdog();
 	device_power_up();
Index: 2.6.14-nlkd/kernel/sched.c
===================================================================
--- 2.6.14-nlkd.orig/kernel/sched.c	2005-11-09 10:40:16.000000000 +0100
+++ 2.6.14-nlkd/kernel/sched.c	2005-11-04 16:19:34.000000000 +0100
@@ -47,6 +47,7 @@
 #include <linux/syscalls.h>
 #include <linux/times.h>
 #include <linux/acct.h>
+#include <linux/nlkd.h>
 #include <asm/tlb.h>
 
 #include <asm/unistd.h>
@@ -1568,12 +1569,17 @@ task_t * context_switch(runqueue_t *rq, 
 	struct mm_struct *mm = next->mm;
 	struct mm_struct *oldmm = prev->active_mm;
 
+	bp_list_disable(1, prev);
+
 	if (unlikely(!mm)) {
 		next->active_mm = oldmm;
 		atomic_inc(&oldmm->mm_count);
 		enter_lazy_tlb(oldmm, next);
-	} else
+	} else {
+		bp_list_disable(oldmm && oldmm != mm, oldmm);
 		switch_mm(oldmm, mm, next);
+		bp_list_enable(oldmm != mm, mm);
+	}
 
 	if (unlikely(!prev->mm)) {
 		prev->active_mm = NULL;
@@ -1584,6 +1590,8 @@ task_t * context_switch(runqueue_t *rq, 
 	/* Here we just switch the register state and the stack. */
 	switch_to(prev, next, prev);
 
+	bp_list_enable(1, current);
+
 	return prev;
 }
 

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 17/39] NLKD/i386 - core adjustments
  2005-11-09 14:11                       ` [PATCH 16/39] NLKD - core adjustments Jan Beulich
@ 2005-11-09 14:11                         ` Jan Beulich
  2005-11-09 19:00                           ` Adrian Bunk
  2005-11-09 14:18                         ` [PATCH 22/39] NLKD - core Jan Beulich
  1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:11 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 129 bytes --]

The core i386 NLKD adjustments to pre-existing code.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-i386.patch --]
[-- Type: application/octet-stream, Size: 9090 bytes --]

The core i386 NLKD adjustments to pre-existing code.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/i386/Kconfig
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/Kconfig	2005-11-04 16:19:32.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/Kconfig	2005-11-04 16:19:32.000000000 +0100
@@ -425,6 +425,11 @@ config X86_CMPXCHG64
 	depends on !M386 && !M486
 	default y
 
+config X86_CMOVE
+	bool
+	depends on !M386 && !M486 && !MCYRIXIII && !M586 && !M586TSC && !M586MMX && !MWINCHIPC6 && !MWINCHIP2 && !MWINCHIP3D && !MGEODEGX1
+	default y
+
 config X86_ALIGNMENT_16
 	bool
 	depends on MWINCHIP3D || MWINCHIP2 || MWINCHIPC6 || MCYRIXIII || X86_ELAN || MK6 || M586MMX || M586TSC || M586 || M486 || MVIAC3_2 || MGEODEGX1
Index: 2.6.14-nlkd/arch/i386/Kconfig.debug
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/Kconfig.debug	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/Kconfig.debug	2005-11-04 16:19:32.000000000 +0100
@@ -54,7 +54,7 @@ config DEBUG_PAGEALLOC
 
 config 4KSTACKS
 	bool "Use 4Kb for kernel stacks instead of 8Kb"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && !NLKD
 	help
 	  If you say Y here the kernel will use a 4Kb stacksize for the
 	  kernel stack attached to each process/thread. This facilitates
Index: 2.6.14-nlkd/arch/i386/kernel/cpu/common.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/cpu/common.c	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/cpu/common.c	2005-11-04 16:19:32.000000000 +0100
@@ -7,6 +7,7 @@
 #include <linux/bootmem.h>
 #include <asm/semaphore.h>
 #include <asm/processor.h>
+#include <asm/debugreg.h>
 #include <asm/i387.h>
 #include <asm/msr.h>
 #include <asm/io.h>
Index: 2.6.14-nlkd/arch/i386/kernel/process.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/process.c	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/process.c	2005-11-04 16:48:57.000000000 +0100
@@ -46,6 +46,7 @@
 #include <asm/io.h>
 #include <asm/ldt.h>
 #include <asm/processor.h>
+#include <asm/debugreg.h>
 #include <asm/i387.h>
 #include <asm/desc.h>
 #ifdef CONFIG_MATH_EMULATION
@@ -393,6 +394,10 @@ void exit_thread(void)
 		tss->io_bitmap_base = INVALID_IO_BITMAP_OFFSET;
 		put_cpu();
 	}
+	if (tsk->thread.debugreg[7]) {
+		enable_debugreg(tsk, 7, 0);
+		tsk->thread.debugreg[7] = 0;
+	}
 }
 
 void flush_thread(void)
@@ -406,6 +411,8 @@ void flush_thread(void)
 	 */
 	kprobe_flush_task(tsk);
 
+ 	if (tsk->thread.debugreg[7])
+		enable_debugreg(tsk, 7, 0);
 	memset(tsk->thread.debugreg, 0, sizeof(unsigned long)*8);
 	memset(tsk->thread.tls_array, 0, sizeof(tsk->thread.tls_array));	
 	/*
@@ -507,6 +514,12 @@ int copy_thread(int nr, unsigned long cl
 		desc->b = LDT_entry_b(&info);
 	}
 
+	if (tsk->thread.debugreg[7]) {
+		p->thread.debugreg[7] = 0;
+		enable_debugreg(p, 7, tsk->thread.debugreg[7]);
+		p->thread.debugreg[7] = tsk->thread.debugreg[7];
+	}
+
 	err = 0;
  out:
 	if (err && p->thread.io_bitmap_ptr) {
Index: 2.6.14-nlkd/arch/i386/kernel/ptrace.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/ptrace.c	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/ptrace.c	2005-11-04 16:19:32.000000000 +0100
@@ -493,7 +493,7 @@ asmlinkage int sys_ptrace(long request, 
 			   *
 			   * Note that LENi == 0x10 is defined on x86_64 in long
 			   * mode (i.e. even for 32-bit userspace software, but
-			   * 64-bit kernel), so the x86_64 mask value is 0x5454.
+			   * 64-bit kernel), so the x86_64 mask value is 0x5554.
 			   * See the AMD manual no. 24593 (AMD64 System
 			   * Programming)*/
 
@@ -506,6 +506,11 @@ asmlinkage int sys_ptrace(long request, 
 
 			  addr -= (long) &dummy->u_debugreg;
 			  addr = addr >> 2;
+
+			  if (enable_debugreg(child, addr, data) < 0) {
+				  ret = -EBUSY;
+				  break;
+			  }
 			  child->thread.debugreg[addr] = data;
 			  ret = 0;
 		  }
Index: 2.6.14-nlkd/arch/i386/kernel/signal.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/signal.c	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/signal.c	2005-11-04 16:19:33.000000000 +0100
@@ -25,6 +25,7 @@
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
 #include <asm/i387.h>
+#include <asm/debugreg.h>
 #include "sigframe.h"
 
 #define DEBUG_SIG 0
@@ -629,7 +630,7 @@ int fastcall do_signal(struct pt_regs *r
 		 * inside the kernel.
 		 */
 		if (unlikely(current->thread.debugreg[7])) {
-			set_debugreg(current->thread.debugreg[7], 7);
+			restore_debugreg();
 		}
 
 		/* Whee!  Actually deliver the signal.  */
Index: 2.6.14-nlkd/arch/i386/kernel/traps.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/traps.c	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/traps.c	2005-11-04 17:00:47.000000000 +0100
@@ -774,7 +774,7 @@ fastcall void __kprobes do_debug(struct 
 	 * the signal is delivered.
 	 */
 clear_dr7:
-	set_debugreg(0, 7);
+	disable_debugreg(regs, 7);
 	return;
 
 debug_vm86:
Index: 2.6.14-nlkd/arch/i386/kernel/vmlinux.lds.S
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/vmlinux.lds.S	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/vmlinux.lds.S	2005-11-07 11:58:12.000000000 +0100
@@ -82,6 +82,12 @@ SECTIONS
   __setup_start = .;
   .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
   __setup_end = .;
+#ifdef CONFIG_NLKD
+  . = ALIGN(4);
+  __start_nlkd_ext = .;
+  .nlkd.ext : AT(ADDR(.nlkd.ext) - LOAD_OFFSET) { *(.nlkd.ext) }
+  __stop_nlkd_ext = .;
+#endif
   __initcall_start = .;
   .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
 	*(.initcall1.init) 
Index: 2.6.14-nlkd/arch/i386/power/cpu.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/power/cpu.c	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/power/cpu.c	2005-11-04 17:05:42.000000000 +0100
@@ -10,6 +10,7 @@
 #include <linux/config.h>
 #include <linux/module.h>
 #include <linux/suspend.h>
+#include <asm/debugreg.h>
 
 static struct saved_context saved_context;
 
Index: 2.6.14-nlkd/include/asm-i386/debugreg.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-i386/debugreg.h	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/include/asm-i386/debugreg.h	2005-11-04 16:19:34.000000000 +0100
@@ -61,4 +61,54 @@
 #define DR_LOCAL_SLOWDOWN (0x100)   /* Local slow the pipeline */
 #define DR_GLOBAL_SLOWDOWN (0x200)  /* Global slow the pipeline */
 
+#ifdef CONFIG_NLKD
+
+# include <linux/nint.h>
+
+struct pt_regs;
+struct task_struct;
+
+# ifdef CONFIG_CDE
+#  define MAYBE_INDIR(x) x
+#  define set_debugreg(val, reg) ((void)(val), (void)(reg))
+# else
+#  define MAYBE_INDIR(x) (*x)
+extern void (*set_debugreg)(uintptr_t value, nuint_t regnum);
+# endif
+
+extern int MAYBE_INDIR(enable_debugreg)(struct task_struct *, nuint_t regnum, uintptr_t value);
+extern int MAYBE_INDIR(disable_debugreg)(struct pt_regs *, nuint_t regnum);
+extern int MAYBE_INDIR(restore_debugreg)(void);
+
+# undef MAYBE_INDIR
+
+#else
+
+# define set_debugreg(value, register)				\
+		__asm__("movl %0,%%db" #register		\
+			: /* no output */			\
+			:"r" (value))
+# define enable_debugreg(task, regnum, value) ({		\
+		(void)(task);					\
+		(void)(regnum);					\
+		(void)(value);					\
+		0;						\
+	})
+# define disable_debugreg(regs, regnum) ({			\
+		(void)(regs);					\
+		(void)(regnum);					\
+		set_debugreg(0, 7);				\
+		0;						\
+	})
+# define restore_debugreg() ({					\
+		set_debugreg(current->thread.debugreg[7], 7);	\
+		0;						\
+	})
+
+#endif /* CONFIG_NLKD */
+
+#define get_debugreg(var, register)				\
+		__asm__("movl %%db" #register ", %0"		\
+			:"=r" (var))
+
 #endif
Index: 2.6.14-nlkd/include/asm-i386/processor.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-i386/processor.h	2005-11-09 10:39:46.000000000 +0100
+++ 2.6.14-nlkd/include/asm-i386/processor.h	2005-11-07 10:20:43.000000000 +0100
@@ -461,6 +461,7 @@ struct thread_struct {
 
 #define INIT_THREAD  {							\
 	.vm86_info = NULL,						\
+	.esp0 = sizeof(init_stack) + (long)&init_stack,			\
 	.sysenter_cs = __KERNEL_CS,					\
 	.io_bitmap_ptr = NULL,						\
 }
@@ -507,17 +508,6 @@ static inline void load_esp0(struct tss_
 } 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))
-
-/*
  * Set IOPL bits in EFLAGS from given mask
  */
 static inline void set_iopl_mask(unsigned mask)

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes
  2005-11-09 14:08                   ` [PATCH 13/39] NLKD/x86-64 " Jan Beulich
@ 2005-11-09 14:13                     ` Jan Beulich
  2005-11-09 14:14                       ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Jan Beulich
  2005-11-10 13:21                       ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Andi Kleen
  2005-11-10 13:19                     ` [PATCH 13/39] NLKD/x86-64 - time adjustment Andi Kleen
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:13 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 543 bytes --]

This
- switches the INT3 handler to run on an IST stack (to cope with
  breakpoints set by a kernel debugger on places where the kernel's
  %gs base hasn't been set up, yet); the IST stack used is shared with
  the INT1 handler's
- allows nesting of INT1/INT3 handlers so that one can, with a kernel
  debugger, debug (at least) the user-mode portions of the INT1/INT3
  handling; the nesting isn't actively enabled here since a kernel-
  debugger-free kernel doesn't need it

From: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-x86_64-debug-stack.patch --]
[-- Type: application/octet-stream, Size: 8981 bytes --]

This
- switches the INT3 handler to run on an IST stack (to cope with
  breakpoints set by a kernel debugger on places where the kernel's
  %gs base hasn't been set up, yet); the IST stack used is shared with
  the INT1 handler's
- allows nesting of INT1/INT3 handlers so that one can, with a kernel
  debugger, debug (at least) the user-mode portions of the INT1/INT3
  handling; the nesting isn't actively enabled here since a kernel-
  debugger-free kernel doesn't need it

From: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/x86_64/kernel/asm-offsets.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/asm-offsets.c	2005-11-09 11:18:26.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/asm-offsets.c	2005-11-04 17:14:08.000000000 +0100
@@ -64,5 +64,10 @@ int main(void)
 	DEFINE(pbe_address, offsetof(struct pbe, address));
 	DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
 	DEFINE(pbe_next, offsetof(struct pbe, next));
+	BLANK();
+	DEFINE(EXCEPTION_STACK_SIZE, EXCEPTION_STKSZ);
+#if DEBUG_STKSZ > EXCEPTION_STKSZ
+	DEFINE(DEBUG_IST, DEBUG_STACK);
+#endif
 	return 0;
 }
Index: 2.6.14-nlkd/arch/x86_64/kernel/entry.S
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/entry.S	2005-11-09 11:18:26.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/entry.S	2005-11-09 10:45:26.000000000 +0100
@@ -685,7 +685,10 @@ END(spurious_interrupt)
 
 	/* error code is on the stack already */
 	/* handle NMI like exceptions that can happen everywhere */
-	.macro paranoidentry sym
+#ifndef DEBUG_IST
+# define DEBUG_IST 0
+#endif
+	.macro paranoidentry sym, ist=0
 	SAVE_ALL
 	cld
 	movl $1,%ebx
@@ -695,10 +698,20 @@ END(spurious_interrupt)
 	js    1f
 	swapgs
 	xorl  %ebx,%ebx
-1:	movq %rsp,%rdi
+1:
+	.if \ist
+	movq	%gs:pda_data_offset, %rbp
+	.endif
+	movq %rsp,%rdi
 	movq ORIG_RAX(%rsp),%rsi
 	movq $-1,ORIG_RAX(%rsp)
+	.if \ist
+	subq	$EXCEPTION_STACK_SIZE, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
+	.endif
 	call \sym
+	.if \ist
+	addq	$EXCEPTION_STACK_SIZE, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
+	.endif
 	cli
 	.endm
 	
@@ -924,7 +937,7 @@ KPROBE_ENTRY(debug)
  	INTR_FRAME
 	pushq $0
 	CFI_ADJUST_CFA_OFFSET 8		
-	paranoidentry do_debug
+	paranoidentry do_debug, DEBUG_IST
 	jmp paranoid_exit
 	CFI_ENDPROC
 END(debug)
@@ -981,7 +994,12 @@ paranoid_schedule:
 END(nmi)
 
 KPROBE_ENTRY(int3)
-	zeroentry do_int3	
+	INTR_FRAME
+	pushq $0
+	CFI_ADJUST_CFA_OFFSET 8
+	paranoidentry do_int3, DEBUG_IST
+	jmp paranoid_exit
+	CFI_ENDPROC
 END(int3)
 	.previous .text
 
Index: 2.6.14-nlkd/arch/x86_64/kernel/setup64.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/setup64.c	2005-11-09 11:18:26.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/setup64.c	2005-11-04 16:19:33.000000000 +0100
@@ -146,7 +146,7 @@ void pda_init(int cpu)
 	pda->irqstackptr += IRQSTACKSIZE-64;
 } 
 
-char boot_exception_stacks[N_EXCEPTION_STACKS * EXCEPTION_STKSZ] 
+char boot_exception_stacks[(N_EXCEPTION_STACKS - 2) * EXCEPTION_STKSZ + DEBUG_STKSZ]
 __attribute__((section(".bss.page_aligned")));
 
 /* May not be marked __init: used by software suspend */
@@ -243,13 +243,27 @@ void __cpuinit cpu_init (void)
 	 */
 	for (v = 0; v < N_EXCEPTION_STACKS; v++) {
 		if (cpu) {
-			estacks = (char *)__get_free_pages(GFP_ATOMIC, 
-						   EXCEPTION_STACK_ORDER);
+			static const unsigned int order[N_EXCEPTION_STACKS] = {
+				[0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
+				[DEBUG_STACK - 1] = DEBUG_STACK_ORDER
+			};
+
+			estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]);
 			if (!estacks)
 				panic("Cannot allocate exception stack %ld %d\n",
 				      v, cpu); 
 		}
-		estacks += EXCEPTION_STKSZ;
+		switch (v + 1) {
+#if DEBUG_STKSZ > EXCEPTION_STKSZ
+		case DEBUG_STACK:
+			cpu_pda[cpu].debugstack = (unsigned long)estacks;
+			estacks += DEBUG_STKSZ;
+			break;
+#endif
+		default:
+			estacks += EXCEPTION_STKSZ;
+			break;
+		}
 		t->ist[v] = (unsigned long)estacks;
 	}
 
Index: 2.6.14-nlkd/arch/x86_64/kernel/traps.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/traps.c	2005-11-09 11:18:26.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/traps.c	2005-11-09 11:19:36.000000000 +0100
@@ -121,19 +121,31 @@ int printk_address(unsigned long address
 static unsigned long *in_exception_stack(unsigned cpu, unsigned long stack,
 					unsigned *usedp, const char **idp)
 {
-	static const char ids[N_EXCEPTION_STACKS][8] = {
+	static char ids[][8] = {
 		[DEBUG_STACK - 1] = "#DB",
 		[NMI_STACK - 1] = "NMI",
 		[DOUBLEFAULT_STACK - 1] = "#DF",
 		[STACKFAULT_STACK - 1] = "#SS",
 		[MCE_STACK - 1] = "#MC",
+#if DEBUG_STKSZ > EXCEPTION_STKSZ
+		[N_EXCEPTION_STACKS ... N_EXCEPTION_STACKS + DEBUG_STKSZ / EXCEPTION_STKSZ - 2] = "#DB[?]"
+#endif
 	};
 	unsigned k;
 
 	for (k = 0; k < N_EXCEPTION_STACKS; k++) {
 		unsigned long end;
 
-		end = per_cpu(init_tss, cpu).ist[k];
+		switch (k + 1) {
+#if DEBUG_STKSZ > EXCEPTION_STKSZ
+		case DEBUG_STACK:
+			end = cpu_pda[cpu].debugstack + DEBUG_STKSZ;
+			break;
+#endif
+		default:
+			end = per_cpu(init_tss, cpu).ist[k];
+			break;
+		}
 		if (stack >= end)
 			continue;
 		if (stack >= end - EXCEPTION_STKSZ) {
@@ -143,6 +155,22 @@ static unsigned long *in_exception_stack
 			*idp = ids[k];
 			return (unsigned long *)end;
 		}
+#if DEBUG_STKSZ > EXCEPTION_STKSZ
+		if (k == DEBUG_STACK - 1 && stack >= end - DEBUG_STKSZ) {
+			unsigned j = N_EXCEPTION_STACKS - 1;
+
+			do {
+				++j;
+				end -= EXCEPTION_STKSZ;
+				ids[j][4] = '1' + (j - N_EXCEPTION_STACKS);
+			} while (stack < end - EXCEPTION_STKSZ);
+			if (*usedp & (1U << j))
+				break;
+			*usedp |= 1U << j;
+			*idp = ids[j];
+			return (unsigned long *)end;
+		}
+#endif
 	}
 	return NULL;
 }
@@ -652,6 +680,7 @@ asmlinkage void default_do_nmi(struct pt
 		io_check_error(reason, regs);
 }
 
+/* runs on IST stack. */
 asmlinkage void __kprobes do_int3(struct pt_regs * regs, long error_code)
 {
 	if (notify_die(DIE_INT3, "int3", regs, error_code, 3, SIGTRAP) == NOTIFY_STOP) {
@@ -942,7 +971,7 @@ void __init trap_init(void)
 	set_intr_gate(0,&divide_error);
 	set_intr_gate_ist(1,&debug,DEBUG_STACK);
 	set_intr_gate_ist(2,&nmi,NMI_STACK);
-	set_system_gate(3,&int3);
+	set_system_gate_ist(3,&int3,DEBUG_STACK); /* int3 can be called from all */
 	set_system_gate(4,&overflow);	/* int4 can be called from all */
 	set_intr_gate(5,&bounds);
 	set_intr_gate(6,&invalid_op);
Index: 2.6.14-nlkd/include/asm-x86_64/desc.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/desc.h	2005-11-09 11:18:27.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/desc.h	2005-11-04 16:19:34.000000000 +0100
@@ -111,6 +111,11 @@ static inline void set_system_gate(int n
 	_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, 0); 
 } 
 
+static inline void set_system_gate_ist(int nr, void *func, unsigned ist)
+{
+	_set_gate(&idt_table[nr], GATE_INTERRUPT, (unsigned long) func, 3, ist);
+}
+
 static inline void set_tssldt_descriptor(void *ptr, unsigned long tss, unsigned type, 
 					 unsigned size) 
 { 
Index: 2.6.14-nlkd/include/asm-x86_64/pda.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/pda.h	2005-11-09 11:18:27.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/pda.h	2005-11-07 10:33:42.000000000 +0100
@@ -12,6 +12,10 @@ struct x8664_pda {
 	unsigned long data_offset;	/* Per cpu data offset from linker address */
 	unsigned long kernelstack;  /* top of kernel stack for current */ 
 	unsigned long oldrsp; 	    /* user rsp for system call */
+#ifdef CONFIG_NLKD /* Better would be DEBUG_STKSZ > EXCEPTION_STKSZ, but
+                      this file can't include processor.h. */
+	unsigned long debugstack;   /* #DB/#BP stack. */
+#endif
         int irqcount;		    /* Irq nesting counter. Starts with -1 */  	
 	int cpunumber;		    /* Logical CPU number */
 	char *irqstackptr;	/* top of irqstack */
Index: 2.6.14-nlkd/include/asm-x86_64/processor.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/processor.h	2005-11-09 11:18:27.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/processor.h	2005-11-07 10:36:06.000000000 +0100
@@ -271,8 +271,10 @@ struct thread_struct {
 #define DEBUG_STACK 4 
 #define MCE_STACK 5
 #define N_EXCEPTION_STACKS 5  /* hw limit: 7 */
-#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
 #define EXCEPTION_STACK_ORDER 0 
+#define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
+#define DEBUG_STACK_ORDER EXCEPTION_STACK_ORDER
+#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
 
 #define start_thread(regs,new_rip,new_rsp) do { \
 	asm volatile("movl %0,%%fs; movl %0,%%es; movl %0,%%ds": :"r" (0));	 \

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers
  2005-11-09 14:13                     ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Jan Beulich
@ 2005-11-09 14:14                       ` Jan Beulich
  2005-11-09 14:15                         ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Jan Beulich
  2005-11-10 13:23                         ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Andi Kleen
  2005-11-10 13:21                       ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Andi Kleen
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:14 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 309 bytes --]

This adds static information about the code regions where the stack
pointer cannot be relied upon. Kernel debuggers may then use this
information to determine which stack to switch to when having a need
to switch off of namely the NMI stack.

From: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-x86_64-stack-invalid.patch --]
[-- Type: application/octet-stream, Size: 3229 bytes --]

This adds static information about the code regions where the stack
pointer cannot be relied upon. Kernel debuggers may then use this
information to determine which stack to switch to when having a need
to switch off of namely the NMI stack.

From: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/x86_64/ia32/ia32entry.S
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/ia32/ia32entry.S	2005-11-09 11:12:58.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/ia32/ia32entry.S	2005-11-04 17:18:10.000000000 +0100
@@ -60,6 +60,7 @@ ENTRY(ia32_sysenter_target)
 	CFI_REGISTER	rsp,rbp
 	swapgs
 	movq	%gs:pda_kernelstack, %rsp
+0:	STACK_INVALID ia32_sysenter_target, 0b
 	addq	$(PDA_STACKOFFSET),%rsp	
 	sti	
  	movl	%ebp,%ebp		/* zero extension */
@@ -169,6 +170,7 @@ ENTRY(ia32_cstar_target)
 	movl	%esp,%r8d
 	CFI_REGISTER	rsp,r8
 	movq	%gs:pda_kernelstack,%rsp
+0:	STACK_INVALID ia32_cstar_target, 0b
 	sti
 	SAVE_ARGS 8,1,1
 	movl 	%eax,%eax	/* zero extension */
@@ -211,8 +213,10 @@ cstar_do_call:	
 	/*CFI_REGISTER rflags,r11*/
 	movl RSP-ARGOFFSET(%rsp),%esp
 	CFI_RESTORE rsp
+0:	STACK_INVALID 0b, 1f
 	swapgs
 	sysretl
+1:
 	
 cstar_tracesys:	
 	CFI_RESTORE_STATE
Index: 2.6.14-nlkd/arch/x86_64/kernel/entry.S
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/entry.S	2005-11-09 10:45:26.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/entry.S	2005-11-07 14:56:02.000000000 +0100
@@ -190,6 +190,7 @@ ENTRY(system_call)
 	swapgs
 	movq	%rsp,%gs:pda_oldrsp 
 	movq	%gs:pda_kernelstack,%rsp
+0:	STACK_INVALID system_call, 0b
 	sti					
 	SAVE_ARGS 8,1
 	movq  %rax,ORIG_RAX-ARGOFFSET(%rsp) 
@@ -224,8 +225,10 @@ sysret_check:		
 	RESTORE_ARGS 0,-ARG_SKIP,1
 	/*CFI_REGISTER	rflags,r11*/
 	movq	%gs:pda_oldrsp,%rsp
+0:	STACK_INVALID 0b, 1f
 	swapgs
 	sysretq
+1:
 
 	/* Handle reschedules */
 	/* edx:	work, edi: workmask */	
Index: 2.6.14-nlkd/arch/x86_64/kernel/vmlinux.lds.S
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/vmlinux.lds.S	2005-11-09 11:12:58.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/vmlinux.lds.S	2005-11-04 16:19:33.000000000 +0100
@@ -30,6 +30,13 @@ SECTIONS
 
   _etext = .;			/* End of text section */
 
+#ifdef CONFIG_NLKD
+  . = ALIGN(8);			/* RSP invalid table */
+  __start___stack_invalid = .;
+  __stack_invalid : AT(ADDR(__stack_invalid) - LOAD_OFFSET) { *(__stack_invalid) }
+  __stop___stack_invalid = .;
+#endif
+
   . = ALIGN(16);		/* Exception table */
   __start___ex_table = .;
   __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET) { *(__ex_table) }
Index: 2.6.14-nlkd/include/asm-x86_64/calling.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/calling.h	2005-11-09 11:12:58.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/calling.h	2005-11-07 10:25:38.000000000 +0100
@@ -158,6 +158,17 @@
 	RESTORE_ARGS 0,\addskip
 	.endm
 
+#ifndef MODULE
+	.macro STACK_INVALID from, to
+# ifdef CONFIG_NLKD
+	.section __stack_invalid, "a", @progbits
+	.align 8
+	.quad \from, \to
+	.previous
+# endif
+ 	.endm
+#endif
+
 	.macro icebp
 	.byte 0xf1
 	.endm

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment
  2005-11-09 14:14                       ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Jan Beulich
@ 2005-11-09 14:15                         ` Jan Beulich
  2005-11-09 14:16                           ` [PATCH 21/39] NLKD/x86-64 - core adjustments Jan Beulich
  2005-11-10 13:24                           ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Andi Kleen
  2005-11-10 13:23                         ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Andi Kleen
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:15 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 410 bytes --]

Touching of the floating point state in a kernel debugger must be
NMI-safe, specifically math_state_restore() must be able to deal with
being called out of an NMI context. In order to do that reliably, the
context switch code must take care to not leave a window open where
the current task's TS_USEDFPU flag and CR0.TS could get out of sync.

From: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-x86_64-switch_to-fpu.patch --]
[-- Type: application/octet-stream, Size: 1438 bytes --]

Touching of the floating point state in a kernel debugger must be
NMI-safe, specifically math_state_restore() must be able to deal with
being called out of an NMI context. In order to do that reliably, the
context switch code must take care to not leave a window open where
the current task's TS_USEDFPU flag and CR0.TS could get out of sync.

From: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/x86_64/kernel/process.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/process.c	2005-11-09 11:20:51.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/process.c	2005-11-04 16:19:33.000000000 +0100
@@ -505,6 +505,10 @@ struct task_struct *__switch_to(struct t
 	int cpu = smp_processor_id();  
 	struct tss_struct *tss = &per_cpu(init_tss, cpu);
 
+	/* This must be done prior to examining TS_USEDFPU in the outgoing
+	   task (and perhaps setting CR0.TS), so that math_state_restore()
+	   will set TS_USEDFPU in the correct (new) task afterwards. */
+	write_pda(pcurrent, next_p);
 	unlazy_fpu(prev_p);
 
 	/*
@@ -564,11 +568,10 @@ struct task_struct *__switch_to(struct t
 	}
 
 	/* 
-	 * Switch the PDA context.
+	 * Switch the remaining PDA context.
 	 */
 	prev->userrsp = read_pda(oldrsp); 
 	write_pda(oldrsp, next->userrsp); 
-	write_pda(pcurrent, next_p); 
 	write_pda(kernelstack, (unsigned long)next_p->thread_info + THREAD_SIZE - PDA_STACKOFFSET);
 
 	/*

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 21/39] NLKD/x86-64 - core adjustments
  2005-11-09 14:15                         ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Jan Beulich
@ 2005-11-09 14:16                           ` Jan Beulich
  2005-11-10 13:24                           ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Andi Kleen
  1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:16 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 122 bytes --]

The core x86-64 NLKD adjustments to pre-existing code.

From: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: linux-2.6.14-nlkd-x86_64.patch --]
[-- Type: application/octet-stream, Size: 13111 bytes --]

The core x86-64 NLKD adjustments to pre-existing code.

From: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/x86_64/ia32/ptrace32.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/ia32/ptrace32.c	2005-11-09 11:12:50.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/ia32/ptrace32.c	2005-11-04 16:19:33.000000000 +0100
@@ -88,22 +88,32 @@ static int putreg32(struct task_struct *
 		return -EIO;
 
 	case offsetof(struct user32, u_debugreg[0]):
+		if (enable_debugreg(child, 0, val) < 0)
+			return -EBUSY;
 		child->thread.debugreg0 = val;
 		break;
 
 	case offsetof(struct user32, u_debugreg[1]):
+		if (enable_debugreg(child, 1, val) < 0)
+			return -EBUSY;
 		child->thread.debugreg1 = val;
 		break;
 
 	case offsetof(struct user32, u_debugreg[2]):
+		if (enable_debugreg(child, 2, val) < 0)
+			return -EBUSY;
 		child->thread.debugreg2 = val;
 		break;
 
 	case offsetof(struct user32, u_debugreg[3]):
+		if (enable_debugreg(child, 3, val) < 0)
+			return -EBUSY;
 		child->thread.debugreg3 = val;
 		break;
 
 	case offsetof(struct user32, u_debugreg[6]):
+		if (enable_debugreg(child, 6, val) < 0)
+			return -EBUSY;
 		child->thread.debugreg6 = val;
 		break; 
 
@@ -112,8 +122,10 @@ static int putreg32(struct task_struct *
 		/* See arch/i386/kernel/ptrace.c for an explanation of
 		 * this awkward check.*/
 		for(i=0; i<4; i++)
-			if ((0x5454 >> ((val >> (16 + 4*i)) & 0xf)) & 1)
+			if ((0x5554 >> ((val >> (16 + 4*i)) & 0xf)) & 1)
 			       return -EIO;
+		if (enable_debugreg(child, 7, val) < 0)
+			return -EBUSY;
 		child->thread.debugreg7 = val; 
 		break; 
 		    
Index: 2.6.14-nlkd/arch/x86_64/kernel/process.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/process.c	2005-11-04 16:19:33.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/process.c	2005-11-04 16:19:33.000000000 +0100
@@ -50,6 +50,7 @@
 #include <asm/desc.h>
 #include <asm/proto.h>
 #include <asm/ia32.h>
+#include <asm/debugreg.h>
 
 asmlinkage extern void ret_from_fork(void);
 
@@ -346,6 +347,10 @@ void exit_thread(void)
 		t->io_bitmap_max = 0;
 		put_cpu();
 	}
+	if (me->thread.debugreg7) {
+		enable_debugreg(me, 7, 0);
+		me->thread.debugreg7 = 0;
+	}
 }
 
 void flush_thread(void)
@@ -363,6 +368,8 @@ void flush_thread(void)
 	if (t->flags & _TIF_ABI_PENDING)
 		t->flags ^= (_TIF_ABI_PENDING | _TIF_IA32);
 
+	if (tsk->thread.debugreg7)
+		enable_debugreg(tsk, 7, 0);
 	tsk->thread.debugreg0 = 0;
 	tsk->thread.debugreg1 = 0;
 	tsk->thread.debugreg2 = 0;
@@ -477,6 +484,13 @@ int copy_thread(int nr, unsigned long cl
 		if (err) 
 			goto out;
 	}
+
+	if (me->thread.debugreg7) {
+		p->thread.debugreg7 = 0;
+		enable_debugreg(p, 7, me->thread.debugreg7);
+		p->thread.debugreg7 = me->thread.debugreg7;
+	}
+
 	err = 0;
 out:
 	if (err && p->thread.io_bitmap_ptr) {
@@ -489,7 +503,7 @@ out:
 /*
  * This special macro can be used to load a debugging register
  */
-#define loaddebug(thread,r) set_debug(thread->debugreg ## r, r)
+#define loaddebug(thread,r) set_debugreg(thread->debugreg ## r, r)
 
 /*
  *	switch_to(x,y) should switch tasks from x to y.
Index: 2.6.14-nlkd/arch/x86_64/kernel/ptrace.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/ptrace.c	2005-11-09 11:12:50.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/ptrace.c	2005-11-04 16:19:33.000000000 +0100
@@ -433,42 +433,66 @@ asmlinkage long sys_ptrace(long request,
 		/* Disallows to set a breakpoint into the vsyscall */
 		case offsetof(struct user, u_debugreg[0]):
 			if (data >= TASK_SIZE_OF(child) - dsize) break;
+			if (enable_debugreg(child, 0, data) < 0) {
+				ret = -EBUSY;
+				break;
+			}
 			child->thread.debugreg0 = data;
 			ret = 0;
 			break;
 		case offsetof(struct user, u_debugreg[1]):
 			if (data >= TASK_SIZE_OF(child) - dsize) break;
+			if (enable_debugreg(child, 1, data) < 0) {
+				ret = -EBUSY;
+				break;
+			}
 			child->thread.debugreg1 = data;
 			ret = 0;
 			break;
 		case offsetof(struct user, u_debugreg[2]):
 			if (data >= TASK_SIZE_OF(child) - dsize) break;
+			if (enable_debugreg(child, 2, data) < 0) {
+				ret = -EBUSY;
+				break;
+			}
 			child->thread.debugreg2 = data;
 			ret = 0;
 			break;
 		case offsetof(struct user, u_debugreg[3]):
 			if (data >= TASK_SIZE_OF(child) - dsize) break;
+			if (enable_debugreg(child, 3, data) < 0) {
+				ret = -EBUSY;
+				break;
+			}
 			child->thread.debugreg3 = data;
 			ret = 0;
 			break;
 		case offsetof(struct user, u_debugreg[6]):
-				  if (data >> 32)
+			if (data >> 32)
 				break; 
+			if (enable_debugreg(child, 6, data) < 0) {
+				ret = -EBUSY;
+				break;
+			}
 			child->thread.debugreg6 = data;
 			ret = 0;
 			break;
 		case offsetof(struct user, u_debugreg[7]):
 			/* See arch/i386/kernel/ptrace.c for an explanation of
 			 * this awkward check.*/
-				  data &= ~DR_CONTROL_RESERVED;
-				  for(i=0; i<4; i++)
-					  if ((0x5454 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
+			data &= ~DR_CONTROL_RESERVED;
+			for(i=0; i<4; i++)
+				if ((0x5554 >> ((data >> (16 + 4*i)) & 0xf)) & 1)
 					break;
 			if (i == 4) {
+				if (enable_debugreg(child, 7, data) < 0) {
+					ret = -EBUSY;
+					break;
+				}
 				child->thread.debugreg7 = data;
-			  ret = 0;
-		  }
-		  break;
+				ret = 0;
+			}
+			break;
 		}
 		break;
 	}
Index: 2.6.14-nlkd/arch/x86_64/kernel/setup64.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/setup64.c	2005-11-04 16:19:33.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/setup64.c	2005-11-04 16:19:33.000000000 +0100
@@ -25,6 +25,7 @@
 #include <asm/percpu.h>
 #include <asm/proto.h>
 #include <asm/sections.h>
+#include <asm/debugreg.h>
 
 char x86_boot_params[BOOT_PARAM_SIZE] __initdata = {0,};
 
@@ -289,12 +290,12 @@ void __cpuinit cpu_init (void)
 	 * Clear all 6 debug registers:
 	 */
 
-	set_debug(0UL, 0);
-	set_debug(0UL, 1);
-	set_debug(0UL, 2);
-	set_debug(0UL, 3);
-	set_debug(0UL, 6);
-	set_debug(0UL, 7);
+	set_debugreg(0UL, 0);
+	set_debugreg(0UL, 1);
+	set_debugreg(0UL, 2);
+	set_debugreg(0UL, 3);
+	set_debugreg(0UL, 6);
+	set_debugreg(0UL, 7);
 
 	fpu_init(); 
 }
Index: 2.6.14-nlkd/arch/x86_64/kernel/signal.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/signal.c	2005-11-09 11:12:50.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/signal.c	2005-11-04 16:19:33.000000000 +0100
@@ -29,6 +29,7 @@
 #include <asm/i387.h>
 #include <asm/proto.h>
 #include <asm/ia32_unistd.h>
+#include <asm/debugreg.h>
 
 /* #define DEBUG_SIG 1 */
 
@@ -439,8 +440,8 @@ int do_signal(struct pt_regs *regs, sigs
 		 * have been cleared if the watchpoint triggered
 		 * inside the kernel.
 		 */
-		if (current->thread.debugreg7)
-			set_debugreg(current->thread.debugreg7, 7);
+		if (unlikely(current->thread.debugreg7))
+			restore_debugreg();
 
 		/* Whee!  Actually deliver the signal.  */
 		return handle_signal(signr, &info, &ka, oldset, regs);
Index: 2.6.14-nlkd/arch/x86_64/kernel/suspend.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/suspend.c	2005-11-09 11:12:50.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/suspend.c	2005-11-04 17:52:58.000000000 +0100
@@ -13,6 +13,7 @@
 #include <asm/proto.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
+#include <asm/debugreg.h>
 
 struct saved_context saved_context;
 
Index: 2.6.14-nlkd/arch/x86_64/kernel/traps.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/traps.c	2005-11-09 11:19:36.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/traps.c	2005-11-07 09:33:53.000000000 +0100
@@ -784,7 +784,7 @@ asmlinkage void __kprobes do_debug(struc
 	info.si_addr = (void __user *)regs->rip;
 	force_sig_info(SIGTRAP, &info, tsk);	
 clear_dr7:
-	set_debugreg(0UL, 7);
+	disable_debugreg(regs, 7);
 	return;
 
 clear_TF_reenable:
Index: 2.6.14-nlkd/arch/x86_64/kernel/vmlinux.lds.S
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/vmlinux.lds.S	2005-11-04 16:19:33.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/vmlinux.lds.S	2005-11-04 16:19:33.000000000 +0100
@@ -144,6 +144,12 @@ SECTIONS
   __setup_start = .;
   .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET) { *(.init.setup) }
   __setup_end = .;
+#ifdef CONFIG_NLKD
+  . = ALIGN(8);
+  __start_nlkd_ext = .;
+  .nlkd.ext : AT(ADDR(.nlkd.ext) - LOAD_OFFSET) { *(.nlkd.ext) }
+  __stop_nlkd_ext = .;
+#endif
   __initcall_start = .;
   .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET) {
 	*(.initcall1.init) 
Index: 2.6.14-nlkd/include/asm-x86_64/debugreg.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/debugreg.h	2005-11-09 11:12:50.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/debugreg.h	2005-11-04 16:19:34.000000000 +0100
@@ -62,4 +62,54 @@
 #define DR_LOCAL_SLOWDOWN (0x100)   /* Local slow the pipeline */
 #define DR_GLOBAL_SLOWDOWN (0x200)  /* Global slow the pipeline */
 
+#ifdef CONFIG_NLKD
+
+# include <linux/nint.h>
+
+struct pt_regs;
+struct task_struct;
+
+# ifdef CONFIG_CDE
+#  define MAYBE_INDIR(x) x
+#  define set_debugreg(val, reg) ((void)(val), (void)(reg))
+# else
+#  define MAYBE_INDIR(x) (*x)
+extern void (*set_debugreg)(uintptr_t value, nuint_t regnum);
+# endif
+
+extern int MAYBE_INDIR(enable_debugreg)(struct task_struct *, nuint_t regnum, uintptr_t value);
+extern int MAYBE_INDIR(disable_debugreg)(struct pt_regs *, nuint_t regnum);
+extern int MAYBE_INDIR(restore_debugreg)(void);
+
+# undef MAYBE_INDIR
+
+#else
+
+# define set_debugreg(value, register)				\
+		__asm__("movq %0,%%db" #register		\
+			: /* no output */			\
+			:"r" (value))
+# define enable_debugreg(task, regnum, value) ({		\
+		(void)(task);					\
+		(void)(regnum);					\
+		(void)(value);					\
+		0;						\
+	})
+# define disable_debugreg(regs, regnum) ({			\
+		(void)(regs);					\
+		(void)(regnum);					\
+		set_debugreg(0UL, 7);				\
+		0;						\
+	})
+# define restore_debugreg() ({					\
+		set_debugreg(current->thread.debugreg7, 7);	\
+		0;						\
+	})
+
+#endif /* CONFIG_NLKD */
+
+#define get_debugreg(var, register)				\
+		__asm__("movq %%db" #register ", %0"		\
+			:"=r" (var))
+
 #endif
Index: 2.6.14-nlkd/include/asm-x86_64/processor.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/processor.h	2005-11-07 10:36:06.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/processor.h	2005-11-07 10:36:06.000000000 +0100
@@ -271,9 +271,22 @@ struct thread_struct {
 #define DEBUG_STACK 4 
 #define MCE_STACK 5
 #define N_EXCEPTION_STACKS 5  /* hw limit: 7 */
+
+#ifndef CONFIG_NLKD
 #define EXCEPTION_STACK_ORDER 0 
+#else
+#define EXCEPTION_STACK_ORDER 1
+#endif
 #define EXCEPTION_STKSZ (PAGE_SIZE << EXCEPTION_STACK_ORDER)
+
+#ifndef CONFIG_NLKD
 #define DEBUG_STACK_ORDER EXCEPTION_STACK_ORDER
+#else
+/* debug and breakpoint exceptions may nest 4 levels deep (minimum
+   requirement is 3 levels if handling exceptions from the debugger
+   should be possible, else 2 levels) */
+#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 2)
+#endif
 #define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
 
 #define start_thread(regs,new_rip,new_rsp) do { \
@@ -288,14 +301,6 @@ struct thread_struct {
 	set_fs(USER_DS);							 \
 } while(0) 
 
-#define get_debugreg(var, register)				\
-		__asm__("movq %%db" #register ", %0"		\
-			:"=r" (var))
-#define set_debugreg(value, register)			\
-		__asm__("movq %0,%%db" #register		\
-			: /* no output */			\
-			:"r" (value))
-
 struct task_struct;
 struct mm_struct;
 
Index: 2.6.14-nlkd/include/asm-x86_64/suspend.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/suspend.h	2005-11-09 11:12:50.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/suspend.h	2005-11-04 16:19:34.000000000 +0100
@@ -39,9 +39,7 @@ extern unsigned long saved_context_r12, 
 extern unsigned long saved_context_eflags;
 
 #define loaddebug(thread,register) \
-               __asm__("movq %0,%%db" #register  \
-                       : /* no output */ \
-                       :"r" ((thread)->debugreg##register))
+	set_debugreg((thread)->debugreg##register, register)
 
 extern void fix_processor_context(void);
 
Index: 2.6.14-nlkd/include/asm-x86_64/system.h
===================================================================
--- 2.6.14-nlkd.orig/include/asm-x86_64/system.h	2005-11-09 11:12:50.000000000 +0100
+++ 2.6.14-nlkd/include/asm-x86_64/system.h	2005-11-04 16:19:34.000000000 +0100
@@ -70,12 +70,6 @@ extern void load_gs_index(unsigned); 
 		".previous"			\
 		: :"r" (value), "r" (0))
 
-#define set_debug(value,register) \
-                __asm__("movq %0,%%db" #register  \
-		: /* no output */ \
-		:"r" ((unsigned long) value))
-
-
 #ifdef __KERNEL__
 struct alt_instr { 
 	__u8 *instr; 		/* original instruction */

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 22/39] NLKD - core
  2005-11-09 14:11                       ` [PATCH 16/39] NLKD - core adjustments Jan Beulich
  2005-11-09 14:11                         ` [PATCH 17/39] NLKD/i386 " Jan Beulich
@ 2005-11-09 14:18                         ` Jan Beulich
  2005-11-09 14:19                           ` [PATCH 23/39] NLKD/x86 " Jan Beulich
  2005-11-09 14:22                           ` [PATCH 26/39] NLKD - run time library Jan Beulich
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:18 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 420 bytes --]

The core NLKD additions.

With other debugging code living scattered across the (official or
external) tree(s), this tries to atb once establish a common place
for debugging code in a new debug/ directory.

Note that this depends on the i386 cmpxchg adjustments patch, which
isn't in 2.6.14, but has supposedly been merged already into 2.6.15.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd.patch --]
[-- Type: application/octet-stream, Size: 62349 bytes --]

The core NLKD additions.

With other debugging code living scattered across the (official or
external) tree(s), this tries to atb once establish a common place
for debugging code in a new debug/ directory.

Note that this depends on the i386 cmpxchg adjustments patch, which
isn't in 2.6.14, but has supposedly been merged already into 2.6.15.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/Makefile
===================================================================
--- 2.6.14-nlkd.orig/Makefile	2005-11-09 11:12:42.000000000 +0100
+++ 2.6.14-nlkd/Makefile	2005-11-04 16:20:57.000000000 +0100
@@ -592,6 +592,7 @@ export MODLIB
 
 ifeq ($(KBUILD_EXTMOD),)
 core-y		+= kernel/ mm/ fs/ ipc/ security/ crypto/
+core-$(CONFIG_DEBUG_KERNEL) += debug/
 
 vmlinux-dirs	:= $(patsubst %/,%,$(filter %/, $(init-y) $(init-m) \
 		     $(core-y) $(core-m) $(drivers-y) $(drivers-m) \
Index: 2.6.14-nlkd/debug/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/Kconfig	2005-11-07 14:01:48.000000000 +0100
@@ -0,0 +1,22 @@
+choice
+	prompt "Kernel debugger"
+	optional
+	depends on DEBUG_KERNEL
+	---help---
+	  Kernel debuggers contain commands which allow memory to be examined,
+	  instructions to be disassembled and breakpoints to be set.
+
+	  If unsure, say N.
+
+config NLKD
+	bool "Novell Linux Kernel Debugger"
+	depends on DEBUG_KERNEL
+	depends on (X86_CMOVE && X86_CMPXCHG64 && X86_TSC) || X86_64
+	depends on !X86 || !OPROFILE
+	---help---
+	  This option provides a kernel debugger framework.  Sub-component
+	  selection will follow later.
+
+endchoice
+
+source "debug/nlkd/Kconfig"
Index: 2.6.14-nlkd/debug/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/Makefile	2005-11-04 14:15:23.000000000 +0100
@@ -0,0 +1 @@
+obj-$(CONFIG_NLKD)            += nlkd/
Index: 2.6.14-nlkd/debug/nlkd/Kconfig
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/Kconfig	2005-11-04 09:52:36.000000000 +0100
@@ -0,0 +1,71 @@
+#*****************************************************************************
+#*
+#*   File Name:      Kconfig
+#*   Created by:     Jan Beulich
+#*   %version:       5 %
+#*   %derived_by:    jbeulich %
+#*   %date_modified: Thu Nov 03 04:12:25 2005 %
+#*
+#*****************************************************************************
+#*****************************************************************************
+#*                                                                           *
+#* Copyright (c) 2004-2005 Novell, Inc. All Rights Reserved.                 *
+#*                                                                           *
+#* This program is free software; you can redistribute it and/or             *
+#* modify it under the terms of version 2 of the GNU General Public License  *
+#* as published by the Free Software Foundation.                             *
+#*                                                                           *
+#* This program is distributed in the hope that it will be useful,           *
+#* but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+#* GNU General Public License for more details.                              *
+#*                                                                           *
+#* You should have received a copy of the GNU General Public License         *
+#* along with this program; if not, contact Novell, Inc.                     *
+#*                                                                           *
+#* To contact Novell about this file by physical or electronic mail,         *
+#* you may find current contact information at www.novell.com.               *
+#*                                                                           *
+#*****************************************************************************
+#*****************************************************************************
+#*
+#*	File Description:
+#*
+#*****************************************************************************
+
+config DEBUGRTL
+	tristate
+	default n
+
+config CDE
+	tristate "Core Debug Engine" #todo if ???
+	depends on NLKD
+	select DEBUGRTL
+	default NLKD
+	---help---
+	  This enables NLKD's core component.  Front-end (agent) selection
+	  will follow later.
+
+	  If compiled as a module, the module will be called cde.
+
+config CDA
+	tristate "Console Debug Agent"
+	depends on CDE && (VGA_CONSOLE || FRAMEBUFFER_CONSOLE) && SERIO_I8042
+	default CDE
+	---help---
+	  This option provides a console based kernel debugger front-end.
+	  See Documentation/cda.txt for additional information.
+
+	  To compile this agent as a module, choose M here: the
+	  module will be called cda.
+
+config RDA
+	tristate "Remote Debug Agent (EXPERIMENTAL)"
+	depends on CDE && EXPERIMENTAL
+	default n
+	---help---
+	  This option provides a remote kernel debugger interface supporting
+	  gdb's protocol.
+
+	  To compile this agent as a module, choose M here: the
+	  module will be called rda.
Index: 2.6.14-nlkd/debug/nlkd/Makefile
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/Makefile	2005-11-09 10:50:39.000000000 +0100
@@ -0,0 +1,108 @@
+#*****************************************************************************
+#*
+#*   File Name:      Makefile
+#*   Created by:     Jan Beulich
+#*   %version:       12 %
+#*   %derived_by:    jbeulich %
+#*   %date_modified: Thu Nov 03 04:12:54 2005 %
+#*
+#*****************************************************************************
+#*****************************************************************************
+#*                                                                           *
+#* Copyright (c) 2004-2005 Novell, Inc. All Rights Reserved.                 *
+#*                                                                           *
+#* This program is free software; you can redistribute it and/or             *
+#* modify it under the terms of version 2 of the GNU General Public License  *
+#* as published by the Free Software Foundation.                             *
+#*                                                                           *
+#* This program is distributed in the hope that it will be useful,           *
+#* but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+#* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+#* GNU General Public License for more details.                              *
+#*                                                                           *
+#* You should have received a copy of the GNU General Public License         *
+#* along with this program; if not, contact Novell, Inc.                     *
+#*                                                                           *
+#* To contact Novell about this file by physical or electronic mail,         *
+#* you may find current contact information at www.novell.com.               *
+#*                                                                           *
+#*****************************************************************************
+#*****************************************************************************
+#*
+#*	File Description:
+#*
+#*****************************************************************************
+
+ifeq ($(CONFIG_DEBUGRTL),y)
+dbg   := obj
+endif
+ifeq ($(CONFIG_DEBUGRTL),m)
+dbg   := debugrtl
+obj-m := debugrtl.o
+dbg-y :=
+endif
+
+ifeq ($(CONFIG_CDE),y)
+cde   := obj
+endif
+ifeq ($(CONFIG_CDE),m)
+cde   := cde
+obj-m := cde.o
+cde-y :=
+endif
+
+arch-$(CONFIG_X86)        := $(if $(CONFIG_X86_64),AMD64,IA32)
+arch-$(CONFIG_IA64)       := IA64
+export arch-y
+
+obj-y                     := nlkd.o nlkd$(arch-y).o
+$(dbg)-$(CONFIG_DEBUGRTL) += dbgutil.o dbg$(arch-y).o
+$(cde)-y                  += cde$(arch-y).o cdeext.o cdefocus.o cdemain.o \
+                             cde$(arch-y)lock.o cdemem.o cdestatemach.o \
+                             cdesym.o $(if $(CONFIG_IA64),,cdeunwind.o) \
+                             cdeutil.o cde$(arch-y)util.o
+$(cde)-$(CONFIG_MODULES)  += cde_syms.o
+$(cde)-$(CONFIG_SMP)      += cderendezvous.o cderpc.o
+$(cde)-$(CONFIG_EFI)      += cdeefi.o
+$(cde)-$(CONFIG_X86)      += cdeX86brkp.o
+$(cde)-$(CONFIG_IA64)     += cdeIA64brkp.o
+
+obj-$(CONFIG_CDA)         += cda/
+obj-$(CONFIG_RDA)         += rda/
+
+EXTRA_AFLAGS := -Wa,--strip-local-absolute
+
+# Need a version of 'as' that supports various features not present or broken
+# in older binutils versions. But since one can't tell gcc what assembler
+# binary to use we have to use another compiler driver that will find the
+# right assembler if the default one doesn't fit our needs. (Note that -Wa,-Z
+# below is necessary because otherwise, up to version 2.15, it will [try to]
+# unlink /dev/null [and succeed at least when run as root]).
+
+assembler_test_body-y := .altmacro;
+assembler_test_body-y += .macro .xyz; .endm; .xyz;
+assembler_test_body-y += .struct; .previous;
+ifneq ($(CONFIG_IA64),y)
+assembler_test_body-$(CONFIG_UNWIND_INFO) += .cfi_startproc;
+ifeq ($(CONFIG_X86),y)
+assembler_test_body-$(CONFIG_UNWIND_INFO) += .cfi_rel_offset $(if $(CONFIG_X86_64),r,e)flags, 0;
+endif
+assembler_test_body-$(CONFIG_UNWIND_INFO) += .cfi_endproc;
+endif
+assembler_test_body-$(CONFIG_X86) += .intel_syntax noprefix;
+assembler_test_body-$(CONFIG_X86) += .bss; .previous;
+assembler_test_body-$(CONFIG_X86) += push (1 shl 1) or not (1 shr 1) mod (1 and 1 xor 2);
+assembler_test_body-$(CONFIG_X86) += .equiv dword, 4; .equiv reg, eax; lea reg, [reg*dword];
+
+assembler_test = $(shell echo '$(assembler_test_body-y)' \
+                   | $(1) -c -o /dev/null -Wa,-Z -xassembler-with-cpp - 2>&1 >/dev/null)
+
+ifneq ($(call assembler_test,$(CC)),)
+CCx := $(shell echo '$(CC)' | sed 's,\(^\|[[:space:]]\)\([^=[:space:]]\+\)\([[:space:]]\|$$\),\1\2x\3,')
+ifneq ($(shell which $(filter-out -%,$(CCx)) 2>/dev/null | grep '/$(CCx)$$'),)
+ifneq ($(call assembler_test,$(CCx)),)
+CCx := echo "Assembler update needed" >&2 && /bin/false
+endif
+endif
+override cmd_as_o_S   = $(CCx) $(a_flags) -c -o $@ $<
+endif
Index: 2.6.14-nlkd/debug/nlkd/nlkd.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/nlkd.c	2005-11-03 12:23:43.000000000 +0100
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ *
+ *   File Name:      nlkd.c
+ *   Created by:     Jan Beulich
+ *   %version:       4 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 04:23:30 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#include <linux/module.h>
+#include <linux/nlkd.h>
+#include <asm/fta-frame.h>
+#include <asm/fta-type.h>
+#include <asm/segment.h>
+#include "nlkd.h"
+
+#if defined(_M_IA64) || defined(__ia64__)
+# include "nlkdIA64.h"
+#elif defined(_M_IX86) || defined(__i386__)
+# include "nlkdIA32.h"
+#elif defined(_M_AMD64) || defined(__x86_64__)
+# include "nlkdAMD64.h"
+#endif
+
+EXPORT_SYMBOL(nlkdAssert);
+EXPORT_SYMBOL(nlkdDebugEvent);
+EXPORT_SYMBOL(nlkdEnterDebugger);
+EXPORT_SYMBOL(nlkdPanic);
+
+#ifdef CONFIG_NLKD_FTA
+struct notifier_block *nlkd_keypress_chain = NULL;
+EXPORT_SYMBOL(nlkd_keypress_chain);
+#endif
+
+volatile int nlkdAgentCount = -1;
+#ifndef CONFIG_CDE
+EXPORT_SYMBOL(nlkdAgentCount);
+const struct nlkdBPXface_s*nlkdBPXface = NULL;
+EXPORT_SYMBOL(nlkdBPXface);
+#endif
+
+#ifndef CONFIG_CDE
+# include <asm/debugreg.h>
+void (*set_debugreg)(uintptr_t value, nuint_t regnum) = _set_debugreg;
+EXPORT_SYMBOL(set_debugreg);
+static int _enable_debugreg(struct task_struct *task, nuint_t regnum, uintptr_t value) {}
+int (*enable_debugreg)(struct task_struct *, nuint_t, uintptr_t) = _enable_debugreg;
+EXPORT_SYMBOL(enable_debugreg);
+int (*disable_debugreg)(struct pt_regs *, nuint_t) = _disable_debugreg;
+EXPORT_SYMBOL(disable_debugreg);
+int (*restore_debugreg)(void) = _restore_debugreg;
+EXPORT_SYMBOL(restore_debugreg);
+#endif
+
+#if defined(CONFIG_X86)
+# ifdef CONFIG_X86_64
+#  define PLT(x) AMD64_##x
+#  define PC rip
+# else
+#  define PLT(x) IA32_##x
+#  define PC eip
+# endif
+# define TYPE PLT(BREAKPOINT)
+# define SUBTYPE eax
+# define TARGET _nlkdEnterDebuggerInstruction_
+# define EXTRA FRAME_PTREGS(frame, cs) == __KERNEL_CS
+# define IPI_TYPE PLT(NMI)
+# define IPI_SUBTYPE cr2
+#elif defined(CONFIG_IA64)
+# define PC iip
+# define TYPE IA64_BREAKFLT
+# define SUBTYPE r8
+# define TARGET _nlkdEnterDebuggerBundle_
+# define EXTRA frame->iim == BREAK_ENTER_DEBUGGER
+# define IPI_TYPE PLT(NMI)
+# define IPI_SUBTYPE iim
+#endif
+
+int nlkdIsDebugEvent(const struct ftaInterruptionCtx_s*frame) {
+	extern const char TARGET[];
+
+	return frame->type == TYPE
+	       && FRAME_PTREGS(frame, PC) == (uintptr_t)TARGET
+	       && EXTRA;
+}
+EXPORT_SYMBOL(nlkdIsDebugEvent);
+
+#ifndef CONFIG_NLKD_FTA
+void nlkdSetDebugEventType(struct ftaInterruptionCtx_s*frame) {
+	if(!frame->sub_type) {
+		if(nlkdIsDebugEvent(frame))
+			frame->sub_type = FRAME_PTREGS(frame, SUBTYPE);
+		else if(frame->type == IPI_TYPE) {
+			frame->sub_type = frame->IPI_SUBTYPE;
+			frame->IPI_SUBTYPE = 0;
+		}
+	}
+}
+EXPORT_SYMBOL(nlkdSetDebugEventType);
+#endif
+
+#undef IPI_TYPE
+#undef IPI_SUBTYPE
+#undef EXTRA
+#undef TARGET
+#undef SUBTYPE
+#undef TYPE
+#undef PC
+#undef PLT
+
+void nlkd_init() {
+	extern nlkdExtension_t __start_nlkd_ext[], __stop_nlkd_ext[];
+	nlkdExtension_t*ext;
+
+	for(ext = __start_nlkd_ext; ext < __stop_nlkd_ext; ++ext) {
+		LSTATUS status = nlkdExtRegister(ext->id,
+		                                 ext->handler,
+		                                 ext->handlerContext,
+		                                 *ext->pModuleId,
+		                                 ext->description,
+		                                 ext->flags);
+		if(status != LSTATUS_SUCCESS)
+			printk(KERN_WARNING "Registration of %s debug extension failed (%08"NPRIX")\n",
+			       ext->id,
+			       status);
+	}
+	cde_init();
+}
+
+void nlkd_init_done() {
+	cde_init_done();
+}
+
+#define NLKD
+#include "cdeext.c"
Index: 2.6.14-nlkd/debug/nlkd/nlkd.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/nlkd.h	2005-10-07 17:18:18.000000000 +0200
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ *
+ *   File Name:      nlkd.h
+ *   Created by:     Jan Beulich
+ *   %version:       2 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Fri Oct 07 09:18:08 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+extern volatile int nlkdAgentCount;
+
+#ifdef CONFIG_CDE
+
+void cde_init(void);
+void cde_init_done(void);
+
+#else
+
+# define cde_init()
+# define cde_init_done()
+
+#endif
Index: 2.6.14-nlkd/include/linux/fta.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/linux/fta.h	2005-11-03 12:03:37.000000000 +0100
@@ -0,0 +1,261 @@
+/*****************************************************************************
+ *
+ *   File Name:      fta.h
+ *   Created by:     Jan Beulich
+ *   %version:       12 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 04:03:24 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2004-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+#ifndef _LINUX_FTA_H
+# define _LINUX_FTA_H
+
+# include <linux/config.h>
+# include <asm/fta-type.h>
+
+typedef enum ftaInterruptionId_e ftaInterruptionId_t;
+typedef struct ftaInterruptionCtx_s ftaFullInterruptionCtx_t;
+
+# ifdef CONFIG_NLKD_FTA
+#  include <linux/linkage.h>
+#  include <linux/lstatus.h>
+#  include <linux/module-id.h>
+#  include <linux/nint.h>
+
+/* --------------------------------------------------------------------------- */
+/* LSTATUS Defines for                                                         */
+/* ftaFaultInterruption..., ftaTrapInterruption... and ftaAbortInterruption... */
+/* --------------------------------------------------------------------------- */
+
+#  define LSTATUS_FTA_HANDLED              MAKE_LSTATUS(FTA, SUCCESS, 0)
+#  define LSTATUS_FTA_NOT_HANDLED          MAKE_LSTATUS(FTA, INFORMATION, 0x0100)
+#  define LSTATUS_FTA_ID_INVALID           MAKE_LSTATUS(FTA, ERROR, 0x0100)
+#  define LSTATUS_FTA_ROUTINE_ADDR_INVALID MAKE_LSTATUS(FTA, ERROR, 0x0101)
+#  define LSTATUS_FTA_STAGE_INVALID        MAKE_LSTATUS(FTA, ERROR, 0x0102)
+#  define LSTATUS_FTA_STAGE_NOT_AVAILABLE  MAKE_LSTATUS(FTA, ERROR, 0x0103)
+#  define LSTATUS_FTA_TAG_ALLOC_FAILURE    MAKE_LSTATUS(FTA, ERROR, 0x0104)
+#  define LSTATUS_FTA_SIGNATURE_INVALID    MAKE_LSTATUS(FTA, ERROR, 0x0105)
+#  define LSTATUS_FTA_TAG_INVALID          MAKE_LSTATUS(FTA, ERROR, 0x0106)
+
+typedef enum ftaInterruptionId_e fta_id_t;
+struct pt_regs;
+
+/*
+ * ftaInterruptionTag_t
+ *
+ * ftaInterruptionTag_t is used as a handle.  When ftaInterruptionSetup()
+ * is called it is passed the address of a variable type of ftaInterruptionTag_t.
+ *
+ * When ftaInterruptionSetup() successfully completes ftaInterruptionTag_t
+ * contains a valid value that can should be used as a parameter when
+ * ftaInterruptionClear() is called.
+ */
+typedef struct ftaInterruption *ftaInterruptionTag_t, *fta_tag_t;
+
+/*
+ * Special flags for this interruption handler.
+ */
+typedef uint64_t	ftaInterruptionFlags_t;
+
+/*
+ * ftaInterruptionStage_t
+ *
+ * ftaInterruptionStage_t is used as a parameter to ftaTrapInterruptionSetup(),
+ * ftaFaultInterruptionSetup() and ftaAbortInterruptionSetup().
+ *
+ * It is used to indicate during which stage the interruption handler should
+ * be called.  For each interruption there may be a specific order in which
+ * different handlers should be called.  The callout order is referred to as
+ * the stage and may be interruption specific.  Providing for a stage
+ * definition for handlers allows the infrastructure to prioritize the callout
+ * order of handlers by stage type.
+ *
+ * Interruption stages as defined as follows:
+ *
+ * FTA_INTERRUPTION_NOTIFIER_ENTRY
+ *     Frame Modification: Not Allowed
+ *     Number Of Handlers: Multiple
+ *            Other Notes: Entry notifier slots are provided for debug purposes.
+ *                         The handler is invoked just after the frame has been
+ *                         saved but before any other handlers are called.
+ *                         These handlers may examine the frame but may not
+ *                         modify it in any way whatsoever.  Notifiers are
+ *                         maintained on a linked list and are called on a
+ *                         first linked, first called basis.
+ *
+ * FTA_INTERRUPTION_NOTIFIER_EXIT
+ *     Frame Modification: Not Allowed
+ *     Number Of Handlers: Multiple
+ *            Other Notes: Exit notifier slots are provided for debug purposes.
+ *                         The handler is invoked after other handlers have
+ *                         been called and just before the stack frame is
+ *                         restored prior to a return from interruption.
+ *                         These handlers may examine the frame but may not
+ *                         modify it in any way whatsoever.  Notifiers are
+ *                         maintained on a linked list and are called on a
+ *                         first linked, first called basis.
+ *
+ * FTA_INTERRUPTION_HANDLER_DEFAULT
+ *     Frame Modification: Allowed
+ *     Number Of Handlers: One
+ *            Other Notes: This is the OS default handler for the interruption.
+ *                         This handler slot is reserved for OS kernel use only.
+ *                         An attempt to register for this handler slot will fail
+ *                         until the previous handler has been cleared.
+ *
+ * FTA_INTERRUPTION_HANDLER_GENERAL_PURPOSE
+ *     Frame Modification: Allowed
+ *     Number Of Handlers: Multiple
+ *            Other Notes: General purpose handlers are maintained on a
+ *                         linked list and are called on a first linked, first
+ *                         called basis.  When a handler of this type claims
+ *                         the interruption has been handled by its return
+ *                         status other general purpose handlers will not be
+ *                         invoked.
+ *
+ * FTA_INTERRUPTION_HANDLER_HEALTH_MONITOR
+ *     Frame Modification: Not Allowed
+ *     Number Of Handlers: One
+ *            Other Notes: The health driver may perform such actions as
+ *                         monitoring the health of the system or logging
+ *                         the cause of critical errors to NVRAM prior to a
+ *                         system crash.  A health handler may view the contents
+ *                         of the frame but should not modify the frame contents.
+ *                         If modification of the frame is required a separate
+ *                         general purpose handler should be registered.
+ *                         An attempt to register for this handler slot will fail
+ *                         until the previous handler has been cleared.
+ *
+ * FTA_INTERRUPTION_HANDLER_APPLICATION_DEBUGGER
+ *     Frame Modification: Allowed
+ *     Number Of Handlers: Multiple
+ *            Other Notes: An application level debugger registration will
+ *                         take precedence over kernel level debuggers.
+ *
+ * FTA_INTERRUPTION_HANDLER_CORE_DEBUG_ENGINE
+ *     Frame Modification: Allowed
+ *     Number Of Handlers: One
+ *            Other Notes: The intention here is to allow the CDE an early peek at the
+ *                         the frame to recover from internally generated interruptions.
+ *
+ * FTA_INTERRUPTION_PATCH_REPLACEMENT
+ *     Frame Modification: Allowed
+ *     Number Of Handlers: One
+ *            Other Notes: A patch replacement handler provides a mechanism whereby
+ *                         the infrastructure for a given interruption may be
+ *                         completely replaced.  The writer of this handler should
+ *                         be intimately familiar with the requirements of the
+ *                         interruption event.  This slot is provided as a means
+ *                         field replacement of the interruption handling infrastructure
+ *                         may be replaced.  Please see ftaGetInterruptionHandlers()
+ *                         for more information on how to find and call registered
+ *                         handlers for the given interruption ID.
+ *                         An attempt to register for this handler slot will fail
+ *                         until the previous handler has been cleared.
+ */
+typedef enum {
+	FTA_INTERRUPTION_NOTIFIER_ENTRY,
+	FTA_INTERRUPTION_NOTIFIER_EXIT,
+	FTA_INTERRUPTION_HANDLER_DEFAULT,
+	FTA_INTERRUPTION_HANDLER_GENERAL_PURPOSE,
+	FTA_INTERRUPTION_HANDLER_HEALTH_MONITOR,
+	FTA_INTERRUPTION_HANDLER_APPLICATION_DEBUGGER,
+	FTA_INTERRUPTION_HANDLER_CORE_DEBUG_ENGINE,
+	FTA_INTERRUPTION_PATCH_REPLACEMENT
+} ftaInterruptionStage_t;
+
+typedef enum {
+	FTA_NOTIFIER_ENTRY = FTA_INTERRUPTION_NOTIFIER_ENTRY,
+	FTA_NOTIFIER_EXIT = FTA_INTERRUPTION_NOTIFIER_EXIT,
+	FTA_HANDLER_DEFAULT = FTA_INTERRUPTION_HANDLER_DEFAULT,
+	FTA_HANDLER_GENERAL_PURPOSE = FTA_INTERRUPTION_HANDLER_GENERAL_PURPOSE,
+	FTA_HANDLER_HEALTH_MONITOR = FTA_INTERRUPTION_HANDLER_HEALTH_MONITOR,
+	FTA_HANDLER_APPLICATION_DEBUGGER = FTA_INTERRUPTION_HANDLER_APPLICATION_DEBUGGER
+} fta_stage_t;
+
+typedef enum {
+	fta_no_async,
+	fta_async_breakpoints,
+	fta_async_interrupts,
+	fta_async_preemption
+} fta_async_level_t;
+
+#  ifndef MODULE
+void asmlinkage ftaAbandonFrame(const ftaFullInterruptionCtx_t *);
+#  endif
+
+#  ifndef FTA_EXPORT
+#   define FTA_EXPORT(type, name, ...) type name(__VA_ARGS__)
+#  endif
+
+# else /* CONFIG_NLKD_FTA */
+#  undef FTA_EXPORT
+# endif /* CONFIG_NLKD_FTA */
+#endif /* _LINUX_FTA_H */
+
+#ifdef FTA_EXPORT
+# include <asm/fta.h>
+
+FTA_EXPORT(LSTATUS, ftaInterruptionSetup,
+	ftaInterruptionId_t,
+	LSTATUS (*)(void *, ftaFullInterruptionCtx_t *),
+	void *,
+	ftaInterruptionFlags_t,
+	ftaInterruptionStage_t,
+	moduleId_t,
+	ftaInterruptionTag_t *);
+FTA_EXPORT(LSTATUS, ftaInterruptionClear, ftaInterruptionTag_t);
+
+FTA_EXPORT(fta_async_level_t, ftaEnable,
+	ftaFullInterruptionCtx_t *,
+	fta_async_level_t);
+FTA_EXPORT(const char*, ftaGetInterruptionName,
+	const ftaFullInterruptionCtx_t *);
+FTA_EXPORT(void, ftaRestore, ftaFullInterruptionCtx_t *, fta_async_level_t);
+
+FTA_EXPORT(int, fta_register_handler,
+	fta_id_t,
+	int(*)(struct pt_regs *, void *),
+	void *,
+	unsigned long flags,
+	fta_stage_t,
+	moduleId_t,
+	fta_tag_t *);
+FTA_EXPORT(int, fta_deregister_handler, fta_tag_t);
+
+FTA_EXPORT(fta_id_t, fta_type, const struct pt_regs *);
+FTA_EXPORT(int, fta_subtype, const struct pt_regs *);
+FTA_EXPORT(void, fta_subtype_set, struct pt_regs *, int);
+FTA_EXPORT(int, fta_from_kernel, const struct pt_regs *);
+
+FTA_EXPORT(void, fta_abandon, const struct pt_regs *);
+FTA_EXPORT(fta_async_level_t, fta_enable, struct pt_regs *, fta_async_level_t);
+FTA_EXPORT(void, fta_restore, struct pt_regs *, fta_async_level_t);
+
+# undef FTA_EXPORT
+#endif /* FTA_EXPORT */
Index: 2.6.14-nlkd/include/linux/lstatus.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/linux/lstatus.h	2005-06-27 12:49:22.000000000 +0200
@@ -0,0 +1,241 @@
+/*****************************************************************************
+ *
+ *   File Name:      lstatus.h
+ *   Created by:     Clyde Griffin
+ *   Date created:   11/1/1998
+ *
+ *   %version:       6 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 04:49:11 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1998-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#ifndef _LINUX_LSTATUS_H
+#define _LINUX_LSTATUS_H
+
+#include <linux/config.h>
+#ifdef __ASSEMBLY__
+# define NUINT_C(v) v
+#else
+# include <linux/nint.h>
+#endif
+
+/*
+ *    The purpose of this file is to provide a common format and encoding
+ *    scheme for API status codes.
+ *    The status classification and naming conventions used in this file are
+ *    as follows.
+ *
+ *    LSTATUS is defined as a native unsigned return code. There are four
+ *    parts to the status.  The low bits contain the status code.  The next
+ *    portion contains the sybsystem identifier, followed by an optional
+ *    subsystem specific unique identifier.  The top bits
+ *    The unique ID may be used in a number of ways and is subsystem
+ *    specific.  It is optional and should be zero if not used.
+ *
+ *    The LSTATUS return code may be viewed as a union defined as follows:
+ *
+ *    typedef union {
+ *    	struct {
+ *    		nuint_t	status:N1;
+ *    		nuint_t	subsystem:N2;
+ *    		nuint_t	uniqueId:N3;
+ *    		nuint_t	category:N4;
+ *    	} fields;
+ *    	LSTATUS status;
+ *    } lStatus_t;
+ *
+ *    Each major subsystem within may allocate a range of status codes by
+ *    adding a #define to the classification section below.
+ *    The convention allows for 255/65535 subsystems in the system with each
+ *    subsystem being allowed to define up to as many as 4095/65535 unique
+ *    status codes or errors. This should be adequate.
+ *
+ *    The first subsystem known as LSTATUS_ is a general purpose
+ *    classification to be used for smaller subsystems, components or
+ *    stand alone APIs which do not clearly fit into a larger grouping.
+ *    Status code additions to the general area should be carefully chosen
+ *    and somewhat generic in flavor as another developer of a different
+ *    component may also use that defined status/error code.
+ *
+ *    In general you are encouraged to create unique classifications
+ *    for large and middle sized subcomponents of the kernel.
+ *
+ *    Status code return types are 32/64 bits in size.
+ *
+ *    Nano kernel subsystems are numbered using bits 31:16.
+ *
+ *    Status codes within each subsystem are defined using bits 15:0.
+ *
+ *    The status codes 0-255 in each {category,subsystem} must be identical
+ *    to those in the generic subsystem.  The first unique status code in any
+ *    given subsystem should not be less than 256.  This convention will
+ *    allow us to become familiar with return codes < 256 regardless of what
+ *    subsystem the status code came from.
+ *
+ *    We do not expect to have more that 256 generic status codes.
+ *
+ *    Specific status definitions within a general classification may be
+ *    defined in another header file more specific to the subcomponent.
+ *    However, general subsystem classifications must be defined in this
+ *    file and listed in numeric order.  Status code definitions in the generic
+ *    classification, LSTATUS_, must also be listed in this file.
+ *
+ *    APIs returning status codes defined by this file must be declared to
+ *    return LSTATUS.  LSTATUS is defined as a nuint_t.
+ *
+ *
+ * Naming:
+ * 	 For the purposes of providing a common look and feel, and to avoid
+ *    naming conflicts the defined names of each status code shall follow the
+ *    rules below.
+ *
+ * 	  1) The status code will be described in all capital letters with the under
+ *        score chararacter separating descriptive words.
+ *
+ * 	  2) The status code will be prefixed with the classification name.
+ *        Example:  Status codes in the SCHED subclassification will begin
+ *        with LSTATUS_SCHED.
+ *
+ * 	  3) The descriptive portion of the status code definition will follow the
+ *        the general classification.
+ *        Example: LSTATUS_SCHED_PARAMETER_INVALID.
+ *
+ */
+
+#if defined(CONFIG_X86_64) || !defined(CONFIG_64BIT)
+# define LSTATUS_WIDTH_STATUS		12
+# define LSTATUS_WIDTH_SUBSYSTEM	8
+# define LSTATUS_WIDTH_UNIQUEID	9
+# define LSTATUS_WIDTH_CATEGORY	3
+#else
+# define LSTATUS_WIDTH_STATUS		16
+# define LSTATUS_WIDTH_SUBSYSTEM	16
+# define LSTATUS_WIDTH_UNIQUEID	28
+# define LSTATUS_WIDTH_CATEGORY	4
+#endif
+
+#ifndef __ASSEMBLY__
+/* ----------------------------------------------------------------------- */
+/*                                                                         */
+/* ----------------------------------------------------------------------- */
+/*
+ *
+ * Use LSTATUS when declaring APIs that return status code definitions defined
+ * using the conventions outlined in this file.
+ *
+ * Example: LSTATUS foo(void);
+ */
+typedef nuint_t LSTATUS;
+
+typedef union {
+	struct {
+		nuint_t status:LSTATUS_WIDTH_STATUS;
+		nuint_t subsystem:LSTATUS_WIDTH_SUBSYSTEM;
+		nuint_t uniqueId:LSTATUS_WIDTH_UNIQUEID;
+		nuint_t category:LSTATUS_WIDTH_CATEGORY;
+	} fields;
+	LSTATUS status;
+} lStatus_t;
+
+typedef struct { int _:sizeof(lStatus_t) <= sizeof(LSTATUS); } lStatus_Size_Assert;
+
+#endif /* __ASSEMBLY__ */
+
+/* ----------------------------------------------------------------------- */
+/*                                                                         */
+/* ----------------------------------------------------------------------- */
+/*
+ * Status code category classifications.
+ */
+#define LSTATUS_CATEGORY_SUCCESS       NUINT_C(0)
+#define LSTATUS_CATEGORY_INFORMATION   NUINT_C(1)
+#define LSTATUS_CATEGORY_NOTICE        NUINT_C(2)
+#define LSTATUS_CATEGORY_WARNING       NUINT_C(3)
+#define LSTATUS_CATEGORY_ERROR         ((NUINT_C(1) << LSTATUS_WIDTH_CATEGORY) - 4)
+#define LSTATUS_CATEGORY_FATAL         ((NUINT_C(1) << LSTATUS_WIDTH_CATEGORY) - 1)
+
+/* ----------------------------------------------------------------------- */
+/*                                                                         */
+/* ----------------------------------------------------------------------- */
+/*
+ * Status code subsystem classifications.
+ */
+#define LSTATUS_SUBSYS_                                          0x0000
+#define LSTATUS_SUBSYS_SCHED                                     0x0001
+#define LSTATUS_SUBSYS_MEMORY                                    0x0002
+#define LSTATUS_SUBSYS_MMU                                       0x0003
+#define LSTATUS_SUBSYS_INTR                                      0x0004
+#define LSTATUS_SUBSYS_FTA                                       0x0005
+#define LSTATUS_SUBSYS_CPU                                       0x0006
+#define LSTATUS_SUBSYS_RESOURCE                                  0x0007
+#define LSTATUS_SUBSYS_CONSOLE                                   0x0008
+#define LSTATUS_SUBSYS_CIOS                                      0x0009
+#define LSTATUS_SUBSYS_PSM                                       0x000A
+#define LSTATUS_SUBSYS_TIMEOUT                                   0x000B
+
+
+/* ----------------------------------------------------------------------- */
+/*                                                                         */
+/* ----------------------------------------------------------------------- */
+/*
+ * LSTATUS construction.
+ */
+#define MAKE_LSTATUS(sub, cat, code)                         \
+	(((((LSTATUS_CATEGORY_##cat << LSTATUS_WIDTH_UNIQUEID)  \
+	    << LSTATUS_WIDTH_SUBSYSTEM) | LSTATUS_SUBSYS_##sub) \
+	  << LSTATUS_WIDTH_STATUS) | (code))
+#define MAKE_LSTATUS_UNIQUE(sub, cat, uid, code)             \
+	((((((LSTATUS_CATEGORY_##cat                            \
+	      << LSTATUS_WIDTH_UNIQUEID) | (uid))               \
+	    << LSTATUS_WIDTH_SUBSYSTEM) | LSTATUS_SUBSYS_##sub) \
+	  << LSTATUS_WIDTH_STATUS) | (code))
+
+/* ----------------------------------------------------------------------- */
+/*                                                                         */
+/* ----------------------------------------------------------------------- */
+/*
+ * LSTATUS_ classification.
+ *
+ * LSTATUS_ is a generic classification.  These definitions may be used
+ * by small subsystems or stand alone APIs which do not require status
+ * code definitions within a unique range.
+ */
+#define LSTATUS_SUCCESS                       MAKE_LSTATUS(, SUCCESS, 0x0000)
+#define LSTATUS_DEFERRED                      MAKE_LSTATUS(, SUCCESS, 0x0001)
+#define LSTATUS_FAILURE                         MAKE_LSTATUS(, ERROR, 0x0001)
+#define LSTATUS_PARAMETER_INVALID               MAKE_LSTATUS(, ERROR, 0x0002)
+#define LSTATUS_PARAMETER_NULL                  MAKE_LSTATUS(, ERROR, 0x0003)
+#define LSTATUS_PARAMETER_OUT_OF_RANGE          MAKE_LSTATUS(, ERROR, 0x0004)
+#define LSTATUS_PARAMETER_INCORRECT_TYPE        MAKE_LSTATUS(, ERROR, 0x0005)
+#define LSTATUS_INVALID_MODULE_ID               MAKE_LSTATUS(, ERROR, 0x0006)
+#define LSTATUS_BUFFER_MISALIGNED               MAKE_LSTATUS(, ERROR, 0x0007)
+
+#define LSTATUS_MEMORY_UNAVAILABLE        MAKE_LSTATUS(MEMORY, ERROR, 0x0000)
+
+#endif /* _LINUX_LSTATUS_H */
Index: 2.6.14-nlkd/include/linux/module-id.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/linux/module-id.h	2005-06-27 12:49:47.000000000 +0200
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ *
+ *   File Name:      module-id.h
+ *   Created by:     Clyde Griffin
+ *   Date created:   11/1/1998
+ *
+ *   %version:       5 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 04:49:36 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1998-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#ifndef _LINUX_MODULE_ID_H
+#define _LINUX_MODULE_ID_H
+
+typedef struct module * moduleId_t;
+
+/* Since THIS_MODULE is NULL for components not built as module, and
+   since we need a non-NULL unique per-component ID in various places,
+   we fake things here. */
+#ifdef MODULE
+extern struct module __this_module;
+# define THIS_MODULE_ID(ident) const moduleId_t ident = &__this_module
+#else
+# define THIS_MODULE_ID(ident) const moduleId_t ident = (moduleId_t)&ident
+#endif
+
+#endif /* _LINUX_MODULE_ID_H */
Index: 2.6.14-nlkd/include/linux/nint.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/linux/nint.h	2005-06-27 14:05:48.000000000 +0200
@@ -0,0 +1,240 @@
+/*****************************************************************************
+ *
+ *   File Name:      nint.h
+ *   Created by:     Clyde Griffin
+ *   Date created:   11/1/1998
+ *
+ *   %version:       5 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 04:50:01 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1998-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *    File Description:
+ *
+ *****************************************************************************/
+
+#ifndef _LINUX_NINT_H
+#define _LINUX_NINT_H
+
+#include <linux/config.h>
+#include <linux/stddef.h>
+#include <linux/types.h>
+#include <linux/nls.h> /* for wchar_t */
+
+/*
+ * Alignment Macros for LoHi Machine Types
+ */
+#ifndef STRICT_ALIGNMENT
+# if defined(_M_IX86) || defined(__i386__) \
+  || defined(_M_AMD64) || defined(__x86_64__)
+#  define STRICT_ALIGNMENT 0
+# else
+#  define STRICT_ALIGNMENT 1
+# endif
+#endif
+#ifndef UNALIGNED_SUPPORT
+# if defined(__INTEL_COMPILER) || (defined(_MSC_VER) && defined(_M_IA64))
+#  define UNALIGNED_SUPPORT __unaligned
+# elif !STRICT_ALIGNMENT
+#  define UNALIGNED_SUPPORT
+# endif
+#endif
+
+#if defined(_M_IA64) || defined(__ia64__)
+
+# define NATIVE_APPEND_(p)		p##64
+# define NATIVE_EMBED_(p, s)		p##64##s
+# define PHYSADDR_APPEND_(p)		p##64
+# define PHYSADDR_EMBED_(p, s)	p##64##s
+
+#elif defined(_M_IX86) || defined(__i386__) \
+   || defined(_M_AMD64) || defined(__x86_64__)
+
+# define NATIVE_APPEND_(p)		p##32
+# define NATIVE_EMBED_(p, s)		p##32##s
+# define PHYSADDR_APPEND_(p)		p##64
+# define PHYSADDR_EMBED_(p, s)	p##64##s
+
+#elif !defined(NATIVE_APPEND_) || !defined(NATIVE_EMBED_) || !defined(PHYSADDR_APPEND_) || !defined(PHYSADDR_EMBED_)
+# error Unimplemented!
+#endif
+
+#ifdef CONFIG_64BIT
+# define POINTER_APPEND_(p)		p##64
+# define POINTER_EMBED_(p, s)		p##64##s
+#else
+# define POINTER_APPEND_(p)		p##32
+# define POINTER_EMBED_(p, s)		p##32##s
+#endif
+
+typedef POINTER_EMBED_(int, _t)	intptr_t;
+typedef POINTER_EMBED_(uint, _t)	uintptr_t;
+typedef NATIVE_EMBED_(int, _t)	nint_t;
+typedef NATIVE_EMBED_(uint, _t)	nuint_t;
+typedef PHYSADDR_EMBED_(uint, _t)	physaddr_t;
+
+#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)
+# ifndef INT32_MAX
+#  define INT8_MAX		INT8_C (0x7f)
+#  define INT8_MIN		(-INT8_MAX-1)
+#  define INT16_MAX		INT16_C(0x7fff)
+#  define INT16_MIN		(-INT16_MAX-1)
+#  define INT32_MAX		INT32_C(0x7fffffff)
+#  define INT32_MIN		(-INT32_MAX-1)
+#  define INT64_MAX		INT64_C(0x7fffffffffffffff)
+#  define INT64_MIN		(-INT64_MAX-1)
+# endif
+# ifndef UINT32_MAX
+#  define UINT8_MAX		UINT8_C (0xff)
+#  define UINT16_MAX	UINT16_C(0xffff)
+#  define UINT32_MAX	UINT32_C(0xffffffff)
+#  define UINT64_MAX	UINT64_C(0xffffffffffffffff)
+# endif
+# define INTPTR_MIN		POINTER_EMBED_(INT, _MIN)
+# define INTPTR_MAX		POINTER_EMBED_(INT, _MAX)
+# define UINTPTR_MAX	POINTER_EMBED_(UINT, _MAX)
+# define NINT_MIN		NATIVE_EMBED_(INT, _MIN)
+# define NINT_MAX		NATIVE_EMBED_(INT, _MAX)
+# define NUINT_MAX		NATIVE_EMBED_(UINT, _MAX)
+# define PHYSADDR_MAX	PHYSADDR_EMBED_(UINT, _MAX)
+#endif
+
+#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS)
+# ifndef INT32_C
+#  define INT8_C(n)		(n)
+#  define INT16_C(n)	(n)
+#  define INT32_C(n)	(n)
+#  define INT64_C(n)	(n##LL)
+# endif
+# ifndef UINT32_C
+#  define UINT8_C(n)	(n)
+#  define UINT16_C(n)	(n)
+#  define UINT32_C(n)	(n##U)
+#  define UINT64_C(n)	(n##ULL)
+# endif
+# define INTPTR_C		POINTER_EMBED_(INT, _C)
+# define UINTPTR_C		POINTER_EMBED_(UINT, _C)
+# define NINT_C		NATIVE_EMBED_(INT, _C)
+# define NUINT_C		NATIVE_EMBED_(UINT, _C)
+# define PHYSADDR_C		PHYSADDR_EMBED_(UINT, _C)
+#endif
+
+#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS)
+# ifndef PRId32
+#  define PRI_8(t)  #t
+#  define PRId8 PRI_8(d)
+#  define PRIi8 PRI_8(i)
+#  define PRIo8 PRI_8(o)
+#  define PRIu8 PRI_8(u)
+#  define PRIx8 PRI_8(x)
+#  define PRIX8 PRI_8(X)
+
+#  define PRI_16(t) #t
+#  define PRId16 PRI_16(d)
+#  define PRIi16 PRI_16(i)
+#  define PRIo16 PRI_16(o)
+#  define PRIu16 PRI_16(u)
+#  define PRIx16 PRI_16(x)
+#  define PRIX16 PRI_16(X)
+
+#  define PRI_32(t) #t
+#  define PRId32 PRI_32(d)
+#  define PRIi32 PRI_32(i)
+#  define PRIo32 PRI_32(o)
+#  define PRIu32 PRI_32(u)
+#  define PRIx32 PRI_32(x)
+#  define PRIX32 PRI_32(X)
+
+#  define PRI_64(t) "L"#t
+#  define PRId64 PRI_64(d)
+#  define PRIi64 PRI_64(i)
+#  define PRIo64 PRI_64(o)
+#  define PRIu64 PRI_64(u)
+#  define PRIx64 PRI_64(x)
+#  define PRIX64 PRI_64(X)
+
+# endif
+# define NPRId		NATIVE_APPEND_(PRId)
+# define NPRIi		NATIVE_APPEND_(PRIi)
+# define NPRIo		NATIVE_APPEND_(PRIo)
+# define NPRIu		NATIVE_APPEND_(PRIu)
+# define NPRIx		NATIVE_APPEND_(PRIx)
+# define NPRIX		NATIVE_APPEND_(PRIX)
+# define NSCNd		NATIVE_APPEND_(SCNd)
+# define NSCNi		NATIVE_APPEND_(SCNi)
+# define NSCNo		NATIVE_APPEND_(SCNo)
+# define NSCNu		NATIVE_APPEND_(SCNu)
+# define NSCNx		NATIVE_APPEND_(SCNx)
+# define PPRId		PHYSADDR_APPEND_(PRId)
+# define PPRIi		PHYSADDR_APPEND_(PRIi)
+# define PPRIo		PHYSADDR_APPEND_(PRIo)
+# define PPRIu		PHYSADDR_APPEND_(PRIu)
+# define PPRIx		PHYSADDR_APPEND_(PRIx)
+# define PPRIX		PHYSADDR_APPEND_(PRIX)
+# define PSCNd		PHYSADDR_APPEND_(SCNd)
+# define PSCNi		PHYSADDR_APPEND_(SCNi)
+# define PSCNo		PHYSADDR_APPEND_(SCNo)
+# define PSCNu		PHYSADDR_APPEND_(SCNu)
+# define PSCNx		PHYSADDR_APPEND_(SCNx)
+#endif
+
+#define GETPTR(addr)	POINTER_APPEND_(GET)(addr)
+#define PUTPTR(n, addr)	POINTER_APPEND_(PUT)(n, addr)
+#define GETN(addr)		NATIVE_APPEND_(GET)(addr)
+#define PUTN(n, addr)	NATIVE_APPEND_(PUT)(n, addr)
+#define GETPHYS(addr)	PHYSADDR_APPEND_(GET)(addr)
+#define PUTPHYS(pa, addr) PHYSADDR_APPEND_(PUT)(pa, addr)
+
+/*
+ * Define a type suitable for forcing 128-bit (16-byte) structure alignment
+ */
+#if defined(__INTEL_COMPILER)
+
+typedef long long __m128;
+typedef __m128 align128_t;
+
+#elif defined(__ECL)
+
+typedef __int128 align128_t;
+
+#elif defined(__GNUC__)
+
+typedef struct {
+	char _;
+} align128_t __attribute__((__aligned__(16)));
+
+#endif
+
+typedef union {
+#if defined(_M_IA64) || defined(__ia64__)
+	align128_t        fp128;
+#endif
+	struct {
+		uint64_t loflt;
+		uint64_t hiflt;
+	} real_fp;
+} float128_t;
+
+#endif /* _LINUX_NINT_H */
Index: 2.6.14-nlkd/include/linux/nlkd.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/linux/nlkd.h	2005-11-03 12:04:12.000000000 +0100
@@ -0,0 +1,241 @@
+/*****************************************************************************
+ *
+ *   File Name:      nlkd.h
+ *   Created by:     Jan Beulich
+ *   %version:       17 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 04:03:57 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#include <linux/config.h>
+
+#ifndef DEBUG_EVENT_ENTER_DEBUGGER
+# define DEBUG_EVENT_ENTER_DEBUGGER		0
+
+/* negative values are error conditions */
+# define DEBUG_EVENT_PANIC			(-1)
+# define DEBUG_EVENT_ASSERT			(-2)
+
+/* positive values are informational */
+# define DEBUG_EVENT_MESSAGE			1
+# define DEBUG_EVENT_MODULE_LOAD		2
+# define DEBUG_EVENT_MODULE_UNLOAD		3
+# define DEBUG_EVENT_THREAD_CREATE		4
+# define DEBUG_EVENT_THREAD_DESTROY	5
+
+# ifndef __ASSEMBLY__
+#  ifdef CONFIG_NLKD
+
+#   include <linux/linkage.h>
+#   include <linux/compiler.h>
+
+asmlinkage void nlkdAssert(const char*string,
+	const char*file,
+	const char*func,
+	unsigned line);
+asmlinkage void nlkdDebugEvent(int eventCode, ...);
+asmlinkage void nlkdEnterDebugger(void);
+asmlinkage void nlkdPanic(const char*, ...);
+struct ftaInterruptionCtx_s;
+int nlkdIsDebugEvent(const struct ftaInterruptionCtx_s*);
+#   ifndef CONFIG_NLKD_FTA
+void nlkdSetDebugEventType(struct ftaInterruptionCtx_s*);
+#   endif
+
+#   if defined(__GNUC__)
+#    define rtASSERT(e) ((void)(likely(e) || (nlkdAssert(#e, __FILE__, __PRETTY_FUNCTION__, __LINE__), 0)))
+#   elif __STDC_VERSION__ >= 199901L
+#    define rtASSERT(e) ((void)(likely(e) || (nlkdAssert(#e, __FILE__, __func__, __LINE__), 0)))
+#   else
+#    define rtASSERT(e) ((void)(likely(e) || (nlkdAssert(#e, __FILE__, NULL, __LINE__), 0)))
+#   endif
+
+#  else /* CONFIG_NLKD */
+
+#   include <linux/kernel.h>
+
+static inline void nlkdDebugEvent(int eventCode, ...) {}
+#   define nlkdPanic panic
+
+#  endif /* CONFIG_NLKD */
+# endif /* !__ASSEMBLY__ */
+#endif /* DEBUG_EVENT_xxx */
+
+#ifndef _LINUX_NLKD_H
+#define _LINUX_NLKD_H
+# ifndef __ASSEMBLY__
+
+#  ifdef CONFIG_NLKD
+
+#   include <linux/module-id.h>
+#   include <linux/nint.h>
+#   include <linux/lstatus.h>
+#   include <stdarg.h>
+
+void nlkd_init(void);
+void nlkd_init_done(void);
+
+#   define NLKD_EXT_ID_MAX 32
+
+typedef void nlkdExtHandler_t(void*context, const char*command);
+
+void nlkdExtInputString(char*buffer, nuint_t bufferSize);
+void nlkdExtOutputString(const char*);
+int nlkdExtPrintf(const char*, ...) __attribute__((__format__(__printf__, 1, 2)));
+LSTATUS nlkdExtRegister(const char*id,
+	nlkdExtHandler_t*,
+	void*handlerContext,
+	moduleId_t,
+	const char*description,
+	nuint_t flags);
+LSTATUS nlkdExtUnregister(const char*id, moduleId_t);
+int nlkdExtVprintf(const char*, va_list);
+
+#   ifndef MODULE
+/* For code needing no initialization (e.g. printk), provide a way to store
+   the handler information without the need to call nlkdExtRegister(). */
+typedef const struct {
+	const char*id;
+	nlkdExtHandler_t*handler;
+	void*handlerContext;
+	const moduleId_t*pModuleId;
+	const char*description;
+	nuint_t flags;
+} nlkdExtension_t;
+#    define NLKD_EXTENSION(id, handler, ctx, mod, descr, flg) \
+	static nlkdExtension_t __nlkd_ext_##id                \
+		__attribute__((__section__(".nlkd.ext")))     \
+		__attribute__((__aligned__(sizeof(void*))))   \
+		__attribute_used__ = {                        \
+		#id, handler, ctx, &mod, descr, flg           \
+	}
+#   endif
+
+struct pt_regs;
+struct cdeBPStruct_s;
+
+#   ifdef CONFIG_CDE
+#    define MAYBE_INDIR(x) cdeBP##x
+#   else
+#    define MAYBE_INDIR(x) (*x)
+extern struct nlkdBPXface_s {
+#   endif
+
+/*
+ *
+ */
+void MAYBE_INDIR(Load)(
+	void);
+
+/*
+ *
+ */
+void MAYBE_INDIR(EnvClearAll)(
+	struct cdeBPStruct_s * * bpHead);
+
+/*
+ *
+ */
+void MAYBE_INDIR(EnvDisableAll)(
+	const struct cdeBPStruct_s * const * bpHead);
+
+/*
+ *
+ */
+void MAYBE_INDIR(EnvEnableAll)(
+	const struct cdeBPStruct_s * const * bpHead);
+
+/*
+ *
+ */
+int MAYBE_INDIR(EnvCheckAll)(
+	const struct pt_regs *,
+	const struct cdeBPStruct_s * const * bpHead);
+
+#   undef MAYBE_INDIR
+#   ifndef CONFIG_CDE
+} const * nlkdBPXface;
+#   endif
+
+#  else
+
+#   define nlkd_init()
+#   define nlkd_init_done()
+
+#  endif
+
+#  ifndef bp_list_handle
+#   if defined(CONFIG_CDE)
+#    define bp_list_handle(what, cond, obj) ((cond) \
+                                             ? cdeBPEnv##what##All(&(obj)->bpList) \
+                                             : (void)(obj))
+#    define bp_list_clear(obj) bp_list_handle(Clear, (obj)->bpList, obj)
+#    define bp_list_check(regs, obj) ((obj)->bpList \
+                                      ? cdeBPEnvCheckAll(regs, &(obj)->bpList) \
+                                      : ((void)(regs), (void)(obj), -1))
+#    define bp_load() cdeBPLoad()
+#   elif defined(CONFIG_NLKD)
+#    define bp_list_handle(what, cond, obj) ((cond) && nlkdBPXface \
+                                             ? nlkdBPXface->Env##what##All(&(obj)->bpList) \
+                                             : (void)(obj))
+#    define bp_list_clear(obj) bp_list_handle(Clear, (obj)->bpList, obj)
+#    define bp_list_check(regs, obj) ((obj)->bpList && nlkdBPXface \
+                                      ? nlkdBPXface->EnvCheckAll(regs, &(obj)->bpList) \
+                                      : ((void)(regs), (void)(obj), 0))
+#    define bp_load() (nlkdBPXface ? nlkdBPXface->Load() : (void)0)
+#   else
+#    define bp_list_handle(what, cond, obj) ((void)(cond), (void)(obj))
+#    define bp_list_clear(obj) ((void)(obj))
+#    define bp_list_check(regs, obj) ((void)(regs), (void)(obj), -1)
+#    define bp_load() ((void)0)
+#   endif
+#   define bp_list_disable(cond, obj) bp_list_handle(Disable, cond, obj)
+#   define bp_list_enable(cond, obj) bp_list_handle(Enable, cond, obj)
+#  endif
+
+#  define ctASSERT_GLUE(x, y) x##y
+#  define ctASSERT_NAME(tag) ctASSERT_GLUE(_ctassert_, tag)
+#  define CTASSERT_DECL(e) struct ctASSERT_NAME(__LINE__) {unsigned _:!!(e);}
+#  define CTASSERT_TYPED_EXPR(t, e) ((t)sizeof(char[1 - 2 * !(e)]))
+#  define CTASSERT_EXPR(e) CTASSERT_TYPED_EXPR(void, e)
+
+# endif /* __ASSEMBLY__ */
+#endif /* _LINUX_NLKD_H */
+
+#undef RTASSERT
+#undef RTVERIFY
+#ifndef __ASSEMBLY__
+# if !defined(CONFIG_NLKD) || !defined(CONFIG_DEBUG_KERNEL) || defined(NDEBUG)
+#  define RTASSERT(e) ((void)0)
+#  define RTVERIFY(e) ((void)(e))
+# else
+#  define RTASSERT rtASSERT
+#  define RTVERIFY rtASSERT
+# endif
+#endif /* !__ASSEMBLY__ */

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 23/39] NLKD/x86 - core
  2005-11-09 14:18                         ` [PATCH 22/39] NLKD - core Jan Beulich
@ 2005-11-09 14:19                           ` Jan Beulich
  2005-11-09 14:20                             ` [PATCH 24/39] NLKD/i386 " Jan Beulich
  2005-11-09 14:21                             ` [PATCH 25/39] NLKD/x86-64 " Jan Beulich
  2005-11-09 14:22                           ` [PATCH 26/39] NLKD - run time library Jan Beulich
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:19 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 122 bytes --]

The core x86 (32- and 64-bit) NLKD additions.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-x86.patch --]
[-- Type: application/octet-stream, Size: 7229 bytes --]

The core x86 (32- and 64-bit) NLKD additions.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/debug/nlkd/asm-x86.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/asm-x86.h	2005-11-03 12:14:32.000000000 +0100
@@ -0,0 +1,290 @@
+/*****************************************************************************
+ *
+ *   File Name:      asm-x86.h
+ *   Created by:     Jan Beulich
+ *   %version:       2 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 04:14:19 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+.intel_syntax noprefix
+.altmacro
+
+.equiv TRUE, 1
+.equiv FALSE, 0
+
+.equiv byte, 1
+.equiv word, 2
+.equiv dword, 4
+.equiv fword, 6
+.equiv qword, 8
+.equiv tbyte, 10
+.equiv oword, 16
+.equiv xmmword, 16
+
+.macro .extproc name
+ .global name
+ .type name, @function
+.endm
+
+.macro .locproc name
+ .type name, @function
+ .align PROCEDURE_ALIGN, 0xCC
+name:
+#ifdef CONFIG_UNWIND_INFO
+ .cfi_startproc
+ .equ .eh.framereg, eh.SP
+ .equ .eh.frameptr, SP
+#endif
+.endm
+
+.macro .pubproc name
+ .locproc name
+ .global name
+.endm
+
+.macro .hidproc name
+ .pubproc name
+ .hidden name
+.endm
+
+.macro .endp name
+ .size name, .-name
+#ifdef CONFIG_UNWIND_INFO
+ .cfi_endproc
+ .equ .eh.framereg, -1
+ .equ .eh.frameptr, -1
+#endif
+.endm
+
+.macro .locentry name, type=@notype
+ .type name, type
+name:
+.endm
+
+.macro .pubentry name, type
+ .locentry name, type
+ .global name
+.endm
+
+.macro .hidentry name, type
+ .pubentry name, type
+ .hidden name
+.endm
+
+.macro .rodata
+ .section .rodata, "a", @progbits
+.endm
+
+// frame unwind info generation support
+
+.macro EHpush item:req, spill=TRUE
+	push	item
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg == eh.SP
+  .cfi_adjust_cfa_offset .eh.stkword
+ .endif
+ .if spill
+  .ifdef eh.&item
+   .if .eh.preserved && (1 << eh.&item)
+    .cfi_rel_offset item, 0
+   .endif
+  .endif
+ .endif
+#endif
+.endm
+
+.macro EHpushC item:req
+ .if 1 | item // just to make sure this is a constant
+	push	item
+ .endif
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg == eh.SP
+  .cfi_adjust_cfa_offset .eh.stkword
+ .endif
+#endif
+.endm
+
+.macro EHpushO item:req
+	push	offset item
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg == eh.SP
+  .cfi_adjust_cfa_offset .eh.stkword
+ .endif
+#endif
+.endm
+
+.macro EHpushV item:req
+	push	[item]
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg == eh.SP
+  .cfi_adjust_cfa_offset .eh.stkword
+ .endif
+#endif
+.endm
+
+.macro EHpop item:req, fill=TRUE
+	pop	item
+#ifdef CONFIG_UNWIND_INFO
+ .if fill
+  .ifdef eh.&item
+   .if .eh.preserved && (1 << eh.&item)
+    .cfi_restore item
+   .endif
+  .endif
+ .endif
+ .if .eh.framereg == eh.SP
+  .cfi_adjust_cfa_offset -.eh.stkword
+ .endif
+#endif
+.endm
+
+.macro EHpopV item:req
+	pop	[item]
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg == eh.SP
+  .cfi_adjust_cfa_offset -.eh.stkword
+ .endif
+#endif
+.endm
+
+.macro EHsetfr dst, src, offs=0
+ .if eh.&dst <> eh.&src
+  .if offs == 0
+	mov	dst, src
+#ifdef CONFIG_UNWIND_INFO
+   .cfi_def_cfa_register dst
+#endif
+  .else
+	lea	dst, [src + (offs) * .eh.stkword]
+#ifdef CONFIG_UNWIND_INFO
+   .cfi_adjust_cfa_offset -(offs) * .eh.stkword
+   .cfi_def_cfa_register dst
+#endif
+  .endif
+ .else
+	add	dst, (offs) * .eh.stkword
+#ifdef CONFIG_UNWIND_INFO
+  .cfi_adjust_cfa_offset -(offs) * .eh.stkword
+#endif
+ .endif
+#ifdef CONFIG_UNWIND_INFO
+ .equ .eh.framereg, eh.&dst
+ .equ .eh.frameptr, dst
+#endif
+.endm
+
+.macro EHenter frsz, level
+	enter	frsz, level
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg <> eh.SP
+  .error "'enter' without SP-based frame is not supported."
+ .endif
+ .cfi_adjust_cfa_offset .eh.stkword
+ .cfi_rel_offset BP, 0
+ .cfi_def_cfa_register BP
+ .equ .eh.framereg, eh.BP
+ .equ .eh.frameptr, BP
+#endif
+.endm
+
+.macro EHleave
+	leave
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg <> eh.BP
+  .error "'leave' without BP-based frame is not supported."
+ .endif
+ .cfi_def_cfa_register SP
+ .cfi_restore BP
+ .cfi_adjust_cfa_offset -.eh.stkword
+ .equ .eh.framereg, eh.SP
+ .equ .eh.frameptr, SP
+#endif
+.endm
+
+.macro EHspill offs:req, reg:req
+	mov	[.eh.frameptr+(offs)*.eh.stkword], reg
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg == eh.SP &&&&& (offs) < 0
+  .warning "Spill offset into SP-relative frame should be positive."
+ .endif
+ .cfi_offset reg, (offs)*.eh.stkword
+#endif
+.endm
+
+.macro EHfill reg:req, offs:req
+	mov	reg, [.eh.frameptr+(offs)*.eh.stkword]
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg == eh.SP &&&&& (offs) < 0
+  .warning "Fill offset into SP-relative frame should be positive."
+ .endif
+ .cfi_restore reg
+#endif
+.endm
+
+.macro EHpushf spill=TRUE
+	pushf
+#ifdef CONFIG_UNWIND_INFO
+ .if .eh.framereg == eh.SP
+  .cfi_adjust_cfa_offset .eh.stkword
+ .endif
+ .if spill
+  .cfi_rel_offset FLAGS, 0
+ .endif
+#endif
+.endm
+
+.macro EHpopf fill=TRUE
+	popf
+#ifdef CONFIG_UNWIND_INFO
+ .if fill
+  .cfi_restore FLAGS
+ .endif
+ .if .eh.framereg == eh.SP
+  .cfi_adjust_cfa_offset -.eh.stkword
+ .endif
+#endif
+.endm
+
+.macro EHpushState
+#ifdef CONFIG_UNWIND_INFO
+ .cfi_remember_state
+#endif
+.endm
+
+.macro EHpopState
+#ifdef CONFIG_UNWIND_INFO
+ .cfi_restore_state
+#endif
+.endm
+
+#ifdef CONFIG_UNWIND_INFO
+.equ .eh.framereg, -1
+.equ .eh.frameptr, -1
+#endif

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 24/39] NLKD/i386 - core
  2005-11-09 14:19                           ` [PATCH 23/39] NLKD/x86 " Jan Beulich
@ 2005-11-09 14:20                             ` Jan Beulich
  2005-11-09 14:21                             ` [PATCH 25/39] NLKD/x86-64 " Jan Beulich
  1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:20 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 106 bytes --]

The core i386 NLKD additions.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-i386.patch --]
[-- Type: application/octet-stream, Size: 47522 bytes --]

The core i386 NLKD additions.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/i386/Kconfig.debug
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/Kconfig.debug	2005-11-09 11:12:40.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/Kconfig.debug	2005-11-04 16:19:32.000000000 +0100
@@ -1,6 +1,7 @@
 menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
+source "debug/Kconfig"
 
 config EARLY_PRINTK
 	bool "Early printk" if EMBEDDED && DEBUG_KERNEL
Index: 2.6.14-nlkd/arch/i386/kernel/asm-offsets.c
===================================================================
--- 2.6.14-nlkd.orig/arch/i386/kernel/asm-offsets.c	2005-11-09 11:12:40.000000000 +0100
+++ 2.6.14-nlkd/arch/i386/kernel/asm-offsets.c	2005-11-04 16:19:32.000000000 +0100
@@ -4,6 +4,7 @@
  * to extract and format the required data.
  */
 
+#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/personality.h>
@@ -13,6 +14,13 @@
 #include <asm/fixmap.h>
 #include <asm/processor.h>
 #include <asm/thread_info.h>
+#ifdef CONFIG_NLKD
+# include <asm/fta-frame.h>
+# include <asm/fta-type.h>
+#endif
+#if defined(CONFIG_CDE) || defined(CONFIG_CDE_MODULE)
+# include <../debug/nlkd/cdelock.h>
+#endif
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -70,4 +78,88 @@ void foo(void)
 	DEFINE(PAGE_SIZE_asm, PAGE_SIZE);
 	DEFINE(THREAD_SIZE_asm, THREAD_SIZE);
 	DEFINE(VSYSCALL_BASE, __fix_to_virt(FIX_VSYSCALL));
+
+#ifdef CONFIG_NLKD
+	BLANK();
+# define TSS_DEF(f) DEFINE(TSS_##f, offsetof (struct tss_struct, f))
+	TSS_DEF(back_link);
+	TSS_DEF(esp0);
+	TSS_DEF(ss0);
+	TSS_DEF(esp1);
+	TSS_DEF(ss1);
+	TSS_DEF(esp2);
+	TSS_DEF(ss2);
+	TSS_DEF(__cr3);
+	TSS_DEF(eip);
+	TSS_DEF(eflags);
+	TSS_DEF(eax);
+	TSS_DEF(ecx);
+	TSS_DEF(edx);
+	TSS_DEF(ebx);
+	TSS_DEF(esp);
+	TSS_DEF(ebp);
+	TSS_DEF(esi);
+	TSS_DEF(edi);
+	TSS_DEF(es);
+	TSS_DEF(cs);
+	TSS_DEF(ss);
+	TSS_DEF(ds);
+	TSS_DEF(fs);
+	TSS_DEF(gs);
+	TSS_DEF(ldt);
+# undef TSS_DEF
+
+	BLANK();
+# define FRAME_TYPE(t) DEFINE(IA32_##t, IA32_##t)
+	FRAME_TYPE(DIVIDE_ERROR);
+	FRAME_TYPE(DEBUG);
+	FRAME_TYPE(NMI);
+	FRAME_TYPE(BREAKPOINT);
+	FRAME_TYPE(OVERFLOW);
+	FRAME_TYPE(BOUNDS_CHECK);
+	FRAME_TYPE(ILLEGAL_OPCODE);
+	FRAME_TYPE(DEVICE_NOT_AVAILABLE);
+	FRAME_TYPE(DOUBLE_FAULT);
+	FRAME_TYPE(COPROCESSOR_SEGMENT_OVERRUN);
+	FRAME_TYPE(INVALID_TSS);
+	FRAME_TYPE(SEGMENT_NOT_PRESENT);
+	FRAME_TYPE(STACK_FAULT);
+	FRAME_TYPE(GENERAL_PROTECTION_FAULT);
+	FRAME_TYPE(PAGE_FAULT);
+	FRAME_TYPE(FP_ERROR);
+	FRAME_TYPE(ALIGNMENT_CHECK);
+	FRAME_TYPE(MACHINE_CHECK);
+	FRAME_TYPE(SIMD_FP_ERROR);
+# undef FRAME_TYPE
+	BLANK();
+# define FRAME_DEF(f) DEFINE(FRAME_##f, offsetof (struct ftaInterruptionCtx_s, f))
+	FRAME_DEF(type);
+	FRAME_DEF(sub_type);
+	FRAME_DEF(state);
+	FRAME_DEF(esp);
+	FRAME_DEF(ss);
+	FRAME_DEF(fs);
+	FRAME_DEF(gs);
+	FRAME_DEF(ldtr);
+	FRAME_DEF(tr);
+	FRAME_DEF(cr0);
+	FRAME_DEF(cr2);
+	FRAME_DEF(cr3);
+	FRAME_DEF(cr4);
+	FRAME_DEF(dr7);
+	FRAME_DEF(debugCtl);
+	FRAME_DEF(ec);
+	FRAME_DEF(pt_regs);
+	FRAME_DEF(fp_mmx_xmm);
+# undef FRAME_DEF
+#endif
+
+#if defined(CONFIG_CDE) || defined(CONFIG_CDE_MODULE)
+	BLANK();
+	DEFINE(CDESPINLOCK_signature, offsetof (cdeSpinLock_t, cdeSpinLockSignature));
+	DEFINE(CDESPINLOCK_cpu,       offsetof (cdeSpinLock_t, cdeSpinLockCpu));
+	DEFINE(CDE_VALID_SPINLOCK_SIGNATURE_LO, (uint32_t)CDE_VALID_SPINLOCK_SIGNATURE);
+	DEFINE(CDE_VALID_SPINLOCK_SIGNATURE_HI, CDE_VALID_SPINLOCK_SIGNATURE >> 32);
+	DEFINE(CDE_SPINLOCK_NOT_OWNED,          CDE_SPINLOCK_NOT_OWNED);
+#endif
 }
Index: 2.6.14-nlkd/debug/nlkd/asm-ia32.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/asm-ia32.h	2005-11-07 12:11:32.000000000 +0100
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ *
+ *   File Name:      asm-ia32.h
+ *   Created by:     Jan Beulich
+ *   %version:       7 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 04:13:50 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#if defined(__ASSEMBLY__) && !defined(ASM_IA32_H)
+#define ASM_IA32_H
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#ifdef CONFIG_UNWIND_INFO
+.equiv eh.eax, 0
+.equiv eh.ecx, 1
+.equiv eh.edx, 2
+.equiv eh.ebx, 3
+.equiv eh.esp, 4
+.equiv eh.ebp, 5
+.equiv eh.esi, 6
+.equiv eh.edi, 7
+.equiv eh.es, 8
+.equiv eh.cs, 9
+.equiv eh.ss, 10
+.equiv eh.ds, 11
+.equiv eh.fs, 12
+.equiv eh.gs, 13
+
+# define SP esp
+# define BP ebp
+# define FLAGS eflags
+.equiv .eh.stkword, dword
+.equiv .eh.preserved, (1 << eh.ebx) | (1 << eh.ebp) | (1 << eh.esi) | (1 << eh.edi) \
+                      | (1 << eh.es) | (1 << eh.cs) | (1 << eh.ds) | (1 << eh.ss) | (1 << eh.fs) | (1 << eh.gs)
+#endif
+
+#include "asm-x86.h"
+
+.ifndef PROCEDURE_ALIGN
+ .equiv PROCEDURE_ALIGN, 0x10
+.endif
+
+.macro load sreg:req, loc:req, aux:req
+	LOCAL set, adj, skip
+set:
+	mov	sreg, loc
+skip:
+ .section .fixup, "ax"
+adj:
+	xor	aux, aux
+	mov	sreg, aux
+	jmp	skip
+ .previous
+ .section __ex_table, "a"
+ .align	dword
+ .long	set, adj
+ .previous
+.endm
+
+.macro fnrstor loc:req
+	frstor	loc
+.endm
+
+.macro fxsr what:req, loc:req
+	LOCAL where, fix, done
+where:
+	fx&what	loc
+done:
+ .section .fixup, "ax"
+fix:
+	fn&what	loc
+	jmp	done
+ .previous
+ .section __ex_table, "a"
+ .align dword
+ .long where, fix
+ .previous
+.endm
+
+.macro fxinit mxcsr:req
+	LOCAL where, fix
+where:
+	ldmxcsr	mxcsr
+fix:
+	fninit
+ .section __ex_table, "a"
+ .align dword
+ .long where, fix
+ .previous
+.endm
+
+#endif /* ASM_IA32_H */
Index: 2.6.14-nlkd/debug/nlkd/nlkdIA32.S
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/nlkdIA32.S	2005-10-07 17:19:06.000000000 +0200
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ *
+ *   File Name:      nlkdIA32.S
+ *   Created by:     jbeulich
+ *   %version:       2 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Fri Oct 07 09:18:56 2005 %
+ *
+ ****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2001-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	 File Description:
+ *
+ ****************************************************************************/
+
+.equiv PROCEDURE_ALIGN, 1
+#include "asm-ia32.h"
+#include <linux/nlkd.h>
+
+//todo .file "nlkd"
+.text
+
+// void nlkdDebugEvent(nint_t eventCode, ...);
+.pubproc nlkdDebugEvent
+	cmp	dword ptr [nlkdAgentCount], 0
+	movsx	eax, byte ptr [esp+dword]
+	jg	_nlkdEnterDebuggerInstruction_
+	test	eax, eax
+	jg	0f
+ .hidentry _nlkdEnterDebuggerInstruction_
+	int	3
+0:
+	jc	1f
+	ret
+1:
+#ifdef CONFIG_UNWIND_INFO
+// Once we get here, the dual frame layout ceases to exist,
+// and hence we can now express the (alternate) frame state.
+ .cfi_def_cfa esp, 2*dword
+ .cfi_offset eip, -2*dword
+#endif
+	ret	dword				// discard eventCode for special case entries
+.endp nlkdDebugEvent
+// void nlkdEnterDebugger(void);
+.pubproc nlkdEnterDebugger
+	mov	eax, DEBUG_EVENT_ENTER_DEBUGGER
+2:
+	push	dword ptr [esp]			// make stack frame consistent with nlkdDebugEvent
+						// (note that there's no point in using EHpush here
+						// because the .eh_frame unwind information can't
+						// express the dual (conditional upon EFLAGS.CF)
+						// frame layout at _nlkdEnterDebuggerInstruction_.
+	stc
+	mov	[esp+dword], eax			// store eventCode
+	jmp	_nlkdEnterDebuggerInstruction_
+.endp nlkdEnterDebugger
+// void nlkdPanic(const char*string, ...);
+.pubproc nlkdPanic
+	mov	eax, DEBUG_EVENT_PANIC
+	jmp	2b
+.endp nlkdPanic
+// void nlkdAssert(const char*string, const char*file, const char*func, nuint_t line);
+.pubproc nlkdAssert
+	mov	eax, DEBUG_EVENT_ASSERT
+	jmp	2b
+.endp nlkdAssert
Index: 2.6.14-nlkd/debug/nlkd/nlkdIA32.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/nlkdIA32.h	2005-10-10 14:52:40.000000000 +0200
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ *
+ *   File Name:      nlkdIA32.h
+ *   Created by:     Jan Beulich
+ *   %version:       1 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Oct 10 06:52:33 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#ifndef CONFIG_CDE
+static void _set_debugreg(uintptr_t value, nuint_t regnum) {
+	switch(regnum) {
+	case 0: __asm__("movl %0,%%db0" : : "r" (value)); break;
+	case 1: __asm__("movl %0,%%db1" : : "r" (value)); break;
+	case 2: __asm__("movl %0,%%db2" : : "r" (value)); break;
+	case 3: __asm__("movl %0,%%db3" : : "r" (value)); break;
+	case 6: __asm__("movl %0,%%db6" : : "r" (value)); break;
+	case 7: __asm__("movl %0,%%db7" : : "r" (value)); break;
+	}
+}
+static int _disable_debugreg(struct pt_regs *regs, nuint_t regnum)
+{
+	_set_debugreg(0, 7);
+}
+static int _restore_debugreg(void)
+{
+	_set_debugreg(current->thread.debugreg[7], 7);
+}
+#endif
Index: 2.6.14-nlkd/include/asm-i386/fta-frame.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/asm-i386/fta-frame.h	2005-11-03 11:49:06.000000000 +0100
@@ -0,0 +1,177 @@
+/*****************************************************************************
+ *
+ *   File Name:      fta-frame.h
+ *   Created by:     Clyde Griffin
+ *   Date created:   1/1/1999
+ *
+ *   %version:       7 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 03:48:54 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *  This module contains the definition of a trap frame.
+ *
+ *****************************************************************************/
+
+#ifndef _ASM_I386_FTA_FRAME_H
+#define _ASM_I386_FTA_FRAME_H
+
+/* values for ftaInterruptionCtx_s.state */
+#ifdef CONFIG_NLKD_FTA
+# define FRAME_COMPLETE_BIT 0
+# define FRAME_COMPLETE (1 << FRAME_COMPLETE_BIT)
+#endif
+
+# ifndef __ASSEMBLY__
+#  include <asm/ia_32.h>
+#  include <asm/ptrace.h>
+
+struct ftaInterruptionCtx_s {
+	uint16_t	type;		/* Trap type */
+	 int8_t	sub_type;		/* Extended type */
+	uint8_t	state;		/* Framework/Debugger only */
+	uint32_t	ec;			/* Error code */
+	uint32_t	cr0;
+	uint32_t	cr4;
+	uint32_t	cr2;
+	uint32_t	cr3;
+	uint64_t	debugCtl;
+	uint32_t	dr7;
+	union {
+		// fp/mmx/sse state (which requires 16-byte alignment and thus needs to be referenced indirectly)
+		fxsave_t	*fp_mmx_xmm;
+		// fp/mmx state
+		fsave_t	*fp_mmx;
+	};
+	uint16_t	ldtr;
+	uint16_t	tr;
+	uint16_t	fs;
+	uint16_t	gs;
+	union {
+		uint32_t	esp;
+		uint16_t	sp;
+	};
+	uint16_t	ss, _ss_pad;
+	union {
+		struct pt_regs pt_regs;
+		struct {
+			union {
+				uint32_t	ebx;
+				uint16_t	bx;
+				struct {
+					uint8_t	bl;
+					uint8_t	bh;
+				};
+			};
+			union {
+				uint32_t	ecx;
+				uint16_t	cx;
+				struct {
+					uint8_t	cl;
+					uint8_t	ch;
+				};
+			};
+			union {
+				uint32_t	edx;
+				uint16_t	dx;
+				struct {
+					uint8_t	dl;
+					uint8_t	dh;
+				};
+			};
+			union {
+				uint32_t	esi;
+				uint16_t	si;
+			};
+			union {
+				uint32_t	edi;
+				uint16_t	di;
+			};
+			union {
+				uint32_t	ebp;
+				uint16_t	bp;
+			};
+			union {
+				uint32_t	eax;
+				uint16_t	ax;
+				struct {
+					uint8_t	al;
+					uint8_t	ah;
+				};
+			};
+			union {
+				struct {
+					uint16_t	ds, _ds_pad;
+				};
+#  ifdef CONFIG_NLKD_FTA
+				uint32_t	_type_raw;
+#  endif
+			};
+			union {
+				struct {
+					uint16_t	es, _es_pad;
+				};
+#  ifdef CONFIG_NLKD_FTA
+				uint32_t	_ebx_raw;
+#  endif
+			};
+			union {
+				uint32_t	orig_eax;
+#  ifdef CONFIG_NLKD_FTA
+				uint32_t	_ec_raw;
+#  endif
+			};
+			union {
+				uint32_t	eip;
+				uint16_t	ip;
+			};
+			uint16_t	cs, _cs_pad;
+			union {
+				uint32_t	eflags;
+				uint16_t	flags;
+			};
+			/*
+			 * From here on field presence dependent on the value in eflags
+			 */
+			union {
+				uint32_t	r3_esp;
+				uint16_t	r3_sp;
+			};
+			uint16_t	r3_ss, _r3_ss_pad;
+		};
+#  ifdef CONFIG_NLKD_FTA
+	};
+#   define FRAME_PTREGS(frame, field) (frame)->field
+#  else
+	} *pt_regs;
+#   define FRAME_PTREGS(frame, field) (frame)->pt_regs->field
+#  endif
+	/* This is only used in cloned frames. */
+	uint32_t	_fp_mmx_xmm_area_[(sizeof(fxsave_t) + 0xf) / sizeof(uint32_t)];
+};
+# endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_I386_FTA_FRAME_H */
Index: 2.6.14-nlkd/include/asm-i386/fta-type.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/asm-i386/fta-type.h	2005-06-27 13:56:50.000000000 +0200
@@ -0,0 +1,89 @@
+/*****************************************************************************
+ *
+ *   File Name:      fta-type.h
+ *   Created by:     Clyde Griffin
+ *   Date created:   1/1/1999
+ *
+ *   %version:       5 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 05:21:26 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *  This module contains the definition of a trap frame.
+ *
+ *****************************************************************************/
+
+#ifndef _ASM_I386_FTA_TYPE_H
+#define _ASM_I386_FTA_TYPE_H
+
+/*
+ * ftaInterruptionId_t
+ *
+ * ftaInterruptionId_t uniquely identifies each type of interruption.
+ *
+ * NOTE:
+ *    Interruption frames may be different for faults, traps, external
+ *    interrupts and aborts.  The consumer of an interruption frame
+ *    needs to be aware of which interruption types are associated with
+ *    with interruption frame types.
+ */
+enum ftaInterruptionId_e
+{
+	IA32_DIVIDE_ERROR,
+	IA32_DEBUG,
+	IA32_NMI,
+	IA32_BREAKPOINT,
+	IA32_OVERFLOW,
+	IA32_BOUNDS_CHECK,
+	IA32_ILLEGAL_OPCODE,
+	IA32_DEVICE_NOT_AVAILABLE,
+	IA32_DOUBLE_FAULT,
+	IA32_COPROCESSOR_SEGMENT_OVERRUN,
+	IA32_INVALID_TSS,
+	IA32_SEGMENT_NOT_PRESENT,
+	IA32_STACK_FAULT,
+	IA32_GENERAL_PROTECTION_FAULT,
+	IA32_PAGE_FAULT,
+	IA32_RSVD_0F,
+	IA32_FP_ERROR,
+	IA32_ALIGNMENT_CHECK,
+	IA32_MACHINE_CHECK,
+	IA32_SIMD_FP_ERROR,
+	IA32_RSVD_14,
+	IA32_RSVD_15,
+	IA32_RSVD_16,
+	IA32_RSVD_17,
+	IA32_RSVD_18,
+	IA32_RSVD_19,
+	IA32_RSVD_1A,
+	IA32_RSVD_1B,
+	IA32_RSVD_1C,
+	IA32_RSVD_1D,
+	IA32_RSVD_1E,
+	IA32_RSVD_1F
+};
+
+#endif /* _ASM_I386_FTA_TYPE_H */
Index: 2.6.14-nlkd/include/asm-i386/ia_32.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/asm-i386/ia_32.h	2005-06-30 15:54:35.000000000 +0200
@@ -0,0 +1,907 @@
+/*****************************************************************************
+ *
+ *   File Name:      ia_32.h
+ *   Created by:     Clyde Griffin, Jan Beulich
+ *   Date created:   21Feb2001
+ *
+ *   %version:       9 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Jun 30 07:54:20 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2001-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#ifndef _ASM_IA_32_H
+#define _ASM_IA_32_H
+
+#ifdef __ASSEMBLY__
+# define UINT64_C(v) (v)
+#else
+# include <linux/types.h>
+#endif
+
+/*
+ * EFLAGS
+ */
+#define EFLAGS_MBZ			0xffc08028
+#define EFLAGS_MBS			0x00000002
+#define EFLAGS_CF			0
+#define EFLAGS_PF			2
+#define EFLAGS_AF			4
+#define EFLAGS_ZF			6
+#define EFLAGS_SF			7
+#define EFLAGS_TF			8
+#define EFLAGS_IF			9
+#define EFLAGS_DF			10
+#define EFLAGS_OF			11
+#define EFLAGS_IOPL			12
+#define EFLAGS_IOPL_LEN		2
+#define EFLAGS_NT			14
+#define EFLAGS_RF			16
+#define EFLAGS_VM			17
+#define EFLAGS_AC			18
+#define EFLAGS_VIF			19
+#define EFLAGS_VIP			20
+#define EFLAGS_ID			21
+
+/*
+ * Privilege levels
+ */
+#define PL_KERNEL			0
+#define PL_USER			3
+
+/*
+ * Selector layout
+ */
+#define SELECTOR_RPL		0
+#define SELECTOR_RPL_LEN		2
+#define SELECTOR_TI			2
+#define SELECTOR_INDEX		3
+#define SELECTOR_INDEX_LEN	13
+
+/*
+ * Descriptor Attributes
+ */
+#define DESCRIPTOR_TYPE		0
+#define DESCRIPTOR_TYPE_LEN	5
+#	define DESCRIPTOR_INVALID	0x00
+#	define DESCRIPTOR_AVAILTSS16	0x01
+#	define DESCRIPTOR_LDT		0x02
+#	define DESCRIPTOR_BUSYTSS16	0x03
+#	define DESCRIPTOR_CALLGATE16	0x04
+#	define DESCRIPTOR_TASKGATE	0x05
+#	define DESCRIPTOR_INTGATE16	0x06
+#	define DESCRIPTOR_TRAPGATE16	0x07
+#	define DESCRIPTOR_AVAILTSS32	0x09
+#	define DESCRIPTOR_BUSYTSS32	0x0b
+#	define DESCRIPTOR_CALLGATE32	0x0c
+#	define DESCRIPTOR_INTGATE32	0x0e
+#	define DESCRIPTOR_TRAPGATE32	0x0f
+#	define DESCRIPTOR_DATA_RO	0x10
+#	define DESCRIPTOR_DATA_RO_ACC	0x11
+#	define DESCRIPTOR_DATA_RW	0x12
+#	define DESCRIPTOR_DATA_RW_ACC	0x13
+#	define DESCRIPTOR_DOWN_RO	0x14
+#	define DESCRIPTOR_DOWN_RO_ACC	0x15
+#	define DESCRIPTOR_DOWN_RW	0x16
+#	define DESCRIPTOR_DOWN_RW_ACC	0x17
+#	define DESCRIPTOR_CODE_XO	0x18
+#	define DESCRIPTOR_CODE_XO_ACC	0x19
+#	define DESCRIPTOR_CODE_XR	0x1a
+#	define DESCRIPTOR_CODE_XR_ACC	0x1b
+#	define DESCRIPTOR_CONF_XO	0x1c
+#	define DESCRIPTOR_CONF_XO_ACC	0x1d
+#	define DESCRIPTOR_CONF_XR	0x1e
+#	define DESCRIPTOR_CONF_XR_ACC	0x1f
+#define DESCRIPTOR_A		0
+#define DESCRIPTOR_W		1
+#define DESCRIPTOR_R		1
+#define DESCRIPTOR_E		2
+#define DESCRIPTOR_C		2
+#define DESCRIPTOR_CODE		3
+#define DESCRIPTOR_S		4
+#define DESCRIPTOR_DPL		5
+#define DESCRIPTOR_DPL_LEN	2
+#define DESCRIPTOR_P		7
+
+#define DESCRIPTOR_AVL		12
+#define DESCRIPTOR_D		14
+#define DESCRIPTOR_B		14
+#define DESCRIPTOR_G		15
+
+/*
+ * Error code layout (different for Page Fault)
+ */
+#define EC_EXT				0
+#define EC_IDT				1
+#define EC_TI				2
+#define EC_SELECTOR_INDEX	3
+#define EC_SELECTOR_INDEX_LEN	13
+
+/*
+ * Control Register 0
+ */
+#define CR0_MBZ			0x1ffaffc0
+#define CR0_PE				0
+#define CR0_MP				1
+#define CR0_EM				2
+#define CR0_TS				3
+#define CR0_ET				4
+#define CR0_NE				5
+#define CR0_WP				16
+#define CR0_AM				18
+#define CR0_NW				29
+#define CR0_CD				30
+#define CR0_PG				31
+
+/*
+ * Control Register 3
+ */
+#define CR3_MBZ			0x00000fe7
+#define CR3_PWT			3
+#define CR3_PCD			4
+#define CR3_PHYS			12
+#define CR3_PHYS_LEN		20
+
+#define PDBR_MBZ			CR3_MBZ
+#define PDBR_PWT			CR3_PWT
+#define PDBR_PCD			CR3_PCD
+#define PDBR_PHYS			CR3_PHYS
+#define PDBR_PHYS_LEN		CR3_PHYS_LEN
+
+#define PDPTR_MBZ			0x00000007
+#define PDPTR_PWT			CR3_PWT
+#define PDPTR_PCD			CR3_PCD
+#define PDPTR_PHYS			5
+#define PDPTR_PHYS_LEN		27
+
+/*
+ * Control Register 4
+ */
+#define CR4_MBZ			0xfffff800
+#define CR4_VME			0
+#define CR4_PVI			1
+#define CR4_TSD			2
+#define CR4_DE				3
+#define CR4_PSE			4
+#define CR4_PAE			5
+#define CR4_MCE			6
+#define CR4_PGE			7
+#define CR4_PCE			8
+#define CR4_OSFXSR			9
+#define CR4_OSXMMEXCPT		10
+
+/*
+ * Page Directory Pointer Table Entry
+ */
+#define PDPTE_MBZ			0x000001e6
+#define PDPTE_MBS			0x00000001
+#define PDPTE_PWT			3
+#define PDPTE_PCD			4
+#define PDPTE_AVL			9
+#define PDPTE_AVL_LEN		3
+#define PDPTE_PHYS			12
+#define PDPTE_PHYS_LEN		40
+
+/*
+ * Page Directory Entry
+ */
+#define PDE_MBZ			0x000001c0
+#define PDE_P				0
+#define PDE_W				1
+#define PDE_U				2
+#define PDE_PWT			3
+#define PDE_PCD			4
+#define PDE_A				5
+#define PDE_LARGE_PTE		7
+#define PDE_AVL			9
+#define PDE_AVL_LEN			3
+#define PDE_PHYS			12
+#define PDE_PHYS_LEN		40
+#define PDE_NX				63
+
+/*
+ * Page Table Entry
+ */
+#define PTE4K_MBZ			0x00000080
+#define PTE2M_MBZ			0x001fe000
+#define PTE2M_MBS			(1U << PDE_LARGE_PTE)
+#define PTE4M_MBZ			0x00000000
+#define PTE4M_MBS			(1U << PDE_LARGE_PTE)
+#define PTE_P				0
+#define PTE_W				1
+#define PTE_U				2
+#define PTE_PWT			3
+#define PTE_PCD			4
+#define PTE_A				5
+#define PTE_D				6
+#define PTE4K_PAT			7
+#define PTE_G				8
+#define PTE_AVL			9
+#define PTE_AVL_LEN			3
+#define PTE2M_PAT			12
+#define PTE4M_PAT			12
+#define PTE4K_PHYS			12
+#define PTE4K_PHYS_LEN		40
+#define PTE2M_PHYS			21
+#define PTE2M_PHYS_LEN		31
+#define PTE4M_PHYS1			13
+#define PTE4M_PHYS1_LEN			9
+#define PTE4M_PHYS			22
+#define PTE4M_PHYS_LEN			10
+#define PTE_NX				63
+
+/*
+ * Debug Register 6
+ */
+#define DR6_B0				0
+#define DR6_B1				1
+#define DR6_B2				2
+#define DR6_B3				3
+#define DR6_BD				13
+#define DR6_BS				14
+#define DR6_BT				15
+
+/*
+ * Debug Register 7
+ */
+#define DR7_RW_LEN			2
+#	define DR7_RW_X			0U
+#	define DR7_RW_W			1U
+#	define DR7_RW_IO			2U
+#	define DR7_RW_RW			3U
+#define DR7_LEN_LEN			2
+#	define DR7_LEN_1			0U
+#	define DR7_LEN_2			1U
+#	define DR7_LEN_4			3U
+#define DR7_L0				0
+#define DR7_G0				1
+#define DR7_L1				2
+#define DR7_G1				3
+#define DR7_L2				4
+#define DR7_G2				5
+#define DR7_L3				6
+#define DR7_G3				7
+#define DR7_LE				8
+#define DR7_GE				9
+#define DR7_GD				13
+#define DR7_RW0			16
+#define DR7_RW0_LEN			DR7_RW_LEN
+#define DR7_LEN0			18
+#define DR7_LEN0_LEN		DR7_LEN_LEN
+#define DR7_RW1			20
+#define DR7_RW1_LEN			DR7_RW_LEN
+#define DR7_LEN1			22
+#define DR7_LEN1_LEN		DR7_LEN_LEN
+#define DR7_RW2			24
+#define DR7_RW2_LEN			DR7_RW_LEN
+#define DR7_LEN2			26
+#define DR7_LEN2_LEN		DR7_LEN_LEN
+#define DR7_RW3			28
+#define DR7_RW3_LEN			DR7_RW_LEN
+#define DR7_LEN3			30
+#define DR7_LEN3_LEN		DR7_LEN_LEN
+
+/*
+ * CPUID return values
+ */
+#define CPUID1_EAX_STEPPING		0
+#define CPUID1_EAX_STEPPING_LEN	4
+#define CPUID1_EAX_MODEL			4
+#define CPUID1_EAX_MODEL_LEN		4
+#define CPUID1_EAX_FAMILY		8
+#define CPUID1_EAX_FAMILY_LEN		4
+#define CPUID1_EAX_TYPE			12
+#define CPUID1_EAX_TYPE_LEN		2
+#define CPUID1_EAX_XMODEL		16
+#define CPUID1_EAX_XMODEL_LEN		4
+#define CPUID1_EAX_XFAMILY		20
+#define CPUID1_EAX_XFAMILY_LEN	4
+#define CPUID1_EBX_BRAND			0
+#define CPUID1_EBX_BRAND_LEN		8
+#define CPUID1_EBX_CLFLSHSZ		8
+#define CPUID1_EBX_CLFLSHSZ_LEN	8
+#define CPUID1_EBX_LPPP			16
+#define CPUID1_EBX_LPPP_LEN		8
+#define CPUID1_EBX_LAPIC_ID		24
+#define CPUID1_EBX_LAPIC_ID_LEN	8
+#define CPUID1_ECX_SSE3			0
+#define CPUID1_ECX_MONITOR		3
+#define CPUID1_ECX_DSCPL			4
+#define CPUID1_ECX_EIST			7
+#define CPUID1_ECX_TM2			8
+#define CPUID1_ECX_CID			10
+#define CPUID1_ECX_CX16			13
+#define CPUID1_ECX_xTPR			14
+#define CPUID1_EDX_FPU			0
+#define CPUID1_EDX_VME			1
+#define CPUID1_EDX_DE			2
+#define CPUID1_EDX_PSE			3
+#define CPUID1_EDX_TSC			4
+#define CPUID1_EDX_MSR			5
+#define CPUID1_EDX_PAE			6
+#define CPUID1_EDX_MCE			7
+#define CPUID1_EDX_CX8			8
+#define CPUID1_EDX_APIC			9
+#define CPUID1_EDX_SEP			11
+#define CPUID1_EDX_MTRR			12
+#define CPUID1_EDX_PGE			13
+#define CPUID1_EDX_MCA			14
+#define CPUID1_EDX_CMOV			15
+#define CPUID1_EDX_PAT			16
+#define CPUID1_EDX_PSE36			17
+#define CPUID1_EDX_PSN			18
+#define CPUID1_EDX_CLFSH			19
+#define CPUID1_EDX_DS			21
+#define CPUID1_EDX_ACPI			22
+#define CPUID1_EDX_MMX			23
+#define CPUID1_EDX_FXSR			24
+#define CPUID1_EDX_SSE			25
+#define CPUID1_EDX_SSE2			26
+#define CPUID1_EDX_SS			27
+#define CPUID1_EDX_HTT			28
+#define CPUID1_EDX_TM			29
+#define CPUID1_EDX_IA64			30
+#define CPUID1_EDX_PBE			31
+
+#define CPUID2_RESERVED			31
+
+#define CPUIDx1_AMD_EAX_STEPPING		CPUID1_EAX_STEPPING
+#define CPUIDx1_AMD_EAX_STEPPING_LEN	CPUID1_EAX_STEPPING_LEN
+#define CPUIDx1_AMD_EAX_MODEL			CPUID1_EAX_MODEL
+#define CPUIDx1_AMD_EAX_MODEL_LEN		CPUID1_EAX_MODEL_LEN
+#define CPUIDx1_AMD_EAX_FAMILY		CPUID1_EAX_FAMILY
+#define CPUIDx1_AMD_EAX_FAMILY_LEN		CPUID1_EAX_FAMILY_LEN
+#define CPUIDx1_AMD_EAX_TYPE			CPUID1_EAX_TYPE
+#define CPUIDx1_AMD_EAX_TYPE_LEN		CPUID1_EAX_TYPE_LEN
+#define CPUIDx1_AMD_EAX_XMODEL		CPUID1_EAX_XMODEL
+#define CPUIDx1_AMD_EAX_XMODEL_LEN		CPUID1_EAX_XMODEL_LEN
+#define CPUIDx1_AMD_EAX_XFAMILY		CPUID1_EAX_XFAMILY
+#define CPUIDx1_AMD_EAX_XFAMILY_LEN	CPUID1_EAX_XFAMILY_LEN
+#define CPUIDx1_AMD_EBX_BRAND			0
+#define CPUIDx1_AMD_EBX_BRAND_LEN		16
+#define CPUIDx1_ECX_LAHF			0
+#define CPUIDx1_ECX_CMP_LEGACY	1
+#define CPUIDx1_ECX_SVM		2
+#define CPUIDx1_ECX_EXT_APIC		3
+#define CPUIDx1_ECX_LOCK_MOV_CR		4
+#define CPUIDx1_ECX_3DNOW_PREFETCH	8
+#define CPUIDx1_EDX_FPU			0
+#define CPUIDx1_EDX_VME			1
+#define CPUIDx1_EDX_DE			2
+#define CPUIDx1_EDX_PSE			3
+#define CPUIDx1_EDX_TSC			4
+#define CPUIDx1_EDX_MSR			5
+#define CPUIDx1_EDX_PAE			6
+#define CPUIDx1_EDX_MCE			7
+#define CPUIDx1_EDX_CX8			8
+#define CPUIDx1_EDX_APIC			9
+#define CPUIDx1_EDX_SCR			11
+#define CPUIDx1_EDX_MTRR			12
+#define CPUIDx1_EDX_PGE			13
+#define CPUIDx1_EDX_MCA			14
+#define CPUIDx1_EDX_CMOV			15
+#define CPUIDx1_EDX_PAT			16
+#define CPUIDx1_EDX_PSE36		17
+#define CPUIDx1_EDX_NX			20
+#define CPUIDx1_EDX_MMX			22
+#define CPUIDx1_EDX_AMDMMX		23
+#define CPUIDx1_EDX_FXSR			24
+#define CPUIDx1_EDX_FXSROPT		25
+#define CPUIDx1_EDX_RDTSCP		27
+#define CPUIDx1_EDX_LM			29
+#define CPUIDx1_EDX_AMD3DNOW		30
+#define CPUIDx1_EDX_3DNOW		31
+
+#define CPUIDx5_AMD_EAX_L1ITLB_2M_NUM		0
+#define CPUIDx5_AMD_EAX_L1ITLB_2M_NUM_LEN	8
+#define CPUIDx5_AMD_EAX_L1ITLB_2M_ASSOC		8
+#define CPUIDx5_AMD_EAX_L1ITLB_2M_ASSOC_LEN	8
+#define CPUIDx5_AMD_EAX_L1DTLB_2M_NUM		16
+#define CPUIDx5_AMD_EAX_L1DTLB_2M_NUM_LEN	8
+#define CPUIDx5_AMD_EAX_L1DTLB_2M_ASSOC		24
+#define CPUIDx5_AMD_EAX_L1DTLB_2M_ASSOC_LEN	8
+#define CPUIDx5_AMD_EBX_L1ITLB_4K_NUM		0
+#define CPUIDx5_AMD_EBX_L1ITLB_4K_NUM_LEN	8
+#define CPUIDx5_AMD_EBX_L1ITLB_4K_ASSOC		8
+#define CPUIDx5_AMD_EBX_L1ITLB_4K_ASSOC_LEN	8
+#define CPUIDx5_AMD_EBX_L1DTLB_4K_NUM		16
+#define CPUIDx5_AMD_EBX_L1DTLB_4K_NUM_LEN	8
+#define CPUIDx5_AMD_EBX_L1DTLB_4K_ASSOC		24
+#define CPUIDx5_AMD_EBX_L1DTLB_4K_ASSOC_LEN	8
+#define CPUIDx5_AMD_ECX_L1IC_LINESIZE		0
+#define CPUIDx5_AMD_ECX_L1IC_LINESIZE_LEN	8
+#define CPUIDx5_AMD_ECX_L1IC_ASSOC			8
+#define CPUIDx5_AMD_ECX_L1IC_ASSOC_LEN		8
+#define CPUIDx5_AMD_ECX_L1IC_LPT			16
+#define CPUIDx5_AMD_ECX_L1IC_LPT_LEN		8
+#define CPUIDx5_AMD_ECX_L1IC_SIZE			24
+#define CPUIDx5_AMD_ECX_L1IC_SIZE_LEN		8
+#define CPUIDx5_AMD_EDX_L1DC_LINESIZE		0
+#define CPUIDx5_AMD_EDX_L1DC_LINESIZE_LEN	8
+#define CPUIDx5_AMD_EDX_L1DC_ASSOC			8
+#define CPUIDx5_AMD_EDX_L1DC_ASSOC_LEN		8
+#define CPUIDx5_AMD_EDX_L1DC_LPT			16
+#define CPUIDx5_AMD_EDX_L1DC_LPT_LEN		8
+#define CPUIDx5_AMD_EDX_L1DC_SIZE			24
+#define CPUIDx5_AMD_EDX_L1DC_SIZE_LEN		8
+
+#define CPUIDx6_AMD_EAX_L2ITLB_2M_NUM		0
+#define CPUIDx6_AMD_EAX_L2ITLB_2M_NUM_LEN	12
+#define CPUIDx6_AMD_EAX_L2ITLB_2M_ASSOC		12
+#define CPUIDx6_AMD_EAX_L2ITLB_2M_ASSOC_LEN	4
+#define CPUIDx6_AMD_EAX_L2DTLB_2M_NUM		16
+#define CPUIDx6_AMD_EAX_L2DTLB_2M_NUM_LEN	12
+#define CPUIDx6_AMD_EAX_L2DTLB_2M_ASSOC		28
+#define CPUIDx6_AMD_EAX_L2DTLB_2M_ASSOC_LEN	4
+#define CPUIDx6_AMD_EBX_L2ITLB_4K_NUM		0
+#define CPUIDx6_AMD_EBX_L2ITLB_4K_NUM_LEN	12
+#define CPUIDx6_AMD_EBX_L2ITLB_4K_ASSOC		12
+#define CPUIDx6_AMD_EBX_L2ITLB_4K_ASSOC_LEN	4
+#define CPUIDx6_AMD_EBX_L2DTLB_4K_NUM		16
+#define CPUIDx6_AMD_EBX_L2DTLB_4K_NUM_LEN	12
+#define CPUIDx6_AMD_EBX_L2DTLB_4K_ASSOC		28
+#define CPUIDx6_AMD_EBX_L2DTLB_4K_ASSOC_LEN	4
+#define CPUIDx6_AMD_ECX_L2UC_LINESIZE		0
+#define CPUIDx6_AMD_ECX_L2UC_LINESIZE_LEN	8
+#define CPUIDx6_AMD_ECX_L2UC_ASSOC			8
+#define CPUIDx6_AMD_ECX_L2UC_ASSOC_LEN		4
+#define CPUIDx6_AMD_ECX_L2UC_LPT			12
+#define CPUIDx6_AMD_ECX_L2UC_LPT_LEN		4
+#define CPUIDx6_AMD_ECX_L2UC_SIZE			16
+#define CPUIDx6_AMD_ECX_L2UC_SIZE_LEN		16
+
+#define CPUIDx7_AMD_EDX_TS			0
+#define CPUIDx7_AMD_EDX_FID			1
+#define CPUIDx7_AMD_EDX_VID			2
+#define CPUIDx7_AMD_EDX_TTP			3
+#define CPUIDx7_AMD_EDX_TM			4
+#define CPUIDx7_AMD_EDX_STC			5
+#define CPUIDx7_AMD_EDX_100MHZ			6
+
+#define CPUIDx8_EAX_PA_BITS			0
+#define CPUIDx8_EAX_PA_BITS_LEN		8
+#define CPUIDx8_EAX_VA_BITS			8
+#define CPUIDx8_EAX_VA_BITS_LEN		16
+#define CPUIDx8_ECX_MAX_CORE			0
+#define CPUIDx8_ECX_MAX_CORE_LEN		8
+
+#define CPUIDxA_EAX_SVMREV		0
+#define CPUIDxA_EAX_SVMREV_LEN		8
+#define CPUIDxA_EAX_0			8
+#define CPUIDxA_EDX_NP			0
+
+#ifndef __ASSEMBLY__
+
+typedef union {
+	uint64_t	q;
+	uint32_t	d[2];
+	uint16_t	w[4];
+	uint8_t	b[8];
+} mmxreg_t;
+
+typedef union {
+	double	dbl[2];
+	float	flt[4];
+	uint64_t	q[2];
+	uint32_t	d[4];
+	uint16_t	w[8];
+	uint8_t	b[16];
+} xmmreg_t;
+
+/*
+ * FXSAVE / FXRSTOR layout
+ */
+typedef struct {
+	uint16_t	fcw;
+	uint16_t	fsw;
+	uint8_t	ftw;
+	uint8_t	_rsrvd1_;
+	uint16_t	fop;
+	uint32_t	fip;
+	uint16_t	fcs;
+	uint16_t	_rsrvd2_;
+	uint32_t	fdp;
+	uint16_t	fds;
+	uint16_t	_rsrvd3_;
+	uint32_t	mxcsr;
+	uint32_t	mxcsr_mask;
+	union {
+		struct {
+			uint64_t	mant;
+			uint32_t	exp:15;
+			int32_t	sign:1;
+			uint32_t	_pad_;
+		}		fp;
+		mmxreg_t	mmx;
+	}		reg[8];
+	xmmreg_t	xmm[8];
+	uint8_t	_rsrvd5_[14*16];
+} fxsave_t __attribute__((__aligned__(16)));
+
+#pragma pack(push, 2)
+
+/*
+ * FSAVE / FRSTOR layout
+ */
+typedef struct {
+	uint16_t	fcw;
+	uint16_t	_rsrvd1_;
+	uint16_t	fsw;
+	uint16_t	_rsrvd2_;
+	uint16_t	ftw;
+	uint16_t	_rsrvd3_;
+	uint32_t	fip;
+	uint16_t	fcs;
+	uint16_t	fop:11;
+	uint16_t	:5;
+	uint32_t	fdp;
+	uint16_t	fds;
+	uint16_t	_rsrvd4_;
+	union {
+		struct {
+			uint64_t	mant;
+			uint16_t	exp:15;
+			int16_t	sign:1;
+		}		fp;
+		mmxreg_t	mmx;
+	}		reg[8];
+} fsave_t;
+
+/*
+ * Descriptor Attributes
+ */
+typedef struct {
+	uint8_t	type:5;
+	uint8_t	dpl:2;
+	uint8_t	p:1;
+} DescriptorAttributes_t;
+
+/*
+ * Descriptor Table Entry
+ */
+typedef union {
+	struct {
+		uint16_t	limitLow;
+		uint16_t	baseLow;
+		uint8_t	baseMid;
+		union {
+			uint8_t	attrLow;
+			DescriptorAttributes_t attr;
+		};
+		union {
+			uint8_t	attrHigh;
+			struct {
+				uint8_t	limitHigh:4;
+				uint8_t	avl:1;
+				uint8_t	:1;
+				uint8_t	d:1;
+				uint8_t	g:1;
+			};
+		};
+		uint8_t	baseHigh;
+	}		segment;
+	struct {
+		uint16_t	offsetLow;
+		uint16_t	selector;
+		union {
+			uint16_t	control;
+			struct {
+				uint8_t	numParms:5;
+				uint8_t	:3;
+				DescriptorAttributes_t attr;
+			};
+		};
+		uint16_t	offsetHigh;
+	}		gate;
+} DescriptorTableEntry_t;
+
+#define IS_SEGMENT(d)		(((d).segment.attrLow & 0x14) != 0x04)
+#define IS_SEGMENT_EXEC(d)	(((d).segment.attrLow & ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE))) \
+							== ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE)))
+#define IS_SEGMENT_READ(d)	(((d).segment.attrLow & ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE))) \
+							== (1U << DESCRIPTOR_S) \
+						   || ((d).segment.attrLow & ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE) | (1U << DESCRIPTOR_R))) \
+							== ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE) | (1U << DESCRIPTOR_R)))
+#define IS_SEGMENT_WRITE(d)	(((d).segment.attrLow & ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_CODE) | (1U << DESCRIPTOR_W))) \
+							== ((1U << DESCRIPTOR_S) | (1U << DESCRIPTOR_W)))
+#define SEGMENT_BASE(d)		((d).segment.baseLow | ((uint32_t)(d).segment.baseMid << 16) | ((uint32_t)(d).segment.baseHigh << 24))
+#define SEGMENT_LIMIT(d)		((d).segment.g \
+							? ((uint32_t)(d).segment.limitLow << 12) | ((uint32_t)(d).segment.limitHigh << 28) | 0xfff \
+							: (d).segment.limitLow | ((uint32_t)(d).segment.limitHigh << 16))
+
+#define IS_GATE(d)			(((d).gate.control & 0x1400) == 0x0400)
+#define GATE_SELECTOR(d)		((d).gate.selector)
+#define GATE_OFFSET(d)		((d).gate.offsetLow | ((uint32_t)(d).gate.offsetHigh << 16))
+
+/*
+ * GDTR/IDTR memory format
+ */
+typedef struct {
+	uint16_t limit;
+	uint32_t base;
+} PseudoDescriptor_t;
+
+#pragma pack(pop)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * FPU Control Word
+ */
+#define FCW_MBZ					0xe0c0
+#define FCW_IM					0
+#define FCW_DM					1
+#define FCW_ZM					2
+#define FCW_OM					3
+#define FCW_UM					4
+#define FCW_PM					5
+#define FCW_PC					8
+#define FCW_PC_LEN				2
+#	define FCW_PC_SINGLE			0U
+#	define FCW_PC_DOUBLE			2U
+#	define FCW_PC_EXTENDED			3U
+#define FCW_RC					10
+#define FCW_RC_LEN				2
+/* The rounding control values are used for both FCW and MXCSR. */
+#	define RC_NEAREST				0U
+#	define RC_DOWN					1U
+#	define RC_UP					2U
+#	define RC_CHOP					3U
+#	define RC_TRUNCATE				RC_CHOP
+#define FCW_X					12
+
+/*
+ * FPU Status Word
+ */
+#define FSW_IE					0
+#define FSW_DE					1
+#define FSW_ZE					2
+#define FSW_OE					3
+#define FSW_UE					4
+#define FSW_PE					5
+#define FSW_SF					6
+#define FSW_ES					7
+#define FSW_C0					8
+#define FSW_C1					9
+#define FSW_C2					10
+#define FSW_TOP				11
+#define FSW_TOP_LEN				3
+#define FSW_C3					14
+#define FSW_B					15
+
+/*
+ * FPU Tag Word
+ */
+#define FTW_TAG_LEN				2
+#	define FTW_VALID				0U
+#	define FTW_ZERO				1U
+#	define FTW_SPECIAL				2U
+#	define FTW_EMPTY				3U
+
+/*
+ * MMX Control and Status Register
+ */
+#define MXCSR_IE				0
+#define MXCSR_DE				1
+#define MXCSR_ZE				2
+#define MXCSR_OE				3
+#define MXCSR_UE				4
+#define MXCSR_PE				5
+#define MXCSR_DAZ				6
+#define MXCSR_IM				7
+#define MXCSR_DM				8
+#define MXCSR_ZM				9
+#define MXCSR_OM				10
+#define MXCSR_UM				11
+#define MXCSR_PM				12
+#define MXCSR_RC				13
+#define MXCSR_RC_LEN			2
+#define MXCSR_FZ				15
+
+#ifndef __ASSEMBLY__
+
+/*
+ * 32-bit Task State Segment layout
+ */
+typedef struct {
+	uint16_t	backlink, _backlink_pad;
+	uint32_t	esp0;
+	uint16_t	ss0, _ss0_pad;
+	uint32_t	esp1;
+	uint16_t	ss1, _ss1_pad;
+	uint32_t	esp2;
+	uint16_t	ss2, _ss2_pad;
+	union {
+		uint32_t	cr3;
+		uint32_t	pdbr;
+		uint32_t	pdptr;
+	};
+	uint32_t	eip;
+	uint32_t	eflags;
+	uint32_t	eax;
+	uint32_t	ecx;
+	uint32_t	edx;
+	uint32_t	ebx;
+	uint32_t	esp;
+	uint32_t	ebp;
+	uint32_t	esi;
+	uint32_t	edi;
+	uint16_t	es, _es_pad;
+	uint16_t	cs, _cs_pad;
+	uint16_t	ss, _ss_pad;
+	uint16_t	ds, _ds_pad;
+	uint16_t	fs, _fs_pad;
+	uint16_t	gs, _gs_pad;
+	uint16_t	ldtr, _ldtr_pad;
+	uint16_t	t:1;
+	uint16_t	iobase;
+} tss32_t;
+
+#endif
+
+/*
+ * MSR indexes
+ */
+#define IA32_TIMESTAMP_COUNTER	0x10
+#define IA32_PLATFORM_ID			0x17
+#define IA32_APIC_BASE			0x1b
+#define IA32_BIOS_UPDATE_TRIG		0x79
+#define IA32_BIOS_SIGN_ID		0x8b
+#define IA32_MTRRCAP			0xfe
+#define IA32_MISC_CTL			0x119
+#define IA32_SYSENTER_CS			0x174
+#define IA32_SYSENTER_ESP		0x175
+#define IA32_SYSENTER_EIP		0x176
+#define IA32_MCG_CAP			0x179
+#define IA32_MCG_STATUS			0x17a
+#define IA32_MCG_CTL			0x17b
+#define IA32_MCG_EAX			0x180
+#define IA32_MCG_EBX			0x181
+#define IA32_MCG_ECX			0x182
+#define IA32_MCG_EDX			0x183
+#define IA32_MCG_ESI			0x184
+#define IA32_MCG_EDI			0x185
+#define IA32_MCG_EBP			0x186
+#define IA32_MCG_ESP			0x187
+#define IA32_MCG_EFLAGS			0x188
+#define IA32_MCG_EIP			0x189
+#define IA32_MCG_MISC			0x18a
+#define IA32_TERM_CONTROL		0x19a
+#define IA32_TERM_INTERRUPT		0x19b
+#define IA32_TERM_STATUS			0x19c
+#define IA32_MISC_ENAB			0x1a0
+#define IA32_DEBUGCTL			0x1d9
+#define IA32_MTRR_PHYSBASE0		0x200
+#define IA32_MTRR_PHYSMASK0		0x201
+#define IA32_MTRR_FIX64K_00000	0x250
+#define IA32_MTRR_FIX16K_80000	0x258
+#define IA32_MTRR_FIX16K_A0000	0x259
+#define IA32_MTRR_FIX4K_C0000		0x268
+#define IA32_MTRR_FIX4K_C8000		0x269
+#define IA32_MTRR_FIX4K_D0000		0x26a
+#define IA32_MTRR_FIX4K_D8000		0x26b
+#define IA32_MTRR_FIX4K_E0000		0x26c
+#define IA32_MTRR_FIX4K_E8000		0x26d
+#define IA32_MTRR_FIX4K_F0000		0x26e
+#define IA32_MTRR_FIX4K_F8000		0x26f
+#define IA32_CR_PAT				0x277
+#define IA32_MTRR_DEFTYPE		0x2ff
+#define IA32_PEBS_ENABLE			0x3f1
+#define IA32_MCi_START			0x400
+#	define IA32_MCi_STEP			4
+#	define IA32_MCi_CTL_OFFSET		0
+#	define IA32_MCi_STATUS_OFFSET		1
+#	define IA32_MCi_ADDR_OFFSET		2
+#	define IA32_MCi_MISC_OFFSET		3
+#define IA32_DTES_AREA			0x600
+
+/*
+ * IA32_APIC_BASE
+ */
+#define APIC_BASE_BSP			8
+#define APIC_BASE_ENABLE			11
+#define APIC_BASE_BASE			12
+#define APIC_BASE_BASE_LEN		24
+
+/*
+ * IA32_MTRRCAP
+ */
+#define MTRRCAP_VCNT			0
+#define MTRRCAP_VCNT_LEN			8
+#define MTRRCAP_FIX				8
+#define MTRRCAP_WC				10
+
+/*
+ * IA32_DEBUGCTL
+ */
+#define DEBUGCTL_LBR			0
+#define DEBUGCTL_BTF			1
+
+/*
+ * IA32_MTRR_DEFTYPE
+ */
+#define MTRR_DEFTYPE_TYPE		0
+#define MTRR_DEFTYPE_TYPE_LEN		8
+#define MTRR_DEFTYPE_FE			10
+#define MTRR_DEFTYPE_E			11
+
+/*
+ * IA32_MTRR_PHYSBASEx
+ */
+#define MTRR_PHYSBASE_TYPE		0
+#define MTRR_PHYSBASE_TYPE_LEN	8
+#define MTRR_PHYSBASE_BASE		12
+#define MTRR_PHYSBASE_BASE_LEN	24
+
+/*
+ * IA32_MTRR_PHYSMASKx
+ */
+#define MTRR_PHYSMASK_V			11
+#define MTRR_PHYSMASK_MASK		12
+#define MTRR_PHYSMASK_MASK_LEN	24
+
+/*
+ * Memory Attributes (MTRRs & PAT)
+ */
+#define IA32_MA_UC				0x00
+#define IA32_MA_WC				0x01
+#define IA32_MA_WT				0x04
+#define IA32_MA_WP				0x05
+#define IA32_MA_WB				0x06
+#define IA32_MA_UC_MINUS			0x07		/* PAT only */
+
+/*
+ * IA32_MCG_CAP
+ */
+#define IA32_MCG_CAP_COUNT		0
+#define IA32_MCG_CAP_COUNT_LEN	8
+#define IA32_MCG_CTL_P			8
+
+/*
+ * IA32_MCG_STATUS
+ */
+#define IA32_MCG_STATUS_RIPV		0
+#define IA32_MCG_STATUS_EIPV		1
+#define IA32_MCG_STATUS_MCIP		2
+
+/*
+ * IA32_MCi
+ */
+#define IA32_MCi_STATUS_MCA_EC	0
+#define IA32_MCi_STATUS_MCA_EC_LEN	16
+#define IA32_MCi_STATUS_MOD_EC	16
+#define IA32_MCi_STATUS_MOD_EC_LEN	16
+#define IA32_MCi_STATUS_PCC		57
+#define IA32_MCi_STATUS_ADDRV		58
+#define IA32_MCi_STATUS_MISCV		59
+#define IA32_MCi_STATUS_EN		60
+#define IA32_MCi_STATUS_UC		61
+#define IA32_MCi_STATUS_OVER		62
+#define IA32_MCi_STATUS_VAL		63
+
+#endif /* _ASM_IA_32_H */

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 25/39] NLKD/x86-64 - core
  2005-11-09 14:19                           ` [PATCH 23/39] NLKD/x86 " Jan Beulich
  2005-11-09 14:20                             ` [PATCH 24/39] NLKD/i386 " Jan Beulich
@ 2005-11-09 14:21                             ` Jan Beulich
  2005-11-10 13:30                               ` Andi Kleen
  1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:21 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 108 bytes --]

The core x86-64 NLKD additions.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-x86_64.patch --]
[-- Type: application/octet-stream, Size: 47902 bytes --]

The core x86-64 NLKD additions.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/arch/x86_64/Kconfig.debug
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/Kconfig.debug	2005-11-09 11:12:39.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/Kconfig.debug	2005-11-04 16:19:33.000000000 +0100
@@ -1,6 +1,7 @@
 menu "Kernel hacking"
 
 source "lib/Kconfig.debug"
+source "debug/Kconfig"
 
 # !SMP for now because the context switch early causes GPF in segment reloading
 # and the GS base checking does the wrong thing then, causing a hang.
Index: 2.6.14-nlkd/arch/x86_64/kernel/asm-offsets.c
===================================================================
--- 2.6.14-nlkd.orig/arch/x86_64/kernel/asm-offsets.c	2005-11-04 17:14:08.000000000 +0100
+++ 2.6.14-nlkd/arch/x86_64/kernel/asm-offsets.c	2005-11-04 17:14:08.000000000 +0100
@@ -14,6 +14,13 @@
 #include <asm/segment.h>
 #include <asm/thread_info.h>
 #include <asm/ia32.h>
+#ifdef CONFIG_NLKD
+# include <asm/fta-frame.h>
+# include <asm/fta-type.h>
+#endif
+#if defined(CONFIG_CDE) || defined(CONFIG_CDE_MODULE)
+# include <../debug/nlkd/cdelock.h>
+#endif
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -39,6 +46,7 @@ int main(void)
 	ENTRY(kernelstack); 
 	ENTRY(oldrsp); 
 	ENTRY(pcurrent); 
+	ENTRY(data_offset);
 	ENTRY(irqcount);
 	ENTRY(cpunumber);
 	ENTRY(irqstackptr);
@@ -65,9 +73,71 @@ int main(void)
 	DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
 	DEFINE(pbe_next, offsetof(struct pbe, next));
 	BLANK();
+#define ENTRY(f) DEFINE(TSS_##f, offsetof (struct tss_struct, f))
+	ENTRY(rsp0);
+	ENTRY(rsp1);
+	ENTRY(rsp2);
+	ENTRY(ist);
+#undef ENTRY
+	BLANK();
 	DEFINE(EXCEPTION_STACK_SIZE, EXCEPTION_STKSZ);
 #if DEBUG_STKSZ > EXCEPTION_STKSZ
 	DEFINE(DEBUG_IST, DEBUG_STACK);
 #endif
+#ifdef CONFIG_NLKD
+	DEFINE(NMI_IST, NMI_STACK);
+	BLANK();
+# define FRAME_TYPE(t) DEFINE(AMD64_##t, AMD64_##t)
+	FRAME_TYPE(DIVIDE_ERROR);
+	FRAME_TYPE(DEBUG);
+	FRAME_TYPE(NMI);
+	FRAME_TYPE(BREAKPOINT);
+	FRAME_TYPE(OVERFLOW);
+	FRAME_TYPE(BOUNDS_CHECK);
+	FRAME_TYPE(ILLEGAL_OPCODE);
+	FRAME_TYPE(DEVICE_NOT_AVAILABLE);
+	FRAME_TYPE(DOUBLE_FAULT);
+	FRAME_TYPE(INVALID_TSS);
+	FRAME_TYPE(SEGMENT_NOT_PRESENT);
+	FRAME_TYPE(STACK_FAULT);
+	FRAME_TYPE(GENERAL_PROTECTION_FAULT);
+	FRAME_TYPE(PAGE_FAULT);
+	FRAME_TYPE(FP_ERROR);
+	FRAME_TYPE(ALIGNMENT_CHECK);
+	FRAME_TYPE(MACHINE_CHECK);
+	FRAME_TYPE(SIMD_FP_ERROR);
+	BLANK();
+# undef FRAME_TYPE
+# define FRAME_DEF(f) DEFINE(FRAME_##f, offsetof (struct ftaInterruptionCtx_s, f))
+	FRAME_DEF(type);
+	FRAME_DEF(sub_type);
+	FRAME_DEF(state);
+	FRAME_DEF(es);
+	FRAME_DEF(ds);
+	FRAME_DEF(fs);
+	FRAME_DEF(gs);
+	FRAME_DEF(ldtr);
+	FRAME_DEF(tr);
+	FRAME_DEF(fs_base);
+	FRAME_DEF(gs_base);
+	FRAME_DEF(cr0);
+	FRAME_DEF(cr2);
+	FRAME_DEF(cr3);
+	FRAME_DEF(cr4);
+	FRAME_DEF(cr8);
+	FRAME_DEF(dr7);
+	FRAME_DEF(debugCtl);
+	FRAME_DEF(ec);
+	FRAME_DEF(pt_regs);
+	FRAME_DEF(fp_mmx_xmm);
+# undef FRAME_DEF
+#endif
+#if defined(CONFIG_CDE) || defined(CONFIG_CDE_MODULE)
+	BLANK();
+	DEFINE(CDESPINLOCK_signature, offsetof (cdeSpinLock_t, cdeSpinLockSignature));
+	DEFINE(CDESPINLOCK_cpu,       offsetof (cdeSpinLock_t, cdeSpinLockCpu));
+	DEFINE(CDE_VALID_SPINLOCK_SIGNATURE, CDE_VALID_SPINLOCK_SIGNATURE);
+	DEFINE(CDE_SPINLOCK_NOT_OWNED,       CDE_SPINLOCK_NOT_OWNED);
+#endif
 	return 0;
 }
Index: 2.6.14-nlkd/debug/nlkd/asm-amd64.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/asm-amd64.h	2005-11-07 12:11:27.000000000 +0100
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ *
+ *   File Name:      asm-amd64.h
+ *   Created by:     Jan Beulich
+ *   %version:       7 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 04:13:21 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved                  *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#if defined(__ASSEMBLY__) && !defined(ASM_AMD64_H)
+#define ASM_AMD64_H
+
+#include <linux/config.h>
+#include <linux/version.h>
+
+#ifdef CONFIG_UNWIND_INFO
+.equiv eh.rax, 0
+.equiv eh.rcx, 1
+.equiv eh.rdx, 2
+.equiv eh.rbx, 3
+.equiv eh.rsp, 4
+.equiv eh.rbp, 5
+.equiv eh.rsi, 6
+.equiv eh.rdi, 7
+.equiv eh.r8, 8
+.equiv eh.r9, 9
+.equiv eh.r10, 10
+.equiv eh.r11, 11
+.equiv eh.r12, 12
+.equiv eh.r13, 13
+.equiv eh.r14, 14
+.equiv eh.r15, 15
+.equiv eh.es, 16
+.equiv eh.cs, 17
+.equiv eh.ss, 18
+.equiv eh.ds, 19
+.equiv eh.fs, 20
+.equiv eh.gs, 21
+
+# define SP rsp
+# define BP rbp
+# define FLAGS rflags
+.equiv .eh.stkword, qword
+.equiv .eh.preserved, (1 << eh.rbx) | (1 << eh.rbp) | (1 << eh.r12) | (1 << eh.r13) | (1 << eh.r14) | (1 << eh.r15) \
+                      | (1 << eh.es) | (1 << eh.cs) | (1 << eh.ds) | (1 << eh.ss) | (1 << eh.fs) | (1 << eh.gs)
+#endif
+
+#include "asm-x86.h"
+
+.ifndef PROCEDURE_ALIGN
+ .equiv PROCEDURE_ALIGN, 0x10
+.endif
+
+.macro load sreg:req, loc:req, aux:req
+	LOCAL set, adj, skip
+set:
+	mov	sreg, loc
+skip:
+ .section .fixup, "ax"
+adj:
+	xor	aux, aux
+ .ifeqs "gs", "&sreg"
+ 	swapgs
+ .endif
+	mov	sreg, aux
+	jmp	skip
+ .previous
+ .section __ex_table, "a"
+ .align	qword
+ .quad	set, adj
+ .previous
+.endm
+
+#endif /* ASM_AMD64_H */
Index: 2.6.14-nlkd/debug/nlkd/nlkdAMD64.S
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/nlkdAMD64.S	2005-10-07 17:18:42.000000000 +0200
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ *
+ *   File Name:      nlkdAMD64.S
+ *   Created by:     jbeulich
+ *   %version:       2 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Fri Oct 07 09:18:32 2005 %
+ *
+ ****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	 File Description:
+ *
+ ****************************************************************************/
+
+.equiv PROCEDURE_ALIGN, 1
+#include "asm-amd64.h"
+#include <linux/nlkd.h>
+
+//todo .file "nlkd"
+.text
+
+// void nlkdDebugEvent(nint_t eventCode, ...);
+.pubproc nlkdDebugEvent
+	cmp	dword ptr [rip+nlkdAgentCount], 0
+	jg	0f
+	test	di, di
+	jg	1f
+0:
+	movsx	eax, di
+	mov	rdi, rsi
+	mov	rsi, rdx
+	mov	rdx, rcx
+	mov	rcx, r8
+	mov	r8, r9
+ .hidentry _nlkdEnterDebuggerInstruction_
+	int	3
+1:
+	ret
+.endp nlkdDebugEvent
+// void nlkdEnterDebugger(void);
+.pubproc nlkdEnterDebugger
+	mov	eax, DEBUG_EVENT_ENTER_DEBUGGER
+	jmp	_nlkdEnterDebuggerInstruction_
+.endp nlkdEnterDebugger
+// void nlkdPanic(const char*string, ...);
+.pubproc nlkdPanic
+	mov	eax, DEBUG_EVENT_PANIC
+	jmp	_nlkdEnterDebuggerInstruction_
+.endp nlkdPanic
+// void nlkdAssert(const char*string, const char*file, const char*func, nuint_t line);
+.pubproc nlkdAssert
+	mov	eax, DEBUG_EVENT_ASSERT
+	jmp	_nlkdEnterDebuggerInstruction_
+.endp nlkdAssert
Index: 2.6.14-nlkd/debug/nlkd/nlkdAMD64.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/nlkdAMD64.h	2005-10-10 14:50:39.000000000 +0200
@@ -0,0 +1,55 @@
+/*****************************************************************************
+ *
+ *   File Name:      nlkdAMD64.h
+ *   Created by:     Jan Beulich
+ *   %version:       1 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Oct 10 06:50:19 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#ifndef CONFIG_CDE
+static void _set_debugreg(uintptr_t value, nuint_t regnum) {
+	switch(regnum) {
+	case 0: __asm__("movq %0,%%db0" : : "r" (value)); break;
+	case 1: __asm__("movq %0,%%db1" : : "r" (value)); break;
+	case 2: __asm__("movq %0,%%db2" : : "r" (value)); break;
+	case 3: __asm__("movq %0,%%db3" : : "r" (value)); break;
+	case 6: __asm__("movq %0,%%db6" : : "r" (value)); break;
+	case 7: __asm__("movq %0,%%db7" : : "r" (value)); break;
+	}
+}
+static int _disable_debugreg(struct pt_regs *regs, nuint_t regnum)
+{
+	_set_debugreg(0, 7);
+}
+static int _restore_debugreg(void)
+{
+	_set_debugreg(current->thread.debugreg7, 7);
+}
+#endif
Index: 2.6.14-nlkd/include/asm-x86_64/fta-frame.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/asm-x86_64/fta-frame.h	2005-11-03 11:51:11.000000000 +0100
@@ -0,0 +1,216 @@
+/*****************************************************************************
+ *
+ *   File Name:      fta-frame.h
+ *   Created by:     Clyde Griffin
+ *   Date created:   1/1/1999
+ *
+ *   %version:       8 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 03:50:57 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *  This module contains the definition of a trap frame.
+ *
+ *****************************************************************************/
+
+#ifndef _ASM_X86_64_FTA_FRAME_H
+#define _ASM_X86_64_FTA_FRAME_H
+
+/* values for ftaInterruptionCtx_s.state */
+# ifdef CONFIG_NLKD_FTA
+#  define FRAME_COMPLETE_BIT 0
+#  define FRAME_COMPLETE (1 << FRAME_COMPLETE_BIT)
+#  define FRAME_NESTED_BIT 1
+#  define FRAME_NESTED (1 << FRAME_NESTED_BIT)
+# endif
+
+# include <asm/ptrace.h>
+# include <asm/x86_64.h>
+
+# ifndef __ASSEMBLY__
+
+struct ftaInterruptionCtx_s {
+	uint32_t	type;		/* Trap type */
+	int16_t	sub_type;		/* Extended type */
+	uint16_t	state;		/* Framework/Debugger only */
+	uint64_t	ec;			/* Error code */
+	uint64_t	cr0;
+	uint64_t	cr4;
+	uint64_t	cr2;
+	uint64_t	cr3;
+	uint64_t	debugCtl;
+	uint64_t	dr7;
+	uint16_t	ldtr;
+	uint16_t	tr;
+	uint32_t	_spare_;
+	uint16_t	ds;
+	uint16_t	es;
+	uint16_t	fs;
+	uint16_t	gs;
+	uint64_t	fs_base;
+	uint64_t	gs_base;
+	fxsave_t	fp_mmx_xmm;
+	uint64_t	cr8;
+	union {
+		struct pt_regs pt_regs;
+		struct {
+			union {
+				uint64_t	r15;
+				uint32_t	r15d;
+				uint16_t	r15w;
+				uint8_t	r15b;
+			};
+			union {
+				uint64_t	r14;
+				uint32_t	r14d;
+				uint16_t	r14w;
+				uint8_t	r14b;
+			};
+			union {
+				uint64_t	r13;
+				uint32_t	r13d;
+				uint16_t	r13w;
+				uint8_t	r13b;
+			};
+			union {
+				uint64_t	r12;
+				uint32_t	r12d;
+				uint16_t	r12w;
+				uint8_t	r12b;
+			};
+			union {
+				uint64_t	rbp;
+				uint32_t	ebp;
+				uint16_t	bp;
+				uint8_t	bpl;
+			};
+			union {
+				uint64_t	rbx;
+				uint32_t	ebx;
+				uint16_t	bx;
+				struct {
+					uint8_t	bl;
+					uint8_t	bh;
+				};
+			};
+			union {
+				uint64_t	r11;
+				uint32_t	r11d;
+				uint16_t	r11w;
+				uint8_t	r11b;
+			};
+			union {
+				uint64_t	r10;
+				uint32_t	r10d;
+				uint16_t	r10w;
+				uint8_t	r10b;
+			};
+			union {
+				uint64_t	r9;
+				uint32_t	r9d;
+				uint16_t	r9w;
+				uint8_t	r9b;
+			};
+			union {
+				uint64_t	r8;
+				uint32_t	r8d;
+				uint16_t	r8w;
+				uint8_t	r8b;
+			};
+			union {
+				uint64_t	rax;
+				uint32_t	eax;
+				uint16_t	ax;
+				struct {
+					uint8_t	al;
+					uint8_t	ah;
+				};
+			};
+			union {
+				uint64_t	rcx;
+				uint32_t	ecx;
+				uint16_t	cx;
+				struct {
+					uint8_t	cl;
+					uint8_t	ch;
+				};
+			};
+			union {
+				uint64_t	rdx;
+				uint32_t	edx;
+				uint16_t	dx;
+				struct {
+					uint8_t	dl;
+					uint8_t	dh;
+				};
+			};
+			union {
+				uint64_t	rsi;
+				uint32_t	esi;
+				uint16_t	si;
+				uint8_t	sil;
+			};
+			union {
+				uint64_t	rdi;
+				uint32_t	edi;
+				uint16_t	di;
+				uint8_t	dil;
+			};
+			union {
+				uint64_t	orig_rax;
+#  ifdef CONFIG_NLKD_FTA
+				uint64_t	_ec_raw;
+#  endif
+			};
+			union {
+				uint64_t	rip;
+				uint32_t	eip;
+			};
+			uint16_t	cs, _cs_pad[3];
+			union {
+				uint64_t	rflags;
+				uint32_t	eflags;
+				uint16_t	flags;
+			};
+			union {
+				uint64_t	rsp;
+				uint32_t	esp;
+				uint16_t	sp;
+				uint8_t	spl;
+			};
+			uint16_t	ss, _ss_pad[3];
+		};
+#  ifdef CONFIG_NLKD_FTA
+	};
+#   define FRAME_PTREGS(frame, field) (frame)->field
+#  else
+	} *pt_regs;
+#   define FRAME_PTREGS(frame, field) (frame)->pt_regs->field
+#  endif
+};
+# endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_X86_64_FTA_FRAME_H */
Index: 2.6.14-nlkd/include/asm-x86_64/fta-type.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/asm-x86_64/fta-type.h	2005-06-27 14:04:21.000000000 +0200
@@ -0,0 +1,89 @@
+/*****************************************************************************
+ *
+ *   File Name:      fta-type.h
+ *   Created by:     Clyde Griffin
+ *   Date created:   1/1/1999
+ *
+ *   %version:       5 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 05:11:34 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *  This module contains the definition of a trap frame.
+ *
+ *****************************************************************************/
+
+#ifndef _ASM_X86_64_FTA_TYPE_H
+#define _ASM_X86_64_FTA_TYPE_H
+
+/*
+ * ftaInterruptionId_t
+ *
+ * ftaInterruptionId_t uniquely identifies each type of interruption.
+ *
+ * NOTE:
+ *    Interruption frames may be different for faults, traps, external
+ *    interrupts and aborts.  The consumer of an interruption frame
+ *    needs to be aware of which interruption types are associated with
+ *    with interruption frame types.
+ */
+enum ftaInterruptionId_e
+{
+	AMD64_DIVIDE_ERROR,
+	AMD64_DEBUG,
+	AMD64_NMI,
+	AMD64_BREAKPOINT,
+	AMD64_OVERFLOW,				/* compatibility mode only */
+	AMD64_BOUNDS_CHECK,				/* compatibility mode only */
+	AMD64_ILLEGAL_OPCODE,
+	AMD64_DEVICE_NOT_AVAILABLE,
+	AMD64_DOUBLE_FAULT,
+	AMD64_RSVD_09,
+	AMD64_INVALID_TSS,
+	AMD64_SEGMENT_NOT_PRESENT,
+	AMD64_STACK_FAULT,
+	AMD64_GENERAL_PROTECTION_FAULT,
+	AMD64_PAGE_FAULT,
+	AMD64_RSVD_0F,
+	AMD64_FP_ERROR,
+	AMD64_ALIGNMENT_CHECK,
+	AMD64_MACHINE_CHECK,
+	AMD64_SIMD_FP_ERROR,
+	AMD64_RSVD_14,
+	AMD64_RSVD_15,
+	AMD64_RSVD_16,
+	AMD64_RSVD_17,
+	AMD64_RSVD_18,
+	AMD64_RSVD_19,
+	AMD64_RSVD_1A,
+	AMD64_RSVD_1B,
+	AMD64_RSVD_1C,
+	AMD64_RSVD_1D,
+	AMD64_RSVD_1E,
+	AMD64_RSVD_1F
+};
+
+#endif /* _ASM_X86_64_FTA_TYPE_H */
Index: 2.6.14-nlkd/include/asm-x86_64/x86_64.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/asm-x86_64/x86_64.h	2005-11-03 11:51:44.000000000 +0100
@@ -0,0 +1,934 @@
+/*****************************************************************************
+ *
+ *   File Name:      x86_64.h
+ *   Created by:     Jan Beulich
+ *   Date created:   Wed Aug 28 02:58:50 2002
+ *
+ *   %version:       9 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 03:51:31 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#ifndef _ASM_X86_64_X86_64_H
+#define _ASM_X86_64_X86_64_H
+
+#ifdef __ASSEMBLY__
+# define UINT64_C(v) (v)
+#else
+# include <linux/types.h>
+#endif
+
+/*
+ * RFLAGS
+ */
+#define RFLAGS_MBZ			UINT64_C(0xffffffffffc08028)
+#define RFLAGS_MBS			UINT64_C(0x0000000000000002)
+#define RFLAGS_CF			0
+#define RFLAGS_PF			2
+#define RFLAGS_AF			4
+#define RFLAGS_ZF			6
+#define RFLAGS_SF			7
+#define RFLAGS_TF			8
+#define RFLAGS_IF			9
+#define RFLAGS_DF			10
+#define RFLAGS_OF			11
+#define RFLAGS_IOPL			12
+#define RFLAGS_IOPL_LEN		2
+#define RFLAGS_NT			14
+#define RFLAGS_RF			16
+#define RFLAGS_VM			17
+#define RFLAGS_AC			18
+#define RFLAGS_VIF			19
+#define RFLAGS_VIP			20
+#define RFLAGS_ID			21
+
+/*
+ * Privilege levels
+ */
+#define PL_KERNEL			0
+#define PL_USER			3
+
+/*
+ * Selector layout
+ */
+#define SELECTOR_RPL		0
+#define SELECTOR_RPL_LEN		2
+#define SELECTOR_TI			2
+#define SELECTOR_INDEX		3
+#define SELECTOR_INDEX_LEN	13
+
+/*
+ * Descriptor Attributes
+ */
+#define DESCRIPTOR_TYPE		0
+#define DESCRIPTOR_TYPE_LEN	5
+#	define DESCRIPTOR_INVALID	0x00
+#	define DESCRIPTOR_LDT		0x02
+#	define DESCRIPTOR_AVAILTSS	0x09
+#	define DESCRIPTOR_BUSYTSS	0x0b
+#	define DESCRIPTOR_CALLGATE	0x0c
+#	define DESCRIPTOR_INTGATE	0x0e
+#	define DESCRIPTOR_TRAPGATE	0x0f
+#	define DESCRIPTOR_DATASEG	0x10
+#	define DESCRIPTOR_CODESEG	0x18
+#	define DESCRIPTOR_CONFORMING	0x1c
+#	define DESCR32_DATA_RO		0x10
+#	define DESCR32_DATA_RO_ACC	0x11
+#	define DESCR32_DATA_RW		0x12
+#	define DESCR32_DATA_RW_ACC	0x13
+#	define DESCR32_DOWN_RO		0x14
+#	define DESCR32_DOWN_RO_ACC	0x15
+#	define DESCR32_DOWN_RW		0x16
+#	define DESCR32_DOWN_RW_ACC	0x17
+#	define DESCR32_CODE_XO		0x18
+#	define DESCR32_CODE_XO_ACC	0x19
+#	define DESCR32_CODE_XR		0x1a
+#	define DESCR32_CODE_XR_ACC	0x1b
+#	define DESCR32_CONF_XO		0x1c
+#	define DESCR32_CONF_XO_ACC	0x1d
+#	define DESCR32_CONF_XR		0x1e
+#	define DESCR32_CONF_XR_ACC	0x1f
+#define DESCR32_A			0
+#define DESCR32_W			1
+#define DESCR32_R			1
+#define DESCR32_E			2
+#define DESCRIPTOR_C		2
+#define DESCRIPTOR_CODE		3
+#define DESCRIPTOR_S		4
+#define DESCRIPTOR_DPL		5
+#define DESCRIPTOR_DPL_LEN	2
+#define DESCRIPTOR_P		7
+
+#define DESCRIPTOR_AVL		12
+#define DESCRIPTOR_L		13
+#define DESCRIPTOR_D		14
+#define DESCR32_B			14
+#define DESCR32_G			15
+
+/*
+ * Error code layout (different for Page Fault)
+ */
+#define EC_EXT				0
+#define EC_IDT				1
+#define EC_TI				2
+#define EC_SELECTOR_INDEX	3
+#define EC_SELECTOR_INDEX_LEN	13
+
+/*
+ * Control Register 0
+ */
+#define CR0_MBZ			UINT64_C(0xffffffff1ffaffc0)
+#define CR0_PE				0
+#define CR0_MP				1
+#define CR0_EM				2
+#define CR0_TS				3
+#define CR0_ET				4
+#define CR0_NE				5
+#define CR0_WP				16
+#define CR0_AM				18
+#define CR0_NW				29
+#define CR0_CD				30
+#define CR0_PG				31
+
+/*
+ * Control Register 3
+ */
+#define CR3_MBZ			UINT64_C(0x0000000000000fe7)
+#define CR3_PWT			3
+#define CR3_PCD			4
+#define CR3_PHYS			12
+#define CR3_PHYS_LEN		40
+
+/*
+ * Control Register 4
+ */
+#define CR4_MBZ			UINT64_C(0xfffffffffffff800)
+#define CR4_VME			0
+#define CR4_PVI			1
+#define CR4_TSD			2
+#define CR4_DE				3
+#define CR4_PSE			4
+#define CR4_PAE			5
+#define CR4_MCE			6
+#define CR4_PGE			7
+#define CR4_PCE			8
+#define CR4_OSFXSR			9
+#define CR4_OSXMMEXCPT		10
+
+/*
+ * Control Register 8
+ */
+#define CR8_MBZ			UINT64_C(0xfffffffffffffff0)
+#define CR8_TPR			0
+#define CR8_TPR_LEN			4
+
+/*
+ * Page Directory Pointer Table Entry
+ */
+#define PML4E_MBZ			UINT64_C(0x00000000000001c0)
+#define PML4E_P			0
+#define PML4E_W			1
+#define PML4E_U			2
+#define PML4E_PWT			3
+#define PML4E_PCD			4
+#define PML4E_A			5
+#define PML4E_AVL			9
+#define PML4E_AVL_LEN		3
+#define PML4E_PHYS			12
+#define PML4E_PHYS_LEN		40
+#define PML4E_AVL2			52
+#define PML4E_AVL2_LEN		11
+#define PML4E_NX			63
+
+/*
+ * Page Directory Pointer Table Entry
+ */
+#define PDPE_MBZ			UINT64_C(0x00000000000001c0)
+#define PDPE_P				0
+#define PDPE_W				1
+#define PDPE_U				2
+#define PDPE_PWT			3
+#define PDPE_PCD			4
+#define PDPE_A				5
+#define PDPE_AVL			9
+#define PDPE_AVL_LEN		3
+#define PDPE_PHYS			12
+#define PDPE_PHYS_LEN		40
+#define PDPE_AVL2			52
+#define PDPE_AVL2_LEN		11
+#define PDPE_NX			63
+
+/*
+ * Page Directory Entry
+ */
+#define PDE_MBZ			UINT64_C(0x00000000000001c0)
+#define PDE_P				0
+#define PDE_W				1
+#define PDE_U				2
+#define PDE_PWT			3
+#define PDE_PCD			4
+#define PDE_A				5
+#define PDE_LARGE_PTE		7
+#define PDE_AVL			9
+#define PDE_AVL_LEN			3
+#define PDE_PHYS			12
+#define PDE_PHYS_LEN		40
+#define PDE_AVL2			52
+#define PDE_AVL2_LEN		11
+#define PDE_NX				63
+
+/*
+ * Page Table Entry
+ */
+#define PTE4K_MBZ			(UINT64_C(1) << PDE_LARGE_PTE)
+#define PTE2M_MBZ			UINT64_C(0x00000000001fe000)
+#define PTE2M_MBS			(UINT64_C(1) << PDE_LARGE_PTE)
+#define PTE_P				0
+#define PTE_W				1
+#define PTE_U				2
+#define PTE_PWT			3
+#define PTE_PCD			4
+#define PTE_A				5
+#define PTE_D				6
+#define PTE4K_PAT			7
+#define PTE_G				8
+#define PTE_AVL			9
+#define PTE_AVL_LEN			3
+#define PTE2M_PAT			12
+#define PTE4K_PHYS			12
+#define PTE4K_PHYS_LEN		40
+#define PTE2M_PHYS			21
+#define PTE2M_PHYS_LEN		31
+#define PTE_AVL2			52
+#define PTE_AVL2_LEN		11
+#define PTE_NX				63
+
+/*
+ * Debug Register 6
+ */
+#define DR6_B0				0
+#define DR6_B1				1
+#define DR6_B2				2
+#define DR6_B3				3
+#define DR6_BD				13
+#define DR6_BS				14
+#define DR6_BT				15
+
+/*
+ * Debug Register 7
+ */
+#define DR7_RW_LEN			2
+#	define DR7_RW_X			0U
+#	define DR7_RW_W			1U
+#	define DR7_RW_IO			2U
+#	define DR7_RW_RW			3U
+#define DR7_LEN_LEN			2
+#	define DR7_LEN_1			0U
+#	define DR7_LEN_2			1U
+#	define DR7_LEN_4			3U
+#	define DR7_LEN_8			2U
+#define DR7_L0				0
+#define DR7_G0				1
+#define DR7_L1				2
+#define DR7_G1				3
+#define DR7_L2				4
+#define DR7_G2				5
+#define DR7_L3				6
+#define DR7_G3				7
+#define DR7_LE				8
+#define DR7_GE				9
+#define DR7_GD				13
+#define DR7_RW0			16
+#define DR7_RW0_LEN			DR7_RW_LEN
+#define DR7_LEN0			18
+#define DR7_LEN0_LEN		DR7_LEN_LEN
+#define DR7_RW1			20
+#define DR7_RW1_LEN			DR7_RW_LEN
+#define DR7_LEN1			22
+#define DR7_LEN1_LEN		DR7_LEN_LEN
+#define DR7_RW2			24
+#define DR7_RW2_LEN			DR7_RW_LEN
+#define DR7_LEN2			26
+#define DR7_LEN2_LEN		DR7_LEN_LEN
+#define DR7_RW3			28
+#define DR7_RW3_LEN			DR7_RW_LEN
+#define DR7_LEN3			30
+#define DR7_LEN3_LEN		DR7_LEN_LEN
+
+/*
+ * CPUID return values
+ */
+#define CPUID1_EAX_STEPPING		0
+#define CPUID1_EAX_STEPPING_LEN	4
+#define CPUID1_EAX_MODEL			4
+#define CPUID1_EAX_MODEL_LEN		4
+#define CPUID1_EAX_FAMILY		8
+#define CPUID1_EAX_FAMILY_LEN		4
+#define CPUID1_EAX_TYPE			12
+#define CPUID1_EAX_TYPE_LEN		2
+#define CPUID1_EAX_XMODEL		16
+#define CPUID1_EAX_XMODEL_LEN		4
+#define CPUID1_EAX_XFAMILY		20
+#define CPUID1_EAX_XFAMILY_LEN	8
+#define CPUID1_EBX_BRAND			0
+#define CPUID1_EBX_BRAND_LEN		8
+#define CPUID1_EBX_CLFLSHSZ		8
+#define CPUID1_EBX_CLFLSHSZ_LEN	8
+#define CPUID1_EBX_LPPP			16
+#define CPUID1_EBX_LPPP_LEN		8
+#define CPUID1_EBX_LAPIC_ID		24
+#define CPUID1_EBX_LAPIC_ID_LEN	8
+#define CPUID1_ECX_SSE3			0
+#define CPUID1_ECX_MONITOR		3
+#define CPUID1_ECX_DSCPL			4
+#define CPUID1_ECX_EIST			7
+#define CPUID1_ECX_TM2			8
+#define CPUID1_ECX_CID			10
+#define CPUID1_ECX_CX16			13
+#define CPUID1_ECX_xTPR			14
+#define CPUID1_EDX_FPU			0
+#define CPUID1_EDX_VME			1
+#define CPUID1_EDX_DE			2
+#define CPUID1_EDX_PSE			3
+#define CPUID1_EDX_TSC			4
+#define CPUID1_EDX_MSR			5
+#define CPUID1_EDX_PAE			6
+#define CPUID1_EDX_MCE			7
+#define CPUID1_EDX_CX8			8
+#define CPUID1_EDX_APIC			9
+#define CPUID1_EDX_SEP			11
+#define CPUID1_EDX_MTRR			12
+#define CPUID1_EDX_PGE			13
+#define CPUID1_EDX_MCA			14
+#define CPUID1_EDX_CMOV			15
+#define CPUID1_EDX_PAT			16
+#define CPUID1_EDX_PSE36			17
+#define CPUID1_EDX_PSN			18
+#define CPUID1_EDX_CLFSH			19
+#define CPUID1_EDX_DS			21
+#define CPUID1_EDX_ACPI			22
+#define CPUID1_EDX_MMX			23
+#define CPUID1_EDX_FXSR			24
+#define CPUID1_EDX_SSE			25
+#define CPUID1_EDX_SSE2			26
+#define CPUID1_EDX_SS			27
+#define CPUID1_EDX_HTT			28
+#define CPUID1_EDX_TM			29
+#define CPUID1_EDX_PBE			31
+
+#define CPUID2_RESERVED			31
+
+#define CPUIDx1_AMD_EAX_STEPPING		CPUID1_EAX_STEPPING
+#define CPUIDx1_AMD_EAX_STEPPING_LEN	CPUID1_EAX_STEPPING_LEN
+#define CPUIDx1_AMD_EAX_MODEL			CPUID1_EAX_MODEL
+#define CPUIDx1_AMD_EAX_MODEL_LEN		CPUID1_EAX_MODEL_LEN
+#define CPUIDx1_AMD_EAX_FAMILY		CPUID1_EAX_FAMILY
+#define CPUIDx1_AMD_EAX_FAMILY_LEN		CPUID1_EAX_FAMILY_LEN
+#define CPUIDx1_AMD_EAX_TYPE			CPUID1_EAX_TYPE
+#define CPUIDx1_AMD_EAX_TYPE_LEN		CPUID1_EAX_TYPE_LEN
+#define CPUIDx1_AMD_EAX_XMODEL		CPUID1_EAX_XMODEL
+#define CPUIDx1_AMD_EAX_XMODEL_LEN		CPUID1_EAX_XMODEL_LEN
+#define CPUIDx1_AMD_EAX_XFAMILY		CPUID1_EAX_XFAMILY
+#define CPUIDx1_AMD_EAX_XFAMILY_LEN	CPUID1_EAX_XFAMILY_LEN
+#define CPUIDx1_AMD_EBX_BRAND			0
+#define CPUIDx1_AMD_EBX_BRAND_LEN		16
+#define CPUIDx1_ECX_LAHF			0
+#define CPUIDx1_ECX_CMP_LEGACY	1
+#define CPUIDx1_ECX_SVM		2
+#define CPUIDx1_ECX_EXT_APIC		3
+#define CPUIDx1_ECX_LOCK_MOV_CR		4
+#define CPUIDx1_ECX_3DNOW_PREFETCH	8
+#define CPUIDx1_EDX_FPU			0
+#define CPUIDx1_EDX_VME			1
+#define CPUIDx1_EDX_DE			2
+#define CPUIDx1_EDX_PSE			3
+#define CPUIDx1_EDX_TSC			4
+#define CPUIDx1_EDX_MSR			5
+#define CPUIDx1_EDX_PAE			6
+#define CPUIDx1_EDX_MCE			7
+#define CPUIDx1_EDX_CX8			8
+#define CPUIDx1_EDX_APIC			9
+#define CPUIDx1_EDX_SCR			11
+#define CPUIDx1_EDX_MTRR			12
+#define CPUIDx1_EDX_PGE			13
+#define CPUIDx1_EDX_MCA			14
+#define CPUIDx1_EDX_CMOV			15
+#define CPUIDx1_EDX_PAT			16
+#define CPUIDx1_EDX_PSE36		17
+#define CPUIDx1_EDX_NX			20
+#define CPUIDx1_EDX_MMX			22
+#define CPUIDx1_EDX_AMDMMX		23
+#define CPUIDx1_EDX_FXSR			24
+#define CPUIDx1_EDX_FXSROPT		25
+#define CPUIDx1_EDX_RDTSCP		27
+#define CPUIDx1_EDX_LM			29
+#define CPUIDx1_EDX_AMD3DNOW		30
+#define CPUIDx1_EDX_3DNOW		31
+
+#define CPUIDx5_AMD_EAX_L1ITLB_2M_NUM		0
+#define CPUIDx5_AMD_EAX_L1ITLB_2M_NUM_LEN	8
+#define CPUIDx5_AMD_EAX_L1ITLB_2M_ASSOC		8
+#define CPUIDx5_AMD_EAX_L1ITLB_2M_ASSOC_LEN	8
+#define CPUIDx5_AMD_EAX_L1DTLB_2M_NUM		16
+#define CPUIDx5_AMD_EAX_L1DTLB_2M_NUM_LEN	8
+#define CPUIDx5_AMD_EAX_L1DTLB_2M_ASSOC		24
+#define CPUIDx5_AMD_EAX_L1DTLB_2M_ASSOC_LEN	8
+#define CPUIDx5_AMD_EBX_L1ITLB_4K_NUM		0
+#define CPUIDx5_AMD_EBX_L1ITLB_4K_NUM_LEN	8
+#define CPUIDx5_AMD_EBX_L1ITLB_4K_ASSOC		8
+#define CPUIDx5_AMD_EBX_L1ITLB_4K_ASSOC_LEN	8
+#define CPUIDx5_AMD_EBX_L1DTLB_4K_NUM		16
+#define CPUIDx5_AMD_EBX_L1DTLB_4K_NUM_LEN	8
+#define CPUIDx5_AMD_EBX_L1DTLB_4K_ASSOC		24
+#define CPUIDx5_AMD_EBX_L1DTLB_4K_ASSOC_LEN	8
+#define CPUIDx5_AMD_ECX_L1IC_LINESIZE		0
+#define CPUIDx5_AMD_ECX_L1IC_LINESIZE_LEN	8
+#define CPUIDx5_AMD_ECX_L1IC_ASSOC			8
+#define CPUIDx5_AMD_ECX_L1IC_ASSOC_LEN		8
+#define CPUIDx5_AMD_ECX_L1IC_LPT			16
+#define CPUIDx5_AMD_ECX_L1IC_LPT_LEN		8
+#define CPUIDx5_AMD_ECX_L1IC_SIZE			24
+#define CPUIDx5_AMD_ECX_L1IC_SIZE_LEN		8
+#define CPUIDx5_AMD_EDX_L1DC_LINESIZE		0
+#define CPUIDx5_AMD_EDX_L1DC_LINESIZE_LEN	8
+#define CPUIDx5_AMD_EDX_L1DC_ASSOC			8
+#define CPUIDx5_AMD_EDX_L1DC_ASSOC_LEN		8
+#define CPUIDx5_AMD_EDX_L1DC_LPT			16
+#define CPUIDx5_AMD_EDX_L1DC_LPT_LEN		8
+#define CPUIDx5_AMD_EDX_L1DC_SIZE			24
+#define CPUIDx5_AMD_EDX_L1DC_SIZE_LEN		8
+
+#define CPUIDx6_AMD_EAX_L2ITLB_2M_NUM		0
+#define CPUIDx6_AMD_EAX_L2ITLB_2M_NUM_LEN	12
+#define CPUIDx6_AMD_EAX_L2ITLB_2M_ASSOC		12
+#define CPUIDx6_AMD_EAX_L2ITLB_2M_ASSOC_LEN	4
+#define CPUIDx6_AMD_EAX_L2DTLB_2M_NUM		16
+#define CPUIDx6_AMD_EAX_L2DTLB_2M_NUM_LEN	12
+#define CPUIDx6_AMD_EAX_L2DTLB_2M_ASSOC		28
+#define CPUIDx6_AMD_EAX_L2DTLB_2M_ASSOC_LEN	4
+#define CPUIDx6_AMD_EBX_L2ITLB_4K_NUM		0
+#define CPUIDx6_AMD_EBX_L2ITLB_4K_NUM_LEN	12
+#define CPUIDx6_AMD_EBX_L2ITLB_4K_ASSOC		12
+#define CPUIDx6_AMD_EBX_L2ITLB_4K_ASSOC_LEN	4
+#define CPUIDx6_AMD_EBX_L2DTLB_4K_NUM		16
+#define CPUIDx6_AMD_EBX_L2DTLB_4K_NUM_LEN	12
+#define CPUIDx6_AMD_EBX_L2DTLB_4K_ASSOC		28
+#define CPUIDx6_AMD_EBX_L2DTLB_4K_ASSOC_LEN	4
+#define CPUIDx6_AMD_ECX_L2UC_LINESIZE		0
+#define CPUIDx6_AMD_ECX_L2UC_LINESIZE_LEN	8
+#define CPUIDx6_AMD_ECX_L2UC_ASSOC			8
+#define CPUIDx6_AMD_ECX_L2UC_ASSOC_LEN		4
+#define CPUIDx6_AMD_ECX_L2UC_LPT			12
+#define CPUIDx6_AMD_ECX_L2UC_LPT_LEN		4
+#define CPUIDx6_AMD_ECX_L2UC_SIZE			16
+#define CPUIDx6_AMD_ECX_L2UC_SIZE_LEN		16
+
+#define CPUIDx7_AMD_EDX_TS			0
+#define CPUIDx7_AMD_EDX_FID			1
+#define CPUIDx7_AMD_EDX_VID			2
+#define CPUIDx7_AMD_EDX_TTP			3
+#define CPUIDx7_AMD_EDX_TM			4
+#define CPUIDx7_AMD_EDX_STC			5
+#define CPUIDx7_AMD_EDX_100MHZ			6
+
+#define CPUIDx8_EAX_PA_BITS			0
+#define CPUIDx8_EAX_PA_BITS_LEN		8
+#define CPUIDx8_EAX_VA_BITS			8
+#define CPUIDx8_EAX_VA_BITS_LEN		16
+#define CPUIDx8_ECX_MAX_CORE			0
+#define CPUIDx8_ECX_MAX_CORE_LEN		8
+
+#define CPUIDxA_EAX_SVMREV		0
+#define CPUIDxA_EAX_SVMREV_LEN		8
+#define CPUIDxA_EAX_0			8
+#define CPUIDxA_EDX_NP			0
+
+#ifndef __ASSEMBLY__
+
+typedef union {
+	uint64_t	q;
+	uint32_t	d[2];
+	uint16_t	w[4];
+	uint8_t	b[8];
+} mmxreg_t;
+
+typedef union {
+	double	dbl[2];
+	float	flt[4];
+	uint64_t	q[2];
+	uint32_t	d[4];
+	uint16_t	w[8];
+	uint8_t	b[16];
+} xmmreg_t __attribute__((__aligned__(16)));
+
+/*
+ * FXSAVE / FXRSTOR layout
+ */
+typedef struct {
+	uint16_t	fcw;
+	uint16_t	fsw;
+	uint8_t	ftw;
+	uint8_t	_rsrvd1_;
+	uint16_t	fop;
+	union {
+		uint64_t	rip;
+		struct {
+			uint32_t	fip;
+			uint16_t	fcs;
+			uint16_t	_rsrvd2_;
+		};
+	};
+	union {
+		uint64_t	rdp;
+		struct {
+			uint32_t	fdp;
+			uint16_t	fds;
+			uint16_t	_rsrvd3_;
+		};
+	};
+	uint32_t	mxcsr;
+	uint32_t	mxcsr_mask;
+	union {
+		struct {
+			uint64_t	mant;
+			uint32_t	exp:15;
+			int32_t	sign:1;
+			uint32_t	_pad_;
+		}		fp;
+		mmxreg_t	mmx;
+	}		reg[8];
+	xmmreg_t	xmm[16];
+	uint8_t	_rsrvd5_[6*16];
+} fxsave_t;
+
+/*
+ * Descriptor Attributes
+ */
+typedef struct {
+	uint8_t	type:5;
+	uint8_t	dpl:2;
+	uint8_t	p:1;
+} DescriptorAttributes_t;
+
+/*
+ * Descriptor Table Entry
+ */
+typedef union {
+	struct {
+		uint16_t	limitLow;
+		uint16_t	baseLow;
+		uint8_t	baseMidLo;
+		union {
+			uint8_t	attrLow;
+			DescriptorAttributes_t attr;
+		};
+		union {
+			uint8_t	attrHigh;
+			struct {
+				uint8_t	limitHigh:4;
+				uint8_t	avl:1;
+				uint8_t	l:1;
+				uint8_t	d:1;
+				uint8_t	g:1;
+			};
+		};
+		uint8_t	baseMidHi;
+		uint32_t	baseHigh;
+		uint32_t	mbz;
+	}		segment;
+	struct {
+		uint16_t	offsetLow;
+		uint16_t	selector;
+		union {
+			uint16_t	control;
+			struct {
+				union {
+					struct {
+						uint8_t	ist:3;
+						uint8_t	:5;
+					};
+					struct {
+						uint8_t	numParm32:5;
+						uint8_t	:3;
+					};
+				};
+				DescriptorAttributes_t attr;
+			};
+		};
+		uint16_t	offsetMid;
+		uint32_t	offsetHigh;
+		uint32_t	mbz;
+	}		gate;
+} DescriptorTableEntry_t;
+
+# define IS_SEGMENT(d)		(((d).segment.attrLow & 0x14) != 0x04)
+# define IS_SEGMENT_EXEC(d)	(!((d).segment.attrLow & (1U << DESCRIPTOR_S)) \
+						 && ((d).segment.l || ((d).segment.attrLow & (1U << DESCR32_CODE))))
+# define IS_SEGMENT_READ(d)	(!((d).segment.attrLow & (1U << DESCRIPTOR_S)) \
+						 && ((d).segment.l \
+						  || !((d).segment.attrLow & (1U << DESCR32_CODE)) \
+						  || ((d).segment.attrLow & (1U << DESCR32_R))))
+# define IS_SEGMENT_WRITE(d)	(!((d).segment.attrLow & (1U << DESCRIPTOR_S)) \
+						 && ((d).segment.l \
+						  || (!((d).segment.attrLow & (1U << DESCR32_CODE)) \
+						   && ((d).segment.attrLow & (1U << DESCR32_W)))))
+# define SEGMENT_BASE(d)		(((d).segment.attrLow & (1U << DESCRIPTOR_S)) ? 0 : \
+						 (d).segment.baseLow | ((uint64_t)(d).segment.baseMidLo << 16) \
+						 | ((uint64_t)(d).segment.baseMidHi << 24) | ((uint64_t)(d).segment.baseHigh << 32))
+# define SEG32_BASE(d)		((d).segment.baseLow | ((uint32_t)(d).segment.baseMidLo << 16) | ((uint32_t)(d).segment.baseMidHi << 24))
+# define SEG32_LIMIT(d)		((d).segment.g \
+							? ((uint32_t)(d).segment.limitLow << 12) | ((uint32_t)(d).segment.limitHigh << 28) | 0xfff \
+							: (d).segment.limitLow | ((uint32_t)(d).segment.limitHigh << 16))
+
+# define IS_GATE(d)			(((d).gate.control & 0x1400) == 0x0400)
+# define GATE_SELECTOR(d)	((d).gate.selector)
+# define GATE_OFFSET(d)		((uint64_t)(d).gate.offsetLow | ((uint64_t)(d).gate.offsetMid << 16) | ((uint64_t)(d).gate.offsetHigh << 32))
+# define GATE32_OFFSET(d)	((uint32_t)(d).gate.offsetLow | ((uint32_t)(d).gate.offsetMid << 16))
+
+# pragma pack(push, 2)
+
+/*
+ * GDTR/IDTR memory format
+ */
+typedef struct {
+	uint16_t limit;
+	uint64_t base;
+} PseudoDescriptor_t;
+
+# pragma pack(pop)
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * FPU Control Word
+ */
+#define FCW_MBZ				0xe0c0
+#define FCW_IM					0
+#define FCW_DM					1
+#define FCW_ZM					2
+#define FCW_OM					3
+#define FCW_UM					4
+#define FCW_PM					5
+#define FCW_PC					8
+#define FCW_PC_LEN				2
+#	define FCW_PC_SINGLE			0
+#	define FCW_PC_DOUBLE			2
+#	define FCW_PC_EXTENDED			3
+#define FCW_RC					10
+#define FCW_RC_LEN				2
+/* The rounding control values are used for both FCW and MXCSR. */
+#	define RC_NEAREST				0
+#	define RC_DOWN					1
+#	define RC_UP					2
+#	define RC_CHOP					3
+#	define RC_TRUNCATE				RC_CHOP
+#define FCW_X					12
+
+/*
+ * FPU Status Word
+ */
+#define FSW_IE					0
+#define FSW_DE					1
+#define FSW_ZE					2
+#define FSW_OE					3
+#define FSW_UE					4
+#define FSW_PE					5
+#define FSW_SF					6
+#define FSW_ES					7
+#define FSW_C0					8
+#define FSW_C1					9
+#define FSW_C2					10
+#define FSW_TOP				11
+#define FSW_TOP_LEN				3
+#define FSW_C3					14
+#define FSW_B					15
+
+/*
+ * FPU Tag Word
+ */
+#define FTW_TAG_LEN				2
+#	define FTW_VALID				0U
+#	define FTW_ZERO				1U
+#	define FTW_SPECIAL				2U
+#	define FTW_EMPTY				3U
+
+/*
+ * MMX Control and Status Register
+ */
+#define MXCSR_IE				0
+#define MXCSR_DE				1
+#define MXCSR_ZE				2
+#define MXCSR_OE				3
+#define MXCSR_UE				4
+#define MXCSR_PE				5
+#define MXCSR_DAZ				6
+#define MXCSR_IM				7
+#define MXCSR_DM				8
+#define MXCSR_ZM				9
+#define MXCSR_OM				10
+#define MXCSR_UM				11
+#define MXCSR_PM				12
+#define MXCSR_RC				13
+#define MXCSR_RC_LEN			2
+#define MXCSR_FZ				15
+
+#ifndef __ASSEMBLY__
+# pragma pack(push, 4)
+
+/*
+ * 64-bit Task State Segment layout
+ */
+typedef struct {
+	uint32_t	_mbz1_;
+	uint64_t	rsp0;
+	uint64_t	rsp1;
+	uint64_t	rsp2;
+	uint64_t	_mbz2_;
+	uint64_t	ist[7];
+	uint64_t	_mbz3_;
+	uint16_t	_mbz4_;
+	uint16_t	iobase;
+} tss64_t;
+
+# pragma pack(pop)
+#endif
+
+/*
+ * MSR indexes
+ */
+#define X86_TSC				0x10
+#define X86_MTRRCAP				0xfe
+#define X86_SYSENTER_CS			0x174
+#define X86_SYSENTER_ESP			0x175
+#define X86_SYSENTER_EIP			0x176
+#define X86_MCG_CAP				0x179
+#define X86_MCG_STATUS			0x17a
+#define X86_MCG_CTL				0x17b
+#define X86_DEBUGCTL			0x1d9
+#define X86_LBF				0x1db
+#define X86_LBT				0x1dc
+#define X86_LIF				0x1dd
+#define X86_LIT				0x1de
+#define X86_MTRR_PHYSBASE0		0x200
+#define X86_MTRR_PHYSMASK0		0x201
+#define X86_MTRR_FIX64K_00000		0x250
+#define X86_MTRR_FIX16K_80000		0x258
+#define X86_MTRR_FIX16K_A0000		0x259
+#define X86_MTRR_FIX4K_C0000		0x268
+#define X86_MTRR_FIX4K_C8000		0x269
+#define X86_MTRR_FIX4K_D0000		0x26a
+#define X86_MTRR_FIX4K_D8000		0x26b
+#define X86_MTRR_FIX4K_E0000		0x26c
+#define X86_MTRR_FIX4K_E8000		0x26d
+#define X86_MTRR_FIX4K_F0000		0x26e
+#define X86_MTRR_FIX4K_F8000		0x26f
+#define X86_CR_PAT				0x277
+#define X86_MTRR_DEFTYPE			0x2ff
+#define X86_MCi_START			0x400
+#	define X86_MCi_STEP				4
+#	define X86_MCi_CTL_OFFSET		0
+#	define X86_MCi_STATUS_OFFSET		1
+#	define X86_MCi_ADDR_OFFSET		2
+#	define X86_MCi_MISC_OFFSET		3
+#define X86_EFER				0xC0000080
+#define X86_STAR				0xC0000081
+#define X86_LSTAR				0xC0000082
+#define X86_CSTAR				0xC0000083
+#define X86_SF_MASK				0xC0000084
+#define X86_FS_BASE				0xC0000100
+#define X86_GS_BASE				0xC0000101
+#define X86_KERNEL_GS_BASE		0xC0000102
+#define X86_SYSCFG				0xC0010010
+#define X86_IORRBASE0			0xC0010016
+#define X86_IORRMASK0			0xC0010017
+#define X86_IORRBASE1			0xC0010018
+#define X86_IORRMASK1			0xC0010019
+#define X86_TOP_MEM				0xC001001a
+#define X86_TOP_MEM2			0xC001001d
+
+/*
+ * X86_MTRRCAP
+ */
+#define MTRRCAP_VCNT			0
+#define MTRRCAP_VCNT_LEN			8
+#define MTRRCAP_FIX				8
+#define MTRRCAP_WC				10
+
+/*
+ * X86_DEBUGCTL
+ */
+#define DEBUGCTL_LBR			0
+#define DEBUGCTL_BTF			1
+#define DEBUGCTL_PB0			2
+#define DEBUGCTL_PB1			3
+#define DEBUGCTL_PB2			4
+#define DEBUGCTL_PB3			5
+
+/*
+ * X86_MTRR_DEFTYPE
+ */
+#define MTRR_DEFTYPE_TYPE		0
+#define MTRR_DEFTYPE_TYPE_LEN		8
+#define MTRR_DEFTYPE_FE			10
+#define MTRR_DEFTYPE_E			11
+
+/*
+ * X86_MTRR_PHYSBASEx
+ */
+#define MTRR_PHYSBASE_TYPE		0
+#define MTRR_PHYSBASE_TYPE_LEN	8
+#define MTRR_PHYSBASE_BASE		12
+#define MTRR_PHYSBASE_BASE_LEN	40
+
+/*
+ * X86_MTRR_PHYSMASKx
+ */
+#define MTRR_PHYSMASK_V			11
+#define MTRR_PHYSMASK_MASK		12
+#define MTRR_PHYSMASK_MASK_LEN	40
+
+/*
+ * Memory Attributes (MTRRs & PAT)
+ */
+#define X86_MA_UC				0x00
+#define X86_MA_WC				0x01
+#define X86_MA_WT				0x04
+#define X86_MA_WP				0x05
+#define X86_MA_WB				0x06
+#define X86_MA_UC_MINUS			0x07		/* PAT only */
+#define X86_MA_WRMEM			0x08		/* mask, fixed-range MTRRs (and IORRs) only */
+#define X86_MA_RDMEM			0x10		/* mask, fixed-range MTRRs (and IORRs) only */
+
+/*
+ * X86_MCG_CAP
+ */
+#define X86_MCG_CAP_COUNT		0
+#define X86_MCG_CAP_COUNT_LEN		8
+#define X86_MCG_CTL_P			8
+
+/*
+ * X86_MCG_STATUS
+ */
+#define X86_MCG_STATUS_RIPV		0
+#define X86_MCG_STATUS_EIPV		1
+#define X86_MCG_STATUS_MCIP		2
+
+/*
+ * X86_MCi
+ */
+#define X86_MCi_STATUS_MCA_EC		0
+#define X86_MCi_STATUS_MCA_EC_LEN	16
+#define X86_MCi_STATUS_MOD_EC		16
+#define X86_MCi_STATUS_MOD_EC_LEN	16
+#define X86_MCi_STATUS_PCC		57
+#define X86_MCi_STATUS_ADDRV		58
+#define X86_MCi_STATUS_MISCV		59
+#define X86_MCi_STATUS_EN		60
+#define X86_MCi_STATUS_UC		61
+#define X86_MCi_STATUS_OVER		62
+#define X86_MCi_STATUS_VAL		63
+
+/*
+ * X86_EFER
+ */
+#define X86_EFER_SCE			0
+#define X86_EFER_LME			8
+#define X86_EFER_LMA			10
+#define X86_EFER_NXE			11
+
+/*
+ * X86_SYSCFG
+ */
+#define X86_SYSCFG_MFDE			18
+#define X86_SYSCFG_MFDM			19
+#define X86_SYSCFG_MVDM			20
+#define X86_SYSCFG_TOM2			21
+
+/*
+ * X86_IORR_PHYSBASEx
+ */
+#define MTRR_PHYSBASE_WRMEM		3
+#define MTRR_PHYSBASE_RDMEM		4
+#define MTRR_PHYSBASE_BASE		12
+#define MTRR_PHYSBASE_LEN		40
+
+/*
+ * X86_IORR_PHYSMASKx
+ */
+#define MTRR_PHYSMASK_V			11
+#define MTRR_PHYSMASK_BASE		12
+#define MTRR_PHYSMASK_LEN		40
+
+/*
+ * X86_TOP_MEMx
+ */
+#define X86_TOP_MEM_PHYS			23
+#define X86_TOP_MEM_LEN			29
+
+#endif /* _ASM_X86_64_X86_64_H */

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 26/39] NLKD - run time library
  2005-11-09 14:18                         ` [PATCH 22/39] NLKD - core Jan Beulich
  2005-11-09 14:19                           ` [PATCH 23/39] NLKD/x86 " Jan Beulich
@ 2005-11-09 14:22                           ` Jan Beulich
  2005-11-09 14:23                             ` [PATCH 27/39] NLKD/i386 " Jan Beulich
       [not found]                             ` <437214B7.76F0.0078.0@novell.com>
  1 sibling, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:22 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 202 bytes --]

Some support definitions and routines of NLKD, the latter primarily to
isolate the debugger code from the rest of the kernel.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-rtl.patch --]
[-- Type: application/octet-stream, Size: 11462 bytes --]

Some support definitions and routines of NLKD, the latter primarily to
isolate the debugger code from the rest of the kernel.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/debug/nlkd/dbgutil.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/dbgutil.c	2005-06-27 11:57:55.000000000 +0200
@@ -0,0 +1,89 @@
+/*****************************************************************************
+ *
+ *   File Name:      dbgutil.c
+ *   Created by:     Jan Beulich
+ *   Date created:   21Jul1999
+ *
+ *   %version:       5 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 03:57:44 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#include <linux/debugrtl.h>
+
+#if !defined(_M_IA64) && !defined(__ia64__) \
+ && !defined(_M_IX86) && !defined(__i386__) \
+ && !defined(_M_AMD64) && !defined(__x86_64__)
+asmlinkage DbgQuotRemS dbgDivideS(nint_t numer, nint_t denom) {
+	DbgQuotRemS sd;
+
+	if (denom == 1)
+	{
+		sd.quot = numer;
+		sd.rem  = 0;
+	}
+	else if (denom == -1)
+	{
+		sd.quot = -numer;
+		sd.rem  = 0;
+	}
+	else
+	{
+		sd.quot = numer / denom;
+		sd.rem  = numer % denom;
+	}
+
+	return sd;
+}
+
+asmlinkage DbgQuotRemU dbgDivideU(nuint_t numer, nuint_t denom) {
+	DbgQuotRemU ud;
+
+	if (denom == 1)
+	{
+		ud.quot = numer;
+		ud.rem  = 0;
+	}
+	else
+	{
+		ud.quot = numer / denom;
+		ud.rem  = numer % denom;
+	}
+	return ud;
+}
+#endif
+
+asmlinkage char*dbgCatStr(char*dst, const char*src) {
+	dbgCopyStr(dst + dbgCountStr(dst), src);
+	return dst;
+}
+
+#include <linux/module.h>
+#define DEBUGRTL_EXPORT(type, name, ...) EXPORT_SYMBOL(name)
+#include <linux/debugrtl.h>
Index: 2.6.14-nlkd/include/linux/debugrtl.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/include/linux/debugrtl.h	2005-11-03 12:03:04.000000000 +0100
@@ -0,0 +1,170 @@
+/*****************************************************************************
+ *
+ *   File Name:      debugrtl.h
+ *   Created by:     Jan Beulich
+ *   Date created:   21Jul1999
+ *
+ *   %version:       9 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Nov 03 04:02:51 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 1999-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+#if !defined(_LINUX_DEBUGRTL_H) || defined(DEBUGRTL_EXPORT)
+
+#ifndef _LINUX_DEBUGRTL_H
+
+# include <linux/config.h>
+# include <linux/linkage.h>
+# include <linux/nint.h>
+
+# define mkalign(d, a) (((d) + ((a) - 1)) & ~((a) - 1))
+# define countof(a) (sizeof(a) / sizeof(*a))
+# define field_sizeof(t, f) (sizeof(((t*)0)->f))
+# define field_countof(t, a) (countof(((t*)0)->a))
+# define field_end(t, f) (offsetof(t, f) + field_sizeof(t, f))
+# define field_typeof(t, f) __typeof__(((t*)0)->f)
+
+# ifdef CONFIG_64BIT
+typedef uint64_t bitvec_t;
+#  define BITVEC_INDEX_SHIFT 6
+# else
+typedef uint32_t bitvec_t;
+#  define BITVEC_INDEX_SHIFT 5
+# endif
+
+# define BITVEC_INDEX_MASK ((1U << BITVEC_INDEX_SHIFT) - 1)
+
+# define BITVEC_SZ(n)	(((n) + BITVEC_INDEX_MASK) >> BITVEC_INDEX_SHIFT)
+# define BITVEC_CLR(p, n)	(((bitvec_t*)(p))[(n) >> BITVEC_INDEX_SHIFT] &= ~((bitvec_t)1 << ((n) & BITVEC_INDEX_MASK)))
+# define BITVEC_SET(p, n)	(((bitvec_t*)(p))[(n) >> BITVEC_INDEX_SHIFT] |=  ((bitvec_t)1 << ((n) & BITVEC_INDEX_MASK)))
+# define BITVEC_TST(p, n)	((((bitvec_t*)(p))[(n) >> BITVEC_INDEX_SHIFT] >> ((n) & BITVEC_INDEX_MASK)) & 1)
+
+typedef struct {
+	nint_t quot;
+	nint_t rem;
+} DbgQuotRemS;
+
+typedef struct {
+	nuint_t quot;
+	nuint_t rem;
+} DbgQuotRemU;
+
+# define DEBUGRTL_EXPORT(type, name, ...) type name(__VA_ARGS__)
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+#endif /* _LINUX_DEBUGRTL_H */
+
+DEBUGRTL_EXPORT(asmlinkage char*, dbgCatStr, char*, const char*);
+DEBUGRTL_EXPORT(asmlinkage int, dbgCompareMem, const void*, const void*, size_t);
+DEBUGRTL_EXPORT(asmlinkage int, dbgCompareStr, const char*, const char*);
+DEBUGRTL_EXPORT(           void*, dbgCopyMem, void*, const void*, size_t);
+DEBUGRTL_EXPORT(asmlinkage char*, dbgCopyStr, char*, const char*);
+DEBUGRTL_EXPORT(asmlinkage char*, dbgCopyStrP, char*, const char*);
+DEBUGRTL_EXPORT(asmlinkage unsigned, dbgCountBits, uint64_t);
+DEBUGRTL_EXPORT(asmlinkage size_t, dbgCountStr, const char*);
+DEBUGRTL_EXPORT(asmlinkage size_t, dbgCountWstr, const wchar_t*);
+DEBUGRTL_EXPORT(asmlinkage DbgQuotRemS, dbgDivideS, nint_t, nint_t);
+DEBUGRTL_EXPORT(asmlinkage DbgQuotRemU, dbgDivideU, nuint_t, nuint_t);
+DEBUGRTL_EXPORT(           void*, dbgFillMem, void*, int, size_t);
+DEBUGRTL_EXPORT(asmlinkage void*, dbgFindByte, const void*, int, size_t);
+DEBUGRTL_EXPORT(asmlinkage char*, dbgFindChar, const char*, int);
+DEBUGRTL_EXPORT(asmlinkage uint8_t*, dbgFindInt8, const uint8_t*, uint8_t, size_t);
+DEBUGRTL_EXPORT(asmlinkage uint16_t*, dbgFindInt16, const uint16_t*, uint16_t, size_t);
+DEBUGRTL_EXPORT(asmlinkage uint32_t*, dbgFindInt32, const uint32_t*, uint32_t, size_t);
+#ifdef CONFIG_64BIT
+DEBUGRTL_EXPORT(asmlinkage uint64_t*, dbgFindInt64, const uint64_t*, uint64_t, size_t);
+#endif
+DEBUGRTL_EXPORT(asmlinkage nuint_t*, dbgFindIntN, const nuint_t*, nuint_t, size_t);
+DEBUGRTL_EXPORT(asmlinkage void**, dbgFindPtr, const void*const*, const void*, size_t);
+DEBUGRTL_EXPORT(asmlinkage wchar_t*, dbgFindWchar, const wchar_t*, wchar_t);
+#undef dbgLower
+DEBUGRTL_EXPORT(asmlinkage int, dbgLower, int);
+DEBUGRTL_EXPORT(asmlinkage nint_t, dbgLog2, uint64_t);
+DEBUGRTL_EXPORT(asmlinkage uint64_t, dbgMultiply, uint64_t, uint64_t, uint64_t*overflow);
+DEBUGRTL_EXPORT(asmlinkage uint8_t, dbgRotl8, uint8_t, nuint_t);
+DEBUGRTL_EXPORT(asmlinkage uint16_t, dbgRotl16, uint16_t, nuint_t);
+DEBUGRTL_EXPORT(asmlinkage uint32_t, dbgRotl32, uint32_t, nuint_t);
+DEBUGRTL_EXPORT(asmlinkage uint64_t, dbgRotl64, uint64_t, nuint_t);
+DEBUGRTL_EXPORT(asmlinkage uint8_t, dbgRotr8, uint8_t, nuint_t);
+DEBUGRTL_EXPORT(asmlinkage uint16_t, dbgRotr16, uint16_t, nuint_t);
+DEBUGRTL_EXPORT(asmlinkage uint32_t, dbgRotr32, uint32_t, nuint_t);
+DEBUGRTL_EXPORT(asmlinkage uint64_t, dbgRotr64, uint64_t, nuint_t);
+#undef dbgUpper
+DEBUGRTL_EXPORT(asmlinkage int, dbgUpper, int);
+DEBUGRTL_EXPORT(asmlinkage char*, dbgWstr2Str, char*, const wchar_t*);
+DEBUGRTL_EXPORT(           void*, dbgZeroMem, void*, size_t);
+
+#ifndef _LINUX_DEBUGRTL_H
+
+# ifdef __cplusplus
+
+inline int dbgLower(int c) { return c >= 'A' && c <= 'Z' ? c + 'a' - 'A' : c; }
+inline int dbgUpper(int c) { return c >= 'a' && c <= 'z' ? c + 'A' - 'a' : c; }
+
+}
+
+# endif
+
+//todo The .global in the following constructs is just a workaround for a bug
+//     in binutils shipped with SL 10.0. This will *ONLY* work if the producer
+//     doesn't include this file (which currently is the case because all
+//     producers are assembly files) - otherwise we'll end up with, say, a
+//     global memcpy defined there and colliding with or overriding the real
+//     one from the kernel's strings library code.
+__asm__(".equiv memcpy, dbgCopyMem\n\t.global memcpy");
+__asm__(".equiv memset, dbgFillMem\n\t.global memset");
+
+# define DEBUGRTL_ALIAS(name) __asm__(".equiv " #name ", dbg" #name "\n\t.global " #name)
+
+# define _LINUX_DEBUGRTL_H
+
+#else
+
+# define DEBUGRTL_ALIAS(name) void dbg##name(void); DEBUGRTL_EXPORT(void, dbg##name, void)
+
+#endif /* _LINUX_DEBUGRTL_H */
+
+#ifndef __cplusplus
+# define dbgLower(c) ((c) >= 'A' && (c) <= 'Z' ? (c) + 'a' - 'A' : (c))
+# define dbgUpper(c) ((c) >= 'a' && (c) <= 'z' ? (c) + 'A' - 'a' : (c))
+#endif
+
+#if defined(__i386__)
+DEBUGRTL_ALIAS(__divdi3);
+DEBUGRTL_ALIAS(__moddi3);
+DEBUGRTL_ALIAS(__udivdi3);
+DEBUGRTL_ALIAS(__umoddi3);
+#endif
+
+#undef DEBUGRTL_ALIAS
+#undef DEBUGRTL_EXPORT
+
+#endif /* !_LINUX_DEBUGRTL_H || DEBUGRTL_EXPORT */

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 27/39] NLKD/i386 - run time library
  2005-11-09 14:22                           ` [PATCH 26/39] NLKD - run time library Jan Beulich
@ 2005-11-09 14:23                             ` Jan Beulich
  2005-11-09 14:23                               ` [PATCH 28/39] NLKD/x86-64 " Jan Beulich
       [not found]                             ` <437214B7.76F0.0078.0@novell.com>
  1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:23 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 138 bytes --]

i386-specific implementation of the support routines of NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-rtl-i386.patch --]
[-- Type: application/octet-stream, Size: 14728 bytes --]

i386-specific implementation of the support routines of NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/debug/nlkd/dbgIA32.S
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/dbgIA32.S	2005-10-05 11:37:24.000000000 +0200
@@ -0,0 +1,721 @@
+/*****************************************************************************
+ *
+ *   File Name:      dbgIA32.S
+ *   Created by:     jbeulich
+ *   %version:       10 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Wed Oct 05 01:10:16 2005 %
+ *
+ ****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2001-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	 File Description:
+ *
+ ****************************************************************************/
+
+#include <linux/config.h>
+.equiv PROCEDURE_ALIGN, 1
+#include "asm-ia32.h"
+
+//todo .file "dbgutil"
+.text
+
+// int dbgCompareMem(const void*, const void*, size_t);
+.pubproc dbgCompareMem
+	mov	ecx, [esp+3*dword]
+	EHpush	esi
+	xor	eax, eax
+	EHpush	edi
+	xor	edx, edx
+	mov	esi, [esp+3*dword]
+	mov	edi, [esp+4*dword]
+	repe cmpsb
+	seta	al
+	EHpop	edi
+	setb	dl
+	EHpop	esi
+	sub	eax, edx
+	ret
+.endp dbgCompareMem
+
+// int dbgCompareStr(const char*, const char*);
+.pubproc dbgCompareStr
+	xor	eax, eax
+	mov	ecx, [esp+dword]
+	mov	edx, [esp+2*dword]
+0:
+	mov	al, [ecx]
+	inc	ecx
+	test	al, al
+	jz	1f
+	cmp	al, [edx]
+	jne	1f
+	inc	edx
+	jmp	0b
+1:
+	movzx	edx, byte ptr [edx]
+	sub	eax, edx
+	ret
+.endp dbgCompareStr
+
+// void*dbgCopyMem(void*, const void*, size_t);
+// Note: The minimum requirements to this routine are that copying between properly
+//       aligned buffers with a suitable size will be carried out with the maximum
+//       access granularity possible.
+.pubproc dbgCopyMem
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	ecx, [esp+3*dword]
+#endif
+	EHpush	esi
+	EHpush	edi
+	test	cl, byte
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	edi, [esp+3*dword]
+	mov	esi, [esp+4*dword]
+	mov	eax, edi
+#else
+	mov	edi, eax
+	mov	esi, edx
+#endif
+	jz	0f
+	rep movsb
+	EHpushState
+	EHpop	edi
+	EHpop	esi
+	ret
+0:
+	EHpopState
+	shr	ecx, 2
+	jnc	1f
+	adc	ecx, ecx
+	.byte	0x66
+1:
+	rep movsd
+	EHpop	edi
+	EHpop	esi
+	ret
+.endp dbgCopyMem
+
+// char*dbgCopyStr(char*, const char*);
+.pubproc dbgCopyStr
+	mov	ecx, [esp+2*dword]
+	mov	edx, [esp+dword]
+	EHpush	ecx
+0:
+	mov	al, [ecx]
+	inc	ecx
+	mov	[edx], al
+	inc	edx
+	test	al, al
+	jnz	0b
+	EHpop	eax
+	ret
+.endp dbgCopyStr
+
+// char*dbgCopyStrP(char*, const char*);
+.pubproc dbgCopyStrP
+	mov	ecx, [esp+2*dword]
+	mov	edx, [esp+dword]
+0:
+	mov	al, [ecx]
+	inc	ecx
+	mov	[edx], al
+	inc	edx
+	test	al, al
+	jnz	0b
+	lea	eax, [edx-byte]
+	ret
+.endp dbgCopyStrP
+
+// unsigned dbgCountBits(uint64_t);
+.pubproc dbgCountBits
+	mov	ecx, [esp+dword]
+	mov	edx, [esp+2*dword]
+	xor	eax, eax
+0:
+	shr	ecx, 1
+	adc	eax, 0
+	shr	edx, 1
+	adc	eax, 0
+	test	ecx, ecx
+	jnz	0b
+	test	edx, edx
+	jnz	0b
+	ret
+.endp dbgCountBits
+
+// size_t dbgCountStr(const char*);
+.pubproc dbgCountStr
+	EHpush	edi
+	or	ecx, not 0
+	xor	eax, eax
+	mov	edi, [esp+2*dword]
+	repne scasb
+	add	ecx, 2
+	EHpop	edi
+	sub	eax, ecx
+	ret
+.endp dbgCountStr
+
+// size_t dbgCountWstr(const wchar_t*);
+.pubproc dbgCountWstr
+	EHpush	edi
+	or	ecx, not 0
+	xor	eax, eax
+	mov	edi, [esp+2*dword]
+	repne scasw
+	add	ecx, 2
+	EHpop	edi
+	sub	eax, ecx
+	ret
+.endp dbgCountWstr
+
+// char*dbgFindChar(const char*, char);
+.pubproc dbgFindChar
+	mov	eax, [esp+dword]
+	movzx	ecx, byte ptr [esp+2*dword]
+0:
+	movzx	edx, byte ptr [eax]
+	cmp	ecx, edx
+	je	1f
+	inc	eax
+	test	edx, edx
+	jnz	0b
+	xor	eax, eax
+0:
+	ret
+.endp dbgFindChar
+
+// wchar_t*dbgFindWchar(const wchar_t*, wchar_t);
+.pubproc dbgFindWchar
+	mov	eax, [esp+dword]
+	movzx	ecx, word ptr [esp+2*dword]
+0:
+	movzx	edx, word ptr [eax]
+	cmp	ecx, edx
+	je	1f
+	add	eax, word
+	test	edx, edx
+	jnz	0b
+	xor	eax, eax
+1:
+	ret
+.endp dbgFindWchar
+
+// char*dbgWstr2Str(char*, const wchar_t*);
+.pubproc dbgWstr2Str
+	EHpush	ebx
+	mov	bl, '?'
+	mov	ecx, [esp+3*dword]
+	mov	edx, [esp+2*dword]
+	EHpush	ecx
+0:
+	movzx	eax, word ptr [ecx]
+	add	ecx, word
+	cmp	eax, 0x7f
+	cmova	eax, ebx
+	mov	[edx], al
+	inc	edx
+	test	eax, eax
+	jnz	0b
+	EHpop	eax
+	EHpop	ebx
+	ret
+.endp dbgWstr2Str
+
+// int dbgLower(int);
+.pubproc dbgLower
+	mov	eax, [esp+dword]
+	cmp	eax, 'A'
+	jb	0f
+	cmp	eax, 'Z'
+	ja	0f
+	add	al, 'a' - 'A'
+0:
+	ret
+.endp dbgLower
+
+// int dbgUpper(int);
+.pubproc dbgUpper
+	mov	eax, [esp+dword]
+	cmp	eax, 'a'
+	jb	0f
+	cmp	eax, 'z'
+	ja	0f
+	add	al, 'A' - 'a'
+0:
+	ret
+.endp dbgUpper
+
+// void*dbgFillMem(void*, int, size_t);
+.pubproc dbgFillMem
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	ecx, [esp+3*dword]
+	mov	eax, [esp+2*dword]
+#else
+	xchg	eax, edx
+#endif
+	jmp	0f
+// void*dbgZeroMem(void*, size_t);
+.pubentry dbgZeroMem
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	ecx, [esp+2*dword]
+#else
+	mov	ecx, edx
+	mov	edx, eax
+#endif
+	xor	eax, eax
+0:
+	EHpush	edi
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	edi, [esp+2*dword]
+	EHpush	edi, FALSE
+#else
+	mov	edi, edx
+#endif
+	rep stosb
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	EHpop	eax
+#else
+	mov	eax, edx
+#endif
+	EHpop	edi
+	ret
+.endp dbgFillMem
+
+// uint8_t*dbgFindInt8(const uint8_t*, uint8_t, size_t);
+// void*dbgFindByte(const void*, int, size_t);
+.pubproc dbgFindInt8
+.pubentry dbgFindByte
+	mov	ecx, [esp+3*dword]
+	EHpush	edi
+	jecxz	0f
+	mov	edi, [esp+2*dword]
+	mov	al, [esp+3*dword]
+	repne scasb
+	lea	eax, [edi-byte]
+	je	1f
+0:
+	xor	eax, eax
+1:
+	EHpop	edi
+	ret
+.endp dbgFindInt8
+
+// uint16_t*dbgFindInt16(const uint16_t*, uint16_t, size_t);
+.pubproc dbgFindInt16
+	mov	ecx, [esp+3*dword]
+	EHpush	edi
+	jecxz	0f
+	mov	edi, [esp+2*dword]
+	mov	eax, [esp+3*dword]
+	repne scasw
+	lea	eax, [edi-word]
+	je	1f
+0:
+	xor	eax, eax
+1:
+	EHpop	edi
+	ret
+.endp dbgFindInt16
+
+// uint32_t*dbgFindInt32(const uint32_t*, uint32_t, size_t);
+// nuint_t*dbgFindIntN(const nuint_t*, nuint_t, size_t);
+// void**dbgFindPtr(const void**, const void*, size_t);
+.pubproc dbgFindInt32
+.pubentry dbgFindIntN
+.pubentry dbgFindPtr
+	mov	ecx, [esp+3*dword]
+	EHpush	edi
+	jecxz	0f
+	mov	edi, [esp+2*dword]
+	mov	eax, [esp+3*dword]
+	repne scasd
+	lea	eax, [edi-dword]
+	je	1f
+0:
+	xor	eax, eax
+1:
+	EHpop	edi
+	ret
+.endp dbgFindInt32
+
+// uint64_t dbgMultiply(uint64_t, uint64_t, uint64_t*overflow);
+.pubproc dbgMultiply
+	mov	eax, [esp+2*dword]
+	EHpush	edi
+	mov	edi, [esp+6*dword]
+	mul	dword ptr [esp+5*dword]
+	mov	[edi], eax
+	mov	eax, [esp+2*dword]
+	mov	[edi+dword], edx
+	mul	dword ptr [esp+5*dword]
+	mov	ecx, eax
+	add	[edi], edx
+	mov	eax, [esp+3*dword]
+	adc	dword ptr [edi+dword], 0
+	mul	dword ptr [esp+4*dword]
+	add	ecx, eax
+	adc	[edi], edx
+	mov	eax, [esp+2*dword]
+	adc	dword ptr [edi+dword], 0
+	mul	dword ptr [esp+4*dword]
+	add	edx, ecx
+	adc	dword ptr [edi], 0
+	add	dword ptr [edi+dword], 0
+	EHpop	edi
+	ret
+.endp dbgMultiply
+
+// nint_t dbgLog2(uint64_t)
+.pubproc dbgLog2
+	bsr	eax, [esp+2*dword]
+	lea	eax, [eax+32]
+	jnz	0f
+	bsr	eax, [esp+1*dword]
+	jnz	0f
+	or	eax, not 0
+0:
+	ret
+.endp dbgLog2
+
+// uint8_t dbgRotl8(uint8_t, nuint_t);
+.pubproc dbgRotl8
+	mov	cl, [esp+2*dword]
+	mov	al, [esp+dword]
+	rol	al, cl
+	ret
+.endp dbgRotl8
+
+// uint8_t dbgRotr8(uint8_t, nuint_t);
+.pubproc dbgRotr8
+	mov	cl, [esp+2*dword]
+	mov	al, [esp+dword]
+	ror	al, cl
+	ret
+.endp dbgRotr8
+
+// uint16_t dbgRotl16(uint16_t, nuint_t);
+.pubproc dbgRotl16
+	mov	cl, [esp+2*dword]
+	mov	eax, [esp+dword]
+	rol	ax, cl
+	ret
+.endp dbgRotl16
+
+// uint16_t dbgRotr16(uint16_t, nuint_t);
+.pubproc dbgRotr16
+	mov	cl, [esp+2*dword]
+	mov	eax, [esp+dword]
+	ror	ax, cl
+	ret
+.endp dbgRotr16
+
+// uint32_t dbgRotl32(uint32_t, nuint_t);
+.pubproc dbgRotl32
+	mov	cl, [esp+2*dword]
+	mov	eax, [esp+dword]
+	rol	eax, cl
+	ret
+.endp dbgRotl32
+
+// uint32_t dbgRotr32(uint32_t, nuint_t);
+.pubproc dbgRotr32
+	mov	cl, [esp+2*dword]
+	mov	eax, [esp+dword]
+	ror	eax, cl
+	ret
+.endp dbgRotr32
+
+// uint64_t dbgRotl64(uint64_t, nuint_t);
+.pubproc dbgRotl64
+	mov	cl, [esp+3*dword]
+	mov	eax, [esp+dword]
+	test	cl, 0x20
+	mov	edx, [esp+2*dword]
+	EHpush	ebx
+	jz	0f
+	xchg	eax, edx
+0:
+	mov	ebx, edx
+	shld	edx, eax, cl
+	shld	eax, ebx, cl
+	EHpop	ebx
+	ret
+.endp dbgRotl64
+
+// uint64_t dbgRotr64(uint64_t, nuint_t);
+.pubproc dbgRotr64
+	mov	cl, [esp+3*dword]
+	mov	eax, [esp+dword]
+	test	cl, 0x20
+	mov	edx, [esp+2*dword]
+	EHpush	ebx
+	jz	0f
+	xchg	eax, edx
+0:
+	mov	ebx, eax
+	shrd	eax, edx, cl
+	shrd	edx, ebx, cl
+	EHpop	ebx
+	ret
+.endp dbgRotr64
+
+.pubproc dbgDivideU
+	mov	eax, [esp+2*dword]
+	xor	edx, edx
+	mov	ecx, [esp+1*dword]
+	div	dword ptr [esp+3*dword]
+	mov	[ecx], eax
+	mov	[ecx+dword], edx
+	mov	eax, ecx
+	ret	dword
+.endp dbgDivideU
+
+.pubproc dbgDivideS
+	mov	eax, [esp+2*dword]
+	mov	ecx, [esp+1*dword]
+	cdq
+	idiv	dword ptr [esp+3*dword]
+	mov	[ecx], eax
+	mov	[ecx+dword], edx
+	mov	eax, ecx
+	ret	dword
+.endp dbgDivideS
+
+.pubproc dbg__divdi3
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	eax, [esp+1*dword]
+	mov	edx, [esp+2*dword]
+# define ARG2_SLOT 3
+#else
+# define ARG2_SLOT 1
+#endif
+	EHpushState
+	EHpush	ebp
+	EHpush	ebx
+	mov	ebp, [esp+(ARG2_SLOT+3)*dword]
+	mov	ebx, [esp+(ARG2_SLOT+2)*dword]
+	EHpush	esi
+	mov	ecx, edx
+	mov	esi, ebp
+	sar	ecx, 31
+	sar	esi, 31
+	xor	eax, ecx
+	xor	edx, ecx
+	xor	ebx, esi
+	xor	ebp, esi
+	sub	eax, ecx
+	sbb	edx, ecx
+	xor	ecx, esi
+	sub	ebx, esi
+	sbb	ebp, esi
+	EHpop	esi
+	jz	.LquickDIV
+	jns	.LscaleDIV
+	// EDX:EAX <= 80000000:00000000, EBP:EBX == 80000000:00000000
+	mov	eax, edx
+	xor	edx, edx
+	shr	eax, 31
+	jmp	.LreturnDIV
+	EHpopState
+.pubentry dbg__udivdi3
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	eax, [esp+1*dword]
+	mov	edx, [esp+2*dword]
+#endif
+	EHpush	ebp
+	EHpush	ebx
+	xor	ecx, ecx
+	mov	ebp, [esp+(ARG2_SLOT+3)*dword]
+	mov	ebx, [esp+(ARG2_SLOT+2)*dword]
+	test	ebp, ebp
+	jz	.LquickDIV
+	js	.LcompareDIV
+.LscaleDIV:
+	EHpush	ecx
+	bsr	ecx, ebp
+	EHpush	edx
+	EHpush	eax
+	inc	ecx				// number of bits to shift (at most 31)
+	EHpush	ebx, FALSE
+	shrd	ebx, ebp, cl
+	shrd	eax, edx, cl
+	shr	edx, cl
+	div	ebx
+	EHpop	ebx, FALSE
+	imul	ebp, eax			// lo(quotient * hi(divisor))
+	mov	ecx, eax
+	mul	ebx				// quotient * lo(divisor)
+	EHpop	ebx, FALSE
+	add	ebp, edx			// EBP:EAX = quotient * divisor
+	sbb	ecx, 0				// adjust quotient (if overflow)
+	xor	edx, edx
+	sub	ebx, eax
+	EHpop	ebx, FALSE
+	mov	eax, ecx
+	sbb	ebx, ebp
+	EHpop	ecx
+	sbb	eax, edx			// adjust quotient
+	jmp	.LreturnDIV
+.LcompareDIV:
+	sub	eax, ebx
+	mov	eax, 0
+	sbb	edx, ebp
+	mov	edx, eax
+	sbb	eax, -1
+	jmp	.LreturnDIV
+.LquickDIV:
+	cmp	edx, ebx
+	jb	0f
+	mov	ebp, eax
+	mov	eax, edx
+	xor	edx, edx
+	div	ebx
+	xchg	eax, ebp
+0:
+	div	ebx
+	mov	edx, ebp
+.LreturnDIV:
+	xor	eax, ecx
+	EHpop	ebx
+	xor	edx, ecx
+	sub	eax, ecx
+	EHpop	ebp
+	sbb	edx, ecx
+	ret
+#undef ARG2_SLOT
+.endp dbg__divdi3
+
+.pubproc dbg__moddi3
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	eax, [esp+1*dword]
+	mov	edx, [esp+2*dword]
+# define ARG2_SLOT 3
+#else
+# define ARG2_SLOT 1
+#endif
+	EHpushState
+	EHpush	ebp
+	EHpush	ebx
+	mov	ebp, [esp+(ARG2_SLOT+3)*dword]
+	mov	ebx, [esp+(ARG2_SLOT+2)*dword]
+	EHpush	esi
+	mov	ecx, edx
+	mov	esi, ebp
+	sar	ecx, 31
+	sar	esi, 31
+	xor	eax, ecx
+	xor	edx, ecx
+	xor	ebx, esi
+	xor	ebp, esi
+	sub	eax, ecx
+	sbb	edx, ecx
+	sub	ebx, esi
+	sbb	ebp, esi
+	EHpop	esi
+	jz	.LquickMOD
+	jns	.LscaleMOD
+	// EDX:EAX <= 80000000:00000000, EBP:EBX == 80000000:00000000
+	not	ebp
+	and	edx, ebp
+	jmp	.LreturnMOD
+	EHpopState
+.pubentry dbg__umoddi3
+#if !defined(CONFIG_REGPARM) || __GNUC__ < 3
+	mov	eax, [esp+1*dword]
+	mov	edx, [esp+2*dword]
+#endif
+	EHpush	ebp
+	EHpush	ebx
+	xor	ecx, ecx
+	mov	ebp, [esp+(ARG2_SLOT+3)*dword]
+	mov	ebx, [esp+(ARG2_SLOT+2)*dword]
+	test	ebp, ebp
+	jz	.LquickMOD
+	js	.LcompareMOD
+.LscaleMOD:
+	EHpush	ecx
+	bsr	ecx, ebp
+	EHpush	esi
+	mov	esi, edx
+	EHpush	edi
+	inc	ecx				// number of bits to shift (at most 31)
+	mov	edi, eax
+	EHpush	ebx, FALSE
+	shrd	ebx, ebp, cl
+	shrd	eax, edx, cl
+	shr	edx, cl
+	mov	ecx, [esp]
+	div	ebx
+	mov	[esp], ebp
+	imul	ebp, eax			// lo(quotient * hi(divisor))
+	mul	ecx				// quotient * lo(divisor)
+	add	edx, ebp			// EDX:EAX = quotient * divisor
+	sbb	ebp, ebp			// record overflow
+	sub	edi, eax
+	sbb	esi, edx
+	mov	eax, ecx
+	sbb	ebp, 0				// accumulate overflow
+	EHpop	edx
+	and	eax, ebp
+	and	edx, ebp
+	add	eax, edi
+	EHpop	edi
+	adc	edx, esi
+	EHpop	esi
+	EHpop	ecx
+	jmp	.LreturnMOD
+.LcompareMOD:
+	sub	eax, ebx
+	EHpush	esi
+	sbb	edx, ebp
+	sbb	esi, esi
+	and	ebx, esi
+	and	ebp, esi
+	add	eax, ebx
+	EHpop	esi
+	adc	edx, ebp
+	jmp	.LreturnMOD
+.LquickMOD:
+	cmp	edx, ebx
+	jb	0f
+	mov	ebp, eax
+	mov	eax, edx
+	xor	edx, edx
+	div	ebx
+	xchg	eax, ebp
+0:
+	div	ebx
+	mov	eax, edx
+	xor	edx, edx
+.LreturnMOD:
+	xor	eax, ecx
+	EHpop	ebx
+	xor	edx, ecx
+	sub	eax, ecx
+	EHpop	ebp
+	sbb	edx, ecx
+	ret
+#undef ARG2_SLOT
+.endp dbg__moddi3

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 28/39] NLKD/x86-64 - run time library
  2005-11-09 14:23                             ` [PATCH 27/39] NLKD/i386 " Jan Beulich
@ 2005-11-09 14:23                               ` Jan Beulich
  2005-11-10 13:32                                 ` Andi Kleen
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:23 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 140 bytes --]

x86_64-specific implementation of the support routines of NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-rtl-x86_64.patch --]
[-- Type: application/octet-stream, Size: 8333 bytes --]

x86_64-specific implementation of the support routines of NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/debug/nlkd/dbgAMD64.S
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/dbgAMD64.S	2005-10-05 11:37:21.000000000 +0200
@@ -0,0 +1,403 @@
+/*****************************************************************************
+ *
+ *   File Name:      dbgAMD64.S
+ *   Created by:     jbeulich
+ *   %version:       8 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Wed Oct 05 01:08:52 2005 %
+ *
+ ****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2002-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	 File Description:
+ *
+ ****************************************************************************/
+
+#include <linux/config.h>
+.equiv PROCEDURE_ALIGN, 1
+#include "asm-amd64.h"
+
+// int dbgCompareMem(const void*, const void*, size_t);
+.pubproc dbgCompareMem
+	mov	rcx, rdx
+	xchg	rsi, rdi
+	xor	eax, eax
+	xor	edx, edx
+	repe cmpsb
+	seta	al
+	setb	dl
+	sub	eax, edx
+	ret
+.endp dbgCompareMem
+
+// int dbgCompareStr(const char*, const char*);
+.pubproc dbgCompareStr
+	xor	eax, eax
+0:
+	mov	al, [rdi]
+	inc	rdi
+	test	al, al
+	jz	1f
+	cmp	al, [rsi]
+	jne	1f
+	inc	rsi
+	jmp	0b
+1:
+	movzx	edx, byte ptr [rsi]
+	sub	eax, edx
+	ret
+.endp dbgCompareStr
+
+// void*dbgCopyMem(void*, const void*, size_t);
+// Note: The minimum requirements to this routine are that copying between properly
+//       aligned buffers with a suitable size will be carried out with the maximum
+//       access granularity possible.
+.pubproc dbgCopyMem
+	mov	rcx, rdx
+	test	dl, byte
+	mov	rax, rdi
+	jz	0f
+	rep movsb
+	ret
+0:
+	test	dl, word or dword
+	jz	2f
+	shr	rcx, 2
+	jnc	1f
+	adc	rcx, rcx
+	.byte	0x66
+1:
+	rep movsd
+	ret
+2:
+	shr	rcx, 3
+	rep movsq
+	ret
+.endp dbgCopyMem
+
+// char*dbgCopyStr(char*, const char*);
+.pubproc dbgCopyStr
+	mov	rax, rdi
+0:
+	cmp	byte ptr [rsi], 0
+	movsb
+	jne	0b
+	ret
+.endp dbgCopyStr
+
+// char*dbgCopyStrP(char*, const char*);
+.pubproc dbgCopyStrP
+0:
+	lodsb
+	stosb
+	test	al, al
+	jnz	0b
+	lea	rax, [rdi-byte]
+	ret
+.endp dbgCopyStrP
+
+// unsigned dbgCountBits(uint64_t);
+.pubproc dbgCountBits
+	shld	rsi, rdi, 32
+	xor	eax, eax
+0:
+	shr	edi, 1
+	adc	eax, 0
+	shr	esi, 1
+	adc	eax, 0
+	test	edi, edi
+	jnz	0b
+	test	esi, esi
+	jnz	0b
+	ret
+.endp dbgCountBits
+
+// size_t dbgCountStr(const char*);
+.pubproc dbgCountStr
+	or	rcx, not 0
+	xor	eax, eax
+	repne scasb
+	add	rcx, 2
+	sub	rax, rcx
+	ret
+.endp dbgCountStr
+
+// size_t dbgCountWstr(const wchar_t*);
+.pubproc dbgCountWstr
+	or	rcx, not 0
+	xor	eax, eax
+	repne scasw
+	add	rcx, 2
+	sub	rax, rcx
+	ret
+.endp dbgCountWstr
+
+// char*dbgFindChar(const char*, char);
+.pubproc dbgFindChar
+0:
+	mov	dl, [rdi]
+	cmp	sil, dl
+	je	1f
+	inc	rdi
+	test	dl, dl
+	jnz	0b
+	xor	eax, eax
+	ret
+1:
+	mov	rax, rdi
+	ret
+.endp dbgFindChar
+
+// wchar_t*dbgFindWchar(const wchar_t*, wchar_t);
+.pubproc dbgFindWchar
+0:
+	mov	dx, [rdi]
+	cmp	si, dx
+	je	1f
+	add	rdi, word
+	test	dx, dx
+	jnz	0b
+	xor	eax, eax
+	ret
+1:
+	mov	rax, rdi
+	ret
+.endp dbgFindWchar
+
+// char*dbgWstr2Str(char*, const wchar_t*);
+.pubproc dbgWstr2Str
+	mov	rax, rdi
+	mov	cl, '?'
+0:
+	movzx	edx, word ptr [rsi]
+	add	rsi, word
+	cmp	edx, 0x7f
+	cmova	edx, ecx
+	mov	[rdi], dl
+	inc	rdi
+	test	edx, edx
+	jnz	0b
+	ret
+.endp dbgWstr2Str
+
+// int dbgLower(int);
+.pubproc dbgLower
+	mov	eax, edi
+	cmp	edi, 'A'
+	jb	0f
+	cmp	edi, 'Z'
+	ja	0f
+	add	al, 'a' - 'A'
+0:
+	ret
+.endp dbgLower
+
+// int dbgUpper(int);
+.pubproc dbgUpper
+	mov	eax, edi
+	cmp	edi, 'a'
+	jb	0f
+	cmp	edi, 'z'
+	ja	0f
+	add	al, 'A' - 'a'
+0:
+	ret
+.endp dbgUpper
+
+// void*dbgFillMem(void*, int, size_t);
+.pubproc dbgFillMem
+	mov	rcx, rdx
+	mov	eax, esi
+	jmp	0f
+// void*dbgZeroMem(void*, size_t);
+.pubentry dbgZeroMem
+	mov	ecx, esi
+	xor	eax, eax
+0:
+	mov	rdx, rdi
+	rep stosb
+	mov	rax, rdx
+	ret
+.endp dbgFillMem
+
+// uint8_t*dbgFindInt8(const uint8_t*, uint8_t, size_t);
+// void*dbgFindByte(const void*, int, size_t);
+.pubproc dbgFindInt8
+.pubentry dbgFindByte
+	mov	rcx, rdx
+	jrcxz	0f
+	mov	eax, esi
+	repne scasb
+	lea	rax, [rdi-byte]
+	je	1f
+0:
+	xor	eax, eax
+1:
+	ret
+.endp dbgFindInt8
+
+// uint16_t*dbgFindInt16(const uint16_t*, uint16_t, size_t);
+.pubproc dbgFindInt16
+	mov	rcx, rdx
+	jrcxz	0f
+	mov	eax, esi
+	repne scasw
+	lea	rax, [rdi-word]
+	je	1f
+0:
+	xor	eax, eax
+1:
+	ret
+.endp dbgFindInt16
+
+// uint32_t*dbgFindInt32(const uint32_t*, uint32_t, size_t);
+// nuint_t*dbgFindIntN(const nuint_t*, nuint_t, size_t);
+.pubproc dbgFindInt32
+.pubentry dbgFindIntN
+	mov	rcx, rdx
+	jrcxz	0f
+	mov	eax, esi
+	repne scasd
+	lea	rax, [rdi-dword]
+	je	1f
+0:
+	xor	eax, eax
+1:
+	ret
+.endp dbgFindInt32
+
+// uint64_t*dbgFindInt64(const uint64_t*, uint64_t, size_t);
+// void**dbgFindPtr(const void**, const void*, size_t);
+.pubproc dbgFindInt64
+.pubentry dbgFindPtr
+	mov	rcx, rdx
+	jrcxz	0f
+	mov	rax, rsi
+	repne scasq
+	lea	rax, [rdi-qword]
+	je	1f
+0:
+	xor	eax, eax
+1:
+	ret
+.endp dbgFindInt64
+
+// uint64_t dbgMultiply(uint64_t, uint64_t, uint64_t*overflow);
+.pubproc dbgMultiply
+	mov	rax, rdi
+	mov	rcx, rdx
+	mul	rsi
+	mov	[rcx], rdx
+	ret
+.endp dbgMultiply
+
+// nint_t dbgLog2(uint64_t)
+.pubproc dbgLog2
+	bsr	rax, rdi
+	jnz	0f
+	or	eax, not 0
+0:
+	ret
+.endp dbgLog2
+
+// uint8_t dbgRotl8(uint8_t, nuint_t);
+.pubproc dbgRotl8
+	mov	eax, edi
+	mov	ecx, esi
+	rol	al, cl
+	ret
+.endp dbgRotl8
+
+// uint8_t dbgRotr8(uint8_t, nuint_t);
+.pubproc dbgRotr8
+	mov	eax, edi
+	mov	ecx, esi
+	ror	al, cl
+	ret
+.endp dbgRotr8
+
+// uint16_t dbgRotl16(uint16_t, nuint_t);
+.pubproc dbgRotl16
+	mov	eax, edi
+	mov	ecx, esi
+	rol	ax, cl
+	ret
+.endp dbgRotl16
+
+// uint16_t dbgRotr16(uint16_t, nuint_t);
+.pubproc dbgRotr16
+	mov	eax, edi
+	mov	ecx, esi
+	ror	ax, cl
+	ret
+.endp dbgRotr16
+
+// uint32_t dbgRotl32(uint32_t, nuint_t);
+.pubproc dbgRotl32
+	mov	eax, edi
+	mov	ecx, esi
+	rol	eax, cl
+	ret
+.endp dbgRotl32
+
+// uint32_t dbgRotr32(uint32_t, nuint_t);
+.pubproc dbgRotr32
+	mov	eax, edi
+	mov	ecx, esi
+	ror	eax, cl
+	ret
+.endp dbgRotr32
+
+// uint64_t dbgRotl64(uint64_t, nuint_t);
+.pubproc dbgRotl64
+	mov	rax, rdi
+	mov	ecx, esi
+	rol	rax, cl
+	ret
+.endp dbgRotl64
+
+// uint64_t dbgRotr64(uint64_t, nuint_t);
+.pubproc dbgRotr64
+	mov	rax, rdi
+	mov	ecx, esi
+	ror	rax, cl
+	ret
+.endp dbgRotr64
+
+.pubproc dbgDivideU
+	mov	eax, edi
+	xor	edx, edx
+	div	esi
+	shl	rdx, 32
+	or	rax, rdx
+	ret
+.endp dbgDivideU
+
+.pubproc dbgDivideS
+	mov	eax, edi
+	cdq
+	idiv	esi
+	shl	rdx, 32
+	or	rax, rdx
+	ret
+.endp dbgDivideS

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 34/39] NLKD/x86 - Console Debug Agent
       [not found]                               ` <4372156A.76F0.0078.0@novell.com>
@ 2005-11-09 14:28                                 ` Jan Beulich
       [not found]                                 ` <43721600.76F0.0078.0@novell.com>
  1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:28 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 152 bytes --]

The x86-dependent (32- and 64-bit) part of the Console Debug Agent of
NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-cda-x86.patch --]
[-- Type: application/octet-stream, Size: 70689 bytes --]

The x86-dependent (32- and 64-bit) part of the Console Debug Agent of
NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/debug/nlkd/cda/x86_1.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/cda/x86_1.c	2005-09-01 08:37:23.000000000 +0200
@@ -0,0 +1,535 @@
+/*****************************************************************************
+ *
+ *   File Name:      x86_1.c
+ *   Created by:     Jan Beulich
+ *   Date created:   08Mar2001
+ *
+ *   %version:       7 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Sep 01 00:37:12 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2001-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+NAME_TABLE(80_, "add", "or", "adc", "sbb", "and", "sub", "xor", "cmp");
+#define names_81_ names_80_
+#define names_82_ names_80_
+#define names_83_ names_80_
+NAME_TABLE(8F_, "pop", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+NAME_TABLE(C0_, "rol", "ror", "rcl", "rcr", "shl", "shr", "sal", "sar");
+#define names_C1_ names_C0_
+NAME_TABLE(C6_, "mov", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+#define names_C7_ names_C6_
+#define names_D0_ names_C0_
+#define names_D1_ names_C0_
+#define names_D2_ names_C0_
+#define names_D3_ names_C0_
+NAME_TABLE(D8m, "fadd", "fmul", "fcom", "fcomp", "fsub", "fsubr", "fdiv", "fdivr");
+NAME_TABLE(D9r2, "fnop", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+NAME_TABLE(D9r4, "fchs", "fabs", NULL, NULL, "ftst", "fxam", NULL, NULL);
+NAME_TABLE(D9r5, "fld1", "fldl2t", "fldl2e", "fldpi", "fldlg2", "fldln2", "fldz", NULL);
+NAME_TABLE(D9r6, "f2xm1", "fyl2x", "fptan", "fpatan", "fxtract", "fprem1", "fdecstp", "fincstp");
+NAME_TABLE(D9r7, "fprem", "fyl2xp1", "fsqrt", "fsincos", "frndint", "fscale", "fsin", "fcos");
+NAME_TABLE(DAm, "fiadd", "fimul", "ficom", "ficomp", "fisub", "fisubr", "fidiv", "fidivr");
+NAME_TABLE(DAr5, NULL, "fucompp", NULL, NULL, NULL, NULL, NULL, NULL);
+NAME_TABLE(DBr4, "fneni", "fndisi", "fnclex", "fninit", "fsetpm", "frstpm", NULL, NULL);
+#define names_DCm names_D8m
+NAME_TABLE(DCr, "fadd", "fmul", NULL, NULL, "fsubr", "fsub", "fdivr", "fdiv");
+NAME_TABLE(DEr3, NULL, "fcompp", NULL, NULL, NULL, NULL, NULL, NULL);
+#define names_DEm names_DAm
+NAME_TABLE(DFr4, "fnstsw", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+NAME_TABLE(FE_, "inc", "dec", NULL, NULL, NULL, NULL, NULL, NULL);
+
+static const OpcodeInfo branch_00[8] = {
+	LEAF_NORMAL(00,	"add",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(01,	"add",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(02,	"add",	r_rm,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(03,	"add",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(04,	"add",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(05,	"add",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(06,	"push",	reg,		ptr,		none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(07,	"pop",	reg,		ptr,		none,	word,	tos,		none,	none,	none)},
+#else
+	LEAF_NORMAL(06,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(07,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+#endif
+branch_08[8] = {
+	LEAF_NORMAL(08,	"or",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(09,	"or",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0A,	"or",	r_rm,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0B,	"or",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0C,	"or",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0D,	"or",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(0E,	"push",	reg,		ptr,		none,	none,	SP,		none,	none,	none),
+#else
+	LEAF_NORMAL(0E,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(0F,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_10[8] = {
+	LEAF_NORMAL(10,	"adc",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(11,	"adc",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(12,	"adc",	r_rm,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(13,	"adc",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(14,	"adc",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(15,	"adc",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(16,	"push",	reg,		ptr,		none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(17,	"pop",	reg,		ptr,		none,	word,	tos,		none,	none,	none)},
+#else
+	LEAF_NORMAL(16,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(17,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+#endif
+branch_18[8] = {
+	LEAF_NORMAL(18,	"sbb",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(19,	"sbb",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(1A,	"sbb",	r_rm,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(1B,	"sbb",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(1C,	"sbb",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(1D,	"sbb",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(1E,	"push",	reg,		ptr,		none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(1F,	"pop",	reg,		ptr,		none,	word,	tos,		none,	none,	none)},
+#else
+	LEAF_NORMAL(1E,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(1F,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+#endif
+branch_20[8] = {
+	LEAF_NORMAL(20,	"and",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(21,	"and",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(22,	"and",	r_rm,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(23,	"and",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(24,	"and",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(25,	"and",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+	LEAF_NORMAL(26,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(27,	"daa",	none,	none,	none,	none,	AX,		sflags,	none,	none)},
+#else
+	LEAF_NORMAL(27,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+#endif
+branch_28[8] = {
+	LEAF_NORMAL(28,	"sub",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(29,	"sub",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(2A,	"sub",	r_rm,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(2B,	"sub",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(2C,	"sub",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(2D,	"sub",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+	LEAF_NORMAL(2E,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(2F,	"das",	none,	none,	none,	none,	AX,		sflags,	none,	none)},
+#else
+	LEAF_NORMAL(2F,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+#endif
+branch_30[8] = {
+	LEAF_NORMAL(30,	"xor",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(31,	"xor",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(32,	"xor",	r_rm,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(33,	"xor",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(34,	"xor",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(35,	"xor",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+	LEAF_NORMAL(36,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(37,	"aaa",	none,	none,	none,	none,	AX,		sflags,	none,	none)},
+#else
+	LEAF_NORMAL(37,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+#endif
+branch_38[8] = {
+	LEAF_NORMAL(38,	"cmp",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(39,	"cmp",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(3A,	"cmp",	r_rm,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(3B,	"cmp",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(3C,	"cmp",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(3D,	"cmp",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+	LEAF_NORMAL(3E,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(3F,	"aas",	none,	none,	none,	none,	AX,		sflags,	none,	none)},
+#else
+	LEAF_NORMAL(3F,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+#endif
+branch_60[8] = {
+#ifndef X86_64
+	LEAF_NORMAL(60,	"pusha",	none,	none,	none,	none,	GRs,		none,	none,	opsz),
+	LEAF_NORMAL(61,	"popa",	none,	none,	none,	none,	GRs,		none,	none,	opsz),
+	LEAF_NORMAL(62,	"bound",	r,		offset,	mm,		2offsets,	none,	none,	none,	none),
+	LEAF_NORMAL(63,	"arpl",	rm_r,	offset,	none,	none,	none,	none,	none,	none),
+#else
+	LEAF_NORMAL(60,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(61,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(62,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(63,	"movsx",	r,		offset,	rm,		dword,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(64,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(65,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(66,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(67,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_68[8] = {
+	LEAF_NORMAL(68,	"push",	imm,		offset64,	none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(69,	"imul",	r_rm,	offset,	imm,		offset32,	sflags,	none,	none,	imul),
+	LEAF_NORMAL(6A,	"push",	simm,	offset,	none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(6B,	"imul",	r_rm,	offset,	simm,	offset,	sflags,	none,	none,	imul),
+	LEAF_NORMAL(6C,	"ins",	str_d,	byte,	cl_dx,	word,	none,	none,	none,	string),
+	LEAF_NORMAL(6D,	"ins",	str_d,	offset32,	cl_dx,	word,	none,	none,	none,	string),
+	LEAF_NORMAL(6E,	"outs",	cl_dx,	word,	str_s,	byte,	none,	none,	none,	string),
+	LEAF_NORMAL(6F,	"outs",	cl_dx,	word,	str_s,	offset32,	none,	none,	none,	string)},
+branch_80[8] = {
+	NAME_NORMAL(80_,			rm,		byte,	imm,		byte,	sflags,			none,	none),
+	NAME_NORMAL(81_,			rm,		offset,	imm,		offset32,	sflags,			none,	none),
+	LEAF_NORMAL(82,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	NAME_NORMAL(83_,			rm,		offset,	simm,	offset,	sflags,			none,	none),
+	LEAF_NORMAL(84,	"test",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(85,	"test",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(86,	"xchg",	rm_r,	byte,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(87,	"xchg",	rm_r,	offset,	none,	none,	none,	none,	none,	none)},
+regmem_8C[2] = {
+	LEAF_NORMAL(8Cm,	"mov",	mm,		word,	r,		ptr,		none,	none,	nowidth,	none),
+	LEAF_NORMAL(8Cr,	"mov",	rr,		offset,	r,		ptr,		none,	none,	none,	none)},
+regmem_8E[2] = {
+	LEAF_NORMAL(8Em,	"mov",	r,		ptr,		mm,		word,	none,	none,	nowidth,	none),
+	LEAF_NORMAL(8Er,	"mov",	r,		ptr,		rr,		offset,	none,	none,	none,	none)},
+branch_88[8] = {
+	LEAF_NORMAL(88,	"mov",	rm_r,	byte,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(89,	"mov",	rm_r,	offset,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(8A,	"mov",	r_rm,	byte,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(8B,	"mov",	r_rm,	offset,	none,	none,	none,	none,	none,	none),
+	REGMEM_ENTRY(8C,	normal),
+	LEAF_NORMAL(8D,	"lea",	r,		offset,	mm,		none,	none,	none,	none,	none),
+	REGMEM_ENTRY(8E,	normal),
+	NAME_NORMAL(8F_,			rm,		offset64,	none,	offset64,	tos,				none,	none)},
+branch_90[8] = {
+	LEAF_NORMAL(90,	"nop",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(91,	"xchg",	accum,	offset,	reg,		offset,	none,	none,	none,	none),
+	LEAF_NORMAL(92,	"xchg",	accum,	offset,	reg,		offset,	none,	none,	none,	none),
+	LEAF_NORMAL(93,	"xchg",	accum,	offset,	reg,		offset,	none,	none,	none,	none),
+	LEAF_NORMAL(94,	"xchg",	accum,	offset,	reg,		offset,	none,	none,	none,	none),
+	LEAF_NORMAL(95,	"xchg",	accum,	offset,	reg,		offset,	none,	none,	none,	none),
+	LEAF_NORMAL(96,	"xchg",	accum,	offset,	reg,		offset,	none,	none,	none,	none),
+	LEAF_NORMAL(97,	"xchg",	accum,	offset,	reg,		offset,	none,	none,	none,	none)},
+branch_98[8] = {
+#ifndef X86_64
+	LEAF_NORMAL(98,	"cbw",	none,	none,	none,	none,	AX,		none,	none,	none),
+	LEAF_NORMAL(99,	"cwd",	none,	none,	none,	none,	DX_AX,	none,	none,	none),
+	LEAF_NORMAL(9A,	"call",	imm,		ptr,		none,	none,	SP,		CS,		none,	none),
+#else
+	LEAF_NORMAL(98,	"cwde",	none,	none,	none,	none,	AX,		none,	none,	none),
+	LEAF_NORMAL(99,	"cdq",	none,	none,	none,	none,	DX_AX,	none,	none,	none),
+	LEAF_NORMAL(9A,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(9B,	"wait",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(9C,	"pushf",	none,	none,	none,	none,	SP,		flags,	none,	opsz),
+	LEAF_NORMAL(9D,	"popf",	none,	none,	none,	offset64,	tos,		flags,	none,	opsz),
+	LEAF_NORMAL(9E,	"sahf",	none,	none,	none,	none,	AX,		sflags,	none,	none),
+	LEAF_NORMAL(9F,	"lahf",	none,	none,	none,	none,	sflags,	AX,		none,	none)},
+branch_A0[8] = {
+	LEAF_NORMAL(A0,	"mov",	accum,	byte,	mem,		byte,	none,	none,	none,	none),
+	LEAF_NORMAL(A1,	"mov",	accum,	offset,	mem,		offset,	none,	none,	none,	none),
+	LEAF_NORMAL(A2,	"mov",	mem,		byte,	accum,	byte,	none,	none,	none,	none),
+	LEAF_NORMAL(A3,	"mov",	mem,		offset,	accum,	offset,	none,	none,	none,	none),
+	LEAF_NORMAL(A4,	"movs",	str_d,	byte,	str_s,	byte,	none,	none,	none,	string),
+	LEAF_NORMAL(A5,	"movs",	str_d,	offset,	str_s,	offset,	none,	none,	none,	string),
+	LEAF_NORMAL(A6,	"cmps",	str_s,	byte,	str_d,	byte,	sflags,	none,	none,	string),
+	LEAF_NORMAL(A7,	"cmps",	str_s,	offset,	str_d,	offset,	sflags,	none,	none,	string)},
+branch_A8[8] = {
+	LEAF_NORMAL(A8,	"test",	accum,	byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(A9,	"test",	accum,	offset,	imm,		offset32,	sflags,	none,	none,	none),
+	LEAF_NORMAL(AA,	"stos",	str_d,	byte,	none,	none,	none,	none,	none,	string),
+	LEAF_NORMAL(AB,	"stos",	str_d,	offset,	none,	none,	none,	none,	none,	string),
+	LEAF_NORMAL(AC,	"lods",	str_s,	byte,	none,	none,	none,	none,	none,	string),
+	LEAF_NORMAL(AD,	"lods",	str_s,	offset,	none,	none,	none,	none,	none,	string),
+	LEAF_NORMAL(AE,	"scas",	str_d,	byte,	none,	none,	sflags,	none,	none,	string),
+	LEAF_NORMAL(AF,	"scas",	str_d,	offset,	none,	none,	sflags,	none,	none,	string)},
+branch_C0[8] = {
+	NAME_NORMAL(C0_,			rm,		byte,	imm,		byte,	sflags,			none,	none),
+	NAME_NORMAL(C1_,			rm,		offset,	imm,		byte,	sflags,			none,	none),
+	LEAF_NORMAL(C2,	"ret",	imm,		word,	none,	offset64,	tos,		none,	none,	none),
+	LEAF_NORMAL(C3,	"ret",	none,	none,	none,	offset64,	tos,		none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(C4,	"les",	r,		offset,	mm,		ptr,		ES,		none,	nowidth,	none),
+	LEAF_NORMAL(C5,	"lds",	r,		offset,	mm,		ptr,		DS,		none,	nowidth,	none),
+#else
+	LEAF_NORMAL(C4,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(C5,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	NAME_NORMAL(C6_,			rm,		byte,	imm,		byte,	none,			none,	none),
+	NAME_NORMAL(C7_,			rm,		offset,	imm,		offset32,	none,			none,	none)},
+branch_C8[8] = {
+	LEAF_NORMAL(C8,	"enter",	imm,		word,	imm,		byte,	BP,		SP,		none,	opsz),
+	LEAF_NORMAL(C9,	"leave",	none,	none,	none,	none,	SP,		BP,		none,	opsz),
+	LEAF_NORMAL(CA,	"retf",	imm,		word,	none,	ptr,		tos,		CS,		none,	none),
+	LEAF_NORMAL(CB,	"retf",	none,	none,	none,	ptr,		tos,		CS,		none,	none),
+	LEAF_NORMAL(CC,	"int3",	none,	none,	none,	none,	SP,		int,		none,	none),
+	LEAF_NORMAL(CD,	"int",	imm,		byte,	none,	none,	SP,		int,		none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(CE,	"into",	none,	none,	none,	none,	SP,		int,		none,	none),
+#else
+	LEAF_NORMAL(CE,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(CF,	"iret",	none,	none,	none,	ptr,		tos,		int,		none,	opsz)},
+branch_D0[8] = {
+	NAME_NORMAL(D0_,			rm,		byte,	imm,		none,	sflags,			none,	none),
+	NAME_NORMAL(D1_,			rm,		offset,	imm,		none,	sflags,			none,	none),
+	NAME_NORMAL(D2_,			rm,		byte,	cl_dx,	byte,	sflags,			none,	none),
+	NAME_NORMAL(D3_,			rm,		offset,	cl_dx,	byte,	sflags,			none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(D4,	"aam",	imm,		byte,	none,	none,	AX,		sflags,	none,	none),
+	LEAF_NORMAL(D5,	"aad",	imm,		byte,	none,	none,	AX,		sflags,	none,	none),
+	LEAF_NORMAL(D6,	"salc",	none,	none,	none,	none,	AX,		sflags,	none,	none),
+#else
+	LEAF_NORMAL(D4,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(D5,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(D6,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(D7,	"xlat",	str_s,	byte,	none,	none,	AX,		none,	none,	string)},
+branch_D9m[8] = {
+	LEAF_NORMAL(D9m0,	"fld",	mm,		real4,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(D9m1,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(D9m2,	"fst",	mm,		real4,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(D9m3,	"fstp",	mm,		real4,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(D9m4,	"fldenv",	mm,		none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(D9m5,	"fldcw",	mm,		word,	none,	none,	fcw,		none,	nowidth,	none),
+	LEAF_NORMAL(D9m6,	"fnstenv", mm,		none,	none,	none,	none,	none,	none,	wait),
+	LEAF_NORMAL(D9m7,	"fnstcw",	mm,		word,	none,	none,	fcw,		none,	nowidth,	wait)},
+branch_DBm[8] = {
+	LEAF_NORMAL(DBm0,	"fild",	mm,		dword,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DBm1,	"fisttp",	mm,	dword,	none,	none,	ST0,	none,	none,	none),
+	LEAF_NORMAL(DBm2,	"fist",	mm,		dword,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DBm3,	"fistp",	mm,		dword,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DBm4,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DBm5,	"fld",	mm,		real10,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DBm6,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DBm7,	"fstp",	mm,		real10,	none,	none,	ST0,		none,	none,	none)},
+branch_DDm[8] = {
+	LEAF_NORMAL(DDm0,	"fld",	mm,		real8,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DDm1,	"fisttp",	mm,	qword,	none,	none,	ST0,	none,	none,	none),
+	LEAF_NORMAL(DDm2,	"fst",	mm,		real8,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DDm3,	"fstp",	mm,		real8,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DDm4,	"frstor",	mm,		none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DDm5,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DDm6,	"fnsave",	mm,		none,	none,	none,	none,	none,	none,	wait),
+	LEAF_NORMAL(DDm7,	"fnstsw",	mm,		word,	none,	none,	fsw,		none,	nowidth,	wait)},
+branch_DFm[8] = {
+	LEAF_NORMAL(DFm0,	"fild",	mm,		word,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DFm1,	"fisttp",	mm,	word,	none,	none,	ST0,	none,	none,	none),
+	LEAF_NORMAL(DFm2,	"fist",	mm,		word,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DFm3,	"fistp",	mm,		word,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DFm4,	"fbld",	mm,		bcd,		none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DFm5,	"fild",	mm,		qword,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DFm6,	"fbstp",	mm,		bcd,		none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DFm7,	"fistp",	mm,		qword,	none,	none,	ST0,		none,	none,	none)},
+branch_D8_m[8] = {
+	NAME_NORMAL(D8m,			mm,		real4,	none,	none,	ST0,				none,	none),
+	BRANCH_ENTRY(D9m),
+	NAME_NORMAL(DAm,			mm,		dword,	none,	none,	ST0,				none,	none),
+	BRANCH_ENTRY(DBm),
+	NAME_NORMAL(DCm,			mm,		real8,	none,	none,	ST0,				none,	none),
+	BRANCH_ENTRY(DDm),
+	NAME_NORMAL(DEm,			mm,		word,	none,	none,	ST0,				none,	none),
+	BRANCH_ENTRY(DFm)},
+branch_D8r[8] = {
+	LEAF_NORMAL(D8r0,	"fadd",	accum,	real10,	rr,		real10,	fsw,		none,	none,	none),
+	LEAF_NORMAL(D8r1,	"fmul",	accum,	real10,	rr,		real10,	fsw,		none,	none,	none),
+	LEAF_NORMAL(D8r2,	"fcom",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(D8r3,	"fcomp",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(D8r4,	"fsub",	accum,	real10,	rr,		real10,	fsw,		none,	none,	none),
+	LEAF_NORMAL(D8r5,	"fsubr",	accum,	real10,	rr,		real10,	fsw,		none,	none,	none),
+	LEAF_NORMAL(D8r6,	"fdiv",	accum,	real10,	rr,		real10,	fsw,		none,	none,	none),
+	LEAF_NORMAL(D8r7,	"fdivr",	accum,	real10,	rr,		real10,	fsw,		none,	none,	none)},
+branch_D9r[8] = {
+	LEAF_NORMAL(D9r0,	"fld",	rr,		real10,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(D9r1,	"fxch",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	NAME_NORMAL(D9r2,			none,	none,	none,	none,	fsw,				none,	none),
+	LEAF_NORMAL(D9r3,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	NAME_NORMAL(D9r4,			none,	none,	none,	none,	ST0,				none,	none),
+	NAME_NORMAL(D9r5,			none,	none,	none,	none,	ST0,				none,	none),
+	NAME_NORMAL(D9r6,			none,	none,	none,	none,	ST0,				none,	none),
+	NAME_NORMAL(D9r7,			none,	none,	none,	none,	ST0,				none,	none)},
+branch_DAr[8] = {
+	LEAF_COND(DAr0,	"fcmov",	accum,	real10,	rr,		real10,	sflags,	ST0,		fpu,		none),
+	LEAF_COND(DAr1,	"fcmov",	accum,	real10,	rr,		real10,	sflags,	ST0,		fpu,		none),
+	LEAF_COND(DAr2,	"fcmov",	accum,	real10,	rr,		real10,	sflags,	ST0,		fpu,		none),
+	LEAF_COND(DAr3,	"fcmov",	accum,	real10,	rr,		real10,	sflags,	ST0,		fpu,		none),
+	LEAF_NORMAL(DAr4,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	NAME_NORMAL(DAr5,			none,	none,	none,	none,	ST0_ST1,			none,	none),
+	LEAF_NORMAL(DAr6,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DAr7,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_DBr[8] = {
+	LEAF_COND(DBr0,	"fcmov",	accum,	real10,	rr,		real10,	sflags,	ST0,		fpu,		none),
+	LEAF_COND(DBr1,	"fcmov",	accum,	real10,	rr,		real10,	sflags,	ST0,		fpu,		none),
+	LEAF_COND(DBr2,	"fcmov",	accum,	real10,	rr,		real10,	sflags,	ST0,		fpu,		none),
+	LEAF_COND(DBr3,	"fcmov",	accum,	real10,	rr,		real10,	sflags,	ST0,		fpu,		none),
+	NAME_NORMAL(DBr4,			none,	none,	none,	none,	none,			none,	wait),
+	LEAF_NORMAL(DBr5,	"fucomi",	accum,	real10,	rr,		real10,	sflags,	none,	none,	none),
+	LEAF_NORMAL(DBr6,	"fcomi",	accum,	real10,	rr,		real10,	sflags,	none,	none,	none),
+	LEAF_NORMAL(DBr7,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_DDr[8] = {
+	LEAF_NORMAL(DDr0,	"ffree",	rr,		real10,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DDr1,	"fxch4",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(DDr2,	"fst",	rr,		real10,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DDr3,	"fstp",	rr,		real10,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DDr4,	"fucom",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(DDr5,	"fucomp",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(DDr6,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DDr7,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_DEr[8] = {
+	LEAF_NORMAL(DEr0,	"faddp",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(DEr1,	"fmulp",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(DEr2,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	NAME_NORMAL(DEr3,			none,	none,	none,	none,	ST0_ST1,			none,	none),
+	LEAF_NORMAL(DEr4,	"fsubrp",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(DEr5,	"fsubp",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(DEr6,	"fdivrp",	rr,		real10,	none,	none,	ST0,		none,	none,	st1),
+	LEAF_NORMAL(DEr7,	"fdivp",	rr,		real10,	none,	none,	ST0,		none,	none,	st1)},
+branch_DFr[8] = {
+	LEAF_NORMAL(DFr0,	"ffreep",	rr,		real10,	none,	none,	ST0,		none,	none,	none),
+	LEAF_NORMAL(DFr1,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DFr2,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(DFr3,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	NAME_NORMAL(DFr4,			accum,	word,	none,	none,	fsw,				none,	wait),
+	LEAF_NORMAL(DFr5,	"fucomip", accum,	real10,	rr,		real10,	sflags,	none,	none,	none),
+	LEAF_NORMAL(DFr6,	"fcomip",	accum,	real10,	rr,		real10,	sflags,	none,	none,	none),
+	LEAF_NORMAL(DFr7,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_D8_r[8] = {
+	BRANCH_ENTRY(D8r),
+	BRANCH_ENTRY(D9r),
+	BRANCH_ENTRY(DAr),
+	BRANCH_ENTRY(DBr),
+	NAME_NORMAL(DCr,			rr,		real10,	accum,	real10,	fsw,				none,	none),
+	BRANCH_ENTRY(DDr),
+	BRANCH_ENTRY(DEr),
+	BRANCH_ENTRY(DFr)},
+regmem_D8[2] = {
+	BRANCH_ENTRY(D8_m),
+	BRANCH_ENTRY(D8_r)},
+branch_E0[8] = {
+	LEAF_COND(E0,		"loop",	disp,	byte,	none,	none,	CX,		sflags,	loop,	adsz),
+	LEAF_COND(E1,		"loop",	disp,	byte,	none,	none,	CX,		sflags,	loop,	adsz),
+	LEAF_COND(E2,		"loop",	disp,	byte,	none,	none,	CX,		none,	loop,	adsz),
+#ifndef X86_64
+	LEAF_COND(E3,		"jcxz",	disp,	byte,	none,	none,	CX,		none,	loop,	none),
+#else
+	LEAF_COND(E3,		"jrcxz",	disp,	byte,	none,	none,	CX,		none,	loop,	none),
+#endif
+	LEAF_NORMAL(E4,	"in",	accum,	byte,	imm,		byte,	none,	none,	none,	none),
+	LEAF_NORMAL(E5,	"in",	accum,	offset32,	imm,		byte,	none,	none,	none,	none),
+	LEAF_NORMAL(E6,	"out",	imm,		byte,	accum,	byte,	none,	none,	none,	none),
+	LEAF_NORMAL(E7,	"out",	imm,		byte,	accum,	offset32,	none,	none,	none,	none)},
+branch_E8[8] = {
+	LEAF_NORMAL(E8,	"call",	disp,	offset,	none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(E9,	"jmp",	disp,	offset,	none,	none,	none,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(EA,	"jmp",	imm,		ptr,		none,	none,	CS,		none,	none,	none),
+#else
+	LEAF_NORMAL(9A,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(EB,	"jmp",	disp,	byte,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(EC,	"in",	accum,	byte,	cl_dx,	word,	none,	none,	none,	none),
+	LEAF_NORMAL(ED,	"in",	accum,	offset32,	cl_dx,	word,	none,	none,	none,	none),
+	LEAF_NORMAL(EE,	"out",	cl_dx,	word,	accum,	byte,	none,	none,	none,	none),
+	LEAF_NORMAL(EF,	"out",	cl_dx,	word,	accum,	offset32,	none,	none,	none,	none)},
+branch_F6_[8] = {
+	LEAF_NORMAL(F6_0,	"test",	rm,		byte,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(F6_1,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(F6_2,	"not",	rm,		byte,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(F6_3,	"neg",	rm,		byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(F6_4,	"mul",	rm,		byte,	none,	none,	DX_AX,	sflags,	none,	none),
+	LEAF_NORMAL(F6_5,	"imul",	rm,		byte,	none,	none,	DX_AX,	sflags,	none,	none),
+	LEAF_NORMAL(F6_6,	"div",	rm,		byte,	none,	none,	DX_AX,	sflags,	none,	none),
+	LEAF_NORMAL(F6_7,	"idiv",	rm,		byte,	none,	none,	DX_AX,	sflags,	none,	none)},
+branch_F7_[8] = {
+	LEAF_NORMAL(F7_0,	"test",	rm,		offset,	imm,		offset32,	sflags,	none,	none,	none),
+	LEAF_NORMAL(F7_1,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(F7_2,	"not",	rm,		offset,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(F7_3,	"neg",	rm,		offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(F7_4,	"mul",	rm,		offset,	none,	none,	DX_AX,	sflags,	none,	none),
+	LEAF_NORMAL(F7_5,	"imul",	rm,		offset,	none,	none,	DX_AX,	sflags,	none,	none),
+	LEAF_NORMAL(F7_6,	"div",	rm,		offset,	none,	none,	DX_AX,	sflags,	none,	none),
+	LEAF_NORMAL(F7_7,	"idiv",	rm,		offset,	none,	none,	DX_AX,	sflags,	none,	none)},
+branch_F0[8] = {
+	LEAF_NORMAL(F0,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(F1,	"icebp",	none,	none,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(F2,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(F3,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(F4,	"hlt",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(F5,	"cmc",	none,	none,	none,	none,	sflags,	none,	none,	none),
+	BRANCH_ENTRY(F6_),
+	BRANCH_ENTRY(F7_)},
+branch_FF_[8] = {
+	LEAF_NORMAL(FF_0,	"inc",	rm,		offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(FF_1,	"dec",	rm,		offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(FF_2,	"call",	rm,		offset64,	none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(FF_3,	"call",	mm,		ptr32,		none,	none,	SP,		CS,		none,	none),
+	LEAF_NORMAL(FF_4,	"jmp",	rm,		offset64,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(FF_5,	"jmp",	mm,		ptr32,		none,	none,	CS,		none,	none,	none),
+	LEAF_NORMAL(FF_6,	"push",	rm,		offset64,	none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(FF_7,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_F8[8] = {
+	LEAF_NORMAL(F8,	"clc",	none,	none,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(F9,	"stc",	none,	none,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(FA,	"cli",	none,	none,	none,	none,	flags,	none,	none,	none),
+	LEAF_NORMAL(FB,	"sti",	none,	none,	none,	none,	flags,	none,	none,	none),
+	LEAF_NORMAL(FC,	"cld",	none,	none,	none,	none,	flags,	none,	none,	none),
+	LEAF_NORMAL(FD,	"std",	none,	none,	none,	none,	flags,	none,	none,	none),
+	NAME_NORMAL(FE_,			rm,		byte,	none,	none,	sflags,			none,	none),
+	BRANCH_ENTRY(FF_)},
+oneByteTable[256 >> 3] = {
+	BRANCH_ENTRY(00),
+	BRANCH_ENTRY(08),
+	BRANCH_ENTRY(10),
+	BRANCH_ENTRY(18),
+	BRANCH_ENTRY(20),
+	BRANCH_ENTRY(28),
+	BRANCH_ENTRY(30),
+	BRANCH_ENTRY(38),
+#ifndef X86_64
+	LEAF_NORMAL(40,	"inc",	reg,		offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(48,	"dec",	reg,		offset,	none,	none,	sflags,	none,	none,	none),
+#else
+	LEAF_NORMAL(40,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(48,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(50,	"push",	reg,		offset64,	none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(58,	"pop",	reg,		offset64,	none,	offset,	tos,		none,	none,	none),
+	BRANCH_ENTRY(60),
+	BRANCH_ENTRY(68),
+	LEAF_COND(70,		"j",		disp,	byte,	none,	none,	sflags,	none,	normal,	none),
+	LEAF_COND(78,		"j",		disp,	byte,	none,	none,	sflags,	none,	normal,	none),
+	BRANCH_ENTRY(80),
+	BRANCH_ENTRY(88),
+	BRANCH_ENTRY(90),
+	BRANCH_ENTRY(98),
+	BRANCH_ENTRY(A0),
+	BRANCH_ENTRY(A8),
+	LEAF_NORMAL(B0,	"mov",	reg,		byte,	imm,		byte,	none,	none,	none,	none),
+	LEAF_NORMAL(B8,	"mov",	reg,		offset,	imm,		offset,	none,	none,	none,	none),
+	BRANCH_ENTRY(C0),
+	BRANCH_ENTRY(C8),
+	BRANCH_ENTRY(D0),
+	REGMEM_ENTRY(D8,	normal),
+	BRANCH_ENTRY(E0),
+	BRANCH_ENTRY(E8),
+	BRANCH_ENTRY(F0),
+	BRANCH_ENTRY(F8)};
Index: 2.6.14-nlkd/debug/nlkd/cda/x86_2.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/cda/x86_2.c	2005-09-01 08:37:51.000000000 +0200
@@ -0,0 +1,453 @@
+/*****************************************************************************
+ *
+ *   File Name:      x86_2.c
+ *   Created by:     Jan Beulich
+ *   Date created:   08Mar2001
+ *
+ *   %version:       8 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Thu Sep 01 00:37:38 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2001-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#ifndef X86_64
+NAME_TABLE(0F00r, "sldt", "str", "lldt", "ltr", "verr", "verw", "jmpe", NULL);
+#else
+NAME_TABLE(0F00r, "sldt", "str", "lldt", "ltr", "verr", "verw", NULL, NULL);
+#endif
+NAME_TABLE(0F71_, NULL, NULL, "psrl", NULL, "psra", NULL, "psll", NULL);
+#define names_0F72_ names_0F71_
+NAME_TABLE(0F73_, NULL, NULL, "psrl", "psrl", NULL, NULL, "psll", "psll");
+NAME_TABLE(0F90, "set", NULL, NULL, NULL, NULL, NULL, NULL, NULL);
+#define names_0F91 names_0F90
+#define names_0F92 names_0F90
+#define names_0F93 names_0F90
+#define names_0F94 names_0F90
+#define names_0F95 names_0F90
+#define names_0F96 names_0F90
+#define names_0F97 names_0F90
+#define names_0F98 names_0F90
+#define names_0F99 names_0F90
+#define names_0F9A names_0F90
+#define names_0F9B names_0F90
+#define names_0F9C names_0F90
+#define names_0F9D names_0F90
+#define names_0F9E names_0F90
+#define names_0F9F names_0F90
+NAME_TABLE(0FBA_, NULL, NULL, NULL, NULL, "bt", "bts", "btr", "btc");
+
+static const OpcodeInfo
+branch_0F00m[8] = {
+	LEAF_NORMAL(0F00m0,	"sldt",	mm,		word,	none,	none,	none,	none,	nowidth,	none),
+	LEAF_NORMAL(0F00m1,	"str",	mm,		word,	none,	none,	none,	none,	nowidth,	none),
+	LEAF_NORMAL(0F00m2,	"lldt",	mm,		word,	none,	none,	none,	none,	nowidth,	none),
+	LEAF_NORMAL(0F00m3,	"ltr",	mm,		word,	none,	none,	none,	none,	nowidth,	none),
+	LEAF_NORMAL(0F00m4,	"verr",	mm,		word,	none,	none,	none,	none,	nowidth,	none),
+	LEAF_NORMAL(0F00m5,	"verw",	mm,		word,	none,	none,	none,	none,	nowidth,	none),
+#ifndef X86_64
+	LEAF_NORMAL(0F00m6,	"jmpe",	mm,		offset,	none,	none,	none,	none,	none,	none),
+#else
+	LEAF_NORMAL(0F00m6,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(0F00m7,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+regmem_0F00[2] = {
+	BRANCH_ENTRY(0F00m),
+	NAME_NORMAL(0F00r,			rr,		offset,	none,	none,	none,			none,	none)},
+branch_0F01_1r[8] = {
+	LEAF_NORMAL(0F01_1r0, "monitor", none,	none,	none,	none,	DS_AX,	DX_CX,	none,	none),
+	LEAF_NORMAL(0F01_1r1, "mwait", none,	none,	none,	none,	CX,		AX,		none,	none),
+	LEAF_NORMAL(0F01_1r2, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_1r3, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_1r4, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_1r5, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_1r6, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_1r7, NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+regmem_0F01_1[2] = {
+	LEAF_NORMAL(0F01_1m, "sidt",	mm,		pword,	none,	none,	none,	none,	none,	opsz),
+	BRANCH_ENTRY(0F01_1r)},
+branch_0F01_3r[8] = {
+	LEAF_NORMAL(0F01_3r0, "vmrun",	none,	none,	none,	none,	AX,	none,	none,	none),
+	LEAF_NORMAL(0F01_3r1, "vmmcall", none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_3r2, "vmload",	none,	none,	none,	none,	AX,	none,	none,	none),
+	LEAF_NORMAL(0F01_3r3, "vmsave",	none,	none,	none,	none,	AX,	none,	none,	none),
+	LEAF_NORMAL(0F01_3r4, "stgi",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_3r5, "clgi",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_3r6, "skinit",	none,	none,	none,	none,	AX,	none,	none,	none),
+	LEAF_NORMAL(0F01_3r7, "invlpga", none,	none,	none,	none,	AX,	CX,	none,	none)},
+regmem_0F01_3[2] = {
+	LEAF_NORMAL(0F01_3m, "lidt",	mm,		pword,	none,	none,	none,	none,	none,	opsz),
+	BRANCH_ENTRY(0F01_3r)},
+regmem_0F01_4[2] = {
+	LEAF_NORMAL(0F01_4m, "smsw",	mm,		word,	none,	none,	none,	none,	nowidth,	none),
+	LEAF_NORMAL(0F01_4r, "smsw",	rr,		offset,	none,	none,	none,	none,	none,	none)},
+branch_0F01_7r[8] = {
+#ifndef X86_64
+	LEAF_NORMAL(0F01_7r0, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#else
+	LEAF_NORMAL(0F01_7r0, "swapgs", none,	none,	none,	none,	GS,		none,	none,	none),
+#endif
+	LEAF_NORMAL(0F01_7r1, "rdtscp", none,	none,	none,	none,	DX_AX,	CX,		none,	none),
+	LEAF_NORMAL(0F01_7r2, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_7r3, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_7r4, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_7r5, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_7r6, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_7r7, NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+regmem_0F01_7[2] = {
+	LEAF_NORMAL(0F01_7m, "invlpg", mm,		none,	none,	none,	none,	none,	none,	none),
+	BRANCH_ENTRY(0F01_7r)},
+branch_0F01_[8] = {
+	LEAF_NORMAL(0F01_0,	"sgdt",	mm,		pword,	none,	none,	none,	none,	none,	opsz),
+	REGMEM_ENTRY(0F01_1, normal),
+	LEAF_NORMAL(0F01_2,	"lgdt",	mm,		pword,	none,	none,	none,	none,	none,	opsz),
+	REGMEM_ENTRY(0F01_3, normal),
+	REGMEM_ENTRY(0F01_4, normal),
+	LEAF_NORMAL(0F01_5,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F01_6,	"lmsw",	rm,		word,	none,	none,	none,	none,	nowidth,	none),
+	REGMEM_ENTRY(0F01_7, normal)},
+branch_0F00[8] = {
+	REGMEM_ENTRY(0F00,	normal),
+	BRANCH_ENTRY(0F01_),
+	LEAF_NORMAL(0F02,	"lar",	r_rm,	offset32,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F03,	"lsl",	r_rm,	offset32,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F04,	NULL,	 none,	none,	none,	none,	none,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(0F05,	"syscall", none,	none,	none,	none,	CX,		int,		none,	none),
+#else
+	LEAF_NORMAL(0F05,	"syscall", none,	none,	none,	none,	CX_R11,	int,		none,	none),
+#endif
+	LEAF_NORMAL(0F06,	"clts",	none,	none,	none,	none,	none,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(0F07,	"sysret", none,	none,	none,	none,	CX,		int,		none,	none)},
+#else
+	LEAF_NORMAL(0F07,	"sysret", none,	none,	none,	none,	CX_R11,	int,		none,	none)},
+#endif
+branch_0F08[8] = {
+	LEAF_NORMAL(0F08,	"invd",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F09,	"wbinvd",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F0A,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F0B,	"ud2",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F0C,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F0D,	"prefetch", mm,	none,	none,	none,	none,	none,	access,	none),	// 3DNow!
+	LEAF_MMX(0F0E,		"femms",	none,	none,	none,	none,	none,			none,	none),	// 3DNow!
+	LEAF_MMX(0F0F,		NULL,	r_rm,	mmx,		none,	none,	none,			3dnow,	none)},	// 3DNow!
+regmem_0F12[8] = {
+	LEAF_XMM(0F12mPS,	"movl",	r,		xmm,		mm,		xmm,		none,			half,	none),
+	LEAF_XMM(0F12rPS,	"movhl",	r,		xmm,		rr,		xmm,		none,			packed,	none),
+	LEAF_XMM(0F12mSS,	"movsldup", r,		xmm,		rm,		xmm,		none,			none,	none),
+	LEAF_XMM(0F12rSS,	"movsldup", r,		xmm,		rm,		xmm,		none,			none,	none),
+	LEAF_XMM(0F12mPD,	"movl",	r,		xmm,		mm,		xmm,		none,			half,	none),
+	LEAF_XMM(0F12rPD,	NULL,	none,	none,	none,	none,	none,			none,	none),
+	LEAF_XMM(0F12mSD,	"movddup", r,		xmm,		rm,		xmm,		none,			none,	none),
+	LEAF_XMM(0F12rSD,	"movddup", r,		xmm,		rm,		xmm,		none,			none,	none)},
+regmem_0F16[8] = {
+	LEAF_XMM(0F16mPS,	"movh",	r,		xmm,		mm,		xmm,		none,			half,	none),
+	LEAF_XMM(0F16rPS,	"movlh",	r,		xmm,		rr,		xmm,		none,			packed,	none),
+	LEAF_XMM(0F16mSS,	"movshdup", r,		xmm,		rm,		xmm,		none,			none,	none),
+	LEAF_XMM(0F16rSS,	"movshdup", r,		xmm,		rm,		xmm,		none,			none,	none),
+	LEAF_XMM(0F16mPD,	"movh",	r,		xmm,		mm,		xmm,		none,			half,	none),
+	LEAF_XMM(0F16rPD,	NULL,	none,	none,	none,	none,	none,			none,	none),
+	LEAF_XMM(0F16mSD,	NULL,	none,	none,	none,	none,	none,			none,	none),
+	LEAF_XMM(0F16rSD,	NULL,	none,	none,	none,	none,	none,			none,	none)},
+branch_0F10[8] = {
+	LEAF_XMM(0F10,		"mov",	r_rm,	xmm,		none,	none,	none,			mode,	none),	// note: ps form is movups
+	LEAF_XMM(0F11,		"mov",	rm_r,	xmm,		none,	none,	none,			mode,	none),	// note: ps form is movups
+	REGMEM_ENTRY(0F12,	xmm),
+	LEAF_XMM(0F13,		"movl",	mm,		xmm,		r,		xmm,		none,			half,	none),
+	LEAF_XMM(0F14,		"unpckl",	r_rm,	xmm,		none,	none,	none,			packed,	none),
+	LEAF_XMM(0F15,		"unpckh",	r_rm,	xmm,		none,	none,	none,			packed,	none),
+	REGMEM_ENTRY(0F16,	xmm),
+	LEAF_XMM(0F17,		"movh",	mm,		xmm,		r,		xmm,		none,			half,	none)},
+branch_0F18[8] = {
+	LEAF_NORMAL(0F18,	"prefetch", mm,	none,	none,	none,	none,	none,	loc,		none),
+	LEAF_NORMAL(0F19,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F1A,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F1B,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F1C,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F1D,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F1E,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F1F,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_0F20[8] = {
+	LEAF_NORMAL(0F20,	"mov",	rr,		reg,		cdt,		reg,		none,	none,	none,	none),
+	LEAF_NORMAL(0F21,	"mov",	rr,		reg,		cdt,		reg,		none,	none,	none,	none),
+	LEAF_NORMAL(0F22,	"mov",	cdt,		reg,		rr,		reg,		none,	none,	none,	none),
+	LEAF_NORMAL(0F23,	"mov",	cdt,		reg,		rr,		reg,		none,	none,	none,	none),
+	LEAF_NORMAL(0F24,	"mov",	rr,		reg,		cdt,		reg,		none,	none,	none,	none),
+	LEAF_NORMAL(0F25,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F26,	"mov",	cdt,		reg,		rr,		reg,		none,	none,	none,	none),
+	LEAF_NORMAL(0F27,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_0F28[8] = {
+	LEAF_XMM(0F28,		"mova",	r_rm,	xmm,		none,	none,	none,			packed,	none),
+	LEAF_XMM(0F29,		"mova",	rm_r,	xmm,		none,	none,	none,			packed,	none),
+	LEAF_XMM(0F2A,		"cvt",	r,		xmm,		rm,		mmx,		mxcsr,			convert, none),
+	LEAF_XMM(0F2B,		"movnt",	mm,		xmm,		r,		xmm,		none,			packed,	none),
+	LEAF_XMM(0F2C,		"cvt",	r,		mmx,		rm,		xmm,		mxcsr,			convert,	none),
+	LEAF_XMM(0F2D,		"cvt",	r,		mmx,		rm,		xmm,		mxcsr,			convert,	none),
+	LEAF_XMM(0F2E,		"ucomi",	r_rm,	xmm,		none,	none,	sflags,			scalar,	none),
+	LEAF_XMM(0F2F,		"comi",	r_rm,	xmm,		none,	none,	sflags,			scalar,	none)},
+branch_0F30[8] = {
+	LEAF_NORMAL(0F30,	"wrmsr",	none,	none,	none,	none,	CX,		DX_AX,	none,	none),
+	LEAF_NORMAL(0F31,	"rdtsc",	none,	none,	none,	none,	DX_AX,	none,	none,	none),
+	LEAF_NORMAL(0F32,	"rdmsr",	none,	none,	none,	none,	CX,		DX_AX,	none,	none),
+	LEAF_NORMAL(0F33,	"rdpmc",	none,	none,	none,	none,	DX_AX,	none,	none,	none),
+#ifndef X86_64
+	LEAF_NORMAL(0F34,	"sysenter", none,	none,	none,	none,	int,		none,	none,	none),
+#else
+	LEAF_NORMAL(0F34,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(0F35,	"sysexit", none,	none,	none,	none,	DX_CX,	int,		none,	none),
+	LEAF_NORMAL(0F36,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0F37,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_0F50[8] = {
+	LEAF_XMM(0F50,		"movmsk",	r,		dword,	rr,		xmm,		none,			packed,	none),
+	LEAF_XMM(0F51,		"sqrt",	r_rm,	xmm,		none,	none,	mxcsr,			mode,	none),
+	LEAF_XMM(0F52,		"rsqrt",	r_rm,	xmm,		none,	none,	mxcsr,			single,	none),
+	LEAF_XMM(0F53,		"rcp",	r_rm,	xmm,		none,	none,	mxcsr,			single,	none),
+	LEAF_XMM(0F54,		"and",	r_rm,	xmm,		none,	none,	none,			packed,	none),
+	LEAF_XMM(0F55,		"andn",	r_rm,	xmm,		none,	none,	none,			packed,	none),
+	LEAF_XMM(0F56,		"or",	r_rm,	xmm,		none,	none,	none,			packed,	none),
+	LEAF_XMM(0F57,		"xor",	r_rm,	xmm,		none,	none,	none,			packed,	none)},
+branch_0F58[8] = {
+	LEAF_XMM(0F58,		"add",	r_rm,	xmm,		none,	none,	mxcsr,			mode,	none),
+	LEAF_XMM(0F59,		"mul",	r_rm,	xmm,		none,	none,	mxcsr,			mode,	none),
+	LEAF_XMM(0F5A,		"cvt",	r,		xmm,		rm,		xmm,		mxcsr,			convert,	none),
+	LEAF_XMM(0F5B,		"cvt",	r,		xmm,		rm,		xmm,		mxcsr,			convert,	none),
+	LEAF_XMM(0F5C,		"sub",	r_rm,	xmm,		none,	none,	mxcsr,			mode,	none),
+	LEAF_XMM(0F5D,		"min",	r_rm,	xmm,		none,	none,	mxcsr,			mode,	none),
+	LEAF_XMM(0F5E,		"div",	r_rm,	xmm,		none,	none,	mxcsr,			mode,	none),
+	LEAF_XMM(0F5F,		"max",	r_rm,	xmm,		none,	none,	mxcsr,			mode,	none)},
+branch_0F60[8] = {
+	LEAF_MMX(0F60,		"punpckl", r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0F61,		"punpckl", r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0F62,		"punpckl", r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0F63,		"pack",	r_rm,	mmx_xmm,	none,	none,	none,			shrink,	none),
+	LEAF_MMX(0F64,		"pcmpgt",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0F65,		"pcmpgt",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0F66,		"pcmpgt",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0F67,		"pack",	r_rm,	mmx_xmm,	none,	none,	none,			shrink,	none)},
+branch_0F68[8] = {
+	LEAF_MMX(0F68,		"punpckh", r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0F69,		"punpckh", r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0F6A,		"punpckh", r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0F6B,		"pack",	r_rm,	mmx_xmm,	none,	none,	none,			shrink,	none),
+	LEAF_MMX(0F6C,		"punpckl", r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0F6D,		"punpckh", r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0F6E,		"mov",	r,		mmx_xmm,	rm,		dword,	none,			normal,	none),
+	LEAF_MMX(0F6F,		"mov",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none)},
+branch_0F70[8] = {
+	LEAF_MMX(0F70,		"pshuf",	r_rm,	mmx_xmm,	imm,		byte,	none,			word,	none),
+	NAME_MMX(0F71_,			rr,		mmx_xmm,	imm,		byte,					normal,	none),
+	NAME_MMX(0F72_,			rr,		mmx_xmm,	imm,		byte,					normal,	none),
+	NAME_MMX(0F73_,			rr,		mmx_xmm,	imm,		byte,					normal,	none),
+	LEAF_MMX(0F74,		"pcmpeq",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0F75,		"pcmpeq",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0F76,		"pcmpeq",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0F77,		"emms",	none,	none,	none,	none,	none,			none,	none)},
+branch_0F78[8] = {
+	LEAF_MMX(0F78,		NULL,	none,	none,	none,	none,	none,			none,	none),
+	LEAF_MMX(0F79,		NULL,	none,	none,	none,	none,	none,			none,	none),
+	LEAF_MMX(0F7A,		NULL,	none,	none,	none,	none,	none,			none,	none),
+	LEAF_MMX(0F7B,		NULL,	none,	none,	none,	none,	none,			none,	none),
+	LEAF_XMM(0F7C,		"hadd",	r_rm,	xmm,		none,	none,	mxcsr,			sse3,	none),
+	LEAF_XMM(0F7D,		"hsub",	r_rm,	xmm,		none,	none,	mxcsr,			sse3,	none),
+	LEAF_MMX(0F7E,		"mov",	rm,		dword,	r,		mmx_xmm,	none,			normal,	none),
+	LEAF_MMX(0F7F,		"mov",	rm_r,	mmx_xmm,	none,	none,	none,			normal,	none)},
+branch_0F90[8] = {
+	NAME_COND(0F90,			rm,		byte,	none,	none,					normal,	none),
+	NAME_COND(0F91,			rm,		byte,	none,	none,					normal,	none),
+	NAME_COND(0F92,			rm,		byte,	none,	none,					normal,	none),
+	NAME_COND(0F93,			rm,		byte,	none,	none,					normal,	none),
+	NAME_COND(0F94,			rm,		byte,	none,	none,					normal,	none),
+	NAME_COND(0F95,			rm,		byte,	none,	none,					normal,	none),
+	NAME_COND(0F96,			rm,		byte,	none,	none,					normal,	none),
+	NAME_COND(0F97,			rm,		byte,	none,	none,					normal,	none)},
+#define branch_0F98 branch_0F90
+branch_0FA0[8] = {
+	LEAF_NORMAL(0FA0,	"push",	reg,		ptr,		none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(0FA1,	"pop",	reg,		ptr,		none,	word,	tos,		none,	none,	none),
+	LEAF_NORMAL(0FA2,	"cpuid",	none,	none,	none,	none,	DX_AX,	CX_BX,	none,	none),
+	LEAF_NORMAL(0FA3,	"bt",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FA4,	"shld",	rm_r,	offset,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FA5,	"shld",	rm_r,	offset,	cl_dx,	byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FA6,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FA7,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+regmem_0FAE_5[2] = {
+	LEAF_NORMAL(0FAE_5m, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FAE_5r, "lfence", none,	none,	none,	none,	none,	none,	none,	none)},
+regmem_0FAE_6[2] = {
+	LEAF_NORMAL(0FAE_6m, NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FAE_6r, "mfence", none,	none,	none,	none,	none,	none,	none,	none)},
+regmem_0FAE_7[2] = {
+	LEAF_NORMAL(0FAE_7m, "clflush", mm,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FAE_7r, "sfence", none,	none,	none,	none,	none,	none,	none,	none)},
+branch_0FAE_[8] = {
+	LEAF_NORMAL(0FAE_0,	"fxsave",	mm,		none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FAE_1,	"fxrstor", mm,		none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FAE_2,	"ldmxcsr", mm,		dword,	none,	none,	mxcsr,	none,	nowidth,	none),
+	LEAF_NORMAL(0FAE_3,	"stmxcsr", mm,		dword,	none,	none,	mxcsr,	none,	nowidth,	none),
+	LEAF_NORMAL(0FAE_4,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	REGMEM_ENTRY(0FAE_5,	normal),
+	REGMEM_ENTRY(0FAE_6,	normal),
+	REGMEM_ENTRY(0FAE_7,	normal)},
+branch_0FA8[8] = {
+	LEAF_NORMAL(0FA8,	"push",	reg,		ptr,		none,	none,	SP,		none,	none,	none),
+	LEAF_NORMAL(0FA9,	"pop",	reg,		ptr,		none,	word,	tos,		none,	none,	none),
+	LEAF_NORMAL(0FAA,	"rsm",	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FAB,	"bts",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FAC,	"shrd",	rm_r,	offset,	imm,		byte,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FAD,	"shrd",	rm_r,	offset,	cl_dx,	byte,	sflags,	none,	none,	none),
+	BRANCH_ENTRY(0FAE_),
+	LEAF_NORMAL(0FAF,	"imul",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none)},
+branch_0FB0[8] = {
+	LEAF_NORMAL(0FB0,	"cmpxchg", mm,		byte,	r,		byte,	AX,		none,	nowidth,	none),
+	LEAF_NORMAL(0FB1,	"cmpxchg", mm,		offset,	r,		offset,	AX,		none,	nowidth,	none),
+	LEAF_NORMAL(0FB2,	"lss",	r,		offset,	mm,		ptr32,	SS,		none,	nowidth,	none),
+	LEAF_NORMAL(0FB3,	"btr",	rm_r,	offset,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FB4,	"lfs",	r,		offset,	mm,		ptr32,	FS,		none,	nowidth,	none),
+	LEAF_NORMAL(0FB5,	"lgs",	r,		offset,	mm,		ptr32,	GS,		none,	nowidth,	none),
+	LEAF_NORMAL(0FB6,	"movzx",	r,		offset,	rm,		byte,	none,	none,	none,	none),
+	LEAF_NORMAL(0FB7,	"movzx",	r,		offset,	rm,		word,	none,	none,	none,	none)},
+branch_0FB8[8] = {
+#ifndef X86_64
+	LEAF_NORMAL(0FB8,	"jmpe",	imm,		offset,	none,	none,	none,	none,	none,	none),
+#else
+	LEAF_NORMAL(0FB8,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+#endif
+	LEAF_NORMAL(0FB9,	"ud2",	none,	none,	none,	none,	none,	none,	none,	none),
+	NAME_NORMAL(0FBA_,			rm,		offset,	imm,		byte,	sflags,			none,	none),
+	LEAF_NORMAL(0FBB,	"btc",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FBC,	"bsf",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FBD,	"bsr",	r_rm,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FBE,	"movsx",	r,		offset,	rm,		byte,	none,	none,	none,	none),
+	LEAF_NORMAL(0FBF,	"movsx",	r,		offset,	rm,		word,	none,	none,	none,	none)},
+branch_0FC7_[8] = {
+	LEAF_NORMAL(0FC7_0,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FC7_1,	"cmpxchg", mm,		qword,	none,	none,	DX_AX,	CX_BX,	nowidth,	none),
+	LEAF_NORMAL(0FC7_2,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FC7_3,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FC7_4,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FC7_5,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FC7_6,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_NORMAL(0FC7_7,	NULL,	none,	none,	none,	none,	none,	none,	none,	none)},
+branch_0FC0[8] = {
+	LEAF_NORMAL(0FC0,	"xadd",	rm_r,	byte,	none,	none,	sflags,	none,	none,	none),
+	LEAF_NORMAL(0FC1,	"xadd",	rm_r,	offset,	none,	none,	sflags,	none,	none,	none),
+	LEAF_XMM(0FC2,		"cmp",	r_rm,	xmm,		imm,		byte,	mxcsr,			mode,	none),
+	LEAF_NORMAL(0FC3,	"movnti",	mm,		dword,	r,		dword,	none,	none,	nowidth,	none),
+	LEAF_MMX(0FC4,		"pinsr",	mmxie,	word,	imm,		byte,	none,			word,	none),
+	LEAF_MMX(0FC5,		"pextr",	mmxie,	mmx_xmm,	imm,		byte,	none,			word,	none),
+	LEAF_XMM(0FC6,		"shuf",	r_rm,	xmm,		imm,		byte,	mxcsr,			packed,	none),
+	BRANCH_ENTRY(0FC7_)},
+branch_0FD0[8] = {
+	LEAF_XMM(0FD0,		"addsub",	r_rm,	xmm,		none,	none,	mxcsr,			sse3,	none),
+	LEAF_MMX(0FD1,		"psrl",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FD2,		"psrl",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FD3,		"psrl",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FD4,		"padd",	r_rm,	mmx_xmm,	none,	none,	none,			quad,	none),
+	LEAF_MMX(0FD5,		"pmull",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_XMM(0FD6,		"mov",	r,		xmm,		rm,		xmm,		none,			convert,	none),
+	LEAF_MMX(0FD7,		"pmovmsk", r,		dword,	rr,		mmx_xmm,	none,			byte,	none)},
+branch_0FD8[8] = {
+	LEAF_MMX(0FD8,		"psub",	r_rm,	mmx_xmm,	none,	none,	none,			saturate,	none),
+	LEAF_MMX(0FD9,		"psub",	r_rm,	mmx_xmm,	none,	none,	none,			saturate,	none),
+	LEAF_MMX(0FDA,		"pmin",	r_rm,	mmx_xmm,	none,	none,	none,			us_bw,	none),
+	LEAF_MMX(0FDB,		"pand",	r_rm,	mmx_xmm,	none,	none,	none,			none,	none),
+	LEAF_MMX(0FDC,		"padd",	r_rm,	mmx_xmm,	none,	none,	none,			saturate,	none),
+	LEAF_MMX(0FDD,		"padd",	r_rm,	mmx_xmm,	none,	none,	none,			saturate,	none),
+	LEAF_MMX(0FDE,		"pmax",	r_rm,	mmx_xmm,	none,	none,	none,			us_bw,	none),
+	LEAF_MMX(0FDF,		"pandn",	r_rm,	mmx_xmm,	none,	none,	none,			none,	none)},
+branch_0FE0[8] = {
+	LEAF_MMX(0FE0,		"pavg",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FE1,		"psra",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FE2,		"psra",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FE3,		"pavg",	r_rm,	mmx_xmm,	none,	none,	none,			word,	none),
+	LEAF_MMX(0FE4,		"pmulhu",	r_rm,	mmx_xmm,	none,	none,	none,			word,	none),
+	LEAF_MMX(0FE5,		"pmulh",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_XMM(0FE6,		"cvt",	r,		xmm,		rm,		xmm,		mxcsr,			convert,	none),
+	LEAF_MMX(0FE7,		"movnt",	mm,		mmx_xmm,	r,		mmx_xmm,	none,			normal,	none)},
+branch_0FE8[8] = {
+	LEAF_MMX(0FE8,		"psub",	r_rm,	mmx_xmm,	none,	none,	none,			saturate,	none),
+	LEAF_MMX(0FE9,		"psub",	r_rm,	mmx_xmm,	none,	none,	none,			saturate,	none),
+	LEAF_MMX(0FEA,		"pmin",	r_rm,	mmx_xmm,	none,	none,	none,			us_bw,	none),
+	LEAF_MMX(0FEB,		"por",	r_rm,	mmx_xmm,	none,	none,	none,			none,	none),
+	LEAF_MMX(0FEC,		"padd",	r_rm,	mmx_xmm,	none,	none,	none,			saturate,	none),
+	LEAF_MMX(0FED,		"padd",	r_rm,	mmx_xmm,	none,	none,	none,			saturate,	none),
+	LEAF_MMX(0FEE,		"pmax",	r_rm,	mmx_xmm,	none,	none,	none,			us_bw,	none),
+	LEAF_MMX(0FEF,		"pxor",	r_rm,	mmx_xmm,	none,	none,	none,			none,	none)},
+branch_0FF0[8] = {
+	LEAF_XMM(0FF0,		"lddqu",	r,		xmm,		mm,		xmm,		none,			none,	none),
+	LEAF_MMX(0FF1,		"psll",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FF2,		"psll",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FF3,		"psll",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FF4,		"pmuludq", r_rm,	mmx_xmm,	none,	none,	none,			none,	none),
+	LEAF_MMX(0FF5,		"pmadd",	r_rm,	mmx_xmm,	none,	none,	none,			expand,	none),
+	LEAF_MMX(0FF6,		"psad",	r_rm,	mmx_xmm,	none,	none,	none,			bw,		none),
+	LEAF_MMX(0FF7,		"maskmov", r,		mmx_xmm,	rr,		mmx_xmm,	DS_DI,			normal,	none)},
+branch_0FF8[8] = {
+	LEAF_MMX(0FF8,		"psub",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FF9,		"psub",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FFA,		"psub",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FFB,		"psub",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FFC,		"padd",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FFD,		"padd",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FFE,		"padd",	r_rm,	mmx_xmm,	none,	none,	none,			normal,	none),
+	LEAF_MMX(0FFF,		NULL,	none,	none,	none,	none,	none,			none,	none)},
+twoByteTable[256 >> 3] = {
+	BRANCH_ENTRY(0F00),
+	BRANCH_ENTRY(0F08),
+	BRANCH_ENTRY(0F10),
+	BRANCH_ENTRY(0F18),
+	BRANCH_ENTRY(0F20),
+	BRANCH_ENTRY(0F28),
+	BRANCH_ENTRY(0F30),
+	LEAF_NORMAL(0F38,	NULL,	none,	none,	none,	none,	none,	none,	none,	none),
+	LEAF_COND(0F40,	"cmov",	r_rm,	offset,	none,	none,	sflags,	none,	normal,	none),
+	LEAF_COND(0F48,	"cmov",	r_rm,	offset,	none,	none,	sflags,	none,	normal,	none),
+	BRANCH_ENTRY(0F50),
+	BRANCH_ENTRY(0F58),
+	BRANCH_ENTRY(0F60),
+	BRANCH_ENTRY(0F68),
+	BRANCH_ENTRY(0F70),
+	BRANCH_ENTRY(0F78),
+	LEAF_COND(0F80,	"j",		disp,	offset,	none,	none,	sflags,	none,	normal,	none),
+	LEAF_COND(0F88,	"j",		disp,	offset,	none,	none,	sflags,	none,	normal,	none),
+	BRANCH_ENTRY(0F90),
+	BRANCH_ENTRY(0F98),
+	BRANCH_ENTRY(0FA0),
+	BRANCH_ENTRY(0FA8),
+	BRANCH_ENTRY(0FB0),
+	BRANCH_ENTRY(0FB8),
+	BRANCH_ENTRY(0FC0),
+	LEAF_NORMAL(0FC8,	"bswap",	reg,		offset,	none,	none,	none,	none,	none,	none),
+	BRANCH_ENTRY(0FD0),
+	BRANCH_ENTRY(0FD8),
+	BRANCH_ENTRY(0FE0),
+	BRANCH_ENTRY(0FE8),
+	BRANCH_ENTRY(0FF0),
+	BRANCH_ENTRY(0FF8)
+};
Index: 2.6.14-nlkd/debug/nlkd/cda/x86_3.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/cda/x86_3.c	2005-06-27 11:40:57.000000000 +0200
@@ -0,0 +1,159 @@
+/*****************************************************************************
+ *
+ *   File Name:      x86_3.c
+ *   Created by:     Jan Beulich
+ *   Date created:   08Mar2001
+ *
+ *   %version:       3 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 03:40:43 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2001-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#define LEAF_3DNOW(oc, m) LEAF_MMX(oc, m, r_rm, mmx, none, none, none, 3dnow, none)
+static const OpcodeInfo k3d0x[16] = {
+	LEAF_3DNOW(k3d00,	NULL),
+	LEAF_3DNOW(k3d01,	NULL),
+	LEAF_3DNOW(k3d02,	NULL),
+	LEAF_3DNOW(k3d03,	NULL),
+	LEAF_3DNOW(k3d04,	NULL),
+	LEAF_3DNOW(k3d05,	NULL),
+	LEAF_3DNOW(k3d06,	NULL),
+	LEAF_3DNOW(k3d07,	NULL),
+	LEAF_3DNOW(k3d08,	NULL),
+	LEAF_3DNOW(k3d09,	NULL),
+	LEAF_3DNOW(k3d0A,	NULL),
+	LEAF_3DNOW(k3d0B,	NULL),
+	LEAF_3DNOW(k3d0C,	"pi2fw"),
+	LEAF_3DNOW(k3d0D,	"pi2fd"),
+	LEAF_3DNOW(k3d0E,	NULL),
+	LEAF_3DNOW(k3d0F,	NULL)},
+k3d1x[16] = {
+	LEAF_3DNOW(k3d10,	NULL),
+	LEAF_3DNOW(k3d11,	NULL),
+	LEAF_3DNOW(k3d12,	NULL),
+	LEAF_3DNOW(k3d13,	NULL),
+	LEAF_3DNOW(k3d14,	NULL),
+	LEAF_3DNOW(k3d15,	NULL),
+	LEAF_3DNOW(k3d16,	NULL),
+	LEAF_3DNOW(k3d17,	NULL),
+	LEAF_3DNOW(k3d18,	NULL),
+	LEAF_3DNOW(k3d19,	NULL),
+	LEAF_3DNOW(k3d1A,	NULL),
+	LEAF_3DNOW(k3d1B,	NULL),
+	LEAF_3DNOW(k3d1C,	"pf2iw"),
+	LEAF_3DNOW(k3d1D,	"pf2id"),
+	LEAF_3DNOW(k3d1E,	NULL),
+	LEAF_3DNOW(k3d1F,	NULL)},
+k3d8x[16] = {
+	LEAF_3DNOW(k3d80,	NULL),
+	LEAF_3DNOW(k3d81,	NULL),
+	LEAF_3DNOW(k3d82,	NULL),
+	LEAF_3DNOW(k3d83,	NULL),
+	LEAF_3DNOW(k3d84,	NULL),
+	LEAF_3DNOW(k3d85,	NULL),
+	LEAF_3DNOW(k3d86,	NULL),
+	LEAF_3DNOW(k3d87,	NULL),
+	LEAF_3DNOW(k3d88,	NULL),
+	LEAF_3DNOW(k3d89,	NULL),
+	LEAF_3DNOW(k3d8A,	"pfnacc"),
+	LEAF_3DNOW(k3d8B,	NULL),
+	LEAF_3DNOW(k3d8C,	NULL),
+	LEAF_3DNOW(k3d8D,	NULL),
+	LEAF_3DNOW(k3d8E,	"pfpnacc"),
+	LEAF_3DNOW(k3d8F,	NULL)},
+k3d9x[16] = {
+	LEAF_3DNOW(k3d90,	"pfcmpge"),
+	LEAF_3DNOW(k3d91,	NULL),
+	LEAF_3DNOW(k3d92,	NULL),
+	LEAF_3DNOW(k3d93,	NULL),
+	LEAF_3DNOW(k3d94,	"pfmin"),
+	LEAF_3DNOW(k3d95,	NULL),
+	LEAF_3DNOW(k3d96,	"pfrcp"),
+	LEAF_3DNOW(k3d97,	"pfrsqrt"),
+	LEAF_3DNOW(k3d98,	NULL),
+	LEAF_3DNOW(k3d99,	NULL),
+	LEAF_3DNOW(k3d9A,	"pfsub"),
+	LEAF_3DNOW(k3d9B,	NULL),
+	LEAF_3DNOW(k3d9C,	NULL),
+	LEAF_3DNOW(k3d9D,	NULL),
+	LEAF_3DNOW(k3d9E,	"pfadd"),
+	LEAF_3DNOW(k3d9F,	NULL)},
+k3dAx[16] = {
+	LEAF_3DNOW(k3dA0,	"pfcmpgt"),
+	LEAF_3DNOW(k3dA1,	NULL),
+	LEAF_3DNOW(k3dA2,	NULL),
+	LEAF_3DNOW(k3dA3,	NULL),
+	LEAF_3DNOW(k3dA4,	"pfmax"),
+	LEAF_3DNOW(k3dA5,	NULL),
+	LEAF_3DNOW(k3dA6,	"pfrcpit1"),
+	LEAF_3DNOW(k3dA7,	"pfrsqit1"),
+	LEAF_3DNOW(k3dA8,	NULL),
+	LEAF_3DNOW(k3dA9,	NULL),
+	LEAF_3DNOW(k3dAA,	"pfsubr"),
+	LEAF_3DNOW(k3dAB,	NULL),
+	LEAF_3DNOW(k3dAC,	NULL),
+	LEAF_3DNOW(k3dAD,	NULL),
+	LEAF_3DNOW(k3dAE,	"pfacc"),
+	LEAF_3DNOW(k3dAF,	NULL)},
+k3dBx[16] = {
+	LEAF_3DNOW(k3dB0,	"pfcmpeq"),
+	LEAF_3DNOW(k3dB1,	NULL),
+	LEAF_3DNOW(k3dB2,	NULL),
+	LEAF_3DNOW(k3dB3,	NULL),
+	LEAF_3DNOW(k3dB4,	"pfmul"),
+	LEAF_3DNOW(k3dB5,	NULL),
+	LEAF_3DNOW(k3dB6,	"pfrcpit2"),
+	LEAF_MMX(k3dB7,	"pmulhr",	r_rm,	mmx,		none,	none,	none,	word,	none),
+	LEAF_3DNOW(k3dB8,	NULL),
+	LEAF_3DNOW(k3dB9,	NULL),
+	LEAF_3DNOW(k3dBA,	NULL),
+	LEAF_3DNOW(k3dBB,	"pswapd"),
+	LEAF_3DNOW(k3dBC,	NULL),
+	LEAF_3DNOW(k3dBD,	NULL),
+	LEAF_3DNOW(k3dBE,	NULL),
+	LEAF_MMX(k3dBF,	"pavgus",	r_rm,	mmx,		none,	none,	none,	byte,	none)},
+#undef LEAF_3DNOW
+*const k3dTable[16] = {
+	k3d0x,
+	k3d1x,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	NULL,
+	k3d8x,
+	k3d9x,
+	k3dAx,
+	k3dBx,
+	NULL,
+	NULL,
+	NULL,
+	NULL
+};
Index: 2.6.14-nlkd/debug/nlkd/cda/x86_op.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/cda/x86_op.c	2005-06-27 11:41:25.000000000 +0200
@@ -0,0 +1,136 @@
+/*****************************************************************************
+ *
+ *   File Name:      x86_op.c
+ *   Created by:     Jan Beulich
+ *   Date created:   08Mar2001
+ *
+ *   %version:       5 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 03:41:13 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2001-2005 Novell, Inc. All Rights Reserved                  *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#if defined(OPERAND)
+
+OPERAND_NEW(_, imm),
+OPERAND(simm),
+OPERAND(accum),
+OPERAND(cl_dx),
+OPERAND(mem),
+OPERAND(reg),
+OPERAND(str_s),
+OPERAND(str_d),
+OPERAND(r),
+OPERAND(rm),
+OPERAND(rr),
+OPERAND(mm),
+OPERAND(cdt),
+OPERAND_END(_)
+// below those that can only occur in position 1
+OPERAND_NEW(1_, disp),
+OPERAND(r_rm),
+OPERAND(rm_r),
+OPERAND(mmxie),
+OPERAND_END(1_)
+
+#elif defined(HIDDEN_OPERAND)
+
+# ifndef X86_64
+HIDDEN_OPERAND(tos, general, reg_esp, none),
+HIDDEN_OPERAND(AX, general, reg_eax, none),
+HIDDEN_OPERAND(CX, general, reg_ecx, none),
+HIDDEN_OPERAND(SP, general, reg_esp, none),
+HIDDEN_OPERAND(BP, general, reg_ebp, none),
+HIDDEN_OPERAND(DX_AX, general, reg_eax, DX),
+HIDDEN_OPERAND(DX_CX, general, reg_ecx, DX),
+HIDDEN_OPERAND(CX_BX, general, reg_ebx, CX),
+HIDDEN_OPERAND(GRs, general, reg_esp, GRs1),
+#  undef CS /* colliding with include/asm/ptrace.h */
+HIDDEN_OPERAND(CS, selector, sreg_cs, none),
+#  undef DS
+HIDDEN_OPERAND(DS, selector, sreg_ds, none),
+#  undef ES
+HIDDEN_OPERAND(ES, selector, sreg_es, none),
+#  undef FS
+HIDDEN_OPERAND(FS, selector, sreg_fs, none),
+#  undef GS
+HIDDEN_OPERAND(GS, selector, sreg_gs, none),
+#  undef SS
+HIDDEN_OPERAND(SS, selector, sreg_ss, none),
+HIDDEN_OPERAND(flags, eflags, 0, none),
+HIDDEN_OPERAND(sflags, flags, 0, none),
+HIDDEN_OPERAND(ST0, floating, st0, none),
+HIDDEN_OPERAND(ST0_ST1, floating, st1, ST0),
+HIDDEN_OPERAND(fsw, fsw, 0, none),
+HIDDEN_OPERAND(fcw, fcw, 0, none),
+HIDDEN_OPERAND(mxcsr, mxcsr, 0, none),
+HIDDEN_OPERAND(DS_AX, general, reg_eax, DS),
+HIDDEN_OPERAND(DS_DI, general, reg_edi, DS),
+HIDDEN_OPERAND(int, selector, sreg_cs, flags),
+HIDDEN_EXTRA(CNT, none, 0, none),
+// below those that can only be referenced from above, but not from x86_?.c
+HIDDEN_EXTRA(DX, general, reg_edx, none),
+HIDDEN_EXTRA(GRs1, general, reg_eax, GRs2),
+HIDDEN_EXTRA(GRs2, general, reg_ecx, GRs3),
+HIDDEN_EXTRA(GRs3, general, reg_edx, GRs4),
+HIDDEN_EXTRA(GRs4, general, reg_ebx, GRs5),
+HIDDEN_EXTRA(GRs5, general, reg_ebp, GRs6),
+HIDDEN_EXTRA(GRs6, general, reg_esi, GRs7),
+HIDDEN_EXTRA(GRs7, general, reg_edi, none)
+# else
+HIDDEN_OPERAND(tos, general, reg_rsp, none),
+HIDDEN_OPERAND(AX, general, reg_rax, none),
+HIDDEN_OPERAND(CX, general, reg_rcx, none),
+HIDDEN_OPERAND(SP, general, reg_rsp, none),
+HIDDEN_OPERAND(BP, general, reg_rbp, none),
+HIDDEN_OPERAND(DI, general, reg_rdi, none),
+HIDDEN_OPERAND(DX_AX, general, reg_rax, DX),
+HIDDEN_OPERAND(DX_CX, general, reg_rcx, DX),
+HIDDEN_OPERAND(CX_BX, general, reg_rbx, CX),
+HIDDEN_OPERAND(CX_R11, general, reg_rcx, R11),
+HIDDEN_OPERAND(CS, selector, sreg_cs, none),
+HIDDEN_OPERAND(FS, selector, sreg_fs, none),
+HIDDEN_OPERAND(GS, selector, sreg_gs, none),
+HIDDEN_OPERAND(SS, selector, sreg_ss, none),
+HIDDEN_OPERAND(flags, rflags, 0, none),
+HIDDEN_OPERAND(sflags, flags, 0, none),
+HIDDEN_OPERAND(ST0, floating, st0, none),
+HIDDEN_OPERAND(ST0_ST1, floating, st1, ST0),
+HIDDEN_OPERAND(fsw, fsw, 0, none),
+HIDDEN_OPERAND(fcw, fcw, 0, none),
+HIDDEN_OPERAND(mxcsr, mxcsr, 0, none),
+#  define hidop_DS_AX hidop_AX
+#  define hidop_DS_DI hidop_DI
+HIDDEN_OPERAND(int, selector, sreg_cs, flags),
+HIDDEN_EXTRA(CNT, none, 0, none),
+// below those that can only be referenced from above, but not from x86_?.c
+HIDDEN_EXTRA(DX, general, reg_rdx, none),
+HIDDEN_EXTRA(R11, general, reg_r11, none)
+# endif
+
+#endif

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 15/39] NLKD - early pseudo-fs
  2005-11-09 14:09                     ` [PATCH 15/39] NLKD - early pseudo-fs Jan Beulich
  2005-11-09 14:11                       ` [PATCH 16/39] NLKD - core adjustments Jan Beulich
@ 2005-11-09 14:29                       ` Al Viro
  2005-11-09 14:37                         ` Jan Beulich
  1 sibling, 1 reply; 105+ messages in thread
From: Al Viro @ 2005-11-09 14:29 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, Nov 09, 2005 at 03:09:54PM +0100, Jan Beulich wrote:
> While for limited amounts of configuration information the kernel
> command line may be suitable, it isn't when it comes to significant
> amounts of configurable entities that need to be set before the full
> kernel infrastructure is available. This patch adds functionality to
> pass one or more configuration files through the initrd, but without
> requiring knowledge of the actual structure (including compression) of
> it; the file(s) is/are attached to the end of the already built
> initrd (which obviously depends on external scripts not provided
> here).

What the hell for?  We _already_ have a way to get any set of files in
a filesystem as soon as we have VFS caches set up (and until then you
can't open anything anyway).

NAK.

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 38/39] NLKD/i386 - Remote Debug Agent
       [not found]                                 ` <43721600.76F0.0078.0@novell.com>
@ 2005-11-09 14:30                                   ` Jan Beulich
  2005-11-09 14:31                                   ` [PATCH 39/39] NLKD/x86-64 " Jan Beulich
  1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:30 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 135 bytes --]

The i386-dependent part of the Remote Debug Agent of NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-rda-i386.patch --]
[-- Type: application/octet-stream, Size: 15695 bytes --]

The i386-dependent part of the Remote Debug Agent of NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/debug/nlkd/rda/rdaIA32.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/rda/rdaIA32.c	2005-06-27 12:00:41.000000000 +0200
@@ -0,0 +1,431 @@
+/*****************************************************************************
+ *
+ *   File Name:      rdaIA32.c
+ *   Created by:     Jan Beulich
+ *   Date created:   23Jan2003
+ *
+ *   %version:       7 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 04:00:30 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2003-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#include <asm/cde.h>
+
+#include "rda.h"
+
+#define r_FTW (r_invalid - 1)
+#define r_FIP (r_invalid - 2)
+#define r_FDP (r_invalid - 3)
+#define r_FOP (r_invalid - 4)
+
+#undef EAX /* colliding with include/asm/ptrace.h */
+#undef ECX
+#undef EDX
+#undef EBX
+#undef EBP
+#undef ESP
+#undef ESI
+#undef EDI
+#undef EIP
+#undef CS
+#undef DS
+#undef ES
+#undef FS
+#undef GS
+#undef SS
+#define REGINFO(gdb, w, cls, idx) gdb,
+enum gdb_registers {
+#include "rdaIA32.incl"
+	gdbCOUNT
+};
+#undef REGINFO
+
+union fpreg_u {
+	float80_t raw;
+	struct {
+		uint32_t mant_lo;
+		uint32_t mant_hi;
+		uint16_t sign_exp;
+	};
+};
+
+cdeBool_t rdaSetPC(RdaSessionState*state, uintptr_t address) {
+	if(!cdeWriteEIP(state->currentFrame, address)) {
+		rdaError(state, RDA_EINVAL);
+		return cdeFalse;
+	}
+	return cdeTrue;
+}
+
+void rdaPutFrameInfo(RdaSessionState*state) {
+	const ftaFullInterruptionCtx_t*frame = state->currentFrame;
+	int sigval;
+	uint32_t value;
+
+	switch(cdeGetInterruptionType(frame, NULL)) {
+	default:
+		sigval = 2;
+		break;
+	case IA32_ILLEGAL_OPCODE:
+		sigval = 4;
+		break;
+	case IA32_DEBUG:
+	case IA32_BREAKPOINT:
+		sigval = 5;
+		break;
+	case IA32_RSVD_0F:
+	case IA32_RSVD_14:
+	case IA32_RSVD_15:
+	case IA32_RSVD_16:
+	case IA32_RSVD_17:
+	case IA32_RSVD_18:
+	case IA32_RSVD_19:
+	case IA32_RSVD_1A:
+	case IA32_RSVD_1B:
+	case IA32_RSVD_1C:
+	case IA32_RSVD_1D:
+	case IA32_RSVD_1E:
+	case IA32_RSVD_1F:
+		sigval = 6;
+		break;
+	case IA32_DOUBLE_FAULT:
+		sigval = 7;
+		break;
+	case IA32_DIVIDE_ERROR:
+	case IA32_DEVICE_NOT_AVAILABLE:
+	case IA32_FP_ERROR:
+	case IA32_SIMD_FP_ERROR:
+		sigval = 8;
+		break;
+	case IA32_ALIGNMENT_CHECK:
+		sigval = 10;
+		break;
+	case IA32_COPROCESSOR_SEGMENT_OVERRUN:
+	case IA32_INVALID_TSS:
+	case IA32_SEGMENT_NOT_PRESENT:
+	case IA32_GENERAL_PROTECTION_FAULT:
+	case IA32_PAGE_FAULT:
+		sigval = 11;
+		break;
+	case IA32_OVERFLOW:
+	case IA32_BOUNDS_CHECK:
+	case IA32_STACK_FAULT:
+		sigval = 16;
+		break;
+	}
+	rdaPutHex(state, sigval, 1);
+	rdaPutHex(state, EIP, 0);
+	rdaPutChar(state, ':');
+	rdaPutHex(state, cdeReadEIP(frame), -4);
+	rdaPutChar(state, ';');
+	if(cdeReadGR(reg_esp, frame, &value)) {
+		rdaPutHex(state, ESP, 0);
+		rdaPutChar(state, ':');
+		rdaPutHex(state, value, -4);
+		rdaPutChar(state, ';');
+	}
+	if(cdeReadGR(reg_ebp, frame, &value)) {
+		rdaPutHex(state, EBP, 0);
+		rdaPutChar(state, ':');
+		rdaPutHex(state, value, -4);
+		rdaPutChar(state, ';');
+	}
+}
+
+#define REGINFO(gdb, w, cls, idx) {r_##cls, idx},
+static const struct regInfo {
+	signed char type;
+	unsigned char index;
+} regInfo[] = {
+#include "rdaIA32.incl"
+};
+#undef REGINFO
+
+void rdaGetRegisters(RdaSessionState*state,
+		const char*input,
+		size_t inputSize) {
+	unsigned i;
+
+	if(state->currentFrame == NULL) {
+		rdaError(state, RDA_EAGAIN);
+		return;
+	}
+	if(inputSize != 0) {
+		rdaError(state, RDA_EINVAL);
+		return;
+	}
+	for(i = 0; i < gdbCOUNT; ++i) {
+		switch(regInfo[i].type) {
+		case r_eip:
+			rdaPutHex(state, cdeReadEIP(state->currentFrame), -4);
+			break;
+		case r_eflags:
+			rdaPutHex(state, cdeReadEFLAGS(state->currentFrame), -4);
+			break;
+		case r_general: {
+				uint32_t value;
+
+				if(!cdeReadGR(regInfo[i].index, state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_selector: {
+				uint16_t value;
+
+				if(!cdeReadSR(regInfo[i].index, state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_floating: {
+				union fpreg_u value;
+
+				if(!cdeReadFR(regInfo[i].index, state->currentFrame, &value.raw))
+					dbgZeroMem(&value, sizeof(value));
+				rdaPutHex(state, value.mant_lo, -4);
+				rdaPutHex(state, value.mant_hi, -4);
+				rdaPutHex(state, value.sign_exp, -2);
+			}
+			break;
+		case r_fcw: {
+				uint16_t value;
+
+				if(!cdeReadFpuControlWord(state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_fsw: {
+				uint16_t value;
+
+				if(!cdeReadFpuStatusWord(state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_FTW: {
+				uint16_t value;
+
+				if(!cdeReadFpuTagWord(state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_FIP: {
+				struct CdeAddress address;
+
+				if(!cdeReadFpuCodePointer(state->currentFrame, &address))
+					dbgZeroMem(&address, sizeof(address));
+				rdaPutHex(state, regInfo[i].index ? address.selector : address.offset, -4);
+			}
+			break;
+		case r_FDP: {
+				struct CdeAddress address;
+
+				if(!cdeReadFpuDataPointer(state->currentFrame, &address))
+					dbgZeroMem(&address, sizeof(address));
+				rdaPutHex(state, regInfo[i].index ? address.selector : address.offset, -4);
+			}
+			break;
+		case r_FOP: {
+				uint16_t value;
+
+				if(!cdeReadFpuOpcode(state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_xmm:
+			if(cdeWriteMXCSR(NULL, 0)) {
+				xmmreg_t value;
+
+				if(!cdeReadXMM(regInfo[i].index, state->currentFrame, &value))
+					dbgZeroMem(&value, sizeof(value));
+				rdaPutHex(state, value.d[0], -4);
+				rdaPutHex(state, value.d[1], -4);
+				rdaPutHex(state, value.d[2], -4);
+				rdaPutHex(state, value.d[3], -4);
+			}
+			break;
+		case r_mxcsr:
+			if(cdeWriteMXCSR(NULL, 0)) {
+				uint32_t value;
+
+				if(!cdeReadMXCSR(state->currentFrame, &value))
+					dbgZeroMem(&value, sizeof(value));
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		default:
+			RTASSERT(!(regInfo + i));
+			break;
+		}
+	}
+}
+
+static cdeBool_t setReg(RdaSessionState*state,
+		const struct regInfo*info,
+		const char**pInput) {
+	cdeBool_t result = cdeFalse;
+
+	switch(info->type) {
+		uint32_t value;
+
+	case r_eip:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = cdeWriteEIP(state->currentFrame, value);
+		break;
+	case r_eflags:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = cdeWriteEFLAGS(state->currentFrame, value);
+		break;
+	case r_general:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = cdeWriteGR(info->index, state->currentFrame, value);
+		break;
+	case r_selector:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = (value == (uint16_t)value && cdeWriteSR(info->index, state->currentFrame, (uint16_t)value));
+		break;
+	case r_floating: {
+			union fpreg_u value;
+
+			value.mant_lo = rdaGetHex(*pInput, pInput, -4);
+			if(*pInput != NULL)
+				value.mant_hi = rdaGetHex(*pInput, pInput, -4);
+			if(*pInput != NULL)
+				value.sign_exp = (uint16_t)rdaGetHex(*pInput, pInput, -2);
+			if(*pInput != NULL)
+				result = cdeWriteFR(info->index, state->currentFrame, &value.raw);
+		}
+		break;
+	case r_fcw:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = (value == (uint16_t)value && cdeWriteFpuControlWord(state->currentFrame, (uint16_t)value));
+		break;
+	case r_fsw:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = (value == (uint16_t)value && cdeWriteFpuStatusWord(state->currentFrame, (uint16_t)value));
+		break;
+	case r_FTW:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = (value == (uint16_t)value && cdeWriteFpuTagWord(state->currentFrame, (uint16_t)value));
+		break;
+	case r_FIP:
+	case r_FDP:
+	case r_FOP:
+		result = cdeFalse;
+		break;
+	case r_xmm: {
+			xmmreg_t value;
+
+			value.d[0] = rdaGetHex(*pInput, pInput, -4);
+			if(*pInput != NULL)
+				value.d[1] = rdaGetHex(*pInput, pInput, -4);
+			if(*pInput != NULL)
+				value.d[2] = rdaGetHex(*pInput, pInput, -4);
+			if(*pInput != NULL)
+				value.d[3] = rdaGetHex(*pInput, pInput, -4);
+			if(*pInput != NULL)
+				result = cdeWriteXMM(info->index, state->currentFrame, &value);
+		}
+		break;
+	case r_mxcsr:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = cdeWriteMXCSR(state->currentFrame, value);
+		break;
+	default:
+		RTASSERT(!info);
+		break;
+	}
+	if(*pInput == NULL) {
+		rdaError(state, RDA_EFORMAT);
+		result = cdeFalse;
+	}
+	else if(!result)
+		rdaError(state, RDA_EINVAL);
+	return result;
+}
+
+void rdaSetRegisters(RdaSessionState*state,
+		const char*input,
+		size_t inputSize) {
+	unsigned index;
+	const char*end;
+
+	if(state->currentFrame == NULL) {
+		rdaError(state, RDA_EAGAIN);
+		return;
+	}
+	if(inputSize & 1) {
+		rdaError(state, RDA_EINVAL);
+		return;
+	}
+	for(index = 0, end = input; index < gdbCOUNT; ++index) {
+		if(!setReg(state, regInfo + index, &end))
+			return;
+		if(input + inputSize == end)
+			break;
+	}
+	if(index == gdbCOUNT)
+		rdaOK(state);
+	else
+		rdaError(state, RDA_EPARTIAL);
+}
+
+void rdaSetRegister(RdaSessionState*state,
+		const char*input,
+		size_t inputSize) {
+	const char*end;
+	uintptr_t index = rdaGetHex(input, &end, 0);
+
+	if(index >= gdbCOUNT) {
+		rdaError(state, RDA_EINVAL);
+		return;
+	}
+	if(state->currentFrame == NULL) {
+		rdaError(state, RDA_EAGAIN);
+		return;
+	}
+	if(!setReg(state, regInfo + index, &input))
+		return;
+	if(input + inputSize == end)
+		rdaOK(state);
+	else
+		rdaError(state, RDA_EFORMAT);
+}
Index: 2.6.14-nlkd/debug/nlkd/rda/rdaIA32.incl
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/rda/rdaIA32.incl	2005-06-27 12:01:06.000000000 +0200
@@ -0,0 +1,78 @@
+/*****************************************************************************
+ *
+ *   File Name:      rdaIA32.incl
+ *   Created by:     Jan Beulich
+ *   Date created:   23Jan2003
+ *
+ *   %version:       3 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 04:00:55 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2003-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+REGINFO(EAX,    4, general,  reg_eax)
+REGINFO(ECX,    4, general,  reg_ecx)
+REGINFO(EDX,    4, general,  reg_edx)
+REGINFO(EBX,    4, general,  reg_ebx)
+REGINFO(ESP,    4, general,  reg_esp)
+REGINFO(EBP,    4, general,  reg_ebp)
+REGINFO(ESI,    4, general,  reg_esi)
+REGINFO(EDI,    4, general,  reg_edi)
+REGINFO(EIP,    4, eip,      0)
+REGINFO(EFLAGS, 4, eflags,   0)
+REGINFO(CS,     4, selector, sreg_cs)
+REGINFO(SS,     4, selector, sreg_ss)
+REGINFO(DS,     4, selector, sreg_ds)
+REGINFO(ES,     4, selector, sreg_es)
+REGINFO(FS,     4, selector, sreg_fs)
+REGINFO(GS,     4, selector, sreg_gs)
+REGINFO(ST0,   10, floating, st0)
+REGINFO(ST1,   10, floating, st1)
+REGINFO(ST2,   10, floating, st2)
+REGINFO(ST3,   10, floating, st3)
+REGINFO(ST4,   10, floating, st4)
+REGINFO(ST5,   10, floating, st5)
+REGINFO(ST6,   10, floating, st6)
+REGINFO(ST7,   10, floating, st7)
+REGINFO(FCTRL,  4, fcw,      0)
+REGINFO(FSTAT,  4, fsw,      0)
+REGINFO(FTAG,   4, FTW,      0)
+REGINFO(FISEG,  4, FIP,      1)
+REGINFO(FIOFF,  4, FIP,      0)
+REGINFO(FOSEG,  4, FDP,      1)
+REGINFO(FOOFF,  4, FDP,      0)
+REGINFO(FOP,    4, FOP,      0)
+REGINFO(XMM0,  16, xmm,      0)
+REGINFO(XMM1,  16, xmm,      1)
+REGINFO(XMM2,  16, xmm,      2)
+REGINFO(XMM3,  16, xmm,      3)
+REGINFO(XMM4,  16, xmm,      4)
+REGINFO(XMM5,  16, xmm,      5)
+REGINFO(XMM6,  16, xmm,      6)
+REGINFO(XMM7,  16, xmm,      7)
+REGINFO(MXCSR,  4, mxcsr,    0)

^ permalink raw reply	[flat|nested] 105+ messages in thread

* [PATCH 39/39] NLKD/x86-64 - Remote Debug Agent
       [not found]                                 ` <43721600.76F0.0078.0@novell.com>
  2005-11-09 14:30                                   ` [PATCH 38/39] NLKD/i386 - Remote " Jan Beulich
@ 2005-11-09 14:31                                   ` Jan Beulich
  1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:31 UTC (permalink / raw)
  To: Andreas Kleen; +Cc: linux-kernel, discuss

[-- Attachment #1: Type: text/plain, Size: 137 bytes --]

The x86_64-dependent part of the Remote Debug Agent of NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

(actual patch attached)


[-- Attachment #2: nlkd-rda-x86_64.patch --]
[-- Type: application/octet-stream, Size: 15648 bytes --]

The x86_64-dependent part of the Remote Debug Agent of NLKD.

Signed-Off-By: Jan Beulich <jbeulich@novell.com>

Index: 2.6.14-nlkd/debug/nlkd/rda/rdaAMD64.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/rda/rdaAMD64.c	2005-06-27 11:59:51.000000000 +0200
@@ -0,0 +1,406 @@
+/*****************************************************************************
+ *
+ *   File Name:      rdaAMD64.c
+ *   Created by:     Jan Beulich
+ *   Date created:   28Jan2003
+ *
+ *   %version:       7 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 03:59:40 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2003-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+#include <asm/cde.h>
+
+#include "rda.h"
+
+#define r_FTW (r_invalid - 1)
+#define r_FIP (r_invalid - 2)
+#define r_FDP (r_invalid - 3)
+#define r_FOP (r_invalid - 4)
+
+#define REGINFO(gdb, w, cls, idx) gdb,
+enum gdb_registers {
+#include "rdaAMD64.incl"
+	gdbCOUNT
+};
+#undef REGINFO
+
+union fpreg_u {
+	float80_t raw;
+	struct {
+		uint64_t mant;
+		uint16_t sign_exp;
+	};
+};
+
+cdeBool_t rdaSetPC(RdaSessionState*state, uintptr_t address) {
+	if(!cdeWriteRIP(state->currentFrame, address)) {
+		rdaError(state, RDA_EINVAL);
+		return cdeFalse;
+	}
+	return cdeTrue;
+}
+
+void rdaPutFrameInfo(RdaSessionState*state) {
+	const ftaFullInterruptionCtx_t*frame = state->currentFrame;
+	int sigval;
+	uint64_t value;
+
+	switch(cdeGetInterruptionType(frame, NULL)) {
+	default:
+		sigval = 2;
+		break;
+	case AMD64_ILLEGAL_OPCODE:
+		sigval = 4;
+		break;
+	case AMD64_DEBUG:
+	case AMD64_BREAKPOINT:
+		sigval = 5;
+		break;
+	case AMD64_RSVD_09:
+	case AMD64_RSVD_0F:
+	case AMD64_RSVD_14:
+	case AMD64_RSVD_15:
+	case AMD64_RSVD_16:
+	case AMD64_RSVD_17:
+	case AMD64_RSVD_18:
+	case AMD64_RSVD_19:
+	case AMD64_RSVD_1A:
+	case AMD64_RSVD_1B:
+	case AMD64_RSVD_1C:
+	case AMD64_RSVD_1D:
+	case AMD64_RSVD_1E:
+	case AMD64_RSVD_1F:
+		sigval = 6;
+		break;
+	case AMD64_DOUBLE_FAULT:
+		sigval = 7;
+		break;
+	case AMD64_DIVIDE_ERROR:
+	case AMD64_DEVICE_NOT_AVAILABLE:
+	case AMD64_FP_ERROR:
+	case AMD64_SIMD_FP_ERROR:
+		sigval = 8;
+		break;
+	case AMD64_ALIGNMENT_CHECK:
+		sigval = 10;
+		break;
+	case AMD64_INVALID_TSS:
+	case AMD64_SEGMENT_NOT_PRESENT:
+	case AMD64_GENERAL_PROTECTION_FAULT:
+	case AMD64_PAGE_FAULT:
+		sigval = 11;
+		break;
+	case AMD64_OVERFLOW:
+	case AMD64_BOUNDS_CHECK:
+	case AMD64_STACK_FAULT:
+		sigval = 16;
+		break;
+	}
+	rdaPutHex(state, sigval, 1);
+	rdaPutHex(state, RIP, 0);
+	rdaPutChar(state, ':');
+	rdaPutHex(state, cdeReadRIP(frame), -8);
+	rdaPutChar(state, ';');
+	if(cdeReadGR(reg_rsp, frame, &value)) {
+		rdaPutHex(state, RSP, 0);
+		rdaPutChar(state, ':');
+		rdaPutHex(state, value, -8);
+		rdaPutChar(state, ';');
+	}
+	if(cdeReadGR(reg_rbp, frame, &value)) {
+		rdaPutHex(state, RBP, 0);
+		rdaPutChar(state, ':');
+		rdaPutHex(state, value, -8);
+		rdaPutChar(state, ';');
+	}
+}
+
+#define REGINFO(gdb, w, cls, idx) {r_##cls, idx},
+static const struct regInfo {
+	signed char type;
+	unsigned char index;
+} regInfo[] = {
+#include "rdaAMD64.incl"
+};
+#undef REGINFO
+
+void rdaGetRegisters(RdaSessionState*state,
+		const char*input,
+		size_t inputSize) {
+	unsigned i;
+
+	if(state->currentFrame == NULL) {
+		rdaError(state, RDA_EAGAIN);
+		return;
+	}
+	if(inputSize != 0) {
+		rdaError(state, RDA_EINVAL);
+		return;
+	}
+	for(i = 0; i < gdbCOUNT; ++i) {
+		switch(regInfo[i].type) {
+		case r_rip:
+			rdaPutHex(state, cdeReadRIP(state->currentFrame), -8);
+			break;
+		case r_rflags:
+			rdaPutHex(state, cdeReadRFLAGS(state->currentFrame), -4);
+			break;
+		case r_general: {
+				uint64_t value;
+
+				if(!cdeReadGR(regInfo[i].index, state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -8);
+			}
+			break;
+		case r_selector: {
+				uint16_t value;
+
+				if(!cdeReadSR(regInfo[i].index, state->currentFrame, &value, NULL))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_floating: {
+				union fpreg_u value;
+
+				if(!cdeReadFR(regInfo[i].index, state->currentFrame, &value.raw))
+					dbgZeroMem(&value, sizeof(value));
+				rdaPutHex(state, value.mant, -8);
+				rdaPutHex(state, value.sign_exp, -2);
+			}
+			break;
+		case r_fcw: {
+				uint16_t value;
+
+				if(!cdeReadFpuControlWord(state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_fsw: {
+				uint16_t value;
+
+				if(!cdeReadFpuStatusWord(state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_FTW: {
+				uint16_t value;
+
+				if(!cdeReadFpuTagWord(state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_FIP: {
+				struct CdeAddress address;
+
+				if(!cdeReadFpuCodePointer(state->currentFrame, &address))
+					dbgZeroMem(&address, sizeof(address));
+				rdaPutHex(state, regInfo[i].index ? address.selector : address.offset, -4);
+			}
+			break;
+		case r_FDP: {
+				struct CdeAddress address;
+
+				if(!cdeReadFpuDataPointer(state->currentFrame, &address))
+					dbgZeroMem(&address, sizeof(address));
+				rdaPutHex(state, regInfo[i].index ? address.selector : address.offset, -4);
+			}
+			break;
+		case r_FOP: {
+				uint16_t value;
+
+				if(!cdeReadFpuOpcode(state->currentFrame, &value))
+					value = 0;
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		case r_xmm:
+			if(cdeWriteMXCSR(NULL, 0)) {
+				xmmreg_t value;
+
+				if(!cdeReadXMM(regInfo[i].index, state->currentFrame, &value))
+					dbgZeroMem(&value, sizeof(value));
+				rdaPutHex(state, value.q[0], -8);
+				rdaPutHex(state, value.q[1], -8);
+			}
+			break;
+		case r_mxcsr:
+			if(cdeWriteMXCSR(NULL, 0)) {
+				uint32_t value;
+
+				if(!cdeReadMXCSR(state->currentFrame, &value))
+					dbgZeroMem(&value, sizeof(value));
+				rdaPutHex(state, value, -4);
+			}
+			break;
+		default:
+			RTASSERT(!(regInfo + i));
+			break;
+		}
+	}
+}
+
+static cdeBool_t setReg(RdaSessionState*state,
+		const struct regInfo*info,
+		const char**pInput) {
+	cdeBool_t result = cdeFalse;
+
+	switch(info->type) {
+		uint64_t value;
+
+	case r_rip:
+		value = rdaGetHex(*pInput, pInput, -8);
+		if(*pInput != NULL)
+			result = cdeWriteRIP(state->currentFrame, value);
+		break;
+	case r_rflags:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = cdeWriteRFLAGS(state->currentFrame, value);
+		break;
+	case r_general:
+		value = rdaGetHex(*pInput, pInput, -8);
+		if(*pInput != NULL)
+			result = cdeWriteGR(info->index, state->currentFrame, value);
+		break;
+	case r_selector:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = (value == (uint16_t)value && cdeWriteSR(info->index, state->currentFrame, (uint16_t)value, NULL));
+		break;
+	case r_floating: {
+			union fpreg_u value;
+
+			value.mant = rdaGetHex(*pInput, pInput, -8);
+			if(*pInput != NULL)
+				value.sign_exp = (uint16_t)rdaGetHex(*pInput, pInput, -2);
+			if(*pInput != NULL)
+				result = cdeWriteFR(info->index, state->currentFrame, &value.raw);
+		}
+		break;
+	case r_fcw:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = (value == (uint16_t)value && cdeWriteFpuControlWord(state->currentFrame, (uint16_t)value));
+		break;
+	case r_fsw:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = (value == (uint16_t)value && cdeWriteFpuStatusWord(state->currentFrame, (uint16_t)value));
+		break;
+	case r_FTW:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = (value == (uint16_t)value && cdeWriteFpuTagWord(state->currentFrame, (uint16_t)value));
+		break;
+	case r_FIP:
+	case r_FDP:
+	case r_FOP:
+		result = cdeFalse;
+		break;
+	case r_xmm: {
+			xmmreg_t value;
+
+			value.q[0] = rdaGetHex(*pInput, pInput, -8);
+			if(*pInput != NULL)
+				value.q[1] = rdaGetHex(*pInput, pInput, -8);
+			if(*pInput != NULL)
+				result = cdeWriteXMM(info->index, state->currentFrame, &value);
+		}
+		break;
+	case r_mxcsr:
+		value = rdaGetHex(*pInput, pInput, -4);
+		if(*pInput != NULL)
+			result = cdeWriteMXCSR(state->currentFrame, (uint32_t)value);
+		break;
+	default:
+		RTASSERT(!info);
+		break;
+	}
+	if(*pInput == NULL) {
+		rdaError(state, RDA_EFORMAT);
+		result = cdeFalse;
+	}
+	else if(!result)
+		rdaError(state, RDA_EINVAL);
+	return result;
+}
+
+void rdaSetRegisters(RdaSessionState*state,
+		const char*input,
+		size_t inputSize) {
+	unsigned index;
+	const char*end;
+
+	if(state->currentFrame == NULL) {
+		rdaError(state, RDA_EAGAIN);
+		return;
+	}
+	if(inputSize & 1) {
+		rdaError(state, RDA_EINVAL);
+		return;
+	}
+	for(index = 0, end = input; index < gdbCOUNT; ++index) {
+		if(!setReg(state, regInfo + index, &end))
+			return;
+		if(input + inputSize == end)
+			break;
+	}
+	if(index == gdbCOUNT)
+		rdaOK(state);
+	else
+		rdaError(state, RDA_EPARTIAL);
+}
+
+void rdaSetRegister(RdaSessionState*state,
+		const char*input,
+		size_t inputSize) {
+	const char*end;
+	uintptr_t index = rdaGetHex(input, &end, 0);
+
+	if(index >= gdbCOUNT) {
+		rdaError(state, RDA_EINVAL);
+		return;
+	}
+	if(state->currentFrame == NULL) {
+		rdaError(state, RDA_EAGAIN);
+		return;
+	}
+	if(!setReg(state, regInfo + index, &input))
+		return;
+	if(input + inputSize == end)
+		rdaOK(state);
+	else
+		rdaError(state, RDA_EFORMAT);
+}
Index: 2.6.14-nlkd/debug/nlkd/rda/rdaAMD64.incl
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ 2.6.14-nlkd/debug/nlkd/rda/rdaAMD64.incl	2005-06-27 12:00:17.000000000 +0200
@@ -0,0 +1,92 @@
+/*****************************************************************************
+ *
+ *   File Name:      rdaAMD64.incl
+ *   Created by:     Jan Beulich
+ *   Date created:   28Jan2003
+ *
+ *   %version:       3 %
+ *   %derived_by:    jbeulich %
+ *   %date_modified: Mon Jun 27 04:00:05 2005 %
+ *
+ *****************************************************************************/
+/*****************************************************************************
+ *                                                                           *
+ * Copyright (c) 2003-2005 Novell, Inc. All Rights Reserved.                 *
+ *                                                                           *
+ * This program is free software; you can redistribute it and/or             *
+ * modify it under the terms of version 2 of the GNU General Public License  *
+ * as published by the Free Software Foundation.                             *
+ *                                                                           *
+ * This program is distributed in the hope that it will be useful,           *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the              *
+ * GNU General Public License for more details.                              *
+ *                                                                           *
+ * You should have received a copy of the GNU General Public License         *
+ * along with this program; if not, contact Novell, Inc.                     *
+ *                                                                           *
+ * To contact Novell about this file by physical or electronic mail,         *
+ * you may find current contact information at www.novell.com.               *
+ *                                                                           *
+ *****************************************************************************/
+/*****************************************************************************
+ *
+ *	File Description:
+ *
+ *****************************************************************************/
+
+REGINFO(RAX,    8, general,  reg_rax)
+REGINFO(RCX,    8, general,  reg_rcx)
+REGINFO(RDX,    8, general,  reg_rdx)
+REGINFO(RBX,    8, general,  reg_rbx)
+REGINFO(RSP,    8, general,  reg_rsp)
+REGINFO(RBP,    8, general,  reg_rbp)
+REGINFO(RSI,    8, general,  reg_rsi)
+REGINFO(RDI,    8, general,  reg_rdi)
+REGINFO(R8,     8, general,  reg_r8)
+REGINFO(R9,     8, general,  reg_r9)
+REGINFO(R10,    8, general,  reg_r10)
+REGINFO(R11,    8, general,  reg_r11)
+REGINFO(R12,    8, general,  reg_r12)
+REGINFO(R13,    8, general,  reg_r13)
+REGINFO(R14,    8, general,  reg_r14)
+REGINFO(R15,    8, general,  reg_r15)
+REGINFO(RIP,    8, rip,      0)
+REGINFO(EFLAGS, 4, rflags,   0)
+REGINFO(DS,     4, selector, sreg_ds)
+REGINFO(ES,     4, selector, sreg_es)
+REGINFO(FS,     4, selector, sreg_fs)
+REGINFO(GS,     4, selector, sreg_gs)
+REGINFO(ST0,   10, floating, st0)
+REGINFO(ST1,   10, floating, st1)
+REGINFO(ST2,   10, floating, st2)
+REGINFO(ST3,   10, floating, st3)
+REGINFO(ST4,   10, floating, st4)
+REGINFO(ST5,   10, floating, st5)
+REGINFO(ST6,   10, floating, st6)
+REGINFO(ST7,   10, floating, st7)
+REGINFO(FCTRL,  4, fcw,      0)
+REGINFO(FSTAT,  4, fsw,      0)
+REGINFO(FTAG,   4, FTW,      0)
+REGINFO(FISEG,  4, FIP,      1)
+REGINFO(FIOFF,  4, FIP,      0)
+REGINFO(FOSEG,  4, FDP,      1)
+REGINFO(FOOFF,  4, FDP,      0)
+REGINFO(FOP,    4, FOP,      0)
+REGINFO(XMM0,  16, xmm,      0)
+REGINFO(XMM1,  16, xmm,      1)
+REGINFO(XMM2,  16, xmm,      2)
+REGINFO(XMM3,  16, xmm,      3)
+REGINFO(XMM4,  16, xmm,      4)
+REGINFO(XMM5,  16, xmm,      5)
+REGINFO(XMM6,  16, xmm,      6)
+REGINFO(XMM7,  16, xmm,      7)
+REGINFO(XMM8,  16, xmm,      8)
+REGINFO(XMM9,  16, xmm,      9)
+REGINFO(XMM10, 16, xmm,      10)
+REGINFO(XMM11, 16, xmm,      11)
+REGINFO(XMM12, 16, xmm,      12)
+REGINFO(XMM13, 16, xmm,      13)
+REGINFO(XMM14, 16, xmm,      14)
+REGINFO(XMM15, 16, xmm,      15)
+REGINFO(MXCSR,  4, mxcsr,    0)

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 15/39] NLKD - early pseudo-fs
  2005-11-09 14:29                       ` [PATCH 15/39] NLKD - early pseudo-fs Al Viro
@ 2005-11-09 14:37                         ` Jan Beulich
  2005-11-09 15:00                           ` Al Viro
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 14:37 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel

>>> Al Viro <viro@ftp.linux.org.uk> 09.11.05 15:29:26 >>>
>On Wed, Nov 09, 2005 at 03:09:54PM +0100, Jan Beulich wrote:
>> While for limited amounts of configuration information the kernel
>> command line may be suitable, it isn't when it comes to significant
>> amounts of configurable entities that need to be set before the
full
>> kernel infrastructure is available. This patch adds functionality
to
>> pass one or more configuration files through the initrd, but
without
>> requiring knowledge of the actual structure (including compression)
of
>> it; the file(s) is/are attached to the end of the already built
>> initrd (which obviously depends on external scripts not provided
>> here).
>
>What the hell for?  We _already_ have a way to get any set of files
in
>a filesystem as soon as we have VFS caches set up (and until then you
>can't open anything anyway).

That's the whole point - a debugger wants this *before* VFS is set up
(and thus obviously without going through VFS in the first place). One
may argue that the naming is odd, but that's nothing I really care
about.

>NAK.

Then suggest an alternative solution.

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 15/39] NLKD - early pseudo-fs
  2005-11-09 14:37                         ` Jan Beulich
@ 2005-11-09 15:00                           ` Al Viro
  2005-11-09 16:00                             ` Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Al Viro @ 2005-11-09 15:00 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, Nov 09, 2005 at 03:37:02PM +0100, Jan Beulich wrote:
> >What the hell for?  We _already_ have a way to get any set of files
> in
> >a filesystem as soon as we have VFS caches set up (and until then you
> >can't open anything anyway).
> 
> That's the whole point - a debugger wants this *before* VFS is set up
> (and thus obviously without going through VFS in the first place). One
> may argue that the naming is odd, but that's nothing I really care
> about.
> 
> >NAK.
> 
> Then suggest an alternative solution.

"Reduce the parts of your config needed that early on to something
saner in size"

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 15/39] NLKD - early pseudo-fs
  2005-11-09 15:00                           ` Al Viro
@ 2005-11-09 16:00                             ` Jan Beulich
  0 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 16:00 UTC (permalink / raw)
  To: Al Viro; +Cc: linux-kernel

>>> Al Viro <viro@ftp.linux.org.uk> 09.11.05 16:00:57 >>>
>On Wed, Nov 09, 2005 at 03:37:02PM +0100, Jan Beulich wrote:
>> >What the hell for?  We _already_ have a way to get any set of
files
>> in
>> >a filesystem as soon as we have VFS caches set up (and until then
you
>> >can't open anything anyway).
>> 
>> That's the whole point - a debugger wants this *before* VFS is set
up
>> (and thus obviously without going through VFS in the first place).
One
>> may argue that the naming is odd, but that's nothing I really care
>> about.
>> 
>> >NAK.
>> 
>> Then suggest an alternative solution.
>
>"Reduce the parts of your config needed that early on to something
>saner in size"

That is no solution. Take a look at what can be configured in NLKD, and
tell me what you'd call a 'saner in size' subset. I can't think of
anything that can be left out; instead, the amount of configurable
things will only grow over time.

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 17:53   ` Alan Cox
@ 2005-11-09 16:25     ` Jeffrey V. Merkey
  2005-11-10 14:48     ` Mark Lord
  1 sibling, 0 replies; 105+ messages in thread
From: Jeffrey V. Merkey @ 2005-11-09 16:25 UTC (permalink / raw)
  To: Alan Cox; +Cc: Jeff Garzik, Jan Beulich, linux-kernel

Alan Cox wrote:

>On Mer, 2005-11-09 at 11:59 -0500, Jeff Garzik wrote:
>  
>
>>Honestly, just seeing all these code changes makes me think we really 
>>don't need it in the kernel.  How many "early" and "alternative" gadgets 
>>do we really need just for this thing?
>>    
>>
>
>I think it is clearly the case that the design is wrong. The existance
>of kgdb shows how putting the complex logic remotely on another system
>is not only a lot cleaner and simpler but can also provide more
>functionality and higher reliability.
>
>The presence of user mode linux and Xen also provide solutions to the
>usual concern about needing two systems, as will future hardware
>features.
>  
>

Not necessarily true with regard to having the functionality in the 
kernel, but for Linux, probably better for maintenance based on the social
issues.  I have MDB fully integrated in the kernel and I don't have all 
these problems.  It's just an update to the kdb hooks, patch, build and go.
Novell should probably just fork the kernel and start their own distro 
and dump the mainstream Linux.  They have the people and infrastructure
to support drivers and do just as good a job as LKML with the old 
NetWare group.  Novell was presented with MDB two years ago and opted
to build their own rather than go with ours.  I have been disappointed 
with the quality of what they have produced to date.

They should fork form Linux and understand that the Linux folks and 
their culture is totaly alien to Novell's culture.   They will never make
progress with the Linux folks and continued interactions will waste both 
groups time.  They have the talent and resources to preempt Linux
and do their own thing.  They need to just go and do it.

J


>Alan
>
>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at  http://www.tux.org/lkml/
>
>  
>


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-09 13:58     ` [PATCH 3/39] NLKD - early/late CPU up/down notification Jan Beulich
                         ` (2 preceding siblings ...)
  2005-11-09 14:01       ` [PATCH 6/39] NLKD - early panic notification Jan Beulich
@ 2005-11-09 16:45       ` Greg KH
  2005-11-09 17:09         ` Jan Beulich
  3 siblings, 1 reply; 105+ messages in thread
From: Greg KH @ 2005-11-09 16:45 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, Nov 09, 2005 at 02:58:55PM +0100, Jan Beulich wrote:
> A mechanism to allow debuggers to learn about starting/dying CPUs as
> early/late as possible. Arch-dependent changes for i386 and x86_64
> will follow.
> 
> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
> 
> (actual patch attached)

Ick, but it's in base64 mode, so I can't quote it to say that your
#ifdef in the .h file is not needed.  Please fix your email client to
send patches properly.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 6/39] NLKD - early panic notification
  2005-11-09 14:01       ` [PATCH 6/39] NLKD - early panic notification Jan Beulich
  2005-11-09 14:02         ` [PATCH 7/39] NLKD - task create/destroy notification Jan Beulich
@ 2005-11-09 16:50         ` Greg KH
  1 sibling, 0 replies; 105+ messages in thread
From: Greg KH @ 2005-11-09 16:50 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, Nov 09, 2005 at 03:01:50PM +0100, Jan Beulich wrote:
> A mechanism to allow debuggers to intercept panic events early.
> 
> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
> 
> (actual patch attached)

EXPORT_SYMBOL_GPL() for any new exports you are adding please.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 1/39] NLKD - an alternative kallsyms approach
  2005-11-09 13:56 ` [PATCH 1/39] NLKD - an alternative kallsyms approach Jan Beulich
  2005-11-09 13:57   ` [PATCH 2/39] NLKD - an alternative early ioremap approach Jan Beulich
@ 2005-11-09 16:50   ` Randy.Dunlap
  2005-11-09 16:57     ` Greg KH
  2005-11-09 17:20     ` Jan Beulich
  1 sibling, 2 replies; 105+ messages in thread
From: Randy.Dunlap @ 2005-11-09 16:50 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, 9 Nov 2005, Jan Beulich wrote:

> This patch provides an alternative to the pre-exisiting kallsyms code.
> That code, from a kernel debugger perspective at least, suffers from
> incomplete information, making it impossible to
> (a) disambiguate multiple static functions of the same name (in
> different source files),
> (b) determine a complete set of attributes for a symbol (namely, the
> symbol's size, but also its type, which gets converted to an nm-like
> one-character representation), and
> (c) retain full section information
>
> This new approach basically makes handling core kernel and module
> symbols the same, by retrieving the kernel's section, symbol, and
> string tables rather than parsing the system map.
>
> At once it adds the functionality to strip unneeded symbols from
> modules, which results in non-neglectable space savings for typical
> distributions (which large amounts of modules). Note that with certain
> recent, but broken binutils versions (2.16.90*, 2.16.91* up to
> and including 2.16.91.0.3) this can only be built without
> CONFIG_MODVERSIONS.
>
> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
>
> (actual patch attached)

It's still not a text-type attachment...

BTW, are you posting these just for comments or did you want
someone to apply/merge them?  If so, who?  You should send them
to that someone (unless you have some other arrangements) --
at least that's the normal procedure.

-- 
~Randy

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 1/39] NLKD - an alternative kallsyms approach
  2005-11-09 16:50   ` [PATCH 1/39] NLKD - an alternative kallsyms approach Randy.Dunlap
@ 2005-11-09 16:57     ` Greg KH
  2005-11-09 17:20     ` Jan Beulich
  1 sibling, 0 replies; 105+ messages in thread
From: Greg KH @ 2005-11-09 16:57 UTC (permalink / raw)
  To: Randy.Dunlap; +Cc: Jan Beulich, linux-kernel

On Wed, Nov 09, 2005 at 08:50:15AM -0800, Randy.Dunlap wrote:
> BTW, are you posting these just for comments or did you want
> someone to apply/merge them?  If so, who?  You should send them
> to that someone (unless you have some other arrangements) --
> at least that's the normal procedure.

And the documented one too, see Documentation/SubmittingPatches, section
5.

Why does no one ever read the documentation...

greg k-h

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 13:54 [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jan Beulich
  2005-11-09 13:56 ` [PATCH 1/39] NLKD - an alternative kallsyms approach Jan Beulich
@ 2005-11-09 16:59 ` Jeff Garzik
  2005-11-09 17:06   ` Randy.Dunlap
  2005-11-09 17:53   ` Alan Cox
       [not found] ` <437214E4.76F0.0078.0@novell.com>
  2 siblings, 2 replies; 105+ messages in thread
From: Jeff Garzik @ 2005-11-09 16:59 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

Jan Beulich wrote:
> The following patch set represents the Novell Linux Kernel Debugger,
> stripped off of its original low-level exception handling framework.


Honestly, just seeing all these code changes makes me think we really 
don't need it in the kernel.  How many "early" and "alternative" gadgets 
do we really need just for this thing?

	Jeff



^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 16:59 ` [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jeff Garzik
@ 2005-11-09 17:06   ` Randy.Dunlap
  2005-11-09 17:14     ` Jan Beulich
  2005-11-13  1:09     ` Andi Kleen
  2005-11-09 17:53   ` Alan Cox
  1 sibling, 2 replies; 105+ messages in thread
From: Randy.Dunlap @ 2005-11-09 17:06 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Jan Beulich, linux-kernel

On Wed, 9 Nov 2005, Jeff Garzik wrote:

> Jan Beulich wrote:
> > The following patch set represents the Novell Linux Kernel Debugger,
> > stripped off of its original low-level exception handling framework.
>
>
> Honestly, just seeing all these code changes makes me think we really
> don't need it in the kernel.  How many "early" and "alternative" gadgets
> do we really need just for this thing?

On the surface I have to agree.  However, if Jan wants feedback
on the patches, that's a reasonable request IMO.
(but they need to be readable via email so that someone
can comment on them)

At a quick blush, I would guess it has as much chance as
kdb does (or did) for merging.

-- 
~Randy

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-09 16:45       ` [PATCH 3/39] NLKD - early/late CPU up/down notification Greg KH
@ 2005-11-09 17:09         ` Jan Beulich
  2005-11-09 17:19           ` Greg KH
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 17:09 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

>>> Greg KH <greg@kroah.com> 09.11.05 17:45:44 >>>
>On Wed, Nov 09, 2005 at 02:58:55PM +0100, Jan Beulich wrote:
>> A mechanism to allow debuggers to learn about starting/dying CPUs
as
>> early/late as possible. Arch-dependent changes for i386 and x86_64
>> will follow.
>> 
>> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
>> 
>> (actual patch attached)
>
>Ick, but it's in base64 mode, so I can't quote it to say that your

That I already was made aware of. Sorry, this worked a few months ago,
but they managed to break this again.

>#ifdef in the .h file is not needed.  Please fix your email client to
>send patches properly.

It's not needed, sure, but by having it there I just wanted to make
clear that this is something that never can be called from a module
(after all, why should one find out at modpost time (and maybe even miss
the message since there are so many past eventual symbol resolution
warnings) when one can already at compile time.

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 17:06   ` Randy.Dunlap
@ 2005-11-09 17:14     ` Jan Beulich
  2005-11-09 17:56       ` Alan Cox
                         ` (3 more replies)
  2005-11-13  1:09     ` Andi Kleen
  1 sibling, 4 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 17:14 UTC (permalink / raw)
  To: Jeff Garzik, Randy.Dunlap; +Cc: linux-kernel

>On the surface I have to agree.  However, if Jan wants feedback
>on the patches, that's a reasonable request IMO.

Getting feedback is not the only goal.

>(but they need to be readable via email so that someone
>can comment on them)

Sorry, I hear this quite often, but I also have to play by some company
rules, one of which is to use a certain mail system (or otherwise be
left alone in case of problems).

>At a quick blush, I would guess it has as much chance as
>kdb does (or did) for merging.

The intention isn't necessarily to merge the whole debugger, but what
we desire is to merge everything to allow the debugger to be built
outside of the tree (perhaps as a standalong module).

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-09 17:09         ` Jan Beulich
@ 2005-11-09 17:19           ` Greg KH
  2005-11-10  7:41             ` Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Greg KH @ 2005-11-09 17:19 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, Nov 09, 2005 at 06:09:27PM +0100, Jan Beulich wrote:
> >>> Greg KH <greg@kroah.com> 09.11.05 17:45:44 >>>
> >#ifdef in the .h file is not needed.  Please fix your email client to
> >send patches properly.
> 
> It's not needed, sure, but by having it there I just wanted to make
> clear that this is something that never can be called from a module
> (after all, why should one find out at modpost time (and maybe even miss
> the message since there are so many past eventual symbol resolution
> warnings) when one can already at compile time.

If it isn't present, and you do a build, you will still get the error at
build time, just during a different part of it.  Adding #ifdef just to
move the error to a different part of the build isn't needed.  Remember,
we want to not use #ifdef at all if we can ever help it.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 1/39] NLKD - an alternative kallsyms approach
  2005-11-09 16:50   ` [PATCH 1/39] NLKD - an alternative kallsyms approach Randy.Dunlap
  2005-11-09 16:57     ` Greg KH
@ 2005-11-09 17:20     ` Jan Beulich
  1 sibling, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-09 17:20 UTC (permalink / raw)
  To: Randy.Dunlap; +Cc: linux-kernel

>BTW, are you posting these just for comments or did you want
>someone to apply/merge them?  If so, who?  You should send them
>to that someone (unless you have some other arrangements) --
>at least that's the normal procedure.

I don't expect the debugger itself to be merged, but I hope the
preparatory pieces could be. And then, if not Andrew (who, as far as I
can see, picks up things from the list just as much as stuff directly
addressed to him), who would I send this to? There's doesn't seem to be
a clear maintainer of i386, for example, and that seems to be the case
for many other parts, too.

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 16:59 ` [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jeff Garzik
  2005-11-09 17:06   ` Randy.Dunlap
@ 2005-11-09 17:53   ` Alan Cox
  2005-11-09 16:25     ` Jeffrey V. Merkey
  2005-11-10 14:48     ` Mark Lord
  1 sibling, 2 replies; 105+ messages in thread
From: Alan Cox @ 2005-11-09 17:53 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: Jan Beulich, linux-kernel

On Mer, 2005-11-09 at 11:59 -0500, Jeff Garzik wrote:
> Honestly, just seeing all these code changes makes me think we really 
> don't need it in the kernel.  How many "early" and "alternative" gadgets 
> do we really need just for this thing?

I think it is clearly the case that the design is wrong. The existance
of kgdb shows how putting the complex logic remotely on another system
is not only a lot cleaner and simpler but can also provide more
functionality and higher reliability.

The presence of user mode linux and Xen also provide solutions to the
usual concern about needing two systems, as will future hardware
features.

Alan


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 17:14     ` Jan Beulich
@ 2005-11-09 17:56       ` Alan Cox
  2005-11-09 18:05       ` Greg KH
                         ` (2 subsequent siblings)
  3 siblings, 0 replies; 105+ messages in thread
From: Alan Cox @ 2005-11-09 17:56 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Jeff Garzik, Randy.Dunlap, linux-kernel

On Mer, 2005-11-09 at 18:14 +0100, Jan Beulich wrote:
> Sorry, I hear this quite often, but I also have to play by some company
> rules, one of which is to use a certain mail system (or otherwise be
> left alone in case of problems).

Which is more important. Your employers email system or the ability of
people to quote and work easily with patches ? Please send patches in a
sensible format, even if you use a different mail tool for all your
other email. 

Other Novell contributors many of them large and important contributors
from SuSE don't appear to be having this problem

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 17:14     ` Jan Beulich
  2005-11-09 17:56       ` Alan Cox
@ 2005-11-09 18:05       ` Greg KH
  2005-11-09 18:54       ` Paul Jackson
  2005-11-10 12:41       ` Christoph Hellwig
  3 siblings, 0 replies; 105+ messages in thread
From: Greg KH @ 2005-11-09 18:05 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, Nov 09, 2005 at 06:14:05PM +0100, Jan Beulich wrote:
> >On the surface I have to agree.  However, if Jan wants feedback
> >on the patches, that's a reasonable request IMO.
> 
> Getting feedback is not the only goal.

What is the goal?  You never stated it.

> >(but they need to be readable via email so that someone
> >can comment on them)
> 
> Sorry, I hear this quite often, but I also have to play by some company
> rules, one of which is to use a certain mail system (or otherwise be
> left alone in case of problems).

Please remember, lkml does _not_ care about any company rules.
You need to follow the community's rules, not try to get the community
to follow yours, if you wish to get them to do anything.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 11/39] NLKD - time adjustment
  2005-11-09 14:06                 ` [PATCH 11/39] NLKD - time adjustment Jan Beulich
                                     ` (2 preceding siblings ...)
  2005-11-09 14:09                   ` [PATCH 14/39] NLKD - kernel trace buffer access Jan Beulich
@ 2005-11-09 18:51                   ` George Anzinger
  3 siblings, 0 replies; 105+ messages in thread
From: George Anzinger @ 2005-11-09 18:51 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

Jan Beulich wrote:
> Generic part of an interface to allow debuggers to update time after
> having halted the system for perhaps extended periods of time. This
> generally requires arch-dependent changes, too, unless the arch-
> dependent time handling is already overflow-safe.
> 
> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
> 
> (actual patch attached)

Perhaps you could teach your mailer how to attach the atachments so that they appear inline to the 
reader.  The problem appears to be that it does not recognize the file type.  This is what it says:

Content-Type: application/octet-stream; name="linux-2.6.14-nlkd-time.patch"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="linux-2.6.14-nlkd-time.patch"

where as a correct attachment might look something like:

Content-Type: text/x-diff;
   charset="us-ascii";
   name="patch_x86_64-kernel-i8259"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
	filename="patch_x86_64-kernel-i8259"

This would allow us to comment on the patch with said comments appearing in the body of the patch.

> 

-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 17:14     ` Jan Beulich
  2005-11-09 17:56       ` Alan Cox
  2005-11-09 18:05       ` Greg KH
@ 2005-11-09 18:54       ` Paul Jackson
  2005-11-10 12:41       ` Christoph Hellwig
  3 siblings, 0 replies; 105+ messages in thread
From: Paul Jackson @ 2005-11-09 18:54 UTC (permalink / raw)
  To: Jan Beulich; +Cc: jgarzik, rdunlap, linux-kernel

Jan wrote:
> Sorry, I hear this quite often, but I also have to play by some company
> rules, one of which is to use a certain mail system (or otherwise be
> left alone in case of problems).

May I recommend a separate tool for sending patches, instead
of using your email client.  Consider for example:

  http://www.speakeasy.org/~pj99/sgi/sendpatchset

-- 
                  I won't rest till it's the best ...
                  Programmer, Linux Scalability
                  Paul Jackson <pj@sgi.com> 1.925.600.0401

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 17/39] NLKD/i386 - core adjustments
  2005-11-09 14:11                         ` [PATCH 17/39] NLKD/i386 " Jan Beulich
@ 2005-11-09 19:00                           ` Adrian Bunk
  2005-11-10  8:04                             ` Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Adrian Bunk @ 2005-11-09 19:00 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, Nov 09, 2005 at 03:11:51PM +0100, Jan Beulich wrote:
> The core i386 NLKD adjustments to pre-existing code.
> 
> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
> 
> (actual patch attached)

If your code doesn't work with 4k stacks you have a problem because
8k stacks will soon be removed (my goal is 2.6.16, perhaps one or two 
releases later).

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 12/39] NLKD/i386 - time adjustment
  2005-11-09 14:06                   ` [PATCH 12/39] NLKD/i386 " Jan Beulich
@ 2005-11-09 19:10                     ` George Anzinger
  2005-11-10  8:12                       ` Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: George Anzinger @ 2005-11-09 19:10 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

Jan Beulich wrote:
> Since i386 time handling is not overflow-safe, these are the
> adjustments needed for allowing debuggers to update time after
> having halted the system for perhaps extended periods of time.
> 
> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
> 
> (actual patch attached)

The patch includes code that seems to imply that gcc can not do mpy of (long long) variables.  It 
does just fine with these.  It also adds (long long) types just fine.  The only problem it has is 
with div, for which we have do_div().

I really do not see the relavence of the run time library patches given the above.  The adjust code 
does not seem to use them.  Also, gcc (with the lib code) does all of this stuff.  The only need for 
it would, possibly, be to debug the library code and even then, I suspect you really want to do that 
in user land and then bring the result into the kernel.

Am I missing something?
> 

-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 14/39] NLKD - kernel trace buffer access
  2005-11-09 14:09                   ` [PATCH 14/39] NLKD - kernel trace buffer access Jan Beulich
  2005-11-09 14:09                     ` [PATCH 15/39] NLKD - early pseudo-fs Jan Beulich
@ 2005-11-10  5:44                     ` Keith Owens
  2005-11-10  8:02                       ` Jan Beulich
  1 sibling, 1 reply; 105+ messages in thread
From: Keith Owens @ 2005-11-10  5:44 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Wed, 09 Nov 2005 15:09:13 +0100, 
"Jan Beulich" <JBeulich@novell.com> wrote:
>Debug extension implementation for NLKD to access the kernel trace
>buffer.

 printk.c |  187 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 187 insertions(+)

This is complete overkill in printk.c.  The only change required to
printk is to add a routine which gets the parameters that define the
buffer, see below from KDB.  The rest of the code in your patch belongs
in the debugger, not in printk.

#ifdef	CONFIG_KDB
/* kdb dmesg command needs access to the syslog buffer.  do_syslog() uses locks
 * so it cannot be used during debugging.  Just tell kdb where the start and
 * end of the physical and logical logs are.  This is equivalent to do_syslog(3).
 */
void kdb_syslog_data(char *syslog_data[4])
{
	syslog_data[0] = log_buf;
	syslog_data[1] = log_buf + log_buf_len;
	syslog_data[2] = log_buf + log_end - (logged_chars < log_buf_len ? logged_chars : log_buf_len);
	syslog_data[3] = log_buf + log_end;
}
#endif	/* CONFIG_KDB */


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-09 17:19           ` Greg KH
@ 2005-11-10  7:41             ` Jan Beulich
  2005-11-10 20:59               ` Sam Ravnborg
  2005-11-10 23:01               ` Greg KH
  0 siblings, 2 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-10  7:41 UTC (permalink / raw)
  To: Greg KH; +Cc: linux-kernel

>>> Greg KH <greg@kroah.com> 09.11.05 18:19:19 >>>
>On Wed, Nov 09, 2005 at 06:09:27PM +0100, Jan Beulich wrote:
>> >>> Greg KH <greg@kroah.com> 09.11.05 17:45:44 >>>
>> >#ifdef in the .h file is not needed.  Please fix your email client
to
>> >send patches properly.
>> 
>> It's not needed, sure, but by having it there I just wanted to make
>> clear that this is something that never can be called from a module
>> (after all, why should one find out at modpost time (and maybe even
miss
>> the message since there are so many past eventual symbol resolution
>> warnings) when one can already at compile time.
>
>If it isn't present, and you do a build, you will still get the error
at
>build time, just during a different part of it.  Adding #ifdef just
to
>move the error to a different part of the build isn't needed. 
Remember,
>we want to not use #ifdef at all if we can ever help it.

I understand that. But you don't see my point, so I'll try to explain
the background: When discovering the reason for the kallsyms change
(also posted with the other NLKD patches) not functioning with
CONFIG_MODVERSIONS and binutils between 2.16.90 and 2.16.91.0.3 I
realized that the warning messages from the modpost build stage are very
easy to overlook (in fact, all reporters of the problem overlooked them
as well as I did on the first build attempting to reproduce the
problem). This basically means these messages are almost useless, and
detection of the problem will likely be deferred to the first attempt to
load an offending module (which, as in the case named, may lead to an
unusable kernel). Hence, at least until this build problem gets
addressed I continue to believe that adding the preprocessor conditional
is the better way of dealing with potential issues. Sure I know that
hundreds of other symbols possibly causing the same problem aren't
protected...

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 14/39] NLKD - kernel trace buffer access
  2005-11-10  5:44                     ` [PATCH 14/39] NLKD - kernel trace buffer access Keith Owens
@ 2005-11-10  8:02                       ` Jan Beulich
  0 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-10  8:02 UTC (permalink / raw)
  To: Keith Owens; +Cc: linux-kernel

>>> Keith Owens <kaos@sgi.com> 10.11.05 06:44:52 >>>
>On Wed, 09 Nov 2005 15:09:13 +0100, 
>"Jan Beulich" <JBeulich@novell.com> wrote:
>>Debug extension implementation for NLKD to access the kernel trace
>>buffer.
>
> printk.c |  187
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 187 insertions(+)
>
>This is complete overkill in printk.c.  The only change required to
>printk is to add a routine which gets the parameters that define the
>buffer, see below from KDB.  The rest of the code in your patch
belongs
>in the debugger, not in printk.

This depends on the perspective...

>#ifdef	CONFIG_KDB
>/* kdb dmesg command needs access to the syslog buffer.  do_syslog()
uses locks
> * so it cannot be used during debugging.  Just tell kdb where the
start and
> * end of the physical and logical logs are.  This is equivalent to
do_syslog(3).
> */
>void kdb_syslog_data(char *syslog_data[4])
>{
>	syslog_data[0] = log_buf;
>	syslog_data[1] = log_buf + log_buf_len;
>	syslog_data[2] = log_buf + log_end - (logged_chars < log_buf_len
? logged_chars : log_buf_len);
>	syslog_data[3] = log_buf + log_end;
>}
>#endif	/* CONFIG_KDB */

The publishing of this function allows uncontrolled access to the
otherwise (and sure purposefully) static symbols; you could as well
globalize the symbols directly. In order for KDB to be a module, this
symbol would even need to be exported. By keeping the debugger access
code in the same file, nothing gets changed visibility-wise for the
outside world.

Further, the design of the debugger extensions of NLKD calls for the
extension code to live in the place their data gets controlled at.
Consider an extension living in a module - how could the debugger access
that information?

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 17/39] NLKD/i386 - core adjustments
  2005-11-09 19:00                           ` Adrian Bunk
@ 2005-11-10  8:04                             ` Jan Beulich
  2005-11-10 10:29                               ` Adrian Bunk
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-10  8:04 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: linux-kernel

>>> Adrian Bunk <bunk@stusta.de> 09.11.05 20:00:17 >>>
>On Wed, Nov 09, 2005 at 03:11:51PM +0100, Jan Beulich wrote:
>> The core i386 NLKD adjustments to pre-existing code.
>> 
>> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
>> 
>> (actual patch attached)
>
>If your code doesn't work with 4k stacks you have a problem because
>8k stacks will soon be removed (my goal is 2.6.16, perhaps one or two

>releases later).

It's not that it doesn't work with them, but chances of stack overflow
are too high for my taste.

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 12/39] NLKD/i386 - time adjustment
  2005-11-09 19:10                     ` George Anzinger
@ 2005-11-10  8:12                       ` Jan Beulich
  2005-11-11  0:17                         ` George Anzinger
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-10  8:12 UTC (permalink / raw)
  To: George Anzinger; +Cc: linux-kernel

>>> George Anzinger <george@mvista.com> 09.11.05 20:10:09 >>>
>Jan Beulich wrote:
>> Since i386 time handling is not overflow-safe, these are the
>> adjustments needed for allowing debuggers to update time after
>> having halted the system for perhaps extended periods of time.
>> 
>> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
>> 
>> (actual patch attached)
>
>The patch includes code that seems to imply that gcc can not do mpy of
(long long) variables.  It 
>does just fine with these.  It also adds (long long) types just fine. 
The only problem it has is 
>with div, for which we have do_div().

gcc can do long long multiplies fine, but only with a long long result.
The code presented, however, needs (at least) 96 bits of the result,
which expressing in C would be far more complicated than doing it with a
couple of assembly statements.

>I really do not see the relavence of the run time library patches
given the above.  The adjust code 
>does not seem to use them.  Also, gcc (with the lib code) does all of
this stuff.  The only need for 
>it would, possibly, be to debug the library code and even then, I
suspect you really want to do that 
>in user land and then bring the result into the kernel.

Which run time library patches are you referring to? NLKD's? If so,
these routines must not be used by code outside of the debugger (and the
opposite is true, too: debugger code must not use common code routines
where ever possible).

Further, it is my understanding that it is for a (unknown to me) reason
that the linux kernel doesn't have the full set of libgcc support
routines. Since the debugger in various places relies on being able to
do 64-bit math on 32-bit systems, I had to add these in a way so that
they'd be hidden from the rest of the kernel (and also so that they'd
satisfy the isolation rules outlined above).

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 17/39] NLKD/i386 - core adjustments
  2005-11-10  8:04                             ` Jan Beulich
@ 2005-11-10 10:29                               ` Adrian Bunk
  2005-11-10 11:52                                 ` Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Adrian Bunk @ 2005-11-10 10:29 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Thu, Nov 10, 2005 at 09:04:58AM +0100, Jan Beulich wrote:
> >>> Adrian Bunk <bunk@stusta.de> 09.11.05 20:00:17 >>>
> >On Wed, Nov 09, 2005 at 03:11:51PM +0100, Jan Beulich wrote:
> >> The core i386 NLKD adjustments to pre-existing code.
> >> 
> >> Signed-Off-By: Jan Beulich <jbeulich@novell.com>
> >> 
> >> (actual patch attached)
> >
> >If your code doesn't work with 4k stacks you have a problem because
> >8k stacks will soon be removed (my goal is 2.6.16, perhaps one or two
> 
> >releases later).
> 
> It's not that it doesn't work with them, but chances of stack overflow
> are too high for my taste.

If there's a chance of a stack overflow the stack usage has to be 
reduced until the chance goes down to 0.

> Jan

cu
Adrian

-- 

       "Is there not promise of rain?" Ling Tan asked suddenly out
        of the darkness. There had been need of rain for many days.
       "Only a promise," Lao Er said.
                                       Pearl S. Buck - Dragon Seed


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 17/39] NLKD/i386 - core adjustments
  2005-11-10 10:29                               ` Adrian Bunk
@ 2005-11-10 11:52                                 ` Jan Beulich
  2005-11-10 12:36                                   ` Lars Marowsky-Bree
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-10 11:52 UTC (permalink / raw)
  To: Adrian Bunk; +Cc: linux-kernel

>If there's a chance of a stack overflow the stack usage has to be 
>reduced until the chance goes down to 0.

How does one reduce stack usage in the presence of recursion driven by
user input (referring to expression evaluation)?

Also, NLKD has an extension to the (simplistic) pt_regs frame
(including e.g. floating point state) and may be used to debug itself
(i.e. there may be more than one frame on the stack at a time).

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 17/39] NLKD/i386 - core adjustments
  2005-11-10 11:52                                 ` Jan Beulich
@ 2005-11-10 12:36                                   ` Lars Marowsky-Bree
  0 siblings, 0 replies; 105+ messages in thread
From: Lars Marowsky-Bree @ 2005-11-10 12:36 UTC (permalink / raw)
  To: Jan Beulich, Adrian Bunk; +Cc: linux-kernel

On 2005-11-10T12:52:07, Jan Beulich <JBeulich@novell.com> wrote:

> >If there's a chance of a stack overflow the stack usage has to be 
> >reduced until the chance goes down to 0.
> How does one reduce stack usage in the presence of recursion driven by
> user input (referring to expression evaluation)?

Recursion removal is a pretty standard technique and featured in almost
all introductionary computer science texts. A quick google query finds
http://portal.acm.org/citation.cfm?id=359344

All recursive algorithms can be expressed non-recursively, although it
might not always be as nice. Or you can put an upper limit on the
allowed complexity of queries.


Sincerely,
    Lars Marowsky-Brée <lmb@suse.de>

-- 
High Availability & Clustering
SUSE Labs, Research and Development
SUSE LINUX Products GmbH - A Novell Business	 -- Charles Darwin
"Ignorance more frequently begets confidence than does knowledge"


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 17:14     ` Jan Beulich
                         ` (2 preceding siblings ...)
  2005-11-09 18:54       ` Paul Jackson
@ 2005-11-10 12:41       ` Christoph Hellwig
  3 siblings, 0 replies; 105+ messages in thread
From: Christoph Hellwig @ 2005-11-10 12:41 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Jeff Garzik, Randy.Dunlap, linux-kernel

On Wed, Nov 09, 2005 at 06:14:05PM +0100, Jan Beulich wrote:
> >At a quick blush, I would guess it has as much chance as
> >kdb does (or did) for merging.
> 
> The intention isn't necessarily to merge the whole debugger, but what
> we desire is to merge everything to allow the debugger to be built
> outside of the tree (perhaps as a standalong module).

While you're posted a few actually useful patches that fix or encehance
core code we're not going to put in any of your odd hooks or exports.
As you might have noticed while reading lkml we are everything but keen
on those.


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 5/39] NLKD/x86-64 - early/late CPU up/down notification
  2005-11-09 14:01       ` [PATCH 5/39] NLKD/x86-64 " Jan Beulich
@ 2005-11-10 13:10         ` Andi Kleen
  2005-11-14  8:04           ` [discuss] " Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 13:10 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Wednesday 09 November 2005 15:01, Jan Beulich wrote:
> x86_64-specific part of the new mechanism to allow debuggers to learn
> about starting/dying CPUs as early/late as possible.

Please just use the normal notifier chains instead (CPU_UP, CPU_DOWN, 
register_cpu_notifier). I don't see much sense to have two different 
mechanisms to do the same thing. While they might be not as early/late
as your mechanism I think the users of your debugger can tolerate that.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-09 14:08                   ` [PATCH 13/39] NLKD/x86-64 " Jan Beulich
  2005-11-09 14:13                     ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Jan Beulich
@ 2005-11-10 13:19                     ` Andi Kleen
  2005-11-10 14:23                       ` Jan Beulich
  2005-11-10 14:43                       ` Vojtech Pavlik
  1 sibling, 2 replies; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 13:19 UTC (permalink / raw)
  To: Jan Beulich, vojtech; +Cc: linux-kernel, discuss

On Wednesday 09 November 2005 15:08, Jan Beulich wrote:
> Since x86-64 time handling is not overflow-safe, these are the
> adjustments needed for allowing debuggers to update time after
> having halted the system for perhaps extended periods of time.
>
> Note that this depends on the HPET definitions adjustments, which
> aren't in 2.6.14, but have supposedly been merged already into 2.6.15.
>
> From: Jan Beulich <jbeulich@novell.com>

<no code quoting because that is hard with your attachments>

In general thanks for the overflow fixes. I understand the code
had generic problems in this area and it's good someone tackling them.

But many details should be changed.

The magic ICH6 HPET enable code has to go. It looks far too fragile and might 
break something else. I also don't want direct PCI config space accesses like 
this. We'll have to wait for ACPI HPET support I think. I think I'll remove 
the original hack for AMD 8111 too - it was only for testing anyways. If you 
still want to use it you have to keep it as a private patch.

Please remove the ifdefs too.  64bit HPET support would be fine, but 
only as a runtime mechanism, not compile time.

Can you remove debugger_jiffies please? 
The code has to handle long delays anyways (e.g. if someone uses a target
probe), so we cannot rely on such hacks anyways.

I don't quite understand why the SMP case should be different from UP
in that ifdef. Can you explain?  It shouldn't in theory.


/* When the TSC gets reset during AP startup, the code below would
+			   incorrectly think we lost a huge amount of ticks. */
That is outdated - the TSCs are not reset anymore since 2.6.12.
Please remove code for handling that.

The union in vxtime_data is ugly - can it be avoided?

Vojtech should probably review that one too when you repost.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes
  2005-11-09 14:13                     ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Jan Beulich
  2005-11-09 14:14                       ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Jan Beulich
@ 2005-11-10 13:21                       ` Andi Kleen
  2005-11-10 14:07                         ` Jan Beulich
  1 sibling, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 13:21 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Wednesday 09 November 2005 15:13, Jan Beulich wrote:
> This
> - switches the INT3 handler to run on an IST stack (to cope with
>   breakpoints set by a kernel debugger on places where the kernel's
>   %gs base hasn't been set up, yet); the IST stack used is shared with
>   the INT1 handler's
> - allows nesting of INT1/INT3 handlers so that one can, with a kernel
>   debugger, debug (at least) the user-mode portions of the INT1/INT3
>   handling; the nesting isn't actively enabled here since a kernel-
>   debugger-free kernel doesn't need it

Looks reasonable except for the CONFIG_NLKD hunk, which doesn't
seem to be related. I think I'll apply it without that.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers
  2005-11-09 14:14                       ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Jan Beulich
  2005-11-09 14:15                         ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Jan Beulich
@ 2005-11-10 13:23                         ` Andi Kleen
  2005-11-10 14:25                           ` Jan Beulich
  1 sibling, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 13:23 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Wednesday 09 November 2005 15:14, Jan Beulich wrote:
> This adds static information about the code regions where the stack
> pointer cannot be relied upon. Kernel debuggers may then use this
> information to determine which stack to switch to when having a need
> to switch off of namely the NMI stack.

Hmm - can't this be expressed in CFI somehow? 

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment
  2005-11-09 14:15                         ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Jan Beulich
  2005-11-09 14:16                           ` [PATCH 21/39] NLKD/x86-64 - core adjustments Jan Beulich
@ 2005-11-10 13:24                           ` Andi Kleen
  2005-11-10 14:07                             ` Jan Beulich
  1 sibling, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 13:24 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Wednesday 09 November 2005 15:15, Jan Beulich wrote:
> Touching of the floating point state in a kernel debugger must be
> NMI-safe, specifically math_state_restore() must be able to deal with
> being called out of an NMI context. In order to do that reliably, the
> context switch code must take care to not leave a window open where
> the current task's TS_USEDFPU flag and CR0.TS could get out of sync.

Didn't we agree earlier on moving unlazy_fpu() down instead? 

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 25/39] NLKD/x86-64 - core
  2005-11-09 14:21                             ` [PATCH 25/39] NLKD/x86-64 " Jan Beulich
@ 2005-11-10 13:30                               ` Andi Kleen
  0 siblings, 0 replies; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 13:30 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Wednesday 09 November 2005 15:21, Jan Beulich wrote:
> The core x86-64 NLKD additions.

I probably won't merge that unless the full NLKD somehow manages to get 
into mainline. Shouldn't be that hard to maintain out of tree or even
build the debugger in a fully separate directory.

My general suggestion would be to move away from using your own
defines for all the architecture state (MSRs etc) but instead use
the ones from the Linux headers instead which should be largely
equivalent (if there are some missing we can probably add them) 
And getting of that Intel style assembly would be good too.

I would move the asm-offset bits into a separate file, perhaps run from
the NLKD Makefile, that should reduce later merging pain.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 28/39] NLKD/x86-64 - run time library
  2005-11-09 14:23                               ` [PATCH 28/39] NLKD/x86-64 " Jan Beulich
@ 2005-11-10 13:32                                 ` Andi Kleen
  0 siblings, 0 replies; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 13:32 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Wednesday 09 November 2005 15:23, Jan Beulich wrote:
> x86_64-specific implementation of the support routines of NLKD.

Same comment as for patch 25.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 32/39] NLKD/x86-64 - Core Debug Engine
       [not found]   ` <4372153C.76F0.0078.0@novell.com>
@ 2005-11-10 13:33     ` Andi Kleen
  0 siblings, 0 replies; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 13:33 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Wednesday 09 November 2005 15:26, Jan Beulich wrote:
> The x86_64-dependent part of the Core Debug Engine of NLKD.

Same comment as #25.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes
  2005-11-10 13:21                       ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Andi Kleen
@ 2005-11-10 14:07                         ` Jan Beulich
  2005-11-10 14:25                           ` Andi Kleen
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-10 14:07 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, discuss

>>> Andi Kleen <ak@suse.de> 10.11.05 14:21:48 >>>
>On Wednesday 09 November 2005 15:13, Jan Beulich wrote:
>> This
>> - switches the INT3 handler to run on an IST stack (to cope with
>>   breakpoints set by a kernel debugger on places where the kernel's
>>   %gs base hasn't been set up, yet); the IST stack used is shared with
>>   the INT1 handler's
>> - allows nesting of INT1/INT3 handlers so that one can, with a kernel
>>   debugger, debug (at least) the user-mode portions of the INT1/INT3
>>   handling; the nesting isn't actively enabled here since a kernel-
>>   debugger-free kernel doesn't need it
>
>Looks reasonable except for the CONFIG_NLKD hunk, which doesn't
>seem to be related. I think I'll apply it without that.

As the comment in that hunk says - this is not the correct test, but the correct test cannot be used. Omitting the hunk altogether will leave orphan references to the pda field (even though these won't cause build problems) in setup64.c and traps.c.

Jan


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment
  2005-11-10 13:24                           ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Andi Kleen
@ 2005-11-10 14:07                             ` Jan Beulich
  0 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-10 14:07 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, discuss

>>> Andi Kleen <ak@suse.de> 10.11.05 14:24:53 >>>
>On Wednesday 09 November 2005 15:15, Jan Beulich wrote:
>> Touching of the floating point state in a kernel debugger must be
>> NMI-safe, specifically math_state_restore() must be able to deal with
>> being called out of an NMI context. In order to do that reliably, the
>> context switch code must take care to not leave a window open where
>> the current task's TS_USEDFPU flag and CR0.TS could get out of sync.
>
>Didn't we agree earlier on moving unlazy_fpu() down instead? 

I wasn't sure about that, and hence I submitted it the way I had coded it.

Jan


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-10 13:19                     ` [PATCH 13/39] NLKD/x86-64 - time adjustment Andi Kleen
@ 2005-11-10 14:23                       ` Jan Beulich
  2005-11-11  2:12                         ` Andi Kleen
  2005-11-10 14:43                       ` Vojtech Pavlik
  1 sibling, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-10 14:23 UTC (permalink / raw)
  To: vojtech, Andi Kleen; +Cc: linux-kernel, discuss

>The magic ICH6 HPET enable code has to go. It looks far too fragile and might 
>break something else. I also don't want direct PCI config space accesses like 
>this. We'll have to wait for ACPI HPET support I think. I think I'll remove 
>the original hack for AMD 8111 too - it was only for testing anyways. If you 
>still want to use it you have to keep it as a private patch.

That's fine with me. However, it was the only way for me to test the HPET code... It's not enabled anyway by default, but if you want the whole hack go away that's fine with me.

>Please remove the ifdefs too.  64bit HPET support would be fine, but 
>only as a runtime mechanism, not compile time.

This I added only for the purpose of not affecting existing code in existing configurations. If the code is generally acceptable, then I'll be more than happy to convert it.

>Can you remove debugger_jiffies please? 
>The code has to handle long delays anyways (e.g. if someone uses a target
>probe), so we cannot rely on such hacks anyways.

As above, I introduced this only to not affect existing code. If the added latency is no problem, then of course only the overflow safe code path should be kept, and then debugger_jiffies is completely unnecessary.

>I don't quite understand why the SMP case should be different from UP
>in that ifdef. Can you explain?  It shouldn't in theory.
>
>
>/* When the TSC gets reset during AP startup, the code below would
>+			   incorrectly think we lost a huge amount of ticks. */
>That is outdated - the TSCs are not reset anymore since 2.6.12.
>Please remove code for handling that.

Good to know, I didn't notice that. The conditional was so that the reset TSC would be considered a rolled-over one, resulting in a huge number of lost ticks.

>The union in vxtime_data is ugly - can it be avoided?

Yes, if the whole code is to become overflow-safe, then it'll just need to be a 64-bit field.

Jan


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes
  2005-11-10 14:07                         ` Jan Beulich
@ 2005-11-10 14:25                           ` Andi Kleen
  2005-11-10 15:00                             ` Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-10 14:25 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Thursday 10 November 2005 15:07, Jan Beulich wrote:
> >>> Andi Kleen <ak@suse.de> 10.11.05 14:21:48 >>>
> >
> >On Wednesday 09 November 2005 15:13, Jan Beulich wrote:
> >> This
> >> - switches the INT3 handler to run on an IST stack (to cope with
> >>   breakpoints set by a kernel debugger on places where the kernel's
> >>   %gs base hasn't been set up, yet); the IST stack used is shared with
> >>   the INT1 handler's
> >> - allows nesting of INT1/INT3 handlers so that one can, with a kernel
> >>   debugger, debug (at least) the user-mode portions of the INT1/INT3
> >>   handling; the nesting isn't actively enabled here since a kernel-
> >>   debugger-free kernel doesn't need it
> >
> >Looks reasonable except for the CONFIG_NLKD hunk, which doesn't
> >seem to be related. I think I'll apply it without that.
>
> As the comment in that hunk says - this is not the correct test, but the
> correct test cannot be used. Omitting the hunk altogether will leave orphan
> references to the pda field (even though these won't cause build problems)
> in setup64.c and traps.c.

!NLKD code relying on CONFIG_NLKD code? That sounds wrong. I won't apply
it then. Please clean up first.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers
  2005-11-10 13:23                         ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Andi Kleen
@ 2005-11-10 14:25                           ` Jan Beulich
  0 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-10 14:25 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, discuss

>>> Andi Kleen <ak@suse.de> 10.11.05 14:23:55 >>>
>On Wednesday 09 November 2005 15:14, Jan Beulich wrote:
>> This adds static information about the code regions where the stack
>> pointer cannot be relied upon. Kernel debuggers may then use this
>> information to determine which stack to switch to when having a need
>> to switch off of namely the NMI stack.
>
>Hmm - can't this be expressed in CFI somehow? 

Probably one could use .cfi_undefined, but the code needing the information (switching away from the NMI stack) shouldn't have to go through parsing the .eh_frame section contents in order to obtain that information.

Jan


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-10 13:19                     ` [PATCH 13/39] NLKD/x86-64 - time adjustment Andi Kleen
  2005-11-10 14:23                       ` Jan Beulich
@ 2005-11-10 14:43                       ` Vojtech Pavlik
  1 sibling, 0 replies; 105+ messages in thread
From: Vojtech Pavlik @ 2005-11-10 14:43 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Jan Beulich, linux-kernel, discuss

On Thu, Nov 10, 2005 at 02:19:03PM +0100, Andi Kleen wrote:
 
> Please remove the ifdefs too.  64bit HPET support would be fine, but 
> only as a runtime mechanism, not compile time.
> 
> Can you remove debugger_jiffies please? 
> The code has to handle long delays anyways (e.g. if someone uses a target
> probe), so we cannot rely on such hacks anyways.
> 
> I don't quite understand why the SMP case should be different from UP
> in that ifdef. Can you explain?  It shouldn't in theory.
> 
> 
> /* When the TSC gets reset during AP startup, the code below would
> +			   incorrectly think we lost a huge amount of ticks. */
> That is outdated - the TSCs are not reset anymore since 2.6.12.
> Please remove code for handling that.
> 
> The union in vxtime_data is ugly - can it be avoided?
> 
> Vojtech should probably review that one too when you repost.
 
I'd like to take a look at the patch as it is, but it seems my spam
filter ate it, and LKML.org doesn't archive binary attachments.

I've done some work on making x86-64 time handling overflow save in the
last few days, so I'm quite interested in what you needed to change.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 17:53   ` Alan Cox
  2005-11-09 16:25     ` Jeffrey V. Merkey
@ 2005-11-10 14:48     ` Mark Lord
  2005-11-10 15:28       ` Tom Rini
                         ` (2 more replies)
  1 sibling, 3 replies; 105+ messages in thread
From: Mark Lord @ 2005-11-10 14:48 UTC (permalink / raw)
  To: Alan Cox; +Cc: Jeff Garzik, Jan Beulich, linux-kernel

Alan Cox wrote:
>
> I think it is clearly the case that the design is wrong. The existance
> of kgdb shows how putting the complex logic remotely on another system
> is not only a lot cleaner and simpler but can also provide more
> functionality and higher reliability.

Unless the target machine is modern (2005+ era) and has no serial ports,
nor any way to add them other than via the USB stack.

Cheers

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes
  2005-11-10 14:25                           ` Andi Kleen
@ 2005-11-10 15:00                             ` Jan Beulich
  2005-11-11  3:39                               ` [discuss] " Andi Kleen
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-10 15:00 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, discuss

>> >Looks reasonable except for the CONFIG_NLKD hunk, which doesn't
>> >seem to be related. I think I'll apply it without that.
>>
>> As the comment in that hunk says - this is not the correct test, but
the
>> correct test cannot be used. Omitting the hunk altogether will leave
orphan
>> references to the pda field (even though these won't cause build
problems)
>> in setup64.c and traps.c.
>
>!NLKD code relying on CONFIG_NLKD code? That sounds wrong. I won't
apply
>it then. Please clean up first.

Since the exception stack size doesn't get set to other than 4k, this
isn't by itself wrong (the NLKD patch later conditionally sets this to
more than 4k). The problem, as said in the patch, is that pda.h cannot
include processor.h, and I see no solution for that (other than breaking
up processor.h).

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-10 14:48     ` Mark Lord
@ 2005-11-10 15:28       ` Tom Rini
  2005-11-10 16:37       ` Alan Cox
  2005-11-13  1:11       ` Andi Kleen
  2 siblings, 0 replies; 105+ messages in thread
From: Tom Rini @ 2005-11-10 15:28 UTC (permalink / raw)
  To: Mark Lord; +Cc: Alan Cox, Jeff Garzik, Jan Beulich, linux-kernel

On Thu, Nov 10, 2005 at 09:48:42AM -0500, Mark Lord wrote:
> Alan Cox wrote:
> >
> >I think it is clearly the case that the design is wrong. The existance
> >of kgdb shows how putting the complex logic remotely on another system
> >is not only a lot cleaner and simpler but can also provide more
> >functionality and higher reliability.
> 
> Unless the target machine is modern (2005+ era) and has no serial ports,
> nor any way to add them other than via the USB stack.

There's always ethernet.  Or, where there is a will, there is a way, as
shown by PowerPC's xmon over firewire.

-- 
Tom Rini
http://gate.crashing.org/~trini/

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-10 14:48     ` Mark Lord
  2005-11-10 15:28       ` Tom Rini
@ 2005-11-10 16:37       ` Alan Cox
  2005-11-13  1:11       ` Andi Kleen
  2 siblings, 0 replies; 105+ messages in thread
From: Alan Cox @ 2005-11-10 16:37 UTC (permalink / raw)
  To: Mark Lord; +Cc: Jeff Garzik, Jan Beulich, linux-kernel

On Iau, 2005-11-10 at 09:48 -0500, Mark Lord wrote:
> Unless the target machine is modern (2005+ era) and has no serial ports,
> nor any way to add them other than via the USB stack.

Debugger USB serial isn't hard. A micro polled USB stack is tiny (see
for example the BIOS USB in a PC). You've also get ethernet and
firewire. gdb remote has supported ethernet for years along with just
about anything else you can get a bitstream in and out of.

Alan


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-10  7:41             ` Jan Beulich
@ 2005-11-10 20:59               ` Sam Ravnborg
  2005-11-11  7:52                 ` Jan Beulich
  2005-11-10 23:01               ` Greg KH
  1 sibling, 1 reply; 105+ messages in thread
From: Sam Ravnborg @ 2005-11-10 20:59 UTC (permalink / raw)
  To: Jan Beulich; +Cc: Greg KH, linux-kernel

> I understand that. But you don't see my point, so I'll try to explain
> the background: When discovering the reason for the kallsyms change
> (also posted with the other NLKD patches) not functioning with
> CONFIG_MODVERSIONS and binutils between 2.16.90 and 2.16.91.0.3 I
> realized that the warning messages from the modpost build stage are very
> easy to overlook (in fact, all reporters of the problem overlooked them
> as well as I did on the first build attempting to reproduce the
> problem). This basically means these messages are almost useless, and
> detection of the problem will likely be deferred to the first attempt to
> load an offending module (which, as in the case named, may lead to an
> unusable kernel). Hence, at least until this build problem gets
> addressed I continue to believe that adding the preprocessor conditional
> is the better way of dealing with potential issues.

Can you elaborate a little what you like to have done to the build
process.

	Sam

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-10  7:41             ` Jan Beulich
  2005-11-10 20:59               ` Sam Ravnborg
@ 2005-11-10 23:01               ` Greg KH
  1 sibling, 0 replies; 105+ messages in thread
From: Greg KH @ 2005-11-10 23:01 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

On Thu, Nov 10, 2005 at 08:41:32AM +0100, Jan Beulich wrote:
> >>> Greg KH <greg@kroah.com> 09.11.05 18:19:19 >>>
> >On Wed, Nov 09, 2005 at 06:09:27PM +0100, Jan Beulich wrote:
> >> >>> Greg KH <greg@kroah.com> 09.11.05 17:45:44 >>>
> >> >#ifdef in the .h file is not needed.  Please fix your email client
> to
> >> >send patches properly.
> >> 
> >> It's not needed, sure, but by having it there I just wanted to make
> >> clear that this is something that never can be called from a module
> >> (after all, why should one find out at modpost time (and maybe even
> miss
> >> the message since there are so many past eventual symbol resolution
> >> warnings) when one can already at compile time.
> >
> >If it isn't present, and you do a build, you will still get the error
> at
> >build time, just during a different part of it.  Adding #ifdef just
> to
> >move the error to a different part of the build isn't needed. 
> Remember,
> >we want to not use #ifdef at all if we can ever help it.
> 
> I understand that. But you don't see my point, so I'll try to explain
> the background: When discovering the reason for the kallsyms change
> (also posted with the other NLKD patches) not functioning with
> CONFIG_MODVERSIONS and binutils between 2.16.90 and 2.16.91.0.3 I
> realized that the warning messages from the modpost build stage are very
> easy to overlook (in fact, all reporters of the problem overlooked them
> as well as I did on the first build attempting to reproduce the
> problem).

When you try to load the module, you will get the error again, right in
your kernel/system log, which explicitly shows that you had a problem.

> This basically means these messages are almost useless, and
> detection of the problem will likely be deferred to the first attempt to
> load an offending module (which, as in the case named, may lead to an
> unusable kernel). Hence, at least until this build problem gets
> addressed I continue to believe that adding the preprocessor conditional
> is the better way of dealing with potential issues. Sure I know that
> hundreds of other symbols possibly causing the same problem aren't
> protected...

Don't try to do things to fix your prior problems in your patch, with
changes today so that you don't do it again in the future :)

The build process properly notifies the builder of the problem, if they
ignore it, there's really nothing more we can do about it, right?

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 12/39] NLKD/i386 - time adjustment
  2005-11-10  8:12                       ` Jan Beulich
@ 2005-11-11  0:17                         ` George Anzinger
  0 siblings, 0 replies; 105+ messages in thread
From: George Anzinger @ 2005-11-11  0:17 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

Jan Beulich wrote:
~
> 
> gcc can do long long multiplies fine, but only with a long long result.
> The code presented, however, needs (at least) 96 bits of the result,
> which expressing in C would be far more complicated than doing it with a
> couple of assembly statements.
> 
Well, if you need that many bits... guess I would need to study the code (hard with binary 
attachments) to understand why you need so many bits.
> 
>>I really do not see the relavence of the run time library patches
> 
~

> 
> Which run time library patches are you referring to? NLKD's? If so,
> these routines must not be used by code outside of the debugger (and the
> opposite is true, too: debugger code must not use common code routines
> where ever possible).

Just what is your argument here?  As I understand it this is only a problem (i.e. sharing the code) 
if you are trying to single step or set breakpoints in the library code.
> 
> Further, it is my understanding that it is for a (unknown to me) reason
> that the linux kernel doesn't have the full set of libgcc support
> routines. Since the debugger in various places relies on being able to
> do 64-bit math on 32-bit systems, I had to add these in a way so that
> they'd be hidden from the rest of the kernel (and also so that they'd
> satisfy the isolation rules outlined above).

Well, the powers that be, decided that the kernel did not need the "missing" routines and that they 
just added bloat.  One then wonders why a debugger needs them.  Could you enlighten us on this?

-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-10 14:23                       ` Jan Beulich
@ 2005-11-11  2:12                         ` Andi Kleen
  2005-11-12  9:22                           ` Vojtech Pavlik
  0 siblings, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-11  2:12 UTC (permalink / raw)
  To: Jan Beulich; +Cc: vojtech, linux-kernel, discuss

On Thursday 10 November 2005 15:23, Jan Beulich wrote:

>
> >Please remove the ifdefs too.  64bit HPET support would be fine, but
> >only as a runtime mechanism, not compile time.
>
> This I added only for the purpose of not affecting existing code in
> existing configurations. If the code is generally acceptable, then I'll be
> more than happy to convert it.

We can't use 64bit HPET everywhere because quite some chipsets only
support 32bit HPET. So it has to be a runtime switch depending on the 
capabilities of the hardware.

>
> >Can you remove debugger_jiffies please?
> >The code has to handle long delays anyways (e.g. if someone uses a target
> >probe), so we cannot rely on such hacks anyways.
>
> As above, I introduced this only to not affect existing code. If the added
> latency is no problem, then of course only the overflow safe code path
> should be kept, and then debugger_jiffies is completely unnecessary.

Hmm - didn't notice anything particularly slow. Or what were you thinking 
about regarding the latency? And it should only run at each timer interrupt,
so it isn't a fast path. So I guess it's best to run it always.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [discuss] Re: [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes
  2005-11-10 15:00                             ` Jan Beulich
@ 2005-11-11  3:39                               ` Andi Kleen
  0 siblings, 0 replies; 105+ messages in thread
From: Andi Kleen @ 2005-11-11  3:39 UTC (permalink / raw)
  To: discuss; +Cc: Jan Beulich, linux-kernel

On Thursday 10 November 2005 16:00, Jan Beulich wrote:

> Since the exception stack size doesn't get set to other than 4k, this
> isn't by itself wrong (the NLKD patch later conditionally sets this to
> more than 4k). The problem, as said in the patch, is that pda.h cannot
> include processor.h, and I see no solution for that (other than breaking
> up processor.h).

You mean for the exception stack size defines? Feel free to put them into
a different header then. processor.h has too much stuff anyways.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-10 20:59               ` Sam Ravnborg
@ 2005-11-11  7:52                 ` Jan Beulich
  2005-11-12 20:52                   ` Randy.Dunlap
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-11  7:52 UTC (permalink / raw)
  To: Sam Ravnborg; +Cc: linux-kernel

>>> Sam Ravnborg <sam@ravnborg.org> 10.11.05 21:59:31 >>>
>> I understand that. But you don't see my point, so I'll try to
explain
>> the background: When discovering the reason for the kallsyms change
>> (also posted with the other NLKD patches) not functioning with
>> CONFIG_MODVERSIONS and binutils between 2.16.90 and 2.16.91.0.3 I
>> realized that the warning messages from the modpost build stage are
very
>> easy to overlook (in fact, all reporters of the problem overlooked
them
>> as well as I did on the first build attempting to reproduce the
>> problem). This basically means these messages are almost useless,
and
>> detection of the problem will likely be deferred to the first
attempt to
>> load an offending module (which, as in the case named, may lead to
an
>> unusable kernel). Hence, at least until this build problem gets
>> addressed I continue to believe that adding the preprocessor
conditional
>> is the better way of dealing with potential issues.
>
>Can you elaborate a little what you like to have done to the build
>process.

As said above, I'd like to see the messages from modpost deferred or
re-issued at the end of the module building process (i.e. after the
perhaps hundreds of *.mod.c files got compiled and the same number of
*.ko got linked, which on a typical distribution will easily scroll off
the original warnings even with a 1000 line history, as seems to be the
default in many cases).

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 2/39] NLKD - an alternative early ioremap approach
  2005-11-09 13:57   ` [PATCH 2/39] NLKD - an alternative early ioremap approach Jan Beulich
  2005-11-09 13:58     ` [PATCH 3/39] NLKD - early/late CPU up/down notification Jan Beulich
@ 2005-11-11 10:06     ` Pavel Machek
  2005-11-11 10:19       ` Jan Beulich
  1 sibling, 1 reply; 105+ messages in thread
From: Pavel Machek @ 2005-11-11 10:06 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel

Hi!

> An alternative to (on i386) boot-time ioremap approaches, which is more
> architecture independent (though arch dependent code needs adjustments
> if this is to be made use of, which with this patch only happens for
> i386 and x86_64) and doesn't require alternative boot-time interfaces.
> 
> Signed-Off-By: Jan Beulich <jbeulich@novell.com>

> (actual patch attached)

Can you inline those patches? I do not care what email system you are
using, get gmail account if you have to. Or just ask for
suse.de/suse.cz account.

Ouch and btw the patch is wrong in first hunk, it adds #else/#endif
without #ifdef. Ouch.

								Pavel
-- 
Thanks, Sharp!

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 2/39] NLKD - an alternative early ioremap approach
  2005-11-11 10:06     ` [PATCH 2/39] NLKD - an alternative early ioremap approach Pavel Machek
@ 2005-11-11 10:19       ` Jan Beulich
  0 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-11 10:19 UTC (permalink / raw)
  To: Pavel Machek; +Cc: linux-kernel

>Ouch and btw the patch is wrong in first hunk, it adds #else/#endif
>without #ifdef. Ouch.

It only adds #else, #if and #endif already exist...

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-11  2:12                         ` Andi Kleen
@ 2005-11-12  9:22                           ` Vojtech Pavlik
  2005-11-12 17:21                             ` Andi Kleen
  0 siblings, 1 reply; 105+ messages in thread
From: Vojtech Pavlik @ 2005-11-12  9:22 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Jan Beulich, linux-kernel, discuss

On Fri, Nov 11, 2005 at 03:12:15AM +0100, Andi Kleen wrote:
> On Thursday 10 November 2005 15:23, Jan Beulich wrote:
> 
> >
> > >Please remove the ifdefs too.  64bit HPET support would be fine, but
> > >only as a runtime mechanism, not compile time.
> >
> > This I added only for the purpose of not affecting existing code in
> > existing configurations. If the code is generally acceptable, then I'll be
> > more than happy to convert it.
> 
> We can't use 64bit HPET everywhere because quite some chipsets only
> support 32bit HPET. So it has to be a runtime switch depending on the 
> capabilities of the hardware.

Is there any advantage to using 64-bit HPET? It's read is even slower
(and thus even more unusable in a vsyscall than a 32-bit HPET read), and
the missing 32 bits can be quite easily added should we need them for
computations, which I doubt.

> > >Can you remove debugger_jiffies please?
> > >The code has to handle long delays anyways (e.g. if someone uses a target
> > >probe), so we cannot rely on such hacks anyways.
> >
> > As above, I introduced this only to not affect existing code. If the added
> > latency is no problem, then of course only the overflow safe code path
> > should be kept, and then debugger_jiffies is completely unnecessary.
> 
> Hmm - didn't notice anything particularly slow. Or what were you thinking 
> about regarding the latency? And it should only run at each timer interrupt,
> so it isn't a fast path. So I guess it's best to run it always.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-12  9:22                           ` Vojtech Pavlik
@ 2005-11-12 17:21                             ` Andi Kleen
  2005-11-12 20:44                               ` Vojtech Pavlik
  0 siblings, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-12 17:21 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Jan Beulich, linux-kernel, discuss

On Saturday 12 November 2005 10:22, Vojtech Pavlik wrote:

> Is there any advantage to using 64-bit HPET? 

Yes - it can tolerate long delays between ticks, e.g. caused by noidletick / 
debuggers / target probes / smm etc. At least the first case will be fairly
important soon.

> It's read is even slower 

Why? The read should be on cache line granuality and there shouldn't
be any difference in theory.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-12 17:21                             ` Andi Kleen
@ 2005-11-12 20:44                               ` Vojtech Pavlik
  2005-11-15  0:38                                 ` George Anzinger
  0 siblings, 1 reply; 105+ messages in thread
From: Vojtech Pavlik @ 2005-11-12 20:44 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Jan Beulich, linux-kernel, discuss

On Sat, Nov 12, 2005 at 06:21:11PM +0100, Andi Kleen wrote:
> On Saturday 12 November 2005 10:22, Vojtech Pavlik wrote:
> 
> > Is there any advantage to using 64-bit HPET? 
> 
> Yes - it can tolerate long delays between ticks, e.g. caused by noidletick / 
> debuggers / target probes / smm etc. At least the first case will be fairly
> important soon.

A 32-bit 14 MHz HPET counter will overflow in approximately 5 minutes. I
don't think going 64-bit makes sense for noidletick, but for debuggers,
etc, it could make a good sense indeed.

> > It's read is even slower 
> 
> Why? The read should be on cache line granuality and there shouldn't
> be any difference in theory.
 
I'll try to measure this. Indeed, in theory there shouldn't be a
significant difference.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 3/39] NLKD - early/late CPU up/down notification
  2005-11-11  7:52                 ` Jan Beulich
@ 2005-11-12 20:52                   ` Randy.Dunlap
  0 siblings, 0 replies; 105+ messages in thread
From: Randy.Dunlap @ 2005-11-12 20:52 UTC (permalink / raw)
  To: Jan Beulich; +Cc: sam, linux-kernel

On Fri, 11 Nov 2005 08:52:38 +0100 Jan Beulich wrote:

> >>> Sam Ravnborg <sam@ravnborg.org> 10.11.05 21:59:31 >>>
> >> I understand that. But you don't see my point, so I'll try to
> explain
> >> the background: When discovering the reason for the kallsyms change
> >> (also posted with the other NLKD patches) not functioning with
> >> CONFIG_MODVERSIONS and binutils between 2.16.90 and 2.16.91.0.3 I
> >> realized that the warning messages from the modpost build stage are
> very
> >> easy to overlook (in fact, all reporters of the problem overlooked
> them
> >> as well as I did on the first build attempting to reproduce the
> >> problem). This basically means these messages are almost useless,
> and
> >> detection of the problem will likely be deferred to the first
> attempt to
> >> load an offending module (which, as in the case named, may lead to
> an
> >> unusable kernel). Hence, at least until this build problem gets
> >> addressed I continue to believe that adding the preprocessor
> conditional
> >> is the better way of dealing with potential issues.
> >
> >Can you elaborate a little what you like to have done to the build
> >process.
> 
> As said above, I'd like to see the messages from modpost deferred or
> re-issued at the end of the module building process (i.e. after the
> perhaps hundreds of *.mod.c files got compiled and the same number of
> *.ko got linked, which on a typical distribution will easily scroll off
> the original warnings even with a 1000 line history, as seems to be the
> default in many cases).

Lots of such error or warning messages scroll away.  All that it takes
is use of egrep "foo|bar" to look for the interesting messages
or egrep -v "foo|bar" to discard the uninteresting (normal) messages.
I do that all the time and I think that it's the right thing to do,
not have the tools regurgitate something that they have already said.

---
~Randy

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-09 17:06   ` Randy.Dunlap
  2005-11-09 17:14     ` Jan Beulich
@ 2005-11-13  1:09     ` Andi Kleen
  2005-11-13  2:53       ` jmerkey
  1 sibling, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-13  1:09 UTC (permalink / raw)
  To: Randy.Dunlap; +Cc: Jan Beulich, linux-kernel, akpm

"Randy.Dunlap" <rdunlap@xenotime.net> writes:

> On Wed, 9 Nov 2005, Jeff Garzik wrote:
> 
> > Jan Beulich wrote:
> > > The following patch set represents the Novell Linux Kernel Debugger,
> > > stripped off of its original low-level exception handling framework.
> >
> >
> > Honestly, just seeing all these code changes makes me think we really
> > don't need it in the kernel.  How many "early" and "alternative" gadgets
> > do we really need just for this thing?
> 
> On the surface I have to agree.  However, if Jan wants feedback
> on the patches, that's a reasonable request IMO.
> (but they need to be readable via email so that someone
> can comment on them)
> 
> At a quick blush, I would guess it has as much chance as
> kdb does (or did) for merging.

I hope we can follow the same strategy as I did for debuggers on x86-64 - 
which imho worked very well. Get all the (sane) hooks in so that everybody
who wants to use their particular flavour of debugger can use it 
by (ideally) either just loading it or alternatively applying a small
core patch and the debugger files elsewhere. The die chains started
from that. 

Making the debugger work modular is a bit more work, but possible (was
done for kdb at least before with some changes). IMHO that's the ideal
state for users - they can just compile it externally and load it when
they need it, but the core kernel doesn't need to carry it. It
conflicts a bit with the usual policy of not exporting stuff that's
not used in the core kernel; but I think making an exception here is
reasonable because

So I guess it's best to concentrate on merging the hooks needed in a sane
way. 

I think the many additions for "early" code in the NLKD patchkit
comes from Jan's desire to make the debugger work in as many weird
corner cases as possible. I must say he found a lot of problems in 
corner cases during that work in x86-64 and i386, fixing generic
bugs and making even the standard oops code and other error handling
code (e.g. double faults on i386) more reliable, which I appreciate. 

The particular early changes have to be weighted of course in
intrusiveness. If it's simple and not too ugly stuff I guess it is
reasonable to consider it. If not the debugger will have
to live without it.

I already merged all the changes that looked good (and where I was cc'ed) 
for x86-64 now. Some patches need changes, and I guess with that
feedback the i386 part can be similarly adjusted.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-10 14:48     ` Mark Lord
  2005-11-10 15:28       ` Tom Rini
  2005-11-10 16:37       ` Alan Cox
@ 2005-11-13  1:11       ` Andi Kleen
  2 siblings, 0 replies; 105+ messages in thread
From: Andi Kleen @ 2005-11-13  1:11 UTC (permalink / raw)
  To: Mark Lord; +Cc: Jeff Garzik, Jan Beulich, linux-kernel

Mark Lord <lkml@rtr.ca> writes:

> Alan Cox wrote:
> >
> > I think it is clearly the case that the design is wrong. The existance
> > of kgdb shows how putting the complex logic remotely on another system
> > is not only a lot cleaner and simpler but can also provide more
> > functionality and higher reliability.
> 
> Unless the target machine is modern (2005+ era) and has no serial ports,
> nor any way to add them other than via the USB stack.

Firewire looks most promising actually right now, at least for Desktop/Laptop
type systems. And servers still have serial ports right now, either in
hardware or simulated in some way.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-13  1:09     ` Andi Kleen
@ 2005-11-13  2:53       ` jmerkey
  2005-11-13  3:44         ` Andi Kleen
  0 siblings, 1 reply; 105+ messages in thread
From: jmerkey @ 2005-11-13  2:53 UTC (permalink / raw)
  To: Andi Kleen; +Cc: Randy.Dunlap, Jan Beulich, linux-kernel, akpm

Andi Kleen wrote:

>"Randy.Dunlap" <rdunlap@xenotime.net> writes:
>
>  
>
>>On Wed, 9 Nov 2005, Jeff Garzik wrote:
>>
>>    
>>
>>>Jan Beulich wrote:
>>>      
>>>
>>>>The following patch set represents the Novell Linux Kernel Debugger,
>>>>stripped off of its original low-level exception handling framework.
>>>>        
>>>>
>>>Honestly, just seeing all these code changes makes me think we really
>>>don't need it in the kernel.  How many "early" and "alternative" gadgets
>>>do we really need just for this thing?
>>>      
>>>
>>On the surface I have to agree.  However, if Jan wants feedback
>>on the patches, that's a reasonable request IMO.
>>(but they need to be readable via email so that someone
>>can comment on them)
>>
>>At a quick blush, I would guess it has as much chance as
>>kdb does (or did) for merging.
>>    
>>
>
>I hope we can follow the same strategy as I did for debuggers on x86-64 - 
>which imho worked very well. Get all the (sane) hooks in so that everybody
>who wants to use their particular flavour of debugger can use it 
>by (ideally) either just loading it or alternatively applying a small
>core patch and the debugger files elsewhere. The die chains started
>from that. 
>  
>
Yes. This is the way to go. Use kdb as a base and instrument an 
alternate debugger interface. You need to also find a good way to
allow GDB to work properly with alternate debuggers. At present, the 
code in traps.c is mutually exclusive since embedded int3
breakpoints trigger in the kernel for gbd. This is busted.

Jeff

>Making the debugger work modular is a bit more work, but possible (was
>done for kdb at least before with some changes). IMHO that's the ideal
>state for users - they can just compile it externally and load it when
>they need it, but the core kernel doesn't need to carry it. It
>conflicts a bit with the usual policy of not exporting stuff that's
>not used in the core kernel; but I think making an exception here is
>reasonable because
>
>So I guess it's best to concentrate on merging the hooks needed in a sane
>way. 
>
>I think the many additions for "early" code in the NLKD patchkit
>comes from Jan's desire to make the debugger work in as many weird
>corner cases as possible. I must say he found a lot of problems in 
>corner cases during that work in x86-64 and i386, fixing generic
>bugs and making even the standard oops code and other error handling
>code (e.g. double faults on i386) more reliable, which I appreciate. 
>
>The particular early changes have to be weighted of course in
>intrusiveness. If it's simple and not too ugly stuff I guess it is
>reasonable to consider it. If not the debugger will have
>to live without it.
>
>I already merged all the changes that looked good (and where I was cc'ed) 
>for x86-64 now. Some patches need changes, and I guess with that
>feedback the i386 part can be similarly adjusted.
>
>-Andi
>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at  http://www.tux.org/lkml/
>
>  
>


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-13  3:44         ` Andi Kleen
@ 2005-11-13  3:26           ` Jeff V. Merkey
  2005-11-13  3:32             ` Jeff V. Merkey
  0 siblings, 1 reply; 105+ messages in thread
From: Jeff V. Merkey @ 2005-11-13  3:26 UTC (permalink / raw)
  To: Andi Kleen; +Cc: jmerkey, Randy.Dunlap, Jan Beulich, linux-kernel, akpm

Andi Kleen wrote:

>On Sunday 13 November 2005 03:53, jmerkey wrote:
>
>  
>
>>Yes. This is the way to go. Use kdb as a base and instrument an 
>>alternate debugger interface. You need to also find a good way to
>>allow GDB to work properly with alternate debuggers. At present, the 
>>code in traps.c is mutually exclusive since embedded int3
>>breakpoints trigger in the kernel for gbd. This is busted.
>>    
>>
>
>
>I don't think we'll support stacking multiple kernel debuggers (except
>for special cases like kprobes+another debugger). It's complicated
>and probably not worth it.
>
>-Andi
>
>
>  
>
I already instrumented an alternate debugger interface in MDB.  It's not 
complicated at all.    Here's the code.  All you
need to do is change two places.  Add the alternate interface into kdb, 
and fix the int3 contention problem with GDB.  GDB
support with kdb action involves creating a callback into GDB signaling 
the int3 POST kdb handling.  In other words, keep
a table of breakpoints for int3 alternate debuggers they must register, 
compare against this table and divert the int3 on this basis,
it is matches the table, send to the registered debugger entry point, if 
it doesn't match, call the GDB handler and send it to
userspace.  Seems simple.  Here's part one.  Someone else can write part 2.

Jeff
diff -Naur ./kdb/kdbmain.c ../linux-2.6.9-mdb/./kdb/kdbmain.c
--- ./kdb/kdbmain.c    2004-10-18 11:46:59.439535288 -0600
+++ ../linux-2.6.9-mdb/./kdb/kdbmain.c    2004-10-18 11:44:47.000000000 
-0600
@@ -57,7 +57,12 @@
 int kdb_seqno = 2;                /* how many times kdb has been entered */
 
 volatile int kdb_nextline = 1;
+
+#if defined(CONFIG_MDB)
+volatile int kdb_new_cpu;        /* Which cpu to switch to */
+#else
 static volatile int kdb_new_cpu;        /* Which cpu to switch to */
+#endif
 
 volatile int kdb_state[NR_CPUS];        /* Per cpu state */
 
@@ -1134,8 +1139,13 @@
 
 extern char kdb_prompt_str[];
 
+#if defined(CONFIG_MDB)
 static int
 kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, 
kdb_dbtrap_t db_result)
+#else
+int
+kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, 
kdb_dbtrap_t db_result)
+#endif
 {
     char *cmdbuf;
     int diag;
@@ -1676,6 +1686,27 @@
     int result = 0;    /* Default is kdb did not handle it */
     int ss_event;
     kdb_dbtrap_t db_result=KDB_DB_NOBPT;
+
+#if defined(CONFIG_MDB)
+        extern int AlternateDebuggerRoutine(kdb_reason_t reason, int 
error,
+                                     struct pt_regs *ef);
+    if (!kdb_on)
+       return 0;
+
+        result = AlternateDebuggerRoutine(reason, error, regs);
+        switch (result)
+        {
+           case 1:  // alternate debugger handled event
+              return 1;
+
+           case -1: // alternate debugger did not handle event
+              return 0;
+
+           default: // drop into kdb
+              break;
+        }
+#endif
+
     atomic_inc(&kdb_event);
 
     switch(reason) {
@@ -3016,6 +3047,40 @@
  * Remarks:
  */
 
+#if defined (CONFIG_MDB)
+
+#include <linux/mdbglobals.h>
+
+void
+mdb_ps1(struct task_struct *p)
+{
+    DBGPrint("0x%p %8d %8d  %d %4d   %c  0x%p %c%s\n",
+           (void *)p, p->pid, p->parent->pid,
+           kdb_task_has_cpu(p), kdb_process_cpu(p),
+           (p->state == 0) ? 'R' :
+             (p->state < 0) ? 'U' :
+             (p->state & TASK_UNINTERRUPTIBLE) ? 'D' :
+             (p->state & TASK_STOPPED || p->ptrace & PT_PTRACED) ? 'T' :
+             (p->state & TASK_ZOMBIE) ? 'Z' :
+             (p->state & TASK_INTERRUPTIBLE) ? 'S' : '?',
+           (void *)(&p->thread),
+           (p == current) ? '*': ' ',
+           p->comm);
+    if (kdb_task_has_cpu(p)) {
+        struct kdb_running_process *krp = kdb_running_process + 
kdb_process_cpu(p);
+        if (!krp->seqno || !krp->p)
+            DBGPrint("  Error: no saved data for this cpu\n");
+        else {
+            if (krp->seqno < kdb_seqno - 1)
+                DBGPrint("  Warning: process state is stale\n");
+            if (krp->p != p)
+                DBGPrint("  Error: does not match running process table 
(0x%p)\n", krp->p);
+        }
+    }
+}
+
+#endif
+
 void
 kdb_ps1(struct task_struct *p)
 {
@@ -3835,6 +3900,10 @@
 void __init
 kdb_init(void)
 {
+#if defined(CONFIG_MDB)
+        extern void mdb_init(void);                
+#endif
+
     kdb_initial_cpu = smp_processor_id();
     /*
      * This must be called before any calls to kdb_printf.
@@ -3855,6 +3924,11 @@
 
     kdb_cmd_init();        /* Preset commands from kdb_cmds */
     kdb_initial_cpu = -1;    /* Avoid recursion problems */
+
+#if defined(CONFIG_MDB)
+        mdb_init();                
+#endif
+
     kdb(KDB_REASON_SILENT, 0, 0);    /* Activate any preset breakpoints 
on boot cpu */
     kdb_initial_cpu = smp_processor_id();
     notifier_chain_register(&panic_notifier_list, &kdb_block);


^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-13  3:26           ` Jeff V. Merkey
@ 2005-11-13  3:32             ` Jeff V. Merkey
  0 siblings, 0 replies; 105+ messages in thread
From: Jeff V. Merkey @ 2005-11-13  3:32 UTC (permalink / raw)
  To: Jeff V. Merkey
  Cc: Andi Kleen, jmerkey, Randy.Dunlap, Jan Beulich, linux-kernel,
	akpm

Jeff V. Merkey wrote:

> Andi Kleen wrote:
>
>> On Sunday 13 November 2005 03:53, jmerkey wrote:
>>
>>  
>>
>>> Yes. This is the way to go. Use kdb as a base and instrument an 
>>> alternate debugger interface. You need to also find a good way to
>>> allow GDB to work properly with alternate debuggers. At present, the 
>>> code in traps.c is mutually exclusive since embedded int3
>>> breakpoints trigger in the kernel for gbd. This is busted.
>>>   
>>
>>
>>
>> I don't think we'll support stacking multiple kernel debuggers (except
>> for special cases like kprobes+another debugger). It's complicated
>> and probably not worth it.
>>
>> -Andi
>>
>>
>>  
>>
> I already instrumented an alternate debugger interface in MDB.  It's 
> not complicated at all.    Here's the code.  All you
> need to do is change two places.  Add the alternate interface into 
> kdb, and fix the int3 contention problem with GDB.  GDB
> support with kdb action involves creating a callback into GDB 
> signaling the int3 POST kdb handling.  In other words, keep
> a table of breakpoints for int3 alternate debuggers they must 
> register, compare against this table and divert the int3 on this basis,
> it is matches the table, send to the registered debugger entry point, 
> if it doesn't match, call the GDB handler and send it to
> userspace.  Seems simple.  Here's part one.  Someone else can write 
> part 2.
>
> Jeff
> diff -Naur ./kdb/kdbmain.c ../linux-2.6.9-mdb/./kdb/kdbmain.c
> --- ./kdb/kdbmain.c    2004-10-18 11:46:59.439535288 -0600
> +++ ../linux-2.6.9-mdb/./kdb/kdbmain.c    2004-10-18 
> 11:44:47.000000000 -0600
> @@ -57,7 +57,12 @@
> int kdb_seqno = 2;                /* how many times kdb has been 
> entered */
>
> volatile int kdb_nextline = 1;
> +
> +#if defined(CONFIG_MDB)
> +volatile int kdb_new_cpu;        /* Which cpu to switch to */
> +#else
> static volatile int kdb_new_cpu;        /* Which cpu to switch to */
> +#endif
>
> volatile int kdb_state[NR_CPUS];        /* Per cpu state */
>
> @@ -1134,8 +1139,13 @@
>
> extern char kdb_prompt_str[];
>
> +#if defined(CONFIG_MDB)
> static int
> kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, 
> kdb_dbtrap_t db_result)
> +#else
> +int
> +kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, 
> kdb_dbtrap_t db_result)
> +#endif
> {
>     char *cmdbuf;
>     int diag;
> @@ -1676,6 +1686,27 @@
>     int result = 0;    /* Default is kdb did not handle it */
>     int ss_event;
>     kdb_dbtrap_t db_result=KDB_DB_NOBPT;
> +
> +#if defined(CONFIG_MDB)
> +        extern int AlternateDebuggerRoutine(kdb_reason_t reason, int 
> error,
> +                                     struct pt_regs *ef);
> +    if (!kdb_on)
> +       return 0;
> +
> +        result = AlternateDebuggerRoutine(reason, error, regs);
> +        switch (result)
> +        {
> +           case 1:  // alternate debugger handled event
> +              return 1;
> +
> +           case -1: // alternate debugger did not handle event
> +              return 0;
> +
> +           default: // drop into kdb
> +              break;
> +        }
> +#endif
> +
>     atomic_inc(&kdb_event);
>
>     switch(reason) {
> @@ -3016,6 +3047,40 @@
>  * Remarks:
>  */
>
> +#if defined (CONFIG_MDB)
> +
> +#include <linux/mdbglobals.h>
> +
> +void
> +mdb_ps1(struct task_struct *p)
> +{
> +    DBGPrint("0x%p %8d %8d  %d %4d   %c  0x%p %c%s\n",
> +           (void *)p, p->pid, p->parent->pid,
> +           kdb_task_has_cpu(p), kdb_process_cpu(p),
> +           (p->state == 0) ? 'R' :
> +             (p->state < 0) ? 'U' :
> +             (p->state & TASK_UNINTERRUPTIBLE) ? 'D' :
> +             (p->state & TASK_STOPPED || p->ptrace & PT_PTRACED) ? 'T' :
> +             (p->state & TASK_ZOMBIE) ? 'Z' :
> +             (p->state & TASK_INTERRUPTIBLE) ? 'S' : '?',
> +           (void *)(&p->thread),
> +           (p == current) ? '*': ' ',
> +           p->comm);
> +    if (kdb_task_has_cpu(p)) {
> +        struct kdb_running_process *krp = kdb_running_process + 
> kdb_process_cpu(p);
> +        if (!krp->seqno || !krp->p)
> +            DBGPrint("  Error: no saved data for this cpu\n");
> +        else {
> +            if (krp->seqno < kdb_seqno - 1)
> +                DBGPrint("  Warning: process state is stale\n");
> +            if (krp->p != p)
> +                DBGPrint("  Error: does not match running process 
> table (0x%p)\n", krp->p);
> +        }
> +    }
> +}
> +
> +#endif
> +
> void
> kdb_ps1(struct task_struct *p)
> {
> @@ -3835,6 +3900,10 @@
> void __init
> kdb_init(void)
> {
> +#if defined(CONFIG_MDB)
> +        extern void mdb_init(void);                +#endif
> +
>     kdb_initial_cpu = smp_processor_id();
>     /*
>      * This must be called before any calls to kdb_printf.
> @@ -3855,6 +3924,11 @@
>
>     kdb_cmd_init();        /* Preset commands from kdb_cmds */
>     kdb_initial_cpu = -1;    /* Avoid recursion problems */
> +
> +#if defined(CONFIG_MDB)
> +        mdb_init();                +#endif
> +
>     kdb(KDB_REASON_SILENT, 0, 0);    /* Activate any preset 
> breakpoints on boot cpu */
>     kdb_initial_cpu = smp_processor_id();
>     notifier_chain_register(&panic_notifier_list, &kdb_block);
>
>
Alternate Debuggers should register an init function called from 
kdb_init.   Calling AlternateDebuggerInterface should call all registred 
debuggers
and allow each one to report status.  NetWare has had an alternate 
debugger interface for years.  It's easy to instrument.  The only thing
in Linux that's odd at all is the way GDB int3's are handled.  All this 
other stuff they are making you put in is not the problem of Linux.

Jeff

Jeff

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 0/39] NLKD - Novell Linux Kernel Debugger
  2005-11-13  2:53       ` jmerkey
@ 2005-11-13  3:44         ` Andi Kleen
  2005-11-13  3:26           ` Jeff V. Merkey
  0 siblings, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-13  3:44 UTC (permalink / raw)
  To: jmerkey; +Cc: Randy.Dunlap, Jan Beulich, linux-kernel, akpm

On Sunday 13 November 2005 03:53, jmerkey wrote:

> Yes. This is the way to go. Use kdb as a base and instrument an 
> alternate debugger interface. You need to also find a good way to
> allow GDB to work properly with alternate debuggers. At present, the 
> code in traps.c is mutually exclusive since embedded int3
> breakpoints trigger in the kernel for gbd. This is busted.


I don't think we'll support stacking multiple kernel debuggers (except
for special cases like kprobes+another debugger). It's complicated
and probably not worth it.

-Andi


^ permalink raw reply	[flat|nested] 105+ messages in thread

* [discuss] Re: [PATCH 5/39] NLKD/x86-64 - early/late CPU up/down notification
  2005-11-10 13:10         ` Andi Kleen
@ 2005-11-14  8:04           ` Jan Beulich
  2005-11-14 12:37             ` Andi Kleen
  0 siblings, 1 reply; 105+ messages in thread
From: Jan Beulich @ 2005-11-14  8:04 UTC (permalink / raw)
  To: Andi Kleen; +Cc: linux-kernel, discuss

>>> Andi Kleen <ak@suse.de> 10.11.05 14:10:16 >>>
>On Wednesday 09 November 2005 15:01, Jan Beulich wrote:
>> x86_64-specific part of the new mechanism to allow debuggers to
learn
>> about starting/dying CPUs as early/late as possible.
>
>Please just use the normal notifier chains instead (CPU_UP, CPU_DOWN,

>register_cpu_notifier). I don't see much sense to have two different 
>mechanisms to do the same thing. While they might be not as
early/late
>as your mechanism I think the users of your debugger can tolerate
that.

Assuming you mean CPU_ONLINE and CPU_DEAD. But no, I don't really like
this. The most significant difference is that the existing notifications
are not sent on the starting CPU, but on the one it got started from.
The point in time is only the second reason for not using these.

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [discuss] Re: [PATCH 5/39] NLKD/x86-64 - early/late CPU up/down notification
  2005-11-14  8:04           ` [discuss] " Jan Beulich
@ 2005-11-14 12:37             ` Andi Kleen
  0 siblings, 0 replies; 105+ messages in thread
From: Andi Kleen @ 2005-11-14 12:37 UTC (permalink / raw)
  To: Jan Beulich; +Cc: linux-kernel, discuss

On Monday 14 November 2005 09:04, Jan Beulich wrote:

> Assuming you mean CPU_ONLINE and CPU_DEAD. 

Yes

> But no, I don't really like 
> this. The most significant difference is that the existing notifications
> are not sent on the starting CPU, but on the one it got started from.
> The point in time is only the second reason for not using these.

Ok, I can see your point. Let's say a new notifier for that would
be ok if you can find at least one other existing in tree user and 
convert it  to it. Does that sound fair? 

Note I'm about to remove the IO apic watchdog setup, so that one
doesn't count.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-12 20:44                               ` Vojtech Pavlik
@ 2005-11-15  0:38                                 ` George Anzinger
  2005-11-15  1:05                                   ` [discuss] " Andi Kleen
  0 siblings, 1 reply; 105+ messages in thread
From: George Anzinger @ 2005-11-15  0:38 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andi Kleen, Jan Beulich, linux-kernel, discuss

Vojtech Pavlik wrote:
> On Sat, Nov 12, 2005 at 06:21:11PM +0100, Andi Kleen wrote:
> 
>>On Saturday 12 November 2005 10:22, Vojtech Pavlik wrote:
>>
>>
>>>Is there any advantage to using 64-bit HPET? 
>>
>>Yes - it can tolerate long delays between ticks, e.g. caused by noidletick / 
>>debuggers / target probes / smm etc. At least the first case will be fairly
>>important soon.
> 
> 
> A 32-bit 14 MHz HPET counter will overflow in approximately 5 minutes. I
> don't think going 64-bit makes sense for noidletick, but for debuggers,
> etc, it could make a good sense indeed.
> 
> 
>>>It's read is even slower 
>>
>>Why? The read should be on cache line granuality and there shouldn't
>>be any difference in theory.
> 
>  
> I'll try to measure this. Indeed, in theory there shouldn't be a
> significant difference.
> 
Doesn't this depend on the atomic nature of the 64-bit read?  If it is really two 32-bit reads one 
would need to do extra work to make sure the two parts belong together.

-- 
George Anzinger   george@mvista.com
HRT (High-res-timers):  http://sourceforge.net/projects/high-res-timers/

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [discuss] Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-15  0:38                                 ` George Anzinger
@ 2005-11-15  1:05                                   ` Andi Kleen
  2005-11-15  7:50                                     ` Vojtech Pavlik
  0 siblings, 1 reply; 105+ messages in thread
From: Andi Kleen @ 2005-11-15  1:05 UTC (permalink / raw)
  To: discuss, george; +Cc: Vojtech Pavlik, Jan Beulich, linux-kernel

On Tuesday 15 November 2005 01:38, George Anzinger wrote:

> Doesn't this depend on the atomic nature of the 64-bit read?  If it is really two 32-bit reads one 
> would need to do extra work to make sure the two parts belong together.

Please take a look at the Subject.

-Andi

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [discuss] Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-15  1:05                                   ` [discuss] " Andi Kleen
@ 2005-11-15  7:50                                     ` Vojtech Pavlik
  2005-11-15  8:24                                       ` Jan Beulich
  0 siblings, 1 reply; 105+ messages in thread
From: Vojtech Pavlik @ 2005-11-15  7:50 UTC (permalink / raw)
  To: Andi Kleen; +Cc: discuss, george, Jan Beulich, linux-kernel

On Tue, Nov 15, 2005 at 02:05:24AM +0100, Andi Kleen wrote:

> On Tuesday 15 November 2005 01:38, George Anzinger wrote:
> 
> > Doesn't this depend on the atomic nature of the 64-bit read?  If it
> > is really two 32-bit reads one would need to do extra work to make
> > sure the two parts belong together.
> 
> Please take a look at the Subject.
 
Still, the HPET doesn't necessarily have to be a 64-bit device. At least
on AMD systems, where it's implemented in AMD8111 Thor, it's bundled
together with other, 32-bit PCI devices like USB. On the other hand, the
8111 HPET doesn't implement a 64-bit conter, and it's likely that the
Intel implementation in the northbridges (or *CH, as Intel prefers
calling the things) is likely native 64-bit.

-- 
Vojtech Pavlik
SuSE Labs, SuSE CR

^ permalink raw reply	[flat|nested] 105+ messages in thread

* Re: [discuss] Re: [PATCH 13/39] NLKD/x86-64 - time adjustment
  2005-11-15  7:50                                     ` Vojtech Pavlik
@ 2005-11-15  8:24                                       ` Jan Beulich
  0 siblings, 0 replies; 105+ messages in thread
From: Jan Beulich @ 2005-11-15  8:24 UTC (permalink / raw)
  To: Vojtech Pavlik, Andi Kleen; +Cc: george, linux-kernel, discuss

>>> Vojtech Pavlik <vojtech@suse.cz> 15.11.05 08:50:26 >>>
>On Tue, Nov 15, 2005 at 02:05:24AM +0100, Andi Kleen wrote:
>
>> On Tuesday 15 November 2005 01:38, George Anzinger wrote:
>> 
>> > Doesn't this depend on the atomic nature of the 64-bit read?  If
it
>> > is really two 32-bit reads one would need to do extra work to
make
>> > sure the two parts belong together.
>> 
>> Please take a look at the Subject.
> 
>Still, the HPET doesn't necessarily have to be a 64-bit device. At
least
>on AMD systems, where it's implemented in AMD8111 Thor, it's bundled
>together with other, 32-bit PCI devices like USB. On the other hand,
the
>8111 HPET doesn't implement a 64-bit conter, and it's likely that the
>Intel implementation in the northbridges (or *CH, as Intel prefers
>calling the things) is likely native 64-bit.

And even then there is no guarantee there isn't something somewhere
converting the 64-bit to pairs of 32-bit accesses. Thus one would in
fact need extra information about the platform to know whether the
entire bus path is 64-bit in order to safely do 64-bit accesses.

However, the changes as I proposed them (and will resubmit hopefully
later today with the adjustments requested by Andi) do intentionally not
do any 64-bit reads, they only use 64-bit writes when resetting counter
or comparator (where all that's needed from the platform is that the
writes to the low 32 bits are done first, which x86 architecturally
guarantees).

Jan

^ permalink raw reply	[flat|nested] 105+ messages in thread

end of thread, other threads:[~2005-11-15  8:23 UTC | newest]

Thread overview: 105+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-11-09 13:54 [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jan Beulich
2005-11-09 13:56 ` [PATCH 1/39] NLKD - an alternative kallsyms approach Jan Beulich
2005-11-09 13:57   ` [PATCH 2/39] NLKD - an alternative early ioremap approach Jan Beulich
2005-11-09 13:58     ` [PATCH 3/39] NLKD - early/late CPU up/down notification Jan Beulich
2005-11-09 13:59       ` [PATCH 4/39] NLKD/i386 " Jan Beulich
2005-11-09 14:01       ` [PATCH 5/39] NLKD/x86-64 " Jan Beulich
2005-11-10 13:10         ` Andi Kleen
2005-11-14  8:04           ` [discuss] " Jan Beulich
2005-11-14 12:37             ` Andi Kleen
2005-11-09 14:01       ` [PATCH 6/39] NLKD - early panic notification Jan Beulich
2005-11-09 14:02         ` [PATCH 7/39] NLKD - task create/destroy notification Jan Beulich
2005-11-09 14:03           ` [PATCH 8/39] NLKD - rmmod notification Jan Beulich
2005-11-09 14:04             ` [PATCH 9/39] NLKD - hotkey notification Jan Beulich
2005-11-09 14:05               ` [PATCH 10/39] NLKD - console layout change notification Jan Beulich
2005-11-09 14:06                 ` [PATCH 11/39] NLKD - time adjustment Jan Beulich
2005-11-09 14:06                   ` [PATCH 12/39] NLKD/i386 " Jan Beulich
2005-11-09 19:10                     ` George Anzinger
2005-11-10  8:12                       ` Jan Beulich
2005-11-11  0:17                         ` George Anzinger
2005-11-09 14:08                   ` [PATCH 13/39] NLKD/x86-64 " Jan Beulich
2005-11-09 14:13                     ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Jan Beulich
2005-11-09 14:14                       ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Jan Beulich
2005-11-09 14:15                         ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Jan Beulich
2005-11-09 14:16                           ` [PATCH 21/39] NLKD/x86-64 - core adjustments Jan Beulich
2005-11-10 13:24                           ` [PATCH 20/39] NLKD/x86-64 - switch_to() floating point adjustment Andi Kleen
2005-11-10 14:07                             ` Jan Beulich
2005-11-10 13:23                         ` [PATCH 19/39] NLKD/x86-64 - stack-pointer-invalid markers Andi Kleen
2005-11-10 14:25                           ` Jan Beulich
2005-11-10 13:21                       ` [PATCH 18/39] NLKD/x86-64 - INT1/INT3 handling changes Andi Kleen
2005-11-10 14:07                         ` Jan Beulich
2005-11-10 14:25                           ` Andi Kleen
2005-11-10 15:00                             ` Jan Beulich
2005-11-11  3:39                               ` [discuss] " Andi Kleen
2005-11-10 13:19                     ` [PATCH 13/39] NLKD/x86-64 - time adjustment Andi Kleen
2005-11-10 14:23                       ` Jan Beulich
2005-11-11  2:12                         ` Andi Kleen
2005-11-12  9:22                           ` Vojtech Pavlik
2005-11-12 17:21                             ` Andi Kleen
2005-11-12 20:44                               ` Vojtech Pavlik
2005-11-15  0:38                                 ` George Anzinger
2005-11-15  1:05                                   ` [discuss] " Andi Kleen
2005-11-15  7:50                                     ` Vojtech Pavlik
2005-11-15  8:24                                       ` Jan Beulich
2005-11-10 14:43                       ` Vojtech Pavlik
2005-11-09 14:09                   ` [PATCH 14/39] NLKD - kernel trace buffer access Jan Beulich
2005-11-09 14:09                     ` [PATCH 15/39] NLKD - early pseudo-fs Jan Beulich
2005-11-09 14:11                       ` [PATCH 16/39] NLKD - core adjustments Jan Beulich
2005-11-09 14:11                         ` [PATCH 17/39] NLKD/i386 " Jan Beulich
2005-11-09 19:00                           ` Adrian Bunk
2005-11-10  8:04                             ` Jan Beulich
2005-11-10 10:29                               ` Adrian Bunk
2005-11-10 11:52                                 ` Jan Beulich
2005-11-10 12:36                                   ` Lars Marowsky-Bree
2005-11-09 14:18                         ` [PATCH 22/39] NLKD - core Jan Beulich
2005-11-09 14:19                           ` [PATCH 23/39] NLKD/x86 " Jan Beulich
2005-11-09 14:20                             ` [PATCH 24/39] NLKD/i386 " Jan Beulich
2005-11-09 14:21                             ` [PATCH 25/39] NLKD/x86-64 " Jan Beulich
2005-11-10 13:30                               ` Andi Kleen
2005-11-09 14:22                           ` [PATCH 26/39] NLKD - run time library Jan Beulich
2005-11-09 14:23                             ` [PATCH 27/39] NLKD/i386 " Jan Beulich
2005-11-09 14:23                               ` [PATCH 28/39] NLKD/x86-64 " Jan Beulich
2005-11-10 13:32                                 ` Andi Kleen
     [not found]                             ` <437214B7.76F0.0078.0@novell.com>
     [not found]                               ` <4372156A.76F0.0078.0@novell.com>
2005-11-09 14:28                                 ` [PATCH 34/39] NLKD/x86 - Console Debug Agent Jan Beulich
     [not found]                                 ` <43721600.76F0.0078.0@novell.com>
2005-11-09 14:30                                   ` [PATCH 38/39] NLKD/i386 - Remote " Jan Beulich
2005-11-09 14:31                                   ` [PATCH 39/39] NLKD/x86-64 " Jan Beulich
2005-11-09 14:29                       ` [PATCH 15/39] NLKD - early pseudo-fs Al Viro
2005-11-09 14:37                         ` Jan Beulich
2005-11-09 15:00                           ` Al Viro
2005-11-09 16:00                             ` Jan Beulich
2005-11-10  5:44                     ` [PATCH 14/39] NLKD - kernel trace buffer access Keith Owens
2005-11-10  8:02                       ` Jan Beulich
2005-11-09 18:51                   ` [PATCH 11/39] NLKD - time adjustment George Anzinger
2005-11-09 16:50         ` [PATCH 6/39] NLKD - early panic notification Greg KH
2005-11-09 16:45       ` [PATCH 3/39] NLKD - early/late CPU up/down notification Greg KH
2005-11-09 17:09         ` Jan Beulich
2005-11-09 17:19           ` Greg KH
2005-11-10  7:41             ` Jan Beulich
2005-11-10 20:59               ` Sam Ravnborg
2005-11-11  7:52                 ` Jan Beulich
2005-11-12 20:52                   ` Randy.Dunlap
2005-11-10 23:01               ` Greg KH
2005-11-11 10:06     ` [PATCH 2/39] NLKD - an alternative early ioremap approach Pavel Machek
2005-11-11 10:19       ` Jan Beulich
2005-11-09 16:50   ` [PATCH 1/39] NLKD - an alternative kallsyms approach Randy.Dunlap
2005-11-09 16:57     ` Greg KH
2005-11-09 17:20     ` Jan Beulich
2005-11-09 16:59 ` [PATCH 0/39] NLKD - Novell Linux Kernel Debugger Jeff Garzik
2005-11-09 17:06   ` Randy.Dunlap
2005-11-09 17:14     ` Jan Beulich
2005-11-09 17:56       ` Alan Cox
2005-11-09 18:05       ` Greg KH
2005-11-09 18:54       ` Paul Jackson
2005-11-10 12:41       ` Christoph Hellwig
2005-11-13  1:09     ` Andi Kleen
2005-11-13  2:53       ` jmerkey
2005-11-13  3:44         ` Andi Kleen
2005-11-13  3:26           ` Jeff V. Merkey
2005-11-13  3:32             ` Jeff V. Merkey
2005-11-09 17:53   ` Alan Cox
2005-11-09 16:25     ` Jeffrey V. Merkey
2005-11-10 14:48     ` Mark Lord
2005-11-10 15:28       ` Tom Rini
2005-11-10 16:37       ` Alan Cox
2005-11-13  1:11       ` Andi Kleen
     [not found] ` <437214E4.76F0.0078.0@novell.com>
     [not found]   ` <4372153C.76F0.0078.0@novell.com>
2005-11-10 13:33     ` [PATCH 32/39] NLKD/x86-64 - Core Debug Engine Andi Kleen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox