I feel like this patch is maybe taking a bit of a wrong angle at achieving what you're trying to do. The code seems to be structured in a way that it has separate functions to test for each of the possible mitigation options one at a time, and pushing the default case into spectre_bhb_loop_affected() feels like a bit of a layering violation. I think it would work the way you wrote it, but it depends heavily on the order functions are called in is_spectre_bhb_affected(), which seems counter-intuitive with the way the functions seem to be designed as independent checks.
What do you think about an approach like this instead:
- Refactor max_bhb_k in spectre_bhb_loop_affected() to be a global instead, which starts out as zero, is updated by spectre_bhb_loop_affected(), and is directly read by spectre_bhb_patch_loop_iter() (could probably remove the `scope` argument from spectre_bhb_loop_affected() then).
- Add a function is_spectre_bhb_safe() that just checks if the MIDR is in the new list you're adding
- Add an `if (is_spectre_bhb_safe()) return false;` to the top of is_spectre_bhb_affected
- Change the `return false` into `return true` at the end of is_spectre_bhb_affected (in fact, you can probably take out some of the other calls that result in returning true as well then)
- In spectre_bhb_enable_mitigations(), at the end of the long if-else chain, put a last else block that prints your WARN_ONCE(), sets the max_bhb_k global to 32, and then does the same stuff that the `if (spectre_bhb_loop_affected())` block would have installed (maybe factoring that out into a helper function called from both cases).
I think that should implement the same "assume unsafe by default unless explicitly listed as safe, check for all other mitigations first, then default to k=32 loop if none found" approach, but makes it a bit more obvious in the code.