xref: /qemu/hw/hyperv/hv-balloon-our_range_memslots.h (revision fc524567087c2537b5103cdfc1d41e4f442892b6)
199a4706aSMaciej S. Szmigiero /*
299a4706aSMaciej S. Szmigiero  * QEMU Hyper-V Dynamic Memory Protocol driver
399a4706aSMaciej S. Szmigiero  *
499a4706aSMaciej S. Szmigiero  * Copyright (C) 2020-2023 Oracle and/or its affiliates.
599a4706aSMaciej S. Szmigiero  *
699a4706aSMaciej S. Szmigiero  * This work is licensed under the terms of the GNU GPL, version 2 or later.
799a4706aSMaciej S. Szmigiero  * See the COPYING file in the top-level directory.
899a4706aSMaciej S. Szmigiero  */
999a4706aSMaciej S. Szmigiero 
1099a4706aSMaciej S. Szmigiero #ifndef HW_HYPERV_HV_BALLOON_OUR_RANGE_MEMSLOTS_H
1199a4706aSMaciej S. Szmigiero #define HW_HYPERV_HV_BALLOON_OUR_RANGE_MEMSLOTS_H
1299a4706aSMaciej S. Szmigiero 
1399a4706aSMaciej S. Szmigiero 
14*8be545baSRichard Henderson #include "system/memory.h"
1599a4706aSMaciej S. Szmigiero #include "qom/object.h"
1699a4706aSMaciej S. Szmigiero #include "hv-balloon-page_range_tree.h"
1799a4706aSMaciej S. Szmigiero 
1899a4706aSMaciej S. Szmigiero /* OurRange */
1999a4706aSMaciej S. Szmigiero #define OUR_RANGE(ptr) ((OurRange *)(ptr))
2099a4706aSMaciej S. Szmigiero 
2199a4706aSMaciej S. Szmigiero /* "our range" means the memory range owned by this driver (for hot-adding) */
2299a4706aSMaciej S. Szmigiero typedef struct OurRange {
2399a4706aSMaciej S. Szmigiero     PageRange range;
2499a4706aSMaciej S. Szmigiero 
2599a4706aSMaciej S. Szmigiero     /* How many pages were hot-added to the guest */
2699a4706aSMaciej S. Szmigiero     uint64_t added;
2799a4706aSMaciej S. Szmigiero 
2899a4706aSMaciej S. Szmigiero     /* Pages at the end not currently usable */
2999a4706aSMaciej S. Szmigiero     uint64_t unusable_tail;
3099a4706aSMaciej S. Szmigiero 
3199a4706aSMaciej S. Szmigiero     /* Memory removed from the guest */
3299a4706aSMaciej S. Szmigiero     PageRangeTree removed_guest, removed_both;
3399a4706aSMaciej S. Szmigiero } OurRange;
3499a4706aSMaciej S. Szmigiero 
our_range_get_remaining_start(OurRange * our_range)3599a4706aSMaciej S. Szmigiero static inline uint64_t our_range_get_remaining_start(OurRange *our_range)
3699a4706aSMaciej S. Szmigiero {
3799a4706aSMaciej S. Szmigiero     return our_range->range.start + our_range->added;
3899a4706aSMaciej S. Szmigiero }
3999a4706aSMaciej S. Szmigiero 
our_range_get_remaining_size(OurRange * our_range)4099a4706aSMaciej S. Szmigiero static inline uint64_t our_range_get_remaining_size(OurRange *our_range)
4199a4706aSMaciej S. Szmigiero {
4299a4706aSMaciej S. Szmigiero     return our_range->range.count - our_range->added - our_range->unusable_tail;
4399a4706aSMaciej S. Szmigiero }
4499a4706aSMaciej S. Szmigiero 
4599a4706aSMaciej S. Szmigiero void hvb_our_range_mark_added(OurRange *our_range, uint64_t additional_size);
4699a4706aSMaciej S. Szmigiero 
our_range_mark_remaining_unusable(OurRange * our_range)4799a4706aSMaciej S. Szmigiero static inline void our_range_mark_remaining_unusable(OurRange *our_range)
4899a4706aSMaciej S. Szmigiero {
4999a4706aSMaciej S. Szmigiero     our_range->unusable_tail = our_range->range.count - our_range->added;
5099a4706aSMaciej S. Szmigiero }
5199a4706aSMaciej S. Szmigiero 
our_range_get_removed_tree(OurRange * our_range,bool both)5299a4706aSMaciej S. Szmigiero static inline PageRangeTree our_range_get_removed_tree(OurRange *our_range,
5399a4706aSMaciej S. Szmigiero                                                        bool both)
5499a4706aSMaciej S. Szmigiero {
5599a4706aSMaciej S. Szmigiero     if (both) {
5699a4706aSMaciej S. Szmigiero         return our_range->removed_both;
5799a4706aSMaciej S. Szmigiero     } else {
5899a4706aSMaciej S. Szmigiero         return our_range->removed_guest;
5999a4706aSMaciej S. Szmigiero     }
6099a4706aSMaciej S. Szmigiero }
6199a4706aSMaciej S. Szmigiero 
our_range_is_removed_tree_empty(OurRange * our_range,bool both)6299a4706aSMaciej S. Szmigiero static inline bool our_range_is_removed_tree_empty(OurRange *our_range,
6399a4706aSMaciej S. Szmigiero                                                    bool both)
6499a4706aSMaciej S. Szmigiero {
6599a4706aSMaciej S. Szmigiero     if (both) {
6699a4706aSMaciej S. Szmigiero         return page_range_tree_is_empty(our_range->removed_both);
6799a4706aSMaciej S. Szmigiero     } else {
6899a4706aSMaciej S. Szmigiero         return page_range_tree_is_empty(our_range->removed_guest);
6999a4706aSMaciej S. Szmigiero     }
7099a4706aSMaciej S. Szmigiero }
7199a4706aSMaciej S. Szmigiero 
7299a4706aSMaciej S. Szmigiero void hvb_our_range_clear_removed_trees(OurRange *our_range);
7399a4706aSMaciej S. Szmigiero 
7499a4706aSMaciej S. Szmigiero /* OurRangeMemslots */
7599a4706aSMaciej S. Szmigiero typedef struct OurRangeMemslotsSlots {
7699a4706aSMaciej S. Szmigiero     /* Nominal size of each memslot (the last one might be smaller) */
7799a4706aSMaciej S. Szmigiero     uint64_t size_each;
7899a4706aSMaciej S. Szmigiero 
7999a4706aSMaciej S. Szmigiero     /* Slots array and its element count */
8099a4706aSMaciej S. Szmigiero     MemoryRegion *slots;
8199a4706aSMaciej S. Szmigiero     unsigned int count;
8299a4706aSMaciej S. Szmigiero 
8399a4706aSMaciej S. Szmigiero     /* How many slots are currently mapped */
8499a4706aSMaciej S. Szmigiero     unsigned int mapped_count;
8599a4706aSMaciej S. Szmigiero } OurRangeMemslotsSlots;
8699a4706aSMaciej S. Szmigiero 
8799a4706aSMaciej S. Szmigiero typedef struct OurRangeMemslots {
8899a4706aSMaciej S. Szmigiero     OurRange range;
8999a4706aSMaciej S. Szmigiero 
9099a4706aSMaciej S. Szmigiero     /* Memslots covering our range */
9199a4706aSMaciej S. Szmigiero     OurRangeMemslotsSlots slots;
9299a4706aSMaciej S. Szmigiero 
9399a4706aSMaciej S. Szmigiero     MemoryRegion *mr;
9499a4706aSMaciej S. Szmigiero } OurRangeMemslots;
9599a4706aSMaciej S. Szmigiero 
9699a4706aSMaciej S. Szmigiero OurRangeMemslots *hvb_our_range_memslots_new(uint64_t addr,
9799a4706aSMaciej S. Szmigiero                                              MemoryRegion *parent_mr,
9899a4706aSMaciej S. Szmigiero                                              MemoryRegion *backing_mr,
9999a4706aSMaciej S. Szmigiero                                              Object *memslot_owner,
10099a4706aSMaciej S. Szmigiero                                              unsigned int memslot_count,
10199a4706aSMaciej S. Szmigiero                                              uint64_t memslot_size);
10299a4706aSMaciej S. Szmigiero void hvb_our_range_memslots_free(OurRangeMemslots *our_range);
10399a4706aSMaciej S. Szmigiero 
10499a4706aSMaciej S. Szmigiero G_DEFINE_AUTOPTR_CLEANUP_FUNC(OurRangeMemslots, hvb_our_range_memslots_free)
10599a4706aSMaciej S. Szmigiero 
10699a4706aSMaciej S. Szmigiero void hvb_our_range_memslots_ensure_mapped_additional(OurRangeMemslots *our_range,
10799a4706aSMaciej S. Szmigiero                                                      uint64_t additional_map_size);
10899a4706aSMaciej S. Szmigiero 
10999a4706aSMaciej S. Szmigiero #endif
110