sys_regs.c (a86b5505304404dc5fc5e62a6dc294706e525003) sys_regs.c (051ff581ce70e822729e9474941f3c206cbf7436)
1/*
2 * Copyright (C) 2012,2013 - ARM Ltd
3 * Author: Marc Zyngier <marc.zyngier@arm.com>
4 *
5 * Derived from arch/arm/kvm/coproc.c:
6 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
7 * Authors: Rusty Russell <rusty@rustcorp.com.au>
8 * Christoffer Dall <c.dall@virtualopensystems.com>

--- 499 unchanged lines hidden (view full) ---

508 else
509 asm volatile("mrs %0, pmceid1_el0\n" : "=r" (pmceid));
510
511 p->regval = pmceid;
512
513 return true;
514}
515
1/*
2 * Copyright (C) 2012,2013 - ARM Ltd
3 * Author: Marc Zyngier <marc.zyngier@arm.com>
4 *
5 * Derived from arch/arm/kvm/coproc.c:
6 * Copyright (C) 2012 - Virtual Open Systems and Columbia University
7 * Authors: Rusty Russell <rusty@rustcorp.com.au>
8 * Christoffer Dall <c.dall@virtualopensystems.com>

--- 499 unchanged lines hidden (view full) ---

508 else
509 asm volatile("mrs %0, pmceid1_el0\n" : "=r" (pmceid));
510
511 p->regval = pmceid;
512
513 return true;
514}
515
516static bool pmu_counter_idx_valid(struct kvm_vcpu *vcpu, u64 idx)
517{
518 u64 pmcr, val;
519
520 pmcr = vcpu_sys_reg(vcpu, PMCR_EL0);
521 val = (pmcr >> ARMV8_PMU_PMCR_N_SHIFT) & ARMV8_PMU_PMCR_N_MASK;
522 if (idx >= val && idx != ARMV8_PMU_CYCLE_IDX)
523 return false;
524
525 return true;
526}
527
528static bool access_pmu_evcntr(struct kvm_vcpu *vcpu,
529 struct sys_reg_params *p,
530 const struct sys_reg_desc *r)
531{
532 u64 idx;
533
534 if (!kvm_arm_pmu_v3_ready(vcpu))
535 return trap_raz_wi(vcpu, p, r);
536
537 if (r->CRn == 9 && r->CRm == 13) {
538 if (r->Op2 == 2) {
539 /* PMXEVCNTR_EL0 */
540 idx = vcpu_sys_reg(vcpu, PMSELR_EL0)
541 & ARMV8_PMU_COUNTER_MASK;
542 } else if (r->Op2 == 0) {
543 /* PMCCNTR_EL0 */
544 idx = ARMV8_PMU_CYCLE_IDX;
545 } else {
546 BUG();
547 }
548 } else if (r->CRn == 14 && (r->CRm & 12) == 8) {
549 /* PMEVCNTRn_EL0 */
550 idx = ((r->CRm & 3) << 3) | (r->Op2 & 7);
551 } else {
552 BUG();
553 }
554
555 if (!pmu_counter_idx_valid(vcpu, idx))
556 return false;
557
558 if (p->is_write)
559 kvm_pmu_set_counter_value(vcpu, idx, p->regval);
560 else
561 p->regval = kvm_pmu_get_counter_value(vcpu, idx);
562
563 return true;
564}
565
516/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
517#define DBG_BCR_BVR_WCR_WVR_EL1(n) \
518 /* DBGBVRn_EL1 */ \
519 { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b100), \
520 trap_bvr, reset_bvr, n, 0, get_bvr, set_bvr }, \
521 /* DBGBCRn_EL1 */ \
522 { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b101), \
523 trap_bcr, reset_bcr, n, 0, get_bcr, set_bcr }, \
524 /* DBGWVRn_EL1 */ \
525 { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b110), \
526 trap_wvr, reset_wvr, n, 0, get_wvr, set_wvr }, \
527 /* DBGWCRn_EL1 */ \
528 { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b111), \
529 trap_wcr, reset_wcr, n, 0, get_wcr, set_wcr }
530
566/* Silly macro to expand the DBG{BCR,BVR,WVR,WCR}n_EL1 registers in one go */
567#define DBG_BCR_BVR_WCR_WVR_EL1(n) \
568 /* DBGBVRn_EL1 */ \
569 { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b100), \
570 trap_bvr, reset_bvr, n, 0, get_bvr, set_bvr }, \
571 /* DBGBCRn_EL1 */ \
572 { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b101), \
573 trap_bcr, reset_bcr, n, 0, get_bcr, set_bcr }, \
574 /* DBGWVRn_EL1 */ \
575 { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b110), \
576 trap_wvr, reset_wvr, n, 0, get_wvr, set_wvr }, \
577 /* DBGWCRn_EL1 */ \
578 { Op0(0b10), Op1(0b000), CRn(0b0000), CRm((n)), Op2(0b111), \
579 trap_wcr, reset_wcr, n, 0, get_wcr, set_wcr }
580
581/* Macro to expand the PMEVCNTRn_EL0 register */
582#define PMU_PMEVCNTR_EL0(n) \
583 /* PMEVCNTRn_EL0 */ \
584 { Op0(0b11), Op1(0b011), CRn(0b1110), \
585 CRm((0b1000 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \
586 access_pmu_evcntr, reset_unknown, (PMEVCNTR0_EL0 + n), }
587
531/*
532 * Architected system registers.
533 * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
534 *
535 * We could trap ID_DFR0 and tell the guest we don't support performance
536 * monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was
537 * NAKed, so it will read the PMCR anyway.
538 *

--- 177 unchanged lines hidden (view full) ---

716 /* PMCEID0_EL0 */
717 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110),
718 access_pmceid },
719 /* PMCEID1_EL0 */
720 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111),
721 access_pmceid },
722 /* PMCCNTR_EL0 */
723 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000),
588/*
589 * Architected system registers.
590 * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2
591 *
592 * We could trap ID_DFR0 and tell the guest we don't support performance
593 * monitoring. Unfortunately the patch to make the kernel check ID_DFR0 was
594 * NAKed, so it will read the PMCR anyway.
595 *

--- 177 unchanged lines hidden (view full) ---

773 /* PMCEID0_EL0 */
774 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b110),
775 access_pmceid },
776 /* PMCEID1_EL0 */
777 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1100), Op2(0b111),
778 access_pmceid },
779 /* PMCCNTR_EL0 */
780 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b000),
724 trap_raz_wi },
781 access_pmu_evcntr, reset_unknown, PMCCNTR_EL0 },
725 /* PMXEVTYPER_EL0 */
726 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001),
727 trap_raz_wi },
728 /* PMXEVCNTR_EL0 */
729 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010),
782 /* PMXEVTYPER_EL0 */
783 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b001),
784 trap_raz_wi },
785 /* PMXEVCNTR_EL0 */
786 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1101), Op2(0b010),
730 trap_raz_wi },
787 access_pmu_evcntr },
731 /* PMUSERENR_EL0 */
732 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000),
733 trap_raz_wi },
734 /* PMOVSSET_EL0 */
735 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011),
736 trap_raz_wi },
737
738 /* TPIDR_EL0 */
739 { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010),
740 NULL, reset_unknown, TPIDR_EL0 },
741 /* TPIDRRO_EL0 */
742 { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b011),
743 NULL, reset_unknown, TPIDRRO_EL0 },
744
788 /* PMUSERENR_EL0 */
789 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b000),
790 trap_raz_wi },
791 /* PMOVSSET_EL0 */
792 { Op0(0b11), Op1(0b011), CRn(0b1001), CRm(0b1110), Op2(0b011),
793 trap_raz_wi },
794
795 /* TPIDR_EL0 */
796 { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b010),
797 NULL, reset_unknown, TPIDR_EL0 },
798 /* TPIDRRO_EL0 */
799 { Op0(0b11), Op1(0b011), CRn(0b1101), CRm(0b0000), Op2(0b011),
800 NULL, reset_unknown, TPIDRRO_EL0 },
801
802 /* PMEVCNTRn_EL0 */
803 PMU_PMEVCNTR_EL0(0),
804 PMU_PMEVCNTR_EL0(1),
805 PMU_PMEVCNTR_EL0(2),
806 PMU_PMEVCNTR_EL0(3),
807 PMU_PMEVCNTR_EL0(4),
808 PMU_PMEVCNTR_EL0(5),
809 PMU_PMEVCNTR_EL0(6),
810 PMU_PMEVCNTR_EL0(7),
811 PMU_PMEVCNTR_EL0(8),
812 PMU_PMEVCNTR_EL0(9),
813 PMU_PMEVCNTR_EL0(10),
814 PMU_PMEVCNTR_EL0(11),
815 PMU_PMEVCNTR_EL0(12),
816 PMU_PMEVCNTR_EL0(13),
817 PMU_PMEVCNTR_EL0(14),
818 PMU_PMEVCNTR_EL0(15),
819 PMU_PMEVCNTR_EL0(16),
820 PMU_PMEVCNTR_EL0(17),
821 PMU_PMEVCNTR_EL0(18),
822 PMU_PMEVCNTR_EL0(19),
823 PMU_PMEVCNTR_EL0(20),
824 PMU_PMEVCNTR_EL0(21),
825 PMU_PMEVCNTR_EL0(22),
826 PMU_PMEVCNTR_EL0(23),
827 PMU_PMEVCNTR_EL0(24),
828 PMU_PMEVCNTR_EL0(25),
829 PMU_PMEVCNTR_EL0(26),
830 PMU_PMEVCNTR_EL0(27),
831 PMU_PMEVCNTR_EL0(28),
832 PMU_PMEVCNTR_EL0(29),
833 PMU_PMEVCNTR_EL0(30),
834
745 /* DACR32_EL2 */
746 { Op0(0b11), Op1(0b100), CRn(0b0011), CRm(0b0000), Op2(0b000),
747 NULL, reset_unknown, DACR32_EL2 },
748 /* IFSR32_EL2 */
749 { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0000), Op2(0b001),
750 NULL, reset_unknown, IFSR32_EL2 },
751 /* FPEXC32_EL2 */
752 { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0011), Op2(0b000),

--- 173 unchanged lines hidden (view full) ---

926static const struct sys_reg_desc cp14_64_regs[] = {
927 /* DBGDRAR (64bit) */
928 { Op1( 0), CRm( 1), .access = trap_raz_wi },
929
930 /* DBGDSAR (64bit) */
931 { Op1( 0), CRm( 2), .access = trap_raz_wi },
932};
933
835 /* DACR32_EL2 */
836 { Op0(0b11), Op1(0b100), CRn(0b0011), CRm(0b0000), Op2(0b000),
837 NULL, reset_unknown, DACR32_EL2 },
838 /* IFSR32_EL2 */
839 { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0000), Op2(0b001),
840 NULL, reset_unknown, IFSR32_EL2 },
841 /* FPEXC32_EL2 */
842 { Op0(0b11), Op1(0b100), CRn(0b0101), CRm(0b0011), Op2(0b000),

--- 173 unchanged lines hidden (view full) ---

1016static const struct sys_reg_desc cp14_64_regs[] = {
1017 /* DBGDRAR (64bit) */
1018 { Op1( 0), CRm( 1), .access = trap_raz_wi },
1019
1020 /* DBGDSAR (64bit) */
1021 { Op1( 0), CRm( 2), .access = trap_raz_wi },
1022};
1023
1024/* Macro to expand the PMEVCNTRn register */
1025#define PMU_PMEVCNTR(n) \
1026 /* PMEVCNTRn */ \
1027 { Op1(0), CRn(0b1110), \
1028 CRm((0b1000 | (((n) >> 3) & 0x3))), Op2(((n) & 0x7)), \
1029 access_pmu_evcntr }
1030
934/*
935 * Trapped cp15 registers. TTBR0/TTBR1 get a double encoding,
936 * depending on the way they are accessed (as a 32bit or a 64bit
937 * register).
938 */
939static const struct sys_reg_desc cp15_regs[] = {
940 { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi },
941

--- 19 unchanged lines hidden (view full) ---

961 /* PMU */
962 { Op1( 0), CRn( 9), CRm(12), Op2( 0), access_pmcr },
963 { Op1( 0), CRn( 9), CRm(12), Op2( 1), trap_raz_wi },
964 { Op1( 0), CRn( 9), CRm(12), Op2( 2), trap_raz_wi },
965 { Op1( 0), CRn( 9), CRm(12), Op2( 3), trap_raz_wi },
966 { Op1( 0), CRn( 9), CRm(12), Op2( 5), access_pmselr },
967 { Op1( 0), CRn( 9), CRm(12), Op2( 6), access_pmceid },
968 { Op1( 0), CRn( 9), CRm(12), Op2( 7), access_pmceid },
1031/*
1032 * Trapped cp15 registers. TTBR0/TTBR1 get a double encoding,
1033 * depending on the way they are accessed (as a 32bit or a 64bit
1034 * register).
1035 */
1036static const struct sys_reg_desc cp15_regs[] = {
1037 { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi },
1038

--- 19 unchanged lines hidden (view full) ---

1058 /* PMU */
1059 { Op1( 0), CRn( 9), CRm(12), Op2( 0), access_pmcr },
1060 { Op1( 0), CRn( 9), CRm(12), Op2( 1), trap_raz_wi },
1061 { Op1( 0), CRn( 9), CRm(12), Op2( 2), trap_raz_wi },
1062 { Op1( 0), CRn( 9), CRm(12), Op2( 3), trap_raz_wi },
1063 { Op1( 0), CRn( 9), CRm(12), Op2( 5), access_pmselr },
1064 { Op1( 0), CRn( 9), CRm(12), Op2( 6), access_pmceid },
1065 { Op1( 0), CRn( 9), CRm(12), Op2( 7), access_pmceid },
969 { Op1( 0), CRn( 9), CRm(13), Op2( 0), trap_raz_wi },
1066 { Op1( 0), CRn( 9), CRm(13), Op2( 0), access_pmu_evcntr },
970 { Op1( 0), CRn( 9), CRm(13), Op2( 1), trap_raz_wi },
1067 { Op1( 0), CRn( 9), CRm(13), Op2( 1), trap_raz_wi },
971 { Op1( 0), CRn( 9), CRm(13), Op2( 2), trap_raz_wi },
1068 { Op1( 0), CRn( 9), CRm(13), Op2( 2), access_pmu_evcntr },
972 { Op1( 0), CRn( 9), CRm(14), Op2( 0), trap_raz_wi },
973 { Op1( 0), CRn( 9), CRm(14), Op2( 1), trap_raz_wi },
974 { Op1( 0), CRn( 9), CRm(14), Op2( 2), trap_raz_wi },
975
976 { Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR },
977 { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR },
978 { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 },
979 { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 },
980
981 /* ICC_SRE */
982 { Op1( 0), CRn(12), CRm(12), Op2( 5), trap_raz_wi },
983
984 { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID },
1069 { Op1( 0), CRn( 9), CRm(14), Op2( 0), trap_raz_wi },
1070 { Op1( 0), CRn( 9), CRm(14), Op2( 1), trap_raz_wi },
1071 { Op1( 0), CRn( 9), CRm(14), Op2( 2), trap_raz_wi },
1072
1073 { Op1( 0), CRn(10), CRm( 2), Op2( 0), access_vm_reg, NULL, c10_PRRR },
1074 { Op1( 0), CRn(10), CRm( 2), Op2( 1), access_vm_reg, NULL, c10_NMRR },
1075 { Op1( 0), CRn(10), CRm( 3), Op2( 0), access_vm_reg, NULL, c10_AMAIR0 },
1076 { Op1( 0), CRn(10), CRm( 3), Op2( 1), access_vm_reg, NULL, c10_AMAIR1 },
1077
1078 /* ICC_SRE */
1079 { Op1( 0), CRn(12), CRm(12), Op2( 5), trap_raz_wi },
1080
1081 { Op1( 0), CRn(13), CRm( 0), Op2( 1), access_vm_reg, NULL, c13_CID },
1082
1083 /* PMEVCNTRn */
1084 PMU_PMEVCNTR(0),
1085 PMU_PMEVCNTR(1),
1086 PMU_PMEVCNTR(2),
1087 PMU_PMEVCNTR(3),
1088 PMU_PMEVCNTR(4),
1089 PMU_PMEVCNTR(5),
1090 PMU_PMEVCNTR(6),
1091 PMU_PMEVCNTR(7),
1092 PMU_PMEVCNTR(8),
1093 PMU_PMEVCNTR(9),
1094 PMU_PMEVCNTR(10),
1095 PMU_PMEVCNTR(11),
1096 PMU_PMEVCNTR(12),
1097 PMU_PMEVCNTR(13),
1098 PMU_PMEVCNTR(14),
1099 PMU_PMEVCNTR(15),
1100 PMU_PMEVCNTR(16),
1101 PMU_PMEVCNTR(17),
1102 PMU_PMEVCNTR(18),
1103 PMU_PMEVCNTR(19),
1104 PMU_PMEVCNTR(20),
1105 PMU_PMEVCNTR(21),
1106 PMU_PMEVCNTR(22),
1107 PMU_PMEVCNTR(23),
1108 PMU_PMEVCNTR(24),
1109 PMU_PMEVCNTR(25),
1110 PMU_PMEVCNTR(26),
1111 PMU_PMEVCNTR(27),
1112 PMU_PMEVCNTR(28),
1113 PMU_PMEVCNTR(29),
1114 PMU_PMEVCNTR(30),
985};
986
987static const struct sys_reg_desc cp15_64_regs[] = {
988 { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 },
1115};
1116
1117static const struct sys_reg_desc cp15_64_regs[] = {
1118 { Op1( 0), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR0 },
1119 { Op1( 0), CRn( 0), CRm( 9), Op2( 0), access_pmu_evcntr },
989 { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi },
990 { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 },
991};
992
993/* Target specific emulation tables */
994static struct kvm_sys_reg_target_table *target_tables[KVM_ARM_NUM_TARGETS];
995
996void kvm_register_target_sys_reg_table(unsigned int target,

--- 836 unchanged lines hidden ---
1120 { Op1( 0), CRn( 0), CRm(12), Op2( 0), access_gic_sgi },
1121 { Op1( 1), CRn( 0), CRm( 2), Op2( 0), access_vm_reg, NULL, c2_TTBR1 },
1122};
1123
1124/* Target specific emulation tables */
1125static struct kvm_sys_reg_target_table *target_tables[KVM_ARM_NUM_TARGETS];
1126
1127void kvm_register_target_sys_reg_table(unsigned int target,

--- 836 unchanged lines hidden ---