Marcus MERIGHI wrote:
> [email protected] (Stefan Kempf), 2016.01.30 (Sat) 10:49 (CET):
> > We need to see how it looks like from within the kernel (and whether
> > the illegal instruction is really raised from within sendsig()). Can you
> > try the diff below?
> 
> > You should get a kernel panic now instead of an illegal instruction
> > signal if you try running ping or top. We need the output of the panic
> > message and the output of the following commands:
> 
> ping(1), top(1) messed up the screen.
> 
> # ping 192.168.188.189                                                  
> PING 192.168.188.189 (192.168.188.189): 56 data bytes
> 64 bytes from 192.168.188.189: icmp_seq=0 ttl=255 time=166.533 ms
> panic: sendsig 1: fxsave 0xffff800032c8a000, sp 0x7f7fff0d20b1,
> fxave_size 512, savefpu_size 832, fpu_save_len 15773951, tf_rsp
> 0x7f7ffffdd238, userstack 1

fpu_save_len is way too large (0xf0b0ff in hex). It should be 832 at
most.  And that causes the kernel to attempt writes outside of the
process stack (and/or to read beyond the saved FPU state).

Either the value we get from CPUID is strange (or we handle CPUID
wrongly), or something trashes fpu_save_len.

Can you try this diff and paste the "cpuid1:" "cpuid2:" lines? Please
revert the previous diff. That will show us what CPUID returns.

Index: arch/amd64/amd64/cpu.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/cpu.c,v
retrieving revision 1.94
diff -u -p -r1.94 cpu.c
--- arch/amd64/amd64/cpu.c      27 Dec 2015 04:31:34 -0000      1.94
+++ arch/amd64/amd64/cpu.c      1 Feb 2016 18:00:02 -0000
@@ -477,6 +477,13 @@ cpu_attach(struct device *parent, struct
  * Initialize the processor appropriately.
  */
 
+__attribute__((noinline)) void
+print_cpuid2(uint32_t ebx)
+{
+       printf("cpuid2: fpu_save_len: 0x%zx, ebx: 0x%x\n",
+           fpu_save_len, ebx);
+}
+
 void
 cpu_init(struct cpu_info *ci)
 {
@@ -510,11 +517,13 @@ cpu_init(struct cpu_info *ci)
 
                xsave_mask = XCR0_X87 | XCR0_SSE;
                CPUID_LEAF(0xd, 0, eax, ebx, ecx, edx);
+               printf("cpuid1: ebx: 0x%x\n", ebx);
                if (eax & XCR0_AVX)
                        xsave_mask |= XCR0_AVX;
                xsetbv(0, xsave_mask);
                CPUID_LEAF(0xd, 0, eax, ebx, ecx, edx);
                fpu_save_len = ebx;
+               print_cpuid2(ebx);
        }
 
 #if NVMM > 0

Reply via email to