OP-TEE / optee_os

Trusted side of the TEE
Other
1.57k stars 1.06k forks source link

Translation fault when using mobj_phys_alloc #6600

Closed TephrocactusMYC closed 8 months ago

TephrocactusMYC commented 9 months ago

Hello! I am trying to implement some memory sharing functions between TAs in optee. Therefore, I used mobj_phys_alloc() to allocate physical memory and mapped it to the same virtual address when TA is loaded. The modified code is located under the /optee/optee_os/core/kernel/ldelf_loader.c path, and the main code is shown below:

static struct mobj *shared_pmem = NULL;   //Here is the code I added.
#define SHARED_VA 0x10000000   //Here is the code I added.
#define SHARED_SIZE 0x1000   //Here is the code I added.
TEE_Result ldelf_load_ldelf(struct user_mode_ctx *uctx)
{

    if (shared_pmem == NULL) {
        shared_pmem = mobj_phys_alloc(0x1000,
                   SHARED_SIZE, TEE_MATTR_MEM_TYPE_CACHED,
                   CORE_MEM_TEE_RAM);
    }   //Here is the code I added.
    DMSG("shared_pmem %p", shared_pmem);   //Here is the code I added.
    TEE_Result res = TEE_SUCCESS;
    vaddr_t stack_addr = 0;
    vaddr_t code_addr = 0;
    vaddr_t rw_addr = 0;
    vaddr_t bb_addr = 0;
    uint32_t prot = 0;

    uctx->is_32bit = is_32bit;

    res = alloc_and_map_fobj(uctx, BOUNCE_BUFFER_SIZE, TEE_MATTR_PRW, 0,
                 &bb_addr);
    if (res)
        return res;
    uctx->bbuf = (void *)bb_addr;
    uctx->bbuf_size = BOUNCE_BUFFER_SIZE;

    res = alloc_and_map_fobj(uctx, LDELF_STACK_SIZE,
                 TEE_MATTR_URW | TEE_MATTR_PRW, VM_FLAG_LDELF,
                 &stack_addr);
    if (res)
        return res;
    uctx->ldelf_stack_ptr = stack_addr + LDELF_STACK_SIZE;

    res = alloc_and_map_fobj(uctx, ldelf_code_size, TEE_MATTR_PRW,
                 VM_FLAG_LDELF, &code_addr);
    if (res)
        return res;
    uctx->entry_func = code_addr + ldelf_entry;

    rw_addr = ROUNDUP(code_addr + ldelf_code_size, SMALL_PAGE_SIZE);
    res = alloc_and_map_fobj(uctx, ldelf_data_size,
                 TEE_MATTR_URW | TEE_MATTR_PRW, VM_FLAG_LDELF,
                 &rw_addr);
    if (res)
        return res;
    res = vm_map(uctx, SHARED_VA, SHARED_SIZE, TEE_MATTR_PRW, 0, shared_pmem, 0);   //Here is the code I added. I am not sure if this is the correct way to write it, because I encountered an error when allocating physical memory.
    DMSG("vm_map result: %d",res);//Here is the code I added.
    if (res)
    {

        return res;
    }
    vm_set_ctx(uctx->ts_ctx);

    memcpy((void *)code_addr, ldelf_data, ldelf_code_size);

    res = copy_to_user((void *)rw_addr, ldelf_data + ldelf_code_size,
               ldelf_data_size);
    if (res)
        return res;

    prot = TEE_MATTR_URX;
    if (IS_ENABLED(CFG_CORE_BTI))
        prot |= TEE_MATTR_GUARDED;

    res = vm_set_prot(uctx, code_addr,
              ROUNDUP(ldelf_code_size, SMALL_PAGE_SIZE), prot);
    if (res)
        return res;

    DMSG("ldelf load address %#"PRIxVA, code_addr);

    return TEE_SUCCESS;
}

Then I got the following error message:

D/TC:0 0 ftmn_boot_tests:202 *************************************************
D/TC:0 0 ftmn_boot_tests:203 **************  Tests complete  *****************
D/TC:0 0 ftmn_boot_tests:204 *************************************************
D/TC:0 0 call_initcalls:40 level 7 release_probe_lists()
D/TC:0 0 call_initcalls:40 level 7 dt_test_release()
D/TC:0 0 call_finalcalls:59 level 1 release_external_dt()
I/TC: Primary CPU switching to normal world boot
I/TC: Secondary CPU 1 initializing
I/TC: Secondary CPU 1 switching to normal world boot
I/TC: Reserved shared memory is enabled
I/TC: Dynamic shared memory is enabled
I/TC: Normal World virtualization support is disabled
I/TC: Asynchronous notifications are disabled
D/TC:1 0 core_mmu_xlat_table_alloc:526 xlat tables used 7 / 8
D/TC:? 0 tee_ta_init_pseudo_ta_session:297 Lookup pseudo TA 7011a688-ddde-4053-a5a9-7b3c4ddf13b8
D/TC:? 0 tee_ta_init_pseudo_ta_session:310 Open device.pta
D/TC:? 0 tee_ta_init_pseudo_ta_session:327 device.pta : 7011a688-ddde-4053-a5a9-7b3c4ddf13b8
D/TC:? 0 tee_ta_close_session:468 csess 0x8b13b990 id 1
D/TC:? 0 tee_ta_close_session:487 Destroy session
D/TC:? 0 tee_ta_init_pseudo_ta_session:297 Lookup pseudo TA f04a0fe7-1f5d-4b9b-abf7-619b85b4ce8c
D/TC:? 0 mobj_phys_init:170 !va && battr != CORE_MEM_SDP_MEM
D/TC:? 0 ldelf_load_ldelf:64 shared_pmem 0x0
D/TC:? 0 ldelf_load_ldelf:113 vm_map result: -65536
D/TC:? 0 tee_ta_open_session:694 init session failed 0xffff0000
D/TC:? 0 tee_ta_init_session_with_context:566 Re-open TA 7011a688-ddde-4053-a5a9-7b3c4ddf13b8
D/TC:? 0 tee_ta_close_session:468 csess 0x8b13b840 id 1
D/TC:? 0 tee_ta_close_session:487 Destroy session

I think shared_pmem should not be 0x0, which means it has not been allocated properly, but I don't know why.

Can you tell me how should I allocate physical memory?

I am not a native English speaker. Some of the content comes from translation software's help. Thank you in advance for those who provide answers for me!

TephrocactusMYC commented 9 months ago

I made some minor modifications to my code,

if (shared_pmem == NULL) {
        shared_pmem = mobj_phys_alloc(0,
                   SHARED_SIZE, TEE_MATTR_MEM_TYPE_CACHED,
                   CORE_MEM_TEE_RAM);
    }

and now the log looks like this.

D/TC:0 0 ftmn_boot_tests:202 *************************************************
D/TC:0 0 ftmn_boot_tests:203 **************  Tests complete  *****************
D/TC:0 0 ftmn_boot_tests:204 *************************************************
D/TC:0 0 call_initcalls:40 level 7 release_probe_lists()
D/TC:0 0 call_initcalls:40 level 7 dt_test_release()
D/TC:0 0 call_finalcalls:59 level 1 release_external_dt()
I/TC: Primary CPU switching to normal world boot
I/TC: Secondary CPU 1 initializing
I/TC: Secondary CPU 1 switching to normal world boot
I/TC: Reserved shared memory is enabled
I/TC: Dynamic shared memory is enabled
I/TC: Normal World virtualization support is disabled
I/TC: Asynchronous notifications are disabled
D/TC:0 0 core_mmu_xlat_table_alloc:526 xlat tables used 7 / 8
D/TC:? 0 tee_ta_init_pseudo_ta_session:297 Lookup pseudo TA 7011a688-ddde-4053-a5a9-7b3c4ddf13b8
D/TC:? 0 tee_ta_init_pseudo_ta_session:310 Open device.pta
D/TC:? 0 tee_ta_init_pseudo_ta_session:327 device.pta : 7011a688-ddde-4053-a5a9-7b3c4ddf13b8
D/TC:? 0 tee_ta_close_session:468 csess 0xc7086990 id 1
D/TC:? 0 tee_ta_close_session:487 Destroy session
D/TC:? 0 tee_ta_init_pseudo_ta_session:297 Lookup pseudo TA f04a0fe7-1f5d-4b9b-abf7-619b85b4ce8c
D/TC:? 0 ldelf_load_ldelf:65 shared_pmem 0xc70863f0
E/TC:0 0 
E/TC:0 0 Core data-abort at address 0x10000000 (translation fault)
E/TC:0 0  esr 0x96000006  ttbr0 0x200000e1b2000   ttbr1 0x00000000   cidr 0x0
E/TC:0 0  cpu #0          cpsr 0x00000104
E/TC:0 0  x0  00000000c70863f0 x1  00000000c7085fa0
E/TC:0 0  x2  0000000000000000 x3  0000000000000000
E/TC:0 0  x4  0000000000000000 x5  00000000c7085fe0
E/TC:0 0  x6  ffffffffffffffb0 x7  000000000000bbd0
E/TC:0 0  x8  00000000c708afa0 x9  00000000c707a3c0
E/TC:0 0  x10 0000000000000000 x11 0000000000000000
E/TC:0 0  x12 0000000000000000 x13 00000000c709ec0d
E/TC:0 0  x14 0000000000000000 x15 0000000000000000
E/TC:0 0  x16 00000000c7004658 x17 0000000000000000
E/TC:0 0  x18 0000000000000000 x19 0000000000001831
E/TC:0 0  x20 00000000c7085fa0 x21 00000000c7086530
E/TC:0 0  x22 0000000000001000 x23 0000000010000000
E/TC:0 0  x24 0000000000000030 x25 0000000000000000
E/TC:0 0  x26 0000000000000000 x27 0000000000000000
E/TC:0 0  x28 00000000c70863f0 x29 00000000c709eeb0
E/TC:0 0  x30 00000000c70067a0 elr 00000000c70067b0
E/TC:0 0  sp_el0 00000000c709eeb0
E/TC:0 0 TEE load address @ 0xc6fe8000
E/TC:0 0 Call stack:
E/TC:0 0  0xc70067b0
E/TC:0 0  0xc6ffbe5c
E/TC:0 0  0xc7002464
E/TC:0 0  0xc6ffeee0
E/TC:0 0  0xc700ee44
E/TC:0 0  0xc6fee0e0
E/TC:0 0  0xc6fee52c
E/TC:0 0 Panic 'unhandled pageable abort' at core/arch/arm/kernel/abort.c:584 <abort_handler>
E/TC:0 0 TEE load address @ 0xc6fe8000
E/TC:0 0 Call stack:
E/TC:0 0  0xc6ff00ec
E/TC:0 0  0xc6ffdc2c
E/TC:0 0  0xc6fef0f8
E/TC:0 0  0xc6fec3b0

I am very puzzled by this phenomenon. How should I correctly use the function mobj_phys_alloc?

I found that the function call stack in the log only has addresses but no symbols. Can I output the symbols of the function call stack by setting certain options during compilation?

jforissier commented 9 months ago

I found that the function call stack in the log only has addresses but no symbols. Can I output the symbols of the function call stack by setting certain options during compilation?

Please see https://optee.readthedocs.io/en/latest/debug/abort_dumps.html.

TephrocactusMYC commented 9 months ago

I found that the function call stack in the log only has addresses but no symbols. Can I output the symbols of the function call stack by setting certain options during compilation?

Please see https://optee.readthedocs.io/en/latest/debug/abort_dumps.html.

Thank you very much!

github-actions[bot] commented 8 months ago

This issue has been marked as a stale issue because it has been open (more than) 30 days with no activity. Remove the stale label or add a comment, otherwise this issue will automatically be closed in 5 days. Note, that you can always re-open a closed issue at any time.