qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
To: qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, david@gibson.dropbear.id.au, clg@kaod.org,
	groug@kaod.org, Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Subject: [Qemu-devel] [QEMU-PPC] [PATCH 11/13] target/ppc: Implement hcall H_COPY_TOFROM_GUEST
Date: Fri,  3 May 2019 15:53:14 +1000	[thread overview]
Message-ID: <20190503055316.6441-12-sjitindarsingh@gmail.com> (raw)
In-Reply-To: <20190503055316.6441-1-sjitindarsingh@gmail.com>

The hcall H_COPY_TOFROM_GUEST of used by a guest acting as a nested
hypervisor to access quadrants since quadrant access is hypervisor
privileged.

Translate the guest address to be accessed, map the memory and perform
the access on behalf of the guest. If the parameters are invalid, the
address can't be translated or the memory cannot be mapped then fail
the access.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 hw/ppc/spapr_hcall.c     | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h   |  3 +-
 target/ppc/mmu-radix64.c |  7 ++---
 target/ppc/mmu-radix64.h |  4 +++
 4 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index a84d5e2163..a370d70500 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -17,6 +17,7 @@
 #include "mmu-book3s-v3.h"
 #include "hw/mem/memory-device.h"
 #include "hw/ppc/ppc.h"
+#include "mmu-radix64.h"
 
 static bool has_spr(PowerPCCPU *cpu, int spr)
 {
@@ -2158,6 +2159,78 @@ static target_ulong h_nested_tlb_invalidate(PowerPCCPU *cpu,
     return H_SUCCESS;
 }
 
+static target_ulong h_copy_tofrom_guest(PowerPCCPU *cpu,
+                                        SpaprMachineState *spapr,
+                                        target_ulong opcode, target_ulong *args)
+{
+    target_ulong lpid = args[0];
+    target_ulong pid = args[1];
+    vaddr eaddr = args[2];
+    target_ulong gp_to = args[3];
+    target_ulong gp_from = args[4];
+    target_ulong n = args[5];
+    int is_load = !!gp_to;
+    void *from, *to;
+    int prot, psize;
+    hwaddr raddr, to_len, from_len;
+
+    if (spapr_get_cap(spapr, SPAPR_CAP_NESTED_KVM_HV) == 0) {
+        return H_FUNCTION;
+    }
+
+    if ((gp_to && gp_from) || (!gp_to && !gp_from)) {
+        return H_PARAMETER;
+    }
+
+    if (eaddr & (0xFFFUL << 52)) {
+        return H_PARAMETER;
+    }
+
+    if (!lpid) {
+        return H_PARAMETER;
+    }
+
+    /* Translate eaddr to raddr */
+    if (ppc_radix64_xlate(cpu, eaddr, is_load, lpid, pid, 1, &raddr, &psize,
+                          &prot, 0)) {
+        return H_NOT_FOUND;
+    }
+    if (((raddr & ((1UL << psize) - 1)) + n) >= (1UL << psize)) {
+        return H_PARAMETER;
+    }
+
+    if (is_load) {
+        gp_from = raddr;
+    } else {
+        gp_to = raddr;
+    }
+
+    /* Map the memory regions and perform a memory copy */
+    from = cpu_physical_memory_map(gp_from, &from_len, 0);
+    if (!from) {
+        return H_NOT_FOUND;
+    }
+    if (from_len < n) {
+        cpu_physical_memory_unmap(from, from_len, 0, 0);
+        return H_PARAMETER;
+    }
+    to = cpu_physical_memory_map(gp_to, &to_len, 1);
+    if (!to) {
+        cpu_physical_memory_unmap(from, from_len, 0, 0);
+        return H_PARAMETER;
+    }
+    if (to_len < n) {
+        cpu_physical_memory_unmap(from, from_len, 0, 0);
+        cpu_physical_memory_unmap(to, to_len, 1, 0);
+        return H_PARAMETER;
+    }
+    memcpy(to, from, n);
+    cpu_physical_memory_unmap(from, from_len, 0, n);
+    cpu_physical_memory_unmap(to, to_len, 1, n);
+
+    return H_SUCCESS;
+}
+
 static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
 static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
 
@@ -2268,6 +2341,7 @@ static void hypercall_register_types(void)
     spapr_register_hypercall(H_SET_PARTITION_TABLE, h_set_partition_table);
     spapr_register_hypercall(H_ENTER_NESTED, h_enter_nested);
     spapr_register_hypercall(H_TLB_INVALIDATE, h_nested_tlb_invalidate);
+    spapr_register_hypercall(H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
 
     /* Virtual Processor Home Node */
     spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY,
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 6a614c445f..d62f4108d4 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -505,7 +505,8 @@ struct SpaprMachineState {
 #define H_SET_PARTITION_TABLE   0xF800
 #define H_ENTER_NESTED          0xF804
 #define H_TLB_INVALIDATE        0xF808
-#define KVMPPC_HCALL_MAX        H_TLB_INVALIDATE
+#define H_COPY_TOFROM_GUEST     0xF80C
+#define KVMPPC_HCALL_MAX        H_COPY_TOFROM_GUEST
 
 typedef struct SpaprDeviceTreeUpdateHeader {
     uint32_t version_id;
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 6118ad1b00..2a8147fc38 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -429,10 +429,9 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, ppc_v3_pate_t *pate)
     return true;
 }
 
-static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx,
-                             uint64_t lpid, uint64_t pid, bool relocation,
-                             hwaddr *raddr, int *psizep, int *protp,
-                             bool cause_excp)
+int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, uint64_t lpid,
+                      uint64_t pid, bool relocation, hwaddr *raddr, int *psizep,
+                      int *protp, bool cause_excp)
 {
     CPUPPCState *env = &cpu->env;
     ppc_v3_pate_t pate;
diff --git a/target/ppc/mmu-radix64.h b/target/ppc/mmu-radix64.h
index 96228546aa..c0bbd5c332 100644
--- a/target/ppc/mmu-radix64.h
+++ b/target/ppc/mmu-radix64.h
@@ -66,6 +66,10 @@ static inline int ppc_radix64_get_prot_amr(PowerPCCPU *cpu)
            (iamr & 0x1 ? 0 : PAGE_EXEC);
 }
 
+int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, uint64_t lpid,
+                      uint64_t pid, bool relocation, hwaddr *raddr, int *psizep,
+                      int *protp, bool cause_excp);
+
 #endif /* TARGET_PPC64 */
 
 #endif /* CONFIG_USER_ONLY */
-- 
2.13.6

WARNING: multiple messages have this Message-ID (diff)
From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
To: qemu-devel@nongnu.org
Cc: groug@kaod.org, qemu-ppc@nongnu.org, clg@kaod.org,
	Suraj Jitindar Singh <sjitindarsingh@gmail.com>,
	david@gibson.dropbear.id.au
Subject: [Qemu-devel] [QEMU-PPC] [PATCH 11/13] target/ppc: Implement hcall H_COPY_TOFROM_GUEST
Date: Fri,  3 May 2019 15:53:14 +1000	[thread overview]
Message-ID: <20190503055316.6441-12-sjitindarsingh@gmail.com> (raw)
Message-ID: <20190503055314.UWvhl3xmX72muF6sZ57o8o3a-7wUbyUQxDOLzHIJchs@z> (raw)
In-Reply-To: <20190503055316.6441-1-sjitindarsingh@gmail.com>

The hcall H_COPY_TOFROM_GUEST of used by a guest acting as a nested
hypervisor to access quadrants since quadrant access is hypervisor
privileged.

Translate the guest address to be accessed, map the memory and perform
the access on behalf of the guest. If the parameters are invalid, the
address can't be translated or the memory cannot be mapped then fail
the access.

Signed-off-by: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
---
 hw/ppc/spapr_hcall.c     | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/hw/ppc/spapr.h   |  3 +-
 target/ppc/mmu-radix64.c |  7 ++---
 target/ppc/mmu-radix64.h |  4 +++
 4 files changed, 83 insertions(+), 5 deletions(-)

diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index a84d5e2163..a370d70500 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -17,6 +17,7 @@
 #include "mmu-book3s-v3.h"
 #include "hw/mem/memory-device.h"
 #include "hw/ppc/ppc.h"
+#include "mmu-radix64.h"
 
 static bool has_spr(PowerPCCPU *cpu, int spr)
 {
@@ -2158,6 +2159,78 @@ static target_ulong h_nested_tlb_invalidate(PowerPCCPU *cpu,
     return H_SUCCESS;
 }
 
+static target_ulong h_copy_tofrom_guest(PowerPCCPU *cpu,
+                                        SpaprMachineState *spapr,
+                                        target_ulong opcode, target_ulong *args)
+{
+    target_ulong lpid = args[0];
+    target_ulong pid = args[1];
+    vaddr eaddr = args[2];
+    target_ulong gp_to = args[3];
+    target_ulong gp_from = args[4];
+    target_ulong n = args[5];
+    int is_load = !!gp_to;
+    void *from, *to;
+    int prot, psize;
+    hwaddr raddr, to_len, from_len;
+
+    if (spapr_get_cap(spapr, SPAPR_CAP_NESTED_KVM_HV) == 0) {
+        return H_FUNCTION;
+    }
+
+    if ((gp_to && gp_from) || (!gp_to && !gp_from)) {
+        return H_PARAMETER;
+    }
+
+    if (eaddr & (0xFFFUL << 52)) {
+        return H_PARAMETER;
+    }
+
+    if (!lpid) {
+        return H_PARAMETER;
+    }
+
+    /* Translate eaddr to raddr */
+    if (ppc_radix64_xlate(cpu, eaddr, is_load, lpid, pid, 1, &raddr, &psize,
+                          &prot, 0)) {
+        return H_NOT_FOUND;
+    }
+    if (((raddr & ((1UL << psize) - 1)) + n) >= (1UL << psize)) {
+        return H_PARAMETER;
+    }
+
+    if (is_load) {
+        gp_from = raddr;
+    } else {
+        gp_to = raddr;
+    }
+
+    /* Map the memory regions and perform a memory copy */
+    from = cpu_physical_memory_map(gp_from, &from_len, 0);
+    if (!from) {
+        return H_NOT_FOUND;
+    }
+    if (from_len < n) {
+        cpu_physical_memory_unmap(from, from_len, 0, 0);
+        return H_PARAMETER;
+    }
+    to = cpu_physical_memory_map(gp_to, &to_len, 1);
+    if (!to) {
+        cpu_physical_memory_unmap(from, from_len, 0, 0);
+        return H_PARAMETER;
+    }
+    if (to_len < n) {
+        cpu_physical_memory_unmap(from, from_len, 0, 0);
+        cpu_physical_memory_unmap(to, to_len, 1, 0);
+        return H_PARAMETER;
+    }
+    memcpy(to, from, n);
+    cpu_physical_memory_unmap(from, from_len, 0, n);
+    cpu_physical_memory_unmap(to, to_len, 1, n);
+
+    return H_SUCCESS;
+}
+
 static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
 static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - KVMPPC_HCALL_BASE + 1];
 
@@ -2268,6 +2341,7 @@ static void hypercall_register_types(void)
     spapr_register_hypercall(H_SET_PARTITION_TABLE, h_set_partition_table);
     spapr_register_hypercall(H_ENTER_NESTED, h_enter_nested);
     spapr_register_hypercall(H_TLB_INVALIDATE, h_nested_tlb_invalidate);
+    spapr_register_hypercall(H_COPY_TOFROM_GUEST, h_copy_tofrom_guest);
 
     /* Virtual Processor Home Node */
     spapr_register_hypercall(H_HOME_NODE_ASSOCIATIVITY,
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 6a614c445f..d62f4108d4 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -505,7 +505,8 @@ struct SpaprMachineState {
 #define H_SET_PARTITION_TABLE   0xF800
 #define H_ENTER_NESTED          0xF804
 #define H_TLB_INVALIDATE        0xF808
-#define KVMPPC_HCALL_MAX        H_TLB_INVALIDATE
+#define H_COPY_TOFROM_GUEST     0xF80C
+#define KVMPPC_HCALL_MAX        H_COPY_TOFROM_GUEST
 
 typedef struct SpaprDeviceTreeUpdateHeader {
     uint32_t version_id;
diff --git a/target/ppc/mmu-radix64.c b/target/ppc/mmu-radix64.c
index 6118ad1b00..2a8147fc38 100644
--- a/target/ppc/mmu-radix64.c
+++ b/target/ppc/mmu-radix64.c
@@ -429,10 +429,9 @@ static bool validate_pate(PowerPCCPU *cpu, uint64_t lpid, ppc_v3_pate_t *pate)
     return true;
 }
 
-static int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx,
-                             uint64_t lpid, uint64_t pid, bool relocation,
-                             hwaddr *raddr, int *psizep, int *protp,
-                             bool cause_excp)
+int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, uint64_t lpid,
+                      uint64_t pid, bool relocation, hwaddr *raddr, int *psizep,
+                      int *protp, bool cause_excp)
 {
     CPUPPCState *env = &cpu->env;
     ppc_v3_pate_t pate;
diff --git a/target/ppc/mmu-radix64.h b/target/ppc/mmu-radix64.h
index 96228546aa..c0bbd5c332 100644
--- a/target/ppc/mmu-radix64.h
+++ b/target/ppc/mmu-radix64.h
@@ -66,6 +66,10 @@ static inline int ppc_radix64_get_prot_amr(PowerPCCPU *cpu)
            (iamr & 0x1 ? 0 : PAGE_EXEC);
 }
 
+int ppc_radix64_xlate(PowerPCCPU *cpu, vaddr eaddr, int rwx, uint64_t lpid,
+                      uint64_t pid, bool relocation, hwaddr *raddr, int *psizep,
+                      int *protp, bool cause_excp);
+
 #endif /* TARGET_PPC64 */
 
 #endif /* CONFIG_USER_ONLY */
-- 
2.13.6



  parent reply	other threads:[~2019-05-03  5:54 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-05-03  5:53 [Qemu-devel] [QEMU-PPC] [PATCH 00/13] target/ppc: Implement KVM support under TCG Suraj Jitindar Singh
2019-05-03  5:53 ` Suraj Jitindar Singh
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 01/13] target/ppc: Implement the VTB for HV access Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-06  6:02   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 02/13] target/ppc: Work [S]PURR implementation and add HV support Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-06  6:15   ` David Gibson
2019-05-07  1:28     ` Suraj Jitindar Singh
2019-05-09  6:45       ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 03/13] target/ppc: Add SPR ASDR Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-06  6:16   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 04/13] target/ppc: Add SPR TBU40 Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-06  6:17   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 05/13] target/ppc: Add privileged message send facilities Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-10  2:09   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 06/13] target/ppc: Enforce that the root page directory size must be at least 5 Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-10  2:11   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 07/13] target/ppc: Handle partition scoped radix tree translation Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-10  2:28   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 08/13] target/ppc: Implement hcall H_SET_PARTITION_TABLE Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-10  2:30   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 09/13] target/ppc: Implement hcall H_ENTER_NESTED Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-10  2:57   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 10/13] target/ppc: Implement hcall H_TLB_INVALIDATE Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-10  6:28   ` David Gibson
2019-05-03  5:53 ` Suraj Jitindar Singh [this message]
2019-05-03  5:53   ` [Qemu-devel] [QEMU-PPC] [PATCH 11/13] target/ppc: Implement hcall H_COPY_TOFROM_GUEST Suraj Jitindar Singh
2019-05-10  6:32   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 12/13] target/ppc: Introduce POWER9 DD2.2 cpu type Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-10  6:32   ` David Gibson
2019-05-03  5:53 ` [Qemu-devel] [QEMU-PPC] [PATCH 13/13] target/ppc: Enable SPAPR_CAP_NESTED_KVM_HV under tcg Suraj Jitindar Singh
2019-05-03  5:53   ` Suraj Jitindar Singh
2019-05-10  6:34   ` David Gibson
2019-05-03  5:58 ` [Qemu-devel] [QEMU-PPC] [PATCH 00/13] target/ppc: Implement KVM support under TCG Suraj Jitindar Singh
2019-05-03  5:58   ` Suraj Jitindar Singh
2019-05-06  6:20 ` David Gibson
2019-05-06 23:45   ` Suraj Jitindar Singh

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=20190503055316.6441-12-sjitindarsingh@gmail.com \
    --to=sjitindarsingh@gmail.com \
    --cc=clg@kaod.org \
    --cc=david@gibson.dropbear.id.au \
    --cc=groug@kaod.org \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).