File Index
Files and directories
Sign in
FILE

sev.h

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/kvm/include/x86/sev.h C
  1/* SPDX-License-Identifier: GPL-2.0-only */
  2/*
  3 * Helpers used for SEV guests
  4 *
  5 */
  6#ifndef SELFTEST_KVM_SEV_H
  7#define SELFTEST_KVM_SEV_H
  8
  9#include <stdint.h>
 10#include <stdbool.h>
 11
 12#include "linux/psp-sev.h"
 13
 14#include "kvm_util.h"
 15#include "svm_util.h"
 16#include "processor.h"
 17
 18enum sev_guest_state {
 19	SEV_GUEST_STATE_UNINITIALIZED = 0,
 20	SEV_GUEST_STATE_LAUNCH_UPDATE,
 21	SEV_GUEST_STATE_LAUNCH_SECRET,
 22	SEV_GUEST_STATE_RUNNING,
 23};
 24
 25#define SEV_POLICY_NO_DBG	(1UL << 0)
 26#define SEV_POLICY_ES		(1UL << 2)
 27
 28#define SNP_POLICY_SMT		(1ULL << 16)
 29#define SNP_POLICY_RSVD_MBO	(1ULL << 17)
 30#define SNP_POLICY_DBG		(1ULL << 19)
 31
 32#define GHCB_MSR_TERM_REQ	0x100
 33
 34static inline bool is_sev_snp_vm(struct kvm_vm *vm)
 35{
 36	return vm->type == KVM_X86_SNP_VM;
 37}
 38
 39static inline bool is_sev_es_vm(struct kvm_vm *vm)
 40{
 41	return is_sev_snp_vm(vm) || vm->type == KVM_X86_SEV_ES_VM;
 42}
 43
 44static inline bool is_sev_vm(struct kvm_vm *vm)
 45{
 46	return is_sev_es_vm(vm) || vm->type == KVM_X86_SEV_VM;
 47}
 48
 49void sev_vm_launch(struct kvm_vm *vm, uint32_t policy);
 50void sev_vm_launch_measure(struct kvm_vm *vm, uint8_t *measurement);
 51void sev_vm_launch_finish(struct kvm_vm *vm);
 52void snp_vm_launch_start(struct kvm_vm *vm, uint64_t policy);
 53void snp_vm_launch_update(struct kvm_vm *vm);
 54void snp_vm_launch_finish(struct kvm_vm *vm);
 55
 56struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code,
 57					   struct kvm_vcpu **cpu);
 58void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, uint8_t *measurement);
 59
 60kvm_static_assert(SEV_RET_SUCCESS == 0);
 61
 62/*
 63 * A SEV-SNP VM requires the policy reserved bit to always be set.
 64 * The SMT policy bit is also required to be set based on SMT being
 65 * available and active on the system.
 66 */
 67static inline u64 snp_default_policy(void)
 68{
 69	return SNP_POLICY_RSVD_MBO | (is_smt_on() ? SNP_POLICY_SMT : 0);
 70}
 71
 72/*
 73 * The KVM_MEMORY_ENCRYPT_OP uAPI is utter garbage and takes an "unsigned long"
 74 * instead of a proper struct.  The size of the parameter is embedded in the
 75 * ioctl number, i.e. is ABI and thus immutable.  Hack around the mess by
 76 * creating an overlay to pass in an "unsigned long" without a cast (casting
 77 * will make the compiler unhappy due to dereferencing an aliased pointer).
 78 */
 79#define __vm_sev_ioctl(vm, cmd, arg)					\
 80({									\
 81	int r;								\
 82									\
 83	union {								\
 84		struct kvm_sev_cmd c;					\
 85		unsigned long raw;					\
 86	} sev_cmd = { .c = {						\
 87		.id = (cmd),						\
 88		.data = (uint64_t)(arg),				\
 89		.sev_fd = (vm)->arch.sev_fd,				\
 90	} };								\
 91									\
 92	r = __vm_ioctl(vm, KVM_MEMORY_ENCRYPT_OP, &sev_cmd.raw);	\
 93	r ?: sev_cmd.c.error;						\
 94})
 95
 96#define vm_sev_ioctl(vm, cmd, arg)					\
 97({									\
 98	int ret = __vm_sev_ioctl(vm, cmd, arg);				\
 99									\
100	__TEST_ASSERT_VM_VCPU_IOCTL(!ret, #cmd,	ret, vm);		\
101})
102
103void sev_vm_init(struct kvm_vm *vm);
104void sev_es_vm_init(struct kvm_vm *vm);
105void snp_vm_init(struct kvm_vm *vm);
106
107static inline void vmgexit(void)
108{
109	__asm__ __volatile__("rep; vmmcall");
110}
111
112static inline void sev_register_encrypted_memory(struct kvm_vm *vm,
113						 struct userspace_mem_region *region)
114{
115	struct kvm_enc_region range = {
116		.addr = region->region.userspace_addr,
117		.size = region->region.memory_size,
118	};
119
120	vm_ioctl(vm, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
121}
122
123static inline void sev_launch_update_data(struct kvm_vm *vm, vm_paddr_t gpa,
124					  uint64_t size)
125{
126	struct kvm_sev_launch_update_data update_data = {
127		.uaddr = (unsigned long)addr_gpa2hva(vm, gpa),
128		.len = size,
129	};
130
131	vm_sev_ioctl(vm, KVM_SEV_LAUNCH_UPDATE_DATA, &update_data);
132}
133
134static inline void snp_launch_update_data(struct kvm_vm *vm, vm_paddr_t gpa,
135					  uint64_t hva, uint64_t size, uint8_t type)
136{
137	struct kvm_sev_snp_launch_update update_data = {
138		.uaddr = hva,
139		.gfn_start = gpa >> PAGE_SHIFT,
140		.len = size,
141		.type = type,
142	};
143
144	vm_sev_ioctl(vm, KVM_SEV_SNP_LAUNCH_UPDATE, &update_data);
145}
146
147#endif /* SELFTEST_KVM_SEV_H */
~/ Read-only file preview.