* SATA (libata) + sg oops in 2.4.28-pre1
@ 2004-08-16 21:04 Tony Battersby
2005-02-19 17:28 ` Jeff Garzik
0 siblings, 1 reply; 3+ messages in thread
From: Tony Battersby @ 2004-08-16 21:04 UTC (permalink / raw)
To: jgarzik; +Cc: linux-ide
[-- Attachment #1: Type: text/plain, Size: 3592 bytes --]
I get an oops trying to get standard inquiry data from a SATA disk via
/dev/sg0 in kernel 2.4.28-pre1:
Unable to handle kernel NULL pointer dereference at virtual address
0000001b
printing eip:
d0873f99
*pde = 00000000
Oops: 0000
ata_piix libata sg e1000
CPU: 0
EIP: 0010:[<d0873f99>] Not tainted
EFLAGS: 00010002
EIP is at ata_scsi_rbuf_get+0x19/0x80 [libata]
eax: 00000000 ebx: d0874060 ecx: cf7c4000 edx: cf7908f4
esi: cfc42800 edi: cf80fd8c ebp: cf790800 esp: cf80fd5c
ds: 0018 es: 0018 ss: 0018
Process cytdtest (pid: 264, stackpage=cf80f000)
Stack: d0874060 cf80fd8c d087401a cfc42800 cf80fd70 c0131d13 cfc42800
c01ac2e0
c01ac2e0 d0874915 cf80fd8c d0874060 cf79087c cf7908f4 cfc42800
c01ac2e0
cfc42800 cf79087c d08747f9 cf79087c cf7908f4 cfc42800 c01ac2e0
00000287
Call Trace:
[<d0874060>] ata_scsiop_inq_std+0x0/0xd0 [libata]
[<d087401a>] ata_scsi_rbuf_fill+0x1a/0x60 [libata]
[<c0131d13>] kmalloc+0xa3/0x180 [kernel]
[<c01ac2e0>] scsi_done+0x0/0xd0 [kernel]
[<c01ac2e0>] scsi_done+0x0/0xd0 [kernel]
[<d0874915>] ata_scsi_simulate+0xe5/0x144 [libata]
[<d0874060>] ata_scsiop_inq_std+0x0/0xd0 [libata]
[<c01ac2e0>] scsi_done+0x0/0xd0 [kernel]
[<d08747f9>] ata_scsi_queuecmd+0xe9/0x120 [libata]
[<c01ac2e0>] scsi_done+0x0/0xd0 [kernel]
[<c01abaa5>] scsi_dispatch_cmd+0x195/0x380 [kernel]
[<c01ac2e0>] scsi_done+0x0/0xd0 [kernel]
[<c01b3cd4>] scsi_request_fn+0x354/0x3b0 [kernel]
[<c01b2f9c>] __scsi_insert_special+0x6c/0x80 [kernel]
[<c01b2ffa>] scsi_insert_special_req+0x1a/0x20 [kernel]
[<c01abeb4>] scsi_do_req+0x174/0x1b0 [kernel]
[<d08681d0>] sg_cmd_done_bh+0x0/0x380 [sg]
[<d086706b>] sg_common_write+0x24b/0x260 [sg]
[<d08681d0>] sg_cmd_done_bh+0x0/0x380 [sg]
[<d0866df5>] sg_new_write+0x225/0x250 [sg]
[<d08669d4>] sg_write+0x104/0x300 [sg]
[<c01147a7>] do_page_fault+0x1a7/0x4eb [kernel]
[<c012a2e6>] do_brk+0x206/0x250 [kernel]
[<c013b456>] sys_write+0x96/0x110 [kernel]
[<c013a9ad>] filp_open+0x4d/0x60 [kernel]
[<c01290ca>] sys_brk+0xba/0xf0 [kernel]
[<c0106ff3>] system_call+0x33/0x38 [kernel]
Code: 0f b6 50 1b 8b 14 95 88 f0 2e c0 8b ba c4 00 00 00 8b 9a c8
The same problem exists in kernel 2.4.27 with 2.4.27-rc3-libata1.patch
applied.
The program to reproduce the problem is attached. *** NOTE *** You must
do "echo 1 > /proc/scsi/sg/allow_dio" before running the program for the
oops to happen.
The condition that triggers the oops is having struct scsi_cmnd::use_sg
!= 0 in ata_scsi_rbuf_get(). The attached test program accomplishes
this by using direct I/O with a user buffer that crosses page
boundaries. The test program works just fine when using indirect I/O or
when using direct I/O with a user buffer that doesn't cross page
boundaries (in which case use_sg == 0).
Here is some extra dmesg output if useful:
libata version 1.02 loaded.
ata_piix version 1.02
PCI: Setting latency timer of device 00:1f.2 to 64
ata1: SATA max UDMA/133 cmd 0xC800 ctl 0xCC02 bmdma 0xD800 irq 10
ata2: SATA max UDMA/133 cmd 0xD000 ctl 0xD402 bmdma 0xD808 irq 10
ata1: dev 0 cfg 49:2f00 82:7c6b 83:7f09 84:4003 85:7c69 86:3e01 87:4003
88:207f
ata1: dev 0 ATA, max UDMA/133, 488397168 sectors: lba48
ata1: dev 0 configured for UDMA/133
ata2: SATA port has no device.
scsi0 : ata_piix
scsi1 : ata_piix
Vendor: ATA Model: Maxtor 7Y250M0 Rev: YAR5
Type: Direct-Access ANSI SCSI revision: 05
Attached scsi disk sda at scsi0, channel 0, id 0, lun 0
SCSI device sda: 488397168 512-byte hdwr sectors (250059 MB)
sda: unknown partition table
Anthony J. Battersby
Cybernetics
[-- Attachment #2: inquiry.c --]
[-- Type: application/octet-stream, Size: 2264 bytes --]
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <scsi/sg.h>
#define TXFER_LEN 56
int main(int argc, char *argv[]) {
char *sgd = (argc == 2) ? argv[1] : "/dev/sg0";
sg_io_hdr_t io;
uint8_t cdb[16];
uint8_t *sense_data;
uint8_t *buf;
int pagesize = getpagesize();
int fd;
unsigned long addr;
ssize_t len;
fd = open(sgd, O_RDWR);
if (fd == -1) {
perror("open(/dev/sgX)");
exit(EXIT_FAILURE);
}
buf = malloc(pagesize + TXFER_LEN);
if (buf == NULL) {
printf("OOM\n");
exit(EXIT_FAILURE);
}
/* Force the buffer to cross a page boundary. */
addr = (unsigned long) buf;
addr = (addr & ~(pagesize - 1)) |
(-(TXFER_LEN / 2) & (pagesize - 1));
buf = (uint8_t *) addr;
sense_data = malloc(0x100);
if (sense_data == NULL) {
printf("OOM\n");
exit(EXIT_FAILURE);
}
memset(&io, 0, sizeof(io));
io.interface_id = 'S';
io.timeout = UINT_MAX;
io.sbp = sense_data;
io.mx_sb_len = 0xff;
io.dxferp = buf;
io.dxfer_len = TXFER_LEN;
io.dxfer_direction = SG_DXFER_FROM_DEV;
io.flags = SG_FLAG_DIRECT_IO;
io.cmdp = cdb;
io.cmd_len = 6;
cdb[0] = 0x12; /* inquiry */
cdb[1] = 0x00;
cdb[2] = 0x00;
cdb[3] = 0x00;
cdb[4] = TXFER_LEN;
cdb[5] = 0x00;
len = write(fd, &io, sizeof(io));
if (len < 0) {
perror("write /dev/sgX");
exit(EXIT_FAILURE);
}
len = read(fd, &io, sizeof(io));
if (len < 0) {
perror("read /dev/sgX");
exit(EXIT_FAILURE);
}
if ((io.status != 0) ||
(io.host_status != 0) ||
((io.driver_status & 0x07) != 0)) {
printf("error getting inquiry string\n");
exit(EXIT_FAILURE);
}
printf("%.28s\n", &buf[8]);
if (!(io.info & SG_INFO_DIRECT_IO)) {
printf("You must do 'echo 1 > /proc/scsi/sg/allow_dio' for the oops to happen.\n");
}
return EXIT_SUCCESS;
}
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2005-02-21 14:35 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-16 21:04 SATA (libata) + sg oops in 2.4.28-pre1 Tony Battersby
2005-02-19 17:28 ` Jeff Garzik
2005-02-21 14:35 ` Tony Battersby
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).