Skip to content

Commit

Permalink
Bring in iovec changes
Browse files Browse the repository at this point in the history
  • Loading branch information
jrtc27 authored and w4123 committed Oct 28, 2024
1 parent 268ee2f commit c19e148
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 2 deletions.
14 changes: 12 additions & 2 deletions sys/arm64/linux/linux.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ typedef uint32_t l_uint;
typedef uint64_t l_ulong;
typedef uint16_t l_ushort;

typedef uintptr_t l_uintptr_t;
typedef l_ulong l_uintptr_t;
typedef l_long l_clock_t;
typedef l_int l_daddr_t;
typedef l_uint l_gid_t;
Expand Down Expand Up @@ -189,10 +189,20 @@ struct linux_pt_regset {
l_ulong cpsr;
};

struct iovec;
struct uio;
struct l_iovec64 {
l_uintptr_t iov_base;
l_size_t iov_len;
};

#ifdef _KERNEL
struct reg;
struct syscall_info;

int linux64_copyiniov(struct l_iovec64 * __capability iovp64,
l_ulong iovcnt, struct iovec **iovp, int error);
int linux64_copyinuio(struct l_iovec64 * __capability iovp64,
l_ulong iovcnt, struct uio **uiop);
void bsd_to_linux_regset(const struct reg *b_reg,
struct linux_pt_regset *l_regset);
void linux_to_bsd_regset(struct reg *b_reg,
Expand Down
69 changes: 69 additions & 0 deletions sys/arm64/linux/linux_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,3 +130,72 @@ linux_ptrace_pokeuser(struct thread *td, pid_t pid, void *addr, void *data)
"not implemented; returning EINVAL", (long)addr);
return (EINVAL);
}

CTASSERT(sizeof(struct l_iovec64) == 16);

int
linux64_copyiniov(struct l_iovec64 * __capability iovp64, l_ulong iovcnt,
struct iovec **iovp, int error)
{
struct l_iovec64 iov64;
struct iovec *iov;
uint64_t iovlen;
int i;
*iovp = NULL;
if (iovcnt > UIO_MAXIOV)
return (error);
iovlen = iovcnt * sizeof(struct iovec);
iov = malloc(iovlen, M_IOV, M_WAITOK);
for (i = 0; i < iovcnt; i++) {
error = copyin(&iovp64[i], &iov64, sizeof(struct l_iovec64));
if (error) {
free(iov, M_IOV);
return (error);
}
IOVEC_INIT_C(&iov[i], __USER_CAP(iov64.iov_base,
iov64.iov_len), iov64.iov_len);
}
*iovp = iov;
return(0);
}

int
linux64_copyinuio(struct l_iovec64 * __capability iovp, l_ulong iovcnt,
struct uio **uiop)
{
struct l_iovec64 iov64;
struct iovec *iov;
struct uio *uio;
uint64_t iovlen;
int error, i;
*uiop = NULL;
if (iovcnt > UIO_MAXIOV)
return (EINVAL);
iovlen = iovcnt * sizeof(struct iovec);
uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK);
iov = (struct iovec *)(uio + 1);
for (i = 0; i < iovcnt; i++) {
error = copyin(&iovp[i], &iov64, sizeof(struct l_iovec64));
if (error) {
free(uio, M_IOV);
return (error);
}
IOVEC_INIT_C(&iov[i], __USER_CAP(iov64.iov_base,
iov64.iov_len), iov64.iov_len);
}
uio->uio_iov = iov;
uio->uio_iovcnt = iovcnt;
uio->uio_segflg = UIO_USERSPACE;
uio->uio_offset = -1;
uio->uio_resid = 0;
for (i = 0; i < iovcnt; i++) {
if (iov->iov_len > INT64_MAX - uio->uio_resid) {
free(uio, M_IOV);
return (EINVAL);
}
uio->uio_resid += iov->iov_len;
iov++;
}
*uiop = uio;
return (0);
}

0 comments on commit c19e148

Please sign in to comment.