From patchwork Tue May 21 12:45:25 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 245305 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 229152C00BB for ; Tue, 21 May 2013 22:46:41 +1000 (EST) Received: from localhost ([::1]:42250 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Uelxf-0004x1-Df for incoming@patchwork.ozlabs.org; Tue, 21 May 2013 08:46:39 -0400 Received: from eggs.gnu.org ([208.118.235.92]:55449) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UelxI-0004py-5r for qemu-devel@nongnu.org; Tue, 21 May 2013 08:46:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1UelxD-00044o-8M for qemu-devel@nongnu.org; Tue, 21 May 2013 08:46:16 -0400 Received: from mail-ea0-x22d.google.com ([2a00:1450:4013:c01::22d]:55684) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1UelxD-00044g-2Y for qemu-devel@nongnu.org; Tue, 21 May 2013 08:46:11 -0400 Received: by mail-ea0-f173.google.com with SMTP id n15so363910ead.18 for ; Tue, 21 May 2013 05:46:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:subject:date:message-id:x-mailer; bh=+hJh8qCdAeRgVfQbhGSNMy0sftkO7R/QCaWZIbwnEDU=; b=EtV3bkUZSD0IRhH1QvWvF6Kq1vg2liaz1N35g6CsXHOEJbDriqKcl2cQoAHoUw8zPc SLR4hEnl2PuVbMpf+SNXotfIW27c25nrGjMEk2/SDu0WeVsYiGyjiDp1W2dVwzRjam3Q FvaZsREi39mzrkv2wRUE0FWPDAk45UfRdLWLHsYqC8MyEgjL+VPDwxXcNGROi8PuBiUI LOFWJ5QnIG8h0HJKaUqd/IKwuS2AMtwpt0fa8JFT379Rz2nxKx8EcLty5La8qCmO7NF2 m82adS6JgV3QLGjDqvzDY0GIp6k/JkHP9vYqNKEWeg1KwUI+72u2BHHc5AwJ7d/ufd18 iCug== X-Received: by 10.15.35.71 with SMTP id f47mr6247055eev.15.1369140370250; Tue, 21 May 2013 05:46:10 -0700 (PDT) Received: from playground.lan (net-37-116-223-193.cust.dsl.vodafone.it. [37.116.223.193]) by mx.google.com with ESMTPSA id m48sm3304809eeh.16.2013.05.21.05.46.08 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Tue, 21 May 2013 05:46:09 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 21 May 2013 14:45:25 +0200 Message-Id: <1369140325-17924-1-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.1.4 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:4013:c01::22d Subject: [Qemu-devel] [PATCH scsi] scsi-generic: fix sign extension of READ CAPACITY(10) data X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Issuing the READ CAPACITY(10) command in the guest will cause QEMU to update its knowledge of the maximum accessible LBA in the disk. The recorded maximum LBA will be wrong if the disk is bigger than 1TB, because ldl_be_p returns a signed int. When this is fixed, a latent bug will be unmasked. If the READ CAPACITY(10) command reported an overflow (0xFFFFFFFF), we must not overwrite the previously-known maximum accessible LBA, or the guest will fail to access the disk above the first 2TB. Signed-off-by: Paolo Bonzini --- hw/scsi/scsi-generic.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 2a9a561..19bd36c 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -198,9 +198,10 @@ static void scsi_read_complete(void * opaque, int ret) scsi_command_complete(r, 0); } else { /* Snoop READ CAPACITY output to set the blocksize. */ - if (r->req.cmd.buf[0] == READ_CAPACITY_10) { + if (r->req.cmd.buf[0] == READ_CAPACITY_10 && + (ldl_be_p(&r->buf[0]) != 0xffffffffU || s->max_lba == 0)) { s->blocksize = ldl_be_p(&r->buf[4]); - s->max_lba = ldl_be_p(&r->buf[0]); + s->max_lba = ldl_be_p(&r->buf[0]) & 0xffffffffULL; } else if (r->req.cmd.buf[0] == SERVICE_ACTION_IN_16 && (r->req.cmd.buf[1] & 31) == SAI_READ_CAPACITY_16) { s->blocksize = ldl_be_p(&r->buf[8]);