| Date | Wed, 2 Feb 2022 07:22:13 +0100 | From | Borislav Petkov <> | Subject | Re: [PATCHv2 13/29] x86/tdx: Add port I/O emulation |
| |
On Mon, Jan 24, 2022 at 06:01:59PM +0300, Kirill A. Shutemov wrote: > diff --git a/arch/x86/kernel/tdx.c b/arch/x86/kernel/tdx.c > index 8e630eeb765d..e73af22a4c11 100644 > --- a/arch/x86/kernel/tdx.c > +++ b/arch/x86/kernel/tdx.c > @@ -13,6 +13,12 @@ > /* TDX module Call Leaf IDs */ > #define TDX_GET_VEINFO 3 > > +/* See Exit Qualification for I/O Instructions in VMX documentation */ > +#define VE_IS_IO_IN(exit_qual) (((exit_qual) & 8) ? 1 : 0) > +#define VE_GET_IO_SIZE(exit_qual) (((exit_qual) & 7) + 1) > +#define VE_GET_PORT_NUM(exit_qual) ((exit_qual) >> 16) > +#define VE_IS_IO_STRING(exit_qual) ((exit_qual) & 16 ? 1 : 0)
Use BIT() and masks here. For example:
#define VE_IS_IO_STRING(e) ((e) & BIT(4))
You don't need the ternary ?: either as you're using them all in a boolean context.
> +static bool tdx_handle_io(struct pt_regs *regs, u32 exit_qual) > +{ > + struct tdx_hypercall_output out; > + int size, port, ret; > + u64 mask; > + bool in; > + > + if (VE_IS_IO_STRING(exit_qual)) > + return false; > + > + in = VE_IS_IO_IN(exit_qual); > + size = VE_GET_IO_SIZE(exit_qual); > + port = VE_GET_PORT_NUM(exit_qual); > + mask = GENMASK(BITS_PER_BYTE * size, 0); > + > + /* > + * Emulate the I/O read/write via hypercall. More info about > + * ABI can be found in TDX Guest-Host-Communication Interface > + * (GHCI) sec titled "TDG.VP.VMCALL<Instruction.IO>".
"section"
> + */ > + ret = _tdx_hypercall(EXIT_REASON_IO_INSTRUCTION, size, !in, port, > + in ? 0 : regs->ax, &out); > + if (!in) > + return !ret; > + > + regs->ax &= ~mask; > + regs->ax |= ret ? UINT_MAX : out.r11 & mask; > + > + return !ret; > +}
-- Regards/Gruss, Boris.
https://people.kernel.org/tglx/notes-about-netiquette
|