]> Pileus Git - ~andy/linux/blobdiff - include/linux/kvm_host.h
KVM: make processes waiting on vcpu mutex killable
[~andy/linux] / include / linux / kvm_host.h
index ce7c32950f4ea4eb00bd76e9130f7f9a24148ddc..80bfc880921ea1fd2fe183e9aeb21ea1e4afca09 100644 (file)
 #define KVM_MMIO_SIZE 8
 #endif
 
+/*
+ * The bit 16 ~ bit 31 of kvm_memory_region::flags are internally used
+ * in kvm, other bits are visible for userspace which are defined in
+ * include/linux/kvm_h.
+ */
+#define KVM_MEMSLOT_INVALID    (1UL << 16)
+
 /*
  * If we support unaligned MMIO, at most one fragment will be split into two:
  */
 #define KVM_MAX_MMIO_FRAGMENTS \
        (KVM_MMIO_SIZE / KVM_USER_MMIO_SIZE + KVM_EXTRA_MMIO_FRAGMENTS)
 
-#define KVM_PFN_ERR_FAULT      (-EFAULT)
-#define KVM_PFN_ERR_HWPOISON   (-EHWPOISON)
-#define KVM_PFN_ERR_BAD                (-ENOENT)
+/*
+ * For the normal pfn, the highest 12 bits should be zero,
+ * so we can mask these bits to indicate the error.
+ */
+#define KVM_PFN_ERR_MASK       (0xfffULL << 52)
+
+#define KVM_PFN_ERR_FAULT      (KVM_PFN_ERR_MASK)
+#define KVM_PFN_ERR_HWPOISON   (KVM_PFN_ERR_MASK + 1)
+#define KVM_PFN_ERR_BAD                (KVM_PFN_ERR_MASK + 2)
+#define KVM_PFN_ERR_RO_FAULT   (KVM_PFN_ERR_MASK + 3)
 
-static inline int is_error_pfn(pfn_t pfn)
+static inline bool is_error_pfn(pfn_t pfn)
 {
-       return IS_ERR_VALUE(pfn);
+       return !!(pfn & KVM_PFN_ERR_MASK);
 }
 
-static inline int is_noslot_pfn(pfn_t pfn)
+static inline bool is_noslot_pfn(pfn_t pfn)
 {
-       return pfn == -ENOENT;
+       return pfn == KVM_PFN_ERR_BAD;
 }
 
-static inline int is_invalid_pfn(pfn_t pfn)
+static inline bool is_invalid_pfn(pfn_t pfn)
 {
        return !is_noslot_pfn(pfn) && is_error_pfn(pfn);
 }
 
+#define KVM_HVA_ERR_BAD                (PAGE_OFFSET)
+#define KVM_HVA_ERR_RO_BAD     (PAGE_OFFSET + PAGE_SIZE)
+
+static inline bool kvm_is_error_hva(unsigned long addr)
+{
+       return addr >= PAGE_OFFSET;
+}
+
 #define KVM_ERR_PTR_BAD_PAGE   (ERR_PTR(-ENOENT))
 
-static inline int is_error_page(struct page *page)
+static inline bool is_error_page(struct page *page)
 {
        return IS_ERR(page);
 }
@@ -386,7 +408,7 @@ static inline struct kvm_vcpu *kvm_get_vcpu(struct kvm *kvm, int i)
 int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id);
 void kvm_vcpu_uninit(struct kvm_vcpu *vcpu);
 
-void vcpu_load(struct kvm_vcpu *vcpu);
+int __must_check vcpu_load(struct kvm_vcpu *vcpu);
 void vcpu_put(struct kvm_vcpu *vcpu);
 
 int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align,
@@ -416,7 +438,6 @@ id_to_memslot(struct kvm_memslots *slots, int id)
        return slot;
 }
 
-int kvm_is_error_hva(unsigned long addr);
 int kvm_set_memory_region(struct kvm *kvm,
                          struct kvm_userspace_memory_region *mem,
                          int user_alloc);
@@ -437,19 +458,23 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
                                int user_alloc);
 bool kvm_largepages_enabled(void);
 void kvm_disable_largepages(void);
-void kvm_arch_flush_shadow(struct kvm *kvm);
+/* flush all memory translations */
+void kvm_arch_flush_shadow_all(struct kvm *kvm);
+/* flush memory translations pointing to 'slot' */
+void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
+                                  struct kvm_memory_slot *slot);
 
 int gfn_to_page_many_atomic(struct kvm *kvm, gfn_t gfn, struct page **pages,
                            int nr_pages);
 
 struct page *gfn_to_page(struct kvm *kvm, gfn_t gfn);
 unsigned long gfn_to_hva(struct kvm *kvm, gfn_t gfn);
+unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn);
 void kvm_release_page_clean(struct page *page);
 void kvm_release_page_dirty(struct page *page);
 void kvm_set_page_dirty(struct page *page);
 void kvm_set_page_accessed(struct page *page);
 
-pfn_t hva_to_pfn_atomic(unsigned long addr);
 pfn_t gfn_to_pfn_atomic(struct kvm *kvm, gfn_t gfn);
 pfn_t gfn_to_pfn_async(struct kvm *kvm, gfn_t gfn, bool *async,
                       bool write_fault, bool *writable);
@@ -457,7 +482,9 @@ pfn_t gfn_to_pfn(struct kvm *kvm, gfn_t gfn);
 pfn_t gfn_to_pfn_prot(struct kvm *kvm, gfn_t gfn, bool write_fault,
                      bool *writable);
 pfn_t gfn_to_pfn_memslot(struct kvm_memory_slot *slot, gfn_t gfn);
-void kvm_release_pfn_dirty(pfn_t);
+pfn_t gfn_to_pfn_memslot_atomic(struct kvm_memory_slot *slot, gfn_t gfn);
+
+void kvm_release_pfn_dirty(pfn_t pfn);
 void kvm_release_pfn_clean(pfn_t pfn);
 void kvm_set_pfn_dirty(pfn_t pfn);
 void kvm_set_pfn_accessed(pfn_t pfn);
@@ -750,6 +777,12 @@ __gfn_to_memslot(struct kvm_memslots *slots, gfn_t gfn)
        return search_memslots(slots, gfn);
 }
 
+static inline unsigned long
+__gfn_to_hva_memslot(struct kvm_memory_slot *slot, gfn_t gfn)
+{
+       return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE;
+}
+
 static inline int memslot_id(struct kvm *kvm, gfn_t gfn)
 {
        return gfn_to_memslot(kvm, gfn)->id;
@@ -770,12 +803,6 @@ hva_to_gfn_memslot(unsigned long hva, struct kvm_memory_slot *slot)
        return slot->base_gfn + gfn_offset;
 }
 
-static inline unsigned long gfn_to_hva_memslot(struct kvm_memory_slot *slot,
-                                              gfn_t gfn)
-{
-       return slot->userspace_addr + (gfn - slot->base_gfn) * PAGE_SIZE;
-}
-
 static inline gpa_t gfn_to_gpa(gfn_t gfn)
 {
        return (gpa_t)gfn << PAGE_SHIFT;