diff options
Diffstat (limited to 'arch/powerpc/kvm/emulate.c')
-rw-r--r-- | arch/powerpc/kvm/emulate.c | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/arch/powerpc/kvm/emulate.c b/arch/powerpc/kvm/emulate.c index cb72a65f4ecc..dbb5d6842a51 100644 --- a/arch/powerpc/kvm/emulate.c +++ b/arch/powerpc/kvm/emulate.c | |||
@@ -38,10 +38,12 @@ | |||
38 | #define OP_31_XOP_LBZX 87 | 38 | #define OP_31_XOP_LBZX 87 |
39 | #define OP_31_XOP_STWX 151 | 39 | #define OP_31_XOP_STWX 151 |
40 | #define OP_31_XOP_STBX 215 | 40 | #define OP_31_XOP_STBX 215 |
41 | #define OP_31_XOP_LBZUX 119 | ||
41 | #define OP_31_XOP_STBUX 247 | 42 | #define OP_31_XOP_STBUX 247 |
42 | #define OP_31_XOP_LHZX 279 | 43 | #define OP_31_XOP_LHZX 279 |
43 | #define OP_31_XOP_LHZUX 311 | 44 | #define OP_31_XOP_LHZUX 311 |
44 | #define OP_31_XOP_MFSPR 339 | 45 | #define OP_31_XOP_MFSPR 339 |
46 | #define OP_31_XOP_LHAX 343 | ||
45 | #define OP_31_XOP_STHX 407 | 47 | #define OP_31_XOP_STHX 407 |
46 | #define OP_31_XOP_STHUX 439 | 48 | #define OP_31_XOP_STHUX 439 |
47 | #define OP_31_XOP_MTSPR 467 | 49 | #define OP_31_XOP_MTSPR 467 |
@@ -62,6 +64,8 @@ | |||
62 | #define OP_STBU 39 | 64 | #define OP_STBU 39 |
63 | #define OP_LHZ 40 | 65 | #define OP_LHZ 40 |
64 | #define OP_LHZU 41 | 66 | #define OP_LHZU 41 |
67 | #define OP_LHA 42 | ||
68 | #define OP_LHAU 43 | ||
65 | #define OP_STH 44 | 69 | #define OP_STH 44 |
66 | #define OP_STHU 45 | 70 | #define OP_STHU 45 |
67 | 71 | ||
@@ -171,6 +175,19 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
171 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | 175 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); |
172 | break; | 176 | break; |
173 | 177 | ||
178 | case OP_31_XOP_LBZUX: | ||
179 | rt = get_rt(inst); | ||
180 | ra = get_ra(inst); | ||
181 | rb = get_rb(inst); | ||
182 | |||
183 | ea = kvmppc_get_gpr(vcpu, rb); | ||
184 | if (ra) | ||
185 | ea += kvmppc_get_gpr(vcpu, ra); | ||
186 | |||
187 | emulated = kvmppc_handle_load(run, vcpu, rt, 1, 1); | ||
188 | kvmppc_set_gpr(vcpu, ra, ea); | ||
189 | break; | ||
190 | |||
174 | case OP_31_XOP_STWX: | 191 | case OP_31_XOP_STWX: |
175 | rs = get_rs(inst); | 192 | rs = get_rs(inst); |
176 | emulated = kvmppc_handle_store(run, vcpu, | 193 | emulated = kvmppc_handle_store(run, vcpu, |
@@ -200,6 +217,11 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
200 | kvmppc_set_gpr(vcpu, rs, ea); | 217 | kvmppc_set_gpr(vcpu, rs, ea); |
201 | break; | 218 | break; |
202 | 219 | ||
220 | case OP_31_XOP_LHAX: | ||
221 | rt = get_rt(inst); | ||
222 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
223 | break; | ||
224 | |||
203 | case OP_31_XOP_LHZX: | 225 | case OP_31_XOP_LHZX: |
204 | rt = get_rt(inst); | 226 | rt = get_rt(inst); |
205 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); | 227 | emulated = kvmppc_handle_load(run, vcpu, rt, 2, 1); |
@@ -450,6 +472,18 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
450 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); | 472 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); |
451 | break; | 473 | break; |
452 | 474 | ||
475 | case OP_LHA: | ||
476 | rt = get_rt(inst); | ||
477 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
478 | break; | ||
479 | |||
480 | case OP_LHAU: | ||
481 | ra = get_ra(inst); | ||
482 | rt = get_rt(inst); | ||
483 | emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1); | ||
484 | kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed); | ||
485 | break; | ||
486 | |||
453 | case OP_STH: | 487 | case OP_STH: |
454 | rs = get_rs(inst); | 488 | rs = get_rs(inst); |
455 | emulated = kvmppc_handle_store(run, vcpu, | 489 | emulated = kvmppc_handle_store(run, vcpu, |
@@ -472,7 +506,9 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu) | |||
472 | 506 | ||
473 | if (emulated == EMULATE_FAIL) { | 507 | if (emulated == EMULATE_FAIL) { |
474 | emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance); | 508 | emulated = kvmppc_core_emulate_op(run, vcpu, inst, &advance); |
475 | if (emulated == EMULATE_FAIL) { | 509 | if (emulated == EMULATE_AGAIN) { |
510 | advance = 0; | ||
511 | } else if (emulated == EMULATE_FAIL) { | ||
476 | advance = 0; | 512 | advance = 0; |
477 | printk(KERN_ERR "Couldn't emulate instruction 0x%08x " | 513 | printk(KERN_ERR "Couldn't emulate instruction 0x%08x " |
478 | "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst)); | 514 | "(op %d xop %d)\n", inst, get_op(inst), get_xop(inst)); |