Module Name: src Committed By: jdolecek Date: Fri Jul 21 18:12:37 UTC 2017
Modified Files: src/sys/dev/ata [jdolecek-ncq]: ata.c Log Message: add checksum verification for data returned by READ LOG EXT; this is mostly just paranoia for eventual driver/hw DMA bugs this doesn't make difference for QEMU, as there the command actually always just fails (it's not implemented) To generate a diff of this commit: cvs rdiff -u -r1.132.8.19 -r1.132.8.20 src/sys/dev/ata/ata.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ata/ata.c diff -u src/sys/dev/ata/ata.c:1.132.8.19 src/sys/dev/ata/ata.c:1.132.8.20 --- src/sys/dev/ata/ata.c:1.132.8.19 Wed Jul 19 19:39:28 2017 +++ src/sys/dev/ata/ata.c Fri Jul 21 18:12:37 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $ */ +/* $NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $ */ /* * Copyright (c) 1998, 2001 Manuel Bouyer. All rights reserved. @@ -25,7 +25,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.19 2017/07/19 19:39:28 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ata.c,v 1.132.8.20 2017/07/21 18:12:37 jdolecek Exp $"); #include "opt_ata.h" @@ -1039,7 +1039,7 @@ ata_read_log_ext_ncq(struct ata_drive_da int rv; struct ata_channel *chp = drvp->chnl_softc; struct atac_softc *atac = chp->ch_atac; - uint8_t *tb; + uint8_t *tb, cksum, page; ATADEBUG_PRINT(("%s\n", __func__), DEBUG_FUNCS); @@ -1072,12 +1072,12 @@ ata_read_log_ext_ncq(struct ata_drive_da */ xfer->c_flags |= C_IMMEDIATE; xfer->c_ata_c.r_command = WDCC_READ_LOG_EXT; - xfer->c_ata_c.r_lba = WDCC_LOG_PAGE_NCQ; + xfer->c_ata_c.r_lba = page = WDCC_LOG_PAGE_NCQ; xfer->c_ata_c.r_st_bmask = WDCS_DRDY; xfer->c_ata_c.r_st_pmask = WDCS_DRDY; xfer->c_ata_c.r_count = 1; xfer->c_ata_c.r_device = WDSD_LBA; - xfer->c_ata_c.flags = AT_READ | AT_LBA | flags; + xfer->c_ata_c.flags = AT_READ | AT_LBA | AT_LBA48 | flags; xfer->c_ata_c.timeout = 1000; /* 1s */ xfer->c_ata_c.data = tb; xfer->c_ata_c.bcount = DEV_BSIZE; @@ -1092,10 +1092,19 @@ ata_read_log_ext_ncq(struct ata_drive_da goto out2; } - /* XXX verify checksum and refuse if not correct (QEMU) */ + cksum = 0; + for (int i = 0; i < DEV_BSIZE; i++) + cksum += tb[i]; + if (cksum != 0) { + aprint_error_dev(drvp->drv_softc, + "invalid checksum %x for READ LOG EXT page %x\n", + cksum, page); + rv = EINVAL; + goto out2; + } if (tb[0] & WDCC_LOG_NQ) { - /* not a NCQ command */ + /* not queued command */ rv = EOPNOTSUPP; goto out2; }