* 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.