Loading drivers/kvm/kvm_main.c +9 −36 Original line number Diff line number Diff line Loading @@ -970,7 +970,7 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn) } static int emulator_read_std(unsigned long addr, unsigned long *val, void *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading Loading @@ -1006,7 +1006,7 @@ static int emulator_read_std(unsigned long addr, } static int emulator_write_std(unsigned long addr, unsigned long val, const void *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading @@ -1016,7 +1016,7 @@ static int emulator_write_std(unsigned long addr, } static int emulator_read_emulated(unsigned long addr, unsigned long *val, void *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading Loading @@ -1044,7 +1044,7 @@ static int emulator_read_emulated(unsigned long addr, } static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned long val, int bytes) const void *val, int bytes) { struct page *page; void *virt; Loading @@ -1057,14 +1057,14 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, kvm_mmu_pre_write(vcpu, gpa, bytes); mark_page_dirty(vcpu->kvm, gpa >> PAGE_SHIFT); virt = kmap_atomic(page, KM_USER0); memcpy(virt + offset_in_page(gpa), &val, bytes); memcpy(virt + offset_in_page(gpa), val, bytes); kunmap_atomic(virt, KM_USER0); kvm_mmu_post_write(vcpu, gpa, bytes); return 1; } static int emulator_write_emulated(unsigned long addr, unsigned long val, const void *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading @@ -1083,14 +1083,14 @@ static int emulator_write_emulated(unsigned long addr, vcpu->mmio_phys_addr = gpa; vcpu->mmio_size = bytes; vcpu->mmio_is_write = 1; memcpy(vcpu->mmio_data, &val, bytes); memcpy(vcpu->mmio_data, val, bytes); return X86EMUL_CONTINUE; } static int emulator_cmpxchg_emulated(unsigned long addr, unsigned long old, unsigned long new, const void *old, const void *new, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading @@ -1103,30 +1103,6 @@ static int emulator_cmpxchg_emulated(unsigned long addr, return emulator_write_emulated(addr, new, bytes, ctxt); } #ifdef CONFIG_X86_32 static int emulator_cmpxchg8b_emulated(unsigned long addr, unsigned long old_lo, unsigned long old_hi, unsigned long new_lo, unsigned long new_hi, struct x86_emulate_ctxt *ctxt) { static int reported; int r; if (!reported) { reported = 1; printk(KERN_WARNING "kvm: emulating exchange8b as write\n"); } r = emulator_write_emulated(addr, new_lo, 4, ctxt); if (r != X86EMUL_CONTINUE) return r; return emulator_write_emulated(addr+4, new_hi, 4, ctxt); } #endif static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) { return kvm_arch_ops->get_segment_base(vcpu, seg); Loading Loading @@ -1201,9 +1177,6 @@ struct x86_emulate_ops emulate_ops = { .read_emulated = emulator_read_emulated, .write_emulated = emulator_write_emulated, .cmpxchg_emulated = emulator_cmpxchg_emulated, #ifdef CONFIG_X86_32 .cmpxchg8b_emulated = emulator_cmpxchg8b_emulated, #endif }; int emulate_instruction(struct kvm_vcpu *vcpu, Loading drivers/kvm/x86_emulate.c +9 −37 Original line number Diff line number Diff line Loading @@ -1045,7 +1045,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) if ((rc = ops->write_std( register_address(ctxt->ss_base, _regs[VCPU_REGS_RSP]), dst.val, dst.bytes, ctxt)) != 0) &dst.val, dst.bytes, ctxt)) != 0) goto done; dst.val = dst.orig_val; /* skanky: disable writeback */ break; Loading Loading @@ -1078,12 +1078,12 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) case OP_MEM: if (lock_prefix) rc = ops->cmpxchg_emulated((unsigned long)dst. ptr, dst.orig_val, dst.val, dst.bytes, ptr, &dst.orig_val, &dst.val, dst.bytes, ctxt); else rc = ops->write_emulated((unsigned long)dst.ptr, dst.val, dst.bytes, &dst.val, dst.bytes, ctxt); if (rc != 0) goto done; Loading Loading @@ -1321,36 +1321,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); break; case 0xc7: /* Grp9 (cmpxchg8b) */ #if defined(__i386__) { unsigned long old_lo, old_hi; if (((rc = ops->read_emulated(cr2 + 0, &old_lo, 4, ctxt)) != 0) || ((rc = ops->read_emulated(cr2 + 4, &old_hi, 4, ctxt)) != 0)) goto done; if ((old_lo != _regs[VCPU_REGS_RAX]) || (old_hi != _regs[VCPU_REGS_RDX])) { _regs[VCPU_REGS_RAX] = old_lo; _regs[VCPU_REGS_RDX] = old_hi; _eflags &= ~EFLG_ZF; } else if (ops->cmpxchg8b_emulated == NULL) { rc = X86EMUL_UNHANDLEABLE; goto done; } else { if ((rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi, _regs[VCPU_REGS_RBX], _regs[VCPU_REGS_RCX], ctxt)) != 0) goto done; _eflags |= EFLG_ZF; } break; } #elif defined(CONFIG_X86_64) { unsigned long old, new; u64 old, new; if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0) goto done; if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || Loading @@ -1359,15 +1331,15 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) _regs[VCPU_REGS_RDX] = (u32) (old >> 32); _eflags &= ~EFLG_ZF; } else { new = (_regs[VCPU_REGS_RCX] << 32) | (u32) _regs[VCPU_REGS_RBX]; if ((rc = ops->cmpxchg_emulated(cr2, old, new, 8, ctxt)) != 0) new = ((u64)_regs[VCPU_REGS_RCX] << 32) | (u32) _regs[VCPU_REGS_RBX]; if ((rc = ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt)) != 0) goto done; _eflags |= EFLG_ZF; } break; } #endif } goto writeback; Loading drivers/kvm/x86_emulate.h +6 −26 Original line number Diff line number Diff line Loading @@ -59,8 +59,7 @@ struct x86_emulate_ops { * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory. */ int (*read_std)(unsigned long addr, unsigned long *val, int (*read_std)(unsigned long addr, void *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); /* Loading @@ -71,8 +70,7 @@ struct x86_emulate_ops { * required). * @bytes: [IN ] Number of bytes to write to memory. */ int (*write_std)(unsigned long addr, unsigned long val, int (*write_std)(unsigned long addr, const void *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); /* Loading @@ -82,7 +80,7 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to read from memory. */ int (*read_emulated) (unsigned long addr, unsigned long *val, void *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); Loading @@ -94,7 +92,7 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to write to memory. */ int (*write_emulated) (unsigned long addr, unsigned long val, const void *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); Loading @@ -107,29 +105,11 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to access using CMPXCHG. */ int (*cmpxchg_emulated) (unsigned long addr, unsigned long old, unsigned long new, const void *old, const void *new, unsigned int bytes, struct x86_emulate_ctxt * ctxt); /* * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an * emulated/special memory area. * @addr: [IN ] Linear address to access. * @old: [IN ] Value expected to be current at @addr. * @new: [IN ] Value to write to @addr. * NOTES: * 1. This function is only ever called when emulating a real CMPXCHG8B. * 2. This function is *never* called on x86/64 systems. * 2. Not defining this function (i.e., specifying NULL) is equivalent * to defining a function that always returns X86EMUL_UNHANDLEABLE. */ int (*cmpxchg8b_emulated) (unsigned long addr, unsigned long old_lo, unsigned long old_hi, unsigned long new_lo, unsigned long new_hi, struct x86_emulate_ctxt * ctxt); }; struct cpu_user_regs; Loading Loading
drivers/kvm/kvm_main.c +9 −36 Original line number Diff line number Diff line Loading @@ -970,7 +970,7 @@ void mark_page_dirty(struct kvm *kvm, gfn_t gfn) } static int emulator_read_std(unsigned long addr, unsigned long *val, void *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading Loading @@ -1006,7 +1006,7 @@ static int emulator_read_std(unsigned long addr, } static int emulator_write_std(unsigned long addr, unsigned long val, const void *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading @@ -1016,7 +1016,7 @@ static int emulator_write_std(unsigned long addr, } static int emulator_read_emulated(unsigned long addr, unsigned long *val, void *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading Loading @@ -1044,7 +1044,7 @@ static int emulator_read_emulated(unsigned long addr, } static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, unsigned long val, int bytes) const void *val, int bytes) { struct page *page; void *virt; Loading @@ -1057,14 +1057,14 @@ static int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa, kvm_mmu_pre_write(vcpu, gpa, bytes); mark_page_dirty(vcpu->kvm, gpa >> PAGE_SHIFT); virt = kmap_atomic(page, KM_USER0); memcpy(virt + offset_in_page(gpa), &val, bytes); memcpy(virt + offset_in_page(gpa), val, bytes); kunmap_atomic(virt, KM_USER0); kvm_mmu_post_write(vcpu, gpa, bytes); return 1; } static int emulator_write_emulated(unsigned long addr, unsigned long val, const void *val, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading @@ -1083,14 +1083,14 @@ static int emulator_write_emulated(unsigned long addr, vcpu->mmio_phys_addr = gpa; vcpu->mmio_size = bytes; vcpu->mmio_is_write = 1; memcpy(vcpu->mmio_data, &val, bytes); memcpy(vcpu->mmio_data, val, bytes); return X86EMUL_CONTINUE; } static int emulator_cmpxchg_emulated(unsigned long addr, unsigned long old, unsigned long new, const void *old, const void *new, unsigned int bytes, struct x86_emulate_ctxt *ctxt) { Loading @@ -1103,30 +1103,6 @@ static int emulator_cmpxchg_emulated(unsigned long addr, return emulator_write_emulated(addr, new, bytes, ctxt); } #ifdef CONFIG_X86_32 static int emulator_cmpxchg8b_emulated(unsigned long addr, unsigned long old_lo, unsigned long old_hi, unsigned long new_lo, unsigned long new_hi, struct x86_emulate_ctxt *ctxt) { static int reported; int r; if (!reported) { reported = 1; printk(KERN_WARNING "kvm: emulating exchange8b as write\n"); } r = emulator_write_emulated(addr, new_lo, 4, ctxt); if (r != X86EMUL_CONTINUE) return r; return emulator_write_emulated(addr+4, new_hi, 4, ctxt); } #endif static unsigned long get_segment_base(struct kvm_vcpu *vcpu, int seg) { return kvm_arch_ops->get_segment_base(vcpu, seg); Loading Loading @@ -1201,9 +1177,6 @@ struct x86_emulate_ops emulate_ops = { .read_emulated = emulator_read_emulated, .write_emulated = emulator_write_emulated, .cmpxchg_emulated = emulator_cmpxchg_emulated, #ifdef CONFIG_X86_32 .cmpxchg8b_emulated = emulator_cmpxchg8b_emulated, #endif }; int emulate_instruction(struct kvm_vcpu *vcpu, Loading
drivers/kvm/x86_emulate.c +9 −37 Original line number Diff line number Diff line Loading @@ -1045,7 +1045,7 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) if ((rc = ops->write_std( register_address(ctxt->ss_base, _regs[VCPU_REGS_RSP]), dst.val, dst.bytes, ctxt)) != 0) &dst.val, dst.bytes, ctxt)) != 0) goto done; dst.val = dst.orig_val; /* skanky: disable writeback */ break; Loading Loading @@ -1078,12 +1078,12 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) case OP_MEM: if (lock_prefix) rc = ops->cmpxchg_emulated((unsigned long)dst. ptr, dst.orig_val, dst.val, dst.bytes, ptr, &dst.orig_val, &dst.val, dst.bytes, ctxt); else rc = ops->write_emulated((unsigned long)dst.ptr, dst.val, dst.bytes, &dst.val, dst.bytes, ctxt); if (rc != 0) goto done; Loading Loading @@ -1321,36 +1321,8 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) realmode_set_cr(ctxt->vcpu, modrm_reg, modrm_val, &_eflags); break; case 0xc7: /* Grp9 (cmpxchg8b) */ #if defined(__i386__) { unsigned long old_lo, old_hi; if (((rc = ops->read_emulated(cr2 + 0, &old_lo, 4, ctxt)) != 0) || ((rc = ops->read_emulated(cr2 + 4, &old_hi, 4, ctxt)) != 0)) goto done; if ((old_lo != _regs[VCPU_REGS_RAX]) || (old_hi != _regs[VCPU_REGS_RDX])) { _regs[VCPU_REGS_RAX] = old_lo; _regs[VCPU_REGS_RDX] = old_hi; _eflags &= ~EFLG_ZF; } else if (ops->cmpxchg8b_emulated == NULL) { rc = X86EMUL_UNHANDLEABLE; goto done; } else { if ((rc = ops->cmpxchg8b_emulated(cr2, old_lo, old_hi, _regs[VCPU_REGS_RBX], _regs[VCPU_REGS_RCX], ctxt)) != 0) goto done; _eflags |= EFLG_ZF; } break; } #elif defined(CONFIG_X86_64) { unsigned long old, new; u64 old, new; if ((rc = ops->read_emulated(cr2, &old, 8, ctxt)) != 0) goto done; if (((u32) (old >> 0) != (u32) _regs[VCPU_REGS_RAX]) || Loading @@ -1359,15 +1331,15 @@ x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) _regs[VCPU_REGS_RDX] = (u32) (old >> 32); _eflags &= ~EFLG_ZF; } else { new = (_regs[VCPU_REGS_RCX] << 32) | (u32) _regs[VCPU_REGS_RBX]; if ((rc = ops->cmpxchg_emulated(cr2, old, new, 8, ctxt)) != 0) new = ((u64)_regs[VCPU_REGS_RCX] << 32) | (u32) _regs[VCPU_REGS_RBX]; if ((rc = ops->cmpxchg_emulated(cr2, &old, &new, 8, ctxt)) != 0) goto done; _eflags |= EFLG_ZF; } break; } #endif } goto writeback; Loading
drivers/kvm/x86_emulate.h +6 −26 Original line number Diff line number Diff line Loading @@ -59,8 +59,7 @@ struct x86_emulate_ops { * @val: [OUT] Value read from memory, zero-extended to 'u_long'. * @bytes: [IN ] Number of bytes to read from memory. */ int (*read_std)(unsigned long addr, unsigned long *val, int (*read_std)(unsigned long addr, void *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); /* Loading @@ -71,8 +70,7 @@ struct x86_emulate_ops { * required). * @bytes: [IN ] Number of bytes to write to memory. */ int (*write_std)(unsigned long addr, unsigned long val, int (*write_std)(unsigned long addr, const void *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); /* Loading @@ -82,7 +80,7 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to read from memory. */ int (*read_emulated) (unsigned long addr, unsigned long *val, void *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); Loading @@ -94,7 +92,7 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to write to memory. */ int (*write_emulated) (unsigned long addr, unsigned long val, const void *val, unsigned int bytes, struct x86_emulate_ctxt * ctxt); Loading @@ -107,29 +105,11 @@ struct x86_emulate_ops { * @bytes: [IN ] Number of bytes to access using CMPXCHG. */ int (*cmpxchg_emulated) (unsigned long addr, unsigned long old, unsigned long new, const void *old, const void *new, unsigned int bytes, struct x86_emulate_ctxt * ctxt); /* * cmpxchg8b_emulated: Emulate an atomic (LOCKed) CMPXCHG8B operation on an * emulated/special memory area. * @addr: [IN ] Linear address to access. * @old: [IN ] Value expected to be current at @addr. * @new: [IN ] Value to write to @addr. * NOTES: * 1. This function is only ever called when emulating a real CMPXCHG8B. * 2. This function is *never* called on x86/64 systems. * 2. Not defining this function (i.e., specifying NULL) is equivalent * to defining a function that always returns X86EMUL_UNHANDLEABLE. */ int (*cmpxchg8b_emulated) (unsigned long addr, unsigned long old_lo, unsigned long old_hi, unsigned long new_lo, unsigned long new_hi, struct x86_emulate_ctxt * ctxt); }; struct cpu_user_regs; Loading