deriveCap_ret_t Arch_deriveCap(cte_t *slot, cap_t cap) { deriveCap_ret_t ret; switch (cap_get_capType(cap)) { case cap_page_table_cap: if (cap_page_table_cap_get_capPTIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving an unmapped PT cap"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_page_directory_cap: if (cap_page_directory_cap_get_capPDIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving a PD cap without an assigned ASID"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; /* This is a deviation from haskell, which has only * one frame cap type on ARM */ case cap_small_frame_cap: ret.cap = cap_small_frame_cap_set_capFMappedASID(cap, asidInvalid); ret.status = EXCEPTION_NONE; return ret; case cap_frame_cap: ret.cap = cap_frame_cap_set_capFMappedASID(cap, asidInvalid); ret.status = EXCEPTION_NONE; return ret; case cap_asid_control_cap: case cap_asid_pool_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; default: /* This assert has no equivalent in haskell, * as the options are restricted by type */ fail("Invalid arch cap"); } }
deriveCap_ret_t Arch_deriveCap(cte_t *slot, cap_t cap) { deriveCap_ret_t ret; switch (cap_get_capType(cap)) { case cap_page_global_directory_cap: if (cap_page_global_directory_cap_get_capPGDIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving a PDG cap without an assigned ASID"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_page_upper_directory_cap: if (cap_page_upper_directory_cap_get_capPUDIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving a PUD cap without an assigned ASID"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_page_directory_cap: if (cap_page_directory_cap_get_capPDIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving a PD cap without an assigned ASID"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_page_table_cap: if (cap_page_table_cap_get_capPTIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving a PT cap without an assigned ASID"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_frame_cap: ret.cap = cap_frame_cap_set_capFMappedASID(cap, asidInvalid); ret.status = EXCEPTION_NONE; return ret; case cap_asid_control_cap: case cap_asid_pool_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; #ifdef CONFIG_ARM_HYPERVISOR_SUPPORT case cap_vcpu_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; #endif default: /* This assert has no equivalent in haskell, * as the options are restricted by type */ fail("Invalid arch cap"); } }
deriveCap_ret_t Arch_deriveCap(cte_t *slot, cap_t cap) { deriveCap_ret_t ret; switch (cap_get_capType(cap)) { case cap_page_table_cap: if (cap_page_table_cap_get_capPTIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving an unmapped PT cap"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_page_directory_cap: if (cap_page_directory_cap_get_capPDIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving a PD cap without an assigned ASID"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_asid_control_cap: case cap_asid_pool_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; case cap_io_port_control_cap: ret.status = EXCEPTION_NONE; ret.cap = cap_null_cap_new(); return ret; case cap_io_port_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; #ifdef CONFIG_IOMMU case cap_io_space_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; case cap_io_page_table_cap: if (cap_io_page_table_cap_get_capIOPTIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; #endif #ifdef CONFIG_VTX case cap_vcpu_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; case cap_ept_pml4_cap: if (cap_ept_pml4_cap_get_capPML4IsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving a EPT PML4 cap without an assigned ASID."); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_ept_pdpt_cap: if (cap_ept_pdpt_cap_get_capPDPTIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving an unmapped EPT PDPT cap."); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_ept_pd_cap: if (cap_ept_pd_cap_get_capPDIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving an unmapped EPT PD cap."); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_ept_pt_cap: if (cap_ept_pt_cap_get_capPTIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving an unmapped EPT PT cap."); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; #endif default: return Mode_deriveCap(slot, cap); } }
deriveCap_ret_t Arch_deriveCap(cte_t* slot, cap_t cap) { deriveCap_ret_t ret; switch (cap_get_capType(cap)) { case cap_page_table_cap: if (cap_page_table_cap_get_capPTIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving an unmapped PT cap"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_page_directory_cap: if (cap_page_directory_cap_get_capPDIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { userError("Deriving a PD cap without an assigned ASID"); current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; case cap_frame_cap: #ifdef CONFIG_IOMMU cap = cap_frame_cap_set_capFIsIOSpace(cap, 0); #endif ret.cap = cap_frame_cap_set_capFMappedASID(cap, asidInvalid); ret.status = EXCEPTION_NONE; return ret; case cap_asid_control_cap: case cap_asid_pool_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; case cap_io_port_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; #ifdef CONFIG_IOMMU case cap_io_space_cap: ret.cap = cap; ret.status = EXCEPTION_NONE; return ret; case cap_io_page_table_cap: if (cap_io_page_table_cap_get_capIOPTIsMapped(cap)) { ret.cap = cap; ret.status = EXCEPTION_NONE; } else { current_syscall_error.type = seL4_IllegalOperation; ret.cap = cap_null_cap_new(); ret.status = EXCEPTION_SYSCALL_ERROR; } return ret; #endif default: /* This assert has no equivalent in haskell, * as the options are restricted by type */ fail("Invalid arch cap type"); } }