diff options
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux/ioctl_tsg.c')
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/ioctl_tsg.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c index f7d20f34..6c68ca58 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_tsg.c | |||
@@ -536,6 +536,57 @@ static int gk20a_tsg_ioctl_get_timeslice(struct gk20a *g, | |||
536 | return 0; | 536 | return 0; |
537 | } | 537 | } |
538 | 538 | ||
539 | static int gk20a_tsg_ioctl_read_single_sm_error_state(struct gk20a *g, | ||
540 | struct tsg_gk20a *tsg, | ||
541 | struct nvgpu_tsg_read_single_sm_error_state_args *args) | ||
542 | { | ||
543 | struct gr_gk20a *gr = &g->gr; | ||
544 | struct nvgpu_tsg_sm_error_state *sm_error_state; | ||
545 | struct nvgpu_tsg_sm_error_state_record sm_error_state_record; | ||
546 | u32 sm_id; | ||
547 | int err = 0; | ||
548 | |||
549 | sm_id = args->sm_id; | ||
550 | if (sm_id >= gr->no_of_sm) | ||
551 | return -EINVAL; | ||
552 | |||
553 | nvgpu_speculation_barrier(); | ||
554 | |||
555 | sm_error_state = tsg->sm_error_states + sm_id; | ||
556 | sm_error_state_record.global_esr = | ||
557 | sm_error_state->hww_global_esr; | ||
558 | sm_error_state_record.warp_esr = | ||
559 | sm_error_state->hww_warp_esr; | ||
560 | sm_error_state_record.warp_esr_pc = | ||
561 | sm_error_state->hww_warp_esr_pc; | ||
562 | sm_error_state_record.global_esr_report_mask = | ||
563 | sm_error_state->hww_global_esr_report_mask; | ||
564 | sm_error_state_record.warp_esr_report_mask = | ||
565 | sm_error_state->hww_warp_esr_report_mask; | ||
566 | |||
567 | if (args->record_size > 0) { | ||
568 | size_t write_size = sizeof(*sm_error_state); | ||
569 | |||
570 | if (write_size > args->record_size) | ||
571 | write_size = args->record_size; | ||
572 | |||
573 | nvgpu_mutex_acquire(&g->dbg_sessions_lock); | ||
574 | err = copy_to_user((void __user *)(uintptr_t) | ||
575 | args->record_mem, | ||
576 | &sm_error_state_record, | ||
577 | write_size); | ||
578 | nvgpu_mutex_release(&g->dbg_sessions_lock); | ||
579 | if (err) { | ||
580 | nvgpu_err(g, "copy_to_user failed!"); | ||
581 | return err; | ||
582 | } | ||
583 | |||
584 | args->record_size = write_size; | ||
585 | } | ||
586 | |||
587 | return 0; | ||
588 | } | ||
589 | |||
539 | long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, | 590 | long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, |
540 | unsigned long arg) | 591 | unsigned long arg) |
541 | { | 592 | { |
@@ -670,6 +721,13 @@ long nvgpu_ioctl_tsg_dev_ioctl(struct file *filp, unsigned int cmd, | |||
670 | break; | 721 | break; |
671 | } | 722 | } |
672 | 723 | ||
724 | case NVGPU_TSG_IOCTL_READ_SINGLE_SM_ERROR_STATE: | ||
725 | { | ||
726 | err = gk20a_tsg_ioctl_read_single_sm_error_state(g, tsg, | ||
727 | (struct nvgpu_tsg_read_single_sm_error_state_args *)buf); | ||
728 | break; | ||
729 | } | ||
730 | |||
673 | default: | 731 | default: |
674 | nvgpu_err(g, "unrecognized tsg gpu ioctl cmd: 0x%x", | 732 | nvgpu_err(g, "unrecognized tsg gpu ioctl cmd: 0x%x", |
675 | cmd); | 733 | cmd); |