// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE-BSD-3-Clause file.
//
// Copyright © 2019 Intel Corporation
//
// Copyright (C) 2020-2021 Alibaba Cloud. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause

//! Virtio queue API for backend device drivers to access virtio queues.

#![deny(missing_docs)]

use std::fmt::{self, Debug, Display};
use std::num::Wrapping;
use std::ops::{Deref, DerefMut};
use std::sync::atomic::Ordering;

use log::error;
use vm_memory::{GuestMemory, GuestMemoryError, VolatileMemoryError};

pub use self::chain::{DescriptorChain, DescriptorChainRwIter};
pub use self::descriptor::{Descriptor, VirtqUsedElem};
pub use self::descriptor_utils::{Reader, Writer};
pub use self::queue::{AvailIter, Queue};
pub use self::queue_sync::QueueSync;
pub use self::state::QueueState;

pub mod defs;
#[cfg(any(test, feature = "test-utils"))]
pub mod mock;

mod chain;
mod descriptor;
mod descriptor_utils;
mod queue;
mod queue_sync;
mod state;

/// Virtio Queue related errors.
#[derive(Debug)]
pub enum Error {
    /// Address overflow.
    AddressOverflow,
    /// Failed to access guest memory.
    GuestMemory(GuestMemoryError),
    /// Invalid indirect descriptor.
    InvalidIndirectDescriptor,
    /// Invalid indirect descriptor table.
    InvalidIndirectDescriptorTable,
    /// Invalid descriptor chain.
    InvalidChain,
    /// Invalid descriptor index.
    InvalidDescriptorIndex,
    /// Invalid max_size.
    InvalidMaxSize,
    /// Invalid Queue Size.
    InvalidSize,
    /// Invalid alignment of descriptor table address.
    InvalidDescTableAlign,
    /// Invalid alignment of available ring address.
    InvalidAvailRingAlign,
    /// Invalid alignment of used ring address.
    InvalidUsedRingAlign,
    /// Invalid available ring index.
    InvalidAvailRingIndex,
    /// The queue is not ready for operation.
    QueueNotReady,
    /// Volatile memory error.
    VolatileMemoryError(VolatileMemoryError),
    /// The combined length of all the buffers in a `DescriptorChain` would overflow.
    DescriptorChainOverflow,
    /// No memory region for this address range.
    FindMemoryRegion,
    /// Descriptor guest memory error.
    GuestMemoryError(GuestMemoryError),
    /// DescriptorChain split is out of bounds.
    SplitOutOfBounds(usize),
}

impl Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        use self::Error::*;

        match self {
            AddressOverflow => write!(f, "address overflow"),
            GuestMemory(_) => write!(f, "error accessing guest memory"),
            InvalidChain => write!(f, "invalid descriptor chain"),
            InvalidIndirectDescriptor => write!(f, "invalid indirect descriptor"),
            InvalidIndirectDescriptorTable => write!(f, "invalid indirect descriptor table"),
            InvalidDescriptorIndex => write!(f, "invalid descriptor index"),
            InvalidMaxSize => write!(f, "invalid queue maximum size"),
            InvalidSize => write!(f, "invalid queue size"),
            InvalidDescTableAlign => write!(
                f,
                "virtio queue descriptor table breaks alignment constraints"
            ),
            InvalidAvailRingAlign => write!(
                f,
                "virtio queue available ring breaks alignment constraints"
            ),
            InvalidUsedRingAlign => {
                write!(f, "virtio queue used ring breaks alignment constraints")
            }
            InvalidAvailRingIndex => write!(
                f,
                "invalid available ring index (more descriptors to process than queue size)"
            ),
            QueueNotReady => write!(f, "trying to process requests on a queue that's not ready"),
            VolatileMemoryError(e) => write!(f, "volatile memory error: {e}"),
            DescriptorChainOverflow => write!(
                f,
                "the combined length of all the buffers in a `DescriptorChain` would overflow"
            ),
            FindMemoryRegion => write!(f, "no memory region for this address range"),
            GuestMemoryError(e) => write!(f, "descriptor guest memory error: {e}"),
            SplitOutOfBounds(off) => write!(f, "`DescriptorChain` split is out of bounds: {off}"),
        }
    }
}

impl std::error::Error for Error {}

/// Trait for objects returned by `QueueT::lock()`.
pub trait QueueGuard<'a> {
    /// Type for guard returned by `Self::lock()`.
    type G: DerefMut<Target = Queue>;
}

/// Trait to access and manipulate a virtio queue.
///
/// To optimize for performance, different implementations of the `QueueT` trait may be
/// provided for single-threaded context and multi-threaded context.
///
/// Using Higher-Rank Trait Bounds (HRTBs) to effectively define an associated type that has a
/// lifetime parameter, without tagging the `QueueT` trait with a lifetime as well.
pub trait QueueT: for<'a> QueueGuard<'a> {
    /// Construct an empty virtio queue state object with the given `max_size`.
    ///
    /// Returns an error if `max_size` is invalid.
    fn new(max_size: u16) -> Result<Self, Error>
    where
        Self: Sized;

    /// Check whether the queue configuration is valid.
    fn is_valid<M: GuestMemory>(&self, mem: &M) -> bool;

    /// Reset the queue to the initial state.
    fn reset(&mut self);

    /// Get an exclusive reference to the underlying `Queue` object.
    ///
    /// Logically this method will acquire the underlying lock protecting the `Queue` Object.
    /// The lock will be released when the returned object gets dropped.
    fn lock(&mut self) -> <Self as QueueGuard>::G;

    /// Get the maximum size of the virtio queue.
    fn max_size(&self) -> u16;

    /// Get the actual size configured by the guest.
    fn size(&self) -> u16;

    /// Configure the queue size for the virtio queue.
    fn set_size(&mut self, size: u16);

    /// Check whether the queue is ready to be processed.
    fn ready(&self) -> bool;

    /// Configure the queue to `ready for processing` state.
    fn set_ready(&mut self, ready: bool);

    /// Set the descriptor table address for the queue.
    ///
    /// The descriptor table address is 64-bit, the corresponding part will be updated if 'low'
    /// and/or `high` is `Some` and valid.
    fn set_desc_table_address(&mut self, low: Option<u32>, high: Option<u32>);

    /// Set the available ring address for the queue.
    ///
    /// The available ring address is 64-bit, the corresponding part will be updated if 'low'
    /// and/or `high` is `Some` and valid.
    fn set_avail_ring_address(&mut self, low: Option<u32>, high: Option<u32>);

    /// Set the used ring address for the queue.
    ///
    /// The used ring address is 64-bit, the corresponding part will be updated if 'low'
    /// and/or `high` is `Some` and valid.
    fn set_used_ring_address(&mut self, low: Option<u32>, high: Option<u32>);

    /// Enable/disable the VIRTIO_F_RING_EVENT_IDX feature for interrupt coalescing.
    fn set_event_idx(&mut self, enabled: bool);

    /// Read the `idx` field from the available ring.
    ///
    /// # Panics
    ///
    /// Panics if order is Release or AcqRel.
    fn avail_idx<M>(&self, mem: &M, order: Ordering) -> Result<Wrapping<u16>, Error>
    where
        M: GuestMemory + ?Sized;

    /// Read the `idx` field from the used ring.
    ///
    /// # Panics
    ///
    /// Panics if order is Release or AcqRel.
    fn used_idx<M: GuestMemory>(&self, mem: &M, order: Ordering) -> Result<Wrapping<u16>, Error>;

    /// Put a used descriptor head into the used ring.
    fn add_used<M: GuestMemory>(&mut self, mem: &M, head_index: u16, len: u32)
        -> Result<(), Error>;

    /// Enable notification events from the guest driver.
    ///
    /// Return true if one or more descriptors can be consumed from the available ring after
    /// notifications were enabled (and thus it's possible there will be no corresponding
    /// notification).
    fn enable_notification<M: GuestMemory>(&mut self, mem: &M) -> Result<bool, Error>;

    /// Disable notification events from the guest driver.
    fn disable_notification<M: GuestMemory>(&mut self, mem: &M) -> Result<(), Error>;

    /// Check whether a notification to the guest is needed.
    ///
    /// Please note this method has side effects: once it returns `true`, it considers the
    /// driver will actually be notified, remember the associated index in the used ring, and
    /// won't return `true` again until the driver updates `used_event` and/or the notification
    /// conditions hold once more.
    fn needs_notification<M: GuestMemory>(&mut self, mem: &M) -> Result<bool, Error>;

    /// Return the index of the next entry in the available ring.
    fn next_avail(&self) -> u16;

    /// Set the index of the next entry in the available ring.
    fn set_next_avail(&mut self, next_avail: u16);

    /// Return the index for the next descriptor in the used ring.
    fn next_used(&self) -> u16;

    /// Set the index for the next descriptor in the used ring.
    fn set_next_used(&mut self, next_used: u16);

    /// Return the address of the descriptor table.
    fn desc_table(&self) -> u64;

    /// Return the address of the available ring.
    fn avail_ring(&self) -> u64;

    /// Return the address of the used ring.
    fn used_ring(&self) -> u64;

    /// Checks whether `VIRTIO_F_RING_EVENT_IDX` is negotiated.
    ///
    /// This getter is only returning the correct value after the device passes the `FEATURES_OK`
    /// status.
    fn event_idx_enabled(&self) -> bool;

    /// Pop and return the next available descriptor chain, or `None` when there are no more
    /// descriptor chains available.
    ///
    /// This enables the consumption of available descriptor chains in a "one at a time"
    /// manner, without having to hold a borrow after the method returns.
    fn pop_descriptor_chain<M>(&mut self, mem: M) -> Option<DescriptorChain<M>>
    where
        M: Clone + Deref,
        M::Target: GuestMemory;
}

/// Trait to access and manipulate a Virtio queue that's known to be exclusively accessed
/// by a single execution thread.
pub trait QueueOwnedT: QueueT {
    /// Get a consuming iterator over all available descriptor chain heads offered by the driver.
    ///
    /// # Arguments
    /// * `mem` - the `GuestMemory` object that can be used to access the queue buffers.
    fn iter<M>(&mut self, mem: M) -> Result<AvailIter<'_, M>, Error>
    where
        M: Deref,
        M::Target: GuestMemory;

    /// Undo the last advancement of the next available index field by decrementing its
    /// value by one.
    fn go_to_previous_position(&mut self);
}
