diff --git a/arch/loongarch/kernel/efi.c b/arch/loongarch/kernel/efi.c index 459583c985be0f91105689049713458489d0a076..76845a225e975f904712b6adb9667622bfec6efc 100644 --- a/arch/loongarch/kernel/efi.c +++ b/arch/loongarch/kernel/efi.c @@ -328,6 +328,18 @@ void __init efi_init(void) if (efi_memmap_init_early(&data) < 0) panic("Unable to map EFI memory map.\n"); + /* + * Reserve the physical memory region occupied by the EFI + * memory map table (header + descriptors). This is crucial + * for kdump, as the kdump kernel relies on this original + * memmap passed by the bootloader. Without reservation, + * this region could be overwritten by the primary kernel. + * Also, set the EFI_PRESERVE_BS_REGIONS flag to indicate that + * critical boot services data regions like this are preserved. + */ + memblock_reserve((phys_addr_t)boot_memmap, sizeof(*tbl) + data.size); + set_bit(EFI_PRESERVE_BS_REGIONS, &efi.flags); + early_memunmap(tbl, sizeof(*tbl)); } } diff --git a/arch/loongarch/kvm/intc/extioi.c b/arch/loongarch/kvm/intc/extioi.c index 440bd8733daeb351ea2ea2d4825b2519ec55aed7..227348d5fe72e1472ba9d06e44ecd722633997fc 100644 --- a/arch/loongarch/kvm/intc/extioi.c +++ b/arch/loongarch/kvm/intc/extioi.c @@ -244,11 +244,10 @@ static int loongarch_extioi_writew(struct kvm_vcpu *vcpu, * update irq when isr is set. */ data = s->enable.reg_u32[index] & ~old_data & s->isr.reg_u32[index]; - index = index << 2; for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - extioi_enable_irq(vcpu, s, index + i, mask, 1); + extioi_enable_irq(vcpu, s, index * 4 + i, mask, 1); } /* * 0: disable irq. @@ -258,7 +257,7 @@ static int loongarch_extioi_writew(struct kvm_vcpu *vcpu, for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - extioi_enable_irq(vcpu, s, index, mask, 0); + extioi_enable_irq(vcpu, s, index * 4 + i, mask, 0); } break; case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END: @@ -331,11 +330,10 @@ static int loongarch_extioi_writel(struct kvm_vcpu *vcpu, * update irq when isr is set. */ data = s->enable.reg_u64[index] & ~old_data & s->isr.reg_u64[index]; - index = index << 3; for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - extioi_enable_irq(vcpu, s, index + i, mask, 1); + extioi_enable_irq(vcpu, s, index * 8 + i, mask, 1); } /* * 0: disable irq. @@ -345,7 +343,7 @@ static int loongarch_extioi_writel(struct kvm_vcpu *vcpu, for (i = 0; i < sizeof(data); i++) { u8 mask = (data >> (i * 8)) & 0xff; - extioi_enable_irq(vcpu, s, index, mask, 0); + extioi_enable_irq(vcpu, s, index * 8 + i, mask, 0); } break; case EXTIOI_BOUNCE_START ... EXTIOI_BOUNCE_END: diff --git a/drivers/gpio/gpio-loongson-64bit.c b/drivers/gpio/gpio-loongson-64bit.c index f916a5ae0290a19f75586fe57e61bd657929c9f9..7363736830e1b80e81f7400814debcd08b01f776 100644 --- a/drivers/gpio/gpio-loongson-64bit.c +++ b/drivers/gpio/gpio-loongson-64bit.c @@ -334,10 +334,10 @@ static const struct loongson_gpio_chip_data loongson_gpio_ls7a2000_data0 = { static const struct loongson_gpio_chip_data loongson_gpio_ls7a2000_data1 = { .label = "ls7a2000_gpio", - .mode = BYTE_CTRL_MODE, - .conf_offset = 0x84, - .in_offset = 0x88, - .out_offset = 0x80, + .mode = BIT_CTRL_MODE, + .conf_offset = 0x4, + .in_offset = 0x8, + .out_offset = 0x0, }; static const struct loongson_gpio_chip_data loongson_gpio_ls3a6000_data = { diff --git a/drivers/iommu/loongarch_iommu.c b/drivers/iommu/loongarch_iommu.c index 63d0d2ce3c0ea15740a59d9dd3820d7da77bce59..6905f2d3ddb8f52cd01d04960a260ea8dd36cd04 100644 --- a/drivers/iommu/loongarch_iommu.c +++ b/drivers/iommu/loongarch_iommu.c @@ -596,13 +596,14 @@ static struct iommu_domain *la_iommu_domain_alloc(unsigned int type) switch (type) { case IOMMU_DOMAIN_BLOCKED: + case IOMMU_DOMAIN_IDENTITY: case IOMMU_DOMAIN_UNMANAGED: info = alloc_dom_info(); if (info == NULL) - return NULL; + return ERR_PTR(-ENOMEM); break; default: - return NULL; + return ERR_PTR(-EINVAL); } return &info->domain; } @@ -756,7 +757,6 @@ static void la_iommu_remove_device(struct device *dev) { struct la_iommu_dev_data *dev_data; - iommu_group_remove_device(dev); dev_data = dev->archdata.iommu; dev->archdata.iommu = NULL; kfree(dev_data); @@ -846,11 +846,13 @@ static int la_iommu_attach_dev(struct iommu_domain *domain, struct device *dev) struct iommu_info *info; unsigned short bdf; - if (domain != NULL && domain->type == IOMMU_DOMAIN_BLOCKED) - return 0; - la_iommu_detach_dev(dev); + if (domain != NULL && + (domain->type == IOMMU_DOMAIN_IDENTITY || + domain->type == IOMMU_DOMAIN_BLOCKED)) + return 0; + if (domain == NULL) return 0; @@ -1186,6 +1188,11 @@ static void la_domain_set_plaform_dma_ops(struct device *dev) */ } +static int la_iommu_def_domain_type(struct device *dev) +{ + return IOMMU_DOMAIN_IDENTITY; +} + const struct iommu_ops la_iommu_ops = { .capable = la_iommu_capable, .domain_alloc = la_iommu_domain_alloc, @@ -1193,6 +1200,7 @@ const struct iommu_ops la_iommu_ops = { .release_device = la_iommu_remove_device, .device_group = la_iommu_device_group, .pgsize_bitmap = LA_IOMMU_PGSIZE, + .def_domain_type = la_iommu_def_domain_type, .owner = THIS_MODULE, .set_platform_dma_ops = la_domain_set_plaform_dma_ops, .default_domain_ops = &(const struct iommu_domain_ops) {