Akihiko Odaki <akihiko.od...@daynix.com> writes: > On 2025/05/06 21:57, Alex Bennée wrote: >> Currently the boot.S code assumes everything starts at EL1. This will >> break things like the memory test which will barf on unaligned memory >> access when run at a higher level. >> Adapt the boot code to do some basic verification of the starting >> mode >> and the minimal configuration to move to the lower exception levels. >> With this we can run the memory test with: >> -M virt,secure=on >> -M virt,secure=on,virtualization=on >> -M virt,virtualisation=on >> If a test needs to be at a particular EL it can use the semihosting >> command line to indicate the level we should execute in. >> Cc: Julian Armistead <julian.armist...@linaro.org> >> Cc: Jim MacArthur <jim.macart...@linaro.org> >> Signed-off-by: Alex Bennée <alex.ben...@linaro.org> <snip> >> + >> + /* sanity check, clamp to 1 if invalid */ >> + cmp w11, #'0' >> + b.lt 1f >> + cmp w11, #'4' >> + b.ge 1f >> + sub w11, w11, #'0' >> + b 2f >> +1: mov w11, #1 >> + >> +2: > > This "sanity check" made me wonder what it is for. This code is simply > unnecessary if any unknown values are to be ignored and is a bit > misleading to have this code as it looks like it adds an additional > behavior. "sub w11, w11, #'0'" is also unnecessary; we can compare w11 > with '2' and '3' later instead. > > The patch message says this sanity check was added with v2 so I looked > for a previous review and found this: > https://lore.kernel.org/qemu-devel/svmkvs.2mf5q4qhsf...@linaro.org/ > >> cmp w11, #'0' >> b.lt curr_sp0_sync >> cmp w11, #'4' >> b.ge curr_sp0_sync > > Now I get the original intent; it was to raise an error instead of > simply ignoring unknown values. However I also see a few problems with > this original code: > - It still ignores unknown strings that are longer than one character.
I'm not intending to handle longer strings in assembly - I think we can live with accepting "1junk" to "3foo". > - curr_sp0_sync leads to the code that writes a message saying > "Terminated by exception.", which is incorrect. > - "cmp w11, #'0'" is unnecessary if you check the value after "sub > w11, w11, #'0'". I'll clean that up. > >> + /* Determine current Exception Level */ >> + mrs x0, CurrentEL >> + lsr x0, x0, #2 /* CurrentEL[3:2] contains the current EL */ >> + >> + /* Branch based on current EL */ >> + cmp x0, #3 >> + b.eq setup_el3 >> + cmp x0, #2 >> + b.eq setup_el2 >> + cmp x0, #1 >> + b.eq at_testel /* Already at EL1, skip transition */ >> + /* Should not be at EL0 - error out */ >> + b curr_sp0_sync >> + >> +setup_el3: >> + /* Ensure we trap if we get anything wrong */ >> + adr x0, vector_table >> + msr vbar_el3, x0 >> + >> + /* Does the test want to be at EL3? */ >> + cmp w11, #3 >> + beq at_testel >> + >> + /* Configure EL3 to for lower states (EL2 or EL1) */ >> + mrs x0, scr_el3 >> + orr x0, x0, #(1 << 10) /* RW = 1: EL2/EL1 execution state is >> AArch64 */ >> + orr x0, x0, #(1 << 0) /* NS = 1: Non-secure state */ >> + msr scr_el3, x0 >> + >> + /* >> + * We need to check if EL2 is actually enabled via ID_AA64PFR0_EL1, >> + * otherwise we should just jump straight to EL1. >> + */ >> + mrs x0, id_aa64pfr0_el1 >> + ubfx x0, x0, #8, #4 /* Extract EL2 field (bits 11:8) */ >> + cbz x0, el2_not_present /* If field is 0 no EL2 */ >> + >> + >> + /* Prepare SPSR for exception return to EL2 */ >> + mov x0, #0x3c9 /* DAIF bits and EL2h mode (9) */ >> + msr spsr_el3, x0 >> + >> + /* Set EL2 entry point */ >> + adr x0, setup_el2 >> + msr elr_el3, x0 >> + >> + /* Return to EL2 */ >> + eret >> + nop > > Why is a nop placed here? Left over debug. I'll drop it. > <snip> -- Alex Bennée Virtualisation Tech Lead @ Linaro