Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 297 lines 7.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2 3// Check that, on a GICv3-capable system (GICv3 native, or GICv5 with 4// FEAT_GCIE_LEGACY), not configuring GICv3 correctly results in all 5// of the sysregs generating an UNDEF exception. Do the same for GICv5 6// on a GICv5 host. 7 8#include <test_util.h> 9#include <kvm_util.h> 10#include <processor.h> 11 12#include <arm64/gic_v5.h> 13 14static volatile bool handled; 15 16#define __check_sr_read(r) \ 17 ({ \ 18 u64 val; \ 19 \ 20 handled = false; \ 21 dsb(sy); \ 22 val = read_sysreg_s(SYS_ ## r); \ 23 val; \ 24 }) 25 26#define __check_sr_write(r) \ 27 do { \ 28 handled = false; \ 29 dsb(sy); \ 30 write_sysreg_s(0, SYS_ ## r); \ 31 isb(); \ 32 } while (0) 33 34#define __check_gicv5_gicr_op(r) \ 35 ({ \ 36 u64 val; \ 37 \ 38 handled = false; \ 39 dsb(sy); \ 40 val = read_sysreg_s(GICV5_OP_GICR_ ## r); \ 41 val; \ 42 }) 43 44#define __check_gicv5_gic_op(r) \ 45 do { \ 46 handled = false; \ 47 dsb(sy); \ 48 write_sysreg_s(0, GICV5_OP_GIC_ ## r); \ 49 isb(); \ 50 } while (0) 51 52/* Fatal checks */ 53#define check_sr_read(r) \ 54 do { \ 55 __check_sr_read(r); \ 56 __GUEST_ASSERT(handled, #r " no read trap"); \ 57 } while (0) 58 59#define check_sr_write(r) \ 60 do { \ 61 __check_sr_write(r); \ 62 __GUEST_ASSERT(handled, #r " no write trap"); \ 63 } while (0) 64 65#define check_sr_rw(r) \ 66 do { \ 67 check_sr_read(r); \ 68 check_sr_write(r); \ 69 } while (0) 70 71#define check_gicv5_gicr_op(r) \ 72 do { \ 73 __check_gicv5_gicr_op(r); \ 74 __GUEST_ASSERT(handled, #r " no read trap"); \ 75 } while (0) 76 77#define check_gicv5_gic_op(r) \ 78 do { \ 79 __check_gicv5_gic_op(r); \ 80 __GUEST_ASSERT(handled, #r " no write trap"); \ 81 } while (0) 82 83static void guest_code_gicv3(void) 84{ 85 u64 val; 86 87 /* 88 * Check that we advertise that ID_AA64PFR0_EL1.GIC == 0, having 89 * hidden the feature at runtime without any other userspace action. 90 */ 91 __GUEST_ASSERT(FIELD_GET(ID_AA64PFR0_EL1_GIC, 92 read_sysreg(id_aa64pfr0_el1)) == 0, 93 "GICv3 wrongly advertised"); 94 95 /* 96 * Access all GICv3 registers, and fail if we don't get an UNDEF. 97 * Note that we happily access all the APxRn registers without 98 * checking their existence, as all we want to see is a failure. 99 */ 100 check_sr_rw(ICC_PMR_EL1); 101 check_sr_read(ICC_IAR0_EL1); 102 check_sr_write(ICC_EOIR0_EL1); 103 check_sr_rw(ICC_HPPIR0_EL1); 104 check_sr_rw(ICC_BPR0_EL1); 105 check_sr_rw(ICC_AP0R0_EL1); 106 check_sr_rw(ICC_AP0R1_EL1); 107 check_sr_rw(ICC_AP0R2_EL1); 108 check_sr_rw(ICC_AP0R3_EL1); 109 check_sr_rw(ICC_AP1R0_EL1); 110 check_sr_rw(ICC_AP1R1_EL1); 111 check_sr_rw(ICC_AP1R2_EL1); 112 check_sr_rw(ICC_AP1R3_EL1); 113 check_sr_write(ICC_DIR_EL1); 114 check_sr_read(ICC_RPR_EL1); 115 check_sr_write(ICC_SGI1R_EL1); 116 check_sr_write(ICC_ASGI1R_EL1); 117 check_sr_write(ICC_SGI0R_EL1); 118 check_sr_read(ICC_IAR1_EL1); 119 check_sr_write(ICC_EOIR1_EL1); 120 check_sr_rw(ICC_HPPIR1_EL1); 121 check_sr_rw(ICC_BPR1_EL1); 122 check_sr_rw(ICC_CTLR_EL1); 123 check_sr_rw(ICC_IGRPEN0_EL1); 124 check_sr_rw(ICC_IGRPEN1_EL1); 125 126 /* 127 * ICC_SRE_EL1 may not be trappable, as ICC_SRE_EL2.Enable can 128 * be RAO/WI. Engage in non-fatal accesses, starting with a 129 * write of 0 to try and disable SRE, and let's see if it 130 * sticks. 131 */ 132 __check_sr_write(ICC_SRE_EL1); 133 if (!handled) 134 GUEST_PRINTF("ICC_SRE_EL1 write not trapping (OK)\n"); 135 136 val = __check_sr_read(ICC_SRE_EL1); 137 if (!handled) { 138 __GUEST_ASSERT((val & BIT(0)), 139 "ICC_SRE_EL1 not trapped but ICC_SRE_EL1.SRE not set\n"); 140 GUEST_PRINTF("ICC_SRE_EL1 read not trapping (OK)\n"); 141 } 142 143 GUEST_DONE(); 144} 145 146static void guest_code_gicv5(void) 147{ 148 /* 149 * Check that we advertise that ID_AA64PFR2_EL1.GCIE == 0, having 150 * hidden the feature at runtime without any other userspace action. 151 */ 152 __GUEST_ASSERT(FIELD_GET(ID_AA64PFR2_EL1_GCIE, 153 read_sysreg_s(SYS_ID_AA64PFR2_EL1)) == 0, 154 "GICv5 wrongly advertised"); 155 156 /* 157 * Try all GICv5 instructions, and fail if we don't get an UNDEF. 158 */ 159 check_gicv5_gic_op(CDAFF); 160 check_gicv5_gic_op(CDDI); 161 check_gicv5_gic_op(CDDIS); 162 check_gicv5_gic_op(CDEOI); 163 check_gicv5_gic_op(CDHM); 164 check_gicv5_gic_op(CDPEND); 165 check_gicv5_gic_op(CDPRI); 166 check_gicv5_gic_op(CDRCFG); 167 check_gicv5_gicr_op(CDIA); 168 check_gicv5_gicr_op(CDNMIA); 169 170 /* Check General System Register acccesses */ 171 check_sr_rw(ICC_APR_EL1); 172 check_sr_rw(ICC_CR0_EL1); 173 check_sr_read(ICC_HPPIR_EL1); 174 check_sr_read(ICC_IAFFIDR_EL1); 175 check_sr_rw(ICC_ICSR_EL1); 176 check_sr_read(ICC_IDR0_EL1); 177 check_sr_rw(ICC_PCR_EL1); 178 179 /* Check PPI System Register accessess */ 180 check_sr_rw(ICC_PPI_CACTIVER0_EL1); 181 check_sr_rw(ICC_PPI_CACTIVER1_EL1); 182 check_sr_rw(ICC_PPI_SACTIVER0_EL1); 183 check_sr_rw(ICC_PPI_SACTIVER1_EL1); 184 check_sr_rw(ICC_PPI_CPENDR0_EL1); 185 check_sr_rw(ICC_PPI_CPENDR1_EL1); 186 check_sr_rw(ICC_PPI_SPENDR0_EL1); 187 check_sr_rw(ICC_PPI_SPENDR1_EL1); 188 check_sr_rw(ICC_PPI_ENABLER0_EL1); 189 check_sr_rw(ICC_PPI_ENABLER1_EL1); 190 check_sr_read(ICC_PPI_HMR0_EL1); 191 check_sr_read(ICC_PPI_HMR1_EL1); 192 check_sr_rw(ICC_PPI_PRIORITYR0_EL1); 193 check_sr_rw(ICC_PPI_PRIORITYR1_EL1); 194 check_sr_rw(ICC_PPI_PRIORITYR2_EL1); 195 check_sr_rw(ICC_PPI_PRIORITYR3_EL1); 196 check_sr_rw(ICC_PPI_PRIORITYR4_EL1); 197 check_sr_rw(ICC_PPI_PRIORITYR5_EL1); 198 check_sr_rw(ICC_PPI_PRIORITYR6_EL1); 199 check_sr_rw(ICC_PPI_PRIORITYR7_EL1); 200 check_sr_rw(ICC_PPI_PRIORITYR8_EL1); 201 check_sr_rw(ICC_PPI_PRIORITYR9_EL1); 202 check_sr_rw(ICC_PPI_PRIORITYR10_EL1); 203 check_sr_rw(ICC_PPI_PRIORITYR11_EL1); 204 check_sr_rw(ICC_PPI_PRIORITYR12_EL1); 205 check_sr_rw(ICC_PPI_PRIORITYR13_EL1); 206 check_sr_rw(ICC_PPI_PRIORITYR14_EL1); 207 check_sr_rw(ICC_PPI_PRIORITYR15_EL1); 208 209 GUEST_DONE(); 210} 211 212static void guest_undef_handler(struct ex_regs *regs) 213{ 214 /* Success, we've gracefully exploded! */ 215 handled = true; 216 regs->pc += 4; 217} 218 219static void test_run_vcpu(struct kvm_vcpu *vcpu) 220{ 221 struct ucall uc; 222 223 do { 224 vcpu_run(vcpu); 225 226 switch (get_ucall(vcpu, &uc)) { 227 case UCALL_ABORT: 228 REPORT_GUEST_ASSERT(uc); 229 break; 230 case UCALL_PRINTF: 231 printf("%s", uc.buffer); 232 break; 233 case UCALL_DONE: 234 break; 235 default: 236 TEST_FAIL("Unknown ucall %lu", uc.cmd); 237 } 238 } while (uc.cmd != UCALL_DONE); 239} 240 241static void test_guest_no_vgic(void *guest_code) 242{ 243 struct kvm_vcpu *vcpu; 244 struct kvm_vm *vm; 245 246 /* Create a VM without a GIC */ 247 vm = vm_create_with_one_vcpu(&vcpu, guest_code); 248 249 vm_init_descriptor_tables(vm); 250 vcpu_init_descriptor_tables(vcpu); 251 252 vm_install_sync_handler(vm, VECTOR_SYNC_CURRENT, 253 ESR_ELx_EC_UNKNOWN, guest_undef_handler); 254 255 test_run_vcpu(vcpu); 256 257 kvm_vm_free(vm); 258} 259 260int main(int argc, char *argv[]) 261{ 262 struct kvm_vcpu *vcpu; 263 struct kvm_vm *vm; 264 bool has_v3, has_v5; 265 u64 pfr; 266 267 test_disable_default_vgic(); 268 269 vm = vm_create_with_one_vcpu(&vcpu, NULL); 270 271 pfr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR0_EL1)); 272 has_v3 = !!FIELD_GET(ID_AA64PFR0_EL1_GIC, pfr); 273 274 pfr = vcpu_get_reg(vcpu, KVM_ARM64_SYS_REG(SYS_ID_AA64PFR2_EL1)); 275 has_v5 = !!FIELD_GET(ID_AA64PFR2_EL1_GCIE, pfr); 276 277 kvm_vm_free(vm); 278 279 __TEST_REQUIRE(has_v3 || has_v5, 280 "Neither GICv3 nor GICv5 supported."); 281 282 if (has_v3) { 283 pr_info("Testing no-vgic-v3\n"); 284 test_guest_no_vgic(guest_code_gicv3); 285 } else { 286 pr_info("No GICv3 support: skipping no-vgic-v3 test\n"); 287 } 288 289 if (has_v5) { 290 pr_info("Testing no-vgic-v5\n"); 291 test_guest_no_vgic(guest_code_gicv5); 292 } else { 293 pr_info("No GICv5 support: skipping no-vgic-v5 test\n"); 294 } 295 296 return 0; 297}