* [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(¬ify_mutex);
+ notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod);
+ up(¬ify_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(¬ify_mutex);
+ notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod);
+ up(¬ify_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,÷_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