Example #1
0
static inline unsigned long __remote_syscall(pid_t pid,
	int syscall_no, char *syscall_name,
	int use_ebx, unsigned long ebx,
	int use_ecx, unsigned long ecx,
	int use_edx, unsigned long edx,
	int use_esi, unsigned long esi,
	int use_edi, unsigned long edi)
{
    struct user_regs_struct orig_regs, regs;
    unsigned long ret;
    int status;

    if (!syscall_loc) {
	fprintf(stderr, "No syscall locations found! Cannot do remote syscall.\n");
	abort();
    }

    if (save_registers(pid, &orig_regs) < 0)
	abort();

    memcpy(&regs, &orig_regs, sizeof(regs));

    regs.eax = syscall_no;
    if (use_ebx) regs.ebx = ebx;
    if (use_ecx) regs.ecx = ecx;
    if (use_edx) regs.edx = edx;
    if (use_esi) regs.esi = esi;
    if (use_edi) regs.edi = edi;

    /* Set up registers for ptrace syscall */
    regs.eip = syscall_loc;
    if (restore_registers(pid, &regs) < 0)
	abort();

    /* Execute call */
    if (ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) < 0) {
	perror("ptrace singlestep");
	abort();
    }
    ret = waitpid(pid, &status, 0);
    if (ret == -1) {
	perror("Failed to wait for child");
	abort();
    }

    /* Get our new registers */
    if (save_registers(pid, &regs) < 0)
	abort();

    /* Return everything back to normal */
    if (restore_registers(pid, &orig_regs) < 0)
	abort();

    if (regs.eax < 0) {
	errno = -regs.eax;
	return -1;
    }

    return regs.eax;
}
Example #2
0
void userspace(union uml_pt_regs *regs)
{
	int err, status, op, pid = userspace_pid[0];

	restore_registers(regs);
		
	err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
	if(err)
		panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
		       errno);
	while(1){
		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
		if(err < 0)
			panic("userspace - waitpid failed, errno = %d\n", 
			      errno);

		regs->skas.is_user = 1;
		save_registers(regs);

		if(WIFSTOPPED(status)){
		  	switch(WSTOPSIG(status)){
			case SIGSEGV:
				handle_segv(pid);
				break;
			case SIGTRAP:
			        handle_trap(pid, regs);
				break;
			case SIGIO:
			case SIGVTALRM:
			case SIGILL:
			case SIGBUS:
			case SIGFPE:
			case SIGWINCH:
				user_signal(WSTOPSIG(status), regs);
				break;
			default:
			        printk("userspace - child stopped with signal "
				       "%d\n", WSTOPSIG(status));
			}
			interrupt_end();
		}

		restore_registers(regs);

		op = singlestepping_skas() ? PTRACE_SINGLESTEP : 
			PTRACE_SYSCALL;
		err = ptrace(op, pid, 0, 0);
		if(err)
			panic("userspace - PTRACE_SYSCALL failed, "
			      "errno = %d\n", errno);
	}
}
void vp9_short_idct10_16x16_add_neon(int16_t *input,
                                  uint8_t *dest, int dest_stride) {
  int16_t pass1_output[16*16] = {0};
  int16_t row_idct_output[16*16] = {0};

  // save d8-d15 register values.
  save_registers();

  /* Parallel idct on the upper 8 rows */
  // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the
  // stage 6 result in pass1_output.
  vp9_short_idct10_16x16_add_neon_pass1(input, pass1_output, 8);

  // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines
  // with result in pass1(pass1_output) to calculate final result in stage 7
  // which will be saved into row_idct_output.
  vp9_short_idct10_16x16_add_neon_pass2(input+1,
                                        row_idct_output,
                                        pass1_output,
                                        0,
                                        dest,
                                        dest_stride);

  /* Skip Parallel idct on the lower 8 rows as they are all 0s */

  /* Parallel idct on the left 8 columns */
  // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the
  // stage 6 result in pass1_output.
  vp9_short_idct16x16_add_neon_pass1(row_idct_output, pass1_output, 8);

  // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines
  // with result in pass1(pass1_output) to calculate final result in stage 7.
  // Then add the result to the destination data.
  vp9_short_idct16x16_add_neon_pass2(row_idct_output+1,
                                     row_idct_output,
                                     pass1_output,
                                     1,
                                     dest,
                                     dest_stride);

  /* Parallel idct on the right 8 columns */
  // First pass processes even elements 0, 2, 4, 6, 8, 10, 12, 14 and save the
  // stage 6 result in pass1_output.
  vp9_short_idct16x16_add_neon_pass1(row_idct_output+8*16, pass1_output, 8);

  // Second pass processes odd elements 1, 3, 5, 7, 9, 11, 13, 15 and combines
  // with result in pass1(pass1_output) to calculate final result in stage 7.
  // Then add the result to the destination data.
  vp9_short_idct16x16_add_neon_pass2(row_idct_output+8*16+1,
                                     row_idct_output+8,
                                     pass1_output,
                                     1,
                                     dest+8,
                                     dest_stride);

  // restore d8-d15 register values.
  restore_registers();

  return;
}
Example #4
0
File: kvm.c Project: dmtcp/dmtcp
static void
pre_ckpt()
{
  int r;

  DPRINTF("\n*** Before checkpointing. ***\n");
  if (dummy == 1) {
    r = save_registers();
    if (r < 0) {
      DPRINTF("ERROR: Querying CPU state from the kernel returned: %d\n", r);
      DPRINTF("WARNING: Please try checkpointing again\n");
    }
    r = save_pit2();
    if (r < 0) {
      DPRINTF("ERROR: Querying PIT state from the kernel returned: %d\n", r);
      DPRINTF("WARNING: Please try checkpointing again\n");
    }
    r = save_irqchip();
    if (r < 0) {
      DPRINTF("ERROR: Querying IRQCHIP state from the kernel returned: %d\n",
              r);
      DPRINTF("WARNING: Please try checkpointing again\n");
    }

    // dummy = 2;
  } else if (dummy >= 2) {
    r = restore_registers();
    if (r < 0) {
      DPRINTF("ERROR: Restoring the registers returned: %d\n", r);
      DPRINTF("WARNING: Cannot continue\n");
      exit(-1);
    }
  }
}
Example #5
0
void userspace(union uml_pt_regs *regs)
{
	int err, status, op, pid = userspace_pid[0];
	int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/

	while(1){
		restore_registers(pid, regs);

		/* Now we set local_using_sysemu to be used for one loop */
		local_using_sysemu = get_using_sysemu();

		op = SELECT_PTRACE_OPERATION(local_using_sysemu, singlestepping(NULL));

		err = ptrace(op, pid, 0, 0);
		if(err)
			panic("userspace - could not resume userspace process, "
			      "pid=%d, ptrace operation = %d, errno = %d\n",
			      op, errno);

		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
		if(err < 0)
			panic("userspace - waitpid failed, errno = %d\n", 
			      errno);

		regs->skas.is_user = 1;
		save_registers(pid, regs);
		UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */

		if(WIFSTOPPED(status)){
		  	switch(WSTOPSIG(status)){
			case SIGSEGV:
                                handle_segv(pid, regs);
				break;
			case SIGTRAP + 0x80:
			        handle_trap(pid, regs, local_using_sysemu);
				break;
			case SIGTRAP:
				relay_signal(SIGTRAP, regs);
				break;
			case SIGIO:
			case SIGVTALRM:
			case SIGILL:
			case SIGBUS:
			case SIGFPE:
			case SIGWINCH:
                                user_signal(WSTOPSIG(status), regs, pid);
				break;
			default:
			        printk("userspace - child stopped with signal "
				       "%d\n", WSTOPSIG(status));
			}
			interrupt_end();

			/* Avoid -ERESTARTSYS handling in host */
			PT_SYSCALL_NR(regs->skas.regs) = -1;
		}
	}
}
Example #6
0
void get_process(pid_t pid, int flags, struct list *process_image, long *bin_offset)
{
    int success = 0;
    char* pagebackup;
    struct user_regs_struct r;
    struct cp_chunk *libcgp;

    start_ptrace(pid);

    if (save_registers(pid, &r) < 0) {
	fprintf(stderr, "Unable to save process's registers!\n");
	goto out_ptrace;
    }

    /* The order below is very important. Do not change without good reason and
     * careful thought.
     */
    fetch_chunks_tls(pid, flags, process_image);

    /* this gives us a scribble zone: */
    fetch_chunks_vma(pid, flags, process_image, bin_offset);

    if (!scribble_zone) {
	fprintf(stderr, "[-] No suitable scribble zone could be found. Aborting.\n");
	goto out_ptrace;
    }
    pagebackup = backup_page(pid, (void*)scribble_zone);

    fetch_chunks_fd(pid, flags, process_image);

    fetch_chunks_sighand(pid, flags, process_image);
    fetch_chunks_i387_data(pid, flags, process_image);
    fetch_chunks_regs(pid, flags, process_image, process_was_stopped);

    /* add __getpid chunk to the image list, if requested by the user */
    if ((flags & REFRESH_PID) && fetch_chunk_libcgp(&libcgp) == 0)
        list_append(process_image, libcgp);

    success = 1;

    restore_page(pid, (void*)scribble_zone, pagebackup);
    restore_registers(pid, &r);
out_ptrace:
    end_ptrace(pid, flags);
    
    if (!success)
	abort();
}
Example #7
0
long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
{
	unsigned long *ptr = addr, tmp;
	long ret;
	int pid = task->mm->context.id.u.pid;

	/*
	 * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
	 * be safe), we need to call arch_prctl on the host because
	 * setting %fs may result in something else happening (like a
	 * GDT or thread.fs being set instead).  So, we let the host
	 * fiddle the registers and thread struct and restore the
	 * registers afterwards.
	 *
	 * So, the saved registers are stored to the process (this
	 * needed because a stub may have been the last thing to run),
	 * arch_prctl is run on the host, then the registers are read
	 * back.
	 */
	switch (code) {
	case ARCH_SET_FS:
	case ARCH_SET_GS:
		ret = restore_registers(pid, &current->thread.regs.regs);
		if (ret)
			return ret;
		break;
	case ARCH_GET_FS:
	case ARCH_GET_GS:
		/*
		 * With these two, we read to a local pointer and
		 * put_user it to the userspace pointer that we were
		 * given.  If addr isn't valid (because it hasn't been
		 * faulted in or is just bogus), we want put_user to
		 * fault it in (or return -EFAULT) instead of having
		 * the host return -EFAULT.
		 */
		ptr = &tmp;
	}

	ret = os_arch_prctl(pid, code, ptr);
	if (ret)
		return ret;

	switch (code) {
	case ARCH_SET_FS:
		current->thread.arch.fs = (unsigned long) ptr;
		ret = save_registers(pid, &current->thread.regs.regs);
		break;
	case ARCH_SET_GS:
		ret = save_registers(pid, &current->thread.regs.regs);
		break;
	case ARCH_GET_FS:
		ret = put_user(tmp, addr);
		break;
	case ARCH_GET_GS:
		ret = put_user(tmp, addr);
		break;
	}

	return ret;
}
long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
{
	unsigned long *ptr = addr, tmp;
	long ret;
	int pid = task->mm->context.id.u.pid;

	/*
                                                             
                                                            
                                                              
                                                             
                                                          
                         
   
                                                           
                                                               
                                                              
         
  */
	switch (code) {
	case ARCH_SET_FS:
	case ARCH_SET_GS:
		ret = restore_registers(pid, &current->thread.regs.regs);
		if (ret)
			return ret;
		break;
	case ARCH_GET_FS:
	case ARCH_GET_GS:
		/*
                                                   
                                                      
                                                        
                                                      
                                                      
                             
   */
		ptr = &tmp;
	}

	ret = os_arch_prctl(pid, code, ptr);
	if (ret)
		return ret;

	switch (code) {
	case ARCH_SET_FS:
		current->thread.arch.fs = (unsigned long) ptr;
		ret = save_registers(pid, &current->thread.regs.regs);
		break;
	case ARCH_SET_GS:
		ret = save_registers(pid, &current->thread.regs.regs);
		break;
	case ARCH_GET_FS:
		ret = put_user(tmp, addr);
		break;
	case ARCH_GET_GS:
		ret = put_user(tmp, addr);
		break;
	}

	return ret;
}
Example #9
0
void userspace(union uml_pt_regs *regs)
{
	int err, status, op, pt_syscall_parm, pid = userspace_pid[0];
	int local_using_sysemu; /*To prevent races if using_sysemu changes under us.*/

	restore_registers(regs);
		
	local_using_sysemu = get_using_sysemu();

	pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;
	err = ptrace(pt_syscall_parm, pid, 0, 0);

	if(err)
		panic("userspace - PTRACE_%s failed, errno = %d\n",
		       local_using_sysemu ? "SYSEMU" : "SYSCALL", errno);
	while(1){
		CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
		if(err < 0)
			panic("userspace - waitpid failed, errno = %d\n", 
			      errno);

		regs->skas.is_user = 1;
		save_registers(regs);

		if(WIFSTOPPED(status)){
		  	switch(WSTOPSIG(status)){
			case SIGSEGV:
				handle_segv(pid);
				break;
			case SIGTRAP:
			        handle_trap(pid, regs, local_using_sysemu);
				break;
			case SIGIO:
			case SIGVTALRM:
			case SIGILL:
			case SIGBUS:
			case SIGFPE:
			case SIGWINCH:
				user_signal(WSTOPSIG(status), regs);
				break;
			default:
			        printk("userspace - child stopped with signal "
				       "%d\n", WSTOPSIG(status));
			}
			interrupt_end();
		}

		restore_registers(regs);

		/*Now we ended the syscall, so re-read local_using_sysemu.*/
		local_using_sysemu = get_using_sysemu();
		pt_syscall_parm = local_using_sysemu ? PTRACE_SYSEMU : PTRACE_SYSCALL;

		op = singlestepping(NULL) ? PTRACE_SINGLESTEP :
			pt_syscall_parm;

		err = ptrace(op, pid, 0, 0);
		if(err)
			panic("userspace - PTRACE_%s failed, "
			      "errno = %d\n",
			      local_using_sysemu ? "SYSEMU" : "SYSCALL", errno);
	}
}
Example #10
0
File: kvm.c Project: dmtcp/dmtcp
static void
restart()
{
  int r;

  DPRINTF("Restarting from checkpoint.\n");
  if (g_kvm_fd > 0 && g_vm_fd > 0 && g_vcpu_fd > 0) {
    r = create_vm();
    if (r < 0) {
      DPRINTF("ERROR: Creating VMFD returned: %d\n", r);
      DPRINTF("WARNING: Please try checkpointing again\n");
      exit(-1);
    } else if (r > 0) {
      int i = 0;
      int t = 0;

      r = restore_id_map_addr();
      if (r < 0) {
        DPRINTF("ERROR: Restoring identity map addr returned: %d\n", r);
        DPRINTF("WARNING: Please try checkpointing again\n");
        exit(-1);
      }
      r = restore_tss_addr();
      if (r < 0) {
        DPRINTF("ERROR: Restoring tss addr returned: %d\n", r);
        DPRINTF("WARNING: Please try checkpointing again\n");
        exit(-1);
      }
      r = create_irqchip();
      if (r < 0) {
        DPRINTF("ERROR: Creating IRQCHIP returned: %d\n", r);
        DPRINTF("WARNING: Please try checkpointing again\n");
        exit(-1);
      }

      r = create_vcpu();
      if (r < 0) {
        DPRINTF("ERROR: Creating new VCPU returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      if (NEXT_FNC(mmap)(g_vcpu_mmap_addr, g_vcpu_mmap_length,
                         g_vcpu_mmap_prot, g_vcpu_mmap_flags | MAP_FIXED,
                         g_vcpu_fd, 0) == MAP_FAILED) {
        DPRINTF("ERROR: Mapping the new VCPU returned MAP_FAILED\n");
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }

      r = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_SIGNAL_MASK, &g_kvm_sigmask);
      if (r < 0) {
        DPRINTF("ERROR: Setting VCPU Signal Mask returned: %d\n", r);
        exit(-1);
      }

      r = NEXT_FNC(ioctl)(g_vm_fd, KVM_IRQ_LINE_STATUS, &g_kvm_irq_level);
      if (r < 0) {
        DPRINTF("ERROR: Setting IRQ LINE status returned: %d\n", r);
        exit(-1);
      }

      r = NEXT_FNC(ioctl)(g_vm_fd, KVM_REGISTER_COALESCED_MMIO,
                          &g_kvm_coalesced_mmio_zone);
      if (r < 0) {
        DPRINTF("ERROR: Setting Coalesced MMIO Zone returned: %d\n", r);
        exit(-1);
      }

      DPRINTF("Setting #%d memory regions\n", g_num_of_memory_regions);
      struct kvm_userspace_memory_region *mem;
      for (i = 0; i < g_num_of_memory_regions; i++) {
        mem = &g_kvm_mem_region[i];
        DPRINTF("slot:%X, flags:%X, start:%llX, size:%llX, ram:%llX)\n",
                mem->slot, mem->flags, mem->guest_phys_addr,
                mem->memory_size, mem->userspace_addr);
        r = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_USER_MEMORY_REGION,
                            &g_kvm_mem_region[i]);
        if (r < 0) {
          DPRINTF("ERROR: Creating memory region #%d returned: \n", i, r);
          perror("ioctl(KVM_SET_USER_MEMORY_REGION)");
        }
      }

      /* See note in the ioctl() wrapper. */
      DPRINTF("Setting routing tables. ptr: %p...\n",
              g_kvm_gsi_routing_table);
      r = NEXT_FNC(ioctl)(g_vm_fd, KVM_SET_GSI_ROUTING,
                          g_kvm_gsi_routing_table);
      if (r < 0) {
        DPRINTF("ERROR: Setting routing table (#routes=%d) returned: "
                "%d\n", g_kvm_gsi_routing_table->nr, r);
      }

      r = create_pit2();
      if (r < 0) {
        DPRINTF("Creating PIT2 returned: %d\n", r);
      }
      r = restore_pit2();
      if (r < 0) {
        DPRINTF("ERROR: Restoring PIT2 returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      int array[] = { 0, 1, 4, 8, 12 };
      g_kvm_irq_level.level = 0;
      for (i = 0; i < 5; i++) {
        g_kvm_irq_level.irq = array[i];
        r = NEXT_FNC(ioctl)(g_vm_fd, KVM_IRQ_LINE_STATUS, &g_kvm_irq_level);
        if (r < 0) {
          DPRINTF("ERROR: Resetting IRQ#%d LINE returned: %d\n",
                  g_kvm_irq_level.irq,
                  r);
          exit(-1);
        }
      }
      r = restore_irqchip();
      if (r < 0) {
        DPRINTF("ERROR: Restoring IRQCHIP returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      r = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_TPR_ACCESS_REPORTING,
                          &g_kvm_tpr_access_ctl);
      if (r < 0) {
        DPRINTF("ERROR: Restoring the tpr access reporting returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      r = NEXT_FNC(ioctl)(g_vcpu_fd, KVM_SET_VAPIC_ADDR,
                          &g_kvm_vapic_addr);
      if (r < 0) {
        DPRINTF("ERROR: Restoring the vapic addr returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
      r = restore_registers();
      if (r < 0) {
        DPRINTF("ERROR: Restoring the registers returned: %d\n", r);
        DPRINTF("WARNING: Cannot continue\n");
        exit(-1);
      }
    }
  }
}