linux/arch/arm64/kernel/hyp-stub.S
<<
>>
Prefs
   1/*
   2 * Hypervisor stub
   3 *
   4 * Copyright (C) 2012 ARM Ltd.
   5 * Author:      Marc Zyngier <marc.zyngier@arm.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include <linux/init.h>
  21#include <linux/linkage.h>
  22
  23#include <asm/assembler.h>
  24#include <asm/ptrace.h>
  25#include <asm/virt.h>
  26
  27        .text
  28        .align 11
  29
  30ENTRY(__hyp_stub_vectors)
  31        ventry  el2_sync_invalid                // Synchronous EL2t
  32        ventry  el2_irq_invalid                 // IRQ EL2t
  33        ventry  el2_fiq_invalid                 // FIQ EL2t
  34        ventry  el2_error_invalid               // Error EL2t
  35
  36        ventry  el2_sync_invalid                // Synchronous EL2h
  37        ventry  el2_irq_invalid                 // IRQ EL2h
  38        ventry  el2_fiq_invalid                 // FIQ EL2h
  39        ventry  el2_error_invalid               // Error EL2h
  40
  41        ventry  el1_sync                        // Synchronous 64-bit EL1
  42        ventry  el1_irq_invalid                 // IRQ 64-bit EL1
  43        ventry  el1_fiq_invalid                 // FIQ 64-bit EL1
  44        ventry  el1_error_invalid               // Error 64-bit EL1
  45
  46        ventry  el1_sync_invalid                // Synchronous 32-bit EL1
  47        ventry  el1_irq_invalid                 // IRQ 32-bit EL1
  48        ventry  el1_fiq_invalid                 // FIQ 32-bit EL1
  49        ventry  el1_error_invalid               // Error 32-bit EL1
  50ENDPROC(__hyp_stub_vectors)
  51
  52        .align 11
  53
  54el1_sync:
  55        mrs     x1, esr_el2
  56        lsr     x1, x1, #26
  57        cmp     x1, #0x16
  58        b.ne    2f                              // Not an HVC trap
  59        cbz     x0, 1f
  60        msr     vbar_el2, x0                    // Set vbar_el2
  61        b       2f
  621:      mrs     x0, vbar_el2                    // Return vbar_el2
  632:      eret
  64ENDPROC(el1_sync)
  65
  66.macro invalid_vector   label
  67\label:
  68        b \label
  69ENDPROC(\label)
  70.endm
  71
  72        invalid_vector  el2_sync_invalid
  73        invalid_vector  el2_irq_invalid
  74        invalid_vector  el2_fiq_invalid
  75        invalid_vector  el2_error_invalid
  76        invalid_vector  el1_sync_invalid
  77        invalid_vector  el1_irq_invalid
  78        invalid_vector  el1_fiq_invalid
  79        invalid_vector  el1_error_invalid
  80
  81/*
  82 * __hyp_set_vectors: Call this after boot to set the initial hypervisor
  83 * vectors as part of hypervisor installation.  On an SMP system, this should
  84 * be called on each CPU.
  85 *
  86 * x0 must be the physical address of the new vector table, and must be
  87 * 2KB aligned.
  88 *
  89 * Before calling this, you must check that the stub hypervisor is installed
  90 * everywhere, by waiting for any secondary CPUs to be brought up and then
  91 * checking that is_hyp_mode_available() is true.
  92 *
  93 * If not, there is a pre-existing hypervisor, some CPUs failed to boot, or
  94 * something else went wrong... in such cases, trying to install a new
  95 * hypervisor is unlikely to work as desired.
  96 *
  97 * When you call into your shiny new hypervisor, sp_el2 will contain junk,
  98 * so you will need to set that to something sensible at the new hypervisor's
  99 * initialisation entry point.
 100 */
 101
 102ENTRY(__hyp_get_vectors)
 103        mov     x0, xzr
 104        // fall through
 105ENTRY(__hyp_set_vectors)
 106        hvc     #0
 107        ret
 108ENDPROC(__hyp_get_vectors)
 109ENDPROC(__hyp_set_vectors)
 110