diff mbox series

KVM: Start populating /sys/hypervisor with KVM entries

Message ID 1539078879-4372-1-git-send-email-sironi@amazon.de (mailing list archive)
State New, archived
Headers show
Series KVM: Start populating /sys/hypervisor with KVM entries | expand

Commit Message

Sironi, Filippo Oct. 9, 2018, 9:54 a.m. UTC
Start populating /sys/hypervisor with KVM entries when we're running on
KVM. This is to replicate functionality that's available when we're
running on Xen.

Let's start with /sys/hypervisor/uuid, which users prefer over
/sys/devices/virtual/dmi/id/product_uuid as a way to recognize a virtual
machine, since it's also available when running on Xen HVM and on Xen PV
and, on top of that doesn't require root privileges by default.

Signed-off-by: Filippo Sironi <sironi@amazon.de>
---
 drivers/Kconfig              |  2 ++
 drivers/Makefile             |  2 ++
 drivers/kvm/Kconfig          | 14 ++++++++++++++
 drivers/kvm/Makefile         |  1 +
 drivers/kvm/sys-hypervisor.c | 26 ++++++++++++++++++++++++++
 5 files changed, 45 insertions(+)
 create mode 100644 drivers/kvm/Kconfig
 create mode 100644 drivers/kvm/Makefile
 create mode 100644 drivers/kvm/sys-hypervisor.c

Comments

Christian Borntraeger Oct. 9, 2018, 10:41 a.m. UTC | #1
On 10/09/2018 11:54 AM, Filippo Sironi wrote:
> Start populating /sys/hypervisor with KVM entries when we're running on
> KVM. This is to replicate functionality that's available when we're
> running on Xen.
> 
> Let's start with /sys/hypervisor/uuid, which users prefer over
> /sys/devices/virtual/dmi/id/product_uuid as a way to recognize a virtual
> machine, since it's also available when running on Xen HVM and on Xen PV
> and, on top of that doesn't require root privileges by default.

Can you make this an arch hook? On s390 it is possible to get the uuid with
the stsi instruction. 
See
https://git.kernel.org/pub/scm/virt/kvm/kvm.git/tree/arch/s390/kernel/sysinfo.c#n248


We do use uuid_t, but we can certainly return a char*.




> 
> Signed-off-by: Filippo Sironi <sironi@amazon.de>
> ---
>  drivers/Kconfig              |  2 ++
>  drivers/Makefile             |  2 ++
>  drivers/kvm/Kconfig          | 14 ++++++++++++++
>  drivers/kvm/Makefile         |  1 +
>  drivers/kvm/sys-hypervisor.c | 26 ++++++++++++++++++++++++++
>  5 files changed, 45 insertions(+)
>  create mode 100644 drivers/kvm/Kconfig
>  create mode 100644 drivers/kvm/Makefile
>  create mode 100644 drivers/kvm/sys-hypervisor.c
> 
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index afc942c54814..597519c5f7c8 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -135,6 +135,8 @@ source "drivers/hv/Kconfig"
> 
>  source "drivers/xen/Kconfig"
> 
> +source "drivers/kvm/Kconfig"
> +
>  source "drivers/staging/Kconfig"
> 
>  source "drivers/platform/Kconfig"
> diff --git a/drivers/Makefile b/drivers/Makefile
> index 1056f9699192..727205e287fc 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -47,6 +47,8 @@ obj-y				+= soc/
>  obj-$(CONFIG_VIRTIO)		+= virtio/
>  obj-$(CONFIG_XEN)		+= xen/
> 
> +obj-$(CONFIG_KVM_GUEST)		+= kvm/
> +
>  # regulators early, since some subsystems rely on them to initialize
>  obj-$(CONFIG_REGULATOR)		+= regulator/
> 
> diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig
> new file mode 100644
> index 000000000000..3fc041df7c11
> --- /dev/null
> +++ b/drivers/kvm/Kconfig
> @@ -0,0 +1,14 @@
> +menu "KVM driver support"
> +        depends on KVM_GUEST
> +
> +config KVM_SYS_HYPERVISOR
> +        bool "Create KVM entries under /sys/hypervisor"
> +        depends on SYSFS
> +        select SYS_HYPERVISOR
> +        default y
> +        help
> +          Create KVM entries under /sys/hypervisor (e.g., uuid). When running
> +          native or on another hypervisor, /sys/hypervisor may still be
> +          present, but it will have no KVM entries.
> +
> +endmenu
> diff --git a/drivers/kvm/Makefile b/drivers/kvm/Makefile
> new file mode 100644
> index 000000000000..73a43fc994b9
> --- /dev/null
> +++ b/drivers/kvm/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_KVM_SYS_HYPERVISOR) += sys-hypervisor.o
> diff --git a/drivers/kvm/sys-hypervisor.c b/drivers/kvm/sys-hypervisor.c
> new file mode 100644
> index 000000000000..ef04ca65cf1a
> --- /dev/null
> +++ b/drivers/kvm/sys-hypervisor.c
> @@ -0,0 +1,26 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#include <asm/kvm_para.h>
> +
> +#include <linux/dmi.h>
> +#include <linux/kobject.h>
> +#include <linux/sysfs.h>
> +
> +static ssize_t uuid_show(struct kobject *obj,
> +			 struct kobj_attribute *attr,
> +			 char *buf)
> +{
> +	const char *uuid = dmi_get_system_info(DMI_PRODUCT_UUID);
> +	return sprintf(buf, "%s\n", uuid);
> +}
> +
> +static struct kobj_attribute uuid = __ATTR_RO(uuid);
> +
> +static int __init uuid_init(void)
> +{
> +	if (!kvm_para_available())
> +		return 0;
> +	return sysfs_create_file(hypervisor_kobj, &uuid.attr);
> +}
> +
> +device_initcall(uuid_init);
>
Konrad Rzeszutek Wilk Oct. 9, 2018, 3 p.m. UTC | #2
On Tue, Oct 09, 2018 at 11:54:39AM +0200, Filippo Sironi wrote:
> Start populating /sys/hypervisor with KVM entries when we're running on
> KVM. This is to replicate functionality that's available when we're
> running on Xen.
> 
> Let's start with /sys/hypervisor/uuid, which users prefer over
> /sys/devices/virtual/dmi/id/product_uuid as a way to recognize a virtual
> machine, since it's also available when running on Xen HVM and on Xen PV
> and, on top of that doesn't require root privileges by default.

Yeey! Thank you for doing this. It has been on my TODO but just never
got to it.

I think you also need to update the Documentation/../sysfs file.
> 
> Signed-off-by: Filippo Sironi <sironi@amazon.de>
> ---
>  drivers/Kconfig              |  2 ++
>  drivers/Makefile             |  2 ++
>  drivers/kvm/Kconfig          | 14 ++++++++++++++
>  drivers/kvm/Makefile         |  1 +
>  drivers/kvm/sys-hypervisor.c | 26 ++++++++++++++++++++++++++
>  5 files changed, 45 insertions(+)
>  create mode 100644 drivers/kvm/Kconfig
>  create mode 100644 drivers/kvm/Makefile
>  create mode 100644 drivers/kvm/sys-hypervisor.c
> 
> diff --git a/drivers/Kconfig b/drivers/Kconfig
> index afc942c54814..597519c5f7c8 100644
> --- a/drivers/Kconfig
> +++ b/drivers/Kconfig
> @@ -135,6 +135,8 @@ source "drivers/hv/Kconfig"
>  
>  source "drivers/xen/Kconfig"
>  
> +source "drivers/kvm/Kconfig"
> +
>  source "drivers/staging/Kconfig"
>  
>  source "drivers/platform/Kconfig"
> diff --git a/drivers/Makefile b/drivers/Makefile
> index 1056f9699192..727205e287fc 100644
> --- a/drivers/Makefile
> +++ b/drivers/Makefile
> @@ -47,6 +47,8 @@ obj-y				+= soc/
>  obj-$(CONFIG_VIRTIO)		+= virtio/
>  obj-$(CONFIG_XEN)		+= xen/
>  
> +obj-$(CONFIG_KVM_GUEST)		+= kvm/
> +
>  # regulators early, since some subsystems rely on them to initialize
>  obj-$(CONFIG_REGULATOR)		+= regulator/
>  
> diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig
> new file mode 100644
> index 000000000000..3fc041df7c11
> --- /dev/null
> +++ b/drivers/kvm/Kconfig
> @@ -0,0 +1,14 @@
> +menu "KVM driver support"
> +        depends on KVM_GUEST
> +
> +config KVM_SYS_HYPERVISOR
> +        bool "Create KVM entries under /sys/hypervisor"
> +        depends on SYSFS
> +        select SYS_HYPERVISOR
> +        default y
> +        help
> +          Create KVM entries under /sys/hypervisor (e.g., uuid). When running
> +          native or on another hypervisor, /sys/hypervisor may still be
> +          present, but it will have no KVM entries.
> +
> +endmenu
> diff --git a/drivers/kvm/Makefile b/drivers/kvm/Makefile
> new file mode 100644
> index 000000000000..73a43fc994b9
> --- /dev/null
> +++ b/drivers/kvm/Makefile
> @@ -0,0 +1 @@
> +obj-$(CONFIG_KVM_SYS_HYPERVISOR) += sys-hypervisor.o
> diff --git a/drivers/kvm/sys-hypervisor.c b/drivers/kvm/sys-hypervisor.c
> new file mode 100644
> index 000000000000..ef04ca65cf1a
> --- /dev/null
> +++ b/drivers/kvm/sys-hypervisor.c
> @@ -0,0 +1,26 @@
> +/* SPDX-License-Identifier: GPL-2.0 */
> +
> +#include <asm/kvm_para.h>
> +
> +#include <linux/dmi.h>
> +#include <linux/kobject.h>
> +#include <linux/sysfs.h>
> +
> +static ssize_t uuid_show(struct kobject *obj,
> +			 struct kobj_attribute *attr,
> +			 char *buf)
> +{
> +	const char *uuid = dmi_get_system_info(DMI_PRODUCT_UUID);
> +	return sprintf(buf, "%s\n", uuid);
> +}
> +
> +static struct kobj_attribute uuid = __ATTR_RO(uuid);
> +
> +static int __init uuid_init(void)
> +{
> +	if (!kvm_para_available())
> +		return 0;
> +	return sysfs_create_file(hypervisor_kobj, &uuid.attr);
> +}
> +
> +device_initcall(uuid_init);
> -- 
> 2.7.4
>
Boris Ostrovsky Oct. 9, 2018, 4:21 p.m. UTC | #3
On 10/9/18 6:41 AM, Christian Borntraeger wrote:
> 
> 
> On 10/09/2018 11:54 AM, Filippo Sironi wrote:
>> Start populating /sys/hypervisor with KVM entries when we're running on
>> KVM. This is to replicate functionality that's available when we're
>> running on Xen.
>>
>> Let's start with /sys/hypervisor/uuid, which users prefer over
>> /sys/devices/virtual/dmi/id/product_uuid as a way to recognize a virtual
>> machine, since it's also available when running on Xen HVM and on Xen PV
>> and, on top of that doesn't require root privileges by default.
> 
> Can you make this an arch hook? On s390 it is possible to get the uuid with
> the stsi instruction. 
> See
> https://git.kernel.org/pub/scm/virt/kvm/kvm.git/tree/arch/s390/kernel/sysinfo.c#n248
> 
> 
> We do use uuid_t, but we can certainly return a char*.


I would suggest having a top-level sys-hypervisor.c that will create
common files that all hypervisors should have (uuid, type, version, etc)
and then have hypervisor- and/or arch-specific hooks.


-boris
Cornelia Huck Oct. 9, 2018, 5:50 p.m. UTC | #4
On Tue, 9 Oct 2018 12:21:46 -0400
Boris Ostrovsky <boris.ostrovsky@oracle.com> wrote:

> On 10/9/18 6:41 AM, Christian Borntraeger wrote:
> > 
> > 
> > On 10/09/2018 11:54 AM, Filippo Sironi wrote:  
> >> Start populating /sys/hypervisor with KVM entries when we're running on
> >> KVM. This is to replicate functionality that's available when we're
> >> running on Xen.
> >>
> >> Let's start with /sys/hypervisor/uuid, which users prefer over
> >> /sys/devices/virtual/dmi/id/product_uuid as a way to recognize a virtual
> >> machine, since it's also available when running on Xen HVM and on Xen PV
> >> and, on top of that doesn't require root privileges by default.  
> > 
> > Can you make this an arch hook? On s390 it is possible to get the uuid with
> > the stsi instruction. 
> > See
> > https://git.kernel.org/pub/scm/virt/kvm/kvm.git/tree/arch/s390/kernel/sysinfo.c#n248
> > 
> > 
> > We do use uuid_t, but we can certainly return a char*.  
> 
> 
> I would suggest having a top-level sys-hypervisor.c that will create
> common files that all hypervisors should have (uuid, type, version, etc)
> and then have hypervisor- and/or arch-specific hooks.

I think we really need *both* hypervisor- and arch-specific hooks.
kernel test robot Oct. 10, 2018, 5:19 a.m. UTC | #5
Hi Filippo,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on linux-sof-driver/master]
[also build test ERROR on v4.19-rc7 next-20181009]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Filippo-Sironi/KVM-Start-populating-sys-hypervisor-with-KVM-entries/20181010-064236
base:   https://github.com/thesofproject/linux master
config: powerpc64-allmodconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 7.2.0-11) 7.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=7.2.0 make.cross ARCH=powerpc64 

All error/warnings (new ones prefixed by >>):

   In file included from arch/powerpc/include/uapi/asm/kvm_para.h:82:0,
                    from arch/powerpc/include/asm/kvm_para.h:22,
                    from drivers//kvm/sys-hypervisor.c:3:
>> arch/powerpc/include/asm/epapr_hcalls.h:109:12: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'epapr_paravirt_early_init'
    int __init epapr_paravirt_early_init(void);
               ^~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from arch/powerpc/include/asm/epapr_hcalls.h:53:0,
                    from arch/powerpc/include/uapi/asm/kvm_para.h:82,
                    from arch/powerpc/include/asm/kvm_para.h:22,
                    from drivers//kvm/sys-hypervisor.c:3:
   arch/powerpc/include/asm/kvm_para.h: In function 'kvm_arch_para_features':
>> arch/powerpc/include/asm/kvm_para.h:58:40: error: 'KVM_HC_FEATURES' undeclared (first use in this function); did you mean 'KVM_HCALL_TOKEN'?
     if(epapr_hypercall0_1(KVM_HCALL_TOKEN(KVM_HC_FEATURES), &r))
                                           ^
   arch/powerpc/include/uapi/asm/epapr_hcalls.h:75:51: note: in definition of macro '_EV_HCALL_TOKEN'
    #define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num))
                                                      ^~~
>> arch/powerpc/include/asm/kvm_para.h:58:24: note: in expansion of macro 'KVM_HCALL_TOKEN'
     if(epapr_hypercall0_1(KVM_HCALL_TOKEN(KVM_HC_FEATURES), &r))
                           ^~~~~~~~~~~~~~~
   arch/powerpc/include/asm/kvm_para.h:58:40: note: each undeclared identifier is reported only once for each function it appears in
     if(epapr_hypercall0_1(KVM_HCALL_TOKEN(KVM_HC_FEATURES), &r))
                                           ^
   arch/powerpc/include/uapi/asm/epapr_hcalls.h:75:51: note: in definition of macro '_EV_HCALL_TOKEN'
    #define _EV_HCALL_TOKEN(id, num) (((id) << 16) | (num))
                                                      ^~~
>> arch/powerpc/include/asm/kvm_para.h:58:24: note: in expansion of macro 'KVM_HCALL_TOKEN'
     if(epapr_hypercall0_1(KVM_HCALL_TOKEN(KVM_HC_FEATURES), &r))
                           ^~~~~~~~~~~~~~~

vim +58 arch/powerpc/include/asm/kvm_para.h

bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  21  
c3617f72 arch/powerpc/include/asm/kvm_para.h David Howells    2012-10-09 @22  #include <uapi/asm/kvm_para.h>
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  23  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  24  #ifdef CONFIG_KVM_GUEST
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  25  
26e673c3 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-09-03  26  #include <linux/of.h>
26e673c3 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-09-03  27  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  28  static inline int kvm_para_available(void)
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  29  {
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  30  	struct device_node *hyper_node;
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  31  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  32  	hyper_node = of_find_node_by_path("/hypervisor");
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  33  	if (!hyper_node)
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  34  		return 0;
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  35  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  36  	if (!of_device_is_compatible(hyper_node, "linux,kvm"))
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  37  		return 0;
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  38  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  39  	return 1;
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  40  }
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  41  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  42  #else
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  43  
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  44  static inline int kvm_para_available(void)
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  45  {
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  46  	return 0;
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  47  }
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  48  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  49  #endif
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  50  
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  51  static inline unsigned int kvm_arch_para_features(void)
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  52  {
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  53  	unsigned long r;
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  54  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  55  	if (!kvm_para_available())
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  56  		return 0;
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  57  
b1f0d94c arch/powerpc/include/asm/kvm_para.h Bharat Bhushan   2013-10-08 @58  	if(epapr_hypercall0_1(KVM_HCALL_TOKEN(KVM_HC_FEATURES), &r))
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  59  		return 0;
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  60  
2a342ed5 arch/powerpc/include/asm/kvm_para.h Alexander Graf   2010-07-29  61  	return r;
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  62  }
bbf45ba5 include/asm-powerpc/kvm_para.h      Hollis Blanchard 2008-04-16  63  

:::::: The code at line 58 was first introduced by commit
:::::: b1f0d94c26b64e814243b736f47e7ef40d96432c kvm/powerpc: move kvm_hypercall0() and friends to epapr_hypercall0()

:::::: TO: Bharat Bhushan <r65777@freescale.com>
:::::: CC: Alexander Graf <agraf@suse.de>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
Sironi, Filippo May 14, 2019, 3:16 p.m. UTC | #6
Long-time Xen HVM and Xen PV users are missing /sys/hypervisor entries when
moving to KVM.  One report is about getting the VM UUID.  The VM UUID can
already be retrieved using /sys/devices/virtual/dmi/id/product_uuid.  This has
two downsides: (1) it requires root privileges and (2) it is only available on
KVM and Xen HVM.

By exposing /sys/hypervisor/uuid when running on KVM as well, we provide an
interface that's functional for KVM, Xen HVM, and Xen PV.  Let's do so by
providing arch-specific hooks so that different architectures can implement the
hooks in different ways.

Further work can be done by consolidating the creation of the basic
/sys/hypervisor across hypervisors.

Filippo Sironi (2):
      KVM: Start populating /sys/hypervisor with KVM entries
      KVM: x86: Implement the arch-specific hook to report the VM UUID
diff mbox series

Patch

diff --git a/drivers/Kconfig b/drivers/Kconfig
index afc942c54814..597519c5f7c8 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -135,6 +135,8 @@  source "drivers/hv/Kconfig"
 
 source "drivers/xen/Kconfig"
 
+source "drivers/kvm/Kconfig"
+
 source "drivers/staging/Kconfig"
 
 source "drivers/platform/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 1056f9699192..727205e287fc 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -47,6 +47,8 @@  obj-y				+= soc/
 obj-$(CONFIG_VIRTIO)		+= virtio/
 obj-$(CONFIG_XEN)		+= xen/
 
+obj-$(CONFIG_KVM_GUEST)		+= kvm/
+
 # regulators early, since some subsystems rely on them to initialize
 obj-$(CONFIG_REGULATOR)		+= regulator/
 
diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig
new file mode 100644
index 000000000000..3fc041df7c11
--- /dev/null
+++ b/drivers/kvm/Kconfig
@@ -0,0 +1,14 @@ 
+menu "KVM driver support"
+        depends on KVM_GUEST
+
+config KVM_SYS_HYPERVISOR
+        bool "Create KVM entries under /sys/hypervisor"
+        depends on SYSFS
+        select SYS_HYPERVISOR
+        default y
+        help
+          Create KVM entries under /sys/hypervisor (e.g., uuid). When running
+          native or on another hypervisor, /sys/hypervisor may still be
+          present, but it will have no KVM entries.
+
+endmenu
diff --git a/drivers/kvm/Makefile b/drivers/kvm/Makefile
new file mode 100644
index 000000000000..73a43fc994b9
--- /dev/null
+++ b/drivers/kvm/Makefile
@@ -0,0 +1 @@ 
+obj-$(CONFIG_KVM_SYS_HYPERVISOR) += sys-hypervisor.o
diff --git a/drivers/kvm/sys-hypervisor.c b/drivers/kvm/sys-hypervisor.c
new file mode 100644
index 000000000000..ef04ca65cf1a
--- /dev/null
+++ b/drivers/kvm/sys-hypervisor.c
@@ -0,0 +1,26 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#include <asm/kvm_para.h>
+
+#include <linux/dmi.h>
+#include <linux/kobject.h>
+#include <linux/sysfs.h>
+
+static ssize_t uuid_show(struct kobject *obj,
+			 struct kobj_attribute *attr,
+			 char *buf)
+{
+	const char *uuid = dmi_get_system_info(DMI_PRODUCT_UUID);
+	return sprintf(buf, "%s\n", uuid);
+}
+
+static struct kobj_attribute uuid = __ATTR_RO(uuid);
+
+static int __init uuid_init(void)
+{
+	if (!kvm_para_available())
+		return 0;
+	return sysfs_create_file(hypervisor_kobj, &uuid.attr);
+}
+
+device_initcall(uuid_init);