[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <6bb65614-d420-49d3-312f-316dc8ca4cc4@intel.com>
Date: Mon, 21 Nov 2022 12:55:58 -0800
From: Dave Hansen <dave.hansen@...el.com>
To: Dexuan Cui <decui@...rosoft.com>, ak@...ux.intel.com,
arnd@...db.de, bp@...en8.de, brijesh.singh@....com,
dan.j.williams@...el.com, dave.hansen@...ux.intel.com,
haiyangz@...rosoft.com, hpa@...or.com, jane.chu@...cle.com,
kirill.shutemov@...ux.intel.com, kys@...rosoft.com,
linux-arch@...r.kernel.org, linux-hyperv@...r.kernel.org,
luto@...nel.org, mingo@...hat.com, peterz@...radead.org,
rostedt@...dmis.org, sathyanarayanan.kuppuswamy@...ux.intel.com,
seanjc@...gle.com, tglx@...utronix.de, tony.luck@...el.com,
wei.liu@...nel.org, x86@...nel.org
Cc: linux-kernel@...r.kernel.org
Subject: Re: [PATCH 2/6] x86/tdx: Retry TDVMCALL_MAP_GPA() when needed
On 11/21/22 11:51, Dexuan Cui wrote:
> +static bool tdx_map_gpa(phys_addr_t start, phys_addr_t end, bool enc)
> +{
> + u64 ret, r11;
'r11' needs a real, logical name.
> + while (1) {
> + ret = _tdx_hypercall_output_r11(TDVMCALL_MAP_GPA, start,
> + end - start, 0, 0, &r11);
> + if (!ret)
> + break;
> +
> + if (ret != TDVMCALL_STATUS_RETRY)
> + break;
> +
> + /*
> + * The guest must retry the operation for the pages in the
> + * region starting at the GPA specified in R11. Make sure R11
> + * contains a sane value.
> + */
> + if ((r11 & ~cc_mkdec(0)) < (start & ~cc_mkdec(0)) ||
> + (r11 & ~cc_mkdec(0)) >= (end & ~cc_mkdec(0)))
> + return false;
This statement is, um, a wee bit ugly.
First, it's not obvious at all why the address masking is necessary.
Second, it's utterly insane to do that mask to 'r11' twice. Third, it's
silly do logically the same thing to start and end every time through
the loop.
This also seems to have built in the idea that cc_mkdec() *SETS* bits
rather than clearing them. That's true for TDX today, but it's a
horrible chunk of code to leave around because it'll confuse actual
legitimate cc_enc/dec() users.
The more I write about it, the more I dislike it.
Why can't this just be:
if ((map_fail_paddr < start) ||
(map_fail_paddr >= end))
return false;
If the hypervisor returns some crazy address in r11 that isn't masked
like the inputs, just fail.
> + start = r11;
> +
> + /* Set the shared (decrypted) bit. */
> + if (!enc)
> + start |= cc_mkdec(0);
Why is only one side of this necessary? Shouldn't it need to be
something like:
if (enc)
start = cc_mkenc(start);
else
start = cc_mkdec(start);
??
> + }
> +
> + return !ret;
> +}
> +
> /*
> * Inform the VMM of the guest's intent for this physical page: shared with
> * the VMM or private to the guest. The VMM is expected to change its mapping
> @@ -707,12 +765,7 @@ static bool tdx_enc_status_changed(unsigned long vaddr, int numpages, bool enc)
> end |= cc_mkdec(0);
> }
>
> - /*
> - * Notify the VMM about page mapping conversion. More info about ABI
> - * can be found in TDX Guest-Host-Communication Interface (GHCI),
> - * section "TDG.VP.VMCALL<MapGPA>"
> - */
> - if (_tdx_hypercall(TDVMCALL_MAP_GPA, start, end - start, 0, 0))
> + if (!tdx_map_gpa(start, end, enc))
> return false;
>
> /* private->shared conversion requires only MapGPA call */
Powered by blists - more mailing lists