[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #17 from Uroš Bizjak --- The assembly is just mirroring what tree optimizers prepare: pretmp_94 = __gcov0.prep_compound_page[7]; _179 = pretmp_94 + 1; ivtmp.1725_211 = (unsigned long long) _179; ... [local count: 955630225]: # ivtmp.1725_77 = PHI # ivtmp.1730_178 = PHI p_16 = (struct page *) ivtmp.1730_178; MEM [(union *)p_16 + 12B] = 1024B; MEM[(volatile long unsigned int *)p_16 + 4B] ={v} _95; PROF_edge_counter_46 = (long long int) ivtmp.1725_77; __gcov0.prep_compound_page[7] = PROF_edge_counter_46; ivtmp.1725_69 = ivtmp.1725_77 + 1; ivtmp.1730_168 = ivtmp.1730_178 + 40; if (_19 != ivtmp.1725_69) goto ; [89.00%] else goto ; [11.00%] So, loop variable is initialized to __gcov0.prep_compound_page[7] ???
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #16 from Uroš Bizjak --- addl$1, __gcov0.prep_compound_page+48 adcl$0, __gcov0.prep_compound_page+52 cmpl$1, %ebx jle .L1470 leal1(%edi), %eax movl__gcov0.prep_compound_page+60, %edx <- load %eax/%edx from $ movl%eax, -24(%ebp) movl__gcov0.prep_compound_page+56, %eax leal40(%edi), %ecx movl%edi, -32(%ebp) addl$1, %eax <- add $1 to %eax/%edx movl%eax, -20(%ebp) <- save to stack frame loc 20 adcl$0, %edx movl__gcov0.prep_compound_page+56, %eax <- load again %eax/%edx from $ movl%edx, -16(%ebp) movl__gcov0.prep_compound_page+60, %edx subl$2, %ebx <- subtract $2 to %ebx, zext to %ebx/%esi xorl%esi, %esi addl$2, %eax <- add $2 to %eax/%edx adcl$0, %edx addl%eax, %ebx <- move %eax/%edx to %ebx/%esi movl-20(%ebp), %eax <- load %eax/%edx from stack frame loc 20 adcl%edx, %esi movl-16(%ebp), %edx movl%esi, %edi <- move %ebx/%esi to %esi/%edi movl%ebx, %esi
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #15 from Uroš Bizjak --- Sorry, %esi/%edi is the correct order. -24(%ebp): some value previously saved to stack frame %ecx: address to write to %eax/%edx: loop iterator %esi/%edi: termination value .L1469: movl%eax, __gcov0.prep_compound_page+56 movl-24(%ebp), %ebx addl$1, %eax <- increase loop iterator (low word)... movl%edx, __gcov0.prep_compound_page+60 adcl$0, %edx <- ... and high word addl$40, %ecx <- increase address pointer movl$1024, -28(%ecx) <- write to address movl%ebx, -36(%ecx)< movl%edi, %ebx <- loop exit test: %eax/%edx == %esi/%edi xorl%edx, %ebx < movl%ebx, -20(%ebp)< movl%esi, %ebx < xorl%eax, %ebx < orl -20(%ebp), %ebx< jne .L1469 <
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #14 from Uroš Bizjak --- The loop is actually pretty simple, please see the interpretation below -24(%ebp): some value previously saved to stack frame %ecx: address to write to %eax/%edx: loop iterator %edi/%esi: termination value .L1469: movl%eax, __gcov0.prep_compound_page+56 movl-24(%ebp), %ebx addl$1, %eax <- increase loop iterator (low word)... movl%edx, __gcov0.prep_compound_page+60 adcl$0, %edx <- ... and high word addl$40, %ecx <- increase address pointer movl$1024, -28(%ecx) <- write to address movl%ebx, -36(%ecx)< movl%edi, %ebx <- loop exit test: %eax/%edx == %edi/%esi xorl%edx, %ebx < movl%ebx, -20(%ebp)< movl%esi, %ebx < xorl%eax, %ebx < orl -20(%ebp), %ebx< jne .L1469 < So, are loop iterator and termination value correct at the beginning of the loop?
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #13 from Uroš Bizjak --- -fverbose-asm annotated assembly: prep_compound_page: pushl %ebp# movl%esp, %ebp #, pushl %edi# movl%eax, %edi # tmp356, page pushl %esi# pushl %ebx# subl$20, %esp #, cmpl$31, %edx #, order movl%edx, -28(%ebp) # order, %sfp ja .L1483 #, .L1464: movzbl -28(%ebp), %ecx # %sfp, tmp365 movl$1, %ebx#, tmp182 sall%cl, %ebx # tmp365, nr_pages cmpl$-1, (%edi) #, MEM[(const struct page *)page_12(D)].flags je .L1486 #, addl$1, __gcov0.prep_compound_page+16 #, __gcov0.prep_compound_page[2] adcl$0, __gcov0.prep_compound_page+20 #, __gcov0.prep_compound_page[2] #APP # 68 "./arch/x86/include/asm/bitops.h" 1 btsl $16,(%edi) #, MEM[(volatile long int *)_19] # 0 "" 2 #NO_APP addl$1, __gcov0.prep_compound_page+48 #, __gcov0.prep_compound_page[6] adcl$0, __gcov0.prep_compound_page+52 #, __gcov0.prep_compound_page[6] cmpl$1, %ebx#, nr_pages jle .L1470 #, leal1(%edi), %eax #, _159 movl__gcov0.prep_compound_page+60, %edx # __gcov0.prep_compound_page[7], ivtmp.1714 movl%eax, -24(%ebp) # _159, %sfp movl__gcov0.prep_compound_page+56, %eax # __gcov0.prep_compound_page[7], ivtmp.1714 leal40(%edi), %ecx #, ivtmp.1720 movl%edi, -32(%ebp) # page, %sfp addl$1, %eax#, ivtmp.1714 movl%eax, -20(%ebp) # ivtmp.1714, %sfp adcl$0, %edx#, ivtmp.1714 movl__gcov0.prep_compound_page+56, %eax # __gcov0.prep_compound_page[7], tmp228 movl%edx, -16(%ebp) # ivtmp.1714, %sfp movl__gcov0.prep_compound_page+60, %edx # __gcov0.prep_compound_page[7], subl$2, %ebx#, tmp226 xorl%esi, %esi # addl$2, %eax#, tmp228 adcl$0, %edx#, addl%eax, %ebx # tmp228, tmp227 movl-20(%ebp), %eax # %sfp, ivtmp.1714 adcl%edx, %esi #, movl-16(%ebp), %edx # %sfp, ivtmp.1714 movl%esi, %edi # _45, _45 movl%ebx, %esi # _45, _45 .p2align 4 .p2align 3 .L1469: movl%eax, __gcov0.prep_compound_page+56 # ivtmp.1714, __gcov0.prep_compound_page[7] movl-24(%ebp), %ebx # %sfp, _159 addl$1, %eax#, ivtmp.1714 movl%edx, __gcov0.prep_compound_page+60 # ivtmp.1714, __gcov0.prep_compound_page[7] adcl$0, %edx#, ivtmp.1714 addl$40, %ecx #, ivtmp.1720 movl$1024, -28(%ecx)#, MEM [(union *)p_15 + 12B] movl%ebx, -36(%ecx) # _159, MEM[(volatile long unsigned int *)p_15 + 4B] movl%edi, %ebx # _45, tmp230 xorl%edx, %ebx # ivtmp.1714, tmp230 movl%ebx, -20(%ebp) # tmp230, %sfp movl%esi, %ebx # _45, tmp231 xorl%eax, %ebx # ivtmp.1714, tmp231 orl -20(%ebp), %ebx # %sfp, tmp358 jne .L1469 #, movl-32(%ebp), %edi # %sfp, page .L1470: movb$1, 48(%edi)#, MEM[(struct page *)page_12(D) + 40B].D.13727.D.13705.compound_dtor ...
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #12 from Linus Torvalds --- So it might be worth pointing explicitly to Vlastimil's email at https://lore.kernel.org/all/2b857e20-5e3a-13ec-a0b0-1f69d2d04...@suse.cz/ which has annotated objdump output and seems to point to the actual bug (or at least part of it), which seems to show how the page counting (in register %ebx) is corrupted by the coverage counts (Vlastimil calls the coverage counts "crap" - it's real data, but from an algorithmic standpoint it obviously has no bearing on the output). That would mesh with "on 32-bit x86, the 64-bit coverage counts require a lot more effort, and we have few registers, and something gets confused and uses register %rax for two things". The bug apparently only happens with -O2, and I think has only been reported with gcc-11, which is what the intel test robots happened to use
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 Andrew Pinski changed: What|Removed |Added Ever confirmed|1 |0 Status|WAITING |UNCONFIRMED --- Comment #11 from Andrew Pinski --- The generated IR from the trunk: [local count: 118111600]: PROF_edge_counter_113 = __gcov0.set_compound_page_dtor[1]; PROF_edge_counter_114 = PROF_edge_counter_113 + 1; __gcov0.set_compound_page_dtor[1] = PROF_edge_counter_114; MEM[(struct page *)page_12(D) + 40B].D.14083.D.14061.compound_dtor = 1; PROF_edge_counter_47 = __gcov0.prep_compound_page[8]; PROF_edge_counter_48 = PROF_edge_counter_47 + 1; __gcov0.prep_compound_page[8] = PROF_edge_counter_48; PROF_edge_counter_96 = __gcov0.set_compound_order[0]; PROF_edge_counter_97 = PROF_edge_counter_96 + 1; __gcov0.set_compound_order[0] = PROF_edge_counter_97; _98 = (unsigned char) order_8(D); MEM[(struct page *)page_12(D) + 40B].D.14083.D.14061.compound_order = _98; if (order_8(D) > 31) goto ; [0.00%] else goto ; [100.00%] [local count: 105119324]: _176 = (long unsigned int) page_12(D); _95 = _176 + 1; pretmp_94 = __gcov0.prep_compound_page[7]; _179 = pretmp_94 + 1; ivtmp.1725_211 = (unsigned long long) _179; _155 = page_12(D) + 40; ivtmp.1730_157 = (unsigned int) _155; _135 = (unsigned int) nr_pages_11; _134 = _135 + 4294967294; _132 = (unsigned long long) _134; _89 = (unsigned long long) pretmp_94; _76 = _89 + 2; _19 = _76 + _132; [local count: 955630225]: # ivtmp.1725_77 = PHI # ivtmp.1730_178 = PHI p_16 = (struct page *) ivtmp.1730_178; MEM [(union *)p_16 + 12B] = 1024B; MEM[(volatile long unsigned int *)p_16 + 4B] ={v} _95; PROF_edge_counter_46 = (long long int) ivtmp.1725_77; __gcov0.prep_compound_page[7] = PROF_edge_counter_46; ivtmp.1725_69 = ivtmp.1725_77 + 1; ivtmp.1730_168 = ivtmp.1730_178 + 40; if (_19 != ivtmp.1725_69) goto ; [89.00%] else goto ; [11.00%]
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #10 from Tang, Feng --- Created attachment 54352 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54352=edit page_alloc.i.xz
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #9 from Tang, Feng --- For original report https://lore.kernel.org/lkml/202301170941.49728982-oliver.s...@intel.com/t/, it was reported by Sang Oliver from 0Day team, but I failed to add him too cc (probably due to he is not registered in this bugzilla system?), so I will try to gather some info (some from Oliver's report, some from my local system when it can't be found from Oliver's report) gcc version: gcc-11 (Debian 11.3.0-8) 11.3.0 gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0 Platform: QEMU Preprocessing file: page_alloc.i (attached) gcc options: from page_alloc.s(got from 'make ARCH=i386 mm/page_alloc.s') # GNU C89 (Ubuntu 11.3.0-1ubuntu1~22.04) version 11.3.0 (x86_64-linux-gnu) # compiled by GNU C version 11.3.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP # GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 # options passed: -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -m32 -msoft-float -mregparm=3 -mpreferred-stack-boundary=2 -march=i686 -mstack-protector-guard-reg=fs -msta ck-protector-guard-symbol=__stack_chk_guard -mindirect-branch=thunk-extern -mindirect-branch-register -O2 -std=gnu90 -fno-strict-aliasing -fno-common -fshort-wchar -fcf-prot ection=none -freg-struct-return -fno-pic -ffreestanding -fno-asynchronous-unwind-tables -fno-jump-tables -fno-delete-null-pointer-checks -fno-allow-store-data-races -fno-reo rder-blocks -fno-ipa-cp-clone -fno-partial-inlining -fstack-protector-strong -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-stack-clash-protection -fno-inline-func tions-called-once -fno-strict-overflow -fstack-check=no -fconserve-stack -fprofile-arcs -ftest-coverage -fno-tree-loop-im -fsanitize=bounds -fsanitize=shift -fsanitize=unrea chable
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #8 from Tang, Feng --- Created attachment 54350 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54350=edit i386 kernel config In https://lore.kernel.org/lkml/202301170941.49728982-oliver.s...@intel.com/t/ Oliver Sang provided a reproduce: To reproduce: # build kernel cd linux cp config-5.13.0-00219-g7118fc2906e2 .config make HOSTCC=gcc-11 CC=gcc-11 ARCH=i386 olddefconfig prepare modules_prepare bzImage modules make HOSTCC=gcc-11 CC=gcc-11 ARCH=i386 INSTALL_MOD_PATH= modules_install cd find lib/ | cpio -o -H newc --quiet | gzip > modules.cgz git clone https://github.com/intel/lkp-tests.git cd lkp-tests bin/lkp qemu -k -m modules.cgz job-script # job-script is attached in this email # if come across any failure that blocks the test, # please remove ~/.lkp and /lkp dir to run from a clean state.
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #7 from Tang, Feng --- Created attachment 54349 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54349=edit original job-script from Oliver (0Day)
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 Tang, Feng changed: What|Removed |Added Attachment #54345|0 |1 is obsolete|| --- Comment #6 from Tang, Feng --- Created attachment 54348 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=54348=edit objdump of prep_compound_page()
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #5 from Andrew Pinski --- Everything we needed is listed at https://gcc.gnu.org/bugs/
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 --- Comment #4 from Tang, Feng --- (In reply to Andrew Pinski from comment #3) > Do you have the preprocessed source that is used generate the bad object > file? > How about the exact command line? Thanks for the prompt response! The error was originally reported by 0Day (which is a kernel automation test robot), and I can locally reproduce it with a little difference. Sorry for my poor knowledge of gcc, do you want me to give the output of " make ARCH=i386 mm/page_alloc.s"? or you can give me to command to generate it. thanks
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 Andrew Pinski changed: What|Removed |Added Ever confirmed|0 |1 Last reconfirmed||2023-01-26 Status|UNCONFIRMED |WAITING --- Comment #3 from Andrew Pinski --- Do you have the preprocessed source that is used generate the bad object file? How about the exact command line?
[Bug target/108552] Linux i386 kernel 5.14 memory corruption for pre_compound_page() when gcov is enabled
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108552 Andrew Pinski changed: What|Removed |Added Component|c |target --- Comment #2 from Andrew Pinski --- This could be a bug in mcount that the kernel provides.