On 25 July 2016 at 22:42, Benjamin Herrenschmidt <b...@kernel.crashing.org> wrote: > On Mon, 2016-07-25 at 19:30 +0530, Richard Henderson wrote: >> > Or can they also be called outside of that context ? >> >> No, not without a valid return address. >> >> E.g. it's not valid to have one helper call another, and for the second >> helper >> use GETPC. For this, typically, one must factor out a common function which >> accepts a "retaddr" argument, which the callers must fill in with GETPC. > > Right, I've figured that out. I notice that the cpu_ldl_code() are > sprinkled in parts that are "chancy". > > For example we have one in powerpc_excp() to read the faulting > instruction, though that *should* never fail it's till not great.
Mmm. Strictly speaking you can't guarantee that that load will work, because the code you're executing could be still cached in the QEMU TLB while the (perverse) guest rewrites the page table so the ldl_code won't work. You might like to take a look at how target-arm handles the similar case (wanting to know information about source register numbers etc for some memory faults). We use a TCG instruction parameter to save the information as we translate the code in target-arm/translate-a64.c, then in restore_state_to_opc() (called after the fault) we can fish it out and put it in the CPU state struct the same way we regain the faulting PC. Then in the exception handler it's available for use. Commit aaa1f954d4 is the meat of it. Alternatively if you just want to do "a load at virtual address but don't longjump anywhere" you probably need to: * do the virt-to-phys translation manually (ie by calling some ppc specific function), so you can capture success/failure of the MMU access checks (and without setting guest visible MMU fault status info) * use address_space_ldl() on the result, so you can pass in a MemTxResult* to capture success/failure of the phys access That's pretty clunky. I meant at some point to look at whether we could provide versions of the cpu_ldl* type functions that allowed a MemTxResult*, but never got to it. > I haven't completely figured out what code path instruction translation > faults take, I assume we longjmp out of the translation loop the same > was as we do out of the execution loop ? I suggest you step through it in a debugger if you fancy a laugh. As I recall it works more by luck than judgement and includes rather more repeated work than is actually necessary. (That is, we do longjump out, but not necessarily to the most sensible point.) thanks -- PMM