• Paul Mackerras's avatar
    KVM: PPC: Book3S PR: Fix VSX handling · 28c483b6
    Paul Mackerras authored
    This fixes various issues in how we were handling the VSX registers
    that exist on POWER7 machines.  First, we were running off the end
    of the current->thread.fpr[] array.  Ultimately this was because the
    vcpu->arch.vsr[] array is sized to be able to store both the FP
    registers and the extra VSX registers (i.e. 64 entries), but PR KVM
    only uses it for the extra VSX registers (i.e. 32 entries).
    
    Secondly, calling load_up_vsx() from C code is a really bad idea,
    because it jumps to fast_exception_return at the end, rather than
    returning with a blr instruction.  This was causing it to jump off
    to a random location with random register contents, since it was using
    the largely uninitialized stack frame created by kvmppc_load_up_vsx.
    
    In fact, it isn't necessary to call either __giveup_vsx or load_up_vsx,
    since giveup_fpu and load_up_fpu handle the extra VSX registers as well
    as the standard FP registers on machines with VSX.  Also, since VSX
    instructions can access the VMX registers and the FP registers as well
    as the extra VSX registers, we have to load up the FP and VMX registers
    before we can turn on the MSR_VSX bit for the guest.  Conversely, if
    we save away any of the VSX or FP registers, we have to turn off MSR_VSX
    for the guest.
    
    To handle all this, it is more convenient for a single call to
    kvmppc_giveup_ext() to handle all the state saving that needs to be done,
    so we make it take a set of MSR bits rather than just one, and the switch
    statement becomes a series of if statements.  Similarly kvmppc_handle_ext
    needs to be able to load up more than one set of registers.
    Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
    Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
    28c483b6
book3s_pr.c 33.4 KB