Char/Misc driver fixes for 5.9-rc3
Here are some small char and misc and other driver subsystem fixes for 5.9-rc3. The majority of these are tiny habanalabs driver fixes, but also in here are: - speakup build fixes now that it is out of staging and got exposed to more build systems all of a sudden - mei driver fix All of these have been in linux-next for a while with no reported issues. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCX0Zmbw8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+yk7DwCg1v16Ow/27oZZN/z2Wu40vRo3pJIAoJqz2ay/ PsrcjZIO15cEarTy1kEq =3RZb -----END PGP SIGNATURE----- Merge tag 'char-misc-5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc Pull char/misc driver fixes from Greg KH: "Here are some small char and misc and other driver subsystem fixes for 5.9-rc3. The majority of these are tiny habanalabs driver fixes, but also in here are: - speakup build fixes now that it is out of staging and got exposed to more build systems all of a sudden - mei driver fix All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-5.9-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: habanalabs: correctly report inbound pci region cfg error habanalabs: check correct vmalloc return code habanalabs: validate FW file size habanalabs: fix incorrect check on failed workqueue create habanalabs: set max power according to card type habanalabs: proper handling of alloc size in coresight habanalabs: set clock gating according to mask habanalabs: verify user input in cs_ioctl_signal_wait habanalabs: Fix a loop in gaudi_extract_ecc_info() habanalabs: Fix memory corruption in debugfs habanalabs: validate packet id during CB parse habanalabs: Validate user address before mapping habanalabs: unmap PCI bars upon iATU failure mei: hdcp: fix mei_hdcp_verify_mprime() input parameter speakup: only build serialio when ISA is enabled speakup: Fix wait_for_xmitr for ttyio case
This commit is contained in:
commit
27563ab6ef
|
@ -42,6 +42,11 @@ config SPEAKUP
|
|||
one of the listed synthesizers, you should say n.
|
||||
|
||||
if SPEAKUP
|
||||
|
||||
config SPEAKUP_SERIALIO
|
||||
def_bool y
|
||||
depends on ISA || COMPILE_TEST
|
||||
|
||||
config SPEAKUP_SYNTH_ACNTSA
|
||||
tristate "Accent SA synthesizer support"
|
||||
help
|
||||
|
@ -52,7 +57,7 @@ config SPEAKUP_SYNTH_ACNTSA
|
|||
|
||||
config SPEAKUP_SYNTH_ACNTPC
|
||||
tristate "Accent PC synthesizer support"
|
||||
depends on ISA || COMPILE_TEST
|
||||
depends on SPEAKUP_SERIALIO
|
||||
help
|
||||
This is the Speakup driver for the accent pc
|
||||
synthesizer. You can say y to build it into the kernel,
|
||||
|
@ -104,7 +109,7 @@ config SPEAKUP_SYNTH_DECEXT
|
|||
|
||||
config SPEAKUP_SYNTH_DECPC
|
||||
depends on m
|
||||
depends on ISA || COMPILE_TEST
|
||||
depends on SPEAKUP_SERIALIO
|
||||
tristate "DECtalk PC (big ISA card) synthesizer support"
|
||||
help
|
||||
|
||||
|
@ -127,7 +132,7 @@ config SPEAKUP_SYNTH_DECPC
|
|||
|
||||
config SPEAKUP_SYNTH_DTLK
|
||||
tristate "DoubleTalk PC synthesizer support"
|
||||
depends on ISA || COMPILE_TEST
|
||||
depends on SPEAKUP_SERIALIO
|
||||
help
|
||||
|
||||
This is the Speakup driver for the internal DoubleTalk
|
||||
|
@ -138,7 +143,7 @@ config SPEAKUP_SYNTH_DTLK
|
|||
|
||||
config SPEAKUP_SYNTH_KEYPC
|
||||
tristate "Keynote Gold PC synthesizer support"
|
||||
depends on ISA || COMPILE_TEST
|
||||
depends on SPEAKUP_SERIALIO
|
||||
help
|
||||
|
||||
This is the Speakup driver for the Keynote Gold
|
||||
|
|
|
@ -25,8 +25,8 @@ speakup-y := \
|
|||
keyhelp.o \
|
||||
kobjects.o \
|
||||
selection.o \
|
||||
serialio.o \
|
||||
spk_ttyio.o \
|
||||
synth.o \
|
||||
thread.o \
|
||||
varhandlers.o
|
||||
speakup-$(CONFIG_SPEAKUP_SERIALIO) += serialio.o
|
||||
|
|
|
@ -32,6 +32,7 @@ static void spk_serial_tiocmset(unsigned int set, unsigned int clear);
|
|||
static unsigned char spk_serial_in(void);
|
||||
static unsigned char spk_serial_in_nowait(void);
|
||||
static void spk_serial_flush_buffer(void);
|
||||
static int spk_serial_wait_for_xmitr(struct spk_synth *in_synth);
|
||||
|
||||
struct spk_io_ops spk_serial_io_ops = {
|
||||
.synth_out = spk_serial_out,
|
||||
|
@ -40,6 +41,7 @@ struct spk_io_ops spk_serial_io_ops = {
|
|||
.synth_in = spk_serial_in,
|
||||
.synth_in_nowait = spk_serial_in_nowait,
|
||||
.flush_buffer = spk_serial_flush_buffer,
|
||||
.wait_for_xmitr = spk_serial_wait_for_xmitr,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(spk_serial_io_ops);
|
||||
|
||||
|
@ -211,7 +213,7 @@ void spk_stop_serial_interrupt(void)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(spk_stop_serial_interrupt);
|
||||
|
||||
int spk_wait_for_xmitr(struct spk_synth *in_synth)
|
||||
static int spk_serial_wait_for_xmitr(struct spk_synth *in_synth)
|
||||
{
|
||||
int tmout = SPK_XMITR_TIMEOUT;
|
||||
|
||||
|
@ -280,7 +282,7 @@ static void spk_serial_flush_buffer(void)
|
|||
|
||||
static int spk_serial_out(struct spk_synth *in_synth, const char ch)
|
||||
{
|
||||
if (in_synth->alive && spk_wait_for_xmitr(in_synth)) {
|
||||
if (in_synth->alive && spk_serial_wait_for_xmitr(in_synth)) {
|
||||
outb_p(ch, speakup_info.port_tts);
|
||||
return 1;
|
||||
}
|
||||
|
@ -295,7 +297,7 @@ const char *spk_serial_synth_immediate(struct spk_synth *synth,
|
|||
while ((ch = *buff)) {
|
||||
if (ch == '\n')
|
||||
ch = synth->procspeech;
|
||||
if (spk_wait_for_xmitr(synth))
|
||||
if (spk_serial_wait_for_xmitr(synth))
|
||||
outb(ch, speakup_info.port_tts);
|
||||
else
|
||||
return buff;
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
|
||||
const struct old_serial_port *spk_serial_init(int index);
|
||||
void spk_stop_serial_interrupt(void);
|
||||
int spk_wait_for_xmitr(struct spk_synth *in_synth);
|
||||
void spk_serial_release(void);
|
||||
void spk_ttyio_release(void);
|
||||
void spk_ttyio_register_ldisc(void);
|
||||
|
|
|
@ -116,6 +116,7 @@ static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear);
|
|||
static unsigned char spk_ttyio_in(void);
|
||||
static unsigned char spk_ttyio_in_nowait(void);
|
||||
static void spk_ttyio_flush_buffer(void);
|
||||
static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth);
|
||||
|
||||
struct spk_io_ops spk_ttyio_ops = {
|
||||
.synth_out = spk_ttyio_out,
|
||||
|
@ -125,6 +126,7 @@ struct spk_io_ops spk_ttyio_ops = {
|
|||
.synth_in = spk_ttyio_in,
|
||||
.synth_in_nowait = spk_ttyio_in_nowait,
|
||||
.flush_buffer = spk_ttyio_flush_buffer,
|
||||
.wait_for_xmitr = spk_ttyio_wait_for_xmitr,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(spk_ttyio_ops);
|
||||
|
||||
|
@ -286,6 +288,11 @@ static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear)
|
|||
mutex_unlock(&speakup_tty_mutex);
|
||||
}
|
||||
|
||||
static int spk_ttyio_wait_for_xmitr(struct spk_synth *in_synth)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned char ttyio_in(int timeout)
|
||||
{
|
||||
struct spk_ldisc_data *ldisc_data = speakup_tty->disc_data;
|
||||
|
|
|
@ -158,6 +158,7 @@ struct spk_io_ops {
|
|||
unsigned char (*synth_in)(void);
|
||||
unsigned char (*synth_in_nowait)(void);
|
||||
void (*flush_buffer)(void);
|
||||
int (*wait_for_xmitr)(struct spk_synth *synth);
|
||||
};
|
||||
|
||||
struct spk_synth {
|
||||
|
|
|
@ -159,7 +159,7 @@ int spk_synth_is_alive_restart(struct spk_synth *synth)
|
|||
{
|
||||
if (synth->alive)
|
||||
return 1;
|
||||
if (spk_wait_for_xmitr(synth) > 0) {
|
||||
if (synth->io_ops->wait_for_xmitr(synth) > 0) {
|
||||
/* restart */
|
||||
synth->alive = 1;
|
||||
synth_printf("%s", synth->init);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/genalloc.h>
|
||||
|
||||
static void cb_fini(struct hl_device *hdev, struct hl_cb *cb)
|
||||
|
@ -300,7 +301,7 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma)
|
|||
struct hl_device *hdev = hpriv->hdev;
|
||||
struct hl_cb *cb;
|
||||
phys_addr_t address;
|
||||
u32 handle;
|
||||
u32 handle, user_cb_size;
|
||||
int rc;
|
||||
|
||||
handle = vma->vm_pgoff;
|
||||
|
@ -314,7 +315,8 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma)
|
|||
}
|
||||
|
||||
/* Validation check */
|
||||
if ((vma->vm_end - vma->vm_start) != ALIGN(cb->size, PAGE_SIZE)) {
|
||||
user_cb_size = vma->vm_end - vma->vm_start;
|
||||
if (user_cb_size != ALIGN(cb->size, PAGE_SIZE)) {
|
||||
dev_err(hdev->dev,
|
||||
"CB mmap failed, mmap size 0x%lx != 0x%x cb size\n",
|
||||
vma->vm_end - vma->vm_start, cb->size);
|
||||
|
@ -322,6 +324,16 @@ int hl_cb_mmap(struct hl_fpriv *hpriv, struct vm_area_struct *vma)
|
|||
goto put_cb;
|
||||
}
|
||||
|
||||
if (!access_ok((void __user *) (uintptr_t) vma->vm_start,
|
||||
user_cb_size)) {
|
||||
dev_err(hdev->dev,
|
||||
"user pointer is invalid - 0x%lx\n",
|
||||
vma->vm_start);
|
||||
|
||||
rc = -EINVAL;
|
||||
goto put_cb;
|
||||
}
|
||||
|
||||
spin_lock(&cb->lock);
|
||||
|
||||
if (cb->mmap) {
|
||||
|
|
|
@ -808,6 +808,14 @@ static int cs_ioctl_signal_wait(struct hl_fpriv *hpriv, enum hl_cs_type cs_type,
|
|||
|
||||
/* currently it is guaranteed to have only one chunk */
|
||||
chunk = &cs_chunk_array[0];
|
||||
|
||||
if (chunk->queue_index >= hdev->asic_prop.max_queues) {
|
||||
dev_err(hdev->dev, "Queue index %d is invalid\n",
|
||||
chunk->queue_index);
|
||||
rc = -EINVAL;
|
||||
goto free_cs_chunk_array;
|
||||
}
|
||||
|
||||
q_idx = chunk->queue_index;
|
||||
hw_queue_prop = &hdev->asic_prop.hw_queues_props[q_idx];
|
||||
q_type = hw_queue_prop->type;
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
static struct dentry *hl_debug_root;
|
||||
|
||||
static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
|
||||
u8 i2c_reg, u32 *val)
|
||||
u8 i2c_reg, long *val)
|
||||
{
|
||||
struct armcp_packet pkt;
|
||||
int rc;
|
||||
|
@ -36,7 +36,7 @@ static int hl_debugfs_i2c_read(struct hl_device *hdev, u8 i2c_bus, u8 i2c_addr,
|
|||
pkt.i2c_reg = i2c_reg;
|
||||
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
|
||||
0, (long *) val);
|
||||
0, val);
|
||||
|
||||
if (rc)
|
||||
dev_err(hdev->dev, "Failed to read from I2C, error %d\n", rc);
|
||||
|
@ -827,7 +827,7 @@ static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
|
|||
struct hl_dbg_device_entry *entry = file_inode(f)->i_private;
|
||||
struct hl_device *hdev = entry->hdev;
|
||||
char tmp_buf[32];
|
||||
u32 val;
|
||||
long val;
|
||||
ssize_t rc;
|
||||
|
||||
if (*ppos)
|
||||
|
@ -842,7 +842,7 @@ static ssize_t hl_i2c_data_read(struct file *f, char __user *buf,
|
|||
return rc;
|
||||
}
|
||||
|
||||
sprintf(tmp_buf, "0x%02x\n", val);
|
||||
sprintf(tmp_buf, "0x%02lx\n", val);
|
||||
rc = simple_read_from_buffer(buf, count, ppos, tmp_buf,
|
||||
strlen(tmp_buf));
|
||||
|
||||
|
|
|
@ -288,7 +288,7 @@ static int device_early_init(struct hl_device *hdev)
|
|||
for (i = 0 ; i < hdev->asic_prop.completion_queues_count ; i++) {
|
||||
snprintf(workq_name, 32, "hl-free-jobs-%u", i);
|
||||
hdev->cq_wq[i] = create_singlethread_workqueue(workq_name);
|
||||
if (hdev->cq_wq == NULL) {
|
||||
if (hdev->cq_wq[i] == NULL) {
|
||||
dev_err(hdev->dev, "Failed to allocate CQ workqueue\n");
|
||||
rc = -ENOMEM;
|
||||
goto free_cq_wq;
|
||||
|
@ -1069,7 +1069,7 @@ again:
|
|||
goto out_err;
|
||||
}
|
||||
|
||||
hl_set_max_power(hdev, hdev->max_power);
|
||||
hl_set_max_power(hdev);
|
||||
} else {
|
||||
rc = hdev->asic_funcs->soft_reset_late_init(hdev);
|
||||
if (rc) {
|
||||
|
@ -1318,6 +1318,11 @@ int hl_device_init(struct hl_device *hdev, struct class *hclass)
|
|||
goto out_disabled;
|
||||
}
|
||||
|
||||
/* Need to call this again because the max power might change,
|
||||
* depending on card type for certain ASICs
|
||||
*/
|
||||
hl_set_max_power(hdev);
|
||||
|
||||
/*
|
||||
* hl_hwmon_init() must be called after device_late_init(), because only
|
||||
* there we get the information from the device about which
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <linux/io-64-nonatomic-lo-hi.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define FW_FILE_MAX_SIZE 0x1400000 /* maximum size of 20MB */
|
||||
/**
|
||||
* hl_fw_load_fw_to_device() - Load F/W code to device's memory.
|
||||
*
|
||||
|
@ -48,6 +49,14 @@ int hl_fw_load_fw_to_device(struct hl_device *hdev, const char *fw_name,
|
|||
|
||||
dev_dbg(hdev->dev, "%s firmware size == %zu\n", fw_name, fw_size);
|
||||
|
||||
if (fw_size > FW_FILE_MAX_SIZE) {
|
||||
dev_err(hdev->dev,
|
||||
"FW file size %zu exceeds maximum of %u bytes\n",
|
||||
fw_size, FW_FILE_MAX_SIZE);
|
||||
rc = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
fw_data = (const u64 *) fw->data;
|
||||
|
||||
memcpy_toio(dst, fw_data, fw_size);
|
||||
|
|
|
@ -1462,6 +1462,8 @@ struct hl_device_idle_busy_ts {
|
|||
* details.
|
||||
* @in_reset: is device in reset flow.
|
||||
* @curr_pll_profile: current PLL profile.
|
||||
* @card_type: Various ASICs have several card types. This indicates the card
|
||||
* type of the current device.
|
||||
* @cs_active_cnt: number of active command submissions on this device (active
|
||||
* means already in H/W queues)
|
||||
* @major: habanalabs kernel driver major.
|
||||
|
@ -1566,6 +1568,7 @@ struct hl_device {
|
|||
u64 clock_gating_mask;
|
||||
atomic_t in_reset;
|
||||
enum hl_pll_frequency curr_pll_profile;
|
||||
enum armcp_card_types card_type;
|
||||
int cs_active_cnt;
|
||||
u32 major;
|
||||
u32 high_pll;
|
||||
|
@ -1651,7 +1654,7 @@ struct hl_ioctl_desc {
|
|||
*
|
||||
* Return: true if the area is inside the valid range, false otherwise.
|
||||
*/
|
||||
static inline bool hl_mem_area_inside_range(u64 address, u32 size,
|
||||
static inline bool hl_mem_area_inside_range(u64 address, u64 size,
|
||||
u64 range_start_address, u64 range_end_address)
|
||||
{
|
||||
u64 end_address = address + size;
|
||||
|
@ -1858,7 +1861,7 @@ int hl_get_pwm_info(struct hl_device *hdev,
|
|||
void hl_set_pwm_info(struct hl_device *hdev, int sensor_index, u32 attr,
|
||||
long value);
|
||||
u64 hl_get_max_power(struct hl_device *hdev);
|
||||
void hl_set_max_power(struct hl_device *hdev, u64 value);
|
||||
void hl_set_max_power(struct hl_device *hdev);
|
||||
int hl_set_voltage(struct hl_device *hdev,
|
||||
int sensor_index, u32 attr, long value);
|
||||
int hl_set_current(struct hl_device *hdev,
|
||||
|
|
|
@ -66,6 +66,11 @@ static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args,
|
|||
num_pgs = (args->alloc.mem_size + (page_size - 1)) >> page_shift;
|
||||
total_size = num_pgs << page_shift;
|
||||
|
||||
if (!total_size) {
|
||||
dev_err(hdev->dev, "Cannot allocate 0 bytes\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
contiguous = args->flags & HL_MEM_CONTIGUOUS;
|
||||
|
||||
if (contiguous) {
|
||||
|
@ -93,7 +98,7 @@ static int alloc_device_memory(struct hl_ctx *ctx, struct hl_mem_in *args,
|
|||
phys_pg_pack->contiguous = contiguous;
|
||||
|
||||
phys_pg_pack->pages = kvmalloc_array(num_pgs, sizeof(u64), GFP_KERNEL);
|
||||
if (!phys_pg_pack->pages) {
|
||||
if (ZERO_OR_NULL_PTR(phys_pg_pack->pages)) {
|
||||
rc = -ENOMEM;
|
||||
goto pages_arr_err;
|
||||
}
|
||||
|
@ -683,7 +688,7 @@ static int init_phys_pg_pack_from_userptr(struct hl_ctx *ctx,
|
|||
|
||||
phys_pg_pack->pages = kvmalloc_array(total_npages, sizeof(u64),
|
||||
GFP_KERNEL);
|
||||
if (!phys_pg_pack->pages) {
|
||||
if (ZERO_OR_NULL_PTR(phys_pg_pack->pages)) {
|
||||
rc = -ENOMEM;
|
||||
goto page_pack_arr_mem_err;
|
||||
}
|
||||
|
|
|
@ -450,7 +450,7 @@ int hl_mmu_init(struct hl_device *hdev)
|
|||
hdev->mmu_shadow_hop0 = kvmalloc_array(prop->max_asid,
|
||||
prop->mmu_hop_table_size,
|
||||
GFP_KERNEL | __GFP_ZERO);
|
||||
if (!hdev->mmu_shadow_hop0) {
|
||||
if (ZERO_OR_NULL_PTR(hdev->mmu_shadow_hop0)) {
|
||||
rc = -ENOMEM;
|
||||
goto err_pool_add;
|
||||
}
|
||||
|
|
|
@ -227,7 +227,7 @@ int hl_pci_set_inbound_region(struct hl_device *hdev, u8 region,
|
|||
}
|
||||
|
||||
/* Point to the specified address */
|
||||
rc = hl_pci_iatu_write(hdev, offset + 0x14,
|
||||
rc |= hl_pci_iatu_write(hdev, offset + 0x14,
|
||||
lower_32_bits(pci_region->addr));
|
||||
rc |= hl_pci_iatu_write(hdev, offset + 0x18,
|
||||
upper_32_bits(pci_region->addr));
|
||||
|
@ -369,15 +369,17 @@ int hl_pci_init(struct hl_device *hdev)
|
|||
rc = hdev->asic_funcs->init_iatu(hdev);
|
||||
if (rc) {
|
||||
dev_err(hdev->dev, "Failed to initialize iATU\n");
|
||||
goto disable_device;
|
||||
goto unmap_pci_bars;
|
||||
}
|
||||
|
||||
rc = hl_pci_set_dma_mask(hdev);
|
||||
if (rc)
|
||||
goto disable_device;
|
||||
goto unmap_pci_bars;
|
||||
|
||||
return 0;
|
||||
|
||||
unmap_pci_bars:
|
||||
hl_pci_bars_unmap(hdev);
|
||||
disable_device:
|
||||
pci_clear_master(pdev);
|
||||
pci_disable_device(pdev);
|
||||
|
|
|
@ -81,7 +81,7 @@ u64 hl_get_max_power(struct hl_device *hdev)
|
|||
return result;
|
||||
}
|
||||
|
||||
void hl_set_max_power(struct hl_device *hdev, u64 value)
|
||||
void hl_set_max_power(struct hl_device *hdev)
|
||||
{
|
||||
struct armcp_packet pkt;
|
||||
int rc;
|
||||
|
@ -90,7 +90,7 @@ void hl_set_max_power(struct hl_device *hdev, u64 value)
|
|||
|
||||
pkt.ctl = cpu_to_le32(ARMCP_PACKET_MAX_POWER_SET <<
|
||||
ARMCP_PKT_CTL_OPCODE_SHIFT);
|
||||
pkt.value = cpu_to_le64(value);
|
||||
pkt.value = cpu_to_le64(hdev->max_power);
|
||||
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
|
||||
0, NULL);
|
||||
|
@ -316,7 +316,7 @@ static ssize_t max_power_store(struct device *dev,
|
|||
}
|
||||
|
||||
hdev->max_power = value;
|
||||
hl_set_max_power(hdev, value);
|
||||
hl_set_max_power(hdev);
|
||||
|
||||
out:
|
||||
return count;
|
||||
|
@ -422,6 +422,7 @@ int hl_sysfs_init(struct hl_device *hdev)
|
|||
hdev->pm_mng_profile = PM_AUTO;
|
||||
else
|
||||
hdev->pm_mng_profile = PM_MANUAL;
|
||||
|
||||
hdev->max_power = hdev->asic_prop.max_power_default;
|
||||
|
||||
hdev->asic_funcs->add_device_attr(hdev, &hl_dev_clks_attr_group);
|
||||
|
|
|
@ -154,6 +154,29 @@ static const u16 gaudi_packet_sizes[MAX_PACKET_ID] = {
|
|||
[PACKET_LOAD_AND_EXE] = sizeof(struct packet_load_and_exe)
|
||||
};
|
||||
|
||||
static inline bool validate_packet_id(enum packet_id id)
|
||||
{
|
||||
switch (id) {
|
||||
case PACKET_WREG_32:
|
||||
case PACKET_WREG_BULK:
|
||||
case PACKET_MSG_LONG:
|
||||
case PACKET_MSG_SHORT:
|
||||
case PACKET_CP_DMA:
|
||||
case PACKET_REPEAT:
|
||||
case PACKET_MSG_PROT:
|
||||
case PACKET_FENCE:
|
||||
case PACKET_LIN_DMA:
|
||||
case PACKET_NOP:
|
||||
case PACKET_STOP:
|
||||
case PACKET_ARB_POINT:
|
||||
case PACKET_WAIT:
|
||||
case PACKET_LOAD_AND_EXE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static const char * const
|
||||
gaudi_tpc_interrupts_cause[GAUDI_NUM_OF_TPC_INTR_CAUSE] = {
|
||||
"tpc_address_exceed_slm",
|
||||
|
@ -433,7 +456,7 @@ static int gaudi_get_fixed_properties(struct hl_device *hdev)
|
|||
prop->num_of_events = GAUDI_EVENT_SIZE;
|
||||
prop->tpc_enabled_mask = TPC_ENABLED_MASK;
|
||||
|
||||
prop->max_power_default = MAX_POWER_DEFAULT;
|
||||
prop->max_power_default = MAX_POWER_DEFAULT_PCI;
|
||||
|
||||
prop->cb_pool_cb_cnt = GAUDI_CB_POOL_CB_CNT;
|
||||
prop->cb_pool_cb_size = GAUDI_CB_POOL_CB_SIZE;
|
||||
|
@ -2485,6 +2508,7 @@ static void gaudi_set_clock_gating(struct hl_device *hdev)
|
|||
{
|
||||
struct gaudi_device *gaudi = hdev->asic_specific;
|
||||
u32 qman_offset;
|
||||
bool enable;
|
||||
int i;
|
||||
|
||||
/* In case we are during debug session, don't enable the clock gate
|
||||
|
@ -2494,46 +2518,43 @@ static void gaudi_set_clock_gating(struct hl_device *hdev)
|
|||
return;
|
||||
|
||||
for (i = GAUDI_PCI_DMA_1, qman_offset = 0 ; i < GAUDI_HBM_DMA_1 ; i++) {
|
||||
if (!(hdev->clock_gating_mask &
|
||||
(BIT_ULL(gaudi_dma_assignment[i]))))
|
||||
continue;
|
||||
enable = !!(hdev->clock_gating_mask &
|
||||
(BIT_ULL(gaudi_dma_assignment[i])));
|
||||
|
||||
qman_offset = gaudi_dma_assignment[i] * DMA_QMAN_OFFSET;
|
||||
WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset, QMAN_CGM1_PWR_GATE_EN);
|
||||
WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset,
|
||||
enable ? QMAN_CGM1_PWR_GATE_EN : 0);
|
||||
WREG32(mmDMA0_QM_CGM_CFG + qman_offset,
|
||||
QMAN_UPPER_CP_CGM_PWR_GATE_EN);
|
||||
enable ? QMAN_UPPER_CP_CGM_PWR_GATE_EN : 0);
|
||||
}
|
||||
|
||||
for (i = GAUDI_HBM_DMA_1 ; i < GAUDI_DMA_MAX ; i++) {
|
||||
if (!(hdev->clock_gating_mask &
|
||||
(BIT_ULL(gaudi_dma_assignment[i]))))
|
||||
continue;
|
||||
enable = !!(hdev->clock_gating_mask &
|
||||
(BIT_ULL(gaudi_dma_assignment[i])));
|
||||
|
||||
qman_offset = gaudi_dma_assignment[i] * DMA_QMAN_OFFSET;
|
||||
WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset, QMAN_CGM1_PWR_GATE_EN);
|
||||
WREG32(mmDMA0_QM_CGM_CFG1 + qman_offset,
|
||||
enable ? QMAN_CGM1_PWR_GATE_EN : 0);
|
||||
WREG32(mmDMA0_QM_CGM_CFG + qman_offset,
|
||||
QMAN_COMMON_CP_CGM_PWR_GATE_EN);
|
||||
enable ? QMAN_COMMON_CP_CGM_PWR_GATE_EN : 0);
|
||||
}
|
||||
|
||||
if (hdev->clock_gating_mask & (BIT_ULL(GAUDI_ENGINE_ID_MME_0))) {
|
||||
WREG32(mmMME0_QM_CGM_CFG1, QMAN_CGM1_PWR_GATE_EN);
|
||||
WREG32(mmMME0_QM_CGM_CFG, QMAN_COMMON_CP_CGM_PWR_GATE_EN);
|
||||
}
|
||||
enable = !!(hdev->clock_gating_mask & (BIT_ULL(GAUDI_ENGINE_ID_MME_0)));
|
||||
WREG32(mmMME0_QM_CGM_CFG1, enable ? QMAN_CGM1_PWR_GATE_EN : 0);
|
||||
WREG32(mmMME0_QM_CGM_CFG, enable ? QMAN_COMMON_CP_CGM_PWR_GATE_EN : 0);
|
||||
|
||||
if (hdev->clock_gating_mask & (BIT_ULL(GAUDI_ENGINE_ID_MME_2))) {
|
||||
WREG32(mmMME2_QM_CGM_CFG1, QMAN_CGM1_PWR_GATE_EN);
|
||||
WREG32(mmMME2_QM_CGM_CFG, QMAN_COMMON_CP_CGM_PWR_GATE_EN);
|
||||
}
|
||||
enable = !!(hdev->clock_gating_mask & (BIT_ULL(GAUDI_ENGINE_ID_MME_2)));
|
||||
WREG32(mmMME2_QM_CGM_CFG1, enable ? QMAN_CGM1_PWR_GATE_EN : 0);
|
||||
WREG32(mmMME2_QM_CGM_CFG, enable ? QMAN_COMMON_CP_CGM_PWR_GATE_EN : 0);
|
||||
|
||||
for (i = 0, qman_offset = 0 ; i < TPC_NUMBER_OF_ENGINES ; i++) {
|
||||
if (!(hdev->clock_gating_mask &
|
||||
(BIT_ULL(GAUDI_ENGINE_ID_TPC_0 + i))))
|
||||
continue;
|
||||
enable = !!(hdev->clock_gating_mask &
|
||||
(BIT_ULL(GAUDI_ENGINE_ID_TPC_0 + i)));
|
||||
|
||||
WREG32(mmTPC0_QM_CGM_CFG1 + qman_offset,
|
||||
QMAN_CGM1_PWR_GATE_EN);
|
||||
enable ? QMAN_CGM1_PWR_GATE_EN : 0);
|
||||
WREG32(mmTPC0_QM_CGM_CFG + qman_offset,
|
||||
QMAN_COMMON_CP_CGM_PWR_GATE_EN);
|
||||
enable ? QMAN_COMMON_CP_CGM_PWR_GATE_EN : 0);
|
||||
|
||||
qman_offset += TPC_QMAN_OFFSET;
|
||||
}
|
||||
|
@ -3772,6 +3793,12 @@ static int gaudi_validate_cb(struct hl_device *hdev,
|
|||
PACKET_HEADER_PACKET_ID_MASK) >>
|
||||
PACKET_HEADER_PACKET_ID_SHIFT);
|
||||
|
||||
if (!validate_packet_id(pkt_id)) {
|
||||
dev_err(hdev->dev, "Invalid packet id %u\n", pkt_id);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
pkt_size = gaudi_packet_sizes[pkt_id];
|
||||
cb_parsed_length += pkt_size;
|
||||
if (cb_parsed_length > parser->user_cb_size) {
|
||||
|
@ -3995,6 +4022,12 @@ static int gaudi_patch_cb(struct hl_device *hdev,
|
|||
PACKET_HEADER_PACKET_ID_MASK) >>
|
||||
PACKET_HEADER_PACKET_ID_SHIFT);
|
||||
|
||||
if (!validate_packet_id(pkt_id)) {
|
||||
dev_err(hdev->dev, "Invalid packet id %u\n", pkt_id);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
pkt_size = gaudi_packet_sizes[pkt_id];
|
||||
cb_parsed_length += pkt_size;
|
||||
if (cb_parsed_length > parser->user_cb_size) {
|
||||
|
@ -5215,7 +5248,7 @@ static int gaudi_extract_ecc_info(struct hl_device *hdev,
|
|||
*memory_wrapper_idx = 0xFF;
|
||||
|
||||
/* Iterate through memory wrappers, a single bit must be set */
|
||||
for (i = 0 ; i > num_mem_regs ; i++) {
|
||||
for (i = 0 ; i < num_mem_regs ; i++) {
|
||||
err_addr += i * 4;
|
||||
err_word = RREG32(err_addr);
|
||||
if (err_word) {
|
||||
|
@ -6022,6 +6055,15 @@ static int gaudi_armcp_info_get(struct hl_device *hdev)
|
|||
strncpy(prop->armcp_info.card_name, GAUDI_DEFAULT_CARD_NAME,
|
||||
CARD_NAME_MAX_LEN);
|
||||
|
||||
hdev->card_type = le32_to_cpu(hdev->asic_prop.armcp_info.card_type);
|
||||
|
||||
if (hdev->card_type == armcp_card_type_pci)
|
||||
prop->max_power_default = MAX_POWER_DEFAULT_PCI;
|
||||
else if (hdev->card_type == armcp_card_type_pmc)
|
||||
prop->max_power_default = MAX_POWER_DEFAULT_PMC;
|
||||
|
||||
hdev->max_power = prop->max_power_default;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,8 @@
|
|||
|
||||
#define GAUDI_MAX_CLK_FREQ 2200000000ull /* 2200 MHz */
|
||||
|
||||
#define MAX_POWER_DEFAULT 200000 /* 200W */
|
||||
#define MAX_POWER_DEFAULT_PCI 200000 /* 200W */
|
||||
#define MAX_POWER_DEFAULT_PMC 350000 /* 350W */
|
||||
|
||||
#define GAUDI_CPU_TIMEOUT_USEC 15000000 /* 15s */
|
||||
|
||||
|
|
|
@ -527,7 +527,7 @@ static int gaudi_config_etf(struct hl_device *hdev,
|
|||
}
|
||||
|
||||
static bool gaudi_etr_validate_address(struct hl_device *hdev, u64 addr,
|
||||
u32 size, bool *is_host)
|
||||
u64 size, bool *is_host)
|
||||
{
|
||||
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||
struct gaudi_device *gaudi = hdev->asic_specific;
|
||||
|
@ -539,6 +539,12 @@ static bool gaudi_etr_validate_address(struct hl_device *hdev, u64 addr,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (addr > (addr + size)) {
|
||||
dev_err(hdev->dev,
|
||||
"ETR buffer size %llu overflow\n", size);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* PMMU and HPMMU addresses are equal, check only one of them */
|
||||
if ((gaudi->hw_cap_initialized & HW_CAP_MMU) &&
|
||||
hl_mem_area_inside_range(addr, size,
|
||||
|
|
|
@ -139,6 +139,25 @@ static u16 goya_packet_sizes[MAX_PACKET_ID] = {
|
|||
[PACKET_STOP] = sizeof(struct packet_stop)
|
||||
};
|
||||
|
||||
static inline bool validate_packet_id(enum packet_id id)
|
||||
{
|
||||
switch (id) {
|
||||
case PACKET_WREG_32:
|
||||
case PACKET_WREG_BULK:
|
||||
case PACKET_MSG_LONG:
|
||||
case PACKET_MSG_SHORT:
|
||||
case PACKET_CP_DMA:
|
||||
case PACKET_MSG_PROT:
|
||||
case PACKET_FENCE:
|
||||
case PACKET_LIN_DMA:
|
||||
case PACKET_NOP:
|
||||
case PACKET_STOP:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static u64 goya_mmu_regs[GOYA_MMU_REGS_NUM] = {
|
||||
mmDMA_QM_0_GLBL_NON_SECURE_PROPS,
|
||||
mmDMA_QM_1_GLBL_NON_SECURE_PROPS,
|
||||
|
@ -3455,6 +3474,12 @@ static int goya_validate_cb(struct hl_device *hdev,
|
|||
PACKET_HEADER_PACKET_ID_MASK) >>
|
||||
PACKET_HEADER_PACKET_ID_SHIFT);
|
||||
|
||||
if (!validate_packet_id(pkt_id)) {
|
||||
dev_err(hdev->dev, "Invalid packet id %u\n", pkt_id);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
pkt_size = goya_packet_sizes[pkt_id];
|
||||
cb_parsed_length += pkt_size;
|
||||
if (cb_parsed_length > parser->user_cb_size) {
|
||||
|
@ -3690,6 +3715,12 @@ static int goya_patch_cb(struct hl_device *hdev,
|
|||
PACKET_HEADER_PACKET_ID_MASK) >>
|
||||
PACKET_HEADER_PACKET_ID_SHIFT);
|
||||
|
||||
if (!validate_packet_id(pkt_id)) {
|
||||
dev_err(hdev->dev, "Invalid packet id %u\n", pkt_id);
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
pkt_size = goya_packet_sizes[pkt_id];
|
||||
cb_parsed_length += pkt_size;
|
||||
if (cb_parsed_length > parser->user_cb_size) {
|
||||
|
|
|
@ -362,11 +362,17 @@ static int goya_config_etf(struct hl_device *hdev,
|
|||
}
|
||||
|
||||
static int goya_etr_validate_address(struct hl_device *hdev, u64 addr,
|
||||
u32 size)
|
||||
u64 size)
|
||||
{
|
||||
struct asic_fixed_properties *prop = &hdev->asic_prop;
|
||||
u64 range_start, range_end;
|
||||
|
||||
if (addr > (addr + size)) {
|
||||
dev_err(hdev->dev,
|
||||
"ETR buffer size %llu overflow\n", size);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (hdev->mmu_enable) {
|
||||
range_start = prop->dmmu.start_addr;
|
||||
range_end = prop->dmmu.end_addr;
|
||||
|
|
|
@ -546,38 +546,46 @@ static int mei_hdcp_verify_mprime(struct device *dev,
|
|||
struct hdcp_port_data *data,
|
||||
struct hdcp2_rep_stream_ready *stream_ready)
|
||||
{
|
||||
struct wired_cmd_repeater_auth_stream_req_in
|
||||
verify_mprime_in = { { 0 } };
|
||||
struct wired_cmd_repeater_auth_stream_req_in *verify_mprime_in;
|
||||
struct wired_cmd_repeater_auth_stream_req_out
|
||||
verify_mprime_out = { { 0 } };
|
||||
struct mei_cl_device *cldev;
|
||||
ssize_t byte;
|
||||
size_t cmd_size;
|
||||
|
||||
if (!dev || !stream_ready || !data)
|
||||
return -EINVAL;
|
||||
|
||||
cldev = to_mei_cl_device(dev);
|
||||
|
||||
verify_mprime_in.header.api_version = HDCP_API_VERSION;
|
||||
verify_mprime_in.header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ;
|
||||
verify_mprime_in.header.status = ME_HDCP_STATUS_SUCCESS;
|
||||
verify_mprime_in.header.buffer_len =
|
||||
cmd_size = struct_size(verify_mprime_in, streams, data->k);
|
||||
if (cmd_size == SIZE_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
verify_mprime_in = kzalloc(cmd_size, GFP_KERNEL);
|
||||
if (!verify_mprime_in)
|
||||
return -ENOMEM;
|
||||
|
||||
verify_mprime_in->header.api_version = HDCP_API_VERSION;
|
||||
verify_mprime_in->header.command_id = WIRED_REPEATER_AUTH_STREAM_REQ;
|
||||
verify_mprime_in->header.status = ME_HDCP_STATUS_SUCCESS;
|
||||
verify_mprime_in->header.buffer_len =
|
||||
WIRED_CMD_BUF_LEN_REPEATER_AUTH_STREAM_REQ_MIN_IN;
|
||||
|
||||
verify_mprime_in.port.integrated_port_type = data->port_type;
|
||||
verify_mprime_in.port.physical_port = (u8)data->fw_ddi;
|
||||
verify_mprime_in.port.attached_transcoder = (u8)data->fw_tc;
|
||||
verify_mprime_in->port.integrated_port_type = data->port_type;
|
||||
verify_mprime_in->port.physical_port = (u8)data->fw_ddi;
|
||||
verify_mprime_in->port.attached_transcoder = (u8)data->fw_tc;
|
||||
|
||||
memcpy(verify_mprime_in.m_prime, stream_ready->m_prime,
|
||||
HDCP_2_2_MPRIME_LEN);
|
||||
drm_hdcp_cpu_to_be24(verify_mprime_in.seq_num_m, data->seq_num_m);
|
||||
memcpy(verify_mprime_in.streams, data->streams,
|
||||
memcpy(verify_mprime_in->m_prime, stream_ready->m_prime, HDCP_2_2_MPRIME_LEN);
|
||||
drm_hdcp_cpu_to_be24(verify_mprime_in->seq_num_m, data->seq_num_m);
|
||||
|
||||
memcpy(verify_mprime_in->streams, data->streams,
|
||||
array_size(data->k, sizeof(*data->streams)));
|
||||
|
||||
verify_mprime_in.k = cpu_to_be16(data->k);
|
||||
verify_mprime_in->k = cpu_to_be16(data->k);
|
||||
|
||||
byte = mei_cldev_send(cldev, (u8 *)&verify_mprime_in,
|
||||
sizeof(verify_mprime_in));
|
||||
byte = mei_cldev_send(cldev, (u8 *)verify_mprime_in, cmd_size);
|
||||
kfree(verify_mprime_in);
|
||||
if (byte < 0) {
|
||||
dev_dbg(dev, "mei_cldev_send failed. %zd\n", byte);
|
||||
return byte;
|
||||
|
|
Loading…
Reference in New Issue