Skip to content

Commit

Permalink
KVM: PPC: Move Shadow MSR calculation to function
Browse files Browse the repository at this point in the history
We keep a copy of the MSR around that we use when we go into the guest context.

That copy is basically the normal process MSR flags OR some allowed guest
specified MSR flags. We also AND the external providers into this, so we get
traps on FPU usage when we haven't activated it on the host yet.

Currently this calculation is part of the set_msr function that we use whenever
we set the guest MSR value. With the external providers, we also have the case
that we don't modify the guest's MSR, but only want to update the shadow MSR.

So let's move the shadow MSR parts to a separate function that we then use
whenever we only need to update it. That way we don't accidently kvm_vcpu_block
within a preempt notifier context.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Avi Kivity <avi@redhat.com>
  • Loading branch information
Alexander Graf authored and Marcelo Tosatti committed Mar 1, 2010
1 parent f7adbba commit a76f849
Showing 1 changed file with 21 additions and 6 deletions.
27 changes: 21 additions & 6 deletions arch/powerpc/kvm/book3s.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,34 @@ static u32 kvmppc_get_dec(struct kvm_vcpu *vcpu)
}
#endif

static void kvmppc_recalc_shadow_msr(struct kvm_vcpu *vcpu)
{
vcpu->arch.shadow_msr = vcpu->arch.msr;
/* Guest MSR values */
vcpu->arch.shadow_msr &= MSR_FE0 | MSR_FE1 | MSR_SF | MSR_SE |
MSR_BE | MSR_DE;
/* Process MSR values */
vcpu->arch.shadow_msr |= MSR_ME | MSR_RI | MSR_IR | MSR_DR | MSR_PR |
MSR_EE;
/* External providers the guest reserved */
vcpu->arch.shadow_msr |= (vcpu->arch.msr & vcpu->arch.guest_owned_ext);
/* 64-bit Process MSR values */
#ifdef CONFIG_PPC_BOOK3S_64
vcpu->arch.shadow_msr |= MSR_ISF | MSR_HV;
#endif
}

void kvmppc_set_msr(struct kvm_vcpu *vcpu, u64 msr)
{
ulong old_msr = vcpu->arch.msr;

#ifdef EXIT_DEBUG
printk(KERN_INFO "KVM: Set MSR to 0x%llx\n", msr);
#endif

msr &= to_book3s(vcpu)->msr_mask;
vcpu->arch.msr = msr;
vcpu->arch.shadow_msr = msr | MSR_USER32;
vcpu->arch.shadow_msr &= (MSR_FE0 | MSR_USER64 | MSR_SE | MSR_BE |
MSR_DE | MSR_FE1);
vcpu->arch.shadow_msr |= (msr & vcpu->arch.guest_owned_ext);
kvmppc_recalc_shadow_msr(vcpu);

if (msr & (MSR_WE|MSR_POW)) {
if (!vcpu->arch.pending_exceptions) {
Expand Down Expand Up @@ -610,7 +625,7 @@ static void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr)

vcpu->arch.guest_owned_ext &= ~msr;
current->thread.regs->msr &= ~msr;
kvmppc_set_msr(vcpu, vcpu->arch.msr);
kvmppc_recalc_shadow_msr(vcpu);
}

/* Handle external providers (FPU, Altivec, VSX) */
Expand Down Expand Up @@ -664,7 +679,7 @@ static int kvmppc_handle_ext(struct kvm_vcpu *vcpu, unsigned int exit_nr,

vcpu->arch.guest_owned_ext |= msr;

kvmppc_set_msr(vcpu, vcpu->arch.msr);
kvmppc_recalc_shadow_msr(vcpu);

return RESUME_GUEST;
}
Expand Down

0 comments on commit a76f849

Please sign in to comment.