Re: [Qemu-devel] [PATCH v3 0/4] hw/misc: Add a MMIO interface to the pvpanicdevice
>On 18/10/2018 15:04, Philippe Mathieu-Daudé wrote: >> Hi, this series takes Peng Hao's previous work but rather than adding yet >> another device, simply add the MMIO interface to the current device (which >> only implements the I/O port access). >> >> The first patches are simple cleanups: >> - patch 1 move the pvpanic device with the 'ocmmon objects' so we compile >> it once for the x86/arm/aarch64 archs, >> - patch 2 simply renames ISA fields/definitions to generic ones. >> >> Then instead of add/use the MMIO pvpanic device in the virt machine in an >> unique patch, I split it in two distinct patches: >> - patch 3 uses Peng Hao's work, but add the MMIO interface to the existing >> device (no logical change). >> - patch 4 is Peng Hao's work in the virt machine (no logical change). >> >> v2 from Peng Hao is: >> https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg03433.html >> >> Regards, >> >> Phil. >> >> Philippe Mathieu-Daudé (4): >> hw/misc/pvpanic: Build the pvpanic device in $(common-obj) >> hw/misc/pvpanic: Cosmetic renaming > >Oops I failed when rebasing, these two are supposed to be from > >Peng Hao > now it can works. In refactoring code, there is still a need to add a type to distinguish different bus device. I add a type TYPE_PVPANIC_MMIO for sysbus pvpanic device and orignal TYPE_PVPANIC for isa pvpanic deivce. bindling-DT "qemu,pvpanic-mmio" in kernel is in review. I will resubmit patches. Thanks. >with below my S-o-b: >[PMD: Use TYPE_PVPANIC definition, split in 2 patches, >improved patch subject] > >> hw/misc/pvpanic: Add the MMIO interface >> hw/arm/virt: Use the pvpanic device >> >> default-configs/arm-softmmu.mak | 2 +- >> hw/arm/virt.c | 21 ++ >> hw/misc/Makefile.objs | 2 +- >> hw/misc/pvpanic.c | 68 + >> include/hw/arm/virt.h | 1 + >> 5 files changed, 84 insertions(+), 10 deletions(-) >>
Re: [Qemu-devel] [PATCH v5 3/3] x86: define a new MSR based feature word -- FEATURE_WORDS_ARCH_CAPABILITIES
On Wed, 2018-10-24 at 07:06 -0300, Eduardo Habkost wrote: > On Mon, Oct 15, 2018 at 12:47:25PM +0800, Robert Hoo wrote: > > Note RSBA is specially treated -- no matter host support it or not, > > qemu > > pretends it is supported. > > > > Signed-off-by: Robert Hoo > > I am now wondering what else we need to be able to remove > CPUID_7_0_EDX_ARCH_CAPABILITIES from > feature_word_info[FEAT_7_0_EDX].unmigratable_flags. Let me know once some thought comes out to you. > > This series is necessary for that, be I think we still can't let > the VM be migrated if arch-capabilities is enabled and we're > running on a host that doesn't have MSR_IA32_ARCH_CAPABILITIES on > kvm_feature_msrs. Agree. So I still keep CPUID_7_0_EDX_ARCH_CAPABILITIES in feature_word_info[FEAT_7_0_EDX].unmigratable_flags for now. > > Reviewed-by: Eduardo Habkost > > > --- > > target/i386/cpu.c | 31 ++- > > target/i386/cpu.h | 8 > > target/i386/kvm.c | 11 +++ > > 3 files changed, 49 insertions(+), 1 deletion(-) > > > > diff --git a/target/i386/cpu.c b/target/i386/cpu.c > > index d191b9c..51c8fd8 100644 > > --- a/target/i386/cpu.c > > +++ b/target/i386/cpu.c > > @@ -1141,6 +1141,27 @@ static FeatureWordInfo > > feature_word_info[FEATURE_WORDS] = { > > }, > > .tcg_features = ~0U, > > }, > > +/*Below are MSR exposed features*/ > > +[FEAT_ARCH_CAPABILITIES] = { > > +.type = MSR_FEATURE_WORD, > > +.feat_names = { > > +"rdctl-no", "ibrs-all", "rsba", "skip-l1dfl-vmentry", > > +"ssb-no", NULL, NULL, NULL, > > +NULL, NULL, NULL, NULL, > > +NULL, NULL, NULL, NULL, > > +NULL, NULL, NULL, NULL, > > +NULL, NULL, NULL, NULL, > > +NULL, NULL, NULL, NULL, > > +NULL, NULL, NULL, NULL, > > +}, > > +.msr = { > > +.index = MSR_IA32_ARCH_CAPABILITIES, > > +.cpuid_dep = { > > +FEAT_7_0_EDX, > > +CPUID_7_0_EDX_ARCH_CAPABILITIES > > +} > > +}, > > +}, > > }; > > > > typedef struct X86RegisterInfo32 { > > @@ -3696,7 +3717,15 @@ static uint32_t > > x86_cpu_get_supported_feature_word(FeatureWord w, > > wi- > > >cpuid.reg); > > break; > > case MSR_FEATURE_WORD: > > -r = kvm_arch_get_supported_msr_feature(kvm_state, wi- > > >msr.index); > > +/* Special case: > > + * No matter host status, IA32_ARCH_CAPABILITIES.RSBA > > [bit 2] > > + * is always supported in guest. > > + */ > > +if (wi->msr.index == MSR_IA32_ARCH_CAPABILITIES) { > > +r = MSR_ARCH_CAP_RSBA; > > +} > > +r |= kvm_arch_get_supported_msr_feature(kvm_state, > > +wi->msr.index); > > break; > > } > > } else if (hvf_enabled()) { > > diff --git a/target/i386/cpu.h b/target/i386/cpu.h > > index 730c06f..52a52ec 100644 > > --- a/target/i386/cpu.h > > +++ b/target/i386/cpu.h > > @@ -502,6 +502,7 @@ typedef enum FeatureWord { > > FEAT_6_EAX, /* CPUID[6].EAX */ > > FEAT_XSAVE_COMP_LO, /* CPUID[EAX=0xd,ECX=0].EAX */ > > FEAT_XSAVE_COMP_HI, /* CPUID[EAX=0xd,ECX=0].EDX */ > > +FEAT_ARCH_CAPABILITIES, > > FEATURE_WORDS, > > } FeatureWord; > > > > @@ -730,6 +731,13 @@ typedef uint32_t > > FeatureWordArray[FEATURE_WORDS]; > > #define CPUID_TOPOLOGY_LEVEL_SMT (1U << 8) > > #define CPUID_TOPOLOGY_LEVEL_CORE (2U << 8) > > > > +/* MSR Feature Bits */ > > +#define MSR_ARCH_CAP_RDCL_NO(1U << 0) > > +#define MSR_ARCH_CAP_IBRS_ALL (1U << 1) > > +#define MSR_ARCH_CAP_RSBA (1U << 2) > > +#define MSR_ARCH_CAP_SKIP_L1DFL_VMENTRY (1U << 3) > > +#define MSR_ARCH_CAP_SSB_NO (1U << 4) > > + > > #ifndef HYPERV_SPINLOCK_NEVER_RETRY > > #define HYPERV_SPINLOCK_NEVER_RETRY 0x > > #endif > > diff --git a/target/i386/kvm.c b/target/i386/kvm.c > > index db79dad..2f7b40d 100644 > > --- a/target/i386/kvm.c > > +++ b/target/i386/kvm.c > > @@ -1928,6 +1928,17 @@ static int kvm_put_msrs(X86CPU *cpu, int > > level) > > } > > #endif > > > > +/* If host supports feature MSR, write down. */ > > +if (kvm_feature_msrs) { > > +int i; > > +for (i = 0; i < kvm_feature_msrs->nmsrs; i++) > > +if (kvm_feature_msrs->indices[i] == > > MSR_IA32_ARCH_CAPABILITIES) { > > +kvm_msr_entry_add(cpu, MSR_IA32_ARCH_CAPABILITIES, > > + env- > > >features[FEAT_ARCH_CAPABILITIES]); > > +break; > > +} > > +} > > + > > /* > > * The following MSRs have side effects on the guest or are > > too heavy > > * for normal writeback. Limit them to reset or full state > > updates. > > -- > > 1.8.3.1 > > > > > >
Re: [Qemu-devel] [PATCH v5 2/3] x86: Data structure changes to support MSR based features
On Wed, 2018-10-24 at 07:16 -0300, Eduardo Habkost wrote: > On Mon, Oct 15, 2018 at 12:47:24PM +0800, Robert Hoo wrote: > > Add FeatureWordType indicator in struct FeatureWordInfo. > > Change feature_word_info[] accordingly. > > Change existing functions that refer to feature_word_info[] > > accordingly. > > > > Signed-off-by: Robert Hoo > > --- > > target/i386/cpu.c | 188 +++--- > > > > 1 file changed, 136 insertions(+), 52 deletions(-) > > > > diff --git a/target/i386/cpu.c b/target/i386/cpu.c > > index c88876d..d191b9c 100644 > > --- a/target/i386/cpu.c > > +++ b/target/i386/cpu.c > > @@ -770,17 +770,36 @@ static void x86_cpu_vendor_words2str(char > > *dst, uint32_t vendor1, > > /* missing: > > CPUID_XSAVE_XSAVEC, CPUID_XSAVE_XSAVES */ > > > > +typedef enum FeatureWordType { > > + CPUID_FEATURE_WORD, > > + MSR_FEATURE_WORD, > > +} FeatureWordType; > > + > > typedef struct FeatureWordInfo { > > +FeatureWordType type; > > /* feature flags names are taken from "Intel Processor > > Identification and > > * the CPUID Instruction" and AMD's "CPUID Specification". > > * In cases of disagreement between feature naming > > conventions, > > * aliases may be added. > > */ > > const char *feat_names[32]; > > -uint32_t cpuid_eax; /* Input EAX for CPUID */ > > -bool cpuid_needs_ecx; /* CPUID instruction uses ECX as input > > */ > > -uint32_t cpuid_ecx; /* Input ECX value for CPUID */ > > -int cpuid_reg;/* output register (R_* constant) */ > > +union { > > +/* If type==CPUID_FEATURE_WORD */ > > +struct { > > +uint32_t eax; /* Input EAX for CPUID */ > > +bool needs_ecx; /* CPUID instruction uses ECX as input > > */ > > +uint32_t ecx; /* Input ECX value for CPUID */ > > +int reg;/* output register (R_* constant) */ > > +} cpuid; > > +/* If type==MSR_FEATURE_WORD */ > > +struct { > > +uint32_t index; > > +struct { /*CPUID that enumerate this MSR*/ > > +FeatureWord cpuid_class; > > +uint32_tcpuid_flag; > > +} cpuid_dep; > > Aren't you going to use this field anywhere? Probably we want to > prevent the VM from starting if a bit is set in the feature world > but the cpuid_dep bit is not set. > > e.g.: > qemu-system-x86_64 -cpu Skylake-Client,-arch-capabilities,+rsba > probably should fail to start. How about in x86_cpu_filter_features() filters the MSR feature word, if its dependent CPUID feature bit is not set? The filter results will be record in cpu->filtered_features, and print out, like other filtered features. > > > +} msr; > > +}; > > [...] >
Re: [Qemu-devel] [PATCH] fw_cfg_reboot: ensure reboot_time is nonegative
Hello Laszlo and Philippe , Thanks for your review, Philippe Mathieu-Daudé 于2018年10月25日周四 上午6:56写道: > Hi, > > On 24/10/18 13:35, Laszlo Ersek wrote: > > On 10/24/18 09:11, Li Qiang wrote: > >> This can avoid setting a negative value to > >> etc/boot-fail-wait. > > Li Qiang, can you add a qtest for this? > > I will try to write one. Is it ok to write it without this patch, as the test will be not passed? Thanks, Li Qiang > >> > >> Signed-off-by: Li Qiang > >> --- > >> hw/nvram/fw_cfg.c | 15 ++- > >> 1 file changed, 10 insertions(+), 5 deletions(-) > >> > >> diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c > >> index f4a52d8..276dcb1 100644 > >> --- a/hw/nvram/fw_cfg.c > >> +++ b/hw/nvram/fw_cfg.c > >> @@ -199,12 +199,17 @@ static void fw_cfg_reboot(FWCfgState *s) > >> reboot_timeout = strtol(p, , 10); > >> } > >> } > >> -/* validate the input */ > >> -if (reboot_timeout > 0x) { > >> -error_report("reboot timeout is larger than 65535, force it to > 65535."); > >> -reboot_timeout = 0x; > >> + > >> +if (reboot_timeout >= 0) { > >> +/* validate the input */ > >> +if (reboot_timeout > 0x) { > >> +error_report("reboot timeout is larger than 65535," > >> + "force it to 65535."); > >> +reboot_timeout = 0x; > >> +} > >> +fw_cfg_add_file(s, "etc/boot-fail-wait", > >> +g_memdup(_timeout, 4), 4); > >> } > >> -fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(_timeout, > 4), 4); > >> } > >> > >> static void fw_cfg_write(FWCfgState *s, uint8_t value) > >> > > > > I don't feel strongly about fixing this issue. > > > > However, if we decide to fix it, we should start with the bare-bones > > strtol() call, visible at the top of the context. I'm not up-to-date on > > what's the best QEMU helper function for this, but I seem to remember it > > checks for trailing garbage, and perhaps even for range. Maybe we should > > Are you suggesting qemu_strtoul()? I agree this would be cleaner. > > I reference the 'boot_splash_time' in fw_cfg_bootsplash. We can also change there. > > even use a different (better) option parsing facility thatn > > qemu_opt_get(). Adding Eric and Markus. > > > > Also, I would suggest forcing negative values (that were explicitly > > specified) to some sensible positive default, such as 5 seconds or so. > > > > Thanks > > Laszlo > > >
[Qemu-devel] [PULL v2 27/28] piix_pci: fix i440fx data sheet link
From: Li Qiang It seems that the intel link is unavailable, change it to point to the qemu site. Signed-off-by: Li Qiang Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Marcel Apfelbaum Acked-by: Michael S. Tsirkin Reviewed-by: Michael S. Tsirkin --- hw/pci-host/piix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 731190d92d..213a81e669 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -40,7 +40,7 @@ /* * I440FX chipset data sheet. - * http://download.intel.com/design/chipsets/datashts/29054901.pdf + * https://wiki.qemu.org/File:29054901.pdf */ #define I440FX_PCI_HOST_BRIDGE(obj) \ -- MST
[Qemu-devel] [PULL v2 26/28] piix: use TYPE_FOO constants than string constats
From: Li Qiang Make them more QOMConventional. Cc:qemu-triv...@nongnu.org Signed-off-by: Li Qiang Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-host/piix.c | 11 +++ 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 82421a86e3..731190d92d 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -95,6 +95,9 @@ typedef struct PIIX3State { #define I440FX_PCI_DEVICE(obj) \ OBJECT_CHECK(PCII440FXState, (obj), TYPE_I440FX_PCI_DEVICE) +#define TYPE_PIIX3_DEVICE "PIIX3" +#define TYPE_PIIX3_XEN_DEVICE "PIIX3-xen" + struct PCII440FXState { /*< private >*/ PCIDevice parent_obj; @@ -424,13 +427,13 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type, * These additional routes can be discovered through ACPI. */ if (xen_enabled()) { PCIDevice *pci_dev = pci_create_simple_multifunction(b, - -1, true, "PIIX3-xen"); + -1, true, TYPE_PIIX3_XEN_DEVICE); piix3 = PIIX3_PCI_DEVICE(pci_dev); pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq, piix3, XEN_PIIX_NUM_PIRQS); } else { PCIDevice *pci_dev = pci_create_simple_multifunction(b, - -1, true, "PIIX3"); + -1, true, TYPE_PIIX3_DEVICE); piix3 = PIIX3_PCI_DEVICE(pci_dev); pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS); @@ -748,7 +751,7 @@ static void piix3_class_init(ObjectClass *klass, void *data) } static const TypeInfo piix3_info = { -.name = "PIIX3", +.name = TYPE_PIIX3_DEVICE, .parent= TYPE_PIIX3_PCI_DEVICE, .class_init= piix3_class_init, }; @@ -761,7 +764,7 @@ static void piix3_xen_class_init(ObjectClass *klass, void *data) }; static const TypeInfo piix3_xen_info = { -.name = "PIIX3-xen", +.name = TYPE_PIIX3_XEN_DEVICE, .parent= TYPE_PIIX3_PCI_DEVICE, .class_init= piix3_xen_class_init, }; -- MST
[Qemu-devel] [PULL v2 14/28] x86_iommu/amd: Add interrupt remap support when VAPIC is enabled
From: "Singh, Brijesh" Emulate the interrupt remapping support when guest virtual APIC is enabled. For more information refer: IOMMU spec rev 3.0 (section 2.2.5.2) When VAPIC is enabled, it uses interrupt remapping as defined in Table 22 and Figure 17 from IOMMU spec. Signed-off-by: Brijesh Singh Reviewed-by: Peter Xu Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/amd_iommu.h | 36 +++ hw/i386/amd_iommu.c | 69 +++- hw/i386/trace-events | 2 ++ 3 files changed, 106 insertions(+), 1 deletion(-) diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index f73be48fca..8061e9c49c 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -103,6 +103,7 @@ #define AMDVI_MMIO_CONTROL_EVENTINTEN (1ULL << 3) #define AMDVI_MMIO_CONTROL_COMWAITINTEN (1ULL << 4) #define AMDVI_MMIO_CONTROL_CMDBUFLEN (1ULL << 12) +#define AMDVI_MMIO_CONTROL_GAEN (1ULL << 17) /* MMIO status register bits */ #define AMDVI_MMIO_STATUS_CMDBUF_RUN (1 << 4) @@ -263,6 +264,38 @@ union irte { } fields; }; +/* Interrupt remapping table fields (Guest VAPIC is enabled) */ +union irte_ga_lo { + uint64_t val; + + /* For int remapping */ + struct { + uint64_t valid:1, +no_fault:1, +/* -- */ +int_type:3, +rq_eoi:1, +dm:1, +/* -- */ +guest_mode:1, +destination:8, +rsvd_1:48; + } fields_remap; +}; + +union irte_ga_hi { + uint64_t val; + struct { + uint64_t vector:8, +rsvd_2:56; + } fields; +}; + +struct irte_ga { + union irte_ga_lo lo; + union irte_ga_hi hi; +}; + #define TYPE_AMD_IOMMU_DEVICE "amd-iommu" #define AMD_IOMMU_DEVICE(obj)\ OBJECT_CHECK(AMDVIState, (obj), TYPE_AMD_IOMMU_DEVICE) @@ -332,6 +365,9 @@ typedef struct AMDVIState { /* IOTLB */ GHashTable *iotlb; + +/* Interrupt remapping */ +bool ga_enabled; } AMDVIState; #endif diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 8e2f13c029..353a810e6b 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -608,6 +608,7 @@ static void amdvi_handle_control_write(AMDVIState *s) s->completion_wait_intr = !!(control & AMDVI_MMIO_CONTROL_COMWAITINTEN); s->cmdbuf_enabled = s->enabled && !!(control & AMDVI_MMIO_CONTROL_CMDBUFLEN); +s->ga_enabled = !!(control & AMDVI_MMIO_CONTROL_GAEN); /* update the flags depending on the control register */ if (s->cmdbuf_enabled) { @@ -1094,6 +1095,65 @@ static int amdvi_int_remap_legacy(AMDVIState *iommu, return 0; } +static int amdvi_get_irte_ga(AMDVIState *s, MSIMessage *origin, uint64_t *dte, + struct irte_ga *irte, uint16_t devid) +{ +uint64_t irte_root, offset; + +irte_root = dte[2] & AMDVI_IR_PHYS_ADDR_MASK; +offset = (origin->data & AMDVI_IRTE_OFFSET) << 4; +trace_amdvi_ir_irte(irte_root, offset); + +if (dma_memory_read(_space_memory, irte_root + offset, +irte, sizeof(*irte))) { +trace_amdvi_ir_err("failed to get irte_ga"); +return -AMDVI_IR_GET_IRTE; +} + +trace_amdvi_ir_irte_ga_val(irte->hi.val, irte->lo.val); +return 0; +} + +static int amdvi_int_remap_ga(AMDVIState *iommu, + MSIMessage *origin, + MSIMessage *translated, + uint64_t *dte, + X86IOMMUIrq *irq, + uint16_t sid) +{ +int ret; +struct irte_ga irte; + +/* get interrupt remapping table */ +ret = amdvi_get_irte_ga(iommu, origin, dte, , sid); +if (ret < 0) { +return ret; +} + +if (!irte.lo.fields_remap.valid) { +trace_amdvi_ir_target_abort("RemapEn is disabled"); +return -AMDVI_IR_TARGET_ABORT; +} + +if (irte.lo.fields_remap.guest_mode) { +error_report_once("guest mode is not zero"); +return -AMDVI_IR_ERR; +} + +if (irte.lo.fields_remap.int_type > AMDVI_IOAPIC_INT_TYPE_ARBITRATED) { +error_report_once("reserved int_type is set"); +return -AMDVI_IR_ERR; +} + +irq->delivery_mode = irte.lo.fields_remap.int_type; +irq->vector = irte.hi.fields.vector; +irq->dest_mode = irte.lo.fields_remap.dm; +irq->redir_hint = irte.lo.fields_remap.rq_eoi; +irq->dest = irte.lo.fields_remap.destination; + +return 0; +} + static int __amdvi_int_remap_msi(AMDVIState *iommu, MSIMessage *origin, MSIMessage *translated, @@ -1101,6 +1161,7 @@ static int __amdvi_int_remap_msi(AMDVIState *iommu,
[Qemu-devel] [PULL v2 22/28] hw/pci-bridge/ioh3420: Remove unuseful header
From: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-bridge/ioh3420.h | 6 -- hw/pci-bridge/ioh3420.c | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) delete mode 100644 hw/pci-bridge/ioh3420.h diff --git a/hw/pci-bridge/ioh3420.h b/hw/pci-bridge/ioh3420.h deleted file mode 100644 index ea423cb991..00 --- a/hw/pci-bridge/ioh3420.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef QEMU_IOH3420_H -#define QEMU_IOH3420_H - -#include "hw/pci/pcie_port.h" - -#endif /* QEMU_IOH3420_H */ diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c index a451d74ee6..81f2de6f07 100644 --- a/hw/pci-bridge/ioh3420.c +++ b/hw/pci-bridge/ioh3420.c @@ -24,7 +24,7 @@ #include "hw/pci/pci_ids.h" #include "hw/pci/msi.h" #include "hw/pci/pcie.h" -#include "ioh3420.h" +#include "hw/pci/pcie_port.h" #define PCI_DEVICE_ID_IOH_EPORT 0x3420 /* D0:F0 express mode */ #define PCI_DEVICE_ID_IOH_REV 0x2 -- MST
[Qemu-devel] [PULL v2 12/28] x86_iommu/amd: Add interrupt remap support when VAPIC is not enabled
From: "Singh, Brijesh" Emulate the interrupt remapping support when guest virtual APIC is not enabled. For more info Refer: AMD IOMMU spec Rev 3.0 - section 2.2.5.1 When VAPIC is not enabled, it uses interrupt remapping as defined in Table 20 and Figure 15 from IOMMU spec. Signed-off-by: Brijesh Singh Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/amd_iommu.h | 44 ++ hw/i386/amd_iommu.c | 199 ++- hw/i386/trace-events | 7 ++ 3 files changed, 249 insertions(+), 1 deletion(-) diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index 4e7cc271c4..f73be48fca 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -217,7 +217,51 @@ /* Interrupt remapping errors */ #define AMDVI_IR_ERR0x1 +#define AMDVI_IR_GET_IRTE 0x2 +#define AMDVI_IR_TARGET_ABORT 0x3 +/* Interrupt remapping */ +#define AMDVI_IR_REMAP_ENABLE 1ULL +#define AMDVI_IR_INTCTL_SHIFT 60 +#define AMDVI_IR_INTCTL_ABORT 0 +#define AMDVI_IR_INTCTL_PASS1 +#define AMDVI_IR_INTCTL_REMAP 2 + +#define AMDVI_IR_PHYS_ADDR_MASK (((1ULL << 45) - 1) << 6) + +/* MSI data 10:0 bits (section 2.2.5.1 Fig 14) */ +#define AMDVI_IRTE_OFFSET 0x7ff + +/* Delivery mode of MSI data (same as IOAPIC deilver mode encoding) */ +#define AMDVI_IOAPIC_INT_TYPE_FIXED 0x0 +#define AMDVI_IOAPIC_INT_TYPE_ARBITRATED 0x1 +#define AMDVI_IOAPIC_INT_TYPE_SMI0x2 +#define AMDVI_IOAPIC_INT_TYPE_NMI0x4 +#define AMDVI_IOAPIC_INT_TYPE_INIT 0x5 +#define AMDVI_IOAPIC_INT_TYPE_EINT 0x7 + +/* Pass through interrupt */ +#define AMDVI_DEV_INT_PASS_MASK (1UL << 56) +#define AMDVI_DEV_EINT_PASS_MASK(1UL << 57) +#define AMDVI_DEV_NMI_PASS_MASK (1UL << 58) +#define AMDVI_DEV_LINT0_PASS_MASK (1UL << 62) +#define AMDVI_DEV_LINT1_PASS_MASK (1UL << 63) + +/* Interrupt remapping table fields (Guest VAPIC not enabled) */ +union irte { +uint32_t val; +struct { +uint32_t valid:1, + no_fault:1, + int_type:3, + rq_eoi:1, + dm:1, + guest_mode:1, + destination:8, + vector:8, + rsvd:8; +} fields; +}; #define TYPE_AMD_IOMMU_DEVICE "amd-iommu" #define AMD_IOMMU_DEVICE(obj)\ diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 9118a75530..8e2f13c029 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -28,6 +28,7 @@ #include "qemu/error-report.h" #include "hw/i386/apic_internal.h" #include "trace.h" +#include "hw/i386/apic-msidef.h" /* used AMD-Vi MMIO registers */ const char *amdvi_mmio_low[] = { @@ -1032,21 +1033,146 @@ static IOMMUTLBEntry amdvi_translate(IOMMUMemoryRegion *iommu, hwaddr addr, return ret; } +static int amdvi_get_irte(AMDVIState *s, MSIMessage *origin, uint64_t *dte, + union irte *irte, uint16_t devid) +{ +uint64_t irte_root, offset; + +irte_root = dte[2] & AMDVI_IR_PHYS_ADDR_MASK; +offset = (origin->data & AMDVI_IRTE_OFFSET) << 2; + +trace_amdvi_ir_irte(irte_root, offset); + +if (dma_memory_read(_space_memory, irte_root + offset, +irte, sizeof(*irte))) { +trace_amdvi_ir_err("failed to get irte"); +return -AMDVI_IR_GET_IRTE; +} + +trace_amdvi_ir_irte_val(irte->val); + +return 0; +} + +static int amdvi_int_remap_legacy(AMDVIState *iommu, + MSIMessage *origin, + MSIMessage *translated, + uint64_t *dte, + X86IOMMUIrq *irq, + uint16_t sid) +{ +int ret; +union irte irte; + +/* get interrupt remapping table */ +ret = amdvi_get_irte(iommu, origin, dte, , sid); +if (ret < 0) { +return ret; +} + +if (!irte.fields.valid) { +trace_amdvi_ir_target_abort("RemapEn is disabled"); +return -AMDVI_IR_TARGET_ABORT; +} + +if (irte.fields.guest_mode) { +error_report_once("guest mode is not zero"); +return -AMDVI_IR_ERR; +} + +if (irte.fields.int_type > AMDVI_IOAPIC_INT_TYPE_ARBITRATED) { +error_report_once("reserved int_type"); +return -AMDVI_IR_ERR; +} + +irq->delivery_mode = irte.fields.int_type; +irq->vector = irte.fields.vector; +irq->dest_mode = irte.fields.dm; +irq->redir_hint = irte.fields.rq_eoi; +irq->dest = irte.fields.destination; + +return 0; +} + +static int __amdvi_int_remap_msi(AMDVIState *iommu, + MSIMessage *origin, +
[Qemu-devel] [PULL v2 21/28] hw/pci-bridge/xio3130: Remove unused functions
From: Philippe Mathieu-Daudé Introduced in 48ebf2f90f8 and faf1e708d5b, these functions were never used. Remove them. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-bridge/xio3130_downstream.h | 11 --- hw/pci-bridge/xio3130_upstream.h | 10 -- hw/pci-bridge/xio3130_downstream.c | 28 +--- hw/pci-bridge/xio3130_upstream.c | 24 +--- 4 files changed, 2 insertions(+), 71 deletions(-) delete mode 100644 hw/pci-bridge/xio3130_downstream.h delete mode 100644 hw/pci-bridge/xio3130_upstream.h diff --git a/hw/pci-bridge/xio3130_downstream.h b/hw/pci-bridge/xio3130_downstream.h deleted file mode 100644 index 8426d9ffa6..00 --- a/hw/pci-bridge/xio3130_downstream.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef QEMU_XIO3130_DOWNSTREAM_H -#define QEMU_XIO3130_DOWNSTREAM_H - -#include "hw/pci/pcie_port.h" - -PCIESlot *xio3130_downstream_init(PCIBus *bus, int devfn, bool multifunction, - const char *bus_name, pci_map_irq_fn map_irq, - uint8_t port, uint8_t chassis, - uint16_t slot); - -#endif /* QEMU_XIO3130_DOWNSTREAM_H */ diff --git a/hw/pci-bridge/xio3130_upstream.h b/hw/pci-bridge/xio3130_upstream.h deleted file mode 100644 index d0ab7577e2..00 --- a/hw/pci-bridge/xio3130_upstream.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef QEMU_XIO3130_UPSTREAM_H -#define QEMU_XIO3130_UPSTREAM_H - -#include "hw/pci/pcie_port.h" - -PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction, -const char *bus_name, pci_map_irq_fn map_irq, -uint8_t port); - -#endif /* QEMU_XIO3130_UPSTREAM_H */ diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c index b202657954..467bbabe4c 100644 --- a/hw/pci-bridge/xio3130_downstream.c +++ b/hw/pci-bridge/xio3130_downstream.c @@ -23,7 +23,7 @@ #include "hw/pci/pci_ids.h" #include "hw/pci/msi.h" #include "hw/pci/pcie.h" -#include "xio3130_downstream.h" +#include "hw/pci/pcie_port.h" #include "qapi/error.h" #define PCI_DEVICE_ID_TI_XIO3130D 0x8233 /* downstream port */ @@ -127,32 +127,6 @@ static void xio3130_downstream_exitfn(PCIDevice *d) pci_bridge_exitfn(d); } -PCIESlot *xio3130_downstream_init(PCIBus *bus, int devfn, bool multifunction, - const char *bus_name, pci_map_irq_fn map_irq, - uint8_t port, uint8_t chassis, - uint16_t slot) -{ -PCIDevice *d; -PCIBridge *br; -DeviceState *qdev; - -d = pci_create_multifunction(bus, devfn, multifunction, - "xio3130-downstream"); -if (!d) { -return NULL; -} -br = PCI_BRIDGE(d); - -qdev = DEVICE(d); -pci_bridge_map_irq(br, bus_name, map_irq); -qdev_prop_set_uint8(qdev, "port", port); -qdev_prop_set_uint8(qdev, "chassis", chassis); -qdev_prop_set_uint16(qdev, "slot", slot); -qdev_init_nofail(qdev); - -return PCIE_SLOT(d); -} - static Property xio3130_downstream_props[] = { DEFINE_PROP_BIT(COMPAT_PROP_PCP, PCIDevice, cap_present, QEMU_PCIE_SLTCAP_PCP_BITNR, true), diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c index bca2f9a5ea..b524908cf1 100644 --- a/hw/pci-bridge/xio3130_upstream.c +++ b/hw/pci-bridge/xio3130_upstream.c @@ -23,7 +23,7 @@ #include "hw/pci/pci_ids.h" #include "hw/pci/msi.h" #include "hw/pci/pcie.h" -#include "xio3130_upstream.h" +#include "hw/pci/pcie_port.h" #define PCI_DEVICE_ID_TI_XIO3130U 0x8232 /* upstream port */ #define XIO3130_REVISION0x2 @@ -108,28 +108,6 @@ static void xio3130_upstream_exitfn(PCIDevice *d) pci_bridge_exitfn(d); } -PCIEPort *xio3130_upstream_init(PCIBus *bus, int devfn, bool multifunction, - const char *bus_name, pci_map_irq_fn map_irq, - uint8_t port) -{ -PCIDevice *d; -PCIBridge *br; -DeviceState *qdev; - -d = pci_create_multifunction(bus, devfn, multifunction, "x3130-upstream"); -if (!d) { -return NULL; -} -br = PCI_BRIDGE(d); - -qdev = DEVICE(d); -pci_bridge_map_irq(br, bus_name, map_irq); -qdev_prop_set_uint8(qdev, "port", port); -qdev_init_nofail(qdev); - -return PCIE_PORT(d); -} - static const VMStateDescription vmstate_xio3130_upstream = { .name = "xio3130-express-upstream-port", .priority = MIG_PRI_PCI_BUS, -- MST
[Qemu-devel] [PULL v2 09/28] x86_iommu/amd: remove V=1 check from amdvi_validate_dte()
From: "Singh, Brijesh" Currently, the amdvi_validate_dte() assumes that a valid DTE will always have V=1. This is not true. The V=1 means that bit[127:1] are valid. A valid DTE can have IV=1 and V=0 (i.e address translation disabled and interrupt remapping enabled) Remove the V=1 check from amdvi_validate_dte(), make the caller responsible to check for V or IV bits. This also fixes a bug in existing code that when error is detected during the translation we'll fail the translation instead of assuming a passthrough mode. Signed-off-by: Brijesh Singh Reviewed-by: Peter Xu Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/amd_iommu.c | 10 +++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 1fd669fef8..7206bb09c2 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -807,7 +807,7 @@ static inline uint64_t amdvi_get_perms(uint64_t entry) AMDVI_DEV_PERM_SHIFT; } -/* a valid entry should have V = 1 and reserved bits honoured */ +/* validate that reserved bits are honoured */ static bool amdvi_validate_dte(AMDVIState *s, uint16_t devid, uint64_t *dte) { @@ -820,7 +820,7 @@ static bool amdvi_validate_dte(AMDVIState *s, uint16_t devid, return false; } -return dte[0] & AMDVI_DEV_VALID; +return true; } /* get a device table entry given the devid */ @@ -966,8 +966,12 @@ static void amdvi_do_translate(AMDVIAddressSpace *as, hwaddr addr, return; } -/* devices with V = 0 are not translated */ if (!amdvi_get_dte(s, devid, entry)) { +return; +} + +/* devices with V = 0 are not translated */ +if (!(entry[0] & AMDVI_DEV_VALID)) { goto out; } -- MST
[Qemu-devel] [PULL v2 16/28] MAINTAINERS: list "tests/acpi-test-data" files in ACPI/SMBIOS section
From: Laszlo Ersek The "tests/acpi-test-data" files are currently not covered by any section in MAINTAINERS, and "scripts/checkpatch.pl" complains when new data files are added. Cc: "Michael S. Tsirkin" Cc: Alex Williamson Cc: Gerd Hoffmann Cc: Igor Mammedov Cc: Marcel Apfelbaum Signed-off-by: Laszlo Ersek Reviewed-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 40672c4eba..b4d4bd4129 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1113,6 +1113,8 @@ F: hw/i386/acpi-build.[hc] F: hw/arm/virt-acpi-build.c F: tests/bios-tables-test.c F: tests/acpi-utils.[hc] +F: tests/acpi-test-data/* +F: tests/acpi-test-data/*/* ppc4xx M: Alexander Graf -- MST
[Qemu-devel] [PULL v2 25/28] i440fx: use ARRAY_SIZE for pam_regions
From: Li Qiang Cc: qemu-triv...@nongnu.org Signed-off-by: Li Qiang Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-host/piix.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index 999db824da..82421a86e3 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -142,7 +142,7 @@ static void i440fx_update_memory_mappings(PCII440FXState *d) PCIDevice *pd = PCI_DEVICE(d); memory_region_transaction_begin(); -for (i = 0; i < 13; i++) { +for (i = 0; i < ARRAY_SIZE(d->pam_regions); i++) { pam_update(>pam_regions[i], i, pd->config[I440FX_PAM + (DIV_ROUND_UP(i, 2))]); } @@ -412,7 +412,7 @@ PCIBus *i440fx_init(const char *host_type, const char *pci_type, init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space, >pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); -for (i = 0; i < 12; ++i) { +for (i = 0; i < ARRAY_SIZE(f->pam_regions) - 1; ++i) { init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space, >pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); -- MST
[Qemu-devel] [PULL v2 08/28] x86_iommu: move vtd_generate_msi_message in common file
From: "Singh, Brijesh" The vtd_generate_msi_message() in intel-iommu is used to construct a MSI Message from IRQ. A similar function will be needed when we add interrupt remapping support in amd-iommu. Moving the function in common file to avoid the code duplication. Rename it to x86_iommu_irq_to_msi_message(). There is no logic changes in the code flow. Signed-off-by: Brijesh Singh Suggested-by: Peter Xu Reviewed-by: Eduardo Habkost Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/i386/intel_iommu.h | 59 --- include/hw/i386/x86-iommu.h | 66 +++ hw/i386/intel_iommu.c | 32 +++-- hw/i386/x86-iommu.c | 24 + 4 files changed, 94 insertions(+), 87 deletions(-) diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h index fbfedcb1c0..ed4e758273 100644 --- a/include/hw/i386/intel_iommu.h +++ b/include/hw/i386/intel_iommu.h @@ -66,8 +66,6 @@ typedef struct VTDIOTLBEntry VTDIOTLBEntry; typedef struct VTDBus VTDBus; typedef union VTD_IR_TableEntry VTD_IR_TableEntry; typedef union VTD_IR_MSIAddress VTD_IR_MSIAddress; -typedef struct VTDIrq VTDIrq; -typedef struct VTD_MSIMessage VTD_MSIMessage; /* Context-Entry */ struct VTDContextEntry { @@ -197,63 +195,6 @@ union VTD_IR_MSIAddress { uint32_t data; }; -/* Generic IRQ entry information */ -struct VTDIrq { -/* Used by both IOAPIC/MSI interrupt remapping */ -uint8_t trigger_mode; -uint8_t vector; -uint8_t delivery_mode; -uint32_t dest; -uint8_t dest_mode; - -/* only used by MSI interrupt remapping */ -uint8_t redir_hint; -uint8_t msi_addr_last_bits; -}; - -struct VTD_MSIMessage { -union { -struct { -#ifdef HOST_WORDS_BIGENDIAN -uint32_t __addr_head:12; /* 0xfee */ -uint32_t dest:8; -uint32_t __reserved:8; -uint32_t redir_hint:1; -uint32_t dest_mode:1; -uint32_t __not_used:2; -#else -uint32_t __not_used:2; -uint32_t dest_mode:1; -uint32_t redir_hint:1; -uint32_t __reserved:8; -uint32_t dest:8; -uint32_t __addr_head:12; /* 0xfee */ -#endif -uint32_t __addr_hi; -} QEMU_PACKED; -uint64_t msi_addr; -}; -union { -struct { -#ifdef HOST_WORDS_BIGENDIAN -uint16_t trigger_mode:1; -uint16_t level:1; -uint16_t __resved:3; -uint16_t delivery_mode:3; -uint16_t vector:8; -#else -uint16_t vector:8; -uint16_t delivery_mode:3; -uint16_t __resved:3; -uint16_t level:1; -uint16_t trigger_mode:1; -#endif -uint16_t __resved1; -} QEMU_PACKED; -uint32_t msi_data; -}; -}; - /* When IR is enabled, all MSI/MSI-X data bits should be zero */ #define VTD_IR_MSI_DATA (0) diff --git a/include/hw/i386/x86-iommu.h b/include/hw/i386/x86-iommu.h index 7c71fc7470..2b22a579a3 100644 --- a/include/hw/i386/x86-iommu.h +++ b/include/hw/i386/x86-iommu.h @@ -22,6 +22,7 @@ #include "hw/sysbus.h" #include "hw/pci/pci.h" +#include "hw/pci/msi.h" #define TYPE_X86_IOMMU_DEVICE ("x86-iommu") #define X86_IOMMU_DEVICE(obj) \ @@ -35,6 +36,8 @@ typedef struct X86IOMMUState X86IOMMUState; typedef struct X86IOMMUClass X86IOMMUClass; +typedef struct X86IOMMUIrq X86IOMMUIrq; +typedef struct X86IOMMU_MSIMessage X86IOMMU_MSIMessage; typedef enum IommuType { TYPE_INTEL, @@ -78,6 +81,63 @@ struct X86IOMMUState { QLIST_HEAD(, IEC_Notifier) iec_notifiers; /* IEC notify list */ }; +/* Generic IRQ entry information when interrupt remapping is enabled */ +struct X86IOMMUIrq { +/* Used by both IOAPIC/MSI interrupt remapping */ +uint8_t trigger_mode; +uint8_t vector; +uint8_t delivery_mode; +uint32_t dest; +uint8_t dest_mode; + +/* only used by MSI interrupt remapping */ +uint8_t redir_hint; +uint8_t msi_addr_last_bits; +}; + +struct X86IOMMU_MSIMessage { +union { +struct { +#ifdef HOST_WORDS_BIGENDIAN +uint32_t __addr_head:12; /* 0xfee */ +uint32_t dest:8; +uint32_t __reserved:8; +uint32_t redir_hint:1; +uint32_t dest_mode:1; +uint32_t __not_used:2; +#else +uint32_t __not_used:2; +uint32_t dest_mode:1; +uint32_t redir_hint:1; +uint32_t __reserved:8; +uint32_t dest:8; +uint32_t __addr_head:12; /* 0xfee */ +#endif +uint32_t __addr_hi; +} QEMU_PACKED; +uint64_t msi_addr; +}; +union { +struct { +#ifdef HOST_WORDS_BIGENDIAN +
[Qemu-devel] [PULL v2 28/28] vhost-scsi: prevent using uninitialized vqs
From: yuchenlin There are 3 virtqueues (ctrl, event and cmd) for virtio scsi device, but seabios will only set the physical address for the 3rd one (cmd). Then in vhost_virtqueue_start(), virtio_queue_get_desc_addr() will be 0 for ctrl and event vq. In this case, ctrl and event vq are not initialized. vhost_verify_ring_mappings may use uninitialized vhost_virtqueue such that vhost_verify_ring_part_mapping returns ENOMEM. When encountered this problem, we got the following logs: qemu-system-x86_64: Unable to map available ring for ring 0 qemu-system-x86_64: Verify ring failure on region 0 Signed-off-by: Forrest Liu Signed-off-by: yuchenlin Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/scsi/vhost-scsi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index becf550085..7f21b4f9d6 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -183,7 +183,7 @@ static void vhost_scsi_realize(DeviceState *dev, Error **errp) } vsc->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; -vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs); +vsc->dev.vqs = g_new0(struct vhost_virtqueue, vsc->dev.nvqs); vsc->dev.vq_index = 0; vsc->dev.backend_features = 0; -- MST
[Qemu-devel] [PULL v2 15/28] x86_iommu/amd: Enable Guest virtual APIC support
From: "Singh, Brijesh" Now that amd-iommu support interrupt remapping, enable the GASup in IVRS table and GASup in extended feature register to indicate that IOMMU support guest virtual APIC mode. GASup provides option to guest OS to make use of 128-bit IRTE. Note that the GAMSup is set to zero to indicate that amd-iommu does not support guest virtual APIC mode (aka AVIC) which would be used for the nested VMs. See Table 21 from IOMMU spec for interrupt virtualization controls Signed-off-by: Brijesh Singh Reviewed-by: Peter Xu Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/amd_iommu.h | 2 +- hw/i386/acpi-build.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index 8061e9c49c..687fcd8521 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -176,7 +176,7 @@ /* extended feature support */ #define AMDVI_EXT_FEATURES (AMDVI_FEATURE_PREFETCH | AMDVI_FEATURE_PPR | \ AMDVI_FEATURE_IA | AMDVI_FEATURE_GT | AMDVI_FEATURE_HE | \ -AMDVI_GATS_MODE | AMDVI_HATS_MODE) +AMDVI_GATS_MODE | AMDVI_HATS_MODE | AMDVI_FEATURE_GA) /* capabilities header */ #define AMDVI_CAPAB_FEATURES (AMDVI_CAPAB_FLAT_EXT | \ diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 1ef396ddbb..236a20eaa8 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2518,7 +2518,8 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker) build_append_int_noprefix(table_data, (48UL << 30) | /* HATS */ (48UL << 28) | /* GATS */ - (1UL << 2),/* GTSup */ + (1UL << 2) | /* GTSup */ + (1UL << 6),/* GASup */ 4); /* * Type 1 device entry reporting all devices -- MST
[Qemu-devel] [PULL v2 23/28] hw/pci: Add missing include
From: Philippe Mathieu-Daudé Noted while refactoring: CC mips-softmmu/hw/mips/gt64xxx_pci.o In file included from include/hw/pci-host/gt64xxx.h:2, from hw/mips/gt64xxx_pci.c:30: include/hw/pci/pci_bus.h:23:5: error: unknown type name ‘PCIIOMMUFunc’ PCIIOMMUFunc iommu_fn; ^~~~ include/hw/pci/pci_bus.h:27:5: error: unknown type name ‘pci_set_irq_fn’ pci_set_irq_fn set_irq; ^~ include/hw/pci/pci_bus.h:28:5: error: unknown type name ‘pci_map_irq_fn’ pci_map_irq_fn map_irq; ^~ include/hw/pci/pci_bus.h:29:5: error: unknown type name ‘pci_route_irq_fn’ pci_route_irq_fn route_intx_to_irq; ^~~~ include/hw/pci/pci_bus.h:31:24: error: ‘PCI_SLOT_MAX’ undeclared here (not in a function) PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX]; ^~~~ include/hw/pci/pci_bus.h:31:39: error: ‘PCI_FUNC_MAX’ undeclared here (not in a function) PCIDevice *devices[PCI_SLOT_MAX * PCI_FUNC_MAX]; ^~~~ make[1]: *** [rules.mak:69: hw/mips/gt64xxx_pci.o] Error 1 make: *** [Makefile:482: subdir-mips-softmmu] Error 2 Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- include/hw/pci/pci_bus.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h index b7da8f555b..dfb75752cb 100644 --- a/include/hw/pci/pci_bus.h +++ b/include/hw/pci/pci_bus.h @@ -1,6 +1,8 @@ #ifndef QEMU_PCI_BUS_H #define QEMU_PCI_BUS_H +#include "hw/pci/pci.h" + /* * PCI Bus datastructures. * -- MST
[Qemu-devel] [PULL v2 07/28] x86_iommu: move the kernel-irqchip check in common code
From: "Singh, Brijesh" Interrupt remapping needs kernel-irqchip={off|split} on both Intel and AMD platforms. Move the check in common place. Signed-off-by: Brijesh Singh Reviewed-by: Peter Xu Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 7 --- hw/i386/x86-iommu.c | 9 + 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index f24ebfca1c..015a6fc492 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -3262,13 +3262,6 @@ static bool vtd_decide_config(IntelIOMMUState *s, Error **errp) { X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s); -/* Currently Intel IOMMU IR only support "kernel-irqchip={off|split}" */ -if (x86_iommu->intr_supported && kvm_irqchip_in_kernel() && -!kvm_irqchip_is_split()) { -error_setg(errp, "Intel Interrupt Remapping cannot work with " - "kernel-irqchip=on, please use 'split|off'."); -return false; -} if (s->intr_eim == ON_OFF_AUTO_ON && !x86_iommu->intr_supported) { error_setg(errp, "eim=on cannot be selected without intremap=on"); return false; diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c index 8a01a2dd25..7440cb8d60 100644 --- a/hw/i386/x86-iommu.c +++ b/hw/i386/x86-iommu.c @@ -25,6 +25,7 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "trace.h" +#include "sysemu/kvm.h" void x86_iommu_iec_register_notifier(X86IOMMUState *iommu, iec_notify_fn fn, void *data) @@ -94,6 +95,14 @@ static void x86_iommu_realize(DeviceState *dev, Error **errp) return; } +/* Both Intel and AMD IOMMU IR only support "kernel-irqchip={off|split}" */ +if (x86_iommu->intr_supported && kvm_irqchip_in_kernel() && +!kvm_irqchip_is_split()) { +error_setg(errp, "Interrupt Remapping cannot work with " + "kernel-irqchip=on, please use 'split|off'."); +return; +} + if (x86_class->realize) { x86_class->realize(dev, errp); } -- MST
[Qemu-devel] [PULL v2 24/28] pci_bridge: fix typo in comment
From: Mao Zhongyi Signed-off-by: Mao Zhongyi Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci/pci_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index 08b7e44e2e..ee9dff2d3a 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -399,7 +399,7 @@ void pci_bridge_exitfn(PCIDevice *pci_dev) /* * before qdev initialization(qdev_init()), this function sets bus_name and - * map_irq callback which are necessry for pci_bridge_initfn() to + * map_irq callback which are necessary for pci_bridge_initfn() to * initialize bus. */ void pci_bridge_map_irq(PCIBridge *br, const char* bus_name, -- MST
[Qemu-devel] [PULL v2 19/28] hw/pci-host/x86: extend the 64-bit PCI hole relative to the fw-assigned base
From: Laszlo Ersek In commit 9fa99d2519cb ("hw/pci-host: Fix x86 Host Bridges 64bit PCI hole", 2017-11-16), we meant to expose such a 64-bit PCI MMIO aperture in the ACPI DSDT that would be at least as large as the new "pci-hole64-size" property (2GB on i440fx, 32GB on q35). The goal was to offer "enough" 64-bit MMIO aperture to the guest OS for hotplug purposes. In that commit, we added or modified five functions: - pc_pci_hole64_start(): shared between i440fx and q35. Provides a default 64-bit base, which starts beyond the cold-plugged 64-bit RAM, and skips the DIMM hotplug area too (if any). - i440fx_pcihost_get_pci_hole64_start(), q35_host_get_pci_hole64_start(): board-specific 64-bit base property getters called abstractly by the ACPI generator. Both of these fall back to pc_pci_hole64_start() if the firmware didn't program any 64-bit hole (i.e. if the firmware didn't assign a 64-bit GPA to any MMIO BAR on any device). Otherwise, they honor the firmware's BAR assignments (i.e., they treat the lowest 64-bit GPA programmed by the firmware as the base address for the aperture). - i440fx_pcihost_get_pci_hole64_end(), q35_host_get_pci_hole64_end(): these intended to extend the aperture to our size recommendation, calculated relative to the base of the aperture. Despite the original intent, i440fx_pcihost_get_pci_hole64_end() and q35_host_get_pci_hole64_end() currently only extend the aperture relative to the default base (pc_pci_hole64_start()), ignoring any programming done by the firmware. This means that our size recommendation may not be met. Fix it by honoring the firmware's address assignments. The strange extension sizes were spotted by Alex, in the log of a guest kernel running on top of OVMF (which prefers to assign 64-bit GPAs to 64-bit BARs). This change only affects DSDT generation, therefore no new compat property is being introduced. Using an i440fx OVMF guest with 5GB RAM, an example _CRS change is: > @@ -881,9 +881,9 @@ > QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, > Cacheable, ReadWrite, > 0x, // Granularity > 0x0008, // Range Minimum > -0x00080001C0FF, // Range Maximum > +0x00087FFF, // Range Maximum > 0x, // Translation Offset > -0x0001C100, // Length > +0x8000, // Length > ,, , AddressRangeMemory, TypeStatic) > }) > Device (GPE0) (On i440fx, the low RAM split is at 3GB, in this case. Therefore, with 5GB guest RAM and no DIMM hotplug range, pc_pci_hole64_start() returns 4 + (5-3) = 6 GB. Adding the 2GB extension to that yields 8GB, which is below the firmware-programmed base of 32GB, before the patch. Therefore, before the patch, the extension is ineffective. After the patch, we add the 2GB extension to the firmware-programmed base, namely 32GB.) Using a q35 OVMF guest with 5GB RAM, an example _CRS change is: > @@ -3162,9 +3162,9 @@ > QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, > Cacheable, ReadWrite, > 0x, // Granularity > 0x0008, // Range Minimum > -0x0009BFFF, // Range Maximum > +0x000F, // Range Maximum > 0x, // Translation Offset > -0x0001C000, // Length > +0x0008, // Length > ,, , AddressRangeMemory, TypeStatic) > }) > Device (GPE0) (On Q35, the low RAM split is at 2GB. Therefore, with 5GB guest RAM and no DIMM hotplug range, pc_pci_hole64_start() returns 4 + (5-2) = 7 GB. Adding the 32GB extension to that yields 39GB (0x_0009_BFFF_ + 1), before the patch. After the patch, we add the 32GB extension to the firmware-programmed base, namely 32GB.) The ACPI test data for the bios-tables-test case that we added earlier in this series are corrected too, as follows: > @@ -3339,9 +3339,9 @@ > QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, > Cacheable, ReadWrite, > 0x, // Granularity > 0x0002, // Range Minimum > -0x0009BFFF, // Range Maximum > +0x0009, // Range Maximum > 0x, // Translation Offset > -0x0007C000, // Length > +0x0008, // Length > ,, , AddressRangeMemory, TypeStatic) > }) > Device (GPE0) Cc: "Michael S. Tsirkin" Cc: Alex Williamson Cc: Gerd Hoffmann Cc: Igor Mammedov Cc: Marcel Apfelbaum Fixes: 9fa99d2519cbf71f871e46871df12cb446dc1c3e Signed-off-by: Laszlo Ersek Reviewed-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S.
[Qemu-devel] [PULL v2 20/28] tests/bios-tables-test: add 64-bit PCI MMIO aperture round-up test on Q35
From: Laszlo Ersek In commit 9fa99d2519cb ("hw/pci-host: Fix x86 Host Bridges 64bit PCI hole", 2017-11-16), we meant to expose such a 64-bit PCI MMIO aperture in the ACPI DSDT that would be at least as large as the new "pci-hole64-size" property (2GB on i440fx, 32GB on q35). The goal was to offer "enough" 64-bit MMIO aperture to the guest OS for hotplug purposes. Currently the aperture is extended relative to a possibly incorrect base. This may result in an aperture size that is smaller than the intent of commit 9fa99d2519cb. We're going to fix the error in a later patch in this series; now we just add a test case that reproduces and captures the problem. In the fix, the test data will be updated as well. In the test case being added: - use 128 MB initial RAM size, - ask for one DIMM hotplug slot, - ask for 2 GB maximum RAM size, - use a pci-testdev with a 64-bit BAR of 2 GB size. Consequences: (1) In pc_memory_init() [hw/i386/pc.c], the DIMM hotplug area size is initially set to 2048-128 = 1920 MB. (Maximum RAM size minus initial RAM size.) (2) The DIMM area base is set to 4096 MB (because the initial RAM is only 128 MB -- there is no initial "high RAM"). (3) Due to commit 085f8e88ba73 ("pc: count in 1Gb hugepage alignment when sizing hotplug-memory container", 2014-11-24), we add 1 GB for the one DIMM hotplug slot that was specified. This sets the DIMM area size to 1920+1024 = 2944 MB. (4) The reserved-memory-end address (exclusive) is set to 4096 + 2944 = 7040 MB (DIMM area base plus DIMM area size). (5) The reserved-memory-end address is rounded up to GB alignment, yielding 7 GB (7168 MB). (6) Given the 2 GB BAR size of pci-testdev, SeaBIOS allocates said 64-bit BAR in 64-bit address space. (7) Because reserved-memory-end is at 7 GB, it is unaligned for the 2 GB BAR. Therefore SeaBIOS allocates the BAR at 8 GB. QEMU then (correctly) assigns the root bridge aperture base this BAR address, to be exposed in \_SB.PCI0._CRS. (8) The intent of commit 9fa99d2519cb dictates that QEMU extend the aperture size to 32 GB, implying a 40 GB end address. However, QEMU performs the extension relative to reserved-memory-end (7 GB), not relative to the bridge aperture base that was correctly deduced from SeaBIOS's BAR programming (8 GB). Therefore we see 39 GB as the aperture end address in \_SB.PCI0._CRS: > QWordMemory (ResourceProducer, PosDecode, MinFixed, MaxFixed, Cacheable, > ReadWrite, > 0x, // Granularity > 0x0002, // Range Minimum > 0x0009BFFF, // Range Maximum > 0x, // Translation Offset > 0x0007C000, // Length > ,, , AddressRangeMemory, TypeStatic) Cc: "Michael S. Tsirkin" Cc: Alex Williamson Cc: Gerd Hoffmann Cc: Igor Mammedov Cc: Marcel Apfelbaum Signed-off-by: Laszlo Ersek Reviewed-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- tests/bios-tables-test.c | 16 tests/acpi-test-data/q35/DSDT.mmio64 | Bin 0 -> 8947 bytes tests/acpi-test-data/q35/SRAT.mmio64 | Bin 0 -> 224 bytes 3 files changed, 16 insertions(+) create mode 100644 tests/acpi-test-data/q35/DSDT.mmio64 create mode 100644 tests/acpi-test-data/q35/SRAT.mmio64 diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c index 4e24930c4b..9dd88f9d86 100644 --- a/tests/bios-tables-test.c +++ b/tests/bios-tables-test.c @@ -708,6 +708,21 @@ static void test_acpi_q35_tcg_bridge(void) free_test_data(); } +static void test_acpi_q35_tcg_mmio64(void) +{ +test_data data = { +.machine = MACHINE_Q35, +.variant = ".mmio64", +.required_struct_types = base_required_struct_types, +.required_struct_types_len = ARRAY_SIZE(base_required_struct_types) +}; + +test_acpi_one("-m 128M,slots=1,maxmem=2G " + "-device pci-testdev,membar=2G", + ); +free_test_data(); +} + static void test_acpi_piix4_tcg_cphp(void) { test_data data; @@ -875,6 +890,7 @@ int main(int argc, char *argv[]) qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge); qtest_add_func("acpi/q35", test_acpi_q35_tcg); qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge); +qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64); qtest_add_func("acpi/piix4/ipmi", test_acpi_piix4_tcg_ipmi); qtest_add_func("acpi/q35/ipmi", test_acpi_q35_tcg_ipmi); qtest_add_func("acpi/piix4/cpuhp", test_acpi_piix4_tcg_cphp); diff --git a/tests/acpi-test-data/q35/DSDT.mmio64 b/tests/acpi-test-data/q35/DSDT.mmio64 new file mode 100644 index ..a058ff2ee31a22a55b5b198bc1531c7f20b243f6 GIT binary patch literal 8947 zcmb7KTW=f38J*=#t05`MZVWfQbOALxMpqxlJWYk`r6l^h@YaKZ)QiHSyDi(2XemIbG~oR z?ChN7uKcdw`*w{n>)+KKuhA`4ueUuPeHLSk+Vt%-GdEcO(6819Rz8)n`gil9jgPAB
[Qemu-devel] [PULL v2 01/28] virtio-blk: fix comment for virtio_blk_rw_complete
From: Yaowei Bai Here should be submit_requests, there is no submit_merged_requests function. Signed-off-by: Yaowei Bai Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/block/virtio-blk.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 225fe44b7a..83cf5c01f9 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -97,8 +97,8 @@ static void virtio_blk_rw_complete(void *opaque, int ret) if (req->qiov.nalloc != -1) { /* If nalloc is != 1 req->qiov is a local copy of the original - * external iovec. It was allocated in submit_merged_requests - * to be able to merge requests. */ + * external iovec. It was allocated in submit_requests to be + * able to merge requests. */ qemu_iovec_destroy(>qiov); } -- MST
[Qemu-devel] [PULL v2 11/28] x86_iommu/amd: Prepare for interrupt remap support
From: "Singh, Brijesh" Register the interrupt remapping callback and read/write ops for the amd-iommu-ir memory region. amd-iommu-ir is set to higher priority to ensure that this region won't be masked out by other memory regions. Signed-off-by: Brijesh Singh Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Peter Xu Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/amd_iommu.h | 14 +- hw/i386/amd_iommu.c | 106 +++ hw/i386/trace-events | 5 ++ 3 files changed, 123 insertions(+), 2 deletions(-) diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index 874030582d..4e7cc271c4 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -206,8 +206,18 @@ #define AMDVI_COMMAND_SIZE 16 -#define AMDVI_INT_ADDR_FIRST 0xfee0 -#define AMDVI_INT_ADDR_LAST 0xfeef +#define AMDVI_INT_ADDR_FIRST0xfee0 +#define AMDVI_INT_ADDR_LAST 0xfeef +#define AMDVI_INT_ADDR_SIZE (AMDVI_INT_ADDR_LAST - AMDVI_INT_ADDR_FIRST + 1) +#define AMDVI_MSI_ADDR_HI_MASK (0xULL) +#define AMDVI_MSI_ADDR_LO_MASK (0xULL) + +/* SB IOAPIC is always on this device in AMD systems */ +#define AMDVI_IOAPIC_SB_DEVID PCI_BUILD_BDF(0, PCI_DEVFN(0x14, 0)) + +/* Interrupt remapping errors */ +#define AMDVI_IR_ERR0x1 + #define TYPE_AMD_IOMMU_DEVICE "amd-iommu" #define AMD_IOMMU_DEVICE(obj)\ diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 4bec1c6688..9118a75530 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -26,6 +26,7 @@ #include "amd_iommu.h" #include "qapi/error.h" #include "qemu/error-report.h" +#include "hw/i386/apic_internal.h" #include "trace.h" /* used AMD-Vi MMIO registers */ @@ -1031,6 +1032,99 @@ static IOMMUTLBEntry amdvi_translate(IOMMUMemoryRegion *iommu, hwaddr addr, return ret; } +/* Interrupt remapping for MSI/MSI-X entry */ +static int amdvi_int_remap_msi(AMDVIState *iommu, + MSIMessage *origin, + MSIMessage *translated, + uint16_t sid) +{ +assert(origin && translated); + +trace_amdvi_ir_remap_msi_req(origin->address, origin->data, sid); + +if (!iommu || !X86_IOMMU_DEVICE(iommu)->intr_supported) { +memcpy(translated, origin, sizeof(*origin)); +goto out; +} + +if (origin->address & AMDVI_MSI_ADDR_HI_MASK) { +trace_amdvi_err("MSI address high 32 bits non-zero when " +"Interrupt Remapping enabled."); +return -AMDVI_IR_ERR; +} + +if ((origin->address & AMDVI_MSI_ADDR_LO_MASK) != APIC_DEFAULT_ADDRESS) { +trace_amdvi_err("MSI is not from IOAPIC."); +return -AMDVI_IR_ERR; +} + +out: +trace_amdvi_ir_remap_msi(origin->address, origin->data, + translated->address, translated->data); +return 0; +} + +static int amdvi_int_remap(X86IOMMUState *iommu, + MSIMessage *origin, + MSIMessage *translated, + uint16_t sid) +{ +return amdvi_int_remap_msi(AMD_IOMMU_DEVICE(iommu), origin, + translated, sid); +} + +static MemTxResult amdvi_mem_ir_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size, + MemTxAttrs attrs) +{ +int ret; +MSIMessage from = { 0, 0 }, to = { 0, 0 }; +uint16_t sid = AMDVI_IOAPIC_SB_DEVID; + +from.address = (uint64_t) addr + AMDVI_INT_ADDR_FIRST; +from.data = (uint32_t) value; + +trace_amdvi_mem_ir_write_req(addr, value, size); + +if (!attrs.unspecified) { +/* We have explicit Source ID */ +sid = attrs.requester_id; +} + +ret = amdvi_int_remap_msi(opaque, , , sid); +if (ret < 0) { +/* TODO: log the event using IOMMU log event interface */ +error_report_once("failed to remap interrupt from devid 0x%x", sid); +return MEMTX_ERROR; +} + +apic_get_class()->send_msi(); + +trace_amdvi_mem_ir_write(to.address, to.data); +return MEMTX_OK; +} + +static MemTxResult amdvi_mem_ir_read(void *opaque, hwaddr addr, + uint64_t *data, unsigned size, + MemTxAttrs attrs) +{ +return MEMTX_OK; +} + +static const MemoryRegionOps amdvi_ir_ops = { +.read_with_attrs = amdvi_mem_ir_read, +.write_with_attrs = amdvi_mem_ir_write, +.endianness = DEVICE_LITTLE_ENDIAN, +.impl = { +.min_access_size = 4, +.max_access_size = 4, +}, +.valid = { +.min_access_size = 4, +.max_access_size = 4, +} +}; + static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) {
[Qemu-devel] [PULL v2 18/28] hw/pci-host/x86: extract get_pci_hole64_start_value() helpers
From: Laszlo Ersek Expose the calculated "hole64 start" GPAs as plain uint64_t values, extracting the internals of the current property getters. This patch doesn't change behavior. Cc: "Michael S. Tsirkin" Cc: Alex Williamson Cc: Gerd Hoffmann Cc: Igor Mammedov Cc: Marcel Apfelbaum Signed-off-by: Laszlo Ersek Reviewed-by: Marcel Apfelbaum Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/pci-host/piix.c | 15 +++ hw/pci-host/q35.c | 15 +++ 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c index da73743fa2..15cc34912e 100644 --- a/hw/pci-host/piix.c +++ b/hw/pci-host/piix.c @@ -249,9 +249,7 @@ static void i440fx_pcihost_get_pci_hole_end(Object *obj, Visitor *v, * the 64bit PCI hole will start after "over 4G RAM" and the * reserved space for memory hotplug if any. */ -static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v, -const char *name, -void *opaque, Error **errp) +static uint64_t i440fx_pcihost_get_pci_hole64_start_value(Object *obj) { PCIHostState *h = PCI_HOST_BRIDGE(obj); I440FXState *s = I440FX_PCI_HOST_BRIDGE(obj); @@ -263,7 +261,16 @@ static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v, if (!value && s->pci_hole64_fix) { value = pc_pci_hole64_start(); } -visit_type_uint64(v, name, , errp); +return value; +} + +static void i440fx_pcihost_get_pci_hole64_start(Object *obj, Visitor *v, +const char *name, +void *opaque, Error **errp) +{ +uint64_t hole64_start = i440fx_pcihost_get_pci_hole64_start_value(obj); + +visit_type_uint64(v, name, _start, errp); } /* diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 8ce1e09932..919de104fc 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -113,9 +113,7 @@ static void q35_host_get_pci_hole_end(Object *obj, Visitor *v, * the 64bit PCI hole will start after "over 4G RAM" and the * reserved space for memory hotplug if any. */ -static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v, - const char *name, void *opaque, - Error **errp) +static uint64_t q35_host_get_pci_hole64_start_value(Object *obj) { PCIHostState *h = PCI_HOST_BRIDGE(obj); Q35PCIHost *s = Q35_HOST_DEVICE(obj); @@ -127,7 +125,16 @@ static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v, if (!value && s->pci_hole64_fix) { value = pc_pci_hole64_start(); } -visit_type_uint64(v, name, , errp); +return value; +} + +static void q35_host_get_pci_hole64_start(Object *obj, Visitor *v, + const char *name, void *opaque, + Error **errp) +{ +uint64_t hole64_start = q35_host_get_pci_hole64_start_value(obj); + +visit_type_uint64(v, name, _start, errp); } /* -- MST
[Qemu-devel] [PULL v2 06/28] vhost-user-blk: start vhost when guest kicks
From: Yongji Xie Some old guests (before commit 7a11370e5: "virtio_blk: enable VQs early") kick virtqueue before setting VIRTIO_CONFIG_S_DRIVER_OK. This violates the virtio spec. But virtio 1.0 transitional devices support this behaviour. So we should start vhost when guest kicks in this case. Signed-off-by: Yongji Xie Signed-off-by: Chai Wen Signed-off-by: Ni Xun Reviewed-by: Stefan Hajnoczi Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/block/vhost-user-blk.c | 25 + 1 file changed, 25 insertions(+) diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index d755223643..1451940845 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -217,7 +217,32 @@ static uint64_t vhost_user_blk_get_features(VirtIODevice *vdev, static void vhost_user_blk_handle_output(VirtIODevice *vdev, VirtQueue *vq) { +VHostUserBlk *s = VHOST_USER_BLK(vdev); +int i; +if (!(virtio_host_has_feature(vdev, VIRTIO_F_VERSION_1) && +!virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1))) { +return; +} + +if (s->dev.started) { +return; +} + +/* Some guests kick before setting VIRTIO_CONFIG_S_DRIVER_OK so start + * vhost here instead of waiting for .set_status(). + */ +vhost_user_blk_start(vdev); + +/* Kick right away to begin processing requests already in vring */ +for (i = 0; i < s->dev.nvqs; i++) { +VirtQueue *kick_vq = virtio_get_queue(vdev, i); + +if (!virtio_queue_get_desc_addr(vdev, i)) { +continue; +} +event_notifier_set(virtio_queue_get_host_notifier(kick_vq)); +} } static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp) -- MST
[Qemu-devel] [PULL v2 02/28] intel_iommu: introduce vtd_reset_caches()
From: Peter Xu Provide the function and use it in vtd_init(). Used to reset both context entry cache and iotlb cache for the whole IOMMU unit. Signed-off-by: Peter Xu Reviewed-by: Eric Auger Reviewed-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 13 + 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 3dfada19a6..1137861a9d 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -227,6 +227,14 @@ static void vtd_reset_iotlb(IntelIOMMUState *s) vtd_iommu_unlock(s); } +static void vtd_reset_caches(IntelIOMMUState *s) +{ +vtd_iommu_lock(s); +vtd_reset_iotlb_locked(s); +vtd_reset_context_cache_locked(s); +vtd_iommu_unlock(s); +} + static uint64_t vtd_get_iotlb_key(uint64_t gfn, uint16_t source_id, uint32_t level) { @@ -3160,10 +3168,7 @@ static void vtd_init(IntelIOMMUState *s) s->cap |= VTD_CAP_CM; } -vtd_iommu_lock(s); -vtd_reset_context_cache_locked(s); -vtd_reset_iotlb_locked(s); -vtd_iommu_unlock(s); +vtd_reset_caches(s); /* Define registers with default values and bit semantics */ vtd_define_long(s, DMAR_VER_REG, 0x10UL, 0, 0); -- MST
[Qemu-devel] [PULL v2 10/28] x86_iommu/amd: make the address space naming consistent with intel-iommu
From: "Singh, Brijesh" To be consistent with intel-iommu: - rename the address space to use '_' instead of '-' - update the memory region relationships Signed-off-by: Brijesh Singh Reviewed-by: Peter Xu Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/amd_iommu.c | 34 +++--- 1 file changed, 27 insertions(+), 7 deletions(-) diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 7206bb09c2..4bec1c6688 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -55,6 +55,7 @@ struct AMDVIAddressSpace { uint8_t bus_num;/* bus number */ uint8_t devfn; /* device function */ AMDVIState *iommu_state;/* AMDVI - one per machine */ +MemoryRegion root; /* AMDVI Root memory map region */ IOMMUMemoryRegion iommu;/* Device's address translation region */ MemoryRegion iommu_ir; /* Device's interrupt remapping region */ AddressSpace as;/* device's corresponding address space */ @@ -1032,8 +1033,9 @@ static IOMMUTLBEntry amdvi_translate(IOMMUMemoryRegion *iommu, hwaddr addr, static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) { +char name[128]; AMDVIState *s = opaque; -AMDVIAddressSpace **iommu_as; +AMDVIAddressSpace **iommu_as, *amdvi_dev_as; int bus_num = pci_bus_num(bus); iommu_as = s->address_spaces[bus_num]; @@ -1046,19 +1048,37 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) /* set up AMD-Vi region */ if (!iommu_as[devfn]) { +snprintf(name, sizeof(name), "amd_iommu_devfn_%d", devfn); + iommu_as[devfn] = g_malloc0(sizeof(AMDVIAddressSpace)); iommu_as[devfn]->bus_num = (uint8_t)bus_num; iommu_as[devfn]->devfn = (uint8_t)devfn; iommu_as[devfn]->iommu_state = s; -memory_region_init_iommu(_as[devfn]->iommu, - sizeof(iommu_as[devfn]->iommu), +amdvi_dev_as = iommu_as[devfn]; + +/* + * Memory region relationships looks like (Address range shows + * only lower 32 bits to make it short in length...): + * + * |-+---+--| + * | Name| Address range | Priority | + * |-+---+--+ + * | amdvi_root | - |0 | + * | amdvi_iommu| - |1 | + * |-+---+--| + */ +memory_region_init_iommu(_dev_as->iommu, + sizeof(amdvi_dev_as->iommu), TYPE_AMD_IOMMU_MEMORY_REGION, OBJECT(s), - "amd-iommu", UINT64_MAX); -address_space_init(_as[devfn]->as, - MEMORY_REGION(_as[devfn]->iommu), - "amd-iommu"); + "amd_iommu", UINT64_MAX); +memory_region_init(_dev_as->root, OBJECT(s), + "amdvi_root", UINT64_MAX); +address_space_init(_dev_as->as, _dev_as->root, name); +memory_region_add_subregion_overlap(_dev_as->root, 0, + MEMORY_REGION(_dev_as->iommu), +1); } return _as[devfn]->as; } -- MST
[Qemu-devel] [PULL v2 04/28] intel_iommu: move ce fetching out when sync shadow
From: Peter Xu There are two callers for vtd_sync_shadow_page_table_range(): one provided a valid context entry and one not. Move that fetching operation into the caller vtd_sync_shadow_page_table() where we need to fetch the context entry. Meanwhile, remove the error_report_once() directly since we're already tracing all the error cases in the previous call. Instead, return error number back to caller. This will not change anything functional since callers are dropping it after all. We do this move majorly because we want to do something more later in vtd_sync_shadow_page_table(). Signed-off-by: Peter Xu Reviewed-by: Eric Auger Reviewed-by: Maxime Coquelin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 41 + 1 file changed, 13 insertions(+), 28 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 306708eb3b..25e54671f4 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -1045,7 +1045,6 @@ static int vtd_sync_shadow_page_hook(IOMMUTLBEntry *entry, return 0; } -/* If context entry is NULL, we'll try to fetch it on our own. */ static int vtd_sync_shadow_page_table_range(VTDAddressSpace *vtd_as, VTDContextEntry *ce, hwaddr addr, hwaddr size) @@ -1057,39 +1056,25 @@ static int vtd_sync_shadow_page_table_range(VTDAddressSpace *vtd_as, .notify_unmap = true, .aw = s->aw_bits, .as = vtd_as, +.domain_id = VTD_CONTEXT_ENTRY_DID(ce->hi), }; -VTDContextEntry ce_cache; -int ret; -if (ce) { -/* If the caller provided context entry, use it */ -ce_cache = *ce; -} else { -/* If the caller didn't provide ce, try to fetch */ -ret = vtd_dev_to_context_entry(s, pci_bus_num(vtd_as->bus), - vtd_as->devfn, _cache); -if (ret) { -/* - * This should not really happen, but in case it happens, - * we just skip the sync for this time. After all we even - * don't have the root table pointer! - */ -error_report_once("%s: invalid context entry for bus 0x%x" - " devfn 0x%x", - __func__, pci_bus_num(vtd_as->bus), - vtd_as->devfn); -return 0; -} -} - -info.domain_id = VTD_CONTEXT_ENTRY_DID(ce_cache.hi); - -return vtd_page_walk(_cache, addr, addr + size, ); +return vtd_page_walk(ce, addr, addr + size, ); } static int vtd_sync_shadow_page_table(VTDAddressSpace *vtd_as) { -return vtd_sync_shadow_page_table_range(vtd_as, NULL, 0, UINT64_MAX); +int ret; +VTDContextEntry ce; + +ret = vtd_dev_to_context_entry(vtd_as->iommu_state, + pci_bus_num(vtd_as->bus), + vtd_as->devfn, ); +if (ret) { +return ret; +} + +return vtd_sync_shadow_page_table_range(vtd_as, , 0, UINT64_MAX); } /* -- MST
[Qemu-devel] [PULL v2 17/28] pci-testdev: add optional memory bar
From: Gerd Hoffmann Add memory bar to pci-testdev. Size is configurable using the membar property. Setting the size to zero (default) turns it off. Can be used to check whether guests handle large pci bars correctly. Reviewed-by: Marc-André Lureau Reviewed-by: Laszlo Ersek Tested-by: Laszlo Ersek Signed-off-by: Gerd Hoffmann Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- docs/specs/pci-testdev.txt | 15 ++- hw/misc/pci-testdev.c | 19 +++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/docs/specs/pci-testdev.txt b/docs/specs/pci-testdev.txt index 128ae222ef..4280a1e73c 100644 --- a/docs/specs/pci-testdev.txt +++ b/docs/specs/pci-testdev.txt @@ -1,11 +1,11 @@ pci-test is a device used for testing low level IO -device implements up to two BARs: BAR0 and BAR1. -Each BAR can be memory or IO. Guests must detect -BAR type and act accordingly. +device implements up to three BARs: BAR0, BAR1 and BAR2. +Each of BAR 0+1 can be memory or IO. Guests must detect +BAR types and act accordingly. -Each BAR size is up to 4K bytes. -Each BAR starts with the following header: +BAR 0+1 size is up to 4K bytes each. +BAR 0+1 starts with the following header: typedef struct PCITestDevHdr { uint8_t test; <- write-only, starts a given test number @@ -24,3 +24,8 @@ All registers are little endian. device is expected to always implement tests 0 to N on each BAR, and to add new tests with higher numbers. In this way a guest can scan test numbers until it detects an access type that it does not support on this BAR, then stop. + +BAR2 is a 64bit memory bar, without backing storage. It is disabled +by default and can be enabled using the membar= property. This +can be used to test whether guests handle pci bars of a specific +(possibly quite large) size correctly. diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c index 32041f535f..a811b2ce20 100644 --- a/hw/misc/pci-testdev.c +++ b/hw/misc/pci-testdev.c @@ -85,6 +85,9 @@ typedef struct PCITestDevState { MemoryRegion portio; IOTest *tests; int current; + +size_t membar_size; +MemoryRegion membar; } PCITestDevState; #define TYPE_PCI_TEST_DEV "pci-testdev" @@ -253,6 +256,16 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp) pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, >mmio); pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, >portio); +if (d->membar_size) { +memory_region_init(>membar, OBJECT(d), "pci-testdev-membar", + d->membar_size); +pci_register_bar(pci_dev, 2, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_PREFETCH | + PCI_BASE_ADDRESS_MEM_TYPE_64, + >membar); +} + d->current = -1; d->tests = g_malloc0(IOTEST_MAX * sizeof *d->tests); for (i = 0; i < IOTEST_MAX; ++i) { @@ -305,6 +318,11 @@ static void qdev_pci_testdev_reset(DeviceState *dev) pci_testdev_reset(d); } +static Property pci_testdev_properties[] = { +DEFINE_PROP_SIZE("membar", PCITestDevState, membar_size, 0), +DEFINE_PROP_END_OF_LIST(), +}; + static void pci_testdev_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -319,6 +337,7 @@ static void pci_testdev_class_init(ObjectClass *klass, void *data) dc->desc = "PCI Test Device"; set_bit(DEVICE_CATEGORY_MISC, dc->categories); dc->reset = qdev_pci_testdev_reset; +dc->props = pci_testdev_properties; } static const TypeInfo pci_testdev_info = { -- MST
[Qemu-devel] [PATCH v3 2/3] hw/arm/nrf51_soc: Connect UART to nRF51 SoC
Wire up nRF51 UART in the corresponding SoC. Signed-off-by: Julia Suvorova --- hw/arm/microbit.c | 2 ++ hw/arm/nrf51_soc.c | 20 include/hw/arm/nrf51_soc.h | 3 +++ 3 files changed, 25 insertions(+) diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c index e7d74116a5..a734e7f650 100644 --- a/hw/arm/microbit.c +++ b/hw/arm/microbit.c @@ -12,6 +12,7 @@ #include "qapi/error.h" #include "hw/boards.h" #include "hw/arm/arm.h" +#include "sysemu/sysemu.h" #include "exec/address-spaces.h" #include "hw/arm/nrf51_soc.h" @@ -35,6 +36,7 @@ static void microbit_init(MachineState *machine) sysbus_init_child_obj(OBJECT(machine), "nrf51", soc, sizeof(s->nrf51), TYPE_NRF51_SOC); +qdev_prop_set_chr(DEVICE(>nrf51), "serial0", serial_hd(0)); object_property_set_link(soc, OBJECT(system_memory), "memory", _fatal); object_property_set_bool(soc, true, "realized", _fatal); diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c index 1a59ef4552..b89c1bdea0 100644 --- a/hw/arm/nrf51_soc.c +++ b/hw/arm/nrf51_soc.c @@ -43,9 +43,12 @@ #define NRF51822_FLASH_SIZE (256 * 1024) #define NRF51822_SRAM_SIZE (16 * 1024) +#define BASE_TO_IRQ(base) ((base >> 12) & 0x1F) + static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp) { NRF51State *s = NRF51_SOC(dev_soc); +MemoryRegion *mr; Error *err = NULL; if (!s->board_memory) { @@ -82,6 +85,18 @@ static void nrf51_soc_realize(DeviceState *dev_soc, Error **errp) } memory_region_add_subregion(>container, SRAM_BASE, >sram); +/* UART */ +object_property_set_bool(OBJECT(>uart), true, "realized", ); +if (err) { +error_propagate(errp, err); +return; +} +mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(>uart), 0); +memory_region_add_subregion_overlap(>container, UART_BASE, mr, 0); +sysbus_connect_irq(SYS_BUS_DEVICE(>uart), 0, + qdev_get_gpio_in(DEVICE(>cpu), + BASE_TO_IRQ(UART_BASE))); + create_unimplemented_device("nrf51_soc.io", IOMEM_BASE, IOMEM_SIZE); create_unimplemented_device("nrf51_soc.ficr", FICR_BASE, FICR_SIZE); create_unimplemented_device("nrf51_soc.private", @@ -99,6 +114,11 @@ static void nrf51_soc_init(Object *obj) qdev_prop_set_string(DEVICE(>cpu), "cpu-type", ARM_CPU_TYPE_NAME("cortex-m0")); qdev_prop_set_uint32(DEVICE(>cpu), "num-irq", 32); + +sysbus_init_child_obj(obj, "uart", >uart, sizeof(s->uart), + TYPE_NRF51_UART); +object_property_add_alias(obj, "serial0", OBJECT(>uart), "chardev", + _abort); } static Property nrf51_soc_properties[] = { diff --git a/include/hw/arm/nrf51_soc.h b/include/hw/arm/nrf51_soc.h index f4e092b554..73fc92e9a8 100644 --- a/include/hw/arm/nrf51_soc.h +++ b/include/hw/arm/nrf51_soc.h @@ -12,6 +12,7 @@ #include "hw/sysbus.h" #include "hw/arm/armv7m.h" +#include "hw/char/nrf51_uart.h" #define TYPE_NRF51_SOC "nrf51-soc" #define NRF51_SOC(obj) \ @@ -24,6 +25,8 @@ typedef struct NRF51State { /*< public >*/ ARMv7MState cpu; +NRF51UARTState uart; + MemoryRegion iomem; MemoryRegion sram; MemoryRegion flash; -- 2.17.1
[Qemu-devel] [PULL v2 05/28] intel_iommu: handle invalid ce for shadow sync
From: Peter Xu We should handle VTD_FR_CONTEXT_ENTRY_P properly when synchronizing shadow page tables. Having invalid context entry there is perfectly valid when we move a device out of an existing domain. When that happens, instead of posting an error we invalidate the whole region. Without this patch, QEMU will crash if we do these steps: (1) start QEMU with VT-d IOMMU and two 10G NICs (ixgbe) (2) bind the NICs with vfio-pci in the guest (3) start testpmd with the NICs applied (4) stop testpmd (5) rebind the NIC back to ixgbe kernel driver The patch should fix it. Reported-by: Pei Zhang Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1627272 Signed-off-by: Peter Xu Reviewed-by: Eric Auger Reviewed-by: Maxime Coquelin Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 17 + 1 file changed, 17 insertions(+) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 25e54671f4..f24ebfca1c 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -38,6 +38,7 @@ #include "trace.h" static void vtd_address_space_refresh_all(IntelIOMMUState *s); +static void vtd_address_space_unmap(VTDAddressSpace *as, IOMMUNotifier *n); static void vtd_define_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val, uint64_t wmask, uint64_t w1cmask) @@ -1066,11 +1067,27 @@ static int vtd_sync_shadow_page_table(VTDAddressSpace *vtd_as) { int ret; VTDContextEntry ce; +IOMMUNotifier *n; ret = vtd_dev_to_context_entry(vtd_as->iommu_state, pci_bus_num(vtd_as->bus), vtd_as->devfn, ); if (ret) { +if (ret == -VTD_FR_CONTEXT_ENTRY_P) { +/* + * It's a valid scenario to have a context entry that is + * not present. For example, when a device is removed + * from an existing domain then the context entry will be + * zeroed by the guest before it was put into another + * domain. When this happens, instead of synchronizing + * the shadow pages we should invalidate all existing + * mappings and notify the backends. + */ +IOMMU_NOTIFIER_FOREACH(n, _as->iommu) { +vtd_address_space_unmap(vtd_as, n); +} +ret = 0; +} return ret; } -- MST
[Qemu-devel] [PULL v2 13/28] i386: acpi: add IVHD device entry for IOAPIC
From: "Singh, Brijesh" When interrupt remapping is enabled, add a special IVHD device (type IOAPIC). Signed-off-by: Brijesh Singh Acked-by: Peter Xu Cc: Peter Xu Cc: "Michael S. Tsirkin" Cc: Paolo Bonzini Cc: Richard Henderson Cc: Eduardo Habkost Cc: Marcel Apfelbaum Cc: Tom Lendacky Cc: Suravee Suthikulpanit Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/acpi-build.c | 28 +++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 1599caa7c5..1ef396ddbb 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2467,9 +2467,12 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker) * IVRS table as specified in AMD IOMMU Specification v2.62, Section 5.2 * accessible here http://support.amd.com/TechDocs/48882_IOMMU.pdf */ +#define IOAPIC_SB_DEVID (uint64_t)PCI_BUILD_BDF(0, PCI_DEVFN(0x14, 0)) + static void build_amd_iommu(GArray *table_data, BIOSLinker *linker) { +int ivhd_table_len = 28; int iommu_start = table_data->len; AMDVIState *s = AMD_IOMMU_DEVICE(x86_iommu_get_default()); @@ -2491,8 +2494,16 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker) (1UL << 6) | /* PrefSup */ (1UL << 7), /* PPRSup */ 1); + +/* + * When interrupt remapping is supported, we add a special IVHD device + * for type IO-APIC. + */ +if (x86_iommu_get_default()->intr_supported) { +ivhd_table_len += 8; +} /* IVHD length */ -build_append_int_noprefix(table_data, 28, 2); +build_append_int_noprefix(table_data, ivhd_table_len, 2); /* DeviceID */ build_append_int_noprefix(table_data, s->devid, 2); /* Capability offset */ @@ -2516,6 +2527,21 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker) */ build_append_int_noprefix(table_data, 0x001, 4); +/* + * Add a special IVHD device type. + * Refer to spec - Table 95: IVHD device entry type codes + * + * Linux IOMMU driver checks for the special IVHD device (type IO-APIC). + * See Linux kernel commit 'c2ff5cf5294bcbd7fa50f7d860e90a66db7e5059' + */ +if (x86_iommu_get_default()->intr_supported) { +build_append_int_noprefix(table_data, + (0x1ull << 56) | /* type IOAPIC */ + (IOAPIC_SB_DEVID << 40) | /* IOAPIC devid */ + 0x48, /* special device */ + 8); +} + build_header(linker, table_data, (void *)(table_data->data + iommu_start), "IVRS", table_data->len - iommu_start, 1, NULL, NULL); } -- MST
[Qemu-devel] [PULL v2 03/28] intel_iommu: better handling of dmar state switch
From: Peter Xu QEMU is not handling the global DMAR switch well, especially when from "on" to "off". Let's first take the example of system reset. Assuming that a guest has IOMMU enabled. When it reboots, we will drop all the existing DMAR mappings to handle the system reset, however we'll still keep the existing memory layouts which has the IOMMU memory region enabled. So after the reboot and before the kernel reloads again, there will be no mapping at all for the host device. That's problematic since any software (for example, SeaBIOS) that runs earlier than the kernel after the reboot will assume the IOMMU is disabled, so any DMA from the software will fail. For example, a guest that boots on an assigned NVMe device might fail to find the boot device after a system reboot/reset and we'll be able to observe SeaBIOS errors if we capture the debugging log: WARNING - Timeout at nvme_wait:144! Meanwhile, we should see DMAR errors on the host of that NVMe device. It's the DMA fault that caused a NVMe driver timeout. The correct fix should be that we do proper switching of device DMA address spaces when system resets, which will setup correct memory regions and notify the backend of the devices. This might not affect much on non-assigned devices since QEMU VT-d emulation will assume a default passthrough mapping if DMAR is not enabled in the GCMD register (please refer to vtd_iommu_translate). However that's required for an assigned devices, since that'll rebuild the correct GPA to HPA mapping that is needed for any DMA operation during guest bootstrap. Besides the system reset, we have some other places that might change the global DMAR status and we'd better do the same thing there. For example, when we change the state of GCMD register, or the DMAR root pointer. Do the same refresh for all these places. For these two places we'll also need to explicitly invalidate the context entry cache and iotlb cache. Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1625173 CC: QEMU Stable Reported-by: Cong Li Signed-off-by: Peter Xu -- v2: - do the same for GCMD write, or root pointer update [Alex] - test is carried out by me this time, by observing the vtd_switch_address_space tracepoint after system reboot v3: - rewrite commit message as suggested by Alex Signed-off-by: Peter Xu Reviewed-by: Eric Auger Reviewed-by: Jason Wang Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/i386/intel_iommu.c | 21 ++--- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 1137861a9d..306708eb3b 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -37,6 +37,8 @@ #include "kvm_i386.h" #include "trace.h" +static void vtd_address_space_refresh_all(IntelIOMMUState *s); + static void vtd_define_quad(IntelIOMMUState *s, hwaddr addr, uint64_t val, uint64_t wmask, uint64_t w1cmask) { @@ -1436,7 +1438,7 @@ static void vtd_context_global_invalidate(IntelIOMMUState *s) vtd_reset_context_cache_locked(s); } vtd_iommu_unlock(s); -vtd_switch_address_space_all(s); +vtd_address_space_refresh_all(s); /* * From VT-d spec 6.5.2.1, a global context entry invalidation * should be followed by a IOTLB global invalidation, so we should @@ -1727,6 +1729,8 @@ static void vtd_handle_gcmd_srtp(IntelIOMMUState *s) vtd_root_table_setup(s); /* Ok - report back to driver */ vtd_set_clear_mask_long(s, DMAR_GSTS_REG, 0, VTD_GSTS_RTPS); +vtd_reset_caches(s); +vtd_address_space_refresh_all(s); } /* Set Interrupt Remap Table Pointer */ @@ -1759,7 +1763,8 @@ static void vtd_handle_gcmd_te(IntelIOMMUState *s, bool en) vtd_set_clear_mask_long(s, DMAR_GSTS_REG, VTD_GSTS_TES, 0); } -vtd_switch_address_space_all(s); +vtd_reset_caches(s); +vtd_address_space_refresh_all(s); } /* Handle Interrupt Remap Enable/Disable */ @@ -3059,6 +3064,12 @@ static void vtd_address_space_unmap_all(IntelIOMMUState *s) } } +static void vtd_address_space_refresh_all(IntelIOMMUState *s) +{ +vtd_address_space_unmap_all(s); +vtd_switch_address_space_all(s); +} + static int vtd_replay_hook(IOMMUTLBEntry *entry, void *private) { memory_region_notify_one((IOMMUNotifier *)private, entry); @@ -3231,11 +3242,7 @@ static void vtd_reset(DeviceState *dev) IntelIOMMUState *s = INTEL_IOMMU_DEVICE(dev); vtd_init(s); - -/* - * When device reset, throw away all mappings and external caches - */ -vtd_address_space_unmap_all(s); +vtd_address_space_refresh_all(s); } static AddressSpace *vtd_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) -- MST
[Qemu-devel] [PATCH v3 1/3] hw/char: Implement nRF51 SoC UART
Not implemented: CTS/NCTS, PSEL*. Signed-off-by: Julia Suvorova --- hw/char/Makefile.objs| 1 + hw/char/nrf51_uart.c | 330 +++ hw/char/trace-events | 4 + include/hw/char/nrf51_uart.h | 78 + 4 files changed, 413 insertions(+) create mode 100644 hw/char/nrf51_uart.c create mode 100644 include/hw/char/nrf51_uart.h diff --git a/hw/char/Makefile.objs b/hw/char/Makefile.objs index b570531291..c4947d7ae7 100644 --- a/hw/char/Makefile.objs +++ b/hw/char/Makefile.objs @@ -1,5 +1,6 @@ common-obj-$(CONFIG_IPACK) += ipoctal232.o common-obj-$(CONFIG_ESCC) += escc.o +common-obj-$(CONFIG_NRF51_SOC) += nrf51_uart.o common-obj-$(CONFIG_PARALLEL) += parallel.o common-obj-$(CONFIG_PARALLEL) += parallel-isa.o common-obj-$(CONFIG_PL011) += pl011.o diff --git a/hw/char/nrf51_uart.c b/hw/char/nrf51_uart.c new file mode 100644 index 00..2f5fae6167 --- /dev/null +++ b/hw/char/nrf51_uart.c @@ -0,0 +1,330 @@ +/* + * nRF51 SoC UART emulation + * + * See nRF51 Series Reference Manual, "29 Universal Asynchronous + * Receiver/Transmitter" for hardware specifications: + * http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.pdf + * + * Copyright (c) 2018 Julia Suvorova + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 or + * (at your option) any later version. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "hw/char/nrf51_uart.h" +#include "trace.h" + +static void nrf51_uart_update_irq(NRF51UARTState *s) +{ +bool irq = false; + +irq |= (s->reg[R_UART_RXDRDY] && +(s->reg[R_UART_INTEN] & R_UART_INTEN_RXDRDY_MASK)); +irq |= (s->reg[R_UART_TXDRDY] && +(s->reg[R_UART_INTEN] & R_UART_INTEN_TXDRDY_MASK)); +irq |= (s->reg[R_UART_ERROR] && +(s->reg[R_UART_INTEN] & R_UART_INTEN_ERROR_MASK)); +irq |= (s->reg[R_UART_RXTO] && +(s->reg[R_UART_INTEN] & R_UART_INTEN_RXTO_MASK)); + +qemu_set_irq(s->irq, irq); +} + +static uint64_t uart_read(void *opaque, hwaddr addr, unsigned int size) +{ +NRF51UARTState *s = NRF51_UART(opaque); +uint64_t r; + +if (!s->enabled) { +return 0; +} + +switch (addr) { +case A_UART_RXD: +r = s->rx_fifo[s->rx_fifo_pos]; +if (s->rx_started && s->rx_fifo_len) { +s->rx_fifo_pos = (s->rx_fifo_pos + 1) % UART_FIFO_LENGTH; +s->rx_fifo_len--; +if (s->rx_fifo_len) { +s->reg[R_UART_RXDRDY] = 1; +nrf51_uart_update_irq(s); +} +qemu_chr_fe_accept_input(>chr); +} +break; +case A_UART_INTENSET: +case A_UART_INTENCLR: +case A_UART_INTEN: +r = s->reg[R_UART_INTEN]; +break; +default: +r = s->reg[addr / 4]; +break; +} + +trace_nrf51_uart_read(addr, r, size); + +return r; +} + +static gboolean uart_transmit(GIOChannel *chan, GIOCondition cond, void *opaque) +{ +NRF51UARTState *s = NRF51_UART(opaque); +int r; +uint8_t c = s->reg[R_UART_TXD]; + +s->watch_tag = 0; + +r = qemu_chr_fe_write(>chr, , 1); +if (r <= 0) { +s->watch_tag = qemu_chr_fe_add_watch(>chr, G_IO_OUT | G_IO_HUP, + uart_transmit, s); +if (!s->watch_tag) { +/* The hardware has no transmit error reporting, + * so silently drop the byte + */ +goto buffer_drained; +} +return FALSE; +} + +buffer_drained: +s->reg[R_UART_TXDRDY] = 1; +s->pending_tx_byte = false; +return FALSE; +} + +static void uart_cancel_transmit(NRF51UARTState *s) +{ +if (s->watch_tag) { +g_source_remove(s->watch_tag); +s->watch_tag = 0; +} +} + +static void uart_write(void *opaque, hwaddr addr, + uint64_t value, unsigned int size) +{ +NRF51UARTState *s = NRF51_UART(opaque); + +trace_nrf51_uart_write(addr, value, size); + +if (!s->enabled && (addr != A_UART_ENABLE)) { +return; +} + +switch (addr) { +case A_UART_TXD: +if (!s->pending_tx_byte && s->tx_started) { +s->reg[R_UART_TXD] = value; +s->pending_tx_byte = true; +uart_transmit(NULL, G_IO_OUT, s); +} +break; +case A_UART_INTEN: +s->reg[R_UART_INTEN] = value; +break; +case A_UART_INTENSET: +s->reg[R_UART_INTEN] |= value; +break; +case A_UART_INTENCLR: +s->reg[R_UART_INTEN] &= ~value; +break; +case A_UART_TXDRDY ... A_UART_RXTO: +s->reg[addr / 4] = value; +break; +case A_UART_ERRORSRC: +s->reg[addr / 4] &= ~value; +break; +case A_UART_RXD: +break; +case A_UART_RXDRDY: +if (value == 0) { +s->reg[R_UART_RXDRDY] = 0; +} +break; +case
[Qemu-devel] [PULL v2 00/28] pci, pc, virtio: fixes, features
The following changes since commit 13399aad4fa87b2878c49d02a5d3bafa6c966ba3: Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2018-10-22' into staging (2018-10-23 17:20:23 +0100) are available in the Git repository at: git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream for you to fetch changes up to 6a9fb4e1ba5594cde7739068617ad88e6117db93: vhost-scsi: prevent using uninitialized vqs (2018-10-24 20:50:13 -0400) pci, pc, virtio: fixes, features AMD IOMMU VAPIC support + fixes all over the place. Signed-off-by: Michael S. Tsirkin Gerd Hoffmann (1): pci-testdev: add optional memory bar Laszlo Ersek (4): MAINTAINERS: list "tests/acpi-test-data" files in ACPI/SMBIOS section hw/pci-host/x86: extract get_pci_hole64_start_value() helpers hw/pci-host/x86: extend the 64-bit PCI hole relative to the fw-assigned base tests/bios-tables-test: add 64-bit PCI MMIO aperture round-up test on Q35 Li Qiang (3): i440fx: use ARRAY_SIZE for pam_regions piix: use TYPE_FOO constants than string constats piix_pci: fix i440fx data sheet link Mao Zhongyi (1): pci_bridge: fix typo in comment Peter Xu (4): intel_iommu: introduce vtd_reset_caches() intel_iommu: better handling of dmar state switch intel_iommu: move ce fetching out when sync shadow intel_iommu: handle invalid ce for shadow sync Philippe Mathieu-Daudé (3): hw/pci-bridge/xio3130: Remove unused functions hw/pci-bridge/ioh3420: Remove unuseful header hw/pci: Add missing include Singh, Brijesh (9): x86_iommu: move the kernel-irqchip check in common code x86_iommu: move vtd_generate_msi_message in common file x86_iommu/amd: remove V=1 check from amdvi_validate_dte() x86_iommu/amd: make the address space naming consistent with intel-iommu x86_iommu/amd: Prepare for interrupt remap support x86_iommu/amd: Add interrupt remap support when VAPIC is not enabled i386: acpi: add IVHD device entry for IOAPIC x86_iommu/amd: Add interrupt remap support when VAPIC is enabled x86_iommu/amd: Enable Guest virtual APIC support Yaowei Bai (1): virtio-blk: fix comment for virtio_blk_rw_complete Yongji Xie (1): vhost-user-blk: start vhost when guest kicks yuchenlin (1): vhost-scsi: prevent using uninitialized vqs docs/specs/pci-testdev.txt | 15 +- hw/i386/amd_iommu.h | 96 +++- hw/pci-bridge/ioh3420.h | 6 - hw/pci-bridge/xio3130_downstream.h | 11 - hw/pci-bridge/xio3130_upstream.h | 10 - include/hw/i386/intel_iommu.h| 59 - include/hw/i386/x86-iommu.h | 66 ++ include/hw/pci/pci_bus.h | 2 + hw/block/vhost-user-blk.c| 25 +++ hw/block/virtio-blk.c| 4 +- hw/i386/acpi-build.c | 31 ++- hw/i386/amd_iommu.c | 414 ++- hw/i386/intel_iommu.c| 131 +-- hw/i386/x86-iommu.c | 33 +++ hw/misc/pci-testdev.c| 19 ++ hw/pci-bridge/ioh3420.c | 2 +- hw/pci-bridge/xio3130_downstream.c | 28 +-- hw/pci-bridge/xio3130_upstream.c | 24 +- hw/pci-host/piix.c | 34 ++- hw/pci-host/q35.c| 17 +- hw/pci/pci_bridge.c | 2 +- hw/scsi/vhost-scsi.c | 2 +- tests/bios-tables-test.c | 16 ++ MAINTAINERS | 2 + hw/i386/trace-events | 14 ++ tests/acpi-test-data/q35/DSDT.mmio64 | Bin 0 -> 8947 bytes tests/acpi-test-data/q35/SRAT.mmio64 | Bin 0 -> 224 bytes 27 files changed, 811 insertions(+), 252 deletions(-) delete mode 100644 hw/pci-bridge/ioh3420.h delete mode 100644 hw/pci-bridge/xio3130_downstream.h delete mode 100644 hw/pci-bridge/xio3130_upstream.h create mode 100644 tests/acpi-test-data/q35/DSDT.mmio64 create mode 100644 tests/acpi-test-data/q35/SRAT.mmio64
[Qemu-devel] [PATCH v3 3/3] tests/boot-serial-test: Add microbit board testcase
New mini-kernel test for nRF51 SoC UART. Signed-off-by: Julia Suvorova Acked-by: Thomas Huth Reviewed-by: Stefan Hajnoczi --- tests/boot-serial-test.c | 19 +++ 1 file changed, 19 insertions(+) diff --git a/tests/boot-serial-test.c b/tests/boot-serial-test.c index f865822e32..8ec6aed35d 100644 --- a/tests/boot-serial-test.c +++ b/tests/boot-serial-test.c @@ -62,6 +62,24 @@ static const uint8_t kernel_aarch64[] = { 0xfd, 0xff, 0xff, 0x17, /* b -12 (loop) */ }; +static const uint8_t kernel_nrf51[] = { +0x00, 0x00, 0x00, 0x00, /* Stack top address */ +0x09, 0x00, 0x00, 0x00, /* Reset handler address */ +0x04, 0x4a, /* ldr r2, [pc, #16] Get ENABLE */ +0x04, 0x21, /* movs r1, #4 */ +0x11, 0x60, /* str r1, [r2] */ +0x04, 0x4a, /* ldr r2, [pc, #16] Get STARTTX */ +0x01, 0x21, /* movs r1, #1 */ +0x11, 0x60, /* str r1, [r2] */ +0x03, 0x4a, /* ldr r2, [pc, #12] Get TXD */ +0x54, 0x21, /* movs r1, 'T' */ +0x11, 0x60, /* str r1, [r2] */ +0xfe, 0xe7, /* b. */ +0x00, 0x25, 0x00, 0x40, /* 0x40002500 = UART ENABLE */ +0x08, 0x20, 0x00, 0x40, /* 0x40002008 = UART STARTTX */ +0x1c, 0x25, 0x00, 0x40 /* 0x4000251c = UART TXD */ +}; + typedef struct testdef { const char *arch; /* Target architecture */ const char *machine;/* Name of the machine */ @@ -105,6 +123,7 @@ static testdef_t tests[] = { { "hppa", "hppa", "", "SeaBIOS wants SYSTEM HALT" }, { "aarch64", "virt", "-cpu cortex-a57", "TT", sizeof(kernel_aarch64), kernel_aarch64 }, +{ "arm", "microbit", "", "T", sizeof(kernel_nrf51), kernel_nrf51 }, { NULL } }; -- 2.17.1
[Qemu-devel] [PATCH v3 0/3] arm: Add nRF51 SoC UART support
This series adds support for the nRF51 SoC UART, that used in BBC Micro:bit board, and QTest for it. v3: * serial_hd() moved to the board code * sysbus_init_child_obj() used for initialization * qemu_chr_fe_accept_input() called after byte popping v2: * Suspend/Enable functionality added * Connection to SoC moved to a separate patch * Added QTest for checking reception functionality * Mini-kernel test changed to fit current implementation * Addressed review comments on R_*, uart_can_receive, VMState, uart_transmit Julia Suvorova (3): hw/char: Implement nRF51 SoC UART hw/arm/nrf51_soc: Connect UART to nRF51 SoC tests/boot-serial-test: Add microbit board testcase hw/arm/microbit.c| 2 + hw/arm/nrf51_soc.c | 20 +++ hw/char/Makefile.objs| 1 + hw/char/nrf51_uart.c | 330 +++ hw/char/trace-events | 4 + include/hw/arm/nrf51_soc.h | 3 + include/hw/char/nrf51_uart.h | 78 + tests/boot-serial-test.c | 19 ++ 8 files changed, 457 insertions(+) create mode 100644 hw/char/nrf51_uart.c create mode 100644 include/hw/char/nrf51_uart.h -- 2.17.1
Re: [Qemu-devel] [PATCH v2 2/3] qemu-iotests: remove unused variable here
Hi Mao, On 24/10/18 11:40, Mao Zhongyi wrote: run git grep '\$here' tests/qemu-iotests This command doesn't look correct, I believe you have to use either - git grep '$here' or - git grep \$here has 0 hits, which means we are setting a variable that no use, so execute the following cmd to remove all of the 'here=...' lines as dead code. This seems to have been removed in e8f8624d3b920de. sed -i '/here=/d' $(git grep -l 'here=' tests/qemu-iotests) Cc: kw...@redhat.com Cc: mre...@redhat.com Cc: ebl...@redhat.com Suggested-by: Eric Blake Please Cc Eric if he suggested, so he can review. Signed-off-by: Mao Zhongyi --- tests/qemu-iotests/001 | 1 - tests/qemu-iotests/002 | 1 - tests/qemu-iotests/003 | 1 - tests/qemu-iotests/004 | 1 - tests/qemu-iotests/005 | 1 - tests/qemu-iotests/007 | 1 - tests/qemu-iotests/008 | 1 - tests/qemu-iotests/009 | 1 - tests/qemu-iotests/010 | 1 - tests/qemu-iotests/011 | 1 - tests/qemu-iotests/012 | 1 - tests/qemu-iotests/013 | 1 - tests/qemu-iotests/014 | 1 - tests/qemu-iotests/015 | 1 - tests/qemu-iotests/017 | 1 - tests/qemu-iotests/018 | 1 - tests/qemu-iotests/019 | 1 - tests/qemu-iotests/020 | 1 - tests/qemu-iotests/021 | 1 - tests/qemu-iotests/022 | 1 - tests/qemu-iotests/023 | 1 - tests/qemu-iotests/024 | 1 - tests/qemu-iotests/025 | 1 - tests/qemu-iotests/026 | 1 - tests/qemu-iotests/027 | 1 - tests/qemu-iotests/028 | 1 - tests/qemu-iotests/029 | 1 - tests/qemu-iotests/031 | 1 - tests/qemu-iotests/032 | 1 - tests/qemu-iotests/033 | 1 - tests/qemu-iotests/034 | 1 - tests/qemu-iotests/035 | 1 - tests/qemu-iotests/036 | 1 - tests/qemu-iotests/037 | 1 - tests/qemu-iotests/038 | 1 - tests/qemu-iotests/039 | 1 - tests/qemu-iotests/042 | 1 - tests/qemu-iotests/043 | 1 - tests/qemu-iotests/046 | 1 - tests/qemu-iotests/047 | 1 - tests/qemu-iotests/049 | 1 - tests/qemu-iotests/050 | 1 - tests/qemu-iotests/051 | 1 - tests/qemu-iotests/052 | 1 - tests/qemu-iotests/053 | 1 - tests/qemu-iotests/054 | 1 - tests/qemu-iotests/058 | 1 - tests/qemu-iotests/059 | 1 - tests/qemu-iotests/060 | 1 - tests/qemu-iotests/061 | 1 - tests/qemu-iotests/062 | 1 - tests/qemu-iotests/063 | 1 - tests/qemu-iotests/064 | 1 - tests/qemu-iotests/066 | 1 - tests/qemu-iotests/067 | 1 - tests/qemu-iotests/068 | 1 - tests/qemu-iotests/069 | 1 - tests/qemu-iotests/070 | 1 - tests/qemu-iotests/071 | 1 - tests/qemu-iotests/072 | 1 - tests/qemu-iotests/073 | 1 - tests/qemu-iotests/075 | 1 - tests/qemu-iotests/076 | 1 - tests/qemu-iotests/077 | 1 - tests/qemu-iotests/078 | 1 - tests/qemu-iotests/079 | 1 - tests/qemu-iotests/080 | 1 - tests/qemu-iotests/081 | 1 - tests/qemu-iotests/082 | 1 - tests/qemu-iotests/083 | 1 - tests/qemu-iotests/084 | 1 - tests/qemu-iotests/085 | 1 - tests/qemu-iotests/086 | 1 - tests/qemu-iotests/087 | 1 - tests/qemu-iotests/088 | 1 - tests/qemu-iotests/089 | 1 - tests/qemu-iotests/090 | 1 - tests/qemu-iotests/091 | 1 - tests/qemu-iotests/092 | 1 - tests/qemu-iotests/094 | 1 - tests/qemu-iotests/095 | 1 - tests/qemu-iotests/097 | 1 - tests/qemu-iotests/098 | 1 - tests/qemu-iotests/099 | 1 - tests/qemu-iotests/101 | 1 - tests/qemu-iotests/102 | 1 - tests/qemu-iotests/103 | 1 - tests/qemu-iotests/104 | 1 - tests/qemu-iotests/105 | 1 - tests/qemu-iotests/106 | 1 - tests/qemu-iotests/107 | 1 - tests/qemu-iotests/108 | 1 - tests/qemu-iotests/109 | 1 - tests/qemu-iotests/110 | 1 - tests/qemu-iotests/111 | 1 - tests/qemu-iotests/112 | 1 - tests/qemu-iotests/113 | 1 - tests/qemu-iotests/114 | 1 - tests/qemu-iotests/115 | 1 - tests/qemu-iotests/116 | 1 - tests/qemu-iotests/117 | 1 - tests/qemu-iotests/119 | 1 - tests/qemu-iotests/120 | 1 - tests/qemu-iotests/121 | 1 - tests/qemu-iotests/122 | 1 - tests/qemu-iotests/123 | 1 - tests/qemu-iotests/125 | 1 - tests/qemu-iotests/126 | 1 - tests/qemu-iotests/127 | 1 - tests/qemu-iotests/128 | 1 - tests/qemu-iotests/130 | 1 - tests/qemu-iotests/131 | 1 - tests/qemu-iotests/133 | 1 - tests/qemu-iotests/134 | 1 - tests/qemu-iotests/135 | 1 - tests/qemu-iotests/137 | 1 - tests/qemu-iotests/138 | 1 - tests/qemu-iotests/140 | 1 - tests/qemu-iotests/141 | 1 - tests/qemu-iotests/142 | 1 - tests/qemu-iotests/143 | 1 - tests/qemu-iotests/144 | 1 - tests/qemu-iotests/145 | 1 - tests/qemu-iotests/146 | 1 - tests/qemu-iotests/150 | 1 - tests/qemu-iotests/153 | 1 - tests/qemu-iotests/154 | 1 - tests/qemu-iotests/156 | 1 - tests/qemu-iotests/157 | 1 - tests/qemu-iotests/158 | 1 - tests/qemu-iotests/159 | 1 - tests/qemu-iotests/160 | 1 - tests/qemu-iotests/162 | 1 - tests/qemu-iotests/170 | 1 - tests/qemu-iotests/171 | 1 - tests/qemu-iotests/172 | 1 - tests/qemu-iotests/173 | 1 - tests/qemu-iotests/174 | 1 - tests/qemu-iotests/175 | 1 - tests/qemu-iotests/176 | 1 -
Re: [Qemu-devel] [PATCH] configs/alpha: Remove unused CONFIG_PARALLEL_ISA switch
On 24/10/18 12:18, Thomas Huth wrote: We don't use CONFIG_PARALLEL_ISA in any of our Makefiles, so this is just a dead config option which can be removed. Fixes: a4cb773928e047b137c6998209cf2eec857fac6b Oops, this slipped while refactoring the series, this is part of a further cleanup that I never finished. Hopefully Kconfig will outdate it. Thanks for cleaning this! Signed-off-by: Thomas Huth Reviewed-by: Philippe Mathieu-Daudé --- default-configs/alpha-softmmu.mak | 1 - 1 file changed, 1 deletion(-) diff --git a/default-configs/alpha-softmmu.mak b/default-configs/alpha-softmmu.mak index bbe361f..61435cc 100644 --- a/default-configs/alpha-softmmu.mak +++ b/default-configs/alpha-softmmu.mak @@ -8,7 +8,6 @@ CONFIG_I82374=y CONFIG_I8254=y CONFIG_I8257=y CONFIG_PARALLEL=y -CONFIG_PARALLEL_ISA=y CONFIG_FDC=y CONFIG_PCKBD=y CONFIG_VGA_CIRRUS=y
Re: [Qemu-devel] [PATCH] fw_cfg: print error message when reading splashfile failed
On 24/10/18 7:12, Li Qiang wrote: Also remove unnecessary 'res' variable. Signed-off-by: Li Qiang --- hw/nvram/fw_cfg.c | 7 +++ 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index 946f765..f4a52d8 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -68,15 +68,14 @@ static char *read_splashfile(char *filename, gsize *file_sizep, int *file_typep) { GError *err = NULL; -gboolean res; gchar *content; int file_type; unsigned int filehead; int bmp_bpp; -res = g_file_get_contents(filename, , file_sizep, ); -if (res == FALSE) { -error_report("failed to read splash file '%s'", filename); +if (!g_file_get_contents(filename, , file_sizep, )) { +error_report("failed to read splash file '%s', %s", Can you use a column like the rest of the codebase? i.e.: "failed to read splash file '%s': %s" The maintainer taking this patch can do this minor change, so: Reviewed-by: Philippe Mathieu-Daudé + filename, err->message); g_error_free(err); return NULL; }
Re: [Qemu-devel] [PATCH] fw_cfg_reboot: ensure reboot_time is nonegative
Hi, On 24/10/18 13:35, Laszlo Ersek wrote: On 10/24/18 09:11, Li Qiang wrote: This can avoid setting a negative value to etc/boot-fail-wait. Li Qiang, can you add a qtest for this? Signed-off-by: Li Qiang --- hw/nvram/fw_cfg.c | 15 ++- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index f4a52d8..276dcb1 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -199,12 +199,17 @@ static void fw_cfg_reboot(FWCfgState *s) reboot_timeout = strtol(p, , 10); } } -/* validate the input */ -if (reboot_timeout > 0x) { -error_report("reboot timeout is larger than 65535, force it to 65535."); -reboot_timeout = 0x; + +if (reboot_timeout >= 0) { +/* validate the input */ +if (reboot_timeout > 0x) { +error_report("reboot timeout is larger than 65535," + "force it to 65535."); +reboot_timeout = 0x; +} +fw_cfg_add_file(s, "etc/boot-fail-wait", +g_memdup(_timeout, 4), 4); } -fw_cfg_add_file(s, "etc/boot-fail-wait", g_memdup(_timeout, 4), 4); } static void fw_cfg_write(FWCfgState *s, uint8_t value) I don't feel strongly about fixing this issue. However, if we decide to fix it, we should start with the bare-bones strtol() call, visible at the top of the context. I'm not up-to-date on what's the best QEMU helper function for this, but I seem to remember it checks for trailing garbage, and perhaps even for range. Maybe we should Are you suggesting qemu_strtoul()? I agree this would be cleaner. even use a different (better) option parsing facility thatn qemu_opt_get(). Adding Eric and Markus. Also, I would suggest forcing negative values (that were explicitly specified) to some sensible positive default, such as 5 seconds or so. Thanks Laszlo
Re: [Qemu-devel] [PATCH] tpm: Zero-init structure to avoid uninitialized variables in valgrind log
On 24/10/18 21:14, Stefan Berger wrote: Zero-init the ptm_loc structure so that we don't have fields that are not initialised. Signed-off-by: Stefan Berger Reviewed-by: Philippe Mathieu-Daudé --- hw/tpm/tpm_emulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c index 10bc20dbec..968f06ae3b 100644 --- a/hw/tpm/tpm_emulator.c +++ b/hw/tpm/tpm_emulator.c @@ -158,7 +158,7 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu, static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number, Error **errp) { -ptm_loc loc; +ptm_loc loc = { 0 }; if (tpm_emu->cur_locty_number == locty_number) { return 0;
Re: [Qemu-devel] [PATCH v2] lsi: Reselection needed to remove pending commands from queue
On 24/10/2018 15:06, George Kennedy wrote: >> >> >> Why didn't lsi_do_command invoke lsi_queue_command? That would set >> s->current to NULL (on the SCSI level, that means the bus is freed; on >> the QEMU level, the idea is that lsi_transfer_data would then start a >> reselection). > > Through the extended period of time with no call to lsi_reselect(), the > check of "s->command_complete" in lsi_do_command() is always "1" and > therefore no call to lsi_queue_command() occurs. > > "s->command_complete" is set to "1" in lsi_transfer_data(). Ok, I think we're getting closer. If the data transfer is from the device (read), then you can disconnect until the read is complete. If the data transfer however is to the device (write), there will be immediately a call to scsi_transfer_data, in order to get the written data, and s->command_complete is set to 1. However, this is wrong: the DMA transfer doesn't per se prevent a disconnect and a later reselect, and this might be the bug. Basically we want to get rid of the "s->command_complete = 1" case completely. The patch to do this change in the SCSI bus handling would look something like this (untested): diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index d1e6534311..c32ef40e78 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -565,6 +565,21 @@ static void lsi_bad_selection(LSIState *s, uint32_t id) lsi_disconnect(s); } +/* Disconnect when DMA has finished but the command did not + * complete immediately. + */ +static void lsi_maybe_disconnect(LSIState *s) +{ +if (!s->current->dma_len && !s->command_complete) { +lsi_add_msg_byte(s, 2); /* SAVE DATA POINTER */ +lsi_add_msg_byte(s, 4); /* DISCONNECT */ +/* wait data */ +lsi_set_phase(s, PHASE_MI); +s->msg_action = 1; +lsi_queue_command(s); +} +} + /* Initiate a SCSI layer data transfer. */ static void lsi_do_dma(LSIState *s, int out) { @@ -612,6 +627,7 @@ static void lsi_do_dma(LSIState *s, int out) if (s->current->dma_len == 0) { s->current->dma_buf = NULL; scsi_req_continue(s->current->req); +lsi_maybe_disconnect(s); } else { s->current->dma_buf += count; lsi_resume_script(s); @@ -631,7 +647,6 @@ static void lsi_queue_command(LSIState *s) s->current = NULL; p->pending = 0; -p->out = (s->sstat1 & PHASE_MASK) == PHASE_DO; } /* Queue a byte for a MSG IN phase. */ @@ -746,7 +761,7 @@ static void lsi_command_complete(SCSIRequest *req, out = (s->sstat1 & PHASE_MASK) == PHASE_DO; trace_lsi_command_complete(status); s->status = status; -s->command_complete = 2; +s->command_complete = 1; if (s->waiting && s->dbc != 0) { /* Raise phase mismatch for short transfers. */ lsi_bad_phase(s, out, PHASE_ST); @@ -781,7 +796,6 @@ static void lsi_transfer_data(SCSIRequest *req, /* host adapter (re)connected */ trace_lsi_transfer_data(req->tag, len); s->current->dma_len = len; -s->command_complete = 1; if (s->waiting) { if (s->waiting == 1 || s->dbc == 0) { lsi_resume_script(s); @@ -819,28 +833,12 @@ static void lsi_do_command(LSIState *s) s->current); n = scsi_req_enqueue(s->current->req); +s->current->out = (n < 0); +lsi_set_phase(s, s->current->out ? PHASE_DO : PHASE_DI); if (n) { -if (n > 0) { -lsi_set_phase(s, PHASE_DI); -} else if (n < 0) { -lsi_set_phase(s, PHASE_DO); -} scsi_req_continue(s->current->req); } -if (!s->command_complete) { -if (n) { -/* Command did not complete immediately so disconnect. */ -lsi_add_msg_byte(s, 2); /* SAVE DATA POINTER */ -lsi_add_msg_byte(s, 4); /* DISCONNECT */ -/* wait data */ -lsi_set_phase(s, PHASE_MI); -s->msg_action = 1; -lsi_queue_command(s); -} else { -/* wait command complete */ -lsi_set_phase(s, PHASE_DI); -} -} +lsi_maybe_disconnect(s); } static void lsi_do_status(LSIState *s) Of course, this doesn't include the change to WAIT RESELECT handling. It only ensures (or attempts to ensure) that the bus is disconnected and later reselected on long-running I/O, no matter the data direction. Thanks, Paolo
Re: [Qemu-devel] [PATCH v2 00/29] target/riscv: Convert to decodetree
On Sat, 20 Oct 2018 00:14:22 PDT (-0700), kbast...@mail.uni-paderborn.de wrote: Hi, this patchset converts the RISC-V decoder to decodetree in three major steps: 1) Convert 32-bit instructions to decodetree [Patch 1-14]: Many of the gen_* functions are called by the decode functions for 16-bit and 32-bit functions. If we move translation code from the gen_* functions to the generated trans_* functions of decode-tree, we get a lot of duplication. Therefore, we mostly generate calls to the old gen_* function which are properly replaced after step 2). Each of the trans_ functions are grouped into files corresponding to their ISA extension, e.g. addi which is in RV32I is translated in the file 'trans_rvi.inc.c'. 2) Convert 16-bit instructions to decodetree [Patch 15-17]: All 16 bit instructions have a direct mapping to a 32 bit instruction. Thus, we convert the arguments in the 16 bit trans_ function to the arguments of the corresponding 32 bit instruction and call the 32 bit trans_ function. 3) Remove old manual decoding in gen_* function [Patch 17-28]: this move all manual translation code into the trans_* instructions of decode tree, such that we can remove the old decode_* functions. the full tree can be found here: https://github.com/bkoppelmann/qemu/tree/riscv-dt-v2 Thanks! I dropped this on top of master and it appears I'm getting a bunch of oops when trying to boot Linux. They're fairly far into the boot process and may be a mistake on my end, I was just wondering if you'd booted Linux? I'll go through the patches and review them. Cheers, Bastian v1->v2: - ex_shift_amount returns uint32_t - use ctx->env instead of current_cpu->env_ptr - fixed functionspacing - RISCV32 now returns false instead of raising an exception - shift translators now also use gen_arithm_imm() - simplified fence/fence_i as suggested by Richard - simplified gen_amo() with function pointers - rs2 @atom_ld is now decimal - use simplfied gen_amo() with function pointers - REQUIRE_FPU uses do {} while (0) - Add REQUIRE_FPU to arithm helpers - RISCV32 now returns false instead of raising an exception - Add REQUIRE_FPU to arithm helpers - Stack allocate arg_c_* structs - ex_rvc_register returns int - special case of trans_c_addi4spn() returns false - consistently return false for reserved cases instead of raising an exception - simplified trans_c_srli by Richard's suggestion - remove extract_cj() since its result isn't used - trans_branch -> gen_branch - trans_load -> gen_load - removed negative memop check - trans_store -> gen_store - removed negative memop check - trans_arith_imm -> gen_arith_imm - Add missing TARGET_RISC64 checks - Reimplement shift translators that were omited in [0004/0028] - trans_shift -> gen_shift - Add missing TARGET_RISCV64 conditions - trans_arith_w -> gen_arith_w - Add missing gen_exception_illegal - dropped 0028 Bastian Koppelmann (29): target/riscv: Move CPURISCVState pointer to DisasContext targer/riscv: Activate decodetree and implemnt LUI & AUIPC target/riscv: Convert RVXI branch insns to decodetree target/riscv: Convert RVXI load/store insns to decodetree target/riscv: Convert RVXI arithmetic insns to decodetree target/riscv: Convert RVXI fence insns to decodetree target/riscv: Convert RVXI csr insns to decodetree target/riscv: Convert RVXM insns to decodetree target/riscv: Convert RV32A insns to decodetree target/riscv: Convert RV64A insns to decodetree target/riscv: Convert RV32F insns to decodetree target/riscv: Convert RV64F insns to decodetree target/riscv: Convert RV32D insns to decodetree target/riscv: Convert RV64D insns to decodetree target/riscv: Convert RV priv insns to decodetree target/riscv: Convert quadrant 0 of RVXC insns to decodetree target/riscv: Convert quadrant 1 of RVXC insns to decodetree target/riscv: Convert quadrant 2 of RVXC insns to decodetree target/riscv: Remove gen_jalr() target/riscv: Remove manual decoding from gen_branch() target/riscv: Remove manual decoding from gen_load() target/riscv: Remove manual decoding from gen_store() target/riscv: Move gen_arith_imm() decoding into trans_* functions target/riscv: make ADD/SUB/OR/XOR/AND insn use arg lists target/riscv: Remove shift and slt insn manual decoding target/riscv: Remove manual decoding of RV32/64M insn target/riscv: Remove gen_system() target/riscv: Remove decode_RV32_64G() target/riscv: Rename trans_arith to gen_arith target/riscv/Makefile.objs| 17 + target/riscv/insn16.decode| 126 ++ target/riscv/insn32.decode| 256 +++
[Qemu-devel] FOSDEM'19 Virtualization & IaaS Devroom CfP
Dear KVM and QEMU community, FOSDEM'19 will feature a Virtualization & IaaS Devroom again. Here is the call for proposals. Please check it out if you would like to submit a talk. Thanks, Stefan --- We are excited to announce that the call for proposals is now open for the Virtualization & IaaS devroom at the upcoming FOSDEM 2019, to be hosted on February 2nd 2019. This year will mark FOSDEM’s 19th anniversary as one of the longest-running free and open source software developer events, attracting thousands of developers and users from all over the world. FOSDEM will be held once again in Brussels, Belgium, on February 2nd & 3rd, 2019. This devroom is a collaborative effort, and is organized by dedicated folks from projects such as OpenStack, Xen Project, oVirt, QEMU, KVM, and Foreman. We would like to invite all those who are involved in these fields to submit your proposals by December 1st, 2018. About the Devroom The Virtualization & IaaS devroom will feature session topics such as open source hypervisors and virtual machine managers such as Xen Project, KVM, bhyve, and VirtualBox, and Infrastructure-as-a-Service projects such as KubeVirt, Apache CloudStack, OpenStack, oVirt, QEMU and OpenNebula. This devroom will host presentations that focus on topics of shared interest, such as KVM; libvirt; shared storage; virtualized networking; cloud security; clustering and high availability; interfacing with multiple hypervisors; hyperconverged deployments; and scaling across hundreds or thousands of servers. Presentations in this devroom will be aimed at developers working on these platforms who are looking to collaborate and improve shared infrastructure or solve common problems. We seek topics that encourage dialog between projects and continued work post-FOSDEM. Important Dates Submission deadline: 1 December 2019 Acceptance notifications: 14 December 2019 Final schedule announcement: 21 December 2019 Devroom: 2nd February 2019 Submit Your Proposal All submissions must be made via the Pentabarf event planning site[1]. If you have not used Pentabarf before, you will need to create an account. If you submitted proposals for FOSDEM in previous years, you can use your existing account. After creating the account, select Create Event to start the submission process. Make sure to select Virtualization and IaaS devroom from the Track list. Please fill out all the required fields, and provide a meaningful abstract and description of your proposed session. Submission Guidelines We expect more proposals than we can possibly accept, so it is vitally important that you submit your proposal on or before the deadline. Late submissions are unlikely to be considered. All presentation slots are 30 minutes, with 20 minutes planned for presentations, and 10 minutes for Q All presentations will be recorded and made available under Creative Commons licenses. In the Submission notes field, please indicate that you agree that your presentation will be licensed under the CC-By-SA-4.0 or CC-By-4.0 license and that you agree to have your presentation recorded. For example: "If my presentation is accepted for FOSDEM, I hereby agree to license all recordings, slides, and other associated materials under the Creative Commons Attribution Share-Alike 4.0 International License. Sincerely, ." In the Submission notes field, please also confirm that if your talk is accepted, you will be able to attend FOSDEM and deliver your presentation. We will not consider proposals from prospective speakers who are unsure whether they will be able to secure funds for travel and lodging to attend FOSDEM. (Sadly, we are not able to offer travel funding for prospective speakers.) Speaker Mentoring Program As a part of the rising efforts to grow our communities and encourage a diverse and inclusive conference ecosystem, we're happy to announce that we'll be offering mentoring for new speakers. Our mentors can help you with tasks such as reviewing your abstract, reviewing your presentation outline or slides, or practicing your talk with you. You may apply to the mentoring program as a newcomer speaker if you: Never presented before or Presented only lightning talks or Presented full-length talks at small meetups (<50 ppl) Submission Guidelines Mentored presentations will have 25-minute slots, where 20 minutes will include the presentation and 5 minutes will be reserved for questions. The number of newcomer session slots is limited, so we will probably not be able to accept all applications. You must submit your talk and abstract to apply for the mentoring program, our mentors are volunteering their time and will happily provide feedback but won't write your presentation for you! If you are experiencing problems with Pentabarf, the proposal submission interface, or have other questions, you can email our devroom mailing list[2] and we will try to help you. How to Apply In addition to agreeing to video recording and confirming
Re: [Qemu-devel] [PULL 00/28] pci, pc, virtio: fixes, features
On Wed, Oct 24, 2018 at 10:06:41PM +0100, Peter Maydell wrote: > On 24 October 2018 at 21:54, Michael S. Tsirkin wrote: > > On Wed, Oct 24, 2018 at 07:21:17AM +0100, Peter Maydell wrote: > >> Hi. This pull request seems to include an accidental update > >> to the dtc submodule. It's in the "intel_iommu: move ce fetching out > >> when sync shadow" commit, and it's not mentioned in the commit > >> message, so I am assuming it is unintentional. > > > Oh not again. At least now you have scripts that catch it, > > I should write a script for that too. Thanks and sorry. > > The relevant part of my scripts is this bit: > https://git.linaro.org/people/peter.maydell/misc-scripts.git/tree/apply-pullreq?id=eeb001fcc1aabd8f077cd2846724120a3aa8f962#n107 > > Specifically, > > if git diff master..staging | grep -q 'Subproject commit'; then > # there's a submodule update in this set of commits > fi > > thanks > -- PMM Thanks added to my pull request script. -- MST
Re: [Qemu-devel] [PATCH RFC 0/2] Fix migration issues
On Mon, Oct 22, 2018 at 07:08:52PM +0800, Fei Li wrote: > Hi, > these two patches are to fix live migration issues. The first is > about multifd, and the second is to fix some error handling. > > But I have a question about using multifd migration. > In our current code, when multifd is used during migration, if there > is an error before the destination receives all new channels (I mean > multifd_recv_new_channel(ioc)), the destination does not exit but > keeps waiting (Hang in recvmsg() in qio_channel_socket_readv) until > the source exits. > > My question is about the state of the destination host if fails during > this period. I did a test, after applying [1/2] patch, if > multifd_new_send_channel_async() fails, the destination host hangs for > a while then later pops up a window saying > "'QEMU (...) [stopped]' is not responding. > You may choose to wait a short while for it to continue or force > the application to quit entirely." > But after closing the window by clicking, the qemu on the dest still > hangs there until I exclusively kill the qemu on the source. > > The source host keeps running as expected, but I guess the hang > phenonmenon in the dest is not right. > Would someone kindly give some suggestions on this? Thanks a lot. Note that it's during KVM forum so the response from anyone might be slow (it ends this week). I think the thing you described seems normal since we can't guarantee the network is always stable, normally I'll expect that the migration will fail but it won't matter much since after all it's a precopy so we lose nothing. So I'm curious about when the error you mentioned happens (e.g., total channel number is N, you only got M channels connected, with M < N) could you just simply kill the destination? Then AFAIU the source can just continue to run, right? > > > Fei Li (2): > migration: fix the multifd code > migration: fix some error handling > > migration/migration.c| 5 + > migration/postcopy-ram.c | 3 +++ > migration/ram.c | 33 +++-- > migration/ram.h | 2 +- > 4 files changed, 28 insertions(+), 15 deletions(-) > > -- > 2.13.7 > Regards, -- Peter Xu
Re: [Qemu-devel] [PULL 00/28] pci, pc, virtio: fixes, features
On 24 October 2018 at 21:54, Michael S. Tsirkin wrote: > On Wed, Oct 24, 2018 at 07:21:17AM +0100, Peter Maydell wrote: >> Hi. This pull request seems to include an accidental update >> to the dtc submodule. It's in the "intel_iommu: move ce fetching out >> when sync shadow" commit, and it's not mentioned in the commit >> message, so I am assuming it is unintentional. > Oh not again. At least now you have scripts that catch it, > I should write a script for that too. Thanks and sorry. The relevant part of my scripts is this bit: https://git.linaro.org/people/peter.maydell/misc-scripts.git/tree/apply-pullreq?id=eeb001fcc1aabd8f077cd2846724120a3aa8f962#n107 Specifically, if git diff master..staging | grep -q 'Subproject commit'; then # there's a submodule update in this set of commits fi thanks -- PMM
Re: [Qemu-devel] [PATCH v2] Fix linux-user crashes in ioctl(SIOCGIFCONF) when ifc_buf is NULL.
On 24/10/2018 21:13, Kan Li wrote: > Summary: > This is to fix bug https://bugs.launchpad.net/qemu/+bug/1796754. > It is valid for ifc_buf to be NULL according to > http://man7.org/linux/man-pages/man7/netdevice.7.html. > > Signed-off-by: Kan Li > --- > linux-user/syscall.c | 55 > > 1 file changed, 30 insertions(+), 25 deletions(-) > Reviewed-by: Laurent Vivier
Re: [Qemu-devel] [PULL 00/28] pci, pc, virtio: fixes, features
On Wed, Oct 24, 2018 at 12:28:52PM +0100, Peter Xu wrote: > On Wed, Oct 24, 2018 at 07:21:17AM +0100, Peter Maydell wrote: > > > dtc | 2 +- > > > > Hi. This pull request seems to include an accidental update > > to the dtc submodule. It's in the "intel_iommu: move ce fetching out > > when sync shadow" commit, and it's not mentioned in the commit > > message, so I am assuming it is unintentional. > > > > Could you fix that and resubmit, please? > > It's my fault. > > Michael, please let me know if you want me to post that single patch > again without that. > > Regards, > > -- > Peter Xu I'll try to fix it myself now. -- MST
Re: [Qemu-devel] [PULL 00/28] pci, pc, virtio: fixes, features
On Wed, Oct 24, 2018 at 07:21:17AM +0100, Peter Maydell wrote: > On 24 October 2018 at 00:41, Michael S. Tsirkin wrote: > > The following changes since commit 13399aad4fa87b2878c49d02a5d3bafa6c966ba3: > > > > Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2018-10-22' > > into staging (2018-10-23 17:20:23 +0100) > > > > are available in the Git repository at: > > > > git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_upstream > > > > for you to fetch changes up to 57b279df457c2c4ef66ce9e1b813df35abde69f7: > > > > vhost-scsi: prevent using uninitialized vqs (2018-10-23 19:29:58 -0400) > > > > > > pci, pc, virtio: fixes, features > > > > AMD IOMMU VAPIC support + fixes all over the place. > > > > Signed-off-by: Michael S. Tsirkin > > > > > > > dtc | 2 +- > > Hi. This pull request seems to include an accidental update > to the dtc submodule. It's in the "intel_iommu: move ce fetching out > when sync shadow" commit, and it's not mentioned in the commit > message, so I am assuming it is unintentional. > > Could you fix that and resubmit, please? > > thanks > -- PMM Oh not again. At least now you have scripts that catch it, I should write a script for that too. Thanks and sorry. -- MST
Re: [Qemu-devel] [PATCH 18/26] hw: acpi: Initial hardware-reduced support
On Wed, Oct 24, 2018 at 12:09:18AM +0200, Paolo Bonzini wrote: > On 22/10/2018 20:36, Samuel Ortiz wrote: > > We build a minimal set of ACPI hardware-reduced tables: XSDT, > > FADT, MADT and a DSDT pointed by a RSDP. > > The DSDT only contains one PCI host bridge for now. > > > > This API will be consumed by new x86 machine type but also potentially > > by the ARM virt one. > > > > Cc: "Michael S. Tsirkin" > > Cc: Igor Mammedov > > Signed-off-by: Samuel Ortiz > > Do not include patches that essentially add dead code. It is nice to > have hardware-reduced support, but if you want to contribute it you need > to add a user as well, for example the ARM virt machine type. > > In fact, using it in the ARM virt machine type is a no-brainer, so doing > that change (even if it's not yet part of NEMU) would be an excellent > way to reduce your delta, without going through the processing of > convincing QEMU maintainers of the advantages of your new x86 machine type. > > Paolo Excellent point, thanks Paolo. -- MST
Re: [Qemu-devel] [PATCH v2] linux-user/flatload: fix initial stack pointer alignment
On 24/10/2018 19:35, Max Filippov wrote: > Stack pointer alignment code incorrectly adds stack_size to sp instead > of subtracting it. It also does not take flat_argvp_envp_on_stack() into > account when calculating stack_size. This results in initial stack > pointer misalignment with certain set of command line arguments and > environment variables and correct alignment for the same binary with a > different set of arguments. This misalignment causes failures in the > following tests in the testsuite of gcc built for xtensa uclinux: > > gcc.dg/torture/vshuf-v64qi.c > gcc.dg/torture/vshuf-v8sf.c > gcc.dg/torture/vshuf-v8si.c > > Signed-off-by: Max Filippov > --- > Changes v1->v2: > - make sp adjustment unconditional > > linux-user/flatload.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/linux-user/flatload.c b/linux-user/flatload.c > index 2eefe55e5000..0122ab3afe65 100644 > --- a/linux-user/flatload.c > +++ b/linux-user/flatload.c > @@ -771,10 +771,10 @@ int load_flt_binary(struct linux_binprm *bprm, struct > image_info *info) > /* Enforce final stack alignment of 16 bytes. This is sufficient > for all current targets, and excess alignment is harmless. */ > stack_len = bprm->envc + bprm->argc + 2; > -stack_len += 3; /* argc, arvg, argp */ > +stack_len += flat_argvp_envp_on_stack() ? 2 : 0; /* arvg, argp */ > +stack_len += 1; /* argc */ > stack_len *= sizeof(abi_ulong); > -if ((sp + stack_len) & 15) > -sp -= 16 - ((sp + stack_len) & 15); > +sp -= (sp - stack_len) & 15; > sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, > flat_argvp_envp_on_stack()); > > Reviewed-by: Laurent Vivier
[Qemu-devel] [Bug 1799792] [NEW] Broken scaling with gtk, gl=on on a hidpi display
Public bug reported: Tested on QEMU 3.0.0 on Arch Linux. I'm using a hidpi screen, and therefore use those environment variables in order to have GTK+ apps properly scaled: GDK_SCALE=2 GDK_DPI_SCALE=0.5 However, QEMU, when launched with "-display gtk,gl=on" option, doesn't scale the window content properly, as seen on the attached screenshot. Switching to "-display gtk,gl=off" and "-display sdl,gl=on" makes it work fine. ** Affects: qemu Importance: Undecided Status: New ** Attachment added: "Screenshot_20181024_222447.png" https://bugs.launchpad.net/bugs/1799792/+attachment/5205039/+files/Screenshot_20181024_222447.png -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1799792 Title: Broken scaling with gtk,gl=on on a hidpi display Status in QEMU: New Bug description: Tested on QEMU 3.0.0 on Arch Linux. I'm using a hidpi screen, and therefore use those environment variables in order to have GTK+ apps properly scaled: GDK_SCALE=2 GDK_DPI_SCALE=0.5 However, QEMU, when launched with "-display gtk,gl=on" option, doesn't scale the window content properly, as seen on the attached screenshot. Switching to "-display gtk,gl=off" and "-display sdl,gl=on" makes it work fine. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1799792/+subscriptions
[Qemu-devel] [PATCH v2] Fix linux-user crashes in ioctl(SIOCGIFCONF) when ifc_buf is NULL.
Summary: This is to fix bug https://bugs.launchpad.net/qemu/+bug/1796754. It is valid for ifc_buf to be NULL according to http://man7.org/linux/man-pages/man7/netdevice.7.html. Signed-off-by: Kan Li --- linux-user/syscall.c | 55 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 15b03e17b9..2453778cfd 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4138,28 +4138,32 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, unlock_user(argptr, arg, 0); host_ifconf = (struct ifconf *)(unsigned long)buf_temp; -target_ifc_len = host_ifconf->ifc_len; target_ifc_buf = (abi_long)(unsigned long)host_ifconf->ifc_buf; - target_ifreq_size = thunk_type_size(ifreq_arg_type, 0); -nb_ifreq = target_ifc_len / target_ifreq_size; -host_ifc_len = nb_ifreq * sizeof(struct ifreq); -outbufsz = sizeof(*host_ifconf) + host_ifc_len; -if (outbufsz > MAX_STRUCT_SIZE) { -/* We can't fit all the extents into the fixed size buffer. - * Allocate one that is large enough and use it instead. - */ -host_ifconf = malloc(outbufsz); -if (!host_ifconf) { -return -TARGET_ENOMEM; +if (target_ifc_buf != 0) { +target_ifc_len = host_ifconf->ifc_len; +nb_ifreq = target_ifc_len / target_ifreq_size; +host_ifc_len = nb_ifreq * sizeof(struct ifreq); + +outbufsz = sizeof(*host_ifconf) + host_ifc_len; +if (outbufsz > MAX_STRUCT_SIZE) { +/* We can't fit all the extents into the fixed size buffer. + * Allocate one that is large enough and use it instead. + */ +host_ifconf = malloc(outbufsz); +if (!host_ifconf) { +return -TARGET_ENOMEM; +} +memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf)); +free_buf = 1; } -memcpy(host_ifconf, buf_temp, sizeof(*host_ifconf)); -free_buf = 1; +host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf); + +host_ifconf->ifc_len = host_ifc_len; +} else { + host_ifc_buf = NULL; } -host_ifc_buf = (char*)host_ifconf + sizeof(*host_ifconf); - -host_ifconf->ifc_len = host_ifc_len; host_ifconf->ifc_buf = host_ifc_buf; ret = get_errno(safe_ioctl(fd, ie->host_cmd, host_ifconf)); @@ -4182,15 +4186,16 @@ static abi_long do_ioctl_ifconf(const IOCTLEntry *ie, uint8_t *buf_temp, thunk_convert(argptr, host_ifconf, arg_type, THUNK_TARGET); unlock_user(argptr, arg, target_size); - /* copy ifreq[] to target user */ - -argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0); -for (i = 0; i < nb_ifreq ; i++) { -thunk_convert(argptr + i * target_ifreq_size, - host_ifc_buf + i * sizeof(struct ifreq), - ifreq_arg_type, THUNK_TARGET); +if (target_ifc_buf != 0) { +/* copy ifreq[] to target user */ +argptr = lock_user(VERIFY_WRITE, target_ifc_buf, target_ifc_len, 0); +for (i = 0; i < nb_ifreq ; i++) { +thunk_convert(argptr + i * target_ifreq_size, + host_ifc_buf + i * sizeof(struct ifreq), + ifreq_arg_type, THUNK_TARGET); +} +unlock_user(argptr, target_ifc_buf, target_ifc_len); } -unlock_user(argptr, target_ifc_buf, target_ifc_len); } if (free_buf) { -- 2.14.5
[Qemu-devel] [Bug 1799768] [NEW] -nodefaults has unclear documentation
Public bug reported: -nodefaults has an unclear documentation, I believe it should states it does not applies to devices created by a machine model. See https://stackoverflow.com/questions/52908614/qemu-s-nodefaults-not- working-as-expected-to-me to read how I came to this. ** Affects: qemu Importance: Undecided Status: New -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1799768 Title: -nodefaults has unclear documentation Status in QEMU: New Bug description: -nodefaults has an unclear documentation, I believe it should states it does not applies to devices created by a machine model. See https://stackoverflow.com/questions/52908614/qemu-s-nodefaults- not-working-as-expected-to-me to read how I came to this. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1799768/+subscriptions
[Qemu-devel] [Bug 1799766] [NEW] -device does not work as -drive do
Public bug reported: Copy/paste of https://stackoverflow.com/questions/52929723/qemu-eject- complains-device-is-not-found-while-it-is-there , since I found this bug trying to find an answer to an own question on Stack Overflow. Below, what was my question the answer I wrote, all exposes the bug. I need to eject a floppy from QEmu 3.0 monitor, but the command surprisingly fails complaining the device is not found, while it is really there. Listing of devices: (qemu) info block fda: dos-6-22/Dos622-1.img (raw) Attached to: /machine/unattached/device[11] Removable device: not locked, tray closed Cache mode: writeback hda: hda.img (raw) Attached to: /machine/peripheral-anon/device[1] Cache mode: writeback Eject command result: (qemu) eject fda Device 'fda' not found This is so although this documentation says this is how I have to do: https://www.linux-kvm.org/page/Change_cdrom (just that I want to eject the floppy instead of the CD‑ROM). The `change` command complains the same: (qemu) change fda dos-6-22/Dos622-2.img raw Device 'fda' not found Is this a bug or me doing something wrong? I tried using different node names, with always the same result. I’m posting as an answer, but I’m not strictly sure. I can just say, if I understand correctly, this is a bug. The answer comes in two parts. First part, is a stripped down failing invocation: qemu-system-i386 \ -monitor stdio \ -machine type=isapc,vmport=off \ -blockdev driver=file,node-name=fda-img,filename=fda.img \ -blockdev driver=raw,node-name=fda,file=fda-img \ -global isa-fdc.driveA=fda (qemu) info block ide1-cd0: [not inserted] Attached to: /machine/unattached/device[19] Removable device: not locked, tray closed sd0: [not inserted] Removable device: not locked, tray closed fda: fda.img (raw) Attached to: /machine/unattached/device[13] Removable device: not locked, tray closed Cache mode: writeback (qemu) eject fda Device 'fda' not found Second part, is the same without the last argument `-global isa- fdc.driveA=fda`: qemu-system-i386 \ -monitor stdio \ -machine type=isapc,vmport=off \ -blockdev driver=file,node-name=fda-img,filename=fda.img \ -blockdev driver=raw,node-name=fda,file=fda-img (qemu) info block ide1-cd0: [not inserted] Attached to: /machine/unattached/device[19] Removable device: not locked, tray closed floppy0: [not inserted] Attached to: /machine/unattached/device[13] Removable device: not locked, tray closed sd0: [not inserted] Removable device: not locked, tray closed (qemu) eject floppy0 There is more error when `-global isa-fdc.driveA=fda` is removed. However, the documentation says: > -global driver=driver,property=property,value=value > Set default value of driver’s property prop to value, e.g.: > qemu-system-i386 -global ide-hd.physical_block_size=4096 disk-image.img > In particular, you can **use this to set driver properties for devices which > are created automatically by the machine model**. To create a device which is > not created automatically and set properties on it, use -device. > -global driver.prop=value is shorthand for -global driver=driver,property=prop,value=value. The longhand syntax works even when driver contains a dot. What I put a stress on in the quote, suggest I’m not misusing `-global` and that’s most probably a bug. **Update for more details:** It seems using `-drive` instead of `-device` and `driveA` assignment, the result is not the same, although RedHat documentation recommands using `-device` instead of `-drive` and QEmu 3.0 documentation says `-drive` is essentially a shortcut for `-device` (“essentially”, not telling about the difference). Below, two cases, with an except of `info block` and an excerpt of `info qtree`. With this one, `eject floppy0` works: qemu-system-i386 \ -monitor stdio \ -machine type=isapc,vmport=off \ -drive format=raw,if=floppy,media=disk,file=fda.img \ -device isa-vga,vgamem_mb=1 \ -serial msmouse […] floppy0 (#block156): fda.img (raw) Attached to: /machine/unattached/device[12] Removable device: not locked, tray closed Cache mode: writeback […] dev: isa-fdc, id "" iobase = 1008 (0x3f0) irq = 6 (0x6) dma = 2 (0x2) driveA = "" driveB = "" check_media_rate = true fdtypeA = "auto" fdtypeB = "auto" fallback = "288" isa irq 6 bus: floppy-bus.0 type floppy-bus dev: floppy, id "" unit
[Qemu-devel] [PATCH] tpm: Zero-init structure to avoid uninitialized variables in valgrind log
Zero-init the ptm_loc structure so that we don't have fields that are not initialised. Signed-off-by: Stefan Berger --- hw/tpm/tpm_emulator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c index 10bc20dbec..968f06ae3b 100644 --- a/hw/tpm/tpm_emulator.c +++ b/hw/tpm/tpm_emulator.c @@ -158,7 +158,7 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator *tpm_emu, static int tpm_emulator_set_locality(TPMEmulator *tpm_emu, uint8_t locty_number, Error **errp) { -ptm_loc loc; +ptm_loc loc = { 0 }; if (tpm_emu->cur_locty_number == locty_number) { return 0; -- 2.17.1
[Qemu-devel] [PATCH v2] linux-user/flatload: fix initial stack pointer alignment
Stack pointer alignment code incorrectly adds stack_size to sp instead of subtracting it. It also does not take flat_argvp_envp_on_stack() into account when calculating stack_size. This results in initial stack pointer misalignment with certain set of command line arguments and environment variables and correct alignment for the same binary with a different set of arguments. This misalignment causes failures in the following tests in the testsuite of gcc built for xtensa uclinux: gcc.dg/torture/vshuf-v64qi.c gcc.dg/torture/vshuf-v8sf.c gcc.dg/torture/vshuf-v8si.c Signed-off-by: Max Filippov --- Changes v1->v2: - make sp adjustment unconditional linux-user/flatload.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/linux-user/flatload.c b/linux-user/flatload.c index 2eefe55e5000..0122ab3afe65 100644 --- a/linux-user/flatload.c +++ b/linux-user/flatload.c @@ -771,10 +771,10 @@ int load_flt_binary(struct linux_binprm *bprm, struct image_info *info) /* Enforce final stack alignment of 16 bytes. This is sufficient for all current targets, and excess alignment is harmless. */ stack_len = bprm->envc + bprm->argc + 2; -stack_len += 3;/* argc, arvg, argp */ +stack_len += flat_argvp_envp_on_stack() ? 2 : 0; /* arvg, argp */ +stack_len += 1; /* argc */ stack_len *= sizeof(abi_ulong); -if ((sp + stack_len) & 15) -sp -= 16 - ((sp + stack_len) & 15); +sp -= (sp - stack_len) & 15; sp = loader_build_argptr(bprm->envc, bprm->argc, sp, p, flat_argvp_envp_on_stack()); -- 2.11.0
Re: [Qemu-devel] [PATCH] linux-user/flatload: fix initial stack pointer alignment
On Wed, Oct 24, 2018 at 10:19 AM Max Filippov wrote: > > On Wed, Oct 24, 2018 at 4:35 AM Laurent Vivier wrote: > > > diff --git a/linux-user/flatload.c b/linux-user/flatload.c > > > index 2eefe55e5000..1893966b5b30 100644 > > > --- a/linux-user/flatload.c > > > +++ b/linux-user/flatload.c > > > > -sp -= 16 - ((sp + stack_len) & 15); > > > +if ((sp - stack_len) & 15) { > > > +sp -= ((sp - stack_len) & 15); > > > +} > > > > If I understand correctly the purpose, I think it could be clearer like: > > > > sp = (sp - stack_len) & ~15; > > Yes, you're right. I'll send v2. Well, not exactly. The sp is not moved down stack_len + alignment bytes, only the alignment bytes. I'll send v2 anyway. -- Thanks. -- Max
Re: [Qemu-devel] [PULL v2 00/33] MIPS queue for October 2018 - part 2 - v2
On 24 October 2018 at 14:40, Aleksandar Markovic wrote: > From: Aleksandar Markovic > > The following changes since commit 13399aad4fa87b2878c49d02a5d3bafa6c966ba3: > > Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2018-10-22' > into staging (2018-10-23 17:20:23 +0100) > > are available in the git repository at: > > https://github.com/AMarkovic/qemu tags/mips-queue-oct-2018-part-2-v2 > > for you to fetch changes up to 373ecd3823f949fd550ec49685299e287af5753e: > > target/mips: Fix decoding of ALIGN and DALIGN instructions (2018-10-24 > 15:20:32 +0200) > > > MIPS queue for October 2018 - part 2 - v2 > > v1->v2: > - disassembler for R5900 feature removed (one whole patch and > parts of several other patches are excluded) > - amended R5900 CPU definition with respect to ASE_MMI > - minor improvements of patch titles, commit messages and comments > > > Applied, thanks. -- PMM
[Qemu-devel] [PULL 5/8] crypto: convert xts_mult_x to use xts_uint128 type
Using 64-bit arithmetic increases the performance for xts-aes-128 when built with gcrypt: Encrypt: 355 MB/s -> 545 MB/s Decrypt: 362 MB/s -> 568 MB/s Reviewed-by: Alberto Garcia Signed-off-by: Daniel P. Berrangé --- crypto/xts.c | 40 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/crypto/xts.c b/crypto/xts.c index 0ad231f3e5..10ec83ff21 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -24,6 +24,7 @@ */ #include "qemu/osdep.h" +#include "qemu/bswap.h" #include "crypto/xts.h" typedef union { @@ -39,19 +40,34 @@ static inline void xts_uint128_xor(xts_uint128 *D, D->u[1] = S1->u[1] ^ S2->u[1]; } -static void xts_mult_x(uint8_t *I) +static inline void xts_uint128_cpu_to_les(xts_uint128 *v) { -int x; -uint8_t t, tt; +cpu_to_le64s(>u[0]); +cpu_to_le64s(>u[1]); +} -for (x = t = 0; x < 16; x++) { -tt = I[x] >> 7; -I[x] = ((I[x] << 1) | t) & 0xFF; -t = tt; -} -if (tt) { -I[0] ^= 0x87; +static inline void xts_uint128_le_to_cpus(xts_uint128 *v) +{ +le64_to_cpus(>u[0]); +le64_to_cpus(>u[1]); +} + +static void xts_mult_x(xts_uint128 *I) +{ +uint64_t tt; + +xts_uint128_le_to_cpus(I); + +tt = I->u[0] >> 63; +I->u[0] <<= 1; + +if (I->u[1] >> 63) { +I->u[0] ^= 0x87; } +I->u[1] <<= 1; +I->u[1] |= tt; + +xts_uint128_cpu_to_les(I); } @@ -79,7 +95,7 @@ static void xts_tweak_encdec(const void *ctx, xts_uint128_xor(dst, dst, iv); /* LFSR the tweak */ -xts_mult_x(iv->b); +xts_mult_x(iv); } @@ -134,7 +150,7 @@ void xts_decrypt(const void *datactx, if (mo > 0) { xts_uint128 S, D; memcpy(, , XTS_BLOCK_SIZE); -xts_mult_x(CC.b); +xts_mult_x(); /* PP = tweak decrypt block m-1 */ memcpy(, src, XTS_BLOCK_SIZE); -- 2.17.2
Re: [Qemu-devel] [PATCH] target/mips: Support Toshiba specific three-operand MADD and MADDU
Hi Philippe, > The three-operand MADD and MADDU are specific to the > Toshiba TX19/TX39/TX79 cores. > > The "32-Bit TX System RISC TX39 Family Architecture manual" > is available at https://wiki.qemu.org/File:DSAE0022432.pdf > > Signed-off-by: Philippe Mathieu-Daudé I'm queueing your MADD and MADDU patch, with minor modifications as shown below, to amend the support for the R5900, based on Aleksandar's latest v2 tag: https://github.com/AMarkovic/qemu tags/mips-queue-oct-2018-part-2-v2 It looks like gen_move_{low32,high32} do sign-extend properly. However, their notes say "sign-extract" as in: /* Sign-extract the low 32-bits to a target_long. */ static inline void gen_move_low32(TCGv ret, TCGv_i64 arg) ... /* Sign-extract the high 32-bits to a target_long. */ static inline void gen_move_high32(TCGv ret, TCGv_i64 arg) Perhaps these are typos? Also, looking at the code for tcg_gen_mulu2_i32 and tcg_gen_add2_i32, they don't appear to be particularly more efficient anyway, in particular since more registers are needed, so let's go with your version. (A subsequent patch will do MADD1 and MADDU1 as well.) Thanks! Fredrik --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4801,8 +4801,8 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, } /* - * These MULT and MULTU instructions implemented in for example the - * Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core + * These MULT[U] and MADD[U] instructions implemented in for example + * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core * architectures are special three-operand variants with the syntax * * MULT[U][1] rd, rs, rt @@ -4811,6 +4811,14 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, * * (rd, LO, HI) <- rs * rt * + * and + * + * MADD[U]rd, rs, rt + * + * such that + * + * (rd, LO, HI) <- (LO, HI) + rs * rt + * * where the low-order 32-bits of the result is placed into both the * GPR rd and the special register LO. The high-order 32-bits of the * result is placed into the special register HI. @@ -4867,8 +4875,48 @@ static void gen_mul_txx9(DisasContext *ctx, uint32_t opc, tcg_temp_free_i32(t3); } break; +case TX79_MMI_MADD: +{ +TCGv_i64 t2 = tcg_temp_new_i64(); +TCGv_i64 t3 = tcg_temp_new_i64(); + +tcg_gen_ext_tl_i64(t2, t0); +tcg_gen_ext_tl_i64(t3, t1); +tcg_gen_mul_i64(t2, t2, t3); +tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); +tcg_gen_add_i64(t2, t2, t3); +tcg_temp_free_i64(t3); +gen_move_low32(cpu_LO[acc], t2); +gen_move_high32(cpu_HI[acc], t2); +if (rd) { +gen_move_low32(cpu_gpr[rd], t2); +} +tcg_temp_free_i64(t2); +} +break; +case TX79_MMI_MADDU: +{ +TCGv_i64 t2 = tcg_temp_new_i64(); +TCGv_i64 t3 = tcg_temp_new_i64(); + +tcg_gen_ext32u_tl(t0, t0); +tcg_gen_ext32u_tl(t1, t1); +tcg_gen_extu_tl_i64(t2, t0); +tcg_gen_extu_tl_i64(t3, t1); +tcg_gen_mul_i64(t2, t2, t3); +tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]); +tcg_gen_add_i64(t2, t2, t3); +tcg_temp_free_i64(t3); +gen_move_low32(cpu_LO[acc], t2); +gen_move_high32(cpu_HI[acc], t2); +if (rd) { +gen_move_low32(cpu_gpr[rd], t2); +} +tcg_temp_free_i64(t2); +} +break; default: -MIPS_INVAL("mul TXx9"); +MIPS_INVAL("mul/madd TXx9"); generate_exception_end(ctx, EXCP_RI); goto out; } @@ -24699,6 +24747,8 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) break; case TX79_MMI_MULT1: case TX79_MMI_MULTU1: +case TX79_MMI_MADD: +case TX79_MMI_MADDU: gen_mul_txx9(ctx, opc, rd, rs, rt); break; case TX79_MMI_DIV1: @@ -24713,8 +24763,6 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) case TX79_MMI_MFHI1: gen_HILO(ctx, opc, 1, rd); break; -case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */ -case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */ case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */ case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */ case TX79_MMI_MADDU1:/* TODO: TX79_MMI_MADDU1 */
[Qemu-devel] [PULL 1/8] crypto: expand algorithm coverage for cipher benchmark
Add testing coverage for AES with XTS, ECB and CTR modes Reviewed-by: Marc-André Lureau Reviewed-by: Alberto Garcia Signed-off-by: Daniel P. Berrangé --- tests/benchmark-crypto-cipher.c | 149 +++- 1 file changed, 126 insertions(+), 23 deletions(-) diff --git a/tests/benchmark-crypto-cipher.c b/tests/benchmark-crypto-cipher.c index f5a0d0bc32..67fdf8c31d 100644 --- a/tests/benchmark-crypto-cipher.c +++ b/tests/benchmark-crypto-cipher.c @@ -15,17 +15,27 @@ #include "crypto/init.h" #include "crypto/cipher.h" -static void test_cipher_speed(const void *opaque) +static void test_cipher_speed(size_t chunk_size, + QCryptoCipherMode mode, + QCryptoCipherAlgorithm alg) { QCryptoCipher *cipher; Error *err = NULL; double total = 0.0; -size_t chunk_size = (size_t)opaque; uint8_t *key = NULL, *iv = NULL; uint8_t *plaintext = NULL, *ciphertext = NULL; -size_t nkey = qcrypto_cipher_get_key_len(QCRYPTO_CIPHER_ALG_AES_128); -size_t niv = qcrypto_cipher_get_iv_len(QCRYPTO_CIPHER_ALG_AES_128, - QCRYPTO_CIPHER_MODE_CBC); +size_t nkey; +size_t niv; + +if (!qcrypto_cipher_supports(alg, mode)) { +return; +} + +nkey = qcrypto_cipher_get_key_len(alg); +niv = qcrypto_cipher_get_iv_len(alg, mode); +if (mode == QCRYPTO_CIPHER_MODE_XTS) { +nkey *= 2; +} key = g_new0(uint8_t, nkey); memset(key, g_test_rand_int(), nkey); @@ -38,14 +48,14 @@ static void test_cipher_speed(const void *opaque) plaintext = g_new0(uint8_t, chunk_size); memset(plaintext, g_test_rand_int(), chunk_size); -cipher = qcrypto_cipher_new(QCRYPTO_CIPHER_ALG_AES_128, -QCRYPTO_CIPHER_MODE_CBC, +cipher = qcrypto_cipher_new(alg, mode, key, nkey, ); g_assert(cipher != NULL); -g_assert(qcrypto_cipher_setiv(cipher, - iv, niv, - ) == 0); +if (mode != QCRYPTO_CIPHER_MODE_ECB) +g_assert(qcrypto_cipher_setiv(cipher, + iv, niv, + ) == 0); g_test_timer_start(); do { @@ -55,13 +65,26 @@ static void test_cipher_speed(const void *opaque) chunk_size, ) == 0); total += chunk_size; -} while (g_test_timer_elapsed() < 5.0); +} while (g_test_timer_elapsed() < 1.0); total /= MiB; -g_print("cbc(aes128): "); -g_print("Testing chunk_size %zu bytes ", chunk_size); -g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last()); -g_print("%.2f MB/sec\n", total / g_test_timer_last()); +g_print("Enc chunk %zu bytes ", chunk_size); +g_print("%.2f MB/sec ", total / g_test_timer_last()); + +total = 0.0; +g_test_timer_start(); +do { +g_assert(qcrypto_cipher_decrypt(cipher, +plaintext, +ciphertext, +chunk_size, +) == 0); +total += chunk_size; +} while (g_test_timer_elapsed() < 1.0); + +total /= MiB; +g_print("Dec chunk %zu bytes ", chunk_size); +g_print("%.2f MB/sec ", total / g_test_timer_last()); qcrypto_cipher_free(cipher); g_free(plaintext); @@ -70,19 +93,99 @@ static void test_cipher_speed(const void *opaque) g_free(key); } -int main(int argc, char **argv) + +static void test_cipher_speed_ecb_aes_128(const void *opaque) +{ +size_t chunk_size = (size_t)opaque; +test_cipher_speed(chunk_size, + QCRYPTO_CIPHER_MODE_ECB, + QCRYPTO_CIPHER_ALG_AES_128); +} + +static void test_cipher_speed_ecb_aes_256(const void *opaque) { -size_t i; -char name[64]; +size_t chunk_size = (size_t)opaque; +test_cipher_speed(chunk_size, + QCRYPTO_CIPHER_MODE_ECB, + QCRYPTO_CIPHER_ALG_AES_256); +} + +static void test_cipher_speed_cbc_aes_128(const void *opaque) +{ +size_t chunk_size = (size_t)opaque; +test_cipher_speed(chunk_size, + QCRYPTO_CIPHER_MODE_CBC, + QCRYPTO_CIPHER_ALG_AES_128); +} +static void test_cipher_speed_cbc_aes_256(const void *opaque) +{ +size_t chunk_size = (size_t)opaque; +test_cipher_speed(chunk_size, + QCRYPTO_CIPHER_MODE_CBC, + QCRYPTO_CIPHER_ALG_AES_256); +} + +static void test_cipher_speed_ctr_aes_128(const void *opaque) +{ +size_t chunk_size = (size_t)opaque; +test_cipher_speed(chunk_size, + QCRYPTO_CIPHER_MODE_CTR, + QCRYPTO_CIPHER_ALG_AES_128); +} + +static void test_cipher_speed_ctr_aes_256(const void
[Qemu-devel] [PULL 2/8] crypto: remove code duplication in tweak encrypt/decrypt
The tweak encrypt/decrypt functions are identical except for the comments, so can be merged. Profiling data shows that the compiler is in fact already merging the two merges in the object files. Reviewed-by: Marc-André Lureau Reviewed-by: Alberto Garcia Signed-off-by: Daniel P. Berrangé --- crypto/xts.c | 64 1 file changed, 15 insertions(+), 49 deletions(-) diff --git a/crypto/xts.c b/crypto/xts.c index 95212341f6..3c1a92f01d 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -43,20 +43,20 @@ static void xts_mult_x(uint8_t *I) /** - * xts_tweak_uncrypt: + * xts_tweak_encdec: * @param ctxt: the cipher context * @param func: the cipher function - * @src: buffer providing the cipher text of XTS_BLOCK_SIZE bytes - * @dst: buffer to output the plain text of XTS_BLOCK_SIZE bytes + * @src: buffer providing the input text of XTS_BLOCK_SIZE bytes + * @dst: buffer to output the output text of XTS_BLOCK_SIZE bytes * @iv: the initialization vector tweak of XTS_BLOCK_SIZE bytes * - * Decrypt data with a tweak + * Encrypt/decrypt data with a tweak */ -static void xts_tweak_decrypt(const void *ctx, - xts_cipher_func *func, - const uint8_t *src, - uint8_t *dst, - uint8_t *iv) +static void xts_tweak_encdec(const void *ctx, + xts_cipher_func *func, + const uint8_t *src, + uint8_t *dst, + uint8_t *iv) { unsigned long x; @@ -105,7 +105,7 @@ void xts_decrypt(const void *datactx, encfunc(tweakctx, XTS_BLOCK_SIZE, T, iv); for (i = 0; i < lim; i++) { -xts_tweak_decrypt(datactx, decfunc, src, dst, T); +xts_tweak_encdec(datactx, decfunc, src, dst, T); src += XTS_BLOCK_SIZE; dst += XTS_BLOCK_SIZE; @@ -117,7 +117,7 @@ void xts_decrypt(const void *datactx, xts_mult_x(CC); /* PP = tweak decrypt block m-1 */ -xts_tweak_decrypt(datactx, decfunc, src, PP, CC); +xts_tweak_encdec(datactx, decfunc, src, PP, CC); /* Pm = first length % XTS_BLOCK_SIZE bytes of PP */ for (i = 0; i < mo; i++) { @@ -129,7 +129,7 @@ void xts_decrypt(const void *datactx, } /* Pm-1 = Tweak uncrypt CC */ -xts_tweak_decrypt(datactx, decfunc, CC, dst, T); +xts_tweak_encdec(datactx, decfunc, CC, dst, T); } /* Decrypt the iv back */ @@ -137,40 +137,6 @@ void xts_decrypt(const void *datactx, } -/** - * xts_tweak_crypt: - * @param ctxt: the cipher context - * @param func: the cipher function - * @src: buffer providing the plain text of XTS_BLOCK_SIZE bytes - * @dst: buffer to output the cipher text of XTS_BLOCK_SIZE bytes - * @iv: the initialization vector tweak of XTS_BLOCK_SIZE bytes - * - * Encrypt data with a tweak - */ -static void xts_tweak_encrypt(const void *ctx, - xts_cipher_func *func, - const uint8_t *src, - uint8_t *dst, - uint8_t *iv) -{ -unsigned long x; - -/* tweak encrypt block i */ -for (x = 0; x < XTS_BLOCK_SIZE; x++) { -dst[x] = src[x] ^ iv[x]; -} - -func(ctx, XTS_BLOCK_SIZE, dst, dst); - -for (x = 0; x < XTS_BLOCK_SIZE; x++) { -dst[x] = dst[x] ^ iv[x]; -} - -/* LFSR the tweak */ -xts_mult_x(iv); -} - - void xts_encrypt(const void *datactx, const void *tweakctx, xts_cipher_func *encfunc, @@ -200,7 +166,7 @@ void xts_encrypt(const void *datactx, encfunc(tweakctx, XTS_BLOCK_SIZE, T, iv); for (i = 0; i < lim; i++) { -xts_tweak_encrypt(datactx, encfunc, src, dst, T); +xts_tweak_encdec(datactx, encfunc, src, dst, T); dst += XTS_BLOCK_SIZE; src += XTS_BLOCK_SIZE; @@ -209,7 +175,7 @@ void xts_encrypt(const void *datactx, /* if length is not a multiple of XTS_BLOCK_SIZE then */ if (mo > 0) { /* CC = tweak encrypt block m-1 */ -xts_tweak_encrypt(datactx, encfunc, src, CC, T); +xts_tweak_encdec(datactx, encfunc, src, CC, T); /* Cm = first length % XTS_BLOCK_SIZE bytes of CC */ for (i = 0; i < mo; i++) { @@ -222,7 +188,7 @@ void xts_encrypt(const void *datactx, } /* Cm-1 = Tweak encrypt PP */ -xts_tweak_encrypt(datactx, encfunc, PP, dst, T); +xts_tweak_encdec(datactx, encfunc, PP, dst, T); } /* Decrypt the iv back */ -- 2.17.2
[Qemu-devel] [PULL 3/8] crypto: introduce a xts_uint128 data type
The new type is designed to allow use of 64-bit arithmetic instead of operating 1-byte at a time. The following patches will use this to improve performance. Reviewed-by: Alberto Garcia Signed-off-by: Daniel P. Berrangé --- crypto/xts.c | 46 ++ 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/crypto/xts.c b/crypto/xts.c index 3c1a92f01d..bee23f890e 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -26,6 +26,12 @@ #include "qemu/osdep.h" #include "crypto/xts.h" +typedef union { +uint8_t b[XTS_BLOCK_SIZE]; +uint64_t u[2]; +} xts_uint128; + + static void xts_mult_x(uint8_t *I) { int x; @@ -85,7 +91,7 @@ void xts_decrypt(const void *datactx, uint8_t *dst, const uint8_t *src) { -uint8_t PP[XTS_BLOCK_SIZE], CC[XTS_BLOCK_SIZE], T[XTS_BLOCK_SIZE]; +xts_uint128 PP, CC, T; unsigned long i, m, mo, lim; /* get number of blocks */ @@ -102,10 +108,10 @@ void xts_decrypt(const void *datactx, } /* encrypt the iv */ -encfunc(tweakctx, XTS_BLOCK_SIZE, T, iv); +encfunc(tweakctx, XTS_BLOCK_SIZE, T.b, iv); for (i = 0; i < lim; i++) { -xts_tweak_encdec(datactx, decfunc, src, dst, T); +xts_tweak_encdec(datactx, decfunc, src, dst, T.b); src += XTS_BLOCK_SIZE; dst += XTS_BLOCK_SIZE; @@ -113,27 +119,27 @@ void xts_decrypt(const void *datactx, /* if length is not a multiple of XTS_BLOCK_SIZE then */ if (mo > 0) { -memcpy(CC, T, XTS_BLOCK_SIZE); -xts_mult_x(CC); +memcpy(, , XTS_BLOCK_SIZE); +xts_mult_x(CC.b); /* PP = tweak decrypt block m-1 */ -xts_tweak_encdec(datactx, decfunc, src, PP, CC); +xts_tweak_encdec(datactx, decfunc, src, PP.b, CC.b); /* Pm = first length % XTS_BLOCK_SIZE bytes of PP */ for (i = 0; i < mo; i++) { -CC[i] = src[XTS_BLOCK_SIZE + i]; -dst[XTS_BLOCK_SIZE + i] = PP[i]; +CC.b[i] = src[XTS_BLOCK_SIZE + i]; +dst[XTS_BLOCK_SIZE + i] = PP.b[i]; } for (; i < XTS_BLOCK_SIZE; i++) { -CC[i] = PP[i]; +CC.b[i] = PP.b[i]; } /* Pm-1 = Tweak uncrypt CC */ -xts_tweak_encdec(datactx, decfunc, CC, dst, T); +xts_tweak_encdec(datactx, decfunc, CC.b, dst, T.b); } /* Decrypt the iv back */ -decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T); +decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T.b); } @@ -146,7 +152,7 @@ void xts_encrypt(const void *datactx, uint8_t *dst, const uint8_t *src) { -uint8_t PP[XTS_BLOCK_SIZE], CC[XTS_BLOCK_SIZE], T[XTS_BLOCK_SIZE]; +xts_uint128 PP, CC, T; unsigned long i, m, mo, lim; /* get number of blocks */ @@ -163,10 +169,10 @@ void xts_encrypt(const void *datactx, } /* encrypt the iv */ -encfunc(tweakctx, XTS_BLOCK_SIZE, T, iv); +encfunc(tweakctx, XTS_BLOCK_SIZE, T.b, iv); for (i = 0; i < lim; i++) { -xts_tweak_encdec(datactx, encfunc, src, dst, T); +xts_tweak_encdec(datactx, encfunc, src, dst, T.b); dst += XTS_BLOCK_SIZE; src += XTS_BLOCK_SIZE; @@ -175,22 +181,22 @@ void xts_encrypt(const void *datactx, /* if length is not a multiple of XTS_BLOCK_SIZE then */ if (mo > 0) { /* CC = tweak encrypt block m-1 */ -xts_tweak_encdec(datactx, encfunc, src, CC, T); +xts_tweak_encdec(datactx, encfunc, src, CC.b, T.b); /* Cm = first length % XTS_BLOCK_SIZE bytes of CC */ for (i = 0; i < mo; i++) { -PP[i] = src[XTS_BLOCK_SIZE + i]; -dst[XTS_BLOCK_SIZE + i] = CC[i]; +PP.b[i] = src[XTS_BLOCK_SIZE + i]; +dst[XTS_BLOCK_SIZE + i] = CC.b[i]; } for (; i < XTS_BLOCK_SIZE; i++) { -PP[i] = CC[i]; +PP.b[i] = CC.b[i]; } /* Cm-1 = Tweak encrypt PP */ -xts_tweak_encdec(datactx, encfunc, PP, dst, T); +xts_tweak_encdec(datactx, encfunc, PP.b, dst, T.b); } /* Decrypt the iv back */ -decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T); +decfunc(tweakctx, XTS_BLOCK_SIZE, iv, T.b); } -- 2.17.2
[Qemu-devel] [PULL 6/8] crypto: annotate xts_tweak_encdec as inlineable
Encouraging the compiler to inline xts_tweak_encdec increases the performance for xts-aes-128 when built with gcrypt: Encrypt: 545 MB/s -> 580 MB/s Decrypt: 568 MB/s -> 602 MB/s Reviewed-by: Alberto Garcia Signed-off-by: Daniel P. Berrangé --- crypto/xts.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crypto/xts.c b/crypto/xts.c index 10ec83ff21..4277ad40de 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -81,11 +81,11 @@ static void xts_mult_x(xts_uint128 *I) * * Encrypt/decrypt data with a tweak */ -static void xts_tweak_encdec(const void *ctx, - xts_cipher_func *func, - const xts_uint128 *src, - xts_uint128 *dst, - xts_uint128 *iv) +static inline void xts_tweak_encdec(const void *ctx, +xts_cipher_func *func, +const xts_uint128 *src, +xts_uint128 *dst, +xts_uint128 *iv) { /* tweak encrypt block i */ xts_uint128_xor(dst, src, iv); -- 2.17.2
[Qemu-devel] [PULL 4/8] crypto: convert xts_tweak_encdec to use xts_uint128 type
Using 64-bit arithmetic increases the performance for xts-aes-128 when built with gcrypt: Encrypt: 272 MB/s -> 355 MB/s Decrypt: 275 MB/s -> 362 MB/s Reviewed-by: Alberto Garcia Signed-off-by: Daniel P. Berrangé --- crypto/xts.c | 84 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/crypto/xts.c b/crypto/xts.c index bee23f890e..0ad231f3e5 100644 --- a/crypto/xts.c +++ b/crypto/xts.c @@ -31,6 +31,13 @@ typedef union { uint64_t u[2]; } xts_uint128; +static inline void xts_uint128_xor(xts_uint128 *D, + const xts_uint128 *S1, + const xts_uint128 *S2) +{ +D->u[0] = S1->u[0] ^ S2->u[0]; +D->u[1] = S1->u[1] ^ S2->u[1]; +} static void xts_mult_x(uint8_t *I) { @@ -60,25 +67,19 @@ static void xts_mult_x(uint8_t *I) */ static void xts_tweak_encdec(const void *ctx, xts_cipher_func *func, - const uint8_t *src, - uint8_t *dst, - uint8_t *iv) + const xts_uint128 *src, + xts_uint128 *dst, + xts_uint128 *iv) { -unsigned long x; - /* tweak encrypt block i */ -for (x = 0; x < XTS_BLOCK_SIZE; x++) { -dst[x] = src[x] ^ iv[x]; -} +xts_uint128_xor(dst, src, iv); -func(ctx, XTS_BLOCK_SIZE, dst, dst); +func(ctx, XTS_BLOCK_SIZE, dst->b, dst->b); -for (x = 0; x < XTS_BLOCK_SIZE; x++) { -dst[x] = dst[x] ^ iv[x]; -} +xts_uint128_xor(dst, dst, iv); /* LFSR the tweak */ -xts_mult_x(iv); +xts_mult_x(iv->b); } @@ -110,20 +111,34 @@ void xts_decrypt(const void *datactx, /* encrypt the iv */ encfunc(tweakctx, XTS_BLOCK_SIZE, T.b, iv); -for (i = 0; i < lim; i++) { -xts_tweak_encdec(datactx, decfunc, src, dst, T.b); - -src += XTS_BLOCK_SIZE; -dst += XTS_BLOCK_SIZE; +if (QEMU_PTR_IS_ALIGNED(src, sizeof(uint64_t)) && +QEMU_PTR_IS_ALIGNED(dst, sizeof(uint64_t))) { +xts_uint128 *S = (xts_uint128 *)src; +xts_uint128 *D = (xts_uint128 *)dst; +for (i = 0; i < lim; i++, S++, D++) { +xts_tweak_encdec(datactx, decfunc, S, D, ); +} +} else { +xts_uint128 D; + +for (i = 0; i < lim; i++) { +memcpy(, src, XTS_BLOCK_SIZE); +xts_tweak_encdec(datactx, decfunc, , , ); +memcpy(dst, , XTS_BLOCK_SIZE); +src += XTS_BLOCK_SIZE; +dst += XTS_BLOCK_SIZE; +} } /* if length is not a multiple of XTS_BLOCK_SIZE then */ if (mo > 0) { +xts_uint128 S, D; memcpy(, , XTS_BLOCK_SIZE); xts_mult_x(CC.b); /* PP = tweak decrypt block m-1 */ -xts_tweak_encdec(datactx, decfunc, src, PP.b, CC.b); +memcpy(, src, XTS_BLOCK_SIZE); +xts_tweak_encdec(datactx, decfunc, , , ); /* Pm = first length % XTS_BLOCK_SIZE bytes of PP */ for (i = 0; i < mo; i++) { @@ -135,7 +150,8 @@ void xts_decrypt(const void *datactx, } /* Pm-1 = Tweak uncrypt CC */ -xts_tweak_encdec(datactx, decfunc, CC.b, dst, T.b); +xts_tweak_encdec(datactx, decfunc, , , ); +memcpy(dst, , XTS_BLOCK_SIZE); } /* Decrypt the iv back */ @@ -171,17 +187,32 @@ void xts_encrypt(const void *datactx, /* encrypt the iv */ encfunc(tweakctx, XTS_BLOCK_SIZE, T.b, iv); -for (i = 0; i < lim; i++) { -xts_tweak_encdec(datactx, encfunc, src, dst, T.b); +if (QEMU_PTR_IS_ALIGNED(src, sizeof(uint64_t)) && +QEMU_PTR_IS_ALIGNED(dst, sizeof(uint64_t))) { +xts_uint128 *S = (xts_uint128 *)src; +xts_uint128 *D = (xts_uint128 *)dst; +for (i = 0; i < lim; i++, S++, D++) { +xts_tweak_encdec(datactx, encfunc, S, D, ); +} +} else { +xts_uint128 D; + +for (i = 0; i < lim; i++) { +memcpy(, src, XTS_BLOCK_SIZE); +xts_tweak_encdec(datactx, encfunc, , , ); +memcpy(dst, , XTS_BLOCK_SIZE); -dst += XTS_BLOCK_SIZE; -src += XTS_BLOCK_SIZE; +dst += XTS_BLOCK_SIZE; +src += XTS_BLOCK_SIZE; +} } /* if length is not a multiple of XTS_BLOCK_SIZE then */ if (mo > 0) { +xts_uint128 S, D; /* CC = tweak encrypt block m-1 */ -xts_tweak_encdec(datactx, encfunc, src, CC.b, T.b); +memcpy(, src, XTS_BLOCK_SIZE); +xts_tweak_encdec(datactx, encfunc, , , ); /* Cm = first length % XTS_BLOCK_SIZE bytes of CC */ for (i = 0; i < mo; i++) { @@ -194,7 +225,8 @@ void xts_encrypt(const void *datactx, } /* Cm-1 = Tweak encrypt PP */ -xts_tweak_encdec(datactx, encfunc, PP.b, dst, T.b); +xts_tweak_encdec(datactx, encfunc, , , ); +
[Qemu-devel] [PULL 0/8] Qcrypto next patches
The following changes since commit c96292036a17857d62b8b5d3c8752bac3d6b7193: Merge remote-tracking branch 'remotes/amarkovic/tags/mips-queue-oct-2018-part-2-v2' into staging (2018-10-24 16:31:40 +0100) are available in the Git repository at: https://github.com/berrange/qemu tags/qcrypto-next-pull-request for you to fetch changes up to 1e0fa32c6c952d2ce9c19d35717c609804dd55d5: crypto: add testing for unaligned buffers with XTS cipher mode (2018-10-24 19:03:37 +0100) Improve performance of XTS cipher mode impl The XTS cipher mode performance is approximately doubled and test coverage is improved. Daniel P. Berrangé (8): crypto: expand algorithm coverage for cipher benchmark crypto: remove code duplication in tweak encrypt/decrypt crypto: introduce a xts_uint128 data type crypto: convert xts_tweak_encdec to use xts_uint128 type crypto: convert xts_mult_x to use xts_uint128 type crypto: annotate xts_tweak_encdec as inlineable crypto: refactor XTS cipher mode test suite crypto: add testing for unaligned buffers with XTS cipher mode crypto/xts.c| 200 +++- tests/benchmark-crypto-cipher.c | 149 + tests/test-crypto-xts.c | 226 +++- 3 files changed, 402 insertions(+), 173 deletions(-) -- 2.17.2
[Qemu-devel] [PULL 8/8] crypto: add testing for unaligned buffers with XTS cipher mode
Validate that the XTS cipher mode will correctly operate with plain text, cipher text and IV buffers that are not 64-bit aligned. Reviewed-by: Alberto Garcia Signed-off-by: Daniel P. Berrangé --- tests/test-crypto-xts.c | 86 + 1 file changed, 86 insertions(+) diff --git a/tests/test-crypto-xts.c b/tests/test-crypto-xts.c index 81606d90ad..6fb61cf635 100644 --- a/tests/test-crypto-xts.c +++ b/tests/test-crypto-xts.c @@ -416,6 +416,88 @@ static void test_xts_split(const void *opaque) } +static void test_xts_unaligned(const void *opaque) +{ +#define BAD_ALIGN 3 +const QCryptoXTSTestData *data = opaque; +uint8_t in[512 + BAD_ALIGN], out[512 + BAD_ALIGN]; +uint8_t Torg[16], T[16 + BAD_ALIGN]; +uint64_t seq; +struct TestAES aesdata; +struct TestAES aestweak; + +AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, ); +AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, ); +AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, ); +AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, ); + +seq = data->seqnum; +STORE64L(seq, Torg); +memset(Torg + 8, 0, 8); + +/* IV not aligned */ +memcpy(T + BAD_ALIGN, Torg, 16); +memcpy(in, data->PTX, data->PTLEN); +xts_encrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T + BAD_ALIGN, data->PTLEN, out, in); + +g_assert(memcmp(out, data->CTX, data->PTLEN) == 0); + +/* plain text not aligned */ +memcpy(T, Torg, 16); +memcpy(in + BAD_ALIGN, data->PTX, data->PTLEN); +xts_encrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T, data->PTLEN, out, in + BAD_ALIGN); + +g_assert(memcmp(out, data->CTX, data->PTLEN) == 0); + +/* cipher text not aligned */ +memcpy(T, Torg, 16); +memcpy(in, data->PTX, data->PTLEN); +xts_encrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T, data->PTLEN, out + BAD_ALIGN, in); + +g_assert(memcmp(out + BAD_ALIGN, data->CTX, data->PTLEN) == 0); + + +/* IV not aligned */ +memcpy(T + BAD_ALIGN, Torg, 16); +memcpy(in, data->CTX, data->PTLEN); +xts_decrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T + BAD_ALIGN, data->PTLEN, out, in); + +g_assert(memcmp(out, data->PTX, data->PTLEN) == 0); + +/* cipher text not aligned */ +memcpy(T, Torg, 16); +memcpy(in + BAD_ALIGN, data->CTX, data->PTLEN); +xts_decrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T, data->PTLEN, out, in + BAD_ALIGN); + +g_assert(memcmp(out, data->PTX, data->PTLEN) == 0); + +/* plain text not aligned */ +memcpy(T, Torg, 16); +memcpy(in, data->CTX, data->PTLEN); +xts_decrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T, data->PTLEN, out + BAD_ALIGN, in); + +g_assert(memcmp(out + BAD_ALIGN, data->PTX, data->PTLEN) == 0); +} + + int main(int argc, char **argv) { size_t i; @@ -437,6 +519,10 @@ int main(int argc, char **argv) g_test_add_data_func(path, _data[i], test_xts_split); g_free(path); } + +path = g_strdup_printf("%s/unaligned", test_data[i].path); +g_test_add_data_func(path, _data[i], test_xts_unaligned); +g_free(path); } return g_test_run(); -- 2.17.2
[Qemu-devel] [PULL 7/8] crypto: refactor XTS cipher mode test suite
The current XTS test overloads two different tests in a single function making the code a little hard to follow. Split it into distinct test cases. Reviewed-by: Alberto Garcia Signed-off-by: Daniel P. Berrangé --- tests/test-crypto-xts.c | 140 +++- 1 file changed, 80 insertions(+), 60 deletions(-) diff --git a/tests/test-crypto-xts.c b/tests/test-crypto-xts.c index 1f1412c45a..81606d90ad 100644 --- a/tests/test-crypto-xts.c +++ b/tests/test-crypto-xts.c @@ -1,7 +1,7 @@ /* * QEMU Crypto XTS cipher mode * - * Copyright (c) 2015-2016 Red Hat, Inc. + * Copyright (c) 2015-2018 Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -340,70 +340,79 @@ static void test_xts_aes_decrypt(const void *ctx, static void test_xts(const void *opaque) { const QCryptoXTSTestData *data = opaque; -unsigned char out[512], Torg[16], T[16]; +uint8_t out[512], Torg[16], T[16]; uint64_t seq; -int j; -unsigned long len; struct TestAES aesdata; struct TestAES aestweak; -for (j = 0; j < 2; j++) { -/* skip the cases where - * the length is smaller than 2*blocklen - * or the length is not a multiple of 32 - */ -if ((j == 1) && ((data->PTLEN < 32) || (data->PTLEN % 32))) { -continue; -} -len = data->PTLEN / 2; - -AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, ); -AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, ); -AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, ); -AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, ); - -seq = data->seqnum; -STORE64L(seq, Torg); -memset(Torg + 8, 0, 8); - -memcpy(T, Torg, sizeof(T)); -if (j == 0) { -xts_encrypt(, , -test_xts_aes_encrypt, -test_xts_aes_decrypt, -T, data->PTLEN, out, data->PTX); -} else { -xts_encrypt(, , -test_xts_aes_encrypt, -test_xts_aes_decrypt, -T, len, out, data->PTX); -xts_encrypt(, , -test_xts_aes_encrypt, -test_xts_aes_decrypt, -T, len, [len], >PTX[len]); -} +AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, ); +AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, ); +AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, ); +AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, ); -g_assert(memcmp(out, data->CTX, data->PTLEN) == 0); - -memcpy(T, Torg, sizeof(T)); -if (j == 0) { -xts_decrypt(, , -test_xts_aes_encrypt, -test_xts_aes_decrypt, -T, data->PTLEN, out, data->CTX); -} else { -xts_decrypt(, , -test_xts_aes_encrypt, -test_xts_aes_decrypt, -T, len, out, data->CTX); -xts_decrypt(, , -test_xts_aes_encrypt, -test_xts_aes_decrypt, -T, len, [len], >CTX[len]); -} +seq = data->seqnum; +STORE64L(seq, Torg); +memset(Torg + 8, 0, 8); -g_assert(memcmp(out, data->PTX, data->PTLEN) == 0); -} +memcpy(T, Torg, sizeof(T)); +xts_encrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T, data->PTLEN, out, data->PTX); + +g_assert(memcmp(out, data->CTX, data->PTLEN) == 0); + +memcpy(T, Torg, sizeof(T)); +xts_decrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T, data->PTLEN, out, data->CTX); + +g_assert(memcmp(out, data->PTX, data->PTLEN) == 0); +} + + +static void test_xts_split(const void *opaque) +{ +const QCryptoXTSTestData *data = opaque; +uint8_t out[512], Torg[16], T[16]; +uint64_t seq; +unsigned long len = data->PTLEN / 2; +struct TestAES aesdata; +struct TestAES aestweak; + +AES_set_encrypt_key(data->key1, data->keylen / 2 * 8, ); +AES_set_decrypt_key(data->key1, data->keylen / 2 * 8, ); +AES_set_encrypt_key(data->key2, data->keylen / 2 * 8, ); +AES_set_decrypt_key(data->key2, data->keylen / 2 * 8, ); + +seq = data->seqnum; +STORE64L(seq, Torg); +memset(Torg + 8, 0, 8); + +memcpy(T, Torg, sizeof(T)); +xts_encrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T, len, out, data->PTX); +xts_encrypt(, , +test_xts_aes_encrypt, +test_xts_aes_decrypt, +T, len, [len], >PTX[len]); + +g_assert(memcmp(out, data->CTX, data->PTLEN) == 0); + +memcpy(T, Torg,
Re: [Qemu-devel] [PATCH] disas/mips: Increase 'member of ISAs' flag holder size
Hi Philippe, On Wed, Oct 24, 2018 at 12:57:32PM +0200, Philippe Mathieu-Daudé wrote: > Increase the size of 'membership' holder size to 64 bits. This is > needed for future extensions since existing bits are almost all used. > (This change is related to f9c9cd63e3), I'm queueing your patch to amend the support for the R5900, based on Aleksandar's latest v2 tag: https://github.com/AMarkovic/qemu tags/mips-queue-oct-2018-part-2-v2 > Signed-off-by: Philippe Mathieu-Daudé > --- > disas/mips.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/disas/mips.c b/disas/mips.c > index 97f661a37e..d73d4094d8 100644 > --- a/disas/mips.c > +++ b/disas/mips.c > @@ -301,7 +301,7 @@ struct mips_opcode >unsigned long pinfo2; >/* A collection of bits describing the instruction sets of which this > instruction or macro is a member. */ > - unsigned long membership; > + uint64_t membership; > }; > > /* These are the characters which may appear in the args field of an > -- > 2.19.1 >
[Qemu-devel] Error with Virtio DMA Remapping
Hi all, I am trying to use QEMU vIOMMU for virtio DMA remapping. When I run the VM, I get the following messages in stderr: qemu-system-x86_64: vtd_iommu_translate: detected translation failure (dev=01:00:00, iova=0x0) qemu-system-x86_64: New fault is not recorded due to compression of faults qemu-system-x86_64: virtio: zero sized buffers are not allowed My QEMU configuration is: ./qemu-system-x86_64 -M accel=kvm -cpu host -smp 2 -m 4G \ -enable-kvm -machine q35,accel=kvm,kernel-irqchip=split \ -device intel-iommu,x-aw-bits=48,device-iotlb=on,pt=false \ -device ioh3420,id=pcie.1,chassis=1 \ -device virtio-scsi-pci,bus=pcie.1,id=scsi0,iommu_platform=on,ats=on, disable-legacy=on,disable-modern=off \ [...] I use QEMU 3.0.50 and host kernel 4.4.0. I followed the instructions here: https://wiki.qemu.org/Features/VT-d#With_Virtio_Devices to enable DMAR for the virtio-scsi device. I see there is a related thread about this error here: http://qemu.11.n7.nabble.com/PATCH-0-2-virtio-scsi-Fix-QEMU-hang-with-vIOMMU-and-ATS-td598736.html#a599086 Is this still an open issue or it has been solved? Please let me know. Thanks, Nikos
[Qemu-devel] [PATCH 2/3] target/mips: Implement emulation of nanoMIPS EVA instructions
From: Dimitrije Nikolic Implement emulation of nanoMIPS EVA instructions. They are all part of P.LS.E0 instruction pool, or one of its subpools. Signed-off-by: Dimitrije Nikolic Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 128 1 file changed, 128 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index 4338b9a..60964c9 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2989,6 +2989,35 @@ static inline void check_nms(DisasContext *ctx) } } +/* + * This code generates a "reserved instruction" exception if the + * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL, + * Config2 TL, and Config5 L2C are unset. + */ +static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx) +{ +if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) && +!(ctx->CP0_Config1 & (1 << CP0C1_DL)) && +!(ctx->CP0_Config1 & (1 << CP0C1_IL)) && +!(ctx->CP0_Config2 & (1 << CP0C2_SL)) && +!(ctx->CP0_Config2 & (1 << CP0C2_TL)) && +!(ctx->CP0_Config5 & (1 << CP0C5_L2C))) +{ +generate_exception_end(ctx, EXCP_RI); +} +} + +/* + * This code generates a "reserved instruction" exception if the + * Config5 EVA bit is NOT set. + */ +static inline void check_eva(DisasContext *ctx) +{ +if (!unlikely(ctx->CP0_Config5 & (1 << CP0C5_EVA))) { +generate_exception_end(ctx, EXCP_RI); +} +} + /* Define small wrappers for gen_load_fpr* so that we have a uniform calling interface for 32 and 64-bit FPRs. No sense in changing @@ -21218,6 +21247,105 @@ static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx) break; } break; +case NM_P_LS_E0: +switch (extract32(ctx->opcode, 11, 4)) { +case NM_LBE: +check_eva(ctx); +check_cp0_enabled(ctx); +gen_ld(ctx, OPC_LBE, rt, rs, s); +break; +case NM_SBE: +check_eva(ctx); +check_cp0_enabled(ctx); +gen_st(ctx, OPC_SBE, rt, rs, s); +break; +case NM_LBUE: +check_eva(ctx); +check_cp0_enabled(ctx); +gen_ld(ctx, OPC_LBUE, rt, rs, s); +break; +case NM_P_PREFE: +if (rt == 31) { +/* case NM_SYNCIE */ +check_eva(ctx); +check_cp0_enabled(ctx); +/* Break the TB to be able to sync copied instructions + immediately */ +ctx->base.is_jmp = DISAS_STOP; +} else { +/* case NM_PREFE */ +check_eva(ctx); +check_cp0_enabled(ctx); +/* Treat as NOP. */ +} +break; +case NM_LHE: +check_eva(ctx); +check_cp0_enabled(ctx); +gen_ld(ctx, OPC_LHE, rt, rs, s); +break; +case NM_SHE: +check_eva(ctx); +check_cp0_enabled(ctx); +gen_st(ctx, OPC_SHE, rt, rs, s); +break; +case NM_LHUE: +check_eva(ctx); +check_cp0_enabled(ctx); +gen_ld(ctx, OPC_LHUE, rt, rs, s); +break; +case NM_CACHEE: +check_nms_dl_il_sl_tl_l2c(ctx); +gen_cache_operation(ctx, rt, rs, s); +break; +case NM_LWE: +check_eva(ctx); +check_cp0_enabled(ctx); +gen_ld(ctx, OPC_LWE, rt, rs, s); +break; +case NM_SWE: +check_eva(ctx); +check_cp0_enabled(ctx); +gen_st(ctx, OPC_SWE, rt, rs, s); +break; +case NM_P_LLE: +switch (extract32(ctx->opcode, 2, 2)) { +case NM_LLE: +check_xnp(ctx); +check_eva(ctx); +check_cp0_enabled(ctx); +gen_ld(ctx, OPC_LLE, rt, rs, s); +break; +case NM_LLWPE: +check_xnp(ctx); +check_eva(ctx); +check_cp0_enabled(ctx); +gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5)); +default: +generate_exception_end(ctx, EXCP_RI); +break; +}
[Qemu-devel] [PATCH 1/3] target/mips: Add nanoMIPS CRC32 instruction pool
From: Aleksandar Markovic Add nanoMIPS CRC32 instruction pool. Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 10 ++ 1 file changed, 10 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index c44a751..4338b9a 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -17475,6 +17475,16 @@ enum { NM_SOV = 0x7a, }; +/* CRC32 instruction pool */ +enum { +NM_CRC32B = 0x00, +NM_CRC32H = 0x01, +NM_CRC32W = 0x02, +NM_CRC32CB = 0x04, +NM_CRC32CH = 0x05, +NM_CRC32CW = 0x06, +}; + /* POOL32A5 instruction pool */ enum { NM_CMP_EQ_PH= 0x00, -- 2.7.4
[Qemu-devel] [PATCH 0/3] target/mips: Add some nanoMIPS bits and pieces
From: Aleksandar Markovic Add some nanoMIPS bits and pieces that for various reasons didn't manage to be integrated. Aleksandar Markovic (2): target/mips: Add nanoMIPS CRC32 instruction pool target/mips: Add disassembler support for nanoMIPS Dimitrije Nikolic (1): target/mips: Implement emulation of nanoMIPS EVA instructions MAINTAINERS | 2 + disas/Makefile.objs | 1 + disas/mips.c|90 +- disas/nanomips.cpp | 22134 ++ disas/nanomips.h| 1100 +++ include/disas/bfd.h | 1 + target/mips/cpu.c |11 +- target/mips/translate.c | 138 + 8 files changed, 23474 insertions(+), 3 deletions(-) create mode 100644 disas/nanomips.cpp create mode 100644 disas/nanomips.h -- 2.7.4
Re: [Qemu-devel] [PATCH] linux-user/flatload: fix initial stack pointer alignment
On Wed, Oct 24, 2018 at 4:35 AM Laurent Vivier wrote: > > diff --git a/linux-user/flatload.c b/linux-user/flatload.c > > index 2eefe55e5000..1893966b5b30 100644 > > --- a/linux-user/flatload.c > > +++ b/linux-user/flatload.c > > -sp -= 16 - ((sp + stack_len) & 15); > > +if ((sp - stack_len) & 15) { > > +sp -= ((sp - stack_len) & 15); > > +} > > If I understand correctly the purpose, I think it could be clearer like: > > sp = (sp - stack_len) & ~15; Yes, you're right. I'll send v2. -- Thanks. -- Max
Re: [Qemu-devel] [PATCH 3/3] ppc/pnv: check size before data buffer access
On 10/23/18 5:37 PM, David Gibson wrote: > On Mon, Oct 22, 2018 at 05:49:07PM +0530, P J P wrote: >> From: Prasad J Pandit >> >> While performing PowerNV memory r/w operations, the access length >> 'sz' could exceed the data[4] buffer size. Add check to avoid OOB >> access. >> >> Reported-by: Moguofang >> Signed-off-by: Prasad J Pandit > > So, it certainly does look like we can get an overrun here. But is > just turning the access into a no-op if the size is too large the > correct behaviour? It doesn't seem a very likely behaviour for the > actual hardware. > > Should we be reporting an error via some register bits? Or should we > be masking or truncating the size field instead the size down to > something smaller? > > BenH or Cedric, do you know how the hardware actually behaves here? 8bytes reads and writes are supported by the ECCB, which interfaces with the OPB master, which interfaces with the LPC HC. The HW is bit complex in that area. There are a few legacy devices. skiboot only uses 1 and 4 bytes accesses if I am correct so we didn't fall into the trap. I think using a data[8] would be more appropriate. It would make the pnv_lpc_do_eccb() routine a little more complex. I tried to rewrite it to have a common one with the P9 LPC model but could not find a common pattern. P9 is purely MMIO based. Something on the TODO list. 8 bytes accesses will then fail anyhow because all MemoryRegionOps have a max_access_size = 4. Thanks, C. > >> --- >> hw/ppc/pnv_lpc.c | 4 >> 1 file changed, 4 insertions(+) >> >> diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c >> index d7721320a2..f5e5bd4053 100644 >> --- a/hw/ppc/pnv_lpc.c >> +++ b/hw/ppc/pnv_lpc.c >> @@ -158,6 +158,10 @@ static void pnv_lpc_do_eccb(PnvLpcController *lpc, >> uint64_t cmd) >> uint8_t data[4]; >> bool success; >> >> +if (sz > sizeof(data)) { >> +return; >> +} >> + >> if (cmd & ECCB_CTL_READ) { >> success = opb_read(lpc, opb_addr, data, sz); >> if (success) { >
[Qemu-devel] [PATCH] migration/colo.c: Fix compilation issue when disable replication
This compilation issue will occur when user use --disable-replication to config Qemu. Reported-by: Thomas Huth Signed-off-by: Zhang Chen --- migration/colo.c | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/migration/colo.c b/migration/colo.c index 956ac236b7..b81e6ec5bb 100644 --- a/migration/colo.c +++ b/migration/colo.c @@ -59,6 +59,8 @@ static bool colo_runstate_is_stopped(void) static void secondary_vm_do_failover(void) { +/* COLO needs enable block-replication */ +#ifdef CONFIG_REPLICATION int old_state; MigrationIncomingState *mis = migration_incoming_get_current(); Error *local_err = NULL; @@ -121,10 +123,14 @@ static void secondary_vm_do_failover(void) if (mis->migration_incoming_co) { qemu_coroutine_enter(mis->migration_incoming_co); } +#else +abort(); +#endif } static void primary_vm_do_failover(void) { +#ifdef CONFIG_REPLICATION MigrationState *s = migrate_get_current(); int old_state; Error *local_err = NULL; @@ -165,6 +171,9 @@ static void primary_vm_do_failover(void) /* Notify COLO thread that failover work is finished */ qemu_sem_post(>colo_exit_sem); +#else +abort(); +#endif } COLOMode get_colo_mode(void) @@ -373,6 +382,7 @@ static int colo_do_checkpoint_transaction(MigrationState *s, QIOChannelBuffer *bioc, QEMUFile *fb) { +#ifdef CONFIG_REPLICATION Error *local_err = NULL; int ret = -1; @@ -483,6 +493,9 @@ out: error_report_err(local_err); } return ret; +#else +abort(); +#endif } static void colo_compare_notify_checkpoint(Notifier *notifier, void *data) @@ -790,13 +803,16 @@ void *colo_process_incoming_thread(void *opaque) qemu_mutex_unlock_iothread(); goto out; } +#ifdef CONFIG_REPLICATION /* discard colo disk buffer */ replication_do_checkpoint_all(_err); if (local_err) { qemu_mutex_unlock_iothread(); goto out; } - +#else +abort(); +#endif /* Notify all filters of all NIC to do checkpoint */ colo_notify_filters_event(COLO_EVENT_CHECKPOINT, _err); -- 2.17.GIT
Re: [Qemu-devel] [PATCH v3] scripts/qemu-binfmt-conf.sh: add bFLT handler registration
On 21/10/2018 17:55, Max Filippov wrote: > bFLT format header doesn't have enough information to register a handler > for a specific architecture. Add switch -f / --flat that registers one > of the qemu binaries as a handler for bFLT executable images. > > Signed-off-by: Max Filippov > --- > Changes v2->v3: > - fix bFLT in the patch subject > > Changes v1->v2: > - drop unintended changes to dtc; > > scripts/qemu-binfmt-conf.sh | 32 ++-- > 1 file changed, 30 insertions(+), 2 deletions(-) BTW, I'm not sure it's the good way to do that. The script has been written with ELF in mind and no other alternative format. Perhaps we can add a format parameter, like "--format elf" (default), "--format bflt" and then take the availabled CPU and mask/magic from the list corresponding for the selected format. And then rename qemu_set_binfmts() to qemu_elf_set_binfmts(), add function qemu_bflt_set_binfmt() and call the one you you need according the format you have selected. Somehing like: FORMAT_BINFMT_MISC_SET=qemu_elf_set_binfmts ... -F|--format) shift FORMAT_BINFMT_MISC_SET=qemu_$1_set_binfmts ;; ... $CHECK $FORMAT_BINFMT_MISC_SET and then qemu_bflt_set_binfmts() { for cpu in ${qemu_target_list} ; do magic='bFLT\x00\x00\x00\x04' mask='\xff\xff\xff\xff\xff\xff\xff\xff' qemu="$QEMU_PATH/qemu-$cpu" qemu="$qemu$QEMU_SUFFIX" $BINFMT_SET done } Then with --systemd you provide only the cpu you want to generate, with --debian you use update-binfmts to select the only one to import, for /proc case we could add another parameter to only register one interpreter (--proc CPU ?) Thanks, Laurent
[Qemu-devel] [PATCH] SDL: set a hint to not bypass the window compositor
Without that, window effects in KWin get suspended as soon as any qemu-sdl window becomes visible. While the SDL default makes sense for games, it's not really suitable for QEMU. Signed-off-by: Sebastian Krzyszkowiak --- ui/sdl2.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ui/sdl2.c b/ui/sdl2.c index 2696b95c79..a10b6e3a08 100644 --- a/ui/sdl2.c +++ b/ui/sdl2.c @@ -786,6 +786,9 @@ static void sdl2_display_init(DisplayState *ds, DisplayOptions *o) SDL_GetError()); exit(1); } +#ifdef SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR /* only available since SDL 2.0.8 */ +SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); +#endif SDL_SetHint(SDL_HINT_GRAB_KEYBOARD, "1"); memset(, 0, sizeof(info)); SDL_VERSION(); -- 2.19.1
Re: [Qemu-devel] [PULL 0/6] qtest, Makefiles and shell script improvements
On 24 October 2018 at 10:52, Thomas Huth wrote: > Hi Peter, > > the following changes since commit 13399aad4fa87b2878c49d02a5d3bafa6c966ba3: > > Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2018-10-22' > into staging (2018-10-23 17:20:23 +0100) > > are available in the git repository at: > > https://gitlab.com/huth/qemu.git tags/pull-request-2018-10-24 > > for you to fetch changes up to 86583a07c4a7d55b04db5942a70d176f5299144a: > > configure: Provide option to explicitly disable AVX2 (2018-10-24 07:39:10 > +0100) > > > - Disable migration-test with TCG on s390x (since there are known problems) > - Small Makefile improvements > - More modern shell scripting changes (use $() instead of ``) > - Add a configure option to disable AVX2 > Applied, thanks. -- PMM
Re: [Qemu-devel] qemu3.0.0 use wine for the application of X86
On 24 October 2018 at 12:16, wj193102 wrote: > Hi,everybody。 > Now I have installed QEMU3.0.0. I want to launch wine by QEMU. But I can't > find qemu-runtime-i386-XXX.tar.gz and qemu-XXX-i386-wine.tar.gz on the QEMU > web page. > Please tell me how I can get them and use the wine by QEMU? Thank you very > much. I'm not sure what you think those tarballs are or why they would be on the QEMU web page? If you've installed QEMU then you should be able to run an i386 wine binary in it, like any other guest binary, but we don't provide guest binaries. We assume you already have those. PS: try something simple first, like an "ls" binary, to check your setup is working, before you try to get wine running under QEMU. PPS: do you really want i386 and not x86-64 ? thanks -- PMM
[Qemu-devel] [PULL v2 10/33] target/mips: Add a placeholder for R5900 LQ
From: Fredrik Noring Add a placeholder for LQ instruction. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 13 +++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 19a8aba..2318116 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -24420,6 +24420,11 @@ static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx) } } +static void decode_tx79_lq(CPUMIPSState *env, DisasContext *ctx) +{ +generate_exception_end(ctx, EXCP_RI);/* TODO: TX79_LQ */ +} + static void gen_tx79_sq(DisasContext *ctx, int base, int rt, int offset) { generate_exception_end(ctx, EXCP_RI);/* TODO: TX79_SQ */ @@ -26425,8 +26430,12 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) } break; case OPC_MSA: /* OPC_MDMX */ -/* MDMX: Not implemented. */ -gen_msa(env, ctx); +if (ctx->insn_flags & INSN_R5900) { +decode_tx79_lq(env, ctx);/* TX79_LQ */ +} else { +/* MDMX: Not implemented. */ +gen_msa(env, ctx); +} break; case OPC_PCREL: check_insn(ctx, ISA_MIPS32R6); -- 2.7.4
[Qemu-devel] [PULL v2 33/33] target/mips: Fix decoding of ALIGN and DALIGN instructions
From: Aleksandar Markovic Opcode for ALIGN and DALIGN must be in fact ranges of opcodes, to allow paremeter 'bp' to occupy two and three bits, respectively. Reviewed-by: Stefan Markovic Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 40 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index fa29c1e..c44a751 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -463,8 +463,10 @@ enum { OPC_WSBH = (0x02 << 6) | OPC_BSHFL, OPC_SEB = (0x10 << 6) | OPC_BSHFL, OPC_SEH = (0x18 << 6) | OPC_BSHFL, -OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp */ -OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */ +OPC_ALIGN = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */ +OPC_ALIGN_1 = (0x09 << 6) | OPC_BSHFL, +OPC_ALIGN_2 = (0x0A << 6) | OPC_BSHFL, +OPC_ALIGN_3 = (0x0B << 6) | OPC_BSHFL, OPC_BITSWAP = (0x00 << 6) | OPC_BSHFL /* 0 */ }; @@ -474,8 +476,14 @@ enum { enum { OPC_DSBH = (0x02 << 6) | OPC_DBSHFL, OPC_DSHD = (0x05 << 6) | OPC_DBSHFL, -OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */ -OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */ +OPC_DALIGN = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */ +OPC_DALIGN_1 = (0x09 << 6) | OPC_DBSHFL, +OPC_DALIGN_2 = (0x0A << 6) | OPC_DBSHFL, +OPC_DALIGN_3 = (0x0B << 6) | OPC_DBSHFL, +OPC_DALIGN_4 = (0x0C << 6) | OPC_DBSHFL, +OPC_DALIGN_5 = (0x0D << 6) | OPC_DBSHFL, +OPC_DALIGN_6 = (0x0E << 6) | OPC_DBSHFL, +OPC_DALIGN_7 = (0x0F << 6) | OPC_DBSHFL, OPC_DBITSWAP = (0x00 << 6) | OPC_DBSHFL, /* 0 */ }; @@ -23957,7 +23965,9 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) op2 = MASK_BSHFL(ctx->opcode); switch (op2) { case OPC_ALIGN: -case OPC_ALIGN_END: +case OPC_ALIGN_1: +case OPC_ALIGN_2: +case OPC_ALIGN_3: gen_align(ctx, 32, rd, rs, rt, sa & 3); break; case OPC_BITSWAP: @@ -23983,7 +23993,13 @@ static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx) op2 = MASK_DBSHFL(ctx->opcode); switch (op2) { case OPC_DALIGN: -case OPC_DALIGN_END: +case OPC_DALIGN_1: +case OPC_DALIGN_2: +case OPC_DALIGN_3: +case OPC_DALIGN_4: +case OPC_DALIGN_5: +case OPC_DALIGN_6: +case OPC_DALIGN_7: gen_align(ctx, 64, rd, rs, rt, sa & 7); break; case OPC_DBITSWAP: @@ -24843,7 +24859,9 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) op2 = MASK_BSHFL(ctx->opcode); switch (op2) { case OPC_ALIGN: -case OPC_ALIGN_END: +case OPC_ALIGN_1: +case OPC_ALIGN_2: +case OPC_ALIGN_3: case OPC_BITSWAP: check_insn(ctx, ISA_MIPS32R6); decode_opc_special3_r6(env, ctx); @@ -24869,7 +24887,13 @@ static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx) op2 = MASK_DBSHFL(ctx->opcode); switch (op2) { case OPC_DALIGN: -case OPC_DALIGN_END: +case OPC_DALIGN_1: +case OPC_DALIGN_2: +case OPC_DALIGN_3: +case OPC_DALIGN_4: +case OPC_DALIGN_5: +case OPC_DALIGN_6: +case OPC_DALIGN_7: case OPC_DBITSWAP: check_insn(ctx, ISA_MIPS32R6); decode_opc_special3_r6(env, ctx); -- 2.7.4
[Qemu-devel] [PULL v2 15/33] target/mips: Add a placeholder for R5900 MMI3 instruction subclass
From: Fredrik Noring Add a placeholder for MMI3 subclass. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 31 ++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index cc00429..1c0400c 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -24527,6 +24527,33 @@ static void decode_tx79_mmi2(CPUMIPSState *env, DisasContext *ctx) } } +static void decode_tx79_mmi3(CPUMIPSState *env, DisasContext *ctx) +{ +uint32_t opc = MASK_TX79_MMI3(ctx->opcode); + +switch (opc) { +case TX79_MMI3_PMADDUW:/* TODO: TX79_MMI3_PMADDUW */ +case TX79_MMI3_PSRAVW: /* TODO: TX79_MMI3_PSRAVW */ +case TX79_MMI3_PMTHI: /* TODO: TX79_MMI3_PMTHI */ +case TX79_MMI3_PMTLO: /* TODO: TX79_MMI3_PMTLO */ +case TX79_MMI3_PINTEH: /* TODO: TX79_MMI3_PINTEH */ +case TX79_MMI3_PMULTUW:/* TODO: TX79_MMI3_PMULTUW */ +case TX79_MMI3_PDIVUW: /* TODO: TX79_MMI3_PDIVUW */ +case TX79_MMI3_PCPYUD: /* TODO: TX79_MMI3_PCPYUD */ +case TX79_MMI3_POR:/* TODO: TX79_MMI3_POR */ +case TX79_MMI3_PNOR: /* TODO: TX79_MMI3_PNOR */ +case TX79_MMI3_PEXCH: /* TODO: TX79_MMI3_PEXCH */ +case TX79_MMI3_PCPYH: /* TODO: TX79_MMI3_PCPYH */ +case TX79_MMI3_PEXCW: /* TODO: TX79_MMI3_PEXCW */ +generate_exception_end(ctx, EXCP_RI); /* TODO: TX79_MMI_CLASS_MMI3 */ +break; +default: +MIPS_INVAL("TX79 MMI class MMI3"); +generate_exception_end(ctx, EXCP_RI); +break; +} +} + static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) { uint32_t opc = MASK_TX79_MMI(ctx->opcode); @@ -24541,6 +24568,9 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) case TX79_MMI_CLASS_MMI2: decode_tx79_mmi2(env, ctx); break; +case TX79_MMI_CLASS_MMI3: +decode_tx79_mmi3(env, ctx); +break; case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */ case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */ case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */ @@ -24554,7 +24584,6 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) case TX79_MMI_DIVU1: /* TODO: TX79_MMI_DIVU1 */ case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */ case TX79_MMI_MADDU1:/* TODO: TX79_MMI_MADDU1 */ -case TX79_MMI_CLASS_MMI3:/* TODO: TX79_MMI_CLASS_MMI3 */ case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */ case TX79_MMI_PMTHL: /* TODO: TX79_MMI_PMTHL */ case TX79_MMI_PSLLH: /* TODO: TX79_MMI_PSLLH */ -- 2.7.4
[Qemu-devel] [PULL v2 32/33] target/mips: Fix the title of translate.c
From: Aleksandar Markovic Replace MIPS32 with MIPS, since the file covers all generations of MIPS architectures. Reviewed-by: Stefan Markovic Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 6c50485..fa29c1e 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -1,5 +1,5 @@ /* - * MIPS32 emulation for qemu: main translation routines. + * MIPS emulation for QEMU - main translation routines * * Copyright (c) 2004-2005 Jocelyn Mayer * Copyright (c) 2006 Marius Groeger (FPU operations) -- 2.7.4
[Qemu-devel] [PULL v2 19/33] target/mips: Support R5900 DIV1 and DIVU1 instructions
From: Fredrik Noring Add support for DIV1 and DIVU1 instructions. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 12 +--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index d7d7145..f2aeaf4 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -4593,11 +4593,14 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, gen_load_gpr(t1, rt); if (acc != 0) { -check_dsp(ctx); +if (!(ctx->insn_flags & INSN_R5900)) { +check_dsp(ctx); +} } switch (opc) { case OPC_DIV: +case TX79_MMI_DIV1: { TCGv t2 = tcg_temp_new(); TCGv t3 = tcg_temp_new(); @@ -4619,6 +4622,7 @@ static void gen_muldiv(DisasContext *ctx, uint32_t opc, } break; case OPC_DIVU: +case TX79_MMI_DIVU1: { TCGv t2 = tcg_const_tl(0); TCGv t3 = tcg_const_tl(1); @@ -24665,6 +24669,10 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) case TX79_MMI_MULTU1: gen_mul_txx9(ctx, opc, rd, rs, rt); break; +case TX79_MMI_DIV1: +case TX79_MMI_DIVU1: +gen_muldiv(ctx, opc, 1, rs, rt); +break; case TX79_MMI_MTLO1: case TX79_MMI_MTHI1: gen_HILO(ctx, opc, 1, rs); @@ -24676,8 +24684,6 @@ static void decode_tx79_mmi(CPUMIPSState *env, DisasContext *ctx) case TX79_MMI_MADD: /* TODO: TX79_MMI_MADD */ case TX79_MMI_MADDU: /* TODO: TX79_MMI_MADDU */ case TX79_MMI_PLZCW: /* TODO: TX79_MMI_PLZCW */ -case TX79_MMI_DIV1: /* TODO: TX79_MMI_DIV1 */ -case TX79_MMI_DIVU1: /* TODO: TX79_MMI_DIVU1 */ case TX79_MMI_MADD1: /* TODO: TX79_MMI_MADD1 */ case TX79_MMI_MADDU1:/* TODO: TX79_MMI_MADDU1 */ case TX79_MMI_PMFHL: /* TODO: TX79_MMI_PMFHL */ -- 2.7.4
[Qemu-devel] [PULL v2 07/33] target/mips: Define R5900 MMI2 opcode constants
From: Fredrik Noring Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 48 1 file changed, 48 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index e233b87..bd51443 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2275,6 +2275,54 @@ enum { TX79_MMI1_QFSRV = (0x1B << 6) | TX79_MMI_CLASS_MMI1, }; +/* + * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI2: + * + * 312610 6 5 0 + * ++--+++ + * | MMI | |function| MMI2 | + * ++--+++ + * + * function bits 7..6 + * bits | 0 | 1 | 2 | 3 + *10..8 | 00 | 01 | 10 | 11 + * ---+---+---+---+--- + *0 000 | PMADDW| * | PSLLVW| PSRLVW + *1 001 | PMSUBW| * | * | * + *2 010 | PMFHI | PMFLO | PINTH | * + *3 011 | PMULTW| PDIVW | PCPYLD| * + *4 100 | PMADDH| PHMADH| PAND | PXOR + *5 101 | PMSUBH| PHMSBH| * | * + *6 110 | * | * | PEXEH | PREVH + *7 111 | PMULTH| PDIVBW| PEXEW | PROT3W + */ + +#define MASK_TX79_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) +enum { +TX79_MMI2_PMADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PSLLVW = (0x02 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PSRLVW = (0x03 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PMSUBW = (0x04 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PMFHI = (0x08 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PMFLO = (0x09 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PINTH = (0x0A << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PMULTW = (0x0C << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PDIVW = (0x0D << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PCPYLD = (0x0E << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PMADDH = (0x10 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PHMADH = (0x11 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PAND = (0x12 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PXOR = (0x13 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PMSUBH = (0x14 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PHMSBH = (0x15 << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PEXEH = (0x1A << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PREVH = (0x1B << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PMULTH = (0x1C << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PDIVBW = (0x1D << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PEXEW = (0x1E << 6) | TX79_MMI_CLASS_MMI2, +TX79_MMI2_PROT3W = (0x1F << 6) | TX79_MMI_CLASS_MMI2, +}; + /* global register indices */ static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; -- 2.7.4
[Qemu-devel] [Bug 1796520] Re: autogen crashes on qemu-sh4-user after 61dedf2af7
** Tags added: linux-user sh4 -- You received this bug notification because you are a member of qemu- devel-ml, which is subscribed to QEMU. https://bugs.launchpad.net/bugs/1796520 Title: autogen crashes on qemu-sh4-user after 61dedf2af7 Status in QEMU: New Bug description: Running "autogen --help" crashes on qemu-sh4-user with: (sid-sh4-sbuild)root@nofan:/# autogen --help Unhandled trap: 0x180 pc=0xf64dd2de sr=0x pr=0xf63b9c74 fpscr=0x0008 spc=0x ssr=0x gbr=0xf61102a8 vbr=0x sgr=0x dbr=0x delayed_pc=0xf64dd2a0 fpul=0x0003 r0=0xf6fc1320 r1=0x r2=0x5dc4 r3=0xf67bfb50 r4=0xf6fc1230 r5=0xf6fc141c r6=0x03ff r7=0x r8=0x0004 r9=0xf63e20bc r10=0xf6fc141c r11=0xf63e28f0 r12=0xf63e2258 r13=0xf63eae1c r14=0x0804 r15=0xf6fc1220 r16=0x r17=0x r18=0x r19=0x r20=0x r21=0x r22=0x r23=0x (sid-sh4-sbuild)root@nofan:/# Bi-secting found this commit to be the culprit: 61dedf2af79fb5866dc7a0f972093682f2185e17 is the first bad commit commit 61dedf2af79fb5866dc7a0f972093682f2185e17 Author: Richard Henderson Date: Tue Jul 18 10:02:50 2017 -1000 target/sh4: Add missing FPSCR.PR == 0 checks Both frchg and fschg require PR == 0, otherwise undefined_operation. Reviewed-by: Aurelien Jarno Signed-off-by: Richard Henderson Message-Id: <20170718200255.31647-26-...@twiddle.net> Signed-off-by: Aurelien Jarno :04 04 980d79b69ae712f23a1e4c56983e97a843153b4a 1024c109f506c7ad57367c63bc8bbbc8a7a36cd7 M target Reverting 61dedf2af79fb5866dc7a0f972093682f2185e17 fixes the problem for me. To manage notifications about this bug go to: https://bugs.launchpad.net/qemu/+bug/1796520/+subscriptions
[Qemu-devel] [PULL v2 23/33] tests/tcg/mips: Add tests for R5900 three-operand MULTU
From: Fredrik Noring Add a test for MULTU. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- tests/tcg/mips/mipsr5900/Makefile | 1 + tests/tcg/mips/mipsr5900/multu.c | 39 +++ 2 files changed, 40 insertions(+) create mode 100644 tests/tcg/mips/mipsr5900/multu.c diff --git a/tests/tcg/mips/mipsr5900/Makefile b/tests/tcg/mips/mipsr5900/Makefile index 6757168..b3ddb9a 100644 --- a/tests/tcg/mips/mipsr5900/Makefile +++ b/tests/tcg/mips/mipsr5900/Makefile @@ -9,6 +9,7 @@ CC = $(CROSS)gcc CFLAGS = -Wall -mabi=32 -march=r5900 -static TESTCASES = mult.tst +TESTCASES += multu.tst all: $(TESTCASES) diff --git a/tests/tcg/mips/mipsr5900/multu.c b/tests/tcg/mips/mipsr5900/multu.c new file mode 100644 index 000..3a59675 --- /dev/null +++ b/tests/tcg/mips/mipsr5900/multu.c @@ -0,0 +1,39 @@ +/* + * Test R5900-specific three-operand MULTU. + */ + +#include +#include +#include + +static uint64_t multu(uint32_t rs, uint32_t rt) +{ +uint32_t rd, lo, hi; +uint64_t r; + +__asm__ __volatile__ ( +"multu %0, %3, %4\n" +"mflo %1\n" +"mfhi %2\n" +: "=r" (rd), "=r" (lo), "=r" (hi) +: "r" (rs), "r" (rt)); +r = ((uint64_t)hi << 32) | (uint32_t)lo; + +assert((uint64_t)rs * rt == r); +assert(rd == lo); + +return r; +} + +int main() +{ +assert(multu(17, 19) == 323); +assert(multu(3, 1) == 7776600043); +assert(multu(12207031, 305175781) == 3725290219116211); + +assert(multu(0x8000U, 0x7FFF) == 0x3FFF8000); +assert(multu(0x8000U, 0x8000U) == 0x4000); +assert(multu(0xU, 0xU) == 0xFFFE0001U); + +return 0; +} -- 2.7.4
[Qemu-devel] [PULL v2 27/33] tests/tcg/mips: Add tests for R5900 MTLO1 and MTHI1
From: Fredrik Noring Add a test for MTLO1 and MTHI1. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- tests/tcg/mips/mipsr5900/Makefile | 1 + tests/tcg/mips/mipsr5900/mtlohi1.c | 40 ++ 2 files changed, 41 insertions(+) create mode 100644 tests/tcg/mips/mipsr5900/mtlohi1.c diff --git a/tests/tcg/mips/mipsr5900/Makefile b/tests/tcg/mips/mipsr5900/Makefile index fd8ee6b..287c248 100644 --- a/tests/tcg/mips/mipsr5900/Makefile +++ b/tests/tcg/mips/mipsr5900/Makefile @@ -9,6 +9,7 @@ CC = $(CROSS)gcc CFLAGS = -Wall -mabi=32 -march=r5900 -static TESTCASES = mflohi1.tst +TESTCASES += mtlohi1.tst TESTCASES += mult.tst TESTCASES += multu.tst diff --git a/tests/tcg/mips/mipsr5900/mtlohi1.c b/tests/tcg/mips/mipsr5900/mtlohi1.c new file mode 100644 index 000..7f3e728 --- /dev/null +++ b/tests/tcg/mips/mipsr5900/mtlohi1.c @@ -0,0 +1,40 @@ +/* + * Test R5900-specific MTLO1 and MTHI1. + */ + +#include +#include +#include + +int main() +{ +int32_t tlo = 12207031, thi = 305175781; +int32_t tlo1 = 32452867, thi1 = 49979687; +int32_t flo, fhi, flo1, fhi1; + +/* Test both LO/HI and LO1/HI1 to verify separation. */ +__asm__ __volatile__ ( +"mtlo %4\n" +"mthi %5\n" +"mtlo1 %6\n" +"mthi1 %7\n" +"move %0, $0\n" +"move %1, $0\n" +"move %2, $0\n" +"move %3, $0\n" +"mflo %0\n" +"mfhi %1\n" +"mflo1 %2\n" +"mfhi1 %3\n" +: "=r" (flo), "=r" (fhi), + "=r" (flo1), "=r" (fhi1) +: "r" (tlo), "r" (thi), + "r" (tlo1), "r" (thi1)); + +assert(flo == 12207031); +assert(fhi == 305175781); +assert(flo1 == 32452867); +assert(fhi1 == 49979687); + +return 0; +} -- 2.7.4
[Qemu-devel] [PULL v2 28/33] tests/tcg/mips: Add tests for R5900 DIV1
From: Fredrik Noring Add a test for DIV1. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- tests/tcg/mips/mipsr5900/Makefile | 3 +- tests/tcg/mips/mipsr5900/div1.c | 73 +++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tests/tcg/mips/mipsr5900/div1.c diff --git a/tests/tcg/mips/mipsr5900/Makefile b/tests/tcg/mips/mipsr5900/Makefile index 287c248..757eb83 100644 --- a/tests/tcg/mips/mipsr5900/Makefile +++ b/tests/tcg/mips/mipsr5900/Makefile @@ -8,7 +8,8 @@ SIM_FLAGS=-cpu R5900 CC = $(CROSS)gcc CFLAGS = -Wall -mabi=32 -march=r5900 -static -TESTCASES = mflohi1.tst +TESTCASES = div1.tst +TESTCASES += mflohi1.tst TESTCASES += mtlohi1.tst TESTCASES += mult.tst TESTCASES += multu.tst diff --git a/tests/tcg/mips/mipsr5900/div1.c b/tests/tcg/mips/mipsr5900/div1.c new file mode 100644 index 000..83dafa0 --- /dev/null +++ b/tests/tcg/mips/mipsr5900/div1.c @@ -0,0 +1,73 @@ +/* + * Test R5900-specific DIV1. + */ + +#include +#include +#include + +struct quotient_remainder { int32_t quotient, remainder; }; + +static struct quotient_remainder div1(int32_t rs, int32_t rt) +{ +int32_t lo, hi; + +__asm__ __volatile__ ( +"div1 $0, %2, %3\n" +"mflo1 %0\n" +"mfhi1 %1\n" +: "=r" (lo), "=r" (hi) +: "r" (rs), "r" (rt)); + +assert(rs / rt == lo); +assert(rs % rt == hi); + +return (struct quotient_remainder) { .quotient = lo, .remainder = hi }; +} + +static void verify_div1(int32_t rs, int32_t rt, +int32_t expected_quotient, +int32_t expected_remainder) +{ +struct quotient_remainder qr = div1(rs, rt); + +assert(qr.quotient == expected_quotient); +assert(qr.remainder == expected_remainder); +} + +static void verify_div1_negations(int32_t rs, int32_t rt, + int32_t expected_quotient, + int32_t expected_remainder) +{ +verify_div1(rs, rt, expected_quotient, expected_remainder); +verify_div1(rs, -rt, -expected_quotient, expected_remainder); +verify_div1(-rs, rt, -expected_quotient, -expected_remainder); +verify_div1(-rs, -rt, expected_quotient, -expected_remainder); +} + +int main() +{ +verify_div1_negations(0, 1, 0, 0); +verify_div1_negations(1, 1, 1, 0); +verify_div1_negations(1, 2, 0, 1); +verify_div1_negations(17, 19, 0, 17); +verify_div1_negations(19, 17, 1, 2); +verify_div1_negations(3, 101, 770, 3); + +verify_div1(-0x8000, 1, -0x8000, 0); + +/* + * Supplementary explanation from the Toshiba TX System RISC TX79 Core + * Architecture manual, A-38 and B-7, https://wiki.qemu.org/File:C790.pdf + * + * Normally, when 0x8000 (-2147483648) the signed minimum value is + * divided by 0x (-1), the operation will result in an overflow. + * However, in this instruction an overflow exception doesn't occur and + * the result will be as follows: + * + * Quotient is 0x8000 (-2147483648), and remainder is 0x (0). + */ +verify_div1(-0x8000, -1, -0x8000, 0); + +return 0; +} -- 2.7.4
[Qemu-devel] [PULL v2 31/33] linux-user/mips: Recognize the R5900 CPU model
From: Fredrik Noring This kind of ELF for the R5900 relies on an IEEE 754-1985 compliant FPU. The R5900 FPU hardware is noncompliant and it is therefore emulated in software by the Linux kernel. QEMU emulates a compliant FPU accordingly. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- linux-user/mips/target_elf.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h index fa5d30b..a98c9bd 100644 --- a/linux-user/mips/target_elf.h +++ b/linux-user/mips/target_elf.h @@ -12,6 +12,9 @@ static inline const char *cpu_get_model(uint32_t eflags) if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) { return "mips32r6-generic"; } +if ((eflags & EF_MIPS_MACH) == EF_MIPS_MACH_5900) { +return "R5900"; +} return "24Kf"; } #endif -- 2.7.4
[Qemu-devel] [PULL v2 20/33] target/mips: Support R5900 MOVN, MOVZ and PREF instructions from MIPS IV
From: Fredrik Noring The R5900 is taken to be MIPS III with certain modifications. From MIPS IV it implements the instructions MOVN, MOVZ and PREF. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index f2aeaf4..551928d 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -23552,7 +23552,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_MOVN: /* Conditional move */ case OPC_MOVZ: check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | - INSN_LOONGSON2E | INSN_LOONGSON2F); + INSN_LOONGSON2E | INSN_LOONGSON2F | INSN_R5900); gen_cond_move(ctx, op1, rd, rs, rt); break; case OPC_MFHI: /* Move from HI/LO */ @@ -26388,7 +26388,8 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_PREF: check_insn_opc_removed(ctx, ISA_MIPS32R6); -check_insn(ctx, ISA_MIPS4 | ISA_MIPS32); +check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 | + INSN_R5900); /* Treat as NOP. */ break; -- 2.7.4
[Qemu-devel] [PULL v2 21/33] target/mips: Make R5900 DMULT[U], DDIV[U], LL[D] and SC[D] user only
From: Fredrik Noring The Linux kernel traps certain reserved instruction exceptions to emulate the corresponding instructions. QEMU plays the role of the kernel in user mode, so those traps are emulated by accepting the instructions. This change adds the function check_insn_opc_user_only to signal a reserved instruction exception for flagged CPUs in QEMU system mode. The MIPS III instructions DMULT[U], DDIV[U], LL[D] and SC[D] are not implemented in R5900 hardware. They are trapped and emulated by the Linux kernel and, accordingly, therefore QEMU user only instructions. Reviewed-by: Aleksandar Markovic Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 23 ++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/target/mips/translate.c b/target/mips/translate.c index 551928d..6c50485 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2872,6 +2872,21 @@ static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags) } } +/* + * The Linux kernel traps certain reserved instruction exceptions to + * emulate the corresponding instructions. QEMU is the kernel in user + * mode, so those traps are emulated by accepting the instructions. + * + * A reserved instruction exception is generated for flagged CPUs if + * QEMU runs in system mode. + */ +static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags) +{ +#ifndef CONFIG_USER_ONLY +check_insn_opc_removed(ctx, flags); +#endif +} + /* This code generates a "reserved instruction" exception if the CPU does not support 64-bit paired-single (PS) floating point data type */ static inline void check_ps(DisasContext *ctx) @@ -23595,6 +23610,7 @@ static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx) case OPC_DDIV: case OPC_DDIVU: check_insn(ctx, ISA_MIPS3); +check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_muldiv(ctx, op1, 0, rs, rt); break; @@ -26350,6 +26366,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) break; case OPC_LL: /* Load and stores */ check_insn(ctx, ISA_MIPS2); +check_insn_opc_user_only(ctx, INSN_R5900); /* Fallthrough */ case OPC_LWL: case OPC_LWR: @@ -26375,6 +26392,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SC: check_insn(ctx, ISA_MIPS2); check_insn_opc_removed(ctx, ISA_MIPS32R6); +check_insn_opc_user_only(ctx, INSN_R5900); gen_st_cond(ctx, op, rt, rs, imm); break; case OPC_CACHE: @@ -26641,9 +26659,11 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) #if defined(TARGET_MIPS64) /* MIPS64 opcodes */ +case OPC_LLD: +check_insn_opc_user_only(ctx, INSN_R5900); +/* fall through */ case OPC_LDL: case OPC_LDR: -case OPC_LLD: check_insn_opc_removed(ctx, ISA_MIPS32R6); /* fall through */ case OPC_LWU: @@ -26664,6 +26684,7 @@ static void decode_opc(CPUMIPSState *env, DisasContext *ctx) case OPC_SCD: check_insn_opc_removed(ctx, ISA_MIPS32R6); check_insn(ctx, ISA_MIPS3); +check_insn_opc_user_only(ctx, INSN_R5900); check_mips_64(ctx); gen_st_cond(ctx, op, rt, rs, imm); break; -- 2.7.4
[Qemu-devel] [PULL v2 25/33] tests/tcg/mips: Add tests for R5900 three-operand MULTU1
From: Fredrik Noring Add a test for MULTU1. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- tests/tcg/mips/mipsr5900/multu.c | 43 +--- 1 file changed, 36 insertions(+), 7 deletions(-) diff --git a/tests/tcg/mips/mipsr5900/multu.c b/tests/tcg/mips/mipsr5900/multu.c index 3a59675..f043904 100644 --- a/tests/tcg/mips/mipsr5900/multu.c +++ b/tests/tcg/mips/mipsr5900/multu.c @@ -1,5 +1,5 @@ /* - * Test R5900-specific three-operand MULTU. + * Test R5900-specific three-operand MULTU and MULTU1. */ #include @@ -25,15 +25,44 @@ static uint64_t multu(uint32_t rs, uint32_t rt) return r; } +static uint64_t multu1(uint32_t rs, uint32_t rt) +{ +uint32_t rd, lo, hi; +uint64_t r; + +__asm__ __volatile__ ( +"multu1 %0, %3, %4\n" +"mflo1 %1\n" +"mfhi1 %2\n" +: "=r" (rd), "=r" (lo), "=r" (hi) +: "r" (rs), "r" (rt)); +r = ((uint64_t)hi << 32) | (uint32_t)lo; + +assert((uint64_t)rs * rt == r); +assert(rd == lo); + +return r; +} + +static uint64_t multu_variants(uint32_t rs, uint32_t rt) +{ +uint64_t rd = multu(rs, rt); +uint64_t rd1 = multu1(rs, rt); + +assert(rd == rd1); + +return rd; +} + int main() { -assert(multu(17, 19) == 323); -assert(multu(3, 1) == 7776600043); -assert(multu(12207031, 305175781) == 3725290219116211); +assert(multu_variants(17, 19) == 323); +assert(multu_variants(3, 1) == 7776600043); +assert(multu_variants(12207031, 305175781) == 3725290219116211); -assert(multu(0x8000U, 0x7FFF) == 0x3FFF8000); -assert(multu(0x8000U, 0x8000U) == 0x4000); -assert(multu(0xU, 0xU) == 0xFFFE0001U); +assert(multu_variants(0x8000U, 0x7FFF) == 0x3FFF8000); +assert(multu_variants(0x8000U, 0x8000U) == 0x4000); +assert(multu_variants(0xU, 0xU) == 0xFFFE0001U); return 0; } -- 2.7.4
[Qemu-devel] [PULL v2 05/33] target/mips: Define R5900 MMI0 opcode constants
From: Fredrik Noring Add definition of MI0 opcodes. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- target/mips/translate.c | 51 + 1 file changed, 51 insertions(+) diff --git a/target/mips/translate.c b/target/mips/translate.c index ae98817..242f2df 100644 --- a/target/mips/translate.c +++ b/target/mips/translate.c @@ -2180,6 +2180,57 @@ enum { TX79_MMI_PSRAW = 0x3F | TX79_CLASS_MMI, }; +/* + * TX79 Multimedia Instructions with opcode field = MMI and bits 5..0 = MMI0: + * + * 312610 6 5 0 + * ++--+++ + * | MMI | |function| MMI0 | + * ++--+++ + * + * function bits 7..6 + * bits | 0 | 1 | 2 | 3 + *10..8 | 00 | 01 | 10 | 11 + * ---+---+---+---+--- + *0 000 | PADDW | PSUBW | PCGTW | PMAXW + *1 001 | PADDH | PSUBH | PCGTH | PMAXH + *2 010 | PADDB | PSUBB | PCGTB | * + *3 011 | * | * | * | * + *4 100 | PADDSW| PSUBSW| PEXTLW| PPACW + *5 101 | PADDSH| PSUBSH| PEXTLH| PPACH + *6 110 | PADDSB| PSUBSB| PEXTLB| PPACB + *7 111 | * | * | PEXT5 | PPAC5 + */ + +#define MASK_TX79_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF)) +enum { +TX79_MMI0_PADDW = (0x00 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PSUBW = (0x01 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PCGTW = (0x02 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PMAXW = (0x03 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PADDH = (0x04 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PSUBH = (0x05 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PCGTH = (0x06 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PMAXH = (0x07 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PADDB = (0x08 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PSUBB = (0x09 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PCGTB = (0x0A << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PADDSW = (0x10 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PSUBSW = (0x11 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PEXTLW = (0x12 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PPACW = (0x13 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PADDSH = (0x14 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PSUBSH = (0x15 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PEXTLH = (0x16 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PPACH = (0x17 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PADDSB = (0x18 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PSUBSB = (0x19 << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PEXTLB = (0x1A << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PPACB = (0x1B << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PEXT5 = (0x1E << 6) | TX79_MMI_CLASS_MMI0, +TX79_MMI0_PPAC5 = (0x1F << 6) | TX79_MMI_CLASS_MMI0, +}; + /* global register indices */ static TCGv cpu_gpr[32], cpu_PC; static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC]; -- 2.7.4
[Qemu-devel] [PULL v2 22/33] tests/tcg/mips: Add tests for R5900 three-operand MULT
From: Fredrik Noring Add a test for MULT. Reviewed-by: Aleksandar Markovic Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- tests/tcg/mips/mipsr5900/Makefile | 25 + tests/tcg/mips/mipsr5900/mult.c | 47 +++ 2 files changed, 72 insertions(+) create mode 100644 tests/tcg/mips/mipsr5900/Makefile create mode 100644 tests/tcg/mips/mipsr5900/mult.c diff --git a/tests/tcg/mips/mipsr5900/Makefile b/tests/tcg/mips/mipsr5900/Makefile new file mode 100644 index 000..6757168 --- /dev/null +++ b/tests/tcg/mips/mipsr5900/Makefile @@ -0,0 +1,25 @@ +-include ../../config-host.mak + +CROSS=mipsr5900el-unknown-linux-gnu- + +SIM=qemu-mipsel +SIM_FLAGS=-cpu R5900 + +CC = $(CROSS)gcc +CFLAGS = -Wall -mabi=32 -march=r5900 -static + +TESTCASES = mult.tst + +all: $(TESTCASES) + +%.tst: %.c + $(CC) $(CFLAGS) $< -o $@ + +check: $(TESTCASES) + @for case in $(TESTCASES); do \ +echo $(SIM) $(SIM_FLAGS) ./$$case;\ +$(SIM) $(SIM_FLAGS) ./$$case; \ + done + +clean: + $(RM) -rf $(TESTCASES) diff --git a/tests/tcg/mips/mipsr5900/mult.c b/tests/tcg/mips/mipsr5900/mult.c new file mode 100644 index 000..2c0c16d --- /dev/null +++ b/tests/tcg/mips/mipsr5900/mult.c @@ -0,0 +1,47 @@ +/* + * Test R5900-specific three-operand MULT. + */ + +#include +#include +#include + +static int64_t mult(int32_t rs, int32_t rt) +{ +int32_t rd, lo, hi; +int64_t r; + +__asm__ __volatile__ ( +"mult %0, %3, %4\n" +"mflo %1\n" +"mfhi %2\n" +: "=r" (rd), "=r" (lo), "=r" (hi) +: "r" (rs), "r" (rt)); +r = ((int64_t)hi << 32) | (uint32_t)lo; + +assert((int64_t)rs * rt == r); +assert(rd == lo); + +return r; +} + +static void verify_mult_negations(int32_t rs, int32_t rt, int64_t expected) +{ +assert(mult(rs, rt) == expected); +assert(mult(-rs, rt) == -expected); +assert(mult(rs, -rt) == -expected); +assert(mult(-rs, -rt) == expected); +} + +int main() +{ +verify_mult_negations(17, 19, 323); +verify_mult_negations(3, 1, 7776600043); +verify_mult_negations(12207031, 305175781, 3725290219116211); + +assert(mult(-0x8000, 0x7FFF) == -0x3FFF8000); +assert(mult(-0x8000, -0x7FFF) == 0x3FFF8000); +assert(mult(-0x8000, -0x8000) == 0x4000); + +return 0; +} -- 2.7.4
[Qemu-devel] [PULL v2 30/33] target/mips: Define the R5900 CPU
From: Fredrik Noring The primary purpose of this change is to support programs compiled by GCC for the R5900 target and thereby run R5900 Linux distributions, for example Gentoo. GCC in version 7.3, by itself, by inspection of the GCC source code and inspection of the generated machine code, for the R5900 target, only emits two instructions that are specific to the R5900: the three- operand MULT and MULTU. GCC and libc also emit certain MIPS III instructions that are not part of the R5900 ISA. They are normally trapped and emulated by the Linux kernel, and therefore need to be treated accordingly by QEMU. A program compiled by GCC is taken to mean source code compiled by GCC under the restrictions above. One can, with the apparent limitations, with a bit of effort obtain a fully functioning operating system such as R5900 Gentoo. Strictly speaking, programs need not be compiled by GCC to make use of this change. Instructions and other facilities of the R5900 not implemented by this change are intended to signal provisional exceptions. One such example is the FPU that is not compliant with IEEE 754-1985 in system mode. It is therefore provisionally disabled. In user space the FPU is trapped and emulated by IEEE 754-1985 compliant software in the kernel, and this is handled accordingly by QEMU. Another example is the 93 multimedia instructions specific to the R5900 that generate provisional reserved instruction exception signals. One of the benefits of running a Linux distribution under QEMU is that programs can be compiled with a native compiler, where the host and target are the same, as opposed to a cross-compiler, where they are not the same. This is especially important in cases where the target hardware does not have the resources to run a native compiler. Problems with cross-compilation are often related to host and target differences in integer sizes, pointer sizes, endianness, machine code, ABI, etc. Sometimes cross-compilation is not even supported by the build script for a given package. One effective way to avoid those problems is to replace the cross-compiler with a native compiler. This change of compilation methods does not resolve the inherent problems with cross-compilation. The native compiler naturally replaces the cross-compiler, because one typically uses one or the other, and preferably the native compiler when the circumstances admit this. The native compiler is also a good test case for the R5900 QEMU user mode. Additionally, Gentoo is well- known for compiling and installing its packages from sources. This change has been tested with Gentoo compiled for R5900, including native compilation of several packages under QEMU. Reviewed-by: Aleksandar Markovic Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Fredrik Noring Signed-off-by: Aleksandar Markovic --- target/mips/translate_init.inc.c | 59 1 file changed, 59 insertions(+) diff --git a/target/mips/translate_init.inc.c b/target/mips/translate_init.inc.c index acab097..85da4a2 100644 --- a/target/mips/translate_init.inc.c +++ b/target/mips/translate_init.inc.c @@ -411,6 +411,65 @@ const mips_def_t mips_defs[] = .mmu_type = MMU_TYPE_R4000, }, { +/* + * The Toshiba TX System RISC TX79 Core Architecture manual + * + * https://wiki.qemu.org/File:C790.pdf + * + * describes the C790 processor that is a follow-up to the R5900. + * There are a few notable differences in that the R5900 FPU + * + * - is not IEEE 754-1985 compliant, + * - does not implement double format, and + * - its machine code is nonstandard. + */ +.name = "R5900", +.CP0_PRid = 0x2E00, +/* No L2 cache, icache size 32k, dcache size 32k, uncached coherency. */ +.CP0_Config0 = (0x3 << 9) | (0x3 << 6) | (0x2 << CP0C0_K0), +.CP0_Status_rw_bitmask = 0xF4C79C1F, +#ifdef CONFIG_USER_ONLY +/* + * R5900 hardware traps to the Linux kernel for IEEE 754-1985 and LL/SC + * emulation. For user only, QEMU is the kernel, so we emulate the traps + * by simply emulating the instructions directly. + * + * Note: Config1 is only used internally, the R5900 has only Config0. + */ +.CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU), +.CP0_LLAddr_rw_bitmask = 0x, +.CP0_LLAddr_shift = 4, +.CP1_fcr0 = (0x38 << FCR0_PRID) | (0x0 << FCR0_REV), +.CP1_fcr31 = 0, +.CP1_fcr31_rw_bitmask = 0x0183, +#else +/* + * The R5900 COP1 FPU implements single-precision floating-point + * operations but is not entirely IEEE 754-1985 compatible. In + * particular, + * + * - NaN (not a number) and +/- infinities are not supported; + * - exception mechanisms are not fully supported; + * - denormalized numbers are not supported; +