Avi, Are you sure there is a sse-mmio branch? I could not find it anywhere... Wei Xu On 3/27/11 4:57 AM, "Avi Kivity" <avi@xxxxxxxxxx> wrote: > On 03/26/2011 12:12 AM, Wei Xu wrote: >> Jiri& Avi: >> >> I attached the patched I did for movq and movdqa emulation. Please note: >> (1) I only implemented those two. Other instructions like addq may be >> following same way. >> (2) I use same guest_fx_image to hold value and fxsave/fxrstor to copy >> to/from registers. This is not very efficient I admit. >> Any suggestions let me know. >> > > Patch is severely whitespace damaged. Please observe the kernel > whitespace style. > > I just remembered that I implemented this once - see the (very old) > branch sse-mmio in kvm.git. > > >> Index: linux/contents/arch/x86/include/asm/kvm_emulate.h >> =================================================================== >> --- linux.orig/contents/arch/x86/include/asm/kvm_emulate.h 2010-07-19 >> 06:42:26.000000000 -0700 >> +++ linux/contents/arch/x86/include/asm/kvm_emulate.h 2011-03-21 >> 09:16:39.000000000 -0700 >> @@ -116,6 +116,7 @@ >> enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type; >> unsigned int bytes; >> unsigned long val, orig_val, *ptr; >> + unsigned long val_simd[2]; >> }; > > Breaks on i386 (ulong is 32-bit). > >> >> if (c->src.type == OP_MEM) { >> + void *val; >> c->src.ptr = (unsigned long *)memop; >> c->src.val = 0; >> + if (c->src.bytes> 8) { /* movdq case */ >> + c->src.val_simd[0] = c->src.val_simd[1] = 0; >> + val = c->src.val_simd; >> + } else { >> + val =&c->src.val; >> + } > > We have a union there for that purpose. > >> @@ -2506,6 +2529,55 @@ >> if (!test_cc(c->b, ctxt->eflags)) >> c->dst.type = OP_NONE; /* no writeback */ >> break; >> + case 0x6f: /* movq from mm/m64 to mm; movdqa from xmm/m128 to xmm */ >> + if (c->op_bytes == 8){ >> + ctxt->vcpu->arch.guest_fx_image.st_space[c->modrm_reg<<2] = >> + (c->src.val& 0x0ffffffff); >> + ctxt->vcpu->arch.guest_fx_image.st_space[(c->modrm_reg<<2)+1] = >> + (c->src.val>> 32); >> + kvm_fx_restore(&ctxt->vcpu->arch.guest_fx_image); >> + c->dst.type = OP_NONE; /* Disable writeback. */ >> + break; >> + } else { /* movdqa */ >> + ctxt->vcpu->arch.guest_fx_image.xmm_space[c->modrm_reg<<2] = >> + (c->src.val_simd[0]& 0x0ffffffff); >> + ctxt->vcpu->arch.guest_fx_image.xmm_space[(c->modrm_reg<<2)+1] = >> + (c->src.val_simd[0]>> 32); >> + ctxt->vcpu->arch.guest_fx_image.xmm_space[(c->modrm_reg<<2)+2] = >> + (c->src.val_simd[1]& 0x0ffffffff); >> + ctxt->vcpu->arch.guest_fx_image.xmm_space[(c->modrm_reg<<2)+3] = >> + (c->src.val_simd[1]>> 32); >> + kvm_fx_restore(&ctxt->vcpu->arch.guest_fx_image); >> + c->dst.type = OP_NONE; /* Disable writeback. */ >> + break; >> + } >> + case 0x7f: /* movq from mm to mm/m64; movdqa from xmm to xmm/m128 */ >> + if (c->op_bytes == 8) { /* movq */ >> + kvm_fx_save(&ctxt->vcpu->arch.guest_fx_image); >> + if (c->dst.type == OP_MEM) { >> + unsigned long lval,uval; >> + lval = >> ctxt->vcpu->arch.guest_fx_image.st_space[c->modrm_reg<<2]; >> + uval = >> ctxt->vcpu->arch.guest_fx_image.st_space[(c->modrm_reg<<2)+1]; >> + c->dst.val = (uval<<32) + lval; >> + } else { >> + c->dst.type = OP_NONE; /* Disable writeback. */ >> + } >> + break; >> + } else { /* movdqa */ >> + kvm_fx_save(&ctxt->vcpu->arch.guest_fx_image); >> + if (c->dst.type == OP_MEM) { >> + unsigned long lval,uval; >> + lval = >> ctxt->vcpu->arch.guest_fx_image.xmm_space[c->modrm_reg<<2]; >> + uval = >> ctxt->vcpu->arch.guest_fx_image.xmm_space[(c->modrm_reg<<2)+1]; >> + c->dst.val_simd[0] = (uval<<32) + lval; >> + lval = >> ctxt->vcpu->arch.guest_fx_image.xmm_space[(c->modrm_reg<<2)+2]; >> + uval = >> ctxt->vcpu->arch.guest_fx_image.xmm_space[(c->modrm_reg<<2)+3]; >> + c->dst.val_simd[1] = (uval<<32) + lval; >> + } else { >> + c->dst.type = OP_NONE; /* Disable writeback. */ >> + } >> + break; >> + } > > In my implementation, I just forced the guest mmu to be active, and used > the sse instructions directly. >> Index: linux/contents/include/linux/kvm.h >> =================================================================== >> --- linux.orig/contents/include/linux/kvm.h 2010-07-19 06:42:23.000000000 >> -0700 >> +++ linux/contents/include/linux/kvm.h 2011-03-21 09:16:39.000000000 -0700 >> @@ -152,7 +152,7 @@ >> /* KVM_EXIT_MMIO */ >> struct { >> __u64 phys_addr; >> - __u8 data[8]; >> + __u8 data[16]; >> __u32 len; >> __u8 is_write; >> } mmio; > > This breaks the userspace interface. My implementation split the I/O > into two separate 64-bit writes. > > I guess I'll have to rebase it. -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html