* [Qemu-devel] [PATCH 1/2] Update Linux headers with KVM_GUEST_MEM_OP ioctl
2015-02-16 12:22 [Qemu-devel] [PATCH 0/2] s390x/kvm: ioctl for reading and writing from/to guest memory Thomas Huth
@ 2015-02-16 12:22 ` Thomas Huth
2015-02-16 12:22 ` [Qemu-devel] [PATCH 2/2] s390x/mmu: Use ioctl for reading and writing from/to guest memory Thomas Huth
1 sibling, 0 replies; 3+ messages in thread
From: Thomas Huth @ 2015-02-16 12:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Thomas Huth, kvm, agraf, borntraeger, cornelia.huck, pbonzini
Synchronized the kvm.h Linux header for the new ioctl.
Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
---
| 21 +++++++++++++++++++++
1 files changed, 21 insertions(+), 0 deletions(-)
--git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index 12045a1..a5f2c8e 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -365,6 +365,23 @@ struct kvm_translation {
__u8 pad[5];
};
+/* for KVM_S390_MEM_OP */
+struct kvm_s390_mem_op {
+ /* in */
+ __u64 gaddr; /* the guest address */
+ __u64 flags; /* arch specific flags */
+ __u32 size; /* amount of bytes */
+ __u32 op; /* type of operation */
+ __u64 buf; /* buffer in userspace */
+ __u8 reserved[32]; /* should be set to 0 */
+};
+/* types for kvm_s390_mem_op->op */
+#define KVM_S390_MEMOP_LOGICAL_READ 0
+#define KVM_S390_MEMOP_LOGICAL_WRITE 1
+/* flags for kvm_s390_mem_op->flags */
+#define KVM_S390_MEMOP_F_CHECK_ONLY (1ULL << 0)
+#define KVM_S390_MEMOP_F_INJECT_EXCEPTION (1ULL << 1)
+
/* for KVM_INTERRUPT */
struct kvm_interrupt {
/* in */
@@ -761,6 +778,8 @@ struct kvm_ppc_smmu_info {
#define KVM_CAP_PPC_FIXUP_HCALL 103
#define KVM_CAP_PPC_ENABLE_HCALL 104
#define KVM_CAP_CHECK_EXTENSION_VM 105
+#define KVM_CAP_S390_USER_SIGP 106
+#define KVM_CAP_S390_MEM_OP 107
#ifdef KVM_CAP_IRQ_ROUTING
@@ -1137,6 +1156,8 @@ struct kvm_s390_ucas_mapping {
#define KVM_ARM_VCPU_INIT _IOW(KVMIO, 0xae, struct kvm_vcpu_init)
#define KVM_ARM_PREFERRED_TARGET _IOR(KVMIO, 0xaf, struct kvm_vcpu_init)
#define KVM_GET_REG_LIST _IOWR(KVMIO, 0xb0, struct kvm_reg_list)
+/* Available with KVM_CAP_S390_MEM_OP */
+#define KVM_S390_MEM_OP _IOW(KVMIO, 0xb1, struct kvm_s390_mem_op)
#define KVM_DEV_ASSIGN_ENABLE_IOMMU (1 << 0)
#define KVM_DEV_ASSIGN_PCI_2_3 (1 << 1)
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [Qemu-devel] [PATCH 2/2] s390x/mmu: Use ioctl for reading and writing from/to guest memory
2015-02-16 12:22 [Qemu-devel] [PATCH 0/2] s390x/kvm: ioctl for reading and writing from/to guest memory Thomas Huth
2015-02-16 12:22 ` [Qemu-devel] [PATCH 1/2] Update Linux headers with KVM_GUEST_MEM_OP ioctl Thomas Huth
@ 2015-02-16 12:22 ` Thomas Huth
1 sibling, 0 replies; 3+ messages in thread
From: Thomas Huth @ 2015-02-16 12:22 UTC (permalink / raw)
To: qemu-devel; +Cc: Thomas Huth, kvm, agraf, borntraeger, cornelia.huck, pbonzini
Add code to make use of the new ioctl for reading from / writing to
virtual guest memory. By using the ioctl, the memory accesses are now
protected with the so-called ipte-lock in the kernel.
Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
---
target-s390x/cpu.h | 7 +++++++
target-s390x/kvm.c | 35 +++++++++++++++++++++++++++++++++++
target-s390x/mmu_helper.c | 9 +++++++++
3 files changed, 51 insertions(+), 0 deletions(-)
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index b6b4632..cffdd1b 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -394,6 +394,8 @@ void kvm_s390_service_interrupt(uint32_t parm);
void kvm_s390_vcpu_interrupt(S390CPU *cpu, struct kvm_s390_irq *irq);
void kvm_s390_floating_interrupt(struct kvm_s390_irq *irq);
int kvm_s390_inject_flic(struct kvm_s390_irq *irq);
+int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
+ bool is_write);
void kvm_s390_access_exception(S390CPU *cpu, uint16_t code, uint64_t te_code);
#else
static inline void kvm_s390_virtio_irq(int config_change, uint64_t token)
@@ -402,6 +404,11 @@ static inline void kvm_s390_virtio_irq(int config_change, uint64_t token)
static inline void kvm_s390_service_interrupt(uint32_t parm)
{
}
+static inline int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, void *hostbuf,
+ int len, bool is_write)
+{
+ return -ENOSYS;
+}
static inline void kvm_s390_access_exception(S390CPU *cpu, uint16_t code,
uint64_t te_code)
{
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 195493c..57a3aa1 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -117,6 +117,7 @@ const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
static int cap_sync_regs;
static int cap_async_pf;
+static int cap_mem_op;
static void *legacy_s390_alloc(size_t size, uint64_t *align);
@@ -176,6 +177,7 @@ int kvm_arch_init(KVMState *s)
{
cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS);
cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF);
+ cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP);
if (kvm_check_extension(s, KVM_CAP_VM_ATTRIBUTES)) {
kvm_s390_enable_cmma(s);
@@ -436,6 +438,39 @@ int kvm_arch_get_registers(CPUState *cs)
return 0;
}
+/**
+ * kvm_s390_mem_op:
+ * @addr: the logical start address in guest memory
+ * @hostbuf: buffer in host memory. NULL = do only checks w/o copying
+ * @len: length that should be transfered
+ * @is_write: true = write, false = read
+ * Returns: 0 on success, non-zero if an exception or error occured
+ *
+ * Use KVM ioctl to read/write from/to guest memory. An access exception
+ * is injected into the vCPU in case of translation errors.
+ */
+int kvm_s390_mem_op(S390CPU *cpu, vaddr addr, void *hostbuf, int len,
+ bool is_write)
+{
+ struct kvm_s390_mem_op mem_op = {
+ .gaddr = addr,
+ .flags = KVM_S390_MEMOP_F_INJECT_EXCEPTION,
+ .size = len,
+ .op = is_write ? KVM_S390_MEMOP_LOGICAL_WRITE
+ : KVM_S390_MEMOP_LOGICAL_READ,
+ .buf = (uint64_t)hostbuf,
+ };
+
+ if (!cap_mem_op) {
+ return -ENOSYS;
+ }
+ if (!hostbuf) {
+ mem_op.flags |= KVM_S390_MEMOP_F_CHECK_ONLY;
+ }
+
+ return kvm_vcpu_ioctl(CPU(cpu), KVM_S390_MEM_OP, &mem_op);
+}
+
/*
* Legacy layout for s390:
* Older S390 KVM requires the topmost vma of the RAM to be
diff --git a/target-s390x/mmu_helper.c b/target-s390x/mmu_helper.c
index b061c85..22f965a 100644
--- a/target-s390x/mmu_helper.c
+++ b/target-s390x/mmu_helper.c
@@ -450,6 +450,15 @@ int s390_cpu_virt_mem_rw(S390CPU *cpu, vaddr laddr, void *hostbuf,
target_ulong *pages;
int ret;
+ if (kvm_enabled()) {
+ ret = kvm_s390_mem_op(cpu, laddr, hostbuf, len, is_write);
+ if (ret >= 0) {
+ return ret;
+ } else if (ret != -ENOSYS) {
+ error_printf("kvm_s390_mem_op() failed: %s\n", strerror(-ret));
+ }
+ }
+
nr_pages = (((laddr & ~TARGET_PAGE_MASK) + len - 1) >> TARGET_PAGE_BITS)
+ 1;
pages = g_malloc(nr_pages * sizeof(*pages));
--
1.7.1
^ permalink raw reply related [flat|nested] 3+ messages in thread