summaryrefslogtreecommitdiffstats
path: root/arch/sparc/kernel/viohs.c
diff options
context:
space:
mode:
authorJag Raman2017-06-23 20:58:29 +0200
committerDavid S. Miller2017-06-25 22:43:11 +0200
commit7b6e04a3edc140a82f5e0e29e59d6dc90a629d34 (patch)
treeaf4fd4d7d671105afcc04851716e768f0d646eb4 /arch/sparc/kernel/viohs.c
parentsparc: kernel: apc: make of_device_ids const (diff)
downloadkernel-qcow2-linux-7b6e04a3edc140a82f5e0e29e59d6dc90a629d34.tar.gz
kernel-qcow2-linux-7b6e04a3edc140a82f5e0e29e59d6dc90a629d34.tar.xz
kernel-qcow2-linux-7b6e04a3edc140a82f5e0e29e59d6dc90a629d34.zip
sparc64: ensure VIO operations are defined while being used
It's possible that VIO operations are not defined for some VIO clients. In that case, VIO ops pointer should be checked for NULL before being used Signed-off-by: Jagannathan Raman <jag.raman@oracle.com> Reviewed-by: Liam Merwick <liam.merwick@oracle.com> Reviewed-by: Shannon Nelson <shannon.nelson@oracle.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/kernel/viohs.c')
-rw-r--r--arch/sparc/kernel/viohs.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/arch/sparc/kernel/viohs.c b/arch/sparc/kernel/viohs.c
index b30b30ab3ddd..ea28cb7118bd 100644
--- a/arch/sparc/kernel/viohs.c
+++ b/arch/sparc/kernel/viohs.c
@@ -223,6 +223,9 @@ static int send_rdx(struct vio_driver_state *vio)
static int send_attr(struct vio_driver_state *vio)
{
+ if (!vio->ops)
+ return -EINVAL;
+
return vio->ops->send_attr(vio);
}
@@ -374,6 +377,9 @@ static int process_attr(struct vio_driver_state *vio, void *pkt)
if (!(vio->hs_state & VIO_HS_GOTVERS))
return handshake_failure(vio);
+ if (!vio->ops)
+ return 0;
+
err = vio->ops->handle_attr(vio, pkt);
if (err < 0) {
return handshake_failure(vio);
@@ -388,6 +394,7 @@ static int process_attr(struct vio_driver_state *vio, void *pkt)
vio->hs_state |= VIO_HS_SENT_DREG;
}
}
+
return 0;
}
@@ -647,10 +654,13 @@ int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt)
err = process_unknown(vio, pkt);
break;
}
+
if (!err &&
vio->hs_state != prev_state &&
- (vio->hs_state & VIO_HS_COMPLETE))
- vio->ops->handshake_complete(vio);
+ (vio->hs_state & VIO_HS_COMPLETE)) {
+ if (vio->ops)
+ vio->ops->handshake_complete(vio);
+ }
return err;
}
@@ -805,8 +815,7 @@ int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev,
return -EINVAL;
}
- if (!ops->send_attr ||
- !ops->handle_attr ||
+ if (!ops || !ops->send_attr || !ops->handle_attr ||
!ops->handshake_complete)
return -EINVAL;