aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kernel/ptrace.c')
-rw-r--r--arch/x86/kernel/ptrace.c169
1 files changed, 85 insertions, 84 deletions
diff --git a/arch/x86/kernel/ptrace.c b/arch/x86/kernel/ptrace.c
index d5904eef1d3..eb92ccbb350 100644
--- a/arch/x86/kernel/ptrace.c
+++ b/arch/x86/kernel/ptrace.c
@@ -600,21 +600,6 @@ static int ptrace_bts_read_record(struct task_struct *child,
600 return sizeof(ret); 600 return sizeof(ret);
601} 601}
602 602
603static int ptrace_bts_write_record(struct task_struct *child,
604 const struct bts_struct *in)
605{
606 int retval;
607
608 if (!child->thread.ds_area_msr)
609 return -ENXIO;
610
611 retval = ds_write_bts((void *)child->thread.ds_area_msr, in);
612 if (retval)
613 return retval;
614
615 return sizeof(*in);
616}
617
618static int ptrace_bts_clear(struct task_struct *child) 603static int ptrace_bts_clear(struct task_struct *child)
619{ 604{
620 if (!child->thread.ds_area_msr) 605 if (!child->thread.ds_area_msr)
@@ -657,75 +642,6 @@ static int ptrace_bts_drain(struct task_struct *child,
657 return end; 642 return end;
658} 643}
659 644
660static int ptrace_bts_realloc(struct task_struct *child,
661 int size, int reduce_size)
662{
663 unsigned long rlim, vm;
664 int ret, old_size;
665
666 if (size < 0)
667 return -EINVAL;
668
669 old_size = ds_get_bts_size((void *)child->thread.ds_area_msr);
670 if (old_size < 0)
671 return old_size;
672
673 ret = ds_free((void **)&child->thread.ds_area_msr);
674 if (ret < 0)
675 goto out;
676
677 size >>= PAGE_SHIFT;
678 old_size >>= PAGE_SHIFT;
679
680 current->mm->total_vm -= old_size;
681 current->mm->locked_vm -= old_size;
682
683 if (size == 0)
684 goto out;
685
686 rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
687 vm = current->mm->total_vm + size;
688 if (rlim < vm) {
689 ret = -ENOMEM;
690
691 if (!reduce_size)
692 goto out;
693
694 size = rlim - current->mm->total_vm;
695 if (size <= 0)
696 goto out;
697 }
698
699 rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
700 vm = current->mm->locked_vm + size;
701 if (rlim < vm) {
702 ret = -ENOMEM;
703
704 if (!reduce_size)
705 goto out;
706
707 size = rlim - current->mm->locked_vm;
708 if (size <= 0)
709 goto out;
710 }
711
712 ret = ds_allocate((void **)&child->thread.ds_area_msr,
713 size << PAGE_SHIFT);
714 if (ret < 0)
715 goto out;
716
717 current->mm->total_vm += size;
718 current->mm->locked_vm += size;
719
720out:
721 if (child->thread.ds_area_msr)
722 set_tsk_thread_flag(child, TIF_DS_AREA_MSR);
723 else
724 clear_tsk_thread_flag(child, TIF_DS_AREA_MSR);
725
726 return ret;
727}
728
729static int ptrace_bts_config(struct task_struct *child, 645static int ptrace_bts_config(struct task_struct *child,
730 long cfg_size, 646 long cfg_size,
731 const struct ptrace_bts_config __user *ucfg) 647 const struct ptrace_bts_config __user *ucfg)
@@ -828,6 +744,91 @@ static int ptrace_bts_status(struct task_struct *child,
828 return sizeof(cfg); 744 return sizeof(cfg);
829} 745}
830 746
747
748static int ptrace_bts_write_record(struct task_struct *child,
749 const struct bts_struct *in)
750{
751 int retval;
752
753 if (!child->thread.ds_area_msr)
754 return -ENXIO;
755
756 retval = ds_write_bts((void *)child->thread.ds_area_msr, in);
757 if (retval)
758 return retval;
759
760 return sizeof(*in);
761}
762
763static int ptrace_bts_realloc(struct task_struct *child,
764 int size, int reduce_size)
765{
766 unsigned long rlim, vm;
767 int ret, old_size;
768
769 if (size < 0)
770 return -EINVAL;
771
772 old_size = ds_get_bts_size((void *)child->thread.ds_area_msr);
773 if (old_size < 0)
774 return old_size;
775
776 ret = ds_free((void **)&child->thread.ds_area_msr);
777 if (ret < 0)
778 goto out;
779
780 size >>= PAGE_SHIFT;
781 old_size >>= PAGE_SHIFT;
782
783 current->mm->total_vm -= old_size;
784 current->mm->locked_vm -= old_size;
785
786 if (size == 0)
787 goto out;
788
789 rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
790 vm = current->mm->total_vm + size;
791 if (rlim < vm) {
792 ret = -ENOMEM;
793
794 if (!reduce_size)
795 goto out;
796
797 size = rlim - current->mm->total_vm;
798 if (size <= 0)
799 goto out;
800 }
801
802 rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
803 vm = current->mm->locked_vm + size;
804 if (rlim < vm) {
805 ret = -ENOMEM;
806
807 if (!reduce_size)
808 goto out;
809
810 size = rlim - current->mm->locked_vm;
811 if (size <= 0)
812 goto out;
813 }
814
815 ret = ds_allocate((void **)&child->thread.ds_area_msr,
816 size << PAGE_SHIFT);
817 if (ret < 0)
818 goto out;
819
820 current->mm->total_vm += size;
821 current->mm->locked_vm += size;
822
823out:
824 if (child->thread.ds_area_msr)
825 set_tsk_thread_flag(child, TIF_DS_AREA_MSR);
826 else
827 clear_tsk_thread_flag(child, TIF_DS_AREA_MSR);
828
829 return ret;
830}
831
831void ptrace_bts_take_timestamp(struct task_struct *tsk, 832void ptrace_bts_take_timestamp(struct task_struct *tsk,
832 enum bts_qualifier qualifier) 833 enum bts_qualifier qualifier)
833{ 834{