in kvm/emulate.c [1511:1652]
enum emulation_result kvm_mips_complete_mmio_load(struct kvm_vcpu *vcpu)
{
struct kvm_run *run = vcpu->run;
unsigned long *gpr = &vcpu->arch.gprs[vcpu->arch.io_gpr];
enum emulation_result er = EMULATE_DONE;
if (run->mmio.len > sizeof(*gpr)) {
kvm_err("Bad MMIO length: %d", run->mmio.len);
er = EMULATE_FAIL;
goto done;
}
/* Restore saved resume PC */
vcpu->arch.pc = vcpu->arch.io_pc;
switch (run->mmio.len) {
case 8:
switch (vcpu->mmio_needed) {
case 11:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffffff) |
(((*(s64 *)run->mmio.data) & 0xff) << 56);
break;
case 12:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffff) |
(((*(s64 *)run->mmio.data) & 0xffff) << 48);
break;
case 13:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffff) |
(((*(s64 *)run->mmio.data) & 0xffffff) << 40);
break;
case 14:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffff) |
(((*(s64 *)run->mmio.data) & 0xffffffff) << 32);
break;
case 15:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff) |
(((*(s64 *)run->mmio.data) & 0xffffffffff) << 24);
break;
case 16:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff) |
(((*(s64 *)run->mmio.data) & 0xffffffffffff) << 16);
break;
case 17:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff) |
(((*(s64 *)run->mmio.data) & 0xffffffffffffff) << 8);
break;
case 18:
case 19:
*gpr = *(s64 *)run->mmio.data;
break;
case 20:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff00000000000000) |
((((*(s64 *)run->mmio.data)) >> 8) & 0xffffffffffffff);
break;
case 21:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff000000000000) |
((((*(s64 *)run->mmio.data)) >> 16) & 0xffffffffffff);
break;
case 22:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff0000000000) |
((((*(s64 *)run->mmio.data)) >> 24) & 0xffffffffff);
break;
case 23:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffff00000000) |
((((*(s64 *)run->mmio.data)) >> 32) & 0xffffffff);
break;
case 24:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffff000000) |
((((*(s64 *)run->mmio.data)) >> 40) & 0xffffff);
break;
case 25:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffff0000) |
((((*(s64 *)run->mmio.data)) >> 48) & 0xffff);
break;
case 26:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffffffffffff00) |
((((*(s64 *)run->mmio.data)) >> 56) & 0xff);
break;
default:
*gpr = *(s64 *)run->mmio.data;
}
break;
case 4:
switch (vcpu->mmio_needed) {
case 1:
*gpr = *(u32 *)run->mmio.data;
break;
case 2:
*gpr = *(s32 *)run->mmio.data;
break;
case 3:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff) |
(((*(s32 *)run->mmio.data) & 0xff) << 24);
break;
case 4:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff) |
(((*(s32 *)run->mmio.data) & 0xffff) << 16);
break;
case 5:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff) |
(((*(s32 *)run->mmio.data) & 0xffffff) << 8);
break;
case 6:
case 7:
*gpr = *(s32 *)run->mmio.data;
break;
case 8:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xff000000) |
((((*(s32 *)run->mmio.data)) >> 8) & 0xffffff);
break;
case 9:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffff0000) |
((((*(s32 *)run->mmio.data)) >> 16) & 0xffff);
break;
case 10:
*gpr = (vcpu->arch.gprs[vcpu->arch.io_gpr] & 0xffffff00) |
((((*(s32 *)run->mmio.data)) >> 24) & 0xff);
break;
default:
*gpr = *(s32 *)run->mmio.data;
}
break;
case 2:
if (vcpu->mmio_needed == 1)
*gpr = *(u16 *)run->mmio.data;
else
*gpr = *(s16 *)run->mmio.data;
break;
case 1:
if (vcpu->mmio_needed == 1)
*gpr = *(u8 *)run->mmio.data;
else
*gpr = *(s8 *)run->mmio.data;
break;
}
done:
return er;
}