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 --- |