Re: [RFC PATCH 6/7] x86/kexec: Debugging support: Dump registers on exception

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 11/5/24 12:38, Woodhouse, David wrote:
On Sun, 2024-11-03 at 05:35 +0000, David Woodhouse wrote:

+
+/* Print the byte in %bl, clobber %rax */
+SYM_CODE_START_LOCAL_NOALIGN(pr_byte)
+       movb    %bl, %al
+       nop
+       andb    $0x0f, %al
+       addb    $0x30, %al
+       cmpb    $0x3a, %al
+       jb      1f
+       addb    $('a' - '0' - 10), %al
+1:     pr_char
+       ANNOTATE_UNRET_SAFE
+       ret
+SYM_CODE_END(pr_byte)
+

Obviously that function name (and comment) are wrong; fixed in my tree.
at
https://git.infradead.org/users/dwmw2/linux.git/shortlog/refs/heads/kexec-debug

This function (and also pr_qword) are also what objtool is complaining
about:

vmlinux.o: warning: objtool: relocate_range+0x2f6: unreachable instruction
vmlinux.o: warning: objtool: relocate_range+0x305: unreachable instruction

I don't quite see why, because pr_qword() quite blatantly calls
pr_nyblle(), as it's now named. And exc_handler() repeatedly calls
pr_qword().

But most of the objtool annotations I've added here were just to make
it shut up and build, without much though. Peter, Josh, any chance you
can help me fix it up please?

It would also be really useful if objtool would let me have data inside
a "code" segment, without complaining that it can't decode it as
instructions — and without also failing to decode the first instruction
of the *subsequent* function. I've put the GDT at the end to work
around that, but it's a bit nasty.


Looking at your code, you have a much bigger problem here:

+/*
+ * This allows other types of serial ports to be used.
+ *  - %al: Character to be printed (no clobber %rax)
+ *  - %rdx: MMIO address or port.
+ */
+.macro pr_char
+       outb    %al, %dx
+.endm
+

This will overflow your UART buffer very quickly since you are now dumping a whole bunch of data. The URT buffer -- if you even have one and it is enabled -- is only 16 bytes in a standard 16550A UART. In older UARTs (or emulated older UARTs) you might not have a buffer at all. To print more than a handful of bytes, you need to poll for the THRE bit=1 (bit 5 of register 5).

What is the point of writing this code in assembly in the first place? A much more logical thing to do is to just push the registers you haven't pushed already onto the stack and call a C function to do the actual dumping? It isn't like it is in any shape, way or form performance critical.

	-hpa


_______________________________________________
kexec mailing list
kexec@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/kexec




[Index of Archives]     [LM Sensors]     [Linux Sound]     [ALSA Users]     [ALSA Devel]     [Linux Audio Users]     [Linux Media]     [Kernel]     [Gimp]     [Yosemite News]     [Linux Media]

  Powered by Linux