2727#include <asm/fpsimd.h>
2828#include <asm/kvm.h>
2929#include <asm/kvm_asm.h>
30+ #include <asm/vncr_mapping.h>
3031
3132#define __KVM_HAVE_ARCH_INTC_INITIALIZED
3233
@@ -325,33 +326,33 @@ struct kvm_vcpu_fault_info {
325326 u64 disr_el1 ; /* Deferred [SError] Status Register */
326327};
327328
329+ /*
330+ * VNCR() just places the VNCR_capable registers in the enum after
331+ * __VNCR_START__, and the value (after correction) to be an 8-byte offset
332+ * from the VNCR base. As we don't require the enum to be otherwise ordered,
333+ * we need the terrible hack below to ensure that we correctly size the
334+ * sys_regs array, no matter what.
335+ *
336+ * The __MAX__ macro has been lifted from Sean Eron Anderson's wonderful
337+ * treasure trove of bit hacks:
338+ * https://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax
339+ */
340+ #define __MAX__ (x ,y ) ((x) ^ (((x) ^ (y)) & -((x) < (y))))
341+ #define VNCR (r ) \
342+ __before_##r, \
343+ r = __VNCR_START__ + ((VNCR_ ## r) / 8), \
344+ __after_##r = __MAX__(__before_##r - 1, r)
345+
328346enum vcpu_sysreg {
329347 __INVALID_SYSREG__ , /* 0 is reserved as an invalid value */
330348 MPIDR_EL1 , /* MultiProcessor Affinity Register */
331349 CLIDR_EL1 , /* Cache Level ID Register */
332350 CSSELR_EL1 , /* Cache Size Selection Register */
333- SCTLR_EL1 , /* System Control Register */
334- ACTLR_EL1 , /* Auxiliary Control Register */
335- CPACR_EL1 , /* Coprocessor Access Control */
336- ZCR_EL1 , /* SVE Control */
337- TTBR0_EL1 , /* Translation Table Base Register 0 */
338- TTBR1_EL1 , /* Translation Table Base Register 1 */
339- TCR_EL1 , /* Translation Control Register */
340- TCR2_EL1 , /* Extended Translation Control Register */
341- ESR_EL1 , /* Exception Syndrome Register */
342- AFSR0_EL1 , /* Auxiliary Fault Status Register 0 */
343- AFSR1_EL1 , /* Auxiliary Fault Status Register 1 */
344- FAR_EL1 , /* Fault Address Register */
345- MAIR_EL1 , /* Memory Attribute Indirection Register */
346- VBAR_EL1 , /* Vector Base Address Register */
347- CONTEXTIDR_EL1 , /* Context ID Register */
348351 TPIDR_EL0 , /* Thread ID, User R/W */
349352 TPIDRRO_EL0 , /* Thread ID, User R/O */
350353 TPIDR_EL1 , /* Thread ID, Privileged */
351- AMAIR_EL1 , /* Aux Memory Attribute Indirection Register */
352354 CNTKCTL_EL1 , /* Timer Control Register (EL1) */
353355 PAR_EL1 , /* Physical Address Register */
354- MDSCR_EL1 , /* Monitor Debug System Control Register */
355356 MDCCINT_EL1 , /* Monitor Debug Comms Channel Interrupt Enable Reg */
356357 OSLSR_EL1 , /* OS Lock Status Register */
357358 DISR_EL1 , /* Deferred Interrupt Status Register */
@@ -382,48 +383,26 @@ enum vcpu_sysreg {
382383 APGAKEYLO_EL1 ,
383384 APGAKEYHI_EL1 ,
384385
385- ELR_EL1 ,
386- SP_EL1 ,
387- SPSR_EL1 ,
388-
389- CNTVOFF_EL2 ,
390- CNTV_CVAL_EL0 ,
391- CNTV_CTL_EL0 ,
392- CNTP_CVAL_EL0 ,
393- CNTP_CTL_EL0 ,
394-
395386 /* Memory Tagging Extension registers */
396387 RGSR_EL1 , /* Random Allocation Tag Seed Register */
397388 GCR_EL1 , /* Tag Control Register */
398- TFSR_EL1 , /* Tag Fault Status Register (EL1) */
399389 TFSRE0_EL1 , /* Tag Fault Status Register (EL0) */
400390
401- /* Permission Indirection Extension registers */
402- PIR_EL1 , /* Permission Indirection Register 1 (EL1) */
403- PIRE0_EL1 , /* Permission Indirection Register 0 (EL1) */
404-
405391 /* 32bit specific registers. */
406392 DACR32_EL2 , /* Domain Access Control Register */
407393 IFSR32_EL2 , /* Instruction Fault Status Register */
408394 FPEXC32_EL2 , /* Floating-Point Exception Control Register */
409395 DBGVCR32_EL2 , /* Debug Vector Catch Register */
410396
411397 /* EL2 registers */
412- VPIDR_EL2 , /* Virtualization Processor ID Register */
413- VMPIDR_EL2 , /* Virtualization Multiprocessor ID Register */
414398 SCTLR_EL2 , /* System Control Register (EL2) */
415399 ACTLR_EL2 , /* Auxiliary Control Register (EL2) */
416- HCR_EL2 , /* Hypervisor Configuration Register */
417400 MDCR_EL2 , /* Monitor Debug Configuration Register (EL2) */
418401 CPTR_EL2 , /* Architectural Feature Trap Register (EL2) */
419- HSTR_EL2 , /* Hypervisor System Trap Register */
420402 HACR_EL2 , /* Hypervisor Auxiliary Control Register */
421- HCRX_EL2 , /* Extended Hypervisor Configuration Register */
422403 TTBR0_EL2 , /* Translation Table Base Register 0 (EL2) */
423404 TTBR1_EL2 , /* Translation Table Base Register 1 (EL2) */
424405 TCR_EL2 , /* Translation Control Register (EL2) */
425- VTTBR_EL2 , /* Virtualization Translation Table Base Register */
426- VTCR_EL2 , /* Virtualization Translation Control Register */
427406 SPSR_EL2 , /* EL2 saved program status register */
428407 ELR_EL2 , /* EL2 exception link register */
429408 AFSR0_EL2 , /* Auxiliary Fault Status Register 0 (EL2) */
@@ -436,19 +415,61 @@ enum vcpu_sysreg {
436415 VBAR_EL2 , /* Vector Base Address Register (EL2) */
437416 RVBAR_EL2 , /* Reset Vector Base Address Register */
438417 CONTEXTIDR_EL2 , /* Context ID Register (EL2) */
439- TPIDR_EL2 , /* EL2 Software Thread ID Register */
440418 CNTHCTL_EL2 , /* Counter-timer Hypervisor Control register */
441419 SP_EL2 , /* EL2 Stack Pointer */
442- HFGRTR_EL2 ,
443- HFGWTR_EL2 ,
444- HFGITR_EL2 ,
445- HDFGRTR_EL2 ,
446- HDFGWTR_EL2 ,
447420 CNTHP_CTL_EL2 ,
448421 CNTHP_CVAL_EL2 ,
449422 CNTHV_CTL_EL2 ,
450423 CNTHV_CVAL_EL2 ,
451424
425+ __VNCR_START__ , /* Any VNCR-capable reg goes after this point */
426+
427+ VNCR (SCTLR_EL1 ),/* System Control Register */
428+ VNCR (ACTLR_EL1 ),/* Auxiliary Control Register */
429+ VNCR (CPACR_EL1 ),/* Coprocessor Access Control */
430+ VNCR (ZCR_EL1 ), /* SVE Control */
431+ VNCR (TTBR0_EL1 ),/* Translation Table Base Register 0 */
432+ VNCR (TTBR1_EL1 ),/* Translation Table Base Register 1 */
433+ VNCR (TCR_EL1 ), /* Translation Control Register */
434+ VNCR (TCR2_EL1 ), /* Extended Translation Control Register */
435+ VNCR (ESR_EL1 ), /* Exception Syndrome Register */
436+ VNCR (AFSR0_EL1 ),/* Auxiliary Fault Status Register 0 */
437+ VNCR (AFSR1_EL1 ),/* Auxiliary Fault Status Register 1 */
438+ VNCR (FAR_EL1 ), /* Fault Address Register */
439+ VNCR (MAIR_EL1 ), /* Memory Attribute Indirection Register */
440+ VNCR (VBAR_EL1 ), /* Vector Base Address Register */
441+ VNCR (CONTEXTIDR_EL1 ), /* Context ID Register */
442+ VNCR (AMAIR_EL1 ),/* Aux Memory Attribute Indirection Register */
443+ VNCR (MDSCR_EL1 ),/* Monitor Debug System Control Register */
444+ VNCR (ELR_EL1 ),
445+ VNCR (SP_EL1 ),
446+ VNCR (SPSR_EL1 ),
447+ VNCR (TFSR_EL1 ), /* Tag Fault Status Register (EL1) */
448+ VNCR (VPIDR_EL2 ),/* Virtualization Processor ID Register */
449+ VNCR (VMPIDR_EL2 ),/* Virtualization Multiprocessor ID Register */
450+ VNCR (HCR_EL2 ), /* Hypervisor Configuration Register */
451+ VNCR (HSTR_EL2 ), /* Hypervisor System Trap Register */
452+ VNCR (VTTBR_EL2 ),/* Virtualization Translation Table Base Register */
453+ VNCR (VTCR_EL2 ), /* Virtualization Translation Control Register */
454+ VNCR (TPIDR_EL2 ),/* EL2 Software Thread ID Register */
455+ VNCR (HCRX_EL2 ), /* Extended Hypervisor Configuration Register */
456+
457+ /* Permission Indirection Extension registers */
458+ VNCR (PIR_EL1 ), /* Permission Indirection Register 1 (EL1) */
459+ VNCR (PIRE0_EL1 ), /* Permission Indirection Register 0 (EL1) */
460+
461+ VNCR (HFGRTR_EL2 ),
462+ VNCR (HFGWTR_EL2 ),
463+ VNCR (HFGITR_EL2 ),
464+ VNCR (HDFGRTR_EL2 ),
465+ VNCR (HDFGWTR_EL2 ),
466+
467+ VNCR (CNTVOFF_EL2 ),
468+ VNCR (CNTV_CVAL_EL0 ),
469+ VNCR (CNTV_CTL_EL0 ),
470+ VNCR (CNTP_CVAL_EL0 ),
471+ VNCR (CNTP_CTL_EL0 ),
472+
452473 NR_SYS_REGS /* Nothing after this line! */
453474};
454475
@@ -465,6 +486,9 @@ struct kvm_cpu_context {
465486 u64 sys_regs [NR_SYS_REGS ];
466487
467488 struct kvm_vcpu * __hyp_running_vcpu ;
489+
490+ /* This pointer has to be 4kB aligned. */
491+ u64 * vncr_array ;
468492};
469493
470494struct kvm_host_data {
@@ -827,8 +851,19 @@ struct kvm_vcpu_arch {
827851 * accessed by a running VCPU. For example, for userspace access or
828852 * for system registers that are never context switched, but only
829853 * emulated.
854+ *
855+ * Don't bother with VNCR-based accesses in the nVHE code, it has no
856+ * business dealing with NV.
830857 */
831- #define __ctxt_sys_reg (c ,r ) (&(c)->sys_regs[(r)])
858+ static inline u64 * __ctxt_sys_reg (const struct kvm_cpu_context * ctxt , int r )
859+ {
860+ #if !defined (__KVM_NVHE_HYPERVISOR__ )
861+ if (unlikely (cpus_have_final_cap (ARM64_HAS_NESTED_VIRT ) &&
862+ r >= __VNCR_START__ && ctxt -> vncr_array ))
863+ return & ctxt -> vncr_array [r - __VNCR_START__ ];
864+ #endif
865+ return (u64 * )& ctxt -> sys_regs [r ];
866+ }
832867
833868#define ctxt_sys_reg (c ,r ) (*__ctxt_sys_reg(c,r))
834869
0 commit comments