On Thu, Oct 20, 2022 at 10:57:14AM -0700, Michael Kelley wrote: > To support PCI pass-thru devices in Confidential VMs, Hyper-V > has added hypercalls to read and write MMIO space. Add the > appropriate definitions to hyperv-tlfs.h and implement > functions to make the hypercalls. These functions are used > in a subsequent patch. > > Co-developed-by: Dexuan Cui <decui@xxxxxxxxxxxxx> > Signed-off-by: Dexuan Cui <decui@xxxxxxxxxxxxx> > Signed-off-by: Michael Kelley <mikelley@xxxxxxxxxxxxx> > --- > arch/x86/include/asm/hyperv-tlfs.h | 3 ++ > drivers/pci/controller/pci-hyperv.c | 62 +++++++++++++++++++++++++++++++++++++ > include/asm-generic/hyperv-tlfs.h | 22 +++++++++++++ > 3 files changed, 87 insertions(+) > > diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h > index 3089ec3..f769b9d 100644 > --- a/arch/x86/include/asm/hyperv-tlfs.h > +++ b/arch/x86/include/asm/hyperv-tlfs.h > @@ -117,6 +117,9 @@ > /* Recommend using enlightened VMCS */ > #define HV_X64_ENLIGHTENED_VMCS_RECOMMENDED BIT(14) > > +/* Use hypercalls for MMIO config space access */ > +#define HV_X64_USE_MMIO_HYPERCALLS BIT(21) > + > /* > * CPU management features identification. > * These are HYPERV_CPUID_CPU_MANAGEMENT_FEATURES.EAX bits. > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c > index e7c6f66..02ebf3e 100644 > --- a/drivers/pci/controller/pci-hyperv.c > +++ b/drivers/pci/controller/pci-hyperv.c > @@ -1054,6 +1054,68 @@ static int wslot_to_devfn(u32 wslot) > return PCI_DEVFN(slot_no.bits.dev, slot_no.bits.func); > } > > +static void hv_pci_read_mmio(phys_addr_t gpa, int size, u32 *val) > +{ > + struct hv_mmio_read_input *in; > + struct hv_mmio_read_output *out; > + u64 ret; > + > + /* > + * Must be called with interrupts disabled so it is safe > + * to use the per-cpu input argument page. Use it for > + * both input and output. > + */ > + in = *this_cpu_ptr(hyperv_pcpu_input_arg); > + out = *this_cpu_ptr(hyperv_pcpu_input_arg) + sizeof(*in); > + in->gpa = gpa; > + in->size = size; > + > + ret = hv_do_hypercall(HVCALL_MMIO_READ, in, out); > + if (hv_result_success(ret)) { > + switch (size) { > + case 1: > + *val = *(u8 *)(out->data); > + break; > + case 2: > + *val = *(u16 *)(out->data); > + break; > + default: > + *val = *(u32 *)(out->data); > + break; > + } > + } else > + pr_err("MMIO read hypercall failed with status %llx\n", ret); Too bad there's not more information to give the user/administrator here. Seeing "MMIO read hypercall failed with status -5" in the log doesn't give many clues about where to look or who to notify. I don't know what's even feasible, but driver name, device, address (gpa), size would all be possibilities. Bjorn