KVM: PPC: Implement Paired Single emulation
The one big thing about the Gekko is paired singles. Paired singles are an extension to the instruction set, that adds 32 single precision floating point registers (qprs), some SPRs to modify the behavior of paired singled operations and instructions to deal with qprs to the instruction set. Unfortunately, it also changes semantics of existing operations that affect single values in FPRs. In most cases they get mirrored to the coresponding QPR. Thanks to that we need to emulate all FPU operations and all the new paired single operations too. In order to achieve that, we use the just introduced FPU call helpers to call the real FPU whenever the guest wants to modify an FPR. Additionally we also fix up the QPR values along the way. That way we can execute paired single FPU operations without implementing a soft fpu. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
This commit is contained in:
parent
e5c29e926c
commit
831317b605
4 changed files with 1294 additions and 0 deletions
|
@ -121,6 +121,7 @@ extern void kvmppc_book3s_queue_irqprio(struct kvm_vcpu *vcpu, unsigned int vec)
|
||||||
extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
|
extern void kvmppc_set_bat(struct kvm_vcpu *vcpu, struct kvmppc_bat *bat,
|
||||||
bool upper, u32 val);
|
bool upper, u32 val);
|
||||||
extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
|
extern void kvmppc_giveup_ext(struct kvm_vcpu *vcpu, ulong msr);
|
||||||
|
extern int kvmppc_emulate_paired_single(struct kvm_run *run, struct kvm_vcpu *vcpu);
|
||||||
|
|
||||||
extern u32 kvmppc_trampoline_lowmem;
|
extern u32 kvmppc_trampoline_lowmem;
|
||||||
extern u32 kvmppc_trampoline_enter;
|
extern u32 kvmppc_trampoline_enter;
|
||||||
|
|
|
@ -41,6 +41,7 @@ kvm-objs-$(CONFIG_KVM_E500) := $(kvm-e500-objs)
|
||||||
kvm-book3s_64-objs := \
|
kvm-book3s_64-objs := \
|
||||||
$(common-objs-y) \
|
$(common-objs-y) \
|
||||||
fpu.o \
|
fpu.o \
|
||||||
|
book3s_paired_singles.o \
|
||||||
book3s.o \
|
book3s.o \
|
||||||
book3s_64_emulate.o \
|
book3s_64_emulate.o \
|
||||||
book3s_64_interrupts.o \
|
book3s_64_interrupts.o \
|
||||||
|
|
|
@ -200,6 +200,9 @@ int kvmppc_core_emulate_op(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||||
emulated = EMULATE_FAIL;
|
emulated = EMULATE_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (emulated == EMULATE_FAIL)
|
||||||
|
emulated = kvmppc_emulate_paired_single(run, vcpu);
|
||||||
|
|
||||||
return emulated;
|
return emulated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1289
arch/powerpc/kvm/book3s_paired_singles.c
Normal file
1289
arch/powerpc/kvm/book3s_paired_singles.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue