Skip to content

Commit 9c27ed1

Browse files
mlim19wenlingz
authored andcommitted
profiling: fix the profiling tool crash by page faults
Profiling tools are broken, which cause page faults during collection. The issue happens by enabling SMAP recently. Therefore, we use stac() and clac() to allow access to buffers allocated by guest. Tacked-On: #2157 Signed-off-by: Min Lim <min.yeol.lim@intel.com> Acked-by: Eddie Dong <eddie.dong@intel.com>
1 parent a177d75 commit 9c27ed1

File tree

2 files changed

+15
-9
lines changed

2 files changed

+15
-9
lines changed

hypervisor/debug/profiling.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,14 @@ static int32_t profiling_sbuf_put_variable(struct shared_buf *sbuf,
235235
* 5. return number of bytes of data put in buffer
236236
*/
237237

238+
stac();
238239
if ((sbuf == NULL) || (data == NULL)) {
239-
dev_dbg(ACRN_DBG_PROFILING, "buffer or data not initialized!");
240+
clac();
240241
return -EINVAL;
241242
}
242243

243244
if (size == 0U) {
244-
dev_dbg(ACRN_DBG_PROFILING,
245-
"0 bytes reqeusted to be put in buffer!");
245+
clac();
246246
return 0;
247247
}
248248

@@ -257,19 +257,15 @@ static int32_t profiling_sbuf_put_variable(struct shared_buf *sbuf,
257257
* Since if the next_tail equals head, then it is assumed
258258
* that buffer is empty, not full
259259
*/
260-
dev_dbg(ACRN_DBG_PROFILING,
261-
"Not enough space to write data! Returning without writing");
260+
clac();
262261
return 0;
263262
}
264263

265264
next_tail = sbuf_next_ptr(sbuf->tail, size, sbuf->size);
266-
dev_dbg(ACRN_DBG_PROFILING, "sbuf->tail: %llu, next_tail: %llu",
267-
sbuf->tail, next_tail);
268265

269266
to = (void *)sbuf + SBUF_HEAD_SIZE + sbuf->tail;
270267

271268
if (next_tail < sbuf->tail) { /* wrap-around */
272-
dev_dbg(ACRN_DBG_PROFILING, "wrap-around condition!");
273269
offset = sbuf->size - sbuf->tail;
274270
(void)memcpy_s(to, offset, data, offset);
275271

@@ -281,11 +277,11 @@ static int32_t profiling_sbuf_put_variable(struct shared_buf *sbuf,
281277
data + offset, size - offset);
282278
}
283279
} else {
284-
dev_dbg(ACRN_DBG_PROFILING, "non-wrap-around!");
285280
(void)memcpy_s(to, size, data, size);
286281
}
287282

288283
sbuf->tail = next_tail;
284+
clac();
289285

290286
return (int32_t)size;
291287
}
@@ -306,6 +302,8 @@ static int32_t profiling_generate_data(int32_t collector, uint32_t type)
306302
struct sep_state *ss = &(get_cpu_var(profiling_info.sep_state));
307303
struct sw_msr_op_info *sw_msrop
308304
= &(get_cpu_var(profiling_info.sw_msr_op_info));
305+
uint64_t rflags;
306+
spinlock_t *sw_lock = NULL;
309307

310308
dev_dbg(ACRN_DBG_PROFILING, "%s: entering cpu%d",
311309
__func__, get_cpu_id());
@@ -322,12 +320,14 @@ static int32_t profiling_generate_data(int32_t collector, uint32_t type)
322320
}
323321

324322
if (ss->pmu_state == PMU_RUNNING) {
323+
stac();
325324
if (sbuf->tail >= sbuf->head) {
326325
remaining_space = sbuf->size
327326
- (sbuf->tail - sbuf->head);
328327
} else {
329328
remaining_space = sbuf->head - sbuf->tail;
330329
}
330+
clac();
331331

332332
/* populate the data header */
333333
pkt_header.tsc = rdtsc();
@@ -393,12 +393,16 @@ static int32_t profiling_generate_data(int32_t collector, uint32_t type)
393393
return 0;
394394
}
395395

396+
sw_lock = &(get_cpu_var(profiling_info.sw_lock));
397+
spinlock_irqsave_obtain(sw_lock, &rflags);
398+
stac();
396399
if (sbuf->tail >= sbuf->head) {
397400
remaining_space
398401
= sbuf->size - (sbuf->tail - sbuf->head);
399402
} else {
400403
remaining_space = sbuf->head - sbuf->tail;
401404
}
405+
clac();
402406

403407
/* populate the data header */
404408
pkt_header.tsc = rdtsc();
@@ -448,6 +452,7 @@ static int32_t profiling_generate_data(int32_t collector, uint32_t type)
448452
(void)profiling_sbuf_put_variable((struct shared_buf *)sbuf,
449453
(uint8_t *)payload, (uint32_t)payload_size);
450454

455+
spinlock_irqrestore_release(sw_lock, rflags);
451456
} else {
452457
dev_dbg(ACRN_ERR_PROFILING,
453458
"%s: Unknown collector type", __func__);

hypervisor/include/debug/profiling_internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ struct profiling_info_wrapper {
291291
struct vm_switch_trace vm_switch_trace;
292292
socwatch_state soc_state;
293293
struct sw_msr_op_info sw_msr_op_info;
294+
spinlock_t sw_lock;
294295
} __aligned(8);
295296

296297
int32_t profiling_get_version_info(struct acrn_vm *vm, uint64_t addr);

0 commit comments

Comments
 (0)