On 03/10/2023 09:28, Michal Orzel wrote:
> 
> 
> Hi Oleg, Stefano
> 
> On 03/10/2023 02:13, Stefano Stabellini wrote:
>> Hi Oleg,
>>
>> You are getting this output:
>>
>>> (XEN) d0v0 Forwarding AES operation: 3254779951 136bb00000000000 -> 
>>> fffffffffffff000
>>
>> Which means that the guest physical address is 0x136bb00000000000 and
>> the translated physical address is 0xfffffffffffff000. It generates an
>> error so you are asking if 0xfffffffffffff000 is incorrect because the
>> translation is incorrect.
>>
>> This is possible. However, I think it is more likely that
>> 0x136bb000_00000000 is incorrect. This an extremely high address. Could
>> it be wrong?
> 
> I think the issue is due to a different way of forming the r1 register for 
> this particular EEMI call:
> 
> Take a look at the PM AES function from Linux:
> https://github.com/Xilinx/linux-xlnx/blob/master/drivers/firmware/xilinx/zynqmp.c#L1975
> and EEMI call invocation:
> https://github.com/Xilinx/linux-xlnx/blob/master/drivers/firmware/xilinx/zynqmp.c#L390
> 
> The register passed as r1 is formed a bit differently than "normally". FWICS:
>  - the upper 32 bits of address are stored in the lower 32 bits of r1 
> register.
>  - the lower 32 bits of address are stored in the upper 32 bits of r1 
> register.
> 
> That is why you are getting a very high address in r1 0x136bb000_00000000.
> 
> Please, try to do the following (not tested):
> 
> case 0xC200002F:
> {
>     register_t gaddr, new_gaddr;
>     paddr_t maddr;
> 
>     gaddr = ((register_t)get_user_reg(regs, 1) << 32) | (get_user_reg(regs, 
> 1) >> 32);
>     maddr = mfn_to_maddr(gfn_to_mfn(current->domain, gaddr_to_gfn(gaddr)));
> 
>     /* Most probably not needed given dma_alloc_coherent use */
>     maddr += gaddr &~ PAGE_MASK;
> 
>     /* Convert back to required format */
>     new_gaddr = ((register_t)maddr << 32) | (maddr >> 32);
> 
>     arm_smccc_1_1_smc(get_user_reg(regs, 0),
>             get_user_reg(regs, 1),
>             new_gaddr,
Wrong placement. This should be for register 1 and not 2, so:
    arm_smccc_1_1_smc(get_user_reg(regs, 0),
            new_gaddr,
            get_user_reg(regs, 2),
            get_user_reg(regs, 3),
            get_user_reg(regs, 4),
            get_user_reg(regs, 5),
            get_user_reg(regs, 6),
            get_user_reg(regs, 7),
            &res);

~Michal

Reply via email to