Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 819b6028 authored by Jason Gunthorpe's avatar Jason Gunthorpe
Browse files

Merge branch '32compat'

The design of the uAPI had intended all structs to share the same layout on 32
and 64 bit compiles. Unfortunately over the years some errors have crept in.

This series fixes all the incompatabilities. It goes along with a userspace
rdma-core series that causes the providers to use these structs directly and
then does various self-checks on the command formation.

Those checks were combined with output from pahole on 32 and 64 bit compiles
to confirm that the structure layouts are the same.

This series does not make implicit padding explicit, as long as the implicit
padding is the same on 32 and 64 bit compiles.

Finally, the issue is put to rest by using __aligned_u64 in the uapi headers,
if new code copies that type, and is checked in userspace, it is unlikely we
will see problems in future.

There are two patches that break the ABI for a 32 bit kernel, one for rxe and
one for mlx4. Both patches have notes, but the overall feeling from Doug and I
is that providing compat is just too difficult and not necessary since there
is no real user of a 32 bit userspace and 32 bit kernel for various good
reasons.

The 32 bit userspace / 64 bit kernel case however does seem to have some real
users and does need to work as designed.

* 32compat:
  RDMA: Change all uapi headers to use __aligned_u64 instead of __u64
  RDMA/rxe: Fix uABI structure layouts for 32/64 compat
  RDMA/mlx4: Fix uABI structure layouts for 32/64 compat
  RDMA/qedr: Fix uABI structure layouts for 32/64 compat
  RDMA/ucma: Fix uABI structure layouts for 32/64 compat
  RDMA: Remove minor pahole differences between 32/64
parents f64705b8 26b99066
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -382,7 +382,11 @@ static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf,
	struct ucma_event *uevent;
	int ret = 0;

	if (out_len < sizeof uevent->resp)
	/*
	 * Old 32 bit user space does not send the 4 byte padding in the
	 * reserved field. We don't care, allow it to keep working.
	 */
	if (out_len < sizeof(uevent->resp) - sizeof(uevent->resp.reserved))
		return -ENOSPC;

	if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
@@ -417,7 +421,8 @@ static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf,
	}

	if (copy_to_user((void __user *)(unsigned long)cmd.response,
			 &uevent->resp, sizeof uevent->resp)) {
			 &uevent->resp,
			 min_t(size_t, out_len, sizeof(uevent->resp)))) {
		ret = -EFAULT;
		goto done;
	}
+5 −1
Original line number Diff line number Diff line
@@ -59,7 +59,11 @@
#include "rxe_verbs.h"
#include "rxe_loc.h"

#define RXE_UVERBS_ABI_VERSION		(1)
/*
 * Version 1 and Version 2 are identical on 64 bit machines, but on 32 bit
 * machines Version 2 has a different struct layout.
 */
#define RXE_UVERBS_ABI_VERSION		2

#define IB_PHYS_STATE_LINK_UP		(5)
#define IB_PHYS_STATE_LINK_DOWN		(3)
+7 −7
Original line number Diff line number Diff line
@@ -65,8 +65,8 @@ struct bnxt_re_pd_resp {
} __attribute__((packed, aligned(4)));

struct bnxt_re_cq_req {
	__u64 cq_va;
	__u64 cq_handle;
	__aligned_u64 cq_va;
	__aligned_u64 cq_handle;
};

struct bnxt_re_cq_resp {
@@ -77,9 +77,9 @@ struct bnxt_re_cq_resp {
};

struct bnxt_re_qp_req {
	__u64 qpsva;
	__u64 qprva;
	__u64 qp_handle;
	__aligned_u64 qpsva;
	__aligned_u64 qprva;
	__aligned_u64 qp_handle;
};

struct bnxt_re_qp_resp {
@@ -88,8 +88,8 @@ struct bnxt_re_qp_resp {
};

struct bnxt_re_srq_req {
	__u64 srqva;
	__u64 srq_handle;
	__aligned_u64 srqva;
	__aligned_u64 srq_handle;
};

struct bnxt_re_srq_resp {
+6 −6
Original line number Diff line number Diff line
@@ -41,21 +41,21 @@
 * Make sure that all structs defined in this file remain laid out so
 * that they pack the same way on 32-bit and 64-bit architectures (to
 * avoid incompatibility between 32-bit userspace and 64-bit kernels).
 * In particular do not use pointer types -- pass pointers in __u64
 * In particular do not use pointer types -- pass pointers in __aligned_u64
 * instead.
 */
struct iwch_create_cq_req {
	__u64 user_rptr_addr;
	__aligned_u64 user_rptr_addr;
};

struct iwch_create_cq_resp_v0 {
	__u64 key;
	__aligned_u64 key;
	__u32 cqid;
	__u32 size_log2;
};

struct iwch_create_cq_resp {
	__u64 key;
	__aligned_u64 key;
	__u32 cqid;
	__u32 size_log2;
	__u32 memsize;
@@ -63,8 +63,8 @@ struct iwch_create_cq_resp {
};

struct iwch_create_qp_resp {
	__u64 key;
	__u64 db_key;
	__aligned_u64 key;
	__aligned_u64 db_key;
	__u32 qpid;
	__u32 size_log2;
	__u32 sq_size_log2;
+12 −12
Original line number Diff line number Diff line
@@ -41,13 +41,13 @@
 * Make sure that all structs defined in this file remain laid out so
 * that they pack the same way on 32-bit and 64-bit architectures (to
 * avoid incompatibility between 32-bit userspace and 64-bit kernels).
 * In particular do not use pointer types -- pass pointers in __u64
 * In particular do not use pointer types -- pass pointers in __aligned_u64
 * instead.
 */
struct c4iw_create_cq_resp {
	__u64 key;
	__u64 gts_key;
	__u64 memsize;
	__aligned_u64 key;
	__aligned_u64 gts_key;
	__aligned_u64 memsize;
	__u32 cqid;
	__u32 size;
	__u32 qid_mask;
@@ -59,13 +59,13 @@ enum {
};

struct c4iw_create_qp_resp {
	__u64 ma_sync_key;
	__u64 sq_key;
	__u64 rq_key;
	__u64 sq_db_gts_key;
	__u64 rq_db_gts_key;
	__u64 sq_memsize;
	__u64 rq_memsize;
	__aligned_u64 ma_sync_key;
	__aligned_u64 sq_key;
	__aligned_u64 rq_key;
	__aligned_u64 sq_db_gts_key;
	__aligned_u64 rq_db_gts_key;
	__aligned_u64 sq_memsize;
	__aligned_u64 rq_memsize;
	__u32 sqid;
	__u32 rqid;
	__u32 sq_size;
@@ -75,7 +75,7 @@ struct c4iw_create_qp_resp {
};

struct c4iw_alloc_ucontext_resp {
	__u64 status_page_key;
	__aligned_u64 status_page_key;
	__u32 status_page_size;
	__u32 reserved; /* explicit padding (optional for i386) */
};
Loading