tree: git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git new_module_alloc_build_test head: 95a003a975385a74057269799edb08d489f9d26b commit: 95a003a975385a74057269799edb08d489f9d26b [3/3] module: replace module_layout with module_memory config: ia64-allyesconfig compiler: ia64-linux-gcc (GCC) 12.1.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://git.kernel.org/pub/scm/linux/kernel/git/song/md.git/commit/?id=95a003a975385a74057269799edb08d489f9d26b git remote add song-md git://git.kernel.org/pub/scm/linux/kernel/git/song/md.git git fetch --no-tags song-md new_module_alloc_build_test git checkout 95a003a975385a74057269799edb08d489f9d26b # save the config file mkdir build_dir && cp config build_dir/.config COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=ia64 olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=ia64 SHELL=/bin/bash arch/ia64/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot All warnings (new ones prefixed by >>): arch/ia64/kernel/module.c:294:1: warning: no previous prototype for 'plt_target' [-Wmissing-prototypes] 294 | plt_target (struct plt_entry *plt) | ^~~~~~~~~~ arch/ia64/kernel/module.c: In function 'in_init': >> arch/ia64/kernel/module.c:493:17: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] 493 | mod_mem = &mod->mod_mem[MOD_MEM_TYPE_INIT_TEXT]; | ^ arch/ia64/kernel/module.c: In function 'in_core': arch/ia64/kernel/module.c:502:17: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers] 502 | mod_mem = &mod->mod_mem[MOD_MEM_TYPE_TEXT]; | ^ arch/ia64/kernel/module.c: In function 'do_reloc': arch/ia64/kernel/module.c:688:72: error: expected ')' before ';' token 688 | mod->mod_mem[MOD_MEM_TYPE_TEXT].base; | ^ | ) arch/ia64/kernel/module.c:686:35: note: to match this '(' 686 | val -= (uint64_t) (in_init(mod, val) ? | ^ arch/ia64/kernel/module.c:763:33: error: expected ';' before '}' token 763 | return -ENOEXEC; | ^ | ; 764 | } | ~ >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_LTV' not handled in switch [-Wswitch] 635 | switch (formula) { | ^~~~~~ >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_PCREL2' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_SPECIAL' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_RSVD17' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_TPREL' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_LTREL_TPREL' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_DTPMOD' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_LTREL_DTPMOD' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_DTPREL' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_LTREL_DTPREL' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_RSVD24' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_RSVD25' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_RSVD26' not handled in switch [-Wswitch] >> arch/ia64/kernel/module.c:635:9: warning: enumeration value 'RV_RSVD27' not handled in switch [-Wswitch] vim +/const +493 arch/ia64/kernel/module.c 487 488 static inline bool 489 in_init (const struct module *mod, uint64_t addr) 490 { 491 struct module_memory *mod_mem; 492 > 493 mod_mem = &mod->mod_mem[MOD_MEM_TYPE_INIT_TEXT]; 494 return addr - (uint64_t)mod_mem->base < mod_mem->size; 495 } 496 497 static inline bool 498 in_core (const struct module *mod, uint64_t addr) 499 { 500 struct module_memory *mod_mem; 501 502 mod_mem = &mod->mod_mem[MOD_MEM_TYPE_TEXT]; 503 return addr - (uint64_t)mod_mem->base < mod_mem->size; 504 } 505 506 static inline bool 507 is_internal (const struct module *mod, uint64_t value) 508 { 509 return in_init(mod, value) || in_core(mod, value); 510 } 511 512 /* 513 * Get gp-relative offset for the linkage-table entry of VALUE. 514 */ 515 static uint64_t 516 get_ltoff (struct module *mod, uint64_t value, int *okp) 517 { 518 struct got_entry *got, *e; 519 520 if (!*okp) 521 return 0; 522 523 got = (void *) mod->arch.got->sh_addr; 524 for (e = got; e < got + mod->arch.next_got_entry; ++e) 525 if (e->val == value) 526 goto found; 527 528 /* Not enough GOT entries? */ 529 BUG_ON(e >= (struct got_entry *) (mod->arch.got->sh_addr + mod->arch.got->sh_size)); 530 531 e->val = value; 532 ++mod->arch.next_got_entry; 533 found: 534 return (uint64_t) e - mod->arch.gp; 535 } 536 537 static inline int 538 gp_addressable (struct module *mod, uint64_t value) 539 { 540 return value - mod->arch.gp + MAX_LTOFF/2 < MAX_LTOFF; 541 } 542 543 /* Get PC-relative PLT entry for this value. Returns 0 on failure. */ 544 static uint64_t 545 get_plt (struct module *mod, const struct insn *insn, uint64_t value, int *okp) 546 { 547 struct plt_entry *plt, *plt_end; 548 uint64_t target_ip, target_gp; 549 550 if (!*okp) 551 return 0; 552 553 if (in_init(mod, (uint64_t) insn)) { 554 plt = (void *) mod->arch.init_plt->sh_addr; 555 plt_end = (void *) plt + mod->arch.init_plt->sh_size; 556 } else { 557 plt = (void *) mod->arch.core_plt->sh_addr; 558 plt_end = (void *) plt + mod->arch.core_plt->sh_size; 559 } 560 561 /* "value" is a pointer to a function-descriptor; fetch the target ip/gp from it: */ 562 target_ip = ((uint64_t *) value)[0]; 563 target_gp = ((uint64_t *) value)[1]; 564 565 /* Look for existing PLT entry. */ 566 while (plt->bundle[0][0]) { 567 if (plt_target(plt) == target_ip) 568 goto found; 569 if (++plt >= plt_end) 570 BUG(); 571 } 572 *plt = ia64_plt_template; 573 if (!patch_plt(mod, plt, target_ip, target_gp)) { 574 *okp = 0; 575 return 0; 576 } 577 #if ARCH_MODULE_DEBUG 578 if (plt_target(plt) != target_ip) { 579 printk("%s: mistargeted PLT: wanted %lx, got %lx\n", 580 __func__, target_ip, plt_target(plt)); 581 *okp = 0; 582 return 0; 583 } 584 #endif 585 found: 586 return (uint64_t) plt; 587 } 588 589 /* Get function descriptor for VALUE. */ 590 static uint64_t 591 get_fdesc (struct module *mod, uint64_t value, int *okp) 592 { 593 struct fdesc *fdesc = (void *) mod->arch.opd->sh_addr; 594 595 if (!*okp) 596 return 0; 597 598 if (!value) { 599 printk(KERN_ERR "%s: fdesc for zero requested!\n", mod->name); 600 return 0; 601 } 602 603 if (!is_internal(mod, value)) 604 /* 605 * If it's not a module-local entry-point, "value" already points to a 606 * function-descriptor. 607 */ 608 return value; 609 610 /* Look for existing function descriptor. */ 611 while (fdesc->addr) { 612 if (fdesc->addr == value) 613 return (uint64_t)fdesc; 614 if ((uint64_t) ++fdesc >= mod->arch.opd->sh_addr + mod->arch.opd->sh_size) 615 BUG(); 616 } 617 618 /* Create new one */ 619 fdesc->addr = value; 620 fdesc->gp = mod->arch.gp; 621 return (uint64_t) fdesc; 622 } 623 624 static inline int 625 do_reloc (struct module *mod, uint8_t r_type, Elf64_Sym *sym, uint64_t addend, 626 Elf64_Shdr *sec, void *location) 627 { 628 enum reloc_target_format format = (r_type >> FORMAT_SHIFT) & FORMAT_MASK; 629 enum reloc_value_formula formula = (r_type >> VALUE_SHIFT) & VALUE_MASK; 630 uint64_t val; 631 int ok = 1; 632 633 val = sym->st_value + addend; 634 > 635 switch (formula) { 636 case RV_SEGREL: /* segment base is arbitrarily chosen to be 0 for kernel modules */ 637 case RV_DIRECT: 638 break; 639 640 case RV_GPREL: val -= mod->arch.gp; break; 641 case RV_LTREL: val = get_ltoff(mod, val, &ok); break; 642 case RV_PLTREL: val = get_plt(mod, location, val, &ok); break; 643 case RV_FPTR: val = get_fdesc(mod, val, &ok); break; 644 case RV_SECREL: val -= sec->sh_addr; break; 645 case RV_LTREL_FPTR: val = get_ltoff(mod, get_fdesc(mod, val, &ok), &ok); break; 646 647 case RV_PCREL: 648 switch (r_type) { 649 case R_IA64_PCREL21B: 650 if ((in_init(mod, val) && in_core(mod, (uint64_t)location)) || 651 (in_core(mod, val) && in_init(mod, (uint64_t)location))) { 652 /* 653 * Init section may have been allocated far away from core, 654 * if the branch won't reach, then allocate a plt for it. 655 */ 656 uint64_t delta = ((int64_t)val - (int64_t)location) / 16; 657 if (delta + (1 << 20) >= (1 << 21)) { 658 val = get_fdesc(mod, val, &ok); 659 val = get_plt(mod, location, val, &ok); 660 } 661 } else if (!is_internal(mod, val)) 662 val = get_plt(mod, location, val, &ok); 663 fallthrough; 664 default: 665 val -= bundle(location); 666 break; 667 668 case R_IA64_PCREL32MSB: 669 case R_IA64_PCREL32LSB: 670 case R_IA64_PCREL64MSB: 671 case R_IA64_PCREL64LSB: 672 val -= (uint64_t) location; 673 break; 674 675 } 676 switch (r_type) { 677 case R_IA64_PCREL60B: format = RF_INSN60; break; 678 case R_IA64_PCREL21B: format = RF_INSN21B; break; 679 case R_IA64_PCREL21M: format = RF_INSN21M; break; 680 case R_IA64_PCREL21F: format = RF_INSN21F; break; 681 default: break; 682 } 683 break; 684 685 case RV_BDREL: 686 val -= (uint64_t) (in_init(mod, val) ? 687 mod->mod_mem[MOD_MEM_TYPE_INIT_TEXT].base : 688 mod->mod_mem[MOD_MEM_TYPE_TEXT].base; 689 break; 690 691 case RV_LTV: 692 /* can link-time value relocs happen here? */ 693 BUG(); 694 break; 695 696 case RV_PCREL2: 697 if (r_type == R_IA64_PCREL21BI) { 698 if (!is_internal(mod, val)) { 699 printk(KERN_ERR "%s: %s reloc against " 700 "non-local symbol (%lx)\n", __func__, 701 reloc_name[r_type], (unsigned long)val); 702 return -ENOEXEC; 703 } 704 format = RF_INSN21B; 705 } 706 val -= bundle(location); 707 break; 708 709 case RV_SPECIAL: 710 switch (r_type) { 711 case R_IA64_IPLTMSB: 712 case R_IA64_IPLTLSB: 713 val = get_fdesc(mod, get_plt(mod, location, val, &ok), &ok); 714 format = RF_64LSB; 715 if (r_type == R_IA64_IPLTMSB) 716 format = RF_64MSB; 717 break; 718 719 case R_IA64_SUB: 720 val = addend - sym->st_value; 721 format = RF_INSN64; 722 break; 723 724 case R_IA64_LTOFF22X: 725 if (gp_addressable(mod, val)) 726 val -= mod->arch.gp; 727 else 728 val = get_ltoff(mod, val, &ok); 729 format = RF_INSN22; 730 break; 731 732 case R_IA64_LDXMOV: 733 if (gp_addressable(mod, val)) { 734 /* turn "ld8" into "mov": */ 735 DEBUGP("%s: patching ld8 at %p to mov\n", __func__, location); 736 ia64_patch((u64) location, 0x1fff80fe000UL, 0x10000000000UL); 737 } 738 return 0; 739 740 default: 741 if (reloc_name[r_type]) 742 printk(KERN_ERR "%s: special reloc %s not supported", 743 mod->name, reloc_name[r_type]); 744 else 745 printk(KERN_ERR "%s: unknown special reloc %x\n", 746 mod->name, r_type); 747 return -ENOEXEC; 748 } 749 break; 750 751 case RV_TPREL: 752 case RV_LTREL_TPREL: 753 case RV_DTPMOD: 754 case RV_LTREL_DTPMOD: 755 case RV_DTPREL: 756 case RV_LTREL_DTPREL: 757 printk(KERN_ERR "%s: %s reloc not supported\n", 758 mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?"); 759 return -ENOEXEC; 760 761 default: 762 printk(KERN_ERR "%s: unknown reloc %x\n", mod->name, r_type); 763 return -ENOEXEC; 764 } 765 766 if (!ok) 767 return -ENOEXEC; 768 769 DEBUGP("%s: [%p]<-%016lx = %s(%lx)\n", __func__, location, val, 770 reloc_name[r_type] ? reloc_name[r_type] : "?", sym->st_value + addend); 771 772 switch (format) { 773 case RF_INSN21B: ok = apply_imm21b(mod, location, (int64_t) val / 16); break; 774 case RF_INSN22: ok = apply_imm22(mod, location, val); break; 775 case RF_INSN64: ok = apply_imm64(mod, location, val); break; 776 case RF_INSN60: ok = apply_imm60(mod, location, (int64_t) val / 16); break; 777 case RF_32LSB: put_unaligned(val, (uint32_t *) location); break; 778 case RF_64LSB: put_unaligned(val, (uint64_t *) location); break; 779 case RF_32MSB: /* ia64 Linux is little-endian... */ 780 case RF_64MSB: /* ia64 Linux is little-endian... */ 781 case RF_INSN14: /* must be within-module, i.e., resolved by "ld -r" */ 782 case RF_INSN21M: /* must be within-module, i.e., resolved by "ld -r" */ 783 case RF_INSN21F: /* must be within-module, i.e., resolved by "ld -r" */ 784 printk(KERN_ERR "%s: format %u needed by %s reloc is not supported\n", 785 mod->name, format, reloc_name[r_type] ? reloc_name[r_type] : "?"); 786 return -ENOEXEC; 787 788 default: 789 printk(KERN_ERR "%s: relocation %s resulted in unknown format %u\n", 790 mod->name, reloc_name[r_type] ? reloc_name[r_type] : "?", format); 791 return -ENOEXEC; 792 } 793 return ok ? 0 : -ENOEXEC; 794 } 795 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests