• Paul Mackerras's avatar
    KVM: PPC: Book3S HV: Align physical and virtual CPU thread numbers · e0b7ec05
    Paul Mackerras authored
    On a threaded processor such as POWER7, we group VCPUs into virtual
    cores and arrange that the VCPUs in a virtual core run on the same
    physical core.  Currently we don't enforce any correspondence between
    virtual thread numbers within a virtual core and physical thread
    numbers.  Physical threads are allocated starting at 0 on a first-come
    first-served basis to runnable virtual threads (VCPUs).
    
    POWER8 implements a new "msgsndp" instruction which guest kernels can
    use to interrupt other threads in the same core or sub-core.  Since
    the instruction takes the destination physical thread ID as a parameter,
    it becomes necessary to align the physical thread IDs with the virtual
    thread IDs, that is, to make sure virtual thread N within a virtual
    core always runs on physical thread N.
    
    This means that it's possible that thread 0, which is where we call
    __kvmppc_vcore_entry, may end up running some other vcpu than the
    one whose task called kvmppc_run_core(), or it may end up running
    no vcpu at all, if for example thread 0 of the virtual core is
    currently executing in userspace.  However, we do need thread 0
    to be responsible for switching the MMU -- a previous version of
    this patch that had other threads switching the MMU was found to
    be responsible for occasional memory corruption and machine check
    interrupts in the guest on POWER7 machines.
    
    To accommodate this, we no longer pass the vcpu pointer to
    __kvmppc_vcore_entry, but instead let the assembly code load it from
    the PACA.  Since the assembly code will need to know the kvm pointer
    and the thread ID for threads which don't have a vcpu, we move the
    thread ID into the PACA and we add a kvm pointer to the virtual core
    structure.
    
    In the case where thread 0 has no vcpu to run, it still calls into
    kvmppc_hv_entry in order to do the MMU switch, and then naps until
    either its vcpu is ready to run in the guest, or some other thread
    needs to exit the guest.  In the latter case, thread 0 jumps to the
    code that switches the MMU back to the host.  This control flow means
    that now we switch the MMU before loading any guest vcpu state.
    Similarly, on guest exit we now save all the guest vcpu state before
    switching the MMU back to the host.  This has required substantial
    code movement, making the diff rather large.
    Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
    Signed-off-by: default avatarAlexander Graf <agraf@suse.de>
    e0b7ec05
book3s_hv_rmhandlers.S 47.5 KB