/* * 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, ®s); 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; }
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; }
// 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; }