• Suraj Jitindar Singh's avatar
    KVM: PPC: Book3S HV: Implement functions to access quadrants 1 & 2 · d7b45615
    Suraj Jitindar Singh authored
    The POWER9 radix mmu has the concept of quadrants. The quadrant number
    is the two high bits of the effective address and determines the fully
    qualified address to be used for the translation. The fully qualified
    address consists of the effective lpid, the effective pid and the
    effective address. This gives then 4 possible quadrants 0, 1, 2, and 3.
    
    When accessing these quadrants the fully qualified address is obtained
    as follows:
    
    Quadrant		| Hypervisor		| Guest
    --------------------------------------------------------------------------
    			| EA[0:1] = 0b00	| EA[0:1] = 0b00
    0			| effLPID = 0		| effLPID = LPIDR
    			| effPID  = PIDR	| effPID  = PIDR
    --------------------------------------------------------------------------
    			| EA[0:1] = 0b01	|
    1			| effLPID = LPIDR	| Invalid Access
    			| effPID  = PIDR	|
    --------------------------------------------------------------------------
    			| EA[0:1] = 0b10	|
    2			| effLPID = LPIDR	| Invalid Access
    			| effPID  = 0		|
    --------------------------------------------------------------------------
    			| EA[0:1] = 0b11	| EA[0:1] = 0b11
    3			| effLPID = 0		| effLPID = LPIDR
    			| effPID  = 0		| effPID  = 0
    --------------------------------------------------------------------------
    
    In the Guest;
    Quadrant 3 is normally used to address the operating system since this
    uses effPID=0 and effLPID=LPIDR, meaning the PID register doesn't need to
    be switched.
    Quadrant 0 is normally used to address user space since the effLPID and
    effPID are taken from the corresponding registers.
    
    In the Host;
    Quadrant 0 and 3 are used as above, however the effLPID is always 0 to
    address the host.
    
    Quadrants 1 and 2 can be used by the host to address guest memory using
    a guest effective address. Since the effLPID comes from the LPID register,
    the host loads the LPID of the guest it would like to access (and the
    PID of the process) and can perform accesses to a guest effective
    address.
    
    This means quadrant 1 can be used to address the guest user space and
    quadrant 2 can be used to address the guest operating system from the
    hypervisor, using a guest effective address.
    
    Access to the quadrants can cause a Hypervisor Data Storage Interrupt
    (HDSI) due to being unable to perform partition scoped translation.
    Previously this could only be generated from a guest and so the code
    path expects us to take the KVM trampoline in the interrupt handler.
    This is no longer the case so we modify the handler to call
    bad_page_fault() to check if we were expecting this fault so we can
    handle it gracefully and just return with an error code. In the hash mmu
    case we still raise an unknown exception since quadrants aren't defined
    for the hash mmu.
    Signed-off-by: default avatarSuraj Jitindar Singh <sjitindarsingh@gmail.com>
    Signed-off-by: default avatarPaul Mackerras <paulus@ozlabs.org>
    d7b45615
exceptions-64s.S 52.2 KB