From: Nuno Das Neves <nunodasne...@linux.microsoft.com> Sent: Tuesday, January 
28, 2025 4:46 PM
> 
> On 1/28/2025 10:45 AM, Michael Kelley wrote:
> > From: Nuno Das Neves <nunodasne...@linux.microsoft.com> Sent: Wednesday, 
> > January 22, 2025 5:48 PM
> >>
> >> Move hv_current_partition_id and hv_get_partition_id() to hv_common.c.
> >> These aren't specific to x86_64 and will be needed by common code.
> >>
> >> Set hv_current_partition_id to HV_PARTITION_ID_SELF by default.
> >>
> >> Use a stack variable for the output of the hypercall. This allows moving
> >> the call of hv_get_partition_id() to hv_common_init() before the percpu
> >> pages are initialized.
> >>
> >> Remove the BUG()s. Failing to get the id need not crash the machine.
> >>
> >> Signed-off-by: Nuno Das Neves <nudas...@microsoft.com>
> >> ---
> >>  arch/x86/hyperv/hv_init.c       | 26 --------------------------
> >>  arch/x86/include/asm/mshyperv.h |  2 --
> >>  drivers/hv/hv_common.c          | 23 +++++++++++++++++++++++
> >>  include/asm-generic/mshyperv.h  |  1 +
> >>  4 files changed, 24 insertions(+), 28 deletions(-)

[snip]

> >> diff --git a/drivers/hv/hv_common.c b/drivers/hv/hv_common.c
> >> index af5d1dc451f6..1da19b64ef16 100644
> >> --- a/drivers/hv/hv_common.c
> >> +++ b/drivers/hv/hv_common.c
> >> @@ -31,6 +31,9 @@
> >>  #include <hyperv/hvhdk.h>
> >>  #include <asm/mshyperv.h>
> >>
> >> +u64 hv_current_partition_id = HV_PARTITION_ID_SELF;
> >> +EXPORT_SYMBOL_GPL(hv_current_partition_id);
> >> +
> >>  /*
> >>   * hv_root_partition, ms_hyperv and hv_nested are defined here with other
> >>   * Hyper-V specific globals so they are shared across all architectures 
> >> and are
> >> @@ -283,6 +286,23 @@ static inline bool hv_output_page_exists(void)
> >>    return hv_root_partition || IS_ENABLED(CONFIG_HYPERV_VTL_MODE);
> >>  }
> >>
> >> +static void __init hv_get_partition_id(void)
> >> +{
> >> +  /*
> >> +   * Note in this case the output can be on the stack because it is just
> >> +   * a single u64 and hence won't cross a page boundary.
> >> +   */
> >> +  struct hv_get_partition_id output;
> >
> > It's unfortunate that the structure name "hv_get_partition_id" is also
> > the name of this function. Could the structure name be changed to
> > follow the pattern of having "output" in the name, like other hypercall
> > parameters? It's not a blocker if it can't be changed. I was just surprised
> > to search for "hv_get_partition_id" and find both uses.
> >
> 
> hv_output_get_partition_id is really the "correct" name from the Hyper-V code,
> so it makes sense to just change it to that in this patch.
> 
> > Also, see the comment at the beginning of hv_query_ext_cap() regarding
> > using a local stack variable as hypercall input or output. The comment
> > originated here [1]. At that time, I didn't investigate Sunil's assertion 
> > any
> > further, and I'm still unsure whether it is really true. But perhaps for
> > consistency and safety we should follow what it says.
> >
> > [1] 
> > https://lore.kernel.org/linux-hyperv/sn4pr2101mb0880db0606a5a0b72ad244b4c0...@sn4pr2101mb0880.namprd21.prod.outlook.com/
> >
> Hmm, from some cursory research it does look like stack variables can't be
> used with virt_to_phys().
> 
> I thought about just using &hv_current_partition directly - I *think* that
> will work - but in the end I think it's just simpler to just move calls so the
> percpu output page can be used as normal. That may save some additional
> back-and-forth as well as explanatory comments in the code.
> 
> I will also add a check for hv_output_page_exists() here, as a precaution in
> case the HV_ACCESS_PARTITION_ID privilege ever becomes decoupled from
> that (as it stands, I believe that permission is only for the root
> partition, but you never know).

Or just use the hyperv_pcpu_input_page, even though the use here is
for output. Then you don't have to worry about whether the output
page exists.  FWIW, I'm working on a set of changes that encapsulates
the assignment of the per-cpu hypercall argument pages, and it does
away with the distinction between the input and output pages. But
that will come sometime after this patch.

Michael

> 
> >> +  u64 status;
> >> +
> >> +  status = hv_do_hypercall(HVCALL_GET_PARTITION_ID, NULL, &output);
> >> +  if (!hv_result_success(status)) {
> >> +          pr_err("Hyper-V: failed to get partition ID: %#lx\n", status);
> >> +          return;
> >> +  }
> >> +  hv_current_partition_id = output.partition_id;
> >> +}
> >> +
> >>  int __init hv_common_init(void)
> >>  {
> >>    int i;
> >> @@ -298,6 +318,9 @@ int __init hv_common_init(void)
> >>    if (hv_is_isolation_supported())
> >>            sysctl_record_panic_msg = 0;
> >>
> >> +  if (ms_hyperv.priv_high & HV_ACCESS_PARTITION_ID)
> >> +          hv_get_partition_id();
> >
> > I don't see how this works. On the x86 side, hv_common_init()
> > is called before the guest ID is set and the hypercall page is setup.
> > So the hypercall in hv_get_partition_id() should fail.
> >
> 
> Oh, I tried to get too clever. I will put it back where it was and
> add it on the arm64 side to hyperv_init() after the per-cpu init as
> I mentioned above.
> 
> Thanks for the comments,
> Nuno

Reply via email to