1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /****************************************************************************** 3 * arch/x86/guest/hyperv/util.c 4 * 5 * Hyper-V utility functions 6 * 7 * Copyright (c) 2020 Microsoft. 8 */ 9 10 #include <xen/cpu.h> 11 #include <xen/cpumask.h> 12 #include <xen/errno.h> 13 14 #include <asm/guest/hyperv.h> 15 #include <asm/guest/hyperv-tlfs.h> 16 17 #include "private.h" 18 cpumask_to_vpset(struct hv_vpset * vpset,const cpumask_t * mask)19int cpumask_to_vpset(struct hv_vpset *vpset, 20 const cpumask_t *mask) 21 { 22 int nr = 1; 23 unsigned int cpu, vcpu_bank, vcpu_offset; 24 unsigned int max_banks = hv_max_vp_index / 64; 25 26 /* Up to 64 banks can be represented by valid_bank_mask */ 27 if ( max_banks > 64 ) 28 return -E2BIG; 29 30 /* Clear all banks to avoid flushing unwanted CPUs */ 31 for ( vcpu_bank = 0; vcpu_bank < max_banks; vcpu_bank++ ) 32 vpset->bank_contents[vcpu_bank] = 0; 33 34 vpset->format = HV_GENERIC_SET_SPARSE_4K; 35 36 for_each_cpu ( cpu, mask ) 37 { 38 unsigned int vcpu = hv_vp_index(cpu); 39 40 vcpu_bank = vcpu / 64; 41 vcpu_offset = vcpu % 64; 42 43 __set_bit(vcpu_offset, &vpset->bank_contents[vcpu_bank]); 44 45 if ( vcpu_bank >= nr ) 46 nr = vcpu_bank + 1; 47 } 48 49 /* Some banks may be empty but that's ok */ 50 vpset->valid_bank_mask = ~0ULL >> (64 - nr); 51 52 return nr; 53 } 54 55 /* 56 * Local variables: 57 * mode: C 58 * c-file-style: "BSD" 59 * c-basic-offset: 4 60 * tab-width: 4 61 * indent-tabs-mode: nil 62 * End: 63 */ 64