Message ID | 20230127112932.38045-16-steven.price@arm.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:eb09:0:0:0:0:0 with SMTP id s9csp783301wrn; Fri, 27 Jan 2023 03:33:28 -0800 (PST) X-Google-Smtp-Source: AK7set8v3OoTOgWD3gtB4qUjenbAhNqEfd211OOcKXtD8wotoDUNBDa55PpNbuj3KtnChOAxuj+K X-Received: by 2002:a17:90b:1b0f:b0:228:f21b:a3ff with SMTP id nu15-20020a17090b1b0f00b00228f21ba3ffmr6133773pjb.42.1674819207945; Fri, 27 Jan 2023 03:33:27 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674819207; cv=none; d=google.com; s=arc-20160816; b=dupd6pNoHQ6qQFrfsAsRqdoxIraRwVf+s+/ldisPPYB0jIFBBADMhgYOnaEuPUYy1v V4+KdADkyfui16B09Sj9IwCJTjGS7/c3O7KGdlZalCYK0UvxUdiyEd1xLPPjYS/HcHBm Tln2HuyMb+LbmPseGk/jB1jj9OC/uAno+h0KCOLhtfxMxAxpMA9nNO6t8XNlSCCMg5bl pXKK59mwEtTzzwveB3yCNq3F1K1/SqzaK6S5yr5SlEUabaYNeTHYKMpq4nCKdHXtxqNh VHoZ9bV6y3p3blWl+On1VM7zTSQZIpqDH70pVWEEORq66IO3ereptioPHSBW2cH5ue6T BV+g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=Y9FNcCprYy/jdopUetMwcjSObdzGeE+b/o893YquEJc=; b=tGqbob4Qxl7fwlY8fY/sgzfBfmW6SArPu78l0NMm6HuDjK6RruBV/yV/71NXf3n6h7 +aErjBv0ss4cMe05Q79rJzffCQVx2AetagA+ku1Tn8AWd1mlcyb/G5tYLZv55yJj8Hld TVNihe/EMV971wYR21FOBgex5D14OIQrNlq6/Tm2e3KEy+O5G20EFKGbI4Xjogm2F3oZ N25nIGkEI+mNdPnS7dec/KFs4Wb5J0Efy2BxfKlr8ikD+GO1y02n/VkE1ufA8u3U94uP r19ynA0tF9Z/QGf+qSst/OyYWb2HfzqhQD2trvbOj7RczzGtMDF92F0XTJZcnNzZjFXe JQ1A== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id g6-20020a63be46000000b004de9a71c3absi3967731pgo.130.2023.01.27.03.33.15; Fri, 27 Jan 2023 03:33:27 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231937AbjA0Lcs (ORCPT <rfc822;lekhanya01809@gmail.com> + 99 others); Fri, 27 Jan 2023 06:32:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41304 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233501AbjA0LcZ (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Fri, 27 Jan 2023 06:32:25 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 671A77D287; Fri, 27 Jan 2023 03:30:57 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 8A7AD1691; Fri, 27 Jan 2023 03:31:03 -0800 (PST) Received: from e122027.cambridge.arm.com (e122027.cambridge.arm.com [10.1.35.16]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 6E86A3F64C; Fri, 27 Jan 2023 03:30:19 -0800 (PST) From: Steven Price <steven.price@arm.com> To: kvm@vger.kernel.org, kvmarm@lists.linux.dev Cc: Steven Price <steven.price@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Marc Zyngier <maz@kernel.org>, Will Deacon <will@kernel.org>, James Morse <james.morse@arm.com>, Oliver Upton <oliver.upton@linux.dev>, Suzuki K Poulose <suzuki.poulose@arm.com>, Zenghui Yu <yuzenghui@huawei.com>, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, Joey Gouly <joey.gouly@arm.com>, Alexandru Elisei <alexandru.elisei@arm.com>, Christoffer Dall <christoffer.dall@arm.com>, Fuad Tabba <tabba@google.com>, linux-coco@lists.linux.dev Subject: [RFC PATCH 15/28] KVM: arm64: Handle realm MMIO emulation Date: Fri, 27 Jan 2023 11:29:19 +0000 Message-Id: <20230127112932.38045-16-steven.price@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230127112932.38045-1-steven.price@arm.com> References: <20230127112248.136810-1-suzuki.poulose@arm.com> <20230127112932.38045-1-steven.price@arm.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1756175225827049893?= X-GMAIL-MSGID: =?utf-8?q?1756175225827049893?= |
Series |
arm64: Support for Arm CCA in KVM
|
|
Commit Message
Steven Price
Jan. 27, 2023, 11:29 a.m. UTC
MMIO emulation for a realm cannot be done directly with the VM's
registers as they are protected from the host. However the RMM interface
provides a structure member for providing the read/written value and
we can transfer this to the appropriate VCPU's register entry and then
depend on the generic MMIO handling code in KVM.
Signed-off-by: Steven Price <steven.price@arm.com>
---
arch/arm64/kvm/mmio.c | 7 +++++++
1 file changed, 7 insertions(+)
Comments
On Fri, 27 Jan 2023 11:29:19 +0000 Steven Price <steven.price@arm.com> wrote: > MMIO emulation for a realm cannot be done directly with the VM's > registers as they are protected from the host. However the RMM interface > provides a structure member for providing the read/written value and More details would be better for helping the review. I can only see the emulated mmio value from the device model (kvmtool or kvm_io_bus) is put into the GPRS[0] of the RecEntry object. But the rest of the flow is missing. I guess RMM copies the value in the RecEntry.GPRS[0] to the target GPR in the guest context in RMI_REC_ENTER when seeing RMI_EMULATED_MMIO. This is for the guest MMIO read path. How about the MMIO write path? I don't see where the RecExit.GPRS[0] is loaded to a varible and returned to the userspace. > we can transfer this to the appropriate VCPU's register entry and then > depend on the generic MMIO handling code in KVM. > > Signed-off-by: Steven Price <steven.price@arm.com> > --- > arch/arm64/kvm/mmio.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c > index 3dd38a151d2a..c4879fa3a8d3 100644 > --- a/arch/arm64/kvm/mmio.c > +++ b/arch/arm64/kvm/mmio.c > @@ -6,6 +6,7 @@ > > #include <linux/kvm_host.h> > #include <asm/kvm_emulate.h> > +#include <asm/rmi_smc.h> > #include <trace/events/kvm.h> > > #include "trace.h" > @@ -109,6 +110,9 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu) > &data); > data = vcpu_data_host_to_guest(vcpu, data, len); > vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); > + > + if (vcpu_is_rec(vcpu)) > + vcpu->arch.rec.run->entry.gprs[0] = data; I think the guest context is maintained by RMM (while KVM can only touch Rec{Entry, Exit} object) so that guest context in the legacy VHE mode is unused. If yes, I guess here is should be: if (unlikely(vcpu_is_rec(vcpu))) vcpu->arch.rec.run->entry.gprs[0] = data; else vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); > } > > /* > @@ -179,6 +183,9 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa) > run->mmio.len = len; > vcpu->mmio_needed = 1; > > + if (vcpu_is_rec(vcpu)) > + vcpu->arch.rec.run->entry.flags |= RMI_EMULATED_MMIO; > + Wouldn't it be better to set this in the kvm_handle_mmio_return where the MMIO read emulation has been surely successful? > if (!ret) { > /* We handled the access successfully in the kernel. */ > if (!is_write)
On 06/03/2023 15:37, Zhi Wang wrote: > On Fri, 27 Jan 2023 11:29:19 +0000 > Steven Price <steven.price@arm.com> wrote: > >> MMIO emulation for a realm cannot be done directly with the VM's >> registers as they are protected from the host. However the RMM interface >> provides a structure member for providing the read/written value and > > More details would be better for helping the review. I can only see the > emulated mmio value from the device model (kvmtool or kvm_io_bus) is put into > the GPRS[0] of the RecEntry object. But the rest of the flow is missing. The commit message is out of date (sorry about that). A previous version of the spec had a dedicated member for the read/write value, but this was changed to just use GPRS[0] as you've spotted. I'll update the text. > I guess RMM copies the value in the RecEntry.GPRS[0] to the target GPR in the > guest context in RMI_REC_ENTER when seeing RMI_EMULATED_MMIO. This is for > the guest MMIO read path. Yes, when entering the guest after an (emulatable) read data abort the value in GPRS[0] is loaded from the RecEntry structure into the appropriate register for the guest. > How about the MMIO write path? I don't see where the RecExit.GPRS[0] is loaded > to a varible and returned to the userspace. The RMM will populate GPRS[0] with the written value in this case (even if another register was actually used in the instruction). We then transfer that to the usual VCPU structure so that the normal fault handling logic works. >> we can transfer this to the appropriate VCPU's register entry and then >> depend on the generic MMIO handling code in KVM. >> >> Signed-off-by: Steven Price <steven.price@arm.com> >> --- >> arch/arm64/kvm/mmio.c | 7 +++++++ >> 1 file changed, 7 insertions(+) >> >> diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c >> index 3dd38a151d2a..c4879fa3a8d3 100644 >> --- a/arch/arm64/kvm/mmio.c >> +++ b/arch/arm64/kvm/mmio.c >> @@ -6,6 +6,7 @@ >> >> #include <linux/kvm_host.h> >> #include <asm/kvm_emulate.h> >> +#include <asm/rmi_smc.h> >> #include <trace/events/kvm.h> >> >> #include "trace.h" >> @@ -109,6 +110,9 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu) >> &data); >> data = vcpu_data_host_to_guest(vcpu, data, len); >> vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); >> + >> + if (vcpu_is_rec(vcpu)) >> + vcpu->arch.rec.run->entry.gprs[0] = data; > > I think the guest context is maintained by RMM (while KVM can only touch > Rec{Entry, Exit} object) so that guest context in the legacy VHE mode is > unused. > > If yes, I guess here is should be: > > if (unlikely(vcpu_is_rec(vcpu))) > vcpu->arch.rec.run->entry.gprs[0] = data; > else > vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); Correct. Although there's no harm in updating with vcpu_set_reg(). But I'll make the change because it's clearer. >> } >> >> /* >> @@ -179,6 +183,9 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa) >> run->mmio.len = len; >> vcpu->mmio_needed = 1; >> >> + if (vcpu_is_rec(vcpu)) >> + vcpu->arch.rec.run->entry.flags |= RMI_EMULATED_MMIO; >> + > > Wouldn't it be better to set this in the kvm_handle_mmio_return where the MMIO > read emulation has been surely successful? Yes, that makes sense - I'll move this. Thanks, Steve >> if (!ret) { >> /* We handled the access successfully in the kernel. */ >> if (!is_write) >
On Fri, 10 Mar 2023 15:47:14 +0000 Steven Price <steven.price@arm.com> wrote: > On 06/03/2023 15:37, Zhi Wang wrote: > > On Fri, 27 Jan 2023 11:29:19 +0000 > > Steven Price <steven.price@arm.com> wrote: > > > >> MMIO emulation for a realm cannot be done directly with the VM's > >> registers as they are protected from the host. However the RMM interface > >> provides a structure member for providing the read/written value and > > > > More details would be better for helping the review. I can only see the > > emulated mmio value from the device model (kvmtool or kvm_io_bus) is put into > > the GPRS[0] of the RecEntry object. But the rest of the flow is missing. > > The commit message is out of date (sorry about that). A previous version > of the spec had a dedicated member for the read/write value, but this > was changed to just use GPRS[0] as you've spotted. I'll update the text. > > > I guess RMM copies the value in the RecEntry.GPRS[0] to the target GPR in the > > guest context in RMI_REC_ENTER when seeing RMI_EMULATED_MMIO. This is for > > the guest MMIO read path. > > Yes, when entering the guest after an (emulatable) read data abort the > value in GPRS[0] is loaded from the RecEntry structure into the > appropriate register for the guest. > > > How about the MMIO write path? I don't see where the RecExit.GPRS[0] is loaded > > to a varible and returned to the userspace. > ----- > The RMM will populate GPRS[0] with the written value in this case (even > if another register was actually used in the instruction). We then > transfer that to the usual VCPU structure so that the normal fault > handling logic works. > ----- Are these in this patch or another patch? > >> we can transfer this to the appropriate VCPU's register entry and then > >> depend on the generic MMIO handling code in KVM. > >> > >> Signed-off-by: Steven Price <steven.price@arm.com> > >> --- > >> arch/arm64/kvm/mmio.c | 7 +++++++ > >> 1 file changed, 7 insertions(+) > >> > >> diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c > >> index 3dd38a151d2a..c4879fa3a8d3 100644 > >> --- a/arch/arm64/kvm/mmio.c > >> +++ b/arch/arm64/kvm/mmio.c > >> @@ -6,6 +6,7 @@ > >> > >> #include <linux/kvm_host.h> > >> #include <asm/kvm_emulate.h> > >> +#include <asm/rmi_smc.h> > >> #include <trace/events/kvm.h> > >> > >> #include "trace.h" > >> @@ -109,6 +110,9 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu) > >> &data); > >> data = vcpu_data_host_to_guest(vcpu, data, len); > >> vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); > >> + > >> + if (vcpu_is_rec(vcpu)) > >> + vcpu->arch.rec.run->entry.gprs[0] = data; > > > > I think the guest context is maintained by RMM (while KVM can only touch > > Rec{Entry, Exit} object) so that guest context in the legacy VHE mode is > > unused. > > > > If yes, I guess here is should be: > > > > if (unlikely(vcpu_is_rec(vcpu))) > > vcpu->arch.rec.run->entry.gprs[0] = data; > > else > > vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); > > Correct. Although there's no harm in updating with vcpu_set_reg(). But > I'll make the change because it's clearer. > > >> } > >> > >> /* > >> @@ -179,6 +183,9 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa) > >> run->mmio.len = len; > >> vcpu->mmio_needed = 1; > >> > >> + if (vcpu_is_rec(vcpu)) > >> + vcpu->arch.rec.run->entry.flags |= RMI_EMULATED_MMIO; > >> + > > > > Wouldn't it be better to set this in the kvm_handle_mmio_return where the MMIO > > read emulation has been surely successful? > > Yes, that makes sense - I'll move this. > > Thanks, > > Steve > > >> if (!ret) { > >> /* We handled the access successfully in the kernel. */ > >> if (!is_write) > > >
On 14/03/2023 15:44, Zhi Wang wrote: > On Fri, 10 Mar 2023 15:47:14 +0000 > Steven Price <steven.price@arm.com> wrote: > >> On 06/03/2023 15:37, Zhi Wang wrote: >>> On Fri, 27 Jan 2023 11:29:19 +0000 >>> Steven Price <steven.price@arm.com> wrote: >>> >>>> MMIO emulation for a realm cannot be done directly with the VM's >>>> registers as they are protected from the host. However the RMM interface >>>> provides a structure member for providing the read/written value and >>> >>> More details would be better for helping the review. I can only see the >>> emulated mmio value from the device model (kvmtool or kvm_io_bus) is put into >>> the GPRS[0] of the RecEntry object. But the rest of the flow is missing. >> >> The commit message is out of date (sorry about that). A previous version >> of the spec had a dedicated member for the read/write value, but this >> was changed to just use GPRS[0] as you've spotted. I'll update the text. >> >>> I guess RMM copies the value in the RecEntry.GPRS[0] to the target GPR in the >>> guest context in RMI_REC_ENTER when seeing RMI_EMULATED_MMIO. This is for >>> the guest MMIO read path. >> >> Yes, when entering the guest after an (emulatable) read data abort the >> value in GPRS[0] is loaded from the RecEntry structure into the >> appropriate register for the guest. >> >>> How about the MMIO write path? I don't see where the RecExit.GPRS[0] is loaded >>> to a varible and returned to the userspace. >> > > ----- >> The RMM will populate GPRS[0] with the written value in this case (even >> if another register was actually used in the instruction). We then >> transfer that to the usual VCPU structure so that the normal fault >> handling logic works. >> > ----- > > Are these in this patch or another patch? The RMM (not included in this particular series[1]) sets the first element of the 'GPRS' array which is in memory shared with the host. The Linux half to populate the vcpu structure is in the previous patch: +static int rec_exit_sync_dabt(struct kvm_vcpu *vcpu) +{ + struct rec *rec = &vcpu->arch.rec; + + if (kvm_vcpu_dabt_iswrite(vcpu) && kvm_vcpu_dabt_isvalid(vcpu)) + vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), + rec->run->exit.gprs[0]); + + return kvm_handle_guest_abort(vcpu); +} I guess it might make sense to pull the 'if' statement out of the previous patch and into this one to keep all the MMIO code together. Steve [1] This Linux code is written against the RMM specification and in theory could work with any RMM implementation. But the TF RMM is open source, so I can point you at the assignment in the latest commit here: https://git.trustedfirmware.org/TF-RMM/tf-rmm.git/tree/runtime/core/exit.c?id=d294b1b05e8d234d32684a982552aa2a17fb9157#n264 >>>> we can transfer this to the appropriate VCPU's register entry and then >>>> depend on the generic MMIO handling code in KVM. >>>> >>>> Signed-off-by: Steven Price <steven.price@arm.com> >>>> --- >>>> arch/arm64/kvm/mmio.c | 7 +++++++ >>>> 1 file changed, 7 insertions(+) >>>> >>>> diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c >>>> index 3dd38a151d2a..c4879fa3a8d3 100644 >>>> --- a/arch/arm64/kvm/mmio.c >>>> +++ b/arch/arm64/kvm/mmio.c >>>> @@ -6,6 +6,7 @@ >>>> >>>> #include <linux/kvm_host.h> >>>> #include <asm/kvm_emulate.h> >>>> +#include <asm/rmi_smc.h> >>>> #include <trace/events/kvm.h> >>>> >>>> #include "trace.h" >>>> @@ -109,6 +110,9 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu) >>>> &data); >>>> data = vcpu_data_host_to_guest(vcpu, data, len); >>>> vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); >>>> + >>>> + if (vcpu_is_rec(vcpu)) >>>> + vcpu->arch.rec.run->entry.gprs[0] = data; >>> >>> I think the guest context is maintained by RMM (while KVM can only touch >>> Rec{Entry, Exit} object) so that guest context in the legacy VHE mode is >>> unused. >>> >>> If yes, I guess here is should be: >>> >>> if (unlikely(vcpu_is_rec(vcpu))) >>> vcpu->arch.rec.run->entry.gprs[0] = data; >>> else >>> vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); >> >> Correct. Although there's no harm in updating with vcpu_set_reg(). But >> I'll make the change because it's clearer. >> >>>> } >>>> >>>> /* >>>> @@ -179,6 +183,9 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa) >>>> run->mmio.len = len; >>>> vcpu->mmio_needed = 1; >>>> >>>> + if (vcpu_is_rec(vcpu)) >>>> + vcpu->arch.rec.run->entry.flags |= RMI_EMULATED_MMIO; >>>> + >>> >>> Wouldn't it be better to set this in the kvm_handle_mmio_return where the MMIO >>> read emulation has been surely successful? >> >> Yes, that makes sense - I'll move this. >> >> Thanks, >> >> Steve >> >>>> if (!ret) { >>>> /* We handled the access successfully in the kernel. */ >>>> if (!is_write) >>> >> >
diff --git a/arch/arm64/kvm/mmio.c b/arch/arm64/kvm/mmio.c index 3dd38a151d2a..c4879fa3a8d3 100644 --- a/arch/arm64/kvm/mmio.c +++ b/arch/arm64/kvm/mmio.c @@ -6,6 +6,7 @@ #include <linux/kvm_host.h> #include <asm/kvm_emulate.h> +#include <asm/rmi_smc.h> #include <trace/events/kvm.h> #include "trace.h" @@ -109,6 +110,9 @@ int kvm_handle_mmio_return(struct kvm_vcpu *vcpu) &data); data = vcpu_data_host_to_guest(vcpu, data, len); vcpu_set_reg(vcpu, kvm_vcpu_dabt_get_rd(vcpu), data); + + if (vcpu_is_rec(vcpu)) + vcpu->arch.rec.run->entry.gprs[0] = data; } /* @@ -179,6 +183,9 @@ int io_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa) run->mmio.len = len; vcpu->mmio_needed = 1; + if (vcpu_is_rec(vcpu)) + vcpu->arch.rec.run->entry.flags |= RMI_EMULATED_MMIO; + if (!ret) { /* We handled the access successfully in the kernel. */ if (!is_write)