Skip to content

Commit

Permalink
argo-linux: forward port to v8 of the series, and add ARM32 driver
Browse files Browse the repository at this point in the history
Signed-off-by: Christopher Clark <[email protected]>
  • Loading branch information
dozylynx authored and dpsmith committed Feb 16, 2019
1 parent cee9284 commit 3ca4ab9
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 71 deletions.
6 changes: 4 additions & 2 deletions argo-linux/Kbuild
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
obj-m += argo.o
obj-m += xen-argo.o

xen-argo-y := argo-module.o
xen-argo-$(CONFIG_ARM) += argo-hypercall.o

ccflags-y := -I$(src)/include
#ccflags-$(CONFIG_X86_32) += -fomit-frame-pointer
35 changes: 35 additions & 0 deletions argo-linux/argo-hypercall.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/opcodes-virt.h>
#include <xen/interface/xen.h>

#ifndef HYPERVISOR_argo_op
#define __HYPERVISOR_argo_op 39
#endif

#define XEN_IMM 0xEA1

#define HYPERCALL_SIMPLE(hypercall) \
ENTRY(HYPERVISOR_##hypercall) \
mov r12, #__HYPERVISOR_##hypercall; \
__HVC(XEN_IMM); \
ret lr; \
ENDPROC(HYPERVISOR_##hypercall)

#define HYPERCALL0 HYPERCALL_SIMPLE
#define HYPERCALL1 HYPERCALL_SIMPLE
#define HYPERCALL2 HYPERCALL_SIMPLE
#define HYPERCALL3 HYPERCALL_SIMPLE
#define HYPERCALL4 HYPERCALL_SIMPLE

#define HYPERCALL5(hypercall) \
ENTRY(HYPERVISOR_##hypercall) \
stmdb sp!, {r4}; \
ldr r4, [sp, #4]; \
mov r12, #__HYPERVISOR_##hypercall; \
__HVC(XEN_IMM); \
ldm sp!, {r4}; \
ret lr; \
ENDPROC(HYPERVISOR_##hypercall)

HYPERCALL5(argo_op);
84 changes: 34 additions & 50 deletions argo-linux/argo.c → argo-linux/argo-module.c
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ summary_ring (struct ring *r)
{
printk(KERN_ERR "ring at %p:\n", r);

printk(KERN_ERR " xen_argo_gfn_array_t at %p for %d:\n",
printk(KERN_ERR " xen_pfn_array_t at %p for %d:\n",
r->gfn_array, r->npfns);

printk(KERN_ERR " xen_argo_ring_t at %p:\n", r->ring);
Expand Down Expand Up @@ -688,6 +688,8 @@ H_argo_sendv(xen_argo_addr_t *s, xen_argo_addr_t *d,
xen_argo_send_addr_t send;
send.dst = *d;
send.src = *s;
send.src.pad = 0;
send.dst.pad = 0;
return HYPERVISOR_argo_op(XEN_ARGO_OP_sendv,
&send, (void *)iovs, niov, protocol);
}
Expand Down Expand Up @@ -802,7 +804,11 @@ refresh_gfn_array(struct ring *r)

for ( i = 0; i < r->npfns; ++i )
{
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)
r->gfn_array[i] = pfn_to_mfn(vmalloc_to_pfn(b));
#else
r->gfn_array[i] = pfn_to_gfn(vmalloc_to_pfn(b));
#endif
b += PAGE_SIZE;
}
}
Expand Down Expand Up @@ -1227,13 +1233,9 @@ xmit_queue_inline(struct argo_ring_id *from, xen_argo_addr_t *to,
argo_spin_lock_irqsave (&pending_xmit_lock, flags);
DEBUG_APPLE;

/* HACK to fix sign extension */
if ( sizeof(void *) == sizeof(uint32_t) )
iov.iov_hnd = (uint64_t) (uint32_t) (uintptr_t) buf;
/* FIXME: need double-check the above is correct on 32-bit */
#ifdef CONFIG_X86_64
else
iov.iov_hnd = (uint64_t) (uintptr_t) buf;
iov.iov_hnd = buf;
#ifdef CONFIG_ARM
iov.pad2 = 0;
#endif

iov.iov_len = len;
Expand Down Expand Up @@ -1475,12 +1477,9 @@ argo_notify(void)
break;
}

/* HACK to fix sign extension */
if ( sizeof(void *) == sizeof(uint32_t) )
iov.iov_hnd = (uint64_t) (uint32_t) (uintptr_t) p->data;
#ifdef CONFIG_X86_64
else
iov.iov_hnd = (uint64_t) (uintptr_t) p->data;
iov.iov_hnd = p->data;
#ifdef CONFIG_ARM
iov.pad2 = 0;
#endif
iov.iov_len = p->len;
iov.pad = 0;
Expand Down Expand Up @@ -1998,14 +1997,10 @@ argo_try_send_sponsor(struct argo_private *p, xen_argo_addr_t *dest,
xen_argo_iov_t iov;
xen_argo_addr_t addr;

/* HACK to fix sign extension */
if ( sizeof(void *) == sizeof(uint32_t) )
iov.iov_hnd = (uint64_t) (uint32_t) (uintptr_t) buf;
#ifdef CONFIG_X86_64
else
iov.iov_hnd = (uint64_t) (uintptr_t) buf;
iov.iov_hnd = buf;
#ifdef CONFIG_ARM
iov.pad2 = 0;
#endif

iov.iov_len = len;
iov.pad = 0;

Expand Down Expand Up @@ -2062,7 +2057,7 @@ argo_try_sendv_sponsor(struct argo_private *p,
DEBUG_APPLE;

#ifdef ARGO_DEBUG
printk (KERN_ERR "sendv returned %ld\n", ret);
printk (KERN_ERR "sendv returned %d\n", ret);
#endif

argo_spin_lock_irqsave(&pending_xmit_lock, flags);
Expand Down Expand Up @@ -2165,12 +2160,9 @@ argo_sendto_from_sponsor(struct argo_private *p,
xen_argo_iov_t iov;
xen_argo_addr_t addr;

/* HACK to fix sign extension */
if ( sizeof(void *) == sizeof(uint32_t) )
iov.iov_hnd = (uint64_t) (uint32_t) (uintptr_t) buf;
#ifdef CONFIG_X86_64
else
iov.iov_hnd = (uint64_t) (uintptr_t) buf;
iov.iov_hnd = buf;
#ifdef CONFIG_ARM
iov.pad2 = 0;
#endif
iov.iov_len = len;
iov.pad = 0;
Expand Down Expand Up @@ -2426,7 +2418,7 @@ argo_recvfrom_dgram(struct argo_private *p, void *buf, size_t len,

DEBUG_APPLE;
#ifdef ARGO_DEBUG
printk("FISHSOUP argo_recvfrom_dgram %p %ld %d %d \n", buf, len,
printk("FISHSOUP argo_recvfrom_dgram %p %u %d %d \n", buf, len,
nonblock, peek);
#endif

Expand Down Expand Up @@ -2611,7 +2603,7 @@ argo_recv_stream(struct argo_private *p, void *_buf, int len, int recv_flags,

ret = copy_to_user(buf, &pending->data[pending->data_ptr], to_copy);
if ( ret )
printk(KERN_ERR "ARGO - copy_to_user failed: buf: %p other: %p to_copy: %u pending %p data_ptr %u data: %p\n",
printk(KERN_ERR "ARGO - copy_to_user failed: buf: %p other: %p to_copy: %lu pending %p data_ptr %lu data: %p\n",
buf, &pending->data[pending->data_ptr], to_copy, pending,
pending->data_ptr, pending->data);
/* FIXME: error exit action here? */
Expand All @@ -2629,7 +2621,7 @@ argo_recv_stream(struct argo_private *p, void *_buf, int len, int recv_flags,
list_del (&pending->node);

#ifdef ARGO_DEBUG
printk(KERN_ERR "OP p=%p k=%ld s=%d c=%d\n", pending,
printk(KERN_ERR "OP p=%p k=%d s=%d c=%d\n", pending,
pending->data_len, p->state,
atomic_read (&p->pending_recv_count));
#endif
Expand Down Expand Up @@ -2745,20 +2737,12 @@ argo_send_stream(struct argo_private *p, const void *_buf, int len,
sh.flags = 0;
sh.conid = p->conid;

/* FIXME: hmmm... */
if ( sizeof(void *) == sizeof(uint32_t) )
{ //HACK to fix sign extension
iovs[0].iov_hnd = (uint64_t) (uint32_t) (uintptr_t) (void *) &sh;
iovs[1].iov_hnd = (uint64_t) (uint32_t) (uintptr_t) (void *) buf;
}
else
{
#ifdef CONFIG_X86_64
iovs[0].iov_hnd = (uint64_t) (uintptr_t) (void *) &sh;
iovs[1].iov_hnd = (uint64_t) (uintptr_t) (void *) buf;
iovs[0].iov_hnd = (void *) &sh;
iovs[1].iov_hnd = (void *) buf;
#ifdef CONFIG_ARM
iovs[0].pad2 = 0;
iovs[1].pad2 = 0;
#endif
}

iovs[0].iov_len = sizeof(sh);
iovs[1].iov_len = to_send;
iovs[0].pad = 0;
Expand Down Expand Up @@ -2808,7 +2792,7 @@ argo_send_stream(struct argo_private *p, const void *_buf, int len,
DEBUG_APPLE;
DEBUG_APPLE;
#ifdef ARGO_DEBUG
printk(KERN_ERR "avacado count=%ld\n", count);
printk(KERN_ERR "avacado count=%d\n", count);
#endif
return count;
}
Expand Down Expand Up @@ -3078,7 +3062,7 @@ allocate_fd_with_private (void *private)
ind->i_uid = current_fsuid();
ind->i_gid = current_fsgid();
d_instantiate(path.dentry, ind);

path.mnt = mntget(argo_mnt);

DEBUG_APPLE;
Expand All @@ -3091,7 +3075,7 @@ allocate_fd_with_private (void *private)

f->private_data = private;
f->f_flags = O_RDWR;

fd_install (fd, f);

return fd;
Expand Down Expand Up @@ -3296,7 +3280,7 @@ argo_sendto(struct argo_private * p, const void *buf, size_t len, int flags,
return -EFAULT;

#ifdef ARGO_DEBUG
printk(KERN_ERR "argo_sendto buf:%p len:%ld nonblock:%d\n", buf, len, nonblock);
printk(KERN_ERR "argo_sendto buf:%p len:%d nonblock:%d\n", buf, len, nonblock);
#endif

if ( flags & MSG_DONTWAIT )
Expand Down Expand Up @@ -3380,7 +3364,7 @@ argo_recvfrom(struct argo_private * p, void *buf, size_t len, int flags,
ssize_t rc = 0;

#ifdef ARGO_DEBUG
printk(KERN_ERR "argo_recvfrom buff:%p len:%ld nonblock:%d\n",
printk(KERN_ERR "argo_recvfrom buff:%p len:%d nonblock:%d\n",
buf, len, nonblock);
#endif

Expand Down Expand Up @@ -3835,7 +3819,7 @@ argo_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
}
break;
default:
printk(KERN_ERR "unknown ioctl: cmd=%x ARGOIOCACCEPT=%x\n", cmd,
printk(KERN_ERR "unknown ioctl: cmd=%x ARGOIOCACCEPT=%lx\n", cmd,
ARGOIOCACCEPT);
DEBUG_BANANA;
}
Expand Down
20 changes: 20 additions & 0 deletions argo-linux/include/argo.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,21 @@
#ifndef HYPERVISOR_argo_op
#define __HYPERVISOR_argo_op 39

#if defined(CONFIG_X86_64) || defined(CONFIG_X86_32)

#ifndef _hypercall5
#define _hypercall5(type, name, a1, a2, a3, a4, a5) \
({ \
__HYPERCALL_DECLS; \
__HYPERCALL_5ARG(a1, a2, a3, a4, a5); \
asm volatile (__HYPERCALL \
: __HYPERCALL_5PARAM \
: __HYPERCALL_ENTRY(name) \
: __HYPERCALL_CLOBBER5); \
(type)__res; \
})
#endif

static inline int __must_check
HYPERVISOR_argo_op(int cmd, void *arg1, void *arg2, uint32_t arg3,
uint32_t arg4)
Expand All @@ -53,6 +68,11 @@ HYPERVISOR_argo_op(int cmd, void *arg1, void *arg2, uint32_t arg3,

return ret;
}
#else
int __must_check
HYPERVISOR_argo_op(int cmd, void *arg1, void *arg2, uint32_t arg3,
uint32_t arg4);
#endif
#endif

#ifndef VIRQ_ARGO
Expand Down
27 changes: 8 additions & 19 deletions argo-linux/include/xen/argo.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,13 @@

#define XEN_ARGO_DOMID_ANY DOMID_INVALID

/*
* The maximum size of an Argo ring is defined to be: 16MB
* -- which is 0x1000000 bytes.
* A byte index into the ring is at most 24 bits.
*/
/* The maximum size of an Argo ring is defined to be: 16MB (0x1000000 bytes). */
#define XEN_ARGO_MAX_RING_SIZE (0x1000000ULL)

/* Fixed-width type for "argo port" number. Nothing to do with evtchns. */
typedef uint32_t xen_argo_port_t;

/* gfn type: 64-bit on all architectures to aid avoiding a compat ABI */
/* gfn type: 64-bit fixed-width on all architectures */
typedef uint64_t xen_argo_gfn_t;

/*
Expand All @@ -56,25 +52,18 @@ typedef uint64_t xen_argo_gfn_t;
* an array of xen_argo_iov_t structs on the hypervisor stack, so could cause
* stack overflow if the value is too large.
* The Linux Argo driver never passes more than two iovs.
*
* This value should also not exceed 128 to ensure that the total amount of data
* posted in a single Argo sendv operation cannot exceed 2^31 bytes, to reduce
* risk of integer overflow defects:
* Each argo iov can hold ~ 2^24 bytes, so XEN_ARGO_MAXIOV <= 2^(31-24),
* ie. keep XEN_ARGO_MAXIOV <= 128.
*/
#define XEN_ARGO_MAXIOV 8U

#ifdef DEFINE_XEN_GUEST_HANDLE
DEFINE_XEN_GUEST_HANDLE(uint8_t);
#endif

typedef struct xen_argo_iov
{
#ifdef XEN_GUEST_HANDLE_64
XEN_GUEST_HANDLE_64(uint8_t) iov_hnd;
#ifdef XEN_GUEST_HANDLE
XEN_GUEST_HANDLE(uint8) iov_hnd;
#else
uint64_t iov_hnd;
uint8_t *iov_hnd;
#ifdef CONFIG_ARM /* FIXME: 32-bit ARM only */
uint32_t pad2;
#endif
#endif
uint32_t iov_len;
uint32_t pad;
Expand Down

0 comments on commit 3ca4ab9

Please sign in to comment.