Exemplo n.º 1
0
/*
 * Restore the VM state from the global _XTIER_inject struct.
 */
void restoreVMState(struct kvm_vcpu *vcpu)
{
	int ret = 0;
	u64 phys_stack = 0;
	struct x86_exception error;
	struct kvm_regs regs;

	// Get actual regiszer state.
	kvm_arch_vcpu_ioctl_get_regs(vcpu, &regs);

	if(_XTIER_inject.event_based && !_XTIER_inject.injection_fault)
	{
		// In case of event-based injection we will not restore RAX
		_XTIER_inject.regs.rax = regs.rax;

		// Set the returning RIP to the saved EIP on the stack
		// Set the returning ESP to the its original value + saved EIP
		phys_stack = vcpu->arch.mmu.gva_to_gpa(vcpu, regs.rsp, 0, &error);

		switch(_XTIER.os)
		{
			case XTIER_OS_UBUNTU_64:
				ret = kvm_read_guest(vcpu->kvm, phys_stack, &_XTIER_inject.regs.rip, 8);
				_XTIER_inject.regs.rsp = regs.rsp + 8;
				break;
			case XTIER_OS_WINDOWS_7_32:
				/* Fall through*/
			case XTIER_OS_UBUNTU_32:
				ret = kvm_write_guest(vcpu->kvm, phys_stack, &_XTIER_inject.regs.rip, 4);
				_XTIER_inject.regs.rsp = regs.rsp + 4;
				break;
			default:
				PRINT_ERROR("OS type is unknown! Cannot restore state!\n");
				return;
		}

		PRINT_DEBUG("EIP will be set to 0x%llx (ESP: 0x%llx, RAX: 0x%llx, FLAGS: 0x%llx)\n", _XTIER_inject.regs.rip,
																				_XTIER_inject.regs.rsp,
																				_XTIER_inject.regs.rax,
																				_XTIER_inject.regs.rflags);
	}

	// Update return value in case userspace wants to use it.
	_XTIER_performance.return_value = regs.rax;

	kvm_arch_vcpu_ioctl_set_regs(vcpu, &(_XTIER_inject.regs));
//	kvm_arch_vcpu_ioctl_set_sregs(vcpu, &(_XTIER_inject.sregs));

	_XTIER_inject.external_function_return_rip = 0;
}
Exemplo n.º 2
0
int kvmppc_ld(struct kvm_vcpu *vcpu, ulong *eaddr, int size, void *ptr,
		      bool data)
{
	ulong mp_pa = vcpu->arch.magic_page_pa & KVM_PAM & PAGE_MASK;
	struct kvmppc_pte pte;
	int rc;

	vcpu->stat.ld++;

	rc = kvmppc_xlate(vcpu, *eaddr, data ? XLATE_DATA : XLATE_INST,
			  XLATE_READ, &pte);
	if (rc)
		return rc;

	*eaddr = pte.raddr;

	if (!pte.may_read)
		return -EPERM;

	if (!data && !pte.may_execute)
		return -ENOEXEC;

	/* Magic page override */
	if (kvmppc_supports_magic_page(vcpu) && mp_pa &&
	    ((pte.raddr & KVM_PAM & PAGE_MASK) == mp_pa) &&
	    !(kvmppc_get_msr(vcpu) & MSR_PR)) {
		void *magic = vcpu->arch.shared;
		magic += pte.eaddr & 0xfff;
		memcpy(ptr, magic, size);
		return EMULATE_DONE;
	}

	if (kvm_read_guest(vcpu->kvm, pte.raddr, ptr, size))
		return EMULATE_DO_MMIO;

	return EMULATE_DONE;
}
Exemplo n.º 3
0
// insert a new job into the tail of the job queue
int crypto_produce_job(struct kvm *kvm, unsigned long vjob_gpa, int vjob_len)
{
	struct vm_job *vjob_hva;
	int ret;
	int hc_ret = 0;
	struct crypto_job *j = NULL;
	char *ibuf = NULL;
	char *obuf = NULL;

	vjob_hva = (struct vm_job *)kmalloc(sizeof(struct vm_job), GFP_KERNEL);
	if(vjob_hva == NULL)
	{
		printk(KERN_ALERT "[CRYPTO] kmalloc allocation of vjob_hva failed\n");
		hc_ret = 1;
		goto out;
	}

	ret = kvm_read_guest(kvm, vjob_gpa, (void *)vjob_hva, vjob_len);
	if(ret != 0)
	{
		printk(KERN_ALERT "[CRYPTO] Failed to read vjob_gpa\n");
		hc_ret = 1;
		goto out;
	}

	ibuf = (char *)kmalloc(vjob_hva->len, GFP_KERNEL);
	obuf = (char *)kmalloc(vjob_hva->len, GFP_KERNEL);
	memset(ibuf, 0, vjob_hva->len);
	memset(obuf, 0, vjob_hva->len);

	ret = kvm_read_guest(kvm, vjob_hva->input_gpa, (void *)ibuf, vjob_hva->len);
	if(ret != 0)
	{
		printk(KERN_ALERT "[CRYPTO] Failed to read input\n");
		hc_ret = 1;
		goto out;
	}

	// alloc and init job
	j = (struct crypto_job *)kmalloc(sizeof(struct crypto_job), GFP_KERNEL);
	j->kvm         = kvm;
	j->job_id      = global_job_id>MAX_JOB_ID?0:global_job_id++;
	j->input       = ibuf;
	j->output      = obuf;
	j->len         = vjob_hva->len;
	j->operation   = vjob_hva->operation;
	j->status      = 0;
	j->next        = NULL;

	//insert new job into queue tail
	mutex_lock(&cq_mutex);

	if(cq.num == 0)  // if job queue is empty
	{
		cq.head = j;
		cq.tail = j;
	}
	else             // if job queue is not empty
	{
		cq.tail->next = j;
		cq.tail = j;
	}
	cq.num++;

	printk(KERN_ALERT "[CRYPTO] Job %d is submitted.\n", j->job_id);
	
	// notify the consumer kthread
	wake_up_interruptible(&cq_wq);

	mutex_unlock(&cq_mutex);

	// wait until the job is processed
	wait_event_interruptible(finish_wq, j->status==1);
	// copy result back to guest VM
	ret = kvm_write_guest(kvm, vjob_hva->output_gpa, (void *)obuf, vjob_hva->len);
	if(ret != 0)
	{
		printk(KERN_ALERT "[CRYPTO] Failed to write the data back\n");
		hc_ret = 1;
		goto out;
	}

out:
	if(vjob_hva)
		kfree(vjob_hva);

	if(ibuf)
		kfree(ibuf);

	if(obuf)
		kfree(obuf);

	if(j)
		kfree(j);

	return hc_ret;
}