Re: [Xen-devel] [PATCH] xen/netfront: tolerate frags with no data
On 19/12/2018 07:00, David Miller wrote: > From: Juergen Gross > Date: Tue, 18 Dec 2018 16:06:19 +0100 > >> At least old Xen net backends seem to send frags with no real data >> sometimes. In case such a fragment happens to occur with the frag limit >> already reached the frontend will BUG currently even if this situation >> is easily recoverable. >> >> Modify the BUG_ON() condition accordingly. >> >> Tested-by: Dietmar Hahn >> Signed-off-by: Juergen Gross > > Applied and queued up for -stable. > > But many of these BUG's in the driver should be converted to > WARNs and recovery code added. > Right, but that will be no stable material then. Will start that effort after Christmas. Juergen ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] xen/netfront: tolerate frags with no data
From: Juergen Gross Date: Tue, 18 Dec 2018 16:06:19 +0100 > At least old Xen net backends seem to send frags with no real data > sometimes. In case such a fragment happens to occur with the frag limit > already reached the frontend will BUG currently even if this situation > is easily recoverable. > > Modify the BUG_ON() condition accordingly. > > Tested-by: Dietmar Hahn > Signed-off-by: Juergen Gross Applied and queued up for -stable. But many of these BUG's in the driver should be converted to WARNs and recovery code added. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [XEN][ARM64] PV DRM failing to convert virtual to physical address
Hello Oleksandr, Please find the attached log file. Could please provide some pointers on how test DomU display. On Tue, Dec 18, 2018 at 12:06 PM Oleksandr Andrushchenko wrote: Hello, Vikram! > * We are using 64 bit arm platform. > * Linux 4.20 Kernel in DomU with PV DRM front-end drivers. > >> Do you have [1] enabled in your DomD kernel? Earlier this configuration was not enabled. Enabled it now. > > * Xen-4.12 unstable version. > >> We never tested PV DRM with 4.12 so far, did you try with 4.10 for example? Xen-4.8 is working on our platform. Xen-4.9 to Xen-4.11 version fails while initializing CPU on our platform. Recently we received patch from Julien for Xen-4.12 unstable version, which has fix. Tried to apply patch on Xen-4.10 stable facing build issue. This is where we are at the moment and have all PV drivers running smoothly > * Able to build displ_be application and also its dependencies. > > Added below configuration in Domain-U config file.*| > |* > *|vdispl = [ 'backend=Domain-0,be-alloc=0,connectors=HDMI-A-1:1920x1080']|* > >> Do you really have DomD as your configuration says? Sorry it not DomD it is Domain-0. >> Not Dom0 running the backend? Domain-0 is running in Dom0 and debian is running as DomU. > Before launching the DomU ran the displ_be application in the > background. > $ displ_be -m DRM -v *:Debug & Please add display back-end logs > > Started Domain-U. > $ xl create -c debian.cfg > >> Could you please build the PV DRM driver as module, >> Built as module. then run the following commands: echo 0xff > /sys/module/drm/parameters/debug echo 8 > /proc/sys/kernel/printk >> and get back with DRM logs in DomU? Please find the attached log file -- Thanks & Regards Vikram KS -- This message contains confidential information and is intended only for the individual(s) named. If you are not the intended recipient, you are notified that disclosing, copying, distributing or taking any action in reliance on the contents of this mail and attached file/s is strictly prohibited. Please notify the sender immediately and delete this e-mail from your system. E-mail transmission cannot be guaranteed to be secured or error-free as information could be intercepted, corrupted, lost, destroyed, arrive late or incomplete, or contain viruses. The sender therefore does not accept liability for any errors or omissions in the contents of this message, which arise as a result of e-mail transmission. === $ displ_be -m DRM -v *:Debug & 19.12.18 05:13:11.447 | Main | INF - backend version: v0.2.1-5-g7fc0-dirty 19.12.18 05:13:11.454 | Main | INF - libxenbe version: v0.2.1-2-g6769-dirty 19.12.18 05:13:11.461 | Drm | DBG - Create Drm card: /dev/dri/card0, FD: 3 19.12.18 05:13:11.476 | Drm | DBG - Connector id: 30, name: HDMI-A-1, connected: 1 19.12.18 05:13:11.485 | XenStore | DBG - Create xen store 19.12.18 05:13:11.490 | XenStore | DBG - Read string domid : 0 19.12.18 05:13:11.496 | XenStore | DBG - Read int domid : 0 19.12.18 05:13:11.501 | DisplBackend | DBG - Create backend, device: vdispl, dom Id: 0 19.12.18 05:13:11.509 | Drm | DBG - Start 19.12.18 05:13:11.514 | XenStore | DBG - Start 19.12.18 05:13:11.518 | XenStore | DBG - Set watch: /local/domain/0/backend/vdispl 19.12.18 05:13:11.527 | XenStore | DBG - Watch triggered: /local/domain/0/backend/vdispl === $ create_domu_debian DomU boot logs: root@hikey960:~# create_domu_debian Parsing config from /debian/debian.cfg 19.12.18 05:21:42.465 | XenStore| DBG - Watch triggered: /local/domain/0/backend/vdispl 19.12.18 05:21:42.474 | XenStore| DBG - Set watch: /local/domain/0/backend/vdispl/2 19.12.18 05:21:42.483 | XenStore| DBG - Watch triggered: /local/domain/0/backend/vdispl 19.12.18 05:21:42.492 | XenStore| DBG - Watch triggered: /local/domain/0/backend/vdispl 19.12.18 05:21:42.501 | XenStore| DBG - Watch triggered: /local/domain/0/backend/vdispl 19.12.18 05:21:42.510 | XenStore| DBG - Watch triggered: /local/domain/0/backend/vdispl 19.12.18 05:21:42.519 | XenStore| DBG - Watch triggered: /local/domain/0/backend/vdispl 19.12.18 05:21:42.528 | XenStore| DBG - Watch triggered: /local/domain/0/backend/vdispl 19.12.18 05:21:42.536 | XenStore| DBG - Watch triggered: /local/domain/0/backend/vdispl/2 19.12.18 05:21:42.546 | DisplBackend| DBG - New frontend found, domid: 2, devid: 0 19.12.18 05:21:42.554 | XenStore| DBG - Create xen store 19.12.18 05:21:42.559 | DisplFrontend | DBG - Dom(2/0) Create frontend handler 19.12.18 05:21:42.567 | XenStore| DBG - Read string /local/domain/0/backend/vdispl/2/0/front
Re: [Xen-devel] [PATCH v3 1/2] xen/pt: fix some pass-thru devices don't work across reboot
On Tue, Dec 18, 2018 at 08:53:46AM -0700, Jan Beulich wrote: On 18.12.18 at 15:43, wrote: >> I find some pass-thru devices don't work any more across guest >> reboot. Assigning it to another domain also meets the same issue. And >> the only way to make it work again is un-binding and binding it to >> pciback. Someone reported this issue one year ago [1]. >> >> If the device's driver doesn't disable MSI-X during shutdown or qemu is >> killed/crashed before the domain shutdown, this domain's pirq won't be >> unmapped. Then xen takes over this work, unmapping all pirq-s, when >> destroying guest. But as pciback has already disabled meory decoding before >> xen unmapping pirq, Xen has to sets the host_maskall flag and maskall bit >> to mask a MSI rather than sets maskbit in MSI-x table. The call trace of >> this process is: >> >> ->arch_domain_destroy >> ->free_domain_pirqs >> ->unmap_domain_pirq (if pirq isn't unmapped by qemu) >> ->pirq_guest_force_unbind >> ->__pirq_guest_unbind >> ->mask_msi_irq(=desc->handler->disable()) >> ->the warning in msi_set_mask_bit() >> >> The host_maskall bit will prevent guests from clearing the maskall bit >> even the device is assigned to another guest later. Then guests cannot >> receive MSIs from this device. >> >> To fix this issue, a pirq is unmapped before memory decoding is disabled by >> pciback. Specifically, when a device is detached from a guest, all >> established >> mappings between pirq and msi are destroying before changing the ownership. >> >> [1]: >> https://lists.xenproject.org/archives/html/xen-devel/2017-09/msg02520.html >> >> Signed-off-by: Chao Gao >> --- >> Applied this patch, qemu would report the error below: >> [00:05.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, >> pirq: 302, gvec: 0xd5) >> [00:05.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, >> pirq: 301, gvec: 0xe5) >> [00:04.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, >> pirq: 359, gvec: 0x41) >> [00:04.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, >> pirq: 358, gvec: 0x51) >> >> Despite of the error, guest shutdown or device hotplug finishs smoothly. >> It seems to me that qemu tries to unbind a msi which is already unbound by >> the code added by this patch. I am not sure whether it is acceptable to >> leave this error there. > >Well, the errors mean that qemu is playing with a device that's no >longer owned by the guest controlled by this qemu instance. At >least with a de-privileged qemu (no idea whether this actually works >with pass-through) that's still a mistake, and hence would need >fixing. Whichever entity it is that invokes the de-assign of the >device, other involved parties should be informed so that they can >keep their hands off the device from that point onwards. > >The hypervisor change itself looks mostly fine, just a few minor >comments. > >> --- a/xen/drivers/passthrough/pci.c >> +++ b/xen/drivers/passthrough/pci.c >> @@ -368,6 +368,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, >> u8 bus, u8 devfn) >> return NULL; >> } >> spin_lock_init(&msix->table_lock); >> +msix->warned = DOMID_INVALID; > >This is an arch-specific field right now; in fact the entire structure >is arch-specific. Playing with any of its fields in common code is >undesirable, but I guess the use of ->table_lock can be taken as >an excuse until this code wants to eventually be used by Arm. >(The structure requiring a lock is sufficiently generic, whereas >the "warned" field may not be universally needed.) I will clean up this place. > >> @@ -1514,6 +1515,52 @@ static int assign_device(struct domain *d, u16 seg, >> u8 bus, u8 devfn, u32 flag) >> return rc; >> } >> >> +/* >> + * Unmap established mappings between domain's pirq and device's MSI. >> + * These mappings were set up by qemu/guest and are expected to be >> + * destroyed when changing the device's ownership. >> + */ >> +static void pci_unmap_msi(struct pci_dev *pdev) >> +{ >> +struct msi_desc *entry, *tmp; >> + >> +ASSERT(pcidevs_locked()); >> + >> +if ( !pdev->domain ) > >There are quite a few uses of pdev->domain - please consider >using a local variable. > >> +return; >> + >> +spin_lock(&pdev->domain->event_lock); >> +list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list ) >> +{ >> +struct pirq *info; >> +struct hvm_pirq_dpci *pirq_dpci; >> +int pirq = domain_irq_to_pirq(pdev->domain, entry->irq), pirq_orig; >> + >> +pirq_orig = pirq; >> + >> +if ( !pirq ) >> +continue; >> + >> +/* For forcibly unmapped pirq, lookup radix tree with absolute >> value */ >> +if ( pirq < 0) >> +pirq = -pirq; >> + >> +info = pirq_info(pdev->domain, pirq); > >Why not simply > >info =
Re: [Xen-devel] [PATCH 00/41] scsi: Mark expected switch fall-throughs
On 12/18/18 9:45 PM, Martin K. Petersen wrote: If you haven't received feedback on a patch you should poke the relevant driver maintainer. Got it. Will do so. Thanks -- Gustavo ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH 00/41] scsi: Mark expected switch fall-throughs
Hi Gustavo, > Only 8 out the 41 patches in this series have been applied so far. I applied the patches that got acked or reviewed by their respective driver maintainers. If you haven't received feedback on a patch you should poke the relevant driver maintainer. -- Martin K. Petersen Oracle Linux Engineering ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [xen-unstable-smoke test] 131436: tolerable all pass - PUSHED
flight 131436 xen-unstable-smoke real [real] http://logs.test-lab.xenproject.org/osstest/logs/131436/ Failures :-/ but no regressions. Tests which did not succeed, but are not blocking: test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass version targeted for testing: xen f60658c6ae47e74792e6cc48ea2effac8bb52826 baseline version: xen 221c2fc433904937966e40c6a2538650253b7204 Last test of basis 131434 2018-12-18 21:00:52 Z0 days Testing same since 131436 2018-12-19 00:00:58 Z0 days1 attempts People who touched revisions under test: Andrii Anisov Julien Grall Matthew Daley Stefano Stabellini jobs: build-amd64 pass build-armhf pass build-amd64-libvirt pass test-armhf-armhf-xl pass test-amd64-amd64-xl-qemuu-debianhvm-i386 pass test-amd64-amd64-libvirt pass sg-report-flight on osstest.test-lab.xenproject.org logs: /home/logs/logs images: /home/logs/images Logs, config files, etc. are available at http://logs.test-lab.xenproject.org/osstest/logs Explanation of these reports, and of osstest in general, is at http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master Test harness code can be found at http://xenbits.xen.org/gitweb?p=osstest.git;a=summary Pushing revision : To xenbits.xen.org:/home/xen/git/xen.git 221c2fc433..f60658c6ae f60658c6ae47e74792e6cc48ea2effac8bb52826 -> smoke ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [linux-next test] 131387: regressions - FAIL
flight 131387 linux-next real [real] http://logs.test-lab.xenproject.org/osstest/logs/131387/ Regressions :-( Tests which did not succeed and are blocking, including tests which could not be run: test-amd64-amd64-xl-qemuu-debianhvm-amd64-shadow 7 xen-boot fail REGR. vs. 131276 test-amd64-amd64-xl-pvshim7 xen-boot fail REGR. vs. 131276 test-amd64-amd64-libvirt 7 xen-boot fail REGR. vs. 131276 test-amd64-amd64-xl-qemut-stubdom-debianhvm-amd64-xsm 7 xen-boot fail REGR. vs. 131276 test-amd64-amd64-xl-qemuu-ovmf-amd64 7 xen-boot fail REGR. vs. 131276 test-amd64-i386-xl-qemuu-debianhvm-amd64-xsm 7 xen-boot fail REGR. vs. 131276 test-amd64-i386-xl-qemuu-debianhvm-amd64-shadow 7 xen-boot fail REGR. vs. 131276 test-armhf-armhf-xl-vhd 10 debian-di-installfail REGR. vs. 131276 test-amd64-i386-qemut-rhel6hvm-amd 12 guest-start/redhat.repeat fail REGR. vs. 131276 test-armhf-armhf-examine 8 reboot fail REGR. vs. 131276 test-armhf-armhf-xl-credit1 7 xen-boot fail REGR. vs. 131276 test-armhf-armhf-xl-cubietruck 7 xen-boot fail REGR. vs. 131276 test-armhf-armhf-xl-multivcpu 7 xen-bootfail REGR. vs. 131276 test-armhf-armhf-libvirt 7 xen-boot fail REGR. vs. 131276 test-armhf-armhf-xl-credit2 7 xen-boot fail REGR. vs. 131276 test-armhf-armhf-xl 7 xen-boot fail REGR. vs. 131276 Regressions which are regarded as allowable (not blocking): test-armhf-armhf-xl-rtds 7 xen-boot fail REGR. vs. 131276 Tests which did not succeed, but are not blocking: test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stop fail blocked in 131276 test-amd64-amd64-pygrub 7 xen-boot fail like 131276 test-amd64-amd64-pair10 xen-boot/src_hostfail like 131276 test-amd64-amd64-pair11 xen-boot/dst_hostfail like 131276 test-amd64-amd64-libvirt-pair 10 xen-boot/src_hostfail like 131276 test-amd64-amd64-libvirt-pair 11 xen-boot/dst_hostfail like 131276 test-amd64-i386-examine 8 reboot fail like 131276 test-amd64-i386-xl-shadow 7 xen-boot fail like 131276 test-amd64-amd64-xl-credit1 7 xen-boot fail like 131276 test-amd64-i386-qemut-rhel6hvm-intel 7 xen-boot fail like 131276 test-amd64-i386-pair 10 xen-boot/src_hostfail like 131276 test-amd64-i386-pair 11 xen-boot/dst_hostfail like 131276 test-amd64-i386-libvirt-xsm 7 xen-boot fail like 131276 test-amd64-i386-libvirt-pair 10 xen-boot/src_hostfail like 131276 test-amd64-i386-libvirt-pair 11 xen-boot/dst_hostfail like 131276 test-amd64-amd64-examine 8 reboot fail like 131276 test-amd64-amd64-xl-qemut-win7-amd64 17 guest-stopfail like 131276 test-armhf-armhf-libvirt-raw 13 saverestore-support-checkfail like 131276 test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stopfail like 131276 test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail like 131276 test-amd64-i386-xl-qemut-win7-amd64 17 guest-stop fail like 131276 test-amd64-i386-xl-qemuu-ws16-amd64 17 guest-stop fail like 131276 test-amd64-amd64-xl-qemut-ws16-amd64 17 guest-stopfail like 131276 test-amd64-amd64-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-i386-libvirt 13 migrate-support-checkfail never pass test-amd64-i386-xl-pvshim12 guest-start fail never pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-amd64-libvirt-vhd 12 migrate-support-checkfail never pass test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2 fail never pass test-armhf-armhf-libvirt-raw 12 migrate-support-checkfail never pass test-amd64-i386-xl-qemut-ws16-amd64 17 guest-stop fail never pass test-armhf-armhf-xl-arndale 13 migrate-support-checkfail never pass test-armhf-armhf-xl-arndale 14 saverestore-support-checkfail never pass test-amd64-i386-xl-qemuu-win10-i386 10 windows-install fail never pass test-amd64-amd64-xl-qemut-win10-i386 10 windows-installfail never pass test-amd64-i386-xl-qemut-win10-i386 10 windows-install fail never pass test-amd64-amd64-xl-qemuu-win10-i386 10 windows-installfail never pass version targeted for testing: linuxd14b746c6c1ca310f679ef13f661587454e2c588 baseline version: linuxf5d582777bcb1c7ff19a5a2343f66ea01de401c6 Last test of basis (not found)
[Xen-devel] [PATCH v8 1/6] xen/arm: introduce platform_smc
From: "Edgar E. Iglesias" Introduce platform_smc as a way to handle firmware calls that Xen does not know about in a platform specific way. This is particularly useful for implementing the SiP (SoC implementation specific) service calls. Signed-off-by: Edgar E. Iglesias Signed-off-by: Stefano Stabellini Acked-by: Julien Grall --- Changes in v4: - add likely --- xen/arch/arm/platform.c| 8 xen/arch/arm/vsmc.c| 4 xen/include/asm-arm/platform.h | 3 +++ 3 files changed, 15 insertions(+) diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c index 6989e58..3426056 100644 --- a/xen/arch/arm/platform.c +++ b/xen/arch/arm/platform.c @@ -127,6 +127,14 @@ void platform_poweroff(void) platform->poweroff(); } +bool platform_smc(struct cpu_user_regs *regs) +{ +if ( likely(platform && platform->smc) ) +return platform->smc(regs); + +return false; +} + bool platform_has_quirk(uint32_t quirk) { uint32_t quirks = 0; diff --git a/xen/arch/arm/vsmc.c b/xen/arch/arm/vsmc.c index c4ccae6..c72b9a0 100644 --- a/xen/arch/arm/vsmc.c +++ b/xen/arch/arm/vsmc.c @@ -25,6 +25,7 @@ #include #include #include +#include /* Number of functions currently supported by Hypervisor Service. */ #define XEN_SMCCC_FUNCTION_COUNT 3 @@ -272,6 +273,9 @@ static bool vsmccc_handle_call(struct cpu_user_regs *regs) case ARM_SMCCC_OWNER_STANDARD: handled = handle_sssc(regs); break; +case ARM_SMCCC_OWNER_SIP: +handled = platform_smc(regs); +break; } } diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h index bf92581..ed4d30a 100644 --- a/xen/include/asm-arm/platform.h +++ b/xen/include/asm-arm/platform.h @@ -25,6 +25,8 @@ struct platform_desc { void (*reset)(void); /* Platform power-off */ void (*poweroff)(void); +/* Platform specific SMC handler */ +bool (*smc)(struct cpu_user_regs *regs); /* * Platform quirks * Defined has a function because a platform can support multiple @@ -54,6 +56,7 @@ int platform_cpu_up(int cpu); #endif void platform_reset(void); void platform_poweroff(void); +bool platform_smc(struct cpu_user_regs *regs); bool platform_has_quirk(uint32_t quirk); bool platform_device_is_blacklisted(const struct dt_device_node *node); -- 1.9.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v8 5/6] xen/arm: zynqmp: Remove blacklist of ZynqMP's PM node
From: "Edgar E. Iglesias" Stop blacklisting ZynqMP's power management node. It is now possible since we allow the hardware domain to issue HVC/SMC calls to firmware. Signed-off-by: Edgar E. Iglesias Signed-off-by: Stefano Stabellini Reviewed-by: Stefano Stabellini Acked-by: Julien Grall --- xen/arch/arm/platforms/xilinx-zynqmp.c | 8 1 file changed, 8 deletions(-) diff --git a/xen/arch/arm/platforms/xilinx-zynqmp.c b/xen/arch/arm/platforms/xilinx-zynqmp.c index 67a08ac..08e3e11 100644 --- a/xen/arch/arm/platforms/xilinx-zynqmp.c +++ b/xen/arch/arm/platforms/xilinx-zynqmp.c @@ -27,13 +27,6 @@ static const char * const zynqmp_dt_compat[] __initconst = NULL }; -static const struct dt_device_match zynqmp_blacklist_dev[] __initconst = -{ -/* Power management is not yet supported. */ -DT_MATCH_COMPATIBLE("xlnx,zynqmp-pm"), -{ /* sentinel */ }, -}; - static bool zynqmp_smc(struct cpu_user_regs *regs) { /* @@ -58,7 +51,6 @@ static bool zynqmp_smc(struct cpu_user_regs *regs) PLATFORM_START(xilinx_zynqmp, "Xilinx ZynqMP") .compatible = zynqmp_dt_compat, .smc = zynqmp_smc, -.blacklist_dev = zynqmp_blacklist_dev, PLATFORM_END /* -- 1.9.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v8 0/6] zynqmp: Add forwarding of platform specific firmware calls
Hi all, Only minor changes in this patch, mainly: - code style - move PM_GET_TRUSTZONE_VERSION to enum - remove ZYNQMP_SIP_SVC_* - add acked-by Cheers, Stefano The following changes since commit 82855aba5bf91e50c81526167c11d4aeaf665e66: tools/libxc: Fix error handling in get_cpuid_domain_info() (2018-11-30 14:21:12 +) are available in the git repository at: http://xenbits.xenproject.org/git-http/people/sstabellini/xen-unstable.git zynqmp-v8 for you to fetch changes up to 28b46979989d806877ccee4218c0aba1f4873ed6: xen/zynqmp: add IPI calls virtualization (2018-12-18 13:45:39 -0800) Edgar E. Iglesias (5): xen/arm: introduce platform_smc xen/arm: zynqmp: Forward plaform specific firmware calls xen/arm: zynqmp: introduce zynqmp specific defines xen/arm: zynqmp: implement zynqmp_eemi xen/arm: zynqmp: Remove blacklist of ZynqMP's PM node Stefano Stabellini (1): xen/zynqmp: add IPI calls virtualization xen/arch/arm/platform.c| 8 + xen/arch/arm/platforms/Makefile| 1 + xen/arch/arm/platforms/xilinx-zynqmp-eemi.c| 218 + xen/arch/arm/platforms/xilinx-zynqmp.c | 28 ++- xen/arch/arm/vsmc.c| 4 + xen/include/asm-arm/platform.h | 3 + xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h | 128 7 files changed, 384 insertions(+), 6 deletions(-) create mode 100644 xen/arch/arm/platforms/xilinx-zynqmp-eemi.c create mode 100644 xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v8 6/6] xen/zynqmp: add IPI calls virtualization
ZynqMP IPI mailbox calls are a small set of EEMI sister calls, often used in conjunction with EEMI related functionalities. Unfortunately they are not part of the EEMI spec, or any other public spec, but the implementation is upstream in ATF: https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.h And patches are close to getting into Linux: https://patchwork.kernel.org/cover/10689501/ Signed-off-by: Stefano Stabellini Acked-by: Julien Grall --- Changes in v7: - add IPI_MAILBOX_FID and use it - remove tabs Changes in v6: - new patch --- xen/arch/arm/platforms/xilinx-zynqmp-eemi.c| 18 ++ xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h | 15 +++ 2 files changed, 33 insertions(+) diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c index 80e990c..2053ed7 100644 --- a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c +++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c @@ -25,6 +25,9 @@ * EEMI firmware API: * https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf * + * IPI firmware API: + * https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.h + * * Power domain node_ids identify the area of effect of the power * management operations. They are the first parameter passed to power * management EEMI calls. @@ -153,6 +156,21 @@ bool zynqmp_eemi(struct cpu_user_regs *regs) ret = XST_PM_NO_ACCESS; goto done; +case IPI_MAILBOX_FID(IPI_MAILBOX_OPEN): +case IPI_MAILBOX_FID(IPI_MAILBOX_RELEASE): +case IPI_MAILBOX_FID(IPI_MAILBOX_STATUS_ENQUIRY): +case IPI_MAILBOX_FID(IPI_MAILBOX_NOTIFY): +case IPI_MAILBOX_FID(IPI_MAILBOX_ACK): +case IPI_MAILBOX_FID(IPI_MAILBOX_ENABLE_IRQ): +case IPI_MAILBOX_FID(IPI_MAILBOX_DISABLE_IRQ): +if ( !is_hardware_domain(current->domain) ) +{ +gprintk(XENLOG_WARNING, "IPI mailbox: fn=%u No access", pm_fn); +ret = XST_PM_NO_ACCESS; +goto done; +} +goto forward_to_fw; + default: gprintk(XENLOG_WARNING, "zynqmp-pm: Unhandled PM Call: %u\n", fid); return false; diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h index 2fbf150..72aadf7 100644 --- a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h +++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h @@ -99,6 +99,21 @@ enum pm_ret_status { XST_PM_ABORT_SUSPEND, }; +/* IPI SMC function numbers enum definition and fids */ +#define IPI_MAILBOX_FID(fid) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ +ARM_SMCCC_CONV_32, \ +ARM_SMCCC_OWNER_SIP, \ +fid) +enum ipi_api_id { +IPI_MAILBOX_OPEN = 0x1000, +IPI_MAILBOX_RELEASE, +IPI_MAILBOX_STATUS_ENQUIRY, +IPI_MAILBOX_NOTIFY, +IPI_MAILBOX_ACK, +IPI_MAILBOX_ENABLE_IRQ, +IPI_MAILBOX_DISABLE_IRQ, +}; + extern bool zynqmp_eemi(struct cpu_user_regs *regs); #endif /* __ASM_ARM_PLATFORMS_ZYNQMP_H */ -- 1.9.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v8 2/6] xen/arm: zynqmp: Forward plaform specific firmware calls
From: "Edgar E. Iglesias" Introduce zynqmp_eemi: a function responsible for implementing access controls over the firmware calls. Only calls that are allowed are forwarded to the firmware. Signed-off-by: Edgar E. Iglesias Signed-off-by: Stefano Stabellini Acked-by: Julien Grall --- Changes in v8: - code style Changes in v7: - print a warning once if not smccc 1.1 Changes in v6: - remove is_domain_64 check - add check for smccc 1.1 - code style Changes in v4: - fix typo - add header guard - add emacs magic - remove #includes that will only be used later - add copyright notice to header - remove SMCCC 1.1 check --- xen/arch/arm/platforms/Makefile| 1 + xen/arch/arm/platforms/xilinx-zynqmp-eemi.c| 34 ++ xen/arch/arm/platforms/xilinx-zynqmp.c | 24 +++ xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h | 30 +++ 4 files changed, 89 insertions(+) create mode 100644 xen/arch/arm/platforms/xilinx-zynqmp-eemi.c create mode 100644 xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h diff --git a/xen/arch/arm/platforms/Makefile b/xen/arch/arm/platforms/Makefile index bd724a1..01608f8 100644 --- a/xen/arch/arm/platforms/Makefile +++ b/xen/arch/arm/platforms/Makefile @@ -9,3 +9,4 @@ obj-$(CONFIG_ALL_PLAT) += sunxi.o obj-$(CONFIG_ALL64_PLAT) += thunderx.o obj-$(CONFIG_ALL64_PLAT) += xgene-storm.o obj-$(CONFIG_MPSOC_PLATFORM) += xilinx-zynqmp.o +obj-$(CONFIG_MPSOC_PLATFORM) += xilinx-zynqmp-eemi.o diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c new file mode 100644 index 000..369bb3f --- /dev/null +++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c @@ -0,0 +1,34 @@ +/* + * xen/arch/arm/platforms/xilinx-zynqmp-eemi.c + * + * Xilinx ZynqMP EEMI API + * + * Copyright (c) 2018 Xilinx Inc. + * Written by Edgar E. Iglesias + * + * This program is free software; you can redistribute it and/or + * modify it under the terms and conditions of the GNU General Public + * License, version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include + +bool zynqmp_eemi(struct cpu_user_regs *regs) +{ +return false; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/arm/platforms/xilinx-zynqmp.c b/xen/arch/arm/platforms/xilinx-zynqmp.c index d8ceded..67a08ac 100644 --- a/xen/arch/arm/platforms/xilinx-zynqmp.c +++ b/xen/arch/arm/platforms/xilinx-zynqmp.c @@ -18,6 +18,8 @@ */ #include +#include +#include static const char * const zynqmp_dt_compat[] __initconst = { @@ -32,8 +34,30 @@ static const struct dt_device_match zynqmp_blacklist_dev[] __initconst = { /* sentinel */ }, }; +static bool zynqmp_smc(struct cpu_user_regs *regs) +{ +/* + * ZynqMP firmware is based on SMCCC 1.1. If SMCCC 1.1 is not + * available something is wrong, don't try to handle it. + */ +if ( !cpus_have_const_cap(ARM_SMCCC_1_1) ) +{ +static bool once = true; + +if ( once ) +{ +printk(XENLOG_WARNING "ZynqMP firmware Error: no SMCCC 1.1 " + "support. Disabling firmware calls."); +once = false; +} +return false; +} +return zynqmp_eemi(regs); +} + PLATFORM_START(xilinx_zynqmp, "Xilinx ZynqMP") .compatible = zynqmp_dt_compat, +.smc = zynqmp_smc, .blacklist_dev = zynqmp_blacklist_dev, PLATFORM_END diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h new file mode 100644 index 000..43cefb5 --- /dev/null +++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2018 Xilinx Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms and conditions of the GNU General Public + * License, version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#ifndef __ASM_ARM_PLATFORMS_ZYNQMP_H +#define __ASM_ASM_PLATFORMS_ZYNQMP_H + +#include + +extern bool zynqmp_eemi(struct cpu_user_regs *regs); + +#endif /* __ASM_ARM_PLATFORMS_ZYNQMP_H */ + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * indent-tabs-mode: nil + * End: + */ -- 1.9.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.
[Xen-devel] [PATCH v8 4/6] xen/arm: zynqmp: implement zynqmp_eemi
From: "Edgar E. Iglesias" zynqmp_eemi uses the defined functions and structs to decide whether to make a call to the firmware, or to simply return a predefined value. Signed-off-by: Edgar E. Iglesias Signed-off-by: Stefano Stabellini --- Changes in v8: - remove redundant ZYNQMP_SIP_SVC_* cases Changes in v7: - add in-code comment - remove tabs - use EEMI_FID Changes in v6: - mmio_access removal moved to previous patch - forward to firmware mandatory smc32 calls - check that the function id belongs to the right range before proceeding - basic is_hardware_domain implementation for domain_has_node_access and domain_has_reset_access Changes in v5: - remove mmio_access handling Changes in v4: - add #include as needed - improve comment - code style --- xen/arch/arm/platforms/xilinx-zynqmp-eemi.c | 168 +++- 1 file changed, 167 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c index 369bb3f..80e990c 100644 --- a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c +++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c @@ -17,11 +17,177 @@ */ #include +#include +#include #include +/* + * EEMI firmware API: + * https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf + * + * Power domain node_ids identify the area of effect of the power + * management operations. They are the first parameter passed to power + * management EEMI calls. + * + * Reset IDs identify the area of effect of a reset operation. They are + * the first parameter passed to reset EEMI calls. + * + * For now, let the hardware domain access to all power domain nodes and + * all reset lines. In the future, we'll check for ownership of + * resources by specific virtual machines. + */ +static inline bool domain_has_node_access(struct domain *d, uint32_t nodeid) +{ +return is_hardware_domain(d); +} + +static inline bool domain_has_reset_access(struct domain *d, uint32_t rst) +{ +return is_hardware_domain(d); +} + bool zynqmp_eemi(struct cpu_user_regs *regs) { -return false; +struct arm_smccc_res res; +uint32_t fid = get_user_reg(regs, 0); +uint32_t nodeid = get_user_reg(regs, 1); +unsigned int pm_fn = fid & 0x; +enum pm_ret_status ret; + +switch ( fid ) +{ +/* Mandatory SMC32 functions. */ +case ARM_SMCCC_CALL_COUNT_FID(SIP): +case ARM_SMCCC_CALL_UID_FID(SIP): +case ARM_SMCCC_REVISION_FID(SIP): +goto forward_to_fw; +/* + * We can't allow CPUs to suspend without Xen knowing about it. + * We accept but ignore the request and wait for the guest to issue + * a WFI or PSCI call which Xen will trap and act accordingly upon. + */ +case EEMI_FID(PM_SELF_SUSPEND): +ret = XST_PM_SUCCESS; +goto done; + +case EEMI_FID(PM_GET_NODE_STATUS): +/* API for PUs. */ +case EEMI_FID(PM_REQ_SUSPEND): +case EEMI_FID(PM_FORCE_POWERDOWN): +case EEMI_FID(PM_ABORT_SUSPEND): +case EEMI_FID(PM_REQ_WAKEUP): +case EEMI_FID(PM_SET_WAKEUP_SOURCE): +/* API for slaves. */ +case EEMI_FID(PM_REQ_NODE): +case EEMI_FID(PM_RELEASE_NODE): +case EEMI_FID(PM_SET_REQUIREMENT): +case EEMI_FID(PM_SET_MAX_LATENCY): +if ( !domain_has_node_access(current->domain, nodeid) ) +{ +gprintk(XENLOG_WARNING, +"zynqmp-pm: fn=%u No access to node %u\n", pm_fn, nodeid); +ret = XST_PM_NO_ACCESS; +goto done; +} +goto forward_to_fw; + +case EEMI_FID(PM_RESET_ASSERT): +case EEMI_FID(PM_RESET_GET_STATUS): +if ( !domain_has_reset_access(current->domain, nodeid) ) +{ +gprintk(XENLOG_WARNING, +"zynqmp-pm: fn=%u No access to reset %u\n", pm_fn, nodeid); +ret = XST_PM_NO_ACCESS; +goto done; +} +goto forward_to_fw; + +/* These calls are safe and always allowed. */ +case EEMI_FID(PM_GET_TRUSTZONE_VERSION): +case EEMI_FID(PM_GET_API_VERSION): +case EEMI_FID(PM_GET_CHIPID): +goto forward_to_fw; + +/* No MMIO access is allowed from non-secure domains */ +case EEMI_FID(PM_MMIO_WRITE): +case EEMI_FID(PM_MMIO_READ): +gprintk(XENLOG_WARNING, +"zynqmp-pm: fn=%u No MMIO access to %u\n", pm_fn, nodeid); +ret = XST_PM_NO_ACCESS; +goto done; + +/* Exclusive to the hardware domain. */ +case EEMI_FID(PM_INIT): +case EEMI_FID(PM_SET_CONFIGURATION): +case EEMI_FID(PM_FPGA_LOAD): +case EEMI_FID(PM_FPGA_GET_STATUS): +case EEMI_FID(PM_SECURE_SHA): +case EEMI_FID(PM_SECURE_RSA): +case EEMI_FID(PM_PINCTRL_SET_FUNCTION): +case EEMI_FID(PM_PINCTRL_REQUEST): +case EEMI_FID(PM_PINCTRL_RELEASE): +case EEMI_FID(PM_PINCTRL_GET_FUNCTION): +case EEMI_FID(PM_PINCTRL_CONFIG_PARAM_GET): +case EEMI_FID(PM_PINCTRL_CONFIG_PARAM_SET): +case EEMI_FID(PM_I
[Xen-devel] [PATCH v8 3/6] xen/arm: zynqmp: introduce zynqmp specific defines
From: "Edgar E. Iglesias" Introduce zynqmp specific defines for the firmware calls. See EEMI: https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf The error codes are described, under XIlPM Error Codes: https://www.xilinx.com/support/documentation/user_guides/ug1137-zynq-ultrascale-mpsoc-swdev.pdf - pm_api_id These are the EEMI function IDs. Unavoidable. - pm_ret_status These are the EEMI return statuses. Unavoidable. Signed-off-by: Edgar E. Iglesias Signed-off-by: Stefano Stabellini --- Changes in v8: - move PM_GET_TRUSTZONE_VERSION to enum - remove redundant ZYNQMP_SIP_SVC_* definitions Changes in v7: - introduce EEMI_FID - remove tabs Changes in v6: - improve commit message - remove MM_*, node ids and reset ids Changes in v5: - remove MMIO access related definitions Changes in v4: - define PM_MMIO_SHIFT --- xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h | 83 ++ 1 file changed, 83 insertions(+) diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h index 43cefb5..2fbf150 100644 --- a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h +++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h @@ -15,6 +15,89 @@ #define __ASM_ASM_PLATFORMS_ZYNQMP_H #include +#include + +#define EEMI_FID(fid) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_CONV_64, \ + ARM_SMCCC_OWNER_SIP, \ + fid) + +enum pm_api_id { +/* Miscellaneous API functions: */ +PM_GET_API_VERSION = 1, /* Do not change or move */ +PM_SET_CONFIGURATION, +PM_GET_NODE_STATUS, +PM_GET_OP_CHARACTERISTIC, +PM_REGISTER_NOTIFIER, +/* API for suspending of PUs: */ +PM_REQ_SUSPEND, +PM_SELF_SUSPEND, +PM_FORCE_POWERDOWN, +PM_ABORT_SUSPEND, +PM_REQ_WAKEUP, +PM_SET_WAKEUP_SOURCE, +PM_SYSTEM_SHUTDOWN, +/* API for managing PM slaves: */ +PM_REQ_NODE, +PM_RELEASE_NODE, +PM_SET_REQUIREMENT, +PM_SET_MAX_LATENCY, +/* Direct control API functions: */ +PM_RESET_ASSERT, +PM_RESET_GET_STATUS, +PM_MMIO_WRITE, +PM_MMIO_READ, +PM_INIT, +PM_FPGA_LOAD, +PM_FPGA_GET_STATUS, +PM_GET_CHIPID, +/* ID 25 is been used by U-boot to process secure boot images */ +/* Secure library generic API functions */ +PM_SECURE_SHA = 26, +PM_SECURE_RSA, +/* Pin control API functions */ +PM_PINCTRL_REQUEST, +PM_PINCTRL_RELEASE, +PM_PINCTRL_GET_FUNCTION, +PM_PINCTRL_SET_FUNCTION, +PM_PINCTRL_CONFIG_PARAM_GET, +PM_PINCTRL_CONFIG_PARAM_SET, +/* PM IOCTL API */ +PM_IOCTL, +/* API to query information from firmware */ +PM_QUERY_DATA, +/* Clock control API functions */ +PM_CLOCK_ENABLE, +PM_CLOCK_DISABLE, +PM_CLOCK_GETSTATE, +PM_CLOCK_SETDIVIDER, +PM_CLOCK_GETDIVIDER, +PM_CLOCK_SETRATE, +PM_CLOCK_GETRATE, +PM_CLOCK_SETPARENT, +PM_CLOCK_GETPARENT, +PM_GET_TRUSTZONE_VERSION = 2563, +PM_API_MAX +}; + +/** + * @XST_PM_SUCCESS:Success + * @XST_PM_INTERNAL: Unexpected error + * @XST_PM_CONFLICT: Conflicting requirements + * @XST_PM_NO_ACCESS: Access rights violation + * @XST_PM_INVALID_NODE: Does not apply to node passed as argument + * @XST_PM_DOUBLE_REQ: Duplicate request + * @XST_PM_ABORT_SUSPEND: Target has aborted suspend + */ +enum pm_ret_status { +XST_PM_SUCCESS = 0, +XST_PM_INTERNAL = 2000, +XST_PM_CONFLICT, +XST_PM_NO_ACCESS, +XST_PM_INVALID_NODE, +XST_PM_DOUBLE_REQ, +XST_PM_ABORT_SUSPEND, +}; extern bool zynqmp_eemi(struct cpu_user_regs *regs); -- 1.9.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [qemu-mainline test] 131399: tolerable FAIL - PUSHED
flight 131399 qemu-mainline real [real] http://logs.test-lab.xenproject.org/osstest/logs/131399/ Failures :-/ but no regressions. Tests which did not succeed, but are not blocking: test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stopfail like 131358 test-armhf-armhf-libvirt 14 saverestore-support-checkfail like 131358 test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail like 131358 test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stopfail like 131358 test-armhf-armhf-libvirt-raw 13 saverestore-support-checkfail like 131358 test-amd64-i386-xl-pvshim12 guest-start fail never pass test-amd64-i386-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-i386-libvirt 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2 fail never pass test-amd64-amd64-libvirt-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass test-armhf-armhf-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-xl-cubietruck 13 migrate-support-checkfail never pass test-armhf-armhf-xl-cubietruck 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-credit1 13 migrate-support-checkfail never pass test-armhf-armhf-xl-credit1 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-rtds 13 migrate-support-checkfail never pass test-armhf-armhf-xl-rtds 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-credit2 13 migrate-support-checkfail never pass test-armhf-armhf-xl-credit2 14 saverestore-support-checkfail never pass test-armhf-armhf-libvirt-raw 12 migrate-support-checkfail never pass test-armhf-armhf-xl-multivcpu 13 migrate-support-checkfail never pass test-armhf-armhf-xl-multivcpu 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-arndale 13 migrate-support-checkfail never pass test-armhf-armhf-xl-arndale 14 saverestore-support-checkfail never pass test-amd64-i386-xl-qemuu-ws16-amd64 17 guest-stop fail never pass test-armhf-armhf-xl-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-xl-vhd 13 saverestore-support-checkfail never pass test-amd64-amd64-xl-qemuu-win10-i386 10 windows-installfail never pass test-amd64-i386-xl-qemuu-win10-i386 10 windows-install fail never pass version targeted for testing: qemuu139108f68486550869bd201f903f1884b78a4ae1 baseline version: qemuu3866e6bebd0cd498e684f1d3ab10b64c853d186f Last test of basis 131358 2018-12-16 14:17:29 Z2 days Testing same since 131399 2018-12-17 16:40:33 Z1 days1 attempts People who touched revisions under test: Alberto Garcia Alex Bennée Christian Borntraeger David Gibson Eduardo Habkost Julio Faracco Kevin Wolf Michael S. Tsirkin Peter Maydell Philippe Mathieu-Daudé Stefan Hajnoczi Thomas Huth Vladimir Sementsov-Ogievskiy jobs: build-amd64-xsm pass build-i386-xsm pass build-amd64 pass build-armhf pass build-i386 pass build-amd64-libvirt pass build-armhf-libvirt pass build-i386-libvirt pass build-amd64-pvopspass build-armhf-pvopspass build-i386-pvops pass test-amd64-amd64-xl pass test-armhf-armhf-xl pass test-amd64-i386-xl pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsmpass test-amd64-amd64-xl-qemuu-debianhvm-amd64-xsmpass test-amd64-i386-xl-qemuu-debianhvm-amd64-xsm pass test-amd64-amd64-libvirt-xsm
[Xen-devel] [xen-unstable-smoke test] 131434: tolerable all pass - PUSHED
flight 131434 xen-unstable-smoke real [real] http://logs.test-lab.xenproject.org/osstest/logs/131434/ Failures :-/ but no regressions. Tests which did not succeed, but are not blocking: test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass version targeted for testing: xen 221c2fc433904937966e40c6a2538650253b7204 baseline version: xen 57f78a734bcabeab75ca21d4e871be78a3463fbe Last test of basis 131431 2018-12-18 17:00:26 Z0 days Testing same since 131434 2018-12-18 21:00:52 Z0 days1 attempts People who touched revisions under test: Andrew Cooper Brian Woods Ian Jackson Jan Beulich Julien Grall jobs: build-amd64 pass build-armhf pass build-amd64-libvirt pass test-armhf-armhf-xl pass test-amd64-amd64-xl-qemuu-debianhvm-i386 pass test-amd64-amd64-libvirt pass sg-report-flight on osstest.test-lab.xenproject.org logs: /home/logs/logs images: /home/logs/images Logs, config files, etc. are available at http://logs.test-lab.xenproject.org/osstest/logs Explanation of these reports, and of osstest in general, is at http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master Test harness code can be found at http://xenbits.xen.org/gitweb?p=osstest.git;a=summary Pushing revision : To xenbits.xen.org:/home/xen/git/xen.git 57f78a734b..221c2fc433 221c2fc433904937966e40c6a2538650253b7204 -> smoke ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH for-4.12 v3] xen/arm: Stop relocating Xen
On Tue, 18 Dec 2018, Stefano Stabellini wrote: > On Tue, 18 Dec 2018, Julien Grall wrote: > > At the moment, Xen is relocated towards the end of the memory. While > > this has the advantage to free space in low memory, the code is not > > compliant with the break-before-make because it requires to switch > > between two sets of page-table. This is not entirely trivial to fix as > > it would require us to go through an identity mapping and disabling MMU. > > > > Furthermore, it looks like that some platform (such as the Hikey960) > > may not be able to bring-up secondary CPUs if the entry is too high. > > > > While Xen should be quite tiny (< 2MB), the current algorigthm to > > allocate Dom0 memory will allocate memory chunk of at least 128MB. > > Those memory chunks will always be 128MB. This means that depending on > > where the modules are loaded, an extra 128MB may disappear. > > > > As there are up to 4 modules (initramfs, XSM, kernel, DTB) loaded in > > low memory. The problem is not entirely new as you could already waste > > 512MB of low-memory. The right solution would be to fix the allocation > > algorightm. But this is independent from this patch. > > > > For user in control of the memory (such as in U-boot), all modules > > should be loaded as much as possible together or outside low-memory (i.e > > above 4GB). For other users (i.e Grub/UEFI), I believe the bootloader is > > already keeping everything together. > > > > Based on the above, it would be fine to stop relocating Xen. This has > > the advantage to simplify the code and should speed-up the boot as > > relocation is not necessary anymore. > > > > Note that the break-before-make issue is not fixed by this patch. > > > > Signed-off-by: Julien Grall > > Reported-by: Matthew Daley > > Tested-by: Matthew Daley > > Reviewed and committed I forgot to add that I fixed a couple of grammar errors in the commit message as I committed. > > --- > > Changes in v3: > > - Update the commit message > > > > Changes in v2: > > - Add Matthew's tested-by > > --- > > xen/arch/arm/arm32/head.S | 54 +++ > > xen/arch/arm/arm64/head.S | 50 +--- > > xen/arch/arm/mm.c | 18 +++-- > > xen/arch/arm/setup.c | 65 > > +++ > > xen/include/asm-arm/mm.h | 2 +- > > 5 files changed, 17 insertions(+), 172 deletions(-) > > > > diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S > > index 93b51e9ef2..390a505e05 100644 > > --- a/xen/arch/arm/arm32/head.S > > +++ b/xen/arch/arm/arm32/head.S > > @@ -469,58 +469,12 @@ fail: PRINT("- Boot failed -\r\n") > > GLOBAL(_end_boot) > > > > /* > > - * Copy Xen to new location and switch TTBR > > + * Switch TTBR > > * r1:r0 ttbr > > - * r2 source address > > - * r3 destination address > > - * [sp]=>r4length > > * > > - * Source and destination must be word aligned, length is rounded up > > - * to a 16 byte boundary. > > - * > > - * MUST BE VERY CAREFUL when saving things to RAM over the copy > > + * TODO: This code does not comply with break-before-make. > > */ > > -ENTRY(relocate_xen) > > -push {r4,r5,r6,r7,r8,r9,r10,r11} > > - > > -ldr r4, [sp, #8*4]/* Get 4th argument from stack > > */ > > - > > -/* Copy 16 bytes at a time using: > > - * r5: counter > > - * r6: data > > - * r7: data > > - * r8: data > > - * r9: data > > - * r10: source > > - * r11: destination > > - */ > > -mov r5, r4 > > -mov r10, r2 > > -mov r11, r3 > > -1: ldmia r10!, {r6, r7, r8, r9} > > -stmia r11!, {r6, r7, r8, r9} > > - > > -subs r5, r5, #16 > > -bgt 1b > > - > > -/* Flush destination from dcache using: > > - * r5: counter > > - * r6: step > > - * r7: vaddr > > - */ > > -dsb/* So the CPU issues all writes to the range */ > > - > > -mov r5, r4 > > -ldr r6, =dcache_line_bytes /* r6 := step */ > > -ldr r6, [r6] > > -mov r7, r3 > > - > > -1: mcr CP32(r7, DCCMVAC) > > - > > -add r7, r7, r6 > > -subs r5, r5, r6 > > -bgt 1b > > - > > +ENTRY(switch_ttbr) > > dsb/* Ensure the flushes happen before > > * continuing */ > > isb/* Ensure synchronization with > > previous > > @@ -543,8 +497,6 @@ ENTRY(relocate_xen) > > dsb/* Ensure completion of TLB+BP > > flush */ > > isb > > > > -pop {r4, r5,r6,r7,r8,r9,r10,r11} > > - > > mov pc, lr > > > > #ifdef CONFIG_EARLY_PRINTK > > diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S > > index ef87b5c254..0b7
Re: [Xen-devel] [PATCH for-4.12 v3] xen/arm: Stop relocating Xen
On Tue, 18 Dec 2018, Julien Grall wrote: > At the moment, Xen is relocated towards the end of the memory. While > this has the advantage to free space in low memory, the code is not > compliant with the break-before-make because it requires to switch > between two sets of page-table. This is not entirely trivial to fix as > it would require us to go through an identity mapping and disabling MMU. > > Furthermore, it looks like that some platform (such as the Hikey960) > may not be able to bring-up secondary CPUs if the entry is too high. > > While Xen should be quite tiny (< 2MB), the current algorigthm to > allocate Dom0 memory will allocate memory chunk of at least 128MB. > Those memory chunks will always be 128MB. This means that depending on > where the modules are loaded, an extra 128MB may disappear. > > As there are up to 4 modules (initramfs, XSM, kernel, DTB) loaded in > low memory. The problem is not entirely new as you could already waste > 512MB of low-memory. The right solution would be to fix the allocation > algorightm. But this is independent from this patch. > > For user in control of the memory (such as in U-boot), all modules > should be loaded as much as possible together or outside low-memory (i.e > above 4GB). For other users (i.e Grub/UEFI), I believe the bootloader is > already keeping everything together. > > Based on the above, it would be fine to stop relocating Xen. This has > the advantage to simplify the code and should speed-up the boot as > relocation is not necessary anymore. > > Note that the break-before-make issue is not fixed by this patch. > > Signed-off-by: Julien Grall > Reported-by: Matthew Daley > Tested-by: Matthew Daley Reviewed and committed > --- > Changes in v3: > - Update the commit message > > Changes in v2: > - Add Matthew's tested-by > --- > xen/arch/arm/arm32/head.S | 54 +++ > xen/arch/arm/arm64/head.S | 50 +--- > xen/arch/arm/mm.c | 18 +++-- > xen/arch/arm/setup.c | 65 > +++ > xen/include/asm-arm/mm.h | 2 +- > 5 files changed, 17 insertions(+), 172 deletions(-) > > diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S > index 93b51e9ef2..390a505e05 100644 > --- a/xen/arch/arm/arm32/head.S > +++ b/xen/arch/arm/arm32/head.S > @@ -469,58 +469,12 @@ fail: PRINT("- Boot failed -\r\n") > GLOBAL(_end_boot) > > /* > - * Copy Xen to new location and switch TTBR > + * Switch TTBR > * r1:r0 ttbr > - * r2 source address > - * r3 destination address > - * [sp]=>r4length > * > - * Source and destination must be word aligned, length is rounded up > - * to a 16 byte boundary. > - * > - * MUST BE VERY CAREFUL when saving things to RAM over the copy > + * TODO: This code does not comply with break-before-make. > */ > -ENTRY(relocate_xen) > -push {r4,r5,r6,r7,r8,r9,r10,r11} > - > -ldr r4, [sp, #8*4]/* Get 4th argument from stack */ > - > -/* Copy 16 bytes at a time using: > - * r5: counter > - * r6: data > - * r7: data > - * r8: data > - * r9: data > - * r10: source > - * r11: destination > - */ > -mov r5, r4 > -mov r10, r2 > -mov r11, r3 > -1: ldmia r10!, {r6, r7, r8, r9} > -stmia r11!, {r6, r7, r8, r9} > - > -subs r5, r5, #16 > -bgt 1b > - > -/* Flush destination from dcache using: > - * r5: counter > - * r6: step > - * r7: vaddr > - */ > -dsb/* So the CPU issues all writes to the range */ > - > -mov r5, r4 > -ldr r6, =dcache_line_bytes /* r6 := step */ > -ldr r6, [r6] > -mov r7, r3 > - > -1: mcr CP32(r7, DCCMVAC) > - > -add r7, r7, r6 > -subs r5, r5, r6 > -bgt 1b > - > +ENTRY(switch_ttbr) > dsb/* Ensure the flushes happen before > * continuing */ > isb/* Ensure synchronization with > previous > @@ -543,8 +497,6 @@ ENTRY(relocate_xen) > dsb/* Ensure completion of TLB+BP flush > */ > isb > > -pop {r4, r5,r6,r7,r8,r9,r10,r11} > - > mov pc, lr > > #ifdef CONFIG_EARLY_PRINTK > diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S > index ef87b5c254..0b7f6e7f92 100644 > --- a/xen/arch/arm/arm64/head.S > +++ b/xen/arch/arm/arm64/head.S > @@ -609,52 +609,14 @@ fail: PRINT("- Boot failed -\r\n") > > GLOBAL(_end_boot) > > -/* Copy Xen to new location and switch TTBR > - * x0ttbr > - * x1source address > - * x2destination address > - * x3length > +/* > + * Switch TTBR > * > - * Source and destination must be word aligned, length is ro
[Xen-devel] Xen 4.11.1 panic
Hello, I tried updating my NetBSD dom0 to 4.11.1 (from 4.11.0 with security patches), and on a 32bits PV domU shutdown I get (100% reproductible): (XEN) Assertion 'preemptible' failed at mm.c:2493 (XEN) [ Xen-4.11.1nb0 x86_64 debug=y Tainted: C ] (XEN) CPU:1 (XEN) RIP:e008:[] free_page_type+0x232/0x790 (XEN) RFLAGS: 00010246 CONTEXT: hypervisor (d0v0) (XEN) rax: 4000 rbx: 4401 rcx: 4000 (XEN) rdx: 8300 rsi: 4401 rdi: 82e004215260 (XEN) rbp: 82e004215260 rsp: 83023704fab8 r8: (XEN) r9: r10: 82e0 r11: 82e004226000 (XEN) r12: r13: 8302135d9000 r14: 10ff (XEN) r15: 1000 cr0: 8005003b cr4: 2660 (XEN) cr3: 00022f0f6000 cr2: 7f7ff60ce7a0 (XEN) fsb: 7f7ff7ff36c0 gsb: 80ca42c0 gss: (XEN) ds: 003f es: 003f fs: gs: ss: e010 cs: e008 (XEN) Xen code around (free_page_type+0x232/0x790): (XEN) 05 00 00 45 85 e4 75 02 <0f> 0b 8b 45 18 85 c0 74 18 89 c0 48 c1 e0 0c 49 (XEN) Xen stack trace from rsp=83023704fab8: (XEN)83023704fe38 00ec 4401 82e004215260 (XEN)82e004215240 00ff 10ff 1000 (XEN)82d08028b83d 00ff8300bedfc000 83023704 82d0 (XEN)82e004215260 82e004215240 8302135d9000 00210a92 (XEN)820040019000 0200 82d08028bedf 01ff (XEN)82e004215240 82d08028b25e 8302 83023704 (XEN)4401 82e004215240 82e004206c60 00ff (XEN)10ff 1000 82d08028b83d 0102 (XEN)83023704 83020001 82e004215240 82e004206c60 (XEN) 820040015010 820040015000 (XEN)82d08028af30 0002 82e004206c60 (XEN)820040015010 82d08028b3d1 00210363 8302135d9000 (XEN)6401 82e004206c60 00ff (XEN)10ff 1000 82d08028b83d 01ff82d08022697f (XEN)83023704 83020001 82e004206c60 83023704fd10 (XEN)8302135d9028 8302135d9000 8302135d9020 82e004206c70 (XEN)82d08028bf1f 82d080274e6b 83023701ec00 e401 (XEN)83023704 8000 8302135d9000 (XEN)8302135d9018 deadbeefdeadf00d 0001 7f7ff7b32004 (XEN)82d080278f83 8302135d9000 7f7ff7b32004 82d080208b2d (XEN) Xen call trace: (XEN)[] free_page_type+0x232/0x790 (XEN)[] mm.c#_put_page_type+0x14d/0x380 (XEN)[] mm.c#put_page_from_l2e+0xdf/0x110 (XEN)[] free_page_type+0x2fe/0x790 (XEN)[] mm.c#_put_page_type+0x14d/0x380 (XEN)[] mm.c#put_page_from_l3e+0x1a0/0x1d0 (XEN)[] free_page_type+0x471/0x790 (XEN)[] mm.c#_put_page_type+0x14d/0x380 (XEN)[] put_page_type_preemptible+0xf/0x10 (XEN)[] domain.c#relinquish_memory+0xab/0x460 (XEN)[] domain_relinquish_resources+0x203/0x290 (XEN)[] domain_kill+0xbd/0x150 (XEN)[] do_domctl+0x7d3/0x1a90 (XEN)[] do_physdev_op_compat+0/0x70 (XEN)[] do_domctl+0/0x1a90 (XEN)[] pv_hypercall+0x20b/0x440 (XEN)[] lstar_enter+0xa2/0x120 (XEN)[] lstar_enter+0xae/0x120 (XEN)[] lstar_enter+0xa2/0x120 (XEN)[] lstar_enter+0xae/0x120 (XEN)[] lstar_enter+0xa2/0x120 (XEN)[] lstar_enter+0xae/0x120 (XEN)[] lstar_enter+0x110/0x120 (XEN) (XEN) (XEN) (XEN) Panic on CPU 1: (XEN) Assertion 'preemptible' failed at mm.c:2493 (XEN) (XEN) (XEN) Reboot in five seconds... -- Manuel Bouyer NetBSD: 26 ans d'experience feront toujours la difference -- ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v7 4/6] xen/arm: zynqmp: implement zynqmp_eemi
On Tue, 18 Dec 2018, Julien Grall wrote: > Hi, > > On 12/17/18 10:10 PM, Stefano Stabellini wrote: > > +/* These calls are safe and always allowed. */ > > +case EEMI_FID(ZYNQMP_SIP_SVC_CALL_COUNT): > > +case EEMI_FID(ZYNQMP_SIP_SVC_UID): > > +case EEMI_FID(ZYNQMP_SIP_SVC_VERSION): > > +case EEMI_FID(PM_GET_TRUSTZONE_VERSION): > > +case EEMI_FID(PM_GET_API_VERSION): > > Above you say the call to PM_GET_API_VERSION are safe and always allowed. But > looking at the ATF implementation the first call to PM_GET_API_VERSION will > enable IPI IRQ. > > AFAICT, Dom0 will be the only domain to access IPI. So what happen if, in the > Dom0less case, the guest is booting before and calling PM_GET_API_VERSION? > > I haven't looked in depth the other SIP functions to see whether there are > other potential issue. On Xilinx MPSoC, the power management handler runs on a separate processor (a Microblaze processor). Xilinx calls it "PMU". The IPI IRQ enabled by ATF is for it to communicate with the PMU, it should not be exposed to virtual machines. Nothing to do on our side here. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v7 4/6] xen/arm: zynqmp: implement zynqmp_eemi
On Tue, 18 Dec 2018, Julien Grall wrote: > Hi Stefano, > > On 12/17/18 10:10 PM, Stefano Stabellini wrote: > > +/* These calls are safe and always allowed. */ > > +case EEMI_FID(ZYNQMP_SIP_SVC_CALL_COUNT): > > +case EEMI_FID(ZYNQMP_SIP_SVC_UID): > > +case EEMI_FID(ZYNQMP_SIP_SVC_VERSION): > > I am a bit surprised that you implement those one using SMC64. Why would you > duplicate the SMC32 version (ARM_SMCCC_CALL_COUNT_FID(SIP))? This is a mistake introduced in the last couple of versions, good catch. ZYNQMP_SIP_SVC_* were preexisting, they go back to the initial implementation by Edgar. The way the code was written before, it didn't matter if the call was SMC32 or SMC64. Now that we match on the full FID, and that we have the right SMC32 calls handled, I'll remove these 3 cases completely. > I also don't seem to find them neither in the spec nor in the ATF code. Yes, I raised the issue internally. In any case, I think it makes sense to handle the mandatory calls in Xen by forwarding them to firmware. > The rest of the code looks good to me. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v7 3/6] xen/arm: zynqmp: introduce zynqmp specific defines
On Tue, 18 Dec 2018, Julien Grall wrote: > Hi Stefano, > > On 12/17/18 10:10 PM, Stefano Stabellini wrote: > > From: "Edgar E. Iglesias" > > > > From: Edgar E. Iglesias > > > > Introduce zynqmp specific defines for the firmware calls. > > See EEMI: > > https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf > > > > The error codes are described, under XIlPM Error Codes: > > https://www.xilinx.com/support/documentation/user_guides/ug1137-zynq-ultrascale-mpsoc-swdev.pdf > > > > - pm_api_id > > These are the EEMI function IDs. Unavoidable. > > > > - pm_ret_status > > These are the EEMI return statuses. Unavoidable. > > > > Signed-off-by: Edgar E. Iglesias > > Signed-off-by: Stefano Stabellini > > > > --- > > > > Changes in v7: > > - introduce EEMI_FID > > - remove tabs > > > > Changes in v6: > > - improve commit message > > - remove MM_*, node ids and reset ids > > > > Changes in v5: > > - remove MMIO access related definitions > > > > Changes in v4: > > - define PM_MMIO_SHIFT > > --- > > xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h | 90 > > ++ > > 1 file changed, 90 insertions(+) > > > > diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h > > b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h > > index 43cefb5..9779b6a 100644 > > --- a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h > > +++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h > > @@ -15,6 +15,96 @@ > > #define __ASM_ASM_PLATFORMS_ZYNQMP_H > > #include > > +#include > > + > > +/* Service calls. */ > > +#define PM_GET_TRUSTZONE_VERSION 0xa03 > > Why does not this belong to the pm_api_id below? You are right, I'll move it below into the enum. > > + > > +/* SMC function IDs for SiP Service queries */ > > +#define ZYNQMP_SIP_SVC_CALL_COUNT 0xff00 > > +#define ZYNQMP_SIP_SVC_UID 0xff01 > > +#define ZYNQMP_SIP_SVC_VERSION 0xff03 > + > > +#define EEMI_FID(fid) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ > > + ARM_SMCCC_CONV_64, \ > > + ARM_SMCCC_OWNER_SIP, \ > > + fid) > > + > > +enum pm_api_id { > > +/* Miscellaneous API functions: */ > > +PM_GET_API_VERSION = 1, /* Do not change or move */ > > +PM_SET_CONFIGURATION, > > +PM_GET_NODE_STATUS, > > +PM_GET_OP_CHARACTERISTIC, > > +PM_REGISTER_NOTIFIER, > > +/* API for suspending of PUs: */ > > +PM_REQ_SUSPEND, > > +PM_SELF_SUSPEND, > > +PM_FORCE_POWERDOWN, > > +PM_ABORT_SUSPEND, > > +PM_REQ_WAKEUP, > > +PM_SET_WAKEUP_SOURCE, > > +PM_SYSTEM_SHUTDOWN, > > +/* API for managing PM slaves: */ > > +PM_REQ_NODE, > > +PM_RELEASE_NODE, > > +PM_SET_REQUIREMENT, > > +PM_SET_MAX_LATENCY, > > +/* Direct control API functions: */ > > +PM_RESET_ASSERT, > > +PM_RESET_GET_STATUS, > > +PM_MMIO_WRITE, > > +PM_MMIO_READ, > > +PM_INIT, > > +PM_FPGA_LOAD, > > +PM_FPGA_GET_STATUS, > > +PM_GET_CHIPID, > > +/* ID 25 is been used by U-boot to process secure boot images */ > > +/* Secure library generic API functions */ > > +PM_SECURE_SHA = 26, > > +PM_SECURE_RSA, > > +/* Pin control API functions */ > > +PM_PINCTRL_REQUEST, > > +PM_PINCTRL_RELEASE, > > +PM_PINCTRL_GET_FUNCTION, > > +PM_PINCTRL_SET_FUNCTION, > > +PM_PINCTRL_CONFIG_PARAM_GET, > > +PM_PINCTRL_CONFIG_PARAM_SET, > > +/* PM IOCTL API */ > > +PM_IOCTL, > > +/* API to query information from firmware */ > > +PM_QUERY_DATA, > > +/* Clock control API functions */ > > +PM_CLOCK_ENABLE, > > +PM_CLOCK_DISABLE, > > +PM_CLOCK_GETSTATE, > > +PM_CLOCK_SETDIVIDER, > > +PM_CLOCK_GETDIVIDER, > > +PM_CLOCK_SETRATE, > > +PM_CLOCK_GETRATE, > > +PM_CLOCK_SETPARENT, > > +PM_CLOCK_GETPARENT, > > +PM_API_MAX > > +}; > > + > > +/** > > + * @XST_PM_SUCCESS:Success > > + * @XST_PM_INTERNAL: Unexpected error > > + * @XST_PM_CONFLICT: Conflicting requirements > > + * @XST_PM_NO_ACCESS: Access rights violation > > + * @XST_PM_INVALID_NODE: Does not apply to node passed as argument > > + * @XST_PM_DOUBLE_REQ: Duplicate request > > + * @XST_PM_ABORT_SUSPEND: Target has aborted suspend > > + */ > > +enum pm_ret_status { > > +XST_PM_SUCCESS = 0, > > +XST_PM_INTERNAL = 2000, > > +XST_PM_CONFLICT, > > +XST_PM_NO_ACCESS, > > +XST_PM_INVALID_NODE, > > +XST_PM_DOUBLE_REQ, > > +XST_PM_ABORT_SUSPEND, > > +}; > > extern bool zynqmp_eemi(struct cpu_user_regs *regs); ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH for-4.12 v4 0/4] xen/arm: Implement Set/Way operations
I committed the series On Tue, 18 Dec 2018, Julien Grall wrote: > Hi all, > > This is version 3 of the series to implement set/way. For more details see > patch #3. > > Cheers, > > Julien Grall (4): > xen/arm: vcpreg: Add wrappers to handle co-proc access trapped by > HCR_EL2.TVM > xen/arm: vsysreg: Add wrapper to handle sysreg access trapped by > HCR_EL2.TVM > xen/arm: Implement Set/Way operations > xen/arm: Track page accessed between batch of Set/Way operations > > xen/arch/arm/arm64/vsysreg.c | 75 +++ > xen/arch/arm/domain.c| 14 > xen/arch/arm/p2m.c | 119 +- > xen/arch/arm/traps.c | 25 ++- > xen/arch/arm/vcpreg.c| 171 > +++ > xen/arch/x86/domain.c| 4 + > xen/common/domain.c | 5 +- > xen/include/asm-arm/cpregs.h | 1 + > xen/include/asm-arm/domain.h | 9 +++ > xen/include/asm-arm/p2m.h| 22 ++ > xen/include/xen/domain.h | 2 + > 11 files changed, 443 insertions(+), 4 deletions(-) > > -- > 2.11.0 > ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH for-4.12 v4 3/4] xen/arm: Implement Set/Way operations
On Tue, 18 Dec 2018, Julien Grall wrote: > Set/Way operations are used to perform maintenance on a given cache. > At the moment, Set/Way operations are not trapped and therefore a guest > OS will directly act on the local cache. However, a vCPU may migrate to > another pCPU in the middle of the processor. This will result to have > cache with stale data (Set/Way are not propagated) potentially causing > crash. This may be the cause of heisenbug noticed in Osstest [1]. > > Furthermore, Set/Way operations are not available on system cache. This > means that OS, such as Linux 32-bit, relying on those operations to > fully clean the cache before disabling MMU may break because data may > sits in system caches and not in RAM. > > For more details about Set/Way, see the talk "The Art of Virtualizing > Cache Maintenance" given at Xen Summit 2018 [2]. > > In the context of Xen, we need to trap Set/Way operations and emulate > them. From the Arm Arm (B1.14.4 in DDI 046C.c), Set/Way operations are > difficult to virtualized. So we can assume that a guest OS using them will > suffer the consequence (i.e slowness) until developer removes all the usage > of Set/Way. > > As the software is not allowed to infer the Set/Way to Physical Address > mapping, Xen will need to go through the guest P2M and clean & > invalidate all the entries mapped. > > Because Set/Way happen in batch (a loop on all Set/Way of a cache), Xen > would need to go through the P2M for every instructions. This is quite > expensive and would severely impact the guest OS. The implementation is > re-using the KVM policy to limit the number of flush: > - If we trap a Set/Way operations, we enable VM trapping (i.e > HVC_EL2.TVM) to detect cache being turned on/off, and do a full > clean. > - We clean the caches when turning on and off > - Once the caches are enabled, we stop trapping VM instructions > > [1] https://lists.xenproject.org/archives/html/xen-devel/2017-09/msg03191.html > [2] https://fr.slideshare.net/xen_com_mgr/virtualizing-cache > > Signed-off-by: Julien Grall Reviewed-by: Stefano Stabellini > --- > Changes in v4: > - Fix typoes > - Update comments > - Remove unecessary {} > > Changes in v2: > - Fix emulation for Set/Way cache flush arm64 sysreg > - Add support for preemption > - Check cache status on every VM traps in Arm64 > - Remove spurious change > --- > xen/arch/arm/arm64/vsysreg.c | 17 + > xen/arch/arm/p2m.c | 90 > > xen/arch/arm/traps.c | 25 +++- > xen/arch/arm/vcpreg.c| 22 +++ > xen/include/asm-arm/domain.h | 9 + > xen/include/asm-arm/p2m.h| 20 ++ > 6 files changed, 182 insertions(+), 1 deletion(-) > > diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c > index 16ac9c344a..8a85507d9d 100644 > --- a/xen/arch/arm/arm64/vsysreg.c > +++ b/xen/arch/arm/arm64/vsysreg.c > @@ -34,9 +34,14 @@ > static bool vreg_emulate_##reg(struct cpu_user_regs *regs, \ > uint64_t *r, bool read) \ > { \ > +struct vcpu *v = current; \ > +bool cache_enabled = vcpu_has_cache_enabled(v); \ > +\ > GUEST_BUG_ON(read); \ > WRITE_SYSREG64(*r, reg);\ > \ > +p2m_toggle_cache(v, cache_enabled); \ > +\ > return true;\ > } > > @@ -85,6 +90,18 @@ void do_sysreg(struct cpu_user_regs *regs, > break; > > /* > + * HCR_EL2.TSW > + * > + * ARMv8 (DDI 0487B.b): Table D1-42 > + */ > +case HSR_SYSREG_DCISW: > +case HSR_SYSREG_DCCSW: > +case HSR_SYSREG_DCCISW: > +if ( !hsr.sysreg.read ) > +p2m_set_way_flush(current); > +break; > + > +/* > * HCR_EL2.TVM > * > * ARMv8 (DDI 0487D.a): Table D1-38 > diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c > index ff52cb178f..22bec7390b 100644 > --- a/xen/arch/arm/p2m.c > +++ b/xen/arch/arm/p2m.c > @@ -3,6 +3,7 @@ > #include > #include > #include > +#include > > #include > #include > @@ -1615,6 +1616,95 @@ int p2m_cache_flush_range(struct domain *d, gfn_t > *pstart, gfn_t end) > return rc; > } > > +/* > + * Clean & invalidate RAM associated to the guest vCPU. > + * > + * The function can only work with the current vCPU and should be called > + * with IRQ enabled as the vCPU could get preempted. > + */ > +void p2m_flush_vm(struct
Re: [Xen-devel] [PATCH -next] x86/xen: Fix read buffer overflow
On Tue, Dec 18, 2018 at 12:35:34PM -0500, Boris Ostrovsky wrote: > On 12/18/18 6:28 AM, Andrew Cooper wrote: > > On 18/12/2018 10:42, YueHaibing wrote: > >> On 2018/12/18 16:31, Juergen Gross wrote: > >>> On 18/12/2018 09:19, YueHaibing wrote: > Fix smatch warning: > > arch/x86/xen/enlighten_pv.c:649 get_trap_addr() error: > buffer overflow 'early_idt_handler_array' 32 <= 32 > > Fixes: 42b3a4cb5609 ("x86/xen: Support early interrupts in xen pv > guests") > Signed-off-by: YueHaibing > --- > arch/x86/xen/enlighten_pv.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c > index 2f6787f..81f200d 100644 > --- a/arch/x86/xen/enlighten_pv.c > +++ b/arch/x86/xen/enlighten_pv.c > @@ -646,7 +646,7 @@ static bool __ref get_trap_addr(void **addr, > unsigned int ist) > > if (nr == ARRAY_SIZE(trap_array) && > *addr >= (void *)early_idt_handler_array[0] && > -*addr < (void > *)early_idt_handler_array[NUM_EXCEPTION_VECTORS]) { > +*addr < (void > *)early_idt_handler_array[NUM_EXCEPTION_VECTORS - 1]) { > nr = (*addr - (void *)early_idt_handler_array[0]) / > EARLY_IDT_HANDLER_SIZE; > *addr = (void *)xen_early_idt_handler_array[nr]; > > >>> No, this patch is wrong. > >>> > >>> early_idt_handler_array is a 2-dimensional array: > >>> > >>> const char > >>> early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; > >>> > >>> So above code doesn't do an out of bounds array access, but checks for > >>> *addr being in the array or outside of it (note the "<" used for the > >>> test). > >> Thank you for your explanation. > > This looks like a smatch bug. I'd feed it back upstream. > > +Dan > Yep. Thanks for the bug report. Let me test my fix and push it later this week. Btw, it might help readability slightly if we made it more clear we were doing pointer math: *addr >= (void *)&early_idt_handler_array[0] && *addr < (void *)&early_idt_handler_array[NUM_EXCEPTION_VECTORS]) { nr = (*addr - (void *)&early_idt_handler_array[0]) / Regardless, this is definitely a bug in Smatch and I will push a fix. regards, dan carpenter ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v3 08/11] optee: add support for arbitrary shared memory
From: Volodymyr Babchuk Shared memory is widely used by NW to communicate with TAs in OP-TEE. NW can share part of own memory with TA or OP-TEE core, by registering it OP-TEE, or by providing a temporal reference. Anyways, information about such memory buffers are sent to OP-TEE as a list of pages. This mechanism is described in optee_msg.h. Mediator should step in when NW tries to share memory with OP-TEE for two reasons: 1. Do address translation from IPA to PA. 2. Pin domain pages till they are mapped into OP-TEE or TA address space, so domain can't transfer this pages to other domain or balloon out them. Address translation is done by translate_noncontig(...) function. It allocates new buffer from xenheap and then walks on guest provided list of pages, translates addresses and stores PAs into newly allocated buffer. This buffer will be provided to OP-TEE instead of original buffer from the guest. This buffer will be free at the end of standard call. In the same time this function pins pages and stores them in struct optee_shm_buf object. This object will live all the time, when given SHM buffer is known to OP-TEE. It will be freed after guest unregisters shared buffer. At this time pages will be unpinned. We don't need to do any special reference counting because OP-TEE tracks buffer on its side. So, mediator will unpin pages only when OP-TEE returns successfully from OPTEE_MSG_CMD_UNREGISTER_SHM call. Signed-off-by: Volodymyr Babchuk --- Changes from v2: - Made sure that guest does not tries to register shared buffer with the same cookie twice - Fixed coding style - Use access_guest_memory_by_ipa() instead of direct memory mapping xen/arch/arm/tee/optee.c | 274 +++ 1 file changed, 274 insertions(+) diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c index 771148e940..cfc3b34df7 100644 --- a/xen/arch/arm/tee/optee.c +++ b/xen/arch/arm/tee/optee.c @@ -37,6 +37,10 @@ */ #define MAX_RPC_SHMSMAX_STD_CALLS +/* Maximum total number of pages that guest can share with OP-TEE */ +#define MAX_TOTAL_SMH_BUF_PG16384 +#define MAX_NONCONTIG_ENTRIES 5 + #define OPTEE_KNOWN_NSEC_CAPS OPTEE_SMC_NSEC_CAP_UNIPROCESSOR #define OPTEE_KNOWN_SEC_CAPS (OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM | \ OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM | \ @@ -50,6 +54,9 @@ struct optee_std_call { struct list_head list; struct optee_msg_arg *xen_arg; paddr_t guest_arg_ipa; +/* Buffer for translated page addresses, shared with OP-TEE */ +void *non_contig[MAX_NONCONTIG_ENTRIES]; +int non_contig_order[MAX_NONCONTIG_ENTRIES]; int optee_thread_id; int rpc_op; bool in_flight; @@ -63,12 +70,23 @@ struct shm_rpc { uint64_t cookie; }; +/* Shared memory buffer for arbitrary data */ +struct optee_shm_buf { +struct list_head list; +uint64_t cookie; +unsigned int max_page_cnt; +unsigned int page_cnt; +struct page_info *pages[]; +}; + /* Domain context */ struct optee_domain { struct list_head call_list; struct list_head shm_rpc_list; +struct list_head optee_shm_buf_list; atomic_t call_count; atomic_t shm_rpc_count; +atomic_t optee_shm_buf_pages; spinlock_t lock; }; @@ -125,9 +143,11 @@ static int optee_enable(struct domain *d) INIT_LIST_HEAD(&ctx->call_list); INIT_LIST_HEAD(&ctx->shm_rpc_list); +INIT_LIST_HEAD(&ctx->optee_shm_buf_list); atomic_set(&ctx->call_count, 0); atomic_set(&ctx->shm_rpc_count, 0); +atomic_set(&ctx->optee_shm_buf_pages, 0); spin_lock_init(&ctx->lock); @@ -325,12 +345,91 @@ static void free_shm_rpc(struct optee_domain *ctx, uint64_t cookie) xfree(shm_rpc); } +static struct optee_shm_buf *allocate_optee_shm_buf(struct optee_domain *ctx, +uint64_t cookie, +unsigned int pages_cnt) +{ +struct optee_shm_buf *optee_shm_buf, *optee_shm_buf_tmp; + +while ( true ) +{ +int old = atomic_read(&ctx->optee_shm_buf_pages); +int new = old + pages_cnt; +if ( new >= MAX_TOTAL_SMH_BUF_PG ) +return NULL; +if ( likely(old == atomic_cmpxchg(&ctx->optee_shm_buf_pages, + old, new)) ) +break; +} + +optee_shm_buf = xzalloc_bytes(sizeof(struct optee_shm_buf) + +pages_cnt * sizeof(struct page *)); +if ( !optee_shm_buf ) +goto err; + +optee_shm_buf->cookie = cookie; +optee_shm_buf->max_page_cnt = pages_cnt; + +spin_lock(&ctx->lock); +/* Check if there is already SHM with the same cookie */ +list_for_each_entry( optee_shm_buf_tmp, &ctx->optee_shm_buf_list, list ) +{ +if ( optee_shm_buf_tmp->cookie == cookie ) +{ +spin_unlock(&ctx->lock); +gprintk(XENLOG_WARNING, "Guest tries t
[Xen-devel] [PATCH v3 04/11] optee: add OP-TEE mediator skeleton
From: Volodymyr Babchuk Add very basic OP-TEE mediator. It can probe for OP-TEE presence, tell it about domain creation/destruction and forward all known calls. This is all what is needed for Dom0 to work with OP-TEE as long as Dom0 shares 1:1 mapped pages with OP-TEE. Any attempt to call OP-TEE from DomU will fail and can lead to spectacular results. Also, problems can arise if Dom0 uses pages mapped from other domains. So, this patch should not be merged without next patches in the series. This code issues two non-preemptible calls to OP-TEE: to create and to destroy client context. They can't block in OP-TEE, but OP-TEE can wait on a splinlocks, so there is no maximal execution time guaranteed. Signed-off-by: Volodymyr Babchuk --- Changes from v2: - Fixed coding style - Introduced tee/Kconfig - Fixed error messages xen/arch/arm/Kconfig| 2 + xen/arch/arm/tee/Kconfig| 4 + xen/arch/arm/tee/Makefile | 1 + xen/arch/arm/tee/optee.c| 151 xen/include/asm-arm/tee/optee_smc.h | 50 + 5 files changed, 208 insertions(+) create mode 100644 xen/arch/arm/tee/Kconfig create mode 100644 xen/arch/arm/tee/optee.c diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index e527b2f885..99e6f0ebb2 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -237,3 +237,5 @@ source "arch/arm/platforms/Kconfig" source "common/Kconfig" source "drivers/Kconfig" + +source "arch/arm/tee/Kconfig" diff --git a/xen/arch/arm/tee/Kconfig b/xen/arch/arm/tee/Kconfig new file mode 100644 index 00..5b829db2e9 --- /dev/null +++ b/xen/arch/arm/tee/Kconfig @@ -0,0 +1,4 @@ +config OPTEE + bool "Enable OP-TEE mediator" + default n + depends on TEE diff --git a/xen/arch/arm/tee/Makefile b/xen/arch/arm/tee/Makefile index c54d4796ff..982c879684 100644 --- a/xen/arch/arm/tee/Makefile +++ b/xen/arch/arm/tee/Makefile @@ -1 +1,2 @@ obj-y += tee.o +obj-$(CONFIG_OPTEE) += optee.o diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c new file mode 100644 index 00..73ad25ee0b --- /dev/null +++ b/xen/arch/arm/tee/optee.c @@ -0,0 +1,151 @@ +/* + * xen/arch/arm/tee/optee.c + * + * OP-TEE mediator + * + * Volodymyr Babchuk + * Copyright (c) 2018 EPAM Systems. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include + +#include +#include + +/* Client ID 0 is reserved for hypervisor itself */ +#define OPTEE_CLIENT_ID(domain) (domain->domain_id + 1) + +static bool optee_probe(void) +{ +struct dt_device_node *node; +struct arm_smccc_res resp; + +/* Check for entry in dtb */ +node = dt_find_compatible_node(NULL, NULL, "linaro,optee-tz"); +if ( !node ) +return false; + +/* Check UID */ +arm_smccc_smc(ARM_SMCCC_CALL_UID_FID(TRUSTED_OS_END), &resp); + +if ( (uint32_t)resp.a0 != OPTEE_MSG_UID_0 || + (uint32_t)resp.a1 != OPTEE_MSG_UID_1 || + (uint32_t)resp.a2 != OPTEE_MSG_UID_2 || + (uint32_t)resp.a3 != OPTEE_MSG_UID_3 ) +return false; + +return true; +} + +static int optee_enable(struct domain *d) +{ +struct arm_smccc_res resp; + +/* + * Inform OP-TEE about a new guest. + * This is a "Fast" call in terms of OP-TEE. This basically + * means that it can't be preempted, because there is no + * thread allocated for it in OP-TEE. It is close to atomic + * context in linux kernel: E.g. no blocking calls can be issued. + * Also, interrupts are disabled. + * Right now OP-TEE just frees allocated memory, so it should be + * really fast. + */ +arm_smccc_smc(OPTEE_SMC_VM_CREATED, OPTEE_CLIENT_ID(d), 0, 0, 0, 0, 0, 0, + &resp); +if ( resp.a0 != OPTEE_SMC_RETURN_OK ) +{ +gprintk(XENLOG_WARNING, "Unable to create OPTEE client: rc = 0x%X\n", +(uint32_t)resp.a0); +return -ENODEV; +} + +return 0; +} + +static void forward_call(struct cpu_user_regs *regs) +{ +struct arm_smccc_res resp; + +arm_smccc_smc(get_user_reg(regs, 0), + get_user_reg(regs, 1), + get_user_reg(regs, 2), + get_user_reg(regs, 3), + get_user_reg(regs, 4), + get_user_reg(regs, 5), + get_user_reg(regs, 6), + OPTEE_CLIENT_ID(current->domain), + &resp); + +set_user_reg(regs, 0, resp.a0); +set_user_reg(regs, 1, resp.a1); +set_user_reg(regs, 2, resp.a2); +set_user_reg(regs, 3, resp.a3); +set_user_reg(regs, 4, 0); +set_user_reg(regs, 5, 0); +set_user_reg(regs, 6, 0); +set_user_reg(regs, 7, 0); +} + +static void optee_domain_destroy(struct domain *d) +{ +struct arm_smccc_res resp; + +/* At this time al
[Xen-devel] [PATCH v3 05/11] optee: add fast calls handling
From: Volodymyr Babchuk Some fast SMCCC calls to OP-TEE should be handled in a special way. Capabilities exchange should be filtered out, so only caps known to mediator are used. Also mediator disables static SHM memory capability, because it can't share OP-TEE memory with a domain. Only domain can share memory with OP-TEE, so it ensures that OP-TEE supports dynamic SHM. Basically, static SHM is a reserved memory region which is always mapped into OP-TEE address space. It belongs to OP-TEE. Normally, NW is allowed to access there, so it can communicate with OP-TEE. On other hand, dynamic SHM is NW's own memory, which it can share with OP-TEE. OP-TEE maps this memory dynamically, when it wants to access it. Because mediator can't share one static SHM region with all guests, it just disables it for all. Signed-off-by: Volodymyr Babchuk --- Changes from v2: - Defined known capabilities explicitely - Fixed code style xen/arch/arm/tee/optee.c | 58 ++-- 1 file changed, 56 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c index 73ad25ee0b..584241b03a 100644 --- a/xen/arch/arm/tee/optee.c +++ b/xen/arch/arm/tee/optee.c @@ -22,6 +22,11 @@ /* Client ID 0 is reserved for hypervisor itself */ #define OPTEE_CLIENT_ID(domain) (domain->domain_id + 1) +#define OPTEE_KNOWN_NSEC_CAPS OPTEE_SMC_NSEC_CAP_UNIPROCESSOR +#define OPTEE_KNOWN_SEC_CAPS (OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM | \ + OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM | \ + OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) + static bool optee_probe(void) { struct dt_device_node *node; @@ -94,6 +99,18 @@ static void forward_call(struct cpu_user_regs *regs) set_user_reg(regs, 7, 0); } +static void set_return(struct cpu_user_regs *regs, uint32_t ret) +{ +set_user_reg(regs, 0, ret); +set_user_reg(regs, 1, 0); +set_user_reg(regs, 2, 0); +set_user_reg(regs, 3, 0); +set_user_reg(regs, 4, 0); +set_user_reg(regs, 5, 0); +set_user_reg(regs, 6, 0); +set_user_reg(regs, 7, 0); +} + static void optee_domain_destroy(struct domain *d) { struct arm_smccc_res resp; @@ -109,6 +126,39 @@ static void optee_domain_destroy(struct domain *d) &resp); } +static bool handle_exchange_capabilities(struct cpu_user_regs *regs) +{ +uint32_t caps; + +/* Filter out unknown guest caps */ +caps = get_user_reg(regs, 1); +caps &= OPTEE_KNOWN_NSEC_CAPS; +set_user_reg(regs, 1, caps); + +forward_call(regs); +if ( get_user_reg(regs, 0) != OPTEE_SMC_RETURN_OK ) +return true; + +caps = get_user_reg(regs, 1); + +/* Filter out unknown OP-TEE caps */ +caps &= OPTEE_KNOWN_SEC_CAPS; + +/* Drop static SHM_RPC cap */ +caps &= ~OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM; + +/* Don't allow guests to work without dynamic SHM */ +if ( !(caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) ) +{ +set_return(regs, OPTEE_SMC_RETURN_ENOTAVAIL); +return true; +} + +set_user_reg(regs, 1, caps); + +return true; +} + static bool optee_handle_call(struct cpu_user_regs *regs) { switch ( get_user_reg(regs, 0) ) @@ -120,12 +170,16 @@ static bool optee_handle_call(struct cpu_user_regs *regs) case OPTEE_SMC_FUNCID_GET_OS_REVISION: case OPTEE_SMC_ENABLE_SHM_CACHE: case OPTEE_SMC_DISABLE_SHM_CACHE: -case OPTEE_SMC_GET_SHM_CONFIG: -case OPTEE_SMC_EXCHANGE_CAPABILITIES: case OPTEE_SMC_CALL_WITH_ARG: case OPTEE_SMC_CALL_RETURN_FROM_RPC: forward_call(regs); return true; +case OPTEE_SMC_GET_SHM_CONFIG: +/* No static SHM available for guests */ +set_return(regs, OPTEE_SMC_RETURN_ENOTAVAIL); +return true; +case OPTEE_SMC_EXCHANGE_CAPABILITIES: +return handle_exchange_capabilities(regs); default: return false; } -- 2.20.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v3 02/11] arm: add tee_enabled flag to xen_arch_domainconfig
From: Volodymyr Babchuk This flag enables TEE support for a domain. Signed-off-by: Volodymyr Babchuk --- xen/arch/arm/domain.c | 4 xen/arch/arm/domctl.c | 1 + xen/include/public/arch-arm.h | 3 +++ 3 files changed, 8 insertions(+) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 11b618515b..f04041931d 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -702,6 +702,10 @@ int arch_domain_create(struct domain *d, if ( (rc = domain_vtimer_init(d, &config->arch)) != 0 ) goto fail; +if ( config->arch.tee_enabled ) +if ( (rc = tee_enable(d)) != 0 ) +goto fail; + update_domain_wallclock_time(d); /* diff --git a/xen/arch/arm/domctl.c b/xen/arch/arm/domctl.c index 20691528a6..f019e035e8 100644 --- a/xen/arch/arm/domctl.c +++ b/xen/arch/arm/domctl.c @@ -13,6 +13,7 @@ #include #include #include +#include #include void arch_get_domain_info(const struct domain *d, diff --git a/xen/include/public/arch-arm.h b/xen/include/public/arch-arm.h index eb424e8286..b7a010e99e 100644 --- a/xen/include/public/arch-arm.h +++ b/xen/include/public/arch-arm.h @@ -323,6 +323,9 @@ struct xen_arch_domainconfig { * */ uint32_t clock_frequency; + +/* IN */ +uint8_t tee_enabled; }; #endif /* __XEN__ || __XEN_TOOLS__ */ -- 2.20.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v3 07/11] optee: add support for RPC SHM buffers
From: Volodymyr Babchuk OP-TEE usually uses the same idea with command buffers (see previous commit) to issue RPC requests. Problem is that initially it has no buffer, where it can write request. So the first RPC request it makes is special: it requests NW to allocate shared buffer for other RPC requests. Usually this buffer is allocated only once for every OP-TEE thread and it remains allocated all the time until shutdown. Mediator needs to pin this buffer(s) to make sure that domain can't transfer it to someone else. Life cycle of this buffer is controlled by OP-TEE. It asks guest to create buffer and it asks it to free it. Signed-off-by: Volodymyr Babchuk --- Changes from v2: - Added check to ensure that guests does not return two SHM buffers with the same cookie - Fixed coding style - Storing RPC parameters during RPC return to make sure, that guest will not change them during call continuation xen/arch/arm/tee/optee.c | 140 ++- 1 file changed, 138 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c index dc90e2ed8e..771148e940 100644 --- a/xen/arch/arm/tee/optee.c +++ b/xen/arch/arm/tee/optee.c @@ -30,6 +30,12 @@ * OP-TEE spawns a thread for every standard call. */ #define MAX_STD_CALLS 16 +/* + * Maximal number of pre-allocated SHM buffers. OP-TEE generally asks + * for one SHM buffer per thread, so this also corresponds to OP-TEE + * option CFG_NUM_THREADS + */ +#define MAX_RPC_SHMSMAX_STD_CALLS #define OPTEE_KNOWN_NSEC_CAPS OPTEE_SMC_NSEC_CAP_UNIPROCESSOR #define OPTEE_KNOWN_SEC_CAPS (OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM | \ @@ -47,12 +53,22 @@ struct optee_std_call { int optee_thread_id; int rpc_op; bool in_flight; +register_t rpc_params[2]; +}; + +/* Pre-allocated SHM buffer for RPC commands */ +struct shm_rpc { +struct list_head list; +struct page_info *guest_page; +uint64_t cookie; }; /* Domain context */ struct optee_domain { struct list_head call_list; +struct list_head shm_rpc_list; atomic_t call_count; +atomic_t shm_rpc_count; spinlock_t lock; }; @@ -108,7 +124,11 @@ static int optee_enable(struct domain *d) } INIT_LIST_HEAD(&ctx->call_list); +INIT_LIST_HEAD(&ctx->shm_rpc_list); + atomic_set(&ctx->call_count, 0); +atomic_set(&ctx->shm_rpc_count, 0); + spin_lock_init(&ctx->lock); d->arch.tee = ctx; @@ -227,11 +247,90 @@ static void put_std_call(struct optee_domain *ctx, struct optee_std_call *call) spin_unlock(&ctx->lock); } +static struct shm_rpc *allocate_and_pin_shm_rpc(struct optee_domain *ctx, +paddr_t gaddr, +uint64_t cookie) +{ +struct shm_rpc *shm_rpc, *shm_rpc_tmp; +int count; + +/* Make sure that guest does not allocate more than MAX_RPC_SHMS */ +count = atomic_add_unless(&ctx->shm_rpc_count, 1, MAX_RPC_SHMS); +if ( count == MAX_RPC_SHMS ) +return NULL; + +shm_rpc = xzalloc(struct shm_rpc); +if ( !shm_rpc ) +goto err; + +/* This page will be shared with OP-TEE, so we need to pin it */ +shm_rpc->guest_page = get_page_from_gfn(current->domain, +paddr_to_pfn(gaddr), +NULL, +P2M_ALLOC); +if ( !shm_rpc->guest_page ) +goto err; + +shm_rpc->cookie = cookie; + +spin_lock(&ctx->lock); +/* Check if there is already SHM with the same cookie */ +list_for_each_entry( shm_rpc_tmp, &ctx->shm_rpc_list, list ) +{ +if ( shm_rpc_tmp->cookie == cookie ) +{ +spin_unlock(&ctx->lock); +gprintk(XENLOG_WARNING, "Guest tries to use the same RPC SHM cookie"); +goto err; +} +} + +list_add_tail(&shm_rpc->list, &ctx->shm_rpc_list); +spin_unlock(&ctx->lock); + +return shm_rpc; + +err: +atomic_dec(&ctx->shm_rpc_count); +put_page(shm_rpc->guest_page); +xfree(shm_rpc); + +return NULL; +} + +static void free_shm_rpc(struct optee_domain *ctx, uint64_t cookie) +{ +struct shm_rpc *shm_rpc; +bool found = false; + +spin_lock(&ctx->lock); + +list_for_each_entry( shm_rpc, &ctx->shm_rpc_list, list ) +{ +if ( shm_rpc->cookie == cookie ) +{ +found = true; +list_del(&shm_rpc->list); +break; +} +} +spin_unlock(&ctx->lock); + +if ( !found ) +return; + +ASSERT(shm_rpc->guest_page); +put_page(shm_rpc->guest_page); + +xfree(shm_rpc); +} + static void optee_domain_destroy(struct domain *d) { struct arm_smccc_res resp; struct optee_std_call *call, *call_tmp; struct optee_domain *ctx = d->arch.tee; +struct shm_rpc *shm_rpc, *shm_rpc_tmp; /* At this time all domain VCPUs shoul
[Xen-devel] [PATCH v3 06/11] optee: add std call handling
From: Volodymyr Babchuk The main way to communicate with OP-TEE is to issue standard SMCCC call. "Standard" is a SMCCC term and it means that call can be interrupted and OP-TEE can return control to NW before completing the call. In contrast with fast calls, where arguments and return values are passed in registers, standard calls use shared memory. Register pair a1,a2 holds 64-bit PA of command buffer, where all arguments are stored and which is used to return data. OP-TEE internally copies contents of this buffer into own secure memory before accessing and validating any data in command buffer. This is done to make sure that NW will not change contents of the validated parameters. Mediator needs to do the same for number of reasons: 1. To make sure that guest will not change data after validation. 2. To translate IPAs to PAs in the command buffer (this is not done in this patch). 3. To hide translated address from guest, so it will not be able to do IPA->PA translation by misusing mediator. During standard call OP-TEE can issue multiple "RPC returns", asking NW to do some work for OP-TEE. NW then issues special call OPTEE_SMC_CALL_RETURN_FROM_RPC to resume handling of the original call. Thus, mediator needs to maintain context for original standard call during multiple SMCCC calls. Standard call is considered complete, when returned value is not a RPC request. Signed-off-by: Volodymyr Babchuk --- Changes from v2: - renamed struct domain_ctx to struct optee_domain - fixed coding style - Now I use access_guest_memory_by_ipa() instead of mappings to read command buffer - Added tracking for in flight calls, so guest can't resume the same call from two CPUs simultaniously xen/arch/arm/tee/optee.c | 319 ++- xen/include/asm-arm/domain.h | 3 + 2 files changed, 320 insertions(+), 2 deletions(-) diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c index 584241b03a..dc90e2ed8e 100644 --- a/xen/arch/arm/tee/optee.c +++ b/xen/arch/arm/tee/optee.c @@ -12,6 +12,8 @@ */ #include +#include +#include #include #include #include @@ -22,11 +24,38 @@ /* Client ID 0 is reserved for hypervisor itself */ #define OPTEE_CLIENT_ID(domain) (domain->domain_id + 1) +/* + * Maximal number of concurrent standard calls from one guest. This + * corresponds to OPTEE configuration option CFG_NUM_THREADS, because + * OP-TEE spawns a thread for every standard call. + */ +#define MAX_STD_CALLS 16 + #define OPTEE_KNOWN_NSEC_CAPS OPTEE_SMC_NSEC_CAP_UNIPROCESSOR #define OPTEE_KNOWN_SEC_CAPS (OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM | \ OPTEE_SMC_SEC_CAP_UNREGISTERED_SHM | \ OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) +/* + * Call context. OP-TEE can issue multiple RPC returns during one call. + * We need to preserve context during them. + */ +struct optee_std_call { +struct list_head list; +struct optee_msg_arg *xen_arg; +paddr_t guest_arg_ipa; +int optee_thread_id; +int rpc_op; +bool in_flight; +}; + +/* Domain context */ +struct optee_domain { +struct list_head call_list; +atomic_t call_count; +spinlock_t lock; +}; + static bool optee_probe(void) { struct dt_device_node *node; @@ -52,6 +81,11 @@ static bool optee_probe(void) static int optee_enable(struct domain *d) { struct arm_smccc_res resp; +struct optee_domain *ctx; + +ctx = xzalloc(struct optee_domain); +if ( !ctx ) +return -ENOMEM; /* * Inform OP-TEE about a new guest. @@ -69,9 +103,16 @@ static int optee_enable(struct domain *d) { gprintk(XENLOG_WARNING, "Unable to create OPTEE client: rc = 0x%X\n", (uint32_t)resp.a0); +xfree(ctx); return -ENODEV; } +INIT_LIST_HEAD(&ctx->call_list); +atomic_set(&ctx->call_count, 0); +spin_lock_init(&ctx->lock); + +d->arch.tee = ctx; + return 0; } @@ -111,9 +152,86 @@ static void set_return(struct cpu_user_regs *regs, uint32_t ret) set_user_reg(regs, 7, 0); } +static struct optee_std_call *allocate_std_call(struct optee_domain *ctx) +{ +struct optee_std_call *call; +int count; + +/* Make sure that guest does not execute more than MAX_STD_CALLS */ +count = atomic_add_unless(&ctx->call_count, 1, MAX_STD_CALLS); +if ( count == MAX_STD_CALLS ) +return NULL; + +call = xzalloc(struct optee_std_call); +if ( !call ) +{ +atomic_dec(&ctx->call_count); +return NULL; +} + +call->optee_thread_id = -1; +call->in_flight = true; + +spin_lock(&ctx->lock); +list_add_tail(&call->list, &ctx->call_list); +spin_unlock(&ctx->lock); + +return call; +} + +static void free_std_call(struct optee_domain *ctx, + struct optee_std_call *call) +{ +atomic_dec(&ctx->call_count); + +spin_lock(&ctx->lock); +list_del(&call->list); +spin_unlock(&c
[Xen-devel] [PATCH v3 11/11] libxl: arm: create optee firmware node in DT if tee=1
From: Volodymyr Babchuk If TEE support is enabled with "tee=1" option in xl.cfg, then we need to inform guest about available TEE. Currently only OP-TEE is supported, so we'll create DT node in a way that is expected by optee driver in linux. Signed-off-by: Volodymyr Babchuk --- tools/libxl/libxl_arm.c | 29 + 1 file changed, 29 insertions(+) diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c index f8b4ef55e0..befccebd19 100644 --- a/tools/libxl/libxl_arm.c +++ b/tools/libxl/libxl_arm.c @@ -409,6 +409,32 @@ static int make_psci_node(libxl__gc *gc, void *fdt) return 0; } +static int make_optee_node(libxl__gc *gc, void *fdt) +{ +int res; +LOG(DEBUG, "Creating OP-TEE node in dtb"); + +res = fdt_begin_node(fdt, "firmware"); +if (res) return res; + +res = fdt_begin_node(fdt, "optee"); +if (res) return res; + +res = fdt_property_compat(gc, fdt, 1, "linaro,optee-tz"); +if (res) return res; + +res = fdt_property_string(fdt, "method", "smc"); +if (res) return res; + +res = fdt_end_node(fdt); +if (res) return res; + +res = fdt_end_node(fdt); +if (res) return res; + +return 0; +} + static int make_memory_nodes(libxl__gc *gc, void *fdt, const struct xc_dom_image *dom) { @@ -922,6 +948,9 @@ next_resize: if (info->arch_arm.vuart == LIBXL_VUART_TYPE_SBSA_UART) FDT( make_vpl011_uart_node(gc, fdt, ainfo, dom) ); +if (libxl_defbool_val(info->tee)) +FDT( make_optee_node(gc, fdt)); + if (pfdt) FDT( copy_partial_fdt(gc, fdt, pfdt) ); -- 2.20.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v3 10/11] xl: add "tee" option for xl.cfg
From: Volodymyr Babchuk This boolean option controls if TEE access is enabled for the domain. If access is enabled, xl will set appropriate flag in architecture configuration to ask hypervisor to enable TEE support. Signed-off-by: Volodymyr Babchuk --- Changes from v2: - Use arch.tee_enabled instead of separate domctl docs/man/xl.cfg.pod.5.in| 10 ++ tools/libxl/libxl_arm.c | 2 ++ tools/libxl/libxl_create.c | 1 + tools/libxl/libxl_types.idl | 1 + tools/xl/xl_parse.c | 1 + 5 files changed, 15 insertions(+) diff --git a/docs/man/xl.cfg.pod.5.in b/docs/man/xl.cfg.pod.5.in index b1c0be14cd..9a7064c951 100644 --- a/docs/man/xl.cfg.pod.5.in +++ b/docs/man/xl.cfg.pod.5.in @@ -2793,6 +2793,16 @@ Currently, only the "sbsa_uart" model is supported for ARM. =back +=over 4 + +=item B + +Enable TEE support for the guest. Currently only OP-TEE is supported. If this +option is enabled, xl will create guest, which can access TEE. Also +OP-TEE node will be emitted into guest's device tree. + +=back + =head3 x86 =over 4 diff --git a/tools/libxl/libxl_arm.c b/tools/libxl/libxl_arm.c index 141e159043..f8b4ef55e0 100644 --- a/tools/libxl/libxl_arm.c +++ b/tools/libxl/libxl_arm.c @@ -89,6 +89,8 @@ int libxl__arch_domain_prepare_config(libxl__gc *gc, return ERROR_FAIL; } +config->arch.tee_enabled = libxl_defbool_val(d_config->b_info.tee); + return 0; } diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c index fa573344bc..bc9c4ee9ef 100644 --- a/tools/libxl/libxl_create.c +++ b/tools/libxl/libxl_create.c @@ -219,6 +219,7 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc, libxl__arch_domain_build_info_setdefault(gc, b_info); libxl_defbool_setdefault(&b_info->dm_restrict, false); +libxl_defbool_setdefault(&b_info->tee, false); switch (b_info->type) { case LIBXL_DOMAIN_TYPE_HVM: diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index 51cf06a3a2..a634f6e704 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -613,6 +613,7 @@ libxl_domain_build_info = Struct("domain_build_info",[ # Alternate p2m is not bound to any architecture or guest type, as it is # supported by x86 HVM and ARM support is planned. ("altp2m", libxl_altp2m_mode), +("tee", libxl_defbool), ], dir=DIR_IN, copy_deprecated_fn="libxl__domain_build_info_copy_deprecated", diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 352cd214dd..af35f1cce0 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -2549,6 +2549,7 @@ skip_usbdev: } xlu_cfg_get_defbool(config, "dm_restrict", &b_info->dm_restrict, 0); +xlu_cfg_get_defbool(config, "tee", &b_info->tee, 0); if (c_info->type == LIBXL_DOMAIN_TYPE_HVM) { if (!xlu_cfg_get_string (config, "vga", &buf, 0)) { -- 2.20.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v3 09/11] optee: add support for RPC commands
From: Volodymyr Babchuk OP-TEE can issue multiple RPC requests. We are interested mostly in request that asks NW to allocate/free shared memory for OP-TEE needs, because mediator need to do address translation in the same way as it was done for shared buffers registered by NW. As mediator now accesses shared command buffer, we need to shadow it in the same way, as we shadow request buffers for STD calls. Signed-off-by: Volodymyr Babchuk --- Changes from v2: - Use access_guest_memory_by_ipa() instead of direct mapping xen/arch/arm/tee/optee.c | 136 +-- 1 file changed, 130 insertions(+), 6 deletions(-) diff --git a/xen/arch/arm/tee/optee.c b/xen/arch/arm/tee/optee.c index cfc3b34df7..bf3535946d 100644 --- a/xen/arch/arm/tee/optee.c +++ b/xen/arch/arm/tee/optee.c @@ -67,6 +67,8 @@ struct optee_std_call { struct shm_rpc { struct list_head list; struct page_info *guest_page; +struct optee_msg_arg *xen_arg; +paddr_t guest_ipa; uint64_t cookie; }; @@ -290,6 +292,11 @@ static struct shm_rpc *allocate_and_pin_shm_rpc(struct optee_domain *ctx, P2M_ALLOC); if ( !shm_rpc->guest_page ) goto err; +shm_rpc->guest_ipa = gaddr; + +shm_rpc->xen_arg = alloc_xenheap_page(); +if ( !shm_rpc->xen_arg ) +goto err; shm_rpc->cookie = cookie; @@ -313,6 +320,7 @@ static struct shm_rpc *allocate_and_pin_shm_rpc(struct optee_domain *ctx, err: atomic_dec(&ctx->shm_rpc_count); put_page(shm_rpc->guest_page); +free_xenheap_page(shm_rpc->xen_arg); xfree(shm_rpc); return NULL; @@ -339,12 +347,32 @@ static void free_shm_rpc(struct optee_domain *ctx, uint64_t cookie) if ( !found ) return; +free_xenheap_page(shm_rpc->xen_arg); + ASSERT(shm_rpc->guest_page); put_page(shm_rpc->guest_page); xfree(shm_rpc); } +static struct shm_rpc *find_shm_rpc(struct optee_domain *ctx, uint64_t cookie) +{ +struct shm_rpc *shm_rpc; + +spin_lock(&ctx->lock); +list_for_each_entry( shm_rpc, &ctx->shm_rpc_list, list ) +{ +if ( shm_rpc->cookie == cookie ) +{ +spin_unlock(&ctx->lock); +return shm_rpc; +} +} +spin_unlock(&ctx->lock); + +return NULL; +} + static struct optee_shm_buf *allocate_optee_shm_buf(struct optee_domain *ctx, uint64_t cookie, unsigned int pages_cnt) @@ -712,6 +740,33 @@ static void copy_std_request_back(struct optee_domain *ctx, put_page(page); } +static void handle_rpc_return(struct optee_domain *ctx, + struct cpu_user_regs *regs, + struct optee_std_call *call) +{ +call->rpc_params[0] = get_user_reg(regs, 1); +call->rpc_params[1] = get_user_reg(regs, 2); +call->optee_thread_id = get_user_reg(regs, 3); +call->rpc_op = OPTEE_SMC_RETURN_GET_RPC_FUNC(get_user_reg(regs, 0)); + +if ( call->rpc_op == OPTEE_SMC_RPC_FUNC_CMD ) +{ +/* Copy RPC request from shadowed buffer to guest */ +uint64_t cookie = get_user_reg(regs, 1) << 32 | get_user_reg(regs, 2); +struct shm_rpc *shm_rpc = find_shm_rpc(ctx, cookie); +if ( !shm_rpc ) +{ +gprintk(XENLOG_ERR, "Can't find SHM-RPC with cookie %lx\n", cookie); +return; +} +access_guest_memory_by_ipa(current->domain, +shm_rpc->guest_ipa, +shm_rpc->xen_arg, +OPTEE_MSG_GET_ARG_SIZE(shm_rpc->xen_arg->num_params), +true); +} +} + static void execute_std_call(struct optee_domain *ctx, struct cpu_user_regs *regs, struct optee_std_call *call) @@ -723,10 +778,7 @@ static void execute_std_call(struct optee_domain *ctx, optee_ret = get_user_reg(regs, 0); if ( OPTEE_SMC_RETURN_IS_RPC(optee_ret) ) { -call->rpc_params[0] = get_user_reg(regs, 1); -call->rpc_params[1] = get_user_reg(regs, 2); -call->optee_thread_id = get_user_reg(regs, 3); -call->rpc_op = OPTEE_SMC_RETURN_GET_RPC_FUNC(optee_ret); +handle_rpc_return(ctx, regs, call); put_std_call(ctx, call); return; } @@ -787,6 +839,78 @@ err: return false; } +static void handle_rpc_cmd_alloc(struct optee_domain *ctx, + struct cpu_user_regs *regs, + struct optee_std_call *call, + struct shm_rpc *shm_rpc) +{ +if ( shm_rpc->xen_arg->params[0].attr != (OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT | +OPTEE_MSG_ATTR_NONCONTIG) ) +{ +gprintk(XENLOG_WARNING, "Invalid attrs for shared mem buffer\n"); +return; +} + +/*
[Xen-devel] [PATCH v3 00/11] TEE mediator (and OP-TEE) support in XEN
From: Volodymyr Babchuk Hello all, Sorry for late submussion. I was busy with other projects. Global changes from v2: - Use domain flags insted of domctl interface to enable optee for guests - Remove patch "libxc: add xc_dom_tee_enable(...) function" because of previous change - Mediator now stores own context in arch part of struct domain, so I removed patch "optee: add domain contexts" Per-patch changes are described in corresponding emails. v2: This is v2 of patch series for OP-TEE mediator support in XEN. Changes from v1: - Added domctl interface, so now xl decides what domain should work with TEE - Removed XSM support due to change described above - Patch with OP-TEE mediator was splited to 7 separate patches - Removed patch with call_smccc() function. Now this series depend on Julien Grall's series "xen/arm: SMCCC fixup and improvement" [3] = v1: This is follow for patch series [1]. There was lots of discussions for that series and I tried to address all of them in this new patchset. Currently, I had a working solution for OP-TEE virtualization and it is being upstreamed right now ([2]). So, I think it is a good time to introduce support in XEN as well. This series include generic TEE mediator framework and full-scale OP-TEE mediator which is working with mentioned chages in OP-TEE. So, multiple domains can work simultaneously with OP-TEE. I added XSM support, so now it is possible to control which domains can work with TEEs. Also I changed way how TEE discovery is done. Now it is very generic and should support any platform. [1] https://lists.xenproject.org/archives/html/xen-devel/2017-10/msg01451.html [2] https://github.com/OP-TEE/optee_os/pull/2370 [3] https://lists.xenproject.org/archives/html/xen-devel/2018-08/msg02138.html Volodymyr Babchuk (11): arm: add generic TEE mediator framework arm: add tee_enabled flag to xen_arch_domainconfig arm: tee: add OP-TEE header files optee: add OP-TEE mediator skeleton optee: add fast calls handling optee: add std call handling optee: add support for RPC SHM buffers optee: add support for arbitrary shared memory optee: add support for RPC commands xl: add "tee" option for xl.cfg libxl: arm: create optee firmware node in DT if tee=1 MAINTAINERS |6 + docs/man/xl.cfg.pod.5.in| 10 + tools/libxl/libxl_arm.c | 31 + tools/libxl/libxl_create.c |1 + tools/libxl/libxl_types.idl |1 + tools/xl/xl_parse.c |1 + xen/arch/arm/Kconfig|9 + xen/arch/arm/Makefile |1 + xen/arch/arm/domain.c |8 + xen/arch/arm/domain_build.c |4 + xen/arch/arm/domctl.c |1 + xen/arch/arm/setup.c|1 + xen/arch/arm/shutdown.c |1 + xen/arch/arm/tee/Kconfig|4 + xen/arch/arm/tee/Makefile |2 + xen/arch/arm/tee/optee.c| 1054 +++ xen/arch/arm/tee/tee.c | 69 ++ xen/arch/arm/vsmc.c |5 + xen/arch/arm/xen.lds.S |7 + xen/include/asm-arm/domain.h|3 + xen/include/asm-arm/tee/optee_msg.h | 444 +++ xen/include/asm-arm/tee/optee_smc.h | 507 + xen/include/asm-arm/tee/tee.h | 91 +++ xen/include/public/arch-arm.h |3 + 24 files changed, 2264 insertions(+) create mode 100644 xen/arch/arm/tee/Kconfig create mode 100644 xen/arch/arm/tee/Makefile create mode 100644 xen/arch/arm/tee/optee.c create mode 100644 xen/arch/arm/tee/tee.c create mode 100644 xen/include/asm-arm/tee/optee_msg.h create mode 100644 xen/include/asm-arm/tee/optee_smc.h create mode 100644 xen/include/asm-arm/tee/tee.h -- 2.20.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH v3 01/11] arm: add generic TEE mediator framework
This patch adds basic framework for TEE mediators. Guests can't talk to TEE directly, we need some entity that will intercept request and decide what to do with them. "TEE mediator" is a such entity. This is how it works: user can build XEN with multiple TEE mediators (see the next patches, where OP-TEE mediator is introduced). TEE mediator register self with REGISTER_TEE_MEDIATOR() macro in the same way, as device drivers use DT_DEVICE_START()/DT_DEVICE_END() macros. In run-time, during initialization, framework calls probe() function for each available mediator driver to find which TEE is installed on the platform. Then generic vSMC handler will call selected mediator when it intercept SMC/HVC that belongs to TEE OS or TEE application. Currently TEE mediator is enabled only for Dom0. Signed-off-by: Volodymyr Babchuk --- Changes from v2: - Removed empty tee/Kconfig file Changes from v1: - Removed tee_remove() function - CONFIG_TEE depends on EXPERT - tee_domain_created() converted to tee_enable() - tee_init() is called using initcall() mechanism - tee_handle_smc() renamed to tee_handle_call() Changes from "RFC" version: - renamed CONFIG_ARM_TEE to CONFIG_TEE - changed discovery mechanism: instead of UUID mathing, TEE-specific probing is used MAINTAINERS | 6 +++ xen/arch/arm/Kconfig | 7 +++ xen/arch/arm/Makefile | 1 + xen/arch/arm/domain.c | 4 ++ xen/arch/arm/domain_build.c | 4 ++ xen/arch/arm/setup.c | 1 + xen/arch/arm/shutdown.c | 1 + xen/arch/arm/tee/Makefile | 1 + xen/arch/arm/tee/tee.c| 69 ++ xen/arch/arm/vsmc.c | 5 ++ xen/arch/arm/xen.lds.S| 7 +++ xen/include/asm-arm/tee/tee.h | 91 +++ 12 files changed, 197 insertions(+) create mode 100644 xen/arch/arm/tee/Makefile create mode 100644 xen/arch/arm/tee/tee.c create mode 100644 xen/include/asm-arm/tee/tee.h diff --git a/MAINTAINERS b/MAINTAINERS index 96a0518f49..eac2b40fdf 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -376,6 +376,12 @@ F: config/Stubdom.mk.in F: m4/stubdom.m4 F: stubdom/ +TEE MEDIATORS +M: Volodymyr Babchuk +S: Supported +F: xen/arch/arm/tee/ +F: xen/include/asm-arm/tee + TOOLSTACK M: Ian Jackson M: Wei Liu diff --git a/xen/arch/arm/Kconfig b/xen/arch/arm/Kconfig index 581de67b6b..e527b2f885 100644 --- a/xen/arch/arm/Kconfig +++ b/xen/arch/arm/Kconfig @@ -105,6 +105,13 @@ config HARDEN_BRANCH_PREDICTOR If unsure, say Y. +config TEE + bool "Enable TEE mediators support" if EXPERT = "y" + default n + help + This option enables generic TEE mediators support. It allows guests + to access real TEE via one of TEE mediators implemented in XEN. + endmenu menu "ARM errata workaround via the alternative framework" diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile index cb902cb6fe..5c2aa34557 100644 --- a/xen/arch/arm/Makefile +++ b/xen/arch/arm/Makefile @@ -5,6 +5,7 @@ subdir-$(CONFIG_ACPI) += acpi ifneq ($(CONFIG_NO_PLAT),y) subdir-y += platforms endif +subdir-$(CONFIG_TEE) += tee obj-$(CONFIG_HAS_ALTERNATIVE) += alternative.o obj-y += bootfdt.init.o diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 1d926dcb29..11b618515b 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -931,6 +932,9 @@ int domain_relinquish_resources(struct domain *d) */ domain_vpl011_deinit(d); +/* Free TEE mediator resources */ +tee_domain_destroy(d); + d->arch.relmem = RELMEM_xen; /* Fallthrough */ diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index b0ec3f0b72..39a887b505 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -1962,6 +1963,9 @@ static int __init construct_domain(struct domain *d, struct kernel_info *kinfo) set_current(saved_current); p2m_restore_state(saved_current); +/* Enable TEE */ +tee_enable(d); + memset(regs, 0, sizeof(*regs)); regs->pc = (register_t)kinfo->entry; diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index e83221ab79..cad568d432 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include diff --git a/xen/arch/arm/shutdown.c b/xen/arch/arm/shutdown.c index b32f07ec0e..30c69506ff 100644 --- a/xen/arch/arm/shutdown.c +++ b/xen/arch/arm/shutdown.c @@ -5,6 +5,7 @@ #include #include #include +#include static void noreturn halt_this_cpu(void *arg) { diff --git a/xen/arch/arm/tee/Makefile b/xen/arch/arm/tee/Makefile new file mode 100644 index 00..c54d4796ff --- /dev/null +++ b/xen/ar
[Xen-devel] [PATCH v3 03/11] arm: tee: add OP-TEE header files
This header files describe protocol between OP-TEE and OP-TEE client driver in Linux. They are needed for upcoming OP-TEE mediator, which is added in the next patch. Reason to add those headers in separate patch is to ease up review. Those files were taken from linux tree (drivers/tee/optee/) and mangled a bit to compile with XEN. Signed-off-by: Volodymyr Babchuk --- xen/include/asm-arm/tee/optee_msg.h | 444 +++ xen/include/asm-arm/tee/optee_smc.h | 457 2 files changed, 901 insertions(+) create mode 100644 xen/include/asm-arm/tee/optee_msg.h create mode 100644 xen/include/asm-arm/tee/optee_smc.h diff --git a/xen/include/asm-arm/tee/optee_msg.h b/xen/include/asm-arm/tee/optee_msg.h new file mode 100644 index 00..10747b2aa8 --- /dev/null +++ b/xen/include/asm-arm/tee/optee_msg.h @@ -0,0 +1,444 @@ +/* + * Copyright (c) 2015-2016, Linaro Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _OPTEE_MSG_H +#define _OPTEE_MSG_H + +#include +#include + +/* + * This file defines the OP-TEE message protocol used to communicate + * with an instance of OP-TEE running in secure world. + * + * This file is divided into three sections. + * 1. Formatting of messages. + * 2. Requests from normal world + * 3. Requests from secure world, Remote Procedure Call (RPC), handled by + *tee-supplicant. + */ + +/* + * Part 1 - formatting of messages + */ + +#define OPTEE_MSG_ATTR_TYPE_NONE 0x0 +#define OPTEE_MSG_ATTR_TYPE_VALUE_INPUT0x1 +#define OPTEE_MSG_ATTR_TYPE_VALUE_OUTPUT 0x2 +#define OPTEE_MSG_ATTR_TYPE_VALUE_INOUT0x3 +#define OPTEE_MSG_ATTR_TYPE_RMEM_INPUT 0x5 +#define OPTEE_MSG_ATTR_TYPE_RMEM_OUTPUT0x6 +#define OPTEE_MSG_ATTR_TYPE_RMEM_INOUT 0x7 +#define OPTEE_MSG_ATTR_TYPE_TMEM_INPUT 0x9 +#define OPTEE_MSG_ATTR_TYPE_TMEM_OUTPUT0xa +#define OPTEE_MSG_ATTR_TYPE_TMEM_INOUT 0xb + +#define OPTEE_MSG_ATTR_TYPE_MASK GENMASK(7, 0) + +/* + * Meta parameter to be absorbed by the Secure OS and not passed + * to the Trusted Application. + * + * Currently only used with OPTEE_MSG_CMD_OPEN_SESSION. + */ +#define OPTEE_MSG_ATTR_METABIT(8) + +/* + * Pointer to a list of pages used to register user-defined SHM buffer. + * Used with OPTEE_MSG_ATTR_TYPE_TMEM_*. + * buf_ptr should point to the beginning of the buffer. Buffer will contain + * list of page addresses. OP-TEE core can reconstruct contiguous buffer from + * that page addresses list. Page addresses are stored as 64 bit values. + * Last entry on a page should point to the next page of buffer. + * Every entry in buffer should point to a 4k page beginning (12 least + * significant bits must be equal to zero). + * + * 12 least significant bints of optee_msg_param.u.tmem.buf_ptr should hold page + * offset of the user buffer. + * + * So, entries should be placed like members of this structure: + * + * struct page_data { + * uint64_t pages_array[OPTEE_MSG_NONCONTIG_PAGE_SIZE/sizeof(uint64_t) - 1]; + * uint64_t next_page_data; + * }; + * + * Structure is designed to exactly fit into the page size + * OPTEE_MSG_NONCONTIG_PAGE_SIZE which is a standard 4KB page. + * + * The size of 4KB is chosen because this is the smallest page size for ARM + * architectures. If REE uses larger pages, it should divide them to 4KB ones. + */ +#define OPTEE_MSG_ATTR_NONCONTIG BIT(9) + +/* + * Memory attributes for caching passed wi
[Xen-devel] [xen-unstable-smoke test] 131431: tolerable all pass - PUSHED
flight 131431 xen-unstable-smoke real [real] http://logs.test-lab.xenproject.org/osstest/logs/131431/ Failures :-/ but no regressions. Tests which did not succeed, but are not blocking: test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass version targeted for testing: xen 57f78a734bcabeab75ca21d4e871be78a3463fbe baseline version: xen 19232b378fab04997c0612e5c19e82c29b59d99e Last test of basis 131428 2018-12-18 14:00:43 Z0 days Testing same since 131431 2018-12-18 17:00:26 Z0 days1 attempts People who touched revisions under test: Andrew Cooper Jan Beulich jobs: build-amd64 pass build-armhf pass build-amd64-libvirt pass test-armhf-armhf-xl pass test-amd64-amd64-xl-qemuu-debianhvm-i386 pass test-amd64-amd64-libvirt pass sg-report-flight on osstest.test-lab.xenproject.org logs: /home/logs/logs images: /home/logs/images Logs, config files, etc. are available at http://logs.test-lab.xenproject.org/osstest/logs Explanation of these reports, and of osstest in general, is at http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master Test harness code can be found at http://xenbits.xen.org/gitweb?p=osstest.git;a=summary Pushing revision : To xenbits.xen.org:/home/xen/git/xen.git 19232b378f..57f78a734b 57f78a734bcabeab75ca21d4e871be78a3463fbe -> smoke ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] drm/xen-front: Make shmem backed display buffer coherent
Den 27.11.2018 11.32, skrev Oleksandr Andrushchenko: From: Oleksandr Andrushchenko When GEM backing storage is allocated with drm_gem_get_pages the backing pages may be cached, thus making it possible that the backend sees only partial content of the buffer which may lead to screen artifacts. Make sure that the frontend's memory is coherent and the backend always sees correct display buffer content. Fixes: c575b7eeb89f ("drm/xen-front: Add support for Xen PV display frontend") Signed-off-by: Oleksandr Andrushchenko --- drivers/gpu/drm/xen/xen_drm_front_gem.c | 62 +++-- 1 file changed, 48 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/xen/xen_drm_front_gem.c b/drivers/gpu/drm/xen/xen_drm_front_gem.c index 47ff019d3aef..c592735e49d2 100644 --- a/drivers/gpu/drm/xen/xen_drm_front_gem.c +++ b/drivers/gpu/drm/xen/xen_drm_front_gem.c @@ -33,8 +33,11 @@ struct xen_gem_object { /* set for buffers allocated by the backend */ bool be_alloc; - /* this is for imported PRIME buffer */ - struct sg_table *sgt_imported; + /* +* this is for imported PRIME buffer or the one allocated via +* drm_gem_get_pages. +*/ + struct sg_table *sgt; }; static inline struct xen_gem_object * @@ -77,10 +80,21 @@ static struct xen_gem_object *gem_create_obj(struct drm_device *dev, return xen_obj; } +struct sg_table *xen_drm_front_gem_get_sg_table(struct drm_gem_object *gem_obj) +{ + struct xen_gem_object *xen_obj = to_xen_gem_obj(gem_obj); + + if (!xen_obj->pages) + return ERR_PTR(-ENOMEM); + + return drm_prime_pages_to_sg(xen_obj->pages, xen_obj->num_pages); +} + static struct xen_gem_object *gem_create(struct drm_device *dev, size_t size) { struct xen_drm_front_drm_info *drm_info = dev->dev_private; struct xen_gem_object *xen_obj; + struct address_space *mapping; int ret; size = round_up(size, PAGE_SIZE); @@ -113,10 +127,14 @@ static struct xen_gem_object *gem_create(struct drm_device *dev, size_t size) xen_obj->be_alloc = true; return xen_obj; } + /* * need to allocate backing pages now, so we can share those * with the backend */ Let's see if I understand what you're doing: Here you say that the pages should be DMA accessible for devices that can only see 4GB. + mapping = xen_obj->base.filp->f_mapping; + mapping_set_gfp_mask(mapping, GFP_USER | __GFP_DMA32); + xen_obj->num_pages = DIV_ROUND_UP(size, PAGE_SIZE); xen_obj->pages = drm_gem_get_pages(&xen_obj->base); if (IS_ERR_OR_NULL(xen_obj->pages)) { @@ -125,8 +143,27 @@ static struct xen_gem_object *gem_create(struct drm_device *dev, size_t size) goto fail; } + xen_obj->sgt = xen_drm_front_gem_get_sg_table(&xen_obj->base); + if (IS_ERR_OR_NULL(xen_obj->sgt)){ + ret = PTR_ERR(xen_obj->sgt); + xen_obj->sgt = NULL; + goto fail_put_pages; + } + + if (!dma_map_sg(dev->dev, xen_obj->sgt->sgl, xen_obj->sgt->nents, + DMA_BIDIRECTIONAL)) { Are you using the DMA streaming API as a way to flush the caches? Does this mean that GFP_USER isn't making the buffer coherent? Noralf. + ret = -EFAULT; + goto fail_free_sgt; + } + return xen_obj; +fail_free_sgt: + sg_free_table(xen_obj->sgt); + xen_obj->sgt = NULL; +fail_put_pages: + drm_gem_put_pages(&xen_obj->base, xen_obj->pages, true, false); + xen_obj->pages = NULL; fail: DRM_ERROR("Failed to allocate buffer with size %zu\n", size); return ERR_PTR(ret); @@ -149,7 +186,7 @@ void xen_drm_front_gem_free_object_unlocked(struct drm_gem_object *gem_obj) struct xen_gem_object *xen_obj = to_xen_gem_obj(gem_obj); if (xen_obj->base.import_attach) { - drm_prime_gem_destroy(&xen_obj->base, xen_obj->sgt_imported); + drm_prime_gem_destroy(&xen_obj->base, xen_obj->sgt); gem_free_pages_array(xen_obj); } else { if (xen_obj->pages) { @@ -158,6 +195,13 @@ void xen_drm_front_gem_free_object_unlocked(struct drm_gem_object *gem_obj) xen_obj->pages); gem_free_pages_array(xen_obj); } else { + if (xen_obj->sgt) { + dma_unmap_sg(xen_obj->base.dev->dev, +xen_obj->sgt->sgl, +xen_obj->sgt->nents, +DMA_BIDIRECTIONAL); + sg_free_table(xen_obj->sgt); + } d
Re: [Xen-devel] [PATCH v2 2/3] drm/xen-front: Use Xen common shared buffer implementation
On 12/18/18 20:31, Boris Ostrovsky wrote: On 12/18/18 11:15 AM, Noralf Trønnes wrote: Den 30.11.2018 08.42, skrev Oleksandr Andrushchenko: From: Oleksandr Andrushchenko Use page directory based shared buffer implementation now available as common code for Xen frontend drivers. Remove flushing of shared buffer on page flip as this workaround needs a proper fix. Signed-off-by: Oleksandr Andrushchenko --- Reviewed-by: Noralf Trønnes Thank you, Noralf! Now that all 3 have been acked/reviewed Applied to for-linus-4.21 Thank you, Boris, Juergen! ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [Qemu-devel] [QEMU PATCH] block: Remove blk_attach_dev_legacy() / legacy_dev code
Thomas Huth writes: > The last user of blk_attach_dev_legacy() is the code in xen_disk.c. > It passes a pointer to a XenBlkDev as second parameter. XenBlkDev > is derived from XenDevice which in turn is derived from DeviceState > since commit 3a6c9172ac5951e ("xen: create qdev for each backend device"). > Thus the code can also simply use blk_attach_dev() with a pointer > to the DeviceState instead. > So we can finally remove all code related to the "legacy_dev" flag, too, > and turn the related "void *" in block-backend.c into "DeviceState *" > to fix some of the remaining TODOs there. > > Signed-off-by: Thomas Huth > --- > Note: I haven't tested the Xen code since I don't have a working Xen > installation at hand. I'd appreciate if someone could check it... Same here. All I can do is review. > block/block-backend.c | 54 > +++--- > hw/block/xen_disk.c| 6 +++-- > include/sysemu/block-backend.h | 5 ++-- > 3 files changed, 15 insertions(+), 50 deletions(-) > > diff --git a/block/block-backend.c b/block/block-backend.c > index 60d37a0..3c3118f 100644 > --- a/block/block-backend.c > +++ b/block/block-backend.c > @@ -47,9 +47,7 @@ struct BlockBackend { > QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ > BlockBackendPublic public; > > -void *dev; /* attached device model, if any */ > -bool legacy_dev;/* true if dev is not a DeviceState */ > -/* TODO change to DeviceState when all users are qdevified */ > +DeviceState *dev; /* attached device model, if any */ > const BlockDevOps *dev_ops; > void *dev_opaque; > > @@ -836,7 +834,11 @@ void blk_get_perm(BlockBackend *blk, uint64_t *perm, > uint64_t *shared_perm) > *shared_perm = blk->shared_perm; > } > > -static int blk_do_attach_dev(BlockBackend *blk, void *dev) > +/* > + * Attach device model @dev to @blk. > + * Return 0 on success, -EBUSY when a device model is attached already. > + */ > +int blk_attach_dev(BlockBackend *blk, DeviceState *dev) > { > if (blk->dev) { > return -EBUSY; > @@ -851,40 +853,16 @@ static int blk_do_attach_dev(BlockBackend *blk, void > *dev) > > blk_ref(blk); > blk->dev = dev; > -blk->legacy_dev = false; > blk_iostatus_reset(blk); > > return 0; > } > > /* > - * Attach device model @dev to @blk. > - * Return 0 on success, -EBUSY when a device model is attached already. > - */ > -int blk_attach_dev(BlockBackend *blk, DeviceState *dev) > -{ > -return blk_do_attach_dev(blk, dev); > -} > - > -/* > - * Attach device model @dev to @blk. > - * @blk must not have a device model attached already. > - * TODO qdevified devices don't use this, remove when devices are qdevified > - */ > -void blk_attach_dev_legacy(BlockBackend *blk, void *dev) > -{ > -if (blk_do_attach_dev(blk, dev) < 0) { > -abort(); > -} > -blk->legacy_dev = true; > -} > - > -/* > * Detach device model @dev from @blk. > * @dev must be currently attached to @blk. > */ > -void blk_detach_dev(BlockBackend *blk, void *dev) > -/* TODO change to DeviceState *dev when all users are qdevified */ > +void blk_detach_dev(BlockBackend *blk, DeviceState *dev) > { > assert(blk->dev == dev); > blk->dev = NULL; > @@ -898,8 +876,7 @@ void blk_detach_dev(BlockBackend *blk, void *dev) > /* > * Return the device model attached to @blk if any, else null. > */ > -void *blk_get_attached_dev(BlockBackend *blk) > -/* TODO change to return DeviceState * when all users are qdevified */ > +DeviceState *blk_get_attached_dev(BlockBackend *blk) > { > return blk->dev; > } > @@ -908,10 +885,7 @@ void *blk_get_attached_dev(BlockBackend *blk) > * device attached to the BlockBackend. */ > char *blk_get_attached_dev_id(BlockBackend *blk) > { > -DeviceState *dev; > - > -assert(!blk->legacy_dev); > -dev = blk->dev; > +DeviceState *dev = blk->dev; > > if (!dev) { > return g_strdup(""); > @@ -949,11 +923,6 @@ BlockBackend *blk_by_dev(void *dev) > void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, > void *opaque) > { > -/* All drivers that use blk_set_dev_ops() are qdevified and we want to > keep > - * it that way, so we can assume blk->dev, if present, is a DeviceState > if > - * blk->dev_ops is set. Non-device users may use dev_ops without device. > */ > -assert(!blk->legacy_dev); > - > blk->dev_ops = ops; > blk->dev_opaque = opaque; > > @@ -979,8 +948,6 @@ void blk_dev_change_media_cb(BlockBackend *blk, bool > load, Error **errp) > bool tray_was_open, tray_is_open; > Error *local_err = NULL; > > -assert(!blk->legacy_dev); > - > tray_was_open = blk_dev_is_tray_open(blk); > blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err); > if (local_err) { > @@ -1779,9 +1746,6 @@ void
Re: [Xen-devel] [PATCH v2 2/3] drm/xen-front: Use Xen common shared buffer implementation
On 12/18/18 11:15 AM, Noralf Trønnes wrote: > > Den 30.11.2018 08.42, skrev Oleksandr Andrushchenko: >> From: Oleksandr Andrushchenko >> >> Use page directory based shared buffer implementation >> now available as common code for Xen frontend drivers. >> >> Remove flushing of shared buffer on page flip as this >> workaround needs a proper fix. >> >> Signed-off-by: Oleksandr Andrushchenko >> >> --- > > Reviewed-by: Noralf Trønnes > Now that all 3 have been acked/reviewed Applied to for-linus-4.21 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [libvirt test] 131392: tolerable all pass - PUSHED
flight 131392 libvirt real [real] http://logs.test-lab.xenproject.org/osstest/logs/131392/ Failures :-/ but no regressions. Tests which did not succeed, but are not blocking: test-armhf-armhf-libvirt-raw 13 saverestore-support-checkfail like 131364 test-armhf-armhf-libvirt 14 saverestore-support-checkfail like 131364 test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-amd64-i386-libvirt 13 migrate-support-checkfail never pass test-amd64-i386-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-amd64-libvirt-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-libvirt-raw 12 migrate-support-checkfail never pass test-armhf-armhf-libvirt 13 migrate-support-checkfail never pass version targeted for testing: libvirt f8f525ff86e5458701289e6bdd9eea1f7875de57 baseline version: libvirt b2485c4ad725fede184b877a753900fd9a37a135 Last test of basis 131364 2018-12-16 18:31:26 Z1 days Testing same since 131392 2018-12-17 13:14:51 Z1 days1 attempts People who touched revisions under test: Radostin Stoyanov jobs: build-amd64-xsm pass build-i386-xsm pass build-amd64 pass build-armhf pass build-i386 pass build-amd64-libvirt pass build-armhf-libvirt pass build-i386-libvirt pass build-amd64-pvopspass build-armhf-pvopspass build-i386-pvops pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsmpass test-amd64-amd64-libvirt-xsm pass test-amd64-i386-libvirt-xsm pass test-amd64-amd64-libvirt pass test-armhf-armhf-libvirt pass test-amd64-i386-libvirt pass test-amd64-amd64-libvirt-pairpass test-amd64-i386-libvirt-pair pass test-armhf-armhf-libvirt-raw pass test-amd64-amd64-libvirt-vhd pass sg-report-flight on osstest.test-lab.xenproject.org logs: /home/logs/logs images: /home/logs/images Logs, config files, etc. are available at http://logs.test-lab.xenproject.org/osstest/logs Explanation of these reports, and of osstest in general, is at http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master Test harness code can be found at http://xenbits.xen.org/gitweb?p=osstest.git;a=summary Pushing revision : To xenbits.xen.org:/home/xen/git/libvirt.git b2485c4ad7..f8f525ff86 f8f525ff86e5458701289e6bdd9eea1f7875de57 -> xen-tested-master ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH for-4.12 v4 4/4] xen/arm: Track page accessed between batch of Set/Way operations
At the moment, the implementation of Set/Way operations will go through all the entries of the guest P2M and flush them. However, this is very expensive and may render unusable a guest OS using them. For instance, Linux 32-bit will use Set/Way operations during secondary CPU bring-up. As the implementation is really expensive, it may be possible to hit the CPU bring-up timeout. To limit the Set/Way impact, we track what pages has been of the guest has been accessed between batch of Set/Way operations. This is done using bit[0] (aka valid bit) of the P2M entry. This patch adds a new per-arch helper is introduced to perform actions just before the guest is first unpaused. This will be used to invalidate the P2M to track access from the start of the guest. Signed-off-by: Julien Grall Reviewed-by: Jan Beulich Reviewed-by: Stefano Stabellini --- While we can spread d->creation_finished all over the code, the per-arch helper to perform actions just before the guest is first unpaused can bring a lot of benefit for both architecture. For instance, on Arm, the flush to the instruction cache could be delayed until the domain is first run. This would improve greatly the performance of creating guest. Changes in v4: - Add Stefano's reviewed-by Changes in v3: - Add Jan reviewed-by for non-ARM pieces Cc: Stefano Stabellini Cc: Julien Grall Cc: Andrew Cooper Cc: George Dunlap Cc: Ian Jackson Cc: Jan Beulich Cc: Konrad Rzeszutek Wilk Cc: Tim Deegan Cc: Wei Liu --- xen/arch/arm/domain.c | 14 ++ xen/arch/arm/p2m.c| 29 +++-- xen/arch/x86/domain.c | 4 xen/common/domain.c | 5 - xen/include/asm-arm/p2m.h | 2 ++ xen/include/xen/domain.h | 2 ++ 6 files changed, 53 insertions(+), 3 deletions(-) diff --git a/xen/arch/arm/domain.c b/xen/arch/arm/domain.c index 1d926dcb29..41f101746e 100644 --- a/xen/arch/arm/domain.c +++ b/xen/arch/arm/domain.c @@ -767,6 +767,20 @@ int arch_domain_soft_reset(struct domain *d) return -ENOSYS; } +void arch_domain_creation_finished(struct domain *d) +{ +/* + * To avoid flushing the whole guest RAM on the first Set/Way, we + * invalidate the P2M to track what has been accessed. + * + * This is only turned when IOMMU is not used or the page-table are + * not shared because bit[0] (e.g valid bit) unset will result + * IOMMU fault that could be not fixed-up. + */ +if ( !iommu_use_hap_pt(d) ) +p2m_invalidate_root(p2m_get_hostp2m(d)); +} + static int is_guest_pv32_psr(uint32_t psr) { switch (psr & PSR_MODE_MASK) diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 22bec7390b..2b5e43f50a 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1079,6 +1079,22 @@ static void p2m_invalidate_table(struct p2m_domain *p2m, mfn_t mfn) } /* + * Invalidate all entries in the root page-tables. This is + * useful to get fault on entry and do an action. + */ +void p2m_invalidate_root(struct p2m_domain *p2m) +{ +unsigned int i; + +p2m_write_lock(p2m); + +for ( i = 0; i < P2M_ROOT_LEVEL; i++ ) +p2m_invalidate_table(p2m, page_to_mfn(p2m->root + i)); + +p2m_write_unlock(p2m); +} + +/* * Resolve any translation fault due to change in the p2m. This * includes break-before-make and valid bit cleared. */ @@ -1587,10 +1603,12 @@ int p2m_cache_flush_range(struct domain *d, gfn_t *pstart, gfn_t end) */ if ( gfn_eq(start, next_block_gfn) ) { -mfn = p2m_get_entry(p2m, start, &t, NULL, &order, NULL); +bool valid; + +mfn = p2m_get_entry(p2m, start, &t, NULL, &order, &valid); next_block_gfn = gfn_next_boundary(start, order); -if ( mfn_eq(mfn, INVALID_MFN) || !p2m_is_any_ram(t) ) +if ( mfn_eq(mfn, INVALID_MFN) || !p2m_is_any_ram(t) || !valid ) { count++; start = next_block_gfn; @@ -1624,6 +1642,7 @@ int p2m_cache_flush_range(struct domain *d, gfn_t *pstart, gfn_t end) */ void p2m_flush_vm(struct vcpu *v) { +struct p2m_domain *p2m = p2m_get_hostp2m(v->domain); int rc; gfn_t start = _gfn(0); @@ -1643,6 +1662,12 @@ void p2m_flush_vm(struct vcpu *v) "P2M has not been correctly cleaned (rc = %d)\n", rc); +/* + * Invalidate the p2m to track which page was modified by the guest + * between call of p2m_flush_vm(). + */ +p2m_invalidate_root(p2m); + v->arch.need_flush_to_ram = false; } diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index f5a1f325aa..32dc4253ff 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -765,6 +765,10 @@ int arch_domain_soft_reset(struct domain *d) return ret; } +void arch_domain_creation_finished(struct domain *d) +{ +} + /* * These are the masks of CR4 bits (subject to hardware availability) which a * PV guest may not legitim
[Xen-devel] [PATCH for-4.12 v4 2/4] xen/arm: vsysreg: Add wrapper to handle sysreg access trapped by HCR_EL2.TVM
A follow-up patch will require to emulate some accesses to system registers trapped by HCR_EL2.TVM. When set, all NS EL1 writes to the virtual memory control registers will be trapped to the hypervisor. This patch adds the infrastructure to passthrough the access to the host registers. Note that HCR_EL2.TVM will be set in a follow-up patch dynamically. Signed-off-by: Julien Grall Reviewed-by: Stefano Stabellini --- Changes in v4: - Add Stefano's reviewed by Changes in v2: - Add missing include vreg.h - Update documentation reference to the lastest one --- xen/arch/arm/arm64/vsysreg.c | 58 1 file changed, 58 insertions(+) diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c index 6e60824572..16ac9c344a 100644 --- a/xen/arch/arm/arm64/vsysreg.c +++ b/xen/arch/arm/arm64/vsysreg.c @@ -21,8 +21,49 @@ #include #include #include +#include #include +/* + * Macro to help generating helpers for registers trapped when + * HCR_EL2.TVM is set. + * + * Note that it only traps NS write access from EL1. + */ +#define TVM_REG(reg)\ +static bool vreg_emulate_##reg(struct cpu_user_regs *regs, \ + uint64_t *r, bool read) \ +{ \ +GUEST_BUG_ON(read); \ +WRITE_SYSREG64(*r, reg);\ +\ +return true;\ +} + +/* Defining helpers for emulating sysreg registers. */ +TVM_REG(SCTLR_EL1) +TVM_REG(TTBR0_EL1) +TVM_REG(TTBR1_EL1) +TVM_REG(TCR_EL1) +TVM_REG(ESR_EL1) +TVM_REG(FAR_EL1) +TVM_REG(AFSR0_EL1) +TVM_REG(AFSR1_EL1) +TVM_REG(MAIR_EL1) +TVM_REG(AMAIR_EL1) +TVM_REG(CONTEXTIDR_EL1) + +/* Macro to generate easily case for co-processor emulation */ +#define GENERATE_CASE(reg) \ +case HSR_SYSREG_##reg: \ +{ \ +bool res; \ +\ +res = vreg_emulate_sysreg64(regs, hsr, vreg_emulate_##reg); \ +ASSERT(res);\ +break; \ +} + void do_sysreg(struct cpu_user_regs *regs, const union hsr hsr) { @@ -44,6 +85,23 @@ void do_sysreg(struct cpu_user_regs *regs, break; /* + * HCR_EL2.TVM + * + * ARMv8 (DDI 0487D.a): Table D1-38 + */ +GENERATE_CASE(SCTLR_EL1) +GENERATE_CASE(TTBR0_EL1) +GENERATE_CASE(TTBR1_EL1) +GENERATE_CASE(TCR_EL1) +GENERATE_CASE(ESR_EL1) +GENERATE_CASE(FAR_EL1) +GENERATE_CASE(AFSR0_EL1) +GENERATE_CASE(AFSR1_EL1) +GENERATE_CASE(MAIR_EL1) +GENERATE_CASE(AMAIR_EL1) +GENERATE_CASE(CONTEXTIDR_EL1) + +/* * MDCR_EL2.TDRA * * ARMv8 (DDI 0487A.d): D1-1508 Table D1-57 -- 2.11.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH for-4.12 v4 3/4] xen/arm: Implement Set/Way operations
Set/Way operations are used to perform maintenance on a given cache. At the moment, Set/Way operations are not trapped and therefore a guest OS will directly act on the local cache. However, a vCPU may migrate to another pCPU in the middle of the processor. This will result to have cache with stale data (Set/Way are not propagated) potentially causing crash. This may be the cause of heisenbug noticed in Osstest [1]. Furthermore, Set/Way operations are not available on system cache. This means that OS, such as Linux 32-bit, relying on those operations to fully clean the cache before disabling MMU may break because data may sits in system caches and not in RAM. For more details about Set/Way, see the talk "The Art of Virtualizing Cache Maintenance" given at Xen Summit 2018 [2]. In the context of Xen, we need to trap Set/Way operations and emulate them. From the Arm Arm (B1.14.4 in DDI 046C.c), Set/Way operations are difficult to virtualized. So we can assume that a guest OS using them will suffer the consequence (i.e slowness) until developer removes all the usage of Set/Way. As the software is not allowed to infer the Set/Way to Physical Address mapping, Xen will need to go through the guest P2M and clean & invalidate all the entries mapped. Because Set/Way happen in batch (a loop on all Set/Way of a cache), Xen would need to go through the P2M for every instructions. This is quite expensive and would severely impact the guest OS. The implementation is re-using the KVM policy to limit the number of flush: - If we trap a Set/Way operations, we enable VM trapping (i.e HVC_EL2.TVM) to detect cache being turned on/off, and do a full clean. - We clean the caches when turning on and off - Once the caches are enabled, we stop trapping VM instructions [1] https://lists.xenproject.org/archives/html/xen-devel/2017-09/msg03191.html [2] https://fr.slideshare.net/xen_com_mgr/virtualizing-cache Signed-off-by: Julien Grall --- Changes in v4: - Fix typoes - Update comments - Remove unecessary {} Changes in v2: - Fix emulation for Set/Way cache flush arm64 sysreg - Add support for preemption - Check cache status on every VM traps in Arm64 - Remove spurious change --- xen/arch/arm/arm64/vsysreg.c | 17 + xen/arch/arm/p2m.c | 90 xen/arch/arm/traps.c | 25 +++- xen/arch/arm/vcpreg.c| 22 +++ xen/include/asm-arm/domain.h | 9 + xen/include/asm-arm/p2m.h| 20 ++ 6 files changed, 182 insertions(+), 1 deletion(-) diff --git a/xen/arch/arm/arm64/vsysreg.c b/xen/arch/arm/arm64/vsysreg.c index 16ac9c344a..8a85507d9d 100644 --- a/xen/arch/arm/arm64/vsysreg.c +++ b/xen/arch/arm/arm64/vsysreg.c @@ -34,9 +34,14 @@ static bool vreg_emulate_##reg(struct cpu_user_regs *regs, \ uint64_t *r, bool read) \ { \ +struct vcpu *v = current; \ +bool cache_enabled = vcpu_has_cache_enabled(v); \ +\ GUEST_BUG_ON(read); \ WRITE_SYSREG64(*r, reg);\ \ +p2m_toggle_cache(v, cache_enabled); \ +\ return true;\ } @@ -85,6 +90,18 @@ void do_sysreg(struct cpu_user_regs *regs, break; /* + * HCR_EL2.TSW + * + * ARMv8 (DDI 0487B.b): Table D1-42 + */ +case HSR_SYSREG_DCISW: +case HSR_SYSREG_DCCSW: +case HSR_SYSREG_DCCISW: +if ( !hsr.sysreg.read ) +p2m_set_way_flush(current); +break; + +/* * HCR_EL2.TVM * * ARMv8 (DDI 0487D.a): Table D1-38 diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index ff52cb178f..22bec7390b 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -1615,6 +1616,95 @@ int p2m_cache_flush_range(struct domain *d, gfn_t *pstart, gfn_t end) return rc; } +/* + * Clean & invalidate RAM associated to the guest vCPU. + * + * The function can only work with the current vCPU and should be called + * with IRQ enabled as the vCPU could get preempted. + */ +void p2m_flush_vm(struct vcpu *v) +{ +int rc; +gfn_t start = _gfn(0); + +ASSERT(v == current); +ASSERT(local_irq_is_enabled()); +ASSERT(v->arch.need_flush_to_ram); + +do +{ +rc = p2m_cache_flush_range(v->domain, &start, _gfn(ULONG_MAX)); +if ( rc == -ERESTART ) +do_softirq(); +} whil
[Xen-devel] [PATCH for-4.12 v4 1/4] xen/arm: vcpreg: Add wrappers to handle co-proc access trapped by HCR_EL2.TVM
A follow-up patch will require to emulate some accesses to some co-processors registers trapped by HCR_EL2.TVM. When set, all NS EL1 writes to the virtual memory control registers will be trapped to the hypervisor. This patch adds the infrastructure to passthrough the access to host registers. For convenience a bunch of helpers have been added to generate the different helpers. Note that HCR_EL2.TVM will be set in a follow-up patch dynamically. Signed-off-by: Julien Grall Reviewed-by: Stefano Stabellini --- Changes in v3: - Add Stefano's reviewed-by Changes in v2: - Add missing include vreg.h - Fixup mask TMV_REG32_COMBINED - Update comments --- xen/arch/arm/vcpreg.c| 149 +++ xen/include/asm-arm/cpregs.h | 1 + 2 files changed, 150 insertions(+) diff --git a/xen/arch/arm/vcpreg.c b/xen/arch/arm/vcpreg.c index 7b783e4bcc..550c25ec3f 100644 --- a/xen/arch/arm/vcpreg.c +++ b/xen/arch/arm/vcpreg.c @@ -23,8 +23,129 @@ #include #include #include +#include #include +/* + * Macros to help generating helpers for registers trapped when + * HCR_EL2.TVM is set. + * + * Note that it only traps NS write access from EL1. + * + * - TVM_REG() should not be used outside of the macros. It is there to + *help defining TVM_REG32() and TVM_REG64() + * - TVM_REG32(regname, xreg) and TVM_REG64(regname, xreg) are used to + *resp. generate helper accessing 32-bit and 64-bit register. "regname" + *is the Arm32 name and "xreg" the Arm64 name. + * - TVM_REG32_COMBINED(lowreg, hireg, xreg) are used to generate a + *pair of register sharing the same Arm64 register, but are 2 distinct + *Arm32 registers. "lowreg" and "hireg" contains the name for on Arm32 + *registers, "xreg" contains the name for the combined register on Arm64. + *The definition of "lowreg" and "higreg" match the Armv8 specification, + *this means "lowreg" is an alias to xreg[31:0] and "high" is an alias to + *xreg[63:32]. + * + */ + +/* The name is passed from the upper macro to workaround macro expansion. */ +#define TVM_REG(sz, func, reg...) \ +static bool func(struct cpu_user_regs *regs, uint##sz##_t *r, bool read)\ +{ \ +GUEST_BUG_ON(read); \ +WRITE_SYSREG##sz(*r, reg); \ +\ +return true;\ +} + +#define TVM_REG32(regname, xreg) TVM_REG(32, vreg_emulate_##regname, xreg) +#define TVM_REG64(regname, xreg) TVM_REG(64, vreg_emulate_##regname, xreg) + +#ifdef CONFIG_ARM_32 +#define TVM_REG32_COMBINED(lowreg, hireg, xreg) \ +/* Use TVM_REG directly to workaround macro expansion. */ \ +TVM_REG(32, vreg_emulate_##lowreg, lowreg) \ +TVM_REG(32, vreg_emulate_##hireg, hireg) + +#else /* CONFIG_ARM_64 */ +#define TVM_REG32_COMBINED(lowreg, hireg, xreg) \ +static bool vreg_emulate_##xreg(struct cpu_user_regs *regs, uint32_t *r,\ +bool read, bool hi) \ +{ \ +register_t reg = READ_SYSREG(xreg); \ +\ +GUEST_BUG_ON(read); \ +if ( hi ) /* reg[63:32] is AArch32 register hireg */\ +{ \ +reg &= GENMASK(31, 0); \ +reg |= ((uint64_t)*r) << 32;\ +} \ +else /* reg[31:0] is AArch32 register lowreg. */\ +{ \ +reg &= GENMASK(63, 32); \ +reg |= *r; \ +} \ +WRITE_SYSREG(reg, xreg);\ +\ +return true;\ +} \ +\ +static bool vreg_emulate_##lowreg(struct cpu_user_regs *regs, uint32_t *r, \ +
[Xen-devel] [PATCH for-4.12 v4 0/4] xen/arm: Implement Set/Way operations
Hi all, This is version 3 of the series to implement set/way. For more details see patch #3. Cheers, Julien Grall (4): xen/arm: vcpreg: Add wrappers to handle co-proc access trapped by HCR_EL2.TVM xen/arm: vsysreg: Add wrapper to handle sysreg access trapped by HCR_EL2.TVM xen/arm: Implement Set/Way operations xen/arm: Track page accessed between batch of Set/Way operations xen/arch/arm/arm64/vsysreg.c | 75 +++ xen/arch/arm/domain.c| 14 xen/arch/arm/p2m.c | 119 +- xen/arch/arm/traps.c | 25 ++- xen/arch/arm/vcpreg.c| 171 +++ xen/arch/x86/domain.c| 4 + xen/common/domain.c | 5 +- xen/include/asm-arm/cpregs.h | 1 + xen/include/asm-arm/domain.h | 9 +++ xen/include/asm-arm/p2m.h| 22 ++ xen/include/xen/domain.h | 2 + 11 files changed, 443 insertions(+), 4 deletions(-) -- 2.11.0 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH for-4.12 v3 4/5] xen/arm: Implement Set/Way operations
Hi Andrew, On 12/14/18 9:31 PM, Andrew Cooper wrote: On 14/12/2018 03:58, Julien Grall wrote: Set/Way operations are used to perform maintenance on a given cache. At the moment, Set/Way operations are not trapped and therefore a guest OS will directly act on the local cache. However, a vCPU may migrate to another pCPU in the middle of the processor. This will result to have cache with stall data (Set/Way are not propagated) potentially causing s/stall/stale/ ? Yes. I tend to confuse the both a lot. Cheers, ~Andrew -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH for-4.12 v3 3/5] xen/arm: p2m: Add support for preemption in p2m_cache_flush_range
Hi Stefano, On 12/14/18 9:27 PM, Stefano Stabellini wrote: On Fri, 14 Dec 2018, Julien Grall wrote: diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c index 17e2523fc1..5639e4b64c 100644 --- a/xen/arch/arm/p2m.c +++ b/xen/arch/arm/p2m.c @@ -1524,13 +1524,17 @@ int relinquish_p2m_mapping(struct domain *d) return rc; } -int p2m_cache_flush_range(struct domain *d, gfn_t start, gfn_t end) +int p2m_cache_flush_range(struct domain *d, gfn_t *pstart, gfn_t end) { struct p2m_domain *p2m = p2m_get_hostp2m(d); gfn_t next_block_gfn; +gfn_t start = *pstart; mfn_t mfn = INVALID_MFN; p2m_type_t t; unsigned int order; +int rc = 0; +/* Counter for preemption */ +unsigned long count = 0; No need for unsigned long, count could be unsigned int or even unsigned short. With this change: Reviewed-by: Stefano Stabellini I will use unsigned short and commit it. Thank you for the review! Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH -next] x86/xen: Fix read buffer overflow
On 12/18/18 6:28 AM, Andrew Cooper wrote: > On 18/12/2018 10:42, YueHaibing wrote: >> On 2018/12/18 16:31, Juergen Gross wrote: >>> On 18/12/2018 09:19, YueHaibing wrote: Fix smatch warning: arch/x86/xen/enlighten_pv.c:649 get_trap_addr() error: buffer overflow 'early_idt_handler_array' 32 <= 32 Fixes: 42b3a4cb5609 ("x86/xen: Support early interrupts in xen pv guests") Signed-off-by: YueHaibing --- arch/x86/xen/enlighten_pv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c index 2f6787f..81f200d 100644 --- a/arch/x86/xen/enlighten_pv.c +++ b/arch/x86/xen/enlighten_pv.c @@ -646,7 +646,7 @@ static bool __ref get_trap_addr(void **addr, unsigned int ist) if (nr == ARRAY_SIZE(trap_array) && *addr >= (void *)early_idt_handler_array[0] && - *addr < (void *)early_idt_handler_array[NUM_EXCEPTION_VECTORS]) { + *addr < (void *)early_idt_handler_array[NUM_EXCEPTION_VECTORS - 1]) { nr = (*addr - (void *)early_idt_handler_array[0]) / EARLY_IDT_HANDLER_SIZE; *addr = (void *)xen_early_idt_handler_array[nr]; >>> No, this patch is wrong. >>> >>> early_idt_handler_array is a 2-dimensional array: >>> >>> const char >>> early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; >>> >>> So above code doesn't do an out of bounds array access, but checks for >>> *addr being in the array or outside of it (note the "<" used for the >>> test). >> Thank you for your explanation. > This looks like a smatch bug. I'd feed it back upstream. +Dan > > It is explicitly permitted in the C spec to construct a pointer to > one-past-the-end of an array, for the purposes of a < comparison. > > I'm not entirely sure where the "32 <= 32" statement is coming from. > > ~Andrew ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [ovmf test] 131414: regressions - FAIL
flight 131414 ovmf real [real] http://logs.test-lab.xenproject.org/osstest/logs/131414/ Regressions :-( Tests which did not succeed and are blocking, including tests which could not be run: build-i3866 xen-buildfail REGR. vs. 129475 build-i386-xsm6 xen-buildfail REGR. vs. 129475 build-amd64-xsm 6 xen-buildfail REGR. vs. 129475 build-amd64 6 xen-buildfail REGR. vs. 129475 Tests which did not succeed, but are not blocking: build-i386-libvirt1 build-check(1) blocked n/a build-amd64-libvirt 1 build-check(1) blocked n/a test-amd64-amd64-xl-qemuu-ovmf-amd64 1 build-check(1) blocked n/a test-amd64-i386-xl-qemuu-ovmf-amd64 1 build-check(1) blocked n/a version targeted for testing: ovmf 736c436e5355e1370f13392a6cecf2cf260608a8 baseline version: ovmf 5ae3184d8c59f7bbb84bad482df6b8020ba58188 Last test of basis 129475 2018-11-05 21:13:11 Z 42 days Failing since129526 2018-11-06 20:49:26 Z 41 days 159 attempts Testing same since 131383 2018-12-17 08:12:19 Z1 days2 attempts People who touched revisions under test: Achin Gupta Ard Biesheuvel Bob Feng bob.c.f...@intel.com BobCF Chasel Chiu Chasel, Chiu Chen A Chen Dandan Bi David Wei Eric Dong Feng, Bob C Fu Siyuan Gary Lin Hao Wu Jaben Carsey Jeff Brasen Jian J Wang Jiaxin Wu Jiewen Yao Laszlo Ersek Leif Lindholm Liming Gao Liu Yu Marc Zyngier Marcin Wojtas Ming Huang Pedroa Liu Ruiyu Ni shenglei Shenglei Zhang Star Zeng Sughosh Ganu Sumit Garg Sun, Zailiang Thomas Abraham Ting Ye Tomasz Michalec Vijayenthiran Subramaniam Vladimir Olovyannikov Wang BinX A Wu Jiaxin Ye Ting Yonghong Zhu yuchenlin Zailiang Sun Zhang, Chao B Zhao, ZhiqiangX ZhiqiangX Zhao zwei4 jobs: build-amd64-xsm fail build-i386-xsm fail build-amd64 fail build-i386 fail build-amd64-libvirt blocked build-i386-libvirt blocked build-amd64-pvopspass build-i386-pvops pass test-amd64-amd64-xl-qemuu-ovmf-amd64 blocked test-amd64-i386-xl-qemuu-ovmf-amd64 blocked sg-report-flight on osstest.test-lab.xenproject.org logs: /home/logs/logs images: /home/logs/images Logs, config files, etc. are available at http://logs.test-lab.xenproject.org/osstest/logs Explanation of these reports, and of osstest in general, is at http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master Test harness code can be found at http://xenbits.xen.org/gitweb?p=osstest.git;a=summary Not pushing. (No revision log; it would be 3661 lines long.) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [xen-unstable-smoke test] 131428: tolerable all pass - PUSHED
flight 131428 xen-unstable-smoke real [real] http://logs.test-lab.xenproject.org/osstest/logs/131428/ Failures :-/ but no regressions. Tests which did not succeed, but are not blocking: test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass version targeted for testing: xen 19232b378fab04997c0612e5c19e82c29b59d99e baseline version: xen 3fd3fda9c26fc3c4f77250f795ed7ff9d38e2ec6 Last test of basis 131400 2018-12-17 17:00:32 Z0 days Testing same since 131428 2018-12-18 14:00:43 Z0 days1 attempts People who touched revisions under test: Andrew Cooper Jan Beulich Razvan Cojocaru jobs: build-amd64 pass build-armhf pass build-amd64-libvirt pass test-armhf-armhf-xl pass test-amd64-amd64-xl-qemuu-debianhvm-i386 pass test-amd64-amd64-libvirt pass sg-report-flight on osstest.test-lab.xenproject.org logs: /home/logs/logs images: /home/logs/images Logs, config files, etc. are available at http://logs.test-lab.xenproject.org/osstest/logs Explanation of these reports, and of osstest in general, is at http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README.email;hb=master http://xenbits.xen.org/gitweb/?p=osstest.git;a=blob;f=README;hb=master Test harness code can be found at http://xenbits.xen.org/gitweb?p=osstest.git;a=summary Pushing revision : To xenbits.xen.org:/home/xen/git/xen.git 3fd3fda9c2..19232b378f 19232b378fab04997c0612e5c19e82c29b59d99e -> smoke ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [linux-4.9 test] 131386: regressions - FAIL
flight 131386 linux-4.9 real [real] http://logs.test-lab.xenproject.org/osstest/logs/131386/ Regressions :-( Tests which did not succeed and are blocking, including tests which could not be run: test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 10 debian-hvm-install fail REGR. vs. 131317 test-armhf-armhf-xl-cubietruck 16 guest-start/debian.repeat fail REGR. vs. 131317 Tests which did not succeed, but are not blocking: test-amd64-i386-xl-qemut-win7-amd64 17 guest-stop fail like 131317 test-amd64-amd64-xl-qemut-win7-amd64 17 guest-stopfail like 131317 test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stopfail like 131317 test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail like 131317 test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stopfail like 131317 test-amd64-amd64-xl-qemuu-dmrestrict-amd64-dmrestrict 10 debian-hvm-install fail never pass test-amd64-amd64-xl-pvhv2-intel 12 guest-start fail never pass test-amd64-i386-xl-qemuu-dmrestrict-amd64-dmrestrict 10 debian-hvm-install fail never pass test-amd64-amd64-xl-pvhv2-amd 12 guest-start fail never pass test-amd64-amd64-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-amd64-i386-xl-pvshim12 guest-start fail never pass test-amd64-i386-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-i386-libvirt 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-armhf-armhf-xl-arndale 13 migrate-support-checkfail never pass test-armhf-armhf-xl-arndale 14 saverestore-support-checkfail never pass test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2 fail never pass test-amd64-amd64-libvirt-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-xl-credit2 13 migrate-support-checkfail never pass test-armhf-armhf-xl-credit2 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-cubietruck 13 migrate-support-checkfail never pass test-armhf-armhf-xl-cubietruck 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-multivcpu 13 migrate-support-checkfail never pass test-armhf-armhf-xl-multivcpu 14 saverestore-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-credit1 13 migrate-support-checkfail never pass test-armhf-armhf-xl-credit1 14 saverestore-support-checkfail never pass test-amd64-amd64-xl-qemut-ws16-amd64 17 guest-stop fail never pass test-amd64-i386-xl-qemut-ws16-amd64 17 guest-stop fail never pass test-amd64-i386-xl-qemuu-ws16-amd64 17 guest-stop fail never pass test-armhf-armhf-libvirt-raw 12 migrate-support-checkfail never pass test-armhf-armhf-libvirt-raw 13 saverestore-support-checkfail never pass test-armhf-armhf-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-libvirt 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-rtds 13 migrate-support-checkfail never pass test-armhf-armhf-xl-rtds 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-xl-vhd 13 saverestore-support-checkfail never pass test-amd64-amd64-xl-qemut-win10-i386 10 windows-installfail never pass test-amd64-amd64-xl-qemuu-win10-i386 10 windows-installfail never pass test-amd64-i386-xl-qemuu-win10-i386 10 windows-install fail never pass test-amd64-i386-xl-qemut-win10-i386 10 windows-install fail never pass version targeted for testing: linux0cff89461d557239296735d18b5a144c8f4b151b baseline version: linux9c2f007c3c5e713749227f179fbe926ce1d38407 Last test of basis 131317 2018-12-14 17:01:21 Z3 days Testing same since 131386 2018-12-17 09:10:13 Z1 days1 attempts People who touched revisions under test: Aaro Koskinen Aaron Brown Adam Ford Al Viro Andrew Bowers Andrew Morton Artem Savkov Catalin Marinas Christoph Paasch Colin Ian King Daniel Axtens Daniel Borkmann Dave Airlie David Howells David S. Miller David Sterba Eric Dumazet Felipe Balbi Filipe Manana Florian Westphal Greg Kroah-Hartman Guenter Roeck Heiner Kallweit Huacai Chen Ingo Molnar Janusz Krzysztofik Jarkko Nikula Jason Gunthorpe Jeff Kirsher Josh Elsasser Josh Poimboeuf Juergen Gross Julian Anastasov Kees Cook Kiran Kuma
Re: [Xen-devel] [PATCH v2 2/3] drm/xen-front: Use Xen common shared buffer implementation
Den 30.11.2018 08.42, skrev Oleksandr Andrushchenko: From: Oleksandr Andrushchenko Use page directory based shared buffer implementation now available as common code for Xen frontend drivers. Remove flushing of shared buffer on page flip as this workaround needs a proper fix. Signed-off-by: Oleksandr Andrushchenko --- Reviewed-by: Noralf Trønnes ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v7 4/6] xen/arm: zynqmp: implement zynqmp_eemi
Hi, On 12/17/18 10:10 PM, Stefano Stabellini wrote: +/* These calls are safe and always allowed. */ +case EEMI_FID(ZYNQMP_SIP_SVC_CALL_COUNT): +case EEMI_FID(ZYNQMP_SIP_SVC_UID): +case EEMI_FID(ZYNQMP_SIP_SVC_VERSION): +case EEMI_FID(PM_GET_TRUSTZONE_VERSION): +case EEMI_FID(PM_GET_API_VERSION): Above you say the call to PM_GET_API_VERSION are safe and always allowed. But looking at the ATF implementation the first call to PM_GET_API_VERSION will enable IPI IRQ. AFAICT, Dom0 will be the only domain to access IPI. So what happen if, in the Dom0less case, the guest is booting before and calling PM_GET_API_VERSION? I haven't looked in depth the other SIP functions to see whether there are other potential issue. Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [QEMU PATCH] block: Remove blk_attach_dev_legacy() / legacy_dev code
The last user of blk_attach_dev_legacy() is the code in xen_disk.c. It passes a pointer to a XenBlkDev as second parameter. XenBlkDev is derived from XenDevice which in turn is derived from DeviceState since commit 3a6c9172ac5951e ("xen: create qdev for each backend device"). Thus the code can also simply use blk_attach_dev() with a pointer to the DeviceState instead. So we can finally remove all code related to the "legacy_dev" flag, too, and turn the related "void *" in block-backend.c into "DeviceState *" to fix some of the remaining TODOs there. Signed-off-by: Thomas Huth --- Note: I haven't tested the Xen code since I don't have a working Xen installation at hand. I'd appreciate if someone could check it... block/block-backend.c | 54 +++--- hw/block/xen_disk.c| 6 +++-- include/sysemu/block-backend.h | 5 ++-- 3 files changed, 15 insertions(+), 50 deletions(-) diff --git a/block/block-backend.c b/block/block-backend.c index 60d37a0..3c3118f 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -47,9 +47,7 @@ struct BlockBackend { QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */ BlockBackendPublic public; -void *dev; /* attached device model, if any */ -bool legacy_dev;/* true if dev is not a DeviceState */ -/* TODO change to DeviceState when all users are qdevified */ +DeviceState *dev; /* attached device model, if any */ const BlockDevOps *dev_ops; void *dev_opaque; @@ -836,7 +834,11 @@ void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm) *shared_perm = blk->shared_perm; } -static int blk_do_attach_dev(BlockBackend *blk, void *dev) +/* + * Attach device model @dev to @blk. + * Return 0 on success, -EBUSY when a device model is attached already. + */ +int blk_attach_dev(BlockBackend *blk, DeviceState *dev) { if (blk->dev) { return -EBUSY; @@ -851,40 +853,16 @@ static int blk_do_attach_dev(BlockBackend *blk, void *dev) blk_ref(blk); blk->dev = dev; -blk->legacy_dev = false; blk_iostatus_reset(blk); return 0; } /* - * Attach device model @dev to @blk. - * Return 0 on success, -EBUSY when a device model is attached already. - */ -int blk_attach_dev(BlockBackend *blk, DeviceState *dev) -{ -return blk_do_attach_dev(blk, dev); -} - -/* - * Attach device model @dev to @blk. - * @blk must not have a device model attached already. - * TODO qdevified devices don't use this, remove when devices are qdevified - */ -void blk_attach_dev_legacy(BlockBackend *blk, void *dev) -{ -if (blk_do_attach_dev(blk, dev) < 0) { -abort(); -} -blk->legacy_dev = true; -} - -/* * Detach device model @dev from @blk. * @dev must be currently attached to @blk. */ -void blk_detach_dev(BlockBackend *blk, void *dev) -/* TODO change to DeviceState *dev when all users are qdevified */ +void blk_detach_dev(BlockBackend *blk, DeviceState *dev) { assert(blk->dev == dev); blk->dev = NULL; @@ -898,8 +876,7 @@ void blk_detach_dev(BlockBackend *blk, void *dev) /* * Return the device model attached to @blk if any, else null. */ -void *blk_get_attached_dev(BlockBackend *blk) -/* TODO change to return DeviceState * when all users are qdevified */ +DeviceState *blk_get_attached_dev(BlockBackend *blk) { return blk->dev; } @@ -908,10 +885,7 @@ void *blk_get_attached_dev(BlockBackend *blk) * device attached to the BlockBackend. */ char *blk_get_attached_dev_id(BlockBackend *blk) { -DeviceState *dev; - -assert(!blk->legacy_dev); -dev = blk->dev; +DeviceState *dev = blk->dev; if (!dev) { return g_strdup(""); @@ -949,11 +923,6 @@ BlockBackend *blk_by_dev(void *dev) void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque) { -/* All drivers that use blk_set_dev_ops() are qdevified and we want to keep - * it that way, so we can assume blk->dev, if present, is a DeviceState if - * blk->dev_ops is set. Non-device users may use dev_ops without device. */ -assert(!blk->legacy_dev); - blk->dev_ops = ops; blk->dev_opaque = opaque; @@ -979,8 +948,6 @@ void blk_dev_change_media_cb(BlockBackend *blk, bool load, Error **errp) bool tray_was_open, tray_is_open; Error *local_err = NULL; -assert(!blk->legacy_dev); - tray_was_open = blk_dev_is_tray_open(blk); blk->dev_ops->change_media_cb(blk->dev_opaque, load, &local_err); if (local_err) { @@ -1779,9 +1746,6 @@ void blk_eject(BlockBackend *blk, bool eject_flag) BlockDriverState *bs = blk_bs(blk); char *id; -/* blk_eject is only called by qdevified devices */ -assert(!blk->legacy_dev); - if (bs) { bdrv_eject(bs, eject_flag); } diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c index 36eff94..9605caf 100644 ---
[Xen-devel] [PATCH 0/3] x86/mm-locks: add a bias to current domain lock levels
Hello, The following series attempts to fix a mm lock level issue that prevents using paging_log_dirty_op from paging callers (like a PVH Dom0). The discussion that lead to this series can be found at: https://lists.xenproject.org/archives/html/xen-devel/2018-12/msg01197.html Thanks, Roger. Roger Pau Monne (3): x86/mm-locks: remove trailing whitespace x86/mm-locks: convert some macros to inline functions x86/mm-locks: apply a bias to lock levels for current domain xen/arch/x86/mm/mm-locks.h | 217 ++--- xen/arch/x86/mm/p2m-pod.c | 5 +- 2 files changed, 130 insertions(+), 92 deletions(-) -- 2.19.2 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH 3/3] x86/mm-locks: apply a bias to lock levels for current domain
paging_log_dirty_op function takes mm locks from a subject domain and then attempts to perform copy to operations against the caller domain in order to copy the result of the hypercall into the caller provided buffer. This works fine when the caller is a non-paging domain, but triggers a lock order panic when the caller is a paging domain due to the fact that at the point where the copy to operation is performed the subject domain paging lock is locked, and the copy operation requires locking the caller p2m lock which has a lower level. Fix this limitation by adding a bias to the level of the caller domain mm locks, so that the lower caller domain mm lock always has a level greater than the higher subject domain lock level. This allows locking the subject domain mm locks and then locking the caller domain mm locks, while keeping the same lock ordering and the changes mostly confined to mm-locks.h. Note that so far only this flow (locking a subject domain locks and then the caller domain ones) has been identified, but not all possible code paths have been inspected. Hence this solution attempts to be a non-intrusive fix for the problem at hand, without discarding further changes in the future if other valid code paths are found that require more complex lock level ordering. Signed-off-by: Roger Pau Monné --- Cc: George Dunlap Cc: Jan Beulich Cc: Andrew Cooper Cc: Wei Liu Cc: Tim Deegan --- xen/arch/x86/mm/mm-locks.h | 119 +++-- xen/arch/x86/mm/p2m-pod.c | 5 +- 2 files changed, 78 insertions(+), 46 deletions(-) diff --git a/xen/arch/x86/mm/mm-locks.h b/xen/arch/x86/mm/mm-locks.h index d3497713e9..055f63e7ec 100644 --- a/xen/arch/x86/mm/mm-locks.h +++ b/xen/arch/x86/mm/mm-locks.h @@ -50,15 +50,35 @@ static inline int _get_lock_level(void) return this_cpu(mm_lock_level); } +#define MM_LOCK_ORDER_MAX64 +/* + * Return the lock level taking the domain bias into account. If the domain + * matches the currently running one a bias of MM_LOCK_ORDER_MAX is applied to + * the lock level, so that mm locks that belong to the caller domain can be + * acquired after having acquired mm locks of a subject domain. + * + * This is required in order to use some hypercalls from a paging domain that + * take locks of a subject domain and then attempt to copy data to/from the + * caller domain. + */ +static inline int _lock_level(const struct domain *d, int l) +{ +ASSERT(l <= MM_LOCK_ORDER_MAX); + +return l + (d == current->domain ? MM_LOCK_ORDER_MAX : 0); +} + /* * If you see this crash, the numbers printed are order levels defined * in this file. */ -static inline void _check_lock_level(int l) +static inline void _check_lock_level(const struct domain *d, int l) { -if ( unlikely(_get_lock_level() > l) ) +int lvl = _lock_level(d, l); + +if ( unlikely(_get_lock_level() > lvl) ) { -printk("mm locking order violation: %i > %i\n", _get_lock_level(), l); +printk("mm locking order violation: %i > %i\n", _get_lock_level(), lvl); BUG(); } } @@ -68,10 +88,11 @@ static inline void _set_lock_level(int l) this_cpu(mm_lock_level) = l; } -static inline void _mm_lock(mm_lock_t *l, const char *func, int level, int rec) +static inline void _mm_lock(const struct domain *d, mm_lock_t *l, +const char *func, int level, int rec) { if ( !((mm_locked_by_me(l)) && rec) ) -_check_lock_level(level); +_check_lock_level(d, level); spin_lock_recursive(&l->lock); if ( l->lock.recurse_cnt == 1 ) { @@ -80,16 +101,17 @@ static inline void _mm_lock(mm_lock_t *l, const char *func, int level, int rec) } else if ( (unlikely(!rec)) ) panic("mm lock already held by %s\n", l->locker_function); -_set_lock_level(level); +_set_lock_level(_lock_level(d, level)); } -static inline void _mm_enforce_order_lock_pre(int level) +static inline void _mm_enforce_order_lock_pre(const struct domain *d, int level) { -_check_lock_level(level); +_check_lock_level(d, level); } -static inline void _mm_enforce_order_lock_post(int level, int *unlock_level, -unsigned short *recurse_count) +static inline void _mm_enforce_order_lock_post(const struct domain *d, int level, + int *unlock_level, + unsigned short *recurse_count) { if ( recurse_count ) { @@ -100,7 +122,7 @@ static inline void _mm_enforce_order_lock_post(int level, int *unlock_level, } else { *unlock_level = _get_lock_level(); } -_set_lock_level(level); +_set_lock_level(_lock_level(d, level)); } @@ -117,16 +139,17 @@ static inline int mm_write_locked_by_me(mm_rwlock_t *l) return (l->locker == get_processor_id()); } -static inline void _mm_write_lock(mm_rwlock_t *l, const char *func, int level
[Xen-devel] [PATCH 1/3] x86/mm-locks: remove trailing whitespace
No functional change. Signed-off-by: Roger Pau Monné --- Cc: George Dunlap Cc: Jan Beulich Cc: Andrew Cooper Cc: Wei Liu --- xen/arch/x86/mm/mm-locks.h | 24 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/mm/mm-locks.h b/xen/arch/x86/mm/mm-locks.h index 95295b62d2..64b8775a6d 100644 --- a/xen/arch/x86/mm/mm-locks.h +++ b/xen/arch/x86/mm/mm-locks.h @@ -3,11 +3,11 @@ * * Spinlocks used by the code in arch/x86/mm. * - * Copyright (c) 2011 Citrix Systems, inc. + * Copyright (c) 2011 Citrix Systems, inc. * Copyright (c) 2007 Advanced Micro Devices (Wei Huang) * Copyright (c) 2006-2007 XenSource Inc. * Copyright (c) 2006 Michael A Fetterman - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -41,7 +41,7 @@ static inline void mm_lock_init(mm_lock_t *l) l->unlock_level = 0; } -static inline int mm_locked_by_me(mm_lock_t *l) +static inline int mm_locked_by_me(mm_lock_t *l) { return (l->lock.recurse_cpu == current->processor); } @@ -67,7 +67,7 @@ do {\ static inline void _mm_lock(mm_lock_t *l, const char *func, int level, int rec) { -if ( !((mm_locked_by_me(l)) && rec) ) +if ( !((mm_locked_by_me(l)) && rec) ) __check_lock_level(level); spin_lock_recursive(&l->lock); if ( l->lock.recurse_cnt == 1 ) @@ -186,7 +186,7 @@ static inline void mm_unlock(mm_lock_t *l) spin_unlock_recursive(&l->lock); } -static inline void mm_enforce_order_unlock(int unlock_level, +static inline void mm_enforce_order_unlock(int unlock_level, unsigned short *recurse_count) { if ( recurse_count ) @@ -310,7 +310,7 @@ declare_mm_rwlock(altp2m); #define gfn_locked_by_me(p,g) p2m_locked_by_me(p) /* PoD lock (per-p2m-table) - * + * * Protects private PoD data structs: entry and cache * counts, page lists, sweep parameters. */ @@ -322,7 +322,7 @@ declare_mm_lock(pod) /* Page alloc lock (per-domain) * - * This is an external lock, not represented by an mm_lock_t. However, + * This is an external lock, not represented by an mm_lock_t. However, * pod code uses it in conjunction with the p2m lock, and expecting * the ordering which we enforce here. * The lock is not recursive. */ @@ -338,13 +338,13 @@ declare_mm_order_constraint(page_alloc) * For shadow pagetables, this lock protects * - all changes to shadow page table pages * - the shadow hash table - * - the shadow page allocator + * - the shadow page allocator * - all changes to guest page table pages * - all changes to the page_info->tlbflush_timestamp - * - the page_info->count fields on shadow pages - * - * For HAP, it protects the NPT/EPT tables and mode changes. - * + * - the page_info->count fields on shadow pages + * + * For HAP, it protects the NPT/EPT tables and mode changes. + * * It also protects the log-dirty bitmap from concurrent accesses (and * teardowns, etc). */ -- 2.19.2 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH 2/3] x86/mm-locks: convert some macros to inline functions
And rename to have only one prefix underscore where applicable. No functional change. Signed-off-by: Roger Pau Monné --- Cc: George Dunlap Cc: Jan Beulich Cc: Andrew Cooper Cc: Wei Liu --- xen/arch/x86/mm/mm-locks.h | 96 -- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/xen/arch/x86/mm/mm-locks.h b/xen/arch/x86/mm/mm-locks.h index 64b8775a6d..d3497713e9 100644 --- a/xen/arch/x86/mm/mm-locks.h +++ b/xen/arch/x86/mm/mm-locks.h @@ -29,7 +29,6 @@ /* Per-CPU variable for enforcing the lock ordering */ DECLARE_PER_CPU(int, mm_lock_level); -#define __get_lock_level() (this_cpu(mm_lock_level)) DECLARE_PERCPU_RWLOCK_GLOBAL(p2m_percpu_rwlock); @@ -46,43 +45,47 @@ static inline int mm_locked_by_me(mm_lock_t *l) return (l->lock.recurse_cpu == current->processor); } +static inline int _get_lock_level(void) +{ +return this_cpu(mm_lock_level); +} + /* * If you see this crash, the numbers printed are order levels defined * in this file. */ -#define __check_lock_level(l) \ -do {\ -if ( unlikely(__get_lock_level() > (l)) ) \ -{ \ -printk("mm locking order violation: %i > %i\n", \ - __get_lock_level(), (l));\ -BUG(); \ -} \ -} while(0) - -#define __set_lock_level(l) \ -do {\ -__get_lock_level() = (l); \ -} while(0) +static inline void _check_lock_level(int l) +{ +if ( unlikely(_get_lock_level() > l) ) +{ +printk("mm locking order violation: %i > %i\n", _get_lock_level(), l); +BUG(); +} +} + +static inline void _set_lock_level(int l) +{ +this_cpu(mm_lock_level) = l; +} static inline void _mm_lock(mm_lock_t *l, const char *func, int level, int rec) { if ( !((mm_locked_by_me(l)) && rec) ) -__check_lock_level(level); +_check_lock_level(level); spin_lock_recursive(&l->lock); if ( l->lock.recurse_cnt == 1 ) { l->locker_function = func; -l->unlock_level = __get_lock_level(); +l->unlock_level = _get_lock_level(); } else if ( (unlikely(!rec)) ) panic("mm lock already held by %s\n", l->locker_function); -__set_lock_level(level); +_set_lock_level(level); } static inline void _mm_enforce_order_lock_pre(int level) { -__check_lock_level(level); +_check_lock_level(level); } static inline void _mm_enforce_order_lock_post(int level, int *unlock_level, @@ -92,12 +95,12 @@ static inline void _mm_enforce_order_lock_post(int level, int *unlock_level, { if ( (*recurse_count)++ == 0 ) { -*unlock_level = __get_lock_level(); +*unlock_level = _get_lock_level(); } } else { -*unlock_level = __get_lock_level(); +*unlock_level = _get_lock_level(); } -__set_lock_level(level); +_set_lock_level(level); } @@ -118,12 +121,12 @@ static inline void _mm_write_lock(mm_rwlock_t *l, const char *func, int level) { if ( !mm_write_locked_by_me(l) ) { -__check_lock_level(level); +_check_lock_level(level); percpu_write_lock(p2m_percpu_rwlock, &l->lock); l->locker = get_processor_id(); l->locker_function = func; -l->unlock_level = __get_lock_level(); -__set_lock_level(level); +l->unlock_level = _get_lock_level(); +_set_lock_level(level); } l->recurse_count++; } @@ -134,13 +137,13 @@ static inline void mm_write_unlock(mm_rwlock_t *l) return; l->locker = -1; l->locker_function = "nobody"; -__set_lock_level(l->unlock_level); +_set_lock_level(l->unlock_level); percpu_write_unlock(p2m_percpu_rwlock, &l->lock); } static inline void _mm_read_lock(mm_rwlock_t *l, int level) { -__check_lock_level(level); +_check_lock_level(level); percpu_read_lock(p2m_percpu_rwlock, &l->lock); /* There's nowhere to store the per-CPU unlock level so we can't * set the lock level. */ @@ -181,7 +184,7 @@ static inline void mm_unlock(mm_lock_t *l) if ( l->lock.recurse_cnt == 1 ) { l->locker_function = "nobody"; -__set_lock_level(l->unlock_level); +_set_lock_level(l->unlock_level); } spin_unlock_recursive(&l->lock); } @@ -194,10 +197,10 @@ static inline void mm_enforce_order_unlock(int unlock_level, BUG_ON(*recurse_count == 0); if ( (*recurse_count)-- == 1 ) { -__set_lock_level(unlock_level); +_set_lock_level(unlock_level); } } else { -__set_lock_level(unlock_level); +_set_lock_level(unlock_level); } } @@ -287,21 +290,24 @@ declare_mm_lock(altp2mlist) #defi
Re: [Xen-devel] [PATCH v7 6/6] xen/zynqmp: add IPI calls virtualization
Hi Stefano, On 12/17/18 10:10 PM, Stefano Stabellini wrote: ZynqMP IPI mailbox calls are a small set of EEMI sister calls, often used in conjunction with EEMI related functionalities. Unfortunately they are not part of the EEMI spec, or any other public spec, but the implementation is upstream in ATF: https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.h And patches are close to getting into Linux: https://patchwork.kernel.org/cover/10689501/ Signed-off-by: Stefano Stabellini Acked-by: Julien Grall Cheers, --- Changes in v7: - add IPI_MAILBOX_FID and use it - remove tabs Changes in v6: - new patch --- xen/arch/arm/platforms/xilinx-zynqmp-eemi.c| 18 ++ xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h | 15 +++ 2 files changed, 33 insertions(+) diff --git a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c index f2fc5b5..7cd3936 100644 --- a/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c +++ b/xen/arch/arm/platforms/xilinx-zynqmp-eemi.c @@ -25,6 +25,9 @@ * EEMI firmware API: * https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf * + * IPI firmware API: + * https://github.com/ARM-software/arm-trusted-firmware/blob/master/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.h + * * Power domain node_ids identify the area of effect of the power * management operations. They are the first parameter passed to power * management EEMI calls. @@ -156,6 +159,21 @@ bool zynqmp_eemi(struct cpu_user_regs *regs) ret = XST_PM_NO_ACCESS; goto done; +case IPI_MAILBOX_FID(IPI_MAILBOX_OPEN): +case IPI_MAILBOX_FID(IPI_MAILBOX_RELEASE): +case IPI_MAILBOX_FID(IPI_MAILBOX_STATUS_ENQUIRY): +case IPI_MAILBOX_FID(IPI_MAILBOX_NOTIFY): +case IPI_MAILBOX_FID(IPI_MAILBOX_ACK): +case IPI_MAILBOX_FID(IPI_MAILBOX_ENABLE_IRQ): +case IPI_MAILBOX_FID(IPI_MAILBOX_DISABLE_IRQ): +if ( !is_hardware_domain(current->domain) ) +{ +gprintk(XENLOG_WARNING, "IPI mailbox: fn=%u No access", pm_fn); +ret = XST_PM_NO_ACCESS; +goto done; +} +goto forward_to_fw; + default: gprintk(XENLOG_WARNING, "zynqmp-pm: Unhandled PM Call: %u\n", fid); return false; diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h index 9779b6a..c27fec6 100644 --- a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h +++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h @@ -106,6 +106,21 @@ enum pm_ret_status { XST_PM_ABORT_SUSPEND, }; +/* IPI SMC function numbers enum definition and fids */ +#define IPI_MAILBOX_FID(fid) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ +ARM_SMCCC_CONV_32, \ +ARM_SMCCC_OWNER_SIP, \ +fid) +enum ipi_api_id { +IPI_MAILBOX_OPEN = 0x1000, +IPI_MAILBOX_RELEASE, +IPI_MAILBOX_STATUS_ENQUIRY, +IPI_MAILBOX_NOTIFY, +IPI_MAILBOX_ACK, +IPI_MAILBOX_ENABLE_IRQ, +IPI_MAILBOX_DISABLE_IRQ, +}; + extern bool zynqmp_eemi(struct cpu_user_regs *regs); #endif /* __ASM_ARM_PLATFORMS_ZYNQMP_H */ -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v7 5/6] xen/arm: zynqmp: Remove blacklist of ZynqMP's PM node
Hi Stefano, On 12/17/18 10:10 PM, Stefano Stabellini wrote: From: "Edgar E. Iglesias" From: Edgar E. Iglesias Stop blacklisting ZynqMP's power management node. It is now possible since we allow the hardware domain to issue HVC/SMC calls to firmware. Signed-off-by: Edgar E. Iglesias Signed-off-by: Stefano Stabellini Reviewed-by: Stefano Stabellini Acked-by: Julien Grall Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v7 4/6] xen/arm: zynqmp: implement zynqmp_eemi
Hi Stefano, On 12/17/18 10:10 PM, Stefano Stabellini wrote: +/* These calls are safe and always allowed. */ +case EEMI_FID(ZYNQMP_SIP_SVC_CALL_COUNT): +case EEMI_FID(ZYNQMP_SIP_SVC_UID): +case EEMI_FID(ZYNQMP_SIP_SVC_VERSION): I am a bit surprised that you implement those one using SMC64. Why would you duplicate the SMC32 version (ARM_SMCCC_CALL_COUNT_FID(SIP))? I also don't seem to find them neither in the spec nor in the ATF code. The rest of the code looks good to me. Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v3 1/2] xen/pt: fix some pass-thru devices don't work across reboot
>>> On 18.12.18 at 15:43, wrote: > I find some pass-thru devices don't work any more across guest > reboot. Assigning it to another domain also meets the same issue. And > the only way to make it work again is un-binding and binding it to > pciback. Someone reported this issue one year ago [1]. > > If the device's driver doesn't disable MSI-X during shutdown or qemu is > killed/crashed before the domain shutdown, this domain's pirq won't be > unmapped. Then xen takes over this work, unmapping all pirq-s, when > destroying guest. But as pciback has already disabled meory decoding before > xen unmapping pirq, Xen has to sets the host_maskall flag and maskall bit > to mask a MSI rather than sets maskbit in MSI-x table. The call trace of > this process is: > > ->arch_domain_destroy > ->free_domain_pirqs > ->unmap_domain_pirq (if pirq isn't unmapped by qemu) > ->pirq_guest_force_unbind > ->__pirq_guest_unbind > ->mask_msi_irq(=desc->handler->disable()) > ->the warning in msi_set_mask_bit() > > The host_maskall bit will prevent guests from clearing the maskall bit > even the device is assigned to another guest later. Then guests cannot > receive MSIs from this device. > > To fix this issue, a pirq is unmapped before memory decoding is disabled by > pciback. Specifically, when a device is detached from a guest, all established > mappings between pirq and msi are destroying before changing the ownership. > > [1]: > https://lists.xenproject.org/archives/html/xen-devel/2017-09/msg02520.html > > Signed-off-by: Chao Gao > --- > Applied this patch, qemu would report the error below: > [00:05.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, > pirq: 302, gvec: 0xd5) > [00:05.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, > pirq: 301, gvec: 0xe5) > [00:04.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, > pirq: 359, gvec: 0x41) > [00:04.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, > pirq: 358, gvec: 0x51) > > Despite of the error, guest shutdown or device hotplug finishs smoothly. > It seems to me that qemu tries to unbind a msi which is already unbound by > the code added by this patch. I am not sure whether it is acceptable to > leave this error there. Well, the errors mean that qemu is playing with a device that's no longer owned by the guest controlled by this qemu instance. At least with a de-privileged qemu (no idea whether this actually works with pass-through) that's still a mistake, and hence would need fixing. Whichever entity it is that invokes the de-assign of the device, other involved parties should be informed so that they can keep their hands off the device from that point onwards. The hypervisor change itself looks mostly fine, just a few minor comments. > --- a/xen/drivers/passthrough/pci.c > +++ b/xen/drivers/passthrough/pci.c > @@ -368,6 +368,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, > u8 bus, u8 devfn) > return NULL; > } > spin_lock_init(&msix->table_lock); > +msix->warned = DOMID_INVALID; This is an arch-specific field right now; in fact the entire structure is arch-specific. Playing with any of its fields in common code is undesirable, but I guess the use of ->table_lock can be taken as an excuse until this code wants to eventually be used by Arm. (The structure requiring a lock is sufficiently generic, whereas the "warned" field may not be universally needed.) > @@ -1514,6 +1515,52 @@ static int assign_device(struct domain *d, u16 seg, u8 > bus, u8 devfn, u32 flag) > return rc; > } > > +/* > + * Unmap established mappings between domain's pirq and device's MSI. > + * These mappings were set up by qemu/guest and are expected to be > + * destroyed when changing the device's ownership. > + */ > +static void pci_unmap_msi(struct pci_dev *pdev) > +{ > +struct msi_desc *entry, *tmp; > + > +ASSERT(pcidevs_locked()); > + > +if ( !pdev->domain ) There are quite a few uses of pdev->domain - please consider using a local variable. > +return; > + > +spin_lock(&pdev->domain->event_lock); > +list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list ) > +{ > +struct pirq *info; > +struct hvm_pirq_dpci *pirq_dpci; > +int pirq = domain_irq_to_pirq(pdev->domain, entry->irq), pirq_orig; > + > +pirq_orig = pirq; > + > +if ( !pirq ) > +continue; > + > +/* For forcibly unmapped pirq, lookup radix tree with absolute value > */ > +if ( pirq < 0) > +pirq = -pirq; > + > +info = pirq_info(pdev->domain, pirq); Why not simply info = pirq_info(pdev->domain, ABS(pirq)); without any pirq_orig? Jan ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/x
Re: [Xen-devel] [PATCH v7 3/6] xen/arm: zynqmp: introduce zynqmp specific defines
Hi Stefano, On 12/17/18 10:10 PM, Stefano Stabellini wrote: From: "Edgar E. Iglesias" From: Edgar E. Iglesias Introduce zynqmp specific defines for the firmware calls. See EEMI: https://www.xilinx.com/support/documentation/user_guides/ug1200-eemi-api.pdf The error codes are described, under XIlPM Error Codes: https://www.xilinx.com/support/documentation/user_guides/ug1137-zynq-ultrascale-mpsoc-swdev.pdf - pm_api_id These are the EEMI function IDs. Unavoidable. - pm_ret_status These are the EEMI return statuses. Unavoidable. Signed-off-by: Edgar E. Iglesias Signed-off-by: Stefano Stabellini --- Changes in v7: - introduce EEMI_FID - remove tabs Changes in v6: - improve commit message - remove MM_*, node ids and reset ids Changes in v5: - remove MMIO access related definitions Changes in v4: - define PM_MMIO_SHIFT --- xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h | 90 ++ 1 file changed, 90 insertions(+) diff --git a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h index 43cefb5..9779b6a 100644 --- a/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h +++ b/xen/include/asm-arm/platforms/xilinx-zynqmp-eemi.h @@ -15,6 +15,96 @@ #define __ASM_ASM_PLATFORMS_ZYNQMP_H #include +#include + +/* Service calls. */ +#define PM_GET_TRUSTZONE_VERSION 0xa03 Why does not this belong to the pm_api_id below? + +/* SMC function IDs for SiP Service queries */ +#define ZYNQMP_SIP_SVC_CALL_COUNT 0xff00 +#define ZYNQMP_SIP_SVC_UID 0xff01 +#define ZYNQMP_SIP_SVC_VERSION 0xff03 > + +#define EEMI_FID(fid) ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ + ARM_SMCCC_CONV_64, \ + ARM_SMCCC_OWNER_SIP, \ + fid) + +enum pm_api_id { +/* Miscellaneous API functions: */ +PM_GET_API_VERSION = 1, /* Do not change or move */ +PM_SET_CONFIGURATION, +PM_GET_NODE_STATUS, +PM_GET_OP_CHARACTERISTIC, +PM_REGISTER_NOTIFIER, +/* API for suspending of PUs: */ +PM_REQ_SUSPEND, +PM_SELF_SUSPEND, +PM_FORCE_POWERDOWN, +PM_ABORT_SUSPEND, +PM_REQ_WAKEUP, +PM_SET_WAKEUP_SOURCE, +PM_SYSTEM_SHUTDOWN, +/* API for managing PM slaves: */ +PM_REQ_NODE, +PM_RELEASE_NODE, +PM_SET_REQUIREMENT, +PM_SET_MAX_LATENCY, +/* Direct control API functions: */ +PM_RESET_ASSERT, +PM_RESET_GET_STATUS, +PM_MMIO_WRITE, +PM_MMIO_READ, +PM_INIT, +PM_FPGA_LOAD, +PM_FPGA_GET_STATUS, +PM_GET_CHIPID, +/* ID 25 is been used by U-boot to process secure boot images */ +/* Secure library generic API functions */ +PM_SECURE_SHA = 26, +PM_SECURE_RSA, +/* Pin control API functions */ +PM_PINCTRL_REQUEST, +PM_PINCTRL_RELEASE, +PM_PINCTRL_GET_FUNCTION, +PM_PINCTRL_SET_FUNCTION, +PM_PINCTRL_CONFIG_PARAM_GET, +PM_PINCTRL_CONFIG_PARAM_SET, +/* PM IOCTL API */ +PM_IOCTL, +/* API to query information from firmware */ +PM_QUERY_DATA, +/* Clock control API functions */ +PM_CLOCK_ENABLE, +PM_CLOCK_DISABLE, +PM_CLOCK_GETSTATE, +PM_CLOCK_SETDIVIDER, +PM_CLOCK_GETDIVIDER, +PM_CLOCK_SETRATE, +PM_CLOCK_GETRATE, +PM_CLOCK_SETPARENT, +PM_CLOCK_GETPARENT, +PM_API_MAX +}; + +/** + * @XST_PM_SUCCESS:Success + * @XST_PM_INTERNAL: Unexpected error + * @XST_PM_CONFLICT: Conflicting requirements + * @XST_PM_NO_ACCESS: Access rights violation + * @XST_PM_INVALID_NODE: Does not apply to node passed as argument + * @XST_PM_DOUBLE_REQ: Duplicate request + * @XST_PM_ABORT_SUSPEND: Target has aborted suspend + */ +enum pm_ret_status { +XST_PM_SUCCESS = 0, +XST_PM_INTERNAL = 2000, +XST_PM_CONFLICT, +XST_PM_NO_ACCESS, +XST_PM_INVALID_NODE, +XST_PM_DOUBLE_REQ, +XST_PM_ABORT_SUSPEND, +}; extern bool zynqmp_eemi(struct cpu_user_regs *regs); Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v7 2/6] xen/arm: zynqmp: Forward plaform specific firmware calls
Hi Stefano, On 12/17/18 10:10 PM, Stefano Stabellini wrote: diff --git a/xen/arch/arm/platforms/xilinx-zynqmp.c b/xen/arch/arm/platforms/xilinx-zynqmp.c index d8ceded..8bc7a9f 100644 --- a/xen/arch/arm/platforms/xilinx-zynqmp.c +++ b/xen/arch/arm/platforms/xilinx-zynqmp.c @@ -18,6 +18,8 @@ */ #include +#include +#include static const char * const zynqmp_dt_compat[] __initconst = { @@ -32,8 +34,29 @@ static const struct dt_device_match zynqmp_blacklist_dev[] __initconst = { /* sentinel */ }, }; +static bool zynqmp_smc(struct cpu_user_regs *regs) +{ +/* + * ZynqMP firmware is based on SMCCC 1.1. If SMCCC 1.1 is not + * available something is wrong, don't try to handle it. + */ +if ( !cpus_have_const_cap(ARM_SMCCC_1_1) ) +{ +static bool once = true; NIT: Newline here please. With that: Acked-by: Julien Grall Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2 1/1] xen/blkback: rework connect_ring() to avoid inconsistent xenstore 'ring-page-order' set by malicious blkfront
On 12/18/2018 11:13 PM, Roger Pau Monné wrote: > On Tue, Dec 18, 2018 at 07:31:59PM +0800, Dongli Zhang wrote: >> Hi Roger, >> >> On 12/18/2018 05:33 PM, Roger Pau Monné wrote: >>> On Tue, Dec 18, 2018 at 08:55:38AM +0800, Dongli Zhang wrote: The xenstore 'ring-page-order' is used globally for each blkback queue and therefore should be read from xenstore only once. However, it is obtained in read_per_ring_refs() which might be called multiple times during the initialization of each blkback queue. If the blkfront is malicious and the 'ring-page-order' is set in different value by blkfront every time before blkback reads it, this may end up at the "WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));" in xen_blkif_disconnect() when frontend is destroyed. This patch reworks connect_ring() to read xenstore 'ring-page-order' only once. Signed-off-by: Dongli Zhang --- Changed since v1: * change the order of xenstore read in read_per_ring_refs(suggested by Roger Pau Monne) * use xenbus_read_unsigned() in connect_ring() (suggested by Roger Pau Monne) drivers/block/xen-blkback/xenbus.c | 70 ++ 1 file changed, 40 insertions(+), 30 deletions(-) diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c index a4bc74e..7178f0f 100644 --- a/drivers/block/xen-blkback/xenbus.c +++ b/drivers/block/xen-blkback/xenbus.c @@ -926,7 +926,7 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) int err, i, j; struct xen_blkif *blkif = ring->blkif; struct xenbus_device *dev = blkif->be->dev; - unsigned int ring_page_order, nr_grefs, evtchn; + unsigned int nr_grefs, evtchn; err = xenbus_scanf(XBT_NIL, dir, "event-channel", "%u", &evtchn); @@ -936,43 +936,38 @@ static int read_per_ring_refs(struct xen_blkif_ring *ring, const char *dir) return err; } - err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u", -&ring_page_order); - if (err != 1) { - err = xenbus_scanf(XBT_NIL, dir, "ring-ref", "%u", &ring_ref[0]); - if (err != 1) { + nr_grefs = blkif->nr_ring_pages; + WARN_ON(!nr_grefs); + + for (i = 0; i < nr_grefs; i++) { + char ring_ref_name[RINGREF_NAME_LEN]; + + snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); + err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, + "%u", &ring_ref[i]); + + if (err != 1 && (i || (!i && nr_grefs > 1))) { >>> >>> AFAICT the above condition can be simplified as "err != 1 && >>> nr_grefs". >>> err = -EINVAL; >>> >>> There's no point in setting err here... >>> - xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir); + xenbus_dev_fatal(dev, err, "reading %s/%s", + dir, ring_ref_name); return err; >>> >>> ...since you can just return -EINVAL (same applies to the other >>> instance below). >> >> I would like to confirm if I would keep the err = -EINVAL in below because >> most >> of the below code is copied from original implementation without >> modification. >> >> There is no err set by xenbus_read_unsigned(). > > Right, but instead of doing: > > err = -EINVAL; > return err; > > You can just do: > > return -EINVAL; > > Which is one line shorter :). However, for the "ring-page-order" case, the err used in xenbus_dev_fatal() is not set as xenbus_read_unsigned() does not return any err? For "ring-page-order", I would still need to set err = -EINVAL with extra one line of code? > >> + ring_page_order = xenbus_read_unsigned(dev->otherend, >> + "ring-page-order", 0); >> + >> + if (ring_page_order > xen_blkif_max_ring_order) { >> + err = -EINVAL; >> + xenbus_dev_fatal(dev, err, >> +"requested ring page order %d exceed >> max:%d", >> +ring_page_order, >> +xen_blkif_max_ring_order); >> + return err; >> + } >> + >> + be->blkif->nr_ring_pages = 1 << ring_page_order; >> >> >> For the rest, I would do something like: >> >> + err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, >> + "%u", &ring_ref[i]); >> + >> + if (err != 1 && nr_grefs > 1) { >> + xenbus_dev_fatal(dev, err, "reading %s/%s", >> +dir, ring_ref_name); >> + return -EINVAL; >> +
Re: [Xen-devel] [PATCH v2 6/5] tools/docs: Remove PVRDTSCP remnants
Andrew Cooper writes ("[Xen-devel] [PATCH v2 6/5] tools/docs: Remove PVRDTSCP remnants"): > PVRDTSCP is believed-unused, and its implementation has adverse consequences > on unrelated functionality in the hypervisor. As a result, support has been > removed. Acked-by: Ian Jackson ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH 00/41] scsi: Mark expected switch fall-throughs
Hi Martin, Friendly ping: Only 8 out the 41 patches in this series have been applied so far. I wonder if you could apply the rest of this series, except: [PATCH 02/41] scsi: NCR5380: Mark expected switch fall-through (I'll send a v2 of this patch) Thanks -- Gustavo On 11/27/18 10:18 PM, Gustavo A. R. Silva wrote: In preparation to enabling -Wimplicit-fallthrough, this patchset aims to mark switch cases where we are expecting to fall through. I reviewed case by case and concluded that each of them is an intentional fall-through. However, it doesn't hurt that the maintainers and supporters of each driver take a look. :) Each commit log contains the particular details for the changes in the corresponding file. This series fix a total of 110 of the following type of warnings in drivers/scsi: drivers/scsi/aic7xxx/aic7xxx_core.c:4921:3: warning: this statement may fall through [-Wimplicit-fallthrough=] ahc_dma_tag_destroy(ahc, scb_data->sg_dmat); ^~~ drivers/scsi/aic7xxx/aic7xxx_core.c:4923:2: note: here case 6: ^~~~ Thanks! Gustavo A. R. Silva (41): scsi: BusLogic: mark expected switch fall-through scsi: NCR5380: Mark expected switch fall-through scsi: aacraid: aachba: Mark expected switch fall-throughs scsi: aacraid: linit: Mark expected switch fall-through scsi: aic7xxx: aic79xx: mark expected switch fall-through scsi: aic7xxx: mark expected switch fall-throughs scsi: be2iscsi: be_iscsi: Mark expected switch fall-through scsi: be2iscsi: be_main: Mark expected switch fall-through scsi: bfa: bfa_fcpim: Mark expected switch fall-throughs scsi: bfa: bfa_fcs_lport: Mark expected switch fall-throughs scsi: bfa: bfa_fcs_rport: Mark expected switch fall-throughs scsi: bfa: bfa_ioc: Mark expected switch fall-throughs scsi: csiostor: csio_wr: mark expected switch fall-through scsi: esas2r: esas2r_init: mark expected switch fall-throughs scsi: hpsa: mark expected switch fall-throughs scsi: imm: mark expected switch fall-throughs scsi: isci: phy: Mark expected switch fall-through scsi: isci: remote_device: Mark expected switch fall-throughs scsi: isci: remote_node_context: mark expected switch fall-throughs scsi: isci: request: mark expected switch fall-through scsi: libfc: fc_rport: Mark expected switch fall-through scsi: lpfc: lpfc_ct: Mark expected switch fall-throughs scsi: lpfc: lpfc_els: Mark expected switch fall-throughs scsi: lpfc: lpfc_hbadisc: Mark expected switch fall-throughs scsi: lpfc: lpfc_nportdisc: Mark expected switch fall-through scsi: lpfc: lpfc_nvme: Mark expected switch fall-through scsi: lpfc: lpfc_scsi: Mark expected switch fall-throughs scsi: lpfc: lpfc_sli: Mark expected switch fall-throughs scsi: megaraid: megaraid_sas_base: Mark expected switch fall-through scsi: megaraid_sas_fusion: Mark expected switch fall-through scsi: mpt3sas: mpt3sas_scsih: Mark expected switch fall-through scsi: myrb: Mark expected switch fall-throughs scsi: osd: osd_initiator: mark expected switch fall-throughs scsi: osst: mark expected switch fall-throughs scsi: ppa: mark expected switch fall-through scsi: qla4xxx: ql4_os: mark expected switch fall-through scsi: st: mark expected switch fall-throughs scsi: sym53c8xx_2: sym_hipd: mark expected switch fall-throughs scsi: sym53c8xx_2: sym_nvram: Mark expected switch fall-through scsi: ufs: ufshcd: mark expected switch fall-throughs scsi: xen-scsifront: mark expected switch fall-through drivers/scsi/BusLogic.c | 1 + drivers/scsi/NCR5380.c | 3 +- drivers/scsi/aacraid/aachba.c | 5 +++- drivers/scsi/aacraid/linit.c| 1 + drivers/scsi/aic7xxx/aic79xx_core.c | 14 + drivers/scsi/aic7xxx/aic7xxx_core.c | 12 ++-- drivers/scsi/be2iscsi/be_iscsi.c| 1 + drivers/scsi/be2iscsi/be_main.c | 1 + drivers/scsi/bfa/bfa_fcpim.c| 6 ++-- drivers/scsi/bfa/bfa_fcs_lport.c| 8 ++--- drivers/scsi/bfa/bfa_fcs_rport.c| 19 +--- drivers/scsi/bfa/bfa_ioc.c | 9 ++ drivers/scsi/csiostor/csio_wr.c | 1 + drivers/scsi/esas2r/esas2r_init.c | 3 +- drivers/scsi/hpsa.c | 5 drivers/scsi/imm.c | 33 +++-- drivers/scsi/isci/phy.c | 1 + drivers/scsi/isci/remote_device.c | 4 +-- drivers/scsi/isci/remote_node_context.c | 4 +-- drivers/scsi/isci/request.c | 2 +- drivers/scsi/libfc/fc_rport.c | 1 + drivers/scsi/lpfc/lpfc_ct.c | 2 ++ drivers/scsi/lpfc/lpfc_els.c| 1 + drivers/scsi/lpfc/lpfc_hbadisc.c| 4 ++- drivers/scsi/lpfc/lpfc_nportdisc.c | 1 + drivers/scsi/lpfc/lp
Re: [Xen-devel] [PATCH] x86emul: permit SAE for V{,U}COMIS{S,D}
>>> On 18.12.18 at 15:28, wrote: > On 10/12/2018 13:56, Jan Beulich wrote: > On 10.12.18 at 14:20, wrote: >>> On 10/12/2018 11:32, Jan Beulich wrote: The avx512_vlen_check() invocation needs to be conditional. Signed-off-by: Jan Beulich >>> I'm not sure if I've asked before, but do LIG instructions really #UD >>> for L=3 ? I don't see any documentation to this effect. >> At least on my Core i9 they do; I have a pending query with Intel >> as to the intentions in general and the lack of clear documentation, >> as well as to the behavior on the Knights line of processors (where >> there is no AVX512VL, and hence where special casing VL=128 and >> VL=256 but not VL= are at least >> questionable). > > VL=3 will surely be 1024 bits wide, but I'd be interested to which > register mnemonic they choose to follow xmm/ymm/zmm. > > I'll try to find some time to poke a Knights machine and see what happens. > >> --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -6179,7 +6179,8 @@ x86_emulate( evex.w != evex.pfx), EXC_UD); host_and_vcpu_must_have(avx512f); -avx512_vlen_check(true); +if ( !evex.br ) >>> On the subject of ineligibility of the code, what about #define sae br ? >>> >>> That way, this would read "if ( !evex.sae ) check_vlen()" >> The three meanings of the bit can't reasonably all be conveyed >> by a acceptably short name. Of course we can introduce aliases >> like the above, but please recall that >> - "br" stands for _b_roadcast or _r_ounding, not _br_oadcast, > > TBH, I'd even forgotten this. I don't see it written anywhere. Despite > what you claim, people will interpret it as _br_oadcast given a lack of > any information to the contrary. > >> - we'd need another alias for the embedded-rounding case then. >> If you're convinced this is a good idea, I can do respective >> renaming both to what may already be committed as well as to >> the rest of the still pending series. >> >> But personally I'd rather not go that route, to make it easier to >> connect with one another all the uses/checks of that bit. This is >> in particular because for insns which allow neither broadcast nor >> rounding/SAE, I certainly don't want to check the same bit twice >> (via its different names). > > The context-dependent meanings are: > * Broadcast > * Static Rounding > * Suppress All Exceptions > > How about naming the field bsr for "broadcast/suppress/rounding" (which > breaks the _br_oadcast vs _b_roadcast/_r_ounding confusion), and > introducing a define for bcast, sae and rounding ? Well, yes, I'd been considering "brs" (I dislike "bsr" for its collision with the same name insn mnemonic). > /* EVEX.b (SDM nomenclature) has encoding-dependent meaning. */ > #define bcast bsr > #define sae bsr > #define rounding bsr > > That way, code with a single meaning can use the context-correct name, > and any cases (are there any?) which don't use one of these modes can > use the underlying field. Well, it's the common case that the field has two meanings: SAE or ER with all register operands and BROADCAST with a memory one. Exceptions are when either broadcast or SAE/ER are not permitted for a particular major opcode. > I don't think it will cause confusion for correlating the uses of the > bit, because we will never be using more than a single name in one context. > > To unblock the original patch (which shouldn't be conflated with this > suggested improvement), Acked-by: Andrew Cooper Thanks. Question then is - are you convinced enough of your proposal for me to re-work things before posting v7 of the main series? And if so are you fine with "brs" instead of "bsr" (and perhaps "er" instead of "rounding", to be closer to SDM terminology)? Jan ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2 1/1] xen/blkback: rework connect_ring() to avoid inconsistent xenstore 'ring-page-order' set by malicious blkfront
On Tue, Dec 18, 2018 at 07:31:59PM +0800, Dongli Zhang wrote: > Hi Roger, > > On 12/18/2018 05:33 PM, Roger Pau Monné wrote: > > On Tue, Dec 18, 2018 at 08:55:38AM +0800, Dongli Zhang wrote: > >> The xenstore 'ring-page-order' is used globally for each blkback queue and > >> therefore should be read from xenstore only once. However, it is obtained > >> in read_per_ring_refs() which might be called multiple times during the > >> initialization of each blkback queue. > >> > >> If the blkfront is malicious and the 'ring-page-order' is set in different > >> value by blkfront every time before blkback reads it, this may end up at > >> the "WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));" in > >> xen_blkif_disconnect() when frontend is destroyed. > >> > >> This patch reworks connect_ring() to read xenstore 'ring-page-order' only > >> once. > >> > >> Signed-off-by: Dongli Zhang > >> --- > >> Changed since v1: > >> * change the order of xenstore read in read_per_ring_refs(suggested by > >> Roger Pau Monne) > >> * use xenbus_read_unsigned() in connect_ring() (suggested by Roger Pau > >> Monne) > >> > >> drivers/block/xen-blkback/xenbus.c | 70 > >> ++ > >> 1 file changed, 40 insertions(+), 30 deletions(-) > >> > >> diff --git a/drivers/block/xen-blkback/xenbus.c > >> b/drivers/block/xen-blkback/xenbus.c > >> index a4bc74e..7178f0f 100644 > >> --- a/drivers/block/xen-blkback/xenbus.c > >> +++ b/drivers/block/xen-blkback/xenbus.c > >> @@ -926,7 +926,7 @@ static int read_per_ring_refs(struct xen_blkif_ring > >> *ring, const char *dir) > >>int err, i, j; > >>struct xen_blkif *blkif = ring->blkif; > >>struct xenbus_device *dev = blkif->be->dev; > >> - unsigned int ring_page_order, nr_grefs, evtchn; > >> + unsigned int nr_grefs, evtchn; > >> > >>err = xenbus_scanf(XBT_NIL, dir, "event-channel", "%u", > >> &evtchn); > >> @@ -936,43 +936,38 @@ static int read_per_ring_refs(struct xen_blkif_ring > >> *ring, const char *dir) > >>return err; > >>} > >> > >> - err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u", > >> -&ring_page_order); > >> - if (err != 1) { > >> - err = xenbus_scanf(XBT_NIL, dir, "ring-ref", "%u", > >> &ring_ref[0]); > >> - if (err != 1) { > >> + nr_grefs = blkif->nr_ring_pages; > >> + WARN_ON(!nr_grefs); > >> + > >> + for (i = 0; i < nr_grefs; i++) { > >> + char ring_ref_name[RINGREF_NAME_LEN]; > >> + > >> + snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); > >> + err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, > >> + "%u", &ring_ref[i]); > >> + > >> + if (err != 1 && (i || (!i && nr_grefs > 1))) { > > > > AFAICT the above condition can be simplified as "err != 1 && > > nr_grefs". > > > >>err = -EINVAL; > > > > There's no point in setting err here... > > > >> - xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir); > >> + xenbus_dev_fatal(dev, err, "reading %s/%s", > >> + dir, ring_ref_name); > >>return err; > > > > ...since you can just return -EINVAL (same applies to the other > > instance below). > > I would like to confirm if I would keep the err = -EINVAL in below because > most > of the below code is copied from original implementation without modification. > > There is no err set by xenbus_read_unsigned(). Right, but instead of doing: err = -EINVAL; return err; You can just do: return -EINVAL; Which is one line shorter :). > + ring_page_order = xenbus_read_unsigned(dev->otherend, > + "ring-page-order", 0); > + > + if (ring_page_order > xen_blkif_max_ring_order) { > + err = -EINVAL; > + xenbus_dev_fatal(dev, err, > +"requested ring page order %d exceed max:%d", > +ring_page_order, > +xen_blkif_max_ring_order); > + return err; > + } > + > + be->blkif->nr_ring_pages = 1 << ring_page_order; > > > For the rest, I would do something like: > > + err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, > + "%u", &ring_ref[i]); > + > + if (err != 1 && nr_grefs > 1) { > + xenbus_dev_fatal(dev, err, "reading %s/%s", > +dir, ring_ref_name); > + return -EINVAL; > + } > > > Thank you very much! Thanks! ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH V3] x86/altp2m: add altp2m_vcpu_disable_notify
Allow altp2m users to disable #VE/VMFUNC alone. Currently it is only possible to disable this functionality when we disable altp2m completely; #VE/VMFUNC can only be enabled once per altp2m session. In addition to making things complete, disabling #VE is also a workaround for CFW116 ("When Virtualization Exceptions are Enabled, EPT Violations May Generate Erroneous Virtualization Exceptions") on Xeon E-2100 CPUs. Signed-off-by: Razvan Cojocaru --- Changes since V2: - Fixed compilation by completing the removal of all references to "pad". Changes since V1: - Updated the patch description to specify E-2100. - Made trying to disable #VE when it's already disabled a no-op. - Removed leftover uint32_t pad; from struct xen_hvm_altp2m_vcpu_disable_notify. --- tools/libxc/include/xenctrl.h | 2 ++ tools/libxc/xc_altp2m.c | 22 ++ xen/arch/x86/hvm/hvm.c | 28 xen/include/public/hvm/hvm_op.h | 11 ++- 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 97ae965..31cdda7 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -1932,6 +1932,8 @@ int xc_altp2m_get_domain_state(xc_interface *handle, uint32_t dom, bool *state); int xc_altp2m_set_domain_state(xc_interface *handle, uint32_t dom, bool state); int xc_altp2m_set_vcpu_enable_notify(xc_interface *handle, uint32_t domid, uint32_t vcpuid, xen_pfn_t gfn); +int xc_altp2m_set_vcpu_disable_notify(xc_interface *handle, uint32_t domid, + uint32_t vcpuid); int xc_altp2m_create_view(xc_interface *handle, uint32_t domid, xenmem_access_t default_access, uint16_t *view_id); int xc_altp2m_destroy_view(xc_interface *handle, uint32_t domid, diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c index 844b9f1..f8cd603 100644 --- a/tools/libxc/xc_altp2m.c +++ b/tools/libxc/xc_altp2m.c @@ -91,6 +91,28 @@ int xc_altp2m_set_vcpu_enable_notify(xc_interface *handle, uint32_t domid, return rc; } +int xc_altp2m_set_vcpu_disable_notify(xc_interface *handle, uint32_t domid, + uint32_t vcpuid) +{ +int rc; +DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg); + +arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg)); +if ( arg == NULL ) +return -1; + +arg->version = HVMOP_ALTP2M_INTERFACE_VERSION; +arg->cmd = HVMOP_altp2m_vcpu_disable_notify; +arg->domain = domid; +arg->u.disable_notify.vcpu_id = vcpuid; + +rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m, + HYPERCALL_BUFFER_AS_ARG(arg)); + +xc_hypercall_buffer_free(handle, arg); +return rc; +} + int xc_altp2m_create_view(xc_interface *handle, uint32_t domid, xenmem_access_t default_access, uint16_t *view_id) { diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index d64b6b6..ca3cb3f 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -4485,6 +4485,7 @@ static int do_altp2m_op( case HVMOP_altp2m_get_domain_state: case HVMOP_altp2m_set_domain_state: case HVMOP_altp2m_vcpu_enable_notify: +case HVMOP_altp2m_vcpu_disable_notify: case HVMOP_altp2m_create_p2m: case HVMOP_altp2m_destroy_p2m: case HVMOP_altp2m_switch_p2m: @@ -4602,6 +4603,33 @@ static int do_altp2m_op( break; } +case HVMOP_altp2m_vcpu_disable_notify: +{ +struct vcpu *v; + +if ( a.u.disable_notify.vcpu_id >= d->max_vcpus ) +{ +rc = -EINVAL; +break; +} + +if ( !cpu_has_vmx_virt_exceptions ) +{ +rc = -EOPNOTSUPP; +break; +} + +v = d->vcpu[a.u.enable_notify.vcpu_id]; + +/* Already disabled, nothing to do. */ +if ( gfn_eq(vcpu_altp2m(v).veinfo_gfn, INVALID_GFN) ) +break; + +vcpu_altp2m(v).veinfo_gfn = INVALID_GFN; +altp2m_vcpu_update_vmfunc_ve(v); +break; +} + case HVMOP_altp2m_create_p2m: if ( !(rc = p2m_init_next_altp2m(d, &a.u.view.view)) ) rc = __copy_to_guest(arg, &a, 1) ? -EFAULT : 0; diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h index 5878a25..c6cd12f 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -232,6 +232,12 @@ struct xen_hvm_altp2m_vcpu_enable_notify { typedef struct xen_hvm_altp2m_vcpu_enable_notify xen_hvm_altp2m_vcpu_enable_notify_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t); +struct xen_hvm_altp2m_vcpu_disable_notify { +uint32_t vcpu_id; +}; +typedef struct xen_hvm_altp2m_vcpu_disable_notify xen_hvm_altp2m_vcpu_disable_notify_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_disable_notify_t); + struct xen_hvm_altp2m_view { /* IN/
Re: [Xen-devel] [PATCH v2 05/10] libxl: Do root checks once in libxl__domain_get_device_model_uid
George Dunlap writes ("Re: [PATCH v2 05/10] libxl: Do root checks once in libxl__domain_get_device_model_uid"): > On Dec 12, 2018, at 3:45 PM, Ian Jackson wrote: > >> +/* > >> + * If dm_restrict isn't set, and we don't have a specified user, don't > >> + * bother setting a `-runas` parameter. > >> + */ > >> if (!libxl_defbool_val(b_info->dm_restrict)) { > >> LOGD(DEBUG, guest_domid, > >> "dm_restrict disabled, starting QEMU as root"); > >> return 0; > >> } > > > > Why `return 0' here but `goto out' earlier ? IMO all the success > > returns should be the same. > > Not exactly — we only want to do the root check if we’re running as an > alternate user. In this case, neither device_model_user nor dm_restrict is > set, so we’re not running as an alternate user, so we don’t want to run the > `if(intended_uid == 0)` check on the normal ‘out’ path. Ah. Fiddly. > I take it you’d prefer to always jump to out, but to have the conditional be, > `if (!rc && user)`? How about if (!rc) { if (user && intended_uid=0) { error case, rc = } } if (!rc) { ? The reason I like this is because this keeps separate the error / flow control logic from the precise details of the reason why we might discover a later error. > > We generally use EINVAL for bad configurations. If you prefer, feel > > free to introduce a new error code. 32-bit signed integers are pretty > > cheap. > > The integers may be cheap, but scanning through trying to comprehend them is > not. :-) It would be nice if we had a doc saying what they meant. > >> +if (rc < 0) > >> +goto out; > >> if (user_base) { > >> LOGD(WARN, guest_domid, "Could not find user %s, falling back to > >> %s", > >> LIBXL_QEMU_USER_RANGE_BASE, LIBXL_QEMU_USER_SHARED); > >> -goto end_search; > >> +intended_uid = user_base->pw_uid; > >> +goto out; > > > > Here we have this pattern again with a `goto out' without a preceding > > assignment to `rc'. AFAICT the rules implied by your out block are: > > > > * Every goto out must be preceded by an assignment to rc. > > IMO there is no reason this should not immediately precede > > the goto out. > > > > * Additionally, if rc is 0 then the goto out must also be preceded > > relatively recently by an assignment to intended_uid. > > Those are rules that you’re implying, not me. :-) My `goto out` invariant in > this patch were: > > 1. rc may be an error code. In this case, rc is returned. > 2. rc may be zero; if rc is zero: > 2a. user must be non-NULL, > 2b. user must be verified to exist on the system, and > 2c. intended_uid must be set to the userid reported in the previous check This formulation of the rules cannot be verified locally. In order to verify these for any particular `goto out' it is necessary to scan back through the previous logic to see whether 2a, 2b, 2c are true. But you are right that I had failed to spot that assignment to user is also required. Perhaps this demonstrates that a comment stating the rules explicitly would be useful. > In order to accept your suggestion above to replace the `return` with a `goto > out`, I have to make the invariant as follows: > > 1. rc may be an error code. In this case, rc is returned. > 2. rc may be zero, and user NULL. In this case, rc is returned. > 3. rc may be zero, and user non-NULL. In this case: > [2b and 2c from above] I would suggest: 1. If rc is an error code, all bets are off about user and intended_uid 2. Otherwise we have success. Then user and intended_uid are appropriate for the situation, which might mean both are sentinel, or both are set to specific values. This seems to make sense to me since the purpose of this function is to discover the right values for user and intended_uid. > In this case, we know that rc is 0 because we just checked the value 6 lines > earlier. If code is ever added in between such that rc becomes non-zero, > *that* code should be calling `goto out` (or thinking carefully about why > falling through to this code is OK). I really dislike the pattern of reusing an rc value. It is OK to build up the results of the computation in the intended answer variables (in this case user and intended_uid). But rc is a `throwaway' variable which has to be trashed by any call to any libxl subfunction. That is, except in the special case of destruction functions, and during the out block, rc is not accumulated or preserved, and has only very local significance. You are saying `but if that other subfunction doesn't succeed, setting rc!=0, it will have to goto out' but that is not a valid assumption. Maybe there is a way of handling the error by trying an alternative approach, or something. In general there is nothing wrong with code like this: rc = libxl_try_mutilate_wombat(gc, dom, &wombat); /* We do not need to mutilate a nonexisten
[Xen-devel] [PATCH] xen/netfront: tolerate frags with no data
At least old Xen net backends seem to send frags with no real data sometimes. In case such a fragment happens to occur with the frag limit already reached the frontend will BUG currently even if this situation is easily recoverable. Modify the BUG_ON() condition accordingly. Cc: sta...@vger.kernel.org Tested-by: Dietmar Hahn Signed-off-by: Juergen Gross --- drivers/net/xen-netfront.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c index f17f602e6171..5b97cc946d70 100644 --- a/drivers/net/xen-netfront.c +++ b/drivers/net/xen-netfront.c @@ -905,7 +905,7 @@ static RING_IDX xennet_fill_frags(struct netfront_queue *queue, if (skb_shinfo(skb)->nr_frags == MAX_SKB_FRAGS) { unsigned int pull_to = NETFRONT_SKB_CB(skb)->pull_to; - BUG_ON(pull_to <= skb_headlen(skb)); + BUG_ON(pull_to < skb_headlen(skb)); __pskb_pull_tail(skb, pull_to - skb_headlen(skb)); } if (unlikely(skb_shinfo(skb)->nr_frags >= MAX_SKB_FRAGS)) { -- 2.16.4 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH for-4.12 v3] xen/arm: Stop relocating Xen
On 18.12.18 15:07, Julien Grall wrote: At the moment, Xen is relocated towards the end of the memory. While this has the advantage to free space in low memory, the code is not compliant with the break-before-make because it requires to switch between two sets of page-table. This is not entirely trivial to fix as it would require us to go through an identity mapping and disabling MMU. Furthermore, it looks like that some platform (such as the Hikey960) may not be able to bring-up secondary CPUs if the entry is too high. While Xen should be quite tiny (< 2MB), the current algorigthm to allocate Dom0 memory will allocate memory chunk of at least 128MB. Those memory chunks will always be 128MB. This means that depending on where the modules are loaded, an extra 128MB may disappear. As there are up to 4 modules (initramfs, XSM, kernel, DTB) loaded in low memory. The problem is not entirely new as you could already waste 512MB of low-memory. The right solution would be to fix the allocation algorightm. But this is independent from this patch. For user in control of the memory (such as in U-boot), all modules should be loaded as much as possible together or outside low-memory (i.e above 4GB). For other users (i.e Grub/UEFI), I believe the bootloader is already keeping everything together. Based on the above, it would be fine to stop relocating Xen. This has the advantage to simplify the code and should speed-up the boot as relocation is not necessary anymore. Note that the break-before-make issue is not fixed by this patch. Signed-off-by: Julien Grall Reported-by: Matthew Daley Tested-by: Matthew Daley As long as the code did not change: Tested-by: Andrii Anisov Reviewed-by: Andrii Anisov -- Sincerely, Andrii Anisov. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH V2] x86/altp2m: add altp2m_vcpu_disable_notify
On 12/18/18 4:54 PM, Razvan Cojocaru wrote: > Allow altp2m users to disable #VE/VMFUNC alone. Currently it is > only possible to disable this functionality when we disable altp2m > completely; #VE/VMFUNC can only be enabled once per altp2m session. > > In addition to making things complete, disabling #VE is also a > workaround for CFW116 ("When Virtualization Exceptions are Enabled, > EPT Violations May Generate Erroneous Virtualization Exceptions") > on Xeon E-2100 CPUs. > > Signed-off-by: Razvan Cojocaru > > --- > Changes since V1: > - Updated the patch description to specify E-2100. > - Made trying to disable #VE when it's already disabled a no-op. > - Removed leftover uint32_t pad; from struct >xen_hvm_altp2m_vcpu_disable_notify. > --- > tools/libxc/include/xenctrl.h | 2 ++ > tools/libxc/xc_altp2m.c | 22 ++ > xen/arch/x86/hvm/hvm.c | 29 + > xen/include/public/hvm/hvm_op.h | 11 ++- > 4 files changed, 63 insertions(+), 1 deletion(-) > > diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h > index 97ae965..31cdda7 100644 > --- a/tools/libxc/include/xenctrl.h > +++ b/tools/libxc/include/xenctrl.h > @@ -1932,6 +1932,8 @@ int xc_altp2m_get_domain_state(xc_interface *handle, > uint32_t dom, bool *state); > int xc_altp2m_set_domain_state(xc_interface *handle, uint32_t dom, bool > state); > int xc_altp2m_set_vcpu_enable_notify(xc_interface *handle, uint32_t domid, > uint32_t vcpuid, xen_pfn_t gfn); > +int xc_altp2m_set_vcpu_disable_notify(xc_interface *handle, uint32_t domid, > + uint32_t vcpuid); > int xc_altp2m_create_view(xc_interface *handle, uint32_t domid, >xenmem_access_t default_access, uint16_t *view_id); > int xc_altp2m_destroy_view(xc_interface *handle, uint32_t domid, > diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c > index 844b9f1..f8cd603 100644 > --- a/tools/libxc/xc_altp2m.c > +++ b/tools/libxc/xc_altp2m.c > @@ -91,6 +91,28 @@ int xc_altp2m_set_vcpu_enable_notify(xc_interface *handle, > uint32_t domid, > return rc; > } > > +int xc_altp2m_set_vcpu_disable_notify(xc_interface *handle, uint32_t domid, > + uint32_t vcpuid) > +{ > +int rc; > +DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg); > + > +arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg)); > +if ( arg == NULL ) > +return -1; > + > +arg->version = HVMOP_ALTP2M_INTERFACE_VERSION; > +arg->cmd = HVMOP_altp2m_vcpu_disable_notify; > +arg->domain = domid; > +arg->u.disable_notify.vcpu_id = vcpuid; > + > +rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m, > + HYPERCALL_BUFFER_AS_ARG(arg)); > + > +xc_hypercall_buffer_free(handle, arg); > +return rc; > +} > + > int xc_altp2m_create_view(xc_interface *handle, uint32_t domid, >xenmem_access_t default_access, uint16_t *view_id) > { > diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c > index d64b6b6..424e4d1 100644 > --- a/xen/arch/x86/hvm/hvm.c > +++ b/xen/arch/x86/hvm/hvm.c > @@ -4485,6 +4485,7 @@ static int do_altp2m_op( > case HVMOP_altp2m_get_domain_state: > case HVMOP_altp2m_set_domain_state: > case HVMOP_altp2m_vcpu_enable_notify: > +case HVMOP_altp2m_vcpu_disable_notify: > case HVMOP_altp2m_create_p2m: > case HVMOP_altp2m_destroy_p2m: > case HVMOP_altp2m_switch_p2m: > @@ -4602,6 +4603,34 @@ static int do_altp2m_op( > break; > } > > +case HVMOP_altp2m_vcpu_disable_notify: > +{ > +struct vcpu *v; > + > +if ( a.u.disable_notify.pad || Sorry, this should obviously have been removed as well. I'll re-send the patch. Thanks, Razvan ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH V2] x86/altp2m: add altp2m_vcpu_disable_notify
Allow altp2m users to disable #VE/VMFUNC alone. Currently it is only possible to disable this functionality when we disable altp2m completely; #VE/VMFUNC can only be enabled once per altp2m session. In addition to making things complete, disabling #VE is also a workaround for CFW116 ("When Virtualization Exceptions are Enabled, EPT Violations May Generate Erroneous Virtualization Exceptions") on Xeon E-2100 CPUs. Signed-off-by: Razvan Cojocaru --- Changes since V1: - Updated the patch description to specify E-2100. - Made trying to disable #VE when it's already disabled a no-op. - Removed leftover uint32_t pad; from struct xen_hvm_altp2m_vcpu_disable_notify. --- tools/libxc/include/xenctrl.h | 2 ++ tools/libxc/xc_altp2m.c | 22 ++ xen/arch/x86/hvm/hvm.c | 29 + xen/include/public/hvm/hvm_op.h | 11 ++- 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h index 97ae965..31cdda7 100644 --- a/tools/libxc/include/xenctrl.h +++ b/tools/libxc/include/xenctrl.h @@ -1932,6 +1932,8 @@ int xc_altp2m_get_domain_state(xc_interface *handle, uint32_t dom, bool *state); int xc_altp2m_set_domain_state(xc_interface *handle, uint32_t dom, bool state); int xc_altp2m_set_vcpu_enable_notify(xc_interface *handle, uint32_t domid, uint32_t vcpuid, xen_pfn_t gfn); +int xc_altp2m_set_vcpu_disable_notify(xc_interface *handle, uint32_t domid, + uint32_t vcpuid); int xc_altp2m_create_view(xc_interface *handle, uint32_t domid, xenmem_access_t default_access, uint16_t *view_id); int xc_altp2m_destroy_view(xc_interface *handle, uint32_t domid, diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c index 844b9f1..f8cd603 100644 --- a/tools/libxc/xc_altp2m.c +++ b/tools/libxc/xc_altp2m.c @@ -91,6 +91,28 @@ int xc_altp2m_set_vcpu_enable_notify(xc_interface *handle, uint32_t domid, return rc; } +int xc_altp2m_set_vcpu_disable_notify(xc_interface *handle, uint32_t domid, + uint32_t vcpuid) +{ +int rc; +DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg); + +arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg)); +if ( arg == NULL ) +return -1; + +arg->version = HVMOP_ALTP2M_INTERFACE_VERSION; +arg->cmd = HVMOP_altp2m_vcpu_disable_notify; +arg->domain = domid; +arg->u.disable_notify.vcpu_id = vcpuid; + +rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m, + HYPERCALL_BUFFER_AS_ARG(arg)); + +xc_hypercall_buffer_free(handle, arg); +return rc; +} + int xc_altp2m_create_view(xc_interface *handle, uint32_t domid, xenmem_access_t default_access, uint16_t *view_id) { diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index d64b6b6..424e4d1 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -4485,6 +4485,7 @@ static int do_altp2m_op( case HVMOP_altp2m_get_domain_state: case HVMOP_altp2m_set_domain_state: case HVMOP_altp2m_vcpu_enable_notify: +case HVMOP_altp2m_vcpu_disable_notify: case HVMOP_altp2m_create_p2m: case HVMOP_altp2m_destroy_p2m: case HVMOP_altp2m_switch_p2m: @@ -4602,6 +4603,34 @@ static int do_altp2m_op( break; } +case HVMOP_altp2m_vcpu_disable_notify: +{ +struct vcpu *v; + +if ( a.u.disable_notify.pad || + a.u.disable_notify.vcpu_id >= d->max_vcpus ) +{ +rc = -EINVAL; +break; +} + +if ( !cpu_has_vmx_virt_exceptions ) +{ +rc = -EOPNOTSUPP; +break; +} + +v = d->vcpu[a.u.enable_notify.vcpu_id]; + +/* Already disabled, nothing to do. */ +if ( gfn_eq(vcpu_altp2m(v).veinfo_gfn, INVALID_GFN) ) +break; + +vcpu_altp2m(v).veinfo_gfn = INVALID_GFN; +altp2m_vcpu_update_vmfunc_ve(v); +break; +} + case HVMOP_altp2m_create_p2m: if ( !(rc = p2m_init_next_altp2m(d, &a.u.view.view)) ) rc = __copy_to_guest(arg, &a, 1) ? -EFAULT : 0; diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h index 5878a25..c6cd12f 100644 --- a/xen/include/public/hvm/hvm_op.h +++ b/xen/include/public/hvm/hvm_op.h @@ -232,6 +232,12 @@ struct xen_hvm_altp2m_vcpu_enable_notify { typedef struct xen_hvm_altp2m_vcpu_enable_notify xen_hvm_altp2m_vcpu_enable_notify_t; DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t); +struct xen_hvm_altp2m_vcpu_disable_notify { +uint32_t vcpu_id; +}; +typedef struct xen_hvm_altp2m_vcpu_disable_notify xen_hvm_altp2m_vcpu_disable_notify_t; +DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_disable_notify_t); + struct xen_hvm_altp2m_view { /* IN/OUT variable */ uint16_t view; @@ -304,7 +310,7 @@
[Xen-devel] [PATCH v3 1/2] xen/pt: fix some pass-thru devices don't work across reboot
I find some pass-thru devices don't work any more across guest reboot. Assigning it to another domain also meets the same issue. And the only way to make it work again is un-binding and binding it to pciback. Someone reported this issue one year ago [1]. If the device's driver doesn't disable MSI-X during shutdown or qemu is killed/crashed before the domain shutdown, this domain's pirq won't be unmapped. Then xen takes over this work, unmapping all pirq-s, when destroying guest. But as pciback has already disabled meory decoding before xen unmapping pirq, Xen has to sets the host_maskall flag and maskall bit to mask a MSI rather than sets maskbit in MSI-x table. The call trace of this process is: ->arch_domain_destroy ->free_domain_pirqs ->unmap_domain_pirq (if pirq isn't unmapped by qemu) ->pirq_guest_force_unbind ->__pirq_guest_unbind ->mask_msi_irq(=desc->handler->disable()) ->the warning in msi_set_mask_bit() The host_maskall bit will prevent guests from clearing the maskall bit even the device is assigned to another guest later. Then guests cannot receive MSIs from this device. To fix this issue, a pirq is unmapped before memory decoding is disabled by pciback. Specifically, when a device is detached from a guest, all established mappings between pirq and msi are destroying before changing the ownership. [1]: https://lists.xenproject.org/archives/html/xen-devel/2017-09/msg02520.html Signed-off-by: Chao Gao --- Applied this patch, qemu would report the error below: [00:05.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, pirq: 302, gvec: 0xd5) [00:05.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, pirq: 301, gvec: 0xe5) [00:04.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, pirq: 359, gvec: 0x41) [00:04.0] msi_msix_disable: Error: Unbinding of MSI-X failed. (err: 1, pirq: 358, gvec: 0x51) Despite of the error, guest shutdown or device hotplug finishs smoothly. It seems to me that qemu tries to unbind a msi which is already unbound by the code added by this patch. I am not sure whether it is acceptable to leave this error there. --- xen/drivers/passthrough/io.c | 57 +-- xen/drivers/passthrough/pci.c | 49 + xen/include/xen/iommu.h | 1 + 3 files changed, 89 insertions(+), 18 deletions(-) diff --git a/xen/drivers/passthrough/io.c b/xen/drivers/passthrough/io.c index a6eb8a4..56ee1ef 100644 --- a/xen/drivers/passthrough/io.c +++ b/xen/drivers/passthrough/io.c @@ -619,6 +619,42 @@ int pt_irq_create_bind( return 0; } +static void pt_irq_destroy_bind_common(struct domain *d, struct pirq *pirq) +{ +struct hvm_pirq_dpci *pirq_dpci = pirq_dpci(pirq); + +ASSERT(spin_is_locked(&d->event_lock)); + +if ( pirq_dpci && (pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) && + list_empty(&pirq_dpci->digl_list) ) +{ +pirq_guest_unbind(d, pirq); +msixtbl_pt_unregister(d, pirq); +if ( pt_irq_need_timer(pirq_dpci->flags) ) +kill_timer(&pirq_dpci->timer); +pirq_dpci->flags = 0; +/* + * See comment in pt_irq_create_bind's PT_IRQ_TYPE_MSI before the + * call to pt_pirq_softirq_reset. + */ +pt_pirq_softirq_reset(pirq_dpci); + +pirq_cleanup_check(pirq, d); +} +} + +void pt_irq_destroy_bind_msi(struct domain *d, struct pirq *pirq) +{ +struct hvm_pirq_dpci *pirq_dpci = pirq_dpci(pirq); + +ASSERT(spin_is_locked(&d->event_lock)); + +if ( pirq_dpci && pirq_dpci->gmsi.posted ) +pi_update_irte(NULL, pirq, 0); + +pt_irq_destroy_bind_common(d, pirq); +} + int pt_irq_destroy_bind( struct domain *d, const struct xen_domctl_bind_pt_irq *pt_irq_bind) { @@ -727,26 +763,11 @@ int pt_irq_destroy_bind( } else what = "bogus"; -} -else if ( pirq_dpci && pirq_dpci->gmsi.posted ) -pi_update_irte(NULL, pirq, 0); - -if ( pirq_dpci && (pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) && - list_empty(&pirq_dpci->digl_list) ) -{ -pirq_guest_unbind(d, pirq); -msixtbl_pt_unregister(d, pirq); -if ( pt_irq_need_timer(pirq_dpci->flags) ) -kill_timer(&pirq_dpci->timer); -pirq_dpci->flags = 0; -/* - * See comment in pt_irq_create_bind's PT_IRQ_TYPE_MSI before the - * call to pt_pirq_softirq_reset. - */ -pt_pirq_softirq_reset(pirq_dpci); -pirq_cleanup_check(pirq, d); +pt_irq_destroy_bind_common(d, pirq); } +else +pt_irq_destroy_bind_msi(d, pirq); spin_unlock(&d->event_lock); diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c index 1277ce2..88a8007 100644 --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -368,6 +368,7 @@ static struct pci_dev *alloc_
[Xen-devel] [PATCH v3 2/2] libxl: don't reset device when it is accessible by the guest
When I destroyed a guest with 'xl destroy', I found the warning in msi_set_mask_bit() in Xen was triggered. After adding "WARN_ON(1)" to that place, I got the call trace below: (XEN) Xen call trace: (XEN)[] msi.c#msi_set_mask_bit+0x1da/0x29b (XEN)[] guest_mask_msi_irq+0x1c/0x1e (XEN)[] vmsi.c#msixtbl_write+0x173/0x1d4 (XEN)[] vmsi.c#_msixtbl_write+0x16/0x18 (XEN)[] hvm_process_io_intercept+0x216/0x270 (XEN)[] hvm_io_intercept+0x27/0x4c (XEN)[] emulate.c#hvmemul_do_io+0x273/0x454 (XEN)[] emulate.c#hvmemul_do_io_buffer+0x3d/0x70 (XEN)[] emulate.c#hvmemul_linear_mmio_access+0x35e/0x436 (XEN)[] emulate.c#linear_write+0xdd/0x13b (XEN)[] emulate.c#hvmemul_write+0xbd/0xf1 (XEN)[] x86_emulate+0x2249d/0x23c5c (XEN)[] x86_emulate_wrapper+0x2b/0x5f (XEN)[] emulate.c#_hvm_emulate_one+0x54/0x1b2 (XEN)[] hvm_emulate_one+0x10/0x12 (XEN)[] hvm_emulate_one_insn+0x42/0x14a (XEN)[] handle_mmio_with_translation+0x4f/0x51 (XEN)[] hvm_hap_nested_page_fault+0x16c/0x6d8 (XEN)[] vmx_vmexit_handler+0x19b0/0x1f2e (XEN)[] vmx_asm_vmexit_handler+0xfa/0x270 It seems to me that guest is trying to mask a msi while the memory decoding of the device is disabled. Performing a device reset without proper method to avoid guest's MSI-X operation would lead to this issue. The fix is basic - detach pci device before resetting the device. Signed-off-by: Chao Gao --- tools/libxl/libxl_pci.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c index 87afa03..855fb71 100644 --- a/tools/libxl/libxl_pci.c +++ b/tools/libxl/libxl_pci.c @@ -1459,17 +1459,17 @@ skip1: fclose(f); } out: -/* don't do multiple resets while some functions are still passed through */ -if ( (pcidev->vdevfn & 0x7) == 0 ) { -libxl__device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); -} - if (!isstubdom) { rc = xc_deassign_device(ctx->xch, domid, pcidev_encode_bdf(pcidev)); if (rc < 0 && (hvm || errno != ENOSYS)) LOGED(ERROR, domainid, "xc_deassign_device failed"); } +/* don't do multiple resets while some functions are still passed through */ +if ( (pcidev->vdevfn & 0x7) == 0 ) { +libxl__device_pci_reset(gc, pcidev->domain, pcidev->bus, pcidev->dev, pcidev->func); +} + stubdomid = libxl_get_stubdom_id(ctx, domid); if (stubdomid != 0) { libxl_device_pci pcidev_s = *pcidev; -- 1.8.3.1 ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] x86emul: permit SAE for V{,U}COMIS{S,D}
On 10/12/2018 13:56, Jan Beulich wrote: On 10.12.18 at 14:20, wrote: >> On 10/12/2018 11:32, Jan Beulich wrote: >>> The avx512_vlen_check() invocation needs to be conditional. >>> >>> Signed-off-by: Jan Beulich >> I'm not sure if I've asked before, but do LIG instructions really #UD >> for L=3 ? I don't see any documentation to this effect. > At least on my Core i9 they do; I have a pending query with Intel > as to the intentions in general and the lack of clear documentation, > as well as to the behavior on the Knights line of processors (where > there is no AVX512VL, and hence where special casing VL=128 and > VL=256 but not VL= are at least > questionable). VL=3 will surely be 1024 bits wide, but I'd be interested to which register mnemonic they choose to follow xmm/ymm/zmm. I'll try to find some time to poke a Knights machine and see what happens. > >>> --- a/xen/arch/x86/x86_emulate/x86_emulate.c >>> +++ b/xen/arch/x86/x86_emulate/x86_emulate.c >>> @@ -6179,7 +6179,8 @@ x86_emulate( >>> evex.w != evex.pfx), >>>EXC_UD); >>> host_and_vcpu_must_have(avx512f); >>> -avx512_vlen_check(true); >>> +if ( !evex.br ) >> On the subject of ineligibility of the code, what about #define sae br ? >> >> That way, this would read "if ( !evex.sae ) check_vlen()" > The three meanings of the bit can't reasonably all be conveyed > by a acceptably short name. Of course we can introduce aliases > like the above, but please recall that > - "br" stands for _b_roadcast or _r_ounding, not _br_oadcast, TBH, I'd even forgotten this. I don't see it written anywhere. Despite what you claim, people will interpret it as _br_oadcast given a lack of any information to the contrary. > - we'd need another alias for the embedded-rounding case then. > If you're convinced this is a good idea, I can do respective > renaming both to what may already be committed as well as to > the rest of the still pending series. > > But personally I'd rather not go that route, to make it easier to > connect with one another all the uses/checks of that bit. This is > in particular because for insns which allow neither broadcast nor > rounding/SAE, I certainly don't want to check the same bit twice > (via its different names). The context-dependent meanings are: * Broadcast * Static Rounding * Suppress All Exceptions How about naming the field bsr for "broadcast/suppress/rounding" (which breaks the _br_oadcast vs _b_roadcast/_r_ounding confusion), and introducing a define for bcast, sae and rounding ? /* EVEX.b (SDM nomenclature) has encoding-dependent meaning. */ #define bcast bsr #define sae bsr #define rounding bsr That way, code with a single meaning can use the context-correct name, and any cases (are there any?) which don't use one of these modes can use the underlying field. (I certainly don't suggest checking the same bit with multiple names. Amongst other things, I expect Coverity will notice.) I don't think it will cause confusion for correlating the uses of the bit, because we will never be using more than a single name in one context. To unblock the original patch (which shouldn't be conflated with this suggested improvement), Acked-by: Andrew Cooper ~Andrew ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] x86/altp2m: add altp2m_vcpu_disable_notify
On 12/18/18 4:10 PM, Jan Beulich wrote: On 14.12.18 at 18:17, wrote: >> Allow altp2m users to disable #VE/VMFUNC alone. Currently it is >> only possible to disable this functionality when we disable altp2m >> completely; #VE/VMFUNC can only be enabled once per altp2m session. >> >> In addition to making things complete, disabling #VE is also a >> workaround for CFW116 ("When Virtualization Exceptions are Enabled, >> EPT Violations May Generate Erroneous Virtualization Exceptions") >> on Xeon CPUs. > > "Xeon CPUs" is overly generic. Yes, the CFW erratum prefix allows > to identify which one you mean, but only (afaik) by going through > the spec updates until you've found the right one. Can you please > be more specific here? Of course, sorry for the ambiguity. I was referring to the E-2100s: https://www.intel.com/content/www/us/en/products/docs/processors/xeon/xeon-e-2100-specification-update.html I will update the patch description. >> @@ -4602,6 +4603,36 @@ static int do_altp2m_op( >> break; >> } >> >> +case HVMOP_altp2m_vcpu_disable_notify: >> +{ >> +struct vcpu *v; >> + >> +if ( a.u.disable_notify.pad || >> + a.u.disable_notify.vcpu_id >= d->max_vcpus ) >> +{ >> +rc = -EINVAL; >> +break; >> +} >> + >> +if ( !cpu_has_vmx_virt_exceptions ) >> +{ >> +rc = -EOPNOTSUPP; >> +break; >> +} >> + >> +v = d->vcpu[a.u.enable_notify.vcpu_id]; >> + >> +if ( gfn_eq(vcpu_altp2m(v).veinfo_gfn, INVALID_GFN) ) >> +{ >> +rc = -EINVAL; >> +break; >> +} > > Why? Disabling what is already disabled is not wrong, and hence > could easily be treated as a no-op. Just tought I'd actually report that this would be a no-op. But it's not important, so I'll make it a no-op (simply break instead of setting rc to -EINVAL). >> --- a/xen/include/public/hvm/hvm_op.h >> +++ b/xen/include/public/hvm/hvm_op.h >> @@ -232,6 +232,13 @@ struct xen_hvm_altp2m_vcpu_enable_notify { >> typedef struct xen_hvm_altp2m_vcpu_enable_notify >> xen_hvm_altp2m_vcpu_enable_notify_t; >> DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t); >> >> +struct xen_hvm_altp2m_vcpu_disable_notify { >> +uint32_t vcpu_id; >> +uint32_t pad; > > Why the pad field? There's no hole left. Sorry, that was an oversight. I'll correct it. Thanks, Razvan ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] x86/altp2m: add altp2m_vcpu_disable_notify
>>> On 14.12.18 at 18:17, wrote: > Allow altp2m users to disable #VE/VMFUNC alone. Currently it is > only possible to disable this functionality when we disable altp2m > completely; #VE/VMFUNC can only be enabled once per altp2m session. > > In addition to making things complete, disabling #VE is also a > workaround for CFW116 ("When Virtualization Exceptions are Enabled, > EPT Violations May Generate Erroneous Virtualization Exceptions") > on Xeon CPUs. "Xeon CPUs" is overly generic. Yes, the CFW erratum prefix allows to identify which one you mean, but only (afaik) by going through the spec updates until you've found the right one. Can you please be more specific here? > @@ -4602,6 +4603,36 @@ static int do_altp2m_op( > break; > } > > +case HVMOP_altp2m_vcpu_disable_notify: > +{ > +struct vcpu *v; > + > +if ( a.u.disable_notify.pad || > + a.u.disable_notify.vcpu_id >= d->max_vcpus ) > +{ > +rc = -EINVAL; > +break; > +} > + > +if ( !cpu_has_vmx_virt_exceptions ) > +{ > +rc = -EOPNOTSUPP; > +break; > +} > + > +v = d->vcpu[a.u.enable_notify.vcpu_id]; > + > +if ( gfn_eq(vcpu_altp2m(v).veinfo_gfn, INVALID_GFN) ) > +{ > +rc = -EINVAL; > +break; > +} Why? Disabling what is already disabled is not wrong, and hence could easily be treated as a no-op. > --- a/xen/include/public/hvm/hvm_op.h > +++ b/xen/include/public/hvm/hvm_op.h > @@ -232,6 +232,13 @@ struct xen_hvm_altp2m_vcpu_enable_notify { > typedef struct xen_hvm_altp2m_vcpu_enable_notify > xen_hvm_altp2m_vcpu_enable_notify_t; > DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_vcpu_enable_notify_t); > > +struct xen_hvm_altp2m_vcpu_disable_notify { > +uint32_t vcpu_id; > +uint32_t pad; Why the pad field? There's no hole left. Jan ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] x86emul: avoid triggering assertions with VME/PVI early #GP check
On 11/12/2018 08:47, Jan Beulich wrote: > In commit efe9cba66c ("x86emul: VME and PVI modes require a #GP(0) check > first thing") I neglected the fact that the retire flags get zapped only > in x86_decode(), which hasn't been invoked yet at the point of the #GP(0) > check added. Move output state initialization into a helper function, > and invoke it from the callers of x86_decode() instead of doing it > (possibly too late) in that function. > > Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2] x86emul: fix vector-length check for AVX512F scalar fused-multiply-add insns
On 11/12/2018 08:48, Jan Beulich wrote: > The check needs to happen whenever EVEX.b (SDM nomenclature) is clear, > not just in the memory operand case. > > Signed-off-by: Jan Beulich > --- > v2: Clarify naming (to address apparent disconnect between description > and code change). Thanks - this is much easier to follow. Acked-by: Andrew Cooper ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] x86emul: work around SandyBridge errata
On 11/12/2018 08:50, Jan Beulich wrote: > There are a number of exception condition related errata on SandyBridge > CPUs, some of which are unexpected #UD (others, of no interest here, are > lack of mandated exceptions, or exceptions of unexpected type). Annotate > the one workaround we already have, and add two more. > > Due to the exception recovery we have in place for stub invocations > these aren't security issues. > > Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH for-4.12 v2 2/2] xen/arm: Stop relocating Xen
On 12/18/18 12:09 PM, Andrii Anisov wrote: Hello Julien, Hi, On 17.12.18 19:34, Andrii Anisov wrote: I see something like following as a quick WA (not even build tested): diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index d2c63a8..bf72ba9 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -223,8 +223,9 @@ fail: * meet these requirements directly. So instead of proceed as follows: * * We first allocate the largest allocation we can as low as we - * can. This then becomes the first bank. This bank must be at least - * 128MB (or dom0_mem if that is smaller). + * can. This then becomes the first bank. This bank is at least 128MB even if + * dom0 is configured for less. It is the way to get that bank 128MB aligned, + * what is required for 32-bit zImage. * * Then we start allocating more memory, trying to allocate the * largest possible size and trying smaller sizes until we @@ -253,7 +254,7 @@ static void __init allocate_memory_11(struct domain *d, struct kernel_info *kinfo) { const unsigned int min_low_order = - get_order_from_bytes(min_t(paddr_t, dom0_mem, MB(128))); + get_order_from_bytes(MB(128)); const unsigned int min_order = get_order_from_bytes(MB(4)); struct page_info *pg; unsigned int order = get_allocation_size(kinfo->unassigned_mem); @@ -268,6 +269,10 @@ static void __init allocate_memory_11(struct domain *d, */ BUG_ON(!is_domain_direct_mapped(d)); + if ( dom0_mem < MB(128)) + printk(XENLOG_WARNING "Allocating 128MB for Domain0 with %"PRIu64"MB\n", + dom0_mem/MB(1)); + printk("Allocating 1:1 mappings totalling %ldMB for dom0:\n", /* Don't want format this as PRIpaddr (16 digit hex) */ (unsigned long)(kinfo->unassigned_mem >> 20)); But I'm not sure if it worth to be sent, because I'm going to rewrite it soon. From the second thought, we have last posting date for 4.12 already in the past. So redesign will not go to 4.12. Maybe it worth to have the thing above as a bugfix for 4.12? What do you think? AFAICT, it was possible to boot a Dom0 with only 64MB on Arm64. So I am not entirely why we would also limit the size there. For Arm32, I think we should just return an error and fail the domain build. If you ask 64MB and we give you 128MB then something is already really wrong. Anyway, I think this should be submitted properly to discuss for Xen 4.12 inclusion. Cheers, -- Julien Grall ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH for-4.12 v3] xen/arm: Stop relocating Xen
At the moment, Xen is relocated towards the end of the memory. While this has the advantage to free space in low memory, the code is not compliant with the break-before-make because it requires to switch between two sets of page-table. This is not entirely trivial to fix as it would require us to go through an identity mapping and disabling MMU. Furthermore, it looks like that some platform (such as the Hikey960) may not be able to bring-up secondary CPUs if the entry is too high. While Xen should be quite tiny (< 2MB), the current algorigthm to allocate Dom0 memory will allocate memory chunk of at least 128MB. Those memory chunks will always be 128MB. This means that depending on where the modules are loaded, an extra 128MB may disappear. As there are up to 4 modules (initramfs, XSM, kernel, DTB) loaded in low memory. The problem is not entirely new as you could already waste 512MB of low-memory. The right solution would be to fix the allocation algorightm. But this is independent from this patch. For user in control of the memory (such as in U-boot), all modules should be loaded as much as possible together or outside low-memory (i.e above 4GB). For other users (i.e Grub/UEFI), I believe the bootloader is already keeping everything together. Based on the above, it would be fine to stop relocating Xen. This has the advantage to simplify the code and should speed-up the boot as relocation is not necessary anymore. Note that the break-before-make issue is not fixed by this patch. Signed-off-by: Julien Grall Reported-by: Matthew Daley Tested-by: Matthew Daley --- Changes in v3: - Update the commit message Changes in v2: - Add Matthew's tested-by --- xen/arch/arm/arm32/head.S | 54 +++ xen/arch/arm/arm64/head.S | 50 +--- xen/arch/arm/mm.c | 18 +++-- xen/arch/arm/setup.c | 65 +++ xen/include/asm-arm/mm.h | 2 +- 5 files changed, 17 insertions(+), 172 deletions(-) diff --git a/xen/arch/arm/arm32/head.S b/xen/arch/arm/arm32/head.S index 93b51e9ef2..390a505e05 100644 --- a/xen/arch/arm/arm32/head.S +++ b/xen/arch/arm/arm32/head.S @@ -469,58 +469,12 @@ fail: PRINT("- Boot failed -\r\n") GLOBAL(_end_boot) /* - * Copy Xen to new location and switch TTBR + * Switch TTBR * r1:r0 ttbr - * r2 source address - * r3 destination address - * [sp]=>r4length * - * Source and destination must be word aligned, length is rounded up - * to a 16 byte boundary. - * - * MUST BE VERY CAREFUL when saving things to RAM over the copy + * TODO: This code does not comply with break-before-make. */ -ENTRY(relocate_xen) -push {r4,r5,r6,r7,r8,r9,r10,r11} - -ldr r4, [sp, #8*4]/* Get 4th argument from stack */ - -/* Copy 16 bytes at a time using: - * r5: counter - * r6: data - * r7: data - * r8: data - * r9: data - * r10: source - * r11: destination - */ -mov r5, r4 -mov r10, r2 -mov r11, r3 -1: ldmia r10!, {r6, r7, r8, r9} -stmia r11!, {r6, r7, r8, r9} - -subs r5, r5, #16 -bgt 1b - -/* Flush destination from dcache using: - * r5: counter - * r6: step - * r7: vaddr - */ -dsb/* So the CPU issues all writes to the range */ - -mov r5, r4 -ldr r6, =dcache_line_bytes /* r6 := step */ -ldr r6, [r6] -mov r7, r3 - -1: mcr CP32(r7, DCCMVAC) - -add r7, r7, r6 -subs r5, r5, r6 -bgt 1b - +ENTRY(switch_ttbr) dsb/* Ensure the flushes happen before * continuing */ isb/* Ensure synchronization with previous @@ -543,8 +497,6 @@ ENTRY(relocate_xen) dsb/* Ensure completion of TLB+BP flush */ isb -pop {r4, r5,r6,r7,r8,r9,r10,r11} - mov pc, lr #ifdef CONFIG_EARLY_PRINTK diff --git a/xen/arch/arm/arm64/head.S b/xen/arch/arm/arm64/head.S index ef87b5c254..0b7f6e7f92 100644 --- a/xen/arch/arm/arm64/head.S +++ b/xen/arch/arm/arm64/head.S @@ -609,52 +609,14 @@ fail: PRINT("- Boot failed -\r\n") GLOBAL(_end_boot) -/* Copy Xen to new location and switch TTBR - * x0ttbr - * x1source address - * x2destination address - * x3length +/* + * Switch TTBR * - * Source and destination must be word aligned, length is rounded up - * to a 16 byte boundary. + * x0ttbr * - * MUST BE VERY CAREFUL when saving things to RAM over the copy */ -ENTRY(relocate_xen) -/* Copy 16 bytes at a time using: - * x9: counter - * x10: data - * x11: data - * x12: source - * x13: destination - */ -mov x9, x
Re: [Xen-devel] [PATCH for-4.12 v2 2/2] xen/arm: Stop relocating Xen
Hello Julien, On 17.12.18 19:34, Andrii Anisov wrote: I see something like following as a quick WA (not even build tested): diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c index d2c63a8..bf72ba9 100644 --- a/xen/arch/arm/domain_build.c +++ b/xen/arch/arm/domain_build.c @@ -223,8 +223,9 @@ fail: * meet these requirements directly. So instead of proceed as follows: * * We first allocate the largest allocation we can as low as we - * can. This then becomes the first bank. This bank must be at least - * 128MB (or dom0_mem if that is smaller). + * can. This then becomes the first bank. This bank is at least 128MB even if + * dom0 is configured for less. It is the way to get that bank 128MB aligned, + * what is required for 32-bit zImage. * * Then we start allocating more memory, trying to allocate the * largest possible size and trying smaller sizes until we @@ -253,7 +254,7 @@ static void __init allocate_memory_11(struct domain *d, struct kernel_info *kinfo) { const unsigned int min_low_order = - get_order_from_bytes(min_t(paddr_t, dom0_mem, MB(128))); + get_order_from_bytes(MB(128)); const unsigned int min_order = get_order_from_bytes(MB(4)); struct page_info *pg; unsigned int order = get_allocation_size(kinfo->unassigned_mem); @@ -268,6 +269,10 @@ static void __init allocate_memory_11(struct domain *d, */ BUG_ON(!is_domain_direct_mapped(d)); + if ( dom0_mem < MB(128)) + printk(XENLOG_WARNING "Allocating 128MB for Domain0 with %"PRIu64"MB\n", + dom0_mem/MB(1)); + printk("Allocating 1:1 mappings totalling %ldMB for dom0:\n", /* Don't want format this as PRIpaddr (16 digit hex) */ (unsigned long)(kinfo->unassigned_mem >> 20)); But I'm not sure if it worth to be sent, because I'm going to rewrite it soon. From the second thought, we have last posting date for 4.12 already in the past. So redesign will not go to 4.12. Maybe it worth to have the thing above as a bugfix for 4.12? What do you think? -- Sincerely, Andrii Anisov. ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] x86emul: fix 3-operand IMUL
On 18/12/2018 11:29, Jan Beulich wrote: > While commit 75066cd4ea ("x86emul: fix {,i}mul and {,i}div") indeed did > as its title says, it broke the 3-operand form by uniformly using AL/AX/ > EAX/RAX as second source operand. Fix this and add tests covering both > cases. > > Reported-by: Andrei Lutas > Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH] x86emul: fix 3-operand IMUL
On 12/18/18 1:29 PM, Jan Beulich wrote: > While commit 75066cd4ea ("x86emul: fix {,i}mul and {,i}div") indeed did > as its title says, it broke the 3-operand form by uniformly using AL/AX/ > EAX/RAX as second source operand. Fix this and add tests covering both > cases. > > Reported-by: Andrei Lutas > Signed-off-by: Jan Beulich Tested-by: Razvan Cojocaru Thank you, Razvan ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [linux-4.14 test] 131385: regressions - FAIL
flight 131385 linux-4.14 real [real] http://logs.test-lab.xenproject.org/osstest/logs/131385/ Regressions :-( Tests which did not succeed and are blocking, including tests which could not be run: test-armhf-armhf-libvirt 17 guest-start.2fail REGR. vs. 131318 Tests which did not succeed, but are not blocking: test-amd64-i386-xl-pvshim12 guest-start fail never pass test-amd64-amd64-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-i386-libvirt 13 migrate-support-checkfail never pass test-amd64-i386-libvirt-xsm 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt 13 migrate-support-checkfail never pass test-amd64-amd64-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-i386-libvirt-qemuu-debianhvm-amd64-xsm 11 migrate-support-check fail never pass test-amd64-amd64-qemuu-nested-amd 17 debian-hvm-install/l1/l2 fail never pass test-amd64-amd64-libvirt-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-xl-multivcpu 13 migrate-support-checkfail never pass test-armhf-armhf-xl-multivcpu 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-cubietruck 13 migrate-support-checkfail never pass test-armhf-armhf-xl-cubietruck 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-rtds 13 migrate-support-checkfail never pass test-armhf-armhf-xl-rtds 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-credit2 13 migrate-support-checkfail never pass test-armhf-armhf-xl-credit2 14 saverestore-support-checkfail never pass test-armhf-armhf-libvirt 13 migrate-support-checkfail never pass test-armhf-armhf-libvirt 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-credit1 13 migrate-support-checkfail never pass test-armhf-armhf-xl-credit1 14 saverestore-support-checkfail never pass test-amd64-i386-xl-qemut-win7-amd64 17 guest-stop fail never pass test-amd64-amd64-xl-qemuu-ws16-amd64 17 guest-stop fail never pass test-amd64-amd64-xl-qemuu-win7-amd64 17 guest-stop fail never pass test-amd64-i386-xl-qemuu-win7-amd64 17 guest-stop fail never pass test-amd64-amd64-xl-qemut-ws16-amd64 17 guest-stop fail never pass test-amd64-amd64-xl-qemut-win7-amd64 17 guest-stop fail never pass test-armhf-armhf-libvirt-raw 12 migrate-support-checkfail never pass test-armhf-armhf-libvirt-raw 13 saverestore-support-checkfail never pass test-armhf-armhf-xl 13 migrate-support-checkfail never pass test-armhf-armhf-xl 14 saverestore-support-checkfail never pass test-armhf-armhf-xl-arndale 13 migrate-support-checkfail never pass test-armhf-armhf-xl-arndale 14 saverestore-support-checkfail never pass test-amd64-i386-xl-qemuu-ws16-amd64 17 guest-stop fail never pass test-amd64-i386-xl-qemut-ws16-amd64 17 guest-stop fail never pass test-armhf-armhf-xl-vhd 12 migrate-support-checkfail never pass test-armhf-armhf-xl-vhd 13 saverestore-support-checkfail never pass test-amd64-i386-xl-qemut-win10-i386 10 windows-install fail never pass test-amd64-amd64-xl-qemut-win10-i386 10 windows-installfail never pass test-amd64-amd64-xl-qemuu-win10-i386 10 windows-installfail never pass test-amd64-i386-xl-qemuu-win10-i386 10 windows-install fail never pass version targeted for testing: linux3beeb2615681fe87f4e6291ade669d50c27ce59a baseline version: linux1bb538a39cf959009d4e424ea4e590a1f58b2ed6 Last test of basis 131318 2018-12-14 18:04:28 Z3 days Testing same since 131385 2018-12-17 08:40:50 Z1 days1 attempts People who touched revisions under test: Aaro Koskinen Aaron Brown Adam Ford Al Viro Alex Deucher Alexandre Belloni Alin Nastac Andrew Bowers Andrew Morton Arnaldo Carvalho de Melo Artem Savkov Artemy Kovalyov Benjamin Tissoires Catalin Marinas Christian Hewitt Christoph Hellwig Christoph Paasch Christophe JAILLET Colin Ian King Daniel Axtens Daniel Borkmann Dave Airlie David Howells David S. Miller David Sterba Davidlohr Bueso Davidlohr Bueso Dennis Dalessandro Doug Ledford Eran Ben Elisha Eric Dumazet Ewan D. Milne Felipe Balbi Felix Kuehling Filipe Manana Florian Westphal Greg Kroah-Hartman Guenter Roeck Hans de Goede Heiner Kallweit Huacai Chen Igor Druzhinin Ingo Molnar Janusz Krzysztofik Jarkko Nikula Jason Gunthorpe Jason Wang Jeff Kirsher Jiri Olsa Jiri Wiesner Jonathan Cameron Josh Elsasser Josh Poimboeuf J
Re: [Xen-devel] MSR load lists on Harpertown
On 18/12/2018 11:37, Jan Beulich wrote: On 18.12.18 at 10:56, wrote: >> On 18/12/2018 02:17, Tian, Kevin wrote: From: Andrew Cooper [mailto:andrew.coop...@citrix.com] Sent: Monday, December 17, 2018 10:21 PM On 17/12/2018 13:09, Andrew Cooper wrote: > On 17/12/2018 02:39, Tian, Kevin wrote: > After some investigation, it turns out that after vmentry, while the > load list has the value 0xd01 (NXE, LMA, LME, SCE), the value loaded > into hardware is 0xd00 (NXE, LMA, LME). > > I.e. when an MSR load list is used for EFER, we resume the guest with > SCE cleared. This is rather terminal for 64bit guests, as > syscall/sysret instructions take a #UD fault. > > I can't see anything relevant in the Specification Update for this > processor. > > I've confirmed that by not using a load list, the current value in > EFER > is preserved once the vmentry is complete, and by disabling the EFER > intercept, I can re-set SCE in non-root context and have > syscall/sysret > work correctly. > > However, given this behaviour, I can't think of any way to context > switch NX properly, and leave 64bit guests in a working state. > > Do you have any suggestions? > >>> I'm checking internally whether it's a known issue. >> from feedbacks that I collected so far, no one is aware of this issue. >> >>> btw did you try upgrading to a newer microcode? >>> >> while I'm approaching more channels, does it work by directly >> WRMSR to EFER just before VMENTRY for above special case ( >> thus remove EFER from MSR load/save list), if ucode update >> also fails? there is just a small window where NX might be wrong >> setting for Xen, but it might be OK for that carefully-baked code >> snippet? > Apologies for the delay. I was travelling last week. > > We cannot load the full guest's EFER value in Xen context. If the guest > has NX disabled, the next stack access in Xen will fault because the NX > bit becomes reserved when EFER.NXE is clear. > > As for the more general case of loading the guests EFER value (ignoring > NXE), we already know that works, because it is how Xen functioned for a > decade. > > I see that the latest production microcode on otcshare is slightly newer > than exists in the microcode_ctl package. I'll give it a spin. The behaviour is still the same, even with the latest microcode: (XEN) microcode: CPU0 updated from revision 0x60f to 0x612, date = 2015-08-02 >>> Just confirmed that there is no erratum which could explain above >>> behavior. >>> >>> I see several options here: >>> >>> a) load guest EFER in Xen context, just before vmentry. make sure no stack >>> access between load and VM enter. but it sounds messy to add such sku >>> specific workaround in that common path (especially just for an old one); >>> >>> b) leave guest following Xen NXE setting on Harpertown. doing so bears >>> with limitation as what fd32dcfe tries to fix, but it's better than syscall >>> error in 64bit guest. also not clean since some ad-hoc logic that is removed >>> by fd32dcfe may have to be added back; >>> >>> c) leave above issue unfixed. Harpertown is pretty old... >>> >>> d) more debug whether above is caused by other software bug >> Option a) is not possible. While we could in principle turn the line of >> pop gpr's into movs and avoid the stack accesses, > How would this avoid stack accesses? Very good point. I blame a complete lack of coffee while writing this email. The only option to make this work would be to map the stack as executable, and we most certainly aren't doing that as a workaround. ~Andrew ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] MSR load lists on Harpertown
>>> On 18.12.18 at 10:56, wrote: > On 18/12/2018 02:17, Tian, Kevin wrote: >>> From: Andrew Cooper [mailto:andrew.coop...@citrix.com] >>> Sent: Monday, December 17, 2018 10:21 PM >>> >>> On 17/12/2018 13:09, Andrew Cooper wrote: On 17/12/2018 02:39, Tian, Kevin wrote: After some investigation, it turns out that after vmentry, while the load list has the value 0xd01 (NXE, LMA, LME, SCE), the value loaded into hardware is 0xd00 (NXE, LMA, LME). I.e. when an MSR load list is used for EFER, we resume the guest with SCE cleared. This is rather terminal for 64bit guests, as syscall/sysret instructions take a #UD fault. I can't see anything relevant in the Specification Update for this processor. I've confirmed that by not using a load list, the current value in EFER is preserved once the vmentry is complete, and by disabling the EFER intercept, I can re-set SCE in non-root context and have syscall/sysret work correctly. However, given this behaviour, I can't think of any way to context switch NX properly, and leave 64bit guests in a working state. Do you have any suggestions? >> I'm checking internally whether it's a known issue. > from feedbacks that I collected so far, no one is aware of this issue. > >> btw did you try upgrading to a newer microcode? >> > while I'm approaching more channels, does it work by directly > WRMSR to EFER just before VMENTRY for above special case ( > thus remove EFER from MSR load/save list), if ucode update > also fails? there is just a small window where NX might be wrong > setting for Xen, but it might be OK for that carefully-baked code > snippet? Apologies for the delay. I was travelling last week. We cannot load the full guest's EFER value in Xen context. If the guest has NX disabled, the next stack access in Xen will fault because the NX bit becomes reserved when EFER.NXE is clear. As for the more general case of loading the guests EFER value (ignoring NXE), we already know that works, because it is how Xen functioned for a decade. I see that the latest production microcode on otcshare is slightly newer than exists in the microcode_ctl package. I'll give it a spin. >>> The behaviour is still the same, even with the latest microcode: >>> >>> (XEN) microcode: CPU0 updated from revision 0x60f to 0x612, date = >>> 2015-08-02 >>> >> Just confirmed that there is no erratum which could explain above >> behavior. >> >> I see several options here: >> >> a) load guest EFER in Xen context, just before vmentry. make sure no stack >> access between load and VM enter. but it sounds messy to add such sku >> specific workaround in that common path (especially just for an old one); >> >> b) leave guest following Xen NXE setting on Harpertown. doing so bears >> with limitation as what fd32dcfe tries to fix, but it's better than syscall >> error in 64bit guest. also not clean since some ad-hoc logic that is removed >> by fd32dcfe may have to be added back; >> >> c) leave above issue unfixed. Harpertown is pretty old... >> >> d) more debug whether above is caused by other software bug > > Option a) is not possible. While we could in principle turn the line of > pop gpr's into movs and avoid the stack accesses, How would this avoid stack accesses? > we will triple fault if an NMI/#MC hits. > > As for option d), I'm quite certain at this point that it is a > hardware/microcode issue, rather than a software issue. > > I'd prefer to leave Harpertown cores working than simply dismissing them > at this point, because they are still useful for compatibility testing. > TBH, I was expecting option b) to be the outcome. So did I, with ... > I don't suppose there is any chance of this being published as an > erratum which I can reference in the source code? ... such a reference. Jan ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2 1/1] xen/blkback: rework connect_ring() to avoid inconsistent xenstore 'ring-page-order' set by malicious blkfront
Hi Roger, On 12/18/2018 05:33 PM, Roger Pau Monné wrote: > On Tue, Dec 18, 2018 at 08:55:38AM +0800, Dongli Zhang wrote: >> The xenstore 'ring-page-order' is used globally for each blkback queue and >> therefore should be read from xenstore only once. However, it is obtained >> in read_per_ring_refs() which might be called multiple times during the >> initialization of each blkback queue. >> >> If the blkfront is malicious and the 'ring-page-order' is set in different >> value by blkfront every time before blkback reads it, this may end up at >> the "WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages));" in >> xen_blkif_disconnect() when frontend is destroyed. >> >> This patch reworks connect_ring() to read xenstore 'ring-page-order' only >> once. >> >> Signed-off-by: Dongli Zhang >> --- >> Changed since v1: >> * change the order of xenstore read in read_per_ring_refs(suggested by >> Roger Pau Monne) >> * use xenbus_read_unsigned() in connect_ring() (suggested by Roger Pau >> Monne) >> >> drivers/block/xen-blkback/xenbus.c | 70 >> ++ >> 1 file changed, 40 insertions(+), 30 deletions(-) >> >> diff --git a/drivers/block/xen-blkback/xenbus.c >> b/drivers/block/xen-blkback/xenbus.c >> index a4bc74e..7178f0f 100644 >> --- a/drivers/block/xen-blkback/xenbus.c >> +++ b/drivers/block/xen-blkback/xenbus.c >> @@ -926,7 +926,7 @@ static int read_per_ring_refs(struct xen_blkif_ring >> *ring, const char *dir) >> int err, i, j; >> struct xen_blkif *blkif = ring->blkif; >> struct xenbus_device *dev = blkif->be->dev; >> -unsigned int ring_page_order, nr_grefs, evtchn; >> +unsigned int nr_grefs, evtchn; >> >> err = xenbus_scanf(XBT_NIL, dir, "event-channel", "%u", >>&evtchn); >> @@ -936,43 +936,38 @@ static int read_per_ring_refs(struct xen_blkif_ring >> *ring, const char *dir) >> return err; >> } >> >> -err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u", >> - &ring_page_order); >> -if (err != 1) { >> -err = xenbus_scanf(XBT_NIL, dir, "ring-ref", "%u", >> &ring_ref[0]); >> -if (err != 1) { >> +nr_grefs = blkif->nr_ring_pages; >> +WARN_ON(!nr_grefs); >> + >> +for (i = 0; i < nr_grefs; i++) { >> +char ring_ref_name[RINGREF_NAME_LEN]; >> + >> +snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); >> +err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, >> + "%u", &ring_ref[i]); >> + >> +if (err != 1 && (i || (!i && nr_grefs > 1))) { > > AFAICT the above condition can be simplified as "err != 1 && > nr_grefs". > >> err = -EINVAL; > > There's no point in setting err here... > >> -xenbus_dev_fatal(dev, err, "reading %s/ring-ref", dir); >> +xenbus_dev_fatal(dev, err, "reading %s/%s", >> + dir, ring_ref_name); >> return err; > > ...since you can just return -EINVAL (same applies to the other > instance below). I would like to confirm if I would keep the err = -EINVAL in below because most of the below code is copied from original implementation without modification. There is no err set by xenbus_read_unsigned(). + ring_page_order = xenbus_read_unsigned(dev->otherend, + "ring-page-order", 0); + + if (ring_page_order > xen_blkif_max_ring_order) { + err = -EINVAL; + xenbus_dev_fatal(dev, err, +"requested ring page order %d exceed max:%d", +ring_page_order, +xen_blkif_max_ring_order); + return err; + } + + be->blkif->nr_ring_pages = 1 << ring_page_order; For the rest, I would do something like: + err = xenbus_scanf(XBT_NIL, dir, ring_ref_name, + "%u", &ring_ref[i]); + + if (err != 1 && nr_grefs > 1) { + xenbus_dev_fatal(dev, err, "reading %s/%s", +dir, ring_ref_name); + return -EINVAL; + } Thank you very much! Dongi Zhang ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
[Xen-devel] [PATCH] x86emul: fix 3-operand IMUL
While commit 75066cd4ea ("x86emul: fix {,i}mul and {,i}div") indeed did as its title says, it broke the 3-operand form by uniformly using AL/AX/ EAX/RAX as second source operand. Fix this and add tests covering both cases. Reported-by: Andrei Lutas Signed-off-by: Jan Beulich --- a/tools/tests/x86_emulator/test_x86_emulator.c +++ b/tools/tests/x86_emulator/test_x86_emulator.c @@ -890,6 +890,42 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); +printf("%-40s", "Testing imull -4(%ecx)..."); +instr[0] = 0xf7; instr[1] = 0x69; instr[2] = 0xfc; +regs.eflags = EFLAGS_ALWAYS_SET; +regs.eip= (unsigned long)&instr[0]; +regs.eax= 0x89abcdef; +res[0] = 0x12345678; +regs.ecx= (unsigned long)(res + 1); +rc = x86_emulate(&ctxt, &emulops); +if ( (rc != X86EMUL_OKAY) || + (regs.eax != 0x89abcdef * 0x12345678) || + (regs.edx != (uint64_t)((int64_t)(int32_t)0x89abcdef * + 0x12345678) >> 32) || + ((regs.eflags & (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF | + X86_EFLAGS_OF)) != + (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF | X86_EFLAGS_OF)) || + (regs.eip != (unsigned long)&instr[3]) ) +goto fail; +printf("okay\n"); + +printf("%-40s", "Testing imul $3,-4(%edx),%ecx..."); +instr[0] = 0x6b; instr[1] = 0x4a; instr[2] = 0xfc; instr[3] = 0x03; +regs.eflags = EFLAGS_ALWAYS_SET; +regs.eip= (unsigned long)&instr[0]; +regs.ecx= 0x12345678; +res[0] = 0x89abcdef; +regs.edx= (unsigned long)(res + 1); +rc = x86_emulate(&ctxt, &emulops); +if ( (rc != X86EMUL_OKAY) || + (regs.ecx != 0x89abcdef * 3) || + ((regs.eflags & (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF | + X86_EFLAGS_OF)) != + (EFLAGS_ALWAYS_SET | X86_EFLAGS_CF | X86_EFLAGS_OF)) || + (regs.eip != (unsigned long)&instr[4]) ) +goto fail; +printf("okay\n"); + #ifndef __x86_64__ printf("%-40s", "Testing daa/das (all inputs)..."); /* Bits 0-7: AL; Bit 8: EFLAGS.AF; Bit 9: EFLAGS.CF; Bit 10: DAA vs. DAS. */ --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -5055,12 +5055,13 @@ x86_emulate( } break; case 5: /* imul */ +dst.val = _regs.r(ax); imul: _regs.eflags &= ~(X86_EFLAGS_OF | X86_EFLAGS_CF); switch ( dst.bytes ) { case 1: -dst.val = (int8_t)src.val * (int8_t)_regs.al; +dst.val = (int8_t)src.val * (int8_t)dst.val; if ( (int8_t)dst.val != (int16_t)dst.val ) _regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF; ASSERT(b > 0x6b); @@ -5068,7 +5069,7 @@ x86_emulate( break; case 2: dst.val = ((uint32_t)(int16_t)src.val * - (uint32_t)(int16_t)_regs.ax); + (uint32_t)(int16_t)dst.val); if ( (int16_t)dst.val != (int32_t)dst.val ) _regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF; if ( b > 0x6b ) @@ -5077,7 +5078,7 @@ x86_emulate( #ifdef __x86_64__ case 4: dst.val = ((uint64_t)(int32_t)src.val * - (uint64_t)(int32_t)_regs.eax); + (uint64_t)(int32_t)dst.val); if ( (int32_t)dst.val != dst.val ) _regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF; if ( b > 0x6b ) @@ -5086,7 +5087,7 @@ x86_emulate( #endif default: u[0] = src.val; -u[1] = _regs.r(ax); +u[1] = dst.val; if ( imul_dbl(u) ) _regs.eflags |= X86_EFLAGS_OF | X86_EFLAGS_CF; if ( b > 0x6b ) ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH -next] x86/xen: Fix read buffer overflow
On 18/12/2018 10:42, YueHaibing wrote: > On 2018/12/18 16:31, Juergen Gross wrote: >> On 18/12/2018 09:19, YueHaibing wrote: >>> Fix smatch warning: >>> >>> arch/x86/xen/enlighten_pv.c:649 get_trap_addr() error: >>> buffer overflow 'early_idt_handler_array' 32 <= 32 >>> >>> Fixes: 42b3a4cb5609 ("x86/xen: Support early interrupts in xen pv guests") >>> Signed-off-by: YueHaibing >>> --- >>> arch/x86/xen/enlighten_pv.c | 2 +- >>> 1 file changed, 1 insertion(+), 1 deletion(-) >>> >>> diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c >>> index 2f6787f..81f200d 100644 >>> --- a/arch/x86/xen/enlighten_pv.c >>> +++ b/arch/x86/xen/enlighten_pv.c >>> @@ -646,7 +646,7 @@ static bool __ref get_trap_addr(void **addr, unsigned >>> int ist) >>> >>> if (nr == ARRAY_SIZE(trap_array) && >>> *addr >= (void *)early_idt_handler_array[0] && >>> - *addr < (void *)early_idt_handler_array[NUM_EXCEPTION_VECTORS]) { >>> + *addr < (void *)early_idt_handler_array[NUM_EXCEPTION_VECTORS - 1]) >>> { >>> nr = (*addr - (void *)early_idt_handler_array[0]) / >>> EARLY_IDT_HANDLER_SIZE; >>> *addr = (void *)xen_early_idt_handler_array[nr]; >>> >> No, this patch is wrong. >> >> early_idt_handler_array is a 2-dimensional array: >> >> const char >> early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; >> >> So above code doesn't do an out of bounds array access, but checks for >> *addr being in the array or outside of it (note the "<" used for the >> test). > Thank you for your explanation. This looks like a smatch bug. I'd feed it back upstream. It is explicitly permitted in the C spec to construct a pointer to one-past-the-end of an array, for the purposes of a < comparison. I'm not entirely sure where the "32 <= 32" statement is coming from. ~Andrew ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel
Re: [Xen-devel] [PATCH v2 08/10] libxl: Kill QEMU by uid when possible
George Dunlap writes ("Re: [PATCH v2 08/10] libxl: Kill QEMU by uid when possible"): > On 12/12/18 4:17 PM, Ian Jackson wrote: > > I am tempted to suggest replacing each call > > PROPAGATE_RC; > > with > > ACCUMULATE_RC(ddms); > > and put the definition in libxl_internal.h for use elsewhere. > > I like that better. What about `ACCUMULATE_RC(ddms->rc)` instead? Then > the same macro could be used for a local variable. Yes, SGTM. > >> +/* > >> + * If there was an error here, accumulate the error and fall back > >> + * to killing by pid. > >> + */ > >> +if (rc) { > >> +PROPAGATE_RC; > >> +LOGD(ERROR, domid, "Reading dm UID path failed for %s", path); > >> +} > > > > From the comment for libxl__xs_read_checked: > > | * On error, *result_out is undefined. > > Arguably this is a bear trap. Maybe you would like to fix it there > > rather than by setting dm_uid_str to 0 here. > > Saying it's "undefined" is probably a bear trap. But you don't like the > way it's actually written -- i.e., that the pointer is only modified if > the value is successfully read? I think that's a weirdly complicated interface with strange implications for normal callers. I dislike threading the logic through like this. By "fix it there" I meant change libxl__xs_read_checked to always set it to 0 on error, and to promise to do that. Sorry not to be explicit. IOW I don't really think libxl__xs_read_checked ought to expect to be used in an accumulate-y way, especially since it only leaves you with the previous value on errors you probably weren't expecting, and not on ENOENT. > >> +if (!reaper_pid) { /* child */ > >> +rc = kill_device_model_uid_child(ddms, dm_uid_str); > >> +_exit(rc); > >> +} > > > > You cannot _exit(rc). See my comments below... > > Is the 'not' attached to "rc" (i.e., the value must be positive), or > '_exit()' (i.e., you must call exit() rather than _exit())? To rc. > >> +static void kill_device_model_uid_cb(libxl__egc *egc, > >> +libxl__ev_child *destroyer, > >> +pid_t pid, int status) > >> +{ > >> +libxl__destroy_devicemodel_state *ddms = CONTAINER_OF(destroyer, > >> *ddms, destroyer); > >> +STATE_AO_GC(ddms->ao); > >> + > >> +if (status) { > >> +int rc = ERROR_FAIL;; > >> + > >> +if (WIFEXITED(status)) > >> +rc = WEXITSTATUS(status) - 128; > > > > This can't be right. Where does this 128 come from ? > > Looks like I was trying to figure out how WEXITSTATUS worked from > looking at the child of devices_destroy_cb() put in _exit() and how > domain_destroy_domid_cb() interpreted it: Namely, I inferred that > _exit(-1) would get you WEXITSTATUS(status) == 127, and extrapolated > that -2 would get you 126, and so on. But _exit(-1) won't get you WEXITSTATUS(status) == 127. Also, there is a manual. But it will be easier if I state what happens: * Only the bottom byte (2's complement) fo the argument to exit() or _exit() is used. This value is called the `exit status'. It is a common idiom to write exit(255) as exit(-1). * The resulting wait status (what you get from waitpid) is exit_status << 8. * If your died due to an uncaught signal, the wait status is the signal number. Plus 128 if the program dumped core. * HOWEVER a parent may experience other wait statuses: * The dynamic linker or other parts of the runtime may sometimes cause your program to exit nonconsensually, perhaps before it even ran any of your code. By convention it will (if it can) print a message to stderr, and use the exit status 255 or 127. * If a shell is involved, the rules are weirdly broken. When a process run by a shell terminates, the shell squashes either the top or bottom byte of the wait status into $?. That is, $? is now either the exit status, or the termination signal, or the termination signal plus 128. Typically if a shell script exits due to failure of a program it ran, it will call exit on $?. So signal numbers can end up showing up as exit statuses. * Kernels sometimes send processes SIGKILL due to OOM. And of course there are a lot of other signals that might arise for various reasons only very loosely within the program's control. * I am shy of exit status 126 due to what I think is a well-founded superstition that someone may steal it for something. * This stuff with the wait status is the same everywhere that's actually a dialect of Unix but macros have been provided WIFEXITED if true, you may use WEXITSTATUS WIFSIGNALEDif true, you may use WTERMSIG WCOREDUMP <- missing on some ancient proprietary unices and as I am a careful programmer I usually handle the remaining case (by printing something like `unexpected wait status %x') too. (There are other macros WIFSTOPPED etc. wh
Re: [Xen-devel] [PATCH -next] x86/xen: Fix read buffer overflow
On 2018/12/18 16:31, Juergen Gross wrote: > On 18/12/2018 09:19, YueHaibing wrote: >> Fix smatch warning: >> >> arch/x86/xen/enlighten_pv.c:649 get_trap_addr() error: >> buffer overflow 'early_idt_handler_array' 32 <= 32 >> >> Fixes: 42b3a4cb5609 ("x86/xen: Support early interrupts in xen pv guests") >> Signed-off-by: YueHaibing >> --- >> arch/x86/xen/enlighten_pv.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c >> index 2f6787f..81f200d 100644 >> --- a/arch/x86/xen/enlighten_pv.c >> +++ b/arch/x86/xen/enlighten_pv.c >> @@ -646,7 +646,7 @@ static bool __ref get_trap_addr(void **addr, unsigned >> int ist) >> >> if (nr == ARRAY_SIZE(trap_array) && >> *addr >= (void *)early_idt_handler_array[0] && >> -*addr < (void *)early_idt_handler_array[NUM_EXCEPTION_VECTORS]) { >> +*addr < (void *)early_idt_handler_array[NUM_EXCEPTION_VECTORS - 1]) >> { >> nr = (*addr - (void *)early_idt_handler_array[0]) / >> EARLY_IDT_HANDLER_SIZE; >> *addr = (void *)xen_early_idt_handler_array[nr]; >> > > No, this patch is wrong. > > early_idt_handler_array is a 2-dimensional array: > > const char > early_idt_handler_array[NUM_EXCEPTION_VECTORS][EARLY_IDT_HANDLER_SIZE]; > > So above code doesn't do an out of bounds array access, but checks for > *addr being in the array or outside of it (note the "<" used for the > test). Thank you for your explanation. > > > Juergen > > . > ___ Xen-devel mailing list Xen-devel@lists.xenproject.org https://lists.xenproject.org/mailman/listinfo/xen-devel