[RFC PATCH 2/6] kvm: Add guest memory Pkey initialization

Jacky Li <[email protected]>
Newsgroups gmane.comp.emulators.kvm.devel,gmane.comp.emulators.qemu
Message-ID <[email protected]>
Add initialization logic during early QEMU startup to allocate a
dedicated userspace protection key (Pkey) for protecting guest physical
memory when enabled via QEMU_ENABLE_PKEY_GUEST_MEMORY.

Signed-off-by: Jacky Li <[email protected]>
---
 include/exec/cpu-common.h |  1 +
 system/vl.c               |  1 +
 util/meson.build          |  2 +-
 util/pkey.c               | 23 +++++++++++++++++++++++
 4 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 6594f7fa1b..5ede0c65dc 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -112,4 +112,5 @@ static inline CPUState *env_cpu(CPUArchState *env)
     return (CPUState *)env_cpu_const(env);
 }
 
+void qemu_init_guest_memory_pkey(void);
 #endif /* CPU_COMMON_H */
diff --git a/system/vl.c b/system/vl.c
index 061cbdf860..e49c6fed39 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -2907,6 +2907,7 @@ void qemu_init(int argc, char **argv)
     module_allow_arch(target_name());
 
     qemu_init_subsystems();
+    qemu_init_guest_memory_pkey();
 
     /* first pass of option parsing */
     optind = 1;
diff --git a/util/meson.build b/util/meson.build
index fa174c07a5..682a078a3d 100644
--- a/util/meson.build
+++ b/util/meson.build
@@ -9,7 +9,7 @@ if host_os != 'windows'
   util_ss.add(files('compatfd.c'))
   util_ss.add(files('event_notifier-posix.c'))
   if host_os != 'emscripten'
-    util_ss.add(files('mmap-alloc.c'))
+    util_ss.add(files('mmap-alloc.c', 'pkey.c'))
   endif
   freebsd_dep = []
   if host_os == 'freebsd'
diff --git a/util/pkey.c b/util/pkey.c
index 4f14a72151..249e36d508 100644
--- a/util/pkey.c
+++ b/util/pkey.c
@@ -40,6 +40,8 @@
 #define PKEY_DISABLE_ACCESS 0x1
 #endif
 
+static int guest_memory_pkey = -1;
+
 /* Each protection key occupies exactly 2 bits in the PKRU register. */
 #define BITS_PER_KEY 2
 /* The mask used to extract/write the 2-bit permission flags. */
@@ -86,6 +88,24 @@ static inline __attribute__((always_inline)) intptr_t local_syscall3(
     return ret;
 }
 
+__attribute__((target("pku"))) void qemu_init_guest_memory_pkey(void)
+{
+    if (guest_memory_pkey != -1) {
+        return;
+    }
+
+    const char *enable_pkey = getenv("QEMU_ENABLE_PKEY_GUEST_MEMORY");
+    if (enable_pkey && strcmp(enable_pkey, "1") == 0) {
+        int pkey = pkey_alloc(0, 0);
+        if (pkey == -1) {
+            error_report("pkey_alloc failed for guest memory: %s",
+                         strerror(errno));
+        } else {
+            guest_memory_pkey = pkey;
+        }
+    }
+}
+
 #else
 /* Dummy implementations for all other configurations (non-x86_64 Linux, */
 /* Windows, macOS, etc.) */
@@ -93,4 +113,7 @@ static inline __attribute__((always_inline)) intptr_t local_syscall3(
 #include <linux/kvm.h>
 #include <sys/ioctl.h>
 #endif
+
+void qemu_init_guest_memory_pkey(void)
+{}
 #endif

-- 
2.55.0.737.g08866a6d13-goog
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.