From: Grant Peltier <[email protected]>
[ Upstream commit 51fb91ed5a6fa855a74731610cd5435d83d6e17f ]
Per the RAA228228 datasheet, READ_TEMPERATURE_1 is not a supported PMBus
command.
Signed-off-by: Grant Peltier <[email protected]>
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/hwmon/pmbus/isl68137.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/pmbus/isl68137.c b/drivers/hwmon/pmbus/isl68137.c
index 0c622711ef7e0..58aa95a3c010c 100644
--- a/drivers/hwmon/pmbus/isl68137.c
+++ b/drivers/hwmon/pmbus/isl68137.c
@@ -67,6 +67,7 @@ enum variants {
raa_dmpvr1_2rail,
raa_dmpvr2_1rail,
raa_dmpvr2_2rail,
+ raa_dmpvr2_2rail_nontc,
raa_dmpvr2_3rail,
raa_dmpvr2_hv,
};
@@ -241,6 +242,10 @@ static int isl68137_probe(struct i2c_client *client,
info->pages = 1;
info->read_word_data = raa_dmpvr2_read_word_data;
break;
+ case raa_dmpvr2_2rail_nontc:
+ info->func[0] &= ~PMBUS_HAVE_TEMP;
+ info->func[1] &= ~PMBUS_HAVE_TEMP;
+ fallthrough;
case raa_dmpvr2_2rail:
info->pages = 2;
info->read_word_data = raa_dmpvr2_read_word_data;
@@ -304,7 +309,7 @@ static const struct i2c_device_id raa_dmpvr_id[] = {
{"raa228000", raa_dmpvr2_hv},
{"raa228004", raa_dmpvr2_hv},
{"raa228006", raa_dmpvr2_hv},
- {"raa228228", raa_dmpvr2_2rail},
+ {"raa228228", raa_dmpvr2_2rail_nontc},
{"raa229001", raa_dmpvr2_2rail},
{"raa229004", raa_dmpvr2_2rail},
{}
--
2.25.1
From: Sebastian Parschauer <[email protected]>
[ Upstream commit 627a49975bdc3220f360a8237603a6344ee6a588 ]
The PixArt OEM mice are known for disconnecting every minute in
runlevel 1 or 3 if they are not always polled. One Lenovo PixArt
mouse is already fixed. Got two references for 17ef:602e and three
references for 17ef:6019 misbehaving like this. Got one direct bug
report for 17ef:6093 from Wyatt Ward (wyatt8740). So add
HID_QUIRK_ALWAYS_POLL for all of them.
Link: https://github.com/sriemer/fix-linux-mouse issue 22
Signed-off-by: Sebastian Parschauer <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/hid/hid-ids.h | 3 +++
drivers/hid/hid-quirks.c | 3 +++
2 files changed, 6 insertions(+)
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index 6f370e020feb3..1f42318a137fb 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -727,6 +727,9 @@
#define USB_DEVICE_ID_LENOVO_TPPRODOCK 0x6067
#define USB_DEVICE_ID_LENOVO_X1_COVER 0x6085
#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D 0x608d
+#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019 0x6019
+#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E 0x602e
+#define USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093 0x6093
#define USB_VENDOR_ID_LG 0x1fd2
#define USB_DEVICE_ID_LG_MULTITOUCH 0x0064
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c
index 934fc0a798d4d..87b57514b92e1 100644
--- a/drivers/hid/hid-quirks.c
+++ b/drivers/hid/hid-quirks.c
@@ -105,6 +105,9 @@ static const struct hid_device_id hid_quirks[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_KYE_EASYPEN_M406XE), HID_QUIRK_MULTI_INPUT },
{ HID_USB_DEVICE(USB_VENDOR_ID_KYE, USB_DEVICE_ID_PIXART_USB_OPTICAL_MOUSE_ID2), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_608D), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6019), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_602E), HID_QUIRK_ALWAYS_POLL },
+ { HID_USB_DEVICE(USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_PIXART_USB_MOUSE_6093), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C007), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_C077), HID_QUIRK_ALWAYS_POLL },
{ HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_KEYBOARD_G710_PLUS), HID_QUIRK_NOGET },
--
2.25.1
From: Samuel Thibault <[email protected]>
[ Upstream commit 2b86d9b8ec6efb86fc5ea44f2d49b1df17f699a1 ]
This was missed while introducing the tty-based serial access.
The only remaining use of wait_for_xmitr with tty-based access is in
spk_synth_is_alive_restart to check whether the synth can be restarted.
With tty-based this is up to the tty layer to cope with the buffering
etc. so we can just say yes.
Signed-off-by: Samuel Thibault <[email protected]>
Link: https://lore.kernel.org/r/20200804160637.x3iycau5izywbgzl@function
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/staging/speakup/serialio.c | 8 +++++---
drivers/staging/speakup/spk_priv.h | 1 -
drivers/staging/speakup/spk_ttyio.c | 7 +++++++
drivers/staging/speakup/spk_types.h | 1 +
drivers/staging/speakup/synth.c | 2 +-
5 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/speakup/serialio.c b/drivers/staging/speakup/serialio.c
index 177a2988641c1..403b01d66367e 100644
--- a/drivers/staging/speakup/serialio.c
+++ b/drivers/staging/speakup/serialio.c
@@ -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;
diff --git a/drivers/staging/speakup/spk_priv.h b/drivers/staging/speakup/spk_priv.h
index c75b408387947..0f4bcbe5ddb93 100644
--- a/drivers/staging/speakup/spk_priv.h
+++ b/drivers/staging/speakup/spk_priv.h
@@ -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);
diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c
index 9b95f77f92657..a831ff64f8ba5 100644
--- a/drivers/staging/speakup/spk_ttyio.c
+++ b/drivers/staging/speakup/spk_ttyio.c
@@ -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;
diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h
index d3272c6d199aa..7398f1196e103 100644
--- a/drivers/staging/speakup/spk_types.h
+++ b/drivers/staging/speakup/spk_types.h
@@ -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 {
diff --git a/drivers/staging/speakup/synth.c b/drivers/staging/speakup/synth.c
index 3568bfb89912c..ac47dbac72075 100644
--- a/drivers/staging/speakup/synth.c
+++ b/drivers/staging/speakup/synth.c
@@ -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);
--
2.25.1
From: Krishna Manikandan <[email protected]>
[ Upstream commit 9d5cbf5fe46e350715389d89d0c350d83289a102 ]
Define shutdown callback for display drm driver,
so as to disable all the CRTCS when shutdown
notification is received by the driver.
This change will turn off the timing engine so
that no display transactions are requested
while mmu translations are getting disabled
during reboot sequence.
Signed-off-by: Krishna Manikandan <[email protected]>
Changes in v2:
- Remove NULL check from msm_pdev_shutdown (Stephen Boyd)
- Change commit text to reflect when this issue
was uncovered (Sai Prakash Ranjan)
Signed-off-by: Rob Clark <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/msm/msm_drv.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index f6ce40bf36998..b4d61af7a104e 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -1328,6 +1328,13 @@ static int msm_pdev_remove(struct platform_device *pdev)
return 0;
}
+static void msm_pdev_shutdown(struct platform_device *pdev)
+{
+ struct drm_device *drm = platform_get_drvdata(pdev);
+
+ drm_atomic_helper_shutdown(drm);
+}
+
static const struct of_device_id dt_match[] = {
{ .compatible = "qcom,mdp4", .data = (void *)KMS_MDP4 },
{ .compatible = "qcom,mdss", .data = (void *)KMS_MDP5 },
@@ -1340,6 +1347,7 @@ MODULE_DEVICE_TABLE(of, dt_match);
static struct platform_driver msm_platform_driver = {
.probe = msm_pdev_probe,
.remove = msm_pdev_remove,
+ .shutdown = msm_pdev_shutdown,
.driver = {
.name = "msm",
.of_match_table = dt_match,
--
2.25.1
From: Hou Pu <[email protected]>
[ Upstream commit acb19e17c5134dd78668c429ecba5b481f038e6a ]
If we configured io timeout of nbd0 to 100s. Later after we
finished using it, we configured nbd0 again and set the io
timeout to 0. We expect it would timeout after 30 seconds
and keep retry. But in fact we could not change the timeout
when we set it to 0. the timeout is still the original 100s.
So change the timeout to default 30s when we set it to zero.
It also behaves same as commit 2da22da57348 ("nbd: fix zero
cmd timeout handling v2").
It becomes more important if we were reconfigure a nbd device
and the io timeout it set to zero. Because it could take 30s
to detect the new socket and thus io could be completed more
quickly compared to 100s.
Signed-off-by: Hou Pu <[email protected]>
Reviewed-by: Josef Bacik <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/block/nbd.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index ce7e9f223b20b..bc9dc1f847e19 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -1360,6 +1360,8 @@ static void nbd_set_cmd_timeout(struct nbd_device *nbd, u64 timeout)
nbd->tag_set.timeout = timeout * HZ;
if (timeout)
blk_queue_rq_timeout(nbd->disk->queue, timeout * HZ);
+ else
+ blk_queue_rq_timeout(nbd->disk->queue, 30 * HZ);
}
/* Must be called with config_lock held */
--
2.25.1
From: Sven Schnelle <[email protected]>
[ Upstream commit 1196f12a2c960951d02262af25af0bb1775ebcc2 ]
Since commit a21ee6055c30 ("lockdep: Change hardirq{s_enabled,_context}
to per-cpu variables") the lockdep code itself uses percpu variables. This
leads to recursions because the percpu macros are calling preempt_enable()
which might call trace_preempt_on().
Signed-off-by: Sven Schnelle <[email protected]>
Reviewed-by: Vasily Gorbik <[email protected]>
Signed-off-by: Vasily Gorbik <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
arch/s390/include/asm/percpu.h | 28 ++++++++++++++--------------
1 file changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h
index 50b4ce8cddfdc..918f0ba4f4d20 100644
--- a/arch/s390/include/asm/percpu.h
+++ b/arch/s390/include/asm/percpu.h
@@ -29,7 +29,7 @@
typedef typeof(pcp) pcp_op_T__; \
pcp_op_T__ old__, new__, prev__; \
pcp_op_T__ *ptr__; \
- preempt_disable(); \
+ preempt_disable_notrace(); \
ptr__ = raw_cpu_ptr(&(pcp)); \
prev__ = *ptr__; \
do { \
@@ -37,7 +37,7 @@
new__ = old__ op (val); \
prev__ = cmpxchg(ptr__, old__, new__); \
} while (prev__ != old__); \
- preempt_enable(); \
+ preempt_enable_notrace(); \
new__; \
})
@@ -68,7 +68,7 @@
typedef typeof(pcp) pcp_op_T__; \
pcp_op_T__ val__ = (val); \
pcp_op_T__ old__, *ptr__; \
- preempt_disable(); \
+ preempt_disable_notrace(); \
ptr__ = raw_cpu_ptr(&(pcp)); \
if (__builtin_constant_p(val__) && \
((szcast)val__ > -129) && ((szcast)val__ < 128)) { \
@@ -84,7 +84,7 @@
: [val__] "d" (val__) \
: "cc"); \
} \
- preempt_enable(); \
+ preempt_enable_notrace(); \
}
#define this_cpu_add_4(pcp, val) arch_this_cpu_add(pcp, val, "laa", "asi", int)
@@ -95,14 +95,14 @@
typedef typeof(pcp) pcp_op_T__; \
pcp_op_T__ val__ = (val); \
pcp_op_T__ old__, *ptr__; \
- preempt_disable(); \
+ preempt_disable_notrace(); \
ptr__ = raw_cpu_ptr(&(pcp)); \
asm volatile( \
op " %[old__],%[val__],%[ptr__]\n" \
: [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \
: [val__] "d" (val__) \
: "cc"); \
- preempt_enable(); \
+ preempt_enable_notrace(); \
old__ + val__; \
})
@@ -114,14 +114,14 @@
typedef typeof(pcp) pcp_op_T__; \
pcp_op_T__ val__ = (val); \
pcp_op_T__ old__, *ptr__; \
- preempt_disable(); \
+ preempt_disable_notrace(); \
ptr__ = raw_cpu_ptr(&(pcp)); \
asm volatile( \
op " %[old__],%[val__],%[ptr__]\n" \
: [old__] "=d" (old__), [ptr__] "+Q" (*ptr__) \
: [val__] "d" (val__) \
: "cc"); \
- preempt_enable(); \
+ preempt_enable_notrace(); \
}
#define this_cpu_and_4(pcp, val) arch_this_cpu_to_op(pcp, val, "lan")
@@ -136,10 +136,10 @@
typedef typeof(pcp) pcp_op_T__; \
pcp_op_T__ ret__; \
pcp_op_T__ *ptr__; \
- preempt_disable(); \
+ preempt_disable_notrace(); \
ptr__ = raw_cpu_ptr(&(pcp)); \
ret__ = cmpxchg(ptr__, oval, nval); \
- preempt_enable(); \
+ preempt_enable_notrace(); \
ret__; \
})
@@ -152,10 +152,10 @@
({ \
typeof(pcp) *ptr__; \
typeof(pcp) ret__; \
- preempt_disable(); \
+ preempt_disable_notrace(); \
ptr__ = raw_cpu_ptr(&(pcp)); \
ret__ = xchg(ptr__, nval); \
- preempt_enable(); \
+ preempt_enable_notrace(); \
ret__; \
})
@@ -171,11 +171,11 @@
typeof(pcp1) *p1__; \
typeof(pcp2) *p2__; \
int ret__; \
- preempt_disable(); \
+ preempt_disable_notrace(); \
p1__ = raw_cpu_ptr(&(pcp1)); \
p2__ = raw_cpu_ptr(&(pcp2)); \
ret__ = __cmpxchg_double(p1__, p2__, o1__, o2__, n1__, n2__); \
- preempt_enable(); \
+ preempt_enable_notrace(); \
ret__; \
})
--
2.25.1
From: Nicholas Kazlauskas <[email protected]>
[ Upstream commit 168f09cdadbd547c2b202246ef9a8183da725f13 ]
[Why]
These aren't stable on some platform configurations when driving
multiple displays, especially on higher resolution.
In particular the delay in asserting p-state and validating from
x86 outweights any power or performance benefit from the hardware
composition.
Under some configurations this will manifest itself as extreme stutter
or unresponsiveness especially when combined with cursor movement.
[How]
Disable these for now. Exposing overlays to userspace doesn't guarantee
that they'll be able to use them in any and all configurations and it's
part of the DRM contract to have userspace gracefully handle validation
failures when they occur.
Valdiation occurs as part of DC and this in particular affects RV, so
disable this in dcn10_global_validation.
Signed-off-by: Nicholas Kazlauskas <[email protected]>
Reviewed-by: Hersen Wu <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
index 17d5cb422025e..8939541ad7afc 100644
--- a/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
+++ b/drivers/gpu/drm/amd/display/dc/dcn10/dcn10_resource.c
@@ -1213,6 +1213,7 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont
bool video_large = false;
bool desktop_large = false;
bool dcc_disabled = false;
+ bool mpo_enabled = false;
for (i = 0; i < context->stream_count; i++) {
if (context->stream_status[i].plane_count == 0)
@@ -1221,6 +1222,9 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont
if (context->stream_status[i].plane_count > 2)
return DC_FAIL_UNSUPPORTED_1;
+ if (context->stream_status[i].plane_count > 1)
+ mpo_enabled = true;
+
for (j = 0; j < context->stream_status[i].plane_count; j++) {
struct dc_plane_state *plane =
context->stream_status[i].plane_states[j];
@@ -1244,6 +1248,10 @@ static enum dc_status dcn10_validate_global(struct dc *dc, struct dc_state *cont
}
}
+ /* Disable MPO in multi-display configurations. */
+ if (context->stream_count > 1 && mpo_enabled)
+ return DC_FAIL_UNSUPPORTED_1;
+
/*
* Workaround: On DCN10 there is UMC issue that causes underflow when
* playing 4k video on 4k desktop with video downscaled and single channel
--
2.25.1
From: Furquan Shaikh <[email protected]>
[ Upstream commit 5896585512e5156482335e902f7c7393b940da51 ]
In `amdgpu_dm_update_backlight_caps()`, there is a local
`amdgpu_dm_backlight_caps` object that is filled in by
`amdgpu_acpi_get_backlight_caps()`. However, this object is
uninitialized before the call and hence the subsequent check for
aux_support can fail since it is not initialized by
`amdgpu_acpi_get_backlight_caps()` as well. This change initializes
this local `amdgpu_dm_backlight_caps` object to 0.
Reviewed-by: Christian König <[email protected]>
Signed-off-by: Furquan Shaikh <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0a39a8558b294..0682fd363cb50 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2844,6 +2844,8 @@ static void amdgpu_dm_update_backlight_caps(struct amdgpu_display_manager *dm)
#if defined(CONFIG_ACPI)
struct amdgpu_dm_backlight_caps caps;
+ memset(&caps, 0, sizeof(caps));
+
if (dm->backlight_caps.caps_valid)
return;
--
2.25.1
From: Tomi Valkeinen <[email protected]>
[ Upstream commit 7fd5b25499bcec157dd4de9a713425efcf4571cd ]
After commit 92cc68e35863c1c61c449efa2b2daef6e9926048 ("drm/vblank: Use
spin_(un)lock_irq() in drm_crtc_vblank_on()") omapdrm locking is broken:
WARNING: inconsistent lock state
5.8.0-rc2-00483-g92cc68e35863 #13 Tainted: G W
--------------------------------
inconsistent {HARDIRQ-ON-W} -> {IN-HARDIRQ-W} usage.
swapper/0/0 [HC1[1]:SC0[0]:HE0:SE1] takes:
ea98222c (&dev->event_lock#2){?.+.}-{2:2}, at: drm_handle_vblank+0x4c/0x520 [drm]
{HARDIRQ-ON-W} state was registered at:
trace_hardirqs_on+0x9c/0x1ec
_raw_spin_unlock_irq+0x20/0x58
omap_crtc_atomic_enable+0x54/0xa0 [omapdrm]
drm_atomic_helper_commit_modeset_enables+0x218/0x270 [drm_kms_helper]
omap_atomic_commit_tail+0x48/0xc4 [omapdrm]
commit_tail+0x9c/0x190 [drm_kms_helper]
drm_atomic_helper_commit+0x154/0x188 [drm_kms_helper]
drm_client_modeset_commit_atomic+0x228/0x268 [drm]
drm_client_modeset_commit_locked+0x60/0x1d0 [drm]
drm_client_modeset_commit+0x24/0x40 [drm]
drm_fb_helper_restore_fbdev_mode_unlocked+0x54/0xa8 [drm_kms_helper]
drm_fb_helper_set_par+0x2c/0x5c [drm_kms_helper]
drm_fb_helper_hotplug_event.part.0+0xa0/0xbc [drm_kms_helper]
drm_kms_helper_hotplug_event+0x24/0x30 [drm_kms_helper]
output_poll_execute+0x1a8/0x1c0 [drm_kms_helper]
process_one_work+0x268/0x800
worker_thread+0x30/0x4e0
kthread+0x164/0x190
ret_from_fork+0x14/0x20
The reason for this is that omapdrm calls drm_crtc_vblank_on() while
holding event_lock taken with spin_lock_irq().
It is not clear why drm_crtc_vblank_on() and drm_crtc_vblank_get() are
called while holding event_lock. I don't see any problem with moving
those calls outside the lock, which is what this patch does.
Signed-off-by: Tomi Valkeinen <[email protected]>
Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
Reviewed-by: Laurent Pinchart <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/omapdrm/omap_crtc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index fce7e944a280b..dbf91b3fd6f08 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -451,11 +451,12 @@ static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
if (omap_state->manually_updated)
return;
- spin_lock_irq(&crtc->dev->event_lock);
drm_crtc_vblank_on(crtc);
+
ret = drm_crtc_vblank_get(crtc);
WARN_ON(ret != 0);
+ spin_lock_irq(&crtc->dev->event_lock);
omap_crtc_arm_event(crtc);
spin_unlock_irq(&crtc->dev->event_lock);
}
--
2.25.1
From: Peilin Ye <[email protected]>
[ Upstream commit 25a097f5204675550afb879ee18238ca917cba7a ]
`uref->usage_index` is not always being properly checked, causing
hiddev_ioctl_usage() to go out of bounds under some cases. Fix it.
Reported-by: [email protected]
Link: https://syzkaller.appspot.com/bug?id=f2aebe90b8c56806b050a20b36f51ed6acabe802
Reviewed-by: Dan Carpenter <[email protected]>
Signed-off-by: Peilin Ye <[email protected]>
Signed-off-by: Jiri Kosina <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/hid/usbhid/hiddev.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c
index 4140dea693e90..4f97e6c120595 100644
--- a/drivers/hid/usbhid/hiddev.c
+++ b/drivers/hid/usbhid/hiddev.c
@@ -519,12 +519,16 @@ static noinline int hiddev_ioctl_usage(struct hiddev *hiddev, unsigned int cmd,
switch (cmd) {
case HIDIOCGUSAGE:
+ if (uref->usage_index >= field->report_count)
+ goto inval;
uref->value = field->value[uref->usage_index];
if (copy_to_user(user_arg, uref, sizeof(*uref)))
goto fault;
goto goodreturn;
case HIDIOCSUSAGE:
+ if (uref->usage_index >= field->report_count)
+ goto inval;
field->value[uref->usage_index] = uref->value;
goto goodreturn;
--
2.25.1
On Mon, Aug 31, 2020 at 11:28:59AM -0400, Sasha Levin wrote:
> From: Samuel Thibault <[email protected]>
>
> [ Upstream commit 2b86d9b8ec6efb86fc5ea44f2d49b1df17f699a1 ]
>
> This was missed while introducing the tty-based serial access.
>
> The only remaining use of wait_for_xmitr with tty-based access is in
> spk_synth_is_alive_restart to check whether the synth can be restarted.
> With tty-based this is up to the tty layer to cope with the buffering
> etc. so we can just say yes.
>
> Signed-off-by: Samuel Thibault <[email protected]>
> Link: https://lore.kernel.org/r/20200804160637.x3iycau5izywbgzl@function
> Signed-off-by: Greg Kroah-Hartman <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---
> drivers/staging/speakup/serialio.c | 8 +++++---
> drivers/staging/speakup/spk_priv.h | 1 -
> drivers/staging/speakup/spk_ttyio.c | 7 +++++++
> drivers/staging/speakup/spk_types.h | 1 +
> drivers/staging/speakup/synth.c | 2 +-
> 5 files changed, 14 insertions(+), 5 deletions(-)
Not needed for 5.8 or older, sorry, this was a 5.9-rc1+ issue only.
thanks,
greg k-h
From: Linus Torvalds <[email protected]>
[ Upstream commit 0a4c56c80f90797e9b9f8426c6aae4c0cf1c9785 ]
Commit ef91bb196b0d ("kernel.h: Silence sparse warning in
lower_32_bits") caused new warnings to show in the fsldma driver, but
that commit was not to blame: it only exposed some very incorrect code
that tried to take the low 32 bits of an address.
That made no sense for multiple reasons, the most notable one being that
that code was intentionally limited to only 32-bit ppc builds, so "only
low 32 bits of an address" was completely nonsensical. There were no
high bits to mask off to begin with.
But even more importantly fropm a correctness standpoint, turning the
address into an integer then caused the subsequent address arithmetic to
be completely wrong too, and the "+1" actually incremented the address
by one, rather than by four.
Which again was incorrect, since the code was reading two 32-bit values
and trying to make a 64-bit end result of it all. Surprisingly, the
iowrite64() did not suffer from the same odd and incorrect model.
This code has never worked, but it's questionable whether anybody cared:
of the two users that actually read the 64-bit value (by way of some C
preprocessor hackery and eventually the 'get_cdar()' inline function),
one of them explicitly ignored the value, and the other one might just
happen to work despite the incorrect value being read.
This patch at least makes it not fail the build any more, and makes the
logic superficially sane. Whether it makes any difference to the code
_working_ or not shall remain a mystery.
Compile-tested-by: Guenter Roeck <[email protected]>
Reviewed-by: Guenter Roeck <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/dma/fsldma.h | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h
index 56f18ae992332..308bed0a560ac 100644
--- a/drivers/dma/fsldma.h
+++ b/drivers/dma/fsldma.h
@@ -205,10 +205,10 @@ struct fsldma_chan {
#else
static u64 fsl_ioread64(const u64 __iomem *addr)
{
- u32 fsl_addr = lower_32_bits(addr);
- u64 fsl_addr_hi = (u64)in_le32((u32 *)(fsl_addr + 1)) << 32;
+ u32 val_lo = in_le32((u32 __iomem *)addr);
+ u32 val_hi = in_le32((u32 __iomem *)addr + 1);
- return fsl_addr_hi | in_le32((u32 *)fsl_addr);
+ return ((u64)val_hi << 32) + val_lo;
}
static void fsl_iowrite64(u64 val, u64 __iomem *addr)
@@ -219,10 +219,10 @@ static void fsl_iowrite64(u64 val, u64 __iomem *addr)
static u64 fsl_ioread64be(const u64 __iomem *addr)
{
- u32 fsl_addr = lower_32_bits(addr);
- u64 fsl_addr_hi = (u64)in_be32((u32 *)fsl_addr) << 32;
+ u32 val_hi = in_be32((u32 __iomem *)addr);
+ u32 val_lo = in_be32((u32 __iomem *)addr + 1);
- return fsl_addr_hi | in_be32((u32 *)(fsl_addr + 1));
+ return ((u64)val_hi << 32) + val_lo;
}
static void fsl_iowrite64be(u64 val, u64 __iomem *addr)
--
2.25.1
From: Dinghao Liu <[email protected]>
[ Upstream commit b67a468a4ccef593cd8df6a02ba3d167b77f0c81 ]
When amdgpu_display_modeset_create_props() fails, state and
state->context should be freed to prevent memleak. It's the
same when amdgpu_dm_audio_init() fails.
Signed-off-by: Dinghao Liu <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
index 0682fd363cb50..580c17c95a1d8 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -2822,12 +2822,18 @@ static int amdgpu_dm_mode_config_init(struct amdgpu_device *adev)
&dm_atomic_state_funcs);
r = amdgpu_display_modeset_create_props(adev);
- if (r)
+ if (r) {
+ dc_release_state(state->context);
+ kfree(state);
return r;
+ }
r = amdgpu_dm_audio_init(adev);
- if (r)
+ if (r) {
+ dc_release_state(state->context);
+ kfree(state);
return r;
+ }
return 0;
}
--
2.25.1
From: Wayne Lin <[email protected]>
[ Upstream commit ef67d792a2fc578319399f605fbec2f99ecc06ea ]
[Why]
In dm_dp_aux_transfer() now, we forget to handle AUX_WR fail cases. We
suppose every write wil get done successfully and hence some AUX
commands might not sent out indeed.
[How]
Check if AUX_WR success. If not, retry it.
Signed-off-by: Wayne Lin <[email protected]>
Reviewed-by: Hersen Wu <[email protected]>
Acked-by: Rodrigo Siqueira <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
index e5ecc5affa1eb..5098fc98cc255 100644
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
@@ -67,7 +67,7 @@ static ssize_t dm_dp_aux_transfer(struct drm_dp_aux *aux,
result = dc_link_aux_transfer_raw(TO_DM_AUX(aux)->ddc_service, &payload,
&operation_result);
- if (payload.write)
+ if (payload.write && result >= 0)
result = msg->size;
if (result < 0)
--
2.25.1
From: Samson Tam <[email protected]>
[ Upstream commit efbde23a3b0164cef27fd394e7d548f46af5b51d ]
[Why]
dongle_type is set during dongle connection but for passive dongles,
dongle_type is not set. If user starts with an active dongle and
then switches to a passive dongle, it will still report as an active
dongle. Trying to emulate the wrong connecter type results in display
not lighting up.
[How]
Set dpcd_caps.dongle_type for passive dongles in detect_dp().
Signed-off-by: Samson Tam <[email protected]>
Reviewed-by: Joshua Aberback <[email protected]>
Acked-by: Eryk Brol <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/amd/display/dc/core/dc_link.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index bdddb46727b1f..885beb0bcc199 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -767,6 +767,7 @@ static bool detect_dp(struct dc_link *link,
sink_caps->signal = dp_passive_dongle_detection(link->ddc,
sink_caps,
audio_support);
+ link->dpcd_caps.dongle_type = sink_caps->dongle_type;
}
return true;
--
2.25.1
From: Jaehyun Chung <[email protected]>
[ Upstream commit b61f05622ace5b9498ae279cdfd1c9f0c1ce3f75 ]
[Why]
Revert HDCP disable sequence change that blanks stream before
disabling HDCP. PSP and HW teams are currently investigating the
root cause of why HDCP cannot be disabled before stream blank,
which is expected to work without issues.
Signed-off-by: Jaehyun Chung <[email protected]>
Reviewed-by: Wenjing Liu <[email protected]>
Acked-by: Eryk Brol <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/amd/display/dc/core/dc_link.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
index 31aa31c280ee6..bdddb46727b1f 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c
@@ -3265,10 +3265,10 @@ void core_link_disable_stream(struct pipe_ctx *pipe_ctx)
core_link_set_avmute(pipe_ctx, true);
}
- dc->hwss.blank_stream(pipe_ctx);
#if defined(CONFIG_DRM_AMD_DC_HDCP)
update_psp_stream_config(pipe_ctx, true);
#endif
+ dc->hwss.blank_stream(pipe_ctx);
if (pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST)
deallocate_mst_payload(pipe_ctx);
--
2.25.1
From: Peter Zijlstra <[email protected]>
[ Upstream commit 49d9c5936314e44d314c605c39cce0fd947f9c3a ]
Match the pattern elsewhere in this file.
Signed-off-by: Peter Zijlstra (Intel) <[email protected]>
Reviewed-by: Steven Rostedt (VMware) <[email protected]>
Reviewed-by: Thomas Gleixner <[email protected]>
Acked-by: Rafael J. Wysocki <[email protected]>
Tested-by: Marco Elver <[email protected]>
Link: https://lkml.kernel.org/r/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/cpuidle/cpuidle.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/cpuidle/cpuidle.c b/drivers/cpuidle/cpuidle.c
index 87197319ab069..2fe4f3cdf54d7 100644
--- a/drivers/cpuidle/cpuidle.c
+++ b/drivers/cpuidle/cpuidle.c
@@ -153,7 +153,8 @@ static void enter_s2idle_proper(struct cpuidle_driver *drv,
*/
stop_critical_timings();
drv->states[index].enter_s2idle(dev, drv, index);
- WARN_ON(!irqs_disabled());
+ if (WARN_ON_ONCE(!irqs_disabled()))
+ local_irq_disable();
/*
* timekeeping_resume() that will be called by tick_unfreeze() for the
* first CPU executing it calls functions containing RCU read-side
--
2.25.1
From: Vineeth Pillai <[email protected]>
[ Upstream commit b46b4a8a57c377b72a98c7930a9f6969d2d4784e ]
There could be instances where a system stall prevents the timesync
packets to be consumed. And this might lead to more than one packet
pending in the ring buffer. Current code empties one packet per callback
and it might be a stale one. So drain all the packets from ring buffer
on each callback.
Signed-off-by: Vineeth Pillai <[email protected]>
Reviewed-by: Michael Kelley <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Wei Liu <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/hv/hv_util.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 1f86e8d9b018d..a4e8d96513c22 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -387,10 +387,23 @@ static void timesync_onchannelcallback(void *context)
struct ictimesync_ref_data *refdata;
u8 *time_txf_buf = util_timesynch.recv_buffer;
- vmbus_recvpacket(channel, time_txf_buf,
- HV_HYP_PAGE_SIZE, &recvlen, &requestid);
+ /*
+ * Drain the ring buffer and use the last packet to update
+ * host_ts
+ */
+ while (1) {
+ int ret = vmbus_recvpacket(channel, time_txf_buf,
+ HV_HYP_PAGE_SIZE, &recvlen,
+ &requestid);
+ if (ret) {
+ pr_warn_once("TimeSync IC pkt recv failed (Err: %d)\n",
+ ret);
+ break;
+ }
+
+ if (!recvlen)
+ break;
- if (recvlen > 0) {
icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[
sizeof(struct vmbuspipe_hdr)];
--
2.25.1
From: Ofir Bitton <[email protected]>
[ Upstream commit bc75be24fa88ef10eecaff2b2a9ada8189e5ab5d ]
During command buffer parsing, driver extracts packet id
from user buffer. Driver must validate this packet id, since it is
being used in order to extract information from internal structures.
Signed-off-by: Ofir Bitton <[email protected]>
Reviewed-by: Oded Gabbay <[email protected]>
Signed-off-by: Oded Gabbay <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/misc/habanalabs/gaudi/gaudi.c | 35 +++++++++++++++++++++++++++
drivers/misc/habanalabs/goya/goya.c | 31 ++++++++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
index 637a9d608707f..0261f60df5633 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -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",
@@ -3859,6 +3882,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) {
@@ -4082,6 +4111,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) {
diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c
index 88460b2138d88..c179085ced7b8 100644
--- a/drivers/misc/habanalabs/goya/goya.c
+++ b/drivers/misc/habanalabs/goya/goya.c
@@ -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,
@@ -3381,6 +3400,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) {
@@ -3616,6 +3641,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) {
--
2.25.1
From: Ray Jui <[email protected]>
[ Upstream commit 0204081128d582965e9e39ca83ee6e4f7d27142b ]
Fix undefined behaviour in the iProc I2C driver by using 'BIT' marcro.
Reported-by: Wolfram Sang <[email protected]>
Signed-off-by: Ray Jui <[email protected]>
Acked-by: Florian Fainelli <[email protected]>
[wsa: in commit msg, don't say 'checkpatch' but name the issue]
Signed-off-by: Wolfram Sang <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/i2c/busses/i2c-bcm-iproc.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/i2c/busses/i2c-bcm-iproc.c b/drivers/i2c/busses/i2c-bcm-iproc.c
index 688e928188214..d8295b1c379d1 100644
--- a/drivers/i2c/busses/i2c-bcm-iproc.c
+++ b/drivers/i2c/busses/i2c-bcm-iproc.c
@@ -720,7 +720,7 @@ static int bcm_iproc_i2c_xfer_internal(struct bcm_iproc_i2c_dev *iproc_i2c,
/* mark the last byte */
if (!process_call && (i == msg->len - 1))
- val |= 1 << M_TX_WR_STATUS_SHIFT;
+ val |= BIT(M_TX_WR_STATUS_SHIFT);
iproc_i2c_wr_reg(iproc_i2c, M_TX_OFFSET, val);
}
@@ -738,7 +738,7 @@ static int bcm_iproc_i2c_xfer_internal(struct bcm_iproc_i2c_dev *iproc_i2c,
*/
addr = i2c_8bit_addr_from_msg(msg);
/* mark it the last byte out */
- val = addr | (1 << M_TX_WR_STATUS_SHIFT);
+ val = addr | BIT(M_TX_WR_STATUS_SHIFT);
iproc_i2c_wr_reg(iproc_i2c, M_TX_OFFSET, val);
}
--
2.25.1
From: Ofir Bitton <[email protected]>
[ Upstream commit 0839152f8c1efc1cc2d515d1ff1e253ca9402ad3 ]
vmalloc can return different return code than NULL and a valid
pointer. We must validate it in order to dereference a non valid
pointer.
Signed-off-by: Ofir Bitton <[email protected]>
Signed-off-by: Oded Gabbay <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/misc/habanalabs/memory.c | 9 +++++++--
drivers/misc/habanalabs/mmu.c | 2 +-
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/habanalabs/memory.c b/drivers/misc/habanalabs/memory.c
index 47da84a177197..e30b1b1877efa 100644
--- a/drivers/misc/habanalabs/memory.c
+++ b/drivers/misc/habanalabs/memory.c
@@ -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;
}
diff --git a/drivers/misc/habanalabs/mmu.c b/drivers/misc/habanalabs/mmu.c
index a290d6b49d788..eb582bd4937ba 100644
--- a/drivers/misc/habanalabs/mmu.c
+++ b/drivers/misc/habanalabs/mmu.c
@@ -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;
}
--
2.25.1
From: Oded Gabbay <[email protected]>
[ Upstream commit 58361aae4b0eed388680a89ac153d27177f40510 ]
In Gaudi, the default max power setting is different between PCI and PMC
cards. Therefore, the driver need to set the default after knowing what is
the card type.
The current code has a bug where it limits the maximum power of the PMC
card to 200W after a reset occurs.
Signed-off-by: Oded Gabbay <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/misc/habanalabs/device.c | 7 ++++++-
drivers/misc/habanalabs/gaudi/gaudi.c | 11 ++++++++++-
drivers/misc/habanalabs/gaudi/gaudiP.h | 3 ++-
drivers/misc/habanalabs/habanalabs.h | 5 ++++-
drivers/misc/habanalabs/sysfs.c | 7 ++++---
5 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/drivers/misc/habanalabs/device.c b/drivers/misc/habanalabs/device.c
index 59608d1bac880..baa4e66d4c457 100644
--- a/drivers/misc/habanalabs/device.c
+++ b/drivers/misc/habanalabs/device.c
@@ -1027,7 +1027,7 @@ int hl_device_reset(struct hl_device *hdev, bool hard_reset,
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) {
@@ -1268,6 +1268,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
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
index 8b6cf722ddf8e..ca183733847b6 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -447,7 +447,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;
@@ -6241,6 +6241,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;
}
diff --git a/drivers/misc/habanalabs/gaudi/gaudiP.h b/drivers/misc/habanalabs/gaudi/gaudiP.h
index 41a8d9bff6bf9..00f1efeaa8832 100644
--- a/drivers/misc/habanalabs/gaudi/gaudiP.h
+++ b/drivers/misc/habanalabs/gaudi/gaudiP.h
@@ -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 */
diff --git a/drivers/misc/habanalabs/habanalabs.h b/drivers/misc/habanalabs/habanalabs.h
index feedf3194ea6c..1072f300252a4 100644
--- a/drivers/misc/habanalabs/habanalabs.h
+++ b/drivers/misc/habanalabs/habanalabs.h
@@ -1408,6 +1408,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.
@@ -1503,6 +1505,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;
@@ -1792,7 +1795,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,
diff --git a/drivers/misc/habanalabs/sysfs.c b/drivers/misc/habanalabs/sysfs.c
index 70b6b1863c2ef..87dadb53ac59d 100644
--- a/drivers/misc/habanalabs/sysfs.c
+++ b/drivers/misc/habanalabs/sysfs.c
@@ -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;
@@ -419,6 +419,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);
--
2.25.1
From: Bob Peterson <[email protected]>
[ Upstream commit 462582b99b6079a6fbcdfc65bac49f5c2a27cfff ]
When a log flush fails due to io errors, it signals the failure but does
not clean up after itself very well. This is because buffers are added to
the transaction tr_buf and tr_databuf queue, but the io error causes
gfs2_log_flush to bypass the "after_commit" functions responsible for
dequeueing the bd elements. If the bd elements are added to the ail list
before the error, function ail_drain takes care of dequeueing them.
But if they haven't gotten that far, the elements are forgotten and
make the transactions unable to be freed.
This patch introduces new function trans_drain which drains the bd
elements from the transaction so they can be freed properly.
Signed-off-by: Bob Peterson <[email protected]>
Signed-off-by: Andreas Gruenbacher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
fs/gfs2/log.c | 31 +++++++++++++++++++++++++++++++
fs/gfs2/trans.c | 1 +
2 files changed, 32 insertions(+)
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index a76e55bc28ebf..27f467a0f008e 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -901,6 +901,36 @@ static void empty_ail1_list(struct gfs2_sbd *sdp)
}
}
+/**
+ * drain_bd - drain the buf and databuf queue for a failed transaction
+ * @tr: the transaction to drain
+ *
+ * When this is called, we're taking an error exit for a log write that failed
+ * but since we bypassed the after_commit functions, we need to remove the
+ * items from the buf and databuf queue.
+ */
+static void trans_drain(struct gfs2_trans *tr)
+{
+ struct gfs2_bufdata *bd;
+ struct list_head *head;
+
+ if (!tr)
+ return;
+
+ head = &tr->tr_buf;
+ while (!list_empty(head)) {
+ bd = list_first_entry(head, struct gfs2_bufdata, bd_list);
+ list_del_init(&bd->bd_list);
+ kmem_cache_free(gfs2_bufdata_cachep, bd);
+ }
+ head = &tr->tr_databuf;
+ while (!list_empty(head)) {
+ bd = list_first_entry(head, struct gfs2_bufdata, bd_list);
+ list_del_init(&bd->bd_list);
+ kmem_cache_free(gfs2_bufdata_cachep, bd);
+ }
+}
+
/**
* gfs2_log_flush - flush incore transaction(s)
* @sdp: the filesystem
@@ -1005,6 +1035,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
out:
if (gfs2_withdrawn(sdp)) {
+ trans_drain(tr);
/**
* If the tr_list is empty, we're withdrawing during a log
* flush that targets a transaction, but the transaction was
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index a3dfa3aa87ad9..d897dd73c5999 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -52,6 +52,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
tr->tr_reserved += gfs2_struct2blk(sdp, revokes);
INIT_LIST_HEAD(&tr->tr_databuf);
INIT_LIST_HEAD(&tr->tr_buf);
+ INIT_LIST_HEAD(&tr->tr_list);
INIT_LIST_HEAD(&tr->tr_ail1_list);
INIT_LIST_HEAD(&tr->tr_ail2_list);
--
2.25.1
From: Ofir Bitton <[email protected]>
[ Upstream commit f1aae40e8dbd2655e3b10cae381a1e8292b19d57 ]
In case the driver fails to configure the PCI controller iATU, it needs to
unmap the PCI bars before exiting so if the driver is removed, the bars
won't be left mapped.
Signed-off-by: Ofir Bitton <[email protected]>
Reviewed-by: Oded Gabbay <[email protected]>
Signed-off-by: Oded Gabbay <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/misc/habanalabs/pci.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/habanalabs/pci.c b/drivers/misc/habanalabs/pci.c
index 9f634ef6f5b37..77022c0b42027 100644
--- a/drivers/misc/habanalabs/pci.c
+++ b/drivers/misc/habanalabs/pci.c
@@ -378,15 +378,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);
--
2.25.1
From: Keith Busch <[email protected]>
[ Upstream commit c41ad98bebb8f4f0335b3c50dbb7583a6149dce4 ]
Zoned block devices reuse the chunk_sectors queue limit to define zone
boundaries. If a such a device happens to also report an optimal
boundary, do not use that to define the chunk_sectors as that may
intermittently interfere with io splitting and zone size queries.
Signed-off-by: Keith Busch <[email protected]>
Signed-off-by: Sagi Grimberg <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/nvme/host/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index f38548e6d55ec..6ea0bab621df3 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1975,7 +1975,7 @@ static int __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)
}
}
- if (iob)
+ if (iob && !blk_queue_is_zoned(ns->queue))
blk_queue_chunk_sectors(ns->queue, rounddown_pow_of_two(iob));
nvme_update_disk_info(disk, ns, id);
#ifdef CONFIG_NVME_MULTIPATH
--
2.25.1
From: Jeff Layton <[email protected]>
[ Upstream commit ebce3eb2f7ef9f6ef01a60874ebd232450107c9a ]
Tuan and Ulrich mentioned that they were hitting a problem on s390x,
which has a 32-bit ino_t value, even though it's a 64-bit arch (for
historical reasons).
I think the current handling of inode numbers in the ceph driver is
wrong. It tries to use 32-bit inode numbers on 32-bit arches, but that's
actually not a problem. 32-bit arches can deal with 64-bit inode numbers
just fine when userland code is compiled with LFS support (the common
case these days).
What we really want to do is just use 64-bit numbers everywhere, unless
someone has mounted with the ino32 mount option. In that case, we want
to ensure that we hash the inode number down to something that will fit
in 32 bits before presenting the value to userland.
Add new helper functions that do this, and only do the conversion before
presenting these values to userland in getattr and readdir.
The inode table hashvalue is changed to just cast the inode number to
unsigned long, as low-order bits are the most likely to vary anyway.
While it's not strictly required, we do want to put something in
inode->i_ino. Instead of basing it on BITS_PER_LONG, however, base it on
the size of the ino_t type.
NOTE: This is a user-visible change on 32-bit arches:
1/ inode numbers will be seen to have changed between kernel versions.
32-bit arches will see large inode numbers now instead of the hashed
ones they saw before.
2/ any really old software not built with LFS support may start failing
stat() calls with -EOVERFLOW on inode numbers >2^32. Nothing much we
can do about these, but hopefully the intersection of people running
such code on ceph will be very small.
The workaround for both problems is to mount with "-o ino32".
[ idryomov: changelog tweak ]
URL: https://tracker.ceph.com/issues/46828
Reported-by: Ulrich Weigand <[email protected]>
Reported-and-Tested-by: Tuan Hoang1 <[email protected]>
Signed-off-by: Jeff Layton <[email protected]>
Reviewed-by: "Yan, Zheng" <[email protected]>
Signed-off-by: Ilya Dryomov <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
fs/ceph/caps.c | 14 ++++-----
fs/ceph/debugfs.c | 4 +--
fs/ceph/dir.c | 31 ++++++++-----------
fs/ceph/file.c | 4 +--
fs/ceph/inode.c | 19 ++++++------
fs/ceph/mds_client.h | 2 +-
fs/ceph/quota.c | 4 +--
fs/ceph/super.h | 73 +++++++++++++++++++++++---------------------
8 files changed, 74 insertions(+), 77 deletions(-)
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
index 972c13aa42259..1206a481c5fc7 100644
--- a/fs/ceph/caps.c
+++ b/fs/ceph/caps.c
@@ -886,8 +886,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
int have = ci->i_snap_caps;
if ((have & mask) == mask) {
- dout("__ceph_caps_issued_mask ino 0x%lx snap issued %s"
- " (mask %s)\n", ci->vfs_inode.i_ino,
+ dout("__ceph_caps_issued_mask ino 0x%llx snap issued %s"
+ " (mask %s)\n", ceph_ino(&ci->vfs_inode),
ceph_cap_string(have),
ceph_cap_string(mask));
return 1;
@@ -898,8 +898,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
if (!__cap_is_valid(cap))
continue;
if ((cap->issued & mask) == mask) {
- dout("__ceph_caps_issued_mask ino 0x%lx cap %p issued %s"
- " (mask %s)\n", ci->vfs_inode.i_ino, cap,
+ dout("__ceph_caps_issued_mask ino 0x%llx cap %p issued %s"
+ " (mask %s)\n", ceph_ino(&ci->vfs_inode), cap,
ceph_cap_string(cap->issued),
ceph_cap_string(mask));
if (touch)
@@ -910,8 +910,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
/* does a combination of caps satisfy mask? */
have |= cap->issued;
if ((have & mask) == mask) {
- dout("__ceph_caps_issued_mask ino 0x%lx combo issued %s"
- " (mask %s)\n", ci->vfs_inode.i_ino,
+ dout("__ceph_caps_issued_mask ino 0x%llx combo issued %s"
+ " (mask %s)\n", ceph_ino(&ci->vfs_inode),
ceph_cap_string(cap->issued),
ceph_cap_string(mask));
if (touch) {
@@ -2870,7 +2870,7 @@ int ceph_get_caps(struct file *filp, int need, int want,
struct cap_wait cw;
DEFINE_WAIT_FUNC(wait, woken_wake_function);
- cw.ino = inode->i_ino;
+ cw.ino = ceph_ino(inode);
cw.tgid = current->tgid;
cw.need = need;
cw.want = want;
diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
index 070ed84813406..74747d8d48619 100644
--- a/fs/ceph/debugfs.c
+++ b/fs/ceph/debugfs.c
@@ -212,7 +212,7 @@ static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
{
struct seq_file *s = p;
- seq_printf(s, "0x%-17lx%-17s%-17s\n", inode->i_ino,
+ seq_printf(s, "0x%-17llx%-17s%-17s\n", ceph_ino(inode),
ceph_cap_string(cap->issued),
ceph_cap_string(cap->implemented));
return 0;
@@ -257,7 +257,7 @@ static int caps_show(struct seq_file *s, void *p)
spin_lock(&mdsc->caps_list_lock);
list_for_each_entry(cw, &mdsc->cap_wait_list, list) {
- seq_printf(s, "%-13d0x%-17lx%-17s%-17s\n", cw->tgid, cw->ino,
+ seq_printf(s, "%-13d0x%-17llx%-17s%-17s\n", cw->tgid, cw->ino,
ceph_cap_string(cw->need),
ceph_cap_string(cw->want));
}
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
index 060bdcc5ce32c..040eaad9d0631 100644
--- a/fs/ceph/dir.c
+++ b/fs/ceph/dir.c
@@ -259,9 +259,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx,
dentry, dentry, d_inode(dentry));
ctx->pos = di->offset;
if (!dir_emit(ctx, dentry->d_name.name,
- dentry->d_name.len,
- ceph_translate_ino(dentry->d_sb,
- d_inode(dentry)->i_ino),
+ dentry->d_name.len, ceph_present_inode(d_inode(dentry)),
d_inode(dentry)->i_mode >> 12)) {
dput(dentry);
err = 0;
@@ -324,18 +322,21 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
/* always start with . and .. */
if (ctx->pos == 0) {
dout("readdir off 0 -> '.'\n");
- if (!dir_emit(ctx, ".", 1,
- ceph_translate_ino(inode->i_sb, inode->i_ino),
+ if (!dir_emit(ctx, ".", 1, ceph_present_inode(inode),
inode->i_mode >> 12))
return 0;
ctx->pos = 1;
}
if (ctx->pos == 1) {
- ino_t ino = parent_ino(file->f_path.dentry);
+ u64 ino;
+ struct dentry *dentry = file->f_path.dentry;
+
+ spin_lock(&dentry->d_lock);
+ ino = ceph_present_inode(dentry->d_parent->d_inode);
+ spin_unlock(&dentry->d_lock);
+
dout("readdir off 1 -> '..'\n");
- if (!dir_emit(ctx, "..", 2,
- ceph_translate_ino(inode->i_sb, ino),
- inode->i_mode >> 12))
+ if (!dir_emit(ctx, "..", 2, ino, inode->i_mode >> 12))
return 0;
ctx->pos = 2;
}
@@ -507,9 +508,6 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
}
for (; i < rinfo->dir_nr; i++) {
struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
- struct ceph_vino vino;
- ino_t ino;
- u32 ftype;
BUG_ON(rde->offset < ctx->pos);
@@ -519,13 +517,10 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
rde->name_len, rde->name, &rde->inode.in);
BUG_ON(!rde->inode.in);
- ftype = le32_to_cpu(rde->inode.in->mode) >> 12;
- vino.ino = le64_to_cpu(rde->inode.in->ino);
- vino.snap = le64_to_cpu(rde->inode.in->snapid);
- ino = ceph_vino_to_ino(vino);
if (!dir_emit(ctx, rde->name, rde->name_len,
- ceph_translate_ino(inode->i_sb, ino), ftype)) {
+ ceph_present_ino(inode->i_sb, le64_to_cpu(rde->inode.in->ino)),
+ le32_to_cpu(rde->inode.in->mode) >> 12)) {
dout("filldir stopping us...\n");
return 0;
}
@@ -1161,7 +1156,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
if (try_async && op == CEPH_MDS_OP_UNLINK &&
(req->r_dir_caps = get_caps_for_async_unlink(dir, dentry))) {
- dout("async unlink on %lu/%.*s caps=%s", dir->i_ino,
+ dout("async unlink on %llu/%.*s caps=%s", ceph_ino(dir),
dentry->d_name.len, dentry->d_name.name,
ceph_cap_string(req->r_dir_caps));
set_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags);
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 160644ddaeed7..26172bb90a459 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -630,8 +630,8 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
} else {
struct dentry *dn;
- dout("%s d_adding new inode 0x%llx to 0x%lx/%s\n", __func__,
- vino.ino, dir->i_ino, dentry->d_name.name);
+ dout("%s d_adding new inode 0x%llx to 0x%llx/%s\n", __func__,
+ vino.ino, ceph_ino(dir), dentry->d_name.name);
ceph_dir_clear_ordered(dir);
ceph_init_inode_acls(inode, as_ctx);
if (inode->i_state & I_NEW) {
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 357c937699d56..d163fa96cb401 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -41,8 +41,10 @@ static void ceph_inode_work(struct work_struct *work);
*/
static int ceph_set_ino_cb(struct inode *inode, void *data)
{
- ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
- inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
+ struct ceph_inode_info *ci = ceph_inode(inode);
+
+ ci->i_vino = *(struct ceph_vino *)data;
+ inode->i_ino = ceph_vino_to_ino_t(ci->i_vino);
inode_set_iversion_raw(inode, 0);
return 0;
}
@@ -50,17 +52,14 @@ static int ceph_set_ino_cb(struct inode *inode, void *data)
struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
{
struct inode *inode;
- ino_t t = ceph_vino_to_ino(vino);
- inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino);
+ inode = iget5_locked(sb, (unsigned long)vino.ino, ceph_ino_compare,
+ ceph_set_ino_cb, &vino);
if (!inode)
return ERR_PTR(-ENOMEM);
- if (inode->i_state & I_NEW)
- dout("get_inode created new inode %p %llx.%llx ino %llx\n",
- inode, ceph_vinop(inode), (u64)inode->i_ino);
- dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino,
- vino.snap, inode);
+ dout("get_inode on %llu=%llx.%llx got %p new %d\n", ceph_present_inode(inode),
+ ceph_vinop(inode), inode, !!(inode->i_state & I_NEW));
return inode;
}
@@ -2378,7 +2377,7 @@ int ceph_getattr(const struct path *path, struct kstat *stat,
}
generic_fillattr(inode, stat);
- stat->ino = ceph_translate_ino(inode->i_sb, inode->i_ino);
+ stat->ino = ceph_present_inode(inode);
/*
* btime on newly-allocated inodes is 0, so if this is still set to
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 5e0c4073a6bea..63c9cd1c28d6c 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -369,7 +369,7 @@ struct ceph_quotarealm_inode {
struct cap_wait {
struct list_head list;
- unsigned long ino;
+ u64 ino;
pid_t tgid;
int need;
int want;
diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c
index 198ddde5c1e6a..cc2c4d40b0222 100644
--- a/fs/ceph/quota.c
+++ b/fs/ceph/quota.c
@@ -23,12 +23,12 @@ static inline bool ceph_has_realms_with_quotas(struct inode *inode)
{
struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
struct super_block *sb = mdsc->fsc->sb;
+ struct inode *root = d_inode(sb->s_root);
if (atomic64_read(&mdsc->quotarealms_count) > 0)
return true;
/* if root is the real CephFS root, we don't have quota realms */
- if (sb->s_root->d_inode &&
- (sb->s_root->d_inode->i_ino == CEPH_INO_ROOT))
+ if (root && ceph_ino(root) == CEPH_INO_ROOT)
return false;
/* otherwise, we can't know for sure */
return true;
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index 5a6cdd39bc103..2af3e06a6d0ce 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -457,15 +457,7 @@ ceph_vino(const struct inode *inode)
return ceph_inode(inode)->i_vino;
}
-/*
- * ino_t is <64 bits on many architectures, blech.
- *
- * i_ino (kernel inode) st_ino (userspace)
- * i386 32 32
- * x86_64+ino32 64 32
- * x86_64 64 64
- */
-static inline u32 ceph_ino_to_ino32(__u64 vino)
+static inline u32 ceph_ino_to_ino32(u64 vino)
{
u32 ino = vino & 0xffffffff;
ino ^= vino >> 32;
@@ -475,34 +467,17 @@ static inline u32 ceph_ino_to_ino32(__u64 vino)
}
/*
- * kernel i_ino value
+ * Inode numbers in cephfs are 64 bits, but inode->i_ino is 32-bits on
+ * some arches. We generally do not use this value inside the ceph driver, but
+ * we do want to set it to something, so that generic vfs code has an
+ * appropriate value for tracepoints and the like.
*/
-static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
+static inline ino_t ceph_vino_to_ino_t(struct ceph_vino vino)
{
-#if BITS_PER_LONG == 32
- return ceph_ino_to_ino32(vino.ino);
-#else
+ if (sizeof(ino_t) == sizeof(u32))
+ return ceph_ino_to_ino32(vino.ino);
return (ino_t)vino.ino;
-#endif
-}
-
-/*
- * user-visible ino (stat, filldir)
- */
-#if BITS_PER_LONG == 32
-static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
-{
- return ino;
-}
-#else
-static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
-{
- if (ceph_test_mount_opt(ceph_sb_to_client(sb), INO32))
- ino = ceph_ino_to_ino32(ino);
- return ino;
}
-#endif
-
/* for printf-style formatting */
#define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap
@@ -511,11 +486,34 @@ static inline u64 ceph_ino(struct inode *inode)
{
return ceph_inode(inode)->i_vino.ino;
}
+
static inline u64 ceph_snap(struct inode *inode)
{
return ceph_inode(inode)->i_vino.snap;
}
+/**
+ * ceph_present_ino - format an inode number for presentation to userland
+ * @sb: superblock where the inode lives
+ * @ino: inode number to (possibly) convert
+ *
+ * If the user mounted with the ino32 option, then the 64-bit value needs
+ * to be converted to something that can fit inside 32 bits. Note that
+ * internal kernel code never uses this value, so this is entirely for
+ * userland consumption.
+ */
+static inline u64 ceph_present_ino(struct super_block *sb, u64 ino)
+{
+ if (unlikely(ceph_test_mount_opt(ceph_sb_to_client(sb), INO32)))
+ return ceph_ino_to_ino32(ino);
+ return ino;
+}
+
+static inline u64 ceph_present_inode(struct inode *inode)
+{
+ return ceph_present_ino(inode->i_sb, ceph_ino(inode));
+}
+
static inline int ceph_ino_compare(struct inode *inode, void *data)
{
struct ceph_vino *pvino = (struct ceph_vino *)data;
@@ -524,11 +522,16 @@ static inline int ceph_ino_compare(struct inode *inode, void *data)
ci->i_vino.snap == pvino->snap;
}
+
static inline struct inode *ceph_find_inode(struct super_block *sb,
struct ceph_vino vino)
{
- ino_t t = ceph_vino_to_ino(vino);
- return ilookup5(sb, t, ceph_ino_compare, &vino);
+ /*
+ * NB: The hashval will be run through the fs/inode.c hash function
+ * anyway, so there is no need to squash the inode number down to
+ * 32-bits first. Just use low-order bits on arches with 32-bit long.
+ */
+ return ilookup5(sb, (unsigned long)vino.ino, ceph_ino_compare, &vino);
}
--
2.25.1
From: Jeff Layton <[email protected]>
[ Upstream commit 496ceaf12432b3d136dcdec48424312e71359ea7 ]
Leases don't currently work correctly on kcephfs, as they are not broken
when caps are revoked. They could eventually be implemented similarly to
how we did them in libcephfs, but for now don't allow them.
[ idryomov: no need for simple_nosetlease() in ceph_dir_fops and
ceph_snapdir_fops ]
Signed-off-by: Jeff Layton <[email protected]>
Reviewed-by: Ilya Dryomov <[email protected]>
Signed-off-by: Ilya Dryomov <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
fs/ceph/file.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/fs/ceph/file.c b/fs/ceph/file.c
index 26172bb90a459..c53c1499f7c58 100644
--- a/fs/ceph/file.c
+++ b/fs/ceph/file.c
@@ -2506,6 +2506,7 @@ const struct file_operations ceph_file_fops = {
.mmap = ceph_mmap,
.fsync = ceph_fsync,
.lock = ceph_lock,
+ .setlease = simple_nosetlease,
.flock = ceph_flock,
.splice_read = generic_file_splice_read,
.splice_write = iter_file_splice_write,
--
2.25.1
From: Vineeth Pillai <[email protected]>
[ Upstream commit 90b125f4cd2697f949f5877df723a0b710693dd0 ]
If for any reason, host timesync messages were not processed by
the guest, hv_ptp_gettime() returns a stale value and the
caller (clock_gettime, PTP ioctl etc) has no means to know this
now. Return an error so that the caller knows about this.
Signed-off-by: Vineeth Pillai <[email protected]>
Reviewed-by: Michael Kelley <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Wei Liu <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/hv/hv_util.c | 46 +++++++++++++++++++++++++++++++++-----------
1 file changed, 35 insertions(+), 11 deletions(-)
diff --git a/drivers/hv/hv_util.c b/drivers/hv/hv_util.c
index 92ee0fe4c919e..1f86e8d9b018d 100644
--- a/drivers/hv/hv_util.c
+++ b/drivers/hv/hv_util.c
@@ -282,26 +282,52 @@ static struct {
spinlock_t lock;
} host_ts;
-static struct timespec64 hv_get_adj_host_time(void)
+static inline u64 reftime_to_ns(u64 reftime)
{
- struct timespec64 ts;
- u64 newtime, reftime;
+ return (reftime - WLTIMEDELTA) * 100;
+}
+
+/*
+ * Hard coded threshold for host timesync delay: 600 seconds
+ */
+static const u64 HOST_TIMESYNC_DELAY_THRESH = 600 * (u64)NSEC_PER_SEC;
+
+static int hv_get_adj_host_time(struct timespec64 *ts)
+{
+ u64 newtime, reftime, timediff_adj;
unsigned long flags;
+ int ret = 0;
spin_lock_irqsave(&host_ts.lock, flags);
reftime = hv_read_reference_counter();
- newtime = host_ts.host_time + (reftime - host_ts.ref_time);
- ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100);
+
+ /*
+ * We need to let the caller know that last update from host
+ * is older than the max allowable threshold. clock_gettime()
+ * and PTP ioctl do not have a documented error that we could
+ * return for this specific case. Use ESTALE to report this.
+ */
+ timediff_adj = reftime - host_ts.ref_time;
+ if (timediff_adj * 100 > HOST_TIMESYNC_DELAY_THRESH) {
+ pr_warn_once("TIMESYNC IC: Stale time stamp, %llu nsecs old\n",
+ (timediff_adj * 100));
+ ret = -ESTALE;
+ }
+
+ newtime = host_ts.host_time + timediff_adj;
+ *ts = ns_to_timespec64(reftime_to_ns(newtime));
spin_unlock_irqrestore(&host_ts.lock, flags);
- return ts;
+ return ret;
}
static void hv_set_host_time(struct work_struct *work)
{
- struct timespec64 ts = hv_get_adj_host_time();
- do_settimeofday64(&ts);
+ struct timespec64 ts;
+
+ if (!hv_get_adj_host_time(&ts))
+ do_settimeofday64(&ts);
}
/*
@@ -622,9 +648,7 @@ static int hv_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)
static int hv_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
{
- *ts = hv_get_adj_host_time();
-
- return 0;
+ return hv_get_adj_host_time(ts);
}
static struct ptp_clock_info ptp_hyperv_info = {
--
2.25.1
From: Dmitry Baryshkov <[email protected]>
[ Upstream commit f5749d6181fa7df5ae741788e5d96f593d3a60b6 ]
New Qualcomm firmware has changed a way it reports back the 'started'
event. Support new register values.
Signed-off-by: Dmitry Baryshkov <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/msm/adreno/a6xx_gmu.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
index 1d330204c465c..2dd1cf1ffbe25 100644
--- a/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
+++ b/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
@@ -207,6 +207,16 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu)
{
int ret;
u32 val;
+ u32 mask, reset_val;
+
+ val = gmu_read(gmu, REG_A6XX_GMU_CM3_DTCM_START + 0xff8);
+ if (val <= 0x20010004) {
+ mask = 0xffffffff;
+ reset_val = 0xbabeface;
+ } else {
+ mask = 0x1ff;
+ reset_val = 0x100;
+ }
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 1);
@@ -218,7 +228,7 @@ static int a6xx_gmu_start(struct a6xx_gmu *gmu)
gmu_write(gmu, REG_A6XX_GMU_CM3_SYSRESET, 0);
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_CM3_FW_INIT_RESULT, val,
- val == 0xbabeface, 100, 10000);
+ (val & mask) == reset_val, 100, 10000);
if (ret)
DRM_DEV_ERROR(gmu->dev, "GMU firmware initialization timed out\n");
--
2.25.1
From: Amit Engel <[email protected]>
[ Upstream commit 0d3b6a8d213a30387b5104b2fb25376d18636f23 ]
Based on nvme spec, when keep alive timeout is set to zero
the keep-alive timer should be disabled.
Signed-off-by: Amit Engel <[email protected]>
Signed-off-by: Sagi Grimberg <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/nvme/target/core.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 6e2f623e472e9..58b035cc67a01 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -396,6 +396,9 @@ static void nvmet_keep_alive_timer(struct work_struct *work)
static void nvmet_start_keep_alive_timer(struct nvmet_ctrl *ctrl)
{
+ if (unlikely(ctrl->kato == 0))
+ return;
+
pr_debug("ctrl %d start keep-alive timer for %d secs\n",
ctrl->cntlid, ctrl->kato);
@@ -405,6 +408,9 @@ static void nvmet_start_keep_alive_timer(struct nvmet_ctrl *ctrl)
static void nvmet_stop_keep_alive_timer(struct nvmet_ctrl *ctrl)
{
+ if (unlikely(ctrl->kato == 0))
+ return;
+
pr_debug("ctrl %d stop keep-alive\n", ctrl->cntlid);
cancel_delayed_work_sync(&ctrl->ka_work);
--
2.25.1
From: Ofir Bitton <[email protected]>
[ Upstream commit f44d23b9095abd91dad9f5f3add2a3149833ec83 ]
Once clock gating is set we enable clock gating according to mask,
we should also disable clock gating according to relevant bits.
Signed-off-by: Ofir Bitton <[email protected]>
Reviewed-by: Oded Gabbay <[email protected]>
Signed-off-by: Oded Gabbay <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/misc/habanalabs/gaudi/gaudi.c | 44 +++++++++++++--------------
1 file changed, 21 insertions(+), 23 deletions(-)
diff --git a/drivers/misc/habanalabs/gaudi/gaudi.c b/drivers/misc/habanalabs/gaudi/gaudi.c
index 0261f60df5633..8b6cf722ddf8e 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi.c
@@ -2564,6 +2564,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
@@ -2573,46 +2574,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;
}
--
2.25.1
From: Rob Clark <[email protected]>
[ Upstream commit 35c719da95c0d28560bff7bafeaf07ebb212665e ]
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c:817 dpu_crtc_enable() error: uninitialized symbol 'request_bandwidth'.
Reported-by: kernel test robot <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
Reviewed-by: Sean Paul <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 969d95aa873c4..1026e1e5bec10 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -827,7 +827,7 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
{
struct dpu_crtc *dpu_crtc;
struct drm_encoder *encoder;
- bool request_bandwidth;
+ bool request_bandwidth = false;
if (!crtc) {
DPU_ERROR("invalid crtc\n");
--
2.25.1
From: Rob Clark <[email protected]>
[ Upstream commit 43906812eaab06423f56af5cca9a9fcdbb4ac454 ]
This has roughly the same effect as drm_atomic_helper_wait_for_vblanks(),
basically just ensuring that vblank accounting is enabled so that we get
valid timestamp/seqn on pageflip events.
Signed-off-by: Rob Clark <[email protected]>
Tested-by: Stephen Boyd <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/msm/msm_atomic.c | 36 ++++++++++++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index 5ccfad794c6a5..561bfa48841c3 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -27,6 +27,34 @@ int msm_atomic_prepare_fb(struct drm_plane *plane,
return msm_framebuffer_prepare(new_state->fb, kms->aspace);
}
+/*
+ * Helpers to control vblanks while we flush.. basically just to ensure
+ * that vblank accounting is switched on, so we get valid seqn/timestamp
+ * on pageflip events (if requested)
+ */
+
+static void vblank_get(struct msm_kms *kms, unsigned crtc_mask)
+{
+ struct drm_crtc *crtc;
+
+ for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
+ if (!crtc->state->active)
+ continue;
+ drm_crtc_vblank_get(crtc);
+ }
+}
+
+static void vblank_put(struct msm_kms *kms, unsigned crtc_mask)
+{
+ struct drm_crtc *crtc;
+
+ for_each_crtc_mask(kms->dev, crtc, crtc_mask) {
+ if (!crtc->state->active)
+ continue;
+ drm_crtc_vblank_put(crtc);
+ }
+}
+
static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
{
unsigned crtc_mask = BIT(crtc_idx);
@@ -44,6 +72,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
kms->funcs->enable_commit(kms);
+ vblank_get(kms, crtc_mask);
+
/*
* Flush hardware updates:
*/
@@ -58,6 +88,8 @@ static void msm_atomic_async_commit(struct msm_kms *kms, int crtc_idx)
kms->funcs->wait_flush(kms, crtc_mask);
trace_msm_atomic_wait_flush_finish(crtc_mask);
+ vblank_put(kms, crtc_mask);
+
mutex_lock(&kms->commit_lock);
kms->funcs->complete_commit(kms, crtc_mask);
mutex_unlock(&kms->commit_lock);
@@ -221,6 +253,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
*/
kms->pending_crtc_mask &= ~crtc_mask;
+ vblank_get(kms, crtc_mask);
+
/*
* Flush hardware updates:
*/
@@ -235,6 +269,8 @@ void msm_atomic_commit_tail(struct drm_atomic_state *state)
kms->funcs->wait_flush(kms, crtc_mask);
trace_msm_atomic_wait_flush_finish(crtc_mask);
+ vblank_put(kms, crtc_mask);
+
mutex_lock(&kms->commit_lock);
kms->funcs->complete_commit(kms, crtc_mask);
mutex_unlock(&kms->commit_lock);
--
2.25.1
From: Kalyan Thota <[email protected]>
[ Upstream commit 4c978caf08aa155bdeadd9e2d4b026d4ce97ebd0 ]
Plane validation uses an API drm_calc_scale which will
return src/dst value as a scale ratio.
when viewing the range on a scale the values should fall in as
Upscale ratio < Unity scale < Downscale ratio for src/dst formula
Fix the min and max scale ratios to suit the API accordingly.
Signed-off-by: Kalyan Thota <[email protected]>
Tested-by: Kristian H. Kristensen <[email protected]>
Reviewed-by: Kristian H. Kristensen <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3b9c33e694bf4..994d23bad3870 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -866,9 +866,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
crtc_state = drm_atomic_get_new_crtc_state(state->state,
state->crtc);
- min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxdwnscale);
+ min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale);
ret = drm_atomic_helper_check_plane_state(state, crtc_state, min_scale,
- pdpu->pipe_sblk->maxupscale << 16,
+ pdpu->pipe_sblk->maxdwnscale << 16,
true, true);
if (ret) {
DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
--
2.25.1
From: John Stultz <[email protected]>
[ Upstream commit 975efc66d4e654207c17f939eb737ac591ac38fe ]
When booting with heavily modularized config, the serial console
may not be able to load until after init when modules that
satisfy needed dependencies have time to load.
Unfortunately, as qcom_geni_console_setup is marked as __init,
the function may have been freed before we get to run it,
causing boot time crashes such as:
[ 6.469057] Unable to handle kernel paging request at virtual address ffffffe645d4e6cc
[ 6.481623] Mem abort info:
[ 6.484466] ESR = 0x86000007
[ 6.487557] EC = 0x21: IABT (current EL), IL = 32 bits
[ 6.492929] SET = 0, FnV = 0g
[ 6.496016] EA = 0, S1PTW = 0
[ 6.499202] swapper pgtable: 4k pages, 39-bit VAs, pgdp=000000008151e000
[ 6.501286] ufshcd-qcom 1d84000.ufshc: ufshcd_print_pwr_info:[RX, TX]: gear=[3, 3], lane[2, 2], pwr[FAST MODE, FAST MODE], rate = 2
[ 6.505977] [ffffffe645d4e6cc] pgd=000000017df9f003, p4d=000000017df9f003, pud=000000017df9f003, pmd=000000017df9c003, pte=0000000000000000
[ 6.505990] Internal error: Oops: 86000007 [#1] PREEMPT SMP
[ 6.505995] Modules linked in: zl10353 zl10039 zl10036 zd1301_demod xc5000 xc4000 ves1x93 ves1820 tuner_xc2028 tuner_simple tuner_types tua9001 tua6100 1
[ 6.506152] isl6405
[ 6.518104] ufshcd-qcom 1d84000.ufshc: ufshcd_find_max_sup_active_icc_level: Regulator capability was not set, actvIccLevel=0
[ 6.530549] horus3a helene fc2580 fc0013 fc0012 fc0011 ec100 e4000 dvb_pll ds3000 drxk drxd drx39xyj dib9000 dib8000 dib7000p dib7000m dib3000mc dibx003
[ 6.624271] CPU: 7 PID: 148 Comm: kworker/7:2 Tainted: G W 5.8.0-mainline-12021-g6defd37ba1cd #3455
[ 6.624273] Hardware name: Thundercomm Dragonboard 845c (DT)
[ 6.624290] Workqueue: events deferred_probe_work_func
[ 6.624296] pstate: 40c00005 (nZcv daif +PAN +UAO BTYPE=--)
[ 6.624307] pc : qcom_geni_console_setup+0x0/0x110
[ 6.624316] lr : try_enable_new_console+0xa0/0x140
[ 6.624318] sp : ffffffc010843a30
[ 6.624320] x29: ffffffc010843a30 x28: ffffffe645c3e7d0
[ 6.624325] x27: ffffff80f8022180 x26: ffffffc010843b28
[ 6.637937] x25: 0000000000000000 x24: ffffffe6462a2000
[ 6.637941] x23: ffffffe646398000 x22: 0000000000000000
[ 6.637945] x21: 0000000000000000 x20: ffffffe6462a5ce8
[ 6.637952] x19: ffffffe646398e38 x18: ffffffffffffffff
[ 6.680296] x17: 0000000000000000 x16: ffffffe64492b900
[ 6.680300] x15: ffffffe6461e9d08 x14: 69202930203d2064
[ 6.680305] x13: 7561625f65736162 x12: 202c363331203d20
[ 6.696434] x11: 0000000000000030 x10: 0101010101010101
[ 6.696438] x9 : 4d4d20746120304d x8 : 7f7f7f7f7f7f7f7f
[ 6.707249] x7 : feff4c524c787373 x6 : 0000000000008080
[ 6.707253] x5 : 0000000000000000 x4 : 8080000000000000
[ 6.707257] x3 : 0000000000000000 x2 : ffffffe645d4e6cc
[ 6.744223] qcom_geni_serial 898000.serial: dev_pm_opp_set_rate: failed to find OPP for freq 102400000 (-34)
[ 6.744966] x1 : fffffffefe74e174 x0 : ffffffe6462a5ce8
[ 6.753580] qcom_geni_serial 898000.serial: dev_pm_opp_set_rate: failed to find OPP for freq 102400000 (-34)
[ 6.761634] Call trace:
[ 6.761639] qcom_geni_console_setup+0x0/0x110
[ 6.761645] register_console+0x29c/0x2f8
[ 6.767981] Bluetooth: hci0: Frame reassembly failed (-84)
[ 6.775252] uart_add_one_port+0x438/0x500
[ 6.775258] qcom_geni_serial_probe+0x2c4/0x4a8
[ 6.775266] platform_drv_probe+0x58/0xa8
[ 6.855359] really_probe+0xec/0x398
[ 6.855362] driver_probe_device+0x5c/0xb8
[ 6.855367] __device_attach_driver+0x98/0xb8
[ 7.184945] bus_for_each_drv+0x74/0xd8
[ 7.188825] __device_attach+0xec/0x148
[ 7.192705] device_initial_probe+0x24/0x30
[ 7.196937] bus_probe_device+0x9c/0xa8
[ 7.200816] deferred_probe_work_func+0x7c/0xb8
[ 7.205398] process_one_work+0x20c/0x4b0
[ 7.209456] worker_thread+0x48/0x460
[ 7.213157] kthread+0x14c/0x158
[ 7.216432] ret_from_fork+0x10/0x18
[ 7.220049] Code: bad PC value
[ 7.223139] ---[ end trace 73f3b21e251d5a70 ]---
Thus this patch removes the __init avoiding crash in such
configs.
Cc: Andy Gross <[email protected]>
Cc: Jiri Slaby <[email protected]>
Cc: Saravana Kannan <[email protected]>
Cc: Todd Kjos <[email protected]>
Cc: Amit Pundir <[email protected]>
Cc: [email protected]
Cc: [email protected]
Suggested-by: Saravana Kannan <[email protected]>
Signed-off-by: John Stultz <[email protected]>
Reviewed-by: Bjorn Andersson <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/tty/serial/qcom_geni_serial.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/tty/serial/qcom_geni_serial.c b/drivers/tty/serial/qcom_geni_serial.c
index 457c0bf8cbf83..ffdf6da016c21 100644
--- a/drivers/tty/serial/qcom_geni_serial.c
+++ b/drivers/tty/serial/qcom_geni_serial.c
@@ -1047,7 +1047,7 @@ static unsigned int qcom_geni_serial_tx_empty(struct uart_port *uport)
}
#ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE
-static int __init qcom_geni_console_setup(struct console *co, char *options)
+static int qcom_geni_console_setup(struct console *co, char *options)
{
struct uart_port *uport;
struct qcom_geni_serial_port *port;
--
2.25.1
On Mon, Aug 31, 2020 at 5:30 PM Sasha Levin <[email protected]> wrote:
>
> From: Jeff Layton <[email protected]>
>
> [ Upstream commit ebce3eb2f7ef9f6ef01a60874ebd232450107c9a ]
>
> Tuan and Ulrich mentioned that they were hitting a problem on s390x,
> which has a 32-bit ino_t value, even though it's a 64-bit arch (for
> historical reasons).
>
> I think the current handling of inode numbers in the ceph driver is
> wrong. It tries to use 32-bit inode numbers on 32-bit arches, but that's
> actually not a problem. 32-bit arches can deal with 64-bit inode numbers
> just fine when userland code is compiled with LFS support (the common
> case these days).
>
> What we really want to do is just use 64-bit numbers everywhere, unless
> someone has mounted with the ino32 mount option. In that case, we want
> to ensure that we hash the inode number down to something that will fit
> in 32 bits before presenting the value to userland.
>
> Add new helper functions that do this, and only do the conversion before
> presenting these values to userland in getattr and readdir.
>
> The inode table hashvalue is changed to just cast the inode number to
> unsigned long, as low-order bits are the most likely to vary anyway.
>
> While it's not strictly required, we do want to put something in
> inode->i_ino. Instead of basing it on BITS_PER_LONG, however, base it on
> the size of the ino_t type.
>
> NOTE: This is a user-visible change on 32-bit arches:
>
> 1/ inode numbers will be seen to have changed between kernel versions.
> 32-bit arches will see large inode numbers now instead of the hashed
> ones they saw before.
>
> 2/ any really old software not built with LFS support may start failing
> stat() calls with -EOVERFLOW on inode numbers >2^32. Nothing much we
> can do about these, but hopefully the intersection of people running
> such code on ceph will be very small.
>
> The workaround for both problems is to mount with "-o ino32".
>
> [ idryomov: changelog tweak ]
>
> URL: https://tracker.ceph.com/issues/46828
> Reported-by: Ulrich Weigand <[email protected]>
> Reported-and-Tested-by: Tuan Hoang1 <[email protected]>
> Signed-off-by: Jeff Layton <[email protected]>
> Reviewed-by: "Yan, Zheng" <[email protected]>
> Signed-off-by: Ilya Dryomov <[email protected]>
> Signed-off-by: Sasha Levin <[email protected]>
> ---
> fs/ceph/caps.c | 14 ++++-----
> fs/ceph/debugfs.c | 4 +--
> fs/ceph/dir.c | 31 ++++++++-----------
> fs/ceph/file.c | 4 +--
> fs/ceph/inode.c | 19 ++++++------
> fs/ceph/mds_client.h | 2 +-
> fs/ceph/quota.c | 4 +--
> fs/ceph/super.h | 73 +++++++++++++++++++++++---------------------
> 8 files changed, 74 insertions(+), 77 deletions(-)
>
> diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
> index 972c13aa42259..1206a481c5fc7 100644
> --- a/fs/ceph/caps.c
> +++ b/fs/ceph/caps.c
> @@ -886,8 +886,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
> int have = ci->i_snap_caps;
>
> if ((have & mask) == mask) {
> - dout("__ceph_caps_issued_mask ino 0x%lx snap issued %s"
> - " (mask %s)\n", ci->vfs_inode.i_ino,
> + dout("__ceph_caps_issued_mask ino 0x%llx snap issued %s"
> + " (mask %s)\n", ceph_ino(&ci->vfs_inode),
> ceph_cap_string(have),
> ceph_cap_string(mask));
> return 1;
> @@ -898,8 +898,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
> if (!__cap_is_valid(cap))
> continue;
> if ((cap->issued & mask) == mask) {
> - dout("__ceph_caps_issued_mask ino 0x%lx cap %p issued %s"
> - " (mask %s)\n", ci->vfs_inode.i_ino, cap,
> + dout("__ceph_caps_issued_mask ino 0x%llx cap %p issued %s"
> + " (mask %s)\n", ceph_ino(&ci->vfs_inode), cap,
> ceph_cap_string(cap->issued),
> ceph_cap_string(mask));
> if (touch)
> @@ -910,8 +910,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
> /* does a combination of caps satisfy mask? */
> have |= cap->issued;
> if ((have & mask) == mask) {
> - dout("__ceph_caps_issued_mask ino 0x%lx combo issued %s"
> - " (mask %s)\n", ci->vfs_inode.i_ino,
> + dout("__ceph_caps_issued_mask ino 0x%llx combo issued %s"
> + " (mask %s)\n", ceph_ino(&ci->vfs_inode),
> ceph_cap_string(cap->issued),
> ceph_cap_string(mask));
> if (touch) {
> @@ -2870,7 +2870,7 @@ int ceph_get_caps(struct file *filp, int need, int want,
> struct cap_wait cw;
> DEFINE_WAIT_FUNC(wait, woken_wake_function);
>
> - cw.ino = inode->i_ino;
> + cw.ino = ceph_ino(inode);
> cw.tgid = current->tgid;
> cw.need = need;
> cw.want = want;
> diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
> index 070ed84813406..74747d8d48619 100644
> --- a/fs/ceph/debugfs.c
> +++ b/fs/ceph/debugfs.c
> @@ -212,7 +212,7 @@ static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
> {
> struct seq_file *s = p;
>
> - seq_printf(s, "0x%-17lx%-17s%-17s\n", inode->i_ino,
> + seq_printf(s, "0x%-17llx%-17s%-17s\n", ceph_ino(inode),
> ceph_cap_string(cap->issued),
> ceph_cap_string(cap->implemented));
> return 0;
> @@ -257,7 +257,7 @@ static int caps_show(struct seq_file *s, void *p)
>
> spin_lock(&mdsc->caps_list_lock);
> list_for_each_entry(cw, &mdsc->cap_wait_list, list) {
> - seq_printf(s, "%-13d0x%-17lx%-17s%-17s\n", cw->tgid, cw->ino,
> + seq_printf(s, "%-13d0x%-17llx%-17s%-17s\n", cw->tgid, cw->ino,
> ceph_cap_string(cw->need),
> ceph_cap_string(cw->want));
> }
> diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
> index 060bdcc5ce32c..040eaad9d0631 100644
> --- a/fs/ceph/dir.c
> +++ b/fs/ceph/dir.c
> @@ -259,9 +259,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx,
> dentry, dentry, d_inode(dentry));
> ctx->pos = di->offset;
> if (!dir_emit(ctx, dentry->d_name.name,
> - dentry->d_name.len,
> - ceph_translate_ino(dentry->d_sb,
> - d_inode(dentry)->i_ino),
> + dentry->d_name.len, ceph_present_inode(d_inode(dentry)),
> d_inode(dentry)->i_mode >> 12)) {
> dput(dentry);
> err = 0;
> @@ -324,18 +322,21 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
> /* always start with . and .. */
> if (ctx->pos == 0) {
> dout("readdir off 0 -> '.'\n");
> - if (!dir_emit(ctx, ".", 1,
> - ceph_translate_ino(inode->i_sb, inode->i_ino),
> + if (!dir_emit(ctx, ".", 1, ceph_present_inode(inode),
> inode->i_mode >> 12))
> return 0;
> ctx->pos = 1;
> }
> if (ctx->pos == 1) {
> - ino_t ino = parent_ino(file->f_path.dentry);
> + u64 ino;
> + struct dentry *dentry = file->f_path.dentry;
> +
> + spin_lock(&dentry->d_lock);
> + ino = ceph_present_inode(dentry->d_parent->d_inode);
> + spin_unlock(&dentry->d_lock);
> +
> dout("readdir off 1 -> '..'\n");
> - if (!dir_emit(ctx, "..", 2,
> - ceph_translate_ino(inode->i_sb, ino),
> - inode->i_mode >> 12))
> + if (!dir_emit(ctx, "..", 2, ino, inode->i_mode >> 12))
> return 0;
> ctx->pos = 2;
> }
> @@ -507,9 +508,6 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
> }
> for (; i < rinfo->dir_nr; i++) {
> struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
> - struct ceph_vino vino;
> - ino_t ino;
> - u32 ftype;
>
> BUG_ON(rde->offset < ctx->pos);
>
> @@ -519,13 +517,10 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
> rde->name_len, rde->name, &rde->inode.in);
>
> BUG_ON(!rde->inode.in);
> - ftype = le32_to_cpu(rde->inode.in->mode) >> 12;
> - vino.ino = le64_to_cpu(rde->inode.in->ino);
> - vino.snap = le64_to_cpu(rde->inode.in->snapid);
> - ino = ceph_vino_to_ino(vino);
>
> if (!dir_emit(ctx, rde->name, rde->name_len,
> - ceph_translate_ino(inode->i_sb, ino), ftype)) {
> + ceph_present_ino(inode->i_sb, le64_to_cpu(rde->inode.in->ino)),
> + le32_to_cpu(rde->inode.in->mode) >> 12)) {
> dout("filldir stopping us...\n");
> return 0;
> }
> @@ -1161,7 +1156,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
>
> if (try_async && op == CEPH_MDS_OP_UNLINK &&
> (req->r_dir_caps = get_caps_for_async_unlink(dir, dentry))) {
> - dout("async unlink on %lu/%.*s caps=%s", dir->i_ino,
> + dout("async unlink on %llu/%.*s caps=%s", ceph_ino(dir),
> dentry->d_name.len, dentry->d_name.name,
> ceph_cap_string(req->r_dir_caps));
> set_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags);
> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
> index 160644ddaeed7..26172bb90a459 100644
> --- a/fs/ceph/file.c
> +++ b/fs/ceph/file.c
> @@ -630,8 +630,8 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
> } else {
> struct dentry *dn;
>
> - dout("%s d_adding new inode 0x%llx to 0x%lx/%s\n", __func__,
> - vino.ino, dir->i_ino, dentry->d_name.name);
> + dout("%s d_adding new inode 0x%llx to 0x%llx/%s\n", __func__,
> + vino.ino, ceph_ino(dir), dentry->d_name.name);
> ceph_dir_clear_ordered(dir);
> ceph_init_inode_acls(inode, as_ctx);
> if (inode->i_state & I_NEW) {
> diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
> index 357c937699d56..d163fa96cb401 100644
> --- a/fs/ceph/inode.c
> +++ b/fs/ceph/inode.c
> @@ -41,8 +41,10 @@ static void ceph_inode_work(struct work_struct *work);
> */
> static int ceph_set_ino_cb(struct inode *inode, void *data)
> {
> - ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
> - inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
> + struct ceph_inode_info *ci = ceph_inode(inode);
> +
> + ci->i_vino = *(struct ceph_vino *)data;
> + inode->i_ino = ceph_vino_to_ino_t(ci->i_vino);
> inode_set_iversion_raw(inode, 0);
> return 0;
> }
> @@ -50,17 +52,14 @@ static int ceph_set_ino_cb(struct inode *inode, void *data)
> struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
> {
> struct inode *inode;
> - ino_t t = ceph_vino_to_ino(vino);
>
> - inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino);
> + inode = iget5_locked(sb, (unsigned long)vino.ino, ceph_ino_compare,
> + ceph_set_ino_cb, &vino);
> if (!inode)
> return ERR_PTR(-ENOMEM);
> - if (inode->i_state & I_NEW)
> - dout("get_inode created new inode %p %llx.%llx ino %llx\n",
> - inode, ceph_vinop(inode), (u64)inode->i_ino);
>
> - dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino,
> - vino.snap, inode);
> + dout("get_inode on %llu=%llx.%llx got %p new %d\n", ceph_present_inode(inode),
> + ceph_vinop(inode), inode, !!(inode->i_state & I_NEW));
> return inode;
> }
>
> @@ -2378,7 +2377,7 @@ int ceph_getattr(const struct path *path, struct kstat *stat,
> }
>
> generic_fillattr(inode, stat);
> - stat->ino = ceph_translate_ino(inode->i_sb, inode->i_ino);
> + stat->ino = ceph_present_inode(inode);
>
> /*
> * btime on newly-allocated inodes is 0, so if this is still set to
> diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
> index 5e0c4073a6bea..63c9cd1c28d6c 100644
> --- a/fs/ceph/mds_client.h
> +++ b/fs/ceph/mds_client.h
> @@ -369,7 +369,7 @@ struct ceph_quotarealm_inode {
>
> struct cap_wait {
> struct list_head list;
> - unsigned long ino;
> + u64 ino;
> pid_t tgid;
> int need;
> int want;
> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c
> index 198ddde5c1e6a..cc2c4d40b0222 100644
> --- a/fs/ceph/quota.c
> +++ b/fs/ceph/quota.c
> @@ -23,12 +23,12 @@ static inline bool ceph_has_realms_with_quotas(struct inode *inode)
> {
> struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
> struct super_block *sb = mdsc->fsc->sb;
> + struct inode *root = d_inode(sb->s_root);
>
> if (atomic64_read(&mdsc->quotarealms_count) > 0)
> return true;
> /* if root is the real CephFS root, we don't have quota realms */
> - if (sb->s_root->d_inode &&
> - (sb->s_root->d_inode->i_ino == CEPH_INO_ROOT))
> + if (root && ceph_ino(root) == CEPH_INO_ROOT)
> return false;
> /* otherwise, we can't know for sure */
> return true;
> diff --git a/fs/ceph/super.h b/fs/ceph/super.h
> index 5a6cdd39bc103..2af3e06a6d0ce 100644
> --- a/fs/ceph/super.h
> +++ b/fs/ceph/super.h
> @@ -457,15 +457,7 @@ ceph_vino(const struct inode *inode)
> return ceph_inode(inode)->i_vino;
> }
>
> -/*
> - * ino_t is <64 bits on many architectures, blech.
> - *
> - * i_ino (kernel inode) st_ino (userspace)
> - * i386 32 32
> - * x86_64+ino32 64 32
> - * x86_64 64 64
> - */
> -static inline u32 ceph_ino_to_ino32(__u64 vino)
> +static inline u32 ceph_ino_to_ino32(u64 vino)
> {
> u32 ino = vino & 0xffffffff;
> ino ^= vino >> 32;
> @@ -475,34 +467,17 @@ static inline u32 ceph_ino_to_ino32(__u64 vino)
> }
>
> /*
> - * kernel i_ino value
> + * Inode numbers in cephfs are 64 bits, but inode->i_ino is 32-bits on
> + * some arches. We generally do not use this value inside the ceph driver, but
> + * we do want to set it to something, so that generic vfs code has an
> + * appropriate value for tracepoints and the like.
> */
> -static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
> +static inline ino_t ceph_vino_to_ino_t(struct ceph_vino vino)
> {
> -#if BITS_PER_LONG == 32
> - return ceph_ino_to_ino32(vino.ino);
> -#else
> + if (sizeof(ino_t) == sizeof(u32))
> + return ceph_ino_to_ino32(vino.ino);
> return (ino_t)vino.ino;
> -#endif
> -}
> -
> -/*
> - * user-visible ino (stat, filldir)
> - */
> -#if BITS_PER_LONG == 32
> -static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
> -{
> - return ino;
> -}
> -#else
> -static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
> -{
> - if (ceph_test_mount_opt(ceph_sb_to_client(sb), INO32))
> - ino = ceph_ino_to_ino32(ino);
> - return ino;
> }
> -#endif
> -
>
> /* for printf-style formatting */
> #define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap
> @@ -511,11 +486,34 @@ static inline u64 ceph_ino(struct inode *inode)
> {
> return ceph_inode(inode)->i_vino.ino;
> }
> +
> static inline u64 ceph_snap(struct inode *inode)
> {
> return ceph_inode(inode)->i_vino.snap;
> }
>
> +/**
> + * ceph_present_ino - format an inode number for presentation to userland
> + * @sb: superblock where the inode lives
> + * @ino: inode number to (possibly) convert
> + *
> + * If the user mounted with the ino32 option, then the 64-bit value needs
> + * to be converted to something that can fit inside 32 bits. Note that
> + * internal kernel code never uses this value, so this is entirely for
> + * userland consumption.
> + */
> +static inline u64 ceph_present_ino(struct super_block *sb, u64 ino)
> +{
> + if (unlikely(ceph_test_mount_opt(ceph_sb_to_client(sb), INO32)))
> + return ceph_ino_to_ino32(ino);
> + return ino;
> +}
> +
> +static inline u64 ceph_present_inode(struct inode *inode)
> +{
> + return ceph_present_ino(inode->i_sb, ceph_ino(inode));
> +}
> +
> static inline int ceph_ino_compare(struct inode *inode, void *data)
> {
> struct ceph_vino *pvino = (struct ceph_vino *)data;
> @@ -524,11 +522,16 @@ static inline int ceph_ino_compare(struct inode *inode, void *data)
> ci->i_vino.snap == pvino->snap;
> }
>
> +
> static inline struct inode *ceph_find_inode(struct super_block *sb,
> struct ceph_vino vino)
> {
> - ino_t t = ceph_vino_to_ino(vino);
> - return ilookup5(sb, t, ceph_ino_compare, &vino);
> + /*
> + * NB: The hashval will be run through the fs/inode.c hash function
> + * anyway, so there is no need to squash the inode number down to
> + * 32-bits first. Just use low-order bits on arches with 32-bit long.
> + */
> + return ilookup5(sb, (unsigned long)vino.ino, ceph_ino_compare, &vino);
> }
>
>
> --
> 2.25.1
Hi Sasha,
This is a user-visible change and wasn't marked for stable for that
reason. Please drop it.
Thanks,
Ilya
From: Kalyan Thota <[email protected]>
[ Upstream commit ccc862b957c6413b008fbe458034372847992d7f ]
In TEST_ONLY commit, rm global_state will duplicate the
object and request for new reservations, once they pass
then the new state will be swapped with the old and will
be available for the Atomic Commit.
This patch fixes some of missing links in the resource
reservation sequence mentioned above.
1) Creation of duplicate state in test_only commit (Rob)
2) Allocate and release the resources on every modeset.
3) Avoid allocation only when active is false.
In a modeset operation, swap state happens well before
disable. Hence clearing reservations in disable will
cause failures in modeset enable.
Allow reservations to be cleared/allocated before swap,
such that only newly committed resources are pushed to HW.
Changes in v1:
- Move the rm release to atomic_check.
- Ensure resource allocation and free happens when active
is not changed i.e only when mode is changed.(Rob)
Changes in v2:
- Handle dpu_kms_get_global_state API failure as it may
return EDEADLK (swboyd).
Signed-off-by: Kalyan Thota <[email protected]>
Signed-off-by: Rob Clark <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 20 +++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 0946a86b37b28..c0cd936314e66 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -586,7 +586,10 @@ static int dpu_encoder_virt_atomic_check(
dpu_kms = to_dpu_kms(priv->kms);
mode = &crtc_state->mode;
adj_mode = &crtc_state->adjusted_mode;
- global_state = dpu_kms_get_existing_global_state(dpu_kms);
+ global_state = dpu_kms_get_global_state(crtc_state->state);
+ if (IS_ERR(global_state))
+ return PTR_ERR(global_state);
+
trace_dpu_enc_atomic_check(DRMID(drm_enc));
/*
@@ -621,12 +624,15 @@ static int dpu_encoder_virt_atomic_check(
/* Reserve dynamic resources now. */
if (!ret) {
/*
- * Avoid reserving resources when mode set is pending. Topology
- * info may not be available to complete reservation.
+ * Release and Allocate resources on every modeset
+ * Dont allocate when active is false.
*/
if (drm_atomic_crtc_needs_modeset(crtc_state)) {
- ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
- drm_enc, crtc_state, topology);
+ dpu_rm_release(global_state, drm_enc);
+
+ if (!crtc_state->active_changed || crtc_state->active)
+ ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
+ drm_enc, crtc_state, topology);
}
}
@@ -1175,7 +1181,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
struct dpu_encoder_virt *dpu_enc = NULL;
struct msm_drm_private *priv;
struct dpu_kms *dpu_kms;
- struct dpu_global_state *global_state;
int i = 0;
if (!drm_enc) {
@@ -1194,7 +1199,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
priv = drm_enc->dev->dev_private;
dpu_kms = to_dpu_kms(priv->kms);
- global_state = dpu_kms_get_existing_global_state(dpu_kms);
trace_dpu_enc_disable(DRMID(drm_enc));
@@ -1224,8 +1228,6 @@ static void dpu_encoder_virt_disable(struct drm_encoder *drm_enc)
DPU_DEBUG_ENC(dpu_enc, "encoder disabled\n");
- dpu_rm_release(global_state, drm_enc);
-
mutex_unlock(&dpu_enc->enc_lock);
}
--
2.25.1
From: Paul Cercueil <[email protected]>
[ Upstream commit 821fc9e261f3af235752f46e59084467cfd440c4 ]
All the wakeup sources we possibly want will go through the interrupt
controller, so the parent IRQ must not be masked during suspend, or
there won't be any way to wake up the system.
Signed-off-by: Paul Cercueil <[email protected]>
Signed-off-by: Marc Zyngier <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/irqchip/irq-ingenic.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/irqchip/irq-ingenic.c b/drivers/irqchip/irq-ingenic.c
index 9f3da4260ca65..b61a8901ef722 100644
--- a/drivers/irqchip/irq-ingenic.c
+++ b/drivers/irqchip/irq-ingenic.c
@@ -125,7 +125,7 @@ static int __init ingenic_intc_of_init(struct device_node *node,
irq_reg_writel(gc, IRQ_MSK(32), JZ_REG_INTC_SET_MASK);
}
- if (request_irq(parent_irq, intc_cascade, 0,
+ if (request_irq(parent_irq, intc_cascade, IRQF_NO_SUSPEND,
"SoC intc cascade interrupt", NULL))
pr_err("Failed to register SoC intc cascade interrupt\n");
return 0;
--
2.25.1
From: Tong Zhang <[email protected]>
[ Upstream commit ed9ab229fea24cbcab17f484297dc8344afb7ea9 ]
core_link_read_dpcd returns only DC_OK(1) and DC_ERROR_UNEXPECTED(-1),
the caller should check error using DC_OK instead of checking against 0
Signed-off-by: Tong Zhang <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
index 91cd884d6f257..7728fd71d1f3a 100644
--- a/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
@@ -4346,9 +4346,9 @@ bool dc_link_get_backlight_level_nits(struct dc_link *link,
link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
return false;
- if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
+ if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_CURRENT_PEAK,
dpcd_backlight_get.raw,
- sizeof(union dpcd_source_backlight_get)))
+ sizeof(union dpcd_source_backlight_get)) != DC_OK)
return false;
*backlight_millinits_avg =
@@ -4387,9 +4387,9 @@ bool dc_link_read_default_bl_aux(struct dc_link *link, uint32_t *backlight_milli
link->connector_signal != SIGNAL_TYPE_DISPLAY_PORT))
return false;
- if (!core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
+ if (core_link_read_dpcd(link, DP_SOURCE_BACKLIGHT_LEVEL,
(uint8_t *) backlight_millinits,
- sizeof(uint32_t)))
+ sizeof(uint32_t)) != DC_OK)
return false;
return true;
--
2.25.1
From: Simon Leiner <[email protected]>
[ Upstream commit d742db70033c745e410523e00522ee0cfe2aa416 ]
On some architectures (like ARM), virt_to_gfn cannot be used for
vmalloc'd memory because of its reliance on virt_to_phys. This patch
introduces a check for vmalloc'd addresses and obtains the PFN using
vmalloc_to_pfn in that case.
Signed-off-by: Simon Leiner <[email protected]>
Reviewed-by: Stefano Stabellini <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Juergen Gross <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/xen/xenbus/xenbus_client.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
index 786fbb7d8be06..907bcbb93afbf 100644
--- a/drivers/xen/xenbus/xenbus_client.c
+++ b/drivers/xen/xenbus/xenbus_client.c
@@ -379,8 +379,14 @@ int xenbus_grant_ring(struct xenbus_device *dev, void *vaddr,
int i, j;
for (i = 0; i < nr_pages; i++) {
- err = gnttab_grant_foreign_access(dev->otherend_id,
- virt_to_gfn(vaddr), 0);
+ unsigned long gfn;
+
+ if (is_vmalloc_addr(vaddr))
+ gfn = pfn_to_gfn(vmalloc_to_pfn(vaddr));
+ else
+ gfn = virt_to_gfn(vaddr);
+
+ err = gnttab_grant_foreign_access(dev->otherend_id, gfn, 0);
if (err < 0) {
xenbus_dev_fatal(dev, err,
"granting access to ring page");
--
2.25.1
From: Brandon Syu <[email protected]>
[ Upstream commit cba4b52e431e5de3d8012281cfe194f1c39a9052 ]
[Why]
When system enters s3/s0i3, backlight PWM would set user level.
[How]
ABM disable function add keep current gain to avoid it.
Signed-off-by: Brandon Syu <[email protected]>
Reviewed-by: Josip Pavic <[email protected]>
Acked-by: Eryk Brol <[email protected]>
Signed-off-by: Alex Deucher <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/gpu/drm/amd/display/dc/dc_stream.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/amd/display/dc/dc_stream.h b/drivers/gpu/drm/amd/display/dc/dc_stream.h
index 49aad691e687e..ccac2315a903a 100644
--- a/drivers/gpu/drm/amd/display/dc/dc_stream.h
+++ b/drivers/gpu/drm/amd/display/dc/dc_stream.h
@@ -222,7 +222,7 @@ struct dc_stream_state {
union stream_update_flags update_flags;
};
-#define ABM_LEVEL_IMMEDIATE_DISABLE 0xFFFFFFFF
+#define ABM_LEVEL_IMMEDIATE_DISABLE 255
struct dc_stream_update {
struct dc_stream_state *stream;
--
2.25.1
From: Ofir Bitton <[email protected]>
[ Upstream commit bce382a8bb080ed5f2f3a06754526dc58b91cca2 ]
We must validate FW size in order not to corrupt memory in case
a malicious FW file will be present in system.
Signed-off-by: Ofir Bitton <[email protected]>
Signed-off-by: Oded Gabbay <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/misc/habanalabs/firmware_if.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/misc/habanalabs/firmware_if.c b/drivers/misc/habanalabs/firmware_if.c
index d27841cb5bcb3..345c228a7971e 100644
--- a/drivers/misc/habanalabs/firmware_if.c
+++ b/drivers/misc/habanalabs/firmware_if.c
@@ -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.
* @hdev: pointer to hl_device structure.
@@ -45,6 +46,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);
--
2.25.1
From: Ofir Bitton <[email protected]>
[ Upstream commit 36545279f076afeb77104f5ffeab850da3b6d107 ]
Allocation size can go up to 64bit but truncated to 32bit,
we should make sure it is not truncated and validate no address
overflow.
Signed-off-by: Ofir Bitton <[email protected]>
Reviewed-by: Oded Gabbay <[email protected]>
Signed-off-by: Oded Gabbay <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/misc/habanalabs/gaudi/gaudi_coresight.c | 8 +++++++-
drivers/misc/habanalabs/goya/goya_coresight.c | 8 +++++++-
drivers/misc/habanalabs/habanalabs.h | 2 +-
3 files changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/misc/habanalabs/gaudi/gaudi_coresight.c b/drivers/misc/habanalabs/gaudi/gaudi_coresight.c
index bf0e062d7b874..cc3d03549a6e4 100644
--- a/drivers/misc/habanalabs/gaudi/gaudi_coresight.c
+++ b/drivers/misc/habanalabs/gaudi/gaudi_coresight.c
@@ -523,7 +523,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;
@@ -535,6 +535,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,
diff --git a/drivers/misc/habanalabs/goya/goya_coresight.c b/drivers/misc/habanalabs/goya/goya_coresight.c
index 1258724ea5106..c23a9fcb74b57 100644
--- a/drivers/misc/habanalabs/goya/goya_coresight.c
+++ b/drivers/misc/habanalabs/goya/goya_coresight.c
@@ -358,11 +358,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;
diff --git a/drivers/misc/habanalabs/habanalabs.h b/drivers/misc/habanalabs/habanalabs.h
index 194d833526964..feedf3194ea6c 100644
--- a/drivers/misc/habanalabs/habanalabs.h
+++ b/drivers/misc/habanalabs/habanalabs.h
@@ -1587,7 +1587,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;
--
2.25.1
From: Tom Rix <[email protected]>
[ Upstream commit cecf7560f00a8419396a2ed0f6e5d245ccb4feac ]
clang static analysis reports this representative problem
applesmc.c:758:10: warning: 1st function call argument is an
uninitialized value
left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
buffer is filled by the earlier call
ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, ...
This problem is reported because a goto skips the status check.
Other similar problems use data from applesmc_read_key before checking
the status. So move the checks to before the use.
Signed-off-by: Tom Rix <[email protected]>
Reviewed-by: Henrik Rydberg <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Guenter Roeck <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
drivers/hwmon/applesmc.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 3166184093157..a18887990f4a2 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -753,15 +753,18 @@ static ssize_t applesmc_light_show(struct device *dev,
}
ret = applesmc_read_key(LIGHT_SENSOR_LEFT_KEY, buffer, data_length);
+ if (ret)
+ goto out;
/* newer macbooks report a single 10-bit bigendian value */
if (data_length == 10) {
left = be16_to_cpu(*(__be16 *)(buffer + 6)) >> 2;
goto out;
}
left = buffer[2];
+
+ ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
if (ret)
goto out;
- ret = applesmc_read_key(LIGHT_SENSOR_RIGHT_KEY, buffer, data_length);
right = buffer[2];
out:
@@ -810,12 +813,11 @@ static ssize_t applesmc_show_fan_speed(struct device *dev,
to_index(attr));
ret = applesmc_read_key(newkey, buffer, 2);
- speed = ((buffer[0] << 8 | buffer[1]) >> 2);
-
if (ret)
return ret;
- else
- return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
+
+ speed = ((buffer[0] << 8 | buffer[1]) >> 2);
+ return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", speed);
}
static ssize_t applesmc_store_fan_speed(struct device *dev,
@@ -851,12 +853,11 @@ static ssize_t applesmc_show_fan_manual(struct device *dev,
u8 buffer[2];
ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
- manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01;
-
if (ret)
return ret;
- else
- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
+
+ manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01;
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", manual);
}
static ssize_t applesmc_store_fan_manual(struct device *dev,
@@ -872,10 +873,11 @@ static ssize_t applesmc_store_fan_manual(struct device *dev,
return -EINVAL;
ret = applesmc_read_key(FANS_MANUAL, buffer, 2);
- val = (buffer[0] << 8 | buffer[1]);
if (ret)
goto out;
+ val = (buffer[0] << 8 | buffer[1]);
+
if (input)
val = val | (0x01 << to_index(attr));
else
@@ -951,13 +953,12 @@ static ssize_t applesmc_key_count_show(struct device *dev,
u32 count;
ret = applesmc_read_key(KEY_COUNT_KEY, buffer, 4);
- count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
- ((u32)buffer[2]<<8) + buffer[3];
-
if (ret)
return ret;
- else
- return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
+
+ count = ((u32)buffer[0]<<24) + ((u32)buffer[1]<<16) +
+ ((u32)buffer[2]<<8) + buffer[3];
+ return snprintf(sysfsbuf, PAGE_SIZE, "%d\n", count);
}
static ssize_t applesmc_key_at_index_read_show(struct device *dev,
--
2.25.1
On Mon, Aug 31, 2020 at 05:33:45PM +0200, Greg Kroah-Hartman wrote:
>On Mon, Aug 31, 2020 at 11:28:59AM -0400, Sasha Levin wrote:
>> From: Samuel Thibault <[email protected]>
>>
>> [ Upstream commit 2b86d9b8ec6efb86fc5ea44f2d49b1df17f699a1 ]
>>
>> This was missed while introducing the tty-based serial access.
>>
>> The only remaining use of wait_for_xmitr with tty-based access is in
>> spk_synth_is_alive_restart to check whether the synth can be restarted.
>> With tty-based this is up to the tty layer to cope with the buffering
>> etc. so we can just say yes.
>>
>> Signed-off-by: Samuel Thibault <[email protected]>
>> Link: https://lore.kernel.org/r/20200804160637.x3iycau5izywbgzl@function
>> Signed-off-by: Greg Kroah-Hartman <[email protected]>
>> Signed-off-by: Sasha Levin <[email protected]>
>> ---
>> drivers/staging/speakup/serialio.c | 8 +++++---
>> drivers/staging/speakup/spk_priv.h | 1 -
>> drivers/staging/speakup/spk_ttyio.c | 7 +++++++
>> drivers/staging/speakup/spk_types.h | 1 +
>> drivers/staging/speakup/synth.c | 2 +-
>> 5 files changed, 14 insertions(+), 5 deletions(-)
>
>Not needed for 5.8 or older, sorry, this was a 5.9-rc1+ issue only.
Dropped, thanks!
--
Thanks,
Sasha
On Mon, Aug 31, 2020 at 06:08:32PM +0200, Ilya Dryomov wrote:
>On Mon, Aug 31, 2020 at 5:30 PM Sasha Levin <[email protected]> wrote:
>>
>> From: Jeff Layton <[email protected]>
>>
>> [ Upstream commit ebce3eb2f7ef9f6ef01a60874ebd232450107c9a ]
>>
>> Tuan and Ulrich mentioned that they were hitting a problem on s390x,
>> which has a 32-bit ino_t value, even though it's a 64-bit arch (for
>> historical reasons).
>>
>> I think the current handling of inode numbers in the ceph driver is
>> wrong. It tries to use 32-bit inode numbers on 32-bit arches, but that's
>> actually not a problem. 32-bit arches can deal with 64-bit inode numbers
>> just fine when userland code is compiled with LFS support (the common
>> case these days).
>>
>> What we really want to do is just use 64-bit numbers everywhere, unless
>> someone has mounted with the ino32 mount option. In that case, we want
>> to ensure that we hash the inode number down to something that will fit
>> in 32 bits before presenting the value to userland.
>>
>> Add new helper functions that do this, and only do the conversion before
>> presenting these values to userland in getattr and readdir.
>>
>> The inode table hashvalue is changed to just cast the inode number to
>> unsigned long, as low-order bits are the most likely to vary anyway.
>>
>> While it's not strictly required, we do want to put something in
>> inode->i_ino. Instead of basing it on BITS_PER_LONG, however, base it on
>> the size of the ino_t type.
>>
>> NOTE: This is a user-visible change on 32-bit arches:
>>
>> 1/ inode numbers will be seen to have changed between kernel versions.
>> 32-bit arches will see large inode numbers now instead of the hashed
>> ones they saw before.
>>
>> 2/ any really old software not built with LFS support may start failing
>> stat() calls with -EOVERFLOW on inode numbers >2^32. Nothing much we
>> can do about these, but hopefully the intersection of people running
>> such code on ceph will be very small.
>>
>> The workaround for both problems is to mount with "-o ino32".
>>
>> [ idryomov: changelog tweak ]
>>
>> URL: https://tracker.ceph.com/issues/46828
>> Reported-by: Ulrich Weigand <[email protected]>
>> Reported-and-Tested-by: Tuan Hoang1 <[email protected]>
>> Signed-off-by: Jeff Layton <[email protected]>
>> Reviewed-by: "Yan, Zheng" <[email protected]>
>> Signed-off-by: Ilya Dryomov <[email protected]>
>> Signed-off-by: Sasha Levin <[email protected]>
>> ---
>> fs/ceph/caps.c | 14 ++++-----
>> fs/ceph/debugfs.c | 4 +--
>> fs/ceph/dir.c | 31 ++++++++-----------
>> fs/ceph/file.c | 4 +--
>> fs/ceph/inode.c | 19 ++++++------
>> fs/ceph/mds_client.h | 2 +-
>> fs/ceph/quota.c | 4 +--
>> fs/ceph/super.h | 73 +++++++++++++++++++++++---------------------
>> 8 files changed, 74 insertions(+), 77 deletions(-)
>>
>> diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c
>> index 972c13aa42259..1206a481c5fc7 100644
>> --- a/fs/ceph/caps.c
>> +++ b/fs/ceph/caps.c
>> @@ -886,8 +886,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
>> int have = ci->i_snap_caps;
>>
>> if ((have & mask) == mask) {
>> - dout("__ceph_caps_issued_mask ino 0x%lx snap issued %s"
>> - " (mask %s)\n", ci->vfs_inode.i_ino,
>> + dout("__ceph_caps_issued_mask ino 0x%llx snap issued %s"
>> + " (mask %s)\n", ceph_ino(&ci->vfs_inode),
>> ceph_cap_string(have),
>> ceph_cap_string(mask));
>> return 1;
>> @@ -898,8 +898,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
>> if (!__cap_is_valid(cap))
>> continue;
>> if ((cap->issued & mask) == mask) {
>> - dout("__ceph_caps_issued_mask ino 0x%lx cap %p issued %s"
>> - " (mask %s)\n", ci->vfs_inode.i_ino, cap,
>> + dout("__ceph_caps_issued_mask ino 0x%llx cap %p issued %s"
>> + " (mask %s)\n", ceph_ino(&ci->vfs_inode), cap,
>> ceph_cap_string(cap->issued),
>> ceph_cap_string(mask));
>> if (touch)
>> @@ -910,8 +910,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
>> /* does a combination of caps satisfy mask? */
>> have |= cap->issued;
>> if ((have & mask) == mask) {
>> - dout("__ceph_caps_issued_mask ino 0x%lx combo issued %s"
>> - " (mask %s)\n", ci->vfs_inode.i_ino,
>> + dout("__ceph_caps_issued_mask ino 0x%llx combo issued %s"
>> + " (mask %s)\n", ceph_ino(&ci->vfs_inode),
>> ceph_cap_string(cap->issued),
>> ceph_cap_string(mask));
>> if (touch) {
>> @@ -2870,7 +2870,7 @@ int ceph_get_caps(struct file *filp, int need, int want,
>> struct cap_wait cw;
>> DEFINE_WAIT_FUNC(wait, woken_wake_function);
>>
>> - cw.ino = inode->i_ino;
>> + cw.ino = ceph_ino(inode);
>> cw.tgid = current->tgid;
>> cw.need = need;
>> cw.want = want;
>> diff --git a/fs/ceph/debugfs.c b/fs/ceph/debugfs.c
>> index 070ed84813406..74747d8d48619 100644
>> --- a/fs/ceph/debugfs.c
>> +++ b/fs/ceph/debugfs.c
>> @@ -212,7 +212,7 @@ static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
>> {
>> struct seq_file *s = p;
>>
>> - seq_printf(s, "0x%-17lx%-17s%-17s\n", inode->i_ino,
>> + seq_printf(s, "0x%-17llx%-17s%-17s\n", ceph_ino(inode),
>> ceph_cap_string(cap->issued),
>> ceph_cap_string(cap->implemented));
>> return 0;
>> @@ -257,7 +257,7 @@ static int caps_show(struct seq_file *s, void *p)
>>
>> spin_lock(&mdsc->caps_list_lock);
>> list_for_each_entry(cw, &mdsc->cap_wait_list, list) {
>> - seq_printf(s, "%-13d0x%-17lx%-17s%-17s\n", cw->tgid, cw->ino,
>> + seq_printf(s, "%-13d0x%-17llx%-17s%-17s\n", cw->tgid, cw->ino,
>> ceph_cap_string(cw->need),
>> ceph_cap_string(cw->want));
>> }
>> diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c
>> index 060bdcc5ce32c..040eaad9d0631 100644
>> --- a/fs/ceph/dir.c
>> +++ b/fs/ceph/dir.c
>> @@ -259,9 +259,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx,
>> dentry, dentry, d_inode(dentry));
>> ctx->pos = di->offset;
>> if (!dir_emit(ctx, dentry->d_name.name,
>> - dentry->d_name.len,
>> - ceph_translate_ino(dentry->d_sb,
>> - d_inode(dentry)->i_ino),
>> + dentry->d_name.len, ceph_present_inode(d_inode(dentry)),
>> d_inode(dentry)->i_mode >> 12)) {
>> dput(dentry);
>> err = 0;
>> @@ -324,18 +322,21 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
>> /* always start with . and .. */
>> if (ctx->pos == 0) {
>> dout("readdir off 0 -> '.'\n");
>> - if (!dir_emit(ctx, ".", 1,
>> - ceph_translate_ino(inode->i_sb, inode->i_ino),
>> + if (!dir_emit(ctx, ".", 1, ceph_present_inode(inode),
>> inode->i_mode >> 12))
>> return 0;
>> ctx->pos = 1;
>> }
>> if (ctx->pos == 1) {
>> - ino_t ino = parent_ino(file->f_path.dentry);
>> + u64 ino;
>> + struct dentry *dentry = file->f_path.dentry;
>> +
>> + spin_lock(&dentry->d_lock);
>> + ino = ceph_present_inode(dentry->d_parent->d_inode);
>> + spin_unlock(&dentry->d_lock);
>> +
>> dout("readdir off 1 -> '..'\n");
>> - if (!dir_emit(ctx, "..", 2,
>> - ceph_translate_ino(inode->i_sb, ino),
>> - inode->i_mode >> 12))
>> + if (!dir_emit(ctx, "..", 2, ino, inode->i_mode >> 12))
>> return 0;
>> ctx->pos = 2;
>> }
>> @@ -507,9 +508,6 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
>> }
>> for (; i < rinfo->dir_nr; i++) {
>> struct ceph_mds_reply_dir_entry *rde = rinfo->dir_entries + i;
>> - struct ceph_vino vino;
>> - ino_t ino;
>> - u32 ftype;
>>
>> BUG_ON(rde->offset < ctx->pos);
>>
>> @@ -519,13 +517,10 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx)
>> rde->name_len, rde->name, &rde->inode.in);
>>
>> BUG_ON(!rde->inode.in);
>> - ftype = le32_to_cpu(rde->inode.in->mode) >> 12;
>> - vino.ino = le64_to_cpu(rde->inode.in->ino);
>> - vino.snap = le64_to_cpu(rde->inode.in->snapid);
>> - ino = ceph_vino_to_ino(vino);
>>
>> if (!dir_emit(ctx, rde->name, rde->name_len,
>> - ceph_translate_ino(inode->i_sb, ino), ftype)) {
>> + ceph_present_ino(inode->i_sb, le64_to_cpu(rde->inode.in->ino)),
>> + le32_to_cpu(rde->inode.in->mode) >> 12)) {
>> dout("filldir stopping us...\n");
>> return 0;
>> }
>> @@ -1161,7 +1156,7 @@ static int ceph_unlink(struct inode *dir, struct dentry *dentry)
>>
>> if (try_async && op == CEPH_MDS_OP_UNLINK &&
>> (req->r_dir_caps = get_caps_for_async_unlink(dir, dentry))) {
>> - dout("async unlink on %lu/%.*s caps=%s", dir->i_ino,
>> + dout("async unlink on %llu/%.*s caps=%s", ceph_ino(dir),
>> dentry->d_name.len, dentry->d_name.name,
>> ceph_cap_string(req->r_dir_caps));
>> set_bit(CEPH_MDS_R_ASYNC, &req->r_req_flags);
>> diff --git a/fs/ceph/file.c b/fs/ceph/file.c
>> index 160644ddaeed7..26172bb90a459 100644
>> --- a/fs/ceph/file.c
>> +++ b/fs/ceph/file.c
>> @@ -630,8 +630,8 @@ static int ceph_finish_async_create(struct inode *dir, struct dentry *dentry,
>> } else {
>> struct dentry *dn;
>>
>> - dout("%s d_adding new inode 0x%llx to 0x%lx/%s\n", __func__,
>> - vino.ino, dir->i_ino, dentry->d_name.name);
>> + dout("%s d_adding new inode 0x%llx to 0x%llx/%s\n", __func__,
>> + vino.ino, ceph_ino(dir), dentry->d_name.name);
>> ceph_dir_clear_ordered(dir);
>> ceph_init_inode_acls(inode, as_ctx);
>> if (inode->i_state & I_NEW) {
>> diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
>> index 357c937699d56..d163fa96cb401 100644
>> --- a/fs/ceph/inode.c
>> +++ b/fs/ceph/inode.c
>> @@ -41,8 +41,10 @@ static void ceph_inode_work(struct work_struct *work);
>> */
>> static int ceph_set_ino_cb(struct inode *inode, void *data)
>> {
>> - ceph_inode(inode)->i_vino = *(struct ceph_vino *)data;
>> - inode->i_ino = ceph_vino_to_ino(*(struct ceph_vino *)data);
>> + struct ceph_inode_info *ci = ceph_inode(inode);
>> +
>> + ci->i_vino = *(struct ceph_vino *)data;
>> + inode->i_ino = ceph_vino_to_ino_t(ci->i_vino);
>> inode_set_iversion_raw(inode, 0);
>> return 0;
>> }
>> @@ -50,17 +52,14 @@ static int ceph_set_ino_cb(struct inode *inode, void *data)
>> struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
>> {
>> struct inode *inode;
>> - ino_t t = ceph_vino_to_ino(vino);
>>
>> - inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino);
>> + inode = iget5_locked(sb, (unsigned long)vino.ino, ceph_ino_compare,
>> + ceph_set_ino_cb, &vino);
>> if (!inode)
>> return ERR_PTR(-ENOMEM);
>> - if (inode->i_state & I_NEW)
>> - dout("get_inode created new inode %p %llx.%llx ino %llx\n",
>> - inode, ceph_vinop(inode), (u64)inode->i_ino);
>>
>> - dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino,
>> - vino.snap, inode);
>> + dout("get_inode on %llu=%llx.%llx got %p new %d\n", ceph_present_inode(inode),
>> + ceph_vinop(inode), inode, !!(inode->i_state & I_NEW));
>> return inode;
>> }
>>
>> @@ -2378,7 +2377,7 @@ int ceph_getattr(const struct path *path, struct kstat *stat,
>> }
>>
>> generic_fillattr(inode, stat);
>> - stat->ino = ceph_translate_ino(inode->i_sb, inode->i_ino);
>> + stat->ino = ceph_present_inode(inode);
>>
>> /*
>> * btime on newly-allocated inodes is 0, so if this is still set to
>> diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
>> index 5e0c4073a6bea..63c9cd1c28d6c 100644
>> --- a/fs/ceph/mds_client.h
>> +++ b/fs/ceph/mds_client.h
>> @@ -369,7 +369,7 @@ struct ceph_quotarealm_inode {
>>
>> struct cap_wait {
>> struct list_head list;
>> - unsigned long ino;
>> + u64 ino;
>> pid_t tgid;
>> int need;
>> int want;
>> diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c
>> index 198ddde5c1e6a..cc2c4d40b0222 100644
>> --- a/fs/ceph/quota.c
>> +++ b/fs/ceph/quota.c
>> @@ -23,12 +23,12 @@ static inline bool ceph_has_realms_with_quotas(struct inode *inode)
>> {
>> struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
>> struct super_block *sb = mdsc->fsc->sb;
>> + struct inode *root = d_inode(sb->s_root);
>>
>> if (atomic64_read(&mdsc->quotarealms_count) > 0)
>> return true;
>> /* if root is the real CephFS root, we don't have quota realms */
>> - if (sb->s_root->d_inode &&
>> - (sb->s_root->d_inode->i_ino == CEPH_INO_ROOT))
>> + if (root && ceph_ino(root) == CEPH_INO_ROOT)
>> return false;
>> /* otherwise, we can't know for sure */
>> return true;
>> diff --git a/fs/ceph/super.h b/fs/ceph/super.h
>> index 5a6cdd39bc103..2af3e06a6d0ce 100644
>> --- a/fs/ceph/super.h
>> +++ b/fs/ceph/super.h
>> @@ -457,15 +457,7 @@ ceph_vino(const struct inode *inode)
>> return ceph_inode(inode)->i_vino;
>> }
>>
>> -/*
>> - * ino_t is <64 bits on many architectures, blech.
>> - *
>> - * i_ino (kernel inode) st_ino (userspace)
>> - * i386 32 32
>> - * x86_64+ino32 64 32
>> - * x86_64 64 64
>> - */
>> -static inline u32 ceph_ino_to_ino32(__u64 vino)
>> +static inline u32 ceph_ino_to_ino32(u64 vino)
>> {
>> u32 ino = vino & 0xffffffff;
>> ino ^= vino >> 32;
>> @@ -475,34 +467,17 @@ static inline u32 ceph_ino_to_ino32(__u64 vino)
>> }
>>
>> /*
>> - * kernel i_ino value
>> + * Inode numbers in cephfs are 64 bits, but inode->i_ino is 32-bits on
>> + * some arches. We generally do not use this value inside the ceph driver, but
>> + * we do want to set it to something, so that generic vfs code has an
>> + * appropriate value for tracepoints and the like.
>> */
>> -static inline ino_t ceph_vino_to_ino(struct ceph_vino vino)
>> +static inline ino_t ceph_vino_to_ino_t(struct ceph_vino vino)
>> {
>> -#if BITS_PER_LONG == 32
>> - return ceph_ino_to_ino32(vino.ino);
>> -#else
>> + if (sizeof(ino_t) == sizeof(u32))
>> + return ceph_ino_to_ino32(vino.ino);
>> return (ino_t)vino.ino;
>> -#endif
>> -}
>> -
>> -/*
>> - * user-visible ino (stat, filldir)
>> - */
>> -#if BITS_PER_LONG == 32
>> -static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
>> -{
>> - return ino;
>> -}
>> -#else
>> -static inline ino_t ceph_translate_ino(struct super_block *sb, ino_t ino)
>> -{
>> - if (ceph_test_mount_opt(ceph_sb_to_client(sb), INO32))
>> - ino = ceph_ino_to_ino32(ino);
>> - return ino;
>> }
>> -#endif
>> -
>>
>> /* for printf-style formatting */
>> #define ceph_vinop(i) ceph_inode(i)->i_vino.ino, ceph_inode(i)->i_vino.snap
>> @@ -511,11 +486,34 @@ static inline u64 ceph_ino(struct inode *inode)
>> {
>> return ceph_inode(inode)->i_vino.ino;
>> }
>> +
>> static inline u64 ceph_snap(struct inode *inode)
>> {
>> return ceph_inode(inode)->i_vino.snap;
>> }
>>
>> +/**
>> + * ceph_present_ino - format an inode number for presentation to userland
>> + * @sb: superblock where the inode lives
>> + * @ino: inode number to (possibly) convert
>> + *
>> + * If the user mounted with the ino32 option, then the 64-bit value needs
>> + * to be converted to something that can fit inside 32 bits. Note that
>> + * internal kernel code never uses this value, so this is entirely for
>> + * userland consumption.
>> + */
>> +static inline u64 ceph_present_ino(struct super_block *sb, u64 ino)
>> +{
>> + if (unlikely(ceph_test_mount_opt(ceph_sb_to_client(sb), INO32)))
>> + return ceph_ino_to_ino32(ino);
>> + return ino;
>> +}
>> +
>> +static inline u64 ceph_present_inode(struct inode *inode)
>> +{
>> + return ceph_present_ino(inode->i_sb, ceph_ino(inode));
>> +}
>> +
>> static inline int ceph_ino_compare(struct inode *inode, void *data)
>> {
>> struct ceph_vino *pvino = (struct ceph_vino *)data;
>> @@ -524,11 +522,16 @@ static inline int ceph_ino_compare(struct inode *inode, void *data)
>> ci->i_vino.snap == pvino->snap;
>> }
>>
>> +
>> static inline struct inode *ceph_find_inode(struct super_block *sb,
>> struct ceph_vino vino)
>> {
>> - ino_t t = ceph_vino_to_ino(vino);
>> - return ilookup5(sb, t, ceph_ino_compare, &vino);
>> + /*
>> + * NB: The hashval will be run through the fs/inode.c hash function
>> + * anyway, so there is no need to squash the inode number down to
>> + * 32-bits first. Just use low-order bits on arches with 32-bit long.
>> + */
>> + return ilookup5(sb, (unsigned long)vino.ino, ceph_ino_compare, &vino);
>> }
>>
>>
>> --
>> 2.25.1
>
>Hi Sasha,
>
>This is a user-visible change and wasn't marked for stable for that
>reason. Please drop it.
Dropped, thanks!
--
Thanks,
Sasha