Loading arch/x86/include/asm/kvm_host.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -908,6 +908,8 @@ struct msr_bitmap_range { /* Xen emulation context */ /* Xen emulation context */ struct kvm_xen { struct kvm_xen { bool long_mode; bool long_mode; bool shinfo_set; struct gfn_to_hva_cache shinfo_cache; }; }; enum kvm_irqchip_mode { enum kvm_irqchip_mode { Loading arch/x86/kvm/xen.c +36 −4 Original line number Original line Diff line number Diff line Loading @@ -13,25 +13,49 @@ #include <linux/kvm_host.h> #include <linux/kvm_host.h> #include <trace/events/kvm.h> #include <trace/events/kvm.h> #include <xen/interface/xen.h> #include "trace.h" #include "trace.h" DEFINE_STATIC_KEY_DEFERRED_FALSE(kvm_xen_enabled, HZ); DEFINE_STATIC_KEY_DEFERRED_FALSE(kvm_xen_enabled, HZ); static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn) { int ret; int idx = srcu_read_lock(&kvm->srcu); ret = kvm_gfn_to_hva_cache_init(kvm, &kvm->arch.xen.shinfo_cache, gfn_to_gpa(gfn), PAGE_SIZE); if (!ret) { kvm->arch.xen.shinfo_set = true; } srcu_read_unlock(&kvm->srcu, idx); return ret; } int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) { { int r = -ENOENT; int r = -ENOENT; mutex_lock(&kvm->lock); mutex_unlock(&kvm->lock); mutex_unlock(&kvm->lock); switch (data->type) { switch (data->type) { case KVM_XEN_ATTR_TYPE_LONG_MODE: case KVM_XEN_ATTR_TYPE_LONG_MODE: if (!IS_ENABLED(CONFIG_64BIT) && data->u.long_mode) if (!IS_ENABLED(CONFIG_64BIT) && data->u.long_mode) { return -EINVAL; r = -EINVAL; } else { kvm->arch.xen.long_mode = !!data->u.long_mode; kvm->arch.xen.long_mode = !!data->u.long_mode; r = 0; r = 0; } break; break; case KVM_XEN_ATTR_TYPE_SHARED_INFO: r = kvm_xen_shared_info_init(kvm, data->u.shared_info.gfn); break; default: default: break; break; } } Loading @@ -51,6 +75,14 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) data->u.long_mode = kvm->arch.xen.long_mode; data->u.long_mode = kvm->arch.xen.long_mode; r = 0; r = 0; break; break; case KVM_XEN_ATTR_TYPE_SHARED_INFO: if (kvm->arch.xen.shinfo_set) { data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_cache.gpa); r = 0; } break; default: default: break; break; } } Loading include/uapi/linux/kvm.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -1595,11 +1595,15 @@ struct kvm_xen_hvm_attr { __u16 pad[3]; __u16 pad[3]; union { union { __u8 long_mode; __u8 long_mode; struct { __u64 gfn; } shared_info; __u64 pad[8]; __u64 pad[8]; } u; } u; }; }; #define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 #define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 #define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1 /* Secure Encrypted Virtualization command */ /* Secure Encrypted Virtualization command */ enum sev_cmd_id { enum sev_cmd_id { Loading Loading
arch/x86/include/asm/kvm_host.h +2 −0 Original line number Original line Diff line number Diff line Loading @@ -908,6 +908,8 @@ struct msr_bitmap_range { /* Xen emulation context */ /* Xen emulation context */ struct kvm_xen { struct kvm_xen { bool long_mode; bool long_mode; bool shinfo_set; struct gfn_to_hva_cache shinfo_cache; }; }; enum kvm_irqchip_mode { enum kvm_irqchip_mode { Loading
arch/x86/kvm/xen.c +36 −4 Original line number Original line Diff line number Diff line Loading @@ -13,25 +13,49 @@ #include <linux/kvm_host.h> #include <linux/kvm_host.h> #include <trace/events/kvm.h> #include <trace/events/kvm.h> #include <xen/interface/xen.h> #include "trace.h" #include "trace.h" DEFINE_STATIC_KEY_DEFERRED_FALSE(kvm_xen_enabled, HZ); DEFINE_STATIC_KEY_DEFERRED_FALSE(kvm_xen_enabled, HZ); static int kvm_xen_shared_info_init(struct kvm *kvm, gfn_t gfn) { int ret; int idx = srcu_read_lock(&kvm->srcu); ret = kvm_gfn_to_hva_cache_init(kvm, &kvm->arch.xen.shinfo_cache, gfn_to_gpa(gfn), PAGE_SIZE); if (!ret) { kvm->arch.xen.shinfo_set = true; } srcu_read_unlock(&kvm->srcu, idx); return ret; } int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) int kvm_xen_hvm_set_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) { { int r = -ENOENT; int r = -ENOENT; mutex_lock(&kvm->lock); mutex_unlock(&kvm->lock); mutex_unlock(&kvm->lock); switch (data->type) { switch (data->type) { case KVM_XEN_ATTR_TYPE_LONG_MODE: case KVM_XEN_ATTR_TYPE_LONG_MODE: if (!IS_ENABLED(CONFIG_64BIT) && data->u.long_mode) if (!IS_ENABLED(CONFIG_64BIT) && data->u.long_mode) { return -EINVAL; r = -EINVAL; } else { kvm->arch.xen.long_mode = !!data->u.long_mode; kvm->arch.xen.long_mode = !!data->u.long_mode; r = 0; r = 0; } break; break; case KVM_XEN_ATTR_TYPE_SHARED_INFO: r = kvm_xen_shared_info_init(kvm, data->u.shared_info.gfn); break; default: default: break; break; } } Loading @@ -51,6 +75,14 @@ int kvm_xen_hvm_get_attr(struct kvm *kvm, struct kvm_xen_hvm_attr *data) data->u.long_mode = kvm->arch.xen.long_mode; data->u.long_mode = kvm->arch.xen.long_mode; r = 0; r = 0; break; break; case KVM_XEN_ATTR_TYPE_SHARED_INFO: if (kvm->arch.xen.shinfo_set) { data->u.shared_info.gfn = gpa_to_gfn(kvm->arch.xen.shinfo_cache.gpa); r = 0; } break; default: default: break; break; } } Loading
include/uapi/linux/kvm.h +4 −0 Original line number Original line Diff line number Diff line Loading @@ -1595,11 +1595,15 @@ struct kvm_xen_hvm_attr { __u16 pad[3]; __u16 pad[3]; union { union { __u8 long_mode; __u8 long_mode; struct { __u64 gfn; } shared_info; __u64 pad[8]; __u64 pad[8]; } u; } u; }; }; #define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 #define KVM_XEN_ATTR_TYPE_LONG_MODE 0x0 #define KVM_XEN_ATTR_TYPE_SHARED_INFO 0x1 /* Secure Encrypted Virtualization command */ /* Secure Encrypted Virtualization command */ enum sev_cmd_id { enum sev_cmd_id { Loading