All of lore.kernel.org
 help / color / mirror / Atom feed
* arch/arm64/kernel/patch-scs.c:67:29: sparse: sparse: incorrect type in assignment (different base types)
@ 2023-11-24 14:39 kernel test robot
  0 siblings, 0 replies; only message in thread
From: kernel test robot @ 2023-11-24 14:39 UTC (permalink / raw)
  To: Ard Biesheuvel; +Cc: oe-kbuild-all, linux-kernel, Will Deacon, Sami Tolvanen

tree:   https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head:   f1a09972a45ae63efbd1587337c4be13b1893330
commit: 3b619e22c4601b444ed2d6a5458271f72625ac89 arm64: implement dynamic shadow call stack for Clang
date:   1 year ago
config: arm64-randconfig-r133-20231123 (https://download.01.org/0day-ci/archive/20231124/202311241547.VshdwLyK-lkp@intel.com/config)
compiler: clang version 15.0.7 (https://github.com/llvm/llvm-project.git 8dfdcc7b7bf66834a761bd8de445840ef68e4d1a)
reproduce: (https://download.01.org/0day-ci/archive/20231124/202311241547.VshdwLyK-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202311241547.VshdwLyK-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
   arch/arm64/kernel/patch-scs.c:249:24: sparse: sparse: symbol 'scs_patch_vmlinux' was not declared. Should it be static?
>> arch/arm64/kernel/patch-scs.c:67:29: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] @@     got restricted __le32 [usertype] @@
   arch/arm64/kernel/patch-scs.c:67:29: sparse:     expected unsigned int [usertype]
   arch/arm64/kernel/patch-scs.c:67:29: sparse:     got restricted __le32 [usertype]
   arch/arm64/kernel/patch-scs.c:70:29: sparse: sparse: incorrect type in assignment (different base types) @@     expected unsigned int [usertype] @@     got restricted __le32 [usertype] @@
   arch/arm64/kernel/patch-scs.c:70:29: sparse:     expected unsigned int [usertype]
   arch/arm64/kernel/patch-scs.c:70:29: sparse:     got restricted __le32 [usertype]

vim +67 arch/arm64/kernel/patch-scs.c

    60	
    61	static void __always_inline scs_patch_loc(u64 loc)
    62	{
    63		u32 insn = le32_to_cpup((void *)loc);
    64	
    65		switch (insn) {
    66		case PACIASP:
  > 67			*(u32 *)loc = cpu_to_le32(SCS_PUSH);
    68			break;
    69		case AUTIASP:
    70			*(u32 *)loc = cpu_to_le32(SCS_POP);
    71			break;
    72		default:
    73			/*
    74			 * While the DW_CFA_negate_ra_state directive is guaranteed to
    75			 * appear right after a PACIASP/AUTIASP instruction, it may
    76			 * also appear after a DW_CFA_restore_state directive that
    77			 * restores a state that is only partially accurate, and is
    78			 * followed by DW_CFA_negate_ra_state directive to toggle the
    79			 * PAC bit again. So we permit other instructions here, and ignore
    80			 * them.
    81			 */
    82			return;
    83		}
    84		dcache_clean_pou(loc, loc + sizeof(u32));
    85	}
    86	
    87	/*
    88	 * Skip one uleb128/sleb128 encoded quantity from the opcode stream. All bytes
    89	 * except the last one have bit #7 set.
    90	 */
    91	static int __always_inline skip_xleb128(const u8 **opcode, int size)
    92	{
    93		u8 c;
    94	
    95		do {
    96			c = *(*opcode)++;
    97			size--;
    98		} while (c & BIT(7));
    99	
   100		return size;
   101	}
   102	
   103	struct eh_frame {
   104		/*
   105		 * The size of this frame if 0 < size < U32_MAX, 0 terminates the list.
   106		 */
   107		u32	size;
   108	
   109		/*
   110		 * The first frame is a Common Information Entry (CIE) frame, followed
   111		 * by one or more Frame Description Entry (FDE) frames. In the former
   112		 * case, this field is 0, otherwise it is the negated offset relative
   113		 * to the associated CIE frame.
   114		 */
   115		u32	cie_id_or_pointer;
   116	
   117		union {
   118			struct { // CIE
   119				u8	version;
   120				u8	augmentation_string[];
   121			};
   122	
   123			struct { // FDE
   124				s32	initial_loc;
   125				s32	range;
   126				u8	opcodes[];
   127			};
   128		};
   129	};
   130	
   131	static int noinstr scs_handle_fde_frame(const struct eh_frame *frame,
   132						bool fde_has_augmentation_data,
   133						int code_alignment_factor)
   134	{
   135		int size = frame->size - offsetof(struct eh_frame, opcodes) + 4;
   136		u64 loc = (u64)offset_to_ptr(&frame->initial_loc);
   137		const u8 *opcode = frame->opcodes;
   138	
   139		if (fde_has_augmentation_data) {
   140			int l;
   141	
   142			// assume single byte uleb128_t
   143			if (WARN_ON(*opcode & BIT(7)))
   144				return -ENOEXEC;
   145	
   146			l = *opcode++;
   147			opcode += l;
   148			size -= l + 1;
   149		}
   150	
   151		/*
   152		 * Starting from 'loc', apply the CFA opcodes that advance the location
   153		 * pointer, and identify the locations of the PAC instructions.
   154		 */
   155		while (size-- > 0) {
   156			switch (*opcode++) {
   157			case DW_CFA_nop:
   158			case DW_CFA_remember_state:
   159			case DW_CFA_restore_state:
   160				break;
   161	
   162			case DW_CFA_advance_loc1:
   163				loc += *opcode++ * code_alignment_factor;
   164				size--;
   165				break;
   166	
   167			case DW_CFA_advance_loc2:
   168				loc += *opcode++ * code_alignment_factor;
   169				loc += (*opcode++ << 8) * code_alignment_factor;
   170				size -= 2;
   171				break;
   172	
   173			case DW_CFA_def_cfa:
   174			case DW_CFA_offset_extended:
   175				size = skip_xleb128(&opcode, size);
   176				fallthrough;
   177			case DW_CFA_def_cfa_offset:
   178			case DW_CFA_def_cfa_offset_sf:
   179			case DW_CFA_def_cfa_register:
   180			case DW_CFA_same_value:
   181			case DW_CFA_restore_extended:
   182			case 0x80 ... 0xbf:
   183				size = skip_xleb128(&opcode, size);
   184				break;
   185	
   186			case DW_CFA_negate_ra_state:
   187				scs_patch_loc(loc - 4);
   188				break;
   189	
   190			case 0x40 ... 0x7f:
   191				// advance loc
   192				loc += (opcode[-1] & 0x3f) * code_alignment_factor;
   193				break;
   194	
   195			case 0xc0 ... 0xff:
   196				break;
   197	
   198			default:
   199				pr_err("unhandled opcode: %02x in FDE frame %lx\n", opcode[-1], (uintptr_t)frame);
   200				return -ENOEXEC;
   201			}
   202		}
   203		return 0;
   204	}
   205	
   206	int noinstr scs_patch(const u8 eh_frame[], int size)
   207	{
   208		const u8 *p = eh_frame;
   209	
   210		while (size > 4) {
   211			const struct eh_frame *frame = (const void *)p;
   212			bool fde_has_augmentation_data = true;
   213			int code_alignment_factor = 1;
   214			int ret;
   215	
   216			if (frame->size == 0 ||
   217			    frame->size == U32_MAX ||
   218			    frame->size > size)
   219				break;
   220	
   221			if (frame->cie_id_or_pointer == 0) {
   222				const u8 *p = frame->augmentation_string;
   223	
   224				/* a 'z' in the augmentation string must come first */
   225				fde_has_augmentation_data = *p == 'z';
   226	
   227				/*
   228				 * The code alignment factor is a uleb128 encoded field
   229				 * but given that the only sensible values are 1 or 4,
   230				 * there is no point in decoding the whole thing.
   231				 */
   232				p += strlen(p) + 1;
   233				if (!WARN_ON(*p & BIT(7)))
   234					code_alignment_factor = *p;
   235			} else {
   236				ret = scs_handle_fde_frame(frame,
   237							   fde_has_augmentation_data,
   238							   code_alignment_factor);
   239				if (ret)
   240					return ret;
   241			}
   242	
   243			p += sizeof(frame->size) + frame->size;
   244			size -= sizeof(frame->size) + frame->size;
   245		}
   246		return 0;
   247	}
   248	
 > 249	asmlinkage void __init scs_patch_vmlinux(void)

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-11-24 14:40 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-11-24 14:39 arch/arm64/kernel/patch-scs.c:67:29: sparse: sparse: incorrect type in assignment (different base types) kernel test robot

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.