git: 2873d841f81c - main - tdfx: Handle errors from copyin() and copyout()

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Wed, 27 Dec 2023 00:06:15 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=2873d841f81cdc205135370875d3d71a3402e90a

commit 2873d841f81cdc205135370875d3d71a3402e90a
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2023-12-26 23:59:21 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2023-12-27 00:00:53 +0000

    tdfx: Handle errors from copyin() and copyout()
    
    This is in preparation for annotating copyin() and related functions
    with __result_use_check.
    
    MFC after:      1 week
---
 sys/dev/tdfx/tdfx_linux.c |  5 +++--
 sys/dev/tdfx/tdfx_pci.c   | 48 +++++++++++++++++++++++------------------------
 2 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/sys/dev/tdfx/tdfx_linux.c b/sys/dev/tdfx/tdfx_linux.c
index 3a2b1b3e3922..f3410106bad2 100644
--- a/sys/dev/tdfx/tdfx_linux.c
+++ b/sys/dev/tdfx/tdfx_linux.c
@@ -58,8 +58,9 @@ linux_ioctl_tdfx(struct thread *td, struct linux_ioctl_args* args)
    if (error != 0)
 	   return (error);
    /* We simply copy the data and send it right to ioctl */
-   copyin((caddr_t)args->arg, &d_pio, sizeof(d_pio));
-   error = fo_ioctl(fp, cmd, (caddr_t)&d_pio, td->td_ucred, td);
+   error = copyin((caddr_t)args->arg, &d_pio, sizeof(d_pio));
+   if (error == 0)
+	error = fo_ioctl(fp, cmd, (caddr_t)&d_pio, td->td_ucred, td);
    fdrop(fp, td);
    return error;
 }
diff --git a/sys/dev/tdfx/tdfx_pci.c b/sys/dev/tdfx/tdfx_pci.c
index 5aa0d9785e27..d73ec841f333 100644
--- a/sys/dev/tdfx/tdfx_pci.c
+++ b/sys/dev/tdfx/tdfx_pci.c
@@ -511,20 +511,16 @@ tdfx_query_fetch(u_int cmd, struct tdfx_pio_data *piod)
 	switch(piod->port) {
 		case PCI_VENDOR_ID_FREEBSD:
 			if(piod->size != 2) return -EINVAL;
-			copyout(&tdfx_info->vendor, piod->value, piod->size);
-			return 0;
+			return -copyout(&tdfx_info->vendor, piod->value, piod->size);
 		case PCI_DEVICE_ID_FREEBSD:
 			if(piod->size != 2) return -EINVAL;
-			copyout(&tdfx_info->type, piod->value, piod->size);
-			return 0;
+			return -copyout(&tdfx_info->type, piod->value, piod->size);
 		case PCI_BASE_ADDRESS_0_FREEBSD:
 			if(piod->size != 4) return -EINVAL;
-			copyout(&tdfx_info->addr0, piod->value, piod->size);
-			return 0;
+			return -copyout(&tdfx_info->addr0, piod->value, piod->size);
 		case PCI_BASE_ADDRESS_1_FREEBSD:
 			if(piod->size != 4) return -EINVAL;
-			copyout(&tdfx_info->addr1, piod->value, piod->size);
-			return 0;
+			return -copyout(&tdfx_info->addr1, piod->value, piod->size);
 		case PCI_PRIBUS_FREEBSD:
 			if(piod->size != 1) return -EINVAL;
 			break;
@@ -552,22 +548,18 @@ tdfx_query_fetch(u_int cmd, struct tdfx_pio_data *piod)
 		case 1:
 			ret_byte = pci_read_config(tdfx_info[piod->device].dev, 
 					piod->port, 1);
-			copyout(&ret_byte, piod->value, 1);
-			break;
+			return -copyout(&ret_byte, piod->value, 1);
 		case 2:
 			ret_word = pci_read_config(tdfx_info[piod->device].dev, 
 					piod->port, 2);
-			copyout(&ret_word, piod->value, 2);
-			break;
+			return -copyout(&ret_word, piod->value, 2);
 		case 4:
 			ret_dword = pci_read_config(tdfx_info[piod->device].dev, 
 					piod->port, 4);
-			copyout(&ret_dword, piod->value, 4);
-			break;
+			return -copyout(&ret_dword, piod->value, 4);
 		default:
 			return -EINVAL;
 	}
-	return 0;
 }
 
 static int
@@ -578,6 +570,7 @@ tdfx_query_update(u_int cmd, struct tdfx_pio_data *piod)
 	u_int8_t  ret_byte;
 	u_int16_t ret_word;
 	u_int32_t ret_dword;
+	int error;
 
 	/* Port vals, mask */
 	u_int32_t retval, preval, mask;
@@ -627,17 +620,23 @@ tdfx_query_update(u_int cmd, struct tdfx_pio_data *piod)
 	 * at once to the ports */
 	switch (piod->size) {
 		case 1:
-			copyin(piod->value, &ret_byte, 1);
+			error = copyin(piod->value, &ret_byte, 1);
+			if (error != 0)
+				return -error;
 			preval = ret_byte << (8 * (piod->port & 0x3));
 			mask = 0xff << (8 * (piod->port & 0x3));
 			break;
 		case 2:
-			copyin(piod->value, &ret_word, 2);
+			error = copyin(piod->value, &ret_word, 2);
+			if (error != 0)
+				return -error;
 			preval = ret_word << (8 * (piod->port & 0x3));
 			mask = 0xffff << (8 * (piod->port & 0x3));
 			break;
 		case 4:
-			copyin(piod->value, &ret_dword, 4);
+			error = copyin(piod->value, &ret_dword, 4);
+			if (error != 0)
+				return -error;
 			preval = ret_dword;
 			mask = ~0;
 			break;
@@ -678,8 +677,7 @@ tdfx_do_pio_rd(struct tdfx_pio_data *piod)
 	/* Write the data to the intended port */
 	workport = piod->port;
 	ret_byte = inb(workport);
-	copyout(&ret_byte, piod->value, sizeof(u_int8_t));
-	return 0;
+	return copyout(&ret_byte, piod->value, sizeof(u_int8_t));
 }
 
 static int
@@ -703,10 +701,12 @@ tdfx_do_pio_wt(struct tdfx_pio_data *piod)
 	}
 
 	/* Write the data to the intended port */
-	copyin(piod->value, &ret_byte, sizeof(u_int8_t));
-	workport = piod->port;
-	outb(workport, ret_byte);
-	return 0;
+	int error = -copyin(piod->value, &ret_byte, sizeof(u_int8_t));
+	if (error == 0) {
+		workport = piod->port;
+		outb(workport, ret_byte);
+	}
+	return error;
 }
 
 static int