From patchwork Mon Feb 16 14:50:44 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 44712 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f199.google.com (mail-wi0-f199.google.com [209.85.212.199]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id 25F2321544 for ; Mon, 16 Feb 2015 14:53:04 +0000 (UTC) Received: by mail-wi0-f199.google.com with SMTP id bs8sf15981865wib.2 for ; Mon, 16 Feb 2015 06:53:03 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:from:to:date:message-id:in-reply-to :references:cc:subject:precedence:list-id:list-unsubscribe:list-post :list-help:list-subscribe:mime-version:content-type :content-transfer-encoding:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:list-archive; bh=8LZgP1hD9UDgfFcGPJjNbszz4VftjWUdqg1W/PFWqJw=; b=OKLZJ8ONCoscKDxC7t5qHEBh45/SqFfJQV6ko1V7OXr+nHey7MhgMRH3xrwxeDBwon F+oJWeKvVCuzuyMPv9k3jO/YTSVdRRauq+pXfpDOt1kbejITfSB5mNXdt5vWQfvxOJ6O tRBAjER3IjtY/t04lceo/BI7Zet54AH8ioIv419/2Hml0Q+n8cojmEJPqdan1zznWcXW GAnFwanbTj3NHNGMIeVkT64vqe2B1O644X/N8XxbMraZPnbhDxTOkCwOnTDrC1Knzn5Z +x8f7v3SO/f5yP85wWS8DRLKU6PiUNZSWPAK30IV7gM60GxBk1SvyYyp6968qZZLeMGj 3i7w== X-Gm-Message-State: ALoCoQnmtAGxBdtK//ZVvUUP2K/oWEP2YLZ4kCRyIIJvIC5wSQ1/AUkvGuzYW3NToqlsmsh6VGHT X-Received: by 10.152.43.166 with SMTP id x6mr2988744lal.3.1424098383477; Mon, 16 Feb 2015 06:53:03 -0800 (PST) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.22.129 with SMTP id d1ls486225laf.18.gmail; Mon, 16 Feb 2015 06:53:03 -0800 (PST) X-Received: by 10.112.133.132 with SMTP id pc4mr11924010lbb.33.1424098383335; Mon, 16 Feb 2015 06:53:03 -0800 (PST) Received: from mail-la0-f42.google.com (mail-la0-f42.google.com. [209.85.215.42]) by mx.google.com with ESMTPS id v8si7925059lbb.44.2015.02.16.06.53.03 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 16 Feb 2015 06:53:03 -0800 (PST) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) client-ip=209.85.215.42; Received: by lamq1 with SMTP id q1so29281187lam.5 for ; Mon, 16 Feb 2015 06:53:03 -0800 (PST) X-Received: by 10.112.56.139 with SMTP id a11mr22828716lbq.36.1424098383233; Mon, 16 Feb 2015 06:53:03 -0800 (PST) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.35.133 with SMTP id h5csp1629575lbj; Mon, 16 Feb 2015 06:53:02 -0800 (PST) X-Received: by 10.220.100.6 with SMTP id w6mr15979464vcn.65.1424098381113; Mon, 16 Feb 2015 06:53:01 -0800 (PST) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id wv13si7293359vcb.5.2015.02.16.06.53.00 (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 16 Feb 2015 06:53:01 -0800 (PST) Received-SPF: none (google.com: xen-devel-bounces@lists.xen.org does not designate permitted sender hosts) client-ip=50.57.142.19; Received: from localhost ([127.0.0.1] helo=lists.xen.org) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YNN1l-0002AW-R6; Mon, 16 Feb 2015 14:52:01 +0000 Received: from mail6.bemta4.messagelabs.com ([85.158.143.247]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1YNN1k-00028W-2c for xen-devel@lists.xenproject.org; Mon, 16 Feb 2015 14:52:00 +0000 Received: from [85.158.143.35] by server-3.bemta-4.messagelabs.com id CF/98-29399-F0402E45; Mon, 16 Feb 2015 14:51:59 +0000 X-Env-Sender: julien.grall@linaro.org X-Msg-Ref: server-6.tower-21.messagelabs.com!1424098296!12127484!1 X-Originating-IP: [74.125.82.170] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 6.13.4; banners=-,-,- X-VirusChecked: Checked Received: (qmail 10746 invoked from network); 16 Feb 2015 14:51:57 -0000 Received: from mail-we0-f170.google.com (HELO mail-we0-f170.google.com) (74.125.82.170) by server-6.tower-21.messagelabs.com with RC4-SHA encrypted SMTP; 16 Feb 2015 14:51:57 -0000 Received: by mail-we0-f170.google.com with SMTP id q59so29704170wes.1 for ; Mon, 16 Feb 2015 06:51:32 -0800 (PST) X-Received: by 10.194.185.9 with SMTP id ey9mr37022607wjc.135.1424098290658; Mon, 16 Feb 2015 06:51:30 -0800 (PST) Received: from chilopoda.uk.xensource.com. ([185.25.64.249]) by mx.google.com with ESMTPSA id dj5sm23172398wjb.28.2015.02.16.06.51.29 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 16 Feb 2015 06:51:29 -0800 (PST) From: Julien Grall To: xen-devel@lists.xenproject.org Date: Mon, 16 Feb 2015 14:50:44 +0000 Message-Id: <1424098255-22490-5-git-send-email-julien.grall@linaro.org> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1424098255-22490-1-git-send-email-julien.grall@linaro.org> References: <1424098255-22490-1-git-send-email-julien.grall@linaro.org> Cc: stefano.stabellini@citrix.com, Vijaya.Kumar@caviumnetworks.com, Julien Grall , tim@xen.org, ian.campbell@citrix.com Subject: [Xen-devel] [PATCH v3 04/15] xen/arm: vgic-v3: Correctly handle RAZ/WI registers X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Post: , List-Help: , List-Subscribe: , MIME-Version: 1.0 Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: julien.grall@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.42 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 List-Archive: Some of the registers are accessible via multiple size (see GICD_IPRIORITYR*). Those registers are incorrectly implemented when they should be RAZ. Only word-access size are currently allowed for them. The paragraph 5.3.1 in the GICv3 spec (PRD03-GENC-010745 24.0) indicates the different access-sizes supported for each register. The current vGICv3 driver is not ready for 32 bits guest and will require some rework. So, for now, only supporting access-size of a system not supporting aarch32. To avoid further issues, introduce different label following the access-size of the registers: - read_as_zero_64 and write_ignore_64: Used for registers accessible via a double-word. - read_as_zero_32 and write_ignore_32: Used for registers accessible via a word. - read_as_zero: Used when we don't have to check the access size. The latter is used when the access size has already been checked in the register emulation and/or when the register offset is reserved/implementation defined. Signed-off-by: Julien Grall --- This patch is candidate for backporting into Xen 4.5. It fixes access to GICD_IPRIORITYR* with byte-access when they are not implemented. Changes in v3: - Typoes in commit message - Add a reference to the paragraph 5.3.1 - Explain why we only use access-sizes for system which doesn't support aarch32 Changes in v2: - This patch replaces https://patches.linaro.org/43320/. A new approach has been taken to explicitly use the size in the goto label and have one version which don't check the access size. It's useful for reserved registers and register we already check the access size. --- xen/arch/arm/vgic-v3.c | 98 +++++++++++++++++++++++++++----------------------- 1 file changed, 54 insertions(+), 44 deletions(-) diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index 9115199..1145972 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -101,7 +101,7 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, { case GICR_CTLR: /* We have not implemented LPI's, read zero */ - goto read_as_zero; + goto read_as_zero_32; case GICR_IIDR: if ( dabt.size != DABT_WORD ) goto bad_width; *r = GICV3_GICR_IIDR_VAL; @@ -117,10 +117,10 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, return 1; case GICR_STATUSR: /* Not implemented */ - goto read_as_zero; + goto read_as_zero_32; case GICR_WAKER: /* Power management is not implemented */ - goto read_as_zero; + goto read_as_zero_32; case GICR_SETLPIR: /* WO. Read as zero */ goto read_as_zero_64; @@ -165,14 +165,14 @@ static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, return 1; case GICR_PIDR3: /* Manufacture/customer defined */ - goto read_as_zero; + goto read_as_zero_32; case GICR_PIDR4: if ( dabt.size != DABT_WORD ) goto bad_width; *r = GICV3_GICR_PIDR4; return 1; case GICR_PIDR5 ... GICR_PIDR7: /* Reserved0 */ - goto read_as_zero; + goto read_as_zero_32; default: printk(XENLOG_G_ERR "%pv: vGICR: read r%d offset %#08x\n not found", @@ -190,7 +190,7 @@ read_as_zero_64: *r = 0; return 1; -read_as_zero: +read_as_zero_32: if ( dabt.size != DABT_WORD ) goto bad_width; *r = 0; return 1; @@ -207,19 +207,19 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, { case GICR_CTLR: /* LPI's not implemented */ - goto write_ignore; + goto write_ignore_32; case GICR_IIDR: /* RO */ - goto write_ignore; + goto write_ignore_32; case GICR_TYPER: /* RO */ goto write_ignore_64; case GICR_STATUSR: /* Not implemented */ - goto write_ignore; + goto write_ignore_32; case GICR_WAKER: /* Power mgmt not implemented */ - goto write_ignore; + goto write_ignore_32; case GICR_SETLPIR: /* LPI is not implemented */ goto write_ignore_64; @@ -240,7 +240,7 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, goto write_ignore_64; case GICR_SYNCR: /* RO */ - goto write_ignore; + goto write_ignore_32; case GICR_MOVLPIR: /* LPI is not implemented */ goto write_ignore_64; @@ -249,7 +249,7 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, goto write_ignore_64; case GICR_PIDR7... GICR_PIDR0: /* RO */ - goto write_ignore; + goto write_ignore_32; default: printk(XENLOG_G_ERR "%pv: vGICR: write r%d offset %#08x\n not found", v, dabt.reg, gicr_reg); @@ -266,7 +266,7 @@ write_ignore_64: if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width; return 1; -write_ignore: +write_ignore_32: if ( dabt.size != DABT_WORD ) goto bad_width; return 1; } @@ -284,6 +284,7 @@ static int __vgic_v3_distr_common_mmio_read(struct vcpu *v, mmio_info_t *info, { case GICD_IGROUPR ... GICD_IGROUPRN: /* We do not implement security extensions for guests, read zero */ + if ( dabt.size != DABT_WORD ) goto bad_width; goto read_as_zero; case GICD_ISENABLER ... GICD_ISENABLERN: if ( dabt.size != DABT_WORD ) goto bad_width; @@ -368,7 +369,6 @@ bad_width: return 0; read_as_zero: - if ( dabt.size != DABT_WORD ) goto bad_width; *r = 0; return 1; } @@ -387,7 +387,7 @@ static int __vgic_v3_distr_common_mmio_write(struct vcpu *v, mmio_info_t *info, { case GICD_IGROUPR ... GICD_IGROUPRN: /* We do not implement security extensions for guests, write ignore */ - goto write_ignore; + goto write_ignore_32; case GICD_ISENABLER ... GICD_ISENABLERN: if ( dabt.size != DABT_WORD ) goto bad_width; rank = vgic_rank_offset(v, 1, reg - GICD_ISENABLER, DABT_WORD); @@ -456,7 +456,7 @@ static int __vgic_v3_distr_common_mmio_write(struct vcpu *v, mmio_info_t *info, vgic_unlock_rank(v, rank, flags); return 1; case GICD_ICFGR: /* Restricted to configure SGIs */ - goto write_ignore; + goto write_ignore_32; case GICD_ICFGR + 4 ... GICD_ICFGRN: /* PPI + SPIs */ /* ICFGR1 for PPI's, which is implementation defined if ICFGR1 is programmable or not. We chose to program */ @@ -481,8 +481,9 @@ bad_width: domain_crash_synchronous(); return 0; -write_ignore: +write_ignore_32: if ( dabt.size != DABT_WORD ) goto bad_width; +write_ignore: return 1; } @@ -499,7 +500,7 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info, { case GICR_IGRPMODR0: /* We do not implement security extensions for guests, read zero */ - goto read_as_zero; + goto read_as_zero_32; case GICR_IGROUPR0: case GICR_ISENABLER0: case GICR_ICENABLER0: @@ -543,8 +544,9 @@ bad_width: domain_crash_synchronous(); return 0; -read_as_zero: +read_as_zero_32: if ( dabt.size != DABT_WORD ) goto bad_width; +read_as_zero: *r = 0; return 1; } @@ -562,7 +564,7 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info, { case GICR_IGRPMODR0: /* We do not implement security extensions for guests, write ignore */ - goto write_ignore; + goto write_ignore_32; case GICR_IGROUPR0: case GICR_ISENABLER0: case GICR_ICENABLER0: @@ -595,7 +597,7 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info, return 1; case GICR_NSACR: /* We do not implement security extensions for guests, write ignore */ - goto write_ignore; + goto write_ignore_32; default: printk(XENLOG_G_ERR "%pv: vGICR: SGI: write r%d offset %#08x\n not found", @@ -610,8 +612,9 @@ bad_width: domain_crash_synchronous(); return 0; -write_ignore: +write_ignore_32: if ( dabt.size != DABT_WORD ) goto bad_width; +write_ignore: return 1; } @@ -711,7 +714,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info) * Optional, Not implemented for now. * Update to support guest debugging. */ - goto read_as_zero; + goto read_as_zero_32; case GICD_IIDR: if ( dabt.size != DABT_WORD ) goto bad_width; *r = GICV3_GICD_IIDR_VAL; @@ -719,7 +722,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info) case 0x020 ... 0x03c: case 0xc000 ... 0xffcc: /* Implementation defined -- read as zero */ - goto read_as_zero; + goto read_as_zero_32; case GICD_IGROUPR ... GICD_IGROUPRN: case GICD_ISENABLER ... GICD_ISENABLERN: case GICD_ICENABLER ... GICD_ICENABLERN: @@ -757,16 +760,16 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info) return 1; case GICD_NSACR ... GICD_NSACRN: /* We do not implement security extensions for guests, read zero */ - goto read_as_zero; + goto read_as_zero_32; case GICD_SGIR: /* Read as ICH_SGIR system register with SRE set. So ignore */ - goto read_as_zero; + goto read_as_zero_32; case GICD_CPENDSGIR ... GICD_CPENDSGIRN: /* Replaced with GICR_ICPENDR0. So ignore write */ - goto read_as_zero; + goto read_as_zero_32; case GICD_SPENDSGIR ... GICD_SPENDSGIRN: /* Replaced with GICR_ISPENDR0. So ignore write */ - goto read_as_zero; + goto read_as_zero_32; case GICD_PIDR0: /* GICv3 identification value */ if ( dabt.size != DABT_WORD ) goto bad_width; @@ -784,7 +787,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info) return 1; case GICD_PIDR3: /* GICv3 identification value. Manufacturer/Customer defined */ - goto read_as_zero; + goto read_as_zero_32; case GICD_PIDR4: /* GICv3 identification value */ if ( dabt.size != DABT_WORD ) goto bad_width; @@ -792,7 +795,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info) return 1; case GICD_PIDR5 ... GICD_PIDR7: /* Reserved0 */ - goto read_as_zero; + goto read_as_zero_32; case 0x00c: case 0x044: case 0x04c: @@ -821,10 +824,14 @@ read_as_zero_64: *r = 0; return 1; -read_as_zero: +read_as_zero_32: if ( dabt.size != DABT_WORD ) goto bad_width; *r = 0; return 1; + +read_as_zero: + *r = 0; + return 1; } static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) @@ -856,32 +863,32 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) return 1; case GICD_TYPER: /* RO -- write ignored */ - goto write_ignore; + goto write_ignore_32; case GICD_IIDR: /* RO -- write ignored */ - goto write_ignore; + goto write_ignore_32; case GICD_STATUSR: /* RO -- write ignored */ - goto write_ignore; + goto write_ignore_32; case GICD_SETSPI_NSR: /* Message based SPI is not implemented */ - goto write_ignore; + goto write_ignore_32; case GICD_CLRSPI_NSR: /* Message based SPI is not implemented */ - goto write_ignore; + goto write_ignore_32; case GICD_SETSPI_SR: /* Message based SPI is not implemented */ - goto write_ignore; + goto write_ignore_32; case GICD_CLRSPI_SR: /* Message based SPI is not implemented */ - goto write_ignore; + goto write_ignore_32; case 0x020 ... 0x03c: case 0xc000 ... 0xffcc: /* Implementation defined -- write ignored */ printk(XENLOG_G_DEBUG "%pv: vGICD: WI on implementation defined register offset %#08x\n", v, gicd_reg); - goto write_ignore; + goto write_ignore_32; case GICD_IGROUPR ... GICD_IGROUPRN: case GICD_ISENABLER ... GICD_ISENABLERN: case GICD_ICENABLER ... GICD_ICENABLERN: @@ -901,7 +908,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width; rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER, DABT_DOUBLE_WORD); - if ( rank == NULL ) goto write_ignore_64; + if ( rank == NULL ) goto write_ignore; BUG_ON(v->domain->max_vcpus > 8); new_irouter = *r; vgic_lock_rank(v, rank, flags); @@ -944,10 +951,10 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) return 1; case GICD_NSACR ... GICD_NSACRN: /* We do not implement security extensions for guests, write ignore */ - goto write_ignore; + goto write_ignore_32; case GICD_SGIR: /* it is accessed as system register in GICv3 */ - goto write_ignore; + goto write_ignore_32; case GICD_CPENDSGIR ... GICD_CPENDSGIRN: /* Replaced with GICR_ICPENDR0. So ignore write */ if ( dabt.size != DABT_WORD ) goto bad_width; @@ -958,7 +965,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) return 0; case GICD_PIDR7... GICD_PIDR0: /* RO -- write ignore */ - goto write_ignore; + goto write_ignore_32; case 0x00c: case 0x044: case 0x04c: @@ -984,13 +991,16 @@ bad_width: domain_crash_synchronous(); return 0; -write_ignore: +write_ignore_32: if ( dabt.size != DABT_WORD ) goto bad_width; return 1; write_ignore_64: if ( dabt.size != DABT_DOUBLE_WORD ) goto bad_width; return 1; + +write_ignore: + return 1; } static int vgic_v3_to_sgi(struct vcpu *v, register_t sgir)