KVM: x86: emulation of dword cmov on long-mode should clear [63:32]
Even if the condition of cmov is not satisfied, bits[63:32] should be cleared. This is clearly stated in Intel's CMOVcc documentation. The solution is to reassign the destination onto itself if the condition is unsatisfied. For that matter the original destination value needs to be read. Signed-off-by: Nadav Amit <namit@cs.technion.ac.il> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
		
					parent
					
						
							
								9e8919ae79
							
						
					
				
			
			
				commit
				
					
						140bad89fd
					
				
			
		
					 1 changed files with 5 additions and 3 deletions
				
			
		| 
						 | 
				
			
			@ -3923,7 +3923,7 @@ static const struct opcode twobyte_table[256] = {
 | 
			
		|||
	N, N,
 | 
			
		||||
	N, N, N, N, N, N, N, N,
 | 
			
		||||
	/* 0x40 - 0x4F */
 | 
			
		||||
	X16(D(DstReg | SrcMem | ModRM | Mov)),
 | 
			
		||||
	X16(D(DstReg | SrcMem | ModRM)),
 | 
			
		||||
	/* 0x50 - 0x5F */
 | 
			
		||||
	N, N, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
 | 
			
		||||
	/* 0x60 - 0x6F */
 | 
			
		||||
| 
						 | 
				
			
			@ -4824,8 +4824,10 @@ twobyte_insn:
 | 
			
		|||
		ops->get_dr(ctxt, ctxt->modrm_reg, &ctxt->dst.val);
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x40 ... 0x4f:	/* cmov */
 | 
			
		||||
		ctxt->dst.val = ctxt->dst.orig_val = ctxt->src.val;
 | 
			
		||||
		if (!test_cc(ctxt->b, ctxt->eflags))
 | 
			
		||||
		if (test_cc(ctxt->b, ctxt->eflags))
 | 
			
		||||
			ctxt->dst.val = ctxt->src.val;
 | 
			
		||||
		else if (ctxt->mode != X86EMUL_MODE_PROT64 ||
 | 
			
		||||
			 ctxt->op_bytes != 4)
 | 
			
		||||
			ctxt->dst.type = OP_NONE; /* no writeback */
 | 
			
		||||
		break;
 | 
			
		||||
	case 0x80 ... 0x8f: /* jnz rel, etc*/
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue