Skip to content

Commit

Permalink
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/mst/vhost

Pull virtio updates from Michael Tsirkin:
 "A small number of improvements all over the place:

   - vdpa/octeon support for multiple interrupts

   - virtio-pci support for error recovery

   - vp_vdpa support for notification with data

   - vhost/net fix to set num_buffers for spec compliance

   - virtio-mem now works with kdump on s390

  And small cleanups all over the place"

* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: (23 commits)
  virtio_blk: Add support for transport error recovery
  virtio_pci: Add support for PCIe Function Level Reset
  vhost/net: Set num_buffers for virtio 1.0
  vdpa/octeon_ep: read vendor-specific PCI capability
  virtio-pci: define type and header for PCI vendor data
  vdpa/octeon_ep: handle device config change events
  vdpa/octeon_ep: enable support for multiple interrupts per device
  vdpa: solidrun: Replace deprecated PCI functions
  s390/kdump: virtio-mem kdump support (CONFIG_PROC_VMCORE_DEVICE_RAM)
  virtio-mem: support CONFIG_PROC_VMCORE_DEVICE_RAM
  virtio-mem: remember usable region size
  virtio-mem: mark device ready before registering callbacks in kdump mode
  fs/proc/vmcore: introduce PROC_VMCORE_DEVICE_RAM to detect device RAM ranges in 2nd kernel
  fs/proc/vmcore: factor out freeing a list of vmcore ranges
  fs/proc/vmcore: factor out allocating a vmcore range and adding it to a list
  fs/proc/vmcore: move vmcore definitions out of kcore.h
  fs/proc/vmcore: prefix all pr_* with "vmcore:"
  fs/proc/vmcore: disallow vmcore modifications while the vmcore is open
  fs/proc/vmcore: replace vmcoredd_mutex by vmcore_mutex
  fs/proc/vmcore: convert vmcore_cb_lock into vmcore_mutex
  ...
  • Loading branch information
torvalds committed Jan 27, 2025
2 parents 805ba04 + 5820a3b commit deee748
Show file tree
Hide file tree
Showing 20 changed files with 735 additions and 193 deletions.
1 change: 1 addition & 0 deletions arch/s390/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ config S390
select MODULES_USE_ELF_RELA
select NEED_DMA_MAP_STATE if PCI
select NEED_PER_CPU_EMBED_FIRST_CHUNK
select NEED_PROC_VMCORE_DEVICE_RAM if PROC_VMCORE
select NEED_SG_DMA_LENGTH if PCI
select OLD_SIGACTION
select OLD_SIGSUSPEND3
Expand Down
39 changes: 31 additions & 8 deletions arch/s390/kernel/crash_dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,19 @@ static int get_mem_chunk_cnt(void)
return cnt;
}

static void fill_ptload(Elf64_Phdr *phdr, unsigned long paddr,
unsigned long vaddr, unsigned long size)
{
phdr->p_type = PT_LOAD;
phdr->p_vaddr = vaddr;
phdr->p_offset = paddr;
phdr->p_paddr = paddr;
phdr->p_filesz = size;
phdr->p_memsz = size;
phdr->p_flags = PF_R | PF_W | PF_X;
phdr->p_align = PAGE_SIZE;
}

/*
* Initialize ELF loads (new kernel)
*/
Expand All @@ -518,14 +531,8 @@ static void loads_init(Elf64_Phdr *phdr, bool os_info_has_vm)
if (os_info_has_vm)
old_identity_base = os_info_old_value(OS_INFO_IDENTITY_BASE);
for_each_physmem_range(idx, &oldmem_type, &start, &end) {
phdr->p_type = PT_LOAD;
phdr->p_vaddr = old_identity_base + start;
phdr->p_offset = start;
phdr->p_paddr = start;
phdr->p_filesz = end - start;
phdr->p_memsz = end - start;
phdr->p_flags = PF_R | PF_W | PF_X;
phdr->p_align = PAGE_SIZE;
fill_ptload(phdr, start, old_identity_base + start,
end - start);
phdr++;
}
}
Expand All @@ -535,6 +542,22 @@ static bool os_info_has_vm(void)
return os_info_old_value(OS_INFO_KASLR_OFFSET);
}

#ifdef CONFIG_PROC_VMCORE_DEVICE_RAM
/*
* Fill PT_LOAD for a physical memory range owned by a device and detected by
* its device driver.
*/
void elfcorehdr_fill_device_ram_ptload_elf64(Elf64_Phdr *phdr,
unsigned long long paddr, unsigned long long size)
{
unsigned long old_identity_base = 0;

if (os_info_has_vm())
old_identity_base = os_info_old_value(OS_INFO_IDENTITY_BASE);
fill_ptload(phdr, paddr, old_identity_base + paddr, size);
}
#endif

/*
* Prepare PT_LOAD type program header for kernel image region
*/
Expand Down
28 changes: 25 additions & 3 deletions drivers/block/virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -1579,8 +1579,7 @@ static void virtblk_remove(struct virtio_device *vdev)
put_disk(vblk->disk);
}

#ifdef CONFIG_PM_SLEEP
static int virtblk_freeze(struct virtio_device *vdev)
static int virtblk_freeze_priv(struct virtio_device *vdev)
{
struct virtio_blk *vblk = vdev->priv;
struct request_queue *q = vblk->disk->queue;
Expand All @@ -1602,7 +1601,7 @@ static int virtblk_freeze(struct virtio_device *vdev)
return 0;
}

static int virtblk_restore(struct virtio_device *vdev)
static int virtblk_restore_priv(struct virtio_device *vdev)
{
struct virtio_blk *vblk = vdev->priv;
int ret;
Expand All @@ -1616,8 +1615,29 @@ static int virtblk_restore(struct virtio_device *vdev)

return 0;
}

#ifdef CONFIG_PM_SLEEP
static int virtblk_freeze(struct virtio_device *vdev)
{
return virtblk_freeze_priv(vdev);
}

static int virtblk_restore(struct virtio_device *vdev)
{
return virtblk_restore_priv(vdev);
}
#endif

static int virtblk_reset_prepare(struct virtio_device *vdev)
{
return virtblk_freeze_priv(vdev);
}

static int virtblk_reset_done(struct virtio_device *vdev)
{
return virtblk_restore_priv(vdev);
}

static const struct virtio_device_id id_table[] = {
{ VIRTIO_ID_BLOCK, VIRTIO_DEV_ANY_ID },
{ 0 },
Expand Down Expand Up @@ -1653,6 +1673,8 @@ static struct virtio_driver virtio_blk = {
.freeze = virtblk_freeze,
.restore = virtblk_restore,
#endif
.reset_prepare = virtblk_reset_prepare,
.reset_done = virtblk_reset_done,
};

static int __init virtio_blk_init(void)
Expand Down
32 changes: 26 additions & 6 deletions drivers/vdpa/octeon_ep/octep_vdpa.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <linux/pci_regs.h>
#include <linux/vdpa.h>
#include <linux/virtio_pci_modern.h>
#include <uapi/linux/virtio_crypto.h>
#include <uapi/linux/virtio_net.h>
#include <uapi/linux/virtio_blk.h>
#include <uapi/linux/virtio_config.h>
Expand All @@ -29,12 +30,12 @@
#define OCTEP_EPF_RINFO(x) (0x000209f0 | ((x) << 25))
#define OCTEP_VF_MBOX_DATA(x) (0x00010210 | ((x) << 17))
#define OCTEP_PF_MBOX_DATA(x) (0x00022000 | ((x) << 4))

#define OCTEP_EPF_RINFO_RPVF(val) (((val) >> 32) & 0xF)
#define OCTEP_EPF_RINFO_NVFS(val) (((val) >> 48) & 0x7F)
#define OCTEP_VF_IN_CTRL(x) (0x00010000 | ((x) << 17))
#define OCTEP_VF_IN_CTRL_RPVF(val) (((val) >> 48) & 0xF)

#define OCTEP_FW_READY_SIGNATURE0 0xFEEDFEED
#define OCTEP_FW_READY_SIGNATURE1 0x3355ffaa
#define OCTEP_MAX_CB_INTR 8

enum octep_vdpa_dev_status {
OCTEP_VDPA_DEV_STATUS_INVALID,
Expand All @@ -48,9 +49,26 @@ enum octep_vdpa_dev_status {
struct octep_vring_info {
struct vdpa_callback cb;
void __iomem *notify_addr;
u32 __iomem *cb_notify_addr;
void __iomem *cb_notify_addr;
phys_addr_t notify_pa;
char msix_name[256];
};

enum octep_pci_vndr_cfg_type {
OCTEP_PCI_VNDR_CFG_TYPE_VIRTIO_ID,
OCTEP_PCI_VNDR_CFG_TYPE_MAX,
};

struct octep_pci_vndr_data {
struct virtio_pci_vndr_data hdr;
u8 id;
u8 bar;
union {
u64 data;
struct {
u32 offset;
u32 length;
};
};
};

struct octep_hw {
Expand All @@ -68,7 +86,9 @@ struct octep_hw {
u64 features;
u16 nr_vring;
u32 config_size;
int irq;
int nb_irqs;
int *irqs;
u8 dev_id;
};

u8 octep_hw_get_status(struct octep_hw *oct_hw);
Expand Down
38 changes: 35 additions & 3 deletions drivers/vdpa/octeon_ep/octep_vdpa_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* Copyright (C) 2024 Marvell. */

#include <linux/iopoll.h>
#include <linux/build_bug.h>

#include "octep_vdpa.h"

Expand Down Expand Up @@ -358,7 +359,14 @@ u16 octep_get_vq_size(struct octep_hw *oct_hw)

static u32 octep_get_config_size(struct octep_hw *oct_hw)
{
return sizeof(struct virtio_net_config);
switch (oct_hw->dev_id) {
case VIRTIO_ID_NET:
return sizeof(struct virtio_net_config);
case VIRTIO_ID_CRYPTO:
return sizeof(struct virtio_crypto_config);
default:
return 0;
}
}

static void __iomem *octep_get_cap_addr(struct octep_hw *oct_hw, struct virtio_pci_cap *cap)
Expand Down Expand Up @@ -416,8 +424,25 @@ static int octep_pci_signature_verify(struct octep_hw *oct_hw)
return 0;
}

static void octep_vndr_data_process(struct octep_hw *oct_hw,
struct octep_pci_vndr_data *vndr_data)
{
BUILD_BUG_ON(sizeof(struct octep_pci_vndr_data) % 4 != 0);

switch (vndr_data->id) {
case OCTEP_PCI_VNDR_CFG_TYPE_VIRTIO_ID:
oct_hw->dev_id = (u8)vndr_data->data;
break;
default:
dev_err(&oct_hw->pdev->dev, "Invalid vendor data id %u\n",
vndr_data->id);
break;
}
}

int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev)
{
struct octep_pci_vndr_data vndr_data;
struct octep_mbox __iomem *mbox;
struct device *dev = &pdev->dev;
struct virtio_pci_cap cap;
Expand Down Expand Up @@ -466,6 +491,15 @@ int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev)
case VIRTIO_PCI_CAP_ISR_CFG:
oct_hw->isr = octep_get_cap_addr(oct_hw, &cap);
break;
case VIRTIO_PCI_CAP_VENDOR_CFG:
octep_pci_caps_read(oct_hw, &vndr_data, sizeof(vndr_data), pos);
if (vndr_data.hdr.vendor_id != PCI_VENDOR_ID_CAVIUM) {
dev_err(dev, "Invalid vendor data\n");
return -EINVAL;
}

octep_vndr_data_process(oct_hw, &vndr_data);
break;
}

pos = cap.cap_next;
Expand Down Expand Up @@ -495,8 +529,6 @@ int octep_hw_caps_read(struct octep_hw *oct_hw, struct pci_dev *pdev)
if (!oct_hw->vqs)
return -ENOMEM;

oct_hw->irq = -1;

dev_info(&pdev->dev, "Device features : %llx\n", oct_hw->features);
dev_info(&pdev->dev, "Maximum queues : %u\n", oct_hw->nr_vring);

Expand Down
Loading

0 comments on commit deee748

Please sign in to comment.