From patchwork Fri Sep 25 14:51:01 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Julien Grall X-Patchwork-Id: 54165 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-wi0-f200.google.com (mail-wi0-f200.google.com [209.85.212.200]) by patches.linaro.org (Postfix) with ESMTPS id C5751218DB for ; Fri, 25 Sep 2015 14:54:45 +0000 (UTC) Received: by wicgb1 with SMTP id gb1sf9325182wic.3 for ; Fri, 25 Sep 2015 07:54:45 -0700 (PDT) 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:mime-version:cc:subject:precedence:list-id :list-unsubscribe:list-post:list-help:list-subscribe:content-type :content-transfer-encoding:sender:errors-to:x-original-sender :x-original-authentication-results:mailing-list:list-archive; bh=5VznvWAEKX4AKayqG9T4RJmUtBqw8IvKj9HazLn/zEo=; b=Arrcrt48YrofO8lzGDYyRWnvZJquE9asY5l10HvBOakgjTWXQExmL+oorcIYmlUGSY c9TeaychwX6FfYrIU4ra3AMbAwrIHuRX8+NrP8Y0J4n6d4a5Cz5AVVBJVqfqELBSUNnG ppVWOWLkjPcQl6WWRrKsfJF8VXdsldgsRkdeDtecwHPSro7sDvFpVsFi0vqq/AC74YC+ ZHCYpMU7V2LmbNpfVO92sVrQ9F6MkafmbuyShfh3xudlRfvZapNONlFA/5LnKhPkBJ1z fdlnVTRrydHt4Rxanj11CTX6am0k0DzcW/yO8KGaIXMSrtOZNXxA/iNbB7jI07a56i5c 69Hw== X-Gm-Message-State: ALoCoQlA6ffN5XukYNqX/wHE5RMeacgEDpb2y+9+1TdRWFN0j6C9tfPI8On2GeuNGx+/snODTn3C X-Received: by 10.112.89.228 with SMTP id br4mr976458lbb.3.1443192885015; Fri, 25 Sep 2015 07:54:45 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.25.19.223 with SMTP id 92ls273827lft.101.gmail; Fri, 25 Sep 2015 07:54:44 -0700 (PDT) X-Received: by 10.152.44.162 with SMTP id f2mr1806425lam.71.1443192884917; Fri, 25 Sep 2015 07:54:44 -0700 (PDT) Received: from mail-la0-f48.google.com (mail-la0-f48.google.com. [209.85.215.48]) by mx.google.com with ESMTPS id r8si1883395lag.114.2015.09.25.07.54.44 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 25 Sep 2015 07:54:44 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.215.48 as permitted sender) client-ip=209.85.215.48; Received: by laclj5 with SMTP id lj5so6015762lac.3 for ; Fri, 25 Sep 2015 07:54:44 -0700 (PDT) X-Received: by 10.112.151.106 with SMTP id up10mr1813428lbb.106.1443192884762; Fri, 25 Sep 2015 07:54:44 -0700 (PDT) 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.59.35 with SMTP id w3csp87339lbq; Fri, 25 Sep 2015 07:54:43 -0700 (PDT) X-Received: by 10.140.96.99 with SMTP id j90mr6523152qge.92.1443192872787; Fri, 25 Sep 2015 07:54:32 -0700 (PDT) Received: from lists.xen.org (lists.xen.org. [50.57.142.19]) by mx.google.com with ESMTPS id 79si3075076qgc.83.2015.09.25.07.54.32 (version=TLSv1 cipher=RC4-SHA bits=128/128); Fri, 25 Sep 2015 07:54:32 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of xen-devel-bounces@lists.xen.org designates 50.57.142.19 as permitted sender) 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 1ZfUMa-0006Ud-0V; Fri, 25 Sep 2015 14:52:40 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xen.org with esmtp (Exim 4.72) (envelope-from ) id 1ZfUMY-0006TR-29 for xen-devel@lists.xenproject.org; Fri, 25 Sep 2015 14:52:38 +0000 Received: from [85.158.137.68] by server-1.bemta-3.messagelabs.com id 07/90-01421-5BF55065; Fri, 25 Sep 2015 14:52:37 +0000 X-Env-Sender: prvs=7034a1692=julien.grall@citrix.com X-Msg-Ref: server-4.tower-31.messagelabs.com!1443192753!46436559!3 X-Originating-IP: [66.165.176.89] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogNjYuMTY1LjE3Ni44OSA9PiAyMDMwMDc=\n, received_headers: No Received headers X-StarScan-Received: X-StarScan-Version: 6.13.16; banners=-,-,- X-VirusChecked: Checked Received: (qmail 22420 invoked from network); 25 Sep 2015 14:52:36 -0000 Received: from smtp.citrix.com (HELO SMTP.CITRIX.COM) (66.165.176.89) by server-4.tower-31.messagelabs.com with RC4-SHA encrypted SMTP; 25 Sep 2015 14:52:36 -0000 X-IronPort-AV: E=Sophos;i="5.17,587,1437436800"; d="scan'208";a="302441434" From: Julien Grall To: Date: Fri, 25 Sep 2015 15:51:01 +0100 Message-ID: <1443192667-16112-3-git-send-email-julien.grall@citrix.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1443192667-16112-1-git-send-email-julien.grall@citrix.com> References: <1443192667-16112-1-git-send-email-julien.grall@citrix.com> MIME-Version: 1.0 X-DLP: MIA2 Cc: ian.campbell@citrix.com, stefano.stabellini@eu.citrix.com, Julien Grall , linux-kernel@vger.kernel.org, Julien Grall , linux-arm-kernel@lists.infradead.org Subject: [Xen-devel] [PATCH v1 2/8] xen/arm: io: Extend write/read handler to pass the register in parameter 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: , 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: patch@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.48 as permitted sender) smtp.mailfrom=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: From: Julien Grall Rather than letting each handler to retrieve the register used by the I/O access, add a new parameter to pass the register in parameter. This will help to implement generic register manipulation on I/O access such as sign-extension and endianess. Read handlers need to modify the value of the register, so a pointer to it is given in argument. Write handlers shouldn't modify the register, therfore only a plain value is given. Signed-off-by: Julien Grall --- Changes in v2: - Patch added --- xen/arch/arm/io.c | 15 ++++--- xen/arch/arm/vgic-v2.c | 46 ++++++++++---------- xen/arch/arm/vgic-v3.c | 105 +++++++++++++++++++++------------------------ xen/arch/arm/vuart.c | 16 +++---- xen/include/asm-arm/mmio.h | 4 +- 5 files changed, 88 insertions(+), 98 deletions(-) diff --git a/xen/arch/arm/io.c b/xen/arch/arm/io.c index 8e55d49..32b2194 100644 --- a/xen/arch/arm/io.c +++ b/xen/arch/arm/io.c @@ -29,6 +29,9 @@ int handle_mmio(mmio_info_t *info) int i; const struct mmio_handler *mmio_handler; const struct io_handler *io_handlers = &v->domain->arch.io_handlers; + struct hsr_dabt dabt = info->dabt; + struct cpu_user_regs *regs = guest_cpu_user_regs(); + register_t *r = select_user_reg(regs, dabt.reg); for ( i = 0; i < io_handlers->num_entries; i++ ) { @@ -36,14 +39,16 @@ int handle_mmio(mmio_info_t *info) if ( (info->gpa >= mmio_handler->addr) && (info->gpa < (mmio_handler->addr + mmio_handler->size)) ) - { - return info->dabt.write ? - mmio_handler->mmio_handler_ops->write_handler(v, info) : - mmio_handler->mmio_handler_ops->read_handler(v, info); - } + goto found; } return 0; + +found: + if ( info->dabt.write ) + return mmio_handler->mmio_handler_ops->write_handler(v, info, *r); + else + return mmio_handler->mmio_handler_ops->read_handler(v, info, r); } void register_mmio_handler(struct domain *d, diff --git a/xen/arch/arm/vgic-v2.c b/xen/arch/arm/vgic-v2.c index fa71598..3d0ce1d 100644 --- a/xen/arch/arm/vgic-v2.c +++ b/xen/arch/arm/vgic-v2.c @@ -50,11 +50,10 @@ void vgic_v2_setup_hw(paddr_t dbase, paddr_t cbase, paddr_t vbase) vgic_v2_hw.vbase = vbase; } -static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info) +static int vgic_v2_distr_mmio_read(struct vcpu *v, mmio_info_t *info, + register_t *r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); struct vgic_irq_rank *rank; int gicd_reg = (int)(info->gpa - v->domain->arch.vgic.dbase); unsigned long flags; @@ -247,11 +246,10 @@ static int vgic_v2_to_sgi(struct vcpu *v, register_t sgir) return vgic_to_sgi(v, sgir, sgi_mode, virq, &target); } -static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) +static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info, + register_t r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); struct vgic_irq_rank *rank; int gicd_reg = (int)(info->gpa - v->domain->arch.vgic.dbase); uint32_t tr; @@ -265,7 +263,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) if ( dabt.size != DABT_WORD ) goto bad_width; /* Ignore all but the enable bit */ vgic_lock(v); - v->domain->arch.vgic.ctlr = (*r) & GICD_CTL_ENABLE; + v->domain->arch.vgic.ctlr = r & GICD_CTL_ENABLE; vgic_unlock(v); return 1; @@ -289,11 +287,11 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) if ( rank == NULL) goto write_ignore; vgic_lock_rank(v, rank, flags); tr = rank->ienable; - rank->ienable |= *r; + rank->ienable |= r; /* The virtual irq is derived from register offset. * The register difference is word difference. So divide by 2(DABT_WORD) * to get Virtual irq number */ - vgic_enable_irqs(v, (*r) & (~tr), + vgic_enable_irqs(v, r & (~tr), (gicd_reg - GICD_ISENABLER) >> DABT_WORD); vgic_unlock_rank(v, rank, flags); return 1; @@ -304,11 +302,11 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) if ( rank == NULL) goto write_ignore; vgic_lock_rank(v, rank, flags); tr = rank->ienable; - rank->ienable &= ~*r; + rank->ienable &= ~r; /* The virtual irq is derived from register offset. * The register difference is word difference. So divide by 2(DABT_WORD) * to get Virtual irq number */ - vgic_disable_irqs(v, (*r) & tr, + vgic_disable_irqs(v, r & tr, (gicd_reg - GICD_ICENABLER) >> DABT_WORD); vgic_unlock_rank(v, rank, flags); return 1; @@ -317,28 +315,28 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: vGICD: unhandled word write %#"PRIregister" to ISPENDR%d\n", - v, *r, gicd_reg - GICD_ISPENDR); + v, r, gicd_reg - GICD_ISPENDR); return 0; case GICD_ICPENDR ... GICD_ICPENDRN: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: vGICD: unhandled word write %#"PRIregister" to ICPENDR%d\n", - v, *r, gicd_reg - GICD_ICPENDR); + v, r, gicd_reg - GICD_ICPENDR); return 0; case GICD_ISACTIVER ... GICD_ISACTIVERN: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: vGICD: unhandled word write %#"PRIregister" to ISACTIVER%d\n", - v, *r, gicd_reg - GICD_ISACTIVER); + v, r, gicd_reg - GICD_ISACTIVER); return 0; case GICD_ICACTIVER ... GICD_ICACTIVERN: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: vGICD: unhandled word write %#"PRIregister" to ICACTIVER%d\n", - v, *r, gicd_reg - GICD_ICACTIVER); + v, r, gicd_reg - GICD_ICACTIVER); return 0; case GICD_ITARGETSR ... GICD_ITARGETSR + 7: @@ -360,7 +358,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) target = target | (target << 8) | (target << 16) | (target << 24); else target = (target << (8 * (gicd_reg & 0x3))); - target &= *r; + target &= r; /* ignore zero writes */ if ( !target ) goto write_ignore; @@ -408,10 +406,10 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) vgic_lock_rank(v, rank, flags); if ( dabt.size == DABT_WORD ) rank->ipriority[REG_RANK_INDEX(8, gicd_reg - GICD_IPRIORITYR, - DABT_WORD)] = *r; + DABT_WORD)] = r; else vgic_byte_write(&rank->ipriority[REG_RANK_INDEX(8, - gicd_reg - GICD_IPRIORITYR, DABT_WORD)], *r, gicd_reg); + gicd_reg - GICD_IPRIORITYR, DABT_WORD)], r, gicd_reg); vgic_unlock_rank(v, rank, flags); return 1; @@ -425,7 +423,7 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) rank = vgic_rank_offset(v, 2, gicd_reg - GICD_ICFGR, DABT_WORD); if ( rank == NULL) goto write_ignore; vgic_lock_rank(v, rank, flags); - rank->icfg[REG_RANK_INDEX(2, gicd_reg - GICD_ICFGR, DABT_WORD)] = *r; + rank->icfg[REG_RANK_INDEX(2, gicd_reg - GICD_ICFGR, DABT_WORD)] = r; vgic_unlock_rank(v, rank, flags); return 1; @@ -435,20 +433,20 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) case GICD_SGIR: if ( dabt.size != DABT_WORD ) goto bad_width; - return vgic_v2_to_sgi(v, *r); + return vgic_v2_to_sgi(v, r); case GICD_CPENDSGIR ... GICD_CPENDSGIRN: if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: vGICD: unhandled %s write %#"PRIregister" to ICPENDSGIR%d\n", - v, dabt.size ? "word" : "byte", *r, gicd_reg - GICD_CPENDSGIR); + v, dabt.size ? "word" : "byte", r, gicd_reg - GICD_CPENDSGIR); return 0; case GICD_SPENDSGIR ... GICD_SPENDSGIRN: if ( dabt.size != DABT_BYTE && dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: vGICD: unhandled %s write %#"PRIregister" to ISPENDSGIR%d\n", - v, dabt.size ? "word" : "byte", *r, gicd_reg - GICD_SPENDSGIR); + v, dabt.size ? "word" : "byte", r, gicd_reg - GICD_SPENDSGIR); return 0; /* Implementation defined -- write ignored */ @@ -475,14 +473,14 @@ static int vgic_v2_distr_mmio_write(struct vcpu *v, mmio_info_t *info) default: printk(XENLOG_G_ERR "%pv: vGICD: unhandled write r%d=%"PRIregister" offset %#08x\n", - v, dabt.reg, *r, gicd_reg); + v, dabt.reg, r, gicd_reg); return 0; } bad_width: printk(XENLOG_G_ERR "%pv: vGICD: bad write width %d r%d=%"PRIregister" offset %#08x\n", - v, dabt.size, dabt.reg, *r, gicd_reg); + v, dabt.size, dabt.reg, r, gicd_reg); domain_crash_synchronous(); return 0; diff --git a/xen/arch/arm/vgic-v3.c b/xen/arch/arm/vgic-v3.c index f1c482d..94f1a5c 100644 --- a/xen/arch/arm/vgic-v3.c +++ b/xen/arch/arm/vgic-v3.c @@ -104,11 +104,10 @@ static struct vcpu *vgic_v3_get_target_vcpu(struct vcpu *v, unsigned int irq) } static int __vgic_v3_rdistr_rd_mmio_read(struct vcpu *v, mmio_info_t *info, - uint32_t gicr_reg) + uint32_t gicr_reg, + register_t *r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); uint64_t aff; switch ( gicr_reg ) @@ -215,11 +214,10 @@ read_as_zero_32: } static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, - uint32_t gicr_reg) + uint32_t gicr_reg, + register_t r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); switch ( gicr_reg ) { @@ -276,7 +274,7 @@ static int __vgic_v3_rdistr_rd_mmio_write(struct vcpu *v, mmio_info_t *info, bad_width: printk(XENLOG_G_ERR "%pv: vGICR: bad write width %d r%d=%"PRIregister" offset %#08x\n", - v, dabt.size, dabt.reg, *r, gicr_reg); + v, dabt.size, dabt.reg, r, gicr_reg); domain_crash_synchronous(); return 0; @@ -290,11 +288,10 @@ write_ignore_32: } static int __vgic_v3_distr_common_mmio_read(const char *name, struct vcpu *v, - mmio_info_t *info, uint32_t reg) + mmio_info_t *info, uint32_t reg, + register_t *r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); struct vgic_irq_rank *rank; unsigned long flags; @@ -369,11 +366,10 @@ read_as_zero: } static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, - mmio_info_t *info, uint32_t reg) + mmio_info_t *info, uint32_t reg, + register_t r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); struct vgic_irq_rank *rank; uint32_t tr; unsigned long flags; @@ -389,9 +385,9 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, if ( rank == NULL ) goto write_ignore; vgic_lock_rank(v, rank, flags); tr = rank->ienable; - rank->ienable |= *r; + rank->ienable |= r; /* The irq number is extracted from offset. so shift by register size */ - vgic_enable_irqs(v, (*r) & (~tr), (reg - GICD_ISENABLER) >> DABT_WORD); + vgic_enable_irqs(v, r & (~tr), (reg - GICD_ISENABLER) >> DABT_WORD); vgic_unlock_rank(v, rank, flags); return 1; case GICD_ICENABLER ... GICD_ICENABLERN: @@ -400,37 +396,37 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, if ( rank == NULL ) goto write_ignore; vgic_lock_rank(v, rank, flags); tr = rank->ienable; - rank->ienable &= ~*r; + rank->ienable &= ~r; /* The irq number is extracted from offset. so shift by register size */ - vgic_disable_irqs(v, (*r) & tr, (reg - GICD_ICENABLER) >> DABT_WORD); + vgic_disable_irqs(v, r & tr, (reg - GICD_ICENABLER) >> DABT_WORD); vgic_unlock_rank(v, rank, flags); return 1; case GICD_ISPENDR ... GICD_ISPENDRN: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: %s: unhandled word write %#"PRIregister" to ISPENDR%d\n", - v, name, *r, reg - GICD_ISPENDR); + v, name, r, reg - GICD_ISPENDR); return 0; case GICD_ICPENDR ... GICD_ICPENDRN: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: %s: unhandled word write %#"PRIregister" to ICPENDR%d\n", - v, name, *r, reg - GICD_ICPENDR); + v, name, r, reg - GICD_ICPENDR); return 0; case GICD_ISACTIVER ... GICD_ISACTIVERN: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: %s: unhandled word write %#"PRIregister" to ISACTIVER%d\n", - v, name, *r, reg - GICD_ISACTIVER); + v, name, r, reg - GICD_ISACTIVER); return 0; case GICD_ICACTIVER ... GICD_ICACTIVERN: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: %s: unhandled word write %#"PRIregister" to ICACTIVER%d\n", - v, name, *r, reg - GICD_ICACTIVER); + v, name, r, reg - GICD_ICACTIVER); return 0; case GICD_IPRIORITYR ... GICD_IPRIORITYRN: @@ -440,10 +436,10 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, vgic_lock_rank(v, rank, flags); if ( dabt.size == DABT_WORD ) rank->ipriority[REG_RANK_INDEX(8, reg - GICD_IPRIORITYR, - DABT_WORD)] = *r; + DABT_WORD)] = r; else vgic_byte_write(&rank->ipriority[REG_RANK_INDEX(8, - reg - GICD_IPRIORITYR, DABT_WORD)], *r, reg); + reg - GICD_IPRIORITYR, DABT_WORD)], r, reg); vgic_unlock_rank(v, rank, flags); return 1; case GICD_ICFGR: /* Restricted to configure SGIs */ @@ -455,20 +451,20 @@ static int __vgic_v3_distr_common_mmio_write(const char *name, struct vcpu *v, rank = vgic_rank_offset(v, 2, reg - GICD_ICFGR, DABT_WORD); if ( rank == NULL ) goto write_ignore; vgic_lock_rank(v, rank, flags); - rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR, DABT_WORD)] = *r; + rank->icfg[REG_RANK_INDEX(2, reg - GICD_ICFGR, DABT_WORD)] = r; vgic_unlock_rank(v, rank, flags); return 1; default: printk(XENLOG_G_ERR "%pv: %s: unhandled write r%d=%"PRIregister" offset %#08x\n", - v, name, dabt.reg, *r, reg); + v, name, dabt.reg, r, reg); return 0; } bad_width: printk(XENLOG_G_ERR "%pv: %s: bad write width %d r%d=%"PRIregister" offset %#08x\n", - v, name, dabt.size, dabt.reg, *r, reg); + v, name, dabt.size, dabt.reg, r, reg); domain_crash_synchronous(); return 0; @@ -479,11 +475,9 @@ write_ignore: } static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info, - uint32_t gicr_reg) + uint32_t gicr_reg, register_t *r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); switch ( gicr_reg ) { @@ -502,7 +496,7 @@ static int vgic_v3_rdistr_sgi_mmio_read(struct vcpu *v, mmio_info_t *info, * So handle in common with GICD handling */ return __vgic_v3_distr_common_mmio_read("vGICR: SGI", v, info, - gicr_reg); + gicr_reg, r); /* Read the pending status of an SGI is via GICR is not supported */ case GICR_ISPENDR0: @@ -533,11 +527,9 @@ read_as_zero: } static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info, - uint32_t gicr_reg) + uint32_t gicr_reg, register_t r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); switch ( gicr_reg ) { @@ -556,19 +548,19 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info, * So handle common with GICD handling */ return __vgic_v3_distr_common_mmio_write("vGICR: SGI", v, - info, gicr_reg); + info, gicr_reg, r); case GICR_ISPENDR0: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: vGICR: SGI: unhandled word write %#"PRIregister" to ISPENDR0\n", - v, *r); + v, r); return 0; case GICR_ICPENDR0: if ( dabt.size != DABT_WORD ) goto bad_width; printk(XENLOG_G_ERR "%pv: vGICR: SGI: unhandled word write %#"PRIregister" to ICPENDR0\n", - v, *r); + v, r); return 0; case GICR_NSACR: @@ -584,7 +576,7 @@ static int vgic_v3_rdistr_sgi_mmio_write(struct vcpu *v, mmio_info_t *info, bad_width: printk(XENLOG_G_ERR "%pv: vGICR: SGI: bad write width %d r%d=%"PRIregister" offset %#08x\n", - v, dabt.size, dabt.reg, *r, gicr_reg); + v, dabt.size, dabt.reg, r, gicr_reg); domain_crash_synchronous(); return 0; @@ -634,7 +626,8 @@ static inline struct vcpu *get_vcpu_from_rdist(paddr_t gpa, return d->vcpu[vcpu_id]; } -static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info) +static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info, + register_t *r) { uint32_t offset; @@ -645,9 +638,9 @@ static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info) return 0; if ( offset < SZ_64K ) - return __vgic_v3_rdistr_rd_mmio_read(v, info, offset); + return __vgic_v3_rdistr_rd_mmio_read(v, info, offset, r); else if ( (offset >= SZ_64K) && (offset < 2 * SZ_64K) ) - return vgic_v3_rdistr_sgi_mmio_read(v, info, (offset - SZ_64K)); + return vgic_v3_rdistr_sgi_mmio_read(v, info, (offset - SZ_64K), r); else printk(XENLOG_G_WARNING "%pv: vGICR: unknown gpa read address %"PRIpaddr"\n", @@ -656,7 +649,8 @@ static int vgic_v3_rdistr_mmio_read(struct vcpu *v, mmio_info_t *info) return 0; } -static int vgic_v3_rdistr_mmio_write(struct vcpu *v, mmio_info_t *info) +static int vgic_v3_rdistr_mmio_write(struct vcpu *v, mmio_info_t *info, + register_t r) { uint32_t offset; @@ -667,9 +661,9 @@ static int vgic_v3_rdistr_mmio_write(struct vcpu *v, mmio_info_t *info) return 0; if ( offset < SZ_64K ) - return __vgic_v3_rdistr_rd_mmio_write(v, info, offset); + return __vgic_v3_rdistr_rd_mmio_write(v, info, offset, r); else if ( (offset >= SZ_64K) && (offset < 2 * SZ_64K) ) - return vgic_v3_rdistr_sgi_mmio_write(v, info, (offset - SZ_64K)); + return vgic_v3_rdistr_sgi_mmio_write(v, info, (offset - SZ_64K), r); else printk(XENLOG_G_WARNING "%pv: vGICR: unknown gpa write address %"PRIpaddr"\n", @@ -678,11 +672,10 @@ static int vgic_v3_rdistr_mmio_write(struct vcpu *v, mmio_info_t *info) return 0; } -static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info) +static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info, + register_t *r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); struct vgic_irq_rank *rank; unsigned long flags; int gicd_reg = (int)(info->gpa - v->domain->arch.vgic.dbase); @@ -745,7 +738,7 @@ static int vgic_v3_distr_mmio_read(struct vcpu *v, mmio_info_t *info) * Above all register are common with GICR and GICD * Manage in common */ - return __vgic_v3_distr_common_mmio_read("vGICD", v, info, gicd_reg); + return __vgic_v3_distr_common_mmio_read("vGICD", v, info, gicd_reg, r); case GICD_IROUTER ... GICD_IROUTER31: /* SGI/PPI is RES0 */ goto read_as_zero_64; @@ -835,11 +828,10 @@ read_as_zero: return 1; } -static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) +static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info, + register_t r) { struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); struct vgic_irq_rank *rank; unsigned long flags; uint64_t new_irouter, old_irouter; @@ -855,7 +847,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) vgic_lock(v); /* Only EnableGrp1A can be changed */ - if ( *r & GICD_CTLR_ENABLE_G1A ) + if ( r & GICD_CTLR_ENABLE_G1A ) v->domain->arch.vgic.ctlr |= GICD_CTLR_ENABLE_G1A; else v->domain->arch.vgic.ctlr &= ~GICD_CTLR_ENABLE_G1A; @@ -901,7 +893,8 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) case GICD_ICFGR ... GICD_ICFGRN: /* Above registers are common with GICR and GICD * Manage in common */ - return __vgic_v3_distr_common_mmio_write("vGICD", v, info, gicd_reg); + return __vgic_v3_distr_common_mmio_write("vGICD", v, info, + gicd_reg, r); case GICD_IROUTER ... GICD_IROUTER31: /* SGI/PPI is RES0 */ goto write_ignore_64; @@ -910,7 +903,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) rank = vgic_rank_offset(v, 64, gicd_reg - GICD_IROUTER, DABT_DOUBLE_WORD); if ( rank == NULL ) goto write_ignore; - new_irouter = *r; + new_irouter = r; vgic_lock_rank(v, rank, flags); old_irouter = rank->v3.irouter[REG_RANK_INDEX(64, @@ -923,7 +916,7 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) { printk(XENLOG_G_DEBUG "%pv: vGICD: wrong irouter at offset %#08x val %#"PRIregister, - v, gicd_reg, *r); + v, gicd_reg, r); vgic_unlock_rank(v, rank, flags); /* * TODO: Don't inject a fault to the guest when the MPIDR is @@ -969,14 +962,14 @@ static int vgic_v3_distr_mmio_write(struct vcpu *v, mmio_info_t *info) default: printk(XENLOG_G_ERR "%pv: vGICD: unhandled write r%d=%"PRIregister" offset %#08x\n", - v, dabt.reg, *r, gicd_reg); + v, dabt.reg, r, gicd_reg); return 0; } bad_width: printk(XENLOG_G_ERR "%pv: vGICD: bad write width %d r%d=%"PRIregister" offset %#08x\n", - v, dabt.size, dabt.reg, *r, gicd_reg); + v, dabt.size, dabt.reg, r, gicd_reg); domain_crash_synchronous(); return 0; diff --git a/xen/arch/arm/vuart.c b/xen/arch/arm/vuart.c index d9f4249..5b8409c 100644 --- a/xen/arch/arm/vuart.c +++ b/xen/arch/arm/vuart.c @@ -45,8 +45,8 @@ #define domain_has_vuart(d) ((d)->arch.vuart.info != NULL) -static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info); -static int vuart_mmio_write(struct vcpu *v, mmio_info_t *info); +static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info, register_t *r); +static int vuart_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r); static const struct mmio_handler_ops vuart_mmio_handler = { .read_handler = vuart_mmio_read, @@ -105,12 +105,9 @@ static void vuart_print_char(struct vcpu *v, char c) spin_unlock(&uart->lock); } -static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info) +static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info, register_t *r) { struct domain *d = v->domain; - struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); paddr_t offset = info->gpa - d->arch.vuart.info->base_addr; perfc_incr(vuart_reads); @@ -125,19 +122,16 @@ static int vuart_mmio_read(struct vcpu *v, mmio_info_t *info) return 1; } -static int vuart_mmio_write(struct vcpu *v, mmio_info_t *info) +static int vuart_mmio_write(struct vcpu *v, mmio_info_t *info, register_t r) { struct domain *d = v->domain; - struct hsr_dabt dabt = info->dabt; - struct cpu_user_regs *regs = guest_cpu_user_regs(); - register_t *r = select_user_reg(regs, dabt.reg); paddr_t offset = info->gpa - d->arch.vuart.info->base_addr; perfc_incr(vuart_writes); if ( offset == d->arch.vuart.info->data_off ) /* ignore any status bits */ - vuart_print_char(v, *r & 0xFF); + vuart_print_char(v, r & 0xFF); return 1; } diff --git a/xen/include/asm-arm/mmio.h b/xen/include/asm-arm/mmio.h index 7278bce..b511334 100644 --- a/xen/include/asm-arm/mmio.h +++ b/xen/include/asm-arm/mmio.h @@ -32,8 +32,8 @@ typedef struct paddr_t gpa; } mmio_info_t; -typedef int (*mmio_read_t)(struct vcpu *v, mmio_info_t *info); -typedef int (*mmio_write_t)(struct vcpu *v, mmio_info_t *info); +typedef int (*mmio_read_t)(struct vcpu *v, mmio_info_t *info, register_t *r); +typedef int (*mmio_write_t)(struct vcpu *v, mmio_info_t *info, register_t r); struct mmio_handler_ops { mmio_read_t read_handler;