memflow / memflow-kvm

Linux kernel module for memflow's KVM connector
MIT License
36 stars 8 forks source link

更新到 linux kernel 5.17.0.r7 #7

Closed cpkt9762 closed 2 years ago

cpkt9762 commented 2 years ago
static int get_sorted_memslots(struct kvm_memslots *slots, int max_slots, vm_memslot_t *slots_out)
{
    struct kvm_memory_slot *slot;
    int slot_count, i, bkt=0;
    slot_count = 0;  
    kvm_for_each_memslot(slot, bkt, slots) { 
        slots_out[slot_count++] = (vm_memslot_t) {
                .base = gfn_to_gpa(slot->base_gfn),
                .host_base = slot->userspace_addr,
                .map_size = gfn_to_gpa(slot->npages)
            }; 
      }; 
    sort(slots_out, slot_count, sizeof(*slots_out), memslot_compare, NULL);

    //TODO: coalesce nearby slots

    return slot_count;
}
static int get_vm_info(struct kvm *kvm, vm_info_t __user *user_info)
{
/**/
    if (kernel_info.slot_count > HASH_SIZE(kvm_memslots(kvm)->id_hash))
        kernel_info.slot_count = HASH_SIZE(kvm_memslots(kvm)->id_hash);

/**/
} 
h33p commented 2 years ago

Being fluent in many different languages, I think I can understand what you want to say.

Ideally, get_vm_info would need to use kvm_for_each_memslot to count the number of slots, it would also need to be gated to take that path on 5.17 upwards.

get_sorted_memslots change seems way better than what I had, however, you need to check against max_slots to not overflow the buffer. Another check was removed, for npages being not 0. I'm not sure exactly if it is needed, but I believe I had it in for a reason. So that should re-appear in the loop.

I am rather busy at the moment, but I would be glad to accept a PR with the changes.

cpkt9762 commented 2 years ago

The reason I use this kvm_for_each_memslot is because "struct kvm_memslots" has changed in linux kernel 5.17.0, it looks like this

kvm_host.h:660
struct kvm_memslots {
    u64 generation;
    atomic_long_t last_used_slot;
    struct rb_root_cached hva_tree;
    struct rb_root gfn_tree;
    /*
     * The mapping table from slot id to memslot.
     *
     * 7-bit bucket count matches the size of the old id to index array for
     * 512 slots, while giving good performance with this slot count.
     * Higher bucket counts bring only small performance improvements but
     * always result in higher memory usage (even for lower memslot counts).
     */
    DECLARE_HASHTABLE(id_hash, 7);
    int node_idx;
};

This was before 5.17.0

struct kvm_memslots {
    u64 generation;
    /* The mapping table from slot id to the index in memslots[]. */
    short id_to_index[KVM_MEM_SLOTS_NUM];
    atomic_t last_used_slot;
    int used_slots;
    struct kvm_memory_slot memslots[];
};
kvm_for_each_memslot in the new kernel 5.17.0 "kvm_host.h:947 line" is declared as

#define kvm_for_each_memslot(memslot, slots)                \
    for (memslot = &slots->memslots[0];             \
         memslot < slots->memslots + slots->used_slots; memslot++)  \
        if (WARN_ON_ONCE(!memslot->npages)) {           \
        } else

max_slots I forgot to check, thank you for the tip, I will add it later

weewoo22 commented 2 years ago

Just chiming in, here's the errors for 5.17.1:

got build log for '/nix/store/bj00iyly2kamhprf2b12vabhq033kb9m-memflow-kmod-0.2.0-beta5+98439ba-5.17.drv' from 'daemon'
@nix { "action": "setPhase", "phase": "unpackPhase" }
unpacking sources
unpacking source archive /nix/store/hrdgzppjamjrax295zflyazgbkbma6i9-source
source root is source
@nix { "action": "setPhase", "phase": "patchPhase" }
patching sources
@nix { "action": "setPhase", "phase": "configurePhase" }
configuring
no configure script, doing nothing
@nix { "action": "setPhase", "phase": "buildPhase" }
building
build flags: SHELL=/nix/store/dndi916j6yxzfzzj2sma2llhrlwahq06-bash-5.1-p16/bin/bash
mkdir -p "/build/source/build"
touch "/build/source/build/Makefile"
/build/source/build
make -C /nix/store/7346yp8lcq0k1ms6akqx6jvkv9rgm90i-linux-5.17-dev/lib/modules/5.17.0/build M=/build/source/build src=/build/source/memflow-kmod modules
make[1]: Entering directory '/nix/store/7346yp8lcq0k1ms6akqx6jvkv9rgm90i-linux-5.17-dev/lib/modules/5.17.0/build'
  CC [M]  /build/source/build/main.o
  CC [M]  /build/source/build/vmtools.o
/build/source/memflow-kmod/vmtools.c: In function 'get_sorted_memslots':
/build/source/memflow-kmod/vmtools.c:109:83: error: 'struct kvm_memslots' has no member named 'used_slots'
  109 |  for (i = 0; i < KVM_MEM_SLOTS_NUM && slot_count < max_slots && slot_count < slots->used_slots; i++) {
      |                                                                                   ^~
/build/source/memflow-kmod/vmtools.c:110:15: error: 'struct kvm_memslots' has no member named 'memslots'
  110 |   slot = slots->memslots + i;
      |               ^~
/build/source/memflow-kmod/vmtools.c:112:27: error: 'struct kvm_memslots' has no member named 'used_slots'
  112 |    if (slot_count >= slots->used_slots) {
      |                           ^~
/build/source/memflow-kmod/vmtools.c: In function 'get_vm_info':
/build/source/memflow-kmod/vmtools.c:154:48: error: 'struct kvm_memslots' has no member named 'used_slots'
  154 |  if (kernel_info.slot_count > kvm_memslots(kvm)->used_slots)
      |                                                ^~
/build/source/memflow-kmod/vmtools.c:155:45: error: 'struct kvm_memslots' has no member named 'used_slots'
  155 |   kernel_info.slot_count = kvm_memslots(kvm)->used_slots;
      |                                             ^~
make[2]: *** [/nix/store/7346yp8lcq0k1ms6akqx6jvkv9rgm90i-linux-5.17-dev/lib/modules/5.17.0/source/scripts/Makefile.build:288: /build/source/build/vmtools.o] Error 1
make[1]: *** [/nix/store/7346yp8lcq0k1ms6akqx6jvkv9rgm90i-linux-5.17-dev/lib/modules/5.17.0/source/Makefile:1831: /build/source/build] Error 2
make[1]: Leaving directory '/nix/store/7346yp8lcq0k1ms6akqx6jvkv9rgm90i-linux-5.17-dev/lib/modules/5.17.0/build'
make: *** [Makefile:23: all] Error 2
weewoo22 commented 2 years ago

This is resolved by 61c8bdb097ce629bfdafdb0b2f6173a521756712. Tested on 5.17.1:

$ uname -r
5.17.1
$ lsmod | rg memflow
memflow                20480  0
kvm                  1048576  2 memflow,kvm_intel