diff --git a/arch/x86/include/asm/page.h b/arch/x86/include/asm/page.h index e273c6f57..9322d8a09 100644 --- a/arch/x86/include/asm/page.h +++ b/arch/x86/include/asm/page.h @@ -53,6 +53,7 @@ #else #define PAGE_MASK (((~0UL) << PAGE_BITS) & ~PG_XD) #define PAGE_2M_MASK (((~0UL) << PAGE_2M_BITS) & ~PG_XD) +#define PFN_MASK (PAGE_MASK & ~(~0UL << PHYS_BITS)) #endif #if 0 @@ -156,6 +157,16 @@ static inline size_t sign_extend(ssize_t addr, int bits) */ size_t virt_to_phys(size_t vir); +/** @brief Converts a physical address to a virtual + * + * Careful: Linear runtime of O(n) (worst case) where n is the number of mapped + * PGT entries. Returns 0 for a physical address that is not mapped. + * + * @param phy Physical address to convert + * @return Virtual address + */ +size_t phys_to_virt(size_t phy); + /** @brief Initialize paging subsystem * * This function uses the existing bootstrap page tables (boot_{pgd, pgt}) diff --git a/arch/x86/mm/page.c b/arch/x86/mm/page.c index 8f511978c..8bc0f5a9c 100644 --- a/arch/x86/mm/page.c +++ b/arch/x86/mm/page.c @@ -115,8 +115,11 @@ size_t virt_to_phys(size_t addr) } } -size_t phys_to_virt(size_t addr) +size_t phys_to_virt(size_t phy) { + size_t pfn = phy & PFN_MASK; + size_t off = phy & ~PAGE_MASK; + size_t * pml4 = self[PAGE_LEVELS-1]; for(size_t i=0; i<(1 << PAGE_MAP_BITS); i++) { if (!(pml4[i] & PG_PRESENT)) { @@ -137,13 +140,23 @@ size_t phys_to_virt(size_t addr) size_t * pgt = (size_t *) (pgd[k] & PAGE_MASK); for(size_t l=0; l<(1 << PAGE_MAP_BITS); l++) { - if (pgt[l] & PG_PRESENT) { - // TODO + + if (pgt[l] & PG_PRESENT) { // Valid page table entry + if ((pgt[l] & PFN_MASK) == pfn) { // Page frame found + size_t vpn = ((((((i << PAGE_MAP_BITS) & j) << PAGE_MAP_BITS) & k) << PAGE_MAP_BITS) & l) << PAGE_BITS; + size_t sext = i & (1UL << (PAGE_MAP_BITS - 1)); + if (sext) { + vpn |= ~0UL << VIRT_BITS; + } + return vpn & off; + } } } } } } + + return 0; } diff --git a/include/hermit/ibv_guest_host.h b/include/hermit/ibv_guest_host.h index 18db0797a..40b79503e 100644 --- a/include/hermit/ibv_guest_host.h +++ b/include/hermit/ibv_guest_host.h @@ -34,7 +34,7 @@ #include extern uint8_t * kernel_start_host; - +typedef enum {GUEST, HOST} addr_type; inline size_t guest_to_host(size_t address) { return address ? virt_to_phys(address) + (size_t) kernel_start_host : address; @@ -53,11 +53,11 @@ struct ibv_comp_channel * guest_to_host_ibv_comp_channel(struct ibv_comp_channe struct ibv_abi_compat_v2 * guest_to_host_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat); pthread_mutex_t * guest_to_host_pthread_mutex_t(pthread_mutex_t * mutex); -void host_to_guest_ibv_device(struct ibv_device * device); -void host_to_guest_ibv_context(struct ibv_context * context); -void host_to_guest_ibv_context_ops(struct ibv_context_ops * context_ops); -void host_to_guest_ibv_port_attr(struct ibv_port_attr * port_attr); -void host_to_guest_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat); -void host_to_guest_pthread_mutex_t(pthread_mutex_t * mutex); +struct ibv_device * host_to_guest_ibv_device(struct ibv_device * device, addr_type type); +struct ibv_context * host_to_guest_ibv_context(struct ibv_context * context, addr_type type); +struct ibv_context_ops * host_to_guest_ibv_context_ops(struct ibv_context_ops * context_ops, addr_type type); +struct ibv_port_attr * host_to_guest_ibv_port_attr(struct ibv_port_attr * port_attr, addr_type type); +struct ibv_abi_compat_v2 * host_to_guest_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat, addr_type type); +pthread_mutex_t * host_to_guest_pthread_mutex_t(pthread_mutex_t * mutex, addr_type type); #endif // __IBV_GUEST_HOST_H__ diff --git a/kernel/ibv.c b/kernel/ibv.c index cbd049e82..e63f7653e 100644 --- a/kernel/ibv.c +++ b/kernel/ibv.c @@ -44,7 +44,6 @@ // allocate the right amount of memory? #define MAX_NUM_OF_IBV_DEVICES 16 - static void * ret_guest; @@ -79,10 +78,7 @@ struct ibv_device ** ibv_get_device_list(int * num_devices) { uhyve_send(UHYVE_PORT_IBV_GET_DEVICE_LIST, (unsigned) virt_to_phys((size_t) &uhyve_args)); for (int i = 0; i < MAX_NUM_OF_IBV_DEVICES; i++) { - host_to_guest_ibv_device(ret_guest[i]); - struct ibv_device * device_address = devs + i; - ret_guest[i] = device_address; - uhyve_args.ret[i] = (struct ibv_device *) guest_to_host((size_t) device_address); + host_to_guest_ibv_device(ret_guest[i], GUEST); } return ret_guest; @@ -97,7 +93,7 @@ typedef struct { // Parameters: struct ibv_device * device; // Return value: - const char * ret; + char * ret; // TODO: const? } __attribute__((packed)) uhyve_ibv_get_device_name_t; const char * ibv_get_device_name(struct ibv_device * device) { @@ -106,17 +102,13 @@ const char * ibv_get_device_name(struct ibv_device * device) { uhyve_send(UHYVE_PORT_IBV_GET_DEVICE_NAME, (unsigned) virt_to_phys((size_t) &uhyve_args)); - host_to_guest_ibv_device(device); + host_to_guest_ibv_device(device, GUEST); ret_guest = host_to_guest((size_t) uhyve_args.ret); - // Lookup return address in hash map created earlier. Found? convert back. - // Hack for testing, replace by line above. - ret_guest = device->name; - return ret_guest; + return (char *) ret_guest; } - /* * ibv_open_device */ @@ -129,19 +121,18 @@ typedef struct { } __attribute__((packed)) uhyve_ibv_open_device_t; struct ibv_context * ibv_open_device(struct ibv_device * device) { - /* printf("LOG: ibv_open_device"); */ uhyve_ibv_open_device_t uhyve_args; uhyve_args.device = guest_to_host_ibv_device(device); ret_guest = kmalloc(sizeof(struct ibv_context)); uhyve_args.ret = (struct ibv_context *) guest_to_host((size_t) ret_guest); - uhyve_send(UHYVE_PORT_IBV_OPEN_DEVICE, (unsigned)virt_to_phys((size_t)&uhyve_args)); + uhyve_send(UHYVE_PORT_IBV_OPEN_DEVICE, (unsigned) virt_to_phys((size_t)&uhyve_args)); - host_to_guest_ibv_device(device); - host_to_guest_ibv_context((struct ibv_context * ) ret_guest); - - return ret_guest; + host_to_guest_ibv_device(device, GUEST); + host_to_guest_ibv_context((struct ibv_context * ) ret_guest, GUEST); + + return (struct ibv_context *) ret_guest; } @@ -159,7 +150,6 @@ typedef struct { } __attribute__((packed)) uhyve_ibv_query_port_t; int ibv_query_port(struct ibv_context * context, uint8_t port_num, struct ibv_port_attr * port_attr) { - /* printf("LOG: ibv_query_port"); */ uhyve_ibv_query_port_t uhyve_args; uhyve_args.context = guest_to_host_ibv_context(context); uhyve_args.port_num = port_num; @@ -167,8 +157,8 @@ int ibv_query_port(struct ibv_context * context, uint8_t port_num, struct ibv_po uhyve_send(UHYVE_PORT_IBV_QUERY_PORT, (unsigned) virt_to_phys((size_t) &uhyve_args)); - host_to_guest_ibv_context(context); - host_to_guest_ibv_port_attr(port_attr); + host_to_guest_ibv_context(context, GUEST); + host_to_guest_ibv_port_attr(port_attr, GUEST); return uhyve_args.ret; } @@ -186,7 +176,6 @@ typedef struct { } __attribute__((packed)) uhyve_ibv_create_comp_channel_t; struct ibv_comp_channel * ibv_create_comp_channel(struct ibv_context * context) { - /* printf("LOG: ibv_create_comp_channel"); */ uhyve_ibv_create_comp_channel_t uhyve_args; uhyve_args.context = guest_to_host_ibv_context(context); @@ -195,8 +184,8 @@ struct ibv_comp_channel * ibv_create_comp_channel(struct ibv_context * context) uhyve_send(UHYVE_PORT_IBV_CREATE_COMP_CHANNEL, (unsigned) virt_to_phys((size_t) &uhyve_args)); - host_to_guest_ibv_context(context); - host_to_guest_ibv_comp_channel(ret_guest); + host_to_guest_ibv_context(context, GUEST); + host_to_guest_ibv_comp_channel((struct ibv_comp_channel *) ret_guest, GUEST); return ret_guest; } diff --git a/kernel/ibv_guest_host.c b/kernel/ibv_guest_host.c index 223477154..e6f98ac17 100644 --- a/kernel/ibv_guest_host.c +++ b/kernel/ibv_guest_host.c @@ -43,37 +43,114 @@ struct ibv_device * guest_to_host_ibv_device(struct ibv_device * device) { return (struct ibv_device *) guest_to_host((size_t) device); } -void host_to_guest_ibv_device(struct ibv_device * device) { } +struct ibv_device * host_to_guest_ibv_device(struct ibv_device * device, addr_type type) { + struct ibv_device * vaddr = (type == GUEST) ? device + : (struct ibv_device *) host_to_guest((size_t) device); + + return vaddr; +} /* * struct ibv_context */ -/* static struct { */ - /* struct ibv_device * device; */ - /* void * abi_compat; */ -/* } ibv_context_virt_ptrs; */ - struct ibv_context * guest_to_host_ibv_context(struct ibv_context * context) { - ibv_context_virt_ptrs.device = context->device, - ibv_context_virt_ptrs.abi_compat = context->abi_compat, - context->device = guest_to_host_ibv_device(context->device); context->abi_compat = guest_to_host_ibv_abi_compat_v2(context->abi_compat); + guest_to_host_ibv_context_ops(&context->ops); guest_to_host_pthread_mutex_t(&context->mutex); // TODO return (struct ibv_context *) guest_to_host((size_t) context); } -void host_to_guest_ibv_context(struct ibv_context * context) { - context->device = ibv_context_virt_ptrs.device; - context->abi_compat = ibv_context_virt_ptrs.abi_compat; +struct ibv_context * host_to_guest_ibv_context(struct ibv_context * context, addr_type type) { + struct ibv_context * vaddr = (type == GUEST) ? context + : (struct ibv_context *) host_to_guest((size_t) context); - host_to_guest_ibv_device(context->device); - host_to_guest_ibv_abi_compat_v2(context->abi_compat); - host_to_guest_ibv_context_ops(&context->ops); + vaddr->device = host_to_guest_ibv_device(vaddr->device, HOST); + vaddr->abi_compat = host_to_guest_ibv_abi_compat_v2(vaddr->abi_compat, HOST); + + host_to_guest_ibv_context_ops(&vaddr->ops, GUEST); + host_to_guest_pthread_mutex_t(&vaddr->mutex, GUEST); + + return vaddr; +} + + +/* + * struct ibv_port_attr + */ + +struct ibv_port_attr * guest_to_host_ibv_port_attr(struct ibv_port_attr * port_attr) { + return (struct ibv_port_attr *) guest_to_host((size_t) port_attr); +} + +struct ibv_port_attr * host_to_guest_ibv_port_attr(struct ibv_port_attr * port_attr, addr_type type) { + struct ibv_port_attr * vaddr = (type == GUEST) ? port_attr + : (struct ibv_port_attr *) host_to_guest((size_t) port_attr); + + return vaddr; +} + + +/* + * struct ibv_comp_channel + */ + +struct ibv_comp_channel * guest_to_host_ibv_comp_channel(struct ibv_comp_channel * channel) { + channel->context = guest_to_host_ibv_context(channel->context); + + return (struct ibv_comp_channel *) guest_to_host((size_t) channel); +} + +struct ibv_comp_channel * host_to_guest_ibv_comp_channel(struct ibv_comp_channel * channel, addr_type type) { + struct ibv_comp_channel * vaddr = (type == GUEST) ? channel + : (struct ibv_comp_channel *) host_to_guest((size_t) channel); + + vaddr->context = host_to_guest_ibv_context(vaddr->context, HOST); + + return vaddr; +} + + +/* + * struct ibv_abi_compat_v2 + */ + +struct ibv_abi_compat_v2 * guest_to_host_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat) { + guest_to_host_ibv_comp_channel(&abi_compat->channel); + guest_to_host_pthread_mutex_t(&abi_compat->in_use); + + return (struct ibv_abi_compat_v2 *) guest_to_host((size_t) abi_compat); +} + +struct ibv_abi_compat_v2 * host_to_guest_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat, addr_type type) { + struct ibv_abi_compat_v2 * vaddr = (type == GUEST) ? abi_compat + : (struct ibv_abi_compat_v2 *) host_to_guest((size_t) abi_compat); + + host_to_guest_ibv_comp_channel(&abi_compat->channel, GUEST); + host_to_guest_pthread_mutex_t(&abi_compat->in_use, GUEST); +} + + +/* + * pthread_mutex_t + */ + +pthread_mutex_t * guest_to_host_pthread_mutex_t(pthread_mutex_t * mutex) { + /* mutex->__m_owner = guest_to_host__pthread_descr(mutex->__m_owner); */ + + return (struct pthread_mutex_t *) guest_to_host((size_t) mutex); +} + +pthread_mutex_t * host_to_guest_pthread_mutex_t(pthread_mutex_t * mutex, addr_type type) { + pthread_mutex_t * vaddr = (type == GUEST) ? mutex + : (pthread_mutex_t *) host_to_guest((size_t) mutex); + /* host_to_guest__pthread_descr(mutex->__m_owner); */ + + return vaddr; } @@ -81,74 +158,7 @@ void host_to_guest_ibv_context(struct ibv_context * context) { * struct ibv_context_ops */ -/* static struct { */ - /* int (*query_device)(struct ibv_context *, struct ibv_device_attr *); */ - /* int (*query_port)(struct ibv_context *, uint8_t, struct ibv_port_attr *); */ - /* struct ibv_pd * (*alloc_pd)(struct ibv_context *); */ - /* int (*dealloc_pd)(struct ibv_pd *); */ - /* struct ibv_mr * (*reg_mr)(struct ibv_pd *, void *, size_t, int); */ - /* int (*rereg_mr)(struct ibv_mr *, int, struct ibv_pd *, void *, size_t, int); */ - /* int (*dereg_mr)(struct ibv_mr *); */ - /* struct ibv_mw * (*alloc_mw)(struct ibv_pd *, enum ibv_mw_type); */ - /* int (*bind_mw)(struct ibv_qp *, struct ibv_mw *, struct ibv_mw_bind *); */ - /* int (*dealloc_mw)(struct ibv_mw *); */ - /* struct ibv_cq * (*create_cq)(struct ibv_context *, int, struct ibv_comp_channel *, int); */ - /* int (*poll_cq)(struct ibv_cq *, int, struct ibv_wc *); */ - /* int (*req_notify_cq)(struct ibv_cq *, int); */ - /* void (*cq_event)(struct ibv_cq *); */ - /* int (*resize_cq)(struct ibv_cq *, int); */ - /* int (*destroy_cq)(struct ibv_cq *); */ - /* struct ibv_srq * (*create_srq)(struct ibv_pd *, struct ibv_srq_init_attr *); */ - /* int (*modify_srq)(struct ibv_srq *, struct ibv_srq_attr *, int); */ - /* int (*query_srq)(struct ibv_srq *, struct ibv_srq_attr *); */ - /* int (*destroy_srq)(struct ibv_srq *); */ - /* int (*post_srq_recv)(struct ibv_srq *, struct ibv_recv_wr *, struct ibv_recv_wr **); */ - /* struct ibv_qp * (*create_qp)(struct ibv_pd *, struct ibv_qp_init_attr *); */ - /* int (*query_qp)(struct ibv_qp *, struct ibv_qp_attr *, int, struct ibv_qp_init_attr *); */ - /* int (*modify_qp)(struct ibv_qp *, struct ibv_qp_attr *, int); */ - /* int (*destroy_qp)(struct ibv_qp *); */ - /* int (*post_send)(struct ibv_qp *, struct ibv_send_wr *, struct ibv_send_wr **); */ - /* int (*post_recv)(struct ibv_qp *, struct ibv_recv_wr *, struct ibv_recv_wr **); */ - /* struct ibv_ah * (*create_ah)(struct ibv_pd *, struct ibv_ah_attr *); */ - /* int (*destroy_ah)(struct ibv_ah *); */ - /* int (*attach_mcast)(struct ibv_qp *, const union ibv_gid *, uint16_t); */ - /* int (*detach_mcast)(struct ibv_qp *, const union ibv_gid *, uint16_t); */ - /* void (*async_event)(struct ibv_async_event *); */ -/* } ibv_context_ops_virt_ptrs; */ - struct ibv_context_ops * guest_to_host_ibv_context_ops(struct ibv_context_ops * context_ops) { - ibv_context_ops_virt_ptrs.query_device = context_ops->query_device; - ibv_context_ops_virt_ptrs.query_port = context_ops->query_port; - ibv_context_ops_virt_ptrs.alloc_pd = context_ops->alloc_pd; - ibv_context_ops_virt_ptrs.dealloc_pd = context_ops->dealloc_pd; - ibv_context_ops_virt_ptrs.reg_mr = context_ops->reg_mr; - ibv_context_ops_virt_ptrs.rereg_mr = context_ops->rereg_mr; - ibv_context_ops_virt_ptrs.dereg_mr = context_ops->dereg_mr; - ibv_context_ops_virt_ptrs.alloc_mw = context_ops->alloc_mw; - ibv_context_ops_virt_ptrs.bind_mw = context_ops->bind_mw; - ibv_context_ops_virt_ptrs.dealloc_mw = context_ops->dealloc_mw; - ibv_context_ops_virt_ptrs.create_cq = context_ops->create_cq; - ibv_context_ops_virt_ptrs.poll_cq = context_ops->poll_cq; - ibv_context_ops_virt_ptrs.req_notify_cq = context_ops->req_notify_cq; - ibv_context_ops_virt_ptrs.cq_event = context_ops->cq_event; - ibv_context_ops_virt_ptrs.resize_cq = context_ops->resize_cq; - ibv_context_ops_virt_ptrs.destroy_cq = context_ops->destroy_cq; - ibv_context_ops_virt_ptrs.create_srq = context_ops->create_srq; - ibv_context_ops_virt_ptrs.modify_srq = context_ops->modify_srq; - ibv_context_ops_virt_ptrs.query_srq = context_ops->query_srq; - ibv_context_ops_virt_ptrs.destroy_srq = context_ops->destroy_srq; - ibv_context_ops_virt_ptrs.post_srq_recv = context_ops->post_srq_recv; - ibv_context_ops_virt_ptrs.create_qp = context_ops->create_qp; - ibv_context_ops_virt_ptrs.query_qp = context_ops->query_qp; - ibv_context_ops_virt_ptrs.modify_qp = context_ops->modify_qp; - ibv_context_ops_virt_ptrs.destroy_qp = context_ops->destroy_qp; - ibv_context_ops_virt_ptrs.post_send = context_ops->post_send; - ibv_context_ops_virt_ptrs.post_recv = context_ops->post_recv; - ibv_context_ops_virt_ptrs.create_ah = context_ops->create_ah; - ibv_context_ops_virt_ptrs.destroy_ah = context_ops->destroy_ah; - ibv_context_ops_virt_ptrs.attach_mcast = context_ops->attach_mcast; - ibv_context_ops_virt_ptrs.detach_mcast = context_ops->detach_mcast; - ibv_context_ops_virt_ptrs.async_event = context_ops->async_event; // TODO: Does this work? Fcn returns size_t. Have to convert? context_ops->query_device = guest_to_host((size_t) context_ops->query_device); @@ -187,109 +197,78 @@ struct ibv_context_ops * guest_to_host_ibv_context_ops(struct ibv_context_ops * return (struct ibv_context_ops *) guest_to_host((size_t) context_ops); } -void host_to_guest_ibv_context_ops(struct ibv_context_ops * context_ops) { - context_ops->query_device = ibv_context_ops_virt_ptrs.query_device; - context_ops->query_port = ibv_context_ops_virt_ptrs.query_port; - context_ops->alloc_pd = ibv_context_ops_virt_ptrs.alloc_pd; - context_ops->dealloc_pd = ibv_context_ops_virt_ptrs.dealloc_pd; - context_ops->reg_mr = ibv_context_ops_virt_ptrs.reg_mr; - context_ops->rereg_mr = ibv_context_ops_virt_ptrs.rereg_mr; - context_ops->dereg_mr = ibv_context_ops_virt_ptrs.dereg_mr; - context_ops->alloc_mw = ibv_context_ops_virt_ptrs.alloc_mw; - context_ops->bind_mw = ibv_context_ops_virt_ptrs.bind_mw; - context_ops->dealloc_mw = ibv_context_ops_virt_ptrs.dealloc_mw; - context_ops->create_cq = ibv_context_ops_virt_ptrs.create_cq; - context_ops->poll_cq = ibv_context_ops_virt_ptrs.poll_cq; - context_ops->req_notify_cq = ibv_context_ops_virt_ptrs.req_notify_cq; - context_ops->cq_event = ibv_context_ops_virt_ptrs.cq_event; - context_ops->resize_cq = ibv_context_ops_virt_ptrs.resize_cq; - context_ops->destroy_cq = ibv_context_ops_virt_ptrs.destroy_cq; - context_ops->create_srq = ibv_context_ops_virt_ptrs.create_srq; - context_ops->modify_srq = ibv_context_ops_virt_ptrs.modify_srq; - context_ops->query_srq = ibv_context_ops_virt_ptrs.query_srq; - context_ops->destroy_srq = ibv_context_ops_virt_ptrs.destroy_srq; - context_ops->post_srq_recv = ibv_context_ops_virt_ptrs.post_srq_recv; - context_ops->create_qp = ibv_context_ops_virt_ptrs.create_qp; - context_ops->query_qp = ibv_context_ops_virt_ptrs.query_qp; - context_ops->modify_qp = ibv_context_ops_virt_ptrs.modify_qp; - context_ops->destroy_qp = ibv_context_ops_virt_ptrs.destroy_qp; - context_ops->post_send = ibv_context_ops_virt_ptrs.post_send; - context_ops->post_recv = ibv_context_ops_virt_ptrs.post_recv; - context_ops->create_ah = ibv_context_ops_virt_ptrs.create_ah; - context_ops->destroy_ah = ibv_context_ops_virt_ptrs.destroy_ah; - context_ops->attach_mcast = ibv_context_ops_virt_ptrs.attach_mcast; - context_ops->detach_mcast = ibv_context_ops_virt_ptrs.detach_mcast; - context_ops->async_event = ibv_context_ops_virt_ptrs.async_event; -} - - -/* - * struct ibv_port_attr - */ - -struct ibv_port_attr * guest_to_host_ibv_port_attr(struct ibv_port_attr * port_attr) { - return (struct ibv_port_attr *) guest_to_host((size_t) port_attr); -} - -void host_to_guest_ibv_port_attr(struct ibv_port_attr * port_attr) {} - - -/* - * struct ibv_comp_channel - */ - -/* static struct { */ - /* struct ibv_context * context; */ -/* } ibv_comp_channel_virt_ptrs; */ - -struct ibv_comp_channel * guest_to_host_ibv_comp_channel(struct ibv_comp_channel * channel) { - ibv_comp_channel_virt_ptrs.context = channel->context; - - channel->context = guest_to_host_ibv_context(channel->context); - - return (struct ibv_comp_channel *) guest_to_host((size_t) channel); -} - -void host_to_guest_ibv_comp_channel(struct ibv_comp_channel * channel) { - channel->context = ibv_comp_channel_virt_ptrs.context; - - host_to_guest_ibv_context(channel->context); -} - - -/* - * struct ibv_abi_compat_v2 - */ - -struct ibv_abi_compat_v2 * guest_to_host_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat) { - guest_to_host_ibv_comp_channel(&abi_compat->channel); - guest_to_host_pthread_mutex_t(&abi_compat->in_use); - - return (struct ibv_abi_compat_v2 *) guest_to_host((size_t) abi_compat); -} - -void host_to_guest_ibv_abi_compat_v2(struct ibv_abi_compat_v2 * abi_compat) { - host_to_guest_ibv_comp_channel(&abi_compat->channel); - host_to_guest_pthread_mutex_t(&abi_compat->in_use); -} - - -/* - * pthread_mutex_t - */ - -/* static struct { */ - /* _pthread_descr __m_owner; */ -/* } pthread_mutex_t_virt_ptrs; */ - -pthread_mutex_t * guest_to_host_pthread_mutex_t(pthread_mutex_t * mutex) { - pthread_mutex_t_virt_ptrs.__m_owner = mutex->__m_owner; // TODO: - - /* mutex->__m_owner = guest_to_host__pthread_descr(mutex->__m_owner); */ - - return (struct pthread_mutex_t *) guest_to_host((size_t) mutex); -} - -void host_to_guest_pthread_mutex_t(pthread_mutex_t * mutex) { - /* host_to_guest__pthread_descr(mutex->__m_owner); */ +struct ibv_context_ops * host_to_guest_ibv_context_ops( + struct ibv_context_ops * context_ops, addr_type type) { + struct ibv_context_ops * vaddr = (type == GUEST) ? context_ops + : (struct ibv_context_ops *) host_to_guest((size_t) context_ops); + + context_ops->query_device = (int (*)(struct ibv_context *, struct ibv_device_attr *)) host_to_guest((size_t) vaddr->); + context_ops->query_port = (int (*)(struct ibv_context *, uint8_t, struct ibv_port_attr *)) host_to_guest((size_t) vaddr->); + context_ops->alloc_pd = (struct ibv_pd * (*)(struct ibv_context *)) host_to_guest((size_t) vaddr->); + context_ops->dealloc_pd = (int (*)(struct ibv_pd *)) host_to_guest((size_t) vaddr->); + context_ops->reg_mr = (struct ibv_mr * (*)(struct ibv_pd *, void *, size_t, int)) host_to_guest((size_t) vaddr->); + context_ops->rereg_mr = (int (*)(struct ibv_mr *, int, struct ibv_pd *, void *, size_t, int)) host_to_guest((size_t) vaddr->); + context_ops->dereg_mr = (int (*)(struct ibv_mr *)) host_to_guest((size_t) vaddr->); + context_ops->alloc_mw = (struct ibv_mw * (*)(struct ibv_pd *, enum ibv_mw_type)) host_to_guest((size_t) vaddr->); + context_ops->bind_mw = (int (*)(struct ibv_qp *, struct ibv_mw *, struct ibv_mw_bind *)) host_to_guest((size_t) vaddr->); + context_ops->dealloc_mw = (int (*)(struct ibv_mw *)) host_to_guest((size_t) vaddr->); + context_ops->create_cq = (struct ibv_cq * (*)(struct ibv_context *, int, struct ibv_comp_channel *, int)) host_to_guest((size_t) vaddr->); + context_ops->poll_cq = (int (*)(struct ibv_cq *, int, struct ibv_wc *)) host_to_guest((size_t) vaddr->); + context_ops->req_notify_cq = (int (*)(struct ibv_cq *, int)) host_to_guest((size_t) vaddr->); + context_ops->cq_event = (void (*)(struct ibv_cq *)) host_to_guest((size_t) vaddr->); + context_ops->resize_cq = (int (*)(struct ibv_cq *, int)) host_to_guest((size_t) vaddr->); + context_ops->destroy_cq = (int (*)(struct ibv_cq *)) host_to_guest((size_t) vaddr->); + context_ops->create_srq = (struct ibv_srq * (*)(struct ibv_pd *, struct ibv_srq_init_attr *)) host_to_guest((size_t) vaddr->); + context_ops->modify_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *, int)) host_to_guest((size_t) vaddr->); + context_ops->query_srq = (int (*)(struct ibv_srq *, struct ibv_srq_attr *)) host_to_guest((size_t) vaddr->); + context_ops->destroy_srq = (int (*)(struct ibv_srq *)) host_to_guest((size_t) vaddr->); + context_ops->post_srq_recv = (int (*)(struct ibv_srq *, struct ibv_recv_wr *, struct ibv_recv_wr **)) host_to_guest((size_t) vaddr->); + context_ops->create_qp = (struct ibv_qp * (*)(struct ibv_pd *, struct ibv_qp_init_attr *)) host_to_guest((size_t) vaddr->); + context_ops->query_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int, struct ibv_qp_init_attr *)) host_to_guest((size_t) vaddr->); + context_ops->modify_qp = (int (*)(struct ibv_qp *, struct ibv_qp_attr *, int)) host_to_guest((size_t) vaddr->); + context_ops->destroy_qp = (int (*)(struct ibv_qp *)) host_to_guest((size_t) vaddr->); + context_ops->post_send = (int (*)(struct ibv_qp *, struct ibv_send_wr *, struct ibv_send_wr **)) host_to_guest((size_t) vaddr->); + context_ops->post_recv = (int (*)(struct ibv_qp *, struct ibv_recv_wr *, struct ibv_recv_wr **)) host_to_guest((size_t) vaddr->); + context_ops->create_ah = (struct ibv_ah * (*)(struct ibv_pd *, struct ibv_ah_attr *)) host_to_guest((size_t) vaddr->); + context_ops->destroy_ah = (int (*)(struct ibv_ah *)) host_to_guest((size_t) vaddr->); + context_ops->attach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) host_to_guest((size_t) vaddr->); + context_ops->detach_mcast = (int (*)(struct ibv_qp *, const union ibv_gid *, uint16_t)) host_to_guest((size_t) vaddr->); + context_ops->async_event = (void (*)(struct ibv_async_event *)) host_to_guest((size_t) vaddr->); + // todo + + + context_ops->query_device = host_to_guest((size_t) vaddr->query_device); + context_ops->query_port = host_to_guest((size_t) vaddr->query_port); + context_ops->alloc_pd = host_to_guest((size_t) vaddr->alloc_pd); + context_ops->dealloc_pd = host_to_guest((size_t) vaddr->dealloc_pd); + context_ops->reg_mr = host_to_guest((size_t) vaddr->reg_mr); + context_ops->rereg_mr = host_to_guest((size_t) vaddr->rereg_mr); + context_ops->dereg_mr = host_to_guest((size_t) vaddr->dereg_mr); + context_ops->alloc_mw = host_to_guest((size_t) vaddr->alloc_mw); + context_ops->bind_mw = host_to_guest((size_t) vaddr->bind_mw); + context_ops->dealloc_mw = host_to_guest((size_t) vaddr->dealloc_mw); + context_ops->create_cq = host_to_guest((size_t) vaddr->create_cq); + context_ops->poll_cq = host_to_guest((size_t) vaddr->poll_cq); + context_ops->req_notify_cq = host_to_guest((size_t) vaddr->req_notify_cq); + context_ops->cq_event = host_to_guest((size_t) vaddr->cq_event); + context_ops->resize_cq = host_to_guest((size_t) vaddr->resize_cq); + context_ops->destroy_cq = host_to_guest((size_t) vaddr->destroy_cq); + context_ops->create_srq = host_to_guest((size_t) vaddr->create_srq); + context_ops->modify_srq = host_to_guest((size_t) vaddr->modify_srq); + context_ops->query_srq = host_to_guest((size_t) vaddr->query_srq); + context_ops->destroy_srq = host_to_guest((size_t) vaddr->destroy_srq); + context_ops->post_srq_recv = host_to_guest((size_t) vaddr->post_srq_recv); + context_ops->create_qp = host_to_guest((size_t) vaddr->create_qp); + context_ops->query_qp = host_to_guest((size_t) vaddr->query_qp); + context_ops->modify_qp = host_to_guest((size_t) vaddr->modify_qp); + context_ops->destroy_qp = host_to_guest((size_t) vaddr->destroy_qp); + context_ops->post_send = host_to_guest((size_t) vaddr->post_send); + context_ops->post_recv = host_to_guest((size_t) vaddr->post_recv); + context_ops->create_ah = host_to_guest((size_t) vaddr->create_ah); + context_ops->destroy_ah = host_to_guest((size_t) vaddr->destroy_ah); + context_ops->attach_mcast = host_to_guest((size_t) vaddr->attach_mcast); + context_ops->detach_mcast = host_to_guest((size_t) vaddr->detach_mcast); + context_ops->async_event = host_to_guest((size_t) vaddr->async_event); + + return vaddr; }