Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 197600
b: refs/heads/master
c: c8c0b6f
h: refs/heads/master
v: v3
  • Loading branch information
Alexander Graf authored and Avi Kivity committed Apr 25, 2010
1 parent 9e7540d commit c7f1ff1
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d6d549b20776c937cb4717b24ef05baec4768f99
refs/heads/master: c8c0b6f2f7db22a340f1311602182a25a2378996
55 changes: 50 additions & 5 deletions trunk/arch/powerpc/kvm/book3s.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
/* #define DEBUG_EXT */

static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
ulong msr);

struct kvm_stats_debugfs_item debugfs_entries[] = {
{ "exits", VCPU_STAT(sum_exits) },
Expand Down Expand Up @@ -629,6 +631,30 @@ static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)
kvmppc_recalc_shadow_msr(vcpu);
}

static int kvmppc_check_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr)
{
ulong srr0 = vcpu->arch.pc;
int ret;

/* Need to do paired single emulation? */
if (!(vcpu->arch.hflags & BOOK3S_HFLAG_PAIRED_SINGLE))
return EMULATE_DONE;

/* Read out the instruction */
ret = kvmppc_ld(vcpu, &srr0, sizeof(u32), &vcpu->arch.last_inst, false);
if (ret == -ENOENT) {
vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 33, 33, 1);
vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 34, 36, 0);
vcpu->arch.msr = kvmppc_set_field(vcpu->arch.msr, 42, 47, 0);
kvmppc_book3s_queue_irqprio(vcpu, BOOK3S_INTERRUPT_INST_STORAGE);
} else if(ret == EMULATE_DONE) {
/* Need to emulate */
return EMULATE_FAIL;
}

return EMULATE_AGAIN;
}

/* Handle external providers (FPU, Altivec, VSX) */
static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,
ulong msr)
Expand Down Expand Up @@ -773,6 +799,7 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
enum emulation_result er;
ulong flags;

program_interrupt:
flags = vcpu->arch.shadow_srr1 & 0x1f0000ull;

if (vcpu->arch.msr & MSR_PR) {
Expand Down Expand Up @@ -816,14 +843,32 @@ int kvmppc_handle_exit(struct kvm_run *run, struct kvm_vcpu *vcpu,
r = RESUME_GUEST;
break;
case BOOK3S_INTERRUPT_FP_UNAVAIL:
r = kvmppc_handle_ext(vcpu, exit_nr, MSR_FP);
break;
case BOOK3S_INTERRUPT_ALTIVEC:
r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VEC);
break;
case BOOK3S_INTERRUPT_VSX:
r = kvmppc_handle_ext(vcpu, exit_nr, MSR_VSX);
{
int ext_msr = 0;

switch (exit_nr) {
case BOOK3S_INTERRUPT_FP_UNAVAIL: ext_msr = MSR_FP; break;
case BOOK3S_INTERRUPT_ALTIVEC: ext_msr = MSR_VEC; break;
case BOOK3S_INTERRUPT_VSX: ext_msr = MSR_VSX; break;
}

switch (kvmppc_check_ext(vcpu, exit_nr)) {
case EMULATE_DONE:
/* everything ok - let's enable the ext */
r = kvmppc_handle_ext(vcpu, exit_nr, ext_msr);
break;
case EMULATE_FAIL:
/* we need to emulate this instruction */
goto program_interrupt;
break;
default:
/* nothing to worry about - go again */
break;
}
break;
}
case BOOK3S_INTERRUPT_MACHINE_CHECK:
case BOOK3S_INTERRUPT_TRACE:
kvmppc_book3s_queue_irqprio(vcpu, exit_nr);
Expand Down

0 comments on commit c7f1ff1

Please sign in to comment.