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

Commit 76dea3bc authored by Roland Dreier's avatar Roland Dreier
Browse files

IB/ehca: Fix clipping of device limits to INT_MAX



Doing min_t(int, foo, INT_MAX) doesn't work correctly, because if foo
is bigger than INT_MAX, then when treated as a signed integer, it will
become negative and hence such an expression is just an elaborate NOP.

Fix such cases in ehca to do min_t(unsigned, foo, INT_MAX) instead.
This fixes negative reported values for max_cqe, max_pd and max_ah:

Before:

        max_cqe:                        -64
        max_pd:                         -1
        max_ah:                         -1

After:
        max_cqe:                        2147483647
        max_pd:                         2147483647
        max_ah:                         2147483647

Based on a bug report and fix from Anton Blanchard <anton@samba.org>.

Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent ede6bc04
Loading
Loading
Loading
Loading
+16 −16
Original line number Diff line number Diff line
@@ -82,17 +82,17 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
	props->vendor_id       = rblock->vendor_id >> 8;
	props->vendor_part_id  = rblock->vendor_part_id >> 16;
	props->hw_ver          = rblock->hw_ver;
	props->max_qp          = min_t(int, rblock->max_qp, INT_MAX);
	props->max_qp_wr       = min_t(int, rblock->max_wqes_wq, INT_MAX);
	props->max_sge         = min_t(int, rblock->max_sge, INT_MAX);
	props->max_sge_rd      = min_t(int, rblock->max_sge_rd, INT_MAX);
	props->max_cq          = min_t(int, rblock->max_cq, INT_MAX);
	props->max_cqe         = min_t(int, rblock->max_cqe, INT_MAX);
	props->max_mr          = min_t(int, rblock->max_mr, INT_MAX);
	props->max_mw          = min_t(int, rblock->max_mw, INT_MAX);
	props->max_pd          = min_t(int, rblock->max_pd, INT_MAX);
	props->max_ah          = min_t(int, rblock->max_ah, INT_MAX);
	props->max_fmr         = min_t(int, rblock->max_mr, INT_MAX);
	props->max_qp          = min_t(unsigned, rblock->max_qp, INT_MAX);
	props->max_qp_wr       = min_t(unsigned, rblock->max_wqes_wq, INT_MAX);
	props->max_sge         = min_t(unsigned, rblock->max_sge, INT_MAX);
	props->max_sge_rd      = min_t(unsigned, rblock->max_sge_rd, INT_MAX);
	props->max_cq          = min_t(unsigned, rblock->max_cq, INT_MAX);
	props->max_cqe         = min_t(unsigned, rblock->max_cqe, INT_MAX);
	props->max_mr          = min_t(unsigned, rblock->max_mr, INT_MAX);
	props->max_mw          = min_t(unsigned, rblock->max_mw, INT_MAX);
	props->max_pd          = min_t(unsigned, rblock->max_pd, INT_MAX);
	props->max_ah          = min_t(unsigned, rblock->max_ah, INT_MAX);
	props->max_fmr         = min_t(unsigned, rblock->max_mr, INT_MAX);

	if (EHCA_BMASK_GET(HCA_CAP_SRQ, shca->hca_cap)) {
		props->max_srq         = props->max_qp;
@@ -104,15 +104,15 @@ int ehca_query_device(struct ib_device *ibdev, struct ib_device_attr *props)
	props->local_ca_ack_delay
		= rblock->local_ca_ack_delay;
	props->max_raw_ipv6_qp
		= min_t(int, rblock->max_raw_ipv6_qp, INT_MAX);
		= min_t(unsigned, rblock->max_raw_ipv6_qp, INT_MAX);
	props->max_raw_ethy_qp
		= min_t(int, rblock->max_raw_ethy_qp, INT_MAX);
		= min_t(unsigned, rblock->max_raw_ethy_qp, INT_MAX);
	props->max_mcast_grp
		= min_t(int, rblock->max_mcast_grp, INT_MAX);
		= min_t(unsigned, rblock->max_mcast_grp, INT_MAX);
	props->max_mcast_qp_attach
		= min_t(int, rblock->max_mcast_qp_attach, INT_MAX);
		= min_t(unsigned, rblock->max_mcast_qp_attach, INT_MAX);
	props->max_total_mcast_qp_attach
		= min_t(int, rblock->max_total_mcast_qp_attach, INT_MAX);
		= min_t(unsigned, rblock->max_total_mcast_qp_attach, INT_MAX);

	/* translate device capabilities */
	props->device_cap_flags = IB_DEVICE_SYS_IMAGE_GUID |