[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <CAHmME9pJ3wb=EbUErJrCRC=VYGhFZqj2ar_AkVPsUvAnqGtwwg@mail.gmail.com>
Date: Fri, 25 Feb 2022 13:00:52 +0100
From: "Jason A. Donenfeld" <Jason@...c4.com>
To: Ard Biesheuvel <ardb@...nel.org>
Cc: linux-hyperv@...r.kernel.org, KVM list <kvm@...r.kernel.org>,
Linux Crypto Mailing List <linux-crypto@...r.kernel.org>,
QEMU Developers <qemu-devel@...gnu.org>,
Linux Kernel Mailing List <linux-kernel@...r.kernel.org>,
adrian@...ity.io, "Woodhouse, David" <dwmw@...zon.co.uk>,
Alexander Graf <graf@...zon.com>,
Colm MacCarthaigh <colmmacc@...zon.com>,
"Weiss, Radu" <raduweis@...zon.com>,
Daniel P. Berrangé <berrange@...hat.com>,
Laszlo Ersek <lersek@...hat.com>,
Igor Mammedov <imammedo@...hat.com>,
Eduardo Habkost <ehabkost@...hat.com>, ben@...portsystems.com,
"Michael S. Tsirkin" <mst@...hat.com>,
KY Srinivasan <kys@...rosoft.com>,
Haiyang Zhang <haiyangz@...rosoft.com>,
Stephen Hemminger <sthemmin@...rosoft.com>,
Wei Liu <wei.liu@...nel.org>, Dexuan Cui <decui@...rosoft.com>,
Dominik Brodowski <linux@...inikbrodowski.net>,
Eric Biggers <ebiggers@...nel.org>,
Jann Horn <jannh@...gle.com>,
Greg Kroah-Hartman <gregkh@...uxfoundation.org>,
"Theodore Y. Ts'o" <tytso@....edu>
Subject: Re: [PATCH v3 2/2] virt: vmgenid: introduce driver for reinitializing
RNG on VM fork
On Fri, Feb 25, 2022 at 12:24 PM Ard Biesheuvel <ardb@...nel.org> wrote:
>
> > @@ -13,6 +13,15 @@ menuconfig VIRT_DRIVERS
> >
> > if VIRT_DRIVERS
> >
> > +config VMGENID
> > + tristate "Virtual Machine Generation ID driver"
> > + default y
>
> Please make this default m - this code can run as a module and the
> feature it relies on is discoverable by udev
Will do.
> > index 000000000000..5da4dc8f25e3
> > --- /dev/null
> > +++ b/drivers/virt/vmgenid.c
> > @@ -0,0 +1,121 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Virtual Machine Generation ID driver
> > + *
> > + * Copyright (C) 2022 Jason A. Donenfeld <Jason@...c4.com>. All Rights Reserved.
> > + * Copyright (C) 2020 Amazon. All rights reserved.
> > + * Copyright (C) 2018 Red Hat Inc. All rights reserved.
> > + */
> > +
> > +#include <linux/kernel.h>
> > +#include <linux/module.h>
> > +#include <linux/acpi.h>
> > +#include <linux/random.h>
> > +
> > +ACPI_MODULE_NAME("vmgenid");
> > +
> > +enum { VMGENID_SIZE = 16 };
> > +
> > +static struct {
> > + u8 this_id[VMGENID_SIZE];
> > + u8 *next_id;
> > +} state;
> > +
>
> This state is singular
>
>
> > +static int vmgenid_acpi_add(struct acpi_device *device)
> > +{
>
> ... whereas this may be called for multiple instances of the device.
> This likely makes no sense, so it is better to reject it here.
Like, return early if it's called a second time? I can do that.
>
> > + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
> > + union acpi_object *pss;
> > + phys_addr_t phys_addr;
> > + acpi_status status;
> > + int ret = 0;
> > +
> > + if (!device)
> > + return -EINVAL;
> > +
> > + status = acpi_evaluate_object(device->handle, "ADDR", NULL, &buffer);
> > + if (ACPI_FAILURE(status)) {
> > + ACPI_EXCEPTION((AE_INFO, status, "Evaluating ADDR"));
> > + return -ENODEV;
> > + }
> > + pss = buffer.pointer;
> > + if (!pss || pss->type != ACPI_TYPE_PACKAGE || pss->package.count != 2 ||
> > + pss->package.elements[0].type != ACPI_TYPE_INTEGER ||
> > + pss->package.elements[1].type != ACPI_TYPE_INTEGER) {
> > + ret = -EINVAL;
> > + goto out;
> > + }
> > +
> > + phys_addr = (pss->package.elements[0].integer.value << 0) |
> > + (pss->package.elements[1].integer.value << 32);
> > + state.next_id = acpi_os_map_memory(phys_addr, VMGENID_SIZE);
>
> No need to use acpi_os_map_memory() here, plain memremap() should be fine.
As we discussed online, I'll use dev_memremap(), and then get rid of
the `.remove = ` function all together.
> > + acpi_os_unmap_memory(state.next_id, VMGENID_SIZE);
>
> memunmap() here
And then as discussed, this goes away too.
>
> > + state.next_id = NULL;
> > + return 0;
> > +}
> > +
> > +static void vmgenid_acpi_notify(struct acpi_device *device, u32 event)
> > +{
> > + u8 old_id[VMGENID_SIZE];
> > +
> > + if (!device || acpi_driver_data(device) != &state)
> > + return;
> > + memcpy(old_id, state.this_id, sizeof(old_id));
> > + memcpy(state.this_id, state.next_id, sizeof(state.this_id));
> > + if (!memcmp(old_id, state.this_id, sizeof(old_id)))
> > + return;
>
> Is this little dance really necessary? I.e., can we just do
>
> add_vmfork_randomness(state.next_id, VMGENID_SIZE)
>
> and be done with it?
Yes it is. vmfork induces a "premature-next" which we really should
not do unless it's really necessary. It torches the whole entropy
pool. In the even that this notifier fires but the ID hasn't changed,
we shouldn't touch anything.
Thanks for the review. v+1 coming up shortly.
Powered by blists - more mailing lists