AArch64 EL2 hypervisor for QEMU virt that boots at EL2
1

Configure Feed

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

Normalise guest abort recovery through stage two fault intents

+24 -5
+24 -5
mm/stage2.c
··· 239 239 return dfsc >= 0x04u && dfsc <= 0x07u; 240 240 } 241 241 242 + enum stage2_fault_intent { 243 + S2_FAULT_PAUSE = 0, 244 + S2_FAULT_REPAIR, 245 + S2_FAULT_MMIO, 246 + }; 247 + 248 + static enum stage2_fault_intent classify_fault(ipa_t ipa, uint32_t dfsc) 249 + { 250 + if (mmio_policy_lookup(ipa) != (const struct mmio_policy_region *)0) { 251 + return S2_FAULT_MMIO; 252 + } 253 + if (dfsc_is_translation(dfsc) && 254 + ipa >= CONFIG_GUEST_IPA_BASE && 255 + ipa < CONFIG_GUEST_IPA_BASE + CONFIG_GUEST_RAM_SIZE) { 256 + return S2_FAULT_REPAIR; 257 + } 258 + return S2_FAULT_PAUSE; 259 + } 260 + 242 261 bool stage2_handle_abort(struct vcpu *vcpu, const struct trap_frame *frame, bool instruction) 243 262 { 244 263 ipa_t ipa; ··· 246 265 paddr_t block_pa; 247 266 uint32_t dfsc; 248 267 struct log_event ev; 268 + enum stage2_fault_intent intent; 249 269 250 270 if (vcpu == (struct vcpu *)0 || frame == (const struct trap_frame *)0) { 251 271 return false; ··· 264 284 ev.pstate = frame->spsr_el2; 265 285 ev.reason = instruction ? 406u : 407u; 266 286 267 - const struct mmio_policy_region *mmio = mmio_policy_lookup(ipa); 268 - if (mmio != (const struct mmio_policy_region *)0) { 287 + intent = classify_fault(ipa, dfsc); 288 + if (intent == S2_FAULT_MMIO) { 289 + const struct mmio_policy_region *mmio = mmio_policy_lookup(ipa); 269 290 ev.reason = 410u; 270 291 ev.name = mmio->name; 271 292 ev.action = (uint32_t)mmio->action; ··· 280 301 return false; 281 302 } 282 303 283 - if (!dfsc_is_translation(dfsc) || 284 - ipa < CONFIG_GUEST_IPA_BASE || 285 - ipa >= CONFIG_GUEST_IPA_BASE + CONFIG_GUEST_RAM_SIZE) { 304 + if (intent != S2_FAULT_REPAIR) { 286 305 log_event_commit(&ev); 287 306 return false; 288 307 }