Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 197596
b: refs/heads/master
c: 3587d53
h: refs/heads/master
v: v3
  • Loading branch information
Alexander Graf authored and Avi Kivity committed Apr 25, 2010
1 parent 1be4b5e commit df1d3bc
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: b104d06632d08957f384ff7403f609fb5dfb9cbd
refs/heads/master: 3587d5348ced089666c51411bd9d771fb0b072cf
1 change: 1 addition & 0 deletions trunk/arch/powerpc/include/asm/kvm_host.h
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ struct kvm_vcpu_arch {

u8 io_gpr; /* GPR used as IO source/target */
u8 mmio_is_bigendian;
u8 mmio_sign_extend;
u8 dcr_needed;
u8 dcr_is_write;

Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/include/asm/kvm_ppc.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ extern void kvmppc_dump_vcpu(struct kvm_vcpu *vcpu);
extern int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_bigendian);
extern int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes,
int is_bigendian);
extern int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
u64 val, unsigned int bytes, int is_bigendian);

Expand Down
14 changes: 14 additions & 0 deletions trunk/arch/powerpc/kvm/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@
#define OP_STBU 39
#define OP_LHZ 40
#define OP_LHZU 41
#define OP_LHA 42
#define OP_LHAU 43
#define OP_STH 44
#define OP_STHU 45

Expand Down Expand Up @@ -450,6 +452,18 @@ int kvmppc_emulate_instruction(struct kvm_run *run, struct kvm_vcpu *vcpu)
kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
break;

case OP_LHA:
rt = get_rt(inst);
emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
break;

case OP_LHAU:
ra = get_ra(inst);
rt = get_rt(inst);
emulated = kvmppc_handle_loads(run, vcpu, rt, 2, 1);
kvmppc_set_gpr(vcpu, ra, vcpu->arch.paddr_accessed);
break;

case OP_STH:
rs = get_rs(inst);
emulated = kvmppc_handle_store(run, vcpu,
Expand Down
29 changes: 29 additions & 0 deletions trunk/arch/powerpc/kvm/powerpc.c
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,22 @@ static void kvmppc_complete_mmio_load(struct kvm_vcpu *vcpu,
}
}

if (vcpu->arch.mmio_sign_extend) {
switch (run->mmio.len) {
#ifdef CONFIG_PPC64
case 4:
gpr = (s64)(s32)gpr;
break;
#endif
case 2:
gpr = (s64)(s16)gpr;
break;
case 1:
gpr = (s64)(s8)gpr;
break;
}
}

kvmppc_set_gpr(vcpu, vcpu->arch.io_gpr, gpr);

switch (vcpu->arch.io_gpr & KVM_REG_EXT_MASK) {
Expand Down Expand Up @@ -338,10 +354,23 @@ int kvmppc_handle_load(struct kvm_run *run, struct kvm_vcpu *vcpu,
vcpu->arch.mmio_is_bigendian = is_bigendian;
vcpu->mmio_needed = 1;
vcpu->mmio_is_write = 0;
vcpu->arch.mmio_sign_extend = 0;

return EMULATE_DO_MMIO;
}

/* Same as above, but sign extends */
int kvmppc_handle_loads(struct kvm_run *run, struct kvm_vcpu *vcpu,
unsigned int rt, unsigned int bytes, int is_bigendian)
{
int r;

r = kvmppc_handle_load(run, vcpu, rt, bytes, is_bigendian);
vcpu->arch.mmio_sign_extend = 1;

return r;
}

int kvmppc_handle_store(struct kvm_run *run, struct kvm_vcpu *vcpu,
u64 val, unsigned int bytes, int is_bigendian)
{
Expand Down

0 comments on commit df1d3bc

Please sign in to comment.