Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mshv: Extend create partition ioctl to support cpu features

The existing mshv create partition ioctl does not provide a way to
specify which cpu features are enabled in the guest. Instead, it
attempts to enable all features and those that are not supported are
silently disabled by the hypervisor.

This was done to reduce unnecessary complexity and is sufficient for
many cases. However, new scenarios require fine-grained control over
these features.

Define a new mshv_create_partition_v2 structure which supports
passing the disabled processor and xsave feature bits through to the
create partition hypercall directly.

Introduce a new flag MSHV_PT_BIT_CPU_AND_XSAVE_FEATURES which enables
the new structure. If unset, the original mshv_create_partition struct
is used, with the old behavior of enabling all features.

Co-developed-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Jinank Jain <jinankjain@microsoft.com>
Signed-off-by: Muminul Islam <muislam@microsoft.com>
Signed-off-by: Nuno Das Neves <nunodasneves@linux.microsoft.com>
Reviewed-by: Michael Kelley <mhklinux@outlook.com>
Signed-off-by: Wei Liu <wei.liu@kernel.org>

authored by

Muminul Islam and committed by
Wei Liu
c91fe5f1 f91bc8f6

+133 -23
+99 -23
drivers/hv/mshv_root_main.c
··· 1855 1855 return 0; 1856 1856 } 1857 1857 1858 - static long 1859 - mshv_ioctl_create_partition(void __user *user_arg, struct device *module_dev) 1860 - { 1861 - struct mshv_create_partition args; 1862 - u64 creation_flags; 1863 - struct hv_partition_creation_properties creation_properties = {}; 1864 - union hv_partition_isolation_properties isolation_properties = {}; 1865 - struct mshv_partition *partition; 1866 - struct file *file; 1867 - int fd; 1868 - long ret; 1858 + static_assert(MSHV_NUM_CPU_FEATURES_BANKS == 1859 + HV_PARTITION_PROCESSOR_FEATURES_BANKS); 1869 1860 1870 - if (copy_from_user(&args, user_arg, sizeof(args))) 1861 + static long mshv_ioctl_process_pt_flags(void __user *user_arg, u64 *pt_flags, 1862 + struct hv_partition_creation_properties *cr_props, 1863 + union hv_partition_isolation_properties *isol_props) 1864 + { 1865 + int i; 1866 + struct mshv_create_partition_v2 args; 1867 + union hv_partition_processor_features *disabled_procs; 1868 + union hv_partition_processor_xsave_features *disabled_xsave; 1869 + 1870 + /* First, copy v1 struct in case user is on previous versions */ 1871 + if (copy_from_user(&args, user_arg, 1872 + sizeof(struct mshv_create_partition))) 1871 1873 return -EFAULT; 1872 1874 1873 1875 if ((args.pt_flags & ~MSHV_PT_FLAGS_MASK) || 1874 1876 args.pt_isolation >= MSHV_PT_ISOLATION_COUNT) 1875 1877 return -EINVAL; 1876 1878 1877 - /* Only support EXO partitions */ 1878 - creation_flags = HV_PARTITION_CREATION_FLAG_EXO_PARTITION | 1879 - HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED; 1879 + disabled_procs = &cr_props->disabled_processor_features; 1880 + disabled_xsave = &cr_props->disabled_processor_xsave_features; 1880 1881 1881 - if (args.pt_flags & BIT(MSHV_PT_BIT_LAPIC)) 1882 - creation_flags |= HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED; 1883 - if (args.pt_flags & BIT(MSHV_PT_BIT_X2APIC)) 1884 - creation_flags |= HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE; 1885 - if (args.pt_flags & BIT(MSHV_PT_BIT_GPA_SUPER_PAGES)) 1886 - creation_flags |= HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED; 1882 + /* Check if user provided newer struct with feature fields */ 1883 + if (args.pt_flags & BIT_ULL(MSHV_PT_BIT_CPU_AND_XSAVE_FEATURES)) { 1884 + if (copy_from_user(&args, user_arg, sizeof(args))) 1885 + return -EFAULT; 1886 + 1887 + /* Re-validate v1 fields after second copy_from_user() */ 1888 + if ((args.pt_flags & ~MSHV_PT_FLAGS_MASK) || 1889 + args.pt_isolation >= MSHV_PT_ISOLATION_COUNT) 1890 + return -EINVAL; 1891 + 1892 + if (args.pt_num_cpu_fbanks != MSHV_NUM_CPU_FEATURES_BANKS || 1893 + mshv_field_nonzero(args, pt_rsvd) || 1894 + mshv_field_nonzero(args, pt_rsvd1)) 1895 + return -EINVAL; 1896 + 1897 + /* 1898 + * Note this assumes MSHV_NUM_CPU_FEATURES_BANKS will never 1899 + * change and equals HV_PARTITION_PROCESSOR_FEATURES_BANKS 1900 + * (i.e. 2). 1901 + * 1902 + * Further banks (index >= 2) will be modifiable as 'early' 1903 + * properties via the set partition property hypercall. 1904 + */ 1905 + for (i = 0; i < HV_PARTITION_PROCESSOR_FEATURES_BANKS; i++) 1906 + disabled_procs->as_uint64[i] = args.pt_cpu_fbanks[i]; 1907 + 1908 + #if IS_ENABLED(CONFIG_X86_64) 1909 + disabled_xsave->as_uint64 = args.pt_disabled_xsave; 1910 + #else 1911 + /* 1912 + * In practice this field is ignored on arm64, but safer to 1913 + * zero it in case it is ever used. 1914 + */ 1915 + disabled_xsave->as_uint64 = 0; 1916 + 1917 + if (mshv_field_nonzero(args, pt_rsvd2)) 1918 + return -EINVAL; 1919 + #endif 1920 + } else { 1921 + /* 1922 + * v1 behavior: try to enable everything. The hypervisor will 1923 + * disable features that are not supported. The banks can be 1924 + * queried via the get partition property hypercall. 1925 + */ 1926 + for (i = 0; i < HV_PARTITION_PROCESSOR_FEATURES_BANKS; i++) 1927 + disabled_procs->as_uint64[i] = 0; 1928 + 1929 + disabled_xsave->as_uint64 = 0; 1930 + } 1931 + 1932 + /* Only support EXO partitions */ 1933 + *pt_flags = HV_PARTITION_CREATION_FLAG_EXO_PARTITION | 1934 + HV_PARTITION_CREATION_FLAG_INTERCEPT_MESSAGE_PAGE_ENABLED; 1935 + 1936 + if (args.pt_flags & BIT_ULL(MSHV_PT_BIT_LAPIC)) 1937 + *pt_flags |= HV_PARTITION_CREATION_FLAG_LAPIC_ENABLED; 1938 + if (args.pt_flags & BIT_ULL(MSHV_PT_BIT_X2APIC)) 1939 + *pt_flags |= HV_PARTITION_CREATION_FLAG_X2APIC_CAPABLE; 1940 + if (args.pt_flags & BIT_ULL(MSHV_PT_BIT_GPA_SUPER_PAGES)) 1941 + *pt_flags |= HV_PARTITION_CREATION_FLAG_GPA_SUPER_PAGES_ENABLED; 1942 + 1943 + isol_props->as_uint64 = 0; 1887 1944 1888 1945 switch (args.pt_isolation) { 1889 1946 case MSHV_PT_ISOLATION_NONE: 1890 - isolation_properties.isolation_type = 1891 - HV_PARTITION_ISOLATION_TYPE_NONE; 1947 + isol_props->isolation_type = HV_PARTITION_ISOLATION_TYPE_NONE; 1892 1948 break; 1893 1949 } 1950 + 1951 + return 0; 1952 + } 1953 + 1954 + static long 1955 + mshv_ioctl_create_partition(void __user *user_arg, struct device *module_dev) 1956 + { 1957 + u64 creation_flags; 1958 + struct hv_partition_creation_properties creation_properties; 1959 + union hv_partition_isolation_properties isolation_properties; 1960 + struct mshv_partition *partition; 1961 + struct file *file; 1962 + int fd; 1963 + long ret; 1964 + 1965 + ret = mshv_ioctl_process_pt_flags(user_arg, &creation_flags, 1966 + &creation_properties, 1967 + &isolation_properties); 1968 + if (ret) 1969 + return ret; 1894 1970 1895 1971 partition = kzalloc(sizeof(*partition), GFP_KERNEL); 1896 1972 if (!partition)
+34
include/uapi/linux/mshv.h
··· 26 26 MSHV_PT_BIT_LAPIC, 27 27 MSHV_PT_BIT_X2APIC, 28 28 MSHV_PT_BIT_GPA_SUPER_PAGES, 29 + MSHV_PT_BIT_CPU_AND_XSAVE_FEATURES, 29 30 MSHV_PT_BIT_COUNT, 30 31 }; 31 32 ··· 42 41 * @pt_flags: Bitmask of 1 << MSHV_PT_BIT_* 43 42 * @pt_isolation: MSHV_PT_ISOLATION_* 44 43 * 44 + * This is the initial/v1 version for backward compatibility. 45 + * 45 46 * Returns a file descriptor to act as a handle to a guest partition. 46 47 * At this point the partition is not yet initialized in the hypervisor. 47 48 * Some operations must be done with the partition in this state, e.g. setting ··· 54 51 __u64 pt_flags; 55 52 __u64 pt_isolation; 56 53 }; 54 + 55 + #define MSHV_NUM_CPU_FEATURES_BANKS 2 56 + 57 + /** 58 + * struct mshv_create_partition_v2 59 + * 60 + * This is extended version of the above initial MSHV_CREATE_PARTITION 61 + * ioctl and allows for following additional parameters: 62 + * 63 + * @pt_num_cpu_fbanks: Must be set to MSHV_NUM_CPU_FEATURES_BANKS. 64 + * @pt_cpu_fbanks: Disabled processor feature banks array. 65 + * @pt_disabled_xsave: Disabled xsave feature bits. 66 + * 67 + * pt_cpu_fbanks and pt_disabled_xsave are passed through as-is to the create 68 + * partition hypercall. 69 + * 70 + * Returns : same as above original mshv_create_partition 71 + */ 72 + struct mshv_create_partition_v2 { 73 + __u64 pt_flags; 74 + __u64 pt_isolation; 75 + __u16 pt_num_cpu_fbanks; 76 + __u8 pt_rsvd[6]; /* MBZ */ 77 + __u64 pt_cpu_fbanks[MSHV_NUM_CPU_FEATURES_BANKS]; 78 + __u64 pt_rsvd1[2]; /* MBZ */ 79 + #if defined(__x86_64__) 80 + __u64 pt_disabled_xsave; 81 + #else 82 + __u64 pt_rsvd2; /* MBZ */ 83 + #endif 84 + } __packed; 57 85 58 86 /* /dev/mshv */ 59 87 #define MSHV_CREATE_PARTITION _IOW(MSHV_IOCTL, 0x00, struct mshv_create_partition)