From: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
To: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
Cc: Avi Kivity <avi@redhat.com>,
Marcelo Tosatti <mtosatti@redhat.com>,
LKML <linux-kernel@vger.kernel.org>, KVM <kvm@vger.kernel.org>
Subject: [PATCH v6 12/12] KVM: indicate readonly access fault
Date: Tue, 21 Aug 2012 11:03:20 +0800 [thread overview]
Message-ID: <5032FA78.9040405@linux.vnet.ibm.com> (raw)
In-Reply-To: <5032F8FD.2020306@linux.vnet.ibm.com>
Introduce write_readonly_mem in mmio-exit-info to indicate this exit is
caused by write access on readonly memslot
Signed-off-by: Xiao Guangrong <xiaoguangrong@linux.vnet.ibm.com>
---
arch/x86/kvm/x86.c | 23 ++++++++++++++---------
include/linux/kvm.h | 3 +++
include/linux/kvm_host.h | 1 +
virt/kvm/kvm_main.c | 3 +++
4 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 42bbf41..6d7fe4a 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3710,9 +3710,10 @@ int emulator_write_phys(struct kvm_vcpu *vcpu, gpa_t gpa,
ret = kvm_write_guest(vcpu->kvm, gpa, val, bytes);
if (ret < 0)
- return 0;
+ return ret;
+
kvm_mmu_pte_write(vcpu, gpa, val, bytes);
- return 1;
+ return 0;
}
struct read_write_emulator_ops {
@@ -3742,7 +3743,7 @@ static int read_prepare(struct kvm_vcpu *vcpu, void *val, int bytes)
static int read_emulate(struct kvm_vcpu *vcpu, gpa_t gpa,
void *val, int bytes)
{
- return !kvm_read_guest(vcpu->kvm, gpa, val, bytes);
+ return kvm_read_guest(vcpu->kvm, gpa, val, bytes);
}
static int write_emulate(struct kvm_vcpu *vcpu, gpa_t gpa,
@@ -3807,7 +3808,8 @@ static int emulator_read_write_onepage(unsigned long addr, void *val,
if (ret)
goto mmio;
- if (ops->read_write_emulate(vcpu, gpa, val, bytes))
+ ret = ops->read_write_emulate(vcpu, gpa, val, bytes);
+ if (!ret)
return X86EMUL_CONTINUE;
mmio:
@@ -3829,6 +3831,7 @@ mmio:
frag->gpa = gpa;
frag->data = val;
frag->len = now;
+ frag->write_readonly_mem = (ret == -EPERM);
gpa += now;
val += now;
@@ -3842,8 +3845,8 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
struct x86_exception *exception,
struct read_write_emulator_ops *ops)
{
+ struct kvm_mmio_fragment *frag;
struct kvm_vcpu *vcpu = emul_to_vcpu(ctxt);
- gpa_t gpa;
int rc;
if (ops->read_write_prepare &&
@@ -3875,17 +3878,18 @@ int emulator_read_write(struct x86_emulate_ctxt *ctxt, unsigned long addr,
if (!vcpu->mmio_nr_fragments)
return rc;
- gpa = vcpu->mmio_fragments[0].gpa;
+ frag = &vcpu->mmio_fragments[0];
vcpu->mmio_needed = 1;
vcpu->mmio_cur_fragment = 0;
- vcpu->run->mmio.len = vcpu->mmio_fragments[0].len;
+ vcpu->run->mmio.len = frag->len;
vcpu->run->mmio.is_write = vcpu->mmio_is_write = ops->write;
vcpu->run->exit_reason = KVM_EXIT_MMIO;
- vcpu->run->mmio.phys_addr = gpa;
+ vcpu->run->mmio.phys_addr = frag->gpa;
+ vcpu->run->mmio.write_readonly_mem = frag->write_readonly_mem;
- return ops->read_write_exit_mmio(vcpu, gpa, val, bytes);
+ return ops->read_write_exit_mmio(vcpu, frag->gpa, val, bytes);
}
static int emulator_read_emulated(struct x86_emulate_ctxt *ctxt,
@@ -5525,6 +5529,7 @@ static int complete_mmio(struct kvm_vcpu *vcpu)
++frag;
run->exit_reason = KVM_EXIT_MMIO;
run->mmio.phys_addr = frag->gpa;
+ vcpu->run->mmio.write_readonly_mem = frag->write_readonly_mem;
if (vcpu->mmio_is_write)
memcpy(run->mmio.data, frag->data, frag->len);
run->mmio.len = frag->len;
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index d808694..9d8002f 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -226,6 +226,9 @@ struct kvm_run {
__u8 data[8];
__u32 len;
__u8 is_write;
+#ifdef __KVM_HAVE_READONLY_MEM
+ __u8 write_readonly_mem;
+#endif
} mmio;
/* KVM_EXIT_HYPERCALL */
struct {
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 5972c98..c37b225 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -189,6 +189,7 @@ struct kvm_mmio_fragment {
gpa_t gpa;
void *data;
unsigned len;
+ bool write_readonly_mem;
};
struct kvm_vcpu {
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 3416f8a..0c7def7 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1456,6 +1456,9 @@ int kvm_write_guest_page(struct kvm *kvm, gfn_t gfn, const void *data,
unsigned long addr;
addr = gfn_to_hva(kvm, gfn);
+ if (addr == KVM_HVA_ERR_RO_BAD)
+ return -EPERM;
+
if (kvm_is_error_hva(addr))
return -EFAULT;
r = __copy_to_user((void __user *)addr + offset, data, len);
--
1.7.7.6
next prev parent reply other threads:[~2012-08-21 3:03 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-21 2:57 [PATCH v6 00/12] KVM: introduce readonly memslot Xiao Guangrong
2012-08-21 2:57 ` [PATCH v6 01/12] KVM: x86: fix possible infinite loop caused by reexecute_instruction Xiao Guangrong
2012-08-22 12:01 ` Avi Kivity
2012-08-22 12:49 ` Xiao Guangrong
2012-08-21 2:58 ` [PATCH v6 02/12] KVM: fix missing check for memslot flags Xiao Guangrong
2012-08-21 2:58 ` [PATCH v6 03/12] KVM: hide KVM_MEMSLOT_INVALID from userspace Xiao Guangrong
2012-08-21 2:59 ` [PATCH v6 04/12] KVM: introduce gfn_to_pfn_memslot_atomic Xiao Guangrong
2012-08-21 2:59 ` [PATCH v6 05/12] KVM: introduce gfn_to_hva_read/kvm_read_hva/kvm_read_hva_atomic Xiao Guangrong
2012-08-21 3:00 ` [PATCH v6 06/12] KVM: reorganize hva_to_pfn Xiao Guangrong
2012-08-21 3:00 ` [PATCH v6 07/12] KVM: use 'writable' as a hint to map writable pfn Xiao Guangrong
2012-08-21 3:01 ` [PATCH v6 08/12] KVM: introduce KVM_PFN_ERR_RO_FAULT Xiao Guangrong
2012-08-21 3:01 ` [PATCH v6 09/12] KVM: introduce KVM_HVA_ERR_BAD Xiao Guangrong
2012-08-21 3:02 ` [PATCH v6 10/12] KVM: introduce KVM_HVA_ERR_RO_BAD Xiao Guangrong
2012-08-21 3:02 ` [PATCH v6 11/12] KVM: introduce readonly memslot Xiao Guangrong
2012-09-07 10:23 ` Jan Kiszka
2012-09-07 10:47 ` Xiao Guangrong
2012-09-07 11:14 ` Jan Kiszka
2012-09-09 13:42 ` Avi Kivity
2012-09-09 13:52 ` Jan Kiszka
2012-08-21 3:03 ` Xiao Guangrong [this message]
2012-08-22 12:06 ` [PATCH v6 12/12] KVM: indicate readonly access fault Avi Kivity
2012-08-22 12:47 ` Xiao Guangrong
2012-09-06 14:09 ` Avi Kivity
2012-09-07 9:56 ` Xiao Guangrong
2012-09-09 13:46 ` Avi Kivity
2012-09-10 22:31 ` Marcelo Tosatti
2012-09-11 9:18 ` Avi Kivity
2012-09-11 14:39 ` Marcelo Tosatti
2012-09-12 15:27 ` Marcelo Tosatti
2012-09-12 15:34 ` Avi Kivity
2012-09-12 15:44 ` Marcelo Tosatti
2012-09-12 15:55 ` Avi Kivity
2012-08-22 12:09 ` [PATCH v6 00/12] KVM: introduce readonly memslot Avi Kivity
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5032FA78.9040405@linux.vnet.ibm.com \
--to=xiaoguangrong@linux.vnet.ibm.com \
--cc=avi@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mtosatti@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.