All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Kelley <mikelley@microsoft.com>
To: vkuznets <vkuznets@redhat.com>
Cc: "linux-hyperv@vger.kernel.org" <linux-hyperv@vger.kernel.org>
Subject: RE: Checking Hyper-V hypercall status
Date: Tue, 16 Feb 2021 14:25:42 +0000	[thread overview]
Message-ID: <MWHPR21MB15932A447B6A9AAE21AE4119D7879@MWHPR21MB1593.namprd21.prod.outlook.com> (raw)
In-Reply-To: <MWHPR21MB15934013452AE9F2DF80C02DD78D9@MWHPR21MB1593.namprd21.prod.outlook.com>

From: Michael Kelley  Sent: Wednesday, February 10, 2021 9:09 AM
> 
> From: Vitaly Kuznetsov <vkuznets@redhat.com> Sent: Tuesday, February 9, 2021 8:51 AM
> >
> > Michael Kelley <mikelley@microsoft.com> writes:
> >
> > > As noted in a previous email, we don't have a consistent
> > > pattern for checking Hyper-V hypercall status.  Existing code and
> > > recent new code uses a number of variants.  The variants work, but
> > > a consistent pattern would improve the readability of the code, and
> > > be more conformant to what the Hyper-V TLFS says about hypercall
> > > status.  In particular, the 64 bit hypercall status contains fields that
> > > the TLFS says should be ignored -- evidently they are not guaranteed
> > > to be zero (though I've never seen otherwise).
> > >
> > > I'd propose the following helper functions to go in
> > > asm-generic/mshyperv.h.  The function names are relatively short
> > > for readability:
> > >
> > > static inline u64 hv_result(u64 status)
> > > {
> > > 	return status & HV_HYPERCALL_RESULT_MASK;
> > > }
> > >
> > > static inline bool hv_result_success(u64 status)
> > > {
> > > 	return hv_result(status) == HV_STATUS_SUCCESS;
> > > }
> > >
> > > static inline unsigned int hv_repcomp(u64 status)
> > > {
> > > 	return (status & HV_HYPERCALL_REP_COMP_MASK) >>
> > > 			HV_HYPERCALL_REP_COMP_OFFSET;
> > > }
> > >
> > > The hv_do_hypercall() function (and its 'rep' and 'fast' variants) should
> > > always assign the result to a u64 local variable, which is the return
> > > type of the functions.  Then the above functions can act on that local
> > > variable.  Here are some examples:
> > >
> > > 	u64		status;
> > > 	unsigned int	completed;
> > >
> > > 	status = hv_do_hypercall(<some args>);
> > > 	if (!hv_result_success(status)) {
> > > 		<handle error case>
> > > 	}
> > >
> > > 	status = hv_do_rep_hypercall(<some args>);
> > > 	if (hv_result(status) == HV_STATUS_INSUFFICIENT_MEMORY) {
> > > 		<deposit more memory pages>
> > > 		goto retry;
> > > 	} else if (!hv_result_success(status)) {
> > > 		<handle error case>
> > > 	}
> > > 	completed = hv_repcomp(status);
> > >
> > >
> > > Thoughts?
> >
> > Personally, I like it and think it's going to be sufficient.
> >
> > Alternatively, I can suggest we introduce something like
> >
> > struct hv_result {
> > 	u64 status:16;
> > 	u64 rsvd1:16;
> > 	u64 reps_comp:12;
> > 	u64 rsvd1:20;
> > };
> >
> > and make hv_do_rep_hypercall() return it. So the code above will look
> > like:
> >
> > 	struct hv_result result;
> >
> > 	result = hv_do_rep_hypercall(<some args>);
> >         if (result.status) == HV_STATUS_INSUFFICIENT_MEMORY) {
> >                 <deposit more memory pages>
> >                 goto retry;
> >         } else if (result.status != HV_STATUS_SUCCESS) {
> >                 <handle error case>
> >         }
> >         completed = result.reps_comp;
> >
> > --
> 
> Your proposal is OK with me as well, though one downside is that it is
> not compatible with current code.  The return type of hv_do_hypercall()
> and friends would change, so we would have to change all occurrences
> in a single patch.  With the helper functions, changing the code to use
> them can be done incrementally.
> 
> Back when I was first working on the patches for Linux on ARM64 on
> Hyper-V, I went down the path of defining a structure for the hypercall
> result, but ended up abandoning it, probably because of the compatibility
> issue.
> 
> But either works and is OK with me.
> 

In thinking about this a few more days, having the hv_do_hypercall()
functions return a struct rather than a scalar value seems a bit off
the beaten path, even if the struct is a 64 bit quantity.  I just wonder
if currently unknown problems might arise later with other tooling
(like sparse) in using that approach.  So I'm leaning toward the
helper function approach instead of bit fields in a struct.

Michael

  reply	other threads:[~2021-02-16 14:27 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-10 17:08 Checking Hyper-V hypercall status Michael Kelley
2021-02-16 14:25 ` Michael Kelley [this message]
2021-02-16 14:55   ` ** POTENTIAL FRAUD ALERT - RED HAT ** " Vitaly Kuznetsov
  -- strict thread matches above, loose matches on Subject: below --
2021-02-09 15:45 Michael Kelley
2021-02-10 16:45 ` Wei Liu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=MWHPR21MB15932A447B6A9AAE21AE4119D7879@MWHPR21MB1593.namprd21.prod.outlook.com \
    --to=mikelley@microsoft.com \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=vkuznets@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.