IB/ehca: Catch failing ioremap()
When ioremap() fails with a NULL pointer, catch the error and pass it to the caller of create_qp() or create_cq() instead of trying to dereference the NULL pointer later on. Signed-off-by: Alexander Schmidt <alexs@linux.vnet.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
This commit is contained in:
parent
91fb0dd9cb
commit
e675b6db12
|
@ -269,6 +269,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
|
||||||
struct ehca_cq *cq,
|
struct ehca_cq *cq,
|
||||||
struct ehca_alloc_cq_parms *param)
|
struct ehca_alloc_cq_parms *param)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
u64 ret;
|
u64 ret;
|
||||||
unsigned long outs[PLPAR_HCALL9_BUFSIZE];
|
unsigned long outs[PLPAR_HCALL9_BUFSIZE];
|
||||||
|
|
||||||
|
@ -283,8 +284,19 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
|
||||||
param->act_nr_of_entries = (u32)outs[3];
|
param->act_nr_of_entries = (u32)outs[3];
|
||||||
param->act_pages = (u32)outs[4];
|
param->act_pages = (u32)outs[4];
|
||||||
|
|
||||||
if (ret == H_SUCCESS)
|
if (ret == H_SUCCESS) {
|
||||||
hcp_galpas_ctor(&cq->galpas, 0, outs[5], outs[6]);
|
rc = hcp_galpas_ctor(&cq->galpas, 0, outs[5], outs[6]);
|
||||||
|
if (rc) {
|
||||||
|
ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
|
||||||
|
rc, outs[5]);
|
||||||
|
|
||||||
|
ehca_plpar_hcall_norets(H_FREE_RESOURCE,
|
||||||
|
adapter_handle.handle, /* r4 */
|
||||||
|
cq->ipz_cq_handle.handle, /* r5 */
|
||||||
|
0, 0, 0, 0, 0);
|
||||||
|
ret = H_NO_MEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == H_NOT_ENOUGH_RESOURCES)
|
if (ret == H_NOT_ENOUGH_RESOURCES)
|
||||||
ehca_gen_err("Not enough resources. ret=%lli", ret);
|
ehca_gen_err("Not enough resources. ret=%lli", ret);
|
||||||
|
@ -295,6 +307,7 @@ u64 hipz_h_alloc_resource_cq(const struct ipz_adapter_handle adapter_handle,
|
||||||
u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
|
u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
|
||||||
struct ehca_alloc_qp_parms *parms, int is_user)
|
struct ehca_alloc_qp_parms *parms, int is_user)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
u64 ret;
|
u64 ret;
|
||||||
u64 allocate_controls, max_r10_reg, r11, r12;
|
u64 allocate_controls, max_r10_reg, r11, r12;
|
||||||
unsigned long outs[PLPAR_HCALL9_BUFSIZE];
|
unsigned long outs[PLPAR_HCALL9_BUFSIZE];
|
||||||
|
@ -358,8 +371,19 @@ u64 hipz_h_alloc_resource_qp(const struct ipz_adapter_handle adapter_handle,
|
||||||
parms->rqueue.queue_size =
|
parms->rqueue.queue_size =
|
||||||
(u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
|
(u32)EHCA_BMASK_GET(H_ALL_RES_QP_RQUEUE_SIZE_PAGES, outs[4]);
|
||||||
|
|
||||||
if (ret == H_SUCCESS)
|
if (ret == H_SUCCESS) {
|
||||||
hcp_galpas_ctor(&parms->galpas, is_user, outs[6], outs[6]);
|
rc = hcp_galpas_ctor(&parms->galpas, is_user, outs[6], outs[6]);
|
||||||
|
if (rc) {
|
||||||
|
ehca_gen_err("Could not establish HW access. rc=%d paddr=%#lx",
|
||||||
|
rc, outs[6]);
|
||||||
|
|
||||||
|
ehca_plpar_hcall_norets(H_FREE_RESOURCE,
|
||||||
|
adapter_handle.handle, /* r4 */
|
||||||
|
parms->qp_handle.handle, /* r5 */
|
||||||
|
0, 0, 0, 0, 0);
|
||||||
|
ret = H_NO_MEM;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ret == H_NOT_ENOUGH_RESOURCES)
|
if (ret == H_NOT_ENOUGH_RESOURCES)
|
||||||
ehca_gen_err("Not enough resources. ret=%lli", ret);
|
ehca_gen_err("Not enough resources. ret=%lli", ret);
|
||||||
|
|
|
@ -42,10 +42,9 @@
|
||||||
#include "ehca_classes.h"
|
#include "ehca_classes.h"
|
||||||
#include "hipz_hw.h"
|
#include "hipz_hw.h"
|
||||||
|
|
||||||
int hcall_map_page(u64 physaddr, u64 *mapaddr)
|
u64 hcall_map_page(u64 physaddr)
|
||||||
{
|
{
|
||||||
*mapaddr = (u64)(ioremap(physaddr, EHCA_PAGESIZE));
|
return (u64)ioremap(physaddr, EHCA_PAGESIZE);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int hcall_unmap_page(u64 mapaddr)
|
int hcall_unmap_page(u64 mapaddr)
|
||||||
|
@ -58,9 +57,9 @@ int hcp_galpas_ctor(struct h_galpas *galpas, int is_user,
|
||||||
u64 paddr_kernel, u64 paddr_user)
|
u64 paddr_kernel, u64 paddr_user)
|
||||||
{
|
{
|
||||||
if (!is_user) {
|
if (!is_user) {
|
||||||
int ret = hcall_map_page(paddr_kernel, &galpas->kernel.fw_handle);
|
galpas->kernel.fw_handle = hcall_map_page(paddr_kernel);
|
||||||
if (ret)
|
if (!galpas->kernel.fw_handle)
|
||||||
return ret;
|
return -ENOMEM;
|
||||||
} else
|
} else
|
||||||
galpas->kernel.fw_handle = 0;
|
galpas->kernel.fw_handle = 0;
|
||||||
|
|
||||||
|
|
|
@ -83,7 +83,7 @@ int hcp_galpas_ctor(struct h_galpas *galpas, int is_user,
|
||||||
|
|
||||||
int hcp_galpas_dtor(struct h_galpas *galpas);
|
int hcp_galpas_dtor(struct h_galpas *galpas);
|
||||||
|
|
||||||
int hcall_map_page(u64 physaddr, u64 * mapaddr);
|
u64 hcall_map_page(u64 physaddr);
|
||||||
|
|
||||||
int hcall_unmap_page(u64 mapaddr);
|
int hcall_unmap_page(u64 mapaddr);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue