1/*
2 * Copyright 2018, Data61
3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
4 * ABN 41 687 119 230.
5 *
6 * This software may be distributed and modified according to the terms of
7 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
8 * See "LICENSE_GPLv2.txt" for details.
9 *
10 * @TAG(DATA61_GPL)
11 */
12
13#ifndef __ARCH_ARMV_VCPU_H_
14#define __ARCH_ARMV_VCPU_H_
15
16#include <config.h>
17
18#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
19
20#include <arch/object/vcpu.h>
21
22/* Note that the HCR_DC for ARMv8 disables S1 translation if enabled */
23/* Trap WFI/WFE/SMC and override CPSR.AIF */
24#define HCR_COMMON ( HCR_TWI | HCR_TWE | HCR_VM | HCR_RW | HCR_AMO | HCR_IMO | HCR_FMO )
25
26/* Allow native tasks to run at EL0, but restrict access */
27#define HCR_NATIVE ( HCR_COMMON | HCR_TGE | HCR_TVM | HCR_TTLB | HCR_DC \
28                   | HCR_TAC | HCR_SWIO |  HCR_TSC | HCR_IMO | HCR_FMO | HCR_AMO)
29#define HCR_VCPU   ( HCR_COMMON)
30
31#define SCTLR_EL1_UCI       BIT(26)     /* Enable EL0 access to DC CVAU, DC CIVAC, DC CVAC,
32                                           and IC IVAU in AArch64 state   */
33#define SCTLR_EL1_C         BIT(2)      /* Enable data and unified caches */
34#define SCTLR_EL1_I         BIT(12)     /* Enable instruction cache       */
35#define SCTLR_EL1_CP15BEN   BIT(5)      /* AArch32 CP15 barrier enable    */
36#define SCTLR_EL1_UTC       BIT(15)     /* Enable EL0 access to CTR_EL0   */
37#define SCTLR_EL1_NTWI      BIT(16)     /* WFI executed as normal         */
38#define SCTLR_EL1_NTWE      BIT(18)     /* WFE executed as normal         */
39
40/* Disable MMU, SP alignment check, and alignment check */
41/* A57 default value */
42#define SCTLR_EL1_RES      0x30d00800   /* Reserved value */
43#define SCTLR_EL1          ( SCTLR_EL1_RES | SCTLR_EL1_CP15BEN | SCTLR_EL1_UTC \
44                           | SCTLR_EL1_NTWI | SCTLR_EL1_NTWE )
45#define SCTLR_EL1_NATIVE   (SCTLR_EL1 | SCTLR_EL1_C | SCTLR_EL1_I | SCTLR_EL1_UCI)
46#define SCTLR_EL1_VM       (SCTLR_EL1 | SCTLR_EL1_UCI)
47#define SCTLR_DEFAULT      SCTLR_EL1_NATIVE
48
49#define UNKNOWN_FAULT       0x2000000
50#define ESR_EC_TFP          0x7         /* Trap instructions that access FPU registers */
51#define ESR_EC_CPACR        0x18        /* Trap access to CPACR                        */
52#define ESR_EC(x)           (((x) & 0xfc000000) >> 26)
53
54#define VTCR_EL2_T0SZ(x)    (x)
55#define VTCR_EL2_SL0(x)     ((x) << 6)
56#define VTCR_EL2_IRGN0(x)   ((x) << 8)
57#define VTCR_EL2_ORGN0(x)   ((x) << 10)
58#define VTCR_EL2_SH0(x)     ((x) << 12)
59#define VTCR_EL2_TG0(x)     ((x) << 14)
60#define VTCR_EL2_PS(x)      ((x) << 16)
61
62/* Physical address size */
63#define PS_4G               0
64#define PS_64G              0b001
65#define PS_1T               0b010
66#define PS_4T               0b011
67#define PS_16T              0b100
68#define PS_256T             0b101
69
70/* Translation granule size */
71#define TG0_4K              0
72#define TG0_64K             0b01
73#define TG0_16K             0b10
74
75/* Shareability attributes */
76#define SH0_NONE            0
77#define SH0_OUTER           0b10
78#define SH0_INNER           0b11
79
80/* Cacheability attributes */
81#define NORMAL_NON_CACHEABLE    0
82#define NORMAL_WB_WA_CACHEABLE  0b01 /* write-back, write-allocate      */
83#define NORMAL_WT_CACHEABLE     0b10 /* write-through                   */
84#define NORMAL_WB_NWA_CACHEABLE 0b11 /* write-back, no write-allocate   */
85
86/* Start level  */
87#define SL0_4K_L2       0           /* 4K, start at level 2 */
88#define SL0_4K_L1       0b01        /* 4K, start at level 1 */
89#define SL0_4K_L0       0b10        /* 4K, start at level 0 */
90
91#define REG_SCTLR_EL1       "sctlr_el1"
92#define REG_TTBR0_EL1       "ttbr0_el1"
93#define REG_TTBR1_EL1       "ttbr1_el1"
94#define REG_TCR_EL1         "tcr_el1"
95#define REG_MAIR_EL1        "mair_el1"
96#define REG_AMAIR_EL1       "amair_el1"
97#define REG_CONTEXTIDR_EL1  "contextidr_el1"
98#define REG_ACTLR_EL1       "actlr_el1"
99#define REG_AFSR0_EL1       "afsr0_el1"
100#define REG_AFSR1_EL1       "afsr1_el1"
101#define REG_ESR_EL1         "esr_el1"
102#define REG_FAR_EL1         "far_el1"
103#define REG_ISR_EL1         "isr_el1"
104#define REG_VBAR_EL1        "vbar_el1"
105#define REG_TPIDR_EL0       "tpidr_el0"
106#define REG_TPIDR_EL1       "tpidr_el1"
107#define REG_TPIDRRO_EL0     "tpidrro_el0"
108#define REG_SP_EL1          "sp_el1"
109#define REG_ELR_EL1         "elr_el1"
110#define REG_SPSR_EL1        "spsr_el1"
111#define REG_CPACR_EL1       "cpacr_el1"
112#define REG_CNTV_TVAL_EL0   "cntv_tval_el0"
113#define REG_CNTV_CTL_EL0    "cntv_ctl_el0"
114#define REG_HCR_EL2         "hcr_el2"
115#define REG_VTCR_EL2        "vtcr_el2"
116
117/* for EL1 SCTLR */
118static inline word_t
119getSCTLR(void)
120{
121    return readSystemControlRegister();
122}
123
124static inline void
125setSCTLR(word_t sctlr)
126{
127    writeSystemControlRegister(sctlr);
128}
129
130static inline word_t
131readTTBR0(void)
132{
133    word_t reg;
134    MRS(REG_TTBR0_EL1, reg);
135    return reg;
136}
137
138static inline void
139writeTTBR0(word_t reg)
140{
141    MSR(REG_TTBR0_EL1, reg);
142}
143
144static inline word_t
145readTTBR1(void)
146{
147    word_t reg;
148    MRS(REG_TTBR1_EL1, reg);
149    return reg;
150}
151
152static inline void
153writeTTBR1(word_t reg)
154{
155    MSR(REG_TTBR1_EL1, reg);
156}
157
158static inline word_t
159readTCR(void)
160{
161    word_t reg;
162    MRS(REG_TCR_EL1, reg);
163    return reg;
164}
165
166static inline void
167writeTCR(word_t reg)
168{
169    MSR(REG_TCR_EL1, reg);
170}
171
172static inline word_t
173readMAIR(void)
174{
175    word_t reg;
176    MRS(REG_MAIR_EL1, reg);
177    return reg;
178}
179
180static inline void
181writeMAIR(word_t reg)
182{
183    MSR(REG_MAIR_EL1, reg);
184}
185
186static inline word_t
187readAMAIR(void)
188{
189    word_t reg;
190    MRS(REG_AMAIR_EL1, reg);
191    return reg;
192}
193
194static inline void
195writeAMAIR(word_t reg)
196{
197    MSR(REG_AMAIR_EL1, reg);
198}
199
200static inline word_t
201readCIDR(void)
202{
203    uint32_t reg;
204    MRS(REG_CONTEXTIDR_EL1, reg);
205    return (word_t)reg;
206}
207
208static inline void
209writeCIDR(word_t reg)
210{
211    MSR(REG_CONTEXTIDR_EL1, (uint32_t)reg);
212}
213
214static inline word_t
215readACTLR(void)
216{
217    word_t reg;
218    MRS(REG_ACTLR_EL1, reg);
219    return reg;
220}
221
222static inline void
223writeACTLR(word_t reg)
224{
225    MSR(REG_ACTLR_EL1, reg);
226}
227
228static inline word_t
229readAFSR0(void)
230{
231    uint32_t reg;
232    MRS(REG_AFSR0_EL1, reg);
233    return (word_t)reg;
234}
235
236static inline void
237writeAFSR0(word_t reg)
238{
239    MSR(REG_AFSR0_EL1, (uint32_t)reg);
240}
241
242static inline word_t
243readAFSR1(void)
244{
245    uint32_t reg;
246    MRS(REG_AFSR1_EL1, reg);
247    return (word_t)reg;
248}
249
250static inline void
251writeAFSR1(word_t reg)
252{
253    MSR(REG_AFSR1_EL1, (uint32_t)reg);
254}
255
256static inline word_t
257readESR(void)
258{
259    uint32_t reg;
260    MRS(REG_ESR_EL1, reg);
261    return (word_t)reg;
262}
263
264static inline void
265writeESR(word_t reg)
266{
267    MSR(REG_ESR_EL1, (uint32_t)reg);
268}
269
270static inline word_t
271readFAR(void)
272{
273    word_t reg;
274    MRS(REG_FAR_EL1, reg);
275    return reg;
276}
277
278static inline void
279writeFAR(word_t reg)
280{
281    MSR(REG_FAR_EL1, (uint32_t)reg);
282}
283
284/* ISR is read-only */
285static inline word_t
286readISR(void)
287{
288    uint32_t reg;
289    MRS(REG_ISR_EL1, reg);
290    return (word_t)reg;
291}
292
293static inline word_t
294readVBAR(void)
295{
296    word_t reg;
297    MRS(REG_VBAR_EL1, reg);
298    return reg;
299}
300
301static inline void
302writeVBAR(word_t reg)
303{
304    MSR(REG_VBAR_EL1, reg);
305}
306
307static inline word_t
308readTPIDR_EL0(void)
309{
310    word_t reg;
311    MRS(REG_TPIDR_EL0, reg);
312    return reg;
313}
314
315static inline void
316writeTPIDR_EL0(word_t reg)
317{
318    MSR(REG_TPIDR_EL0, reg);
319}
320
321static inline word_t
322readTPIDR_EL1(void)
323{
324    word_t reg;
325    MRS(REG_TPIDR_EL1, reg);
326    return reg;
327}
328
329static inline void
330writeTPIDR_EL1(word_t reg)
331{
332    MSR(REG_TPIDR_EL1, reg);
333}
334
335static inline word_t
336readTPIDRRO_EL0(void)
337{
338    word_t reg;
339    MRS(REG_TPIDRRO_EL0, reg);
340    return reg;
341}
342
343static inline void
344writeTPIDRRO_EL0(word_t reg)
345{
346    MSR(REG_TPIDRRO_EL0, reg);
347}
348
349static inline word_t
350readSP_EL1(void)
351{
352    word_t reg;
353    MRS(REG_SP_EL1, reg);
354    return reg;
355}
356
357static inline void
358writeSP_EL1(word_t reg)
359{
360    MSR(REG_SP_EL1, reg);
361}
362
363static inline word_t
364readELR_EL1(void)
365{
366    word_t reg;
367    MRS(REG_ELR_EL1, reg);
368    return reg;
369}
370
371static inline void
372writeELR_EL1(word_t reg)
373{
374    MRS(REG_ELR_EL1, reg);
375}
376
377static inline word_t
378readSPSR_EL1(void)
379{
380    word_t reg;
381    MRS(REG_SPSR_EL1, reg);
382    return reg;
383}
384
385static inline void
386writeSPSR_EL1(word_t reg)
387{
388    MSR(REG_SPSR_EL1, reg);
389}
390
391static inline word_t
392readCPACR_EL1(void)
393{
394    word_t reg;
395    MRS(REG_CPACR_EL1, reg);
396    return reg;
397}
398
399static inline void
400writeCPACR_EL1(word_t reg)
401{
402    MSR(REG_CPACR_EL1, reg);
403}
404
405static inline word_t
406readCNTV_TVAL_EL0(void)
407{
408    word_t reg;
409    MRS(REG_CNTV_TVAL_EL0, reg);
410    return reg;
411}
412
413static inline void
414writeCNTV_TVAL_EL0(word_t reg)
415{
416    MSR(REG_CNTV_TVAL_EL0, reg);
417}
418
419static inline word_t
420readCNTV_CTL_EL0(void)
421{
422    word_t reg;
423    MRS(REG_CNTV_CTL_EL0, reg);
424    return reg;
425}
426
427static inline void
428writeCNTV_CTL_EL0(word_t reg)
429{
430    MSR(REG_CNTV_CTL_EL0, reg);
431}
432
433static word_t
434vcpu_hw_read_reg(word_t reg_index)
435{
436    word_t reg = 0;
437    switch (reg_index) {
438    case seL4_VCPUReg_SCTLR:
439        return getSCTLR();
440    case seL4_VCPUReg_TTBR0:
441        return readTTBR0();
442    case seL4_VCPUReg_TTBR1:
443        return readTTBR1();
444    case seL4_VCPUReg_TCR:
445        return readTCR();
446    case seL4_VCPUReg_MAIR:
447        return readMAIR();
448    case seL4_VCPUReg_AMAIR:
449        return readAMAIR();
450    case seL4_VCPUReg_CIDR:
451        return readCIDR();
452    case seL4_VCPUReg_ACTLR:
453        return readACTLR();
454    case seL4_VCPUReg_CPACR:
455        return readCPACR_EL1();
456    case seL4_VCPUReg_AFSR0:
457        return readAFSR0();
458    case seL4_VCPUReg_AFSR1:
459        return readAFSR1();
460    case seL4_VCPUReg_ESR:
461        return readESR();
462    case seL4_VCPUReg_FAR:
463        return readFAR();
464    case seL4_VCPUReg_ISR:
465        return readISR();
466    case seL4_VCPUReg_VBAR:
467        return readVBAR();
468    case seL4_VCPUReg_TPIDR_EL0:
469        return readTPIDR_EL0();
470    case seL4_VCPUReg_TPIDR_EL1:
471        return readTPIDR_EL1();
472    case seL4_VCPUReg_TPIDRRO_EL0:
473        return readTPIDRRO_EL0();
474    case seL4_VCPUReg_CNTV_TVAL:
475        return readCNTV_TVAL_EL0();
476    case seL4_VCPUReg_CNTV_CTL:
477        return readCNTV_CTL_EL0();
478    case seL4_VCPUReg_CNTV_CVAL:
479        return 0;
480    case seL4_VCPUReg_SP_EL1:
481        return readSP_EL1();
482    case seL4_VCPUReg_ELR_EL1:
483        return readELR_EL1();
484    case seL4_VCPUReg_SPSR_EL1:
485        return readSPSR_EL1();
486    default:
487        fail("ARM/HYP: Invalid register index");
488    }
489
490    return reg;
491}
492
493static void
494vcpu_hw_write_reg(word_t reg_index, word_t reg)
495{
496    switch (reg_index) {
497    case seL4_VCPUReg_SCTLR:
498        return setSCTLR(reg);
499    case seL4_VCPUReg_TTBR0:
500        return writeTTBR0(reg);
501    case seL4_VCPUReg_TTBR1:
502        return writeTTBR1(reg);
503    case seL4_VCPUReg_TCR:
504        return writeTCR(reg);
505    case seL4_VCPUReg_MAIR:
506        return writeMAIR(reg);
507    case seL4_VCPUReg_AMAIR:
508        return writeAMAIR(reg);
509    case seL4_VCPUReg_CIDR:
510        return writeCIDR(reg);
511    case seL4_VCPUReg_ACTLR:
512        return writeACTLR(reg);
513    case seL4_VCPUReg_CPACR:
514        return writeCPACR_EL1(reg);
515    case seL4_VCPUReg_AFSR0:
516        return writeAFSR0(reg);
517    case seL4_VCPUReg_AFSR1:
518        return writeAFSR1(reg);
519    case seL4_VCPUReg_ESR:
520        return writeESR(reg);
521    case seL4_VCPUReg_FAR:
522        return writeFAR(reg);
523    case seL4_VCPUReg_ISR:
524        /* ISR is read-only */
525        return;
526    case seL4_VCPUReg_VBAR:
527        return writeVBAR(reg);
528    case seL4_VCPUReg_TPIDR_EL0:
529        return writeTPIDR_EL0(reg);
530    case seL4_VCPUReg_TPIDR_EL1:
531        return writeTPIDR_EL1(reg);
532    case seL4_VCPUReg_TPIDRRO_EL0:
533        return writeTPIDRRO_EL0(reg);
534    case seL4_VCPUReg_CNTV_TVAL:
535        return writeCNTV_TVAL_EL0(reg);
536    case seL4_VCPUReg_CNTV_CTL:
537        return writeCNTV_CTL_EL0(reg);
538    case seL4_VCPUReg_CNTV_CVAL:
539        return;
540    case seL4_VCPUReg_SP_EL1:
541        return writeSP_EL1(reg);
542    case seL4_VCPUReg_ELR_EL1:
543        return writeELR_EL1(reg);
544    case seL4_VCPUReg_SPSR_EL1:
545        return writeSPSR_EL1(reg);
546    default:
547        fail("ARM/HYP: Invalid register index");
548    }
549
550    return;
551}
552
553static inline void
554vcpu_save_reg(vcpu_t *vcpu, word_t reg)
555{
556    if (reg >= seL4_VCPUReg_Num || vcpu == NULL) {
557        fail("ARM/HYP: Invalid register index or NULL VCPU");
558        return;
559    }
560    vcpu->regs[reg] = vcpu_hw_read_reg(reg);
561}
562
563static inline void
564vcpu_save_reg_range(vcpu_t *vcpu, word_t start, word_t end)
565{
566    for (word_t i = start; i <= end; i++) {
567        vcpu_save_reg(vcpu, i);
568    }
569}
570
571static inline void
572vcpu_restore_reg(vcpu_t *vcpu, word_t reg)
573{
574    if (reg >= seL4_VCPUReg_Num || vcpu == NULL) {
575        fail("ARM/HYP: Invalid register index or NULL VCPU");
576        return;
577    }
578    vcpu_hw_write_reg(reg, vcpu->regs[reg]);
579}
580
581static inline void
582vcpu_restore_reg_range(vcpu_t *vcpu, word_t start, word_t end)
583{
584    for (word_t i = start; i <= end; i++) {
585        vcpu_restore_reg(vcpu, i);
586    }
587}
588
589static inline word_t
590vcpu_read_reg(vcpu_t *vcpu, word_t reg)
591{
592    if (reg >= seL4_VCPUReg_Num || vcpu == NULL) {
593        fail("ARM/HYP: Invalid register index or NULL VCPU");
594        return 0;
595    }
596    return vcpu->regs[reg];
597}
598
599static inline void
600vcpu_write_reg(vcpu_t *vcpu, word_t reg, word_t value)
601{
602    if (reg >= seL4_VCPUReg_Num || vcpu == NULL) {
603        fail("ARM/HYP: Invalid register index or NULL VCPU");
604        return;
605    }
606    vcpu->regs[reg] = value;
607}
608
609static word_t
610readVCPUReg(vcpu_t *vcpu, word_t field)
611{
612    if (likely(armHSCurVCPU == vcpu)) {
613        switch (field) {
614        case seL4_VCPUReg_SCTLR:
615            /* The SCTLR value is switched to/from hardware when we enable/disable
616             * the vcpu, not when we switch vcpus */
617            if (armHSVCPUActive) {
618                return getSCTLR();
619            } else {
620                return vcpu_read_reg(vcpu, field);
621            }
622        default:
623            return vcpu_hw_read_reg(field);
624        }
625    } else {
626        return vcpu_read_reg(vcpu, field);
627    }
628}
629
630static void
631writeVCPUReg(vcpu_t *vcpu, word_t field, word_t value)
632{
633    if (likely(armHSCurVCPU == vcpu)) {
634        switch (field) {
635        case seL4_VCPUReg_SCTLR:
636            if (armHSVCPUActive) {
637                setSCTLR(value);
638            } else {
639                vcpu_write_reg(vcpu, field, value);
640            }
641            break;
642        default:
643            return vcpu_hw_write_reg(field, value);
644        }
645    } else {
646        vcpu_write_reg(vcpu, field, value);
647    }
648}
649
650static inline void
651vcpu_init_vtcr(void)
652{
653    /* Set up the stage-2 translation control register for cores supporting 44-bit PA */
654    uint32_t vtcr_el2 = VTCR_EL2_T0SZ(20);                   // 44-bit input IPA
655    vtcr_el2 |= VTCR_EL2_SL0(SL0_4K_L0);                     // 4KiB, start at level 0
656    vtcr_el2 |= VTCR_EL2_IRGN0(NORMAL_WB_WA_CACHEABLE);      // inner write-back, read/write allocate
657    vtcr_el2 |= VTCR_EL2_ORGN0(NORMAL_WB_WA_CACHEABLE);      // outer write-back, read/write allocate
658    vtcr_el2 |= VTCR_EL2_SH0(SH0_INNER);                     // inner shareable
659    vtcr_el2 |= VTCR_EL2_TG0(TG0_4K);                        // 4KiB page size
660    vtcr_el2 |= VTCR_EL2_PS(PS_16T);                         // 44-bit PA size
661    vtcr_el2 |= BIT(31);                                     // reserved as 1
662
663    MSR(REG_VTCR_EL2, vtcr_el2);
664    isb();
665}
666
667static inline void
668armv_vcpu_boot_init(void)
669{
670    word_t hcr_el2 = 0;
671
672    vcpu_init_vtcr();
673
674    hcr_el2 = HCR_NATIVE;
675    MSR(REG_HCR_EL2, hcr_el2);
676    isb();
677
678    /* set the SCTLR_EL1 for running native seL4 threads */
679    MSR(REG_SCTLR_EL1, SCTLR_EL1_NATIVE);
680    isb();
681}
682
683static inline void
684armv_vcpu_enable(vcpu_t *vcpu)
685{
686    MSR(REG_HCR_EL2, HCR_VCPU);
687    isb();
688    vcpu_restore_reg(vcpu, seL4_VCPUReg_SCTLR);
689    isb();
690
691    set_gic_vcpu_ctrl_hcr(vcpu->vgic.hcr);
692#ifdef CONFIG_HAVE_FPU
693    vcpu_restore_reg(vcpu, seL4_VCPUReg_CPACR);
694#endif
695}
696
697static inline void
698armv_vcpu_disable(vcpu_t *vcpu)
699{
700
701    uint32_t hcr;
702    dsb();
703    if (likely(vcpu)) {
704        hcr = get_gic_vcpu_ctrl_hcr();
705        vcpu->vgic.hcr = hcr;
706        vcpu_save_reg(vcpu, seL4_VCPUReg_SCTLR);
707#ifdef CONFIG_HAVE_FPU
708        vcpu_save_reg(vcpu, seL4_VCPUReg_CPACR);
709#endif
710        isb();
711    }
712    /* Turn off the VGIC */
713    set_gic_vcpu_ctrl_hcr(0);
714    isb();
715
716    /* Stage 1 MMU off */
717    setSCTLR(SCTLR_DEFAULT);
718    isb();
719    MSR(REG_HCR_EL2, HCR_NATIVE);
720    isb();
721
722#ifdef CONFIG_HAVE_FPU
723    /* Allow FPU instructions in EL0 and EL1 for native
724     * threads by setting the CPACR_EL1. The CPTR_EL2 is
725     * used to trap the FPU instructions to EL2.
726     */
727    enableFpuEL01();
728#endif
729}
730
731static inline void
732armv_vcpu_init(vcpu_t *vcpu)
733{
734    vcpu_write_reg(vcpu, seL4_VCPUReg_SCTLR, SCTLR_EL1_VM);
735}
736
737static inline bool_t
738armv_handleVCPUFault(word_t hsr)
739{
740#ifdef CONFIG_HAVE_FPU
741    if ((ESR_EC(hsr) == ESR_EC_TFP || ESR_EC(hsr) == ESR_EC_CPACR) && !isFpuEnable()) {
742        handleFPUFault();
743        setNextPC(NODE_STATE(ksCurThread), getRestartPC(NODE_STATE(ksCurThread)));
744        return true;
745    }
746#endif
747
748    if (hsr == UNKNOWN_FAULT) {
749        handleUserLevelFault(0, 0);
750        return true;
751    }
752
753    return false;
754}
755
756#endif /* End of CONFIG_ARM_HYPERVISOR_SUPPORT */
757
758#endif
759
760